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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
itemization(
it() Constructors:
Default, copy and move constructors. No data can be retrieved from
tt(SType) objects that were constructed by tt(SType)'s default
constructors, but they can accept values of defined polymorphic types,
which may then be retrieved from those objects.
it() Operators:
The standard overloaded assignment operators (copy and move assignment
operators) are available.
In addition the members
verb(
SType &operator=(Type const &value)
and
SType &operator=(Type &&tmp)
)
are defined for each of the polymorphic semantic value types. Up to
version 6.03.00 these members were defined as member templates, but
sometimes awkward compilation errors were encountered as with member
templates tt(Type) must exactly match one of the defined polymorphic
semantic types since tt(Type) is used to determine the appropriate
tt(Meta_::Tag_) value. As a consequence, if, e.g., a polymorphic type
tt(%polymorphic INT: int) is defined then an assignment like tt($$ =
true) fails, since the inferred type is tt(bool) and no matching
polymorphic type is available. Now that the assignment operators are
defined as plain member functions this problem isn't encountered
anymore because standard type conversions may then be applied by the
compiler. Note that ambiguities may still be encountered. If, e.g.,
polymorphic types are defined for tt(int) and tt(char) and an
expression like tt($$ = 30U) is used the compiler cannot tell whether
tt($$) refers to the tt(int) or to the tt(char) semantic value. A
standard (static) cast, or explicitly calling the tt(assign) member
(see the next item) solves these kind of ambiguities.
When tt(operator=(Type const &value)) is used, the left-hand side
tt(SType) object receives a copy of tt(value); when tt(operator=(Type
&&tmp)) is used, tt(tmp) is move-assigned to the left-hand side
tt(SType) object;
it() tt(void assign<tag>(Args &&...args))
The tt(tag) template argument must be a tt(Tag_) value. This member
function constructs a semantic value of the type matching tt(tag) from
the arguments that are passed to this member (zero arguments are OK if
the type associated with tt(tag) supports default construction). The
constructed value (not a copy of this value) is then stored in the
tt(STYPE_) object for which tt(assign) has been called.
As a tt(Meta_::Tag_) value must be specified when using tt(assign)
the compiler can use the explicit tag to convert tt(assign's) arguments
to an tt(SType) object of the type matching the specified tag.
The member tt(assign) can be used to store a specific polymorphic
semantic value in an tt(STYPE_) object. It differs from the set of
tt(operator=(Type)) members in that tt(assign) accepts multiple
arguments to construct the requested tt(SType) value from, whereas the
tt(operator=) members only accept single arguments of defined
polymorphic types.
To initialize an tt(STYPE_) object with a default tt(STYPE_) value,
direct assignment can be used (e.g., tt(d_lval_ = STYPE_{})). To
assign a semantic value to a production rule using tt(assign) the
tt(_$$) notation must be used, as tt($$) is interpreted as the
polymorphic value type that is associated with the production
rule:
verb(
_$$.assign<Tag_::CHAR>(30U);
)
it() tt(DataType &get<tag>()), and tt(DataType const &get<tag>() const)
These members return references to the object's semantic values. The
tt(tag) must be a tt(Tag_) value: its specification tells the
compiler which semantic value type it must use.
When the option/directive tt(tag-mismatches on) was specified then
tt(get), when called from the generated tt(parse) function, performs a
run-time check to confirm that the specified tag corresponds to
object's actual tt(Tag_) value. If a mismatch is observed, then the
parsing function aborts with a fatal error message. When
shorthand notations (like tt($$) and tt($1)) are used in production
rules' action blocks, then bic() can determine the correct tt(tag),
preventing the run-time check from failing.
But once a fatal error em(is) encountered, it can be difficult to
determine which action block generated the error. If this happens,
then consider regenerating the parser specifying the tt(--debug)
option, calling
verb(parser.setDebug(Parser::ACTIONCASES))
before calling the parser's tt(parse) function.
Following this the case-entry numbers of the tt(switch) which is
defined in the parser's tt(executeAction) member are inserted into the
standard output stream just before the matching statements are
executed. The action case number that's reported just before the
program reports the fatal error tells you in which of the grammar's
action block the error was encountered.
it() tt(Tag_ tag() const)
The tag matching the semantic value's polymorphic type is returned. The
returned value is a valid tt(Tag_) value when the tt(SType) object's
tt(valid) member returns tt(true);
By default, or after assigning a plain (default) tt(STYPE_) object to
an tt(STYPE_) object (e.g., using a statement like tt($$ =
STYPE_{})), tt(valid) returns tt(false), and the tt(tag) member
returns tt(Meta_::sizeofTag_).
it() tt(bool valid() const)
The value tt(true) is returned if the object contains a semantic
value. Otherwise tt(false) is returned. Note that default tt(STYPE_)
values can be assigned to tt(STYPE_) objects, but they do not
represent valid semantic values. See also the previous description of
the tt(tag) member.
)
|