Mus*_*faM 5 grammar yacc bison shift-reduce-conflict
%token <token> PLUS MINUS INT
%left PLUS MINUS
Run Code Online (Sandbox Code Playgroud)
这有效:
exp : exp PLUS exp;
exp : exp MINUS exp;
exp : INT;
Run Code Online (Sandbox Code Playgroud)
这有 2 个转移/减少冲突:
exp : exp binaryop exp;
exp : INT;
binaryop: PLUS | MINUS ;
Run Code Online (Sandbox Code Playgroud)
为什么?
这是因为第二个实际上是模棱两可的。第一个语法也是如此,但是您通过添加%left.
这%left在第二个语法中不起作用,因为关联性和优先级不是从规则到规则继承的。即binaryop非终结符不会继承任何这样的东西,即使它产生PLUS和MINUS。关联性和优先级被本地化为规则,并围绕终端符号。
我们不能做%left binaryop,但我们可以稍微重构一下语法:
exp : exp binaryop term
exp : term;
term : INT;
binaryop: PLUS | MINUS ;
Run Code Online (Sandbox Code Playgroud)
现在没有冲突,因为它是隐式左关联的。即越来越长的表达式的产生只能发生在 的左侧binaryop,因为右侧是term只产生 INT 的 a。