我正在使用野牛,但遇到了转移/减少冲突。野牛已经确定了一种转移/减少冲突。我找不到这种语言的歧义:
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,因此这两个语法基本上是相同的。我仍然需要一些解释。
答案 0 :(得分:0)
Shift / reduce冲突并不一定意味着您的语法是模棱两可的。所有模棱两可的语法都会产生平移/归约或归约/归约冲突,但反之并不一定成立。
以您的情况为例,假设解析器已启动并且刚刚读取IDENT令牌,然后读取LPAR。它有两种选择。首先,可能是因为您正在制作开始非终端的第一个(较长)分支。在这种情况下,您应该在以后调整LPAR并减少整个长表达式的计划。其次,可能是您正在生成start非终结符的第二个(较短的)分支,这意味着您应该将IDENT还原为atom。仅仅知道下一个终端是LPAR并不能帮助您区分这些情况,因此转移/减少冲突。
另一方面,在没有更多上下文可用之前,语法的第二个版本不需要决定如何处理前端的IDENT,因此没有冲突。