[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 5/5] c: add support for YYNOMEM
From: |
Akim Demaille |
Subject: |
[PATCH 5/5] c: add support for YYNOMEM |
Date: |
Sat, 16 Jan 2021 12:59:05 +0100 |
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.
---
NEWS | 5 ++++
data/skeletons/glr.c | 8 +++++--
data/skeletons/yacc.c | 23 +++++++++---------
doc/bison.texi | 54 ++++++++++++++++++++++++++++---------------
tests/README.md | 1 +
tests/calc.at | 11 +++++++--
6 files changed, 67 insertions(+), 35 deletions(-)
diff --git a/NEWS b/NEWS
index e12ba6fa..f2c235eb 100644
--- a/NEWS
+++ b/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]
diff --git a/data/skeletons/glr.c b/data/skeletons/glr.c
index ab398101..b9334aa2 100644
--- a/data/skeletons/glr.c
+++ b/data/skeletons/glr.c
@@ -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)
diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c
index 56a050b3..739382ce 100644
--- a/data/skeletons/yacc.c
+++ b/data/skeletons/yacc.c
@@ -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
/*----------------------------------------------------------.
diff --git a/doc/bison.texi b/doc/bison.texi
index e5cc7bd7..586dd5ce 100644
--- a/doc/bison.texi
+++ b/doc/bison.texi
@@ -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"
diff --git a/tests/README.md b/tests/README.md
index 76990a04..53d1a2bf 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -32,3 +32,4 @@ The grammar features several special directives:
- `!!` YYERROR
- `!+` YYACCEPT
- `!-` YYABORT
+- `!*` YYNOMEM
diff --git a/tests/calc.at b/tests/calc.at
index 2643d570..e7a5b070 100644
--- a/tests/calc.at
+++ b/tests/calc.at
@@ -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.
--
2.30.0
- [PATCH 0/5] Introduce YYNOMEM in C skeletons, Akim Demaille, 2021/01/16
- [PATCH 1/5] tests: check YYACCEPT and YYABORT, Akim Demaille, 2021/01/16
- [PATCH 2/5] glr.c: style: formatting changes, Akim Demaille, 2021/01/16
- [PATCH 3/5] yacc.c, glr.c: style: rename yyreturn and yyreturnlab, Akim Demaille, 2021/01/16
- [PATCH 4/5] doc: spell check, Akim Demaille, 2021/01/16
- [PATCH 5/5] c: add support for YYNOMEM,
Akim Demaille <=