仅通过ANTLR 4消耗java文件的注释(/ ** ..... * /)部分,并跳过其余部分

时间:2014-11-23 11:01:47

标签: java antlr antlr4

我是ANTLR的新手并且熟悉ANTLR 4.如何仅从java文件(或任何文件)中使用注释部分(/ ** ... * /)并跳过其余部分。

我有以下文件“t.txt”: -

t.txt

/**

@Key1("value1")
@Key2("value2")

*/

This is the text that we need to skip. Only wanted to read the above commented section.

//END_OF_FILE

AND我的语法文件如下: -

MyGrammar.g4

grammar MyGrammar;

file : (pair | LINE_COMMENT)* ;

pair : ID VALUE ;

ID  :   '@' ('A'..'Z') (~('('|'\r'|'\n') | '\\)')* ;

VALUE   :  '(' (~('\r'|'\n'))*;

COMMENT : '/**' .*? '*/';

WS : [\t\r\n]+  -> skip;

LINE_COMMENT
     : '#' ~('\r'|'\n')* ('\r'|'\n'|EOF)
     ;

我知道COMMENT规则会读取评论部分,但在此我不知道如何跳过文件内容的其余部分并强制antlr仅从COMMENT内容中读取ID和值。

1 个答案:

答案 0 :(得分:2)

您可以使用lexical modes。当词法分析器偶然发现"/**"并忽略其他所有内容时,只需切换到另一个模式

请注意,词汇模式不能用于组合语法。您将不得不定义一个单独的词法分析器和解析器语法。

一个小型演示:

AnnotationLexer.g4

lexer grammar AnnotationLexer;

ANNOTATION_START
 : '/**' -> mode(INSIDE), skip
 ;

IGNORE
 : . -> skip
 ;

mode INSIDE;

ID
 : '@' [A-Z] (~[(\r\n] | '\\)')*
 ;

VALUE
 : '(' ~[\r\n]*
 ;

ANNOTATION_END
 : '*/' -> mode(DEFAULT_MODE), skip
 ;

IGNORE_INSIDE
 : [ \t\r\n] -> skip
 ;

file:AnnotationParser.g4

parser grammar AnnotationParser;

options {
  tokenVocab=AnnotationLexer;
}

parse
 : pair* EOF
 ;

pair
 : ID VALUE {System.out.println("ID=" + $ID.text + ", VALUE=" + $VALUE.text);}
 ;

现在只需使用词法分析器和解析器:

String input = "/**\n" +
        "\n" +
        "@Key1(\"value1\")\n" +
        "@Key2(\"value2\")\n" +
        "\n" +
        "*/\n" +
        "\n" +
        "This is the text that we need to skip. Only wanted to read the above commented section.\n" +
        "\n" +
        "//END_OF_FILE";

AnnotationLexer lexer = new AnnotationLexer(new ANTLRInputStream(input));
AnnotationParser parser = new AnnotationParser(new CommonTokenStream(lexer));
parser.parse();

将产生以下输出:

ID=@Key1, VALUE=("value1")
ID=@Key2, VALUE=("value2")