* Noteworthy changes in release ?.? (????-??-??) [?]
- %lex-param {arg1_type *arg1}
- %lex-param {arg2_type *arg2}
- %parse-param {arg1_type *arg1}
- %parse-param {arg2_type *arg2}
+** Additional yylex/yyparse arguments
+
+ The new directive %param declare additional argument to both yylex
+ and yyparse. The %lex-param, %parse-param, and %param directives
+ support one or more arguments. Instead of
+
- %param {arg1_type *arg1} {arg2_type *arg2}
++ %lex-param {arg1_type *arg1}
++ %lex-param {arg2_type *arg2}
++ %parse-param {arg1_type *arg1}
++ %parse-param {arg2_type *arg2}
+
+ one may now declare
+
- %token FILE for ERROR
- %define api.tokens.prefix "TOK_"
- %%
- start: FILE for ERROR;
++ %param {arg1_type *arg1} {arg2_type *arg2}
+
+** Java skeleton improvements
+
+ The constants for token names were moved to the Lexer interface.
+ Also, it is possible to add code to the parser's constructors using
+ "%code init" and "%define init_throws".
+
+** C++ skeleton improvements
+
+ The C++ parser features a syntax_error exception, which can be
+ thrown from the scanner or from user rules to raise syntax errors.
+ This facilitates reporting errors caught in sub-functions (e.g.,
+ rejecting too large integral literals from a conversion function
+ used by the scanner, or rejecting invalid combinations from a
+ factory invoked by the user actions).
+
+** Variable api.tokens.prefix
+
+ The variable api.tokens.prefix changes the way tokens are identified in
+ the generated files. This is especially useful to avoid collisions
+ with identifiers in the target language. For instance
+
++ %token FILE for ERROR
++ %define api.tokens.prefix "TOK_"
++ %%
++ start: FILE for ERROR;
+
+ will generate the definition of the symbols TOK_FILE, TOK_for, and
+ TOK_ERROR in the generated sources. In particular, the scanner must
+ use these prefixed token names, although the grammar itself still
+ uses the short names (as in the sample rule given above).
+
+** Variable api.namespace
+
+ The "namespace" variable is renamed "api.namespace". Backward
+ compatibility is ensured, but upgrading is recommended.
+
+** Variable parse.error
+
+ The variable error controls the verbosity of error messages. The
+ use of the %error-verbose directive is deprecated in favor of
+ %define parse.error "verbose".
+
+** Semantic predicates
+
+ The new, experimental, semantic-predicate feature allows actions of
+ the form %?{ BOOLEAN-EXPRESSION }, which cause syntax errors (as for
+ YYERROR) if the expression evaluates to 0, and are evaluated immediately
+ in GLR parsers, rather than being deferred. The result is that they
+ allow the programmer to prune possible parses based on the values of
+ runtime expressions.
+
++* Noteworthy changes in release ?.? (????-??-??) [?]
++
+ ** Future changes:
+
+ The next major release will drop support for generating parsers in K&R C,
+ and remove the definition of yystype (removal announced since Bison
+ 1.875).
+
+ ** The generated header is included (yacc.c)
+
+ Instead of duplicating the content of the generated header (definition of
+ YYSTYPE, yyltype etc.), the generated parser now includes it, as was
+ already the case for GLR or C++ parsers.
+
+ ** Headers (yacc.c, glr.c, glr.cc)
+
+ *** Guards
+
+ The generated headers are now guarded, as is already the case for C++
+ parsers (lalr1.cc). For intance, with --defines=foo.h:
+
+ #ifndef YY_FOO_H
+ # define YY_FOO_H
+ ...
+ #endif /* !YY_FOO_H */
+
+ *** New declarations
+
+ The generated header now declares yydebug and yyparse. Both honor
+ --name-prefix=bar_, and yield
+
+ int bar_parse (void);
+
+ rather than
+
+ #define yyparse bar_parse
+ int yyparse (void);
+
+ in order to facilitate the inclusion of several parser headers inside a
+ single compilation unit.
+
* Noteworthy changes in release 2.5.1 (2012-06-05) [stable]
** Future changes:
# define YYLTYPE_IS_TRIVIAL 1
#endif]])
])
-# define YYDEBUG ]b4_debug_flag[
+
+ # b4_declare_yydebug
+ # ------------------
+ m4_define([b4_declare_yydebug],
+ [[/* Enabling traces. */
+ #ifndef YYDEBUG
++# define YYDEBUG ]b4_parse_trace_if([1], [0])[
+ #endif
+ #if YYDEBUG
+ extern int ]b4_prefix[debug;
+ #endif][]dnl
+ ])
]b4_null_define[
]b4_defines_if([[#include "@basename(]b4_spec_defines_file[@)"]],
- [b4_shared_declarations])[
+ [b4_shared_declarations])[
- /* Enabling traces. */
- #ifndef YYDEBUG
- # define YYDEBUG ]b4_parse_trace_if([1], [0])[
- #endif
-
/* Enabling verbose error messages. */
#ifdef YYERROR_VERBOSE
# undef YYERROR_VERBOSE
{
]b4_conflicting_rules[
};
-
-static const ]b4_int_type_for([b4_check])[ yycheck[] =
-{
- ]b4_check[
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
-static const ]b4_int_type_for([b4_stos])[ yystos[] =
-{
- ]b4_stos[
-};
-
\f
- /* Prevent warning if -Wmissing-prototypes. */
- ]b4_c_ansi_function_decl([yyparse], [int], b4_parse_param)[
-
/* Error token number */
#define YYTERROR 1
return YYID (yyresult);
}
-
-]b4_epilogue
+]b4_epilogue[]dnl
b4_defines_if(
[@output(b4_spec_defines_file@)@
- b4_copyright([Bison interface for Yacc-like parsers in C])dnl
-
- b4_percent_code_get([[requires]])[]dnl
-b4_copyright([Bison interface for Yacc-like parsers in C],
- [1984, 1989-1990, 2000-2012])[
++b4_copyright([Bison interface for Yacc-like parsers in C])[
- b4_token_enums_defines(b4_tokens)[
- ]b4_declare_yylstype[
+ ]b4_cpp_guard_open([b4_spec_defines_file])[
+ ]b4_shared_declarations[
]b4_pure_if([], [[extern YYSTYPE ]b4_prefix[lval;
- ]b4_locations_if([[extern YYLTYPE ]b4_prefix[lloc;]])])dnl
- b4_push_if([[
- #ifndef YYPUSH_DECLS
- # define YYPUSH_DECLS
- struct ]b4_prefix[pstate;
- typedef struct ]b4_prefix[pstate ]b4_prefix[pstate;
- enum { YYPUSH_MORE = 4 };
- ]b4_pull_if([b4_c_function_decl([b4_prefix[parse]], [[int]], b4_parse_param)
- ])b4_c_function_decl([b4_prefix[push_parse]], [[int]],
- [[b4_prefix[pstate *yyps]], [[yyps]]]b4_pure_if([,
- [[[int yypushed_char]], [[yypushed_char]]],
- [[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([,
- [[[YYLTYPE const *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
- b4_parse_param]))
- b4_pull_if([b4_c_function_decl([b4_prefix[pull_parse]], [[int]],
- [[b4_prefix[pstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [,
- b4_parse_param]))])
- b4_c_function_decl([b4_prefix[pstate_new]], [b4_prefix[pstate *]],
- [[[void]], []])
- b4_c_function_decl([b4_prefix[pstate_delete]], [[void]],
- [[b4_prefix[pstate *yyps]], [[yyps]]])[
- #endif
- ]])
- b4_percent_code_get([[provides]])[]dnl
- ])dnl b4_defines_if
+ ]b4_locations_if([[extern YYLTYPE ]b4_prefix[lloc;]])])[
+ ]b4_cpp_guard_close([b4_spec_defines_file])[
+ ]])dnl b4_defines_if
m4_divert_pop(0)
+m4_popdef([b4_copyright_years])
# instead of being attached to the empty rule dedicated to this
# action.
+ AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([[input.y]],
-[[%error-verbose
+[[%define parse.error verbose
%debug
%{
- # include <stdio.h>
- # include <stdlib.h>
- static void yyerror (const char *msg);
- static int yylex (void);
+ ]AT_YYERROR_DECLARE[
+ ]AT_YYLEX_DECLARE[
%}
%%
exp: { putchar ('0'); }
AT_SETUP([Exotic Dollars])
+ AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([[input.y]],
-[[%error-verbose
+[[%define parse.error verbose
%debug
%{
- # include <stdio.h>
- # include <stdlib.h>
- static void yyerror (const char *msg);
- static int yylex (void);
+ ]AT_YYERROR_DECLARE[
+ ]AT_YYLEX_DECLARE[
# define USE(Var)
%}
AT_DATA_GRAMMAR([[input.y]],
[[
%{
-#include <stdio.h>
+# include <stdio.h>
- static int yylex (void);
- static void yyerror (char const *msg);
+ ]AT_YYERROR_DECLARE[
+ ]AT_YYLEX_DECLARE[
typedef struct { int val; } stype;
# define YYSTYPE stype
%}
# called for $end, and that $$ and @$ work correctly.
AT_SETUP([Default tagless %printer and %destructor])
-
+ AT_BISON_OPTION_PUSHDEFS([%locations])
AT_DATA_GRAMMAR([[input.y]],
-[[%error-verbose
+[[%define parse.error verbose
%debug
%locations
%initial-action {
## ------------------------------------------------------ ##
AT_SETUP([Default tagged and per-type %printer and %destructor])
-
+ AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([[input.y]],
-[[%error-verbose
+[[%define parse.error verbose
%debug
%{
[m4_pushdef([kind], []) m4_pushdef([not_kind], [*])],
[m4_pushdef([kind], [*]) m4_pushdef([not_kind], [])])
+ AT_BISON_OPTION_PUSHDEFS([%locations])
AT_DATA_GRAMMAR([[input]]$1[[.y]],
-[[%error-verbose
+[[%define parse.error verbose
%debug
%locations
%initial-action {
/* A C++ error reporting function. */
void
-AT_NAME_PREFIX::parser::error (const location_type& l, const std::string& m)
+AT_NAME_PREFIX::parser::error (AT_LOCATION_IF([const location_type& l, ])const std::string& m)
{
- (void) l;
std::cerr << AT_LOCATION_IF([l << ": " << ])m << std::endl;
}
-
- /* A C++ yyparse that simulates the C signature. */
- int
- yyparse (AT_PARAM_IF([semantic_value *result, int *count]))
- {
- AT_NAME_PREFIX::parser parser[]AT_PARAM_IF([ (result, count)]);
- #if YYDEBUG
- parser.set_debug_level (1);
- #endif
- return parser.parse ();
- }
],
[/* A C error reporting function. */
static void
yylval = value_as_yystype (input[toknum]);
return input[toknum++];
}
-
- static void
- yyerror (const char *msg)
- {
- fprintf (stderr, "%s\n", msg);
- }
]])
-# Pacify Emacs' font-lock-mode: "
+# Pacify Emacs'font-lock-mode: "
AT_DATA([main.c],
[[typedef int value;
[m4_bmatch([$3], [%glr-parser\|%parse-param], [$1], [$2])])
m4_pushdef([AT_NAME_PREFIX],
[m4_bmatch([$3], [%name-prefix ".*"],
- [m4_bregexp([$3], [name-prefix "\([^"]*\)"], [\1])],
+ [m4_bregexp([$3], [name-prefix "\([^""]*\)"], [\1])],
+ [yy])])
+ m4_pushdef([AT_API_PREFIX],
+ [m4_bmatch([$3], [%define api\.prefix ".*"],
+ [m4_bregexp([$3], [%define api\.prefix "\([^""]*\)"], [\1])],
[yy])])
+m4_pushdef([AT_TOKEN_PREFIX],
+[m4_bmatch([$3], [%define api.tokens.prefix ".*"],
+ [m4_bregexp([$3], [%define api.tokens.prefix "\(.*\)"], [\1])])])
# yyerror receives the location if %location & %pure & (%glr or %parse-param).
m4_pushdef([AT_YYERROR_ARG_LOC_IF],
[AT_GLR_OR_PARAM_IF([AT_PURE_AND_LOC_IF([$1], [$2])],
# AT_SKEL_JAVA_IF.
m4_define([AT_FULL_COMPILE], [
AT_SKEL_JAVA_IF([
- AT_BISON_CHECK([[-o ]$1[.java ]$1[.y]])
- AT_JAVA_COMPILE([$1[.java]]m4_ifval($2,
- [[$1[.java ]$1[-]$2[.java]]]))
+ AT_BISON_CHECK([-o $1.java $1.y])
+ AT_JAVA_COMPILE([$1.java],
+ m4_join([ ],
+ [$1.java],
+ m4_ifval($2, [[$1-$2.java]]),
+ m4_ifval($3, [[$1-$3.java]])))
], [
AT_SKEL_CC_IF([
- AT_BISON_CHECK([[-o ]$1[.cc ]$1[.y]])
- AT_COMPILE_CXX([$1]m4_ifval($2, [, [$1[.cc ]$1[-]$2[.cc]]]))
+ AT_BISON_CHECK([-o $1.cc $1.y])
+ AT_COMPILE_CXX([$1],
+ m4_join([ ],
+ [$1.cc],
+ m4_ifval($2, [[$1-$2.cc]]),
+ m4_ifval($3, [[$1-$3.cc]])))
], [
- AT_BISON_CHECK([[-o ]$1[.c ]$1[.y]])
- AT_COMPILE([$1]m4_ifval($2, [, [$1[.c ]$1[-]$2[.c]]]))
+ AT_BISON_CHECK([-o $1.c $1.y])
+ AT_COMPILE([$1],
+ m4_join([ ],
- [$1.c],
++ [$1.c],
+ m4_ifval($2, [[$1-$2.c]]),
+ m4_ifval($3, [[$1-$3.c]])))
])
])
])
[AT_DATA_GRAMMAR([dancer.y],
[%{
static int yylex (AT_LALR1_CC_IF([int *], [void]));
-AT_LALR1_CC_IF([],
+AT_LALR1_CC_IF([#include <cstdlib>],
[#include <stdlib.h>
#include <stdio.h>
- static void yyerror (const char *);])
+ ]AT_YYERROR_DECLARE[])
%}
$1
%token ARROW INVALID NUMBER STRING DATA
# --------------------------------
m4_define([_AT_DATA_EXPECT2_Y],
[AT_DATA_GRAMMAR([expect2.y],
-[[%{
-static int yylex (]AT_LALR1_CC_IF([int *], [void]));
-AT_LALR1_CC_IF([],
-[[#include <stdio.h>
-#include <stdlib.h>
+[%{
+static int yylex (AT_LALR1_CC_IF([int *], [void]));
- AT_LALR1_CC_IF([#include <cstdlib>],
- [#include <stdio.h>
- #include <stdlib.h>
- static void yyerror (const char *);])
++AT_LALR1_CC_IF([[#include <cstdlib>]],
++[[#include <stdlib.h>
++#include <stdio.h>
+ ]AT_YYERROR_DECLARE])[
%}
$1
%defines
-## --------------------------------------- ##
-## %error-verbose and YYSTACK_USE_ALLOCA. ##
-## --------------------------------------- ##
+## -------------------------------------------- ##
+## parse.error=verbose and YYSTACK_USE_ALLOCA. ##
+## -------------------------------------------- ##
-AT_SETUP([[%error-verbose and YYSTACK_USE_ALLOCA]])
+AT_SETUP([[parse.error=verbose and YYSTACK_USE_ALLOCA]])
+ AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([input.y],
[[%code {
#include <stdio.h>
%%
- void
- yyerror (char const *msg)
- {
- fprintf (stderr, "%s\n", msg);
- }
-
- int
- yylex (void)
- {
+ ]AT_YYERROR_DEFINE[
-/* Induce two syntax error messages (which requires full error
- recovery by shifting 3 tokens) in order to detect any loss of the
- reallocated buffer. */
+ /* Induce two syntax error messages (which requires full error
+ recovery by shifting 3 tokens) in order to detect any loss of the
+ reallocated buffer. */
- static char const *input = "abc";
- return *input++;
- }
-
+ ]AT_YYLEX_DEFINE([abc])[
int
main (void)
{
# size calculation would return YYSIZE_MAXIMUM to yyparse. Then,
# yyparse would invoke yyerror using the old contents of yymsg.
-AT_SETUP([[%error-verbose overflow]])
+AT_SETUP([[parse.error=verbose overflow]])
+
+ AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([input.y],
[[%code {
#include <stdio.h>
%%
- void
- yyerror (char const *msg)
- {
- fprintf (stderr, "%s\n", msg);
- }
-
- int
- yylex (void)
- {
+ ]AT_YYERROR_DEFINE[
-/* Induce two syntax error messages (which requires full error
- recovery by shifting 3 tokens). */
+ /* Induce two syntax error messages (which requires full error
+ recovery by shifting 3 tokens). */
- static char const *input = "abc";
- return *input++;
- }
-
+ ]AT_YYLEX_DEFINE([abc])[
int
main (void)
{