bisonc++api(3)
bisonc++api(3) β the bisonc++ API π
okay bestie, pull up a chair, because this is the manual page for the application programmer's interface of the classes bisonc++ generates, and we're gonna get through it together. this is part 1 of 3, so hydrate, we're not done yet β¨
NAME π
bisonc++ β Application programmer's interface of bisonc++ generated classes
DESCRIPTION π¦
So bisonc++ descends from bison++(1), which itself descends from bison(1), like a whole little parser dynasty π. Just like those programs, bisonc++ generates a parser for an LALR(1) grammar. But here's the slay: bisonc++ generates C++ code β an expandable C++ class. main character energy fr.
If you want the general overview, go read bisonc++(1). This manual page is all about the application programmer's interface of the classes that bisonc++ generates. It's got these sections, in this order:
- DESCRIPTION: this section right here, bestie;
- PUBLIC SYMBOLS: constructor, enums, members, and types that calling software can use;
- PRIVATE ENUMS AND -TYPES: enumerations and types only available to the Parser class;
- PRIVATE MEMBER FUNCTIONS: member functions that are only available to the Parser class;
- PRIVATE DATA MEMBERS: data members that are only available to the Parser class;
- TYPES AND VARIABLES IN THE ANONYMOUS NAMESPACE: an overview of the types and variables used to define and store the grammar-tables generated by
bisonc++; - SEE ALSO: references to other programs and documentation;
- AUTHOR: at the end of this man-page.
Now the rules, and listen up because these matter π:
Every identifier ending in an underscore character is reserved for bisonc++. Member functions ending in an underscore must not be redefined. Data members ending in an underscore are available in the generated parser class, and user-defined members of the parser class may modify them. Some members like (error, exceptionHandler, lex) are defined in the parser class and must remain present, but their implementations may be altered by the user. And members for which no default implementation is provided in the parser's internal header file (e.g., Parser.ih) may not be redefined or masked by user-provided code.
no cap, that last one is a hard no. don't touch it.
UNDERSCORES π
Starting with version 6.02.00, bisonc++ reserved identifiers no longer end in two underscore characters, but in one. why tho? because according to the C++ standard, identifiers with two or more consecutive underscore characters are reserved by the language itself π. So this change was necessary, periodt.
In practice this could require some minor modifications of existing source files using bisonc++'s facilities, most likely limited to changing Tokens__ into Tokens_ and changing Meta__ into Meta_. lowkey painless.
The complete list of affected names is:
- Enums:
DebugMode_,ErrorRecovery_,Return_,Tag_,Tokens_ - Enums values:
PARSE_ABORT_,PARSE_ACCEPT_,UNEXPECTED_TOKEN_,sizeofTag_ - Type / namespace designators:
Meta_,PI_,STYPE_ - Member functions:
clearin_,errorRecovery_,errorVerbose_,executeAction_,lex_,lookup_,nextCycle_,nextToken_,popToken_,pop_,print_,pushToken_,push_,recovery_,redoToken_,reduce_,savedToken_,shift_,stackSize_,startRecovery_,state_,token_,top_,vs_, - Protected data members:
d_acceptedTokens_,d_actionCases_,d_debug_,d_nErrors_,d_requiredTokens_,d_val_,idOfTag_,s_nErrors_
PUBLIC SYMBOLS β¨
Parser classes generated by bisonc++ offer the following public constructor, enums, members and types. (In this overview, parser class-name prefixes like Parser:: were omitted, so don't come for me.)
- Constructors β the generated parser class merely defines the default constructor. Copy and move constructors are not available. The default constructor is a real default: it's declared as such in the parser's header file. Additional constructors can easily be added to the parser class's interface. And since the initialization of the parser's base class is performed by the parser base class's default constructor, constructors that are added to the generated parser class automatically call the base class constructor β so additional constructors do not have to explicitly initialize the parser's base class. cute, right?
DebugMode_β the values of this enum configure the type of debug information that gets displayed (assuming thedebugoption/directive was specified whenbisonc++generated the parser's code). It has three values:OFF: no debug information is displayed when the generated parser'sparsefunction is called;ON: extensive debug information about the parsing process is displayed when the generated parser'sparsefunction is called;ACTIONCASES: just before executing the grammar's action blocks, the action block number is written to the standard output stream. These action block numbers refer tocaselabels of theswitchthat's defined in the parser'sexecuteActionfunction. It's commonly used to find the action block where a fatal semantic value mismatch was observed.
The bit_or operator can be used to combine ON and ACTIONCASES (see the member function setDebug(DebugMode_ mode) below).
LTYPE_β the parser's location type (user-definable). Available only when either%lsp-needed,%ltypeor%locationstructhas been declared.STYPE_β the parser's stack-type (user-definable), defaults toint.Tokens_β the enumeration type of all the symbolic tokens defined in the grammar file (i.e., bisonc++'s input file). The scanner should be prepared to return these symbolic tokens. Note that, since the symbolic tokens are defined in the parser's class and not in the scanner's class, the lexical scanner must prefix the parser's class name to the symbolic token names when they're returned. E.g.,return Parser::IDENTshould be used rather thanreturn IDENT.int parse()β the parser's parsing member function. It returns0when parsing was successfully completed;1if errors were encountered while parsing the input.void setDebug(bool mode)β this member can activate or deactivate the debug-code compiled into the parsing function. It's always defined but is only operational if thedebugdirective option was specified whenbisonc++generated the parse function. If so, it is not active by default; to activate the debug output callsetDebug(true), to suppress the debug output callsetDebug(false).void setDebug(DebugMode_ mode)β this member can also activate or deactivate the debug-code compiled into the parsing function. LikesetDebug(bool)it's always defined but only operational if thedebugdirective option was specified whenbisonc++generated the parse function. If so, it is not active by default; to activate, callsetDebug(Parser::ON),setDebug(Parser::ACTIONCASES), orsetDebug(Parser::ON | Parser::ACTIONCASES). To suppress the debug code output callsetDebug(Parser_::OFF)or simplysetDebug(false).
When the %polymorphic directive is used:
Meta_β templates and classes that are required for implementing the polymorphic semantic values are all declared in theMeta_namespace. TheMeta_namespace itself is nested under the namespace that may have been declared by the%namespacedirective.Tag_β the (strongly typed) enum classTag_contains all the tag-identifiers specified by the%polymorphicdirective. It's declared outside of the Parser's class, but within the namespace that may have been declared by the%namespacedirective.
PRIVATE ENUMS AND -TYPES π§
These enumerations and types can be used by members of parser classes generated by bisonc++. They're actually protected members inherited from the parser's base class β so iykyk, they're yours but they're inherited π.
Base::ErrorRecovery_β this enumeration defines one value:
UNEXPECTED_TOKEN_
When the parsing process throws UNEXPECTED_TOKEN_ the recovery procedure is started (i.e., it is started whenever a syntactic error is encountered or ERROR() is called).
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.
If the error recovery procedure fails (i.e., if no acceptable token is ever encountered) error recovery falls back to the default recovery mode: the parsing process terminates. π
Base::Return_β this enumeration defines two values:
PARSE_ACCEPT = 0,
PARSE_ABORT = 1
(which are also used as the parse function's return values).
When the %polymorphic directive is used:
Meta_::sizeofTag_βsizeofTag_defines the number of tags that were defined for polymorphic semantic values.
π PRIVATE MEMBER FUNCTIONS π
Ok bestie, so these are the members you can actually use from inside parser classes generated by bisonc++. When you see them prefixed with Base::, they're lowkey protected members inherited from the parser's base class. We're listing them below. After that there's a whole other squad of members that get used during the parsing process β and those? Do not touch, do not modify, do not mask with your own user-defined code. Fr fr. π«Ά
void Base::ABORT() const throw(Return_)β call this from literally any member function (like, from any of the parser's action blocks) to say "this failed" and terminate the parsing function with error value1. It's a major glow-up over theYYABORTmacro from bison++ β becauseYYABORTcould not be called from outside the parsing member function. Iconic behavior. πvoid Base::ACCEPT() const throw(Return_)β call this from any member function (again, from any of the parser's action blocks) to declare successful parsing and terminate the parsing function. Another glow-up: bison++'sYYACCEPTmacro couldn't be called from outside the parsing member function. Slay. β¨void Base::ERROR() const throw(ErrorRecovery_)β call this from any member function (yep, any action block) to generate an error, which makes the parser run its error recovery code. Same story: it's a marked extension and improvement over bison++'sYYERRORmacro, becauseYYERRORcouldn't be called from outside the parsing member function. πvoid error()β by default this is implemented inline in theparser.ihinternal header file. It writes a simple message to the standard error stream. It gets called when a syntactic error is encountered, and its default implementation may safely be altered. You have permission, bestie. πvoid exceptionHandler(std::exception const &exc)β the default implementation lives inline inparser.ihinternal header file, and it's literally just a throw statement that rethrows a caught exception.
The parse member function's body is essentially a while statement, where the next token is obtained through the parser's lex member. That token then gets processed according to the current state of the parsing process. This can result in executing actions over which the parsing process has no control β and those actions may throw exceptions. π
Such exceptions don't necessarily have to terminate the parsing process. They could be thrown by code linked to the parser that just checks for semantic errors (like divisions by zero) and throws exceptions if it spots them. The exceptionHandler member receives and may handle those exceptions without necessarily ending the parsing process. It receives any std::exception thrown by the parser's actions, as though the action block itself was wrapped in a try ... catch statement. Of course you can still use an explicit try ... catch inside action blocks. But exceptionHandler can factor out code that's common to various action blocks. Main character energy. π¦
The next example shows an explicit implementation of exceptionHandler: any std::exception thrown by the parser's action blocks is caught, showing the exception's message, and increasing the parser's error count. After this parsing continues as if no exception had been thrown:
void Parser::exceptionHandler(std::exception const &exc)
{
std::cout << exc.what() << β\nβ;
++d_nErrors_;
}
int lex()β by default implemented inline in theparser.ihinternal header file. It can be pre-implemented bybisonc++using the scanner option or directive (see above); alternatively it must be implemented by the programmer. It interfaces to the lexical scanner and should return the next token produced by that scanner β either as a plain character or as one of the symbolic tokens defined in theParser::Tokens_enumeration. Zero or negative token values are interpreted asend of input. πvoid print()β by default implemented inline inparser.ihinternal header file. This member callsprint_to display the last received token and the corresponding matched text. Theprint_member is only implemented if the--print-tokensoption or%print-tokensdirective was used when the parsing function was generated. Callingprint_fromprintis unconditional, but it can easily be controlled by the using program, for example by defining a command-line option. πsize_t stackSize_() constβ returns the current number of elements in the parser's state-stack.size_t state_() constβ returns the current parsing-state.bool Base::recovery_() constβ returnstruewhile recovering from a syntax error.int Base::token_() constβ returns the currently considered token.
The following members are required during the parsing process. They should not be modified or masked by user-defined code:
Base::ParserBase()void Base::clearin_()()void errorRecovery_()void Base::errorVerbose_()void executeAction_(int)int lex_(int token)int Base::lookup()LTYPE_ const &lsp_(int) constβ (only available when%lsp-needed,%ltypeor%locationstructwas specified).void nextCycle_()void nextToken_()void Base::pop_()void Base::popToken_()void print_()()void Base::push_()void Base::pushToken_()void Base::shift_(int state)void Base::redoToken_(int rule)void Base::reduce_(int rule)void Base::savedToken_()void Base::symbol_()void Base::startRecovert_()void Base::top_()int Base::token_() constvoid Base::vs_(int idx)
π PRIVATE DATA MEMBERS π
Ok so these data members can be used by members of parser classes generated by bisonc++. And all of them are actually protected members inherited from the parser's base class. The more you know. π
size_t d_acceptedTokens_β counts the number of accepted tokens since the start of theparse()function or since the last detected syntactic error. It's initialized tod_requiredTokens_so that an early error can be detected as well. πbool d_actionCases_β when the debug option has been specified, this variable (falseby default) determines whether the number of the action block that's about to be executed by the parser's memberexecuteActionwill be displayed to the standard output stream. πbool d_debug_β when the debug option has been specified, this variable (trueby default) determines whether debug information is actually displayed. β¨LTYPE_ d_loc_β the location type value associated with a terminal token. It can be used by, for example, lexical scanners to pass location information of a matched token to the parser in parallel with a returned token. It's available only when%lsp-needed,%ltypeor%locationstructhas been defined.
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 d_loc_, d_loc_'s address should be passed to the scanner. This can be realized, for example, by defining a member void setLoc(STYPE_ *) in the lexical scanner, which is then called from the parser's constructor as follows:
d_scanner.setSLoc(&d_loc_);
Subsequently, the lexical scanner may assign a value to the parser's d_loc_ variable through the pointer to d_loc_ stored inside the lexical scanner. π¦
size_t d_nErrors_β the number of errors counted byparse. It's initialized by the parser's base class initializer and is updated whileparseexecutes. Whenparsehas returned, it contains the total number of errors counted byparse. Errors are not counted if suppressed (i.e., ifd_acceptedTokens_is less thand_requiredTokens_). πsize_t d_requiredTokens_β defines the minimum number of accepted tokens that theparsefunction must have processed before a syntactic error can be generated. πSTYPE_ d_val_β the semantic value of a returned token or nonterminal symbol. With nonterminal tokens it's assigned a value through the action rule's symbol$$. 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 tod_val_,d_val_'s address should be passed to the scanner. This can be realized, for example, by passingd_val_'s address to the lexical scanner's constructor.
Subsequently, the lexical scanner may assign a value to the parser's d_val_ variable through the pointer to d_val_ stored in a data member of the lexical scanner.
Note that in some cases this approach must be used to make the correct semantic value available to the parser. In particular, when a grammar state defines multiple reductions, depending on the next token, the reduction's action only takes place following the retrieval of the next token, thus losing the initially matched token text. π
If STYPE is a polymorphic semantic value, specific requirements for assigning values to d_val_ apply. .
π BUGS π
okay bestie, listen up, this part is IMPORTANT. With bisonc++ version 6.00.00 the following members were modified. Where necessary, alternatives are mentioned. Read them, love them, update your code, don't text me at 3am about it. π
bool Base::debug() constβ bestie this one's gone-gone. Use thed_debug_data member instead. πvoid error(char const *)β she was replaced. Now it's justvoid error(). no arguments, no drama. β¨void exceptionHandler_(std::exception const &exc)β the way that this one has too many underscores π omit the final ones, so:void exceptionHandler(std::exception const &exc)πvoid executeAction(int)β add one underscore to the declaration in the parser class interface:void executeAction_(int)π¦int lookup(bool)β literally just omit this member from the parser class interface. bye babe πvoid nextCycle_(int)β add this member declaration to the parser class interface. she's new here, be nice πΈvoid nextToken(int)β add one underscore to the declaration in the parser class interface:void nextToken_(int)πsize_t d_nextToken_β removed from the interface. periodt. πint d_state_β usestate_()instead, that's the vibe now β¨int d_token_β usetoken_()instead, same energy π«ΆLTYPE_ d_vsp_β removed from the interface. Usevsp_()instead. no cap. π₯
π§ TYPES AND VARIABLES IN THE ANONYMOUS NAMESPACE π§
okay so, 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. So like, you can peek, but don't touch. π
char const author[]β defining the name and e-mail address of Bisonc++'s author. yes, she's got her own lil string, iconic behavior honestly πReserved_β this enumeration defines some token values used internally by the parsing functions. They are:
UNDETERMINED_ = -2,
EOF_ = -1,
errTok_ = 256,
These tokens are used by the parser to determine whether another token should be requested from the lexical scanner, and to handle error-conditions. π
StateTypeβ this enumeration defines several additional token values used internally by the parsing functions. They are:
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
These tokens are used by the parser to define the types of the various states of the analyzed grammar. it's giving state machine realness β
StateTransitionβ this enumeration only defines a single symbolic constant:ACCEPT_, which is used in the state transition tables to indicate that the accepting state has been reached. one constant, main character energy, we love her πPI_(Production Info) β this struct provides information about production rules. It has two fields:d_nonTermis the identification number of the production's nonterminal, andd_sizerepresents the number of elements of the production rule. two fields, zero filler πstatic PI_ s_productionInfoβ used internally by the parsing function. πSR_(Shift-Reduce Info) β this struct provides the shift/reduce information for the various grammatic states.SR_values are collected in arrays, one array per grammatic state. These arrays, nameds_<nr>, where<nr>is a state number, are defined in the anonymous namespace as well. TheSR_elements consist of two unions, defining fields that are applicable to, respectively, the first, intermediate and the last array elements.
okay this next bit is dense bestie, so let's break it down πΈ:
- The first element of each array consists of (1st field) a
StateTypeand (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 attempted. so like, zero = we're on our own, lowkey π
STACK_EXPANSION_β an enumeration value specifying the number of additional elements that are added to the state- and semantic value stacks when full. growth mindset fr fr π±static SR_ s_<nr>[]β here,<nr>is a numerical value representing a state number. Used internally by the parsing function. π’static SR_ *s_state[]β used internally by the parsing function. π«Ά
π SEE ALSO π
go read these bestie, they're all part of the lore:
bison(1)bison++(1)bisonc++(1)bisonc++input(7)bison.info(using texinfo)flexc++(1)https://fbb-git.gitlab.io/bisoncpp/
and some absolute classics for the girlies who love theory π:
- Lakos, J. (2001) Large Scale C++ Software Design, Addison Wesley.
- Aho, A.V., Sethi, R., Ullman, J.D. (1986) Compilers, Addison Wesley.
π AUTHOR π
Frank B. Brokken (f.b.brokken@rug.nl). legend behavior, no notes, we stan π
and that's a wrap on this whole page bestie!! πβ¨ this was bisonc++.6.09.02, dated 2005-2025, and honestly? twenty years of serving parser realness, we love to see it. go forth and parse, you've got this fr fr π
π
π¦ where this page comes from
- ubuntu resolute: bisonc++ 6.09.02-1 Β· GPL-3.0-or-later
- ubuntu stonking: bisonc++ 6.09.02-1build1 Β· GPL-3.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms