yacc.c: use negative numbers for errors in auxiliary functions

yyparse returns 0, 1, 2 since ages (accept, reject, memory exhausted).
Some of our auxiliary functions such as yy_lac and
yyreport_syntax_error also need to return error codes and also use 0,
1, 2.  Because it uses yy_lac, yyexpected_tokens also needs to return
"problem", "memory exhausted", but in case of success, it needs to
return the number of tokens, so it cannot use 1 and 2 as error code.
Currently it uses -1 and -2, which is later converted into 1 and 2 as
yacc.c expects it.

Let's simplify this and use consistently -1 and -2 for auxiliary
functions that are not exposed (or not yet exposed) to the user.  In
particular this will save the user from having to convert
yyexpected_tokens's -2 into yyreport_syntax_error's 2: both return -1
or -2.

* data/skeletons/yacc.c (yy_lac, yyreport_syntax_error)
(yy_lac_stack_realloc): Return -1, -2 for errors instead of 1, 2.
Adjust callers.
* examples/c/bistromathic/parse.y (yyreport_syntax_error): Do take
error codes into account.
Issue a syntax error message even if we ran out of memory.
* src/parse-gram.y, tests/local.at (yyreport_syntax_error): Adjust.
This commit is contained in:
Akim Demaille
2020-03-21 08:39:31 +01:00
parent 1079595b2a
commit 84b1972c96
4 changed files with 36 additions and 29 deletions

View File

