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