Previous: Bison Declarations, Up: Bison Grammar Files [Contents][Index]
Most programs that use Bison parse only one language and therefore contain
only one Bison parser. But what if you want to parse more than one language
with the same program? Then you need to avoid name conflicts between
different definitions of functions and variables such as yyparse
,
yylval
. To use different parsers from the same compilation unit, you
also need to avoid conflicts on types and macros (e.g., YYSTYPE
)
exported in the generated header.
The easy way to do this is to define the %define
variable
api.prefix
. With different api.prefix
s it is guaranteed that
headers do not conflict when included together, and that compiled objects
can be linked together too. Specifying ‘%define api.prefix
{prefix}’ (or passing the option -Dapi.prefix={prefix}, see
Invoking Bison) renames the interface functions and
variables of the Bison parser to start with prefix instead of
‘yy’, and all the macros to start by PREFIX (i.e., prefix
upper-cased) instead of ‘YY’.
The renamed symbols include yyparse
, yylex
, yyerror
,
yynerrs
, yylval
, yylloc
, yychar
and
yydebug
. If you use a push parser, yypush_parse
,
yypull_parse
, yypstate
, yypstate_new
and
yypstate_delete
will also be renamed. The renamed macros include
YYSTYPE
, YYLTYPE
, and YYDEBUG
, which is treated
specifically — more about this below.
For example, if you use ‘%define api.prefix {c}’, the names become
cparse
, clex
, …, CSTYPE
, CLTYPE
, and so
on.
Users of Flex must update the signature of the generated yylex
function. Since the Flex scanner usually includes the generated header of
the parser (to get the definitions of the tokens, etc.), the most convenient
way is to insert the declaration of yylex
in the provides
section:
%define api.prefix {c} // Emitted in the header file, after the definition of YYSTYPE. %code provides { // Tell Flex the expected prototype of yylex. #define YY_DECL \ int clex (CSTYPE *yylval, CLTYPE *yylloc) // Declare the scanner. YY_DECL; }
The %define
variable api.prefix
works in two different ways.
In the implementation file, it works by adding macro definitions to the
beginning of the parser implementation file, defining yyparse
as
prefixparse
, and so on:
#define YYSTYPE CTYPE #define yyparse cparse #define yylval clval ... YYSTYPE yylval; int yyparse (void);
This effectively substitutes one name for the other in the entire parser
implementation file, thus the “original” names (yylex
,
YYSTYPE
, …) are also usable in the parser implementation file.
However, in the parser header file, the symbols are defined renamed, for instance:
extern CSTYPE clval; int cparse (void);
The macro YYDEBUG
is commonly used to enable the tracing support in
parsers. To comply with this tradition, when api.prefix
is used,
YYDEBUG
(not renamed) is used as a default value:
/* Debug traces. */ #ifndef CDEBUG # if defined YYDEBUG # if YYDEBUG # define CDEBUG 1 # else # define CDEBUG 0 # endif # else # define CDEBUG 0 # endif #endif #if CDEBUG extern int cdebug; #endif
Prior to Bison 2.6, a feature similar to api.prefix
was provided by
the obsolete directive %name-prefix
(see Bison Symbols) and
the option --name-prefix (see Output Files).
Previous: Bison Declarations, Up: Bison Grammar Files [Contents][Index]