转换/减少yacc语法中的冲突

时间:2018-04-18 19:58:21

标签: parsing grammar yacc lalr

我写了一个语法,规则如下:

A : B '?'  
  | B
  | A '+' A
  ;

B : "a"
  | "c" A "t" A
  ;

这给了我一个转移/减少冲突

A : B . '?'  (96)
A : B .  (98)

我尝试过多种方法来改变语法,但当我尝试改变时,我似乎会产生更多的冲突。我该如何消除这种冲突?

提前感谢您,我们将不胜感激。

1 个答案:

答案 0 :(得分:2)

LALR(1)解析器使用单字符前瞻解决冲突。当前瞻不能消除不同动作之间的歧义时,就会向用户显示冲突。

在以下状态中,“?”先行意味着解析器可以转移。

A : B . '?'
A : B .

但如果减少A怎么办?它可能会降低到以下状态:

B: "c" A "t" A .

通过减少B,可以直接进入:

A : B . '?'
A : B .

因此,“?”也是减少的有效前瞻。

那你怎么解决这个问题呢?

您有两种选择:

1)尝试用左递归而不是右递归重写语法。 可能帮助,但这不能保证。

2)告诉YACC在发生此冲突时选择哪一个(例如,使用%left或%right)。

或者,或许,使用更智能的解析器。例如elkhound或antlr。