简体   繁体   English

我的LR(0)语法有什么问题?

[英]What's wrong with my LR(0) grammar?

I'm trying to make my own LR(0) parser, and I'm running into trouble with some grammars. 我正在尝试制作自己的LR(0)解析器,并且遇到一些语法问题。

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: 我的程序为此语法派生的LR(0)表是:

         '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 • 该警告源于以下事实:状态3-对应于mexp • * 1 | mexp • mexp • * 1 | mexp • -- has both a reduction r2 and a state transition s4 for the input * . mexp • * 1 | mexp • -对输入* 既有约r2 又有状态转移s4

But it seems like according to Wikipedia , this should not be happening -- I should only have reductions: 但是根据Wikipedia的说法,这似乎不应该发生-我应该减少一下:

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 r m . 如果项目集i包含形式为A→w•的项目,并且A→w是m > 0的规则m ,则操作表中状态i的行将完全由化简操作r m填充。

The funny thing is, when I remove the rule exp: mexp , I don't get any such conflicts. 有趣的是,当我删除规则exp: mexp ,没有任何此类冲突。

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)?) (换句话说,这个语法实际上不是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?) (我的桌子错了吗,还是我做错了其他事情?)

(After reading that Wikipedia page more carefully.) (在仔细阅读了Wikipedia页面之后。)

The Wikipeda quote is (emphasis added): Wikipeda的引用是(强调):

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 r m . 如果项目集i包含形式为A→w•的项目,并且A→w是m> 0的规则m 则操作表中状态i的行将完全由化简操作r m填充。

Rule 0 is the augmented start rule, which in your case should be: 规则0是扩充起始规则,在您的情况下,应为:

start : mexp '$'

(Personally, I prefer adding the EOF token explicitly; there are fewer exceptions that way.) (就我个人而言,我更喜欢显式添加EOF令牌;这样,例外情况就更少了。)

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. 实际上不是LR(0),因为单位缩减规则(exp→mexp)会导致您发现的移位减少冲突。

The Wikipedia article's exception for m = 0 would be unnecessary if the rule were written with an explicit end-marker; 如果规则是用显式的结束标记编写的,则Wikipedia文章中m = 0的例外将是不必要的。 in this case, the action acc is generated according to modified action 3: 在这种情况下,操作acc是根据修改后的操作3生成的:

  1. An extra column for '$' (end of input) is added to the action table that contains acc for every item set that contains S → E • '$'. 在操作表中添加了额外的'$'列(输入的末尾),该表包含包含S→E•'$'的每个项目集的acc。

(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.) (实际上,您不需要“额外的列”部分;使用显式的结束标记,您应该已经有一个列。要点是用acc动作覆盖shift动作。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM