【问题标题】:Shift/reduce conflict despite precedence rules尽管有优先规则,但转移/减少冲突
【发布时间】:2015-05-20 01:04:53
【问题描述】:

我正在为其编写解析器的语言具有三个相关的结构:ord 运算符,由 TOK_ORD 表示,它将字符表达式转换为整数表达式,以及 [ ] 和 @987654325 @,分别用于索引和字段访问,就像在 C 中一样。

这是我的优先规则的摘录:

%right TOK_ORD
%left  PREC_INDEX PREC_MEMBER

我的语法有一个非终结符expr,它代表表达式。以下是语法中的一些相关 sn-ps(TOK_IDENT 是我的 .l 文件中定义的标识符的正则表达式):

expr     : TOK_ORD expr                         { /* semantic actions */ }
         | variable                             { /* semantic actions */ }
         ;
variable : expr '[' expr ']' %prec PREC_INDEX   { /* semantic actions */ }
         | expr '.' TOK_IDENT %prec PREC_MEMBER { /* semantic actions */ }
         ;

以下是野牛输出文件中有关移位/减少冲突的信息:

state 61

42 expr: expr . '=' expr
43     | expr . TOK_EQ expr
44     | expr . TOK_NE expr
45     | expr . TOK_LT expr
46     | expr . TOK_LE expr
47     | expr . TOK_GT expr
48     | expr . TOK_GE expr
49     | expr . '+' expr
50     | expr . '-' expr
51     | expr . '*' expr
52     | expr . '/' expr
53     | expr . '%' expr
57     | TOK_ORD expr .
72 variable: expr . '[' expr ']'
73         | expr . '.' TOK_IDENT

'['  shift, and go to state 92
'.'  shift, and go to state 93

'['       [reduce using rule 57 (expr)]
'.'       [reduce using rule 57 (expr)]
$default  reduce using rule 57 (expr)

状态 92 和 93,供参考:

state 92

72 variable: expr '[' . expr ']'

TOK_FALSE      shift, and go to state 14
TOK_TRUE       shift, and go to state 15
TOK_NULL       shift, and go to state 16
TOK_NEW        shift, and go to state 17
TOK_IDENT      shift, and go to state 53
TOK_INTCON     shift, and go to state 19
TOK_CHARCON    shift, and go to state 20
TOK_STRINGCON  shift, and go to state 21
TOK_ORD        shift, and go to state 22
TOK_CHR        shift, and go to state 23
'+'            shift, and go to state 24
'-'            shift, and go to state 25
'!'            shift, and go to state 26
'('            shift, and go to state 29

expr       go to state 125
allocator  go to state 44
call       go to state 45
callargs   go to state 46
variable   go to state 47
constant   go to state 48


state 93

73 variable: expr '.' . TOK_IDENT

我不明白为什么会有移位/减少冲突。我的语法清楚地定义了索引和字段访问的优先级高于ord,但这似乎还不够。

如果您想知道,是的,这是家庭作业,但作业已经上交并评分。我正在回过头来尝试修复班次/减少冲突,以便更好地了解正在发生的事情。

【问题讨论】:

    标签: parsing bison shift-reduce-conflict


    【解决方案1】:

    通过比较产生式(或减少,如果您愿意)的优先级与标记(前瞻标记)的优先级来解决移位/减少冲突的优先级)。

    这个简单的事实有点模糊,因为野牛根据产生式中最后一个标记的优先级设置产生式的优先级(默认情况下),所以看起来优先级值只分配给标记,优先级比较是令牌优先级之间。但这并不准确:优先级比较总是在产生式(可能会减少)和令牌(可能会转移)之间进行。

    正如野牛手册所说:

    ...冲突的解决通过比较 正在考虑的规则优先于前瞻规则 令牌。如果令牌的优先级更高,则选择转移。 如果规则的优先级较高,则选择减少。

    现在,您使用显式声明定义两个 variable 产生式的优先级:

    variable : expr '[' expr ']' %prec PREC_INDEX   { /* semantic actions */ }
             | expr '.' TOK_IDENT %prec PREC_MEMBER { /* semantic actions */ }
    

    但这些产品从不参与移位/减少冲突。当到达variable 规则中的任何一个的末尾时,就没有转移的可能性。这些产生式可以归约的项集没有移位动作。

    在包含移位/归约冲突的状态下,冲突是潜在归约之间的冲突:

     expr: TOK_ORD expr
    

    以及涉及前瞻令牌.[ 的可能变化。这些冲突将通过分别比较TOK_ORD 减少的优先级与前瞻标记.[ 的优先级来解决。如果这些标记没有声明优先级,则无法使用优先级机制解决移位/归约冲突。

    不过,在这种情况下,我预计在其他州会有大量的移位/减少冲突,其中选项是减少二元运算符(例如 expr: expr '+' expr)或移位 . /[ 扩展最右边的表达式。所以如果没有这样的移位/减少冲突,解释会更复杂,我需要看更多的语法才能理解它。

    【讨论】:

    • 我的语法中有大约 30 个移位/减少冲突,所以是的,其他地方也有类似的问题。我只是问了这个问题,希望理解这个问题可以帮助纠正其余的问题。
    • 那么为.[定义优先级的解决方案是什么?
    • @justin:是的,准确地说。代替不使用的 PREC_INDEX 和 PREC_MEMBER。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-09
    相关资源
    最近更新 更多