为什么这个Yacc/野牛规则没有用?



with

%nonassoc ELSE
%nonassoc THEN

我得到

$ 野牛 -dv tiger.yy tiger.yy
:74.5-28: 警告:由于冲突,规则在解析器中无用 [-Wother]
: 如果 exp 那么 exp 否则 exp
^^^^^^^^^^^^^^^^^^^^^^^^

但与

%nonassoc THEN
%nonassoc ELSE

该规则有效。

这是怎么回事?为什么会这样?

正如警告所说,该规则是无用的,因为如果THEN优先于 ELSE ,那么解决移位/减少冲突会使规则无法应用。

我认为语法实际上包括以下内容:

exp: IF exp THEN exp ELSE exp
   | IF exp THEN exp

因为如果ELSE条款是强制性的,就不会有冲突。上面的规则存在移位/减少冲突,因为当ELSE是解析IF exp THEN IF exp THEN exp ELSE...的前瞻令牌时,可以移位ELSE或将内部IF exp THEN exp减少exp

为了正确解析表达式,必须支持移位操作,以便ELSE与最内层的可用IF相关联。如果没有优先声明,这将是默认解决方案,因为 yacc/bison 更喜欢移位而不是减少。但是,如果 bison 使用默认分辨率,它还会产生有关分辨率的警告。为避免出现警告,通常通过赋予ELSE优先于 THEN 来显式强制默认解析。这就是

%nonassoc THEN
%nonassoc ELSE

确实如此。如果按其他顺序编写优先级声明,

%nonassoc ELSE
%nonassoc THEN

然后你给THEN优先于 ELSE ,这意味着你指示解析器生成器更喜欢减少最后一个非终端THEN的生产,而不是移位ELSE。Bison/yacc 会服从该请求,但如果它这样做,它就永远无法改变ELSE,使包含ELSE的规则变得无用。

最新更新