如何识别 ANTLR 中的额外输入错误?
How to recognize extra input error in ANTLR?
这里是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
会被忽略。
那么这里出了什么问题?
默认情况下,规则会匹配尽可能多的输入,然后将其余部分留在令牌流中。因此,当您将输入 (3+5)4
提供给 prog
规则时,您会注意到令牌 4
之后仍将位于令牌流中。所以理论上你可以调用另一个规则然后使用它。
当您不想要这种行为时(对于您从主代码调用的规则通常不需要这种行为),您可以将 EOF
添加到规则的末尾以表示它必须始终匹配到文件末尾,如果不能匹配则产生错误。
因此,当您将 prog
规则更改为:
时,您会得到预期的错误
prog: stat+ EOF ;
这里是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
会被忽略。
那么这里出了什么问题?
默认情况下,规则会匹配尽可能多的输入,然后将其余部分留在令牌流中。因此,当您将输入 (3+5)4
提供给 prog
规则时,您会注意到令牌 4
之后仍将位于令牌流中。所以理论上你可以调用另一个规则然后使用它。
当您不想要这种行为时(对于您从主代码调用的规则通常不需要这种行为),您可以将 EOF
添加到规则的末尾以表示它必须始终匹配到文件末尾,如果不能匹配则产生错误。
因此,当您将 prog
规则更改为:
prog: stat+ EOF ;