我很难坚持我正在尝试从编译器的样本期末考试中提出的问题。如果有人可以帮我解释,我将非常感激。感谢
考虑下面列出的语法G
$
+
T | Ť*
F | ˚Fident
| (
E )
其中+ * ident()是终端符号,$
是文件结尾。
a)这个语法LR(0)?证明你的答案。
b)语法单反(1)?证明你的答案。
c)这个语法LALR(1)?证明你的答案。
答案 0 :(得分:9)
如果你能证明语法是LR(0)那么它当然是SLR(1)和LALR(1)因为LR(0)更具限制性。
不幸的是,语法不是LR(0)。
例如,假设您刚刚认出了E:
S -> E . $
如果后面的内容是+
或*
符号,则不得将此E减少为S,因为E
可以跟+
或*
继续建立更大的表达:
S -> E . $
E -> E . + T
T -> T . * F
这要求我们向前看一个令牌以了解在该状态下该做什么:转移(+
或*
)或减少($
)。
SLR(1)添加了前瞻,并利用跟随设置信息进行缩减(总比没有好,但是从语法中全局获得的跟随设置信息不是上下文敏感的,就像特定于状态的前瞻集一样在LALR(1))。
在SLR(1)下,上述冲突消失了,因为仅当前瞻符号位于S -> E
的跟随集中时才会考虑S
缩减,并且以下集合中的唯一内容S
是EOF符号$
。如果输入符号不是$
,如+
,则不考虑减少;发生了与减少不相冲突的转变。
因此,语法不会因为该冲突而成为SLR(1)
。但是,它可能还有其他冲突。透过它看,我看不到一个;但要正确地“证明答案”,你必须生成所有LR(0)状态项,并完成验证未违反SLR(1)约束的例程。 (对于SLR(1),您使用简单的LR(0)项,因为SLR(1)不会以任何新的方式扩充这些项。请记住,它只使用从语法中剔除的后续信息来消除冲突。)
如果是SLR(1),则LALR(1)按子集关系下降。
<强>更新强>
Red Dragon Book( Compilers:Principles,Techniques and Tools ,Aho,Sethi,Ullman,1988)在一组示例中使用完全相同的语法,这些示例显示了规范LR的推导( 0)项集和关联的DFA,以及填写解析表的一些步骤。这是在4.7节,从例4.34开始。