【问题标题】:Why is this Yacc/bison rule useless?为什么这个 Yacc/bison 规则没用?
【发布时间】:2017-07-01 11:59:51
【问题描述】:

%nonassoc ELSE
%nonassoc THEN

我明白了

$ bison -dv tiger.yy
Tiger.yy:74.5-28:警告:由于冲突,规则在解析器中无用 [-Wother]
: IF exp THEN exp ELSE exp
^^^^^^^^^^^^^^^^^^^^^^^^

但有

%nonassoc THEN
%nonassoc ELSE

规则有效。

这里发生了什么?为什么会这样?

【问题讨论】:

  • 这是两个解析器之间的唯一区别吗?

标签: parsing bison yacc


【解决方案1】:

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

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

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

因为如果ELSE 子句是强制性的,就不会有冲突。上面的规则有一个移位/减少冲突,因为当ELSEIF exp THEN IF exp THEN exp ELSE... 解析中的前瞻标记时,可以shift ELSEreduce 内部IF exp THEN expexp

为了正确解析表达式,有必要支持 shift 操作,以便ELSE 将与最里面的可用IF 相关联。如果没有优先声明,那将是默认的解决方案,因为 yacc/bison 更喜欢 shift 而不是 reduce。但是,如果 bison 使用默认分辨率,它也会产生有关分辨率的警告。为避免警告,通常通过使ELSE 优先于THEN 来显式强制默认分辨率。就是这样

%nonassoc THEN
%nonassoc ELSE

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

%nonassoc ELSE
%nonassoc THEN

那么您将THEN 优先于ELSE,这意味着您指示解析器生成器更喜欢减少最后一个非终结符为THEN 的产生式而不是移位ELSE。 Bison/yacc 将服从该请求,但如果它这样做了,它将永远无法移动 ELSE,从而使包含 ELSE 的规则变得无用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    相关资源
    最近更新 更多