I have YYSTYPE
defined in parser.hpp
file for scanner.lex
use:
// parser.hpp
#define YYSTYPE Atom
typedef struct Atom
{
int i_value;
TypeEnum e_type;
string *str_value;
Node *node;
} atom_t;
In parser.ypp
I'm getting an error on RetType
"Semantic value used inside actions but has not declared the type"
RetType:
Type {}
| VOID {
debugPrint("Here");
$$.e_type = TYPE_VOID;
}
;
I want to get rid of the error and use %union
but couldn't figure out how to:
//
%union {
struct atom_t atom;
}
%type <atom> RetType;
You really should not be using
#define YYSTYPE Atom
And if you do so, you will not be able to use %union
(or any of the other ways bison provides to declare the semantic type), because putting a #define YYSTYPE
into an external header file completely bypasses bison's attempt to set the semantic type itself.
What you should instead do is use
%define api.value.type { Atom }
in your bison prologue. That will copy the declaration of YYSTYPE
into the bison-generated header, so you don't need to worry about it in your own header files.
Of course, that assumes that you are content for all terminals and non-terminals to use the same semantic value type, so that there is no need to use %type
at all. However, bison allows you to use %type
declarations in conjunction with api.value.type
declarations, with the proviso that if you use a %type
declaration anywhere, you must use it for all grammar symbols whose value is referenced (which is the same as the requirement for a grammar which uses the %union
declaration).
If you declare %type <atom>
for a particular grammar symbol, then bison translates any reference to that symbol's semantic value ($$
or $n
, depending on whether the symbol is on the left- or right-hand side of the :
) into what would effectively be $$.atom
. It's a simple textual substitution, since bison doesn't know anything about the semantic type itself, and it doesn't require that the selector be a simple word; you could, if you wanted to, use %type <atom.node>
, in which case all references to those symbols' values would have .atom.node
appended to them. That's not usually very useful outside of unions, because you no longer have any way of referring to the base value, but you might have a use case which fits.