java: add support for parse.error=detailed

In Java there is no need for N_ and yytranslate_.  So instead of
hard-coding the use of N_ in the table of the symbol names, rely on
b4_symbol_translate.

* src/output.c (prepare_symbol_names): Use b4_symbol_translate instead
of N_.
* data/skeletons/c.m4 (b4_symbol_translate): New.
* data/skeletons/lalr1.java (yysymbolName): New.
Use it.
* examples/java/calc/Calc.y: Use parse.error=detailed.
* tests/calc.at: Check parse.error=detailed.
This commit is contained in:
Akim Demaille
2020-02-06 08:25:44 +01:00
parent 650b253843
commit 52db24b2bc
6 changed files with 91 additions and 46 deletions

View File

@@ -470,6 +470,13 @@ m4_define([b4_token_enums_defines],
[b4_token_enums[]b4_yacc_if([b4_token_defines])])
# b4_symbol_translate(STRING)
# ---------------------------
m4_define([b4_symbol_translate],
[[N_($1)]])
## ----------------- ##
## Semantic Values. ##
## ----------------- ##

View File

@@ -220,6 +220,13 @@ m4_define([b4_position_type], [b4_percent_define_get([[api.position.type]])])
## ----------------- ##
# b4_symbol_translate(STRING)
# ---------------------------
m4_define([b4_symbol_translate],
[[_($1)]])
# b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG])
# ----------------------------------------------
# See README.

View File

