I'm working on the parser component of my Tiger compiler in SML using ML-Yacc. I cannot find any glaring problems with my grammar file (I've used priority rules to resolve all shift-reduce conflicts) but it seems to never reduce using the second and third rules of lvalue
, which I've specified as follows:
lvalue : ID ()
| lvalue DOT ID ()
| lvalue LBRACK exp RBRACK ()
The grammar for exp
is:
exp : lvalue ()
| INT ()
| ID LBRACK exp RBRACK OF exp ()
| lvalue ASSIGN exp ()
...
When trying to parse a[0] := 5
, I expect it to reduce using the fourth exp
rule (where the lvalue
is lvalue LBRACK exp RBRACK
). Instead, Yacc finds a syntax error and substitutes ASSIGN
for OF
and parses using the third exp
rule.
Similar problems occur with lvalue DOT ID
.
I solved my problem as I was typing the question up, so I'll answer my question in case anybody else runs into this problem.
The issue (I think) is that the grammar forlvalue
is left-recursive. I thought Yacc might throw a warning about it, but it didn't - maybe the precedence rules I set hid the problem. Left-factoring the grammar fixed the problem:edit: Left-factoring just happened to resolve the problem, but left-recursion was not the issue. See comment below and a similar linked question.