为什么这个 Yacc/bison 规则没用?
Why is this Yacc/bison rule useless?
和
%nonassoc ELSE
%nonassoc THEN
我明白了
$ bison -dv tiger.yy
tiger.yy:74.5-28: warning: rule useless in parser due to conflicts [-Wother]
: IF exp THEN exp ELSE exp
^^^^^^^^^^^^^^^^^^^^^^^^
但
%nonassoc THEN
%nonassoc ELSE
规则有效。
这是怎么回事?为什么会这样?
如警告所述,该规则无用,因为如果 THEN
优先于 ELSE
,则 shift/reduce 冲突的解决使得该规则无法应用.
我认为语法实际上包含如下内容:
exp: IF exp THEN exp ELSE exp
| IF exp THEN exp
因为如果 ELSE
子句是强制性的,就不会有冲突。上面的规则有一个 shift/reduce 冲突,因为当 ELSE
是 IF exp THEN IF exp THEN exp ELSE...
解析中的先行标记时,可以 shift ELSE
或 减少 内部 IF exp THEN exp
到 exp
.
为了正确解析表达式,有必要支持shift动作,这样ELSE
就会与最里面可用的[=22]相关联=].如果没有优先级声明,那将是默认的解决方案,因为 yacc/bison 更喜欢 shift 而不是 reduce。但是,如果 bison 使用默认分辨率,它还会生成有关该分辨率的警告。为了避免警告,通常通过给予 ELSE
优先于 THEN
来显式强制默认分辨率。就是这样
%nonassoc THEN
%nonassoc ELSE
确实如此。如果您以其他顺序编写优先级声明,
%nonassoc ELSE
%nonassoc THEN
那么你给 THEN
优先于 ELSE
,这意味着你指示解析器生成器更喜欢减少最后一个非终结符是 THEN
的产生式而不是移位 [=14] =]. Bison/yacc 将服从该请求,但如果它这样做,它永远不会改变 ELSE
,从而使包含 ELSE
的规则变得无用。
和
%nonassoc ELSE
%nonassoc THEN
我明白了
$ bison -dv tiger.yy
tiger.yy:74.5-28: warning: rule useless in parser due to conflicts [-Wother]
: IF exp THEN exp ELSE exp
^^^^^^^^^^^^^^^^^^^^^^^^
但
%nonassoc THEN
%nonassoc ELSE
规则有效。
这是怎么回事?为什么会这样?
如警告所述,该规则无用,因为如果 THEN
优先于 ELSE
,则 shift/reduce 冲突的解决使得该规则无法应用.
我认为语法实际上包含如下内容:
exp: IF exp THEN exp ELSE exp
| IF exp THEN exp
因为如果 ELSE
子句是强制性的,就不会有冲突。上面的规则有一个 shift/reduce 冲突,因为当 ELSE
是 IF exp THEN IF exp THEN exp ELSE...
解析中的先行标记时,可以 shift ELSE
或 减少 内部 IF exp THEN exp
到 exp
.
为了正确解析表达式,有必要支持shift动作,这样ELSE
就会与最里面可用的[=22]相关联=].如果没有优先级声明,那将是默认的解决方案,因为 yacc/bison 更喜欢 shift 而不是 reduce。但是,如果 bison 使用默认分辨率,它还会生成有关该分辨率的警告。为了避免警告,通常通过给予 ELSE
优先于 THEN
来显式强制默认分辨率。就是这样
%nonassoc THEN
%nonassoc ELSE
确实如此。如果您以其他顺序编写优先级声明,
%nonassoc ELSE
%nonassoc THEN
那么你给 THEN
优先于 ELSE
,这意味着你指示解析器生成器更喜欢减少最后一个非终结符是 THEN
的产生式而不是移位 [=14] =]. Bison/yacc 将服从该请求,但如果它这样做,它永远不会改变 ELSE
,从而使包含 ELSE
的规则变得无用。