@@ -488,42 +488,6 @@ m4_define([b4_define_state],[[
return YYNEWSTATE;
}
]b4_error_verbose_if([[
/* Return YYSTR after stripping away unnecessary quotes and
backslashes, so that it's suitable for yyerror. The heuristic is
that double-quoting is unnecessary unless the string contains an
apostrophe, a comma, or backslash (other than backslash-backslash).
YYSTR is taken from yytname. */
private final String yytnamerr_ (String yystr)
{
if (yystr.charAt (0) == '"')
{
StringBuffer yyr = new StringBuffer ();
strip_quotes: for (int i = 1; i < yystr.length (); i++)
switch (yystr.charAt (i))
{
case '\'':
case ',':
break strip_quotes;
case '\\':
if (yystr.charAt(++i) != '\\')
break strip_quotes;
/* Fall through. */
default:
yyr.append (yystr.charAt (i));
break;
case '"':
return yyr.toString ();
}
}
else if (yystr.equals ("$end"))
return "end of input";
return yystr;
}
]])[
]b4_parse_trace_if([[
/*--------------------------------.
| Print this symbol on YYOUTPUT. |
@@ -534,7 +498,7 @@ m4_define([b4_define_state],[[
b4_locations_if([, Object yylocationp])[)
{
yycdebug (s + (yytype < yyntokens_ ? " token " : " nterm ")
+ yytname_[yytype] + " ("]b4_locations_if([
+ yysymbolName (yytype) + " ("]b4_locations_if([
+ yylocationp + ": "])[
+ (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")");
}]])[
@@ -924,7 +888,7 @@ b4_dollar_popdef[]dnl
with internationalization. */
StringBuffer res =
new StringBuffer ("syntax error, unexpected ");
res.append (yytnamerr_ (yytname_[tok]));
res.append (yysymbolName (tok));
int yyn = yypact_[yystate];
if (!yyPactValueIsDefault (yyn))
{
@@ -949,7 +913,7 @@ b4_dollar_popdef[]dnl
&& !yyTableValueIsError (yytable_[x + yyn]))
{
res.append (count++ == 0 ? ", expecting " : " or ");
res.append (yytnamerr_ (yytname_[x]));
res.append (yysymbolName (x));
}
}
}
@@ -984,10 +948,64 @@ b4_dollar_popdef[]dnl
]b4_parser_tables_define[
]m4_bmatch(b4_percent_define_get([[parse.error]]),
[simple\|verbose],
[[ /* Return YYSTR after stripping away unnecessary quotes and
backslashes, so that it's suitable for yyerror. The heuristic is
that double-quoting is unnecessary unless the string contains an
apostrophe, a comma, or backslash (other than backslash-backslash).
YYSTR is taken from yytname. */
private static String yytnamerr_ (String yystr)
{
if (yystr.charAt (0) == '"')
{
StringBuffer yyr = new StringBuffer ();
strip_quotes: for (int i = 1; i < yystr.length (); i++)
switch (yystr.charAt (i))
{
case '\'':
case ',':
break strip_quotes;
case '\\':
if (yystr.charAt(++i) != '\\')
break strip_quotes;
/* Fall through. */
default:
yyr.append (yystr.charAt (i));
break;
case '"':
return yyr.toString ();
}
}
else if (yystr.equals ("$end"))
return "end of input";
return yystr;
}
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at \a yyntokens_, nonterminals. */
]b4_typed_parser_table_define([String], [tname], [b4_tname])[
static String yysymbolName (int yysymbol)
{
return yytnamerr_ (yytname_[yysymbol]);
}
]],
[custom\|detailed],
[[/* The user-facing name of the symbol whose (internal) number is
YYSYMBOL. No bounds checking. */
static String yysymbolName (int yysymbol)
{
String[] yy_sname =
{
]b4_symbol_names[
};
return yy_sname[yysymbol];
}]])[
]b4_parse_trace_if([[
]b4_integral_parser_table_define([rline], [b4_rline],
[[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[

View File

@@ -3,7 +3,7 @@
%define api.parser.class {Calc}
%define api.parser.public
%define parse.error verbose
%define parse.error detailed
%define parse.trace
%locations

View File

@@ -200,8 +200,8 @@ prepare_symbol_names (char const *muscle_name)
set_quoting_flags (qo, QA_SPLIT_TRIGRAPHS);
for (int i = 0; i < nsyms; i++)
{
char *cp =
symbols[i]->tag[0] == '"' && !quote
char *cp
= symbols[i]->tag[0] == '"' && !quote
? xescape_trigraphs (symbols[i]->tag)
: quotearg_alloc (symbols[i]->tag, -1, qo);
/* Width of the next token, including the two quotes, the
@@ -219,10 +219,10 @@ prepare_symbol_names (char const *muscle_name)
if (i)
obstack_1grow (&format_obstack, ' ');
if (!quote && symbols[i]->translatable)
obstack_sgrow (&format_obstack, "N_(");
obstack_sgrow (&format_obstack, "]b4_symbol_translate([");
obstack_escape (&format_obstack, cp);
if (!quote && symbols[i]->translatable)
obstack_1grow (&format_obstack, ')');
obstack_sgrow (&format_obstack, "])[");
free (cp);
obstack_1grow (&format_obstack, ',');
j += width;

View File

@@ -509,7 +509,6 @@ void location_print (FILE *o, Span s);
const char *
_ (const char *cp)
{
/* Make sure only "end of input" is translated. */
if (strcmp (cp, "end of input") == 0)
return "end of file";
else if (strcmp (cp, "number") == 0)
@@ -649,10 +648,23 @@ m4_define([_AT_DATA_CALC_Y(java)],
}
%code {
]AT_CALC_MAIN[
]AT_CALC_MAIN[
]AT_TOKEN_TRANSLATE_IF([[
static String _ (String s)
{
if (s.equals ("end of input"))
return "end of file";
else if (s.equals ("number"))
return "nombre";
else
return s;
}
]])[
}
/* Bison Declarations */
%token CALC_EOF 0 ]AT_TOKEN_TRANSLATE_IF([_("end of input")], ["end of input"])[
%token <Integer> NUM "number"
%type <Integer> exp
@@ -1173,6 +1185,7 @@ m4_define([AT_CHECK_CALC_LALR1_JAVA],
[AT_CHECK_CALC([%language "Java" $1], [$2])])
AT_CHECK_CALC_LALR1_JAVA
AT_CHECK_CALC_LALR1_JAVA([%define parse.error detailed])
AT_CHECK_CALC_LALR1_JAVA([%define parse.error verbose])
AT_CHECK_CALC_LALR1_JAVA([%locations %define parse.error verbose])
AT_CHECK_CALC_LALR1_JAVA([%define parse.trace %define parse.error verbose])