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
|
Specifying the tt(%polymorphic) directive results in a parser using
polymorphic semantic values. Polymorphic semantic value specifications
consist of a em(tag), which is a bf(C++) identifier, and a bf(C++) type
definition.
Tags and type definitions are separated by colons, and multiple semantic
value specifications are separated by semicolons. The semicolon trailing the
final semantic value specification is optional: type name specifications
end at a semicolon or at a percent character (indicating the beginning of the
next directive). End of line comment and standard bf(C) comment may also be
used, but both are ignored.
The tt(%polymorphic) directive may be specified only once, and the
tt(%polymorphic, %stype) and tt(%union) directives are mutually exclusive.
Here is an example, defining three semantic values types: tt(int),
tt(std::string) and tt(std::vector<double>):
verb(
%polymorphic INT: int; STRING: std::string;
VECT: std::vector<double>
)
The identifier to the left of the colon is called the em(type-tag) (or
simply `em(tag)'), and the type definition to the right of the colon is called
the em(type-definition). Types specified at the tt(%polymorphic)
type-definitions must be built-in types or class-type declarations. Since
bic() version 4.12.00 the types no longer have to be default-constructible.
As the parser's generic semantic value type is called tt(STYPE_), and as
functions called by the parser may return tt(STYPE_) values and may expect
tt(STYPE_) arguments, grammar symbols can also be associated with the generic
tt(STYPE_) semantic type using tt(%type <STYPE_>) directives.
To prevent ambiguities the generic tt(STYPE_) type cannot be specified as a
polymorphic type. E.g., a specification like tt(GENERIC: STYPE_) cannot be
used when defining the tag/type pairs at the tt(%polymorphic)
directive.
When polymorphic type-names refer to types that have not yet been declared
by the parser's base class header, then these types must be declared in a
separate header file, included into the parser's base class header file
through the tt(%baseclass-preinclude) directive.
|