为什么bison在不明确的语法中存在移位/减少冲突



我正在使用bison,并且遇到了shift/reduce冲突。Bison已经确定了一个转变/减少冲突。我找不到这种语言的歧义:

start
: IDENT trailer EQUAL atom trailer SEMICOLON
| atom trailer SEMICOLON
;
atom
: LPAR atom trailer RPAR
| IDENT
;
trailer
: %empty
| LPAR RPAR
;

底部附近的python语法文档中也描述了这个问题。我可以使用本文档描述的解决方案来消除歧义(将第2行更改为atom trialer EQUAL atom trailer SEMICOLON.

既然它已经解决了,我可以继续前进了,但我仍然对这个问题感到好奇。请向我描述上面语法的问题,并用有两个独特解析树的语言给出一个例句。

EDIT 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,所以这两个语法本质上是相同的。我仍然需要一些解释。

Shift/reduce冲突并不一定意味着语法不明确。所有模棱两可的语法都会产生shift/reduce或reduce/reduce冲突,但反过来不一定成立。

在您的案例中,假设解析器已经启动,并且刚刚读取了一个IDENT令牌,后跟LPAR。它有两种选择。首先,可能是您正在生成起始非终结符的第一个(更长的)分支。在这种情况下,您应该用稍后减少整个长表达式的计划来转移LPAR。其次,可能是您正在生成起始非终结符的第二个(较短)分支,这意味着您应该将IDENT减少回atom。仅仅知道下一个终端是LPAR并不能帮助您区分这些情况,因此会产生偏移/减少冲突。

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

最新更新