这个YACC代码如何引起移位/减少冲突?(非常简单)

时间:2019-05-07 11:19:09

标签: yacc

我真的试图理解为什么这会引起冲突,但是我认为我缺少了一些东西。

%token D
%start a

%%

a
    : b
    | a '+' b
    ;

b
    : c
    | c '+' '+'
    ;

c
    : D
    ;

我发现同样的'+'字符也造成了问题,但是我在这段代码中找不到任何歧义...

我真的很感激

1 个答案:

答案 0 :(得分:1)

让我们为您的替代品添加标签,如下所示:

a
    : b          // a1
    | a '+' b    // a2
    ;

b
    : c          // b1
    | c '+' '+'  // b2
    ;

现在,如果解析器刚刚解析了c,下一个令牌是'+',则有两种可能性:+可能是c '+' '+'的一部分,应该选择哪种情况b2,或者+可以是a '+' b的一部分,在这种情况下应该选择b1,然后选择a2。但是,如果没有看到第二个+,解析器就无法知道是哪种情况,而作为LALR(1)解析器生成器的YACC只能向前看一个令牌,而不是两个。

这就是为什么您会遇到冲突。正如已经指出的那样,解决方案是使++成为单个令牌。这还有一个好处,就是++内不再允许使用空格,这与现有语言的语法更加匹配。