Quite soon, I found the Lua grammar on the ANTLR github to skip operator precedence.

The old grammar is:

exp
: ...
| exp binop exp | unop exp
;
binop
: '+' | '-' | '*' | '/' | '^' | '%' | '..'
| '<' | '<=' | '>' | '>=' | '==' | '~='
| 'and' | 'or'
;
unop
: '-' | 'not' | '#'
;

Obviously, there is no trace of operator precedence. A quick check to the Lua reference tells us the precedence and also specifies operator associativity. So I went with this:

exp
: ...
| <assoc=right> exp operatorPower exp
| operatorUnary exp
| exp operatorMulDivMod exp
| exp operatorAddSub exp
| <assoc=right> exp operatorStrcat exp
| exp operatorComparison exp
| exp operatorAnd exp
| exp operatorOr exp
| ...
;
operatorOr
: 'or';
operatorAnd
: 'and';
operatorComparison
: '<' | '>' | '<=' | '>=' | '~=' | '==';
operatorStrcat
: '..';
operatorAddSub
: '+' | '-';
operatorMulDivMod
: '*' | '/' | '%';
operatorUnary
: 'not' | '#' | '-';
operatorPower
: '^';

Curiously, ANTLR syntax for <assoc=right> has changed somewhere between ANTRL 4.0 and 4.2, rendering the ANLTR4 reference wrong on that aspect. The manual says to write it like

rule : exp '^'<assoc=right> exp;

while now the <assoc=right> should be applied to the ‘:’ or ‘|’ :

rule :<assoc=right> exp '^' exp;

If using the first syntax (the manual one) the build emits a warning AC0157: rule ‘exp’ contains an ‘assoc’ terminal option in an unrecognized location

References to this peculiarity: TheAntlrGuy wiki and an helpful StackOverflow post.

01 Oct