]> git.saurik.com Git - bison.git/commitdiff
Merge remote-tracking branch 'origin/maint'
authorAkim Demaille <akim@lrde.epita.fr>
Thu, 29 Nov 2012 13:54:37 +0000 (14:54 +0100)
committerAkim Demaille <akim@lrde.epita.fr>
Thu, 29 Nov 2012 14:20:03 +0000 (15:20 +0100)
* 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

1  2 
NEWS
data/yacc.c
doc/bison.texi
tests/actions.at
tests/calc.at
tests/local.at

diff --cc NEWS
index c8cab5e0bde6c8c0a01bf0b53b8400040a7cf8b2,2cd57c2802933c0d268b31f3ade19b52496ec20a..a1bb0f91c8a1f9aee932ca01ef0ca434f370d4e7
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -2,246 -2,17 +2,257 @@@ GNU Bison NEW
  
  * Noteworthy changes in release ?.? (????-??-??) [?]
  
 +** Incompatible changes
 +
 +*** Obsolete features
 +
 +  Support for YYFAIL is removed (deprecated in Bison 2.4.2).
 +  Support for yystype and yyltype (instead of YYSTYPE and YYLTYPE)
 +  is removed (deprecated in Bison 1.875).
 +  Support for YYPARSE_PARAM is removed (deprecated in Bison 1.875).
 +
 +** Warnings
 +
 +*** Enhancements of the -Werror option
 +
 +  The -Werror=CATEGORY option is now recognized, and will treat specified
 +  warnings as errors. The warnings need not have been explicitly activated
 +  using the -W option, this is similar to what GCC 4.7 does.
 +
 +  For example, given the following command line, Bison will treat both
 +  warnings related to POSIX Yacc incompatibilities and S/R conflicts as
 +  errors (and only those):
 +
 +    $ bison -Werror=yacc,error=conflicts-sr input.y
 +
 +  If no categories are specified, -Werror will make all active warnings into
 +  errors. For example, the following line does the same the previous example:
 +
 +    $ bison -Werror -Wnone -Wyacc -Wconflicts-sr input.y
 +
 +  (By default -Wconflicts-sr,conflicts-rr,deprecated,other is enabled.)
 +
 +  Note that the categories in this -Werror option may not be prefixed with
 +  "no-". However, -Wno-error[=CATEGORY] is valid.
 +
 +  Note that -y enables -Werror=yacc. Therefore it is now possible to require
 +  Yacc-like behavior (e.g., always generate y.tab.c), but to report
 +  incompatibilities as warnings: "-y -Wno-error=yacc".
 +
 +*** The display of warnings is now richer
 +
 +  The option that controls a given warning is now displayed:
 +
 +    foo.y:4.6: warning: type clash on default action: <foo> != <bar> [-Wother]
 +
 +  In the case of warnings treated as errors, the prefix is changed from
 +  "warning: " to "error: ", and the suffix is displayed, in a manner similar
 +  to GCC, as [-Werror=CATEGORY].
 +
 +  For instance, where the previous version of Bison would report (and exit
 +  with failure):
 +
 +    bison: warnings being treated as errors
 +    input.y:1.1: warning: stray ',' treated as white space
 +
 +  it now reports:
 +
 +    input.y:1.1: error: stray ',' treated as white space [-Werror=other]
 +
 +*** Deprecated constructs
 +
 +  The new 'deprecated' warning category flags obsolete constructs whose
 +  support will be discontinued.  It is enabled by default.  These warnings
 +  used to be reported as 'other' warnings.
 +
 +*** Useless semantic types
 +
 +  Bison now warns about useless (uninhabited) semantic types.  Since
 +  semantic types are not declared to Bison (they are defined in the opaque
 +  %union structure), it is %printer/%destructor directives about useless
 +  types that trigger the warning:
 +
 +    %token <type1> term
 +    %type  <type2> nterm
 +    %printer    {} <type1> <type3>
 +    %destructor {} <type2> <type4>
 +    %%
 +    nterm: term { $$ = $1; };
 +
 +    3.28-34: warning: type <type3> is used, but is not associated to any symbol
 +    4.28-34: warning: type <type4> is used, but is not associated to any symbol
 +
 +*** Undefined but unused symbols
 +
 +  Bison used to raise an error for undefined symbols that are not used in
 +  the grammar.  This is now only a warning.
 +
 +    %printer    {} symbol1
 +    %destructor {} symbol2
 +    %type <type>   symbol3
 +    %%
 +    exp: "a";
 +
 +*** Useless destructors or printers
 +
 +  Bison now warns about useless destructors or printers.  In the following
 +  example, the printer for <type1>, and the destructor for <type2> are
 +  useless: all symbols of <type1> (token1) already have a printer, and all
 +  symbols of type <type2> (token2) already have a destructor.
 +
 +    %token <type1> token1
 +           <type2> token2
 +           <type3> token3
 +           <type4> token4
 +    %printer    {} token1 <type1> <type3>
 +    %destructor {} token2 <type2> <type4>
 +
 +*** Conflicts
 +
 +  The warnings and error messages about shift/reduce and reduce/reduce
 +  conflicts have been normalized.  For instance on the following foo.y file:
 +
 +    %glr-parser
 +    %%
 +    exp: exp '+' exp | '0' | '0';
 +
 +  compare the previous version of bison:
 +
 +    $ bison foo.y
 +    foo.y: conflicts: 1 shift/reduce, 2 reduce/reduce
 +    $ bison -Werror foo.y
 +    bison: warnings being treated as errors
 +    foo.y: conflicts: 1 shift/reduce, 2 reduce/reduce
 +
 +  with the new behavior:
 +
 +    $ bison foo.y
 +    foo.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 +    foo.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
 +    $ bison -Werror foo.y
 +    foo.y: error: 1 shift/reduce conflict [-Werror=conflicts-sr]
 +    foo.y: error: 2 reduce/reduce conflicts [-Werror=conflicts-rr]
 +
 +  When %expect or %expect-rr is used, such as with bar.y:
 +
 +    %expect 0
 +    %glr-parser
 +    %%
 +    exp: exp '+' exp | '0' | '0';
 +
 +  Former behavior:
 +
 +    $ bison bar.y
 +    bar.y: conflicts: 1 shift/reduce, 2 reduce/reduce
 +    bar.y: expected 0 shift/reduce conflicts
 +    bar.y: expected 0 reduce/reduce conflicts
 +
 +  New one:
 +
 +    $ bison bar.y
 +    bar.y: error: shift/reduce conflicts: 1 found, 0 expected
 +    bar.y: error: reduce/reduce conflicts: 2 found, 0 expected
 +
 +** Additional yylex/yyparse arguments
 +
 +  The new directive %param declares additional arguments to both yylex and
 +  yyparse.  The %lex-param, %parse-param, and %param directives support one
 +  or more arguments.  Instead of
 +
 +    %lex-param   {arg1_type *arg1}
 +    %lex-param   {arg2_type *arg2}
 +    %parse-param {arg1_type *arg1}
 +    %parse-param {arg2_type *arg2}
 +
 +  one may now declare
 +
 +    %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++ skeletons improvements
 +
 +*** The parser header is no longer mandatory (lalr1.cc, glr.cc)
 +
 +  Using %defines is now optional.  Without it, the needed support classes
 +  are defined in the generated parser, instead of additional files (such as
 +  location.hh, position.hh and stack.hh).
 +
 +*** Locations are no longer mandatory (lalr1.cc, glr.cc)
 +
 +  Both lalr1.cc and glr.cc no longer require %location.
 +
 +*** syntax_error exception (lalr1.cc)
 +
 +  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.token.prefix
 +
 +  The variable api.token.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.token.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).
 +
 +** Renamed %define variables
 +
 +  The following variables have been renamed for consistency.  Backward
 +  compatibility is ensured, but upgrading is recommended.
 +
 +    lr.default-reductions      -> lr.default-reduction
 +    lr.keep-unreachable-states -> lr.keep-unreachable-state
 +    namespace                  -> api.namespace
 +
 +** Variable parse.error
 +
 +  This variable 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 run-time
 +  expressions.
 +
 +** The directive %expect-rr is now an error in non GLR mode
 +
 +  It used to be an error only if used in non GLR mode, _and_ if there are
 +  reduce/reduce conflicts.
 +
 +* 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 --cc data/yacc.c
