m4_divert(-1) # C++ skeleton for Bison # Copyright (C) 2002 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 # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA # 02111-1307 USA m4_include([c.m4]) # b4_lhs_value([TYPE]) # -------------------- # Expansion of $$. m4_define([b4_lhs_value], [yyval[]m4_ifval([$1], [.$1])]) # b4_rhs_value(RULE-LENGTH, NUM, [TYPE]) # -------------------------------------- # Expansion of $NUM, where the current rule has RULE-LENGTH # symbols on RHS. m4_define([b4_rhs_value], [(*(semantic_stack_.end() - m4_eval([$1 - $2 + 1])))m4_ifval([$3], [.$3])]) m4_define_default([b4_ltype], [Location]) # b4_lhs_location() # ----------------- # Expansion of @$. m4_define([b4_lhs_location], [yyloc]) # b4_rhs_location(RULE-LENGTH, NUM) # --------------------------------- # Expansion of @NUM, where the current rule has RULE-LENGTH symbols # on RHS. m4_define([b4_rhs_location], [location_stack_@<:@m4_eval([$1 - $2])@:>@]) m4_define_default([b4_input_suffix], [.y]) m4_define_default([b4_output_parser_suffix], [m4_translit(b4_input_suffix , [yY], [cC])]) m4_define_default([b4_output_parser_name], [b4_output_prefix[]b4_output _infix[]b4_output_parser_suffix[]]) m4_define_default([b4_output_header_suffix ], [m4_translit(b4_input_suffix, [yY], [hH])]) m4_define_default([b4_output_header_name], [b4_output_prefix[]b4_output _infix[]b4_output_header_suffix[]]) m4_define_default([b4_header_guard], [m4_bpatsubst(m4_toupper([BISON_]b4_output_header_name), [[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]], [_])]) m4_define([b4_inherit], [m4_ifdef([b4_root], [: public b4_root ], [])]) m4_define([b4_param], [m4_ifdef([b4_root], [, const Param& param], [])]) m4_define([b4_constructor], [m4_ifdef([b4_root], [b4_root (param), ], [])]) # b4_token_enum_defines(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER) # ------------------------------------------------------- # Output the definition of the tokens (if there are) as enums. m4_define([b4_token_enum_defines], [m4_if(address@hidden, [[]], [], [enum token_type { m4_map_sep([ b4_token_enum], [, ], address@hidden) }; ]) ]) m4_divert(0)dnl #output "b4_output_header_name" b4_copyright([C++ Skeleton parser for LALR(1) parsing with Bison], [2002]) #ifndef b4_header_guard # define b4_header_guard #include #include #include /* Using locations. */ #define YYLSP_NEEDED b4_locations_flag #if YYLSP_NEEDED #include "location.hh" #endif // Line __line__ of __file__. #line __oline__ "__ofile__" namespace b4_prefix { // Tokens: b4_token_enum_defines(b4_tokens) } // namespace b4_prefix // Copy the first part of user declarations to the C++ header file: b4_pre_prologue // Enabling traces: #ifndef YYDEBUG # define YYDEBUG b4_debug #endif // Enabling verbose error message: #ifndef YYERROR_VERBOSE # define YYERROR_VERBOSE b4_error_verbose #endif #ifndef YYSTYPE m4_ifdef([b4_stype], [#line b4_stype_line "b4_filename" typedef union b4_stype yystype; // Line __line__ of __file__. #line __oline__ "__ofile__"], [typedef int yystype;]) # define YYSTYPE yystype #endif // Line __line__ of __file__. #line __oline__ "__ofile__" #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ Current.last_line = Rhs[[N]].last_line; \ Current.last_column = Rhs[[N]].last_column; #endif namespace b4_prefix { class parser; struct parser_traits { typedef b4_int_type_for([b4_translate]) token_type; typedef b4_int_type_for([b4_rhs]) rhs_type; typedef int state_type; typedef YYSTYPE semantic_type; #if YYLSP_NEEDED typedef b4_ltype location_type; #endif }; } // namespace b4_prefix namespace b4_prefix { // template class parser b4_inherit { public: typedef parser_traits::token_type token_type; typedef parser_traits::rhs_type rhs_type; typedef parser_traits::state_type state_type; typedef parser_traits::semantic_type semantic_type; #if YYLSP_NEEDED typedef parser_traits::location_type location_type; #endif struct value_type { state_type state_; semantic_type semantic_; #if YYLSP_NEEDED location_type location_; #endif }; typedef std::vector stack_type; typedef std::vector state_stack; typedef std::vector semantic_stack; #if YYLSP_NEEDED typedef std::vector location_stack; #endif parser(bool debug = false[]b4_param) : b4_constructor[]isp_(&std::cin), osp_(&std::cout), error_osp_(&std::cerr), do_debug_(debug), debug_osp_(&std::clog), lexer_(&std::cin, &std::cout) {} // p = value produced by parse // s = current $$, l = current @$. #if !YYLSP_NEEDED int parse(parse_type& p, semantic_type& s = semantic_type()); #else int parse(parse_type& p, semantic_type& s = semantic_type(), location_type& l = location_type()); #endif std::istream& operator>>(parse_type& d); friend parser& operator>>(std::istream&, parser&); friend std::istream& operator>>(std::istream&, parse_type&); protected: lexer_type lexer_; void lex_(); #if 0 void error_(); void print_(); #endif void yyerror(const std::string& errstr); private: // Stacks: state_stack state_stack_; semantic_stack semantic_stack_; #if YYLSP_NEEDED location_stack location_stack_; #endif // Parsing tables: static const b4_int_type_for([b4_pact]) pact_[[]]; static const b4_int_type_for([b4_pact]) pact_ninf_; static const b4_int_type_for([b4_defact]) defact_[[]]; static const b4_int_type_for([b4_pgoto]) pgoto_[[]]; static const b4_int_type_for([b4_defgoto]) defgoto_[[]]; static const b4_int_type_for([b4_table]) table_[[]]; static const b4_int_type_for([b4_table]) table_ninf_; static const b4_int_type_for([b4_check]) check_[[]]; static const b4_int_type_for([b4_r1]) r1_[[]]; static const b4_int_type_for([b4_r2]) r2_[[]]; #if YYDEBUG || YYERROR_VERBOSE static const char* const name_[[]]; #endif // Tables for debugging: #if YYDEBUG static const rhs_type rhs_[[]]; static const b4_int_type_for([b4_prhs]) prhs_[[]]; static const b4_int_type_for([b4_rline]) rline_[[]]; static const b4_int_type_for([b4_stos]) stos_[[]]; static const b4_int_type_for([b4_toknum]) token_number_[[]]; #endif // Even more tables: static inline token_type translate_(int token); // Constants: static const int eof_; static const int last_; static const int nnts_; static const int empty_; static const int final_; static const int terror_; static const int errcode_; static const int ntokens_; static const int initdepth_; static const unsigned user_token_number_max_; static const token_type undef_token_; // State: int state_; // Current state. int n_; // What to do: if < 0, negative of rule; if >= 0, a state. int rule_length_; // Rule length. std::istream* isp_; // Input stream; forwarded to the lexer; default std::cin. std::ostream* osp_; // Output stream; default std::cout. std::ostream* error_osp_; // Error output stream; default std::cerr. // Debugging: bool do_debug_; std::ostream* debug_osp_; // Debug output stream; default std::clog. // Lookahead and lookahead in internal form: int lookahead_; int ilooka_; // Message: std::string message; // Semantic value and location of lookahead token. semantic_type lookahead_value_; #if YYLSP_NEEDED location_type lookahead_location_; #endif }; inline parser& operator>>(std::istream& ist, parser& p) { p.isp_ = &ist; return p; } inline std::istream& operator>>(std::istream& is, parse_type& x) { is >> parser() >> x; return is; } } // namespace b4_prefix #endif /* not b4_header_guard */ dnl #output "b4_output_prefix[]b4_output_infix[].cc" b4_copyright([C++ Skeleton parser for LALR(1) parsing with Bison], [2002]) #include "b4_output_header_name" // Copy the second part of user declarations to the C++ source file: b4_post_prologue // Enable debugging if requested. #if YYDEBUG # define YYCDEBUG if (do_debug_) (*debug_osp_) #else // !YYDEBUG # define YYCDEBUG if (0) (*debug_osp_) #endif // !YYDEBUG #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY -2 #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrlab1 /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yychar1 = YYTRANSLATE (yychar); \ YYPOPSTACK; \ goto yybackup; \ } \ else \ { \ yyerror("syntax error: cannot back up"); \ YYERROR; \ } \ while (0) #define YYTERROR 1 #define YYERRCODE 256 #if !YYLSP_NEEDED int b4_prefix::parser::parse(parse_type& yypval, semantic_type& yyval) #else int b4_prefix::parser::parse(parse_type& yypval, semantic_type& yyval, location_type& yyloc) #endif { int nerrs = 0; int errstatus = 0; // Initialize stack: state_stack_ = state_stack(0); semantic_stack_ = semantic_stack(1); #if YYLSP_NEEDED location_stack_ = location_stack(1); #endif // Start: state_ = 0; lookahead_ = empty_; YYCDEBUG << "Starting parse" << std::endl; // New state. yynewstate: state_stack_.push_back(state_); YYCDEBUG << "Entering state " << state_ << std::endl; goto yybackup; // Backup. yybackup: // Try to make a decision without lookahead: n_ = pact_[[state_]]; if (n_ == pact_ninf_) goto yydefault; // Read a lookahead token. if (lookahead_ == empty_) { YYCDEBUG << "Reading a token: "; lex_(); } // Convert token to internal form. if (lookahead_ <= 0) { lookahead_ = eof_; ilooka_ = 0; YYCDEBUG << "Now at end of input." << std::endl; } else { ilooka_ = translate_(lookahead_); #if YYDEBUG if (do_debug_) { YYCDEBUG << "Next token is " << lookahead_ << " (" << name_[[ilooka_]]; #if 0 print_(); #endif YYCDEBUG << ')' << std::endl; } #endif } n_ += ilooka_; if (n_ < 0 || n_ > last_ || check_[[n_]] != ilooka_) goto yydefault; // Reduce or error. n_ = table_[[n_]]; if (n_ < 0) { if (n_ == table_ninf_) goto yyerrlab; else { n_ = -n_; goto yyreduce; } } else if (n_ == 0) goto yyerrlab; // Accept? if (n_ == final_) goto yyacceptlab; // Shift the lookahead token: YYCDEBUG << "Shifting token " << lookahead_ << " (" << name_[[ilooka_]] << "), "; // Discard the token being shifted unless it is eof: if (lookahead_ != eof_) lookahead_ = empty_; semantic_stack_.push_back(lookahead_value_); #if YYLSP_NEEDED location_stack_.push_back(lookahead_location_); #endif /* Count tokens shifted since error; after three, turn off error status. */ if (errstatus) --errstatus; state_ = n_; goto yynewstate; // Default action. yydefault: n_ = defact_[[state_]]; if (n_ == 0) goto yyerrlab; goto yyreduce; // Reduce. yyreduce: rule_length_ = r2_[[n_]]; #if YYDEBUG if (do_debug_) { YYCDEBUG << "Reducing via rule " << n_ - 1 << " (line " << rline_[[n_]] << "), "; for (b4_int_type_for([b4_prhs]) i = prhs_[[n_]]; rhs_[[i]] >= 0; ++i) YYCDEBUG < " << name_[[r1_[n_]]] << std::endl; } #endif #if YYLSP_NEEDED if (rule_length_) { Slice slice(location_stack_, rule_length_); YYLLOC_DEFAULT(yyloc, slice, rule_length_); } #endif switch (n_) { default: // Action default value: // When rule length > 0: $$ = $1. // When rule length = 0, $$ = semantic_type() (initialization value). if (rule_length_ > 0) { yyval = *(semantic_stack_.end() - rule_length_ + 1); #if YYLSP_NEEDED yyloc = *(location_stack_.end() - rule_length_ + 1); #endif } else { yyval = semantic_type(); #if YYLSP_NEEDED yyloc = location_type(); #endif } break; b4_actions } // Line __line__ of __file__. #line __oline__ "__ofile__" state_stack_.erase(state_stack_.end() - rule_length_, state_stack_.end()); semantic_stack_.erase(semantic_stack_.end() - rule_length_, semantic_stack_.end()); #if YYLSP_NEEDED location_stack_.erase(location_stack_.end() - rule_length_, location_stack_.end()); #endif #if YYDEBUG if (do_debug_) { YYCDEBUG << "state stack now"; for (state_stack::const_iterator i = state_stack_.begin(); i != state_stack_.end(); ++i) YYCDEBUG << ' ' << *i; YYCDEBUG << std::endl; } #endif semantic_stack_.push_back(yyval); #if YYLSP_NEEDED location_stack_.push_back(yyloc); #endif // Shift the result of the reduction. n_ = r1_[[n_]]; state_ = pgoto_[[n_ - ntokens_]] + state_stack_.back(); if (state_ >= 0 && state_ <= last_ && check_[[state_]] == state_stack_.back()) state_ = table_[[state_]]; else state_ = defgoto_[[n_ - ntokens_]]; goto yynewstate; // Report and recover from errors. This is very incomplete. yyerrlab: // If not already recovering from an error, report this error. if (!errstatus) { ++nerrs; #if YYERROR_VERBOSE n_ = pact_[[state_]]; if (pact_ninf_ < n_ && n_ < last_) { message = "parse error, unexpected "; message += name_[[ilooka_]]; int count = 0; for (int x = (n_ < 0 ? -n_ : 0); x < ntokens_ + nnts_; ++x) if (check_[[x + n_]] == x && x != terror_) ++count; if (count < 5) { count = 0; for (int x = (n_ < 0 ? -n_ : 0); x < ntokens_ + nnts_; ++x) if (check_[[x + n_]] == x && x != terror_) { message += (!count++) ? ", expecting " : " or "; message += name_[[x]]; } } } else #endif message = "parse error"; #if 1 yyerror(message); #else error_(); #endif } goto yyerrlab1; // Error raised explicitly by an action. yyerrlab1: if (errstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ /* Return failure if at end of input. */ if (lookahead_ == eof_) goto yyabortlab; YYCDEBUG << "Discarding token " << lookahead_ << " (" << name_[[ilooka_]] << ")." << std::endl; lookahead_ = empty_; } /* Else will try to reuse lookahead token after shifting the error token. */ errstatus = 3; for (;;) { n_ = pact_[[state_]]; if (n_ != pact_ninf_) { n_ += terror_; if (0 <= n_ && n_ <= last_ && check_[[n_]] == terror_) { n_ = table_[[n_]]; if (0 < n_) break; } } /* Pop the current state because it cannot handle the error token. */ if (state_stack_.empty()) goto yyabortlab; #if YYDEBUG if (do_debug_) { if (stos_[[state_]] < ntokens_) { YYCDEBUG << "Error: popping token " << token_number_[[stos_[state_]]] << " (" << name_[[stos_[state_]]]; # ifdef YYPRINT YYPRINT(stderr, token_number_[[stos_[state_]]], semantic_stack_.top()); # endif YYCDEBUG << ')' << std::endl; } else { YYCDEBUG << "Error: popping nonterminal (" << name_[[stos_[state_]]] << ')' << std::endl; } } #endif state_ = (state_stack_.pop_back(), state_stack_.back()); semantic_stack_.pop_back(); #if YYLSP_NEEDED location_stack_.pop_back(); #endif #if YYDEBUG if (do_debug_) { YYCDEBUG << "Error: state stack now"; for (state_stack::const_iterator i = state_stack_.begin(); i != state_stack_.end(); ++i) YYCDEBUG << ' ' << *i; YYCDEBUG << std::endl; } #endif } if (n_ == final_) goto yyacceptlab; YYCDEBUG << "Shifting error token, "; semantic_stack_.push_back(lookahead_value_); #if YYLSP_NEEDED location_stack_.push_back(lookahead_location_); #endif state_ = n_; goto yynewstate; // Accept. yyacceptlab: return 0; // Abort. yyabortlab: return 1; } std::istream& b4_prefix::parser::operator>>(parse_type& x) { lexer_.initialize(isp_); if (parse(x) != 0) isp_->setstate(std::ios::failbit); else isp_->clear(isp_->rdstate() & ~(std::ios::failbit | std::ios::badbit)); return *isp_; } void b4_prefix::parser::lex_() { #if !YYLSP_NEEDED lookahead_ = lexer_.lex(lookahead_value_); #else lookahead_ = lexer_.lex(lookahead_value_, lookahead_location_); #endif } /* YYPACT[[STATE-NUM]] -- Index in YYTABLE of the portion describing STATE-NUM. */ const b4_int_type_for([b4_pact]) b4_prefix::parser::pact_ninf_ = b4_pact_ninf; const b4_int_type_for([b4_pact]) b4_prefix::parser::pact_[[]] = { b4_pact }; /* YYDEFACT[[S]] -- default rule to reduce with in state S when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ const b4_int_type_for([b4_defact]) b4_prefix::parser::defact_[[]] = { b4_defact }; /* YYPGOTO[[NTERM-NUM]]. */ const b4_int_type_for([b4_pgoto]) b4_prefix::parser::pgoto_[[]] = { b4_pgoto }; /* YYDEFGOTO[[NTERM-NUM]]. */ const b4_int_type_for([b4_defgoto]) b4_prefix::parser::defgoto_[[]] = { b4_defgoto }; /* YYTABLE[[YYPACT[STATE-NUM]]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. */ const b4_int_type_for([b4_table]) b4_prefix::parser::table_ninf_ = b4_table_ninf; const b4_int_type_for([b4_table]) b4_prefix::parser::table_[[]] = { b4_table }; /* YYCHECK. */ const b4_int_type_for([b4_check]) b4_prefix::parser::check_[[]] = { b4_check }; #if YYDEBUG /* STOS_[[STATE-NUM]] -- The (internal number of the) accessing symbol of state STATE-NUM. */ const b4_int_type_for([b4_stos]) b4_prefix::parser::stos_[[]] = { b4_stos }; /* TOKEN_NUMBER_[[YYLEX-NUM]] -- Internal token number corresponding to YYLEX-NUM. */ const b4_int_type_for([b4_toknum]) b4_prefix::parser::token_number_[[]] = { b4_toknum }; #endif /* YYR1[[YYN]] -- Symbol number of symbol that rule YYN derives. */ const b4_int_type_for([b4_r1]) b4_prefix::parser::r1_[[]] = { b4_r1 }; /* YYR2[[YYN]] -- Number of symbols composing right hand side of rule YYN. */ const b4_int_type_for([b4_r2]) b4_prefix::parser::r2_[[]] = { b4_r2 }; #if YYDEBUG || YYERROR_VERBOSE /* YYTNAME[[SYMBOL-NUM]] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ const char* const b4_prefix::parser::name_[[]] = { b4_tname }; #endif #if YYDEBUG /* YYRHS -- A `-1'-separated list of the rules' RHS. */ const b4_prefix::parser::rhs_type b4_prefix::parser::rhs_[[]] = { b4_rhs }; /* YYPRHS[[YYN]] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ const b4_int_type_for([b4_prhs]) b4_prefix::parser::prhs_[[]] = { b4_prhs }; /* YYRLINE[[YYN]] -- source line where rule number YYN was defined. */ const b4_int_type_for([b4_rline]) b4_prefix::parser::rline_[[]] = { b4_rline }; #endif /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ b4_prefix::parser::token_type b4_prefix::parser::translate_(int token) { static const token_type translate_[[]] = { b4_translate }; if ((unsigned) token <= user_token_number_max_) return translate_[[token]]; else return undef_token_; } const int b4_prefix::parser::eof_ = 0; const int b4_prefix::parser::last_ = b4_last; const int b4_prefix::parser::nnts_ = b4_nterms_number; const int b4_prefix::parser::empty_ =-2; const int b4_prefix::parser::final_ = b4_final_state_number; const int b4_prefix::parser::terror_ = 1; const int b4_prefix::parser::errcode_ = 256; const int b4_prefix::parser::ntokens_ = b4_tokens_number; const int b4_prefix::parser::initdepth_ = b4_initdepth; const unsigned b4_prefix::parser::user_token_number_max_ = b4_user_token_number_max; const b4_prefix::parser::token_type b4_prefix::parser::undef_token_ = b4_undef_token_number; b4_epilogue dnl #output "location.hh" b4_copyright([2002]) #ifndef BISON_LOCATION_HH # define BISON_LOCATION_HH namespace b4_prefix { struct Position { int line; int column; }; struct Location { Position first; Position last; }; } #endif // not BISON_LOCATION_HH