我是antlr的新手,到目前为止,我知道如何解析源文件以及访问访问者和侦听器。我想在源文件ex./@start和//@end中创建指示符,我想通过使用listener访问该指示符,但我面临的问题是,通过.g4中行注释的lexer规则跳过了注释(我在github中使用了语法文件c++(。如何创建一个语法分析器规则而不影响语法文件中的其他规则?我需要使用该指示符的ctx在之前进行wrtiing或替换,这是我的目标下面的代码解释了源文件。
for(int i=1;i<=c;i++)
{
fact=fact*i;
//@start ...this is indicator 1
}
//@end ...this is indicator 2
printf("Factorial is %d",fact);
感谢
使用刚刚从https://github.com/antlr/grammars-v4,称为CPP14Lexer.g4和CPP14Parser.g4。线路408 的双工器
LineComment: '//' ~ [rn]* -> skip;
跳过行注释。但是lexer规则是贪婪的:如果两个规则以相同的字符开头,lexer将选择消耗最多字符的一个。因此,您可以根据需要添加两条规则:
Start_indicator : '//@start' ~ [rn]* ;
End_indicator : '//@end' ~ [rn]* ;
LineComment : '//' ~ [rn]* -> skip;
解析器必须识别这些令牌,例如,在statement
规则中添加indicator
规则(lexer规则以大写字母开头,解析器规则以小写字母开头(:
statement:
labeledStatement
| attributeSpecifierSeq? (
expressionStatement
| compoundStatement
| selectionStatement
| iterationStatement
| jumpStatement
| tryBlock
)
| declarationStatement
| indicator
;
indicator : Start_indicator | End_indicator ;
使用main
包围您的示例以避免错误,请将t.text
归档
int main(int argc, char *argv[]) {
for(int i=1;i<=c;i++)
{
fact=fact*i;
//@start ...this is indicator 1
}
//@end ...this is indicator 2
printf("Factorial is %d",fact);
}
执行:
$ export CLASSPATH=".:/usr/local/lib/antlr-4.6-complete.jar"
$ alias a4='java -jar /usr/local/lib/antlr-4.6-complete.jar'
$ alias grun='java org.antlr.v4.gui.TestRig'
$ a4 CPP*.g4
$ javac CPP*.java
$ grun CPP14 translationUnit -tokens t.text
[@0,0:2='int',<'int'>,1:0]
[@1,4:7='main',<Identifier>,1:4]
...
[@28,64:67='fact',<Identifier>,4:4]
[@29,68:68='=',<'='>,4:8]
[@30,69:72='fact',<Identifier>,4:9]
[@31,73:73='*',<'*'>,4:13]
[@32,74:74='i',<Identifier>,4:14]
[@33,75:75=';',<';'>,4:15]
[@34,81:111='//@start ...this is indicator 1',<Start_indicator>,5:4]
[@35,117:117='}',<'}'>,7:0]
[@36,120:148='//@end ...this is indicator 2',<End_indicator>,8:1]
[@37,150:155='printf',<Identifier>,9:0]
[@38,156:156='(',<'('>,9:6]
[@39,157:173='"Factorial is %d"',<StringLiteral>,9:7]
[@40,174:174=',',<','>,9:24]
[@41,175:178='fact',<Identifier>,9:25]
[@42,179:179=')',<')'>,9:29]
[@43,180:180=';',<';'>,9:30]
[@44,182:182='}',<'}'>,10:0]
[@45,184:183='<EOF>',<EOF>,11:0]
已经为Start_indicator
和End_indicator
生成了单独的令牌。解析器规则可以在生成的CPP14ParserListener.java
:中找到
/**
* Enter a parse tree produced by {@link CPP14Parser#indicator}.
* @param ctx the parse tree
*/
void enterIndicator(CPP14Parser.IndicatorContext ctx);