1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
Syntax: bf(%union) tt(union-definition body)
In the grammars of many programs different types of data are used for different
terminal and nonterminal tokens. For example, a numeric constant may
need type tt(int) or tt(double), while a string needs type tt(std::string),
and an identifier might need a pointer to an entry in a symbol table.
Traditionally, the tt(%union) directive has always been used to accomplish
this. The directive defines a bf(C) union-type whose fields specify one or
more data types for semantic values. The directive tt(%union) is followed by a
pair of braces containing one or more field definitions. For example:
verb(
%union {
double u_val;
symrec *u_tptr;
};
)
In this example the two fields represent a tt(double) and a tt(symrec
*). The associated field names are tt(u_val) and tt(u_tptr), which are used in
the tt(%token) and tt(%type) directives to specify types that are associated
with terminal or nonterminal symbols (see section ref(TYPE)).
Notes:
itemization(
it() The semicolon following the closing brace is em(optional).
it() Since bf(C++-11) class types can be used in tt(union)
definitions; they can also be used when defining b()'s tt(%union)
directives. When a class type variant is required, all required
constructors, the destructor and other members (like overloaded
assignment operators) must be able to handle the actual class type
data fields properly. A discussion of how to use unrestricted unions
is beyon this manual's scope, but can be found, e.g., in the url(C++
Annotations)(http://cppannotations.sf.net). See also section
ref(SEMANTICS).
it() The tt(%union) directive is also a bit of an anachronism. In many
situations using tt(%polymorphic) is more attractive than using
tt(%union) (cf. section ref(POLYMORPHIC)).
)
Although the tt(%union) directive is still supported by b(), its use is
largely superseded by the newer tt(%polymorphic) directive, allowing b() and
the bf(C++) compiler to verify that the correct types are used when semantic
values are assigned or retrieved, which, in turn, helps preventing run-time
errors.
tt(%stype, %union) and tt(%polymorphic) are mutually exclusive: only one
of these directives can be used.
|