bison-patches
[Top][All Lists]
Advanced

[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],




reply via email to

[Prev in Thread] Current Thread [Next in Thread]