summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/skeletons/glr.c20
-rw-r--r--data/skeletons/yacc.c26
-rw-r--r--tests/actions.at2
-rw-r--r--tests/conflicts.at60
4 files changed, 88 insertions, 20 deletions
diff --git a/data/skeletons/glr.c b/data/skeletons/glr.c
index a3a9a711..8603d51f 100644
--- a/data/skeletons/glr.c
+++ b/data/skeletons/glr.c
@@ -2071,18 +2071,18 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
#else
{
yySymbol yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
- ptrdiff_t yysize0 = yytnamerr (YY_NULLPTR, yytokenName (yytoken));
- ptrdiff_t yysize = yysize0;
yybool yysize_overflow = yyfalse;
char* yymsg = YY_NULLPTR;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
const char *yyformat = YY_NULLPTR;
- /* Arguments of yyformat. */
+ /* Arguments of yyformat: reported tokens (one for the "unexpected",
+ one per "expected"). */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- /* Number of reported tokens (one for the "unexpected", one per
- "expected"). */
+ /* Actual size of YYARG. */
int yycount = 0;
+ /* Cumulated lengths of YYARG. */
+ ptrdiff_t yysize = 0;
/* There are many possibilities here to consider:
- If this state is a consistent state with a default action, then
@@ -2110,6 +2110,8 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
if (yytoken != YYEMPTY)
{
int yyn = yypact[yystackp->yytops.yystates[0]->yylrState];
+ ptrdiff_t yysize0 = yytnamerr (YY_NULLPTR, yytokenName (yytoken));
+ yysize = yysize0;
yyarg[yycount++] = yytokenName (yytoken);
if (!yypact_value_is_default (yyn))
{
@@ -2160,7 +2162,9 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
}
{
- ptrdiff_t yysz = YY_CAST (ptrdiff_t, strlen (yyformat));
+ /* Don't count the "%s"s in the final size, but reserve room for
+ the terminator. */
+ ptrdiff_t yysz = YY_CAST (ptrdiff_t, strlen (yyformat)) - 2 * yycount + 1;
if (YYSIZEMAX - yysize < yysz)
yysize_overflow = yytrue;
else
@@ -2183,8 +2187,8 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
}
else
{
- yyp++;
- yyformat++;
+ ++yyp;
+ ++yyformat;
}
}
yyerror (]b4_lyyerror_args[yymsg);
diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c
index e970189c..3eff66dd 100644
--- a/data/skeletons/yacc.c
+++ b/data/skeletons/yacc.c
@@ -1137,16 +1137,16 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
]b4_lac_if([[yy_state_t *yyesa, yy_state_t **yyes,
YYPTRDIFF_T *yyes_capacity, ]])[yy_state_t *yyssp, int yytoken)
{
- YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
- YYPTRDIFF_T yysize = yysize0;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
const char *yyformat = YY_NULLPTR;
- /* Arguments of yyformat. */
+ /* Arguments of yyformat: reported tokens (one for the "unexpected",
+ one per "expected"). */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- /* Number of reported tokens (one for the "unexpected", one per
- "expected"). */
+ /* Actual size of YYARG. */
int yycount = 0;
+ /* Cumulated lengths of YYARG. */
+ YYPTRDIFF_T yysize = 0;
/* There are many possibilities here to consider:
- If this state is a consistent state with a default action, then
@@ -1178,7 +1178,9 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
*/
if (yytoken != YYEMPTY)
{
- int yyn = yypact[*yyssp];]b4_lac_if([[
+ int yyn = yypact[*yyssp];
+ YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+ yysize = yysize0;]b4_lac_if([[
YYDPRINTF ((stderr, "Constructing syntax error message\n"));]])[
yyarg[yycount++] = yytname[yytoken];
if (!yypact_value_is_default (yyn))
@@ -1217,8 +1219,8 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
}
yyarg[yycount++] = yytname[yyx];
{
- YYPTRDIFF_T yysize1 = yysize + yytnamerr (YY_NULLPTR,
- yytname[yyx]);
+ YYPTRDIFF_T yysize1
+ = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
yysize = yysize1;
else
@@ -1249,7 +1251,9 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
}
{
- YYPTRDIFF_T yysize1 = yysize + yystrlen (yyformat);
+ /* Don't count the "%s"s in the final size, but reserve room for
+ the terminator. */
+ YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1;
if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
yysize = yysize1;
else
@@ -1279,8 +1283,8 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
}
else
{
- yyp++;
- yyformat++;
+ ++yyp;
+ ++yyformat;
}
}
return 0;
diff --git a/tests/actions.at b/tests/actions.at
index 34325c7a..c702373c 100644
--- a/tests/actions.at
+++ b/tests/actions.at
@@ -473,7 +473,7 @@ AT_BISON_OPTION_POPDEFS
AT_CLEANUP
])
-## FIXME: test Java.
+## FIXME: test Java and D.
m4_map_args([AT_TEST], [yacc.c], [glr.c], [lalr1.cc], [glr.cc])
m4_popdef([AT_TEST])
diff --git a/tests/conflicts.at b/tests/conflicts.at
index e857bf20..92050fbe 100644
--- a/tests/conflicts.at
+++ b/tests/conflicts.at
@@ -1019,6 +1019,66 @@ input.y:12.3-18: warning: rule useless in parser due to conflicts [-Wother]
AT_CLEANUP
+## ---------------------------------------- ##
+## Syntax error in consistent error state. ##
+## ---------------------------------------- ##
+
+# AT_TEST(SKELETON-NAME)
+# ----------------------
+# Make sure yysyntax_error does nothing silly when called on yytoken
+# == YYEMPTY.
+
+m4_pushdef([AT_TEST],
+[AT_SETUP([Syntax error in consistent error state: $1])
+
+AT_BISON_OPTION_PUSHDEFS([%skeleton "$1"])
+
+AT_DATA_GRAMMAR([input.y],
+[[%define parse.error verbose
+%skeleton "$1"
+%%
+%nonassoc 'a';
+
+start: 'a' consistent-error-on-a-a 'a';
+
+consistent-error-on-a-a:
+ 'a' default-reduction
+ | 'a' default-reduction 'a'
+ ;
+
+default-reduction: %empty;
+
+%code {
+ #include <stdio.h>
+ ]AT_YYERROR_DECLARE[
+ ]AT_YYLEX_DECLARE[
+};
+%%
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE("aa")[
+]AT_MAIN_DEFINE[
+]])
+
+AT_BISON_CHECK([-o input.AT_LANG_EXT input.y], 0, [],
+[[input.y:17.5-25: warning: rule useless in parser due to conflicts [-Wother]
+input.y:18.5-29: warning: rule useless in parser due to conflicts [-Wother]
+]])
+AT_LANG_COMPILE([input])
+AT_PARSER_CHECK([[input]], 1, [],
+[[syntax error
+]])
+
+AT_BISON_OPTION_POPDEFS
+AT_CLEANUP
+])
+
+## FIXME: test Java and D.
+m4_map_args([AT_TEST], [yacc.c], [glr.c], [lalr1.cc], [glr.cc])
+
+m4_popdef([AT_TEST])
+
+
+
## -------------------------------- ##
## Defaulted Conflicted Reduction. ##
## -------------------------------- ##