0

我正在尝试为微小的 Visual Basic 语言编写解析器。而且我无法解决下一个班次/减少冲突。我有这些规则:

simple_type_name:
    qualified_type_name
    | primitive_type_name;

qualified_type_name:
    ID
    | qualified_type_name PERIOD ID;

primitive_type_name: BOOLEAN|CHAR|STRING|BYTE|SBYTE|USHORT|SHORT|UINTEGER|INTEGER|ULONG|LONG|SINGLE|DOUBLE;

野牛对我说:

simple_type_name  ->  qualified_type_name .   (rule 20)
qualified_type_name  ->  qualified_type_name . PERIOD ID   (rule 23)

PERIOD  shift, and go to state 41

PERIOD  [reduce using rule 20 (simple_type_name)]
$default reduce using rule 20 (simple_type_name)

那么,在这场冲突中,正确的解决方案是什么?

4

1 回答 1

2

您必须在语法中有一些其他规则,其中simple_type_name后跟 a PERIOD。就像是:

expression: simple_type_name PERIOD expression

也许?

问题是它需要更多的前瞻性来确定之后PERIOD是一个简单ID的,使它成为一个合格的类型名称,还是其他东西,使它成为一个简单的类型名称。

一种可能的解决方案(无法说出,因为您没有展示足够的语法)是取消simple_type_name其后跟句号的位置 - 复制规则,simple_type_name同时替换为qualified_type_nameand primitive_type_name。对于上面的expression示例,这将是:

expression: qualified_type_name PERIOD expression
          | primitive_type_name PERIOD expression

根据您的语法的其余部分,可能有必要或需要完全分解simple_type_name,用重复的规则替换所有提及它并删除simple_type_name规则本身

编辑

好的,你已经链接了更多的语法,所以我们可以看到有问题的使用simple_type_name是在尾随上下文中(在规则的 rhs 的末尾),所以简单的分解是不够的。您可以通过重复分解(simple_type_name如上所述分解,然后分解simple_expression和/或type_name同样)来修复它。目标是将分解推向一个具有

    ... some-nonterminal PERIOD ...

在右侧,并将其替换为规则

    ... other-nonterminal PERIOD ... | ... qualified_type_name PERIOD ...

whereother-nonterminalsome-nonterminal与导致单个qualified_type_name删除的规则的重复。

不幸的是,这很容易导致语法规模呈指数级增长,因此可能不切实际。在这种情况下,唯一的选择可能是使用更强大的解析方法,例如 bison 的%glr-parser选项或使用btyacc进行回溯。

于 2013-12-03T17:27:32.373 回答