为什么野牛会与明确的语法发生移位/减少冲突?

时间:2019-01-11 13:48:29

标签: parsing bison context-free-grammar

我正在使用野牛,但遇到了转移/减少冲突。野牛已经确定了一种转移/减少冲突。我找不到这种语言的歧义:

start
    : IDENT trailer EQUAL atom trailer SEMICOLON
    | atom trailer SEMICOLON
    ;

atom
    : LPAR atom trailer RPAR
    | IDENT
    ;

trailer
    : %empty
    | LPAR RPAR
    ;

底部附近的python grammar documentation中也描述了此问题。我可以使用本文档介绍的解决方案消除歧义(将第2行更改为atom trialer EQUAL atom trailer SEMICOLON

现在它已解决,我可以继续前进,但是我仍然对该问题感到好奇。请向我描述上面语法的问题,并用带有两个唯一分析树的语言给出一个例句。

编辑1
经过进一步调查,以下内容存在转移/减少冲突:

start
    : IDENT LPAR RPAR EQUAL atom LPAR RPAR SEMICOLON
    | atom LPAR RPAR SEMICOLON
    ;

atom
    : IDENT
    ;

但这没有移位/减少冲突:

start
    : IDENT LPAR RPAR EQUAL IDENT LPAR RPAR SEMICOLON
    | IDENT LPAR RPAR SEMICOLON
    ;

这对我来说似乎很可疑,因为在第一个语法中,原子被迫产生IDENT,因此这两个语法基本上是相同的。我仍然需要一些解释。

1 个答案:

答案 0 :(得分:0)

Shift / reduce冲突并不一定意味着您的语法是模棱两可的。所有模棱两可的语法都会产生平移/归约或归约/归约冲突,但反之并不一定成立。

以您的情况为例,假设解析器已启动并且刚刚读取IDENT令牌,然后读取LPAR。它有两种选择。首先,可能是因为您正在制作开始非终端的第一个(较长)分支。在这种情况下,您应该在以后调整LPAR并减少整个长表达式的计划。其次,可能是您正在生成start非终结符的第二个(较短的)分支,这意味着您应该将IDENT还原为atom。仅仅知道下一个终端是LPAR并不能帮助您区分这些情况,因此转移/减少冲突。

另一方面,在没有更多上下文可用之前,语法的第二个版本不需要决定如何处理前端的IDENT,因此没有冲突。