mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
c: add support for YYNOMEM
Suggested by Joe Nelson <joe@begriffs.com>. https://lists.gnu.org/r/help-bison/2020-12/msg00020.html * data/skeletons/glr.c, data/skeletons/yacc.c (YYNOMEM): New. Use it. (yyexhaustedlab): Rename as... (yynomemlab): this. * tests/calc.at: Check it. * doc/bison.texi: Document it. Fix incorrect statements about non-existing constants for YYERROR etc.
This commit is contained in:
5
NEWS
5
NEWS
@@ -64,6 +64,11 @@ GNU Bison NEWS
|
||||
The Java skeleton (lalr1.java) now supports LAC, via the `parse.lac`
|
||||
%define variable.
|
||||
|
||||
*** Abort parsing for memory exhaustion (C)
|
||||
|
||||
The user actions may now use YYNOMEM to abort the current parse with
|
||||
memory exhaustion.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.7.4 (2020-11-14) [stable]
|
||||
|
||||
|
||||
@@ -442,7 +442,7 @@ int yychar;])[
|
||||
|
||||
enum { YYENOMEM = -2 };
|
||||
|
||||
typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
|
||||
typedef enum { yyok, yyaccept, yyabort, yyerr, yynomem } YYRESULTTAG;
|
||||
|
||||
#define YYCHK(YYE) \
|
||||
do { \
|
||||
@@ -898,7 +898,7 @@ yyfill (yyGLRStackItem *yyvsp, int *yylow, int yylow1, yybool yynormal)
|
||||
* and top stack item YYVSP. YYLVALP points to place to put semantic
|
||||
* value ($$), and yylocp points to place for location information
|
||||
* (@@$). Returns yyok for normal return, yyaccept for YYACCEPT,
|
||||
* yyerr for YYERROR, yyabort for YYABORT. */
|
||||
* yyerr for YYERROR, yyabort for YYABORT, yynomem for YYNOMEM. */
|
||||
static YYRESULTTAG
|
||||
yyuserAction (yyRuleNum yyrule, int yyrhslen, yyGLRStackItem* yyvsp,
|
||||
yyGLRStack* yystackp, YYPTRDIFF_T yyk,
|
||||
@@ -915,6 +915,8 @@ yyuserAction (yyRuleNum yyrule, int yyrhslen, yyGLRStackItem* yyvsp,
|
||||
# define YYACCEPT return yyaccept
|
||||
# undef YYABORT
|
||||
# define YYABORT return yyabort
|
||||
# undef YYNOMEM
|
||||
# define YYNOMEM return yynomem
|
||||
# undef YYERROR
|
||||
# define YYERROR return yyerrok, yyerr
|
||||
# undef YYRECOVERING
|
||||
@@ -965,6 +967,7 @@ yyuserAction (yyRuleNum yyrule, int yyrhslen, yyGLRStackItem* yyvsp,
|
||||
# undef yyerrok
|
||||
# undef YYABORT
|
||||
# undef YYACCEPT
|
||||
# undef YYNOMEM
|
||||
# undef YYERROR
|
||||
# undef YYBACKUP
|
||||
# undef yyclearin
|
||||
@@ -2431,6 +2434,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
case yyabort: goto yyabortlab; \
|
||||
case yyaccept: goto yyacceptlab; \
|
||||
case yyerr: goto yyuser_error; \
|
||||
case yynomem: goto yyexhaustedlab; \
|
||||
default: goto yybuglab; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@@ -732,6 +732,7 @@ enum { YYENOMEM = -2 };
|
||||
#define YYACCEPT goto yyacceptlab
|
||||
#define YYABORT goto yyabortlab
|
||||
#define YYERROR goto yyerrorlab
|
||||
#define YYNOMEM goto yyexhaustedlab
|
||||
|
||||
|
||||
#define YYRECOVERING() (!!yyerrstatus)
|
||||
@@ -987,7 +988,7 @@ do { \
|
||||
switch (yy_lac (yyesa, &yyes, &yyes_capacity, yyssp, yytoken)) \
|
||||
{ \
|
||||
case YYENOMEM: \
|
||||
goto yyexhaustedlab; \
|
||||
YYNOMEM; \
|
||||
case 1: \
|
||||
goto yyerrlab; \
|
||||
} \
|
||||
@@ -1707,7 +1708,7 @@ yysetstate:
|
||||
|
||||
if (yyss + yystacksize - 1 <= yyssp)
|
||||
#if !defined yyoverflow && !defined YYSTACK_RELOCATE
|
||||
goto yyexhaustedlab;
|
||||
YYNOMEM;
|
||||
#else
|
||||
{
|
||||
/* Get the current used size of the three stacks, in elements. */
|
||||
@@ -1738,7 +1739,7 @@ yysetstate:
|
||||
# else /* defined YYSTACK_RELOCATE */
|
||||
/* Extend the stack our own way. */
|
||||
if (YYMAXDEPTH <= yystacksize)
|
||||
goto yyexhaustedlab;
|
||||
YYNOMEM;
|
||||
yystacksize *= 2;
|
||||
if (YYMAXDEPTH < yystacksize)
|
||||
yystacksize = YYMAXDEPTH;
|
||||
@@ -1749,7 +1750,7 @@ yysetstate:
|
||||
YY_CAST (union yyalloc *,
|
||||
YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
|
||||
if (! yyptr)
|
||||
goto yyexhaustedlab;
|
||||
YYNOMEM;
|
||||
YYSTACK_RELOCATE (yyss_alloc, yyss);
|
||||
YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([
|
||||
YYSTACK_RELOCATE (yyls_alloc, yyls);])[
|
||||
@@ -1980,8 +1981,8 @@ yyerrlab:
|
||||
if (yychar != ]b4_symbol(empty, id)[)
|
||||
YY_LAC_ESTABLISH;]])[
|
||||
if (yyreport_syntax_error (&yyctx]m4_ifset([b4_parse_param],
|
||||
[[, ]b4_args(b4_parse_param)])[) == 2)
|
||||
goto yyexhaustedlab;
|
||||
[[, ]b4_args(b4_parse_param)])[) == 2)
|
||||
YYNOMEM;
|
||||
}]],
|
||||
[simple],
|
||||
[[ yyerror (]b4_yyerror_args[YY_("syntax error"));]],
|
||||
@@ -2016,7 +2017,7 @@ yyerrlab:
|
||||
}
|
||||
yyerror (]b4_yyerror_args[yymsgp);
|
||||
if (yysyntax_error_status == YYENOMEM)
|
||||
goto yyexhaustedlab;
|
||||
YYNOMEM;
|
||||
}]])[
|
||||
}
|
||||
]b4_locations_if([[
|
||||
@@ -2132,15 +2133,13 @@ yyabortlab:
|
||||
goto yyreturnlab;
|
||||
|
||||
|
||||
#if ]b4_lac_if([[1]], [b4_parse_error_case([simple], [[!defined yyoverflow]], [[1]])])[
|
||||
/*-------------------------------------------------.
|
||||
| yyexhaustedlab -- memory exhaustion comes here. |
|
||||
`-------------------------------------------------*/
|
||||
/*-----------------------------------------------------------.
|
||||
| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
|
||||
`-----------------------------------------------------------*/
|
||||
yyexhaustedlab:
|
||||
yyerror (]b4_yyerror_args[YY_("memory exhausted"));
|
||||
yyresult = 2;
|
||||
goto yyreturnlab;
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------.
|
||||
|
||||
@@ -5239,10 +5239,10 @@ For instance, if your locations use a file name, you may use
|
||||
@findex %destructor
|
||||
@findex <*>
|
||||
@findex <>
|
||||
During error recovery (@pxref{Error Recovery}), symbols already pushed
|
||||
on the stack and tokens coming from the rest of the file are discarded
|
||||
until the parser falls on its feet. If the parser runs out of memory,
|
||||
or if it returns via @code{YYABORT} or @code{YYACCEPT}, all the
|
||||
During error recovery (@pxref{Error Recovery}), symbols already pushed on
|
||||
the stack and tokens coming from the rest of the file are discarded until
|
||||
the parser falls on its feet. If the parser runs out of memory, or if it
|
||||
returns via @code{YYABORT}, @code{YYACCEPT} or @code{YYNOMEM}, all the
|
||||
symbols on the stack must be discarded. Even if the parser succeeds, it
|
||||
must discard the start symbol.
|
||||
|
||||
@@ -5368,8 +5368,8 @@ the start symbol, when the parser succeeds.
|
||||
@end itemize
|
||||
|
||||
The parser can @dfn{return immediately} because of an explicit call to
|
||||
@code{YYABORT} or @code{YYACCEPT}, or failed error recovery, or memory
|
||||
exhaustion.
|
||||
@code{YYABORT}, @code{YYACCEPT} or @code{YYNOMEM}, or failed error recovery,
|
||||
or memory exhaustion.
|
||||
|
||||
Right-hand side symbols of a rule that explicitly triggers a syntax
|
||||
error via @code{YYERROR} are not discarded automatically. As a rule
|
||||
@@ -7215,6 +7215,11 @@ Return immediately with value 0 (to report success).
|
||||
Return immediately with value 1 (to report failure).
|
||||
@end defmac
|
||||
|
||||
@defmac YYNOMEM
|
||||
@findex YYNOMEM
|
||||
Return immediately with value 2 (to report memory exhaustion).
|
||||
@end defmac
|
||||
|
||||
If you use a reentrant parser, you can optionally pass additional
|
||||
parameter information to it in a reentrant way. To do so, use the
|
||||
declaration @code{%parse-param}:
|
||||
@@ -7936,6 +7941,11 @@ want to print an error message, call @code{yyerror} explicitly before
|
||||
the @samp{YYERROR;} statement. @xref{Error Recovery}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Macro} YYNOMEM @code{;}
|
||||
Return immediately from @code{yyparse}, indicating memory exhaustion.
|
||||
@xref{Parser Function}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Macro} YYRECOVERING
|
||||
@findex YYRECOVERING
|
||||
The expression @code{YYRECOVERING ()} yields 1 when the parser
|
||||
@@ -14676,10 +14686,10 @@ api.push-pull both" declaration is used (@pxref{%define
|
||||
Summary}). The @code{Location} and @code{Position}
|
||||
parameters are available only if location tracking is active.
|
||||
|
||||
The value returned by the @code{push_parse} method is one of the following
|
||||
four constants: @code{YYABORT}, @code{YYACCEPT}, @code{YYERROR}, or
|
||||
@code{YYPUSH_MORE}. This new value, @code{YYPUSH_MORE}, may be returned if
|
||||
more input is required to finish parsing the grammar.
|
||||
The value returned by the @code{push_parse} method is one of the following:
|
||||
0 (success), 1 (abort), 2 (memory exhaustion), or @code{YYPUSH_MORE}. This
|
||||
new value, @code{YYPUSH_MORE}, may be returned if more input is required to
|
||||
finish parsing the grammar.
|
||||
|
||||
If api.push-pull is declared as @code{both}, then the generated parser class
|
||||
will also implement the @code{parse} method. This method's body is a loop
|
||||
@@ -14719,13 +14729,12 @@ section summarizes these differences.
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Java lacks a preprocessor, so the @code{YYERROR}, @code{YYACCEPT},
|
||||
@code{YYABORT} symbols (@pxref{Table of Symbols}) cannot obviously be
|
||||
macros. Instead, they should be preceded by @code{return} when they
|
||||
appear in an action. The actual definition of these symbols is
|
||||
opaque to the Bison grammar, and it might change in the future. The
|
||||
only meaningful operation that you can do, is to return them.
|
||||
@xref{Java Action Features}.
|
||||
Java lacks a preprocessor, so obviously the @code{YYERROR}, @code{YYACCEPT},
|
||||
@code{YYABORT} symbols (@pxref{Table of Symbols}) cannot be macros.
|
||||
Instead, they should be preceded by @code{return} when they appear in an
|
||||
action. The actual definition of these symbols is opaque to the Bison
|
||||
grammar, and it might change in the future. The only meaningful operation
|
||||
that you can do, is to return them. @xref{Java Action Features}.
|
||||
|
||||
Note that of these three symbols, only @code{YYACCEPT} and
|
||||
@code{YYABORT} will cause a return from the @code{yyparse}
|
||||
@@ -16006,6 +16015,12 @@ pure push parser, it is a member of @code{yypstate}.)
|
||||
@xref{Error Reporting Function}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Macro} YYNOMEM
|
||||
Macro to pretend that memory is exhausted, by making @code{yyparse} return 2
|
||||
immediately. The error reporting function @code{yyerror} is called.
|
||||
@xref{Parser Function}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Function} yyparse
|
||||
The parser function produced by Bison; call this function to start
|
||||
parsing. @xref{Parser Function}.
|
||||
@@ -16518,12 +16533,13 @@ London, Department of Computer Science, TR-00-12 (December 2000).
|
||||
@c LocalWords: YYUNDEF SymbolKind yypcontext YYENOMEM TOKENMAX getBundle
|
||||
@c LocalWords: ResourceBundle myResources getString getName getToken ylwrap
|
||||
@c LocalWords: getLocation getExpectedTokens reportSyntaxError bistromathic
|
||||
@c LocalWords: TokenKind Automake's rtti Wcounterexamples Chinawat PLDI
|
||||
@c LocalWords: TokenKind Automake's rtti Wcounterexamples Chinawat PLDI buf
|
||||
@c LocalWords: Isradisaikul tcite pcite rgbGreen colorGreen rgbYellow Wcex
|
||||
@c LocalWords: colorYellow rgbRed colorRed rgbBlue colorBlue rgbPurple Ddoc
|
||||
@c LocalWords: colorPurple ifhtml ifnothtml situ rcex MERCHANTABILITY Wnone
|
||||
@c LocalWords: diagError diagNotice diagWarning diagOff danglingElseCex
|
||||
@c LocalWords: nonunifying
|
||||
@c LocalWords: nonunifying YYNOMEM Wuseless dgettext textdomain domainname
|
||||
@c LocalWords: dirname typeof writeln YYBISON
|
||||
|
||||
@c Local Variables:
|
||||
@c ispell-dictionary: "american"
|
||||
|
||||
@@ -32,3 +32,4 @@ The grammar features several special directives:
|
||||
- `!!` YYERROR
|
||||
- `!+` YYACCEPT
|
||||
- `!-` YYABORT
|
||||
- `!*` YYNOMEM
|
||||
|
||||
@@ -447,7 +447,8 @@ exp:
|
||||
| '-' error { $$ = 0; YYERROR; }
|
||||
| '!' '!' { $$ = 0; YYERROR; }
|
||||
| '!' '+' { $$ = 0; YYACCEPT; }
|
||||
| '!' '-' { $$ = 0; YYABORT; }
|
||||
| '!' '-' { $$ = 0; YYABORT; }]AT_C_IF([[
|
||||
| '!' '*' { $$ = 0; YYNOMEM; }]])[
|
||||
;
|
||||
%%
|
||||
|
||||
@@ -1224,7 +1225,7 @@ _AT_CHECK_CALC_ERROR([$1], [0], [(* *) + (*) + (*)],
|
||||
|
||||
# Special actions.
|
||||
# ----------------
|
||||
# !+ => YYACCEPT, !- => YYABORT, !! => YYERROR.
|
||||
# !+ => YYACCEPT, !- => YYABORT, !! => YYERROR, !* => YYNOMEM.
|
||||
|
||||
# YYACCEPT.
|
||||
# Java lacks the traces at the end for cleaning the stack
|
||||
@@ -1238,6 +1239,12 @@ _AT_CHECK_CALC([], [1 + 2 * 3 + !+ ++],
|
||||
_AT_CHECK_CALC_ERROR([$1], [1], [1 + 2 * 3 + !- ++],
|
||||
[AT_PARAM_IF([final: 0 0 0])],
|
||||
[102])
|
||||
AT_C_IF(
|
||||
[# YYNOMEM.
|
||||
_AT_CHECK_CALC_ERROR([$1], [2], [1 + 2 * 3 + !* ++],
|
||||
[AT_PARAM_IF([final: 0 0 1])],
|
||||
[102],
|
||||
[1.14: memory exhausted])])
|
||||
|
||||
|
||||
# YYerror.
|
||||
|
||||
Reference in New Issue
Block a user