.TH "bisonc++" "1" "2005\-2014" "bisonc++\&.4\&.09\&.02\&.tar\&.gz" "bisonc++ parser generator" .PP .SH "NAME" bisonc++ \- Generate a C++ parser class and parsing function .PP .SH "SYNOPSIS" \fBbisonc++\fP [OPTIONS] \fIgrammar\-file\fP .PP .SH "SECTIONS" This manual page contains the following sections: .IP "1\&. DESCRIPTION" overview and short history of of \fBbisonc++\fP; .IP "2\&. GENERATED FILES" files \fBbisonc++\fP may generate; .IP "3\&. OPTIONS" \fBBisonc++\fP\(cq\&s command\-line options; .IP "4\&. DIRECTIVES" \fBBisonc++\fP\(cq\&s grammar\-specification directives; .IP "5\&. POLYMORPHIC SEMANTIC VALUES" How to use polymorphic semantic values in parsers generated by \fBbisonc++\fP; .IP "6\&. PUBLIC MEMBERS AND \-TYPES" Members and types that can be used by calling software; .IP "7\&. PRIVATE ENUMS AND \-TYPES" Enumerations and types only available to the \fIParser\fP class; .IP "8\&. PRIVATE MEMBER FUNCTIONS" Member functions that are only available to the \fIParser\fP class; .IP "9\&. PRIVATE DATA MEMBERS" Data members that are only available to the \fIParser\fP class; .IP "10\&. TYPES AND VARIABLES IN THE ANONYMOUS NAMESPACE" An overview of the types and variables that are used to define and store the grammar\-tables generated by \fBbisonc++\fP; .IP "11\&. RESTRICTIONS ON TOKEN NAMES" Name restrictions for user\-defined symbols; .IP "12\&. OBSOLETE SYMBOLS" Symbols available to \fBbison\fP(1), but not to \fBbisonc++\fP; .IP "13\&. EXAMPLE" Guess what this is? .IP "14\&. USING PARSER\-CLASS SYMBOLS IN LEXICAL SCANNERS" How to refer to \fIParser\fP tokens from within a lexical scanner; .IP "15\&. FILES" (Skeleton) files used by \fBbisonc++\fP; .IP "16\&. SEE ALSO" References to other programs and documentation; .IP "17\&. BUGS" Some additional stuff that should not qualify as bugs\&. .IP "18\&. ABOUT bisonc++" More history; .IP "AUTHOR" At the end of this man\-page\&. .PP Looking for a specific section? Search for its number + a dot\&. .PP .SH "1\&. DESCRIPTION" .PP \fBBisonc++\fP derives from previous work on \fBbison\fP by Alain Coetmeur (coetmeur@icdc\&.fr), who created in the early \(cq\&90s a \fBC++\fP class encapsulating the \fIyyparse\fP function as generated by the GNU\-\fBbison\fP parser generator\&. .PP Initial versions of \fBbisonc++\fP (up to version 0\&.92) wrapped Alain\(cq\&s program in a program offering a more modern user\-interface, removing all old\-style (\fBC\fP) \fI%define\fP directives from \fBbison++\fP\(cq\&s input specification file (see below for an in\-depth discussion of the differences between \fBbison++\fP and \fBbisonc++\fP)\&. Starting with version 0\&.98, \fBbisonc++\fP represents a complete rebuilt of the parser generator, closely following descriptions given in Aho, Sethi and Ullman\(cq\&s \fIDragon Book\fP\&. Since version 0\&.98 \fBbisonc++\fP is a \fBC++\fP program, rather than a \fBC\fP program generating \fBC++\fP code\&. .PP \fBBisonc++\fP expands the concepts initially implemented in \fBbison\fP and \fBbison++\fP, offering a cleaner setup of the generated parser class\&. The parser class is derived from a base\-class, mainly containing the parser\(cq\&s token\- and type\-definitions as well as several member functions which should not be modified by the programmer\&. .PP Most of these base\-class members might also be defined directly in the parser class, but were defined in the parser\(cq\&s base\-class\&. This design results in a very lean parser class, declaring only members that are actually defined by the programmer or that have to be defined by \fBbisonc++\fP itself (e\&.g\&., the member function \fIparse\fP as well as some support functions requiring access to facilities that are only available in the parser class itself, rather than in the parser\(cq\&s base class)\&. .PP This design does not require any virtual members: the members which are not involved in the actual parsing process may always be (re)implemented directly by the programmer\&. Thus there is no need to apply or define virtual member functions\&. .PP In fact, there are only two public members in the parser class generated by \fBbisonc++\fP: \fIsetDebug\fP (see below) and \fIparse\fP\&. Remaining members are private, and those that can be redefined by the programmer using \fBbisonc++\fP usually receive initial, very simple default in\-line implementations\&. The (partial) exception to this rule is the member function \fIlex\fP, producing the next lexical token\&. For \fIlex\fP either a standardized interface or a mere declaration is offered (requiring the programmer to provide his/her own \fIlex\fP implementation)\&. .PP To enforce a primitive namespace, \fBbison\fP used a well\-known naming\-convention: all its public symbols started with \fIyy\fP or \fIYY\fP\&. \fBBison++\fP followed \fBbison\fP in this respect, even though a class by itself offers enough protection of its identifiers\&. Consequently, these \fIyy\fP and \fIYY\fP conventions are now outdated, and \fBbisonc++\fP does not generate or use symbols defined in either the parser (base) class or in its member functions starting with \fIyy\fP or \fIYY\fP\&. Instead, following a suggestion by Lakos (2001), all data members start with \fId_\fP, and all static data members start with \fIs_\fP\&. This convention was not introduced to enforce identifier protection, but to clarify the storage type of variables\&. Other (local) symbols lack specific prefixes\&. Furthermore, \fBbisonc++\fP allows its users to define the parser class in a particular namespace of their own choice\&. .PP \fBBisonc++\fP should be used as follows: .IP o As usual, a grammar must be defined\&. With \fBbisonc++\fP this is not different, and the reader is referred to \fBbisonc++\fP\(cq\&s manual and other sources (like Aho, Sethi and Ullman\(cq\&s book) for details about how to specify and decorate grammars\&. .IP o The number and function of the various \fI%define\fP declarations as used by \fBbison++\fP, however, is greatly modified\&. Actually, all of \fBbison\fP\(cq\&s \fI%define\fP declarations were replaced by their (former) first arguments\&. Furthermore, `macro\-style\(cq\& declarations are no longer supported or required\&. Finally, all directives use lower\-case characters only and do not contain underscore characters (but sometimes hyphens)\&. E\&.g\&., \fI%define DEBUG\fP is now declared as \fI%debug\fP; \fI%define LSP_NEEDED\fP is now declared as \fI%lsp\-needed\fP (note the hyphen)\&. .IP o As noted, no `macro style\(cq\& \fI%define\fP declarations are required anymore\&. Instead, the normal practice of defining class members in source files and declaring them in a class header files can be adhered to using \fBbisonc++\fP\&. Basically, \fBbisonc++\fP concentrates on its main tasks: defining a parser class and implementing its parsing function \fIint parse\fP, leaving all other parts of the parser class\(cq\& definition to the programmer\&. .IP o Having specified the grammar and (usually) some directives \fBbisonc++\fP is able to generate files defining the parser class and to implement the member function \fIparse\fP and its support functions\&. See the next section for details about the various files that may be generated by \fBbisonc++\fP\&. .IP o All members (except for the member \fIparse\fP and its support functions) must be implemented by the programmer\&. Additional member functions should be declared in the parser class\(cq\& header\&. At the very least the member \fIint lex()\fP \fImust\fP be implemented (although a standard implementation can be generated by \fBbisonc++\fP)\&. The member \fIlex\fP is called by \fIparse\fP to obtain the next available token\&. The member function \fIvoid error(char const *msg)\fP may also be re\-implemented by the programmer, and a basic in\-line implementation is provided by default\&. The member function \fIerror\fP is called when \fIparse\fP detects (syntactic) errors\&. .IP o The parser can now be used in a program\&. A very simple example would be: .nf int main() { Parser parser; return parser\&.parse(); } .fi .PP .SH "2\&. GENERATED FILES" .PP \fBBisonc++\fP may create the following files: .IP o A file containing the implementation of the member function \fIparse\fP and its support functions\&. The member \fIparse\fP is a public member that can be called to parse a token\-sequence according to a specified LALR1 type of grammar\&. By default the implementations of these members are written on the file \fIparse\&.cc\fP\&. The programmer should not modify the contents of this file; it is rewritten every time \fBbisonc++\fP is called\&. .IP o A file containing an initial setup of the parser class, containing the declaration of the public member \fIparse\fP and of its (private) support members\&. New members may safely be declared in the parser class, as it is only created by \fBbisonc++\fP if not yet existing, using the filename \fI\&.h\fP (where \fI\fP is the the name of the defined parser class)\&. .IP o A file containing the parser class\(cq\& \fIbase class\fP\&. This base class should not be modified by the programmer\&. It contains types defined by \fBbisonc++\fP, as well as several (protected) data members and member functions, which should not be redefined by the programmer\&. All symbolic parser terminal tokens are defined in this class, thereby escalating these definitions to a separate class (cf\&. Lakos, (2001)), which in turn prevents circular dependencies between the lexical scanner and the parser (here, circular dependencies may easily be encountered, as the parser needs access to the lexical scanner class when defining the lexical scanner as one of its data members, whereas the lexical scanner needs access to the parser class to know about the grammar\(cq\&s symbolic terminal tokens; escalation is a way out of such circular dependencies)\&. By default this file is (re)written any time \fBbisonc++\fP is called, using the filename \fIbase\&.h\fP\&. .IP o A file containing an \fIimplementation header\fP\&. The implementation header rather than the parser\(cq\&s class header file should be included by the parser\(cq\&s source files implementing member functions declared by the programmer\&. The implementation header first includes the parser class\(cq\&s header file, and then provides default in\-line implementations for its members \fIerror\fP and \fIprint\fP (which may be altered by the programmer)\&. The member \fIlex\fP may also receive a standard in\-line implementation\&. Alternatively, its implementation can be provided by the programmer (see below)\&. Any directives and/or namespace directives required for the proper compilation of the parser\(cq\&s additional member functions should be declared next\&. The implementation header is included by the file defining \fIparse\fP\&. By default the implementation header is created if not yet existing, receiving the filename \fI\&.ih\fP\&. .IP o A verbose description of the generated parser\&. This file is comparable to the verbose ouput file originally generated by \fBbison++\fP\&. It is generated when the option \fI\-\-verbose\fP or \fI\-V\fP is provided\&. If so, \fBbisonc++\fP writes the file \fI\&.output\fP, where \fI\fP is the name of the file containing the grammar definition\&. .PP .SH "3\&. OPTIONS" Where available, single letter options are listed between parentheses beyond their associated long\-option variants\&. Single letter options require arguments if their associated long options require arguments\&. Options affecting the class header or implementation header file are ignored if these files already exist\&. Options accepting a `filename\(cq\& do not accept path names, i\&.e\&., they cannot contain directory separators (\fI/\fP); options accepting a \(cq\&pathname\(cq\& may contain directory separators\&. .PP Some options may generate errors\&. This happens when an option conflicts with the contents of a file which \fBbisonc++\fP cannot modify (e\&.g\&., a parser class header file exists, but doesn\(cq\&t define a name space, but a \fI\-\-namespace\fP option was provided)\&. .PP To solve the error the offending option could be omitted, the existing file could be removed, or the existing file could be hand\-edited according to the option\(cq\&s specification\&. Note that \fBbisonc++\fP currently does not handle the opposite error condition: if a previously used option is omitted, then \fBbisonc++\fP does not detect the inconsistency\&. In those cases compilation errors may be generated\&. .PP .IP o \fB\-\-analyze\-only\fP (\fB\-A\fP) .br Only analyze the grammar\&. No files are (re)written\&. This option can be used to test the grammatic correctness of modification `in situ\(cq\&, without overwriting previously generated files\&. If the grammar contains syntactic errors only syntax analysis is performed\&. .IP .IP o \fB\-\-baseclass\-header\fP=\fIfilename\fP (\fB\-b\fP) .br \fIFilename\fP defines the name of the file to contain the parser\(cq\&s base class\&. This class defines, e\&.g\&., the parser\(cq\&s symbolic tokens\&. Defaults to the name of the parser class plus the suffix \fIbase\&.h\fP\&. It is generated, unless otherwise indicated (see \fI\-\-no\-baseclass\-header\fP and \fI\-\-dont\-rewrite\-baseclass\-header\fP below)\&. .IP It is an error if this option is used and an already existing parser class header file does not contain \fI#include \(dq\&filename\(dq\&\fP\&. .IP .IP o \fB\-\-baseclass\-preinclude\fP=\fIpathname\fP (\fB\-H\fP) .br \fIPathname\fP defines the path to the file preincluded in the parser\(cq\&s base\-class header\&. This option is needed in situations where the base class header file refers to types which might not yet be known\&. E\&.g\&., with polymorphic semantic values a \fIstd::string\fP value type might be used\&. Since the \fIstring\fP header file is not by default included in \fIparserbase\&.h\fP we somehow need to inform the compiler about this and possibly other headers\&. The suggested procedure is to use a pre\-include header file declaring the required types\&. By default `\fIheader\fP\(cq\& is surrounded by double quotes: \fI#include \(dq\&header\(dq\&\fP is used when the option \fI\-H header\fP is specified\&. When the argument is surrounded by pointed brackets \fI#include
\fP is included\&. In the latter case, quotes might be required to escape interpretation by the shell (e\&.g\&., using \fI\-H \(cq\&
\(cq\&\fP)\&. .IP .IP o \fB\-\-baseclass\-skeleton\fP=\fIpathname\fP (\fB\-B\fP) .br \fIPathname\fP defines the path name to the file containing the skeleton of the parser\(cq\&s base class\&. It defaults to the installation\-defined default path name (e\&.g\&., \fI/usr/share/bisonc++/\fP plus \fIbisonc++base\&.h\fP)\&. .IP .IP o \fB\-\-class\-header\fP=\fIfilename\fP (\fB\-c\fP) .br \fIFilename\fP defines the name of the file to contain the parser class\&. Defaults to the name of the parser class plus the suffix \fI\&.h\fP .IP It is an error if this option is used and an already existing implementation header file does not contain \fI#include \(dq\&filename\(dq\&\fP\&. .IP .IP o \fB\-\-class\-name\fP \fIclassName\fP .br Defines the name of the \fBC++\fP class that is generated\&. If neither this option, nor the \fI%class\-name\fP directory is specified, then the default class name (\fIParser\fP) is used\&. .IP It is an error if this option is used and an already existing parser\-class header file does not define \fIclass `className\(cq\&\fP and/or if an already existing implementation header file does not define members of the class \fI`className\(cq\&\fP\&. .IP .IP o \fB\-\-class\-skeleton\fP=\fIpathname\fP (\fB\-C\fP) .br \fIPathname\fP defines the path name to the file containing the skeleton of the parser class\&. It defaults to the installation\-defined default path name (e\&.g\&., \fI/usr/share/bisonc++/\fP plus \fIbisonc++\&.h\fP)\&. .IP .IP o \fB\-\-construction\fP .br Details about the construction of the parsing tables are written to the same file as written by the \fI\-\-verbose\fP option (i\&.e\&., \fI\&.output\fP, where \fI\fP is the input file read by \fBbisonc++\fP\&. This information is primarily useful for developers\&. It augments the information written to the verbose grammar output file, generated by the \fI\-\-verbose\fP option\&. .IP .IP o \fB\-\-debug\fP .br Provide \fIparse\fP and its support functions with debugging code, showing the actual parsing process on the standard output stream\&. When included, the debugging output is active by default, but its activity may be controlled using the \fIsetDebug(bool on\-off)\fP member\&. An \fI#ifdef DEBUG\fP macro is not supported by \fBbisonc++\fP\&. Rerun \fBbisonc++\fP without the \fI\-\-debug\fP option to remove the debugging code\&. .IP .IP o \fB\-\-error\-verbose\fP .br When a syntactic error is reported, the generated parse function dumps the parser\(cq\&s state stack to the standard output stream\&. The stack dump shows on separate lines a stack index followed by the state stored at the indicated stack element\&. The first stack element is the stack\(cq\&s top element\&. .IP .IP o \fB\-\-filenames\fP=\fIfilename\fP (\fB\-f\fP) .br \fIFilename\fP is a generic file name that is used for all header files generated by \fBbisonc++\fP\&. Options defining specific file names are also available (which then, in turn, overrule the name specified by this option)\&. .IP .IP o \fB\-\-flex\fP .br \fBBisonc++\fP generates code calling \fId_scanner\&.yylex()\fP to obtain the next lexical token, and calling \fId_scanner\&.YYText()\fP for the matched text, unless overruled by options or directives explicitly defining these functions\&. By default, the interface defined by \fBflexc++\fP(1) is used\&. This option is only interpreted if the \fI\-\-scanner\fP option or \fI%scanner\fP directive is also used\&. .IP .IP o \fB\-\-help\fP (\fB\-h\fP) .br Write basic usage information to the standard output stream and terminate\&. .IP .IP o \fB\-\-implementation\-header\fP=\fIfilename\fP (\fB\-i\fP) .br \fIFilename\fP defines the name of the file to contain the implementation header\&. It defaults to the name of the generated parser class plus the suffix \fI\&.ih\fP\&. .IP The implementation header should contain all directives and declarations \fIonly\fP used by the implementations of the parser\(cq\&s member functions\&. It is the only header file that is included by the source file containing \fIparse\fP\(cq\&s implementation\&. User defined implementation of other class members may use the same convention, thus concentrating all directives and declarations that are required for the compilation of other source files belonging to the parser class in one header file\&. .IP .IP o \fB\-\-implementation\-skeleton\fP=\fIpathname\fP (\fB\-I\fP) .br \fIPathname\fP defines the path name to the file containing the skeleton of the implementation header\&. t defaults to the installation\-defined default path name (e\&.g\&., \fI/usr/share/bisonc++/\fP plus \fIbisonc++\&.ih\fP)\&. .IP .IP o \fB\-\-insert\-stype\fP .br This option is only effective if the \fIdebug\fP option (or \fI%debug\fP directive) has also been specified\&. When \fIinsert\-stype\fP has been specified the parsing function\(cq\&s debug output also shows selected semantic values\&. It should only be used if objects or variables of the semantic value type \fISTYPE__\fP can be inserted into \fIostreams\fP\&. .IP .IP o \fB\-\-max\-inclusion\-depth\fP=\fIvalue\fP .br Set the maximum number of nested grammar files\&. Defaults to 10\&. .IP .IP o \fB\-\-namespace\fP \fIidentifier\fP .br Define all of the code generated by \fBbisonc++\fP in the name space \fIidentifier\fP\&. By default no name space is defined\&. If this options is used the implementation header is provided with a commented out \fIusing namespace\fP declaration for the specified name space\&. In addition, the parser and parser base class header files also use the specified namespace to define their include guard directives\&. .IP It is an error if this option is used and an already existing parser\-class header file and/or implementation header file does not define \fInamespace identifier\fP\&. .IP .IP o \fB\-\-no\-baseclass\-header\fP .br Do not write the file containing the parser class\(cq\& base class, even if that file doesn\(cq\&t yet exist\&. By default the file containing the parser\(cq\&s base class is (re)written each time \fBbisonc++\fP is called\&. Note that this option should normally be avoided, as the base class defines the symbolic terminal tokens that are returned by the lexical scanner\&. By suppressing the construction of this file any modification in these terminal tokens will not be communicated to the lexical scanner\&. .IP .IP o \fB\-\-no\-decoration\fP (\fB\-D\fP) .br Do not include the user\-defined actions when generating the parser\(cq\&s \fIparse\fP member\&. This effectively generates a parser which merely performs semantic checks, without performing the actions which are normally executed when rules have been matched\&. This may be useful in situations where a (partially or completely) decorated grammar is reorganized, and the syntactical correctness of the modified grammar must be verified, or in situations where the grammar has already been decorated, but functions which are called from the rules\(cq\&s actions have not yet been impleemented\&. .IP .IP o \fB\-\-no\-lines\fP .br Do not put \fI#line\fP preprocessor directives in the file containing the parser\(cq\&s \fIparse\fP function\&. By default the file containing the parser\(cq\&s \fIparse\fP function also contains \fI#line\fP preprocessor directives\&. This option allows the compiler and debuggers to associate errors with lines in your grammar specification file, rather than with the source file containing the \fIparse\fP function itself\&. .IP .IP o \fB\-\-no\-parse\-member\fP .br Do not write the file containing the parser\(cq\&s predefined parser member functions, even if that file doesn\(cq\&t yet exist\&. By default the file containing the parser\(cq\&s \fIparse\fP member function is (re)written each time \fBbisonc++\fP is called\&. Note that this option should normally be avoided, as this file contains parsing tables which are altered whenever the grammar definition is modified\&. .IP .IP o \fB\-\-own\-debug\fP .br Extensively displays the actions performed by \fBbisonc++\fP\(cq\&s parser when it processes the grammar specification \fBs\fP\&. This implies the \fI\-\-verbose\fP option\&. .IP .IP o \fB\-\-own\-tokens\fP (\fB\-T\fP) .br The tokens returned as well as the text matched when \fBbisonc++\fP reads its input files(s) are shown when this option is used\&. .IP This option does \fInot\fP result in the generated parsing function displaying returned tokens and matched text\&. If that is what you want, use the \fI\-\-print\-tokens\fP option\&. .IP .IP o \fB\-\-parsefun\-skeleton\fP=\fIpathname\fP (\fB\-P\fP) .br \fIPathname\fP defines the path name of the file containing the parsing member function\(cq\&s skeleton\&. It defaults to the installation\-defined default path name (e\&.g\&., \fI/usr/share/bisonc++/\fP plus \fIbisonc++\&.cc\fP)\&. .IP .IP o \fB\-\-parsefun\-source\fP=\fIfilename\fP (\fB\-p\fP) .br \fIFilename\fP defines the name of the source file to contain the parser member function \fIparse\fP\&. Defaults to \fIparse\&.cc\fP\&. .IP .IP o \fB\-\-polymorphic\-skeleton\fP=\fIpathame\fP (\fB\-M\fP) .br \fIPathname\fP defines the path name of the file containing the skeleton of the polymorphic template classes\&. It defaults to the installation\-defined default path name (e\&.g\&., \fI/usr/share/bisonc++/\fP plus \fIbisonc++polymorphic\fP)\&. .IP .IP o \fB\-\-polymorphic\-inline\-skeleton\fP=\fIpathname\fP (\fB\-m\fP) .br \fIPathname\fP defines the path name of the file containing the skeleton of the inline implementations of the members of the polymorphic template classes\&. It defaults to the installation\-defined default path name (e\&.g\&., \fI/usr/share/bisonc++/\fP plus \fIbisonc++polymorphic\fP)\&. .IP .IP o \fB\-\-print\-tokens\fP (\fB\-t\fP) .br The generated parsing function implements a function \fIprint__\fP displaying (on the standard output stream) the tokens returned by the parser\(cq\&s scanner as well as the corresponding matched text\&. This implementation is suppressed when the parsing function is generated without using this option\&. The member \fIprint__\fP) is called from \fIParser::print\fP, which is defined in\-line in the the parser\(cq\&s class header\&. Calling \fIParser::print__\fP can thus easily be controlled from \fIprint\fP, using, e\&.g\&., a variable that set by the program using the parser generated by \fBbisonc++\fP\&. .IP This option does \fInot\fP show the tokens returned and text matched by \fBbisonc++\fP itself when it is reading its input \fBs\fP\&. If that is what you want, use the \fI\-\-own\-tokens\fP option\&. .IP .IP o \fB\-\-required\-tokens\fP=\fInumber\fP .br Following a syntactic error, require at least \fInumber\fP successfully processed tokens before another syntactic error can be reported\&. By default \fInumber\fP is zero\&. .IP .IP o \fB\-\-scanner\fP=\fIpathname\fP (\fB\-s\fP) .br \fIPathname\fP defines the path name to the file defining the scanner\(cq\&s class interface (e\&.g\&., \fI\(dq\&\&.\&./scanner/scanner\&.h\(dq\&\fP)\&. When this option is used the parser\(cq\&s member \fIint lex()\fP is predefined as .nf int Parser::lex() { return d_scanner\&.lex(); } .fi and an object \fIScanner d_scanner\fP is composed into the parser (but see also option \fIscanner\-class\-name\fP)\&. The example shows the function that\(cq\&s called by default\&. When the \fI\-\-flex\fP option (or \fI%flex\fP directive) is specified the function \fId_scanner\&.yylex()\fP is called\&. Any other function to call can be specified using the \fI\-\-scanner\-token\-function\fP option (or \fI%scanner\-token\-function\fP directive)\&. .IP By default \fBbisonc++\fP surrounds \fIpathname\fP by double quotes (using, e\&.g\&., \fI#include \(dq\&pathname\(dq\&\fP)\&. When \fIpathname\fP is surrounded by pointed brackets \fI#include \fP is included\&. .IP It is an error if this option is used and an already existing parser class header file does not include \fI`pathname\(cq\&\fP\&. .IP .IP o \fB\-\-scanner\-class\-name\fP \fIscannerClassName\fP .br Defines the name of the scanner class, declared by the \fIpathname\fP header file that is specified at the \fIscanner\fP option or directive\&. By default the class name \fIScanner\fP is used\&. .IP It is an error if this option is used and either the \fIscanner\fP option was not provided, or the parser class interface in an already existing parser class header file does not declare a scanner class \fId_scanner\fP object\&. .IP .IP o \fB\-\-scanner\-debug\fP .br Show de scanner\(cq\&s matched rules and returned tokens\&. This offers an extensive display of the rules and tokens matched and returned by \fBbisonc++\fP\(cq\&s scanner, not of just the tokens and matched text received by \fBbisonc++\fP\&. If that is what you want use the \fI\-\-own\-tokens\fP option\&. .IP .IP o \fB\-\-scanner\-matched\-text\-function\fP=\fIfunction\-call\fP .br The scanner function returning the text that was matched at the last call of the scanner\(cq\&s token function\&. A complete function call expression should be provided (including a scanner object, if used)\&. This option overrules the \fId_scanner\&.matched()\fP call used by default when the \fI%scanner\fP directive is specified, and it overrules the \fId_scanner\&.YYText()\fP call used when the \fI%flex\fP directive is provided\&. Example: .nf \-\-scanner\-matched\-text\-function \(dq\&myScanner\&.matchedText()\(dq\& .fi .IP .IP o \fB\-\-scanner\-token\-function\fP=\fIfunction\-call\fP .br The scanner function returning the next token, called from the parser\(cq\&s \fIlex\fP function\&. A complete function call expression should be provided (including a scanner object, if used)\&. This option overrules the \fId_scanner\&.lex()\fP call used by default when the \fI%scanner\fP directive is specified, and it overrules the \fId_scanner\&.yylex()\fP call used when the \fI%flex\fP directive is provided\&. Example: .nf \-\-scanner\-token\-function \(dq\&myScanner\&.nextToken()\(dq\& .fi .IP It is an error if this option is used and the scanner token function is not called from the code in an already existing implementation header\&. .IP .IP o \fB\-\-show\-filenames\fP .br Writes the names of the generated files to the standard error stream\&. .IP .IP o \fB\-\-skeleton\-directory\fP=\fIdirectory\fP (\fB\-S\fP) .br Specifies the directory containing the skeleton files\&. This option can be overridden by the specific skeleton\-specifying options (\fI\-B \-C, \-H, \-I, \-M\fP and \fI\-m\fP)\&. .IP .IP o \fB\-\-target\-directory\fP=\fIpathname\fP .br \fIPathname\fP defines the directory where generated files should be written\&. By default this is the directory where \fBbisonc++\fP is called\&. .IP .IP o \fB\-\-thread\-safe\fP .br No static data are modified, making \fBbisonc++\fP thread\-safe\&. .IP .IP o \fB\-\-usage\fP .br Write basic usage information to the standard output stream and terminate\&. .IP .IP o \fB\-\-verbose\fP (\fB\-V\fP) .br Write a file containing verbose descriptions of the parser states and what is done for each type of look\-ahead token in that state\&. This file also describes all conflicts detected in the grammar, both those resolved by operator precedence and those that remain unresolved\&. It is not created by default, but if requested the information is written on \fI\&.output\fP, where \fI\fP is the grammar specification file passed to \fBbisonc++\fP\&. .IP .IP o \fB\-\-version\fP (\fB\-v\fP) .br Display \fBbisonc++\fP\(cq\&s version number and terminate\&. .IP .SH "4\&. DIRECTIVES" .PP The following directives can be specified in the initial section of the grammar specification file\&. When command\-line options for directives exist, they overrule the corresponding directives given in the grammar specification file\&. Directives affecting the class header or implementation header file are ignored if these files already exist\&. .PP Directives accepting a `filename\(cq\& do not accept path names, i\&.e\&., they cannot contain directory separators (\fI/\fP); directives accepting a \(cq\&pathname\(cq\& may contain directory separators\&. A \(cq\&pathname\(cq\& using blank characters should be surrounded by double quotes\&. .PP Some directives may generate errors\&. This happens when a directive conflicts with the contents of a file which \fBbisonc++\fP cannot modify (e\&.g\&., a parser class header file exists, but doesn\(cq\&t define a name space, but a \fI%namespace\fP directive was provided)\&. .PP To solve such errore the offending directive could be omitted, the existing file could be removed, or the existing file could be hand\-edited according to the directive\(cq\&s specification\&. .PP .IP o \fB%baseclass\-header\fP \fIfilename\fP .br \fIFilename\fP defines the name of the file to contain the parser\(cq\&s base class\&. This class defines, e\&.g\&., the parser\(cq\&s symbolic tokens\&. Defaults to the name of the parser class plus the suffix \fIbase\&.h\fP\&. This directive is overruled by the \fB\-\-baseclass\-header\fP (\fB\-b\fP) command\-line option\&. .IP It is an error if this directive is used and an already existing parser class header file does not contain \fI#include \(dq\&filename\(dq\&\fP\&. .IP o \fB%baseclass\-preinclude\fP \fIpathname\fP .br \fIPathname\fP defines the path to the file preincluded by the parser\(cq\&s base\-class header\&. See the description of the \fI\-\-baseclass\-preinclude\fP option for details about this directive\&. By default, \fBbisonc++\fP surrounds \fIheader\fP by double quotes\&. However, when \fIheader\fP itself is surrounded by pointed brackets \fI#include
\fP is included\&. .IP o \fB%class\-header\fP \fIfilename\fP .br \fIFilename\fP defines the name of the file to contain the parser class\&. Defaults to the name of the parser class plus the suffix \fI\&.h\fP This directive is overruled by the \fB\-\-class\-header\fP (\fB\-c\fP) command\-line option\&. .IP It is an error if this directive is used and an already existing implementation header file does not contain \fI#include \(dq\&filename\(dq\&\fP\&. .IP o \fB%class\-name\fP \fIparser\-class\-name\fP .br Declares the name of the parser class\&. It defines the name of the \fBC++\fP class that is generated\&. If no \fI%class\-name\fP is specified the default class name \fIParser\fP is used\&. .IP It is an error if this directive is used and an already existing parser\-class header file does not define \fIclass `className\(cq\&\fP and/or if an already existing implementation header file does not define members of the class \fI`className\(cq\&\fP\&. .IP o \fB%debug\fP .br Provide \fIparse\fP and its support functions with debugging code, showing the actual parsing process on the standard output stream\&. When included, the debugging output is active by default, but its activity may be controlled using the \fIsetDebug(bool on\-off)\fP member\&. No \fI#ifdef DEBUG\fP macros are used anymore\&. To remove existing debugging code re\-run \fBbisonc++\fP without the \fI\-\-debug\fP option or \fI%debug\fP declaration\&. .IP o \fB%error\-verbose\fP .br This directive can be specified to dump the parser\(cq\&s state stack to the standard output stream when the parser encounters a syntactic error\&. The stack dump shows on separate lines a stack index followed by the state stored at the indicated stack element\&. The first stack element is the stack\(cq\&s top element\&. .IP o \fB%expect\fP \fInumber\fP .br This directive specifies the exact number of shift/reduce and reduce/reduce conflicts for which no warnings are to be generated\&. Details of the conflicts are reported in the verbose output file (e\&.g\&., \fIgrammar\&.output\fP)\&. If the number of actually encountered conflicts deviates from `\fInumber\fP\(cq\&, then this directive is ignored\&. .IP o \fB%filenames\fP \fIfilename\fP .br \fIFilename\fP is a generic filename that is used for all header files generated by \fBbisonc++\fP\&. Options defining specific filenames are also available (which then, in turn, overrule the name specified by this directive)\&. This directive is overruled by the \fB\-\-filenames\fP (\fB\-f\fP) command\-line option\&. .IP o \fB%flex\fP .br When provided, the scanner member returning the matched text is called as \fId_scanner\&.YYText()\fP, and the scanner member returning the next lexical token is called as \fId_scanner\&.yylex()\fP\&. This directive is only interpreted if the \fI%scanner\fP directive is also provided\&. .IP o \fB%implementation\-header\fP \fIfilename\fP .br \fIFilename\fP defines the name of the file to contain the implementation header\&. It defaults to the name of the generated parser class plus the suffix \fI\&.ih\fP\&. .br The implementation header should contain all directives and declarations that are \fIonly\fP used by the parser\(cq\&s member functions\&. It is the only header file that is included by the source file containing \fIparse\fP\(cq\&s implementation\&. User defined implementation of other class members may use the same convention, thus concentrating all directives and declarations that are required for the compilation of other source files belonging to the parser class in one header file\&. .br This directive is overruled by the \fB\-\-implementation\-header\fP (\fB\-i\fP) command\-line option\&. .IP o \fB%include\fP \fIpathname\fP .br This directive is used to switch to \fIpathname\fP while processing a grammar specification\&. Unless \fIpathname\fP defines an absolute file\-path, \fIpathname\fP is searched relative to the location of \fBbisonc++\fP\(cq\&s main grammar specification file (i\&.e\&., the grammar file that was specified as \fBbisonc++\fP\(cq\&s command\-line option)\&. This directive can be used to split long grammar specification files in shorter, meaningful units\&. After processing \fIpathname\fP processing continues beyond the \fI%include pathname\fP directive\&. .IP o \fB%left\fP \fIterminal \&.\&.\&.\fP .br Defines the names of symbolic terminal tokens that must be treated as left\-associative\&. I\&.e\&., in case of a shift/reduce conflict, a reduction is preferred over a shift\&. Sequences of \fI%left, %nonassoc, %right\fP and \fI%token\fP directives may be used to define the precedence of operators\&. In expressions, the first used directive defines the tokens having the lowest precedence, the last used defines the tokens having the highest priority\&. See also \fI%token\fP below\&. .IP o \fB%locationstruct\fP \fIstruct\-definition\fP .br Defines the organization of the location\-struct data type \fILTYPE__\fP\&. This struct should be specified analogously to the way the parser\(cq\&s stacktype is defined using \fI%union\fP (see below)\&. The location struct is named \fILTYPE__\fP\&. By default (if neither \fIlocationstruct\fP nor \fILTYPE__\fP is specified) the standard location struct (see the next directive) is used: .IP o \fB%lsp\-needed\fP .br This directive results in \fBbisonc++\fP generating a parser using the standard location stack\&. This stack\(cq\&s default type is: .nf struct LTYPE__ { int timestamp; int first_line; int first_column; int last_line; int last_column; char *text; }; .fi \fBBisonc++\fP does \fInot\fP provide the elements of the \fILTYPE__\fP struct with values\&. Action blocks of production rules may refer to the location stack element associated with a production element using \fI@\fP variables, like \fI@1\&.timestamp, @3\&.text, @5\fP\&. The rule\(cq\&s location struct itself may be referred to as either \fId_loc__\fP or \fI@@\fP\&. .IP o \fB%ltype typename\fP .br Specifies a user\-defined token location type\&. If \fI%ltype\fP is used, \fItypename\fP should be the name of an alternate (predefined) type (e\&.g\&., \fIsize_t\fP)\&. It should not be used if a \fI%locationstruct\fP specification is defined (see below)\&. Within the parser class, this type is available as the type `\fILTYPE__\fP\(cq\&\&. All text on the line following \fI%ltype\fP is used for the \fItypename\fP specification\&. It should therefore not contain comment or any other characters that are not part of the actual type definition\&. .IP o \fB%namespace\fP \fInamespace\fP .br Define all of the code generated by \fBbisonc++\fP in the name space \fInamespace\fP\&. By default no name space is defined\&. If this directive is used the implementation header is provided with a commented out \fIusing namespace\fP declaration for the specified name space\&. In addition, the parser and parser base class header files also use the specified namespace to define their include guard directives\&. .IP It is an error if this directive is used and an already existing parser\-class header file and/or implementation header file does not define \fInamespace identifier\fP\&. .IP o \fB%negative\-dollar\-indices\fP .br Do not generate warnings when zero\- or negative dollar\-indices are used in the grammar\(cq\&s action blocks\&. Zero or negative dollar\-indices are commonly used to implement inherited attributes, and should normally be avoided\&. When used, they can be specified like \fI$\-1\fP, or like \fI$\-1\fP, where \fItype\fP is empty; an \fISTYPE__\fP tag; or a field\-name\&. However, note that in combination with the \fI%polymorphic\fP directive (see below) only the \fI$\-i\fP format can be used\&. .IP o \fB%no\-lines\fP .br By default \fI#line\fP preprocessor directives are inserted just before action statements in the file containing the parser\(cq\&s \fIparse\fP function\&. These directives are suppressed by the \fI%no\-lines\fP directive\&. .IP o \fB%nonassoc\fP \fIterminal \&.\&.\&.\fP .br Defines the names of symbolic terminal tokens that should be treated as non\-associative\&. I\&.e\&., in case of a shift/reduce conflict, a reduction is preferred over a shift\&. Sequences of \fI%left, %nonassoc, %right\fP and \fI%token\fP directives may be used to define the precedence of operators\&. In expressions, the first used directive defines the tokens having the lowest precedence, the last used defines the tokens having the highest priority\&. See also \fI%token\fP below\&. .IP o \fB%parsefun\-source\fP \fIfilename\fP .br \fIFilename\fP defines the name of the file to contain the parser member function \fIparse\fP\&. Defaults to \fIparse\&.cc\fP\&. This directive is overruled by the \fB\-\-parse\-source\fP (\fB\-p\fP) command\-line option\&. .IP o \fB%polymorphic\fP \fIpolymorphic\-specification(s)\fP .br Bison\(cq\&s traditional way of handling multiple semantic values is to use a \fI%union\fP specification (see below)\&. Although \fI%union\fP is supported by \fBbisonc++\fP, a polymorphic semantic value class is preferred due to its improved type safety\&. .IP The \fI%polymorphic\fP directive defines a polymorphic semantic value class and can be used instead of a \fI%union\fP specification\&. Refer to section \fBPOLYMORPHIC SEMANTIC VALUES\fP below or to \fBbisonc++\fP\(cq\&s user manual for a detailed description of the specification, characteristics, and use of polymorphic semantic values\&. .IP o \fB%prec\fP \fItoken\fP .br Overrules the defined precendence of an operator for a particular grammatical rule\&. A well known application of \fI%prec\fP is: .nf expression: \(cq\&\-\(cq\& expression %prec UMINUS { \&.\&.\&. } .fi Here, the default priority and precedence of the `\fI\-\fP\(cq\& token as the subtraction operator is overruled by the precedence and priority of the \fIUMINUS\fP token, which is commonly defined as .nf %right UMINUS .fi (see below) following, e\&.g\&., the \fI\(cq\&*\(cq\&\fP and \fI\(cq\&/\(cq\&\fP operators\&. .IP o \fB%print\-tokens\fP .br The \fIprint\fP directive provides an implementation of the Parser class\(cq\&s \fIprint__\fP function displaying the current token value and the text matched by the lexical scanner as received by the generated \fIparse\fP function\&. .IP o \fB%required\-tokens\fP \fInumber\fP .br Following a syntactic error, require at least \fInumber\fP successfully processed tokens before another syntactic error can be reported\&. By default \fInumber\fP is zero\&. .IP o \fB%right\fP \fIterminal \&.\&.\&.\fP .br Defines the names of symbolic terminal tokens that should be treated as right\-associative\&. I\&.e\&., in case of a shift/reduce conflict, a shift is preferred over a reduction\&. Sequences of \fI%left, %nonassoc, %right\fP and \fI%token\fP directives may be used to define the precedence of operators\&. In expressions, the first used directive defines the tokens having the lowest precedence, the last used defines the tokens having the highest priority\&. See also \fI%token\fP below\&. .IP o \fB%scanner\fP \fIpathname\fP .br Use \fIpathname\fP as the path name to the file pre\-included in the parser\(cq\&s class header\&. See the description of the \fI\-\-scanner\fP option for details about this directive\&. Similar to the convention adopted for this argument, \fIpathname\fP by default is surrounded by double quotes\&. However, when the argument is surrounded by pointed brackets \fI#include \fP is included\&. This directive results in the definition of a composed \fIScanner d_scanner\fP data member into the generated parser, and in the definition of a \fIint lex()\fP member, returning \fId_scanner\&.lex()\fP\&. .IP By specifying the \fI%flex\fP directive the function \fId_scanner\&.yylex()\fP is called\&. Any other function to call can be specified using the \fI\-\-scanner\-token\-function\fP option (or \fI%scanner\-token\-function\fP directive)\&. .IP It is an error if this directive is used and an already existing parser class header file does not include \fI`pathname\(cq\&\fP\&. .IP o \fB%scanner\-class\-name\fP \fIscannerClassName\fP .br Defines the name of the scanner class, declared by the \fIpathname\fP header file that is specified at the \fIscanner\fP option or directive\&. By default the class name \fIScanner\fP is used\&. .IP It is an error if this directive is used and either the \fIscanner\fP directive was not provided, or the parser class interface in an already existing parser class header file does not declare a scanner class \fId_scanner\fP object\&. .IP o \fB%scanner\-matched\-text\-function\fP \fIfunction\-call\fP .br The scanner function returning the text that was matched by the lexical scanner after its token function (see below) has returned\&. A complete function call expression should be provided (including a scanner object, if used)\&. Example: .nf %scanner\-matched\-text\-function myScanner\&.matchedText() .fi By specifying the \fI%flex\fP directive the function \fId_scanner\&.YYText()\fP is called\&. .IP If the function call contains white space \fIscanner\-token\-function\fP should be surrounded by double quotes\&. .IP o \fB%scanner\-token\-function\fP \fIfunction\-call\fP .br The scanner function returning the next token, called from the generated parser\(cq\&s \fIlex\fP function\&. A complete function call expression should be provided (including a scanner object, if used)\&. Example: .nf %scanner\-token\-function d_scanner\&.lex() .fi If the function call contains white space \fIscanner\-token\-function\fP should be surrounded by double quotes\&. .IP It is an error if this directive is used and the scanner token function is not called from the code in an already existing implementation header\&. .IP o \fB%start\fP \fInon\-terminal\fP .br The non\-terminal \fInon\-terminal\fP should be used as the grammar\(cq\&s start\-symbol\&. If omitted, the first grammatical rule is used as the grammar\(cq\&s starting rule\&. All syntactically correct sentences must be derivable from this starting rule\&. .IP o \fB%stype typename\fP .br The type of the semantic value of non\-terminal tokens\&. By default it is \fIint\fP\&. \fI%stype, %union,\fP and \fI%polymorphic\fP are mutually exclusive directives\&. .IP Within the parser class, the semantic value type is available as the type `\fISTYPE__\fP\(cq\&\&. All text on the line following \fI%stype\fP is used for the \fItypename\fP specification\&. It should therefore not contain comment or any other characters that are not part of the actual type definition\&. .IP o \fB%target\-directory pathname\fP .br \fIPathname\fP defines the directory where generated files should be written\&. By default this is the directory where \fBbisonc++\fP is called\&. This directive is overruled by the \fI\-\-target\-directory\fP command\-line option\&. .IP o \fB%token\fP \fIterminal \&.\&.\&.\fP .br Defines the names of symbolic terminal tokens\&. Sequences of \fI%left, %nonassoc, %right\fP and \fI%token\fP directives may be used to define the precedence of operators\&. In expressions, the first used directive defines the tokens having the lowest precedence, the last used defines the tokens having the highest priority\&. See also \fI%token\fP below\&. .br \fBNOTE:\fP Symbolic tokens are defined as \fIenum\fP\-values in the parser\(cq\&s base class\&. The names of symbolic tokens may not be equal to the names of the members and types defined by \fBbisonc++\fP itself (see the next sections)\&. This requirement is \fInot\fP enforced by \fBbisonc++\fP, but compilation errors may result if this requirement is violated\&. .IP o \fB%type\fP \fI non\-terminal \&.\&.\&.\fP .br In combination with \fI%polymorphic\fP or \fI%union\fP: associate the semantic value of a non\-terminal symbol with a polymorphic semantic value tag or union field defined by these directives\&. .IP o \fB%union\fP \fIunion\-definition\fP .br Acts identically to the identically named \fBbison\fP and \fBbison++\fP declaration\&. \fBBisonc++\fP generates a union, named \fISTYPE__\fP, as its semantic type\&. .IP o \fB%weak\-tags\fP .br This directive is ignored unless the \fI%polymorphic\fP directive was specified\&. It results in the declaration of \fIenum Tag__\fP rather than \fIenum class Tag__\fP\&. When in doubt, don\(cq\&t use this directive\&. .PP .SH "5\&. POLYMORPHIC SEMANTIC VALUES" .PP The \fI%polymorphic\fP directive results in \fBbisonc++\fP generating a parser using polymorphic semantic values\&. The various semantic values are specified as pairs, consisting of \fItags\fP (which are \fBC++\fP identifiers), and \fBC++\fP type names\&. Tags and type names are separated from each other by colons\&. Multiple tag and type name combinations are separated from each other by semicolons, and an optional semicolon ends the final tag/type specification\&. .PP Here is an example, defining three semantic values: an \fIint\fP, a \fIstd::string\fP and a \fIstd::vector\fP: .nf %polymorphic INT: int; STRING: std::string; VECT: std::vector .fi The identifier to the left of the colon is called the \fItag\-identifier\fP (or simply \fItag\fP), and the type name to the right of the colon is called the \fItype\-name\fP\&. The type\-names must be built\-in types or must offer default constructors\&. .PP If type\-names refer to types declared in header files that were not already included by the parser\(cq\&s base class header, then these header files must be inserted using the \fI%baseclass\-preinclude\fP directive\&. .PP The \fI%type\fP directive is used to associate (non\-)terminals with semantic value types\&. .PP Semantic values may also be associated with terminal tokens\&. In that case it is the lexical scanner\(cq\&s responsibility to assign a properly typed value to the parser\(cq\&s \fISTYPE__ d_val__\fP data member\&. .PP Non\-terminals may automatically be associated with polymorphic semantic values using \fI%type\fP directives\&. E\&.g\&., after: .nf %polymorphic INT: int; TEXT: std::string %type expr .fi the \fIexpr\fP non\-terminal returns \fIint\fP semantic values\&. In this case, a rule like: .nf expr: expr \(cq\&+\(cq\& expr { $$ = $1 + $3; } .fi automatically associates $$, $1 and $3 with \fIint\fP values\&. $$ is an lvalue (representing the semantic value associated with the \fIexpr:\fP rule), while $1 and $3 represent the \fIint\fP semantic value associated with the \fIexpr\fP non\-terminal in the production rule \fI\(cq\&\-\(cq\& expr\fP (rvalues)\&. .PP 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\(cq\&s return value \fI$$\fP, however, semantic value types can explicitly be specified using the common `$$\(cq\& or `$1\(cq\& syntax\&. (In this and following examples index number 1 represents any valid positive index; \-1 represents any valid negative index)\&. .PP The type\-overruling syntax does not allow blanks to be used (so $$ is OK, $< INT >$ isn\(cq\&t)\&. .PP Various combinations of type\-associations and type specifications may be encountered: .IP o $\-1: \fI%type\fP associations are ignored, and the semantic value type \fISTYPE__\fP is used instead\&. A warning is issued unless the \fI%negative\-dollar\-indices\fP directive was specified\&. .IP o $\-1: \fIerror\fP: \fI\fP specifications are not allowed for negative dollar indices\&. .PP \fB%type and $$ or $1 specifications:\fP .TS tab(~); ----- lssss ----- cccll ----- cccll cs-ss cccll cs-ss cccll cs-ss cccll ----- cccll cs-ss cccll cs-ss cccll cs-ss cccll ----- cccll cs-ss cccll cs-ss cccll cs-ss cccll ----- cccll cs-ss cccll cs-ss cccll cs-ss cccll ----- c. $$ or $1 specifications %type~~$~~action: absent~~no ~~STYPE__ is used ~~$~~tag\-override ~~$<>~~STYPE__ is used ~~$~~STYPE__ is used STYPE__~~no ~~STYPE__ is used ~~$~~tag\-override ~~$<>~~STYPE__ is used ~~$~~STYPE__ is used (existing) tag~~no ~~auto\-tag ~~$~~tag\-override ~~$<>~~STYPE__ is used ~~$~~STYPE__ is used (undefined) tag~~no ~~tag\-error ~~$~~tag\-override ~~$<>~~STYPE__ is used ~~$~~STYPE__ is used .TE .PP auto\-tag: $$ and $1 represent, respectively, \fI$$\&.get()\fP and \fI$1\&.get()\fP; .PP tag\-error: \fIerror:\fP tag undefined; .PP tag\-override: if \fIid\fP is a defined tag, then $$ and $1 represent the tag\(cq\&s type\&. Otherwise: \fIerror\fP (using undefined tag \fIid\fP)\&. .PP \fBMember calls\fP (`$$\&.\(cq\&, `$1\&.\(cq\&, etc\&.): .PP When using `$$\&.\(cq\& or `$1\&.\(cq\& default tags are ignored\&. A warning is issued that the default tag is ignored\&. This syntax allows members of the semantic value type (\fISTYPE__\fP) 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 ($1)\&.member())\&. The opposite, overriding default tag associations, is accomplished using constructions like $$ and $1\&. .PP 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: .nf %polymorphic INT: int %type ident %% type: ident arg ; arg: { call($\-1\->get()); } ; .fi In this example \fIcall\fP may define an \fIint\fP or \fIint &\fP parameter\&. .PP It is also possible to delegate specification of the semantic value to the function \fIcall\fP itself, as shown next: .nf %polymorphic INT: int %type ident %% type: ident arg ; arg: { call($\-1); } ; .fi Here, the function \fIcall\fP could be implemented like this: .nf void call(STYPE__ &st) { st\->get() = 5; } .fi .PP The \fI%polymorphic\fP directive adds the following definitions and declarations to the generated base class header and parser source file (if the \fI%namespace\fP directive was used then all declared/defined elements are placed inside the name space that is specified by the \fI%namespace\fP directive): .IP o An additional header is included in the parser\(cq\&s base class header: .nf #include .fi .IP o All semantic value type identifiers are collected in a strongly typed `\fITag__\fP\(cq\& enumeration\&. E\&.g\&., .nf enum class Tag__ { INT, STRING, VECT }; .fi .IP o The name space \fIMeta__\fP contains almost all of the code implementing polymorphic values\&. .PP The name space \fIMeta__\fP contains the following elements: .IP o A polymorphic base class \fIBase\fP\&. This class is normally not explicitly referred to by user\-defined code\&. Refer to by \fBbisonc++\fP\(cq\&s user manual for a detailed description of this class\&. .IP .IP o For each of the tag\-identifiers specified with the \fI%polymorphic\fP directive a class template \fISemantic\fP is defined, containing a data element of the type\-name matching the \fITag__\fP for which \fISemantic\fP was derived\&. .IP The \fISemantic\fP classes are normally not explicitly referred to by user\-defined code\&. Refer to by \fBbisonc++\fP\(cq\&s user manual for a detailed description of these classes\&. .IP .IP o A class \fISType\fP, derived from \fIstd::shared_ptr\fP\&. This class becomes the parser\(cq\&s semantic value type, offering the following members: .br .IP \fIConstructors:\fP default, copy and move constructors; .br .IP \fIAssignment operators:\fP copy and move assignment operators declaring \fISType\fP or any of the \fI%polymorphic\fP type\-names as their right\-hand side operands; .br .IP \fITag__ tag() const\fP, returning \fISemantic\fP\(cq\&s \fITag__\fP value; .br .IP \fIDataType &get()\fP returns a reference to the semantic value stored inside \fISemantic\fP\&. .IP This member checks for 0\-pointers and for \fITag__\fP mismatches between the requested and actual \fITag__\fP, in that case replacing the current \fISemantic\fP object pointed to by a new \fISemantic\fP object of the requested \fITag__\fP\&. .IP \fIDataType &data()\fP returns a reference to the semantic value stored inside \fISemantic\fP\&. .IP This is a (partially) \fIunchecking\fP variant of the corresponing \fIget\fP member, resulting in a \fISegfault\fP if used when the \fIshared_ptr\fP holds a 0\-pointer, compilation may fail in case of a mismatch between the requested and actual \fITag__\fP\&. .PP Since \fBbisonc++\fP declares \fItypedef Meta__::SType STYPE__\fP, polymorphic semantic values can be used without referring to the name space \fIMeta__\fP\&. .PP .SH "6\&. PUBLIC MEMBERS AND \-TYPES" .PP The following public members and types are available to users of the parser classes generated by \fBbisonc++\fP (parser class\-name prefixes (e\&.g\&., \fIParser::\fP) prefixes are silently implied): .IP o \fBLTYPE__\fP: .br The parser\(cq\&s location type (user\-definable)\&. Available only when either \fI%lsp\-needed, %ltype\fP or \fI%locationstruct\fP has been declared\&. .IP o \fBSTYPE__\fP: .br The parser\(cq\&s stack\-type (user\-definable), defaults to \fBint\fP\&. .IP o \fBTokens__\fP: .br The enumeration type of all the symbolic tokens defined in the grammar file (i\&.e\&., \fBbisonc++\fP\(cq\&s input file)\&. The scanner should be prepared to return these symbolic tokens\&. Note that, since the symbolic tokens are defined in the parser\(cq\&s class and not in the scanner\(cq\&s class, the lexical scanner must prefix the parser\(cq\&s class name to the symbolic token names when they are returned\&. E\&.g\&., \fIreturn Parser::IDENT\fP should be used rather than \fIreturn IDENT\fP\&. .IP o \fBint parse()\fP: .br The parser\(cq\&s parsing member function\&. It returns 0 when parsing was successfully completed; 1 if errors were encountered while parsing the input\&. .IP o \fBvoid setDebug(bool mode)\fP: .br This member can be used to activate or deactivate the debug\-code compiled into the parsing function\&. It is always defined but is only operational if the \fI%debug\fP directive or \fI\-\-debug\fP option was specified\&. When debugging code has been compiled into the parsing function, it is \fInot\fP active by default\&. To activate the debugging code, use \fIsetDebug(true)\fP\&. .IP This member can be used to activate or deactivate the debug\-code compiled into the parsing function\&. It is available but has no effect if no debug code has been compiled into the parsing function\&. When debugging code has been compiled into the parsing function, it is active by default, but debug\-code is suppressed by calling \fIsetDebug(false)\fP\&. .PP When the \fI%polymorphic\fP directive is used: .IP o \fBMeta__\fP: .br Templates and classes that are required for implementing the polymorphic semantic values are all declared in the \fIMeta__\fP namespace\&. The \fIMeta__\fP namespace itself is nested under the namespace that may have been declared by the \fI%namespace\fP directive\&. .IP .IP o \fBTag__\fP: .br The (strongly typed) \fIenum class Tag__\fP contains all the tag\-identifiers specified by the \fI%polymorphic\fP directive\&. It is declared outside of the Parser\(cq\&s class, but within the namespace that may have been declared by the \fI%namespace\fP directive\&. .PP .SH "7\&. PRIVATE ENUMS AND \-TYPES" .PP The following enumerations and types can be used by members of parser classes generated by \fBbisonc++\fP\&. They are actually protected members inherited from the parser\(cq\&s base class\&. .IP o \fBBase::ErrorRecovery__\fP: .br This enumeration defines two values: .nf DEFAULT_RECOVERY_MODE__, UNEXPECTED_TOKEN__ .fi The \fIDEFAULT_RECOVERY_MODE__\fP terminates the parsing process\&. The non\-default recovery procedure is available once an \fIerror\fP token is used in a production rule\&. When the parsing process throws \fIUNEXPECTED_TOKEN__\fP the recovery procedure is started (i\&.e\&., it is started whenever a syntactic error is encountered or \fIERROR\fP\fI()\fP is called)\&. .IP The recovery procedure consists of (1) looking for the first state on the state\-stack having an error\-production, followed by (2) handling all state transitions that are possible without retrieving a terminal token\&. Then, in the state requiring a terminal token and starting with the initial unexpected token (3) all subsequent terminal tokens are ignored until a token is retrieved which is a continuation token in that state\&. .IP If the error recovery procedure fails (i\&.e\&., if no acceptable token is ever encountered) error recovery falls back to the default recovery mode (i\&.e\&., the parsing process is terminated)\&. .IP .IP o \fBBase::Return__\fP: .br This enumeration defines two values: .nf PARSE_ACCEPT = 0, PARSE_ABORT = 1 .fi (which are of course the \fIparse\fP function\(cq\&s return values)\&. .PP .SH "8\&. PRIVATE MEMBER FUNCTIONS" .PP The following members can be used by members of parser classes generated by \fBbisonc++\fP\&. When prefixed by \fIBase::\fP they are actually protected members inherited from the parser\(cq\&s base class\&. Members for which the phrase ``Used internally\(cq\&\(cq\& is used should not be called by user\-defined code\&. .IP o \fBBase::ParserBase()\fP: .br Used internally\&. .IP o \fBvoid Base::ABORT() const throw(Return__)\fP: .br This member can be called from any member function (called from any of the parser\(cq\&s action blocks) to indicate a failure while parsing thus terminating the parsing function with an error value 1\&. Note that this offers a marked extension and improvement of the macro \fIYYABORT\fP defined by \fBbison++\fP in that \fIYYABORT\fP could not be called from outside of the parsing member function\&. .IP o \fBvoid Base::ACCEPT() const throw(Return__)\fP: .br This member can be called from any member function (called from any of the parser\(cq\&s action blocks) to indicate successful parsing and thus terminating the parsing function\&. Note that this offers a marked extension and improvement of the macro \fIYYACCEPT\fP defined by \fBbison++\fP in that \fIYYACCEPT\fP could not be called from outside of the parsing member function\&. .IP o \fBvoid Base::clearin()\fP: .br This member replaces \fBbison\fP(++)\(cq\&s macro \fIyyclearin\fP and causes \fBbisonc++\fP to request another token from its \fIlex()\fP member, even if the current token has not yet been processed\&. It is a useful member when the parser should be reset to its initial state, e\&.g\&., between successive calls of \fIparse\fP\&. In this situation the scanner will probably be reloaded with new information too\&. .IP o \fBbool Base::debug() const\fP: .br This member returns the current value of the debug variable\&. .IP o \fBvoid Base::ERROR() const throw(ErrorRecovery__)\fP: .br This member can be called from any member function (called from any of the parser\(cq\&s action blocks) to generate an error, and results in the parser executing its error recovery code\&. Note that this offers a marked extension and improvement of the macro \fIYYERROR\fP defined by \fBbison++\fP in that \fIYYERROR\fP could not be called from outside of the parsing member function\&. .IP o \fBvoid error(char const *msg)\fP: .br By default implemented inline in the \fIparser\&.ih\fP internal header file, it writes a simple message to the standard error stream\&. It is called when a syntactic error is encountered, and its default implementation may safely be altered\&. .IP o \fBvoid errorRecovery__()\fP: .br Used internally\&. .IP o \fBvoid Base::errorVerbose__()\fP: .br Used internally\&. .IP o \fBvoid exceptionHandler__(std::exception const &exc)\fP: .br This member\(cq\&s default implementation is provided inline in the \fIparser\&.ih\fP internal header file\&. It consists of a mere \fIthrow\fP statement, rethrowing a caught exception\&. .IP The \fIparse\fP member function\(cq\&s body essentially consists of a \fIwhile\fP statement, in which the next token is obtained via the parser\(cq\&s \fIlex\fP member\&. This token is then processed according to the current state of the parsing process\&. This may result in executing actions over which the parsing process has no control and which may result in exceptions being thrown\&. .IP Such exceptions do not necessarily have to terminate the parsing process: they could be thrown by code, linked to the parser, that simply checks for semantic errors (like divisions by zero) throwing exceptions if such errors are observed\&. .IP The member \fIexceptionHandler__\fP receives and may handle such exceptions without necessarily ending the parsing process\&. It receives any \fIstd::exception\fP thrown by the parser\(cq\&s actions, as though the action block itself was surrounded by a \fItry \&.\&.\&. catch\fP statement\&. It is of course still possible to use an explicit \fItry \&.\&.\&. catch\fP statement within action blocks\&. However, \fIexceptionHandler__\fP can be used to factor out code that is common to various action blocks\&. .IP The next example shows an explicit implementation of \fIexceptionHandler__\fP: any \fIstd::exception\fP thrown by the parser\(cq\&s action blocks is caught, showing the exception\(cq\&s message, and increasing the parser\(cq\&s error count\&. After this parsing continues as if no exception had been thrown: .nf void Parser::exceptionHandler__(std::exception const &exc) { std::cout << exc\&.what() << \(cq\&\en\(cq\&; ++d_nErrors__; } .fi .IP \fBNote:\fP Parser\-class header files (e\&.g\&., Parser\&.h) and parser\-class internal header files (e\&.g\&., Parser\&.ih) generated with \fBbisonc++\fP < 4\&.02\&.00 require two hand\-modifications when using \fBbisonc++\fP >= 4\&.02\&.00: .IP In Parser\&.h, just below the declaration .nf void print__(); .fi add: .nf void exceptionHandler__(std::exception const &exc); .fi .IP In Parser\&.ih, assuming the name of the generated class is `Parser\(cq\&, add the following member definition (if a namespace is used: within the namespace\(cq\&s scope): .nf inline void Parser::exceptionHandler__(std::exception const &exc) { throw; // re\-implement to handle exceptions thrown by actions } .fi .IP o \fBvoid executeAction(int)\fP: .br Used internally\&. .IP o \fBint lex()\fP: .br By default implemented inline in the \fIparser\&.ih\fP internal header file, it can be pre\-implemented by \fBbisonc++\fP using the \fIscanner\fP option or directive (see above); alternatively it \fImust\fP be implemented by the programmer\&. It interfaces to the lexical scanner, and should return the next token produced by the lexical scanner, either as a plain character or as one of the symbolic tokens defined in the \fIParser::Tokens__\fP enumeration\&. Zero or negative token values are interpreted as `end of input\(cq\&\&. .IP o \fBint lookup(bool)\fP: .br Used internally\&. .IP o \fBvoid nextToken()\fP: .br Used internally\&. .IP o \fBvoid Base::pop__()\fP: .br Used internally\&. .IP o \fBvoid Base::popToken__()\fP: .br Used internally\&. .IP o \fBvoid print__()()\fP: .br Used internally\&. .IP o \fBvoid print()\fP: .br By default implemented inline in the \fIparser\&.ih\fP internal header file, this member calls \fIprint__\fP to display the last received token and corrseponding matched text\&. The \fIprint__\fP member is only implemented if the \fI\-\-print\-tokens\fP option or \fI%print\-tokens\fP directive was used when the parsing function was generated\&. Calling \fIprint__\fP from \fIprint\fP is unconditional, but can easily be controlled by the using program, by defining, e\&.g\&., a command\-line option\&. .IP o \fBvoid Base::push__()\fP: .br Used internally\&. .IP o \fBvoid Base::pushToken__()\fP: .br Used internally\&. .IP o \fBvoid Base::reduce__()\fP: .br Used internally\&. .IP o \fBvoid Base::symbol__()\fP: .br Used internally\&. .IP o \fBvoid Base::top__()\fP: .br Used internally\&. ) .PP .SH "9\&. PRIVATE DATA MEMBERS" .PP The following data members can be used by members of parser classes generated by \fBbisonc++\fP\&. All data members are actually protected members inherited from the parser\(cq\&s base class\&. .IP o \fBsize_t d_acceptedTokens__\fP: .br Counts the number of accepted tokens since the start of the \fIparse()\fP function or since the last detected syntactic error\&. It is initialized to \fId_requiredTokens__\fP to allow an early error to be detected as well\&. .IP o \fBbool d_debug__\fP: .br When the \fIdebug\fP option has been specified, this variable (\fItrue\fP by default) determines whether debug information is actually displayed\&. .IP o \fBLTYPE__ d_loc__\fP: .br The location type value associated with a terminal token\&. It can be used by, e\&.g\&., lexical scanners to pass location information of a matched token to the parser in parallel with a returned token\&. It is available only when \fI%lsp\-needed, %ltype\fP or \fI%locationstruct\fP has been defined\&. .br Lexical scanners may be offered the facility to assign a value to this variable in parallel with a returned token\&. In order to allow a scanner access to \fId_loc__\fP, \fId_loc__\fP\(cq\&s address should be passed to the scanner\&. This can be realized, for example, by defining a member \fIvoid setLoc(STYPE__ *)\fP in the lexical scanner, which is then called from the parser\(cq\&s constructor as follows: .nf d_scanner\&.setSLoc(&d_loc__); .fi Subsequently, the lexical scanner may assign a value to the parser\(cq\&s \fId_loc__\fP variable through the pointer to \fId_loc__\fP stored inside the lexical scanner\&. .IP o \fBLTYPE__ d_lsp__\fP: .br The location stack pointer\&. Do not modify\&. .IP o \fBsize_t d_nErrors__\fP: .br The number of errors counted by \fIparse\fP\&. It is initialized by the parser\(cq\&s base class initializer, and is updated while \fIparse\fP executes\&. When \fIparse\fP has returned it contains the total number of errors counted by \fIparse\fP\&. Errors are not counted if suppressed (i\&.e\&., if \fId_acceptedTokens__\fP is less than \fId_requiredTokens__\fP)\&. .IP o \fBsize_t d_nextToken__\fP: .br A pending token\&. Do not modify\&. .IP o \fBsize_t d_requiredTokens__\fP: .br Defines the minimum number of accepted tokens that the \fIparse\fP function must have processed before a syntactic error can be generated\&. .IP o \fBint d_state__\fP: .br The current parsing state\&. Do not modify\&. .IP o \fBint d_token__\fP: .br The current token\&. Do not modify\&. .IP o \fBSTYPE__ d_val__\fP: .br The semantic value of a returned token or non\-terminal symbol\&. With non\-terminal tokens it is assigned a value through the action rule\(cq\&s symbol \fI$$\fP\&. Lexical scanners may be offered the facility to assign a semantic value to this variable in parallel with a returned token\&. In order to allow a scanner access to \fId_val__\fP, \fId_val__\fP\(cq\&s address should be passed to the scanner\&. This can be realized, for example, by passing \fId_val__\fP\(cq\&s address to the lexical scanner\(cq\&s constructor\&. Subsequently, the lexical scanner may assign a value to the parser\(cq\&s \fId_val__\fP variable through the pointer to \fId_val__\fP stored in a data member of the lexical scanner\&. Note that in some cases this approach \fImust\fP be used to make available the correct semantic value to the parser\&. In particular, when a grammar state defines multiple reductions, depending on the next token, the reduction\(cq\&s action only takes place following the retrieval of the next token, thus losing the initially matched token text\&. .IP o \fBLTYPE__ d_vsp__\fP: .br The semantic value stack pointer\&. Do not modify\&. .PP .SH "10\&. TYPES AND VARIABLES IN THE ANONYMOUS NAMESPACE" .PP In the file defining the \fIparse\fP 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\&. .PP .IP o \fBchar const author[]\fP: .br Defining the name and e\-mail address of \fBBisonc++\fP\(cq\&s author\&. .IP o \fBReservedTokens\fP: .br This enumeration defines some token values used internally by the parsing functions\&. They are: .nf PARSE_ACCEPT = 0, _UNDETERMINED_ = \-2, _EOF_ = \-1, _error_ = 256, .fi These tokens are used by the parser to determine whether another token should be requested from the lexical scanner, and to handle error\-conditions\&. .IP o \fBStateType\fP: .br This enumeration defines several moe token values used internally by the parsing functions\&. They are: .nf NORMAL, ERR_ITEM, REQ_TOKEN, ERR_REQ, // ERR_ITEM | REQ_TOKEN DEF_RED, // state having default reduction ERR_DEF, // ERR_ITEM | DEF_RED REQ_DEF, // REQ_TOKEN | DEF_RED ERR_REQ_DEF // ERR_ITEM | REQ_TOKEN | DEF_RED .fi These tokens are used by the parser to define the types of the various states of the analyzed grammar\&. .IP o \fBPI__\fP (Production Info): .br This \fIstruct\fP provides information about production rules\&. It has two fields: \fId_nonTerm\fP is the identification number of the production\(cq\&s non\-terminal, \fId_size\fP represents the number of elements of the productin rule\&. .IP o \fBstatic PI__ s_productionInfo\fP: .br Used internally by the parsing function\&. .IP o \fBSR__\fP (Shift\-Reduce Info): .br This \fIstruct\fP provides the shift/reduce information for the various grammatic states\&. \fISR__\fP values are collected in arrays, one array per grammatic state\&. These array, named \fIs_\fP\fI\fP, where tt is a state number are defined in the anonymous namespace as well\&. The \fISR__\fP elements consist of two unions, defining fields that are applicable to, respectively, the first, intermediate and the last array elements\&. .br The first element of each array consists of (1st field) a \fIStateType\fP and (2nd field) the index of the last array element; intermediate elements consist of (1st field) a symbol value and (2nd field) (if negative) the production rule number reducing to the indicated symbol value or (if positive) the next state when the symbol given in the 1st field is the current token; the last element of each array consists of (1st field) a placeholder for the current token and (2nd field) the (negative) rule number to reduce to by default or the (positive) number of an error\-state to go to when an erroneous token has been retrieved\&. If the 2nd field is zero, no error or default action has been defined for the state, and error\-recovery is attepted\&. .IP o \fBSTACK_EXPANSION\fP: .br An enumeration value specifying the number of additional elements that are added to the state\- and semantic value stacks when full\&. .IP o \fBstatic SR__ s_[]\fP: .br Here, \fI\fP is a numerical value representing a state number\&. Used internally by the parsing function\&. .IP o \fBstatic SR__ *s_state[]\fP: .br Used internally by the parsing function\&. .PP .SH "11\&. RESTRICTIONS ON TOKEN NAMES" .PP To avoid collisions with names defined by the parser\(cq\&s (base) class, the following identifiers should not be used as token names: .IP o Identifiers ending in two underscores; .IP o Any of the following identifiers: \fIABORT, ACCEPT, ERROR, clearin, debug\fP, or \fIsetDebug\fP\&. .PP .SH "12\&. OBSOLETE SYMBOLS" .PP All \fBDECLARATIONS\fP and \fBDEFINE\fP symbols not listed above but defined in \fBbison++\fP are obsolete with \fBbisonc++\fP\&. In particular, there is no \fI%header{ \&.\&.\&. %}\fP section anymore\&. Also, all \fBDEFINE\fP symbols related to member functions are now obsolete\&. There is no need for these symbols anymore as they can simply be declared in the class header file and defined elsewhere\&. .PP .SH "13\&. EXAMPLE" .PP Using a fairly worn\-out example, we\(cq\&ll construct a simple calculator below\&. The basic operators as well as parentheses can be used to specify expressions, and each expression should be terminated by a newline\&. The program terminates when a \fIq\fP is entered\&. Empty lines result in a mere prompt\&. .PP First an associated grammar is constructed\&. When a syntactic error is encountered all tokens are skipped until then next newline and a simple message is printed using the default \fIerror\fP function\&. It is assumed that no semantic errors occur (in particular, no divisions by zero)\&. The grammar is decorated with actions performed when the corresponding grammatical production rule is recognized\&. The grammar itself is rather standard and straightforward, but note the first part of the specification file, containing various other directives, among which the \fI%scanner\fP directive, resulting in a composed \fId_scanner\fP object as well as an implementation of the member function \fIint lex\fP\&. In this example, a common \fIScanner\fP class construction strategy was used: the class \fIScanner\fP was derived from the class \fIyyFlexLexer\fP generated by \fBflex++\fP(1)\&. The actual process of constructing a class using \fBflex++\fP(1) is beyond the scope of this man\-page, but \fBflex++\fP(1)\(cq\&s specification file is mentioned below, to further complete the example\&. Here is \fBbisonc++\fP\(cq\&s input file: .PP .nf %filenames parser %scanner \&.\&./scanner/scanner\&.h // lowest precedence %token NUMBER // integral numbers EOLN // newline %left \(cq\&+\(cq\& \(cq\&\-\(cq\& %left \(cq\&*\(cq\& \(cq\&/\(cq\& %right UNARY // highest precedence %% expressions: expressions evaluate | prompt ; evaluate: alternative prompt ; prompt: { prompt(); } ; alternative: expression EOLN { cout << $1 << endl; } | \(cq\&q\(cq\& done | EOLN | error EOLN ; done: { cout << \(dq\&Done\&.\en\(dq\&; ACCEPT(); } ; expression: expression \(cq\&+\(cq\& expression { $$ = $1 + $3; } | expression \(cq\&\-\(cq\& expression { $$ = $1 \- $3; } | expression \(cq\&*\(cq\& expression { $$ = $1 * $3; } | expression \(cq\&/\(cq\& expression { $$ = $1 / $3; } | \(cq\&\-\(cq\& expression %prec UNARY { $$ = \-$2; } | \(cq\&+\(cq\& expression %prec UNARY { $$ = $2; } | \(cq\&(\(cq\& expression \(cq\&)\(cq\& { $$ = $2; } | NUMBER { $$ = stoul(d_scanner\&.matched()); } ; .fi .PP Next, \fBbisonc++\fP processes this file\&. In the process, \fBbisonc++\fP generates the following files from its skeletons: .IP o The parser\(cq\&s base class, which should not be modified by the programmer: .IP .nf // Generated by Bisonc++ V4\&.01\&.02 on Wed, 06 Mar 2013 15:26:21 +0100 #ifndef ParserBase_h_included #define ParserBase_h_included #include #include namespace // anonymous { struct PI__; } class ParserBase { public: // $insert tokens // Symbolic tokens: enum Tokens__ { NUMBER = 257, EOLN, UNARY, }; // $insert STYPE typedef int STYPE__; private: int d_stackIdx__; std::vector d_stateStack__; std::vector d_valueStack__; protected: enum Return__ { PARSE_ACCEPT__ = 0, // values used as parse()\(cq\&s return values PARSE_ABORT__ = 1 }; enum ErrorRecovery__ { DEFAULT_RECOVERY_MODE__, UNEXPECTED_TOKEN__, }; bool d_debug__; size_t d_nErrors__; size_t d_requiredTokens__; size_t d_acceptedTokens__; int d_token__; int d_nextToken__; size_t d_state__; STYPE__ *d_vsp__; STYPE__ d_val__; STYPE__ d_nextVal__; ParserBase(); void ABORT() const; void ACCEPT() const; void ERROR() const; void clearin(); bool debug() const; void pop__(size_t count = 1); void push__(size_t nextState); void popToken__(); void pushToken__(int token); void reduce__(PI__ const &productionInfo); void errorVerbose__(); size_t top__() const; public: void setDebug(bool mode); }; inline bool ParserBase::debug() const { return d_debug__; } inline void ParserBase::setDebug(bool mode) { d_debug__ = mode; } inline void ParserBase::ABORT() const { throw PARSE_ABORT__; } inline void ParserBase::ACCEPT() const { throw PARSE_ACCEPT__; } inline void ParserBase::ERROR() const { throw UNEXPECTED_TOKEN__; } // As a convenience, when including ParserBase\&.h its symbols are available as // symbols in the class Parser, too\&. #define Parser ParserBase #endif .fi .IP .IP o The parser class \fIparser\&.h\fP itself\&. In the grammar specification various member functions are used (e\&.g\&., \fIdone\fP) and \fIprompt\fP\&. These functions are so small that they can very well be implemented inline\&. Note that \fIdone\fP calls \fIACCEPT\fP to terminate further parsing\&. \fIACCEPT\fP and related members (e\&.g\&., \fIABORT\fP) can be called from any member called by \fIparse\fP\&. As a consequence, action blocks could contain mere function calls, rather than several statements, thus minimizing the need to rerun \fBbisonc++\fP when an action is modified\&. .IP Once \fBbisonc++\fP had created \fIparser\&.h\fP it was augmented with the required additional members, resulting in the following final version: .IP .nf #ifndef Parser_h_included #define Parser_h_included // $insert baseclass #include \(dq\&parserbase\&.h\(dq\& // $insert scanner\&.h #include \(dq\&\&.\&./scanner/scanner\&.h\(dq\& #undef Parser class Parser: public ParserBase { // $insert scannerobject Scanner d_scanner; public: int parse(); private: void error(char const *msg); int lex(); void print(); void prompt(); void done(); // support functions for parse(): void executeAction(int ruleNr); void errorRecovery(); int lookup(bool recovery); void nextToken(); void print__(); }; inline void Parser::prompt() { std::cout << \(dq\&? \(dq\& << std::flush; } inline void Parser::done() { std::cout << \(dq\&Done\en\(dq\&; ACCEPT(); } #endif .fi .IP .IP o To complete the example, the following lexical scanner specification was used: .IP .nf %interactive %filenames scanner %% [ \et]+ // skip white space \en return Parser::EOLN; [0\-9]+ return Parser::NUMBER; \&. return matched()[0]; %% .fi .IP .IP o Since no member functions other than \fIparse\fP were defined in separate source files, only \fIparse\fP includes \fIparser\&.ih\fP\&. Since \fIcerr\fP is used in the grammar\(cq\&s actions, a \fIusing namespace std\fP or comparable statement is required\&. This was effectuated from \fIparser\&.ih\fP Here is the implementation header declaring the standard namespace: .IP .nf // Generated by Bisonc++ V4\&.01\&.02 on Wed, 06 Mar 2013 15:10:36 +0100 // Include this file in the sources of the class Parser\&. // $insert class\&.h #include \(dq\&parser\&.h\(dq\& inline void Parser::error(char const *msg) { std::cerr << msg << \(cq\&\en\(cq\&; } // $insert lex inline int Parser::lex() { return d_scanner\&.lex(); } inline void Parser::print() { print__(); // displays tokens if \-\-print was specified } // Add here includes that are only required for the compilation // of Parser\(cq\&s sources\&. // UN\-comment the next using\-declaration if you want to use // int Parser\(cq\&s sources symbols from the namespace std without // specifying std:: using namespace std; .fi .IP The implementation of the parsing member function \fIparse\fP is basically irrelevant, since it should not be modified by the programmer\&. It was written on the file \fIparse\&.cc\fP\&. .IP o Finally, here is the program offering our simple calculator: .IP .nf #include \(dq\&parser/parser\&.h\(dq\& int main() { Parser calculator; return calculator\&.parse(); } .fi .PP .SH "14\&. USING PARSER\-CLASS SYMBOLS IN LEXICAL SCANNERS" .PP Note here that although the file \fIparserbase\&.h\fP, defining the parser class\(cq\& base\-class, rather than the header file \fIparser\&.h\fP defining the parser class is included, the lexical scanner may simply return tokens of the class \fIParser\fP (e\&.g\&., \fIParser::NUMBER\fP rather than \fIParserBase::NUMBER\fP)\&. In fact, using a simple \fI#define \- #undef\fP pair generated by the \fBbisonc++\fP respectively at the end of the base class header the file and just before the definition of the parser class itself it is the possible to assume in the lexical scanner that all symbols defined in the the parser\(cq\&s base class are actually defined in the parser class itself\&. It the should be noted that this feature can only be used to access base class the \fIenum\fP and types\&. The actual parser class is not available by the time the the lexical scanner is defined, thus avoiding circular class dependencies\&. .PP .SH "15\&. FILES" .IP o \fBbisonc++base\&.h\fP: skeleton of the parser\(cq\&s base class; .IP o \fBbisonc++\&.h\fP: skeleton of the parser class; .IP o \fBbisonc++\&.ih\fP: skeleton of the implementation header; .IP o \fBbisonc++\&.cc\fP: skeleton of the member \fIparse\fP; .IP o \fBbisonc++polymorphic\fP: skeleton of the declarations used by \fI%polymorphic\fP; .IP o \fBbisonc++polymorphic\&.inline\fP: skeleton of the inline implementations of the members declared in \fBbisonc++polymorphic\fP\&. .PP .SH "16\&. SEE ALSO" \fBbison\fP(1), \fBbison++\fP(1), \fBbison\&.info\fP (using texinfo), \fBflex++\fP(1) .PP Lakos, J\&. (2001) \fBLarge Scale C++ Software Design\fP, Addison Wesley\&. .br Aho, A\&.V\&., Sethi, R\&., Ullman, J\&.D\&. (1986) \fBCompilers\fP, Addison Wesley\&. .PP .SH "17\&. BUGS" .PP Parser\-class header files (e\&.g\&., Parser\&.h) and parser\-class internal header files (e\&.g\&., Parser\&.ih) generated with bisonc++ < 4\&.02\&.00 require two hand\-modifications when used in combination with bisonc++ >= 4\&.02\&.00\&. See the description of \fIexceptionHandler__\fP for details\&. .PP Discontinued options: .IP o \fB\-\-include\-only\fP .IP o \fB\-\-namespace\fP .PP To avoid collisions with names defined by the parser\(cq\&s (base) class, the following identifiers should not be used as token nams: .IP o Identifiers ending in two underscores; .IP o Any of the following identifiers: \fIABORT, ACCEPT, ERROR, clearin, debug, error\fP, or \fIsetDebug\fP\&. .PP When re\-using files generated by \fBbisonc++\fP before version 2\&.0\&.0, minor hand\-modification might be necessary\&. The identifiers in the following list (defined in the parser\(cq\&s base class) now have two underscores affixed to them: \fILTYPE, STYPE\fP and \fITokens\fP\&. When using classes derived from the generated parser class, the following identifiers are available in such derived classes: \fIDEFAULT_RECOVERY_MODE, ErrorRecovery, Return, UNEXPECTED_TOKEN, d_debug, d_loc, d_lsp, d_nErrors, d_nextToken, d_state, d_token, d_val\fP, and \fId_vsp\fP\&. When used in derived classes, they too need two underscores affixed to them\&. .PP The member function \fIvoid lookup\fP (< 1\&.00) was replaced by \fIint lookup\fP\&. When regenerating parsers created by early versions of \fBbisonc++\fP (versions before version 1\&.00), \fIlookup\fP\(cq\&s prototype should be corrected by hand, since \fBbisonc++\fP will not by itself rewrite the parser class\(cq\&s header file\&. .PP The \fISemantic\fP parser, mentioned in \fBbison++\fP(1) is not implemented in \fBbisonc++\fP(1)\&. According to \fBbison++\fP(1) the semantic parser was not available in \fBbison++\fP either\&. It is possible that the \fIPure\fP parser is now available through the \fI\-\-thread\-safe\fP option\&. .PP .SH "18\&. ABOUT bisonc++" .PP \fBBisonc++\fP was based on \fBbison++\fP, originally developed by Alain Coetmeur (coetmeur@icdc\&.fr), R&D department (RDT), Informatique\-CDC, France, who based his work on \fBbison\fP, GNU version 1\&.21\&. .PP \fBBisonc++\fP version 0\&.98 and beyond is a complete rewrite of an LALR\-1 parser generator, closely following the construction process as described in Aho, Sethi and Ullman\(cq\&s (1986) book \fBCompilers\fP (i\&.e\&., the \fIDragon book\fP)\&. It uses the same grammar specification as \fBbison\fP and \fBbison++\fP, and it uses practically the same options and directives as \fBbisonc++\fP versions earlier than 0\&.98\&. Variables, declarations and macros that are obsolete were removed\&. .PP .SH "AUTHOR" .PP Frank B\&. Brokken (f\&.b\&.brokken@rug\&.nl)\&.