m4_divert(-1) -*- C -*-
# C++ GLR skeleton for Bison
-# Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2004, 2005, 2006 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
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA
+
+# This skeleton produces a C++ class that encapsulates a C glr parser.
+# This is in order to reduce the maintenance burden. The glr.c
+# skeleton is clean and pure enough so that there are no real
+# problems. The C++ interface is the same as that of lalr1.cc. In
+# fact, glr.c can replace yacc.c without the user noticing any
+# difference, and similarly for glr.cc replacing lalr1.cc.
+#
+# The passing of parse-params
+#
+# The additional arguments are stored as members of the parser
+# object, yyparser. The C routines need to carry yyparser
+# throughout the C parser; that easy: just let yyparser become an
+# additional parse-param. But because the C++ skeleton needs to
+# know the "real" original parse-param, we save them
+# (b4_parse_param_orig). Note that b4_parse_param is overquoted
+# (and c.m4 strips one level of quotes). This is a PITA, and
+# explains why there are so many levels of quotes.
+#
+# The locations
+#
+# We use location.cc just like lalr1.cc, but because glr.c stores
+# the locations in a (C++) union, the position and location classes
+# must not have a constructor. Therefore, contrary to lalr1.cc, we
+# must not define "b4_location_constructors". As a consequence the
+# user must initialize the first positions (in particular the
+# filename member).
+
+
# We require a pure interface using locations.
m4_define([b4_location_flag], [1])
m4_define([b4_pure], [1])
m4_include(b4_pkgdatadir/[location.cc])
-# b4_yysymprint_generate(FUNCTION-DECLARATOR)
-# -------------------------------------------
-# Generate the "yysymprint" function, which declaration is issued using
-# FUNCTION-DECLARATOR, which may be "b4_c_ansi_function_def" for ISO C
-# or "b4_c_function_def" for K&R.
-m4_define([b4_yysymprint_generate],
-[b4_c_ansi_function_decl([yyerror],
- [static void],
- [[yy::b4_parser_class_name::location_type *yylocationp], [yylocationp]],
- b4_parse_param,
- [[const char* msg], [msg]])[
+# Save the parse parameters.
+m4_define([b4_parse_param_orig], m4_defn([b4_parse_param]))
+
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
+# b4_yy_symbol_print_generate
+# ---------------------------
+# Bypass the default implementation to generate the "yy_symbol_print"
+# and "yy_symbol_value_print" functions.
+m4_define([b4_yy_symbol_print_generate],
+[[
+/*--------------------.
+| Print this symbol. |
+`--------------------*/
-]$1([yysymprint],
+]b4_c_ansi_function_def([yy_symbol_print],
[static void],
- [[FILE *yyoutput], [yyoutput]],
+ [[FILE *], []],
[[int yytype], [yytype]],
[[const yy::b4_parser_class_name::semantic_type *yyvaluep],
- [yyvaluep]][]dnl
-b4_location_if([,
+ [yyvaluep]],
[[const yy::b4_parser_class_name::location_type *yylocationp],
- [yylocationp]]])[]dnl
-m4_ifset([b4_parse_param], [, b4_parse_param]))[
+ [yylocationp]],
+ b4_parse_param)[
{
- (void) yyoutput;
- yyparser.yysymprint_ (yytype, yyvaluep]b4_location_if([, yylocationp])[);
+]b4_parse_param_use[]dnl
+[ yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_location_if([, yylocationp])[);
}
]])
-m4_prepend([b4_epilogue],
-[[
+
+# Declare yyerror.
+m4_append([b4_post_prologue],
+[/* Line __line__ of glr.cc. */
+b4_syncline([@oline@], [@ofile@])
+
+b4_c_ansi_function_decl([yyerror],
+ [static void],
+ [[yy::b4_parser_class_name::location_type *yylocationp], [yylocationp]],
+ b4_parse_param,
+ [[const char* msg], [msg]])])
+
+
+# Define yyerror.
+m4_append([b4_epilogue],
+[/* Line __line__ of glr.cc. */
+b4_syncline([@oline@], [@ofile@])[
/*------------------.
| Report an error. |
`------------------*/
b4_parse_param,
[[const char* msg], [msg]])[
{
- yyparser.error (*yylocationp, msg);
+]b4_parse_param_use[]dnl
+[ yyparser.error (*yylocationp, msg);
}
namespace yy
{
-]dnl Restore the actual parser params.
-m4_popdef([b4_parse_param])dnl
-[
- /// Build a parser object.
+]dnl In this section, the parse param are the original parse_params.
+m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
+[ /// Build a parser object.
]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)
: yycdebug_ (&std::cerr)]b4_parse_param_cons[
{
}
#if YYDEBUG
+ /*--------------------.
+ | Print this symbol. |
+ `--------------------*/
- /*--------------------------------.
- | Print this symbol on YYOUTPUT. |
- `--------------------------------*/
-
- void
- ]b4_parser_class_name[::yysymprint_ (int yytype,
+ inline void
+ ]b4_parser_class_name[::yy_symbol_value_print_ (int yytype,
const semantic_type* yyvaluep, const location_type* yylocationp)
{
/* Pacify ``unused variable'' warnings. */
- (void) yyvaluep;
- (void) yylocationp;
- /* Backward compatibility, but should be removed eventually. */
- std::ostream& cdebug_ = *yycdebug_;
- (void) cdebug_;
-
- *yycdebug_ << (yytype < YYNTOKENS ? "token" : "nterm")
- << ' ' << yytname[yytype] << " ("
- << *yylocationp << ": ";
+ YYUSE (yyvaluep);
+ YYUSE (yylocationp);
switch (yytype)
{
]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl
[ default:
break;
}
+ }
+
+
+ void
+ ]b4_parser_class_name[::yy_symbol_print_ (int yytype,
+ const semantic_type* yyvaluep, const location_type* yylocationp)
+ {
+ *yycdebug_ << (yytype < YYNTOKENS ? "token" : "nterm")
+ << ' ' << yytname[yytype] << " ("
+ << *yylocationp << ": ";
+ yy_symbol_value_print_ (yytype, yyvaluep, yylocationp);
*yycdebug_ << ')';
}
}
#endif /* ! YYDEBUG */
-
-} // namespace yy
+]m4_popdef([b4_parse_param])dnl
+[} // namespace yy
]])
-# Let glr.c believe that the user arguments are only the parser itself.
-m4_pushdef([b4_parse_param],
- [[yy::b4_parser_class_name& yyparser, yyparser],]
- m4_defn([b4_parse_param]))
+
+# Let glr.c believe that the user arguments include the parser itself.
+m4_ifset([b4_parse_param],
+[m4_pushdef([b4_parse_param],
+ m4_dquote([[[yy::b4_parser_class_name& yyparser], [[yyparser]]],]
+m4_defn([b4_parse_param])))],
+[m4_pushdef([b4_parse_param],
+ [[[[yy::b4_parser_class_name& yyparser], [[yyparser]]]]])
+])
m4_include(b4_pkgdatadir/[glr.c])
+m4_popdef([b4_parse_param])
+
+
@output @output_header_name@
b4_copyright([C++ Skeleton parser for GLALR(1) parsing with Bison],
- [2002, 2003, 2004, 2005])[
+ [2002, 2003, 2004, 2005, 2006])[
+
+/* C++ GLR parser skeleton written by Akim Demaille. */
+
#ifndef PARSER_HEADER_H
# define PARSER_HEADER_H
]/* Line __line__ of glr.cc. */
b4_syncline([@oline@], [@ofile@])[
-#include "stack.hh"
#include "location.hh"
/* Enabling traces. */
/// Symbol semantic values.
#if ! defined (YYSTYPE)
]m4_ifdef([b4_stype],
-[b4_syncline([b4_stype_line], [b4_file_name])
- union semantic_type b4_stype;
+[ union semantic_type
+b4_stype
/* Line __line__ of lalr1.cc. */
-b4_syncline([@oline@], [@ofile@])],
+b4_syncline([@oline@], [@ofile@])
+ ;],
[ typedef int semantic_type;])[
#else
typedef YYSTYPE semantic_type;
#if YYDEBUG
public:
+ /// \brief Report a symbol value on the debug stream.
+ /// \param yytype The token type.
+ /// \param yyvaluep Its semantic value.
+ /// \param yylocationp Its location.
+ virtual void yy_symbol_value_print_ (int yytype,
+ const semantic_type* yyvaluep,
+ const location_type* yylocationp);
/// \brief Report a symbol on the debug stream.
/// \param yytype The token type.
/// \param yyvaluep Its semantic value.
/// \param yylocationp Its location.
- virtual void yysymprint_ (int yytype,
- const semantic_type* yyvaluep,
- const location_type* yylocationp);
+ virtual void yy_symbol_print_ (int yytype,
+ const semantic_type* yyvaluep,
+ const location_type* yylocationp);
private:
#endif /* ! YYDEBUG */
};
]dnl Redirections for glr.c.
-[#define YYSTYPE yy::]b4_parser_class_name[::semantic_type
-#define YYLTYPE yy::]b4_parser_class_name[::location_type
+m4_ifset([b4_global_tokens_and_yystype],
+[b4_token_defines(b4_tokens)])
+[
+#ifndef YYSTYPE
+# define YYSTYPE yy::]b4_parser_class_name[::semantic_type
+#endif
+#ifndef YYLTYPE
+# define YYLTYPE yy::]b4_parser_class_name[::location_type
+#endif
}