1
votes

I'm using antlr v4 (eliminates direct left recursion).

My grammar's non-terminals are: and, or, id.

and has higher priority than or, and both of them are left associative.
According to Antlr4 reference if I put and before or it will have higher precedence.

So I have written this simple grammar:

expr : 'id'
     | expr BINOP expr
     ;

BINOP: 'and'<assoc=left>    //higher precedence
     | 'or'<assoc=left>     //lower precedence
     ;

But when it parses the string id and id or id and id the associativity is ok but
precedence is not ok: ((id and id) or id) and id.

If I turn BINOP into a parser rule:

binop: 'and'<assoc=left>
     | 'or'<assoc=left>
     ;

neither associativity nor precedence work correctly:
id and (id or (id and id))

However when I implement BINOP inside expr parser rule:

expr : 'id'
     | expr 'and'<assoc=left> expr
     | expr 'or'<assoc=left> expr
     ;

everything works fine and I get the desired parse tree:
(id and id) or (id and id)

I googled a lot about the problem but I couldn't find anything.

I would be very glad if anyone could tell me where the problem is, and how
can I get correct associativity and precedence by having a separate rule for BINOP.

Thanks for your time.

1

1 Answers

0
votes

The assoc=left is default so does nothing here. Also, precedence works on alternative level and you have put both operators at the same level:

expr BINOP expr

Ter