【发布时间】:2010-01-15 00:35:44
【问题描述】:
我一直在研究类似 C 的语法,以供个人娱乐。但是,我遇到了 shift/reduce 冲突,我很确定它们可以得到解决。
现在我的expressions 看起来像这样,以简化的形式,没有操作:
%left '+' '-'
%%
expr
: NUMBER
| IDENTIFIER
| expr '+' expr
| expr '-' expr
/* other operators like '*', '/', etc. */
| expr '(' expr ')' /* function call */
%%
但是,这会导致移位/归约冲突:解析器不确定如何处理括号。从-v 告诉我的内容来看,尚不清楚像expr '+' expr '(' 这样的表达式是否应该将expr '+' expr 减少为expr 或移动括号。
显然,我希望括号移动。 foo % bar(4) 不应该最终成为 (foo % bar)(4)。但是,我没有成功使用 %prec 指令来表示这个意思。在规则之后添加%left FUNCALL 和%prec FUNCALL 不会产生任何变化。
我知道 Bison 的 LALR 解析器在遇到 shift/reduce 时的默认路径是 shift,我可以使用 %expect 来 fix 解决这个问题。但是,每个表达式都会产生一个冲突,我是否需要更改该列表,我还需要更改 %expect 声明,这对我来说似乎是一个相当丑陋的解决方案。此外,我相信你们中的一个聪明的孩子有解决这个问题的办法。
我的目标是有一个类似于上面的规则,Bison 会知道,每当它遇到函数调用规则中的'(' 时,它就会移动括号,而不会发生移位/减少冲突。作为记录,我对%prec 指令的使用如下,所以如果我做错了,你可以纠正我。它确实存在移位/减少冲突。
%left '+' '-'
%left FUNCALL
%%
expr
: NUMBER
| IDENTIFIER
| expr '+' expr
| expr '-' expr
/* other operators like '*', '/', etc. */
| expr '(' expr ')' %prec FUNCALL /* function call */
%%
【问题讨论】:
标签: bison