api.prefix.

* data/c.m4 (b4_api_prefix, b4_api_PREFIX): New.
(b4_prefix, b4_union_name, b4_token_enums, b4_declare_yylstype): Use them.
* data/glr.c, data/yacc.c, data/glr.cc, data/lalr1.cc: Use them to change
the prefix of exported preprocessor symbols.
* src/getargs.c (usage): Ditto.
* tests/headers.at (Several parsers): New.
* tests/local.at (AT_API_PREFIX): New.
AT_YYSTYPE, AT_YYLTYPE): Adjust.
* doc/bison.texi (Multiple Parsers): Move documentation of %name-prefix to...
(Table of Symbols): here.
(Multiple Parsers): Document api.prefix.
(%define Summary): Point to it.
Use @code for variable names.
(Bison Options): -p/--name-prefix are obsoleted.
* NEWS: Announce api.prefix.
This commit is contained in:
Akim Demaille
2012-06-26 10:09:10 +02:00
parent 087dcd7868
commit 4b3847c3c0
10 changed files with 320 additions and 96 deletions

54
NEWS
View File

@@ -70,6 +70,60 @@ GNU Bison NEWS
For the same reasons, the undocumented and unused macro YYLSP_NEEDED is no For the same reasons, the undocumented and unused macro YYLSP_NEEDED is no
longer defined. longer defined.
** New %define variable: api.prefix
Now that the generated headers are more complete and properly protected
against multiple inclusions, constant names, such as YYSTYPE are a
problem. While yyparse and others are properly renamed by %name-prefix,
YYSTYPE, YYDEBUG and others have never been affected by it. Because it
would introduce backward compatibility issues in projects not expecting
YYSTYPE to be renamed, instead of changing the behavior of %name-prefix,
it is deprecated in favor of a new %define variable: api.prefix.
The following examples compares both:
%name-prefix "bar_" | %define api.prefix "bar_"
%token <ival> FOO %token <ival> FOO
%union { int ival; } %union { int ival; }
%% %%
exp: 'a'; exp: 'a';
bison generates:
#ifndef BAR_FOO_H #ifndef BAR_FOO_H
# define BAR_FOO_H # define BAR_FOO_H
/* Enabling traces. */ /* Enabling traces. */
# ifndef YYDEBUG # ifndef YYDEBUG
# define YYDEBUG 0 # define YYDEBUG 0
# endif # endif
# if YYDEBUG # if YYDEBUG
extern int bar_debug; extern int bar_debug;
# endif # endif
/* Tokens. */ /* Tokens. */
# ifndef YYTOKENTYPE | # ifndef BAR_TOKENTYPE
# define YYTOKENTYPE | # define BAR_TOKENTYPE
enum yytokentype { | enum bar_tokentype {
FOO = 258 FOO = 258
}; };
# endif # endif
#if ! defined YYSTYPE \ | #if ! defined BAR_STYPE \
&& ! defined YYSTYPE_IS_DECLARED | && ! defined BAR_STYPE_IS_DECLARED
typedef union YYSTYPE | typedef union BAR_STYPE
{ {
int ival; int ival;
} YYSTYPE; | } BAR_STYPE;
# define YYSTYPE_IS_DECLARED 1 | # define BAR_STYPE_IS_DECLARED 1
#endif #endif
extern YYSTYPE bar_lval; | extern BAR_STYPE bar_lval;
int bar_parse (void); int bar_parse (void);
#endif /* !BAR_FOO_H */ #endif /* !BAR_FOO_H */
* Noteworthy changes in release 2.5.1 (2012-06-05) [stable] * Noteworthy changes in release 2.5.1 (2012-06-05) [stable]
** Future changes: ** Future changes:

View File

