Antlr 4中可选规则的语法错误无法正常工作

时间:2019-05-09 20:58:43

标签: antlr antlr4

我正在使用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显示语法错误,而不管它是否发生在可选规则上,或者是否需要修复我的语法定义或其他内容。

谢谢。

1 个答案:

答案 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,仅在语法上解析后,如果输入中没有任何内容,则该程序仅在语法上有效。这将为您提供输入所需的语法错误。