尽管有优先规则,仍然可以改变/减少冲突

时间:2015-05-20 01:04:54

标签: parsing bison shift-reduce-conflict

我编写解析器的语言有三个与此相关的构造:ord运算符,由TOK_ORD表示,将字符表达式转换为整数表达式,{{1 } [],分别用于索引和字段访问,就像在C中一样。

这是我的优先规则摘录:

.

我的语法有一个非终结%right TOK_ORD %left PREC_INDEX PREC_MEMBER ,代表表达式。以下是语法中的一些相关摘录(expr是我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 */ }
         ;

国家92和93,供参考:

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)

我不明白为什么会出现转变/减少冲突。我的语法清楚地定义索引和字段访问的优先级高于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 ,但这似乎不够。

如果您想知道,是的,这是作业,但作业已经上交并评分。我会回过头来尝试解决转移/减少冲突,这样我就能更好地了解正在发生的事情。

1 个答案:

答案 0 :(得分:2)

优先解决转移/减少冲突的方法是将生产(或减少,如果您愿意)的优先级与令牌的优先级进行比较(前瞻令牌) )。

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

正如野牛手册所说:

  

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

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

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

但这些作品从不参与转变/减少冲突。当达到任一variable规则的末尾时,不可能移位。可以减少这些作品的项目集没有移位动作。

在包含转移/减少冲突的状态中,冲突在潜在的减少之间:

 expr: TOK_ORD expr

以及涉及前瞻代币.[的可能转变。这些冲突将通过将TOK_ORD缩减的优先级分别与前瞻标记.[的优先级进行比较来解决。如果这些令牌没有声明优先级,则无法使用优先级机制解决shift / reduce冲突。

在这种情况下,我希望在其他状态下存在大量的移位/减少冲突,其中选项是减少二元运算符(例如expr: expr '+' expr)或移位{ {1}} / .扩展最右边的expr。因此,如果没有这样的转移/减少冲突,解释会更复杂,我需要看到更多的语法来理解它。