解决 reduce/reduce 冲突

Solving a reduce/reduce conflict

如果我有一个语法,其中某个表达式可以匹配两个产生式,我显然会与 yacc 发生 reduce/reduce 冲突。具体来说,假设我有两个作品(FirstProduction 和 SecondProduction),它们都可以是 TOKEN END.

那么 yacc 将无法知道要将什么 TOKEN END 减少到(FirstProduction 或 SecondProduction)。但是,我想让 yacc 在这种情况下优先考虑 FirstProduction。我怎样才能做到这一点?

请注意,FirstProductionSecondProduction 可能是很多东西,而 Body 是语法中唯一发生冲突的地方。

此外,我知道在这些情况下,yacc 将选择语法中声明的第一个产生式。但是,我想避免出现任何 reduce/reduce 警告。

Bison 无法明确地将一个作品标记为优于另一个作品;唯一的此类机制是优先关系,它可以解决 shift/reduce 冲突。正如您所说,文件顺序提供了隐含的优先级。您可以使用 %expect 声明来抑制警告;不幸的是,这只能让你告诉 bison 预期有多少冲突,而不是哪些冲突。

您可以重构语法以不允许第二个列表以可能属于第一个列表的内容开头:

Body: FirstProductionList SecondProductionList
    | FirstProductionList
    ;

FirstProductionList: FirstProductionList FirstProduction
                   | /* empty */
                   ;

SecondProductionList: SecondProductionList SecondProduction
                    | NonFirstProduction
                    ;

NonFirstProductionSecondProduction 独有的任何产生式,标志着从减少 FirstProdutions 到 SecondProductions

的转变