Reputation: 210352
I'm trying to make my own LR(0) parser, and I'm running into trouble with some grammars.
Basically, for the grammar
exp: mexp
mexp: '1'
mexp: mexp '*' '1'
my parser is outputting
State 0: • 1
| • mexp
| • exp
| • mexp * 1
State 1: 1 •
State 2: exp •
State 3: mexp • * 1
| mexp •
State 4: mexp * • 1
State 5: mexp * 1 •
with the warning
(state 3, *) already has reduction: exp: mexp
The LR(0) table my program derived for this grammar is:
'1' exp mexp '*' $
State 0: s1 s2 s3
State 1: r3 r3 r3
State 2: acc
State 3: r2 s4 r2
State 4: s5
State 5: r4 r4 r4
where $ denotes the end of file.
The warning stems from the fact that state 3 -- which corresponds to mexp • * 1 | mexp •
-- has both a reduction r2
and a state transition s4
for the input *
.
But it seems like according to Wikipedia, this should not be happening -- I should only have reductions:
If an item set i contains an item of the form A → w • and A → w is rule m with m > 0 then the row for state i in the action table is completely filled with the reduce action rm.
The funny thing is, when I remove the rule exp: mexp
, I don't get any such conflicts.
So what I'm having trouble figuring out is, is this indeed a genuine problem in the grammar?
(In other words, is this grammar not, in fact, LR(0)?)
I don't believe this to be the case but I'm not sure.
If so, why? And if not, then what's wrong? (Is my table wrong, or am I doing something else incorrectly?)
Upvotes: 0
Views: 264
Reputation: 241671
(After reading that Wikipedia page more carefully.)
The Wikipeda quote is (emphasis added):
If an item set i contains an item of the form A → w • and A → w is rule m with m > 0 then the row for state i in the action table is completely filled with the reduce action rm.
Rule 0 is the augmented start rule, which in your case should be:
start : mexp '$'
(Personally, I prefer adding the EOF token explicitly; there are fewer exceptions that way.)
However, what you've got, I think, is:
start : exp '$'
exp : mexp
which actually isn't LR(0), because the unit reduction rule ( exp → mexp ) leads to the shift-reduce conflict you discovered.
The Wikipedia article's exception for m = 0
would be unnecessary if the rule were written with an explicit end-marker; in this case, the action acc
is generated according to modified action 3:
- An extra column for '$' (end of input) is added to the action table that contains acc for every item set that contains S → E • '$'.
(Actually, you don't need the "extra column" part; with an explicit end-marker you should already have a column for it. The point is to override the shift action with an acc action.)
Upvotes: 1