Bison YACC中的冲突导致无效规则

Bison YACC中的冲突导致无效规则,bison,yacc,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:进一步将语法简化为仅以下规则。由于相同的冲突导致相同的错误。如果我删除规则中的字段_decl,冲突就会消失 member_decl: field_decl | method_decl; field_decl:

错误消息:

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:进一步将语法简化为仅以下规则。由于相同的冲突导致相同的错误。如果我删除规则中的字段_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输出中的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)]

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

好的,问题似乎是:您正在生成一个LALR1解析器。如果前面有一个lookahead,则无法区分字段\u decl和方法\u decl规则。为什么?因为二者看起来完全相同,因为乍一看解析器无法区分返回类型和可能包含INT或FLOAT的类型。我不是100%确定,因为我对LR、LALR等之间的区别的记忆现在都很模糊,但这似乎就是问题所在——这一点特别表明,当您尝试删除字段decl时,错误消失了。

好的,所以问题似乎是:您正在生成一个LALR1解析器。如果前面有一个lookahead,则无法区分字段\u decl和方法\u decl规则。为什么?因为二者看起来完全相同,因为乍一看解析器无法区分返回类型和可能包含INT或FLOAT的类型。我不是100%确定,因为我对LR、LALR等之间的区别的记忆现在都很模糊,但似乎这就是问题所在——这一点特别表明,当您尝试删除字段decl时,错误消失了。

我认为这就是为什么出现问题的原因

我可以使用与您相同的完整语法获得类似的警告,但有%的令牌规则,因此我可以编译它:

%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中编译时没有任何错误。您只需在字段_decl的处理中添加一个语义检查,以确保相关类型$2不是无效的。

我认为您遇到问题的原因是正确的

我可以使用与您相同的完整语法获得类似的警告,但有%的令牌规则,因此我可以编译它:

%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中编译时没有任何错误。您只需要在字段_decl的处理中添加语义检查,以确保相关类型$2不为空。

是否可能您没有提到类型也可以是标识?这真的是您未编辑的语法吗?我为type->IDENT添加了一个规则,它产生了更多冲突。是的,它是未经编辑语法的一部分。这是一个非常简化的语法分析器。您能否将其简化为显示相同错误消息的最小语法?是的,请查看编辑。相同的错误。请尝试进一步减少它。如果删除最后三种形式的方法,错误是否仍然存在?您能否删除字段\u decl规则及其引用等?我们试图找到显示错误的最小语法。是否可能您没有提到类型也可以是标识?这真的是您未编辑的语法吗?我为type->IDENT添加了一个规则,它产生了更多冲突。是的,它是未经编辑语法的一部分。这是一个非常简化的语法分析器。您能否将其简化为显示相同错误消息的最小语法?是的,请查看编辑。相同的错误。请尝试进一步减少它。如果删除最后三种形式的方法,错误是否仍然存在?您能否删除字段\u decl规则及其引用等?我们正试图找到显示错误的最小语法。啊,好的,这是有道理的。有没有关于我如何在保持相同语法的同时解决这个问题的建议?啊,好吧,这是有道理的。在保持相同语法的情况下,我如何解决这个问题,有什么建议吗?