    The i(declaration section) contains several sets of declarations, among
which definitions of all the tokens used in the grammar and the priorities and
associativities of the mathematical operators. Moreover, several new and
important specifications can be used here as well. Those relevant to our
current example and only available in tt(bisonc++) are discussed here. The
reader is referred to tt(bisonc++)'s man-page for a full description.
    itemization(
    it() bi(%baseclass-preinclude) tt(header)nl()
          Use tt(header) as the pathname to the file pre-included in the
           parser's base-class header.  This declaration is useful in
           situations where the base class header file refers to types which
           might not yet be known. E.g., with ti(%union) a tt(std::string *)
           field might be used. Since the class tt(std::string) might not yet
           be known to the compiler once it processes the base class header
           file we need a way to inform the compiler about these classes and
           types. The suggested procedure is to use a pre-include header file
           declaring the required types. By default tt(header) is
           surrounded by double quotes (using, e.g., tt(#include "header")).
           When the argument is surrounded by angle brackets tt(#include
           <header>) is included. In the latter case, quotes might be
           required to escape interpretation by the shell (e.g., using tt(-H
           '<header>')).
    it() bi(%filenames) tt(header) nl()
           Defines the generic name of all generated files, unless overridden
            by specific names. By default the generated files use the
           class-name as the generic file name.
    it() bi(%scanner) tt(header)nl()
           Use tt(header) as the pathname to the file pre-included in the
            parser's class header. This file should define a class
            tt(Scanner), offering a member tt(int lex()) producing the next
            token from the input stream to be analyzed by the parser generated
            by tt(bisonc++). When this option is used the parser's member
            tt(int lex()) is predefined as (assuming the default parser class
            name tt(Parser) is used):
            verb(inline int Parser::lex()
{
    return d_scanner.lex();
})

and an object tt(Scanner d_scanner) is composed into the
            parser. The tt(d_scanner) object is constructed by its
            default constructor. If another constructor is required, the
            parser class may be provided with an appropriate (overloaded)
            parser constructor after having constructed the default parser
            class header file using tt(bisonc++).  By default tt(header) is
            surrounded by double quotes (using, e.g., tt(#include
            "header")).  When the argument is surrounded by angle brackets
            tt(#include <header>) is included.
    it() bi(%stype) tt(typename) nl()
           The type of the semantic value of tokens.  The specification
            tt(typename) should be the name of an unstructured type (e.g.,
            tt(size_t)). By default it is tt(int). See tt(YYSTYPE) in
            tt(bison).  It should not be used if a tt(%union) specification is
            used.  Within the parser class, this type may be used as
            tt(STYPE).
    it() bi(%union) tt(union-definition) nl()
           Acts identically to the tt(bison) declaration.  As with tt(bison)
            this generates a union for the parser's semantic type.  The union
            type is named tt(STYPE). If no tt(%union) is declared, a simple
            stack-type may be defined using the tt(%stype) declaration. If no
            tt(%stype) declaration is used, the default stacktype (tt(int)) is
            used.
    )
    An example of a tt(%union) declaration is:
        verb(    %union
    {
        int     i;
        double  d;
    };)

In pre-C++11 code a i(union) cannot contain objects as its fields, as
constructors cannot be called when a union is created.  This means that
    hi(string: as union member) a tt(string) cannot be a member of the
union. A tt(string *), however, em(is) a possible union member.  It might also
be possible to use em(unrestricted unions) (cf. section ref(UNIONS)), having
class type objects as fields.

As an aside: the scanner does not have to know about such a union. It
can simply pass its scanned text to the parser through its ti(matched) member
function. For example using a statement like
        verb(    $$.i = A2x(d_scanner.matched());)

matched text is converted to a value of an appropriate type.

    Tokens and non-terminals can be associated with union fields. This is
strongly advised, as it prevents type mismatches, since the compiler may then
check for type correctness. At the same time, the bison specific
variables tt($$), tt($1), tt($2), etc. may be used, rather than the full field
specification (like tt($$.i)).  A non-terminal or a token may be associated
with a union field using the
    tt(<fieldname>) specification. E.g.,
        verb(    %token <i> INT          // token association (deprecated, see below)
           <d> DOUBLE
    %type  <i> intExpr      // non-terminal association)

In the example developed here, both the tokens and the non-terminals can
be associated with a union field. However, as noted before, the scanner does
not have to know about all this. In our opinion, it is cleaner to let the
scanner do just one thing: scan texts. The em(parser), knowing what the input
is all about, may then convert strings like tt("123") to an integer
value. Consequently, the association of a union field and a token is
discouraged. Below, while describing the grammar's rules, this is further
illustrated.

    In the tt(%union) discussion the ti(%token) and ti(%type) specifications
should be noted. They are used to specify the tokens (terminal symbols) that
can be returned by the scanner, and to specify the return types of
non-terminals.  Apart from tt(%token) the token declarators ti(%left),
ti(%right), and ti(%nonassoc) can be used to specify the associativity of
operators. The tokens mentioned at these indicators are interpreted as tokens
indicating operators, associating in the indicated direction. The precedence
of operators is defined by their order: the first specification has the lowest
priority. To overrule a certain precedence in a certain context ti(%prec) can
be used. As all this is standard tt(bisonc++) practice, it isn't further
elaborated here. The documentation provided with tt(bisonc++)'s distribution
should be consulted for further reference.

    Here is the specification of the calculator's declaration section:
        verbinclude(//DECLARATION bisonc++/parser/grammar)
    In the declaration section tt(%type) specifiers are used, associating the
tt(intExpr) rule's value (see the next section) to the tt(i)-field of the
semantic-value union, and associating tt(doubleExpr)'s value to the
tt(d)-field. This approach, admittedly, is rather complex, as expression rules
must be included for each of the supported union types. Alternatives are
definitely possible, and involve the use of em(polymorphic semantic
values), covered in detail in the 
    url(Bisonc++ user guide)
        (http://fbb-git.gitlab.io/bisoncpp/manual/bisonc++.html).
