From 3fc16193d99d8ae347fa44d31edd884279d78310 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 20 Sep 2004 09:32:55 +0000 Subject: [PATCH] * data/yacc.c (YY_LOCATION_PRINT): New. Define when we know YYLTYPE's structure, i.e., when the default YYLLOC_DEFAULT is used. * data/c.m4 (b4_yysymprint_generate): Use it. * data/lalr1.cc (YYLLOC_DEFAULT): Stop relying on the initial value of the result. (error_start_): Replace with... (error_range_): this location array. This allows to replace code relying on the implementation of locations by portable code. * data/yacc.c (yylerrsp): Replace with... (yyerror_range): this. Every time a token is popped, update yyerror_range[0], to have an accurate location for the error token. * data/glr.c (YY_LOCATION_PRINT): New. (yyprocessOneStack): Fix an invocation of YY_SYMBOL_PRINT: deference a pointer. * tests/actions.at (_AT_CHECK_PRINTER_AND_DESTRUCTOR): No longer report the location in %printers. * src/scan-skel.l: Instead of abort, report error messages to ease understanding skeleton scanning failures. --- ChangeLog | 25 +++++++++++++++++++++++++ data/c.m4 | 18 +++++++++++------- data/glr.c | 18 +++++++++++++++--- data/lalr1.cc | 35 +++++++++++++++++++---------------- data/yacc.c | 44 ++++++++++++++++++++++++++++++++------------ src/scan-skel.l | 7 ++++--- tests/actions.at | 2 +- 7 files changed, 107 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index f9818fae..388ad7f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2004-09-20 Akim Demaille + + * data/yacc.c (YY_LOCATION_PRINT): New. + Define when we know YYLTYPE's structure, i.e., when the default + YYLLOC_DEFAULT is used. + * data/c.m4 (b4_yysymprint_generate): Use it. + * data/lalr1.cc (YYLLOC_DEFAULT): Stop relying on the initial + value of the result. + (error_start_): Replace with... + (error_range_): this location array. + This allows to replace code relying on the implementation of + locations by portable code. + * data/yacc.c (yylerrsp): Replace with... + (yyerror_range): this. + Every time a token is popped, update yyerror_range[0], to have an + accurate location for the error token. + * data/glr.c (YY_LOCATION_PRINT): New. + (yyprocessOneStack): Fix an invocation of YY_SYMBOL_PRINT: + deference a pointer. + * tests/actions.at (_AT_CHECK_PRINTER_AND_DESTRUCTOR): No longer + report the location in %printers. + + * src/scan-skel.l: Instead of abort, report error messages to ease + understanding skeleton scanning failures. + 2004-09-16 Akim Demaille * data/lalr1.cc (Stack::Iterator, Stack::ConstIterator): Rename as... diff --git a/data/c.m4 b/data/c.m4 index 1d81b54a..04b2e762 100644 --- a/data/c.m4 +++ b/data/c.m4 @@ -396,23 +396,27 @@ m4_define([b4_yysymprint_generate], (void) yyvaluep; b4_location_if([ (void) yylocationp; ])dnl - +[ if (yytype < YYNTOKENS) { - YYFPRINTF (yyoutput, "token %s (", yytname[[yytype]]); + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); # ifdef YYPRINT - YYPRINT (yyoutput, yytoknum[[yytype]], *yyvaluep); + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # endif } else - YYFPRINTF (yyoutput, "nterm %s (", yytname[[yytype]]); + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); +]b4_location_if([ YY_LOCATION_PRINT (yyoutput, *yylocationp); + fprintf (yyoutput, ": "); +])dnl +[ switch (yytype) { -m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl - default: +]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl +[ default: break; } YYFPRINTF (yyoutput, ")"); } -]) +]]) diff --git a/data/glr.c b/data/glr.c index b594a83b..060b3283 100644 --- a/data/glr.c +++ b/data/glr.c @@ -420,8 +420,7 @@ static const ]b4_int_type_for([b4_stos])[ yystos[] = /* Error token number */ #define YYTERROR 1 -/* YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). */ +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. */ ]b4_location_if([[ #define YYRHSLOC(yyRhs,YYK) ((yyRhs)[YYK].yystate.yyloc) @@ -432,6 +431,15 @@ static const ]b4_int_type_for([b4_stos])[ yystos[] = (yyCurrent).first_column = YYRHSLOC(yyRhs, 1).first_column, \ (yyCurrent).last_line = YYRHSLOC(yyRhs, YYN).last_line, \ (yyCurrent).last_column = YYRHSLOC(yyRhs, YYN).last_column) + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) #endif ]],[ #ifndef YYLLOC_DEFAULT @@ -439,6 +447,10 @@ static const ]b4_int_type_for([b4_stos])[ yystos[] = #endif ])[ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + /* YYLEX -- calling `yylex' with the right arguments. */ #define YYLEX ]b4_c_function_call([yylex], [int], b4_lex_param)[ @@ -1579,7 +1591,7 @@ yyprocessOneStack (yyGLRStack* yystack, int yyk, if (yyisShiftAction (yyaction)) { YYDPRINTF ((stderr, "On stack %d, ", yyk)); - YY_SYMBOL_PRINT ("shifting", yytokenp, yylvalp, yyllocp); + YY_SYMBOL_PRINT ("shifting", *yytokenp, yylvalp, yyllocp); yyglrShift (yystack, yyk, yyaction, yyposn+1, *yylvalp, yyllocp]b4_user_args[); YYDPRINTF ((stderr, ", now in state #%d\n", diff --git a/data/lalr1.cc b/data/lalr1.cc index 74db24cf..ef5aad8e 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -172,9 +172,14 @@ b4_syncline([@oline@], [@ofile@])], ]/* Line __line__ of lalr1.cc. */ b4_syncline([@oline@], [@ofile@])[ +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. */ + #ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - ((Current).end = Rhs[N].end) +# define YYLLOC_DEFAULT(Current, Rhs, N) \ +do { \ + ((Current).begin = (Rhs)[1].begin); \ + ((Current).end = (Rhs)[N].end); \ +} while (0) #endif namespace yy @@ -323,8 +328,8 @@ namespace yy /* Semantic value and location of look-ahead token. */ SemanticType value; LocationType location; - /* Beginning of the last erroneous token popped off. */ - Position error_start_; + /// The locations where the error started and ended. + Location error_range_[2]; /* @@$ and $$. */ SemanticType yyval; @@ -604,7 +609,7 @@ yyerrlab: /* If not already recovering from an error, report this error. */ report_syntax_error_ (); - error_start_ = location.begin; + error_range_[0] = location; if (errstatus_ == 3) { /* If just tried and failed to reuse look-ahead token after an @@ -618,7 +623,7 @@ yyerrlab: if (looka_ == eof_) for (;;) { - error_start_ = location_stack_[0].begin; + error_range_[0] = location_stack_[0]; pop (); if (state_stack_.height () == 1) YYABORT; @@ -652,7 +657,7 @@ yyerrorlab: goto yyerrorlab; #endif - error_start_ = location_stack_[len_ - 1].begin; + error_range_[0] = location_stack_[len_ - 1]; pop (len_); state_ = state_stack_[0]; goto yyerrlab1; @@ -681,10 +686,9 @@ yyerrlab1: if (state_stack_.height () == 1) YYABORT; + error_range_[0] = location_stack_[0]; destruct_ ("Error: popping", stos_[state_], &semantic_stack_[0], &location_stack_[0]); - error_start_ = location_stack_[0].begin; - pop (); state_ = state_stack_[0]; YY_STACK_PRINT (); @@ -693,13 +697,12 @@ yyerrlab1: if (n_ == final_) goto yyacceptlab; - { - Location errloc; - errloc.begin = error_start_; - errloc.end = location.end; - semantic_stack_.push (value); - location_stack_.push (errloc); - } + error_range_[1] = location; + // Using LOCATION is tempting, but would change the location of + // the look-ahead. YYLOC is available though. + YYLLOC_DEFAULT (yyloc, error_range_ - 1, 2); + semantic_stack_.push (value); + location_stack_.push (yyloc); /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", stos_[n_], diff --git a/data/yacc.c b/data/yacc.c index cf6c4329..840e7cec 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -501,11 +501,12 @@ do \ } \ while (0) + #define YYTERROR 1 #define YYERRCODE 256 -/* YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). */ + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. */ #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ @@ -513,8 +514,22 @@ while (0) (Current).first_column = (Rhs)[1].first_column, \ (Current).last_line = (Rhs)[N].last_line, \ (Current).last_column = (Rhs)[N].last_column) + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +#endif + +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif + /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM @@ -770,7 +785,8 @@ b4_c_function_def([yyparse], [int], b4_parse_param) YYLTYPE yylsa[YYINITDEPTH]; YYLTYPE *yyls = yylsa; YYLTYPE *yylsp; - YYLTYPE *yylerrsp;]])[ + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[2];]])[ #define YYPOPSTACK (yyvsp--, yyssp--]b4_location_if([, yylsp--])[) @@ -1097,7 +1113,7 @@ yyerrlab: yyerror (]b4_yyerror_args["syntax error"); } -]b4_location_if([ yylerrsp = yylsp;])[ +]b4_location_if([[ yyerror_range[0] = yylloc;]])[ if (yyerrstatus == 3) { @@ -1111,6 +1127,7 @@ yyerrlab: if (yychar == YYEOF) for (;;) { +]b4_location_if([[ yyerror_range[0] = *yylsp;]])[ YYPOPSTACK; if (yyssp == yyss) YYABORT; @@ -1122,7 +1139,6 @@ yyerrlab: { yydestruct ("Error: discarding", yytoken, &yylval]b4_location_if([, &yylloc])[); yychar = YYEMPTY; -]b4_location_if([ *++yylerrsp = yylloc;])[ } } @@ -1143,13 +1159,12 @@ yyerrorlab: goto yyerrorlab; #endif - yyvsp -= yylen; +]b4_location_if([[ yyerror_range[0] = yylsp[1-yylen]; + yylsp -= yylen; + ]])[yyvsp -= yylen; yyssp -= yylen; yystate = *yyssp; - ]b4_location_if([yylerrsp = yylsp; - *++yylerrsp = yyloc; - yylsp -= yylen; - ])[goto yyerrlab1; + goto yyerrlab1; /*-------------------------------------------------------------. @@ -1176,6 +1191,7 @@ yyerrlab1: if (yyssp == yyss) YYABORT; +]b4_location_if([[ yyerror_range[0] = *yylsp;]])[ yydestruct ("Error: popping", yystos[yystate], yyvsp]b4_location_if([, yylsp])[); YYPOPSTACK; yystate = *yyssp; @@ -1186,8 +1202,12 @@ yyerrlab1: YYACCEPT; *++yyvsp = yylval; -]b4_location_if([ YYLLOC_DEFAULT (yyloc, yylsp, yylerrsp - yylsp); - *++yylsp = yyloc;])[ +]b4_location_if([[ + yyerror_range[1] = yylloc; + /* Using YYLLOC is tempting, but would change the location of + the look-ahead. YYLOC is available though. */ + YYLLOC_DEFAULT (yyloc, yyerror_range - 1, 2); + *++yylsp = yyloc;]])[ /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); diff --git a/src/scan-skel.l b/src/scan-skel.l index af5226c9..47b696da 100644 --- a/src/scan-skel.l +++ b/src/scan-skel.l @@ -1,6 +1,6 @@ /* Scan Bison Skeletons. -*- C -*- - Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -55,7 +55,7 @@ int skel_lex (void); else if (strcmp (filename, "@output_parser_name@") == 0) filename = parser_file_name; else - abort (); + fatal ("invalid token in skeleton: %s", yytext); } XFREE (outname); @@ -74,7 +74,8 @@ int skel_lex (void); "@output_parser_name@" QPUTS (parser_file_name); "@output_header_name@" QPUTS (spec_defines_file); -"@" abort (); + /* This pattern must not match more than the previous @ patterns. */ +@[^{}@\n]* fatal ("invalid @ in skeleton: %s", yytext); \n lineno++; ECHO; [^@\n]+ ECHO; diff --git a/tests/actions.at b/tests/actions.at index 6de55cf9..d4d420e5 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -197,7 +197,7 @@ m4_ifval([$6], [%union %printer { ]AT_LALR1_CC_IF([cdebug_ << $$;], - [fprintf (yyoutput, "%d@%d-%d", $$, RANGE (@$))])[; + [fprintf (yyoutput, "%d", $$)])[; } input line thing 'x' 'y' -- 2.45.2