以下是[filename] .output的摘录 国家94
32 expr: expr . opt_at_type '.' TYPEID '(' opt_expr_list ')'
39 | expr . '+' expr
40 | expr . '-' expr
41 | expr . '*' expr
42 | expr . '/' expr
42 | expr '/' expr .
44 | expr . '<' expr
45 | expr . LE expr
46 | expr . '=' expr
'@' shift, and go to state 73
'.' reduce using rule 23 (opt_at_type)
'.' [reduce using rule 42 (expr)]
$default reduce using rule 42 (expr)
opt_at_type go to state 74
opt_at_type定义为:
opt_at_type:
{ $$ = idtable.add_string("SELF_TYPE"); }
| '@' TYPEID
{ $$ = $2; }
;
你能告诉我为什么会这样吗?
答案 0 :(得分:1)
您遇到的问题是,仅考虑yacc优先级以解决转移/减少冲突,而不是减少/减少。在这种情况下,opt_at_type
规则可以匹配空字符串(它是可选的),从而导致减少/减少冲突。
要解决此问题,您需要解除规则以摆脱epsilon生产:
expr: expr '.' TYPEID '(' opt_expr_list ')'
| expr '@' TYPEID '.' TYPEID '(' opt_expr_list ')'
| expr '+' expr
:
如果没有epsilon生产,它不需要提前减少,因此冲突变成了转移/减少冲突,通常可以通过yacc优先级来解决。
答案 1 :(得分:0)
当Bison看到以下内容时:
expr '/' expr '.'
它不知道这是否等同于:
1) expr opt_at_type '.'
OR
2) expr '/' expr opt_at_type '.'
对于1)它会首先将expr '/' expr
减少到expr
,而对于2)它会先减少/ *清空* /到opt_at_type
。
所以我们发现了歧义,为了解决这个问题,你必须确定你想要的语法。一种解决方案是将第一个expr规则作为单独的规则,以便它不能在其他表达式中使用,如下所示:
typeexpr: expr opt_at_type '.' TYPEID '(' opt_expr_list ')'