I am trying to construct a parser with Bison. I have the following in the first section:
%union {
int ttype;
// enums used in lexer
Staff stafftype;
Numeral numeral;
Quality quality;
Inversion inversion;
Pitch pitch;
Accidental accidental;
// Classes used in parser
Roman roman;
}
%token <stafftype> STAFFTYPE
%token <numeral> NUMERAL
%token <quality> QUALITY
%token <inversion> INVERSION
%token <pitch> PITCH
%token <accidental> ACCIDENTAL
%token <ttype> COLON
%token <ttype> SLASH
%token <ttype> COMMA
%type <roman> accidentalRoman
With some grammar rules. Here is one:
accidentalRoman
: NUMERAL { $$ = Roman($1); }
| ACCIDENTAL NUMERAL { $$ = Roman($2, $1); }
;
I basically have three related questions.
- What does the %union really represent? I thought it represented types the lexer could return. My lexer rules contain statements like
return STAFFTYPE
, to indicate that I have populatedyylval.stafftype
with aStaff
object. Fair enough. However; - the union also seems to have something to do with the
$$ =
statements in the grammar actions. Why do the result types of grammar actions need to be in the union? - In my example, the
Roman
class has a constructor with parameters. However, declaration in the union causes the errorno matching function for call to 'Roman::Roman()'
. Is there any way around this? I'm trying to build up a parse tree with$$ =
, and the nodes in the tree definitely need parameters in their constructors. In fact, it doesn't even allow a 0-parameter constructor:error: union member 'YYSTYPE::roman' with non-trivial 'Roman::Roman().
union
which contains exactly what%union
provides.union
(in C++) and classes do not work well together (due to the construction issue). It may work under some restrictions but I prefer to prevent this completely. – Scheff's Cat%union
is used to attribute rules. Whenever, there is extra data which has to be passed for a token (flex) or a rule (bison),%union
comes into play. That was OK in C but may cause conflicts if you want to use it in C++. (Sorry, I start to repeat me.) A work around could be, to use global variables (may be even stacks) instead of attributes (crafted with%union
). For me, it was one reason to stop the usage of bison (and making recursive descent parsers instead. Btw. debugging and maintenance was the main reason...) – Scheff's Cat