Support i18n of the parse error messages.

* TODO (lalr1.cc/I18n): Remove.
	* data/lalr1.cc (yysyntax_error_): Support the translation of the
	error messages, as done in yacc.c.
	Stay within the yy* pseudo namespace.
This commit is contained in:
Akim Demaille
2008-08-21 21:46:13 +02:00
parent 00a8a0832d
commit a0ffc1751e
3 changed files with 55 additions and 32 deletions

View File

@@ -1,3 +1,11 @@
2008-11-11 Akim Demaille <demaille@gostai.com>
Support i18n of the parse error messages.
* TODO (lalr1.cc/I18n): Remove.
* data/lalr1.cc (yysyntax_error_): Support the translation of the
error messages, as done in yacc.c.
Stay within the yy* pseudo namespace.
2008-11-11 Akim Demaille <demaille@gostai.com> 2008-11-11 Akim Demaille <demaille@gostai.com>
More TODO. More TODO.

4
TODO
View File

@@ -106,10 +106,6 @@ find something clean (not like YYLSP_NEEDED...).
Before releasing, make sure the documentation ("Understanding your Before releasing, make sure the documentation ("Understanding your
parser") refers to the current `output' format. parser") refers to the current `output' format.
* lalr1.cc
** I18n
Catch up with yacc.c.
* Report * Report
** GLR ** GLR

View File

@@ -1385,9 +1385,9 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
// Generate an error message. // Generate an error message.
std::string std::string
]b4_parser_class_name[::yysyntax_error_ (int yystate, int]dnl ]b4_parser_class_name[::yysyntax_error_ (int yystate, int]dnl
b4_error_verbose_if([ tok])[) b4_error_verbose_if([ yytoken])[)
{ {
std::string res; std::string yyres;
YYUSE (yystate); YYUSE (yystate);
#if YYERROR_VERBOSE #if YYERROR_VERBOSE
int yyn = yypact_[yystate]; int yyn = yypact_[yystate];
@@ -1400,36 +1400,55 @@ b4_error_verbose_if([ tok])[)
/* Stay within bounds of both yycheck and yytname. */ /* Stay within bounds of both yycheck and yytname. */
int yychecklim = yylast_ - yyn + 1; int yychecklim = yylast_ - yyn + 1;
int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
int count = 0;
for (int x = yyxbegin; x < yyxend; ++x)
if (yycheck_[x + yyn] == x && x != yyterror_)
++count;
// FIXME: This method of building the message is not compatible // Number of "expected" tokens.
// with internationalization. It should work like yacc.c does it. size_t yycount = 0;
// That is, first build a string that looks like this: // Its maximum.
// "syntax error, unexpected %s or %s or %s" enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
// Then, invoke YY_ on this string. // Arguments of yyformat.
// Finally, use the string as a format to output char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
// yytname_[tok], etc. yyarg[yycount++] = yytname_[yytoken];
// Until this gets fixed, this message appears in English only. for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
res = "syntax error, unexpected "; if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_)
res += yytnamerr_ (yytname_[tok]); {
if (count < 5) if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
{ {
count = 0; yycount = 1;
for (int x = yyxbegin; x < yyxend; ++x) break;
if (yycheck_[x + yyn] == x && x != yyterror_) }
{ else
res += (!count++) ? ", expecting " : " or "; yyarg[yycount++] = yytname_[yyx];
res += yytnamerr_ (yytname_[x]); }
}
} char const* yyformat = 0;
switch (yycount)
{
#define YYCASE_(N, S) \
case N: \
yyformat = S; \
break
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_
}
// Argument number.
size_t yyi = 0;
for (char const* yyp = yyformat; *yyp; ++yyp)
if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
{
yyres += yytnamerr_ (yyarg[yyi++]);
++yyp;
}
else
yyres += *yyp;
} }
else else
#endif #endif
res = YY_("syntax error"); yyres = YY_("syntax error");
return res; return yyres;
} }