From 93724f139a641f6242c93f1504eaf6ecfcaf439f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 7 Nov 2002 12:52:19 +0000 Subject: [PATCH] Let yyerror always receive the msg as last argument, so that yyerror can be variadic. * data/yacc.c (b4_yyerror_args): New. Use it when calling yyerror. * data/glr.c (b4_yyerror_args, b4_lyyerror_args): New. Use it when calling yyerror. * doc/bison.texinfo (Error Reporting): Adjust. * tests/calc.at (_AT_DATA_CALC_Y): Adjust. * tests/cxx-type.at (_AT_TEST_GLR_CALC): Adjust. --- ChangeLog | 13 +++++++++++++ data/glr.c | 26 +++++++++++++++++++++----- data/yacc.c | 19 ++++++++++--------- doc/bison.texinfo | 26 +++++++++++++++++--------- tests/calc.at | 13 +++++++------ tests/cxx-type.at | 10 ++++++---- 6 files changed, 74 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6cbcf67..27a868c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2002-11-07 Akim Demaille + + Let yyerror always receive the msg as last argument, so that + yyerror can be variadic. + + * data/yacc.c (b4_yyerror_args): New. + Use it when calling yyerror. + * data/glr.c (b4_yyerror_args, b4_lyyerror_args): New. + Use it when calling yyerror. + * doc/bison.texinfo (Error Reporting): Adjust. + * tests/calc.at (_AT_DATA_CALC_Y): Adjust. + * tests/cxx-type.at (_AT_TEST_GLR_CALC): Adjust. + 2002-11-07 Paul Eggert * src/scan-gram.l (unexpected_end_of_file): New function. diff --git a/data/glr.c b/data/glr.c index daea8b9..0db4757 100644 --- a/data/glr.c +++ b/data/glr.c @@ -54,9 +54,25 @@ m4_define([b4_user_formals], [m4_ifset([b4_parse_param], [, b4_c_ansi_formals(b4_parse_param)])]) +# b4_yyerror_args +# --------------- +# Arguments passed to yyerror: user args plus yylloc. +m4_define([b4_yyerror_args], +[b4_pure_if([b4_location_if([yylocp, ])])dnl +m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])]) + + +# b4_lyyerror_args +# ---------------- +# Same as above, but on the lookahead, hence yyllocp instead of yylocp. +m4_define([b4_lyyerror_args], +[b4_pure_if([b4_location_if([yyllocp, ])])dnl +m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])]) + + # b4_pure_args # ------------ -# Arguments passed to yyerror: user args plus yylloc. +# Arguments needed by yyerror: user args plus yylloc. m4_define([b4_pure_args], [b4_pure_if([b4_location_if([, yylocp])])[]b4_user_args]) @@ -581,7 +597,7 @@ yyFail (yyGLRStack* yystack]b4_pure_formals[, const char* yyformat, ...) va_start (yyap, yyformat); yystack->yyerrflag = 1; vsprintf (yymsg, yyformat, yyap); - yyerror (yymsg]b4_pure_args[); + yyerror (]b4_yyerror_args[yymsg); } longjmp (yystack->yyexception_buffer, 1); } @@ -636,7 +652,7 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp, # undef YYBACKUP # define YYBACKUP(Token, Value) \ do { \ - yyerror ("syntax error: cannot back up"]b4_pure_args[); \ + yyerror (]b4_yyerror_args["syntax error: cannot back up"); \ YYERROR; \ } while (0) @@ -1591,12 +1607,12 @@ yyreportParseError (yyGLRStack* yystack, yyprefix = " or "; } } - yyerror (yymsg]b4_lpure_args[); + yyerror (]b4_lyyerror_args[yymsg); free (yymsg); } else #endif - yyerror ("parse error"]b4_lpure_args[); + yyerror (]b4_lyyerror_args["parse error"); yynerrs += 1; } } diff --git a/data/yacc.c b/data/yacc.c index c6045e2..1c735a0 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -48,11 +48,12 @@ m4_define([b4_Pure_if], [$2])]) -# b4_pure_args -# ------------ +# b4_yyerror_args +# --------------- # Arguments passed to yyerror: user args plus yylloc. -m4_define([b4_pure_args], -[b4_Pure_if([b4_location_if([, &yylloc])])[]b4_user_args]) +m4_define([b4_yyerror_args], +[b4_Pure_if([b4_location_if([&yylloc, ])])dnl +m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])]) # b4_lex_param @@ -529,7 +530,7 @@ do \ } \ else \ { \ - yyerror ("syntax error: cannot back up"b4_pure_args); \ + yyerror (b4_yyerror_args"syntax error: cannot back up"); \ YYERROR; \ } \ while (0) @@ -1135,15 +1136,15 @@ yyerrlab: yycount++; } } - yyerror (yymsg]b4_pure_args[); + yyerror (]b4_yyerror_args[yymsg); YYSTACK_FREE (yymsg); } else - yyerror ("parse error; also virtual memory exhausted"]b4_pure_args[); + yyerror (]b4_yyerror_args["parse error; also virtual memory exhausted"); } else #endif /* YYERROR_VERBOSE */ - yyerror ("parse error"]b4_pure_args[); + yyerror (]b4_yyerror_args["parse error"); } goto yyerrlab1; @@ -1258,7 +1259,7 @@ yyabortlab: | yyoverflowlab -- parser overflow comes here. | `----------------------------------------------*/ yyoverflowlab: - yyerror ("parser stack overflow"]b4_pure_args[); + yyerror (]b4_yyerror_args["parser stack overflow"); yyresult = 2; /* Fall through. */ #endif diff --git a/doc/bison.texinfo b/doc/bison.texinfo index 290cbab..123c526 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -1357,7 +1357,7 @@ here is the definition we will use: #include void -yyerror (const char *s) /* called by yyparse on error */ +yyerror (const char *s) /* Called by yyparse on error. */ @{ printf ("%s\n", s); @} @@ -1973,7 +1973,7 @@ main (void) @group void -yyerror (const char *s) /* Called by yyparse on error */ +yyerror (const char *s) /* Called by yyparse on error. */ @{ printf ("%s\n", s); @} @@ -4050,7 +4050,7 @@ The following definition suffices in simple programs: @example @group void -yyerror (char *s) +yyerror (const char *s) @{ @end group @group @@ -4064,7 +4064,7 @@ error recovery if you have written suitable error recovery grammar rules (@pxref{Error Recovery}). If recovery is impossible, @code{yyparse} will immediately return 1. -Oviously, in location tracking pure parsers, @code{yyerror} should have +Obviously, in location tracking pure parsers, @code{yyerror} should have an access to the current location. This is indeed the case for the GLR parsers, but not for the Yacc parser, for historical reasons. I.e., if @samp{%locations %pure-parser} is passed then the prototypes for @@ -4072,14 +4072,14 @@ parsers, but not for the Yacc parser, for historical reasons. I.e., if @example void yyerror (const char *msg); /* Yacc parsers. */ -void yyerror (const char *msg, YYLTYPE *locp); /* GLR parsers. */ +void yyerror (YYLTYPE *locp, const char *msg); /* GLR parsers. */ @end example If @samp{%parse-param "int *nastiness" "nastiness"} is used, then: @example -void yyerror (int *randomness); /* Yacc parsers. */ -void yyerror (int *randomness); /* GLR parsers. */ +void yyerror (int *randomness, const char *msg); /* Yacc parsers. */ +void yyerror (int *randomness, const char *msg); /* GLR parsers. */ @end example Finally, GLR and Yacc parsers share the same @code{yyerror} calling @@ -4104,10 +4104,18 @@ results in the following signatures for all the parser kinds: @example int yylex (YYSTYPE *lvalp, YYLTYPE *llocp, int *nastiness); int yyparse (int *nastiness, int *randomness); -void yyerror (const char *msg, YYLTYPE *locp, - int *nastiness, int *randomness); +void yyerror (YYLTYPE *locp, + int *nastiness, int *randomness, + const char *msg); @end example +@noident +Please, note that the prototypes are only indications of how the code +produced by Bison will use @code{yyerror}, but you still have freedom +and the exit value, and even on making @code{yyerror} a variadic +function. It is precisely to enable this that the message is passed +last. + @vindex yynerrs The variable @code{yynerrs} contains the number of syntax errors encountered so far. Normally this variable is global; but if you diff --git a/tests/calc.at b/tests/calc.at index 4399d25..aff3b45 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -100,9 +100,9 @@ static int power (int base, int exponent); /* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ -static void yyerror (const char *s - ]AT_YYERROR_ARG_LOC_IF([, YYLTYPE *yylloc])[ - ]AT_PARAM_IF([, value_t *result, int *count])[ +static void yyerror (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *yylloc, ])[ + ]AT_PARAM_IF([value_t *result, int *count, ])[ + const char *s ); static int yylex (LEX_FORMALS); static int yygetc (LEX_FORMALS); @@ -154,9 +154,10 @@ exp: FILE *yyin; static void -yyerror (const char *s - ]AT_YYERROR_ARG_LOC_IF([, YYLTYPE *yylloc])[ - ]AT_PARAM_IF([, value_t *result, int *count])[) +yyerror (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *yylloc, ])[ + ]AT_PARAM_IF([value_t *result, int *count, ])[ + const char *s + ) { ]AT_PARAM_IF([(void) result; (void) count; ])[ ]AT_YYERROR_SEES_LOC_IF([ diff --git a/tests/cxx-type.at b/tests/cxx-type.at index 61c7f50..b63b2dd 100644 --- a/tests/cxx-type.at +++ b/tests/cxx-type.at @@ -36,10 +36,11 @@ $1 ]m4_bmatch([$2], [stmtMerge], [ static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1);])[ #define YYINITDEPTH 10 - int yyerror (const char *s + int yyerror ( #if YYPURE && YYLSP_NEEDED - , YYLTYPE *yylocation + YYLTYPE *yylocation, #endif + const char *s ); #if YYPURE @@ -157,10 +158,11 @@ yylex () } int -yyerror (const char *s +yyerror ( #if YYPURE && YYLSP_NEEDED - , YYLTYPE *yylocation + YYLTYPE *yylocation, #endif + const char *s ) { #if YYPURE && YYLSP_NEEDED -- 2.7.4