index 32218409484875c1f4188d2196d2fe6581661c25,0f3155234fdf9c82e7721367e94a599d61e6fb35..2b6d10acbb3b7e5c67bf9d881a4d2951a42b6bf3
@@@ -84,8 -94,8 +96,8 @@@ m4_define([b4_yyerror_arg_loc_if]
  # ---------------
  # 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_c_args(b4_parse_param), ])])
 +m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])])
  
  
  # b4_lex_param
diff --cc doc/bison.texi
index 31a46ed5f8f607d1408d0efaaef0438ee2ad863e,fc880315cac4aa17282e1d8872e84502b103f027..a6ff03b2c1b5f263cbcfdb966c4f76d46280a8c8
@@@ -5508,16 -5373,46 +5508,48 @@@ The parser namespace is @code{foo} and 
  @item Purpose: Request a pure (reentrant) parser program.
  @xref{Pure Decl, ,A Pure (Reentrant) Parser}.
  
- @item Accepted Values: Boolean
+ @item 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
+ @code{yyerror} 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
+ @code{%parse-param}, for historical reasons.
+ I.e., if @samp{%locations %define api.pure} is passed then the prototypes for
+ @code{yyerror} are:
+ @example
+ void yyerror (char const *msg);                 /* Yacc parsers.  */
+ void yyerror (YYLTYPE *locp, char const *msg);  /* GLR parsers.  */
+ @end example
+ But if @samp{%locations %define api.pure %parse-param @{int *nastiness@}} is
+ used, then both parsers have the same signature:
+ @example
+ void yyerror (YYLTYPE *llocp, int *nastiness, char const *msg);
+ @end example
+ (@pxref{Error Reporting, ,The Error
+ Reporting Function @code{yyerror}})
  
  @item Default Value: @code{false}
