D.De
D.De

Reputation: 13

ANTLR 4 / Parser recognizes erroneous expression as valid

Grammar file Expr.g4:

grammar Expr;

expr:   expr ('*'|'/'|'+'|'-'|'%') expr 
    |   '(' expr ')'
    |   INT 
    ;

INT :   [0-9]+ ;
WS  :   [ \t\n]+ -> skip ;

I use the current ANTLR-Version 4.7.1: In ./bashrc:

alias antlr4='java -jar ~/antlr4/antlr-4.7.1-complete.jar'
alias grun='java org.antlr.v4.runtime.misc.TestRig'

With this grammar the expression '1(' shouldn't be recognized as valid, but it is.

grun Expr expr -tokens on the command line with input '1(' and CTRL-D for EOF gives:

[@0,0:0='1',<INT>,1:0]

[@1,1:1='(',<'('>,1:1]

[@2,2:1='<EOF>',<EOF>,1:2]

While the expression '1(' is not rejected, ')1' is:

[@0,0:0=')',<')'>,1:0]

[@1,1:1='1',<INT>,1:1]

[@2,2:1='<EOF>',<EOF>,1:2]

line 1:0 extraneous input ')' expecting {'(', INT}

Did I miss something?

Upvotes: 1

Views: 89

Answers (1)

sepp2k
sepp2k

Reputation: 370112

When you invoke a rule in ANTLR, it successfully returns a result as long as it can match any prefix of the input. If you want a rule to only succeed if it matches the entire remaining input, you'll need to add EOF as the last token.

However, you don't want to add EOF to the expr rule because you also use that rule to match sub-expressions. So instead you should define another rule that's just expr EOF and invoke that one with grun.

Upvotes: 3

Related Questions