Bison中的冲突类型

时间:2016-01-21 08:35:05

标签: bison yacc

%token<val>num 
%left '+' '-'

shift/reduce冲突的示例:

Expr:num {$$=$1};
     |Expr '+' Expr;{};
     |Expr '-' Expr;{};

我想承认reduce/reduce冲突。 当两个或多个规则适用于相同的输入序列(令牌)

时,会发生这种情况

例如:

Prod: proda|prodb
     proda :'x'
     prodb : 'x'

任何人都可以轻松地提出一些如何识别reduce/reduce冲突的想法吗?

2 个答案:

答案 0 :(得分:1)

嗯,你刚刚描述了冲突之间的区别。有什么问题?

shift/reduce冲突意味着野牛不知道他是否应该shift(再读一个终端并将其放在堆栈的顶部)或reduce(转换几个终端/堆栈上的非终端进入新的非终端)。 shift/reduce表示I don't know - should I apply a rule now or wait a bit, read some text and apply another rule there?此类冲突通常通过shift操作解决。

reduce/reduce冲突意味着有两种或更多种方法来减少堆栈顶部的终端/非终端。 reduce/reduce表示I don't know - should I apply this rule or that rule now?。这种冲突比shift/reduce严重得多 - 语法含糊不清,有些事情确实是错误的。

通常最好不要识别减少/减少,但避免它。从一开始就清楚地知道自己想做什么。不时修改你的语法。您是否有机会重新制定另一条规则?

在调试现有冲突时,bison -v选项会创建一个*.output文件,其中包含对所有冲突的详细描述。这是第一次阅读起来非常困难,需要了解LR1 parsing如何进行,但阅读它的优点也很棒。

答案 1 :(得分:0)

最简单的方法是创建y.output文件。

使用命令../Images/yes.gif。这将创建yacc如何工作的输出。找到yacc说你的冲突所在的州,然后了解哪个点符号非常重要。在文件意味着。

如果你的输出文件是这样的:

  

4 | Expr。 '+'Expr; {};

表达后对你说:“我读过Expr,输入时我有'+'。

当你遇到这样的情况时,会出现Reduce-Reduce冲突:

yacc -v parser_name.y

在这种情况下,你有Expr。在规则的最后,Yacc不知道要做哪个减少,那就是Reduce-Reduce冲突。