Polymorphic semantic values are used when the %polymorphic directive is
used. 

E.g., in the specification '%polymorphic TEXT: std::string;'
    'TEXT' is the semantic value tag name used in the grammar specification,
and 
    'std::string' is the C++ type that's used when referring to TEXT. 

The (polymorphic) semantic value type used by the grammar is
'Parser::STYPE_'. By associating non-terminals with a polymorphic semantic
value type (using %type specifications, like '%type <TEXT> identifier') $$
values used by the specified non-terminal automatically use the indicated
semantic value tag name. E.g.,
    identifier:
        IDENTIFIER
        {
            $$ = d_matched;
        }
    ;
When using %type specifications a C++ type can directly be assigned to $$,
and the intended semantic value tag does not have to be specified.

Parser::STYPE_ is available in Parser, but it's defined in parserbase.h. Thus
the type is 'owned' by bisonc++, and cannot be modified in the Parser class.

In addition to the polymorphic tag types defined in the grammar file, a final
%polymorphic specification is added to the generated grammar:
        %polymorphic END_TAG_: EndPolyType_
where both END_TAG_ and EndPolyType_ are (because of the trailing underscores)
names that cannot be used otherwise. A default constructed STYPE_ object
refers to END_TAG_ and contains an End_PolyType value: it is merely used to
ensure that an STYPE_ value is always defined. E.g., it is used in
Parser::setPrecedence.

The parserbase.h file is generated by members of the class Generator, starting
with the skeletons/bisonc++base.h file (in this README file the names used by
default are used). 

When generating files the skeletons use $insert specifications which are
recognized by Generator::filter, calling the corresponding functions specified
in Generator::s_insert (generator/data.cc). The names of those functions are
identical to the names used at the $insert specifications (e.g. '$insert
polymorphic' Generator::polymorphic is called to generate that part of the
generated file). It starts by defining the enum class Tag_ followed by the
definiton of the (empty) class EndPolyType_. E.g., for bisonc++ itself it is:

    // $insert polymorphic
    enum class Tag_
    {
        SYMBOL,
        TERMINAL,
        BLOCK,
        TEXT,
        SIZE_T,
        BOOL,
        END_TAG_
    };
    
    class EndPolyType_
    {};

Semantic value handling is defined in the namespace Meta_ (covered
below). Once the Meta_ namespace has been defined the class ParserBase is
defined ($insert parserbase). Here, STYPE_ is defined by

        using STYPE_ = Meta_::SType;

For each polymorphic tag / C++ type combination the Meta_ namespace defines

    template <typename Tp_>
    struct TagOf;
and    
    template <Tag_ tag>
    struct TypeOf;

and also specializations for the semantic value tags / C++ types, defining,
respectively the associated C++ types and semantic value tags. E.g.,

    template <>
    struct TagOf<std::string>
    {
        static Tag_ const tag = Tag_::TEXT;
    };
and
    template <>
    struct TypeOf<Tag_::TEXT>
    {
        using type = std::string;
    };


Meta_::SType is a wrapper class, derived from std::unique_ptr<Meta_::Base>
It contains the common constructors (default, copy, move), operator= members
for all polymorphic C++ types, an explicit assign member template 
handling the assignments in the operator= members, as in:

    inline SType &SType::operator=(std::string const &value)
    {
        assign< Tag_::TEXT >(value);
        return *this;
    }

and get() members returning the C++ data values of the polymorphic semantic
types (called, assuming STYPE_ value is available) as
value.get<Tag_::TEXT>(). If 'value' does holds a different polymorphic
semantic value then a fatal error results. Finally, it has a member 'tag()'
returning the STYPE_'s Tag_ value.

Next, the Meta_ namespace defines the polymorphic base class Base. Each STYPE_
object contains a pointer to a Base object, which in fact points to an
instantiation of the class template Semantic (see below), where each Semantic
object is constructed for a particular Tag_ (like Semantic_<Tag_::TEXT>,
constructed for the %polymorphic TEXT: std::string polymorphic value. As Base
is the polymorphic base class, all characteristics of the various Semantic
types are accessed via Base members:

        Tag_ tag() const;           returns the Semantic value's tag
        Base *clone() const;        returns a pointer to a newly allocated
                                    copy of the current Semantic object
        void *data() const;         returns a pointer to the data of the
                                    Semantic object.


The class template Semantic has standard constructors and a template
constructor member specifying the required argument(s) and Tag_. Other than
that, its vClone and vData member implementations are provided in parserbase.h

