# --------------------------------------------------------------
# Declare "parser::yy<TABLE-NAME>_" which contents is CONTENT.
m4_define([b4_integral_parser_table_declare],
-[m4_ifval([$3], [b4_c_comment([$3], [ ])
+[m4_ifval([$3], [b4_comment([$3], [ ])
])dnl
static const b4_int_type_for([$2]) yy$1_[[]];dnl
])
# Same as in C, but using references instead of pointers.
m4_define([b4_symbol_action],
[b4_symbol_if([$1], [has_$2],
-[m4_pushdef([b4_dollar_dollar],
- [b4_symbol_value_template([yysym.value],
- b4_symbol_if([$1], [has_type],
- [b4_symbol([$1], [type])]))])dnl
-m4_pushdef([b4_at_dollar], [yysym.location])dnl
+[m4_pushdef([b4_symbol_value], m4_defn([b4_symbol_value_template]))[]dnl
+b4_dollar_pushdef([yysym.value],
+ b4_symbol_if([$1], [has_type],
+ [m4_dquote(b4_symbol([$1], [type]))]),
+ [yysym.location])dnl
b4_symbol_case_([$1])
b4_syncline([b4_symbol([$1], [$2_line])], ["b4_symbol([$1], [$2_file])"])
b4_symbol([$1], [$2])
b4_syncline([@oline@], [@ofile@])
break;
-m4_popdef([b4_at_dollar])dnl
-m4_popdef([b4_dollar_dollar])dnl
+m4_popdef([b4_symbol_value])[]dnl
+b4_dollar_popdef[]dnl
])])
m4_define([b4_parser_class_name],
[b4_percent_define_get([[parser_class_name]])])
-# The header is mandatory.
-b4_defines_if([],
- [b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
-
-b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
- [# Backward compatibility.
+b4_bison_locations_if([# Backward compatibility.
m4_define([b4_location_constructors])
- m4_include(b4_pkgdatadir/[location.cc])])])
+ m4_include(b4_pkgdatadir/[location.cc])])
m4_include(b4_pkgdatadir/[stack.hh])
b4_variant_if([m4_include(b4_pkgdatadir/[variant.hh])])
-# We do want M4 expansion after # for CPP macros.
-m4_changecom()
-m4_divert_push(0)dnl
-@output(b4_spec_defines_file@)@
-b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
-[
-/**
- ** \file ]b4_spec_defines_file[
- ** Define the ]b4_namespace_ref[::parser class.
- */
+# b4_shared_declarations
+# ----------------------
+# Declaration that might either go into the header (if --defines)
+# or open coded in the parser body.
+m4_define([b4_shared_declarations],
+[b4_percent_code_get([[requires]])[
+]b4_parse_assert_if([# include <cassert>])[
+# include <deque>
+# include <iostream>
+# include <stdexcept>
+# include <string>]b4_defines_if([[
+# include "stack.hh"
+]b4_bison_locations_if([[# include "location.hh"]])])[
+
+]b4_YYDEBUG_define[
-/* C++ LALR(1) parser skeleton written by Akim Demaille. */
-
-]b4_cpp_guard_open([b4_spec_defines_file])[
-
-]b4_percent_code_get([[requires]])[
-
-]b4_parse_assert_if([#include <cassert>])[
-#include <stdexcept>
-#include <string>
-#include <iostream>
-#include "stack.hh"
-]b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
- [[#include "location.hh"]])])[
-
-]b4_variant_if([b4_namespace_open
-b4_variant_define
-b4_namespace_close])[
-
-]b4_null_define[
+]b4_namespace_open[
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG ]b4_parse_trace_if([1], [0])[
-#endif
+]b4_defines_if([],
+[b4_stack_define
+b4_bison_locations_if([b4_position_define
+b4_location_define])])[
-]b4_namespace_open[
+]b4_variant_if([b4_variant_define])[
/// A Bison parser.
class ]b4_parser_class_name[
/// \returns 0 iff parsing succeeded.
virtual int parse ();
-#if YYDEBUG
+#if ]b4_api_PREFIX[DEBUG
/// The current debugging stream.
std::ostream& debug_stream () const;
/// Set the current debugging stream.
void set_debug_level (debug_level_type l);
#endif
- /// Report a syntax error.]b4_locations_if([
- /// \param loc where the syntax error is found.])[
+ /// Report a syntax error.]b4_locations_if([[
+ /// \param loc where the syntax error is found.]])[
/// \param msg a description of the syntax error.
- virtual void error (]b4_locations_if([const location_type& loc, ])[const std::string& msg);
+ virtual void error (]b4_locations_if([[const location_type& loc, ]])[const std::string& msg);
/// Report a syntax error.
void error (const syntax_error& err);
/// Convert the symbol name \a n to a form suitable for a diagnostic.
static std::string yytnamerr_ (const char *n);])[
-]b4_token_table_if([], [[#if YYDEBUG]])[
+]b4_token_table_if([], [[#if ]b4_api_PREFIX[DEBUG]])[
/// For a symbol, its name in clear.
static const char* const yytname_[];
-]b4_token_table_if([[#if YYDEBUG]])[
+]b4_token_table_if([[#if ]b4_api_PREFIX[DEBUG]])[
]b4_integral_parser_table_declare([rline], [b4_rline],
[YYRLINE[YYN] -- Source line where rule number YYN was defined.])[
/// Report on the debug stream that the rule \a r is going to be reduced.
// Debugging.
int yydebug_;
std::ostream* yycdebug_;
-#endif // YYDEBUG
+#endif // ]b4_api_PREFIX[DEBUG
/// Convert a scanner token number \a t to a symbol number.
- static inline token_number_type yytranslate_ (]b4_lex_symbol_if([token_type], [int])[ t);
+ static inline token_number_type yytranslate_ (]b4_token_ctor_if([token_type], [int])[ t);
-#if YYDEBUG
+#if ]b4_api_PREFIX[DEBUG
/// \brief Display a symbol type, value and location.
/// \param yyo The output stream.
/// \param yysym The symbol.
inline stack_symbol_type ();
/// Constructor.
- inline stack_symbol_type (]b4_args([state_type s],
+ inline stack_symbol_type (]b4_join([state_type s],
[const semantic_type& v],
b4_locations_if([const location_type& l]))[);
]b4_parse_param_vars[
};
-]b4_lex_symbol_if([b4_yytranslate_define
+]b4_token_ctor_if([b4_yytranslate_define
b4_public_types_define])[
]b4_namespace_close[
]b4_percent_define_flag_if([[global_tokens_and_yystype]],
-[b4_token_defines(b4_tokens)
+[b4_token_defines
#ifndef ]b4_api_PREFIX[STYPE
/* Redirection for backward compatibility. */
#endif
])[
]b4_percent_code_get([[provides]])[
+]])
+
+b4_defines_if(
+[b4_output_begin([b4_spec_defines_file])
+b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
+[
+/**
+ ** \file ]b4_spec_defines_file[
+ ** Define the ]b4_namespace_ref[::parser class.
+ */
+
+/* C++ LALR(1) parser skeleton written by Akim Demaille. */
+
+]b4_cpp_guard_open([b4_spec_defines_file])[
+]b4_shared_declarations[
]b4_cpp_guard_close([b4_spec_defines_file])
-@output(b4_parser_file_name@)@
+b4_output_end()
+])
+
+
+b4_output_begin([b4_parser_file_name])
b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++])
b4_percent_code_get([[top]])[]dnl
m4_if(b4_prefix, [yy], [],
// Take the name prefix into account.
#define yylex b4_prefix[]lex])[
-/* First part of user declarations. */
+// First part of user declarations.
]b4_user_pre_prologue[
-#include "@basename(]b4_spec_defines_file[@)"
+]b4_null_define[
+
+]b4_defines_if([[#include "@basename(]b4_spec_defines_file[@)"]],
+ [b4_shared_declarations])[
/* User implementation prologue. */
-]b4_user_post_prologue
-b4_percent_code_get[]dnl
+]b4_user_post_prologue[
+]b4_percent_code_get[
-[#ifndef YY_
+#ifndef YY_
# if defined YYENABLE_NLS && YYENABLE_NLS
# if ENABLE_NLS
# include <libintl.h> /* FIXME: INFRINGES ON USER NAME SPACE */
#endif
]b4_locations_if([dnl
-[/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
- If N is 0, then set CURRENT to the empty location which ends
- the previous symbol: RHS[0] (always defined). */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (N) \
- { \
- (Current).begin = YYRHSLOC (Rhs, 1).begin; \
- (Current).end = YYRHSLOC (Rhs, N).end; \
- } \
- else \
- { \
- (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end; \
- } \
- while (false)
-#endif]])[
+[#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)
+]b4_yylloc_default_define])[
/* Suppress unused-variable warnings by "using" E. */
#define YYUSE(e) ((void) (e))
/* Enable debugging if requested. */
-#if YYDEBUG
+#if ]b4_api_PREFIX[DEBUG
/* A pseudo ostream that takes yydebug_ into account. */
# define YYCDEBUG if (yydebug_) (*yycdebug_)
yystack_print_ (); \
} while (false)
-#else /* !YYDEBUG */
+#else /* !]b4_api_PREFIX[DEBUG */
# define YYCDEBUG if (false) std::cerr
# define YY_SYMBOL_PRINT(Title, Symbol) YYUSE(Symbol)
# define YY_REDUCE_PRINT(Rule) static_cast<void>(0)
# define YY_STACK_PRINT() static_cast<void>(0)
-#endif /* !YYDEBUG */
+#endif /* !]b4_api_PREFIX[DEBUG */
#define yyerrok (yyerrstatus_ = 0)
#define yyclearin (yyempty = true)
/// Build a parser object.
]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
:])[
-#if YYDEBUG
+#if ]b4_api_PREFIX[DEBUG
]m4_ifset([b4_parse_param], [ ], [ :])[yydebug_ (false),
yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
#endif]b4_parse_param_cons[
| Symbol types. |
`---------------*/
-]b4_lex_symbol_if([], [b4_public_types_define])[
+]b4_token_ctor_if([], [b4_public_types_define])[
// stack_symbol_type.
]b4_parser_class_name[::stack_symbol_type::stack_symbol_type ()
{
}
- ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type (]b4_args(
+ ]b4_parser_class_name[::stack_symbol_type::stack_symbol_type (]b4_join(
[state_type s],
[const semantic_type& v],
b4_locations_if([const location_type& l]))[)
b4_symbol_variant([[yytype]], [[yysym.value]], [[template destroy]])])[
}
-#if YYDEBUG
+#if ]b4_api_PREFIX[DEBUG
template <typename Exact>
void
]b4_parser_class_name[::yy_print_ (std::ostream& yyo,
if (m)
YY_SYMBOL_PRINT (m, sym);
]b4_variant_if(
-[[ yystack_.push (stack_symbol_type (]b4_args(
+[[ yystack_.push (stack_symbol_type (]b4_join(
[s],
[semantic_type()],
b4_locations_if([sym.location]))[));
]b4_symbol_variant([[yystos_[s]]], [[yystack_[0].value]],
[build], [sym.value])],
-[[ yystack_.push (stack_symbol_type (]b4_args(
+[[ yystack_.push (stack_symbol_type (]b4_join(
[s],
[sym.value],
b4_locations_if([sym.location]))[));]])[
if (m)
YY_SYMBOL_PRINT (m, s);
]b4_variant_if(
-[[ yystack_.push (stack_symbol_type (]b4_args(
+[[ yystack_.push (stack_symbol_type (]b4_join(
[s.state],
[semantic_type()],
b4_locations_if([s.location]))[));
yystack_.pop (n);
}
-#if YYDEBUG
+#if ]b4_api_PREFIX[DEBUG
std::ostream&
]b4_parser_class_name[::debug_stream () const
{
{
yydebug_ = l;
}
-#endif // YYDEBUG
+#endif // ]b4_api_PREFIX[DEBUG
inline ]b4_parser_class_name[::state_type
]b4_parser_class_name[::yy_lr_goto_state_ (state_type yystate, int yylhs)
/// Whether yyla contains a lookahead.
bool yyempty = true;
- /* State. */
+ // State.
int yyn;
int yylen = 0;
- /* Error handling. */
+ // Error handling.
int yynerrs_ = 0;
int yyerrstatus_ = 0;
/// $$ and @@$.
stack_symbol_type yylhs;
- /// The return value of parse().
+ /// The return value of parse ().
int yyresult;
+ // FIXME: This shoud be completely indented. It is not yet to
+ // avoid gratuitous conflicts when merging into the master branch.
+ try
+ {
YYCDEBUG << "Starting parse" << std::endl;
]m4_ifdef([b4_initial_action], [
-m4_pushdef([b4_at_dollar], [yyla.location])dnl
-m4_pushdef([b4_dollar_dollar], [yyla.value])dnl
+b4_dollar_pushdef([yyla.value], [], [yyla.location])dnl
/* User initialization code. */
b4_user_initial_action
-m4_popdef([b4_dollar_dollar])dnl
-m4_popdef([b4_at_dollar])])dnl
+b4_dollar_popdef])[]dnl
[ /* Initialize the stack. The initial state will be set in
yynewstate, since the latter expects the semantical and the
{
YYCDEBUG << "Reading a token: ";
try
- {
-]b4_lex_symbol_if(
-[ yyla = b4_c_function_call([yylex], [symbol_type],
+ {
+]b4_token_ctor_if(
+[ yyla = b4_function_call([yylex], [symbol_type],
m4_ifdef([b4_lex_param], b4_lex_param));],
-[ yyla.type = yytranslate_ (b4_c_function_call([yylex], [int],
+[ yyla.type = yytranslate_ (b4_function_call([yylex], [int],
[b4_api_PREFIX[STYPE*], [&yyla.value]][]dnl
b4_locations_if([, [[location*], [&yyla.location]]])dnl
m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
- }
+ }
catch (const syntax_error& yyexc)
- {
- error (yyexc);
- goto yyerrlab1;
- }
+ {
+ error (yyexc);
+ goto yyerrlab1;
+ }
yyempty = false;
}
YY_SYMBOL_PRINT ("Next token is", yyla);
// Perform the reduction.
YY_REDUCE_PRINT (yyn);
try
- {
- switch (yyn)
{
+ switch (yyn)
+ {
]b4_user_actions[
- default:
- break;
+ default:
+ break;
+ }
}
- }
catch (const syntax_error& yyexc)
- {
- error (yyexc);
- YYERROR;
- }
+ {
+ error (yyexc);
+ YYERROR;
+ }
YY_SYMBOL_PRINT ("-> $$ =", yylhs);
]b4_variant_if([[
// Destroy the rhs symbols.
if (!yyerrstatus_)
{
++yynerrs_;
- error (]b4_args(b4_locations_if([yyla.location]),
+ error (]b4_join(b4_locations_if([yyla.location]),
[[yysyntax_error_ (yystack_[0].state,
yyempty ? yyempty_ : yyla.type)]])[);
}
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
yypop_ (yylen);
- while (yystack_.size () != 1)
+ while (1 < yystack_.size ())
{
yy_destroy_ ("Cleanup: popping", yystack_[0]);
yypop_ ();
return yyresult;
}
+ catch (...)
+ {
+ YYCDEBUG << "Exception caught: cleaning lookahead and stack"
+ << std::endl;
+ // Do not try to display the values of the reclaimed symbols,
+ // as their printer might throw an exception.
+ if (!yyempty)
+ yy_destroy_ (YY_NULL, yyla);
+
+ while (1 < yystack_.size ())
+ {
+ yy_destroy_ (YY_NULL, yystack_[0]);
+ yypop_ ();
+ }
+ throw;
+ }
+ }
void
]b4_parser_class_name[::error (const syntax_error& yyexc)
{
- error (]b4_args(b4_locations_if([yyexc.location]),
+ error (]b4_join(b4_locations_if([yyexc.location]),
[[yyexc.what()]])[);
}
]b4_parser_tables_define[
-]b4_token_table_if([], [[#if YYDEBUG]])[
+]b4_token_table_if([], [[#if ]b4_api_PREFIX[DEBUG]])[
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at \a yyntokens_, nonterminals. */
const char*
]b4_tname[
};
-]b4_token_table_if([[#if YYDEBUG]])[
+]b4_token_table_if([[#if ]b4_api_PREFIX[DEBUG]])[
]b4_integral_parser_table_define([rline], [b4_rline])[
// Print the state stack on the debug stream.
YY_SYMBOL_PRINT (" $" << yyi + 1 << " =",
]b4_rhs_data(yynrhs, yyi + 1)[);
}
-#endif // YYDEBUG
+#endif // ]b4_api_PREFIX[DEBUG
-]b4_lex_symbol_if([], [b4_yytranslate_define])[
+]b4_token_ctor_if([], [b4_yytranslate_define])[
]b4_namespace_close[
]b4_epilogue[]dnl
-m4_divert_pop(0)
+b4_output_end()
+
+
m4_popdef([b4_copyright_years])dnl