]>
git.saurik.com Git - bison.git/blob - data/glr.cc
   1 # C++ GLR skeleton for Bison 
   3 # Copyright (C) 2002-2012 Free Software Foundation, Inc. 
   5 # This program is free software: you can redistribute it and/or modify 
   6 # it under the terms of the GNU General Public License as published by 
   7 # the Free Software Foundation, either version 3 of the License, or 
   8 # (at your option) any later version. 
  10 # This program is distributed in the hope that it will be useful, 
  11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  13 # GNU General Public License for more details. 
  15 # You should have received a copy of the GNU General Public License 
  16 # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  19 # This skeleton produces a C++ class that encapsulates a C glr parser. 
  20 # This is in order to reduce the maintenance burden.  The glr.c 
  21 # skeleton is clean and pure enough so that there are no real 
  22 # problems.  The C++ interface is the same as that of lalr1.cc.  In 
  23 # fact, glr.c can replace yacc.c without the user noticing any 
  24 # difference, and similarly for glr.cc replacing lalr1.cc. 
  26 # The passing of parse-params 
  28 #   The additional arguments are stored as members of the parser 
  29 #   object, yyparser.  The C routines need to carry yyparser 
  30 #   throughout the C parser; that's easy: make yyparser an 
  31 #   additional parse-param.  But because the C++ skeleton needs to 
  32 #   know the "real" original parse-param, we save them 
  33 #   (b4_parse_param_orig).  Note that b4_parse_param is overquoted 
  34 #   (and c.m4 strips one level of quotes).  This is a PITA, and 
  35 #   explains why there are so many levels of quotes. 
  39 #   We use location.cc just like lalr1.cc, but because glr.c stores 
  40 #   the locations in a union, the position and location classes 
  41 #   must not have a constructor.  Therefore, contrary to lalr1.cc, we 
  42 #   must not define "b4_location_constructors".  As a consequence the 
  43 #   user must initialize the first positions (in particular the 
  46 b4_token_ctor_if([b4_variant_if([], 
  47   [b4_fatal_at(b4_percent_define_get_loc(api.token.constructor), 
  48                [cannot use '%s' without '%s'], 
  49                [%define api.token.constructor], 
  50                [%define api.value.type variant]))])]) 
  52 # We require a pure interface. 
  53 m4_define([b4_pure_flag],      [1]) 
  55 m4_include(b4_pkgdatadir/[c++.m4]) 
  56 b4_bison_locations_if([m4_include(b4_pkgdatadir/[location.cc])]) 
  58 m4_define([b4_parser_class_name], 
  59           [b4_percent_define_get([[parser_class_name]])]) 
  61 # Save the parse parameters. 
  62 m4_define([b4_parse_param_orig], m4_defn([b4_parse_param])) 
  67 m4_ifset([b4_parse_param], 
  68 [m4_define([b4_parse_param_wrap], 
  69            [[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]],] 
  70 m4_defn([b4_parse_param]))], 
  71 [m4_define([b4_parse_param_wrap], 
  72            [[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]]]) 
  76 # b4_yy_symbol_print_define 
  77 # ------------------------- 
  78 # Bypass the default implementation to generate the "yy_symbol_print" 
  79 # and "yy_symbol_value_print" functions. 
  80 m4_define([b4_yy_symbol_print_define], 
  82 /*--------------------. 
  83 | Print this symbol.  | 
  84 `--------------------*/ 
  86 ]b4_function_define([yy_symbol_print], 
  89     [[int yytype],  [yytype]], 
  90     [[const ]b4_namespace_ref::b4_parser_class_name[::semantic_type *yyvaluep], 
  93     [[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp], 
  97 ]b4_parse_param_use[]dnl 
  98 [  yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_locations_if([, yylocationp])[); 
 102 # Hijack the initial action to initialize the locations. 
 103 ]b4_bison_locations_if([m4_define([b4_initial_action], 
 104 [yylloc.initialize ();]m4_ifdef([b4_initial_action], [ 
 105 m4_defn([b4_initial_action])]))])[ 
 107 # Hijack the post prologue to insert early definition of YYLLOC_DEFAULT 
 108 # and declaration of yyerror. 
 109 ]m4_append([b4_post_prologue], 
 110 [b4_syncline([@oline@], [@ofile@])[ 
 111 ]b4_yylloc_default_define[ 
 112 #define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc) 
 113 ]b4_function_declare([yyerror], 
 114     [static void],b4_locations_if([ 
 115     [[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp], 
 118     [[const char* msg], [msg]])]) 
 123 #undef yylval]b4_locations_if([ 
 126 m4_if(b4_prefix, [yy], [], 
 127 [[/* Substitute the variable and function names.  */ 
 128 #define yyparse ]b4_prefix[parse 
 129 #define yylex   ]b4_prefix[lex 
 130 #define yyerror ]b4_prefix[error 
 131 #define yydebug ]b4_prefix[debug 
 133 #define yylval  ]b4_prefix[lval 
 134 #define yychar  ]b4_prefix[char 
 135 #define yynerrs ]b4_prefix[nerrs]b4_locations_if([[ 
 136 #define yylloc  ]b4_prefix[lloc]])])) 
 138 # Hijack the epilogue to define implementations (yyerror, parser member 
 140 m4_append([b4_epilogue], 
 141 [b4_syncline([@oline@], [@ofile@])[ 
 143 /*------------------. 
 145 `------------------*/ 
 147 ]b4_function_define([yyerror], 
 148     [static void],b4_locations_if([ 
 149     [[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp], 
 152     [[const char* msg], [msg]])[ 
 154 ]b4_parse_param_use[]dnl 
 155 [  yyparser.error (]b4_locations_if([[*yylocationp, ]])[msg); 
 160 ]dnl In this section, the parse params are the original parse_params. 
 161 m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl 
 162 [  /// Build a parser object. 
 163   ]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [ 
 165 #if ]b4_api_PREFIX[DEBUG 
 166     ]m4_ifset([b4_parse_param], [  ], [ :])[yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[ 
 167 #endif]b4_parse_param_cons[ 
 171   ]b4_parser_class_name::~b4_parser_class_name[ () 
 176   ]b4_parser_class_name[::parse () 
 178     return ::yyparse (*this]b4_user_args[); 
 181 #if ]b4_api_PREFIX[DEBUG 
 182   /*--------------------. 
 183   | Print this symbol.  | 
 184   `--------------------*/ 
 187   ]b4_parser_class_name[::yy_symbol_value_print_ (int yytype, 
 188                            const semantic_type* yyvaluep]b4_locations_if([[, 
 189                            const location_type* yylocationp]])[) 
 191     YYUSE (yylocationp);]])[ 
 193     std::ostream& yyoutput = debug_stream (); 
 194     std::ostream& yyo = yyoutput; 
 198 ]b4_symbol_foreach([b4_symbol_printer])dnl 
 206   ]b4_parser_class_name[::yy_symbol_print_ (int yytype, 
 207                            const semantic_type* yyvaluep]b4_locations_if([[, 
 208                            const location_type* yylocationp]])[) 
 210     *yycdebug_ << (yytype < YYNTOKENS ? "token" : "nterm") 
 211                << ' ' << yytname[yytype] << " ("]b4_locations_if([[ 
 212                << *yylocationp << ": "]])[; 
 213     yy_symbol_value_print_ (yytype, yyvaluep]b4_locations_if([[, yylocationp]])[); 
 218   ]b4_parser_class_name[::debug_stream () const 
 224   ]b4_parser_class_name[::set_debug_stream (std::ostream& o) 
 230   ]b4_parser_class_name[::debug_level_type 
 231   ]b4_parser_class_name[::debug_level () const 
 237   ]b4_parser_class_name[::set_debug_level (debug_level_type l) 
 239     // Actually, it is yydebug which is really used. 
 244 ]m4_popdef([b4_parse_param])dnl 
 248 # b4_shared_declarations 
 249 # ---------------------- 
 250 # Declaration that might either go into the header (if --defines) 
 251 # or open coded in the parser body. 
 252 m4_define([b4_shared_declarations], 
 253 [m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl 
 254 b4_percent_code_get([[requires]])[ 
 258 #include <iostream>]b4_defines_if([ 
 259 b4_bison_locations_if([[#include "location.hh"]])])[ 
 265 [b4_bison_locations_if([b4_position_define 
 266 b4_location_define])])[ 
 269   class ]b4_parser_class_name[ 
 272 ]b4_public_types_declare[ 
 274     /// Build a parser object. 
 275     ]b4_parser_class_name[ (]b4_parse_param_decl[); 
 276     virtual ~]b4_parser_class_name[ (); 
 279     /// \returns  0 iff parsing succeeded. 
 280     virtual int parse (); 
 282     /// The current debugging stream. 
 283     std::ostream& debug_stream () const; 
 284     /// Set the current debugging stream. 
 285     void set_debug_stream (std::ostream &); 
 287     /// Type for debugging levels. 
 288     typedef int debug_level_type; 
 289     /// The current debugging level. 
 290     debug_level_type debug_level () const; 
 291     /// Set the current debugging level. 
 292     void set_debug_level (debug_level_type l); 
 295     /// Report a syntax error.]b4_locations_if([[ 
 296     /// \param loc    where the syntax error is found.]])[ 
 297     /// \param msg    a description of the syntax error. 
 298     virtual void error (]b4_locations_if([[const location_type& loc, ]])[const std::string& msg); 
 300 # if ]b4_api_PREFIX[DEBUG 
 302     /// \brief Report a symbol value on the debug stream. 
 303     /// \param yytype       The token type. 
 304     /// \param yyvaluep     Its semantic value.]b4_locations_if([[ 
 305     /// \param yylocationp  Its location.]])[ 
 306     virtual void yy_symbol_value_print_ (int yytype, 
 307                                          const semantic_type* yyvaluep]b4_locations_if([[, 
 308                                          const location_type* yylocationp]])[); 
 309     /// \brief Report a symbol on the debug stream. 
 310     /// \param yytype       The token type. 
 311     /// \param yyvaluep     Its semantic value.]b4_locations_if([[ 
 312     /// \param yylocationp  Its location.]])[ 
 313     virtual void yy_symbol_print_ (int yytype, 
 314                                    const semantic_type* yyvaluep]b4_locations_if([[, 
 315                                    const location_type* yylocationp]])[); 
 318     std::ostream* yycdebug_; 
 321 ]b4_parse_param_vars[ 
 324 ]dnl Redirections for glr.c. 
 325 b4_percent_define_flag_if([[global_tokens_and_yystype]], 
 328 #ifndef ]b4_api_PREFIX[STYPE 
 329 # define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class_name[::semantic_type 
 331 #ifndef ]b4_api_PREFIX[LTYPE 
 332 # define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class_name[::location_type 
 336 ]b4_percent_code_get([[provides]])[ 
 337 ]m4_popdef([b4_parse_param])dnl 
 341 [b4_output_begin([b4_spec_defines_file]) 
 342 b4_copyright([Skeleton interface for Bison GLR parsers in C++], 
 345 // C++ GLR parser skeleton written by Akim Demaille. 
 347 ]b4_cpp_guard_open([b4_spec_defines_file])[ 
 348 ]b4_shared_declarations[ 
 349 ]b4_cpp_guard_close([b4_spec_defines_file])[ 
 352 # Let glr.c (and b4_shared_declarations) believe that the user 
 353 # arguments include the parser itself. 
 354 m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_wrap])) 
 355 m4_include(b4_pkgdatadir/[glr.c]) 
 356 m4_popdef([b4_parse_param])