mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-19 09:13:04 +00:00
Merge remote-tracking branch 'origin/maint'
* origin/maint: NEWS: spell check. api.prefix. Conflicts: data/c.m4 data/glr.cc data/lalr1.cc doc/bison.texi
This commit is contained in:
66
NEWS
66
NEWS
@@ -129,7 +129,7 @@ GNU Bison NEWS
|
|||||||
*** K&C parsers
|
*** K&C parsers
|
||||||
|
|
||||||
Support for generating parsers in K&R C will be removed. Parsers
|
Support for generating parsers in K&R C will be removed. Parsers
|
||||||
generated for C supprt ISO C90, and are tested with ISO C99 and ISO C11
|
generated for C support ISO C90, and are tested with ISO C99 and ISO C11
|
||||||
compilers.
|
compilers.
|
||||||
|
|
||||||
*** Features deprecated since Bison 1.875
|
*** Features deprecated since Bison 1.875
|
||||||
@@ -156,7 +156,7 @@ GNU Bison NEWS
|
|||||||
*** Guards (yacc.c, glr.c, glr.cc)
|
*** Guards (yacc.c, glr.c, glr.cc)
|
||||||
|
|
||||||
The generated headers are now guarded, as is already the case for C++
|
The generated headers are now guarded, as is already the case for C++
|
||||||
parsers (lalr1.cc). For intance, with --defines=foo.h:
|
parsers (lalr1.cc). For instance, with --defines=foo.h:
|
||||||
|
|
||||||
#ifndef YY_FOO_H
|
#ifndef YY_FOO_H
|
||||||
# define YY_FOO_H
|
# define YY_FOO_H
|
||||||
@@ -189,6 +189,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:
|
||||||
@@ -1357,7 +1411,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
- a single argument only can be added,
|
- a single argument only can be added,
|
||||||
- their types are weak (void *),
|
- their types are weak (void *),
|
||||||
- this context is not passed to anciliary functions such as yyerror,
|
- this context is not passed to ancillary functions such as yyerror,
|
||||||
- only yacc.c parsers support them.
|
- only yacc.c parsers support them.
|
||||||
|
|
||||||
The new %parse-param/%lex-param directives provide a more precise control.
|
The new %parse-param/%lex-param directives provide a more precise control.
|
||||||
@@ -1855,9 +1909,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
LocalWords: struct yystype DJGPP lex param Haible NUM alloca YYSTACK NUL goto
|
LocalWords: struct yystype DJGPP lex param Haible NUM alloca YYSTACK NUL goto
|
||||||
LocalWords: YYMAXDEPTH Unescaped UCNs YYLTYPE's yyltype typedefs inline Yaccs
|
LocalWords: YYMAXDEPTH Unescaped UCNs YYLTYPE's yyltype typedefs inline Yaccs
|
||||||
LocalWords: Heriyanto Reenable dprec Hilfinger Eggert MYEOF Folle Menezes EOF
|
LocalWords: Heriyanto Reenable dprec Hilfinger Eggert MYEOF Folle Menezes EOF
|
||||||
LocalWords: Lackovic define's itemset Groff Gettext malloc NEWS'ed YYDEBUG
|
LocalWords: Lackovic define's itemset Groff Gettext malloc NEWS'ed YYDEBUG YY
|
||||||
LocalWords: namespaces strerror const autoconfiguration Dconst Autoconf's FDL
|
LocalWords: namespaces strerror const autoconfiguration Dconst Autoconf's FDL
|
||||||
LocalWords: Automake TMPDIR LESSEQ
|
LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh
|
||||||
|
LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf
|
||||||
|
LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp
|
||||||
|
|
||||||
Local Variables:
|
Local Variables:
|
||||||
mode: outline
|
mode: outline
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ m4_ifdef([b4_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;]])])])
|
||||||
|
|
||||||
|
|
||||||
# b4_public_types_declare
|
# b4_public_types_declare
|
||||||
@@ -124,10 +124,10 @@ m4_ifdef([b4_stype],
|
|||||||
# Define the public types: token, semantic value, location, and so forth.
|
# Define the public types: token, semantic value, location, and so forth.
|
||||||
# Depending on %define token_lex, may be output in the header or source file.
|
# Depending on %define token_lex, may be output in the header or source file.
|
||||||
m4_define([b4_public_types_declare],
|
m4_define([b4_public_types_declare],
|
||||||
[[#ifndef YYSTYPE
|
[[#ifndef ]b4_api_PREFIX[STYPE
|
||||||
]b4_semantic_type_declare[
|
]b4_semantic_type_declare[
|
||||||
#else
|
#else
|
||||||
typedef YYSTYPE semantic_type;
|
typedef ]b4_api_PREFIX[STYPE semantic_type;
|
||||||
#endif]b4_locations_if([
|
#endif]b4_locations_if([
|
||||||
/// Symbol locations.
|
/// Symbol locations.
|
||||||
typedef b4_percent_define_get([[location_type]],
|
typedef b4_percent_define_get([[location_type]],
|
||||||
|
|||||||
67
data/c.m4
67
data/c.m4
@@ -107,11 +107,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. ##
|
||||||
@@ -267,18 +280,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)
|
||||||
@@ -570,39 +583,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
|
||||||
|
|||||||
@@ -196,6 +196,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
|
||||||
|
|||||||
@@ -321,11 +321,11 @@ b4_copyright([Skeleton interface for Bison GLR parsers in C++],
|
|||||||
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[
|
||||||
|
|||||||
@@ -342,9 +342,9 @@ b4_public_types_define])[
|
|||||||
]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]])[
|
||||||
@@ -734,7 +734,7 @@ m4_popdef([b4_at_dollar])])dnl
|
|||||||
[ yyla = b4_c_function_call([yylex], [symbol_type],
|
[ yyla = b4_c_function_call([yylex], [symbol_type],
|
||||||
m4_ifdef([b4_lex_param], b4_lex_param));],
|
m4_ifdef([b4_lex_param], b4_lex_param));],
|
||||||
[ yyla.type = yytranslate_ (b4_c_function_call([yylex], [int],
|
[ yyla.type = yytranslate_ (b4_c_function_call([yylex], [int],
|
||||||
[[YYSTYPE*], [&yyla.value]][]dnl
|
[b4_api_PREFIX[STYPE*], [&yyla.value]][]dnl
|
||||||
b4_locations_if([, [[location*], [&yyla.location]]])dnl
|
b4_locations_if([, [[location*], [&yyla.location]]])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
@@ -308,7 +308,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([[
|
||||||
|
|||||||
112
doc/bison.texi
112
doc/bison.texi
@@ -5452,6 +5452,20 @@ The parser namespace is @code{foo} and @code{yylex} is referenced as
|
|||||||
@c namespace
|
@c namespace
|
||||||
|
|
||||||
|
|
||||||
|
@c ================================================== api.prefix
|
||||||
|
@item 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 api.pure
|
||||||
@@ -5830,34 +5844,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
|
||||||
@@ -9238,8 +9280,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
|
||||||
@@ -11701,9 +11744,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}
|
||||||
|
|||||||
@@ -305,10 +305,11 @@ Parser:\n\
|
|||||||
-t, --debug instrument the parser for tracing\n\
|
-t, --debug instrument the parser for tracing\n\
|
||||||
same as `-Dparse.trace'\n\
|
same as `-Dparse.trace'\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
|
||||||
|
|||||||
@@ -148,6 +148,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])],
|
||||||
@@ -168,10 +170,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(
|
||||||
@@ -226,6 +228,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