    The tt(%type) directive is used to associate (non-)terminals with semantic
value types.

Non-terminals may be associated with polymorphic semantic
values using tt(%type) directives. E.g., after:
        verb(
    %polymorphic INT: int; TEXT: std::string
    %type <INT> expr
        )
    the tt(expr) non-terminal returns tt(int) semantic values. In this case,
a rule like:
        verb(
    expr:
        expr '+' expr
        {
            $$ = $1 + $3;
        }
        )
    automatically associates $$, $1 and $3 with tt(int) values. Here $$ is an
lvalue (representing the semantic value associated with the tt(expr:) rule),
while $1 and $3 represent, because of the tt(%type) specification, tt(int)
semantic values which are associated with, resp., the first and second
tt(expr) non-terminal in the production rule tt(expr '+' expr).

    When negative dollar indices (like $-1) are used, pre-defined associations
between non-terminals and semantic types are ignored.  With positive indices
or in combination with the production rule's return value tt($$), however,
semantic value types can explicitly be specified using the common `$<type>$'
or `$<type>1' syntax. (In this and following examples index number 1 represents
any valid positive index; -1 represents any valid negative index).

The type-overruling syntax does not allow blanks to be used (so $<INT>$ is OK,
$< INT >$ isn't).

Various combinations of type-associations and type specifications may be
encountered:
itemization(
it() $-1: tt(%type) associations are ignored, and the semantic value type
    tt(STYPE__) is used instead. A warning is issued unless the
    tt(%negative-dollar-indices) directive was specified.
it() $<tag>-1: em(error): tt(<tag>) specifications are not allowed for
    negative dollar indices. 
)

whenhtml(
center(
table(1)(l)(
rowline()
row(cell(center(includefile(polytable))))
))
includefile(polytablenotes)
rowline()
)

whenman(
bf(%type<TAG> and $$ or $1 specifications:)
includefile(polytable)
includefile(polytablenotes)

bf(Member calls) (`$$.', `$1.', `($$)', `($1)', etc.):)

    When using `$$.' or `$1.' default tags are ignored. A warning is issued
that the default tag is ignored. This syntax allows members of the semantic
value type (tt(STYPE__)) to be called explicitly. The default tag is only
ignored if there are no additional characters (e.g., blanks, closing
parentheses) between the dollar-expressions and the member selector operator
(e.g., no tags are used with $1.member(), but tags are used with
tt(($1).member())). In fact, notations like tt(($$), ($1)), etc. are synonym
to using tt($$.get<Tag__::TYPE>(), $1.get<Tag__::TYPE>())

The opposite, overriding default tag associations, is
accomplished using constructions like $<STYPE__>$ and $<STYPE__>1.

When negative dollar indices are used, the appropriate tag must explicitly be
specified. The next example shows how this is realized in the grammar
specification file itself:
        verb(
    %polymorphic INT: int
    %type <INT> ident
    %%
    
    type:
        ident arg
    ;
    
    arg:
        {
            call($-1.get<Tag__::INT>());
        }
    ;
        )
    In this example tt(call) may define an tt(int) or tt(int &) parameter. 

It is also possible to delegate specification of the semantic value to the
function tt(call) itself, as shown next:
        verb(
    %polymorphic INT: int
    %type <INT> ident
    %%
    
    type:
        ident arg
    ;
    
    arg:
        {
            call($-1);
        }
    ;
        )
    Here, the function tt(call) could be implemented like this:
        verb(
    void call(STYPE__ &st)
    {
        st.get<Tag__::INT>() = 5;
    }
        )

Semantic values may also directly be associated with terminal tokens. In that
case it is the lexical scanner's responsibility to assign a properly typed
value to the parser's tt(STYPE__ d_val__) data member. When the lexical
scanner receives a pointer to the parser's tt(d_val__) data member (using,
e.g., a member tt(setSval(STYPE__ *dval)))
    IFDEF(manual)((cf. section ref(PRIVDATA)))(), 
then the lecical scanner must use em(tagged assignment) as shown in the above
example to reach the different polymorphic types. The lexical scanner, having
defined a tt(Parser::STYPE__ *d_val) data member could then use statements
like
        verb(
    d_val.get<Tag__::INT>() = stoi(matched());
        )
    to assign an tt(int) value to the parser's semantic value, which is then
immediately available when the lexical scanner's tt(lex) function
returns. Note, however that this also adds intelligence about the meaning of a
tt(Parser::INT) token to the scanner. It can be argued that this knowledge
belongs to the parser, and that the scanner should merely recognize regular
expressions and return tokens and their corresponding matched text.




