LR(1)解析

时间:2016-03-24 13:04:20

标签: parsing compiler-construction theory lr

陈述是否正确:

当且仅当存在项目时,在LR(1)解析器中发生移位减少冲突:

A - >阿尔法。

A - > α 。测试

使得跟随(A)与First(beta)不相交。

其中A是非终端,alpha和beta可能是空语法符号序列。“

(直观地说,这是因为没有办法根据堆栈顶部和前瞻确定是否适合转移或减少)

注意:如果你们认为这取决于第一个/后续评论定义的任何细节,我会提供。

1 个答案:

答案 0 :(得分:2)

不,该陈述不正确。

假设某些语法:

  • 制作包括:
    • A→α
    • A→αβ
  • 跟随(A)∩FIRST(β)≠∅

这对语法来说还不足以产生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 ·,导致错误的转移 - 减少冲突。