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

时间:2012-10-17 21:40:19

标签: parsing language-agnostic grammar lr

我正在尝试创建自己的LR(0)解析器,而且我遇到了一些语法问题。

基本上,语法

exp:  mexp
mexp: '1'
mexp: mexp '*' '1'

我的解析器正在输出

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 •

带警告

(state 3, *) already has reduction:  exp: mexp

我的程序为这个语法派生的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

其中$表示文件的结尾。

警告源于这样一个事实:状态3 - 对应于mexp • * 1 | mexp • - 两者减少r2 状态输入s4的转化*

但似乎according to Wikipedia,这不应该发生 - 我应该只有减少:

  

如果项目 i 包含A→w形式的项目,而A→w是规则 m ,其中 m > 0然后动作表中状态 i 的行完全用reduce动作r m 填充。

有趣的是,当我删除规则exp: mexp时,我没有遇到任何此类冲突。

所以我弄清楚的是,这确实是语法中的一个真正的问题吗? (换句话说,这个语法实际上不是LR(0)吗?)
我不相信这种情况,但我不确定。

如果是这样,为什么?如果没有,那么什么是错的? (我的桌子错了,还是我做错了什么?)

1 个答案:

答案 0 :(得分:1)

(更仔细阅读维基百科页面后。)

维基百科的报价是(重点补充):

  

如果一个项目集i包含一个形式为A→w的项目,而A→w是规则m ,其中m> 0 然后动作表中状态i的行完全用reduce动作r m 填充。

规则0是增强的开始规则,在您的情况下应该是:

start : mexp '$'

(就个人而言,我更喜欢明确地添加EOF令牌;这样的例外情况就更少了。)

但是,我认为你得到的是:

start : exp '$'
exp   : mexp

实际上不是LR(0),因为单位缩减规则(exp→mexp)会导致您发现的移位减少冲突。

如果规则是用明确的结束标记写的,那么维基百科文章对m = 0的例外是不必要的;在这种情况下,动作acc是根据修改的动作3生成的:

  
      
  1. “$”(输入结束)的额外列添加到操作表中,该表包含每个包含S→E的项目集合的acc•'$'。
  2.   

(实际上,你不需要“额外列”部分;使用明确的结束标记你应该已经有了一个列。重点是用acc动作覆盖shift行动。)