@@ -84,11 +84,24 @@ m4_define([b4_identification],
## Default values. ## ## Default values. ##
## ---------------- ## ## ---------------- ##
# If the %union is not named, its name is YYSTYPE. # b4_api_prefix, b4_api_PREFIX
m4_define_default([b4_union_name], [YYSTYPE]) # ----------------------------
# Corresponds to %define api.prefix
b4_percent_define_default([[api.prefix]], [[yy]])
m4_define([b4_api_prefix],
[b4_percent_define_get([[api.prefix]])])
m4_define([b4_api_PREFIX],
[m4_toupper(b4_api_prefix)])
# b4_prefix
# ---------
# If the %name-prefix is not given, it is api.prefix.
m4_define_default([b4_prefix], [b4_api_prefix])
# If the %union is not named, its name is YYSTYPE.
m4_define_default([b4_union_name], [b4_api_PREFIX[]STYPE])
# If the %name-prefix is not given, it is yy.
m4_define_default([b4_prefix], [yy])
## ------------------------ ## ## ------------------------ ##
## Pure/impure interfaces. ## ## Pure/impure interfaces. ##
@@ -232,18 +245,18 @@ m4_define([b4_token_enum],
# Output the definition of the tokens (if there are) as enums. # Output the definition of the tokens (if there are) as enums.
m4_define([b4_token_enums], m4_define([b4_token_enums],
[m4_if([$#$1], [1], [], [m4_if([$#$1], [1], [],
[/* Tokens. */ [[/* Tokens. */
#ifndef YYTOKENTYPE #ifndef ]b4_api_PREFIX[TOKENTYPE
# define YYTOKENTYPE # define ]b4_api_PREFIX[TOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers /* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */ know about them. */
enum yytokentype { enum ]b4_api_prefix[tokentype {
m4_map_sep([ b4_token_enum], [, ]m4_map_sep([ b4_token_enum], [,
], ],
[$@]) [$@])[
}; };
#endif #endif
])]) ]])])
# b4_token_enums_defines(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER) # b4_token_enums_defines(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
@@ -533,39 +546,39 @@ b4_locations_if([, yylocationp])[]b4_user_args[);
## -------------- ## ## -------------- ##
# b4_declare_yylstype # b4_declare_yylstype
# ------------------ # -------------------
# Declarations that might either go into the header (if --defines) or # Declarations that might either go into the header (if --defines) or
# in the parser body. Declare YYSTYPE/YYLTYPE, and yylval/yylloc. # in the parser body. Declare YYSTYPE/YYLTYPE, and yylval/yylloc.
m4_define([b4_declare_yylstype], m4_define([b4_declare_yylstype],
[[#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED [[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
]m4_ifdef([b4_stype], ]m4_ifdef([b4_stype],
[[typedef union ]b4_union_name[ [[typedef union ]b4_union_name[
{ {
]b4_user_stype[ ]b4_user_stype[
} YYSTYPE; } ]b4_api_PREFIX[STYPE;
# define YYSTYPE_IS_TRIVIAL 1]], # define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]],
[m4_if(b4_tag_seen_flag, 0, [m4_if(b4_tag_seen_flag, 0,
[[typedef int YYSTYPE; [[typedef int ]b4_api_PREFIX[STYPE;
# define YYSTYPE_IS_TRIVIAL 1]])])[ # define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]])])[
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define ]b4_api_prefix[stype ]b4_api_PREFIX[STYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1 # define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
#endif]b4_locations_if([[ #endif]b4_locations_if([[
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED #if ! defined ]b4_api_PREFIX[LTYPE && ! defined ]b4_api_PREFIX[LTYPE_IS_DECLARED
typedef struct YYLTYPE typedef struct ]b4_api_PREFIX[LTYPE
{ {
int first_line; int first_line;
int first_column; int first_column;
int last_line; int last_line;
int last_column; int last_column;
} YYLTYPE; } ]b4_api_PREFIX[LTYPE;
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ # define ]b4_api_prefix[ltype ]b4_api_PREFIX[LTYPE /* obsolescent; will be withdrawn */
# define YYLTYPE_IS_DECLARED 1 # define ]b4_api_PREFIX[LTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1 # define ]b4_api_PREFIX[LTYPE_IS_TRIVIAL 1
#endif]]) #endif]])
b4_pure_if([], [[extern YYSTYPE ]b4_prefix[lval; b4_pure_if([], [[extern ]b4_api_PREFIX[STYPE ]b4_prefix[lval;
]b4_locations_if([[extern YYLTYPE ]b4_prefix[lloc;]])])[]dnl ]b4_locations_if([[extern ]b4_api_PREFIX[LTYPE ]b4_prefix[lloc;]])])[]dnl
]) ])
# b4_declare_yydebug # b4_declare_yydebug

View File

@@ -188,6 +188,14 @@ b4_copyright([Skeleton implementation for Bison GLR parsers in C],
]b4_identification ]b4_identification
b4_percent_code_get([[top]])[ b4_percent_code_get([[top]])[
]m4_if(b4_api_prefix, [yy], [],
[[/* Substitute the type names. */
#define YYSTYPE ]b4_api_PREFIX[STYPE
#define YYSTYPE_IS_TRIVIAL ]b4_api_PREFIX[STYPE_IS_TRIVIAL
#define YYSTYPE_IS_DECLARED ]b4_api_PREFIX[STYPE_IS_DECLARED]b4_locations_if([[
#define YYLTYPE ]b4_api_PREFIX[LTYPE
#define YYLTYPE_IS_TRIVIAL ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
#define YYLTYPE_IS_DECLARED ]b4_api_PREFIX[LTYPE_IS_DECLARED]])])[
]m4_if(b4_prefix, [yy], [], ]m4_if(b4_prefix, [yy], [],
[[/* Substitute the variable and function names. */ [[/* Substitute the variable and function names. */
#define yyparse ]b4_prefix[parse #define yyparse ]b4_prefix[parse

View File

@@ -269,7 +269,7 @@ b4_copyright([Skeleton interface for Bison GLR parsers in C++],
{ {
public: public:
/// Symbol semantic values. /// Symbol semantic values.
#ifndef YYSTYPE #ifndef ]b4_api_PREFIX[STYPE
]m4_ifdef([b4_stype], ]m4_ifdef([b4_stype],
[ union semantic_type [ union semantic_type
{ {
@@ -277,9 +277,9 @@ b4_user_stype
};], };],
[m4_if(b4_tag_seen_flag, 0, [m4_if(b4_tag_seen_flag, 0,
[[ typedef int semantic_type;]], [[ typedef int semantic_type;]],
[[ typedef YYSTYPE semantic_type;]])])[ [[ typedef ]b4_api_PREFIX[STYPE semantic_type;]])])[
#else #else
typedef YYSTYPE semantic_type; typedef ]b4_api_PREFIX[STYPE semantic_type;
#endif #endif
/// Symbol locations. /// Symbol locations.
typedef ]b4_percent_define_get([[location_type]], typedef ]b4_percent_define_get([[location_type]],
@@ -350,11 +350,11 @@ b4_user_stype
b4_percent_define_flag_if([[global_tokens_and_yystype]], b4_percent_define_flag_if([[global_tokens_and_yystype]],
[b4_token_defines(b4_tokens)]) [b4_token_defines(b4_tokens)])
[ [
#ifndef YYSTYPE #ifndef ]b4_api_PREFIX[STYPE
# define YYSTYPE ]b4_namespace_ref[::]b4_parser_class_name[::semantic_type # define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class_name[::semantic_type
#endif #endif
#ifndef YYLTYPE #ifndef ]b4_api_PREFIX[LTYPE
# define YYLTYPE ]b4_namespace_ref[::]b4_parser_class_name[::location_type # define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class_name[::location_type
#endif #endif
]b4_namespace_close[ ]b4_namespace_close[

View File

@@ -69,7 +69,7 @@ b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++],
{ {
public: public:
/// Symbol semantic values. /// Symbol semantic values.
#ifndef YYSTYPE #ifndef ]b4_api_PREFIX[STYPE
]m4_ifdef([b4_stype], ]m4_ifdef([b4_stype],
[ union semantic_type [ union semantic_type
{ {
@@ -77,9 +77,9 @@ b4_user_stype
};], };],
[m4_if(b4_tag_seen_flag, 0, [m4_if(b4_tag_seen_flag, 0,
[[ typedef int semantic_type;]], [[ typedef int semantic_type;]],
[[ typedef YYSTYPE semantic_type;]])])[ [[ typedef ]b4_api_PREFIX[STYPE semantic_type;]])])[
#else #else
typedef YYSTYPE semantic_type; typedef ]b4_api_PREFIX[STYPE semantic_type;
#endif #endif
/// Symbol locations. /// Symbol locations.
typedef ]b4_percent_define_get([[location_type]], typedef ]b4_percent_define_get([[location_type]],
@@ -262,9 +262,9 @@ b4_user_stype
]b4_percent_define_flag_if([[global_tokens_and_yystype]], ]b4_percent_define_flag_if([[global_tokens_and_yystype]],
[b4_token_defines(b4_tokens) [b4_token_defines(b4_tokens)
#ifndef YYSTYPE #ifndef ]b4_api_PREFIX[STYPE
/* Redirection for backward compatibility. */ /* Redirection for backward compatibility. */
# define YYSTYPE b4_namespace_ref::b4_parser_class_name::semantic_type # define ]b4_api_PREFIX[STYPE b4_namespace_ref::b4_parser_class_name::semantic_type
#endif #endif
])[ ])[
]b4_percent_code_get([[provides]])[ ]b4_percent_code_get([[provides]])[
@@ -597,7 +597,7 @@ m4_popdef([b4_at_dollar])])dnl
{ {
YYCDEBUG << "Reading a token: "; YYCDEBUG << "Reading a token: ";
yychar = ]b4_c_function_call([yylex], [int], yychar = ]b4_c_function_call([yylex], [int],
[[YYSTYPE*], [&yylval]][]dnl [b4_api_PREFIX[STYPE*], [&yylval]][]dnl
b4_locations_if([, [[location*], [&yylloc]]])dnl b4_locations_if([, [[location*], [&yylloc]]])dnl
m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
} }

View File

@@ -307,7 +307,15 @@ b4_copyright([Bison implementation for Yacc-like parsers in C],
]b4_identification ]b4_identification
b4_percent_code_get([[top]])[]dnl b4_percent_code_get([[top]])[]dnl
m4_if(b4_prefix, [yy], [], m4_if(b4_api_prefix, [yy], [],
[[/* Substitute the type names. */
#define YYSTYPE ]b4_api_PREFIX[STYPE
#define YYSTYPE_IS_TRIVIAL ]b4_api_PREFIX[STYPE_IS_TRIVIAL
#define YYSTYPE_IS_DECLARED ]b4_api_PREFIX[STYPE_IS_DECLARED]b4_locations_if([[
#define YYLTYPE ]b4_api_PREFIX[LTYPE
#define YYLTYPE_IS_TRIVIAL ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
#define YYLTYPE_IS_DECLARED ]b4_api_PREFIX[LTYPE_IS_DECLARED]])])[
]m4_if(b4_prefix, [yy], [],
[[/* Substitute the variable and function names. */]b4_pull_if([[ [[/* Substitute the variable and function names. */]b4_pull_if([[
#define yyparse ]b4_prefix[parse]])b4_push_if([[ #define yyparse ]b4_prefix[parse]])b4_push_if([[
#define yypush_parse ]b4_prefix[push_parse]b4_pull_if([[ #define yypush_parse ]b4_prefix[push_parse]b4_pull_if([[

View File

@@ -5154,22 +5154,6 @@ grammar does not use it, using @samp{%locations} allows for more
accurate syntax error messages. accurate syntax error messages.
@end deffn @end deffn
@deffn {Directive} %name-prefix "@var{prefix}"
Rename the external symbols used in the parser so that they start with
@var{prefix} instead of @samp{yy}. The precise list of symbols renamed
in C parsers
is @code{yyparse}, @code{yylex}, @code{yyerror}, @code{yynerrs},
@code{yylval}, @code{yychar}, @code{yydebug}, and
(if locations are used) @code{yylloc}. If you use a push parser,
@code{yypush_parse}, @code{yypull_parse}, @code{yypstate},
@code{yypstate_new} and @code{yypstate_delete} will
also be renamed. For example, if you use @samp{%name-prefix "c_"}, the
names become @code{c_parse}, @code{c_lex}, and so on.
For C++ parsers, see the @code{%define namespace} documentation in this
section.
@xref{Multiple Parsers, ,Multiple Parsers in the Same Program}.
@end deffn
@ifset defaultprec @ifset defaultprec
@deffn {Directive} %no-default-prec @deffn {Directive} %no-default-prec
Do not assign a precedence to rules lacking an explicit @code{%prec} Do not assign a precedence to rules lacking an explicit @code{%prec}
@@ -5317,8 +5301,23 @@ Unaccepted @var{variable}s produce an error.
Some of the accepted @var{variable}s are: Some of the accepted @var{variable}s are:
@itemize @bullet @itemize @bullet
@c ================================================== api.prefix
@item @code{api.prefix}
@findex %define api.prefix
@itemize @bullet
@item Language(s): All
@item Purpose: Rename exported symbols
@xref{Multiple Parsers, ,Multiple Parsers in the Same Program}.
@item Accepted Values: String
@item Default Value: @code{yy}
@end itemize
@c ================================================== api.pure @c ================================================== api.pure
@item api.pure @item @code{api.pure}
@findex %define api.pure @findex %define api.pure
@itemize @bullet @itemize @bullet
@@ -5332,7 +5331,9 @@ Some of the accepted @var{variable}s are:
@item Default Value: @code{false} @item Default Value: @code{false}
@end itemize @end itemize
@item api.push-pull @c ================================================== api.push-pull
@item @code{api.push-pull}
@findex %define api.push-pull @findex %define api.push-pull
@itemize @bullet @itemize @bullet
@@ -5350,7 +5351,7 @@ More user feedback will help to stabilize it.)
@c ================================================== lr.default-reductions @c ================================================== lr.default-reductions
@item lr.default-reductions @item @code{lr.default-reductions}
@findex %define lr.default-reductions @findex %define lr.default-reductions
@itemize @bullet @itemize @bullet
@@ -5371,7 +5372,7 @@ feedback will help to stabilize it.)
@c ============================================ lr.keep-unreachable-states @c ============================================ lr.keep-unreachable-states
@item lr.keep-unreachable-states @item @code{lr.keep-unreachable-states}
@findex %define lr.keep-unreachable-states @findex %define lr.keep-unreachable-states
@itemize @bullet @itemize @bullet
@@ -5384,7 +5385,7 @@ remain in the parser tables. @xref{Unreachable States}.
@c ================================================== lr.type @c ================================================== lr.type
@item lr.type @item @code{lr.type}
@findex %define lr.type @findex %define lr.type
@itemize @bullet @itemize @bullet
@@ -5399,7 +5400,9 @@ More user feedback will help to stabilize it.)
@item Default Value: @code{lalr} @item Default Value: @code{lalr}
@end itemize @end itemize
@item namespace @c ================================================== namespace
@item @code{namespace}
@findex %define namespace @findex %define namespace
@itemize @itemize
@@ -5452,7 +5455,7 @@ The parser namespace is @code{foo} and @code{yylex} is referenced as
@end itemize @end itemize
@c ================================================== parse.lac @c ================================================== parse.lac
@item parse.lac @item @code{parse.lac}
@findex %define parse.lac @findex %define parse.lac
@itemize @itemize
@@ -5585,34 +5588,62 @@ of the standard Bison skeletons.
@section Multiple Parsers in the Same Program @section Multiple Parsers in the Same Program
Most programs that use Bison parse only one language and therefore contain 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 only one Bison parser. But what if you want to parse more than one language
language with the same program? Then you need to avoid a name conflict with the same program? Then you need to avoid name conflicts between
between different definitions of @code{yyparse}, @code{yylval}, and so on. different definitions of functions and variables such as @code{yyparse},
@code{yylval}. To use different parsers from the same compilation unit, you
also need to avoid conflicts on types and macros (e.g., @code{YYSTYPE})
exported in the generated header.
The easy way to do this is to use the option @samp{-p @var{prefix}} The easy way to do this is to define the @code{%define} variable
(@pxref{Invocation, ,Invoking Bison}). This renames the interface @code{api.prefix} (possibly using the option
functions and variables of the Bison parser to start with @var{prefix} @samp{-Dapi.prefix=@var{prefix}}, see @ref{Invocation, ,Invoking Bison}).
instead of @samp{yy}. You can use this to give each parser distinct This renames the interface functions and variables of the Bison parser to
names that do not conflict. start with @var{prefix} instead of @samp{yy}, and all the macros to start by
@var{PREFIX} (i.e., @var{prefix} upper cased) instead of @samp{YY}. You can
use this to give each parser distinct names that do not conflict.
The precise list of symbols renamed is @code{yyparse}, @code{yylex}, The renamed symbols include @code{yyparse}, @code{yylex}, @code{yyerror},
@code{yyerror}, @code{yynerrs}, @code{yylval}, @code{yylloc}, @code{yynerrs}, @code{yylval}, @code{yylloc}, @code{yychar} and
@code{yychar} and @code{yydebug}. If you use a push parser, @code{yydebug}. If you use a push parser, @code{yypush_parse},
@code{yypush_parse}, @code{yypull_parse}, @code{yypstate}, @code{yypull_parse}, @code{yypstate}, @code{yypstate_new} and
@code{yypstate_new} and @code{yypstate_delete} will also be renamed. @code{yypstate_delete} will also be renamed. The renamed macros include
For example, if you use @samp{-p c}, the names become @code{cparse}, @code{YYSTYPE}, @code{YYSTYPE_IS_TRIVIAL}, @code{YYSTYPE_IS_DECLARED},
@code{clex}, and so on. @code{YYLTYPE}, @code{YYLTYPE_IS_TRIVIAL}, and @code{YYLTYPE_IS_DECLARED}.
@strong{All the other variables and macros associated with Bison are not For example, if you use @samp{%define api.prefix c}, the names become
renamed.} These others are not global; there is no conflict if the same @code{cparse}, @code{clex}, @dots{}, @code{CSTYPE}, @code{CLTYPE}, and so
name is used in different parsers. For example, @code{YYSTYPE} is not on.
renamed, but defining this in different ways in different parsers causes
no trouble (@pxref{Value Type, ,Data Types of Semantic Values}).
The @samp{-p} option works by adding macro definitions to the The @code{%define} variable @code{api.prefix} works in two different ways.
beginning of the parser implementation file, defining @code{yyparse} In the implementation file, it works by adding macro definitions to the
as @code{@var{prefix}parse}, and so on. This effectively substitutes beginning of the parser implementation file, defining @code{yyparse} as
one name for the other in the entire parser implementation file. @code{@var{prefix}parse}, and so on:
@example
#define YYSTYPE CTYPE
#define yyparse cparse
#define yylval clval
...
YYSTYPE yylval;
int yyparse (void);
@end example
This effectively substitutes one name for the other in the entire parser
implementation file, thus the ``original'' names (@code{yylex},
@code{YYSTYPE}, @dots{}) are also usable in the parser implementation file.
However, in the parser header file, the symbols are defined renamed, for
instance:
@example
extern CSTYPE clval;
int cparse (void);
@end example
Previously, a similar feature was provided by the obsoleted directive
@code{%name-prefix} (@pxref{Table of Symbols, ,Bison Symbols}) and option
@code{--name-prefix} (@pxref{Bison Options}).
@node Interface @node Interface
@chapter Parser C-Language Interface @chapter Parser C-Language Interface
@@ -8924,8 +8955,9 @@ Pretend that @code{%locations} was specified. @xref{Decl Summary}.
@item -p @var{prefix} @item -p @var{prefix}
@itemx --name-prefix=@var{prefix} @itemx --name-prefix=@var{prefix}
Pretend that @code{%name-prefix "@var{prefix}"} was specified. Pretend that @code{%name-prefix "@var{prefix}"} was specified (@pxref{Decl
@xref{Decl Summary}. Summary}). Obsoleted by @code{-Dapi.prefix=@var{prefix}}. @xref{Multiple
Parsers, ,Multiple Parsers in the Same Program}.
@item -l @item -l
@itemx --no-lines @itemx --no-lines
@@ -11054,9 +11086,24 @@ function is applied to the two semantic values to get a single result.
@end deffn @end deffn
@deffn {Directive} %name-prefix "@var{prefix}" @deffn {Directive} %name-prefix "@var{prefix}"
Bison declaration to rename the external symbols. @xref{Decl Summary}. Obsoleted by the @code{%define} variable @code{api.prefix} (@pxref{Multiple
Parsers, ,Multiple Parsers in the Same Program}).
Rename the external symbols (variables and functions) used in the parser so
that they start with @var{prefix} instead of @samp{yy}. Contrary to
@code{api.prefix}, do no rename types and macros.
The precise list of symbols renamed in C parsers is @code{yyparse},
@code{yylex}, @code{yyerror}, @code{yynerrs}, @code{yylval}, @code{yychar},
@code{yydebug}, and (if locations are used) @code{yylloc}. If you use a
push parser, @code{yypush_parse}, @code{yypull_parse}, @code{yypstate},
@code{yypstate_new} and @code{yypstate_delete} will also be renamed. For
example, if you use @samp{%name-prefix "c_"}, the names become
@code{c_parse}, @code{c_lex}, and so on. For C++ parsers, see the
@code{%define namespace} documentation in this section.
@end deffn @end deffn
@ifset defaultprec @ifset defaultprec
@deffn {Directive} %no-default-prec @deffn {Directive} %no-default-prec
Do not assign a precedence to rules that lack an explicit @samp{%prec} Do not assign a precedence to rules that lack an explicit @samp{%prec}

View File

@@ -311,10 +311,11 @@ Parser:\n\
-S, --skeleton=FILE specify the skeleton to use\n\ -S, --skeleton=FILE specify the skeleton to use\n\
-t, --debug instrument the parser for debugging\n\ -t, --debug instrument the parser for debugging\n\
--locations enable location support\n\ --locations enable location support\n\
-D, --define=NAME[=VALUE] similar to `%define NAME \"VALUE\"'\n\ -D, --define=NAME[=VALUE] similar to '%define NAME \"VALUE\"'\n\
-F, --force-define=NAME[=VALUE] override `%define NAME \"VALUE\"'\n\ -F, --force-define=NAME[=VALUE] override '%define NAME \"VALUE\"'\n\
-p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\ -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\
-l, --no-lines don't generate `#line' directives\n\ deprecated by '-Dapi.prefix=PREFIX'\n\
-l, --no-lines don't generate '#line' directives\n\
-k, --token-table include a table of token names\n\ -k, --token-table include a table of token names\n\
\n\ \n\
"), stdout); "), stdout);

View File

@@ -117,3 +117,93 @@ AT_COMPILE([caller], [caller.o input.o])
AT_PARSER_CHECK([./caller]) AT_PARSER_CHECK([./caller])
AT_CLEANUP AT_CLEANUP
## ----------------- ##
## Several parsers. ##
## ----------------- ##
AT_SETUP([Several parsers])
# AT_DATA_GRAMMAR_SEVERAL([PREFIX], [DIRECTIVES])
# -----------------------------------------------
# Generate and compile to *.o. Make sure there is no YY* nor yy* in
# the header (but YYDEBUG and YYPARSE_PARAM).
m4_define([AT_DATA_GRAMMAR_SEVERAL],
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix "$1_" $2])
AT_DATA_GRAMMAR([AT_SKEL_CC_IF([$1.yy], [$1.y])],
[[%define api.prefix "$1_"
$2
%union
{
int integer;
}
%{
#include <stdio.h>
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
%}
%%
exp:
'x' '1' { printf ("x1\n"); }
| 'x' '2' { printf ("x2\n"); }
| 'x' '3' { printf ("x3\n"); }
| 'x' '4' { printf ("x4\n"); }
| 'x' '5' { printf ("x5\n"); }
| 'x' '6' { printf ("x6\n"); }
;
%%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE(["$1"])[
]])
AT_BISON_CHECK([-d -o AT_SKEL_CC_IF([$1.cc $1.yy], [$1.c $1.y])])
# C++ output relies on namespaces and still uses yy a lot.
AT_SKEL_CC_IF([],
[AT_CHECK([$EGREP -i yy $1.h | $EGREP -v 'YY(DEBUG|PARSE_PARAM)'], [1])])
AT_LANG_COMPILE([$1.o])
AT_BISON_OPTION_POPDEFS
])
AT_DATA([main.cc],
[[extern "C"
{
#include "x1.h"
#include "x2.h"
#include "x3.h"
#include "x4.h"
}
#include "x5.hh"
//#include "x6.hh"
int
main (void)
{
int errs = 0;
errs += x1_parse();
errs += x2_parse();
errs += x3_parse();
errs += x4_parse();
x5_::parser p5;
errs += p5.parse();
// errs += x6_parse();
return !!errs;
}
]])
AT_DATA_GRAMMAR_SEVERAL([x1], [])
AT_DATA_GRAMMAR_SEVERAL([x2], [%locations %debug])
AT_DATA_GRAMMAR_SEVERAL([x3], [%glr-parser])
AT_DATA_GRAMMAR_SEVERAL([x4], [%locations %debug %glr-parser])
AT_DATA_GRAMMAR_SEVERAL([x5], [%locations %debug %language "c++"])
#AT_DATA_GRAMMAR_SEVERAL([x6], [%locations %language "c++"])
AT_COMPILE_CXX([parser], [x1.o x2.o x3.o x4.o x5.o main.cc])
AT_CHECK([./parser], [0],
[[x1
x2
x3
x4
x5
]])
AT_CLEANUP

View File

@@ -145,6 +145,8 @@ m4_pushdef([AT_API_prefix],
[m4_bmatch([$3], [%define api\.prefix ".*"], [m4_bmatch([$3], [%define api\.prefix ".*"],
[m4_bregexp([$3], [%define api\.prefix "\([^""]*\)"], [\1])], [m4_bregexp([$3], [%define api\.prefix "\([^""]*\)"], [\1])],
[yy])]) [yy])])
m4_pushdef([AT_API_PREFIX],
[m4_toupper(AT_API_prefix)])
# yyerror receives the location if %location & %pure & (%glr or %parse-param). # yyerror receives the location if %location & %pure & (%glr or %parse-param).
m4_pushdef([AT_YYERROR_ARG_LOC_IF], m4_pushdef([AT_YYERROR_ARG_LOC_IF],
[AT_GLR_OR_PARAM_IF([AT_PURE_AND_LOC_IF([$1], [$2])], [AT_GLR_OR_PARAM_IF([AT_PURE_AND_LOC_IF([$1], [$2])],
@@ -165,10 +167,10 @@ m4_pushdef([AT_PURE_LEX_IF],
m4_pushdef([AT_YYSTYPE], m4_pushdef([AT_YYSTYPE],
[AT_SKEL_CC_IF([AT_NAME_PREFIX[::parser::semantic_type]], [AT_SKEL_CC_IF([AT_NAME_PREFIX[::parser::semantic_type]],
[[YYSTYPE]])]) [AT_API_PREFIX[STYPE]])])
m4_pushdef([AT_YYLTYPE], m4_pushdef([AT_YYLTYPE],
[AT_SKEL_CC_IF([AT_NAME_PREFIX[::parser::location_type]], [AT_SKEL_CC_IF([AT_NAME_PREFIX[::parser::location_type]],
[[YYLTYPE]])]) [AT_API_PREFIX[LTYPE]])])
AT_PURE_LEX_IF( AT_PURE_LEX_IF(
@@ -221,6 +223,7 @@ m4_popdef([AT_LOC])
m4_popdef([AT_PURE_LEX_IF]) m4_popdef([AT_PURE_LEX_IF])
m4_popdef([AT_YYERROR_SEES_LOC_IF]) m4_popdef([AT_YYERROR_SEES_LOC_IF])
m4_popdef([AT_YYERROR_ARG_LOC_IF]) m4_popdef([AT_YYERROR_ARG_LOC_IF])
m4_popdef([AT_API_PREFIX])
m4_popdef([AT_API_prefix]) m4_popdef([AT_API_prefix])
m4_popdef([AT_NAME_PREFIX]) m4_popdef([AT_NAME_PREFIX])
m4_popdef([AT_GLR_OR_PARAM_IF]) m4_popdef([AT_GLR_OR_PARAM_IF])