Description
There are a few issues with the associativity option:
- In doc/options.md, the associativity option is presented as follows:
grammar ExprLR; expr : expr '^'<assoc=right> expr | expr '*' expr // match subexpressions joined with '*' operator | expr '+' expr // match subexpressions joined with '+' operator | INT // matches simple integer atom ;
- The other page mentioning this option is correct but not entirely accurate. In doc/left-recursion.md:
e : e '*' e | e '+' e |<assoc=right> e '?' e ':' e |<assoc=right> e '=' e | INT ;If your 4.0 or 4.1 grammar uses a right-associative ternary operator, you will need to update your grammar to
include <assoc=right> on the alternative operator. To smooth the transition, <assoc=right> is still allowed on
token references but it is ignored.
If the first rule is right-associative, there is only an alternative operator on its right, so I assume the actual position is before the factor. Unless it's possible to put it inside parentheses or elsewhere, like e : e '*' e | {pred}? (e '+' e | e <assoc=right> '?' e ':' e | INT)
, in which case it's more complicated to explain.
- If a grammar is compiled using that option with the pre-4.0 format, ANTLR issues the following warning:
warning(157): Calc.g4:10:7: rule expr contains an assoc terminal option in an unrecognized location
It should be an error instead because it's very likely to produce a parser that doesn't correspond to what the user expects, and a simple warning is too easy to overlook. If an element of the parsed grammar is not good, the whole grammar should be rejected with a precise (and, if possible, helpful) error message:
error(XYZ): Calc.g4:10:7: rule expr contains an assoc terminal option in an unrecognized location. This terminal option should be at the beginning of the factor containing the target operator.
Note
I could do a pull request with the doc fix, although I'm not entirely sure of the rule, and there seems to be many pending pull requests. But I don't think I'm the right person to modify the warning message—I could try, but only if I'm sure the pull request has a chance to pass, so if that's fine for everyone and if the project is still active.