我编写解析器的语言有三个与此相关的构造: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
,但这似乎不够。
如果您想知道,是的,这是作业,但作业已经上交并评分。我会回过头来尝试解决转移/减少冲突,这样我就能更好地了解正在发生的事情。
答案 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。因此,如果没有这样的转移/减少冲突,解释会更复杂,我需要看到更多的语法来理解它。