multistart: also give access to yynerrs

This is something that has always bothered me: with pure parsers (and
they all should be) the user does not have an (easy) access to yynerrs
at the end of the parse.  In the case of error recovery, that's the
only direct means to know if there were errors.  The usual approach
being having the user maintain a counter incremented each time yyerror
is called.

So here, also capture yynerrs in the return value of the start-symbol
parsing functions.

* data/skeletons/yacc.c (yy_parse_impl_t): New.
(yy_parse_impl): Use it.
(b4_accept): Fill it.
* examples/c/lexcalc/parse.y, examples/c/lexcalc/scan.l: No longer
pass nerrs as lex- and parse-param, just use the resulting yynerrs.
bistromathic and reccalc both demonstrate %param.
This commit is contained in:
Akim Demaille
2020-08-03 19:02:15 +02:00
parent f4d33ff4b4
commit d441a34791
4 changed files with 39 additions and 24 deletions

View File

@@ -25,10 +25,10 @@
{
// Tell Flex the expected prototype of yylex.
#define YY_DECL \
yytoken_kind_t yylex (YYSTYPE* yylval, YYLTYPE *yylloc, int *nerrs)
yytoken_kind_t yylex (YYSTYPE* yylval, YYLTYPE *yylloc)
YY_DECL;
void yyerror (YYLTYPE *loc, int *nerrs, const char *msg);
void yyerror (YYLTYPE *loc, const char *msg);
}
// Emitted on top of the implementation file.
@@ -62,9 +62,6 @@
// Enable debug traces (see yydebug in main).
%define parse.trace
// Error count, exchanged between main, yyparse and yylex.
%param {int *nerrs}
%token
PLUS "+"
MINUS "-"
@@ -109,7 +106,7 @@ exp:
{
if ($3 == 0)
{
yyerror (&@$, nerrs, "error: division by zero");
yyerror (&@$, "error: division by zero");
YYERROR;
}
else
@@ -121,19 +118,19 @@ exp:
%%
// Epilogue (C code).
void yyerror (YYLTYPE *loc, int *nerrs, const char *msg)
void yyerror (YYLTYPE *loc, const char *msg)
{
YY_LOCATION_PRINT (stderr, *loc);
fprintf (stderr, ": %s\n", msg);
++*nerrs;
}
int main (int argc, const char *argv[])
{
int nerrs = 0;
// Possibly enable parser runtime debugging.
yydebug = !!getenv ("YYDEBUG");
int parse_expression_p = 0;
int nerrs = 0;
// Enable parse traces on option -p.
for (int i = 0; i < argc; ++i)
if (1 < argc && strcmp (argv[1], "-p") == 0)
@@ -143,14 +140,19 @@ int main (int argc, const char *argv[])
if (parse_expression_p)
{
yyparse_expression_t res = yyparse_expression (&nerrs);
yyparse_expression_t res = yyparse_expression ();
nerrs = res.yynerrs;
if (res.yystatus == 0)
printf ("expression: %d\n", res.yyvalue);
else
printf ("expression: failure\n");
}
else
yyparse_input (&nerrs);
nerrs = yyparse_input ().yynerrs;
if (nerrs)
fprintf (stderr, "errors: %d\n", nerrs);
// Exit on failure if there were errors.
return !!nerrs;
}