Reputation: 1101
I'm having trouble with associativity. For some reason my = operator has higher precedence than my :: operator
So for instance, if I have
"1::[] = []"
in as a string, I would get
1 = []::[]
as my expression instead of
[1] = []
If my string is "1::2::[] = []"
I thought I it would parse it into exp1 EQ exp2, then from then on it will parse exp1 and exp2. But it is parsing as exp1 COLONCOLON exp2 instead
.
.
.
%nonassoc LET FUN IF
%left OR
%left AND
%left EQ NE LT LE
%right SEMI COLONCOLON
%left PLUS MINUS
%left MUL DIV
%left APP
.
.
.
exp4:
| exp4 EQ exp9 { Bin ($1,Eq,$3) }
| exp4 NE exp9 { Bin ($1,Ne,$3) }
| exp4 LT exp9 { Bin ($1,Lt,$3) }
| exp4 LE exp9 { Bin ($1,Le,$3) }
| exp9 { $1 }
exp9:
| exp COLONCOLON exp9 { Bin ($1,Cons,$3) }
| inner { $1 }
.
.
.
Upvotes: 2
Views: 209
Reputation: 35210
Rules aren't just applied like functions, so you can't refactor your grammar in a set of rules, at least with ocamlyacc
. You can try to use menhir
, that allows such refactoring by inlining rules (%inline
directive).
To enable menhir
you need to install it, and pass an option -use-menhir
to ocamlbuild
, if you're using it.
Upvotes: 4
Reputation: 126150
It looks like you might have multiple expression rules (exp
, exp1
, exp2
, ... exp9
), in which case the precedence of operations is determined by the interrelation of those rules (which rule expands to which other rule), and the %left
/%right
declarations are largely irrelevant.
The yacc precedence rules are only used to resolve shift/reduce conflicts, and if your grammar doesn't have shift/reduce conflicts (having resolved the ambiguity by using multiple rules), the precedence levels will have no effect.
Upvotes: 4