/*============================================================================= | |
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 |