在Bison下改变/减少与C语法的冲突

时间:2010-01-15 00:35:44

标签: bison

为了个人娱乐,我一直在研究类C语法。但是,我一直在遇到转换/减少冲突,我很确定它们可以解决。

现在我的expressions看起来像这样,以简化的形式被剥夺了行动:

%left '+' '-'

%%
expr
 : NUMBER
 | IDENTIFIER
 | expr '+' expr
 | expr '-' expr
 /* other operators like '*', '/', etc. */
 | expr '(' expr ')' /* function call */
%%

但是,这会导致转换/减少冲突:解析器不确定如何处理括号。根据{{​​1}}告诉我的情况,不清楚-v这样的表达式是否应将expr '+' expr '('缩减为expr '+' expr或移位括号。

显然,我希望改变括号。 expr不应该最终成为foo % bar(4)。但是,我没有成功使用(foo % bar)(4)指令。在规则之后添加%prec%left FUNCALL不会产生任何变化。

我知道当遇到shift / reduce时,默认路径Bison的LALR解析器将会移动,并且我可以使用%prec FUNCALL fix 解决问题。但是,为每个表达式生成一个冲突,并且我需要更改该列表,我还需要更改%expect声明,这看起来对我来说是一个相当丑陋的解决方案。此外,我相信你们其中一个聪明的孩子能解决这个问题。

我的目标是制定一个类似于上述规则的规则,Bison将知道每当它遇到函数调用规则中的%expect时,它就会移动括号,而不会发生可能的移位/减少冲突。为了记录,我使用'('指令如下,所以如果我做错了你可以纠正我。它确实有转移/减少冲突。

%prec

1 个答案:

答案 0 :(得分:4)

您需要将%left '('添加到您的优先规则中(或%nonassoc '('可能更好)。

优先级在yacc / bison中解决转移/减少冲突的方式是它将规则的优先级与令牌的优先级进行比较转移。在您的示例中,冲突在减少expr: expr '+' expr和转移'('之间,因此要解决它,您需要'('的优先级(并且您希望它高于规则,来自'+'

%prec指令仅设置规则的优先级,覆盖其默认优先级,该优先级来自其rhs上的第一个标记。它不会以任何方式影响规则中出现的令牌的优先级。