Antlr 4 中可选规则的语法错误无法按预期工作

Syntactic errors on optional rules in Antlr 4 doesn't work as expected

我正在使用 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" 并且能够识别错误并显示相应的消息:"Missing '}'".

拜托,有人可以指导我找到正确的地址吗?我需要知道如何让 Antlr4 显示语法错误,无论它发生在可选规则上还是我需要修复我的语法定义或其他东西。

谢谢。

如果输入流包含的输入多于您调用的规则所需的输入,通常这不是语法错误。额外的输入只是留在流中。例如,这允许您在循环中调用规则。

因此,如果您在输入 if (2==2){ let a = 4; } else { let b = 5; 上调用 prog 规则,if (2==2){ let a = 4; } 部分将被解析为 if-statement 而没有 else 和 else { let b = 5;将保留在输入缓冲区中。

因为这不是您想要的,您应该在 prog 规则的末尾添加 EOF

prog       : stat+ EOF;

EOF 告诉 ANTLR 程序只有在解析后输入中没有任何内容时才在语法上有效。这将为您提供输入所需的语法错误。