- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = yylast_ - yyn + 1;
- 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
- // with internationalization. It should work like yacc.c does it.
- // That is, first build a string that looks like this:
- // "syntax error, unexpected %s or %s or %s"
- // Then, invoke YY_ on this string.
- // Finally, use the string as a format to output
- // yytname_[tok], etc.
- // Until this gets fixed, this message appears in English only.
- res = "syntax error, unexpected ";
- res += yytnamerr_ (yytname_[tok]);
- if (count < 5)
- {
- count = 0;
- for (int x = yyxbegin; x < yyxend; ++x)
- if (yycheck_[x + yyn] == x && x != yyterror_)
- {
- res += (!count++) ? ", expecting " : " or ";
- res += yytnamerr_ (yytname_[x]);
- }
- }
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = yylast_ - yyn + 1;
+ int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
+
+ // Number of reported tokens (one for the "unexpected", one per
+ // "expected").
+ size_t yycount = 0;
+ // Its maximum.
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ // Arguments of yyformat.
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ yyarg[yycount++] = yytname_[yytoken];
+ for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_
+ && !yy_table_value_is_error_ (yytable_[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ break;
+ }
+ else
+ yyarg[yycount++] = yytname_[yyx];
+ }
+
+ 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_