Syntactic errors on optional rules in Antlr 4 does

2020-05-08 12:07发布

问题:

I am using Antlr 4.7.2. I am trying to implement an "if else" statement:

Main problem is that optional rule is not being included on ParseTree, for this reason I think I am not getting the syntax's errors on that optional rule.

Ones of my current grammar definition are:

 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) ;

Everything work good when and I write the code correct syntactically and run grammar using "org.antlr.v4.gui.TestRig":

if (2==2){
    let a = 4;
}
else{
    let b = 5;  //var declaration
}

But when I wrote next code, "else_stat" rule is not included on the ParseTree result and Antlr4 doesn't report any syntactic error.

if (2==2){
    let a = 4;
}
else{
    let b = 5;

If I remove "?" from "else_stat" rule (making it mandatory), Antlr4 include "else_stat" at ParseTree and is able to identify the error and show the corresponding message: "Missing '}'".

Please, anybody could guide me in the right address? I need to know how to make Antlr4 show the syntactic error regardless it happens on optional rules or if I need to fix my grammar definition or something else.

Thanks.

回答1:

Normally it is not a syntax error if an input stream contains more input than what is required by the rule you invoke. The additional input is simply left in the stream. This allows you to invoke rules in a loop for example.

So if you invoke your prog rule on the input if (2==2){ let a = 4; } else { let b = 5;, the if (2==2){ let a = 4; } part will be parsed as an if-statement without else and else { let b = 5; will remain in the input buffer.

Since that's not what you want, you should add EOF at the end of your prog rule:

prog       : stat+ EOF;

The EOF tells ANTLR that a program is only syntactically valid if there's nothing left in the input after parsing it. This will give you the syntax error you want for your input.



标签: antlr antlr4