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.
This commit is contained in:
Akim Demaille
2002-11-07 12:52:19 +00:00
parent 0e25cad542
commit 93724f139a
6 changed files with 74 additions and 33 deletions

View File

@@ -1,3 +1,16 @@
2002-11-07 Akim Demaille <akim@epita.fr>
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 <eggert@twinsun.com> 2002-11-07 Paul Eggert <eggert@twinsun.com>
* src/scan-gram.l (unexpected_end_of_file): New function. * src/scan-gram.l (unexpected_end_of_file): New function.

View File

@@ -54,9 +54,25 @@ m4_define([b4_user_formals],
[m4_ifset([b4_parse_param], [, b4_c_ansi_formals(b4_parse_param)])]) [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 # b4_pure_args
# ------------ # ------------
# Arguments passed to yyerror: user args plus yylloc. # Arguments needed by yyerror: user args plus yylloc.
m4_define([b4_pure_args], m4_define([b4_pure_args],
[b4_pure_if([b4_location_if([, yylocp])])[]b4_user_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); va_start (yyap, yyformat);
yystack->yyerrflag = 1; yystack->yyerrflag = 1;
vsprintf (yymsg, yyformat, yyap); vsprintf (yymsg, yyformat, yyap);
yyerror (yymsg]b4_pure_args[); yyerror (]b4_yyerror_args[yymsg);
} }
longjmp (yystack->yyexception_buffer, 1); longjmp (yystack->yyexception_buffer, 1);
} }
@@ -636,7 +652,7 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
# undef YYBACKUP # undef YYBACKUP
# define YYBACKUP(Token, Value) \ # define YYBACKUP(Token, Value) \
do { \ do { \
yyerror ("syntax error: cannot back up"]b4_pure_args[); \ yyerror (]b4_yyerror_args["syntax error: cannot back up"); \
YYERROR; \ YYERROR; \
} while (0) } while (0)
@@ -1591,12 +1607,12 @@ yyreportParseError (yyGLRStack* yystack,
yyprefix = " or "; yyprefix = " or ";
} }
} }
yyerror (yymsg]b4_lpure_args[); yyerror (]b4_lyyerror_args[yymsg);
free (yymsg); free (yymsg);
} }
else else
#endif #endif
yyerror ("parse error"]b4_lpure_args[); yyerror (]b4_lyyerror_args["parse error");
yynerrs += 1; yynerrs += 1;
} }
} }

View File

@@ -48,11 +48,12 @@ m4_define([b4_Pure_if],
[$2])]) [$2])])
# b4_pure_args # b4_yyerror_args
# ------------ # ---------------
# Arguments passed to yyerror: user args plus yylloc. # Arguments passed to yyerror: user args plus yylloc.
m4_define([b4_pure_args], m4_define([b4_yyerror_args],
[b4_Pure_if([b4_location_if([, &yylloc])])[]b4_user_args]) [b4_Pure_if([b4_location_if([&yylloc, ])])dnl
m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])])
# b4_lex_param # b4_lex_param
@@ -529,7 +530,7 @@ do \
} \ } \
else \ else \
{ \ { \
yyerror ("syntax error: cannot back up"b4_pure_args); \ yyerror (b4_yyerror_args"syntax error: cannot back up"); \
YYERROR; \ YYERROR; \
} \ } \
while (0) while (0)
@@ -1135,15 +1136,15 @@ yyerrlab:
yycount++; yycount++;
} }
} }
yyerror (yymsg]b4_pure_args[); yyerror (]b4_yyerror_args[yymsg);
YYSTACK_FREE (yymsg); YYSTACK_FREE (yymsg);
} }
else else
yyerror ("parse error; also virtual memory exhausted"]b4_pure_args[); yyerror (]b4_yyerror_args["parse error; also virtual memory exhausted");
} }
else else
#endif /* YYERROR_VERBOSE */ #endif /* YYERROR_VERBOSE */
yyerror ("parse error"]b4_pure_args[); yyerror (]b4_yyerror_args["parse error");
} }
goto yyerrlab1; goto yyerrlab1;
@@ -1258,7 +1259,7 @@ yyabortlab:
| yyoverflowlab -- parser overflow comes here. | | yyoverflowlab -- parser overflow comes here. |
`----------------------------------------------*/ `----------------------------------------------*/
yyoverflowlab: yyoverflowlab:
yyerror ("parser stack overflow"]b4_pure_args[); yyerror (]b4_yyerror_args["parser stack overflow");
yyresult = 2; yyresult = 2;
/* Fall through. */ /* Fall through. */
#endif #endif

View File

