如何消除 bison 中变量声明的 shift/reduce 冲突?

How to remove shift/reduce conflicts on variable declarations in bison?

我正在处理我的编译器设计项目,我必须从这个语法中删除所有歧义。起初,以下代码(.yac)有 27 个 shift/reduce 冲突和 3 个 reduce/reduce 冲突。我设法使它们只有 15 个 shift/reduce 冲突,现在我可以看到只有 BOOLEAN_KW[ 等变量声明存在冲突=39=],等等。我真的需要解决这个问题,我知道一些 PrecedencePriority 需要在这里使用,我测试了很多可能性,但没有成功。如果有人可以帮助我处理显示 shift/reduce 上的冲突的 bison 输出文件,我将不胜感激。 顺便说一句,我想这些 reduce/conflicts 是 bison 出于确认目的而给我的一些警告,但不幸的是,即使知道这些也不会让我 运行 整个 lexerparser 与我的主程序,我在尝试 运行 整个代码时遇到此错误:

    Error : syntax error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
    at YYParser$YYStack.stateAt(YYParser.java:315)
    at YYParser.parse(YYParser.java:1568)
    at global.main(global.java:39)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

最后,这是我使用 bison 启用 -o output 选项的输出,其中显示了冲突代码的早期部分: My code is uploaded here.

关键警告是:

Rules useless in parser due to conflicts

5 declarations: /* empty */

指的是这些作品:

declarations_list: declarations_list declarations
                 | /* empty */

declarations: type_specifiers declarator_list SEMICOLON_KW
            | /* empty */

这表示 declarations_list 由零个或多个 declarations 组成。但是,declaration 可能为空。所以这显然是模棱两可的:在给定的 declarations_list 中出现了多少个空 declarations 非终结符实例?它可以是任何数字,因为它们都是空的。

所有 shift/reduce 冲突都源于这种本质上的歧义。当解析器需要一个declarations_list时,它需要决定在列表的开头解析多少个空的declarations

默认情况下,它选择不插入任何declarations,这使得产生式:

declarations: /* empty */

没用(正如警告所说)。由于产生式实际上是无用的,您不妨将其删除,从而避免歧义(以及 shift/reduce 冲突)。

正如 Austin Hastings 在评论中指出的那样,这对解析器的行为没有影响。解析器已经消除了无用的产生式,并且不会改变对任何输入的响应。因此,如果某些输入在您尝试解析它时产生了意外的语法错误,这反映了您的语法存在一些不同的问题。