* tests/regression.at (input.y): s/YYEOF/MYEOF/, as the skeleton

defines it.
* data/glr.c (yystos): New.
(b4_yysymprint_generate, b4_yydestruct_generate): Invoke.
(YYDSYMPRINT): New.
(yyval): Don't define it, it is handled via M4.
(yyrecoverParseError): Free verbosely the discarded symbols.
* data/yacc.c (yysymprint): Remove, rather...
(b4_yysymprint_generate): invoke.
* data/c.m4 (b4_yysymprint_generate): New.
Accept pointers as arguments, as opposed to the version from
yacc.c.
(b4_yydestruct_generate): Likewise.
* tests/cations.at (Printers and Destructors): Use Bison directives
instead of CPP macros.
Don't rely on internal details.
This commit is contained in:
Akim Demaille
2002-11-12 09:03:13 +00:00
parent b0400cc6ef
commit 7bd6c77e5e
7 changed files with 156 additions and 77 deletions

View File

@@ -1,3 +1,22 @@
2002-11-12 Akim Demaille <akim@epita.fr>
* tests/regression.at (input.y): s/YYEOF/MYEOF/, as the skeleton
defines it.
* data/glr.c (yystos): New.
(b4_yysymprint_generate, b4_yydestruct_generate): Invoke.
(YYDSYMPRINT): New.
(yyval): Don't define it, it is handled via M4.
(yyrecoverParseError): Free verbosely the discarded symbols.
* data/yacc.c (yysymprint): Remove, rather...
(b4_yysymprint_generate): invoke.
* data/c.m4 (b4_yysymprint_generate): New.
Accept pointers as arguments, as opposed to the version from
yacc.c.
(b4_yydestruct_generate): Likewise.
* tests/cations.at (Printers and Destructors): Use Bison directives
instead of CPP macros.
Don't rely on internal details.
2002-11-12 Akim Demaille <akim@epita.fr> 2002-11-12 Akim Demaille <akim@epita.fr>
* data/c.m4 (b4_yydestruct_generate, b4_symbol_actions): New. * data/c.m4 (b4_yydestruct_generate, b4_symbol_actions): New.

4
NEWS
View File

@@ -164,9 +164,9 @@ Changes in version 1.50, 2002-10-04:
the user symbol is used in the reports, the graphs, and the verbose the user symbol is used in the reports, the graphs, and the verbose
error messages instead of `$end', which remains being the default. error messages instead of `$end', which remains being the default.
For instance For instance
%token YYEOF 0 %token MYEOF 0
or or
%token YYEOF 0 "end of file" %token MYEOF 0 "end of file"
* Semantic parser * Semantic parser
This old option, which has been broken for ages, is removed. This old option, which has been broken for ages, is removed.

View File

