stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -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
|
||||
+97
@@ -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
|
||||
+120
@@ -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
|
||||
+574
@@ -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
|
||||
+121
@@ -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
|
||||
+31
@@ -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
|
||||
Reference in New Issue
Block a user