summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorAkim Demaille <akim.demaille@gmail.com>2020-01-03 09:50:09 +0100
committerAkim Demaille <akim.demaille@gmail.com>2020-01-17 06:49:59 +0100
commitcda19346064e90b88816158db461cc80d45610e3 (patch)
treedf91dbe83ecf317bc943294509045ebb6fac7dc1 /examples
parent5b883180e65b719bf581c01c43bacae0f9f5eee1 (diff)
downloadbison-cda19346064e90b88816158db461cc80d45610e3.tar.gz
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.
Diffstat (limited to 'examples')
-rw-r--r--examples/c/calc/calc.y23
1 files changed, 23 insertions, 0 deletions
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
@@ -52,6 +53,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)
{
int c;