这是ANTLR中简单算术表达式的语法。我想获得一个简单的算术表达式的解析树。
grammar LabeledExpr; // rename to distinguish from Expr.g4
prog: stat+ ;
stat: expr NEWLINE # printExpr
| ID '=' expr NEWLINE # assign
| NEWLINE # blank
;
expr: expr op=('*'|'/') expr # MulDiv
| expr op=('+'|'-') expr # AddSub
| INT # int
| ID # id
| '(' expr ')' # parens
;
MUL : '*' ; // assigns token name to '*' used above in grammar
DIV : '/' ;
ADD : '+' ;
SUB : '-' ;
ID : [a-zA-Z]+ ; // match identifiers
INT : [0-9]+ ; // match integers
NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement
signal)
WS : [ \t]+ -> skip ; // toss out whitespace
现在,我输入(3+5)*4
,ANTLR会正确生成表达式的解析树。但是,如果我输入的(3+5)4
不是有效输入,那么我也不会得到任何错误和解析树。从输出看来,似乎仅接受(3+5)
。
我还注意到一些类似的情况,如果在输入中找到了一些匹配项,则其余输入将被忽略。例如,我定义了一个语法:
relation_op : LESS_THAN | LEQ | GREATER_THAN | GEQ | EQUAL |
DOUBLE_EQUAL | NEQ;
//Capital letters are predefined symbols(<,>,=...)
然后,我输入<dskjkdsd
,将正确显示<
的分析树,而忽略额外的错误输入dskjkdsd
。
那么这出了什么问题?
答案 0 :(得分:2)
默认情况下,规则会尽可能匹配所有输入,然后将其余输入留在令牌流中。因此,当您将输入(3+5)4
输入到prog
规则时,您会注意到令牌4
之后仍将位于令牌流中。因此,从理论上讲,您可以调用另一个使用它的规则。
当您不希望这种行为时(通常对于从主代码调用的规则而言,您通常不希望这样做),您可以在规则的末尾添加EOF
,以表示该行为必须始终匹配直到文件末尾,如果不能,则产生错误。
因此,当您将prog
规则更改为:
prog: stat+ EOF ;