From 46ab1d0cbe69b429e2e5f1934faa53d1de46620d Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Wed, 22 Jan 2020 22:29:09 +0100 Subject: [PATCH] diagnostics: report syntax errors in color * 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: missing '"' at end of line 10 | %token " | ^ -input.y:10.8-11.0: error: syntax error, unexpected string, expecting character literal or identifier or +input.y:10.8-11.0: error: syntax error, unexpected string, expecting character literal or identifier or 10 | %token " | ^ ]])