X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/678094a2f5f7cdad1b909c4265987c5301ee9540..5422d56a718805a2470558808355e04182a12d65:/data/lalr1.cc diff --git a/data/lalr1.cc b/data/lalr1.cc index 206aee99..801f5904 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -1,7 +1,6 @@ # C++ skeleton for Bison -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, -# 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 @@ -36,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, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010]) + [2002-2011]) dnl FIXME: This is wrong, we want computed header guards. [ /* C++ LALR(1) parser skeleton written by Akim Demaille. */ @@ -283,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, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010]) + [2002-2011]) b4_percent_code_get([[top]])[]dnl m4_if(b4_prefix, [yy], [], [ @@ -692,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); @@ -715,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)); } @@ -824,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. */ @@ -848,26 +870,52 @@ b4_error_verbose_if([int yystate, int yytoken], [int, int])[) {]b4_error_verbose_if([[ std::string yyres; - int yyn = yypact_[yystate]; - if (yypact_ninf_ < yyn && yyn <= yylast_) + // 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_) { + yyarg[yycount++] = yytname_[yytoken]; + int yyn = yypact_[yystate]; + if (!yy_pact_value_is_default_ (yyn)) + { /* 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])) @@ -880,6 +928,8 @@ b4_error_verbose_if([int yystate, int yytoken], else yyarg[yycount++] = yytname_[yyx]; } + } + } char const* yyformat = 0; switch (yycount) @@ -888,6 +938,7 @@ b4_error_verbose_if([int yystate, int yytoken], 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")); @@ -895,6 +946,7 @@ b4_error_verbose_if([int yystate, int yytoken], 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) @@ -905,9 +957,6 @@ b4_error_verbose_if([int yystate, int yytoken], } else yyres += *yyp; - } - else - yyres = YY_("syntax error"); return yyres;]], [[ return YY_("syntax error");]])[ } @@ -1090,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, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010])[ + [2002-2011])[ #ifndef BISON_STACK_HH # define BISON_STACK_HH