mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-21 02:03:03 +00:00
yacc.c: add custom error message generation
When parse.error is custom, let users define a yyreport_syntax_error function, and use it. * data/skeletons/bison.m4 (b4_error_verbose_if): Accept 'custom'. * data/skeletons/yacc.c: Implement it. * examples/c/calc/calc.y: Experiment with it.
This commit is contained in:
@@ -1018,13 +1018,14 @@ m4_define([b4_bison_locations_if],
|
|||||||
|
|
||||||
# b4_error_verbose_if([IF-ERRORS-ARE-VERBOSE], [IF-NOT])
|
# b4_error_verbose_if([IF-ERRORS-ARE-VERBOSE], [IF-NOT])
|
||||||
# ------------------------------------------------------
|
# ------------------------------------------------------
|
||||||
# Map %define parse.error "(simple|verbose)" to b4_error_verbose_if and
|
# Map %define parse.error "(custom|simple|verbose)" to b4_error_verbose_if and
|
||||||
# b4_error_verbose_flag.
|
# b4_error_verbose_flag.
|
||||||
b4_percent_define_default([[parse.error]], [[simple]])
|
b4_percent_define_default([[parse.error]], [[simple]])
|
||||||
b4_percent_define_check_values([[[[parse.error]],
|
b4_percent_define_check_values([[[[parse.error]],
|
||||||
[[simple]], [[verbose]]]])
|
[[custom]], [[simple]], [[verbose]]]])
|
||||||
m4_define([b4_error_verbose_flag],
|
m4_define([b4_error_verbose_flag],
|
||||||
[m4_case(b4_percent_define_get([[parse.error]]),
|
[m4_case(b4_percent_define_get([[parse.error]]),
|
||||||
|
[custom], [[1]],
|
||||||
[simple], [[0]],
|
[simple], [[0]],
|
||||||
[verbose], [[1]])])
|
[verbose], [[1]])])
|
||||||
b4_define_flag_if([error_verbose])
|
b4_define_flag_if([error_verbose])
|
||||||
|
|||||||
@@ -1136,7 +1136,11 @@ yysyntax_error_arguments (const yyparse_context_t *yyctx,
|
|||||||
}
|
}
|
||||||
]])[
|
]])[
|
||||||
|
|
||||||
]m4_case(b4_percent_define_get([[parse.error]]), [verbose],
|
]m4_case(b4_percent_define_get([[parse.error]]),
|
||||||
|
[custom],
|
||||||
|
[[static int
|
||||||
|
yyreport_syntax_error (const yyparse_context_t *yyctx);]],
|
||||||
|
[verbose],
|
||||||
[[# ifndef yystrlen
|
[[# ifndef yystrlen
|
||||||
# if defined __GLIBC__ && defined _STRING_H
|
# if defined __GLIBC__ && defined _STRING_H
|
||||||
# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S)))
|
# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S)))
|
||||||
@@ -1786,6 +1790,15 @@ yyerrlab:
|
|||||||
{
|
{
|
||||||
++yynerrs;
|
++yynerrs;
|
||||||
]m4_case(b4_percent_define_get([[parse.error]]),
|
]m4_case(b4_percent_define_get([[parse.error]]),
|
||||||
|
[custom],
|
||||||
|
[[ {
|
||||||
|
yyparse_context_t yyctx
|
||||||
|
= {yyssp, yytoken]b4_lac_if([[, yyesa, &yyes, &yyes_capacity]])[};]b4_lac_if([[
|
||||||
|
if (yychar != YYEMPTY)
|
||||||
|
YY_LAC_ESTABLISH;]])[
|
||||||
|
if (yyreport_syntax_error (]b4_yyerror_args[&yyctx) == 2)
|
||||||
|
goto yyexhaustedlab;
|
||||||
|
}]],
|
||||||
[simple],
|
[simple],
|
||||||
[[ yyerror (]b4_yyerror_args[YY_("syntax error"));]],
|
[[ yyerror (]b4_yyerror_args[YY_("syntax error"));]],
|
||||||
[verbose],
|
[verbose],
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
%define api.header.include {"calc.h"}
|
%define api.header.include {"calc.h"}
|
||||||
%define api.value.type union /* Generate YYSTYPE from these types: */
|
%define api.value.type union /* Generate YYSTYPE from these types: */
|
||||||
|
%define parse.error custom
|
||||||
%token <double> NUM "number"
|
%token <double> NUM "number"
|
||||||
%type <double> expr term fact
|
%type <double> expr term fact
|
||||||
|
|
||||||
@@ -51,6 +52,28 @@ fact:
|
|||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
int
|
||||||
|
yyreport_syntax_error (const yyparse_context_t *ctx)
|
||||||
|
{
|
||||||
|
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 10 };
|
||||||
|
/* Arguments of yyformat: reported tokens (one for the "unexpected",
|
||||||
|
one per "expected"). */
|
||||||
|
int arg[YYERROR_VERBOSE_ARGS_MAXIMUM];
|
||||||
|
int n = yysyntax_error_arguments (ctx, arg, sizeof arg / sizeof *arg);
|
||||||
|
if (n == -2)
|
||||||
|
return 2;
|
||||||
|
fprintf (stderr, "SYNTAX ERROR on token [%s]", yysymbol_name (arg[0]));
|
||||||
|
if (1 < n)
|
||||||
|
{
|
||||||
|
fprintf (stderr, " (expected:");
|
||||||
|
for (int i = 1; i < n; ++i)
|
||||||
|
fprintf (stderr, " [%s]", yysymbol_name (arg[i]));
|
||||||
|
fprintf (stderr, ")");
|
||||||
|
}
|
||||||
|
fprintf (stderr, "\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
yylex (void)
|
yylex (void)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user