+ @item History: the @code{full} value was introduced in Bison 2.7
  @end itemize
 +@c api.pure
 +
  
 -@c ================================================== api.push-pull
  
 -@item @code{api.push-pull}
 +@c ================================================== api.push-pull
 +@item api.push-pull
  @findex %define api.push-pull
  
  @itemize @bullet
@@@ -5636,10 -5461,6 +5668,10 @@@ remain in the parser tables.  @xref{Unr
  @item Accepted Values: Boolean
  @item Default Value: @code{false}
  @end itemize
- @code{lr.keep-unreachable-state} in 2.5, and as
 +introduced as @code{lr.keep_unreachable_states} in 2.3b, renamed as
++@code{lr.keep-unreachable-states} in 2.5, and as
 +@code{lr.keep-unreachable-state} in 2.8.
 +@c lr.keep-unreachable-state
  
  @c ================================================== lr.type
  
@@@ -6348,27 -6148,18 +6401,28 @@@ textual locations, then the type @code{
  this case, omit the second argument; @code{yylex} will be called with
  only one argument.
  
 -
 -If you wish to pass the additional parameter data to @code{yylex}, use
 +If you wish to pass additional arguments to @code{yylex}, use
  @code{%lex-param} just like @code{%parse-param} (@pxref{Parser
 -Function}).
 +Function}).  To pass additional arguments to both @code{yylex} and
 +@code{yyparse}, use @code{%param}.
  
 -@deffn {Directive} lex-param @{@var{argument-declaration}@}
 +@deffn {Directive} %lex-param @{@var{argument-declaration}@} @dots{}
  @findex %lex-param
 -Declare that the braced-code @var{argument-declaration} is an
 -additional @code{yylex} argument declaration.
 +Specify that @var{argument-declaration} are additional @code{yylex} argument
 +declarations.  You may pass one or more such declarations, which is
 +equivalent to repeating @code{%lex-param}.
 +@end deffn
 +
 +@deffn {Directive} %param @{@var{argument-declaration}@} @dots{}
 +@findex %param
 +Specify that @var{argument-declaration} are additional
 +@code{yylex}/@code{yyparse} argument declaration.  This is equivalent to
 +@samp{%lex-param @{@var{argument-declaration}@} @dots{} %parse-param
 +@{@var{argument-declaration}@} @dots{}}.  You may pass one or more
 +declarations, which is equivalent to repeating @code{%param}.
  @end deffn
  
+ @noindent
  For instance:
  
  @example
  @end example
  
  @noindent
 -results in the following signature:
 +results in the following signatures:
  
  @example
 -int yylex (int *nastiness);
 +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);
 +int yyparse (parser_mode *mode, environment_type *env);
  @end example
  
  @noindent
- and finally, if both @samp{%define api.pure} and @code{%locations} are used:
 -If @code{%define api.pure full} (or just @code{%define api.pure}) is added:
++and finally, if both @samp{%define api.pure full} and @code{%locations} are
++used:
  
  @example
 -int yylex (YYSTYPE *lvalp, int *nastiness);
 +int yylex   (YYSTYPE *lvalp, YYLTYPE *llocp,
 +             scanner_mode *mode, environment_type *env);
 +int yyparse (parser_mode *mode, environment_type *env);
  @end example
  
  @node Error Reporting
@@@ -7863,11 -7551,11 +7884,11 @@@ token for which there is a conflict.  T
  split the parse instead.
  
  To adjust which states have default reductions enabled, use the
 -@code{%define lr.default-reductions} directive.
 +@code{%define lr.default-reduction} directive.
  
- @deffn {Directive} {%define lr.default-reduction @var{WHERE}}
 -@deffn {Directive} {%define lr.default-reductions} @var{where}
++@deffn {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}
@@@ -8001,9 -7689,9 +8022,9 @@@ resolution because they are useless in 
  keeping unreachable states is sometimes useful when trying to understand the
  relationship between the parser and the grammar.
  
- @deffn {Directive} {%define lr.keep-unreachable-state @var{VALUE}}
 -@deffn {Directive} {%define lr.keep-unreachable-states} @var{value}
++@deffn {Directive} {%define lr.keep-unreachable-state} @var{value}
  Request that Bison allow unreachable states to remain in the parser tables.
- @var{VALUE} must be a Boolean.  The default is @code{false}.
+ @var{value} must be a Boolean.  The default is @code{false}.
  @end deffn
  
  There are a few caveats to consider:
@@@ -10267,23 -9799,11 +10288,23 @@@ signature is used
  
  The parser invokes the scanner by calling @code{yylex}.  Contrary to C
  parsers, C++ parsers are always pure: there is no point in using the
 -@code{%define api.pure full} directive.  Therefore the interface is as follows.
 +@samp{%define api.pure} directive.  The actual interface with @code{yylex}
 +depends whether you use unions, or variants.
 +
 +@menu
 +* Split Symbols::         Passing symbols as two/three components
 +* Complete Symbols::      Making symbols a whole
 +@end menu
 +
 +@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}, ...)
 -Return the next token.  Its type is the return value, its semantic
 -value and location being @var{yylval} and @var{yylloc}.  Invocations of
 +@deftypemethodx {parser} {int} yylex (semantic_type* @var{yylval}, @var{type1} @var{arg1}, ...)
 +Return the next token.  Its type is the return value, its semantic value and
 +location (if enabled) being @var{yylval} and @var{yylloc}.  Invocations of
  @samp{%lex-param @{@var{type1} @var{arg1}@}} yield additional arguments.
  @end deftypemethod
  
@@@ -10977,8 -10362,8 +10998,7 @@@ You can create documentation for genera
  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
 -and @code{%define api.pure full} 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.
Simple merge
diff --cc tests/calc.at
index f336b69eba2aaff1a4de8ce9eb93386663e847e6,f72836ee26d1992371ff6d2463fb2bf50d942471..565b31cc6db37a64fb2a29ef978f9327d127f003
@@@ -601,26 -599,26 +601,26 @@@ AT_CHECK_CALC_LALR(
  AT_CHECK_CALC_LALR([%defines])
  AT_CHECK_CALC_LALR([%locations])
  
 -AT_CHECK_CALC_LALR([%name-prefix="calc"]) dnl test deprecated `='
 +AT_CHECK_CALC_LALR([%name-prefix "calc"])
  AT_CHECK_CALC_LALR([%verbose])
  AT_CHECK_CALC_LALR([%yacc])
 -AT_CHECK_CALC_LALR([%error-verbose])
 +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([%error-verbose %locations])
 +AT_CHECK_CALC_LALR([%define parse.error verbose %locations])
  
 -AT_CHECK_CALC_LALR([%error-verbose %locations %defines %name-prefix "calc" %verbose %yacc])
 -AT_CHECK_CALC_LALR([%error-verbose %locations %defines %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %define api.prefix "calc" %verbose %yacc])
 +AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %name-prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
  
  AT_CHECK_CALC_LALR([%debug])
 -AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
 -AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
 +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 %verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
 -AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %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 %error-verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
 +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 --cc tests/local.at
index e24c0acb7dc7fdccf4ce7bf5f7ea953254fb8ab8,48afab83dcb39d62b5b46f42570815ab60e87619..121dedf2c2614a5b641d27ac435a689db92220b2
@@@ -171,14 -161,26 +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])])
 +                    [$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])])
@@@ -251,11 -251,7 +259,9 @@@ m4_popdef([AT_YYERROR_SEES_LOC_IF]
  m4_popdef([AT_YYERROR_ARG_LOC_IF])
  m4_popdef([AT_API_PREFIX])
  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])