如何在明确的语法中解决转移 - 减少冲突

时间:2009-06-06 02:55:34

标签: parsing grammar shift-reduce-conflict lalr

我正在尝试使用LALR(1)解析器生成器解析一个简单的语法(Bison,但问题不是特定于该工具),而且我正在遇到一个shift-reduce冲突。我发现的关于修复这些内容的文档和其他来源倾向于说出以下一个或多个:

  • 如果语法含糊不清(例如if-then-else ambiguity),请更改语言以修复歧义。
  • 如果是运营商优先级问题,请明确指定优先级。
  • 接受默认分辨率并告诉发生器不要抱怨它。

然而,这些似乎都不适用于我的情况:语法是明确无误的(尽管当然它只有一个前瞻性字符含糊不清),它只有一个操作符,默认分辨率导致解析正确形成的输入上的错误。是否有任何技术可以重新定义语法,以消除不属于上述存储桶的移位减少冲突?

具体来说,这是有问题的语法:

%token LETTER

%%
%start input;
input:          /* empty */ | input input_elt;
input_elt:      rule | statement;
statement:      successor ';';
rule:           LETTER "->" successor ';';
successor:      /* empty */ | successor LETTER;
%%

目的是解析“[A-Za-z] +”或“[A-Za-z] - > [A-Za-z] +”形式的分号分隔行。

2 个答案:

答案 0 :(得分:2)

使用Solaris版yacc,我得到:

1: shift/reduce conflict (shift 5, red'n 7) on LETTER
state 1
    $accept :  input_$end
    input :  input_input_elt
    successor : _    (7)

    $end  accept
    LETTER  shift 5
    .  reduce 7

    input_elt  goto 2
    rule  goto 3
    statement  goto 4
    successor  goto 6

因此,麻烦的是,通常是空的规则 - 特别是空的继任者。你是否想要允许分号作为有效输入还不是很清楚 - 目前,它是。如果您将后续规则修改为:

successor: LETTER | successor LETTER;

消除了转移/减少冲突。

答案 1 :(得分:0)

感谢您减少语法并发布。将后续规则更改为 -

successor:      /* empty */ | LETTER successor;

......为我工作。 ITYM 语言看起来很明确。