I am using the antlr4 plugin for IntelliJ to create a grammar for a project I'm working on. In the process of learning how to use antlr, I took a look at Github user shmatov's simple antlr4 calculator shown below.
grammar Calculator;
INT : [0-9]+;
DOUBLE : [0-9]+'.'[0-9]+;
PI : 'pi';
E : 'e';
POW : '^';
NL : '\n';
WS : [ \t\r]+ -> skip;
ID : [a-zA-Z_][a-zA-Z_0-9]*;
PLUS : '+';
EQUAL : '=';
MINUS : '-';
MULT : '*';
DIV : '/';
LPAR : '(';
RPAR : ')';
input
: plusOrMinus NL? EOF # Calculate
;
plusOrMinus
: plusOrMinus PLUS multOrDiv # Plus
| plusOrMinus MINUS multOrDiv # Minus
| multOrDiv # ToMultOrDiv
;
multOrDiv
: multOrDiv MULT pow # Multiplication
| multOrDiv DIV pow # Division
| pow # ToPow
;
pow
: unaryMinus (POW pow)? # Power
;
unaryMinus
: MINUS unaryMinus # ChangeSign
| atom # ToAtom
;
atom
: PI # ConstantPI
| E # ConstantE
| DOUBLE # Double
| INT # Int
| ID # Variable
| LPAR plusOrMinus RPAR # Braces
;
Interestingly, when a single number is entered, such as the integer '5', the resulting parse tree shows that the # Plus and # Multiplication labels are run. This doesn't make a lot of sense to me. There are no +
or *
operators in the input. I've uploaded an image of the parse tree below to give a better idea of what I'm talking about.
It seems that antlr just defaults to whatever the first alternative in the rule is, but wouldn't it make more sense for the calculator to take the straight path through labels # Calculate -> # ToMultOrDiv -> # ToPow -> # ToAtom -> # Int
? How does it even go through # Plus and # Multiplication without the right operators?