Skip to content

Issues with "<assoc=right>" in doc and parser generator #4841

Open
@blueglyph

Description

@blueglyph

There are a few issues with the associativity option:

  1. 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
 	;
  1. 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.

  1. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions