doc: introduce api.pure full, rearrange some examples

* NEWS: Add entry.
* doc/bison.texi (%define Summary): Show the old Yacc behaviour.
(Parser Function): Move parse-param examples here.
(Pure Calling): Remove parse-param examples.
(Error Reporting): Don't show the old behavior, stick to 'full'.
This commit is contained in:
Theophile Ranquet
2012-11-26 18:17:15 +01:00
parent 6428a8a4a5
commit 1f1bd57297
2 changed files with 86 additions and 66 deletions

11
NEWS
View File

@@ -2,6 +2,17 @@ GNU Bison NEWS
* Noteworthy changes in release ?.? (????-??-??) [?] * 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 ** Changes in the format of error messages
This used to be the format of many error reports: This used to be the format of many error reports:

View File

@@ -4866,6 +4866,7 @@ may override this restriction with the @code{%start} declaration as follows:
@cindex reentrant parser @cindex reentrant parser
@cindex pure parser @cindex pure parser
@findex %define api.pure @findex %define api.pure
@findex %define api.pure full
A @dfn{reentrant} program is one which does not alter in the course of A @dfn{reentrant} program is one which does not alter in the course of
execution; in other words, it consists entirely of @dfn{pure} (read-only) execution; in other words, it consists entirely of @dfn{pure} (read-only)
@@ -4885,7 +4886,7 @@ declaration @code{%define api.pure} says that you want the parser to be
reentrant. It looks like this: reentrant. It looks like this:
@example @example
%define api.pure %define api.pure full
@end example @end example
The result is that the communication variables @code{yylval} and The result is that the communication variables @code{yylval} and
@@ -4935,7 +4936,7 @@ compatibility with the impure Yacc pull mode interface. Unless you know
what you are doing, your declarations should look like this: what you are doing, your declarations should look like this:
@example @example
%define api.pure %define api.pure full
%define api.push-pull push %define api.push-pull push
@end example @end example
@@ -5008,8 +5009,8 @@ yypull_parse (ps); /* Will call the lexer */
yypstate_delete (ps); yypstate_delete (ps);
@end example @end example
Adding the @code{%define api.pure} declaration does exactly the same thing to Adding the @code{%define api.pure full} declaration does exactly the same thing
the generated parser with @code{%define api.push-pull both} as it did for to the generated parser with @code{%define api.push-pull both} as it did for
@code{%define api.push-pull push}. @code{%define api.push-pull push}.
@node Decl Summary @node Decl Summary
@@ -5373,9 +5374,40 @@ Some of the accepted @var{variable}s are:
@item Purpose: Request a pure (reentrant) parser program. @item Purpose: Request a pure (reentrant) parser program.
@xref{Pure Decl, ,A Pure (Reentrant) Parser}. @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 yylex (@pxref{Pure Calling}), and also that of
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 Default Value: @code{false}
@item History: the @code{full} value was introduced in Bison 2.7
@end itemize @end itemize
@c ================================================== api.push-pull @c ================================================== api.push-pull
@@ -5820,6 +5852,27 @@ In the grammar actions, use expressions like this to refer to the data:
exp: @dots{} @{ @dots{}; *randomness += 1; @dots{} @} exp: @dots{} @{ @dots{}; *randomness += 1; @dots{} @}
@end example @end example
@noindent
Using the following:
@example
%parse-param @{int *randomness@}
@end example
Results in these signatures:
@example
void yyerror (int *randomness, const char *msg);
int yyparse (int *randomness);
@end example
@noindent
Or, if both @code{%define api.pure full} (or just @code{%define api.pure})
and @code{%locations} are used:
@example
void yyerror (YYLTYPE *llocp, int *randomness, const char *msg);
int yyparse (int *randomness);
@end example
@node Push Parser Function @node Push Parser Function
@section The Push Parser Function @code{yypush_parse} @section The Push Parser Function @code{yypush_parse}
@findex yypush_parse @findex yypush_parse
@@ -6071,7 +6124,7 @@ The data type of @code{yylloc} has the name @code{YYLTYPE}.
@node Pure Calling @node Pure Calling
@subsection Calling Conventions for Pure Parsers @subsection Calling Conventions for Pure Parsers
When you use the Bison declaration @code{%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} pure, reentrant parser, the global communication variables @code{yylval}
and @code{yylloc} cannot be used. (@xref{Pure Decl, ,A Pure (Reentrant) and @code{yylloc} cannot be used. (@xref{Pure Decl, ,A Pure (Reentrant)
Parser}.) In such parsers the two global variables are replaced by Parser}.) In such parsers the two global variables are replaced by
@@ -6106,35 +6159,25 @@ Declare that the braced-code @var{argument-declaration} is an
additional @code{yylex} argument declaration. additional @code{yylex} argument declaration.
@end deffn @end deffn
@noindent
For instance: For instance:
@example @example
%parse-param @{int *nastiness@}
%lex-param @{int *nastiness@} %lex-param @{int *nastiness@}
%parse-param @{int *randomness@}
@end example @end example
@noindent @noindent
results in the following signatures: results in the following signature:
@example @example
int yylex (int *nastiness); int yylex (int *nastiness);
int yyparse (int *nastiness, int *randomness);
@end example
If @code{%define api.pure} is added:
@example
int yylex (YYSTYPE *lvalp, int *nastiness);
int yyparse (int *nastiness, int *randomness);
@end example @end example
@noindent @noindent
and finally, if both @code{%define api.pure} and @code{%locations} are used: If @code{%define api.pure full} (or just @code{%define api.pure}) is added:
@example @example
int yylex (YYSTYPE *lvalp, YYLTYPE *llocp, int *nastiness); int yylex (YYSTYPE *lvalp, int *nastiness);
int yyparse (int *nastiness, int *randomness);
@end example @end example
@node Error Reporting @node Error Reporting
@@ -6194,50 +6237,16 @@ error recovery if you have written suitable error recovery grammar rules
immediately return 1. immediately return 1.
Obviously, in location tracking pure parsers, @code{yyerror} should have Obviously, in location tracking pure parsers, @code{yyerror} should have
an access to the current location. an access to the current location. With @code{%define api.pure}, this is
This is indeed the case for the GLR indeed the case for the GLR parsers, but not for the Yacc parser, for
parsers, but not for the Yacc parser, for historical reasons. I.e., if historical reasons, and this is the why @code{%define api.pure full} should be
@samp{%locations %define api.pure} is passed then the prototypes for prefered over @code{%define api.pure}.
@code{yyerror} are:
When @code{%locations %define api.pure full} is used, @code{yyerror} has the
following signature:
@example @example
void yyerror (char const *msg); /* Yacc parsers. */ void yyerror (YYLTYPE *locp, char const *msg);
void yyerror (YYLTYPE *locp, char const *msg); /* GLR parsers. */
@end example
If @samp{%parse-param @{int *nastiness@}} is used, then:
@example
void yyerror (int *nastiness, char const *msg); /* Yacc parsers. */
void yyerror (int *nastiness, char const *msg); /* GLR parsers. */
@end 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
@code{%define api.pure} are pure.
I.e.:
@example
/* Location tracking. */
%locations
/* Pure yylex. */
%define api.pure
%lex-param @{int *nastiness@}
/* Pure yyparse. */
%parse-param @{int *nastiness@}
%parse-param @{int *randomness@}
@end example
@noindent
results in the following signatures for all the parser kinds:
@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);
@end example @end example
@noindent @noindent
@@ -9790,7 +9799,7 @@ described by @var{m}.
The parser invokes the scanner by calling @code{yylex}. Contrary to C 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 parsers, C++ parsers are always pure: there is no point in using the
@code{%define api.pure} directive. Therefore the interface is as follows. @code{%define api.pure full} directive. Therefore the interface is as follows.
@deftypemethod {parser} {int} yylex (semantic_type* @var{yylval}, location_type* @var{yylloc}, @var{type1} @var{arg1}, ...) @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 Return the next token. Its type is the return value, its semantic
@@ -10353,7 +10362,7 @@ You can create documentation for generated parsers using Javadoc.
Contrary to C parsers, Java parsers do not use global variables; the 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. 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} Therefore, all Java parsers are ``pure'', and the @code{%pure-parser}
and @code{%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. Java.
Push parsers are currently unsupported in Java and @code{%define Push parsers are currently unsupported in Java and @code{%define
@@ -10936,7 +10945,7 @@ or
@quotation @quotation
My parser includes support for an @samp{#include}-like feature, in My parser includes support for an @samp{#include}-like feature, in
which case I run @code{yyparse} from @code{yyparse}. This fails 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 @end quotation
These problems typically come not from Bison itself, but from These problems typically come not from Bison itself, but from