Home | History | Annotate | Download | only in data
      1                                                                     -*- C -*-
      2 
      3 # C++ GLR skeleton for Bison
      4 
      5 # Copyright (C) 2002-2012 Free Software Foundation, Inc.
      6 
      7 # This program is free software: you can redistribute it and/or modify
      8 # it under the terms of the GNU General Public License as published by
      9 # the Free Software Foundation, either version 3 of the License, or
     10 # (at your option) any later version.
     11 #
     12 # This program is distributed in the hope that it will be useful,
     13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 # GNU General Public License for more details.
     16 #
     17 # You should have received a copy of the GNU General Public License
     18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     19 
     20 
     21 # This skeleton produces a C++ class that encapsulates a C glr parser.
     22 # This is in order to reduce the maintenance burden.  The glr.c
     23 # skeleton is clean and pure enough so that there are no real
     24 # problems.  The C++ interface is the same as that of lalr1.cc.  In
     25 # fact, glr.c can replace yacc.c without the user noticing any
     26 # difference, and similarly for glr.cc replacing lalr1.cc.
     27 #
     28 # The passing of parse-params
     29 #
     30 #   The additional arguments are stored as members of the parser
     31 #   object, yyparser.  The C routines need to carry yyparser
     32 #   throughout the C parser; that easy: just let yyparser become an
     33 #   additional parse-param.  But because the C++ skeleton needs to
     34 #   know the "real" original parse-param, we save them
     35 #   (b4_parse_param_orig).  Note that b4_parse_param is overquoted
     36 #   (and c.m4 strips one level of quotes).  This is a PITA, and
     37 #   explains why there are so many levels of quotes.
     38 #
     39 # The locations
     40 #
     41 #   We use location.cc just like lalr1.cc, but because glr.c stores
     42 #   the locations in a (C++) union, the position and location classes
     43 #   must not have a constructor.  Therefore, contrary to lalr1.cc, we
     44 #   must not define "b4_location_constructors".  As a consequence the
     45 #   user must initialize the first positions (in particular the
     46 #   filename member).
     47 
     48 # We require a pure interface using locations.
     49 m4_define([b4_locations_flag], [1])
     50 m4_define([b4_pure_flag],      [1])
     51 
     52 # The header is mandatory.
     53 b4_defines_if([],
     54               [b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
     55 
     56 m4_include(b4_pkgdatadir/[c++.m4])
     57 b4_percent_define_ifdef([[api.location.type]], [],
     58                         [m4_include(b4_pkgdatadir/[location.cc])])
     59 
     60 m4_define([b4_parser_class_name],
     61           [b4_percent_define_get([[parser_class_name]])])
     62 
     63 # Save the parse parameters.
     64 m4_define([b4_parse_param_orig], m4_defn([b4_parse_param]))
     65 
     66 
     67 # b4_yy_symbol_print_generate
     68 # ---------------------------
     69 # Bypass the default implementation to generate the "yy_symbol_print"
     70 # and "yy_symbol_value_print" functions.
     71 m4_define([b4_yy_symbol_print_generate],
     72 [[
     73 /*--------------------.
     74 | Print this symbol.  |
     75 `--------------------*/
     76 
     77 ]b4_c_ansi_function_def([yy_symbol_print],
     78     [static void],
     79     [[FILE *],               []],
     80     [[int yytype],           [yytype]],
     81     [[const ]b4_namespace_ref::b4_parser_class_name[::semantic_type *yyvaluep],
     82                              [yyvaluep]],
     83     [[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp],
     84                              [yylocationp]],
     85     b4_parse_param)[
     86 {
     87 ]b4_parse_param_use[]dnl
     88 [  yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_locations_if([, yylocationp])[);
     89 }
     90 ]])[
     91 
     92 # Hijack the initial action to initialize the locations.
     93 ]b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
     94 [m4_define([b4_initial_action],
     95 [yylloc.initialize ();]m4_ifdef([b4_initial_action], [
     96 m4_defn([b4_initial_action])]))])])[
     97 
     98 # Hijack the post prologue to insert early definition of YYLLOC_DEFAULT
     99 # and declaration of yyerror.
    100 ]m4_append([b4_post_prologue],
    101 [b4_syncline([@oline@], [@ofile@])[
    102 ]b4_yylloc_default_define[
    103 #define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
    104 ]b4_c_ansi_function_decl([yyerror],
    105     [static void],
    106     [[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp],
    107                         [yylocationp]],
    108     b4_parse_param,
    109     [[const char* msg], [msg]])])
    110 
    111 
    112 # Hijack the epilogue to define implementations (yyerror, parser member
    113 # functions etc.).
    114 m4_append([b4_epilogue],
    115 [b4_syncline([@oline@], [@ofile@])[
    116 /*------------------.
    117 | Report an error.  |
    118 `------------------*/
    119 
    120 ]b4_c_ansi_function_def([yyerror],
    121     [static void],
    122     [[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp],
    123                         [yylocationp]],
    124     b4_parse_param,
    125     [[const char* msg], [msg]])[
    126 {
    127 ]b4_parse_param_use[]dnl
    128 [  yyparser.error (*yylocationp, msg);
    129 }
    130 
    131 
    132 ]b4_namespace_open[
    133 ]dnl In this section, the parse param are the original parse_params.
    134 m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
    135 [  /// Build a parser object.
    136   ]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
    137     :])[
    138 #if ]b4_api_PREFIX[DEBUG
    139     ]m4_ifset([b4_parse_param], [  ], [ :])[
    140       yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
    141 #endif]b4_parse_param_cons[
    142   {
    143   }
    144 
    145   ]b4_parser_class_name::~b4_parser_class_name[ ()
    146   {
    147   }
    148 
    149   int
    150   ]b4_parser_class_name[::parse ()
    151   {
    152     return ::yyparse (*this]b4_user_args[);
    153   }
    154 
    155 #if ]b4_api_PREFIX[DEBUG
    156   /*--------------------.
    157   | Print this symbol.  |
    158   `--------------------*/
    159 
    160   inline void
    161   ]b4_parser_class_name[::yy_symbol_value_print_ (int yytype,
    162                            const semantic_type* yyvaluep,
    163                            const location_type* yylocationp)
    164   {
    165     YYUSE (yylocationp);
    166     YYUSE (yyvaluep);
    167     std::ostream& yyoutput = debug_stream ();
    168     std::ostream& yyo = yyoutput;
    169     YYUSE (yyo);
    170     switch (yytype)
    171       {
    172   ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl
    173 [        default:
    174           break;
    175       }
    176   }
    177 
    178 
    179   void
    180   ]b4_parser_class_name[::yy_symbol_print_ (int yytype,
    181                            const semantic_type* yyvaluep,
    182                            const location_type* yylocationp)
    183   {
    184     *yycdebug_ << (yytype < YYNTOKENS ? "token" : "nterm")
    185                << ' ' << yytname[yytype] << " ("
    186                << *yylocationp << ": ";
    187     yy_symbol_value_print_ (yytype, yyvaluep, yylocationp);
    188     *yycdebug_ << ')';
    189   }
    190 
    191   std::ostream&
    192   ]b4_parser_class_name[::debug_stream () const
    193   {
    194     return *yycdebug_;
    195   }
    196 
    197   void
    198   ]b4_parser_class_name[::set_debug_stream (std::ostream& o)
    199   {
    200     yycdebug_ = &o;
    201   }
    202 
    203 
    204   ]b4_parser_class_name[::debug_level_type
    205   ]b4_parser_class_name[::debug_level () const
    206   {
    207     return yydebug;
    208   }
    209 
    210   void
    211   ]b4_parser_class_name[::set_debug_level (debug_level_type l)
    212   {
    213     // Actually, it is yydebug which is really used.
    214     yydebug = l;
    215   }
    216 
    217 #endif
    218 ]m4_popdef([b4_parse_param])dnl
    219 b4_namespace_close])
    220 
    221 
    222 # Let glr.c believe that the user arguments include the parser itself.
    223 m4_ifset([b4_parse_param],
    224 [m4_pushdef([b4_parse_param],
    225             [[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]],]
    226 m4_defn([b4_parse_param]))],
    227 [m4_pushdef([b4_parse_param],
    228             [[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]]])
    229 ])
    230 m4_include(b4_pkgdatadir/[glr.c])
    231 m4_popdef([b4_parse_param])
    232 
    233 b4_output_begin([b4_spec_defines_file])
    234 b4_copyright([Skeleton interface for Bison GLR parsers in C++],
    235              [2002-2006, 2009-2012])[
    236 
    237 /* C++ GLR parser skeleton written by Akim Demaille.  */
    238 
    239 ]b4_cpp_guard_open([b4_spec_defines_file])[
    240 
    241 ]b4_percent_code_get([[requires]])[
    242 
    243 # include <string>
    244 # include <iostream>
    245 ]b4_percent_define_ifdef([[api.location.type]], [],
    246                          [[# include "location.hh"]])[
    247 
    248 ]b4_YYDEBUG_define[
    249 
    250 ]b4_namespace_open[
    251   /// A Bison parser.
    252   class ]b4_parser_class_name[
    253   {
    254   public:
    255     /// Symbol semantic values.
    256 # ifndef ]b4_api_PREFIX[STYPE
    257 ]m4_ifdef([b4_stype],
    258 [    union semantic_type
    259     {
    260 b4_user_stype
    261     };],
    262 [m4_if(b4_tag_seen_flag, 0,
    263 [[    typedef int semantic_type;]],
    264 [[    typedef ]b4_api_PREFIX[STYPE semantic_type;]])])[
    265 # else
    266     typedef ]b4_api_PREFIX[STYPE semantic_type;
    267 # endif
    268     /// Symbol locations.
    269     typedef ]b4_percent_define_get([[api.location.type]],
    270                                    [[location]])[ location_type;
    271     /// Tokens.
    272     struct token
    273     {
    274       ]b4_token_enums(b4_tokens)[
    275     };
    276     /// Token type.
    277     typedef token::yytokentype token_type;
    278 
    279     /// Build a parser object.
    280     ]b4_parser_class_name[ (]b4_parse_param_decl[);
    281     virtual ~]b4_parser_class_name[ ();
    282 
    283     /// Parse.
    284     /// \returns  0 iff parsing succeeded.
    285     virtual int parse ();
    286 
    287     /// The current debugging stream.
    288     std::ostream& debug_stream () const;
    289     /// Set the current debugging stream.
    290     void set_debug_stream (std::ostream &);
    291 
    292     /// Type for debugging levels.
    293     typedef int debug_level_type;
    294     /// The current debugging level.
    295     debug_level_type debug_level () const;
    296     /// Set the current debugging level.
    297     void set_debug_level (debug_level_type l);
    298 
    299   private:
    300 
    301   public:
    302     /// Report a syntax error.
    303     /// \param loc    where the syntax error is found.
    304     /// \param msg    a description of the syntax error.
    305     virtual void error (const location_type& loc, const std::string& msg);
    306   private:
    307 
    308 # if ]b4_api_PREFIX[DEBUG
    309   public:
    310     /// \brief Report a symbol value on the debug stream.
    311     /// \param yytype       The token type.
    312     /// \param yyvaluep     Its semantic value.
    313     /// \param yylocationp  Its location.
    314     virtual void yy_symbol_value_print_ (int yytype,
    315                                          const semantic_type* yyvaluep,
    316                                          const location_type* yylocationp);
    317     /// \brief Report a symbol on the debug stream.
    318     /// \param yytype       The token type.
    319     /// \param yyvaluep     Its semantic value.
    320     /// \param yylocationp  Its location.
    321     virtual void yy_symbol_print_ (int yytype,
    322                                    const semantic_type* yyvaluep,
    323                                    const location_type* yylocationp);
    324   private:
    325     /* Debugging.  */
    326     std::ostream* yycdebug_;
    327 # endif
    328 
    329 ]b4_parse_param_vars[
    330   };
    331 
    332 ]dnl Redirections for glr.c.
    333 b4_percent_define_flag_if([[global_tokens_and_yystype]],
    334 [b4_token_defines(b4_tokens)])
    335 [
    336 #ifndef ]b4_api_PREFIX[STYPE
    337 # define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class_name[::semantic_type
    338 #endif
    339 #ifndef ]b4_api_PREFIX[LTYPE
    340 # define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class_name[::location_type
    341 #endif
    342 
    343 ]b4_namespace_close[
    344 ]b4_percent_code_get([[provides]])[
    345 ]b4_cpp_guard_close([b4_spec_defines_file])[
    346 ]b4_output_end()
    347