[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
{master} merge maint
From: |
Akim Demaille |
Subject: |
{master} merge maint |
Date: |
Thu, 29 Nov 2012 15:28:47 +0100 |
commit 5807bb9156930091850a52b5bb9ab9f89082b04e
Merge: f5fceda 511dd97
Author: Akim Demaille <address@hidden>
Date: Thu Nov 29 14:54:37 2012 +0100
Merge remote-tracking branch 'origin/maint'
* origin/maint:
doc: minor fixes
doc: improve the index
doc: introduce api.pure full, rearrange some examples
yacc.c: support "%define api.pure full"
local.at: improvements
Conflicts:
NEWS
data/yacc.c
doc/bison.texi
tests/calc.at
diff --git a/NEWS b/NEWS
index c8cab5e..a1bb0f9 100644
--- a/NEWS
+++ b/NEWS
@@ -242,6 +242,17 @@ GNU Bison NEWS
* Noteworthy changes in release ?.? (????-??-??) [?]
+** New value for %define variable: api.pure full
+
+ The %define variable api.pure requests a pure (reentrant) parser. However,
+ for historical reasons, using it in a location-tracking Yacc parser resulted
+ in an yyerror function that did not take a location as a parameter. With this
+ new value, the user may request a better pure parser, where yyerror does take
+ a location as a parameter (in location-tracking parsers).
+
+ The use of "%define api.pure true" is deprecated in favor of this new
+ "%define api.pure full".
+
** Changes in the format of error messages
This used to be the format of many error reports:
diff --git a/data/yacc.c b/data/yacc.c
index 3221840..2b6d10a 100644
--- a/data/yacc.c
+++ b/data/yacc.c
@@ -67,24 +67,36 @@ m4_define_default([b4_stack_depth_init], [200])
## ------------------------ ##
b4_percent_define_default([[api.pure]], [[false]])
-b4_define_flag_if([pure])
-m4_define([b4_pure_flag],
- [b4_percent_define_flag_if([[api.pure]], [[1]], [[0]])])
-
-# b4_yacc_pure_if(IF-TRUE, IF-FALSE)
-# ----------------------------------
-# Expand IF-TRUE, if %pure-parser and %parse-param, IF-FALSE otherwise.
-m4_define([b4_yacc_pure_if],
-[b4_pure_if([m4_ifset([b4_parse_param],
- [$1], [$2])],
- [$2])])
-
+b4_percent_define_check_values([[[[api.pure]],
+ [[false]], [[true]], [[]], [[full]]]])
+
+m4_define([b4_pure_flag], [[0]])
+m4_case(b4_percent_define_get([[api.pure]]),
+ [false], [m4_define([b4_pure_flag], [[0]])],
+ [true], [m4_define([b4_pure_flag], [[1]])],
+ [], [m4_define([b4_pure_flag], [[1]])],
+ [full], [m4_define([b4_pure_flag], [[2]])])
+
+m4_define([b4_pure_if],
+[m4_case(b4_pure_flag,
+ [0], [$2],
+ [1], [$1],
+ [2], [$1])])
+ [m4_fatal([invalid api.pure value: ]$1)])])
+
+# b4_yyerror_arg_loc_if(ARG)
+# --------------------------
+# Expand ARG iff yyerror is to be given a location as argument.
+m4_define([b4_yyerror_arg_loc_if],
+[b4_locations_if([m4_case(b4_pure_flag,
+ [1], [m4_ifset([b4_parse_param], [$1])],
+ [2], [$1])])])
# b4_yyerror_args
# ---------------
# Arguments passed to yyerror: user args plus yylloc.
m4_define([b4_yyerror_args],
-[b4_yacc_pure_if([b4_locations_if([&yylloc, ])])dnl
+[b4_yyerror_arg_loc_if([&yylloc, ])dnl
m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])])
diff --git a/doc/bison.texi b/doc/bison.texi
index 31a46ed..a6ff03b 100644
--- a/doc/bison.texi
+++ b/doc/bison.texi
@@ -4954,7 +4954,7 @@ declaration @samp{%define api.pure} says that you want
the parser to be
reentrant. It looks like this:
@example
-%define api.pure
+%define api.pure full
@end example
The result is that the communication variables @code{yylval} and
@@ -5004,7 +5004,7 @@ compatibility with the impure Yacc pull mode interface.
Unless you know
what you are doing, your declarations should look like this:
@example
-%define api.pure
+%define api.pure full
%define api.push-pull push
@end example
@@ -5508,9 +5508,41 @@ The parser namespace is @code{foo} and @code{yylex} is
referenced as
@item Purpose: Request a pure (reentrant) parser program.
@xref{Pure Decl, ,A Pure (Reentrant) Parser}.
address@hidden Accepted Values: Boolean
address@hidden Accepted Values: @code{true}, @code{false}, @code{full}
+
+The value may be omitted: this is equivalent to specifying @code{true}, as is
+the case for Boolean values.
+
+When @code{%define api.pure full} is used, the parser is made reentrant. This
+changes the signature for @code{yylex} (@pxref{Pure Calling}), and also that of
address@hidden when the tracking of locations has been activated, as shown
+below.
+
+The @code{true} value is very similar to the @code{full} value, the only
+difference is in the signature of @code{yyerror} on Yacc parsers without
address@hidden, for historical reasons.
+
+I.e., if @samp{%locations %define api.pure} is passed then the prototypes for
address@hidden are:
+
address@hidden
+void yyerror (char const *msg); /* Yacc parsers. */
+void yyerror (YYLTYPE *locp, char const *msg); /* GLR parsers. */
address@hidden example
+
+But if @samp{%locations %define api.pure %parse-param @{int address@hidden is
+used, then both parsers have the same signature:
+
address@hidden
+void yyerror (YYLTYPE *llocp, int *nastiness, char const *msg);
address@hidden example
+
+(@pxref{Error Reporting, ,The Error
+Reporting Function @code{yyerror}})
@item Default Value: @code{false}
+
address@hidden History: the @code{full} value was introduced in Bison 2.7
@end itemize
@c api.pure
@@ -5637,7 +5669,7 @@ remain in the parser tables. @xref{Unreachable States}.
@item Default Value: @code{false}
@end itemize
introduced as @code{lr.keep_unreachable_states} in 2.3b, renamed as
address@hidden in 2.5, and as
address@hidden in 2.5, and as
@code{lr.keep-unreachable-state} in 2.8.
@c lr.keep-unreachable-state
@@ -6073,6 +6105,27 @@ In the grammar actions, use expressions like this to
refer to the data:
exp: @dots{} @{ @dots{}; *randomness += 1; @dots{} @}
@end example
address@hidden
+Using the following:
address@hidden
+%parse-param @{int address@hidden
address@hidden example
+
+Results in these signatures:
address@hidden
+void yyerror (int *randomness, const char *msg);
+int yyparse (int *randomness);
address@hidden example
+
address@hidden
+Or, if both @code{%define api.pure full} (or just @code{%define api.pure})
+and @code{%locations} are used:
+
address@hidden
+void yyerror (YYLTYPE *llocp, int *randomness, const char *msg);
+int yyparse (int *randomness);
address@hidden example
+
@node Push Parser Function
@section The Push Parser Function @code{yypush_parse}
@findex yypush_parse
@@ -6324,7 +6377,7 @@ The data type of @code{yylloc} has the name
@code{YYLTYPE}.
@node Pure Calling
@subsection Calling Conventions for Pure Parsers
-When you use the Bison declaration @samp{%define api.pure} to request a
+When you use the Bison declaration @code{%define api.pure full} to request a
pure, reentrant parser, the global communication variables @code{yylval}
and @code{yylloc} cannot be used. (@xref{Pure Decl, ,A Pure (Reentrant)
Parser}.) In such parsers the two global variables are replaced by
@@ -6369,6 +6422,7 @@ Specify that @var{argument-declaration} are additional
declarations, which is equivalent to repeating @code{%param}.
@end deffn
address@hidden
For instance:
@example
@@ -6385,7 +6439,7 @@ int yylex (scanner_mode *mode, environment_type *env);
int yyparse (parser_mode *mode, environment_type *env);
@end example
-If @samp{%define api.pure} is added:
+If @samp{%define api.pure full} is added:
@example
int yylex (YYSTYPE *lvalp, scanner_mode *mode, environment_type *env);
@@ -6393,7 +6447,8 @@ int yyparse (parser_mode *mode, environment_type *env);
@end example
@noindent
-and finally, if both @samp{%define api.pure} and @code{%locations} are used:
+and finally, if both @samp{%define api.pure full} and @code{%locations} are
+used:
@example
int yylex (YYSTYPE *lvalp, YYLTYPE *llocp,
@@ -6458,50 +6513,16 @@ error recovery if you have written suitable error
recovery grammar rules
immediately return 1.
Obviously, in location tracking pure parsers, @code{yyerror} should have
-an access to the current location.
-This is indeed the case for the GLR
-parsers, but not for the Yacc parser, for historical reasons. I.e., if
address@hidden %define api.pure} is passed then the prototypes for
address@hidden are:
-
address@hidden
-void yyerror (char const *msg); /* Yacc parsers. */
-void yyerror (YYLTYPE *locp, char const *msg); /* GLR parsers. */
address@hidden example
+an access to the current location. With @code{%define api.pure}, this is
+indeed the case for the GLR parsers, but not for the Yacc parser, for
+historical reasons, and this is the why @code{%define api.pure full} should be
+prefered over @code{%define api.pure}.
-If @samp{%parse-param @{int address@hidden is used, then:
-
address@hidden
-void yyerror (int *nastiness, char const *msg); /* Yacc parsers. */
-void yyerror (int *nastiness, char const *msg); /* GLR parsers. */
address@hidden example
-
-Finally, GLR and Yacc parsers share the same @code{yyerror} calling
-convention for absolutely pure parsers, i.e., when the calling
-convention of @code{yylex} @emph{and} the calling convention of
address@hidden api.pure} are pure.
-I.e.:
-
address@hidden
-/* Location tracking. */
-%locations
-/* Pure yylex. */
-%define api.pure
-%lex-param @{int address@hidden
-/* Pure yyparse. */
-%parse-param @{int address@hidden
-%parse-param @{int address@hidden
address@hidden example
-
address@hidden
-results in the following signatures for all the parser kinds:
+When @code{%locations %define api.pure full} is used, @code{yyerror} has the
+following signature:
@example
-int yylex (YYSTYPE *lvalp, YYLTYPE *llocp, int *nastiness);
-int yyparse (int *nastiness, int *randomness);
-void yyerror (YYLTYPE *locp,
- int *nastiness, int *randomness,
- char const *msg);
+void yyerror (YYLTYPE *locp, char const *msg);
@end example
@noindent
@@ -7675,9 +7696,9 @@ mysterious behavior altogether. You simply need to
activate a more powerful
parser table construction algorithm by using the @code{%define lr.type}
directive.
address@hidden {Directive} {%define lr.type @var{TYPE}}
address@hidden {Directive} {%define lr.type} @var{type}
Specify the type of parser tables within the LR(1) family. The accepted
-values for @var{TYPE} are:
+values for @var{type} are:
@itemize
@item @code{lalr} (default)
@@ -7865,9 +7886,9 @@ split the parse instead.
To adjust which states have default reductions enabled, use the
@code{%define lr.default-reduction} directive.
address@hidden {Directive} {%define lr.default-reduction @var{WHERE}}
address@hidden {Directive} {%define lr.default-reduction} @var{where}
Specify the kind of states that are permitted to contain default reductions.
-The accepted values of @var{WHERE} are:
+The accepted values of @var{where} are:
@itemize
@item @code{most} (default for LALR and IELR)
@item @code{consistent}
@@ -7905,7 +7926,7 @@ that solves these problems for canonical LR, IELR, and
LALR without
sacrificing @code{%nonassoc}, default reductions, or state merging. You can
enable LAC with the @code{%define parse.lac} directive.
address@hidden {Directive} {%define parse.lac @var{VALUE}}
address@hidden {Directive} {%define parse.lac} @var{value}
Enable LAC to improve syntax error handling.
@itemize
@item @code{none} (default)
@@ -8001,9 +8022,9 @@ resolution because they are useless in the generated
parser. However,
keeping unreachable states is sometimes useful when trying to understand the
relationship between the parser and the grammar.
address@hidden {Directive} {%define lr.keep-unreachable-state @var{VALUE}}
address@hidden {Directive} {%define lr.keep-unreachable-state} @var{value}
Request that Bison allow unreachable states to remain in the parser tables.
address@hidden must be a Boolean. The default is @code{false}.
address@hidden must be a Boolean. The default is @code{false}.
@end deffn
There are a few caveats to consider:
@@ -10278,7 +10299,7 @@ depends whether you use unions, or variants.
@node Split Symbols
@subsubsection Split Symbols
-Therefore the interface is as follows.
+The interface is as follows.
@deftypemethod {parser} {int} yylex (semantic_type* @var{yylval},
location_type* @var{yylloc}, @var{type1} @var{arg1}, ...)
@deftypemethodx {parser} {int} yylex (semantic_type* @var{yylval}, @var{type1}
@var{arg1}, ...)
@@ -10977,8 +10998,7 @@ You can create documentation for generated parsers
using Javadoc.
Contrary to C parsers, Java parsers do not use global variables; the
state of the parser is always local to an instance of the parser class.
Therefore, all Java parsers are ``pure'', and the @code{%pure-parser}
-and @samp{%define api.pure} directives does not do anything when used in
-Java.
+and @code{%define api.pure} directives do nothing when used in Java.
Push parsers are currently unsupported in Java and @code{%define
api.push-pull} have no effect.
@@ -11612,7 +11632,7 @@ or
@quotation
My parser includes support for an @samp{#include}-like feature, in
which case I run @code{yyparse} from @code{yyparse}. This fails
-although I did specify @samp{%define api.pure}.
+although I did specify @samp{%define api.pure full}.
@end quotation
These problems typically come not from Bison itself, but from
diff --git a/gnulib b/gnulib
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit daf7f8c02242c535d596231e2f655109b97fa2bc
+Subproject commit daf7f8c02242c535d596231e2f655109b97fa2bc-dirty
diff --git a/tests/actions.at b/tests/actions.at
index 099237c..8278293 100644
--- a/tests/actions.at
+++ b/tests/actions.at
@@ -79,7 +79,7 @@ AT_CLEANUP
m4_pushdef([AT_TEST],
[AT_SETUP([Initial location: $1 $2])
-AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" $2 %parse-param { int x }])
+AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1" $2])
AT_DATA_GRAMMAR([[input.y]],
[[%defines /* FIXME: Required by lalr1.cc in Bison 2.6. */
%locations
@@ -87,7 +87,6 @@ AT_DATA_GRAMMAR([[input.y]],
%skeleton "$1"
]$2[
]$3[
-%parse-param { int x } // Useless, but used to force yyerror purity.
%code
{
# include <stdio.h>
@@ -113,11 +112,11 @@ exp: { ]AT_SKEL_CC_IF([[std::cerr << @$ << std::endl]],
int
main (void)
{]AT_SKEL_CC_IF([[
- yy::parser p (0);
+ yy::parser p;
p.set_debug_level (!!getenv("YYDEBUG"));
return p.parse ();]], [[
yydebug = !!getenv("YYDEBUG");
- return !!yyparse (0);]])[
+ return !!yyparse (]AT_PARAM_IF([0])[);]])[
}
]])
@@ -132,10 +131,12 @@ AT_CLEANUP
## FIXME: test Java, and iterate over skeletons.
AT_TEST([yacc.c])
-AT_TEST([yacc.c], [%define api.pure])
+AT_TEST([yacc.c], [%define api.pure full])
+AT_TEST([yacc.c], [%define api.pure %parse-param { int x }])
AT_TEST([yacc.c], [%define api.push-pull both])
-AT_TEST([yacc.c], [%define api.push-pull both %define api.pure])
+AT_TEST([yacc.c], [%define api.push-pull both %define api.pure full])
AT_TEST([glr.c])
+AT_TEST([glr.c], [%define api.pure])
AT_TEST([lalr1.cc])
AT_TEST([glr.cc])
@@ -146,7 +147,7 @@ AT_TEST([glr.cc])
## Weirdly enough, to trigger the warning with GCC 4.7, we must not
## use fprintf, so run the test twice: once to check the warning
## (absence thereof), and another time to check the value.
-AT_TEST([yacc.c], [%define api.pure],
+AT_TEST([yacc.c], [%define api.pure full],
[[%{
# define YYLTYPE int
# define YY_LOCATION_PRINT(Stream, Loc) \
@@ -157,7 +158,7 @@ AT_TEST([yacc.c], [%define api.pure],
]],
[@&address@hidden)
-AT_TEST([yacc.c], [%define api.pure],
+AT_TEST([yacc.c], [%define api.pure full],
[[%{
# define YYLTYPE int
# define YY_LOCATION_PRINT(Stream, Loc) \
diff --git a/tests/calc.at b/tests/calc.at
index f336b69..565b31c 100644
--- a/tests/calc.at
+++ b/tests/calc.at
@@ -606,8 +606,8 @@ AT_CHECK_CALC_LALR([%verbose])
AT_CHECK_CALC_LALR([%yacc])
AT_CHECK_CALC_LALR([%define parse.error verbose])
-AT_CHECK_CALC_LALR([%define api.pure %locations])
-AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure %locations])
+AT_CHECK_CALC_LALR([%define api.pure full %locations])
+AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full
%locations])
AT_CHECK_CALC_LALR([%define parse.error verbose %locations])
AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %define
api.prefix "calc" %verbose %yacc])
@@ -617,8 +617,8 @@ AT_CHECK_CALC_LALR([%debug])
AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines
%name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines
%define api.prefix "calc" %verbose %yacc])
-AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug
%locations %defines %name-prefix "calc" %verbose %yacc])
-AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure %define
parse.error verbose %debug %locations %defines %define api.prefix "calc"
%verbose %yacc])
+AT_CHECK_CALC_LALR([%define api.pure full %define parse.error verbose %debug
%locations %defines %name-prefix "calc" %verbose %yacc])
+AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %define
parse.error verbose %debug %locations %defines %define api.prefix "calc"
%verbose %yacc])
AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug
%locations %defines %define api.prefix "calc" %verbose %yacc %parse-param
{semantic_value *result} %parse-param {int *count}])
diff --git a/tests/local.at b/tests/local.at
index e24c0ac..121dedf 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -152,10 +152,6 @@ m4_pushdef([AT_PURE_IF],
[m4_bmatch([$3], [%define *api\.pure\|%pure-parser],
[m4_bmatch([$3], [%define *api\.pure *"?false"?], [$2], [$1])],
[$2])])
-m4_pushdef([AT_PURE_AND_LOC_IF],
-[m4_bmatch([$3], [%locations], [AT_PURE_IF($@)], [$2])])
-m4_pushdef([AT_GLR_OR_PARAM_IF],
-[m4_bmatch([$3], [%glr-parser\|%parse-param], [$1], [$2])])
m4_pushdef([AT_NAME_PREFIX],
[m4_bmatch([$3], [\(%define api\.prefix\|%name-prefix\) ".*"],
[m4_bregexp([$3], [\(%define api\.prefix\|%name-prefix\)
"\([^""]*\)"], [\2])],
@@ -171,14 +167,26 @@ m4_pushdef([AT_API_prefix],
[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, and if the parser is pure. For
+# historical reasons, with the "yacc.c" skeleton, the location is not passed
+# unless an additional "%parse-param" is present, or if the purity is defined
+# as "full".
m4_pushdef([AT_YYERROR_ARG_LOC_IF],
-[AT_GLR_OR_PARAM_IF([AT_PURE_AND_LOC_IF([$1], [$2])],
+[AT_LOCATION_IF([AT_PURE_IF([m4_bmatch([$3],
+ m4_quote(m4_join([\|],
+ [%define api.pure
"?full"?],
+ [%glr-parser],
+ [%parse-param],
+ [%skeleton
"?glr.c"?])),
+ [$1], [$2])],
+ [$2])],
[$2])])
-# yyerror always sees the locations (when activated), except if
-# (yacc & pure & !param). FIXME: This is wrong. See the manual.
+
+# yyerror always sees the locations (when activated) if the parser is impure.
+# When the parser is pure, yyerror sees the location if it is received as an
+# argument.
m4_pushdef([AT_YYERROR_SEES_LOC_IF],
-[AT_LOCATION_IF([AT_YACC_IF([AT_PURE_IF([AT_PARAM_IF([$1], [$2])],
+[AT_LOCATION_IF([AT_YACC_IF([AT_PURE_IF([AT_YYERROR_ARG_LOC_IF([$1], [$2])],
[$1])],
[$1])],
[$2])])
@@ -254,8 +262,6 @@ m4_popdef([AT_API_prefix])
m4_popdef([AT_TOKEN_PREFIX])
m4_popdef([AT_TOKEN_CTOR_IF])
m4_popdef([AT_NAME_PREFIX])
-m4_popdef([AT_GLR_OR_PARAM_IF])
-m4_popdef([AT_PURE_AND_LOC_IF])
m4_popdef([AT_LOCATION_TYPE_IF])
m4_popdef([AT_LOCATION_IF])
m4_popdef([AT_PARSE_PARAMS])
@@ -360,6 +366,7 @@ static
}]dnl
])
+# AT_YYERROR_FORMALS
# AT_YYERROR_PROTOTYPE
# AT_YYERROR_DECLARE_EXTERN
# AT_YYERROR_DECLARE
@@ -368,7 +375,7 @@ static
# Must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS pair.
m4_define([AT_YYERROR_FORMALS],
[m4_case(AT_LANG,
-[c], [AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE *llocp, ])AT_PARSE_PARAMS [const char
*msg]])[]dnl
+[c], [AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE const * const llocp, ])AT_PARSE_PARAMS
[const char *msg]])[]dnl
])
m4_define([AT_YYERROR_PROTOTYPE],
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- {master} merge maint,
Akim Demaille <=