Sugihara
Sugihara

Reputation: 1101

OCaml parser for :: case

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

Answers (2)

ivg
ivg

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

Chris Dodd
Chris Dodd

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

Related Questions