如何使用bison输入文件修复类型冲突警告



我是使用野牛的新手,我试图修改使用野牛输入文件的解释器。我总是收到类型冲突警告。我认为这是因为表达式和case_statement没有值,但我不确定如何修复它。

这是警告。

parser.y:97.9-59: warning: type clash on default action: <value> != <> [-Wother]
97 |         IF expression THEN statement_ ELSE statement_ ENDIF |
|         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
parser.y:98.9-30: warning: type clash on default action: <value> != <> [-Wother]
98 |         case_statement ENDCASE ;

这就是问题所在的代码

%union
{
CharPtr iden;
Operators oper;
int value;
}
%token <iden> IDENTIFIER
%token <value> INT_LITERAL REAL_LITERAL BOOL_LITERAL
%token <oper> ADDOP MULOP RELOP REMOP EXPOP
%token ANDOP
%token BEGIN_ BOOLEAN END ENDREDUCE FUNCTION INTEGER IS REDUCE RETURNS
%token ARROW OROP NOTOP CASE ELSE ENDCASE ENDIF IF REAL
%token OTHERS THEN WHEN
%type <value> body statement_ statement reductions expression relation term factor primary 
power conjunction
%type <oper> operator
%%
statement_:
statement ';' |
error ';' {$$ = 0;} ;
statement:
expression |
REDUCE operator reductions ENDREDUCE {$$ = $3;} |
IF expression THEN statement_ ELSE statement_ ENDIF |
case_statement ENDCASE ;
case:
WHEN INT_LITERAL ARROW statement_;
cases:
case cases_others;
case_statement:
CASE expression IS cases OTHERS ARROW statement_ ';' |
error ';' ;
cases_others:
case cases_others |
;

您已经声明statement具有类型<value>,这意味着statement的每个替代产品必须将$$设置为类型<value>的东西。

语法中的大多数备选项没有关联的操作,因此Bison插入默认操作$$ = $1;。为此,$$(即statement)的类型必须与该替代方案中的$1的类型相同。这是Bison可以检查的东西,因为它知道所有语法符号的类型,所以它会检查,以便能够在默认操作明显不正确时警告您。

statement的情况下,您有四个产品。statement: expression不是问题,因为expression被声明为<value>类型。statement: reduce也不是问题,因为它具有$$ = $3;的动作。(Bison不会对显式操作进行类型检查,因为它几乎必须是C编译器才能确定用C编写的操作是否类型安全。但是如果它确实检查了,这个也可以,因为$3reductions,reductions也被声明为<value>类型。

但是,其他两个选择确实存在问题。两者都没有显式的操作,而且在这两种情况下,$1都是一个没有声明类型的语法符号(关键字IF当然不应该有值,而非终结符case-statement可能应该有值,因为您将需要它来赋值给statement)。$$ = $1;将把statement的语义值设置为未分配的值,这显然是不正确的。因此有了警告。

要静音警告,给这两个选项一个操作。如上所述,Bison不会检查显式操作是否正确输入。但是,要正确解决这个问题,您需要弄清楚在这两种情况下给$$的值。

注意这只是一个警告,而不是一个错误。Bison无法判断你没有在背后赋值,也无法判断C是否在两种不同类型之间进行隐式转换。因此,在某些情况下,$$ = $1;实际上是可以的,即使$$$1具有不同(或没有)声明的类型。但是大多数情况下,默认操作中的类型不匹配表明存在错误,并且警告是合理的。

最新更新