如何识别ANTLR中的额外输入错误?

时间:2018-12-17 13:04:08

标签: expression antlr grammar antlr4

这是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)

parsing tree for <code>(3+5)*4</code> parsing tree for <code>(3+5)4</code>

我还注意到一些类似的情况,如果在输入中找到了一些匹配项,则其余输入将被忽略。例如,我定义了一个语法:

relation_op : LESS_THAN | LEQ | GREATER_THAN | GEQ | EQUAL |
              DOUBLE_EQUAL | NEQ; 
              //Capital letters are predefined symbols(<,>,=...)

然后,我输入<dskjkdsd,将正确显示<的分析树,而忽略额外的错误输入dskjkdsd

enter image description here

那么这出了什么问题?

1 个答案:

答案 0 :(得分:2)

默认情况下,规则会尽可能匹配所有输入,然后将其余输入留在令牌流中。因此,当您将输入(3+5)4输入到prog规则时,您会注意到令牌4之后仍将位于令牌流中。因此,从理论上讲,您可以调用另一个使用它的规则。

当您不希望这种行为时(通常对于从主代码调用的规则而言,您通常不希望这样做),您可以在规则的末尾添加EOF,以表示该行为必须始终匹配直到文件末尾,如果不能,则产生错误。

因此,当您将prog规则更改为:

时,您会得到预期的错误。
prog: stat+ EOF ;