@@ -327,8 +327,8 @@ m4_define([b4_syncline],
# SYMBOL-ACTION, SYMBOL-TYPENAME) # SYMBOL-ACTION, SYMBOL-TYPENAME)
# ------------------------------------------------- # -------------------------------------------------
m4_define([b4_symbol_actions], m4_define([b4_symbol_actions],
[m4_pushdef([b4_dollar_dollar], [yyvalue.$6])dnl [m4_pushdef([b4_dollar_dollar], [yyvaluep->$6])dnl
m4_pushdef([b4_at_dollar], [yylocation])dnl m4_pushdef([b4_at_dollar], [(*yylocationp)])dnl
case $4: /* $3 */ case $4: /* $3 */
b4_syncline([$2], [$1]) b4_syncline([$2], [$1])
$5; $5;
@@ -351,13 +351,13 @@ m4_define([b4_yydestruct_generate],
]$1([yydestruct], ]$1([yydestruct],
[static void], [static void],
[[int yytype], [yytype]], [[int yytype], [yytype]],
[[YYSTYPE yyvalue], [yyvalue]]b4_location_if([, [[YYSTYPE *yyvaluep], [yyvaluep]]b4_location_if([,
[[YYLTYPE yylocation], [yylocation]]]))[ [[YYLTYPE *yylocationp], [yylocationp]]]))[
{ {
/* Pacify ``unused variable'' warnings. */ /* Pacify ``unused variable'' warnings. */
(void) yyvalue; (void) yyvaluep;
]b4_location_if([ (void) yylocation; ]b4_location_if([ (void) yylocationp;
])[ ])[
switch (yytype) switch (yytype)
{ {
@@ -367,3 +367,46 @@ m4_define([b4_yydestruct_generate],
} }
}]dnl }]dnl
]) ])
# b4_yysymprint_generate(FUNTION-DECLARATOR)
# ------------------------------------------
# Generate the "yysymprint" function, which declaration is issued using
# FUNTION-DECLARATOR, which may be "b4_c_ansi_function_def" for ISO C
# or "b4_c_function_def" for K&R.
m4_define([b4_yysymprint_generate],
[[/*-----------------------------.
| Print this symbol on YYOUT. |
`-----------------------------*/
]$1([yysymprint],
[static void],
[[FILE *yyout], [yyout]],
[[int yytype], [yytype]],
[[YYSTYPE *yyvaluep], [yyvaluep]]b4_location_if([,
[[YYLTYPE *yylocationp], [yylocationp]]]))
{
/* Pacify ``unused variable'' warnings. */
(void) yyvaluep;
b4_location_if([ (void) yylocationp;
])dnl
if (yytype < YYNTOKENS)
{
YYFPRINTF (yyout, "token %s (", yytname[[yytype]]);
# ifdef YYPRINT
YYPRINT (yyout, yytoknum[[yytype]], yyvalue);
# endif
}
else
YYFPRINTF (yyout, "nterm %s (", yytname[[yytype]]);
switch (yytype)
{
m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl
default:
break;
}
YYFPRINTF (yyout, ")");
}
])

View File

@@ -395,6 +395,13 @@ static const ]b4_int_type_for([b4_check])[ yycheck[] =
]b4_check[ ]b4_check[
}; };
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const ]b4_int_type_for([b4_stos])[ yystos[] =
{
]b4_stos[
};
/* Prevent warning if -Wmissing-prototypes. */ /* Prevent warning if -Wmissing-prototypes. */
]b4_c_ansi_function_decl([yyparse], [int], b4_parse_param)[ ]b4_c_ansi_function_decl([yyparse], [int], b4_parse_param)[
@@ -451,12 +458,25 @@ do { \
if (yydebug) \ if (yydebug) \
YYFPRINTF Args; \ YYFPRINTF Args; \
} while (0) } while (0)
]b4_yysymprint_generate([b4_c_ansi_function_def])[
# define YYDSYMPRINT(Args) \
do { \
if (yydebug) \
yysymprint Args; \
} while (0)
/* Nonzero means print parse trace. It is left uninitialized so that /* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */ multiple parsers can coexist. */
int yydebug; int yydebug;
#else /* !YYDEBUG */ #else /* !YYDEBUG */
/* Avoid empty `if' bodies. */ /* Avoid empty `if' bodies. */
# define YYDPRINTF(Args) {} # define YYDPRINTF(Args) {}
# define YYDSYMPRINT(Args) {}
#endif /* !YYDEBUG */ #endif /* !YYDEBUG */
/* YYINITDEPTH -- initial size of the parser's stacks. */ /* YYINITDEPTH -- initial size of the parser's stacks. */
@@ -611,8 +631,6 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
*yyvalp = yyvsp[1-yyrhslen].yystate.yysemantics.yysval; *yyvalp = yyvsp[1-yyrhslen].yystate.yysemantics.yysval;
*yylocp = yyvsp[1-yyrhslen].yystate.yyloc; *yylocp = yyvsp[1-yyrhslen].yystate.yyloc;
} }
# undef yyval
# define yyval (*yyvalp)
# undef yyerrok # undef yyerrok
# define yyerrok (yystack->yyerrState = 0) # define yyerrok (yystack->yyerrState = 0)
# undef YYACCEPT # undef YYACCEPT
@@ -639,7 +657,6 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
} }
return yyok; return yyok;
# undef yyval
# undef yyerrok # undef yyerrok
# undef YYABORT # undef YYABORT
# undef YYACCEPT # undef YYACCEPT
@@ -669,6 +686,8 @@ yyuserMerge (int yyn, YYSTYPE* yy0, YYSTYPE* yy1)
[ [
/* Bison grammar-table manipulation. */ /* Bison grammar-table manipulation. */
]b4_yydestruct_generate([b4_c_ansi_function_def])[
/** Number of symbols composing the right hand side of rule #RULE. */ /** Number of symbols composing the right hand side of rule #RULE. */
static inline int static inline int
yyrhsLength (yyRuleNum yyrule) yyrhsLength (yyRuleNum yyrule)
@@ -1621,10 +1640,31 @@ yyrecoverParseError (yyGLRStack* yystack,
while (yytrue) while (yytrue)
{ {
if (*yytokenp == YYEOF) if (*yytokenp == YYEOF)
yyFail (yystack][]b4_lpure_args[, NULL); {
/* Now pop stack until we find a state that shifts the
error token. */
while (yystack->yytops.yystates[0] != NULL)
{
yyGLRState *yys = yystack->yytops.yystates[0];
YYDPRINTF ((stderr, "Error: popping "));
YYDSYMPRINT ((stderr,
yystos[yys->yylrState],
&yys->yysemantics.yysval]b4_location_if([, &yys->yyloc])[));
YYDPRINTF ((stderr, "\n"));
yydestruct (yystos[yys->yylrState],
&yys->yysemantics.yysval]b4_location_if([, &yys->yyloc])[);
yystack->yytops.yystates[0] = yys->yypred;
yystack->yynextFree -= 1;
yystack->yyspaceLeft += 1;
}
yyFail (yystack][]b4_lpure_args[, NULL);
}
if (*yytokenp != YYEMPTY) if (*yytokenp != YYEMPTY)
YYDPRINTF ((stderr, "Discarding token %s\n", {
yytokenName (*yytokenp))); YYDPRINTF ((stderr, "Discarding token %s\n",
yytokenName (*yytokenp)));
yydestruct (*yytokenp, yylvalp]b4_location_if([, yyllocp])[);
}
YYDPRINTF ((stderr, "Reading a token: ")); YYDPRINTF ((stderr, "Reading a token: "));
yychar = YYLEX; yychar = YYLEX;
*yytokenp = YYTRANSLATE (yychar); *yytokenp = YYTRANSLATE (yychar);
@@ -1657,20 +1697,28 @@ yyrecoverParseError (yyGLRStack* yystack,
/* Now pop stack until we find a state that shifts the error token. */ /* Now pop stack until we find a state that shifts the error token. */
while (yystack->yytops.yystates[0] != NULL) while (yystack->yytops.yystates[0] != NULL)
{ {
yyj = yypact[yystack->yytops.yystates[0]->yylrState]; yyGLRState *yys = yystack->yytops.yystates[0];
yyj = yypact[yys->yylrState];
if (! yyis_pact_ninf (yyj)) if (! yyis_pact_ninf (yyj))
{ {
yyj += YYTERROR; yyj += YYTERROR;
if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == YYTERROR if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == YYTERROR
&& yyisShiftAction (yytable[yyj])) && yyisShiftAction (yytable[yyj]))
{ {
YYDPRINTF ((stderr, "Shifting error token, "));
yyglrShift (yystack, 0, yytable[yyj], yyglrShift (yystack, 0, yytable[yyj],
yystack->yytops.yystates[0]->yyposn, yys->yyposn, *yylvalp, yyllocp]b4_user_args[);
*yylvalp, yyllocp]b4_user_args[);
break; break;
} }
} }
yystack->yytops.yystates[0] = yystack->yytops.yystates[0]->yypred; YYDPRINTF ((stderr, "Error: popping "));
YYDSYMPRINT ((stderr,
yystos[yys->yylrState],
&yys->yysemantics.yysval]b4_location_if([, &yys->yyloc])[));
YYDPRINTF ((stderr, "\n"));
yydestruct (yystos[yys->yylrState],
&yys->yysemantics.yysval]b4_location_if([, &yys->yyloc])[);
yystack->yytops.yystates[0] = yys->yypred;
yystack->yynextFree -= 1; yystack->yynextFree -= 1;
yystack->yyspaceLeft += 1; yystack->yyspaceLeft += 1;
} }

View File

@@ -620,42 +620,8 @@ yystpcpy (yydest, yysrc)
#if YYDEBUG #if YYDEBUG
/*-----------------------------. b4_yysymprint_generate([b4_c_function_def])
| Print this symbol on YYOUT. |
`-----------------------------*/
b4_c_function_def([yysymprint],
[static void],
[[FILE *yyout], [yyout]],
[[int yytype], [yytype]],
[[YYSTYPE yyvalue], [yyvalue]]b4_location_if([,
[[YYLTYPE yylocation], [yylocation]]]))
{
/* Pacify ``unused variable'' warnings. */
(void) yyvalue;
b4_location_if([ (void) yylocation;
])dnl
if (yytype < YYNTOKENS)
{
YYFPRINTF (yyout, "token %s (", yytname[[yytype]]);
# ifdef YYPRINT
YYPRINT (yyout, yytoknum[[yytype]], yyvalue);
# endif
}
else
YYFPRINTF (yyout, "nterm %s (", yytname[[yytype]]);
switch (yytype)
{
m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl
default:
break;
}
YYFPRINTF (yyout, ")");
}
#endif /* YYDEBUG. */ #endif /* YYDEBUG. */
b4_yydestruct_generate([b4_c_function_def]) b4_yydestruct_generate([b4_c_function_def])
@@ -888,7 +854,7 @@ yybackup:
/* We have to keep this `#if YYDEBUG', since we use variables /* We have to keep this `#if YYDEBUG', since we use variables
which are defined only if `YYDEBUG' is set. */ which are defined only if `YYDEBUG' is set. */
YYDPRINTF ((stderr, "Next token is ")); YYDPRINTF ((stderr, "Next token is "));
YYDSYMPRINT ((stderr, yytoken, yylval]b4_location_if([, yyloc])[)); YYDSYMPRINT ((stderr, yytoken, &yylval]b4_location_if([, &yyloc])[));
YYDPRINTF ((stderr, "\n")); YYDPRINTF ((stderr, "\n"));
} }
@@ -1097,9 +1063,9 @@ yyerrlab1:
YYDPRINTF ((stderr, "Error: popping ")); YYDPRINTF ((stderr, "Error: popping "));
YYDSYMPRINT ((stderr, YYDSYMPRINT ((stderr,
yystos[*yyssp], yystos[*yyssp],
*yyvsp]b4_location_if([, *yylsp])[)); yyvsp]b4_location_if([, yylsp])[));
YYDPRINTF ((stderr, "\n")); YYDPRINTF ((stderr, "\n"));
yydestruct (yystos[*yyssp], *yyvsp]b4_location_if([, *yylsp])[); yydestruct (yystos[*yyssp], yyvsp]b4_location_if([, yylsp])[);
YYPOPSTACK; YYPOPSTACK;
} }
YYABORT; YYABORT;
@@ -1107,7 +1073,7 @@ yyerrlab1:
YYDPRINTF ((stderr, "Discarding token %d (%s).\n", YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
yytoken, yytname[yytoken])); yytoken, yytname[yytoken]));
yydestruct (yytoken, yylval]b4_location_if([, yylloc])[); yydestruct (yytoken, &yylval]b4_location_if([, &yylloc])[);
yytoken = YYEMPTY; yytoken = YYEMPTY;
} }
@@ -1136,10 +1102,10 @@ yyerrlab1:
YYDPRINTF ((stderr, "Error: popping ")); YYDPRINTF ((stderr, "Error: popping "));
YYDSYMPRINT ((stderr, YYDSYMPRINT ((stderr,
yystos[*yyssp], *yyvsp]b4_location_if([, *yylsp])[)); yystos[*yyssp], yyvsp]b4_location_if([, yylsp])[));
YYDPRINTF ((stderr, "\n")); YYDPRINTF ((stderr, "\n"));
yydestruct (yystos[yystate], *yyvsp]b4_location_if([, *yylsp])[); yydestruct (yystos[yystate], yyvsp]b4_location_if([, yylsp])[);
yyvsp--; yyvsp--;
yystate = *--yyssp; yystate = *--yyssp;
]b4_location_if([ yylsp--;])[ ]b4_location_if([ yylsp--;])[

View File

@@ -167,10 +167,13 @@ AT_DATA([[input.y]],
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#define YYERROR_VERBOSE 1 static int yylex (void);
#define YYDEBUG 1 static void yyerror (const char *msg);
%} %}
%error-verbose
%debug
%verbose %verbose
%locations
%union %union
{ {
int ival; int ival;
@@ -181,20 +184,20 @@ AT_DATA([[input.y]],
input line thing 'x' input line thing 'x'
%destructor %destructor
{ { fprintf (stdout, "Freeing nterm input (%d from %d)\n", $$, @$.first_line); }
fprintf (stdout, "Freeing "); input
/* FIXME: Ouch: INTERNAL DETAILS EXPOSED HERE. */
/* Cannot use $$ which is the union member, not the union itself. */
yysymprint (stdout, yytype, yyvalue, @$);
fprintf (stdout, "\n");
}
input line thing 'x'
%{ %destructor
static int yylex (void); { fprintf (stdout, "Freeing nterm line (%d from %d)\n", $$, @$.first_line); }
static void yyerror (const char *msg); line
%}
%destructor
{ fprintf (stdout, "Freeing nterm thing (%d from %d)\n", $$, @$.first_line); }
thing
%destructor
{ fprintf (stdout, "Freeing token 'x' (%d from %d)\n", $$, @$.first_line); }
'x'
%% %%
input: input:
@@ -295,7 +298,7 @@ main (void)
} }
]]) ]])
AT_CHECK([bison --location -d -v -o input.c input.y]) AT_CHECK([bison -o input.c input.y])
AT_COMPILE([input]) AT_COMPILE([input])
AT_PARSER_CHECK([./input], 1, AT_PARSER_CHECK([./input], 1,
[[sending: 'x' (value = 0, line 0) [[sending: 'x' (value = 0, line 0)

View File

@@ -318,7 +318,7 @@ AT_DATA([input.y],
void yyerror (const char *s); void yyerror (const char *s);
int yylex (void); int yylex (void);
%} %}
[%token YYEOF 0 "end of file" [%token MYEOF 0 "end of file"
%token 'a' "a" %token 'a' "a"
%token b "b" %token b "b"
%token c 'c' %token c 'c'