@@ -877,7 +877,7 @@ static char yypstate_allocated = 0;]])])[
*YYTOP, and *YYCAPACITY to reflect the new capacity and memory *YYTOP, and *YYCAPACITY to reflect the new capacity and memory
location. If *YYBOTTOM != YYBOTTOM_NO_FREE, then free the old stack location. If *YYBOTTOM != YYBOTTOM_NO_FREE, then free the old stack
using YYSTACK_FREE. Return 0 if successful or if no reallocation is using YYSTACK_FREE. Return 0 if successful or if no reallocation is
required. Return 1 if memory is exhausted. */ required. Return -2 if memory is exhausted. */
static int static int
yy_lac_stack_realloc (YYPTRDIFF_T *yycapacity, YYPTRDIFF_T yyadd, yy_lac_stack_realloc (YYPTRDIFF_T *yycapacity, YYPTRDIFF_T yyadd,
#if ]b4_api_PREFIX[DEBUG #if ]b4_api_PREFIX[DEBUG
@@ -902,7 +902,7 @@ yy_lac_stack_realloc (YYPTRDIFF_T *yycapacity, YYPTRDIFF_T yyadd,
{ {
YYDPRINTF ((stderr, "%smax size exceeded%s", yydebug_prefix, YYDPRINTF ((stderr, "%smax size exceeded%s", yydebug_prefix,
yydebug_suffix)); yydebug_suffix));
return 1; return -2;
} }
if (YYMAXDEPTH < yyalloc) if (YYMAXDEPTH < yyalloc)
yyalloc = YYMAXDEPTH; yyalloc = YYMAXDEPTH;
@@ -914,7 +914,7 @@ yy_lac_stack_realloc (YYPTRDIFF_T *yycapacity, YYPTRDIFF_T yyadd,
{ {
YYDPRINTF ((stderr, "%srealloc failed%s", yydebug_prefix, YYDPRINTF ((stderr, "%srealloc failed%s", yydebug_prefix,
yydebug_suffix)); yydebug_suffix));
return 1; return -2;
} }
if (*yytop != yytop_empty) if (*yytop != yytop_empty)
{ {
@@ -970,7 +970,7 @@ do { \
yy_lac_established = 1; \ yy_lac_established = 1; \
switch (yy_lac (yyesa, &yyes, &yyes_capacity, yyssp, yytoken)) \ switch (yy_lac (yyesa, &yyes, &yyes_capacity, yyssp, yytoken)) \
{ \ { \
case 2: \ case -2: \
goto yyexhaustedlab; \ goto yyexhaustedlab; \
case 1: \ case 1: \
goto yyerrlab; \ goto yyerrlab; \
@@ -1005,7 +1005,7 @@ do { \
/* Given the stack whose top is *YYSSP, return 0 iff YYTOKEN can /* Given the stack whose top is *YYSSP, return 0 iff YYTOKEN can
eventually (after perhaps some reductions) be shifted, return 1 if eventually (after perhaps some reductions) be shifted, return 1 if
not, or return 2 if memory is exhausted. As preconditions and not, or return -2 if memory is exhausted. As preconditions and
postconditions: *YYES_CAPACITY is the allocated size of the array to postconditions: *YYES_CAPACITY is the allocated size of the array to
which *YYES points, and either *YYES = YYESA or *YYES points to an which *YYES points, and either *YYES = YYESA or *YYES points to an
array allocated with YYSTACK_ALLOC. yy_lac may overwrite the array allocated with YYSTACK_ALLOC. yy_lac may overwrite the
@@ -1105,7 +1105,7 @@ yy_lac (yy_state_t *yyesa, yy_state_t **yyes,
yyes, yyesa, &yyesp, yyes_prev)) yyes, yyesa, &yyesp, yyes_prev))
{ {
YYDPRINTF ((stderr, "\n")); YYDPRINTF ((stderr, "\n"));
return 2; return -2;
} }
YY_IGNORE_USELESS_CAST_BEGIN YY_IGNORE_USELESS_CAST_BEGIN
*++yyesp = YY_CAST (yy_state_t, yystate); *++yyesp = YY_CAST (yy_state_t, yystate);
@@ -1132,7 +1132,9 @@ typedef struct
/* Put in YYARG at most YYARGN of the expected tokens given the /* Put in YYARG at most YYARGN of the expected tokens given the
current YYCTX, and return the number of tokens stored in YYARG. If current YYCTX, and return the number of tokens stored in YYARG. If
YYARG is null, return the number of expected tokens (guaranteed to YYARG is null, return the number of expected tokens (guaranteed to
be less than YYNTOKENS). */]b4_push_if([[ be less than YYNTOKENS). Return -2 on memory exhaustion. Return 0
if there are more than YYARGN expected tokens, yet fill YYARG up to
YYARGN. */]b4_push_if([[
static int static int
yypstate_expected_tokens (yypstate *yyps, yypstate_expected_tokens (yypstate *yyps,
int yyarg[], int yyargn)]], [[ int yyarg[], int yyargn)]], [[
@@ -1149,7 +1151,7 @@ yyexpected_tokens (const yyparse_context_t *yyctx,
switch (yy_lac (]b4_push_if([[yyps->yyesa, &yyps->yyes, &yyps->yyes_capacity, yyps->yyssp, yyx]], switch (yy_lac (]b4_push_if([[yyps->yyesa, &yyps->yyes, &yyps->yyes_capacity, yyps->yyssp, yyx]],
[[yyctx->yyesa, yyctx->yyes, yyctx->yyes_capacity, yyctx->yyssp, yyx]])[)) [[yyctx->yyesa, yyctx->yyes, yyctx->yyes_capacity, yyctx->yyssp, yyx]])[))
{ {
case 2: case -2:
return -2; return -2;
case 1: case 1:
continue; continue;
@@ -1358,11 +1360,11 @@ yytnamerr (char *yyres, const char *yystr)
YYSSP.]b4_lac_if([[ In order to see if a particular token T is a YYSSP.]b4_lac_if([[ In order to see if a particular token T is a
valid looakhead, invoke yy_lac (YYESA, YYES, YYES_CAPACITY, YYSSP, T).]])[ valid looakhead, invoke yy_lac (YYESA, YYES, YYES_CAPACITY, YYSSP, T).]])[
Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is
not large enough to hold the message. In that case, also set not large enough to hold the message. In that case, also set
*YYMSG_ALLOC to the required number of bytes. Return 2 if the *YYMSG_ALLOC to the required number of bytes. Return -2 if the
required number of bytes is too large to store]b4_lac_if([[ or if required number of bytes is too large to store]b4_lac_if([[ or if
yy_lac returned 2]])[. */ yy_lac returned -2]])[. */
static int static int
yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
const yyparse_context_t *yyctx) const yyparse_context_t *yyctx)
@@ -1379,7 +1381,7 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
/* Actual size of YYARG. */ /* Actual size of YYARG. */
int yycount = yysyntax_error_arguments (yyctx, yyarg, YYARGS_MAX); int yycount = yysyntax_error_arguments (yyctx, yyarg, YYARGS_MAX);
if (yycount == -2) if (yycount == -2)
return 2; return -2;
switch (yycount) switch (yycount)
{ {
@@ -1411,7 +1413,7 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
yysize = yysize1; yysize = yysize1;
else else
return 2; return -2;
} }
} }
@@ -1421,7 +1423,7 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
if (! (yysize <= *yymsg_alloc if (! (yysize <= *yymsg_alloc
&& *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
*yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
return 1; return -1;
} }
/* Avoid sprintf, as that infringes on the user's name space. /* Avoid sprintf, as that infringes on the user's name space.
@@ -1906,7 +1908,7 @@ yyerrlab:
yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx);
if (yysyntax_error_status == 0) if (yysyntax_error_status == 0)
yymsgp = yymsg; yymsgp = yymsg;
else if (yysyntax_error_status == 1) else if (yysyntax_error_status == -1)
{ {
if (yymsg != yymsgbuf) if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg); YYSTACK_FREE (yymsg);
@@ -1922,11 +1924,11 @@ yyerrlab:
{ {
yymsg = yymsgbuf; yymsg = yymsgbuf;
yymsg_alloc = sizeof yymsgbuf; yymsg_alloc = sizeof yymsgbuf;
yysyntax_error_status = 2; yysyntax_error_status = -2;
} }
} }
yyerror (]b4_yyerror_args[yymsgp); yyerror (]b4_yyerror_args[yymsgp);
if (yysyntax_error_status == 2) if (yysyntax_error_status == -2)
goto yyexhaustedlab; goto yyexhaustedlab;
}]])[ }]])[
} }

View File

@@ -285,19 +285,24 @@ int
yyreport_syntax_error (const yyparse_context_t *ctx) yyreport_syntax_error (const yyparse_context_t *ctx)
{ {
enum { ARGMAX = 10 }; enum { ARGMAX = 10 };
int res = 0;
int arg[ARGMAX]; int arg[ARGMAX];
int n = yysyntax_error_arguments (ctx, arg, ARGMAX); int n = yysyntax_error_arguments (ctx, arg, ARGMAX);
if (n == -2) if (n < 0)
return 2; // Forward errors to yyparse.
res = n;
YY_LOCATION_PRINT (stderr, *yyparse_context_location (ctx)); YY_LOCATION_PRINT (stderr, *yyparse_context_location (ctx));
fprintf (stderr, ": syntax error"); fprintf (stderr, ": syntax error");
for (int i = 1; i < n; ++i) if (n >= 0)
fprintf (stderr, "%s %s", {
i == 1 ? ": expected" : " or", yysymbol_name (arg[i])); for (int i = 1; i < n; ++i)
if (n) fprintf (stderr, "%s %s",
fprintf (stderr, " before %s", yysymbol_name (arg[0])); i == 1 ? ": expected" : " or", yysymbol_name (arg[i]));
if (n)
fprintf (stderr, " before %s", yysymbol_name (arg[0]));
}
fprintf (stderr, "\n"); fprintf (stderr, "\n");
return 0; return res;
} }
// Called by yyparse on error. // Called by yyparse on error.

View File

@@ -806,8 +806,8 @@ yyreport_syntax_error (const yyparse_context_t *ctx)
one per "expected"). */ one per "expected"). */
int arg[ARGS_MAX]; int arg[ARGS_MAX];
int n = yysyntax_error_arguments (ctx, arg, ARGS_MAX); int n = yysyntax_error_arguments (ctx, arg, ARGS_MAX);
if (n == -2) if (n < 0)
return 2; return n;
const char *argv[ARGS_MAX]; const char *argv[ARGS_MAX];
for (int i = 0; i < n; ++i) for (int i = 0; i < n; ++i)
argv[i] = yysymbol_name (arg[i]); argv[i] = yysymbol_name (arg[i]);

View File

@@ -632,8 +632,8 @@ yyreport_syntax_error (const yyparse_context_t *ctx]AT_PARAM_IF([, AT_PARSE_PARA
YYUSE (\1);])])[]m4_bmatch(m4_defn([AT_PARSE_PARAMS]), [nerrs],[[ YYUSE (\1);])])[]m4_bmatch(m4_defn([AT_PARSE_PARAMS]), [nerrs],[[
++global_nerrs; ++global_nerrs;
++*nerrs;]])[ ++*nerrs;]])[
if (n == -2) if (n < 0)
return 2; return n;
if (n) if (n)
{]AT_LOCATION_IF([[ {]AT_LOCATION_IF([[
LOCATION_PRINT (stderr, *yyparse_context_location (ctx)); LOCATION_PRINT (stderr, *yyparse_context_location (ctx));