X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/a005dbcbe34382c2b9cb3075e83aa79ac2e651b4..5422d56a718805a2470558808355e04182a12d65:/data/lalr1.cc diff --git a/data/lalr1.cc b/data/lalr1.cc index d56c8b82..801f5904 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -1,6 +1,6 @@ # C++ skeleton for Bison -# Copyright (C) 2002-2010 Free Software Foundation, Inc. +# Copyright (C) 2002-2011 Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -24,9 +24,10 @@ m4_define([b4_parser_class_name], b4_defines_if([], [b4_fatal([b4_skeleton[: using %%defines is mandatory]])]) -# Backward compatibility. -m4_define([b4_location_constructors]) -m4_include(b4_pkgdatadir/[location.cc]) +b4_percent_define_ifdef([[location_type]], [], + [# Backward compatibility. + m4_define([b4_location_constructors]) + m4_include(b4_pkgdatadir/[location.cc])]) # We do want M4 expansion after # for CPP macros. m4_changecom() @@ -34,7 +35,7 @@ m4_divert_push(0)dnl b4_defines_if( [@output(b4_spec_defines_file@)@ b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++], - [2002-2010]) + [2002-2011]) dnl FIXME: This is wrong, we want computed header guards. [ /* C++ LALR(1) parser skeleton written by Akim Demaille. */ @@ -47,13 +48,8 @@ dnl FIXME: This is wrong, we want computed header guards. #include #include #include "stack.hh" - -]b4_namespace_open[ - class position; - class location; -]b4_namespace_close[ - -#include "location.hh" +]b4_percent_define_ifdef([[location_type]], [], + [[#include "location.hh"]])[ /* Enabling traces. */ #ifndef YYDEBUG @@ -73,25 +69,6 @@ dnl FIXME: This is wrong, we want computed header guards. # define YYTOKEN_TABLE ]b4_token_table[ #endif -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ -do { \ - if (N) \ - { \ - (Current).begin = (Rhs)[1].begin; \ - (Current).end = (Rhs)[N].end; \ - } \ - else \ - { \ - (Current).begin = (Current).end = (Rhs)[0].end; \ - } \ -} while (false) -#endif - ]b4_namespace_open[ /// A Bison parser. @@ -112,7 +89,8 @@ b4_user_stype typedef YYSTYPE semantic_type; #endif /// Symbol locations. - typedef ]b4_percent_define_get([[location_type]])[ location_type; + typedef ]b4_percent_define_get([[location_type]], + [[location]])[ location_type; /// Tokens. struct token { @@ -304,7 +282,7 @@ b4_percent_code_get([[provides]])[]dnl ])dnl @output(b4_parser_file_name@)@ b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++], - [2002-2010]) + [2002-2011]) b4_percent_code_get([[top]])[]dnl m4_if(b4_prefix, [yy], [], [ @@ -333,6 +311,26 @@ b4_percent_code_get[]dnl # endif #endif +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).begin = YYRHSLOC (Rhs, 1).begin; \ + (Current).end = YYRHSLOC (Rhs, N).end; \ + } \ + else \ + { \ + (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end; \ + } \ + while (false) +#endif + /* Suppress unused-variable warnings by "using" E. */ #define YYUSE(e) ((void) (e)) @@ -693,6 +691,17 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; default: break; } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action + invokes YYABORT, YYACCEPT, or YYERROR immediately after altering + yychar. In the case of YYABORT or YYACCEPT, an incorrect + destructor might then be invoked immediately. In the case of + YYERROR, subsequent parser actions might lead to an incorrect + destructor call or verbose syntax error message before the + lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], &yyval, &yyloc); yypop_ (yylen); @@ -716,10 +725,16 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yytranslate_ (yychar); + /* If not already recovering from an error, report this error. */ if (!yyerrstatus_) { ++yynerrs_; + if (yychar == yyempty_) + yytoken = yyempty_; error (yylloc, yysyntax_error_ (yystate, yytoken)); } @@ -825,7 +840,13 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; yyreturn: if (yychar != yyempty_) - yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); + { + /* Make sure we have latest lookahead translation. See comments + at user semantic actions for why this is necessary. */ + yytoken = yytranslate_ (yychar); + yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval, + &yylloc); + } /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ @@ -847,70 +868,97 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; ]b4_parser_class_name[::yysyntax_error_ (]dnl b4_error_verbose_if([int yystate, int yytoken], [int, int])[) - { - std::string yyres;]b4_error_verbose_if([[ - int yyn = yypact_[yystate]; - if (yypact_ninf_ < yyn && yyn <= yylast_) + {]b4_error_verbose_if([[ + std::string yyres; + // 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]; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yytoken) is + if this state is a consistent state with a default action. + Thus, detecting the absence of a lookahead is sufficient to + determine that there is no unexpected or expected token to + report. In that case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is + a consistent state with a default action. There might have + been a previous inconsistent state, consistent state with a + non-default action, or user semantic action that manipulated + yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state + merging (from LALR or IELR) and default reductions corrupt the + expected token list. However, the list is correct for + canonical LR with one exception: it will still contain any + token that will not be accepted due to an error action in a + later state. + */ + if (yytoken != yyempty_) { - /* 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])) + int yyn = yypact_[yystate]; + if (!yy_pact_value_is_default_ (yyn)) { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - break; - } - else - yyarg[yycount++] = yytname_[yyx]; + /* 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_; + 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")); + char const* yyformat = 0; + switch (yycount) + { +#define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + 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_ - } - // Argument number. - size_t yyi = 0; - for (char const* yyp = yyformat; *yyp; ++yyp) - if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount) - { - yyres += yytnamerr_ (yyarg[yyi++]); - ++yyp; - } - else - yyres += *yyp; } - else - ]])dnl -[ yyres = YY_("syntax error"); - return yyres; + + // Argument number. + size_t yyi = 0; + for (char const* yyp = yyformat; *yyp; ++yyp) + if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount) + { + yyres += yytnamerr_ (yyarg[yyi++]); + ++yyp; + } + else + yyres += *yyp; + return yyres;]], [[ + return YY_("syntax error");]])[ } @@ -1091,7 +1139,7 @@ b4_error_verbose_if([int yystate, int yytoken], dnl @output(b4_dir_prefix[]stack.hh@)@ b4_copyright([Stack handling for Bison parsers in C++], - [2002-2010])[ + [2002-2011])[ #ifndef BISON_STACK_HH # define BISON_STACK_HH