@@ -1357,7 +1357,7 @@ here is the definition we will use:
#include <stdio.h> #include <stdio.h>
void void
yyerror (const char *s) /* called by yyparse on error */ yyerror (const char *s) /* Called by yyparse on error. */
@{ @{
printf ("%s\n", s); printf ("%s\n", s);
@} @}
@@ -1973,7 +1973,7 @@ main (void)
@group @group
void void
yyerror (const char *s) /* Called by yyparse on error */ yyerror (const char *s) /* Called by yyparse on error. */
@{ @{
printf ("%s\n", s); printf ("%s\n", s);
@} @}
@@ -4050,7 +4050,7 @@ The following definition suffices in simple programs:
@example @example
@group @group
void void
yyerror (char *s) yyerror (const char *s)
@{ @{
@end group @end group
@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 (@pxref{Error Recovery}). If recovery is impossible, @code{yyparse} will
immediately return 1. 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 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 parsers, but not for the Yacc parser, for historical reasons. I.e., if
@samp{%locations %pure-parser} is passed then the prototypes for @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 @example
void yyerror (const char *msg); /* Yacc parsers. */ 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 @end example
If @samp{%parse-param "int *nastiness" "nastiness"} is used, then: If @samp{%parse-param "int *nastiness" "nastiness"} is used, then:
@example @example
void yyerror (int *randomness); /* Yacc parsers. */ void yyerror (int *randomness, const char *msg); /* Yacc parsers. */
void yyerror (int *randomness); /* GLR parsers. */ void yyerror (int *randomness, const char *msg); /* GLR parsers. */
@end example @end example
Finally, GLR and Yacc parsers share the same @code{yyerror} calling 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 @example
int yylex (YYSTYPE *lvalp, YYLTYPE *llocp, int *nastiness); int yylex (YYSTYPE *lvalp, YYLTYPE *llocp, int *nastiness);
int yyparse (int *nastiness, int *randomness); int yyparse (int *nastiness, int *randomness);
void yyerror (const char *msg, YYLTYPE *locp, void yyerror (YYLTYPE *locp,
int *nastiness, int *randomness); int *nastiness, int *randomness,
const char *msg);
@end example @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 @vindex yynerrs
The variable @code{yynerrs} contains the number of syntax errors The variable @code{yynerrs} contains the number of syntax errors
encountered so far. Normally this variable is global; but if you encountered so far. Normally this variable is global; but if you

View File

@@ -100,9 +100,9 @@ static int power (int base, int exponent);
/* yyerror receives the location if: /* yyerror receives the location if:
- %location & %pure & %glr - %location & %pure & %glr
- %location & %pure & %yacc & %parse-param. */ - %location & %pure & %yacc & %parse-param. */
static void yyerror (const char *s static void yyerror (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *yylloc, ])[
]AT_YYERROR_ARG_LOC_IF([, YYLTYPE *yylloc])[ ]AT_PARAM_IF([value_t *result, int *count, ])[
]AT_PARAM_IF([, value_t *result, int *count])[ const char *s
); );
static int yylex (LEX_FORMALS); static int yylex (LEX_FORMALS);
static int yygetc (LEX_FORMALS); static int yygetc (LEX_FORMALS);
@@ -154,9 +154,10 @@ exp:
FILE *yyin; FILE *yyin;
static void static void
yyerror (const char *s yyerror (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *yylloc, ])[
]AT_YYERROR_ARG_LOC_IF([, YYLTYPE *yylloc])[ ]AT_PARAM_IF([value_t *result, int *count, ])[
]AT_PARAM_IF([, value_t *result, int *count])[) const char *s
)
{ {
]AT_PARAM_IF([(void) result; (void) count; ])[ ]AT_PARAM_IF([(void) result; (void) count; ])[
]AT_YYERROR_SEES_LOC_IF([ ]AT_YYERROR_SEES_LOC_IF([

View File

@@ -36,10 +36,11 @@ $1
]m4_bmatch([$2], [stmtMerge], ]m4_bmatch([$2], [stmtMerge],
[ static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1);])[ [ static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1);])[
#define YYINITDEPTH 10 #define YYINITDEPTH 10
int yyerror (const char *s int yyerror (
#if YYPURE && YYLSP_NEEDED #if YYPURE && YYLSP_NEEDED
, YYLTYPE *yylocation YYLTYPE *yylocation,
#endif #endif
const char *s
); );
#if YYPURE #if YYPURE
@@ -157,10 +158,11 @@ yylex ()
} }
int int
yyerror (const char *s yyerror (
#if YYPURE && YYLSP_NEEDED #if YYPURE && YYLSP_NEEDED
, YYLTYPE *yylocation YYLTYPE *yylocation,
#endif #endif
const char *s
) )
{ {
#if YYPURE && YYLSP_NEEDED #if YYPURE && YYLSP_NEEDED