mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-23 03:03:02 +00:00
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:
54
NEWS
54
NEWS
@@ -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:
|
||||||
|
|||||||
67
data/c.m4
67
data/c.m4
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
14
data/glr.cc
14
data/glr.cc
@@ -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[
|
||||||
|
|||||||
@@ -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))[;
|
||||||
}
|
}
|
||||||
|
|||||||
10
data/yacc.c
10
data/yacc.c
@@ -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([[
|
||||||
|
|||||||
147
doc/bison.texi
147
doc/bison.texi
@@ -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}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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])
|
||||||
|
|||||||
Reference in New Issue
Block a user