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 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>
* src/scan-gram.l (unexpected_end_of_file): New function.
[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])
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);
}
# 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)
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;
}
}
[$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
} \
else \
{ \
- yyerror ("syntax error: cannot back up"b4_pure_args); \
+ yyerror (b4_yyerror_args"syntax error: cannot back up"); \
YYERROR; \
} \
while (0)
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;
| 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
#include <stdio.h>
void
-yyerror (const char *s) /* called by yyparse on error */
+yyerror (const char *s) /* Called by yyparse on error. */
@{
printf ("%s\n", s);
@}
@group
void
-yyerror (const char *s) /* Called by yyparse on error */
+yyerror (const char *s) /* Called by yyparse on error. */
@{
printf ("%s\n", s);
@}
@example
@group
void
-yyerror (char *s)
+yyerror (const char *s)
@{
@end group
@group
(@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
@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
@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
/* 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);
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([
]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
}
int
-yyerror (const char *s
+yyerror (
#if YYPURE && YYLSP_NEEDED
- , YYLTYPE *yylocation
+ YYLTYPE *yylocation,
#endif
+ const char *s
)
{
#if YYPURE && YYLSP_NEEDED