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.
This commit is contained in:
Akim Demaille
2020-01-22 22:29:09 +01:00
parent f54a5b303b
commit 46ab1d0cbe
4 changed files with 65 additions and 3 deletions

View File

@@ -29,3 +29,6 @@
/* "Sections" in traces (--trace). */
.trace0 { color: green; }
.expected { color: green; }
.unexpected { color: red; }

View File

@@ -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)

View File

@@ -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

View File

@@ -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>
]])