我正在使用Antlr 4.7.2。我正在尝试执行“ if else”语句:
主要问题是ParseTree上未包含可选规则,因此我认为该可选规则没有语法错误。
我当前的语法定义是:
prog : stat+ ;
stat : func_declaration #rFuncDeclStat
| if_stat #rIfStat
| while_stat #rWhileStat
| for_stat #rForStat
| 'return' expr? STAT_END #rReturnStat
| LET ID ('=' expr)? STAT_END #rVarDeclStat
| var_reference '=' expr STAT_END #rAssignStat
| print_stat #rPrintStat
| expr STAT_END #rFuncCallStat
;
block_stat : '{' stat* '}' ;
if_stat : if '(' expr ')' (stat | block_stat) else_stat?;
else_stat : ELSE (stat | block_stat) ;
当我语法正确地编写代码并使用“ org.antlr.v4.gui.TestRig”运行语法时,一切工作都很好:
if (2==2){
let a = 4;
}
else{
let b = 5; //var declaration
}
但是当我编写下一个代码时,“ else_stat”规则未包含在ParseTree结果中,并且Antlr4不会报告任何语法错误。
if (2==2){
let a = 4;
}
else{
let b = 5;
如果我删除“?”根据“ else_stat”规则(使其成为强制性规则),Antlr4在ParseTree中包括“ else_stat”,并且能够识别错误并显示相应的消息:“缺少'}'”。
请,有人可以引导我进入正确的地址吗?我需要知道如何使Antlr4显示语法错误,而不管它是否发生在可选规则上,或者是否需要修复我的语法定义或其他内容。
谢谢。
答案 0 :(得分:1)
通常,如果输入流包含的输入多于调用规则所要求的输入,则不是语法错误。只是将附加输入保留在流中。例如,这使您可以循环调用规则。
因此,如果您在输入prog
上调用if (2==2){ let a = 4; } else { let b = 5;
规则,则if (2==2){ let a = 4; }
部分将被解析为if语句,而其他则else { let b = 5;
将保留在输入缓冲区。
由于这不是您想要的,因此应在EOF
规则的末尾添加prog
:
prog : stat+ EOF;
EOF
告诉ANTLR,仅在语法上解析后,如果输入中没有任何内容,则该程序仅在语法上有效。这将为您提供输入所需的语法错误。