I need to use flex and bison to parse some code.
The default type of YYSTYPE is int
, even though I never declared it that way. Is that a default from bison?
It would help me a lot to pass strings back. I read this: How to solve Bison warning "... has no declared type" This looks like a good approach. (I don't need the full power of a union yet, just the char* part, but I might as well use the union because it might be helpful later.)
It's not working for me. I get these errors:
y:111.37-38: $1 of `ConstExpression' has no declared type
y:113.34-35: $1 of `ConstFactor' has no declared type
y:114.35-36: $1 of `ConstFactor' has no declared type
y:119.34-35: $1 of `Type' has no declared type
y:109.23-48: warning: type clash on default action: <str> != <>
y:115.23-27: warning: type clash on default action: <str> != <>
[...more of the same snipped...]
Here are the declarations from my y
grammar file:
%union {
char *str;
}
%type<str> ConstExpression ConstFactor Type
Here is one line from my .l
file:
[a-zA-Z]+[a-zA-Z0-9]* { yylval.str = strdup(yytext); return yident;}
What else do I need to do to resolve the errors?
Actually, I'm pretty sure I know what's wrong without seeing the grammar.
It's necessary to declare the types of terminal symbols as well, as they can and often do return semantic value. Think about things like ID
and NUMBER
, which have yyval
data. But yacc doesn't have any way to know whether it's just an 'x'
or something more, and the default action in a rule is: $$ = $1
For example, the following grammar makes it through yacc just fine, but try removing one more more of the symbols from the %type
below:
%union {
char *s;
}
%type <s> r1 r2 'x'
%%
r1: r2;
r2: 'x' { printf("%s\n", $1); };