stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,187 @@
/*=============================================================================
Copyright (c) 2002-2003 Joel de Guzman
Copyright (c) 2002-2003 Martin Wille
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_FOR_HPP
#define BOOST_SPIRIT_FOR_HPP
////////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/composite/composite.hpp>
#include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
////////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
namespace impl
{
template <typename FuncT>
struct for_functor
{
typedef typename boost::call_traits<FuncT>::param_type param_t;
for_functor(param_t f) : func(f) {}
for_functor() {}
FuncT func;
};
template <typename InitF>
struct for_init_functor : for_functor<InitF>
{
typedef for_functor<InitF> base_t;
typedef typename base_t::param_t param_t;
for_init_functor(param_t f) : base_t(f) {}
for_init_functor() : base_t() {}
void init() const { /*return*/ this->func(); }
};
template <typename StepF>
struct for_step_functor : for_functor<StepF>
{
typedef for_functor<StepF> base_t;
typedef typename base_t::param_t param_t;
for_step_functor(param_t f) : base_t(f) {}
for_step_functor() : base_t() {}
void step() const { /*return*/ this->func(); }
};
//////////////////////////////////
// for_parser
template
<
typename InitF, typename CondT, typename StepF,
typename ParsableT
>
struct for_parser
: private for_init_functor<InitF>
, private for_step_functor<StepF>
, private condition_evaluator<typename as_parser<CondT>::type>
, public unary
<
typename as_parser<ParsableT>::type,
parser< for_parser<InitF, CondT, StepF, ParsableT> >
>
{
typedef for_parser<InitF, CondT, StepF, ParsableT> self_t;
typedef as_parser<CondT> cond_as_parser_t;
typedef typename cond_as_parser_t::type condition_t;
typedef condition_evaluator<condition_t> eval_t;
typedef as_parser<ParsableT> as_parser_t;
typedef typename as_parser_t::type parser_t;
typedef unary< parser_t, parser< self_t > > base_t;
//////////////////////////////
// constructor, saves init, condition and step functors
// for later use the parse member function
for_parser
(
InitF const &i, CondT const &c, StepF const &s,
ParsableT const &p
)
: for_init_functor<InitF>(i)
, for_step_functor<StepF>(s)
, eval_t(cond_as_parser_t::convert(c))
, base_t(as_parser_t::convert(p))
{ }
for_parser()
: for_init_functor<InitF>()
, for_step_functor<StepF>()
, eval_t()
, base_t()
{}
//////////////////////////////
// parse member function
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const &scan) const
{
typedef typename parser_result<self_t, ScannerT>::type
result_t;
typedef typename parser_result<parser_t, ScannerT>::type
body_result_t;
typename ScannerT::iterator_t save(scan.first);
std::size_t length = 0;
int eval_length = 0;
this->init();
while ((eval_length = this->evaluate(scan))>=0)
{
length += eval_length;
body_result_t tmp(this->subject().parse(scan));
if (tmp)
{
length+=tmp.length();
}
else
{
return scan.no_match();
}
this->step();
}
BOOST_SPIRIT_CLASSIC_NS::nil_t attr;
return scan.create_match
(length, attr, save, scan.first);
}
};
//////////////////////////////////
// for_parser_gen generates takes the body parser in brackets
// and returns the for_parser
template <typename InitF, typename CondT, typename StepF>
struct for_parser_gen
{
for_parser_gen(InitF const &i, CondT const &c, StepF const &s)
: init(i)
, condition(c)
, step(s)
{}
template <typename ParsableT>
for_parser<InitF, CondT, StepF, ParsableT>
operator[](ParsableT const &p) const
{
return for_parser<InitF, CondT, StepF, ParsableT>
(init, condition, step, p);
}
InitF const &init;
CondT const &condition;
StepF const &step;
};
} // namespace impl
//////////////////////////////
// for_p, returns for-parser generator
// Usage: spirit::for_p(init-ftor, condition, step-ftor)[body]
template
<
typename InitF, typename ConditionT, typename StepF
>
impl::for_parser_gen<InitF, ConditionT, StepF>
for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f)
{
return impl::for_parser_gen<InitF, ConditionT, StepF>
(init_f, condition, step_f);
}
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif // BOOST_SPIRIT_FOR_HPP
@@ -0,0 +1,229 @@
/*=============================================================================
Copyright (c) 2002-2003 Joel de Guzman
Copyright (c) 2002 Juan Carlos Arevalo-Baeza
Copyright (c) 2002-2003 Martin Wille
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_IF_HPP
#define BOOST_SPIRIT_IF_HPP
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/composite/composite.hpp>
#include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
namespace impl {
//////////////////////////////////
// if-else-parser, holds two alternative parsers and a conditional functor
// that selects between them.
template <typename ParsableTrueT, typename ParsableFalseT, typename CondT>
struct if_else_parser
: public condition_evaluator<typename as_parser<CondT>::type>
, public binary
<
typename as_parser<ParsableTrueT>::type,
typename as_parser<ParsableFalseT>::type,
parser< if_else_parser<ParsableTrueT, ParsableFalseT, CondT> >
>
{
typedef if_else_parser<ParsableTrueT, ParsableFalseT, CondT> self_t;
typedef as_parser<ParsableTrueT> as_parser_true_t;
typedef as_parser<ParsableFalseT> as_parser_false_t;
typedef typename as_parser_true_t::type parser_true_t;
typedef typename as_parser_false_t::type parser_false_t;
typedef as_parser<CondT> cond_as_parser_t;
typedef typename cond_as_parser_t::type condition_t;
typedef binary<parser_true_t, parser_false_t, parser<self_t> > base_t;
typedef condition_evaluator<condition_t> eval_t;
if_else_parser
(
ParsableTrueT const& p_true,
ParsableFalseT const& p_false,
CondT const& cond_
)
: eval_t(cond_as_parser_t::convert(cond_))
, base_t
(
as_parser_true_t::convert(p_true),
as_parser_false_t::convert(p_false)
)
{ }
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, nil_t>::type type;
};
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
typedef typename parser_result
<parser_true_t, ScannerT>::type then_result_t;
typedef typename parser_result
<parser_false_t, ScannerT>::type else_result_t;
typename ScannerT::iterator_t const save(scan.first);
std::ptrdiff_t length = this->evaluate(scan);
if (length >= 0)
{
then_result_t then_result(this->left().parse(scan));
if (then_result)
{
length += then_result.length();
return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
}
}
else
{
else_result_t else_result(this->right().parse(scan));
if (else_result)
{
length = else_result.length();
return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
}
}
return scan.no_match();
}
};
//////////////////////////////////
// if-else-parser generator, takes the false-parser in brackets
// and returns the if-else-parser.
template <typename ParsableTrueT, typename CondT>
struct if_else_parser_gen
{
if_else_parser_gen(ParsableTrueT const& p_true_, CondT const& cond_)
: p_true(p_true_)
, cond(cond_) {}
template <typename ParsableFalseT>
if_else_parser
<
ParsableTrueT,
ParsableFalseT,
CondT
>
operator[](ParsableFalseT const& p_false) const
{
return if_else_parser<ParsableTrueT, ParsableFalseT, CondT>
(
p_true,
p_false,
cond
);
}
ParsableTrueT const &p_true;
CondT const &cond;
};
//////////////////////////////////
// if-parser, conditionally runs a parser is a functor condition is true.
// If the condition is fales, it fails the parse.
// It can optionally become an if-else-parser through the member else_p.
template <typename ParsableT, typename CondT>
struct if_parser
: public condition_evaluator<typename as_parser<CondT>::type>
, public unary
<
typename as_parser<ParsableT>::type,
parser<if_parser<ParsableT, CondT> > >
{
typedef if_parser<ParsableT, CondT> self_t;
typedef as_parser<ParsableT> as_parser_t;
typedef typename as_parser_t::type parser_t;
typedef as_parser<CondT> cond_as_parser_t;
typedef typename cond_as_parser_t::type condition_t;
typedef condition_evaluator<condition_t> eval_t;
typedef unary<parser_t, parser<self_t> > base_t;
if_parser(ParsableT const& p, CondT const& cond_)
: eval_t(cond_as_parser_t::convert(cond_))
, base_t(as_parser_t::convert(p))
, else_p(p, cond_)
{}
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, nil_t>::type type;
};
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
typedef typename parser_result<parser_t, ScannerT>::type t_result_t;
typename ScannerT::iterator_t const save(scan.first);
std::ptrdiff_t length = this->evaluate(scan);
if (length >= 0)
{
t_result_t then_result(this->subject().parse(scan));
if (then_result)
{
length += then_result.length();
return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
}
return scan.no_match();
}
return scan.empty_match();
}
if_else_parser_gen<ParsableT, CondT> else_p;
};
//////////////////////////////////
// if-parser generator, takes the true-parser in brackets and returns the
// if-parser.
template <typename CondT>
struct if_parser_gen
{
if_parser_gen(CondT const& cond_) : cond(cond_) {}
template <typename ParsableT>
if_parser
<
ParsableT,
CondT
>
operator[](ParsableT const& subject) const
{
return if_parser<ParsableT, CondT>(subject, cond);
}
CondT const &cond;
};
} // namespace impl
//////////////////////////////////
// if_p function, returns "if" parser generator
template <typename CondT>
impl::if_parser_gen<CondT>
if_p(CondT const& cond)
{
return impl::if_parser_gen<CondT>(cond);
}
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif // BOOST_SPIRIT_IF_HPP
@@ -0,0 +1,97 @@
/*=============================================================================
Copyright (c) 2002-2003 Martin Wille
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_CONDITIONS_IPP
#define BOOST_SPIRIT_CONDITIONS_IPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/meta/parser_traits.hpp>
#include <boost/spirit/home/classic/core/composite/epsilon.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
namespace impl {
///////////////////////////////////////////////////////////////////////////////
//
// condition evaluation
//
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////
// condition_parser_selector, decides which parser to use for a condition
// If the template argument is a parser then that parser is used.
// If the template argument is a functor then a condition parser using
// the functor is chosen
template <typename T> struct embed_t_accessor
{
typedef typename T::embed_t type;
};
template <typename ConditionT>
struct condition_parser_selector
{
typedef
typename mpl::if_<
is_parser<ConditionT>,
ConditionT,
condition_parser<ConditionT>
>::type
type;
typedef typename embed_t_accessor<type>::type embed_t;
};
//////////////////////////////////
// condition_evaluator, uses a parser to check wether a condition is met
// takes a parser or a functor that can be evaluated in boolean context
// as template parameter.
// JDG 4-15-03 refactored
template <typename ConditionT>
struct condition_evaluator
{
typedef condition_parser_selector<ConditionT> selector_t;
typedef typename selector_t::type selected_t;
typedef typename selector_t::embed_t cond_embed_t;
typedef typename boost::call_traits<cond_embed_t>::param_type
param_t;
condition_evaluator(param_t s) : cond(s) {}
/////////////////////////////
// evaluate, checks wether condition is met
// returns length of a match or a negative number for no-match
template <typename ScannerT>
std::ptrdiff_t
evaluate(ScannerT const &scan) const
{
typedef typename ScannerT::iterator_t iterator_t;
typedef typename parser_result<selected_t, ScannerT>::type cres_t;
iterator_t save(scan.first);
cres_t result = cond.parse(scan);
if (!result) // reset the position if evaluation
scan.first = save; // fails.
return result.length();
}
cond_embed_t cond;
};
///////////////////////////////////////////////////////////////////////////////
} // namespace impl
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit
#endif
@@ -0,0 +1,120 @@
/*=============================================================================
Copyright (c) 2003 Hartmut Kaiser
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_SELECT_IPP
#define BOOST_SPIRIT_SELECT_IPP
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/composite/composite.hpp>
#include <boost/spirit/home/classic/meta/as_parser.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
namespace impl {
///////////////////////////////////////////////////////////////////////////////
template <typename ParserT>
struct as_embedded_parser : public as_parser<ParserT>
{
typedef typename as_parser<ParserT>::type::derived_t::embed_t type;
};
///////////////////////////////////////////////////////////////////////////////
// no implementation here to catch unknown BehaviourT template arguments
template <typename ResultT, typename BehaviourT>
struct select_match_gen;
// implementation for the select_default_no_fail behaviour
template <typename ResultT>
struct select_match_gen<ResultT, select_default_no_fail> {
template <typename ScannerT>
static ResultT
do_ (ScannerT const &scan)
{
return scan.create_match(0, -1, scan.first, scan.first);
}
};
// implementation for the select_default_fail behaviour
template <typename ResultT>
struct select_match_gen<ResultT, select_default_fail> {
template <typename ScannerT>
static ResultT
do_ (ScannerT const &scan)
{
return scan.no_match();
}
};
///////////////////////////////////////////////////////////////////////////////
template <int N, typename ResultT, typename TupleT, typename BehaviourT>
struct parse_tuple_element {
BOOST_STATIC_CONSTANT(int, index = (TupleT::length - N));
template <typename ScannerT>
static ResultT
do_(TupleT const &t, ScannerT const &scan)
{
typedef typename ::phoenix::tuple_element<index, TupleT>::type parser_t;
typedef typename ScannerT::iterator_t iterator_t;
typedef typename parser_result<parser_t, ScannerT>::type result_t;
iterator_t save(scan.first);
result_t result(t[::phoenix::tuple_index<index>()].parse(scan));
if (result) {
return scan.create_match(result.length(), TupleT::length - N,
save, scan.first);
}
scan.first = save; // reset the input stream
return parse_tuple_element<N-1, ResultT, TupleT, BehaviourT>::
do_(t, scan);
}
};
template <typename ResultT, typename TupleT, typename BehaviourT>
struct parse_tuple_element<1, ResultT, TupleT, BehaviourT> {
BOOST_STATIC_CONSTANT(int, index = (TupleT::length - 1));
template <typename ScannerT>
static ResultT
do_(TupleT const &t, ScannerT const &scan)
{
typedef typename ::phoenix::tuple_element<index, TupleT>::type parser_t;
typedef typename ScannerT::iterator_t iterator_t;
typedef typename parser_result<parser_t, ScannerT>::type result_t;
iterator_t save(scan.first);
result_t result(t[::phoenix::tuple_index<index>()].parse(scan));
if (result) {
return scan.create_match(result.length(), TupleT::length - 1,
save, scan.first);
}
scan.first = save; // reset the input stream
return select_match_gen<ResultT, BehaviourT>::do_(scan);
}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace impl
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit
#endif // BOOST_SPIRIT_SELECT_IPP
@@ -0,0 +1,574 @@
/*=============================================================================
Copyright (c) 2003 Hartmut Kaiser
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_SWITCH_IPP
#define BOOST_SPIRIT_SWITCH_IPP
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/inc.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/repeat_from_to.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
#include <boost/spirit/home/classic/core/composite/composite.hpp>
#include <boost/spirit/home/classic/meta/as_parser.hpp>
#include <boost/spirit/home/classic/phoenix/actor.hpp>
#include <boost/spirit/home/classic/phoenix/tuples.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
// forward declaration
template <int N, typename ParserT, bool IsDefault> struct case_parser;
///////////////////////////////////////////////////////////////////////////////
namespace impl {
///////////////////////////////////////////////////////////////////////////////
// parse helper functions
template <typename ParserT, typename ScannerT>
inline typename parser_result<ParserT, ScannerT>::type
delegate_parse(ParserT const &p, ScannerT const &scan,
typename ScannerT::iterator_t const save)
{
typedef typename parser_result<ParserT, ScannerT>::type result_t;
result_t result (p.subject().parse(scan));
if (!result)
scan.first = save;
return result;
}
///////////////////////////////////////////////////////////////////////////////
// General default case handling (no default_p case branch given).
// First try to match the current parser node (if the condition value is
// matched) and, if that fails, return a no_match
template <int N, bool IsDefault, bool HasDefault>
struct default_delegate_parse {
template <
typename ParserT, typename DefaultT,
typename ValueT, typename ScannerT
>
static typename parser_result<ParserT, ScannerT>::type
parse (ValueT const &value, ParserT const &p, DefaultT const &,
ScannerT const &scan, typename ScannerT::iterator_t const save)
{
if (value == N)
return delegate_parse(p, scan, save);
return scan.no_match();
}
};
// The current case parser node is the default parser.
// Ignore the given case value and try to match the given default parser.
template <int N, bool HasDefault>
struct default_delegate_parse<N, true, HasDefault> {
template <
typename ParserT, typename DefaultT,
typename ValueT, typename ScannerT
>
static typename parser_result<ParserT, ScannerT>::type
parse (ValueT const& /*value*/, ParserT const &, DefaultT const &d,
ScannerT const &scan, typename ScannerT::iterator_t const save)
{
// Since there is a default_p case branch defined, the corresponding
// parser shouldn't be the nothing_parser
BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
return delegate_parse(d, scan, save);
}
};
// The current case parser node is not the default parser, but there is a
// default_p branch given inside the switch_p parser.
// First try to match the current parser node (if the condition value is
// matched) and, if that fails, match the given default_p parser.
template <int N>
struct default_delegate_parse<N, false, true> {
template <
typename ParserT, typename DefaultT,
typename ValueT, typename ScannerT
>
static typename parser_result<ParserT, ScannerT>::type
parse (ValueT const &value, ParserT const &p, DefaultT const &d,
ScannerT const &scan, typename ScannerT::iterator_t const save)
{
// Since there is a default_p case branch defined, the corresponding
// parser shouldn't be the nothing_parser
BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
if (value == N)
return delegate_parse(p, scan, save);
return delegate_parse(d, scan, save);
}
};
///////////////////////////////////////////////////////////////////////////////
// Look through the case parser chain to test, if there is a default case
// branch defined (returned by 'value').
template <typename CaseT, bool IsSimple = CaseT::is_simple>
struct default_case;
////////////////////////////////////////
template <typename ResultT, bool IsDefault>
struct get_default_parser {
template <typename ParserT>
static ResultT
get(parser<ParserT> const &p)
{
return default_case<typename ParserT::derived_t::left_t>::
get(p.derived().left());
}
};
template <typename ResultT>
struct get_default_parser<ResultT, true> {
template <typename ParserT>
static ResultT
get(parser<ParserT> const &p) { return p.derived().right(); }
};
////////////////////////////////////////
template <typename CaseT, bool IsSimple>
struct default_case {
// The 'value' constant is true, if the current case_parser or one of its
// left siblings is a default_p generated case_parser.
BOOST_STATIC_CONSTANT(bool, value =
(CaseT::is_default || default_case<typename CaseT::left_t>::value));
// The 'is_epsilon' constant is true, if the current case_parser or one of
// its left siblings is a default_p generated parser with an attached
// epsilon_p (this is generated by the plain default_p).
BOOST_STATIC_CONSTANT(bool, is_epsilon = (
(CaseT::is_default && CaseT::is_epsilon) ||
default_case<typename CaseT::left_t>::is_epsilon
));
// The computed 'type' represents the type of the default case branch
// parser (if there is one) or nothing_parser (if there isn't any default
// case branch).
typedef typename boost::mpl::if_c<
CaseT::is_default, typename CaseT::right_embed_t,
typename default_case<typename CaseT::left_t>::type
>::type type;
// The get function returns the parser attached to the default case branch
// (if there is one) or an instance of a nothing_parser (if there isn't
// any default case branch).
template <typename ParserT>
static type
get(parser<ParserT> const &p)
{ return get_default_parser<type, CaseT::is_default>::get(p); }
};
////////////////////////////////////////
template <typename ResultT, bool IsDefault>
struct get_default_parser_simple {
template <typename ParserT>
static ResultT
get(parser<ParserT> const &p) { return p.derived(); }
};
template <typename ResultT>
struct get_default_parser_simple<ResultT, false> {
template <typename ParserT>
static nothing_parser
get(parser<ParserT> const &) { return nothing_p; }
};
////////////////////////////////////////
// Specialization of the default_case template for the last (leftmost) element
// of the case parser chain.
template <typename CaseT>
struct default_case<CaseT, true> {
// The 'value' and 'is_epsilon' constant, the 'type' type and the function
// 'get' are described above.
BOOST_STATIC_CONSTANT(bool, value = CaseT::is_default);
BOOST_STATIC_CONSTANT(bool, is_epsilon = (
CaseT::is_default && CaseT::is_epsilon
));
typedef typename boost::mpl::if_c<
CaseT::is_default, CaseT, nothing_parser
>::type type;
template <typename ParserT>
static type
get(parser<ParserT> const &p)
{ return get_default_parser_simple<type, value>::get(p); }
};
///////////////////////////////////////////////////////////////////////////////
// The case_chain template calculates recursivly the depth of the left
// subchain of the given case branch node.
template <typename CaseT, bool IsSimple = CaseT::is_simple>
struct case_chain {
BOOST_STATIC_CONSTANT(int, depth = (
case_chain<typename CaseT::left_t>::depth + 1
));
};
template <typename CaseT>
struct case_chain<CaseT, true> {
BOOST_STATIC_CONSTANT(int, depth = 0);
};
///////////////////////////////////////////////////////////////////////////////
// The chain_parser template is used to extract the type and the instance of
// a left or a right parser, burried arbitrary deep inside the case parser
// chain.
template <int Depth, typename CaseT>
struct chain_parser {
typedef typename CaseT::left_t our_left_t;
typedef typename chain_parser<Depth-1, our_left_t>::left_t left_t;
typedef typename chain_parser<Depth-1, our_left_t>::right_t right_t;
static left_t
left(CaseT const &p)
{ return chain_parser<Depth-1, our_left_t>::left(p.left()); }
static right_t
right(CaseT const &p)
{ return chain_parser<Depth-1, our_left_t>::right(p.left()); }
};
template <typename CaseT>
struct chain_parser<1, CaseT> {
typedef typename CaseT::left_t left_t;
typedef typename CaseT::right_t right_t;
static left_t left(CaseT const &p) { return p.left(); }
static right_t right(CaseT const &p) { return p.right(); }
};
template <typename CaseT>
struct chain_parser<0, CaseT>; // shouldn't be instantiated
///////////////////////////////////////////////////////////////////////////////
// Type computing meta function for calculating the type of the return value
// of the used conditional switch expression
template <typename TargetT, typename ScannerT>
struct condition_result {
typedef typename TargetT::template result<ScannerT>::type type;
};
///////////////////////////////////////////////////////////////////////////////
template <typename LeftT, typename RightT, bool IsDefault>
struct compound_case_parser
: public binary<LeftT, RightT,
parser<compound_case_parser<LeftT, RightT, IsDefault> > >
{
typedef compound_case_parser<LeftT, RightT, IsDefault> self_t;
typedef binary_parser_category parser_category_t;
typedef binary<LeftT, RightT, parser<self_t> > base_t;
BOOST_STATIC_CONSTANT(int, value = RightT::value);
BOOST_STATIC_CONSTANT(bool, is_default = IsDefault);
BOOST_STATIC_CONSTANT(bool, is_simple = false);
BOOST_STATIC_CONSTANT(bool, is_epsilon = (
is_default &&
boost::is_same<typename RightT::subject_t, epsilon_parser>::value
));
compound_case_parser(parser<LeftT> const &lhs, parser<RightT> const &rhs)
: base_t(lhs.derived(), rhs.derived())
{}
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, nil_t>::type type;
};
template <typename ScannerT, typename CondT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan, CondT const &cond) const;
template <int N1, typename ParserT1, bool IsDefault1>
compound_case_parser<
self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1
>
operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const
{
// If the following compile time assertion fires, you've probably used
// more than one default_p case inside the switch_p parser construct.
BOOST_STATIC_ASSERT(!default_case<self_t>::value || !IsDefault1);
// If this compile time assertion fires, you've probably want to use
// more case_p/default_p case branches, than possible.
BOOST_STATIC_ASSERT(
case_chain<self_t>::depth < BOOST_SPIRIT_SWITCH_CASE_LIMIT
);
typedef case_parser<N1, ParserT1, IsDefault1> right_t;
return compound_case_parser<self_t, right_t, IsDefault1>(*this, p);
}
};
///////////////////////////////////////////////////////////////////////////////
// The parse_switch::do_ functions dispatch to the correct parser, which is
// selected through the given conditional switch value.
template <int Value, int Depth, bool IsDefault>
struct parse_switch;
///////////////////////////////////////////////////////////////////////////////
//
// The following generates a couple of parse_switch template specializations
// with an increasing number of handled case branches (for 1..N).
//
// template <int Value, bool IsDefault>
// struct parse_switch<Value, N, IsDefault> {
//
// template <typename ParserT, typename ScannerT>
// static typename parser_result<ParserT, ScannerT>::type
// do_(ParserT const &p, ScannerT const &scan, long cond_value,
// typename ScannerT::iterator_t const &save)
// {
// typedef ParserT left_t0;
// typedef typename left_t0::left left_t1;
// ...
//
// switch (cond_value) {
// case left_tN::value:
// return delegate_parse(chain_parser<
// case_chain<ParserT>::depth, ParserT
// >::left(p), scan, save);
// ...
// case left_t1::value:
// return delegate_parse(chain_parser<
// 1, left_t1
// >::right(p.left()), scan, save);
//
// case left_t0::value:
// default:
// typedef default_case<ParserT> default_t;
// typedef default_delegate_parse<
// Value, IsDefault, default_t::value>
// default_parse_t;
//
// return default_parse_t::parse(cond_value, p.right(),
// default_t::get(p), scan, save);
// }
// }
// };
//
///////////////////////////////////////////////////////////////////////////////
#define BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS(z, N, _) \
typedef typename BOOST_PP_CAT(left_t, N)::left_t \
BOOST_PP_CAT(left_t, BOOST_PP_INC(N)); \
/**/
#define BOOST_SPIRIT_PARSE_SWITCH_CASES(z, N, _) \
case (long)(BOOST_PP_CAT(left_t, N)::value): \
return delegate_parse(chain_parser<N, left_t1>::right(p.left()), \
scan, save); \
/**/
#define BOOST_SPIRIT_PARSE_SWITCHES(z, N, _) \
template <int Value, bool IsDefault> \
struct parse_switch<Value, BOOST_PP_INC(N), IsDefault> { \
\
template <typename ParserT, typename ScannerT> \
static typename parser_result<ParserT, ScannerT>::type \
do_(ParserT const &p, ScannerT const &scan, long cond_value, \
typename ScannerT::iterator_t const &save) \
{ \
typedef ParserT left_t0; \
BOOST_PP_REPEAT_FROM_TO_ ## z(0, BOOST_PP_INC(N), \
BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS, _) \
\
switch (cond_value) { \
case (long)(BOOST_PP_CAT(left_t, BOOST_PP_INC(N))::value): \
return delegate_parse( \
chain_parser< \
case_chain<ParserT>::depth, ParserT \
>::left(p), scan, save); \
\
BOOST_PP_REPEAT_FROM_TO_ ## z(1, BOOST_PP_INC(N), \
BOOST_SPIRIT_PARSE_SWITCH_CASES, _) \
\
case (long)(left_t0::value): \
default: \
typedef default_case<ParserT> default_t; \
typedef \
default_delegate_parse<Value, IsDefault, default_t::value> \
default_parse_t; \
\
return default_parse_t::parse(cond_value, p.right(), \
default_t::get(p), scan, save); \
} \
} \
}; \
/**/
BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_SPIRIT_SWITCH_CASE_LIMIT),
BOOST_SPIRIT_PARSE_SWITCHES, _)
#undef BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS
#undef BOOST_SPIRIT_PARSE_SWITCH_CASES
#undef BOOST_SPIRIT_PARSE_SWITCHES
///////////////////////////////////////////////////////////////////////////////
template <typename LeftT, typename RightT, bool IsDefault>
template <typename ScannerT, typename CondT>
inline typename parser_result<
compound_case_parser<LeftT, RightT, IsDefault>, ScannerT
>::type
compound_case_parser<LeftT, RightT, IsDefault>::
parse(ScannerT const& scan, CondT const &cond) const
{
scan.at_end(); // allow skipper to take effect
return parse_switch<value, case_chain<self_t>::depth, is_default>::
do_(*this, scan, cond(scan), scan.first);
}
///////////////////////////////////////////////////////////////////////////////
// The switch condition is to be evaluated from a parser result value.
template <typename ParserT>
struct cond_functor {
typedef cond_functor<ParserT> self_t;
cond_functor(ParserT const &p_)
: p(p_)
{}
template <typename ScannerT>
struct result
{
typedef typename parser_result<ParserT, ScannerT>::type::attr_t type;
};
template <typename ScannerT>
typename condition_result<self_t, ScannerT>::type
operator()(ScannerT const &scan) const
{
typedef typename parser_result<ParserT, ScannerT>::type result_t;
typedef typename result_t::attr_t attr_t;
result_t result(p.parse(scan));
return !result ? attr_t() : result.value();
}
typename ParserT::embed_t p;
};
template <typename ParserT>
struct make_cond_functor {
typedef as_parser<ParserT> as_parser_t;
static cond_functor<typename as_parser_t::type>
do_(ParserT const &cond)
{
return cond_functor<typename as_parser_t::type>(
as_parser_t::convert(cond));
}
};
///////////////////////////////////////////////////////////////////////////////
// The switch condition is to be evaluated from a phoenix actor
template <typename ActorT>
struct cond_actor {
typedef cond_actor<ActorT> self_t;
cond_actor(ActorT const &actor_)
: actor(actor_)
{}
template <typename ScannerT>
struct result
{
typedef typename ::phoenix::actor_result<ActorT, ::phoenix::tuple<> >::type
type;
};
template <typename ScannerT>
typename condition_result<self_t, ScannerT>::type
operator()(ScannerT const& /*scan*/) const
{
return actor();
}
ActorT const &actor;
};
template <typename ActorT>
struct make_cond_functor< ::phoenix::actor<ActorT> > {
static cond_actor< ::phoenix::actor<ActorT> >
do_(::phoenix::actor<ActorT> const &actor)
{
return cond_actor< ::phoenix::actor<ActorT> >(actor);
}
};
///////////////////////////////////////////////////////////////////////////////
// The switch condition is to be taken directly from the input stream
struct get_next_token_cond {
typedef get_next_token_cond self_t;
template <typename ScannerT>
struct result
{
typedef typename ScannerT::value_t type;
};
template <typename ScannerT>
typename condition_result<self_t, ScannerT>::type
operator()(ScannerT const &scan) const
{
typename ScannerT::value_t val(*scan);
++scan.first;
return val;
}
};
template <>
struct make_cond_functor<get_next_token_cond> {
static get_next_token_cond
do_(get_next_token_cond const &cond)
{
return cond;
}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace impl
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit
#endif // BOOST_SPIRIT_SWITCH_IPP
@@ -0,0 +1,66 @@
/*=============================================================================
Copyright (c) 2003 Joel de Guzman
Copyright (c) 2003 Vaclav Vesely
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_LAZY_HPP
#define BOOST_SPIRIT_LAZY_HPP
////////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/phoenix/actor.hpp>
////////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
////////////////////////////////////////////////////////////////////////////
//
// lazy_parser, holds phoenix actor which returns a spirit parser.
//
////////////////////////////////////////////////////////////////////////////
template<class ActorT>
struct lazy_parser : parser<lazy_parser<ActorT> >
{
typedef lazy_parser<ActorT> self_t;
typedef typename ::phoenix::actor_result<
ActorT, ::phoenix::tuple<> >::plain_type actor_result_t;
template<typename ScannerT>
struct result
{
typedef typename
parser_result<actor_result_t, ScannerT>::type
type;
};
lazy_parser(ActorT const& actor_)
: actor(actor_) {}
template<typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{ return actor().parse(scan); }
ActorT actor;
};
//////////////////////////////
// lazy_p, returns lazy_parser
// Usage: lazy_p(actor)
template<class ActorT>
lazy_parser<ActorT> lazy_p(ActorT const& actor)
{ return lazy_parser<ActorT>(actor); }
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif // BOOST_SPIRIT_LAZY_HPP
@@ -0,0 +1,76 @@
/*=============================================================================
Copyright (c) 1998-2003 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_RULE_ALIAS_HPP)
#define BOOST_SPIRIT_RULE_ALIAS_HPP
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////
//
// rule_alias class
//
///////////////////////////////////////////////////////////////////////////
template <typename ParserT>
class rule_alias :
public parser<rule_alias<ParserT> >
{
public:
typedef rule_alias<ParserT> self_t;
template <typename ScannerT>
struct result
{
typedef typename parser_result<ParserT, ScannerT>::type type;
};
rule_alias()
: ptr(0) {}
rule_alias(ParserT const& p)
: ptr(&p) {}
rule_alias&
operator=(ParserT const& p)
{
ptr = &p;
return *this;
}
template <typename ScannerT>
typename parser_result<ParserT, ScannerT>::type
parse(ScannerT const& scan) const
{
if (ptr)
return ptr->parse(scan);
else
return scan.no_match();
}
ParserT const&
get() const
{
BOOST_ASSERT(ptr != 0);
return *ptr;
}
private:
ParserT const* ptr; // hold it by pointer
};
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
@@ -0,0 +1,245 @@
/*=============================================================================
Copyright (c) 2003 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_SELECT_HPP
#define BOOST_SPIRIT_SELECT_HPP
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/enum.hpp>
#include <boost/preprocessor/enum_params.hpp>
#include <boost/preprocessor/enum_params_with_defaults.hpp>
#include <boost/preprocessor/inc.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/phoenix/tuples.hpp>
///////////////////////////////////////////////////////////////////////////////
//
// Spirit predefined maximum number of possible embedded select_p parsers.
// It should NOT be greater than PHOENIX_LIMIT!
//
///////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_SPIRIT_SELECT_LIMIT)
#define BOOST_SPIRIT_SELECT_LIMIT PHOENIX_LIMIT
#endif // !defined(BOOST_SPIRIT_SELECT_LIMIT)
///////////////////////////////////////////////////////////////////////////////
//
// ensure BOOST_SPIRIT_SELECT_LIMIT <= PHOENIX_LIMIT and
// BOOST_SPIRIT_SELECT_LIMIT > 0
// BOOST_SPIRIT_SELECT_LIMIT <= 15
//
// [Pushed this down a little to make CW happy with BOOST_STATIC_ASSERT]
// [Otherwise, it complains: 'boost_static_assert_test_42' redefined]
//
///////////////////////////////////////////////////////////////////////////////
BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT <= PHOENIX_LIMIT);
BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT > 0);
BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT <= 15);
///////////////////////////////////////////////////////////////////////////////
//
// Calculate the required amount of tuple members rounded up to the nearest
// integer dividable by 3
//
///////////////////////////////////////////////////////////////////////////////
#if BOOST_SPIRIT_SELECT_LIMIT > 12
#define BOOST_SPIRIT_SELECT_LIMIT_A 15
#elif BOOST_SPIRIT_SELECT_LIMIT > 9
#define BOOST_SPIRIT_SELECT_LIMIT_A 12
#elif BOOST_SPIRIT_SELECT_LIMIT > 6
#define BOOST_SPIRIT_SELECT_LIMIT_A 9
#elif BOOST_SPIRIT_SELECT_LIMIT > 3
#define BOOST_SPIRIT_SELECT_LIMIT_A 6
#else
#define BOOST_SPIRIT_SELECT_LIMIT_A 3
#endif
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// The select_default_no_fail and select_default_fail structs are used to
// distinguish two different behaviours for the select_parser in case that not
// any of the given sub-parsers match.
//
// If the select_parser is used with the select_default_no_fail behaviour,
// then in case of no matching sub-parser the whole select_parser returns an
// empty match and the value -1.
//
// If the select_parser is used with the select_default_fail behaviour, then
// in case of no matching sub-parser the whole select_parser fails to match at
// all.
//
///////////////////////////////////////////////////////////////////////////////
struct select_default_no_fail {};
struct select_default_fail {};
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/dynamic/impl/select.ipp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
template <typename TupleT, typename BehaviourT, typename T>
struct select_parser
: public parser<select_parser<TupleT, BehaviourT, T> >
{
typedef select_parser<TupleT, BehaviourT, T> self_t;
select_parser(TupleT const &t_)
: t(t_)
{}
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, T>::type type;
};
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
typedef typename parser_result<self_t, ScannerT>::type result_t;
if (!scan.at_end()) {
return impl::parse_tuple_element<
TupleT::length, result_t, TupleT, BehaviourT>::do_(t, scan);
}
return impl::select_match_gen<result_t, BehaviourT>::do_(scan);
}
TupleT const t;
};
///////////////////////////////////////////////////////////////////////////////
template <typename BehaviourT, typename T = int>
struct select_parser_gen {
///////////////////////////////////////////////////////////////////////////
//
// This generates different select_parser_gen::operator()() functions with
// an increasing number of parser parameters:
//
// template <typename ParserT0, ...>
// select_parser<
// ::phoenix::tuple<
// typename impl::as_embedded_parser<ParserT0>::type,
// ...
// >,
// BehaviourT,
// T
// >
// operator()(ParserT0 const &p0, ...) const
// {
// typedef impl::as_embedded_parser<ParserT0> parser_t0;
// ...
//
// typedef ::phoenix::tuple<
// parser_t0::type,
// ...
// > tuple_t;
// typedef select_parser<tuple_t, BehaviourT, T> result_t;
//
// return result_t(tuple_t(
// parser_t0::convert(p0),
// ...
// ));
// }
//
// The number of generated functions depends on the maximum tuple member
// limit defined by the PHOENIX_LIMIT pp constant.
//
///////////////////////////////////////////////////////////////////////////
#define BOOST_SPIRIT_SELECT_EMBEDDED(z, N, _) \
typename impl::as_embedded_parser<BOOST_PP_CAT(ParserT, N)>::type \
/**/
#define BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF(z, N, _) \
typedef impl::as_embedded_parser<BOOST_PP_CAT(ParserT, N)> \
BOOST_PP_CAT(parser_t, N); \
/**/
#define BOOST_SPIRIT_SELECT_CONVERT(z, N, _) \
BOOST_PP_CAT(parser_t, N)::convert(BOOST_PP_CAT(p, N)) \
/**/
#define BOOST_SPIRIT_SELECT_PARSER(z, N, _) \
template < \
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ParserT) \
> \
select_parser< \
::phoenix::tuple< \
BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N), \
BOOST_SPIRIT_SELECT_EMBEDDED, _) \
>, \
BehaviourT, \
T \
> \
operator()( \
BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(N), \
ParserT, const &p) \
) const \
{ \
BOOST_PP_REPEAT_ ## z(BOOST_PP_INC(N), \
BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF, _) \
\
typedef ::phoenix::tuple< \
BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(N), \
typename parser_t, ::type BOOST_PP_INTERCEPT) \
> tuple_t; \
typedef select_parser<tuple_t, BehaviourT, T> result_t; \
\
return result_t(tuple_t( \
BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N), \
BOOST_SPIRIT_SELECT_CONVERT, _) \
)); \
} \
/**/
BOOST_PP_REPEAT(BOOST_SPIRIT_SELECT_LIMIT_A,
BOOST_SPIRIT_SELECT_PARSER, _)
#undef BOOST_SPIRIT_SELECT_PARSER
#undef BOOST_SPIRIT_SELECT_CONVERT
#undef BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF
#undef BOOST_SPIRIT_SELECT_EMBEDDED
///////////////////////////////////////////////////////////////////////////
};
///////////////////////////////////////////////////////////////////////////////
//
// Predefined parser generator helper objects
//
///////////////////////////////////////////////////////////////////////////////
select_parser_gen<select_default_no_fail> const select_p =
select_parser_gen<select_default_no_fail>();
select_parser_gen<select_default_fail> const select_fail_p =
select_parser_gen<select_default_fail>();
#undef BOOST_SPIRIT_SELECT_LIMIT_A
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif // BOOST_SPIRIT_SELECT_HPP
@@ -0,0 +1,121 @@
/*=============================================================================
Copyright (c) 1998-2003 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_STORED_RULE_HPP)
#define BOOST_SPIRIT_STORED_RULE_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/non_terminal/impl/rule.ipp>
#include <boost/spirit/home/classic/dynamic/rule_alias.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/spirit/home/classic/dynamic/stored_rule_fwd.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////
//
// stored_rule class
//
///////////////////////////////////////////////////////////////////////////
template <
typename T0
, typename T1
, typename T2
, bool EmbedByValue
>
class stored_rule
: public impl::rule_base<
stored_rule<T0, T1, T2, EmbedByValue>
, typename mpl::if_c<
EmbedByValue
, stored_rule<T0, T1, T2, true>
, stored_rule<T0, T1, T2> const&>::type
, T0, T1, T2>
{
public:
typedef stored_rule<T0, T1, T2, EmbedByValue> self_t;
typedef impl::rule_base<
self_t
, typename mpl::if_c<
EmbedByValue
, stored_rule<T0, T1, T2, true>
, self_t const&>::type
, T0, T1, T2>
base_t;
typedef typename base_t::scanner_t scanner_t;
typedef typename base_t::attr_t attr_t;
typedef impl::abstract_parser<scanner_t, attr_t> abstract_parser_t;
typedef rule_alias<self_t> alias_t;
stored_rule() : ptr() {}
~stored_rule() {}
stored_rule(stored_rule const& r)
: ptr(r.ptr) {}
template <typename ParserT>
stored_rule(ParserT const& p)
: ptr(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p)) {}
template <typename ParserT>
stored_rule& operator=(ParserT const& p)
{
ptr.reset(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p));
return *this;
}
stored_rule& operator=(stored_rule const& r)
{
// If this is placed above the templatized assignment
// operator, VC6 incorrectly complains ambiguity with
// r1 = r2, where r1 and r2 are both rules.
ptr = r.ptr;
return *this;
}
stored_rule<T0, T1, T2, true>
copy() const
{
return stored_rule<T0, T1, T2, true>(ptr);
}
alias_t
alias() const
{
return alias_t(*this);
}
private:
friend class impl::rule_base_access;
friend class stored_rule<T0, T1, T2, !EmbedByValue>;
abstract_parser_t*
get() const
{
return ptr.get();
}
stored_rule(shared_ptr<abstract_parser_t> const& ptr)
: ptr(ptr) {}
shared_ptr<abstract_parser_t> ptr;
};
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
@@ -0,0 +1,31 @@
/*=============================================================================
Copyright (c) 2006 Tobias Schwinger
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_STORED_RULE_FWD_HPP)
#define BOOST_SPIRIT_STORED_RULE_FWD_HPP
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/nil.hpp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
template <
typename T0 = nil_t
, typename T1 = nil_t
, typename T2 = nil_t
, bool EmbedByValue = false
>
class stored_rule;
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
@@ -0,0 +1,259 @@
/*=============================================================================
Copyright (c) 2003 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_SWITCH_HPP
#define BOOST_SPIRIT_SWITCH_HPP
///////////////////////////////////////////////////////////////////////////////
//
// The default_p parser generator template uses the following magic number
// as the corresponding case label value inside the generated switch()
// statements. If this number conflicts with your code, please pick a
// different one.
//
///////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_SPIRIT_DEFAULTCASE_MAGIC)
#define BOOST_SPIRIT_DEFAULTCASE_MAGIC 0x15F97A7
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Spirit predefined maximum number of possible case_p/default_p case branch
// parsers.
//
///////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_SPIRIT_SWITCH_CASE_LIMIT)
#define BOOST_SPIRIT_SWITCH_CASE_LIMIT 3
#endif // !defined(BOOST_SPIRIT_SWITCH_CASE_LIMIT)
///////////////////////////////////////////////////////////////////////////////
#include <boost/static_assert.hpp>
///////////////////////////////////////////////////////////////////////////////
//
// Ensure BOOST_SPIRIT_SELECT_LIMIT > 0
//
///////////////////////////////////////////////////////////////////////////////
BOOST_STATIC_ASSERT(BOOST_SPIRIT_SWITCH_CASE_LIMIT > 0);
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/config.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/composite/epsilon.hpp>
#include <boost/spirit/home/classic/dynamic/impl/switch.ipp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// The switch_parser allows to build switch like parsing constructs, which
// will have much better perfomance as comparable straight solutions.
//
// Input stream driven syntax:
//
// switch_p
// [
// case_p<'a'>
// (...parser to use, if the next character is 'a'...),
// case_p<'b'>
// (...parser to use, if the next character is 'b'...),
// default_p
// (...parser to use, if nothing was matched before...)
// ]
//
// General syntax:
//
// switch_p(...lazy expression returning the switch condition value...)
// [
// case_p<1>
// (...parser to use, if the switch condition value is 1...),
// case_p<2>
// (...parser to use, if the switch condition value is 2...),
// default_p
// (...parser to use, if nothing was matched before...)
// ]
//
// The maximum number of possible case_p branches is defined by the p constant
// BOOST_SPIRIT_SWITCH_CASE_LIMIT (this value defaults to 3 if not otherwise
// defined).
//
///////////////////////////////////////////////////////////////////////////////
template <typename CaseT, typename CondT = impl::get_next_token_cond>
struct switch_parser
: public unary<CaseT, parser<switch_parser<CaseT, CondT> > >
{
typedef switch_parser<CaseT, CondT> self_t;
typedef unary_parser_category parser_category_t;
typedef unary<CaseT, parser<self_t> > base_t;
switch_parser(CaseT const &case_)
: base_t(case_), cond(CondT())
{}
switch_parser(CaseT const &case_, CondT const &cond_)
: base_t(case_), cond(cond_)
{}
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, nil_t>::type type;
};
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
return this->subject().parse(scan,
impl::make_cond_functor<CondT>::do_(cond));
}
CondT cond;
};
///////////////////////////////////////////////////////////////////////////////
template <typename CondT>
struct switch_cond_parser
{
switch_cond_parser(CondT const &cond_)
: cond(cond_)
{}
template <typename ParserT>
switch_parser<ParserT, CondT>
operator[](parser<ParserT> const &p) const
{
return switch_parser<ParserT, CondT>(p.derived(), cond);
}
CondT const &cond;
};
///////////////////////////////////////////////////////////////////////////////
template <int N, typename ParserT, bool IsDefault>
struct case_parser
: public unary<ParserT, parser<case_parser<N, ParserT, IsDefault> > >
{
typedef case_parser<N, ParserT, IsDefault> self_t;
typedef unary_parser_category parser_category_t;
typedef unary<ParserT, parser<self_t> > base_t;
typedef typename base_t::subject_t self_subject_t;
BOOST_STATIC_CONSTANT(int, value = N);
BOOST_STATIC_CONSTANT(bool, is_default = IsDefault);
BOOST_STATIC_CONSTANT(bool, is_simple = true);
BOOST_STATIC_CONSTANT(bool, is_epsilon = (
is_default && boost::is_same<self_subject_t, epsilon_parser>::value
));
case_parser(parser<ParserT> const &p)
: base_t(p.derived())
{}
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, nil_t>::type type;
};
template <typename ScannerT, typename CondT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan, CondT const &cond) const
{
typedef impl::default_case<self_t> default_t;
if (!scan.at_end()) {
typedef impl::default_delegate_parse<
value, is_default, default_t::value> default_parse_t;
typename ScannerT::iterator_t const save(scan.first);
return default_parse_t::parse(cond(scan), *this,
*this, scan, save);
}
return default_t::is_epsilon ? scan.empty_match() : scan.no_match();
}
template <int N1, typename ParserT1, bool IsDefault1>
impl::compound_case_parser<
self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1
>
operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const
{
// If the following compile time assertion fires, you've probably used
// more than one default_p case inside the switch_p parser construct.
BOOST_STATIC_ASSERT(!is_default || !IsDefault1);
typedef case_parser<N1, ParserT1, IsDefault1> right_t;
return impl::compound_case_parser<self_t, right_t, IsDefault1>(*this, p);
}
};
///////////////////////////////////////////////////////////////////////////////
struct switch_parser_gen {
// This generates a switch parser, which is driven by the condition value
// returned by the lazy parameter expression 'cond'. This may be a parser,
// which result is used or a phoenix actor, which will be dereferenced to
// obtain the switch condition value.
template <typename CondT>
switch_cond_parser<CondT>
operator()(CondT const &cond) const
{
return switch_cond_parser<CondT>(cond);
}
// This generates a switch parser, which is driven by the next character/token
// found in the input stream.
template <typename CaseT>
switch_parser<CaseT>
operator[](parser<CaseT> const &p) const
{
return switch_parser<CaseT>(p.derived());
}
};
switch_parser_gen const switch_p = switch_parser_gen();
///////////////////////////////////////////////////////////////////////////////
template <int N, typename ParserT>
inline case_parser<N, ParserT, false>
case_p(parser<ParserT> const &p)
{
return case_parser<N, ParserT, false>(p);
}
///////////////////////////////////////////////////////////////////////////////
struct default_parser_gen
: public case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, epsilon_parser, true>
{
default_parser_gen()
: case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, epsilon_parser, true>
(epsilon_p)
{}
template <typename ParserT>
case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, ParserT, true>
operator()(parser<ParserT> const &p) const
{
return case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, ParserT, true>(p);
}
};
default_parser_gen const default_p = default_parser_gen();
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif // BOOST_SPIRIT_SWITCH_HPP
@@ -0,0 +1,89 @@
/*=============================================================================
Copyright (c) 2006 Tobias Schwinger
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_DYNAMIC_TYPEOF_HPP)
#define BOOST_SPIRIT_DYNAMIC_TYPEOF_HPP
#include <boost/typeof/typeof.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/typeof.hpp>
#include <boost/spirit/home/classic/dynamic/stored_rule_fwd.hpp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
// if.hpp
template <class ParsableT, typename CondT> struct if_parser;
template <class ParsableTrueT, class ParsableFalseT, typename CondT>
struct if_else_parser;
// for.hpp
namespace impl {
template<typename InitF, typename CondT, typename StepF, class ParsableT>
struct for_parser;
}
// while.hpp
template<typename ParsableT, typename CondT, bool is_do_parser>
struct while_parser;
// lazy.hpp
template<typename ActorT> struct lazy_parser;
// rule_alias.hpp
template <typename ParserT> class rule_alias;
// switch.hpp
template <typename CaseT, typename CondT> struct switch_parser;
template <int N, class ParserT, bool IsDefault> struct case_parser;
// select.hpp
template <typename TupleT, typename BehaviourT, typename T>
struct select_parser;
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
// if.hpp
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::if_parser,2)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::if_else_parser,3)
// for.hpp
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::impl::for_parser,4)
// while.hpp
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::while_parser,(class)(class)(bool))
// lazy.hpp
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::lazy_parser,1)
// stored_rule.hpp (has forward header)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::stored_rule,(typename)(typename)(typename)(bool))
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::stored_rule,3)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::stored_rule,2)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::stored_rule,1)
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::stored_rule<>)
// rule_alias.hpp
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::rule_alias,1)
// switch.hpp
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::switch_parser,2)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::case_parser,(int)(class)(bool))
// select.hpp
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::select_parser,3)
#endif
@@ -0,0 +1,189 @@
/*=============================================================================
Copyright (c) 2002-2003 Joel de Guzman
Copyright (c) 2002-2003 Martin Wille
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_WHILE_HPP
#define BOOST_SPIRIT_WHILE_HPP
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/composite/composite.hpp>
#include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
////////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
namespace impl {
//////////////////////////////////
// while parser
// object are created by while_parser_gen and do_parser_gen
template <typename ParsableT, typename CondT, bool is_do_parser>
struct while_parser
: public condition_evaluator< typename as_parser<CondT>::type >
, public unary // the parent stores a copy of the body parser
<
typename as_parser<ParsableT>::type,
parser<while_parser<ParsableT, CondT, is_do_parser> >
>
{
typedef while_parser<ParsableT, CondT, is_do_parser> self_t;
typedef as_parser<ParsableT> as_parser_t;
typedef typename as_parser_t::type parser_t;
typedef as_parser<CondT> cond_as_parser_t;
typedef typename cond_as_parser_t::type condition_t;
typedef unary<parser_t, parser<self_t> > base_t;
typedef condition_evaluator<condition_t> eval_t;
//////////////////////////////
// constructor, saves condition and body parser
while_parser(ParsableT const &body, CondT const &cond)
: eval_t(cond_as_parser_t::convert(cond))
, base_t(as_parser_t::convert(body))
{}
//////////////////////////////
// result type computer.
template <typename ScannerT>
struct result
{
typedef typename match_result
<ScannerT, nil_t>::type type;
};
//////////////////////////////
// parse member function
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
typedef typename parser_result<parser_t, ScannerT>::type sresult_t;
typedef typename ScannerT::iterator_t iterator_t;
iterator_t save(scan.first);
std::size_t length = 0;
int eval_length = 0;
bool dont_check_condition = is_do_parser;
while (dont_check_condition || (eval_length=this->evaluate(scan))>=0)
{
dont_check_condition = false;
length += eval_length;
sresult_t tmp(this->subject().parse(scan));
if (tmp)
{
length+=tmp.length();
}
else
{
return scan.no_match();
}
}
return scan.create_match(length, nil_t(), save, scan.first);
}
};
//////////////////////////////////
// while-parser generator, takes the body-parser in brackets
// and returns the actual while-parser.
template <typename CondT>
struct while_parser_gen
{
//////////////////////////////
// constructor, saves the condition for use by operator[]
while_parser_gen(CondT const& cond_) : cond(cond_) {}
//////////////////////////////
// operator[] returns the actual while-parser object
template <typename ParsableT>
while_parser<ParsableT, CondT, false>
operator[](ParsableT const &subject) const
{
return while_parser<ParsableT, CondT, false>(subject, cond);
}
private:
//////////////////////////////
// the condition is stored by reference here.
// this should not cause any harm since object of type
// while_parser_gen<> are only used as temporaries
// the while-parser object constructed by the operator[]
// stores a copy of the condition.
CondT const &cond;
};
//////////////////////////////////
// do-while-parser generator, takes the condition as
// parameter to while_p member function and returns the
// actual do-while-parser.
template <typename ParsableT>
struct do_while_parser_gen
{
//////////////////////////////
// constructor. saves the body parser for use by while_p.
explicit do_while_parser_gen(ParsableT const &body_parser)
: body(body_parser)
{}
//////////////////////////////
// while_p returns the actual while-parser object
template <typename CondT>
while_parser<ParsableT, CondT, true>
while_p(CondT cond) const
{
return while_parser<ParsableT, CondT, true>(body, cond);
}
private:
//////////////////////////////
// the body is stored by reference here
// this should not cause any harm since object of type
// do_while_parser_gen<> are only used as temporaries
// the while-parser object constructed by the while_p
// member function stores a copy of the body parser.
ParsableT const &body;
};
struct do_parser_gen
{
inline do_parser_gen() {}
template <typename ParsableT>
impl::do_while_parser_gen<ParsableT>
operator[](ParsableT const& body) const
{
return impl::do_while_parser_gen<ParsableT>(body);
}
};
} // namespace impl
//////////////////////////////////
// while_p function, while-parser generator
// Usage: spirit::while_p(Condition)[Body]
template <typename CondT>
impl::while_parser_gen<CondT>
while_p(CondT const& cond)
{
return impl::while_parser_gen<CondT>(cond);
}
//////////////////////////////////
// do_p functor, do-while-parser generator
// Usage: spirit::do_p[Body].while_p(Condition)
impl::do_parser_gen const do_p = impl::do_parser_gen();
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif // BOOST_SPIRIT_WHILE_HPP