bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/6] diagnostics: report syntax errors in color


From: Akim Demaille
Subject: [PATCH 3/6] diagnostics: report syntax errors in color
Date: Thu, 23 Jan 2020 08:50:58 +0100

* src/parse-gram.y (parse.error): Set to 'custom'.
(yyreport_syntax_error): New.
* data/bison-default.css (.expected, .unexpected): New.
* tests/diagnostics.at: Adjust.
---
 data/bison-default.css |  3 +++
 src/complain.c         |  2 +-
 src/parse-gram.y       | 61 +++++++++++++++++++++++++++++++++++++++++-
 tests/diagnostics.at   |  2 +-
 4 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/data/bison-default.css b/data/bison-default.css
index 6f4900a9..17b9b657 100644
--- a/data/bison-default.css
+++ b/data/bison-default.css
@@ -29,3 +29,6 @@
 
 /* "Sections" in traces (--trace).  */
 .trace0    { color: green; }
+
+.expected   { color: green; }
+.unexpected { color: red; }
diff --git a/src/complain.c b/src/complain.c
index b98fea05..c8843283 100644
--- a/src/complain.c
+++ b/src/complain.c
@@ -477,10 +477,10 @@ static void
 complains (const location *loc, int *indent, warnings flags,
            const char *message, va_list args)
 {
-  severity s = warning_severity (flags);
   if ((flags & complaint) && complaint_status < status_complaint)
     complaint_status = status_complaint;
 
+  severity s = warning_severity (flags);
   if (severity_warning <= s)
     {
       if (severity_error <= s && ! complaint_status)
diff --git a/src/parse-gram.y b/src/parse-gram.y
index 30b2bef1..3ed07a31 100644
--- a/src/parse-gram.y
+++ b/src/parse-gram.y
@@ -125,7 +125,7 @@
 %define api.token.raw
 %define api.value.type union
 %define locations
-%define parse.error detailed
+%define parse.error custom
 %define parse.lac full
 %define parse.trace
 %defines
@@ -801,6 +801,65 @@ epilogue.opt:
 
 %%
 
+int
+yyreport_syntax_error (const yyparse_context_t *ctx)
+{
+  if (complaint_status < status_complaint)
+    complaint_status = status_complaint;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *format = YY_NULLPTR;
+  /* Arguments of format: reported tokens (one for the "unexpected",
+     one per "expected"). */
+  int arg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  int n = yysyntax_error_arguments (ctx, arg, YYERROR_VERBOSE_ARGS_MAXIMUM);
+  switch (n)
+    {
+    case -2:
+      return 2;
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        format = S;                         \
+      break
+    default: /* Avoid compiler warnings. */
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or 
%s"));
+# undef YYCASE_
+    }
+  location_print (*yyparse_context_location (ctx), stderr);
+  fputs (": ", stderr);
+  begin_use_class ("error", stderr);
+  fputs ("error:", stderr);
+  end_use_class ("error", stderr);
+  fputc (' ', stderr);
+  {
+    int i = 0;
+    while (*format)
+      if (format[0] == '%' && format[1] == 's' && i < n)
+        {
+          const char *style = i == 0 ? "unexpected" : "expected";
+          begin_use_class (style, stderr);
+          fputs (yysymbol_name (arg[i]), stderr);
+          end_use_class (style, stderr);
+          format += 2;
+          ++i;
+        }
+      else
+        {
+          fputc (*format, stderr);
+          ++format;
+        }
+  }
+  fputc ('\n', stderr);
+  location_caret (*yyparse_context_location (ctx), "error", stderr);
+  return 0;
+}
+
+
 /* Return the location of the left-hand side of a rule whose
    right-hand side is RHS[1] ... RHS[N].  Ignore empty nonterminals in
    the right-hand side, and return an empty location equal to the end
diff --git a/tests/diagnostics.at b/tests/diagnostics.at
index b0b5ee3e..d0c7ff4f 100644
--- a/tests/diagnostics.at
+++ b/tests/diagnostics.at
@@ -273,7 +273,7 @@ AT_TEST([[Carriage return]],
 [[input.y:10.8-11.0: <error>error:</error> missing '"' at end of line
    10 | %token <error>"</error>
       |        <error>^</error>
-input.y:10.8-11.0: <error>error:</error> syntax error, unexpected string, 
expecting character literal or identifier or <tag>
+input.y:10.8-11.0: <error>error:</error> syntax error, unexpected 
<unexpected>string</unexpected>, expecting <expected>character 
literal</expected> or <expected>identifier</expected> or 
<expected><tag></expected>
    10 | %token <error>"</error>
       |        <error>^</error>
 ]])
-- 
2.25.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]