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
的规则变得无用。