由于YACC中的冲突导致无用的规则

时间:2012-02-28 01:04:38

标签: bison yacc

错误消息:

bison -vdy tjc.y
conflicts: 2 shift/reduce
tjc.y:72.26-29: warning: rule useless in parser due to conflicts: return_type: type

编辑2:进一步将语法简化为以下规则。由于同一冲突导致相同的错误。如果我删除规则中的field_decl,那么冲突就会消失。

member_decl:      field_decl |  method_decl;

field_decl: STATIC type IDENT EQ SEMI;

method_decl:      STATIC return_type IDENT LPAR RPAR;

type:             INT | FLOAT;

return_type:      type | VOID;

这是y.output中带有shift / reduce冲突的部分:

state 18

7 field_decl: STATIC type . IDENT EQ SEMI
14 return_type: type .

IDENT  shift, and go to state 23

IDENT  [reduce using rule 14 (return_type)]

请帮我看看这里出了什么问题。

2 个答案:

答案 0 :(得分:3)

我认为Perry' analysis您遇到问题的原因是正确的。

我能用这个完整的语法得到类似的警告(与你的相同,但有%token规则,所以我可以编译它):

%token STATIC IDENT FLOAT INT VOID LPAR RPAR EQ SEMI

%%
member_decl:    field_decl |  method_decl;
field_decl:     STATIC type IDENT EQ SEMI;
method_decl:    STATIC return_type IDENT LPAR RPAR;
type:           INT | FLOAT;
return_type:    type | VOID;
%%

鉴于分析,我可能会修复它的方式是:

%token STATIC IDENT FLOAT INT VOID LPAR RPAR EQ SEMI

%%
member_decl:    field_decl |  method_decl;
field_decl:     STATIC type IDENT EQ SEMI;
method_decl:    STATIC type IDENT LPAR RPAR;
type:           INT | FLOAT | VOID;
%%

这在Bison中没有任何错误编译。您只需要在field_decl的处理中添加语义检查,以确保相关的type$2)不是VOID

答案 1 :(得分:2)

好的,问题似乎就是这样:你正在生成一个LALR(1)解析器。有一个前瞻,你无法区分field_decl和method_decl规则。为什么?因为两者看起来都相同,因为乍一看解析器无法区分return_type和类型(两者都可能包含INT或FLOAT)。我不是100%肯定,因为我对LR,LALR等之间区别的记忆现在都很模糊,但看起来这就是问题 - 尤其是当你尝试删除field_decl这一事实时错误消失了。