1
votes

I'm new to using bison and am trying to modify an interpreter that uses a bison input file. I keep getting a type clash warning. I think it is because the expression and case_statement don't have a value, but I'm not sure how to fix it.

This is the warning.

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 ;

And here is the code that is the problem

%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 |
    ;
1

1 Answers

1
votes

You've declared statement to have the type <value>, which means that every alternative production for statement must set $$ to something of type <value>.

Most of the alternatives in your grammar don't have associated actions, so Bison inserts the default action $$ = $1;. For that to work, the type of $$ (i.e. statement) has to be the same as the type of whatever $1 is in that alternative. That's something Bison can check, since it knows the types of all grammar symbols, and so it does check that, in order to be able to warn you if the default action is obviously incorrect.

In the case of statement, you have four productions. statement: expression isn't a problem because expression is declared to have the type <value>. statement: reduce isn't a problem either, because it has the action $$ = $3;. (Bison doesn't type-check explicit actions because it would have to almost be a C compiler to figure out whether an action written in C is type-safe. But if it did check, this one would be fine, too, because $3 is reductions and reductions is also declared to be of type <value>.

The other two alternatives, though, do present a problem. Neither has an explicit action, and in both cases $1 is a grammar symbol with no declared type (the keyword IF, which certainly shouldn't have a value, and the non-terminal case-statement, which probably should, since you're going to need it to assign to statement). $$ = $1; will set the semantic value of statement to an unassigned value, and that's obviously not correct. Hence the warnings.

To silence the warning, give both of those alternatives an action. As noted above, Bison doesn't check that explicit actions are correctly type. To fix the problem correctly, though, you'll need to figure out what value to give $$ in both of those cases.

Note that it is just a warning, not an error. Bison cannot tell that you haven't assigned a value behind it's back, nor can it figure out whether C has an implicit conversion between two different types. So in some cases $$ = $1; is actually OK even though $$ and $1 have different (or no) declared types. But most of the time a type mismatch in the default action indicates an error, and the warning is reasonable.