Chapter 6: The Generated Parser Class' Members

Bisonc++ generates a C++ class, rather than a function like Bison. Bisonc++'s class is a plain C++ class and not a fairly complex macro-based class like the one generated by Bison++. The C++ class generated by bisonc++ does not have (need) virtual members. Its essential member (the member parse()) is generated from the grammar specification and so the software engineer will therefore hardly ever feel the need to override that function. All but a few of the remaining predefined members have very clear definitions and meanings as well, making it unlikely that they should ever require overriding.

It is likely that members like lex() and/or error() need dedicated definitions with different parsers generated by Bison++; but then again: while defining the grammar the definition of the associated support members is a natural extension of defining the grammar, and can be realized in parallel with defining the grammar, in practice not requiring any virtual members. By not defining (requiring) virtual members the parser's class organization is simplified, and calling non-virtual members will be just a trifle faster than calling these member functions as virtual functions.

In this chapter all available members and features of the generated parser class are discussed. Having read this chapter you should be able to use the generated parser class in your program (using its public members) and to use its facilities in the actions defined for the various production rules and/or use these facilities in additional class members that you might have defined yourself.

In the remainder of this chapter the class's public members are first discussed, to be followed by the class's private members. While constructing the grammar all private members are available in the action parts of the grammaticalrules. Furthermore, any member (and so not just from the action blocks) may generate errors (thus initiating error recovery procedures) and may flag the (un)successful parsing of the information given to the parser (terminating the parsing function parse()).

6.1: Public Members and Types

The following public members and types are available to users of the parser classes generated by bisonc++ (parser class-name prefixes (e.g., Parser::) prefixes are silently implied):

When the %polymorphic directive is used:

6.2: Protected Enumerations and Types

The following enumerations and types can be used by members of parser classes generated by bisonc++. They are actually protected members inherited from the parser's base class.

6.3: Non-public Member Functions

The following members can be used by members of parser classes generated by bisonc++. When prefixed by Base:: they are actually protected members inherited from the parser's base class. Members for which the phrase ``Used internally'' is used should not be called by user-defined code. :
By default implemented inline in the parser.ih internal header file, this member calls print__ to display the last received token and corrseponding matched text. The print__ member is only implemented if the --print-tokens option or %print-tokens directive was used when the parsing function was generated. Calling print__ from print is unconditional, but can easily be controlled by the using program, by defining, e.g., a command-line option.
  • void Base::push__():
    Used internally.
  • void Base::pushToken__():
    Used internally.
  • void Base::reduce__():
    Used internally.
  • void Base::symbol__():
    Used internally.
  • void Base::top__():
    Used internally. )

    6.3.1: `lex()': Interfacing the Lexical Analyzer

    The int lex() private member function is called by the parse() member to obtain the next lexical token. By default it is not implemented, but the %scanner directive (see section 5.5.19) may be used to pre-implement a standard interface to a lexical analyzer.

    The lex() member function interfaces to the lexical scanner, and it is expected to return the next token produced by the lexical scanner. This token may either be a plain character or it may be one of the symbolic tokens defined in the Parser::Tokens enumeration. Any zero or negative token value is interpreted as `end of input', causing parse() to return.

    The lex() member function may be implemented in various ways:

    6.4: Protected Data Members

    The following private members can be used by members of parser classes generated by bisonc++. All data members are actually protected members inherited from the parser's base class.

    6.5: Types and Variables in the Anonymous Namespace

    In the file defining the parse function the following types and variables are defined in the anonymous namespace. These are mentioned here for the sake of completeness, and are not normally accessible to other parts of the parser.

    6.6: Summary of Special Constructions for Actions

    Here is an overview of special syntactic constructions that may be used inside action blocks: