AFAIK,Happy是LALR(1)解析器。好吧,我的语法主要是LALR(1)。不幸的是,当大多数与Happy相关的代码已经编写时,我(很傻)发现一个reduce-reduce冲突为时已晚。
罪魁祸首的规则如下:
Symbol : Nonterm1 Nonterm2 Nonterm3
| Nonterm3
问题是,Nonterm1
和Nonterm3
(虽然不相同)仍然足够相似,足以引起减少-减少冲突。 也许我可以用消除这些冲突的方式来重写它们,但是由于它们都非常复杂,所以我认为我不能胜任这项工作(这需要大量重复,我想)。
另一方面,Nonterm2
很简单-它总是减少为一个字符(即:
),该字符既不会出现在Nonterm1
也不会出现在Nonterm3
中。
因此,消除reduce-reduce冲突所需的唯一修改是:
Symbol : Nonterm1 Nonterm2 Nonterm3
| Nonterm2 Nonterm3
它有效,但是...我不喜欢它。它要求在笨拙的地方用:
使输入文件混乱。
我确实相信语法即使是最初编写的方式也没有歧义。减少-减少冲突可以通过至少两种方式手动消除:
Nonterm1
中不能出现的任何字符排在最前面。如果是冒号,请返回并减少到Nonterm1 Nonterm2 Nonterm3
。否则,请减少为Nonterm3
。在这种情况下,Happy中是否有任何功能会有所帮助?他们的文档中提到的单语法例分析器对您有帮助吗?还是该使用GLR了?但是我在他们的文档中读到,GLR是用于模棱两可的语法的,它允许返回许多可能的语法分析。但我相信我的语法是明确的。