问题描述
我有以下语法:
S -> x S y
S -> y A S y
A -> B z x
A -> x y
B -> B y
B -> epsilon
我已经构建了 LR(0) 项:
我想构建 SLR(1)。这是我得到的表格,没有包括完成的规则(最后包含点的规则,我们从中总结出减少部分):
我得到的决赛桌是:
如您所见,我在第 3 行遇到了 Shift-Reduce 冲突。在回答中,他们说不应该有任何冲突。所以我猜我没有正确插入 reduce 部分(这就是为什么我分成了部分以便您轻松检查我的解决方案)。我认为在建表的算法中,我们会查看每条末尾有点的规则作为reduce 部分。据我了解,对于每一个我们都需要为整行添加reduce(这部分我不确定)。例如,对于 A -> x y o
,我们需要将 R4(因为它是规则的编号)添加到第 9 行的所有字段(因为它是 I9)。因此,对于 I3 上的 B -> o
,我在整条线上得到了 R6,这会产生冲突。我哪里错了?我们什么时候给条目添加reduce?
解决方法
据我所知,对于每一个我们都需要为整行添加reduce。
不完全是。生成非终结符 N
的规则的缩减操作仅应用于 FOLLOW(N)
中的那些先行符号。这个限制显然是有效的。如果下一个符号不能跟在非终结符之后,那么解析器将无法在减少后移动该符号。另一方面,它不是成功的保证;即使前瞻位于非终结符的 FOLLOW 集合中,也不能保证它位于解析器在执行 GOTO 操作后将转换到的特定状态的第一个集合。进一步细化前瞻是 LALR 解析器与 SLR 解析器的区别。
在您的语法中,FOLLOW(B)
是 {y,z}
,因此reduce 操作只会放置在这两个单元格中,而不会放置在对应于 x
的单元格中。所以没有冲突。