Extract variant.hh

* data/variant.hh: New, extracted from...
	* data/lalr1.cc: here.
	Adjust.
	* data/local.mk: Adjust.
This commit is contained in:
Akim Demaille
2008-12-23 10:44:53 +01:00
parent 51bacae6b5
commit 507aa0e2a8
4 changed files with 224 additions and 179 deletions

View File

@@ -1,3 +1,11 @@
2009-02-19 Akim Demaille <demaille@gostai.com>
Extract variant.hh
* data/variant.hh: New, extracted from...
* data/lalr1.cc: here.
Adjust.
* data/local.mk: Adjust.
2009-02-19 Akim Demaille <demaille@gostai.com> 2009-02-19 Akim Demaille <demaille@gostai.com>
Extract stack.hh from lalr1.cc. Extract stack.hh from lalr1.cc.

View File

@@ -42,27 +42,10 @@ m4_define([b4_integral_parser_table_define],
# b4_symbol_value_template(VAL, [TYPE]) # b4_symbol_value_template(VAL, [TYPE])
# ------------------------------------- # -------------------------------------
# Same as b4_symbol_value, but used in a template method. # Same as b4_symbol_value, but used in a template method. It makes
# a difference when using variants.
m4_copy([b4_symbol_value], [b4_symbol_value_template]) m4_copy([b4_symbol_value], [b4_symbol_value_template])
# How the semantic value is extracted when using variants.
b4_variant_if([
# b4_symbol_value(VAL, [TYPE])
# ----------------------------
m4_define([b4_symbol_value],
[m4_ifval([$2],
[$1.as< $2 >()],
[$1])])
# b4_symbol_value_template(VAL, [TYPE])
# -------------------------------------
# Same as b4_symbol_value, but used in a template method.
m4_define([b4_symbol_value_template],
[m4_ifval([$2],
[$1.template as< $2 >()],
[$1])])
]) # b4_variant_if
# b4_lex_symbol_if([IF-YYLEX-RETURNS-A-COMPLETE-SYMBOL], [IF-NOT]) # b4_lex_symbol_if([IF-YYLEX-RETURNS-A-COMPLETE-SYMBOL], [IF-NOT])
# ---------------------------------------------------------------- # ----------------------------------------------------------------
@@ -80,14 +63,14 @@ m4_define([b4_assert_if],
# -------------------- # --------------------
# Expansion of $<TYPE>$. # Expansion of $<TYPE>$.
m4_define([b4_lhs_value], m4_define([b4_lhs_value],
[b4_symbol_value([yylhs.value], [$1])]) [b4_symbol_value([yylhs.value], [$1])])
# b4_lhs_location() # b4_lhs_location()
# ----------------- # -----------------
# Expansion of @$. # Expansion of @$.
m4_define([b4_lhs_location], m4_define([b4_lhs_location],
[yylhs.location]) [yylhs.location])
# b4_rhs_data(RULE-LENGTH, NUM) # b4_rhs_data(RULE-LENGTH, NUM)
@@ -121,6 +104,7 @@ m4_define([b4_rhs_value],
m4_define([b4_rhs_location], m4_define([b4_rhs_location],
[b4_rhs_data([$1], [$2]).location]) [b4_rhs_data([$1], [$2]).location])
# b4_symbol_action(SYMBOL-NUM, KIND) # b4_symbol_action(SYMBOL-NUM, KIND)
# ---------------------------------- # ----------------------------------
# Run the action KIND (destructor or printer) for SYMBOL-NUM. # Run the action KIND (destructor or printer) for SYMBOL-NUM.
@@ -287,60 +271,6 @@ m4_define([b4_symbol_constructor_definitions],
b4_symbol_foreach([b4_symbol_constructor_definition_])])]) b4_symbol_foreach([b4_symbol_constructor_definition_])])])
# b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS])
# ------------------------------------------------
# Run some ACTION ("build", or "destroy") on YYVAL of symbol type
# YYTYPE.
m4_define([b4_symbol_variant],
[m4_pushdef([b4_dollar_dollar],
[$2.$3< $][3 >(m4_shift3($@))])dnl
switch ($1)
{
b4_type_foreach([b4_type_action_])[]dnl
default:
break;
}
m4_popdef([b4_dollar_dollar])dnl
])
# _b4_char_sizeof_counter
# -----------------------
# A counter used by _b4_char_sizeof_dummy to create fresh symbols.
m4_define([_b4_char_sizeof_counter],
[0])
# _b4_char_sizeof_dummy
# ---------------------
# At each call return a new C++ identifier.
m4_define([_b4_char_sizeof_dummy],
[m4_define([_b4_char_sizeof_counter], m4_incr(_b4_char_sizeof_counter))dnl
dummy[]_b4_char_sizeof_counter])
# b4_char_sizeof_(SYMBOL-NUM)
# ---------------------------
# A comment describing this symbol.
m4_define([b4_char_sizeof_],
[ // b4_symbol([$1], [tag])
])
# b4_char_sizeof(SYMBOL-NUMS)
# --------------------------
# To be mapped on the list of type names to produce:
#
# char dummy1[sizeof(type_name_1)];
# char dummy2[sizeof(type_name_2)];
#
# for defined type names.
m4_define([b4_char_sizeof],
[b4_symbol_if([$1], [has_type],
[
m4_map([b4_char_sizeof_], [$@])dnl
char _b4_char_sizeof_dummy@{sizeof([b4_symbol([$1], [type])])@};
])])
# b4_yytranslate_definition # b4_yytranslate_definition
# ------------------------- # -------------------------
# Define yytranslate_. Sometimes we want it in the header file, # Define yytranslate_. Sometimes we want it in the header file,
@@ -385,6 +315,7 @@ b4_locations_if(
m4_define([b4_location_constructors]) m4_define([b4_location_constructors])
m4_include(b4_pkgdatadir/[location.cc])]) m4_include(b4_pkgdatadir/[location.cc])])
m4_include(b4_pkgdatadir/[stack.hh]) m4_include(b4_pkgdatadir/[stack.hh])
b4_variant_if([m4_include(b4_pkgdatadir/[variant.hh])])
# We do want M4 expansion after # for CPP macros. # We do want M4 expansion after # for CPP macros.
m4_changecom() m4_changecom()
@@ -408,109 +339,7 @@ dnl FIXME: This is wrong, we want computed header guards.
]b4_namespace_open[ ]b4_namespace_open[
]b4_locations_if([ class position; ]b4_locations_if([ class position;
class location;])[ class location;])[
]b4_variant_if( ]b4_variant_if([b4_variant_definition])[
[[
/// A char[S] buffer to store and retrieve objects.
///
/// Sort of a variant, but does not keep track of the nature
/// of the stored data, since that knowledge is available
/// via the current state.
template <size_t S>
struct variant
{]b4_assert_if([
/// Whether something is contained.
bool built;
])[
/// Empty construction.
inline
variant ()]b4_assert_if([
: built(false)])[
{}
/// Instantiate a \a T in here.
template <typename T>
inline T&
build()
{]b4_assert_if([
assert(!built);
built = true;])[
return *new (buffer.raw) T;
}
/// Instantiate a \a T in here from \a t.
template <typename T>
inline T&
build(const T& t)
{]b4_assert_if([
assert(!built);
built = true;])[
return *new (buffer.raw) T(t);
}
/// Construct and fill.
template <typename T>
inline
variant (const T& t)]b4_assert_if([
: built(true)])[
{
new (buffer.raw) T(t);
}
/// Accessor to a built \a T.
template <typename T>
inline T&
as()
{]b4_assert_if([
assert(built);])[
return reinterpret_cast<T&>(buffer.raw);
}
/// 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.raw);
}
/// 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.
/// Long double is chosen as it has the strongest alignment
/// constraints.
union {
long double align_me;
char raw[S];
} buffer;
};
]])[
]b4_namespace_close[ ]b4_namespace_close[
]b4_locations_if([#include "location.hh"])[ ]b4_locations_if([#include "location.hh"])[
@@ -1202,7 +1031,7 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
/* Variants are always initialized to an empty instance of the /* Variants are always initialized to an empty instance of the
correct type. The default $$=$1 rule is NOT applied when using correct type. The default $$=$1 rule is NOT applied when using
variants */ variants */
]b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])[],[ ]b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build]),[
/* If YYLEN is nonzero, implement the default value of the action: /* If YYLEN is nonzero, implement the default value of the action:
`$$ = $1'. Otherwise, use the top of the stack. `$$ = $1'. Otherwise, use the top of the stack.

View File

@@ -28,6 +28,7 @@ dist_pkgdata_DATA = \
data/lalr1.java \ data/lalr1.java \
data/location.cc \ data/location.cc \
data/stack.hh \ data/stack.hh \
data/variant.hh \
data/yacc.c data/yacc.c
m4sugardir = $(pkgdatadir)/m4sugar m4sugardir = $(pkgdatadir)/m4sugar

207
data/variant.hh Normal file
View File

@@ -0,0 +1,207 @@
# C++ skeleton for Bison
# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
# 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
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
## --------- ##
## variant. ##
## --------- ##
# b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS])
# ------------------------------------------------
# Run some ACTION ("build", or "destroy") on YYVAL of symbol type
# YYTYPE.
m4_define([b4_symbol_variant],
[m4_pushdef([b4_dollar_dollar],
[$2.$3< $][3 >(m4_shift3($@))])dnl
switch ($1)
{
b4_type_foreach([b4_type_action_])[]dnl
default:
break;
}
m4_popdef([b4_dollar_dollar])dnl
])
# _b4_char_sizeof_counter
# -----------------------
# A counter used by _b4_char_sizeof_dummy to create fresh symbols.
m4_define([_b4_char_sizeof_counter],
[0])
# _b4_char_sizeof_dummy
# ---------------------
# At each call return a new C++ identifier.
m4_define([_b4_char_sizeof_dummy],
[m4_define([_b4_char_sizeof_counter], m4_incr(_b4_char_sizeof_counter))dnl
dummy[]_b4_char_sizeof_counter])
# b4_char_sizeof_(SYMBOL-NUM)
# ---------------------------
# A comment describing this symbol.
m4_define([b4_char_sizeof_],
[ // b4_symbol([$1], [tag])
])
# b4_char_sizeof(SYMBOL-NUMS)
# ---------------------------
# To be mapped on the list of type names to produce:
#
# char dummy1[sizeof(type_name_1)];
# char dummy2[sizeof(type_name_2)];
#
# for defined type names.
m4_define([b4_char_sizeof],
[b4_symbol_if([$1], [has_type],
[
m4_map([b4_char_sizeof_], [$@])dnl
char _b4_char_sizeof_dummy@{sizeof([b4_symbol([$1], [type])])@};
])])
# b4_variant_definition
# ---------------------
# Define "variant".
m4_define([b4_variant_definition],
[[
/// A char[S] buffer to store and retrieve objects.
///
/// Sort of a variant, but does not keep track of the nature
/// of the stored data, since that knowledge is available
/// via the current state.
template <size_t S>
struct variant
{]b4_assert_if([
/// Whether something is contained.
bool built;
])[
/// Empty construction.
inline
variant ()]b4_assert_if([
: built (false)])[
{}
/// Instantiate a \a T in here.
template <typename T>
inline T&
build ()
{]b4_assert_if([
assert (!built);
built = true;])[
return *new (buffer.raw) T;
}
/// Instantiate a \a T in here from \a t.
template <typename T>
inline T&
build (const T& t)
{]b4_assert_if([
assert(!built);
built = true;])[
return *new (buffer.raw) T(t);
}
/// Construct and fill.
template <typename T>
inline
variant (const T& t)]b4_assert_if([
: built (true)])[
{
new (buffer.raw) T(t);
}
/// Accessor to a built \a T.
template <typename T>
inline T&
as ()
{]b4_assert_if([
assert (built);])[
return reinterpret_cast<T&>(buffer.raw);
}
/// 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.raw);
}
/// 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.
/// Long double is chosen as it has the strongest alignment
/// constraints.
union
{
long double align_me;
char raw[S];
} buffer;
};
]])
## -------------------------- ##
## Adjustments for variants. ##
## -------------------------- ##
# How the semantic value is extracted when using variants.
# b4_symbol_value(VAL, [TYPE])
# ----------------------------
m4_define([b4_symbol_value],
[m4_ifval([$2],
[$1.as< $2 >()],
[$1])])
# b4_symbol_value_template(VAL, [TYPE])
# -------------------------------------
# Same as b4_symbol_value, but used in a template method.
m4_define([b4_symbol_value_template],
[m4_ifval([$2],
[$1.template as< $2 >()],
[$1])])