grammar - 为什么这个简单的语法会有移位/归约冲突?

标签 grammar bison yacc shift-reduce-conflict

%token <token> PLUS MINUS INT
%left PLUS MINUS

这个有效:

exp : exp PLUS exp;
exp : exp MINUS exp;
exp : INT;

这有 2 个转变/减少冲突:

exp : exp binaryop exp;
exp : INT;
binaryop: PLUS | MINUS ;

为什么?

最佳答案

这是因为第二个实际上是不明确的。第一个语法也是如此,但您通过添加 %left 解决了歧义。

这个%left在第二个语法中不起作用,因为结合性和优先级不是从一个规则继承到另一个规则的。 IE。 binaryop 非终结符不会继承任何这样的东西,即使它产生 PLUSMINUS 。关联性和优先级被本地化为规则,并围绕终结符号。

我们无法执行%left binaryop,但我们可以稍微重构一下语法:

exp : exp binaryop term
exp : term;
term : INT;
binaryop: PLUS | MINUS ;

现在没有冲突,因为它是隐式左关联的。 IE。越来越长的表达式的产生只能发生在binaryop的左侧,因为右侧是一个term,它只产生一个INT。

关于grammar - 为什么这个简单的语法会有移位/归约冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9716917/

相关文章:

c - 链表不通过递归调用传播

regex - Perl6 中的语法有点过于贪婪

java - 执行由 Jasmin 生成的文件 .classes 时出错

ANTLR4 相互左递归

c - 在函数 ‘yylex’ : 'Variable’ undeclared 中

c - 如何在 yacc 中使用 yylval 和 union

objective-c - Parsekit 还是自己解析?

c - 关于 Flex、Bison 和 Segmentation Fault

Bison 错误处理

从 bison 或 yacc 过滤 y.output?