Parsing LR(1)解析中移位/归约冲突的定义

Parsing LR(1)解析中移位/归约冲突的定义,parsing,compiler-construction,theory,lr,Parsing,Compiler Construction,Theory,Lr,这样说是否正确: “当且仅当存在以下项时,LR(1)解析器中才会发生移位-减少冲突: A->alpha A->alpha.beta 这样跟随(A)和第一(beta)就不会分离 其中A是非终端,alpha和beta可能是语法符号的空序列。” (直观地说,这是因为无法根据堆栈顶部和前瞻性来确定移位还是缩小) 注意:如果你们认为这取决于第一条/第二条评论定义的任何细节,我将提供。不,这句话是不正确的 在某些语法中假设: prog → stmt prog → prog stmt stmt → expr

这样说是否正确:

“当且仅当存在以下项时,LR(1)解析器中才会发生移位-减少冲突:

A->alpha

A->alpha.beta

这样跟随(A)和第一(beta)就不会分离

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

(直观地说,这是因为无法根据堆栈顶部和前瞻性来确定移位还是缩小)


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

不,这句话是不正确的

在某些语法中假设:

prog → stmt
prog → prog stmt
stmt → expr
stmt → func
expr → ID
expr → '(' expr ')'
func → ID '(' ')' stmt
  • 这些作品包括:
    • A→ α
    • A→ αβ
  • 跟进(A)∩ 第一(β)≠ ∅
这还不足以让语法产生移位-减少冲突,因为它要求非终结符
a
在包含FOLLOW(a)的先行上下文中是可到达的∩ 第一(β)

因此,只有当我们要求减少语法,或者至少不包含任何不可达到或无用的结果时,上述内容才足以产生移位-减少冲突

但是,上述条件不是必需的,因为不要求移位和减少适用于同一非端子,甚至“相关”非端子。考虑下面的简单语法:

prog → stmt
prog → prog stmt
stmt → expr
stmt → func
expr → ID
expr → '(' expr ')'
func → ID '(' ')' stmt
该语法(实际上并不含糊)在包含
ID的状态中有一个shift-reduce冲突。(
因为
ID
可以减少为
expr
,然后
stmt
,或者
可以作为
函数的一部分进行移位。)→ ID'('')stmt


尽管这是一个侧重点,但值得注意的是,FOLLOW set仅用于构造SLR(k)语法。规范LR(k)构造——甚至是LALR(k)构造——将成功地为语法生成解析器,在语法中使用FOLLOW set而不是完全的前向计算将表明(不存在)shift-reduce冲突。经典示例取自《龙之书》(我的副本中的示例4.39),使用稍微有意义的非终端名称编辑:

stmt → lvalue '=' rvalue
stmt → rvalue
lvalue → '*' rvalue
lvalue → ID
rvalue → lvalue

这里,FOLLOW(rvalue)是{=,$},因此状态为{
stmt→ 左值·“=”右值
右值→ 左值·
}是的,这就是它的定义。你是在问这是否一定是一个S/R冲突,还是每个S/R冲突都有这种形式?@rici很好,我的意思是,如果每个S/R冲突都有这种形式,这是一个很好的答案。谢谢如果我的陈述/定义正确,可以修改它以指定语法不包含多余的/无法达到的缩减,并且应该进一步将这些项修改为A->α。和B->α。β。例如,不要求LHS在每种情况下都相同?在您发现此注释后,是否将upvote/accept稍后。@N.McA.:注释中的条件不是ne当然是移位-减少冲突。我的第二个例子是这样的,但是在使用规范LR(1)解析器(也不是LALR(1)解析器)的语法中没有移位-减少冲突。啊,我正要评论一下,问是否会出现这种情况。我认为SLR(1)正确吗解析器,我们使用下面的集合来确定reduce操作,这将是一个冲突?这意味着SLR和规范LR接受的语法集合是不同的。另外,我没有提到的另一个S/R冲突的情况是a->α和a->α。β,其中β派生空字符串。是的,SLR(1)是LR(1)的严格子集。