The single-stack C++ parser is now the standard one.

* data/lalr1.cc: Rename as...
	* data/lalr1-split.cc: this.
	* data/lalr1-fusion.cc: Rename as...
	* data/lalr1.cc: this.
	* etc/bench.pl.in: Adjust.
This commit is contained in:
Akim Demaille
2008-07-31 11:03:04 +02:00
parent 8cdabf02ea
commit 8901f32e4a
4 changed files with 433 additions and 424 deletions

View File

@@ -1,3 +1,12 @@
2008-11-07 Akim Demaille <demaille@gostai.com>
The single-stack C++ parser is now the standard one.
* data/lalr1.cc: Rename as...
* data/lalr1-split.cc: this.
* data/lalr1-fusion.cc: Rename as...
* data/lalr1.cc: this.
* etc/bench.pl.in: Adjust.
2008-11-07 Akim Demaille <demaille@gostai.com> 2008-11-07 Akim Demaille <demaille@gostai.com>
Avoid empty-if warnings. Avoid empty-if warnings.

View File

@@ -18,16 +18,8 @@
m4_include(b4_pkgdatadir/[c++.m4]) m4_include(b4_pkgdatadir/[c++.m4])
# b4_table_define(TABLE-NAME, CONTENT) m4_pushdef([b4_copyright_years],
# ------------------------------------ [2002, 2003, 2004, 2005, 2006, 2007, 2008])
# Define "parser::yy<TABLE-NAME>_" which contents is CONTENT.
m4_define([b4_table_define],
[const b4_int_type_for([$2])
b4_parser_class_name::yy$1_[[]] =
{
$2
}dnl
])
# How the semantic value is extracted when using variants. # How the semantic value is extracted when using variants.
b4_variant_if([ b4_variant_if([
@@ -40,27 +32,6 @@ b4_variant_if([
]) # b4_variant_if ]) # b4_variant_if
# b4_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT])
# ----------------------------------------------------
m4_define([b4_assert_if],
[b4_percent_define_ifdef([[assert]], [$1], [$2])])
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
# --------------------------------------
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
# symbols on RHS.
m4_define([b4_rhs_value],
[b4_symbol_value([yystack_@{($1) - ($2)@}.value], [$3])])
# b4_rhs_location(RULE-LENGTH, NUM)
# ---------------------------------
# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
# on RHS.
m4_define([b4_rhs_location],
[yystack_@{($1) - ($2)@}.location])
# b4_symbol_actions(FILENAME, LINENO, # b4_symbol_actions(FILENAME, LINENO,
# SYMBOL-TAG, SYMBOL-NUM, # SYMBOL-TAG, SYMBOL-NUM,
# SYMBOL-ACTION, SYMBOL-TYPENAME) # SYMBOL-ACTION, SYMBOL-TYPENAME)
@@ -91,13 +62,13 @@ m4_define([b4_symbol_action_],
])]) ])])
# b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS]) # b4_symbol_variant(YYTYPE, YYVAL, ACTION)
# ------------------------------------------------ # ----------------------------------------
# Run some ACTION ("build", or "destroy") on YYVAL of symbol type # Run some ACTION ("build", or "destroy") on YYVAL of symbol type
# YYTYPE. # YYTYPE.
m4_define([b4_symbol_variant], m4_define([b4_symbol_variant],
[m4_pushdef([b4_dollar_dollar], [m4_pushdef([b4_dollar_dollar],
[$2.$3<$][3>(m4_shift3($@))])dnl [$2.$3<$][3>()])dnl
switch ($1) switch ($1)
{ {
m4_map([b4_symbol_action_], m4_defn([b4_type_names])) m4_map([b4_symbol_action_], m4_defn([b4_type_names]))
@@ -138,9 +109,6 @@ m4_define([b4_char_sizeof],
]) ])
m4_pushdef([b4_copyright_years],
[2002, 2003, 2004, 2005, 2006, 2007, 2008])
m4_define([b4_parser_class_name], m4_define([b4_parser_class_name],
[b4_percent_define_get([[parser_class_name]])]) [b4_percent_define_get([[parser_class_name]])])
@@ -167,7 +135,6 @@ dnl FIXME: This is wrong, we want computed header guards.
]b4_percent_code_get([[requires]])[ ]b4_percent_code_get([[requires]])[
]b4_assert_if([#include <cassert>])[
#include <string> #include <string>
#include <iostream> #include <iostream>
#include "stack.hh" #include "stack.hh"
@@ -175,8 +142,7 @@ dnl FIXME: This is wrong, we want computed header guards.
]b4_namespace_open[ ]b4_namespace_open[
class position; class position;
class location; class location;
]b4_variant_if( ]b4_variant_if([[
[[
/// A char[S] buffer to store and retrieve objects. /// A char[S] buffer to store and retrieve objects.
/// ///
/// Sort of a variant, but does not keep track of the nature /// Sort of a variant, but does not keep track of the nature
@@ -184,60 +150,13 @@ dnl FIXME: This is wrong, we want computed header guards.
/// via the current state. /// via the current state.
template <size_t S> template <size_t S>
struct variant struct variant
{]b4_assert_if([ {
/// Whether something is contained.
bool built;
/// Initially uninitialized.
variant ()
: built(false)
{}])[
/// Instantiate a \a T in here. /// Instantiate a \a T in here.
template <typename T> template <typename T>
inline T& inline void
build() build()
{]b4_assert_if([
assert(!built);
built = true;])[
return *new (buffer) T;
}
/// Accessor to a built \a T.
template <typename T>
inline T&
as()
{]b4_assert_if([
assert(built);])[
return reinterpret_cast<T&>(buffer);
}
/// Const accessor to a built \a T (for %printer).
template <typename T>
inline const T&
as() const
{]b4_assert_if([
assert(built);])[
return reinterpret_cast<const T&>(buffer);
}
/// Swap the content with \a other.
template <typename T>
inline void
swap(variant<S>& other)
{ {
std::swap(as<T>(), other.as<T>()); new (buffer) T;
}
/// Assign the content of \a other to this.
/// Destroys \a other.
template <typename T>
inline void
build(variant<S>& other)
{
build<T>();
swap<T>(other);
other.destroy<T>();
} }
/// Destroy the stored \a T. /// Destroy the stored \a T.
@@ -245,8 +164,23 @@ dnl FIXME: This is wrong, we want computed header guards.
inline void inline void
destroy() destroy()
{ {
as<T>().~T();]b4_assert_if([ reinterpret_cast<T&>(buffer).~T();
built = false;])[ }
/// Accessor to a built \a T.
template <typename T>
inline T&
as()
{
return reinterpret_cast<T&>(buffer);
}
/// Const accessor to a built \a T (for %printer).
template <typename T>
inline const T&
as() const
{
return reinterpret_cast<const T&>(buffer);
} }
/// A buffer large enough to store any of the semantic values. /// A buffer large enough to store any of the semantic values.
@@ -284,12 +218,12 @@ dnl FIXME: This is wrong, we want computed header guards.
do { \ do { \
if (N) \ if (N) \
{ \ { \
(Current).begin = (Rhs)[1].location.begin; \ (Current).begin = (Rhs)[1].begin; \
(Current).end = (Rhs)[N].location.end; \ (Current).end = (Rhs)[N].end; \
} \ } \
else \ else \
{ \ { \
(Current).begin = (Current).end = (Rhs)[0].location.end; \ (Current).begin = (Current).end = (Rhs)[0].end; \
} \ } \
} while (false) } while (false)
#endif #endif
@@ -361,7 +295,8 @@ m4_ifdef([b4_stype],
/// Generate an error message. /// Generate an error message.
/// \param state the state where the error occurred. /// \param state the state where the error occurred.
/// \param tok the lookahead token. /// \param tok the lookahead token.
virtual std::string yysyntax_error_ (int yystate, int tok); virtual std::string yysyntax_error_ (int yystate]dnl
b4_error_verbose_if([, int tok])[);
#if YYDEBUG #if YYDEBUG
/// \brief Report a symbol value on the debug stream. /// \brief Report a symbol value on the debug stream.
@@ -380,8 +315,22 @@ m4_ifdef([b4_stype],
const location_type& yylocation); const location_type& yylocation);
#endif #endif
/// State numbers. /// State numbers.
typedef int state_type; typedef int state_type;
/// State stack type.
typedef stack<state_type> state_stack_type;
/// Semantic value stack type.
typedef stack<semantic_type> semantic_stack_type;
/// location stack type.
typedef stack<location_type> location_stack_type;
/// The state stack.
state_stack_type yystate_stack_;
/// The semantic value stack.
semantic_stack_type yysemantic_stack_;
/// The location stack.
location_stack_type yylocation_stack_;
/// Internal symbol numbers. /// Internal symbol numbers.
typedef ]b4_int_type_for([b4_translate])[ token_number_type; typedef ]b4_int_type_for([b4_translate])[ token_number_type;
@@ -427,8 +376,10 @@ m4_ifdef([b4_stype],
#endif #endif
#if YYDEBUG #if YYDEBUG
/// A type to store symbol numbers and -1.
typedef ]b4_int_type_for([b4_rhs])[ rhs_number_type;
/// A `-1'-separated list of the rules' RHS. /// A `-1'-separated list of the rules' RHS.
static const ]b4_int_type_for([b4_rhs])[ yyrhs_[]; static const rhs_number_type yyrhs_[];
/// For each rule, the index of the first RHS symbol in \a yyrhs_. /// For each rule, the index of the first RHS symbol in \a yyrhs_.
static const ]b4_int_type_for([b4_prhs])[ yyprhs_[]; static const ]b4_int_type_for([b4_prhs])[ yyprhs_[];
/// For each rule, its source line number. /// For each rule, its source line number.
@@ -450,7 +401,6 @@ m4_ifdef([b4_stype],
/// \brief Reclaim the memory associated to a symbol. /// \brief Reclaim the memory associated to a symbol.
/// \param yymsg Why this token is reclaimed. /// \param yymsg Why this token is reclaimed.
/// If null, nothing is printed at all.
/// \param yytype The symbol type. /// \param yytype The symbol type.
/// \param yyvalue Its semantic value. /// \param yyvalue Its semantic value.
/// \param yylocation Its location. /// \param yylocation Its location.
@@ -459,31 +409,6 @@ m4_ifdef([b4_stype],
semantic_type& yyvalue, semantic_type& yyvalue,
location_type& yylocation); location_type& yylocation);
/// Element of the stack: a state and its attributes.
struct data_type
{
/// Default constructor.
data_type ();
/// Constructor.
data_type (state_type s, const semantic_type& v, const location_type& l);
/// The state.
state_type state;
/// The semantic value.
semantic_type value;
/// The location.
location_type location;
};
/// Stack type.
typedef stack<data_type> stack_type;
/// The stack.
stack_type yystack_;
/// Push a new state on the stack. /// Push a new state on the stack.
/// \warning the contents of \a v is stolen. /// \warning the contents of \a v is stolen.
inline void yypush_ (state_type s, inline void yypush_ (state_type s,
@@ -560,33 +485,33 @@ b4_percent_code_get[]dnl
# define YYCDEBUG if (yydebug_) (*yycdebug_) # define YYCDEBUG if (yydebug_) (*yycdebug_)
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
do { \ do { \
if (yydebug_) \ if (yydebug_) \
{ \ { \
*yycdebug_ << Title << ' '; \ *yycdebug_ << Title << ' '; \
yy_symbol_print_ ((Type), (Value), (Location)); \ yy_symbol_print_ ((Type), (Value), (Location)); \
*yycdebug_ << std::endl; \ *yycdebug_ << std::endl; \
} \ } \
} while (false) } while (false)
# define YY_REDUCE_PRINT(Rule) \ # define YY_REDUCE_PRINT(Rule) \
do { \ do { \
if (yydebug_) \ if (yydebug_) \
yy_reduce_print_ (Rule); \ yy_reduce_print_ (Rule); \
} while (false) } while (false)
# define YY_STACK_PRINT() \ # define YY_STACK_PRINT() \
do { \ do { \
if (yydebug_) \ if (yydebug_) \
yystack_print_ (); \ yystack_print_ (); \
} while (false) } while (false)
#else /* !YYDEBUG */ #else /* !YYDEBUG */
# define YYCDEBUG if (false) std::cerr # define YYCDEBUG if (false) std::cerr
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) static_cast<void>(0) # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
# define YY_REDUCE_PRINT(Rule) static_cast<void>(0) # define YY_REDUCE_PRINT(Rule)
# define YY_STACK_PRINT() static_cast<void>(0) # define YY_STACK_PRINT()
#endif /* !YYDEBUG */ #endif /* !YYDEBUG */
@@ -694,50 +619,31 @@ b4_percent_code_get[]dnl
YYUSE (yyvalue); YYUSE (yyvalue);
YYUSE (yylocation); YYUSE (yylocation);
if (yymsg)
YY_SYMBOL_PRINT (yymsg, yytype, yyvalue, yylocation); YY_SYMBOL_PRINT (yymsg, yytype, yyvalue, yylocation);
// User destructor.
switch (yytype) switch (yytype)
{ {
]m4_map([b4_symbol_actions], m4_defn([b4_symbol_destructors]))[ ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_destructors]))[
default: default:
break; break;
}]b4_variant_if([
// Type destructor.
b4_symbol_variant([[yytype]], [[yyvalue]], [[destroy]])])[
} }
]b4_parser_class_name[::data_type::data_type ()
: state()
, value()
, location()
{
}
]b4_parser_class_name[::data_type::data_type (state_type s,
const semantic_type& v, const location_type& l)
: state(s)
, value(v)
, location(l)
{
} }
void void
]b4_parser_class_name[::yypush_ (state_type s, ]b4_parser_class_name[::yypush_ (state_type s,
semantic_type& v, const location_type& l) semantic_type& v, const location_type& l)
{ {
]b4_variant_if( yystate_stack_.push (s);
[[ yystack_.push (data_type (s, semantic_type(), l)); yysemantic_stack_.push (v);
]b4_symbol_variant([[yystos_[s]]], [[yystack_[0].value]], [build], [v])], yylocation_stack_.push (l);
[ yystack_.push (data_type (s, v, l));])[
} }
void void
]b4_parser_class_name[::yypop_ (unsigned int n) ]b4_parser_class_name[::yypop_ (unsigned int n)
{ {
yystack_.pop (n); yystate_stack_.pop (n);
yysemantic_stack_.pop (n);
yylocation_stack_.pop (n);
} }
#if YYDEBUG #if YYDEBUG
@@ -788,7 +694,7 @@ b4_percent_code_get[]dnl
/// Location of the lookahead. /// Location of the lookahead.
location_type yylloc; location_type yylloc;
/// The locations where the error started and ended. /// The locations where the error started and ended.
data_type yyerror_range[2]; location_type yyerror_range[2];
/// $$. /// $$.
semantic_type yyval; semantic_type yyval;
@@ -807,11 +713,13 @@ m4_pushdef([b4_dollar_dollar], [yylval])dnl
m4_popdef([b4_dollar_dollar])dnl m4_popdef([b4_dollar_dollar])dnl
m4_popdef([b4_at_dollar])])dnl m4_popdef([b4_at_dollar])])dnl
[ /* Initialize the stack. The initial state will be set in [ /* Initialize the stacks. The initial state will be pushed in
yynewstate, since the latter expects the semantical and the yynewstate, since the latter expects the semantical and the
location values to have been already stored, initialize these location values to have been already stored, initialize these
stacks with a primary value. */ stacks with a primary value. */
yystack_ = stack_type (0); yystate_stack_ = state_stack_type (0);
yysemantic_stack_ = semantic_stack_type (0);
yylocation_stack_ = location_stack_type (0);
yypush_ (yystate, yylval, yylloc); yypush_ (yystate, yylval, yylloc);
// A new state was pushed on the stack. // A new state was pushed on the stack.
@@ -913,17 +821,14 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
This behavior is undocumented and Bison This behavior is undocumented and Bison
users should not rely upon it. */ users should not rely upon it. */
if (yylen) if (yylen)
yyval = yystack_@{yylen - 1@}.value; yyval = yysemantic_stack_@{yylen - 1@};
else else
yyval = yystack_@{0@}.value;])[ yyval = yysemantic_stack_@{0@};])[
// Compute the default @@$.
{ {
slice<data_type, stack_type> slice (yystack_, yylen); slice<location_type, location_stack_type> slice (yylocation_stack_, yylen);
YYLLOC_DEFAULT (yyloc, slice, yylen); YYLLOC_DEFAULT (yyloc, slice, yylen);
} }
// Perform the reduction.
YY_REDUCE_PRINT (yyn); YY_REDUCE_PRINT (yyn);
switch (yyn) switch (yyn)
{ {
@@ -932,20 +837,6 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
break; break;
} }
YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], yyval, yyloc); YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], yyval, yyloc);
]b4_variant_if([[
// Destroy the lhs symbols.
for (int i = 0; i < yylen; ++i)
// Destroy a variant which value may have be swapped with yyval.
// The value of yyval (hence maybe one of these lhs symbols)
// depends on what does the default contruction for this type.
// In the case of pointers for instance, nothing is done, so the
// value is junk. Therefore do not try to report the content in
// the debug trace, it's junk. Hence yymsg = 0. Besides, that
// keeps exactly the same traces as with the other Bison
// skeletons.
yydestruct_ (0,
yystos_[yystack_[i].state],
yystack_[i].value, yystack_[i].location);]])[
yypop_ (yylen); yypop_ (yylen);
yylen = 0; yylen = 0;
@@ -953,9 +844,9 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
/* Shift the result of the reduction. */ /* Shift the result of the reduction. */
yyn = yyr1_[yyn]; yyn = yyr1_[yyn];
yystate = yypgoto_[yyn - yyntokens_] + yystack_[0].state; yystate = yypgoto_[yyn - yyntokens_] + yystate_stack_[0];
if (0 <= yystate && yystate <= yylast_ if (0 <= yystate && yystate <= yylast_
&& yycheck_[yystate] == yystack_[0].state) && yycheck_[yystate] == yystate_stack_[0])
yystate = yytable_[yystate]; yystate = yytable_[yystate];
else else
yystate = yydefgoto_[yyn - yyntokens_]; yystate = yydefgoto_[yyn - yyntokens_];
@@ -970,10 +861,11 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
if (!yyerrstatus_) if (!yyerrstatus_)
{ {
++yynerrs_; ++yynerrs_;
error (yylloc, yysyntax_error_ (yystate, yytoken)); error (yylloc, yysyntax_error_ (yystate]dnl
b4_error_verbose_if([, yytoken])[));
} }
yyerror_range[0].location = yylloc; yyerror_range[0] = yylloc;
if (yyerrstatus_ == 3) if (yyerrstatus_ == 3)
{ {
/* If just tried and failed to reuse lookahead token after an /* If just tried and failed to reuse lookahead token after an
@@ -1008,12 +900,12 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
if (false) if (false)
goto yyerrorlab; goto yyerrorlab;
yyerror_range[0].location = yystack_[yylen - 1].location; yyerror_range[0] = yylocation_stack_[yylen - 1];
/* Do not reclaim the symbols of the rule which action triggered /* Do not reclaim the symbols of the rule which action triggered
this YYERROR. */ this YYERROR. */
yypop_ (yylen); yypop_ (yylen);
yylen = 0; yylen = 0;
yystate = yystack_[0].state; yystate = yystate_stack_[0];
goto yyerrlab1; goto yyerrlab1;
/*-------------------------------------------------------------. /*-------------------------------------------------------------.
@@ -1036,27 +928,27 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
} }
} }
// Pop the current state because it cannot handle the error token. /* Pop the current state because it cannot handle the error token. */
if (yystack_.size () == 1) if (yystate_stack_.size () == 1)
YYABORT; YYABORT;
yyerror_range[0].location = yystack_[0].location; yyerror_range[0] = yylocation_stack_[0];
yydestruct_ ("Error: popping", yydestruct_ ("Error: popping",
yystos_[yystate], yystos_[yystate],
yystack_[0].value, yystack_[0].location); yysemantic_stack_[0], yylocation_stack_[0]);
yypop_ (); yypop_ ();
yystate = yystack_[0].state; yystate = yystate_stack_[0];
YY_STACK_PRINT (); YY_STACK_PRINT ();
} }
yyerror_range[1].location = yylloc; yyerror_range[1] = yylloc;
// Using YYLLOC is tempting, but would change the location of // Using YYLLOC is tempting, but would change the location of
// the lookahead. YYLOC is available though. // the lookahead. YYLOC is available though.
YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
/* Shift the error token. */ /* Shift the error token. */
YY_SYMBOL_PRINT ("Shifting", yystos_[yyn], YY_SYMBOL_PRINT ("Shifting", yystos_[yyn],
yystack_[0].value, yystack_[0].location); yysemantic_stack_[0], yylocation_stack_[0]);
yystate = yyn; yystate = yyn;
yypush_ (yystate, yylval, yyloc); yypush_ (yystate, yylval, yyloc);
@@ -1079,11 +971,12 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
/* Do not reclaim the symbols of the rule which action triggered /* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */ this YYABORT or YYACCEPT. */
yypop_ (yylen); yypop_ (yylen);
while (yystack_.size () != 1) while (yystate_stack_.size () != 1)
{ {
yydestruct_ ("Cleanup: popping", yydestruct_ ("Cleanup: popping",
yystos_[yystack_[0].state], yystos_[yystate_stack_[0]],
yystack_[0].value, yystack_[0].location); yysemantic_stack_[0],
yylocation_stack_[0]);
yypop_ (); yypop_ ();
} }
@@ -1092,8 +985,8 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
// Generate an error message. // Generate an error message.
std::string std::string
]b4_parser_class_name[::yysyntax_error_ (int yystate, int]dnl ]b4_parser_class_name[::yysyntax_error_ (int yystate]dnl
b4_error_verbose_if([ tok])[) b4_error_verbose_if([, int tok])[)
{ {
std::string res; std::string res;
YYUSE (yystate); YYUSE (yystate);
@@ -1144,43 +1037,83 @@ b4_error_verbose_if([ tok])[)
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */ STATE-NUM. */
const ]b4_int_type(b4_pact_ninf, b4_pact_ninf) b4_parser_class_name::yypact_ninf_ = b4_pact_ninf[; const ]b4_int_type(b4_pact_ninf, b4_pact_ninf) b4_parser_class_name::yypact_ninf_ = b4_pact_ninf[;
]b4_table_define([pact], [b4_pact])[; const ]b4_int_type_for([b4_pact])[
]b4_parser_class_name[::yypact_[] =
{
]b4_pact[
};
/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE /* 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 doesn't specify something else to do. Zero means the default is an
error. */ error. */
]b4_table_define([defact], [b4_defact])[; const ]b4_int_type_for([b4_defact])[
]b4_parser_class_name[::yydefact_[] =
{
]b4_defact[
};
/* YYPGOTO[NTERM-NUM]. */ /* YYPGOTO[NTERM-NUM]. */
]b4_table_define([pgoto], [b4_pgoto])[; const ]b4_int_type_for([b4_pgoto])[
]b4_parser_class_name[::yypgoto_[] =
{
]b4_pgoto[
};
/* YYDEFGOTO[NTERM-NUM]. */ /* YYDEFGOTO[NTERM-NUM]. */
]b4_table_define([defgoto], [b4_defgoto])[; const ]b4_int_type_for([b4_defgoto])[
]b4_parser_class_name[::yydefgoto_[] =
{
]b4_defgoto[
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says. */ number is the opposite. If zero, do what YYDEFACT says. */
const ]b4_int_type(b4_table_ninf, b4_table_ninf) b4_parser_class_name::yytable_ninf_ = b4_table_ninf[; const ]b4_int_type(b4_table_ninf, b4_table_ninf) b4_parser_class_name::yytable_ninf_ = b4_table_ninf[;
]b4_table_define([table], [b4_table])[; const ]b4_int_type_for([b4_table])[
]b4_parser_class_name[::yytable_[] =
{
]b4_table[
};
/* YYCHECK. */ /* YYCHECK. */
]b4_table_define([check], [b4_check])[; const ]b4_int_type_for([b4_check])[
]b4_parser_class_name[::yycheck_[] =
{
]b4_check[
};
/* STOS_[STATE-NUM] -- The (internal number of the) accessing /* STOS_[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */ symbol of state STATE-NUM. */
]b4_table_define([stos], [b4_stos])[; const ]b4_int_type_for([b4_stos])[
]b4_parser_class_name[::yystos_[] =
{
]b4_stos[
};
#if YYDEBUG #if YYDEBUG
/* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding
to YYLEX-NUM. */ to YYLEX-NUM. */
]b4_table_define([token_number], [b4_toknum])[; const ]b4_int_type_for([b4_toknum])[
]b4_parser_class_name[::yytoken_number_[] =
{
]b4_toknum[
};
#endif #endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
]b4_table_define([r1], [b4_r1])[; const ]b4_int_type_for([b4_r1])[
]b4_parser_class_name[::yyr1_[] =
{
]b4_r1[
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
]b4_table_define([r2], [b4_r2])[; const ]b4_int_type_for([b4_r2])[
]b4_parser_class_name[::yyr2_[] =
{
]b4_r2[
};
#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
@@ -1194,25 +1127,35 @@ b4_error_verbose_if([ tok])[)
#if YYDEBUG #if YYDEBUG
/* YYRHS -- A `-1'-separated list of the rules' RHS. */ /* YYRHS -- A `-1'-separated list of the rules' RHS. */
]b4_table_define([rhs], [b4_rhs])[; const ]b4_parser_class_name[::rhs_number_type
]b4_parser_class_name[::yyrhs_[] =
{
]b4_rhs[
};
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */ YYRHS. */
]b4_table_define([prhs], [b4_prhs])[; const ]b4_int_type_for([b4_prhs])[
]b4_parser_class_name[::yyprhs_[] =
{
]b4_prhs[
};
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
]b4_table_define([rline], [b4_rline])[; const ]b4_int_type_for([b4_rline])[
]b4_parser_class_name[::yyrline_[] =
{
]b4_rline[
};
// Print the state stack on the debug stream. // Print the state stack on the debug stream.
void void
]b4_parser_class_name[::yystack_print_ () ]b4_parser_class_name[::yystack_print_ ()
{ {
*yycdebug_ << "Stack now"; *yycdebug_ << "Stack now";
for (stack_type::const_iterator for (state_stack_type::const_iterator i = yystate_stack_.begin ();
i = yystack_.begin (), i != yystate_stack_.end (); ++i)
i_end = yystack_.end (); *yycdebug_ << ' ' << *i;
i != i_end; ++i)
*yycdebug_ << ' ' << i->state;
*yycdebug_ << std::endl; *yycdebug_ << std::endl;
} }
@@ -1264,7 +1207,8 @@ b4_error_verbose_if([ tok])[)
]b4_namespace_close[ ]b4_namespace_close[
]b4_epilogue[]dnl ]b4_epilogue
dnl
@output(b4_dir_prefix[]stack.hh@)@ @output(b4_dir_prefix[]stack.hh@)@
b4_copyright([Stack handling for Bison parsers in C++])[ b4_copyright([Stack handling for Bison parsers in C++])[

View File

@@ -18,8 +18,16 @@
m4_include(b4_pkgdatadir/[c++.m4]) m4_include(b4_pkgdatadir/[c++.m4])
m4_pushdef([b4_copyright_years], # b4_table_define(TABLE-NAME, CONTENT)
[2002, 2003, 2004, 2005, 2006, 2007, 2008]) # ------------------------------------
# Define "parser::yy<TABLE-NAME>_" which contents is CONTENT.
m4_define([b4_table_define],
[const b4_int_type_for([$2])
b4_parser_class_name::yy$1_[[]] =
{
$2
}dnl
])
# How the semantic value is extracted when using variants. # How the semantic value is extracted when using variants.
b4_variant_if([ b4_variant_if([
@@ -32,6 +40,27 @@ b4_variant_if([
]) # b4_variant_if ]) # b4_variant_if
# b4_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT])
# ----------------------------------------------------
m4_define([b4_assert_if],
[b4_percent_define_ifdef([[assert]], [$1], [$2])])
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
# --------------------------------------
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
# symbols on RHS.
m4_define([b4_rhs_value],
[b4_symbol_value([yystack_@{($1) - ($2)@}.value], [$3])])
# b4_rhs_location(RULE-LENGTH, NUM)
# ---------------------------------
# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
# on RHS.
m4_define([b4_rhs_location],
[yystack_@{($1) - ($2)@}.location])
# b4_symbol_actions(FILENAME, LINENO, # b4_symbol_actions(FILENAME, LINENO,
# SYMBOL-TAG, SYMBOL-NUM, # SYMBOL-TAG, SYMBOL-NUM,
# SYMBOL-ACTION, SYMBOL-TYPENAME) # SYMBOL-ACTION, SYMBOL-TYPENAME)
@@ -62,13 +91,13 @@ m4_define([b4_symbol_action_],
])]) ])])
# b4_symbol_variant(YYTYPE, YYVAL, ACTION) # b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS])
# ---------------------------------------- # ------------------------------------------------
# Run some ACTION ("build", or "destroy") on YYVAL of symbol type # Run some ACTION ("build", or "destroy") on YYVAL of symbol type
# YYTYPE. # YYTYPE.
m4_define([b4_symbol_variant], m4_define([b4_symbol_variant],
[m4_pushdef([b4_dollar_dollar], [m4_pushdef([b4_dollar_dollar],
[$2.$3<$][3>()])dnl [$2.$3<$][3>(m4_shift3($@))])dnl
switch ($1) switch ($1)
{ {
m4_map([b4_symbol_action_], m4_defn([b4_type_names])) m4_map([b4_symbol_action_], m4_defn([b4_type_names]))
@@ -109,6 +138,9 @@ m4_define([b4_char_sizeof],
]) ])
m4_pushdef([b4_copyright_years],
[2002, 2003, 2004, 2005, 2006, 2007, 2008])
m4_define([b4_parser_class_name], m4_define([b4_parser_class_name],
[b4_percent_define_get([[parser_class_name]])]) [b4_percent_define_get([[parser_class_name]])])
@@ -135,6 +167,7 @@ dnl FIXME: This is wrong, we want computed header guards.
]b4_percent_code_get([[requires]])[ ]b4_percent_code_get([[requires]])[
]b4_assert_if([#include <cassert>])[
#include <string> #include <string>
#include <iostream> #include <iostream>
#include "stack.hh" #include "stack.hh"
@@ -142,7 +175,8 @@ dnl FIXME: This is wrong, we want computed header guards.
]b4_namespace_open[ ]b4_namespace_open[
class position; class position;
class location; class location;
]b4_variant_if([[ ]b4_variant_if(
[[
/// A char[S] buffer to store and retrieve objects. /// A char[S] buffer to store and retrieve objects.
/// ///
/// Sort of a variant, but does not keep track of the nature /// Sort of a variant, but does not keep track of the nature
@@ -150,28 +184,31 @@ dnl FIXME: This is wrong, we want computed header guards.
/// via the current state. /// via the current state.
template <size_t S> template <size_t S>
struct variant struct variant
{ {]b4_assert_if([
/// Whether something is contained.
bool built;
/// Initially uninitialized.
variant ()
: built(false)
{}])[
/// Instantiate a \a T in here. /// Instantiate a \a T in here.
template <typename T> template <typename T>
inline void inline T&
build() build()
{ {]b4_assert_if([
new (buffer) T; assert(!built);
} built = true;])[
return *new (buffer) T;
/// Destroy the stored \a T.
template <typename T>
inline void
destroy()
{
reinterpret_cast<T&>(buffer).~T();
} }
/// Accessor to a built \a T. /// Accessor to a built \a T.
template <typename T> template <typename T>
inline T& inline T&
as() as()
{ {]b4_assert_if([
assert(built);])[
return reinterpret_cast<T&>(buffer); return reinterpret_cast<T&>(buffer);
} }
@@ -179,10 +216,39 @@ dnl FIXME: This is wrong, we want computed header guards.
template <typename T> template <typename T>
inline const T& inline const T&
as() const as() const
{ {]b4_assert_if([
assert(built);])[
return reinterpret_cast<const T&>(buffer); return reinterpret_cast<const T&>(buffer);
} }
/// Swap the content with \a other.
template <typename T>
inline void
swap(variant<S>& other)
{
std::swap(as<T>(), other.as<T>());
}
/// Assign the content of \a other to this.
/// Destroys \a other.
template <typename T>
inline void
build(variant<S>& other)
{
build<T>();
swap<T>(other);
other.destroy<T>();
}
/// Destroy the stored \a T.
template <typename T>
inline void
destroy()
{
as<T>().~T();]b4_assert_if([
built = false;])[
}
/// A buffer large enough to store any of the semantic values. /// A buffer large enough to store any of the semantic values.
char buffer[S]; char buffer[S];
}; };
@@ -218,12 +284,12 @@ dnl FIXME: This is wrong, we want computed header guards.
do { \ do { \
if (N) \ if (N) \
{ \ { \
(Current).begin = (Rhs)[1].begin; \ (Current).begin = (Rhs)[1].location.begin; \
(Current).end = (Rhs)[N].end; \ (Current).end = (Rhs)[N].location.end; \
} \ } \
else \ else \
{ \ { \
(Current).begin = (Current).end = (Rhs)[0].end; \ (Current).begin = (Current).end = (Rhs)[0].location.end; \
} \ } \
} while (false) } while (false)
#endif #endif
@@ -295,8 +361,7 @@ m4_ifdef([b4_stype],
/// Generate an error message. /// Generate an error message.
/// \param state the state where the error occurred. /// \param state the state where the error occurred.
/// \param tok the lookahead token. /// \param tok the lookahead token.
virtual std::string yysyntax_error_ (int yystate]dnl virtual std::string yysyntax_error_ (int yystate, int tok);
b4_error_verbose_if([, int tok])[);
#if YYDEBUG #if YYDEBUG
/// \brief Report a symbol value on the debug stream. /// \brief Report a symbol value on the debug stream.
@@ -315,22 +380,8 @@ b4_error_verbose_if([, int tok])[);
const location_type& yylocation); const location_type& yylocation);
#endif #endif
/// State numbers. /// State numbers.
typedef int state_type; typedef int state_type;
/// State stack type.
typedef stack<state_type> state_stack_type;
/// Semantic value stack type.
typedef stack<semantic_type> semantic_stack_type;
/// location stack type.
typedef stack<location_type> location_stack_type;
/// The state stack.
state_stack_type yystate_stack_;
/// The semantic value stack.
semantic_stack_type yysemantic_stack_;
/// The location stack.
location_stack_type yylocation_stack_;
/// Internal symbol numbers. /// Internal symbol numbers.
typedef ]b4_int_type_for([b4_translate])[ token_number_type; typedef ]b4_int_type_for([b4_translate])[ token_number_type;
@@ -376,10 +427,8 @@ b4_error_verbose_if([, int tok])[);
#endif #endif
#if YYDEBUG #if YYDEBUG
/// A type to store symbol numbers and -1.
typedef ]b4_int_type_for([b4_rhs])[ rhs_number_type;
/// A `-1'-separated list of the rules' RHS. /// A `-1'-separated list of the rules' RHS.
static const rhs_number_type yyrhs_[]; static const ]b4_int_type_for([b4_rhs])[ yyrhs_[];
/// For each rule, the index of the first RHS symbol in \a yyrhs_. /// For each rule, the index of the first RHS symbol in \a yyrhs_.
static const ]b4_int_type_for([b4_prhs])[ yyprhs_[]; static const ]b4_int_type_for([b4_prhs])[ yyprhs_[];
/// For each rule, its source line number. /// For each rule, its source line number.
@@ -401,6 +450,7 @@ b4_error_verbose_if([, int tok])[);
/// \brief Reclaim the memory associated to a symbol. /// \brief Reclaim the memory associated to a symbol.
/// \param yymsg Why this token is reclaimed. /// \param yymsg Why this token is reclaimed.
/// If null, nothing is printed at all.
/// \param yytype The symbol type. /// \param yytype The symbol type.
/// \param yyvalue Its semantic value. /// \param yyvalue Its semantic value.
/// \param yylocation Its location. /// \param yylocation Its location.
@@ -409,6 +459,31 @@ b4_error_verbose_if([, int tok])[);
semantic_type& yyvalue, semantic_type& yyvalue,
location_type& yylocation); location_type& yylocation);
/// Element of the stack: a state and its attributes.
struct data_type
{
/// Default constructor.
data_type ();
/// Constructor.
data_type (state_type s, const semantic_type& v, const location_type& l);
/// The state.
state_type state;
/// The semantic value.
semantic_type value;
/// The location.
location_type location;
};
/// Stack type.
typedef stack<data_type> stack_type;
/// The stack.
stack_type yystack_;
/// Push a new state on the stack. /// Push a new state on the stack.
/// \warning the contents of \a v is stolen. /// \warning the contents of \a v is stolen.
inline void yypush_ (state_type s, inline void yypush_ (state_type s,
@@ -485,33 +560,33 @@ b4_percent_code_get[]dnl
# define YYCDEBUG if (yydebug_) (*yycdebug_) # define YYCDEBUG if (yydebug_) (*yycdebug_)
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
do { \ do { \
if (yydebug_) \ if (yydebug_) \
{ \ { \
*yycdebug_ << Title << ' '; \ *yycdebug_ << Title << ' '; \
yy_symbol_print_ ((Type), (Value), (Location)); \ yy_symbol_print_ ((Type), (Value), (Location)); \
*yycdebug_ << std::endl; \ *yycdebug_ << std::endl; \
} \ } \
} while (false) } while (false)
# define YY_REDUCE_PRINT(Rule) \ # define YY_REDUCE_PRINT(Rule) \
do { \ do { \
if (yydebug_) \ if (yydebug_) \
yy_reduce_print_ (Rule); \ yy_reduce_print_ (Rule); \
} while (false) } while (false)
# define YY_STACK_PRINT() \ # define YY_STACK_PRINT() \
do { \ do { \
if (yydebug_) \ if (yydebug_) \
yystack_print_ (); \ yystack_print_ (); \
} while (false) } while (false)
#else /* !YYDEBUG */ #else /* !YYDEBUG */
# define YYCDEBUG if (false) std::cerr # define YYCDEBUG if (false) std::cerr
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) static_cast<void>(0)
# define YY_REDUCE_PRINT(Rule) # define YY_REDUCE_PRINT(Rule) static_cast<void>(0)
# define YY_STACK_PRINT() # define YY_STACK_PRINT() static_cast<void>(0)
#endif /* !YYDEBUG */ #endif /* !YYDEBUG */
@@ -619,31 +694,50 @@ do { \
YYUSE (yyvalue); YYUSE (yyvalue);
YYUSE (yylocation); YYUSE (yylocation);
if (yymsg)
YY_SYMBOL_PRINT (yymsg, yytype, yyvalue, yylocation); YY_SYMBOL_PRINT (yymsg, yytype, yyvalue, yylocation);
// User destructor.
switch (yytype) switch (yytype)
{ {
]m4_map([b4_symbol_actions], m4_defn([b4_symbol_destructors]))[ ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_destructors]))[
default: default:
break; break;
}]b4_variant_if([
// Type destructor.
b4_symbol_variant([[yytype]], [[yyvalue]], [[destroy]])])[
} }
]b4_parser_class_name[::data_type::data_type ()
: state()
, value()
, location()
{
}
]b4_parser_class_name[::data_type::data_type (state_type s,
const semantic_type& v, const location_type& l)
: state(s)
, value(v)
, location(l)
{
} }
void void
]b4_parser_class_name[::yypush_ (state_type s, ]b4_parser_class_name[::yypush_ (state_type s,
semantic_type& v, const location_type& l) semantic_type& v, const location_type& l)
{ {
yystate_stack_.push (s); ]b4_variant_if(
yysemantic_stack_.push (v); [[ yystack_.push (data_type (s, semantic_type(), l));
yylocation_stack_.push (l); ]b4_symbol_variant([[yystos_[s]]], [[yystack_[0].value]], [build], [v])],
[ yystack_.push (data_type (s, v, l));])[
} }
void void
]b4_parser_class_name[::yypop_ (unsigned int n) ]b4_parser_class_name[::yypop_ (unsigned int n)
{ {
yystate_stack_.pop (n); yystack_.pop (n);
yysemantic_stack_.pop (n);
yylocation_stack_.pop (n);
} }
#if YYDEBUG #if YYDEBUG
@@ -694,7 +788,7 @@ do { \
/// Location of the lookahead. /// Location of the lookahead.
location_type yylloc; location_type yylloc;
/// The locations where the error started and ended. /// The locations where the error started and ended.
location_type yyerror_range[2]; data_type yyerror_range[2];
/// $$. /// $$.
semantic_type yyval; semantic_type yyval;
@@ -713,13 +807,11 @@ m4_pushdef([b4_dollar_dollar], [yylval])dnl
m4_popdef([b4_dollar_dollar])dnl m4_popdef([b4_dollar_dollar])dnl
m4_popdef([b4_at_dollar])])dnl m4_popdef([b4_at_dollar])])dnl
[ /* Initialize the stacks. The initial state will be pushed in [ /* Initialize the stack. The initial state will be set in
yynewstate, since the latter expects the semantical and the yynewstate, since the latter expects the semantical and the
location values to have been already stored, initialize these location values to have been already stored, initialize these
stacks with a primary value. */ stacks with a primary value. */
yystate_stack_ = state_stack_type (0); yystack_ = stack_type (0);
yysemantic_stack_ = semantic_stack_type (0);
yylocation_stack_ = location_stack_type (0);
yypush_ (yystate, yylval, yylloc); yypush_ (yystate, yylval, yylloc);
// A new state was pushed on the stack. // A new state was pushed on the stack.
@@ -821,14 +913,17 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
This behavior is undocumented and Bison This behavior is undocumented and Bison
users should not rely upon it. */ users should not rely upon it. */
if (yylen) if (yylen)
yyval = yysemantic_stack_@{yylen - 1@}; yyval = yystack_@{yylen - 1@}.value;
else else
yyval = yysemantic_stack_@{0@};])[ yyval = yystack_@{0@}.value;])[
// Compute the default @@$.
{ {
slice<location_type, location_stack_type> slice (yylocation_stack_, yylen); slice<data_type, stack_type> slice (yystack_, yylen);
YYLLOC_DEFAULT (yyloc, slice, yylen); YYLLOC_DEFAULT (yyloc, slice, yylen);
} }
// Perform the reduction.
YY_REDUCE_PRINT (yyn); YY_REDUCE_PRINT (yyn);
switch (yyn) switch (yyn)
{ {
@@ -837,6 +932,20 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
break; break;
} }
YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], yyval, yyloc); YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], yyval, yyloc);
]b4_variant_if([[
// Destroy the lhs symbols.
for (int i = 0; i < yylen; ++i)
// Destroy a variant which value may have be swapped with yyval.
// The value of yyval (hence maybe one of these lhs symbols)
// depends on what does the default contruction for this type.
// In the case of pointers for instance, nothing is done, so the
// value is junk. Therefore do not try to report the content in
// the debug trace, it's junk. Hence yymsg = 0. Besides, that
// keeps exactly the same traces as with the other Bison
// skeletons.
yydestruct_ (0,
yystos_[yystack_[i].state],
yystack_[i].value, yystack_[i].location);]])[
yypop_ (yylen); yypop_ (yylen);
yylen = 0; yylen = 0;
@@ -844,9 +953,9 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
/* Shift the result of the reduction. */ /* Shift the result of the reduction. */
yyn = yyr1_[yyn]; yyn = yyr1_[yyn];
yystate = yypgoto_[yyn - yyntokens_] + yystate_stack_[0]; yystate = yypgoto_[yyn - yyntokens_] + yystack_[0].state;
if (0 <= yystate && yystate <= yylast_ if (0 <= yystate && yystate <= yylast_
&& yycheck_[yystate] == yystate_stack_[0]) && yycheck_[yystate] == yystack_[0].state)
yystate = yytable_[yystate]; yystate = yytable_[yystate];
else else
yystate = yydefgoto_[yyn - yyntokens_]; yystate = yydefgoto_[yyn - yyntokens_];
@@ -861,11 +970,10 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[;
if (!yyerrstatus_) if (!yyerrstatus_)
{ {
++yynerrs_; ++yynerrs_;
error (yylloc, yysyntax_error_ (yystate]dnl error (yylloc, yysyntax_error_ (yystate, yytoken));
b4_error_verbose_if([, yytoken])[));
} }
yyerror_range[0] = yylloc; yyerror_range[0].location = yylloc;
if (yyerrstatus_ == 3) if (yyerrstatus_ == 3)
{ {
/* If just tried and failed to reuse lookahead token after an /* If just tried and failed to reuse lookahead token after an
@@ -900,12 +1008,12 @@ b4_error_verbose_if([, yytoken])[));
if (false) if (false)
goto yyerrorlab; goto yyerrorlab;
yyerror_range[0] = yylocation_stack_[yylen - 1]; yyerror_range[0].location = yystack_[yylen - 1].location;
/* Do not reclaim the symbols of the rule which action triggered /* Do not reclaim the symbols of the rule which action triggered
this YYERROR. */ this YYERROR. */
yypop_ (yylen); yypop_ (yylen);
yylen = 0; yylen = 0;
yystate = yystate_stack_[0]; yystate = yystack_[0].state;
goto yyerrlab1; goto yyerrlab1;
/*-------------------------------------------------------------. /*-------------------------------------------------------------.
@@ -928,27 +1036,27 @@ b4_error_verbose_if([, yytoken])[));
} }
} }
/* Pop the current state because it cannot handle the error token. */ // Pop the current state because it cannot handle the error token.
if (yystate_stack_.size () == 1) if (yystack_.size () == 1)
YYABORT; YYABORT;
yyerror_range[0] = yylocation_stack_[0]; yyerror_range[0].location = yystack_[0].location;
yydestruct_ ("Error: popping", yydestruct_ ("Error: popping",
yystos_[yystate], yystos_[yystate],
yysemantic_stack_[0], yylocation_stack_[0]); yystack_[0].value, yystack_[0].location);
yypop_ (); yypop_ ();
yystate = yystate_stack_[0]; yystate = yystack_[0].state;
YY_STACK_PRINT (); YY_STACK_PRINT ();
} }
yyerror_range[1] = yylloc; yyerror_range[1].location = yylloc;
// Using YYLLOC is tempting, but would change the location of // Using YYLLOC is tempting, but would change the location of
// the lookahead. YYLOC is available though. // the lookahead. YYLOC is available though.
YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
/* Shift the error token. */ /* Shift the error token. */
YY_SYMBOL_PRINT ("Shifting", yystos_[yyn], YY_SYMBOL_PRINT ("Shifting", yystos_[yyn],
yysemantic_stack_[0], yylocation_stack_[0]); yystack_[0].value, yystack_[0].location);
yystate = yyn; yystate = yyn;
yypush_ (yystate, yylval, yyloc); yypush_ (yystate, yylval, yyloc);
@@ -971,12 +1079,11 @@ b4_error_verbose_if([, yytoken])[));
/* Do not reclaim the symbols of the rule which action triggered /* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */ this YYABORT or YYACCEPT. */
yypop_ (yylen); yypop_ (yylen);
while (yystate_stack_.size () != 1) while (yystack_.size () != 1)
{ {
yydestruct_ ("Cleanup: popping", yydestruct_ ("Cleanup: popping",
yystos_[yystate_stack_[0]], yystos_[yystack_[0].state],
yysemantic_stack_[0], yystack_[0].value, yystack_[0].location);
yylocation_stack_[0]);
yypop_ (); yypop_ ();
} }
@@ -985,8 +1092,8 @@ b4_error_verbose_if([, yytoken])[));
// Generate an error message. // Generate an error message.
std::string std::string
]b4_parser_class_name[::yysyntax_error_ (int yystate]dnl ]b4_parser_class_name[::yysyntax_error_ (int yystate, int]dnl
b4_error_verbose_if([, int tok])[) b4_error_verbose_if([ tok])[)
{ {
std::string res; std::string res;
YYUSE (yystate); YYUSE (yystate);
@@ -1037,83 +1144,43 @@ b4_error_verbose_if([, int tok])[)
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */ STATE-NUM. */
const ]b4_int_type(b4_pact_ninf, b4_pact_ninf) b4_parser_class_name::yypact_ninf_ = b4_pact_ninf[; const ]b4_int_type(b4_pact_ninf, b4_pact_ninf) b4_parser_class_name::yypact_ninf_ = b4_pact_ninf[;
const ]b4_int_type_for([b4_pact])[ ]b4_table_define([pact], [b4_pact])[;
]b4_parser_class_name[::yypact_[] =
{
]b4_pact[
};
/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE /* 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 doesn't specify something else to do. Zero means the default is an
error. */ error. */
const ]b4_int_type_for([b4_defact])[ ]b4_table_define([defact], [b4_defact])[;
]b4_parser_class_name[::yydefact_[] =
{
]b4_defact[
};
/* YYPGOTO[NTERM-NUM]. */ /* YYPGOTO[NTERM-NUM]. */
const ]b4_int_type_for([b4_pgoto])[ ]b4_table_define([pgoto], [b4_pgoto])[;
]b4_parser_class_name[::yypgoto_[] =
{
]b4_pgoto[
};
/* YYDEFGOTO[NTERM-NUM]. */ /* YYDEFGOTO[NTERM-NUM]. */
const ]b4_int_type_for([b4_defgoto])[ ]b4_table_define([defgoto], [b4_defgoto])[;
]b4_parser_class_name[::yydefgoto_[] =
{
]b4_defgoto[
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says. */ number is the opposite. If zero, do what YYDEFACT says. */
const ]b4_int_type(b4_table_ninf, b4_table_ninf) b4_parser_class_name::yytable_ninf_ = b4_table_ninf[; const ]b4_int_type(b4_table_ninf, b4_table_ninf) b4_parser_class_name::yytable_ninf_ = b4_table_ninf[;
const ]b4_int_type_for([b4_table])[ ]b4_table_define([table], [b4_table])[;
]b4_parser_class_name[::yytable_[] =
{
]b4_table[
};
/* YYCHECK. */ /* YYCHECK. */
const ]b4_int_type_for([b4_check])[ ]b4_table_define([check], [b4_check])[;
]b4_parser_class_name[::yycheck_[] =
{
]b4_check[
};
/* STOS_[STATE-NUM] -- The (internal number of the) accessing /* STOS_[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */ symbol of state STATE-NUM. */
const ]b4_int_type_for([b4_stos])[ ]b4_table_define([stos], [b4_stos])[;
]b4_parser_class_name[::yystos_[] =
{
]b4_stos[
};
#if YYDEBUG #if YYDEBUG
/* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding
to YYLEX-NUM. */ to YYLEX-NUM. */
const ]b4_int_type_for([b4_toknum])[ ]b4_table_define([token_number], [b4_toknum])[;
]b4_parser_class_name[::yytoken_number_[] =
{
]b4_toknum[
};
#endif #endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
const ]b4_int_type_for([b4_r1])[ ]b4_table_define([r1], [b4_r1])[;
]b4_parser_class_name[::yyr1_[] =
{
]b4_r1[
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
const ]b4_int_type_for([b4_r2])[ ]b4_table_define([r2], [b4_r2])[;
]b4_parser_class_name[::yyr2_[] =
{
]b4_r2[
};
#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
@@ -1127,35 +1194,25 @@ b4_error_verbose_if([, int tok])[)
#if YYDEBUG #if YYDEBUG
/* YYRHS -- A `-1'-separated list of the rules' RHS. */ /* YYRHS -- A `-1'-separated list of the rules' RHS. */
const ]b4_parser_class_name[::rhs_number_type ]b4_table_define([rhs], [b4_rhs])[;
]b4_parser_class_name[::yyrhs_[] =
{
]b4_rhs[
};
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */ YYRHS. */
const ]b4_int_type_for([b4_prhs])[ ]b4_table_define([prhs], [b4_prhs])[;
]b4_parser_class_name[::yyprhs_[] =
{
]b4_prhs[
};
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
const ]b4_int_type_for([b4_rline])[ ]b4_table_define([rline], [b4_rline])[;
]b4_parser_class_name[::yyrline_[] =
{
]b4_rline[
};
// Print the state stack on the debug stream. // Print the state stack on the debug stream.
void void
]b4_parser_class_name[::yystack_print_ () ]b4_parser_class_name[::yystack_print_ ()
{ {
*yycdebug_ << "Stack now"; *yycdebug_ << "Stack now";
for (state_stack_type::const_iterator i = yystate_stack_.begin (); for (stack_type::const_iterator
i != yystate_stack_.end (); ++i) i = yystack_.begin (),
*yycdebug_ << ' ' << *i; i_end = yystack_.end ();
i != i_end; ++i)
*yycdebug_ << ' ' << i->state;
*yycdebug_ << std::endl; *yycdebug_ << std::endl;
} }
@@ -1207,8 +1264,7 @@ b4_error_verbose_if([, int tok])[)
]b4_namespace_close[ ]b4_namespace_close[
]b4_epilogue ]b4_epilogue[]dnl
dnl
@output(b4_dir_prefix[]stack.hh@)@ @output(b4_dir_prefix[]stack.hh@)@
b4_copyright([Stack handling for Bison parsers in C++])[ b4_copyright([Stack handling for Bison parsers in C++])[

View File

@@ -581,7 +581,7 @@ EOF
} }
else else
{ {
# Not using Boost variants. # Not using Bison variants.
print $out <<'EOF'; print $out <<'EOF';
%union {int ival; std::string* sval;} %union {int ival; std::string* sval;}
%token <sval> TEXT %token <sval> TEXT
@@ -810,13 +810,13 @@ sub bench_variant_parser ()
bench_grammar bench_grammar
('variant', ('variant',
( (
"f-union" => ['%skeleton "lalr1-fusion.cc"'], "f-union" => ['%skeleton "lalr1.cc"'],
"f-uni-deb" => ['%skeleton "lalr1-fusion.cc"', '%debug'], "f-uni-deb" => ['%skeleton "lalr1.cc"', '%debug'],
"f-var" => ['%skeleton "lalr1-fusion.cc"', '%define variant'], "f-var" => ['%skeleton "lalr1.cc"', '%define variant'],
"f-var-deb" => ['%skeleton "lalr1-fusion.cc"', '%debug', '%define variant'], "f-var-deb" => ['%skeleton "lalr1.cc"', '%debug', '%define variant'],
"f-var-dtr" => ['%skeleton "lalr1-fusion.cc"', '%define variant', "%code {\n#define VARIANT_DESTROY\n}"], "f-var-dtr" => ['%skeleton "lalr1.cc"', '%define variant', "%code {\n#define VARIANT_DESTROY\n}"],
"f-var-deb-dtr" => ['%skeleton "lalr1-fusion.cc"', '%debug', '%define variant', "%code {\n#define VARIANT_DESTROY\n}"], "f-var-deb-dtr" => ['%skeleton "lalr1.cc"', '%debug', '%define variant', "%code {\n#define VARIANT_DESTROY\n}"],
"f-var-deb-dtr-ass" => ['%skeleton "lalr1-fusion.cc"', '%debug', '%define variant', "%code {\n#define VARIANT_DESTROY\n}", "%define assert"], "f-var-deb-dtr-ass" => ['%skeleton "lalr1.cc"', '%debug', '%define variant', "%code {\n#define VARIANT_DESTROY\n}", "%define assert"],
) )
); );
} }
@@ -834,8 +834,8 @@ sub bench_fusion_parser ()
bench_grammar bench_grammar
('variant', ('variant',
( (
"split" => [], "split" => ['%skeleton "lalr1-split.cc"'],
"fused" => ['%skeleton "lalr1-fusion.cc"'], "fused" => ['%skeleton "lalr1.cc"'],
) )
); );
} }