陈述是否正确:
当且仅当存在项目时,在LR(1)解析器中发生移位减少冲突:
A - >阿尔法。
A - > α 。测试
使得跟随(A)与First(beta)不相交。
其中A是非终端,alpha和beta可能是空语法符号序列。“
(直观地说,这是因为没有办法根据堆栈顶部和前瞻确定是否适合转移或减少)
注意:如果你们认为这取决于第一个/后续评论定义的任何细节,我会提供。
答案 0 :(得分:2)
不,该陈述不正确。
假设某些语法:
这对语法来说还不足以产生shift-reduce冲突,因为它要求在前瞻包含FOLLOW的上下文中非终端A
可到达 (A)∩FIRST(β)。
因此,只有当我们要求减少语法,或者至少不包含任何无法访问或无用的产品时,上面足以生成一个shift-reduce冲突。
但是,上述条件不是必要的,因为不要求移位和缩小适用于相同的非终端或甚至“相关的”非终端。请考虑以下简单语法:
prog → stmt
prog → prog stmt
stmt → expr
stmt → func
expr → ID
expr → '(' expr ')'
func → ID '(' ')' stmt
该语法(在发生时不含糊不清)在包含ID . (
的状态中存在移位减少冲突,因为ID
可以缩减为expr
然后{{1 }}或stmt
可以作为(
的一部分进行转移。
虽然这是一个侧点,但值得注意的是FOLLOW集只用于构造SLR(k)语法。规范的LR(k)构造 - 甚至是LALR(k)构造 - 将成功地为语法生成解析器,其中使用FOLLOW集而不是完整的先行计算将指示(不存在的)shift-reduce冲突。这个经典的例子取自龙书(我的副本中的例子4.39),用更有意义的非终端名称进行编辑:
func → ID '(' ')' stmt
此处,FOLLOW( rvalue )为{ = , $ },因此状态为{stmt → lvalue '=' rvalue
stmt → rvalue
lvalue → '*' rvalue
lvalue → ID
rvalue → lvalue
,stmt → lvalue · '=' rvalue
},似乎可以减少rvalue → lvalue ·
,导致错误的转移 - 减少冲突。