From 7bd6c77e5e135196b9461c404d2aca4c4fc516fa Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 12 Nov 2002 09:03:13 +0000 Subject: [PATCH] * 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. --- ChangeLog | 19 ++++++++++++ NEWS | 4 +-- data/c.m4 | 57 +++++++++++++++++++++++++++++++----- data/glr.c | 70 ++++++++++++++++++++++++++++++++++++++------- data/yacc.c | 48 +++++-------------------------- tests/actions.at | 35 ++++++++++++----------- tests/regression.at | 2 +- 7 files changed, 157 insertions(+), 78 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0d6dc3b5..a6107150 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2002-11-12 Akim Demaille + + * 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 * data/c.m4 (b4_yydestruct_generate, b4_symbol_actions): New. diff --git a/NEWS b/NEWS index 1bf3b70d..b12e9745 100644 --- a/NEWS +++ b/NEWS @@ -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 error messages instead of `$end', which remains being the default. For instance - %token YYEOF 0 + %token MYEOF 0 or - %token YYEOF 0 "end of file" + %token MYEOF 0 "end of file" * Semantic parser This old option, which has been broken for ages, is removed. diff --git a/data/c.m4 b/data/c.m4 index d6de2a93..58d8e1a9 100644 --- a/data/c.m4 +++ b/data/c.m4 @@ -327,8 +327,8 @@ m4_define([b4_syncline], # SYMBOL-ACTION, SYMBOL-TYPENAME) # ------------------------------------------------- m4_define([b4_symbol_actions], -[m4_pushdef([b4_dollar_dollar], [yyvalue.$6])dnl -m4_pushdef([b4_at_dollar], [yylocation])dnl +[m4_pushdef([b4_dollar_dollar], [yyvaluep->$6])dnl +m4_pushdef([b4_at_dollar], [(*yylocationp)])dnl case $4: /* $3 */ b4_syncline([$2], [$1]) $5; @@ -351,13 +351,13 @@ m4_define([b4_yydestruct_generate], ]$1([yydestruct], [static void], - [[int yytype], [yytype]], - [[YYSTYPE yyvalue], [yyvalue]]b4_location_if([, - [[YYLTYPE yylocation], [yylocation]]]))[ + [[int yytype], [yytype]], + [[YYSTYPE *yyvaluep], [yyvaluep]]b4_location_if([, + [[YYLTYPE *yylocationp], [yylocationp]]]))[ { /* Pacify ``unused variable'' warnings. */ - (void) yyvalue; -]b4_location_if([ (void) yylocation; + (void) yyvaluep; +]b4_location_if([ (void) yylocationp; ])[ switch (yytype) { @@ -367,3 +367,46 @@ m4_define([b4_yydestruct_generate], } }]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, ")"); +} +]) diff --git a/data/glr.c b/data/glr.c index 7191458f..cc8d6f18 100644 --- a/data/glr.c +++ b/data/glr.c @@ -395,6 +395,13 @@ static const ]b4_int_type_for([b4_check])[ yycheck[] = ]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. */ ]b4_c_ansi_function_decl([yyparse], [int], b4_parse_param)[ @@ -451,12 +458,25 @@ do { \ if (yydebug) \ YYFPRINTF Args; \ } 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 multiple parsers can coexist. */ int yydebug; + #else /* !YYDEBUG */ + /* Avoid empty `if' bodies. */ -# define YYDPRINTF(Args) {} +# define YYDPRINTF(Args) {} +# define YYDSYMPRINT(Args) {} + #endif /* !YYDEBUG */ /* 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; *yylocp = yyvsp[1-yyrhslen].yystate.yyloc; } -# undef yyval -# define yyval (*yyvalp) # undef yyerrok # define yyerrok (yystack->yyerrState = 0) # undef YYACCEPT @@ -639,7 +657,6 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp, } return yyok; -# undef yyval # undef yyerrok # undef YYABORT # undef YYACCEPT @@ -669,6 +686,8 @@ yyuserMerge (int yyn, YYSTYPE* yy0, YYSTYPE* yy1) [ /* Bison grammar-table manipulation. */ +]b4_yydestruct_generate([b4_c_ansi_function_def])[ + /** Number of symbols composing the right hand side of rule #RULE. */ static inline int yyrhsLength (yyRuleNum yyrule) @@ -1621,10 +1640,31 @@ yyrecoverParseError (yyGLRStack* yystack, while (yytrue) { 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) - 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: ")); yychar = YYLEX; *yytokenp = YYTRANSLATE (yychar); @@ -1657,20 +1697,28 @@ yyrecoverParseError (yyGLRStack* yystack, /* Now pop stack until we find a state that shifts the error token. */ 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)) { yyj += YYTERROR; if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == YYTERROR && yyisShiftAction (yytable[yyj])) { + YYDPRINTF ((stderr, "Shifting error token, ")); yyglrShift (yystack, 0, yytable[yyj], - yystack->yytops.yystates[0]->yyposn, - *yylvalp, yyllocp]b4_user_args[); + yys->yyposn, *yylvalp, yyllocp]b4_user_args[); 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->yyspaceLeft += 1; } diff --git a/data/yacc.c b/data/yacc.c index 0879a43c..8f597902 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -620,42 +620,8 @@ yystpcpy (yydest, yysrc) #if YYDEBUG -/*-----------------------------. -| 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, ")"); -} +b4_yysymprint_generate([b4_c_function_def]) #endif /* YYDEBUG. */ - b4_yydestruct_generate([b4_c_function_def]) @@ -888,7 +854,7 @@ yybackup: /* We have to keep this `#if YYDEBUG', since we use variables which are defined only if `YYDEBUG' is set. */ YYDPRINTF ((stderr, "Next token is ")); - YYDSYMPRINT ((stderr, yytoken, yylval]b4_location_if([, yyloc])[)); + YYDSYMPRINT ((stderr, yytoken, &yylval]b4_location_if([, &yyloc])[)); YYDPRINTF ((stderr, "\n")); } @@ -1097,9 +1063,9 @@ yyerrlab1: YYDPRINTF ((stderr, "Error: popping ")); YYDSYMPRINT ((stderr, yystos[*yyssp], - *yyvsp]b4_location_if([, *yylsp])[)); + yyvsp]b4_location_if([, yylsp])[)); YYDPRINTF ((stderr, "\n")); - yydestruct (yystos[*yyssp], *yyvsp]b4_location_if([, *yylsp])[); + yydestruct (yystos[*yyssp], yyvsp]b4_location_if([, yylsp])[); YYPOPSTACK; } YYABORT; @@ -1107,7 +1073,7 @@ yyerrlab1: YYDPRINTF ((stderr, "Discarding token %d (%s).\n", yytoken, yytname[yytoken])); - yydestruct (yytoken, yylval]b4_location_if([, yylloc])[); + yydestruct (yytoken, &yylval]b4_location_if([, &yylloc])[); yytoken = YYEMPTY; } @@ -1136,10 +1102,10 @@ yyerrlab1: YYDPRINTF ((stderr, "Error: popping ")); YYDSYMPRINT ((stderr, - yystos[*yyssp], *yyvsp]b4_location_if([, *yylsp])[)); + yystos[*yyssp], yyvsp]b4_location_if([, yylsp])[)); YYDPRINTF ((stderr, "\n")); - yydestruct (yystos[yystate], *yyvsp]b4_location_if([, *yylsp])[); + yydestruct (yystos[yystate], yyvsp]b4_location_if([, yylsp])[); yyvsp--; yystate = *--yyssp; ]b4_location_if([ yylsp--;])[ diff --git a/tests/actions.at b/tests/actions.at index e6e23866..0ed50fe4 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -167,10 +167,13 @@ AT_DATA([[input.y]], #include #include -#define YYERROR_VERBOSE 1 -#define YYDEBUG 1 +static int yylex (void); +static void yyerror (const char *msg); %} +%error-verbose +%debug %verbose +%locations %union { int ival; @@ -181,20 +184,20 @@ AT_DATA([[input.y]], input line thing 'x' %destructor - { - fprintf (stdout, "Freeing "); - /* 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' - -%{ -static int yylex (void); -static void yyerror (const char *msg); -%} + { fprintf (stdout, "Freeing nterm input (%d from %d)\n", $$, @$.first_line); } + input +%destructor + { fprintf (stdout, "Freeing nterm line (%d from %d)\n", $$, @$.first_line); } + 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: @@ -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_PARSER_CHECK([./input], 1, [[sending: 'x' (value = 0, line 0) diff --git a/tests/regression.at b/tests/regression.at index d91dbc6e..ec5e140f 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -318,7 +318,7 @@ AT_DATA([input.y], void yyerror (const char *s); int yylex (void); %} -[%token YYEOF 0 "end of file" +[%token MYEOF 0 "end of file" %token 'a' "a" %token b "b" %token c 'c' -- 2.45.2