[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 04/12] yacc.c: add custom error message generation
From: |
Akim Demaille |
Subject: |
[PATCH 04/12] yacc.c: add custom error message generation |
Date: |
Thu, 16 Jan 2020 07:58:15 +0100 |
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.
---
data/skeletons/bison.m4 | 5 +++--
data/skeletons/yacc.c | 15 ++++++++++++++-
examples/c/calc/calc.y | 23 +++++++++++++++++++++++
3 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/data/skeletons/bison.m4 b/data/skeletons/bison.m4
index c7be4037..946e7642 100644
--- a/data/skeletons/bison.m4
+++ b/data/skeletons/bison.m4
@@ -1018,13 +1018,14 @@ m4_define([b4_bison_locations_if],
# 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_percent_define_default([[parse.error]], [[simple]])
b4_percent_define_check_values([[[[parse.error]],
- [[simple]], [[verbose]]]])
+ [[custom]], [[simple]], [[verbose]]]])
m4_define([b4_error_verbose_flag],
[m4_case(b4_percent_define_get([[parse.error]]),
+ [custom], [[1]],
[simple], [[0]],
[verbose], [[1]])])
b4_define_flag_if([error_verbose])
diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c
index ff53b8d0..022b01de 100644
--- a/data/skeletons/yacc.c
+++ b/data/skeletons/yacc.c
@@ -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
# if defined __GLIBC__ && defined _STRING_H
# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S)))
@@ -1786,6 +1790,15 @@ yyerrlab:
{
++yynerrs;
]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],
[[ yyerror (]b4_yyerror_args[YY_("syntax error"));]],
[verbose],
diff --git a/examples/c/calc/calc.y b/examples/c/calc/calc.y
index a9896e43..0ba74da6 100644
--- a/examples/c/calc/calc.y
+++ b/examples/c/calc/calc.y
@@ -9,6 +9,7 @@
%define api.header.include {"calc.h"}
%define api.value.type union /* Generate YYSTYPE from these types: */
+%define parse.error custom
%token <double> NUM "number"
%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
yylex (void)
{
--
2.24.1
- Re: RFC: custom error messages, (continued)
- Re: RFC: custom error messages, Christian Schoenebeck, 2020/01/03
- Re: RFC: custom error messages, Akim Demaille, 2020/01/05
- Re: RFC: custom error messages, Christian Schoenebeck, 2020/01/09
- Re: RFC: custom error messages, Akim Demaille, 2020/01/10
- Re: RFC: custom error messages, Christian Schoenebeck, 2020/01/14
- Re: RFC: custom error messages, Akim Demaille, 2020/01/14
- [PATCH 00/12] RFC: yyreport_error_message, Akim Demaille, 2020/01/16
- [PATCH 02/12] yacc.c: store token numbers, not token strings, Akim Demaille, 2020/01/16
- [PATCH 03/12] yacc.c: style: avoid macros, Akim Demaille, 2020/01/16
- [PATCH 01/12] yacc.c: extract yyerror_message_arguments, Akim Demaille, 2020/01/16
- [PATCH 04/12] yacc.c: add custom error message generation,
Akim Demaille <=
- [PATCH 06/12] tests: compute verbose error messages from the custom ones, Akim Demaille, 2020/01/16
- [PATCH 05/12] yacc.c: check custom error messages, Akim Demaille, 2020/01/16
- [PATCH 07/12] yacc.c: isolate yyexpected_tokens, Akim Demaille, 2020/01/16
- [PATCH 08/12] yacc.c: let custom error messages see the location, Akim Demaille, 2020/01/16
- [PATCH 09/12] yacc.c: check custom error messages with parse-params, Akim Demaille, 2020/01/16
- [PATCH 10/12] tests: a clearer test for parse-params, Akim Demaille, 2020/01/16
- [PATCH 12/12] yacc.c: portability to G++ 4.8, Akim Demaille, 2020/01/16
- [PATCH 11/12] yacc.c: pass the parse-params to yyreport_syntax_error, Akim Demaille, 2020/01/16
- Re: RFC: custom error messages, Christian Schoenebeck, 2020/01/16
- Re: RFC: custom error messages, Akim Demaille, 2020/01/17