Chris@16: /*============================================================================= Chris@16: Copyright (c) 2002-2003 Joel de Guzman Chris@16: Copyright (c) 2002-2003 Martin Wille Chris@16: http://spirit.sourceforge.net/ Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: =============================================================================*/ Chris@16: #ifndef BOOST_SPIRIT_FOR_HPP Chris@16: #define BOOST_SPIRIT_FOR_HPP Chris@16: //////////////////////////////////////////////////////////////////////////////// Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: namespace boost { namespace spirit { Chris@16: Chris@16: BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN Chris@16: Chris@16: namespace impl Chris@16: { Chris@16: Chris@16: template Chris@16: struct for_functor Chris@16: { Chris@16: typedef typename boost::call_traits::param_type param_t; Chris@16: Chris@16: for_functor(param_t f) : func(f) {} Chris@16: for_functor() {} Chris@16: FuncT func; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct for_init_functor : for_functor Chris@16: { Chris@16: typedef for_functor base_t; Chris@16: typedef typename base_t::param_t param_t; Chris@16: Chris@16: for_init_functor(param_t f) : base_t(f) {} Chris@16: for_init_functor() : base_t() {} Chris@16: void init() const { /*return*/ this->func(); } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct for_step_functor : for_functor Chris@16: { Chris@16: typedef for_functor base_t; Chris@16: typedef typename base_t::param_t param_t; Chris@16: Chris@16: for_step_functor(param_t f) : base_t(f) {} Chris@16: for_step_functor() : base_t() {} Chris@16: void step() const { /*return*/ this->func(); } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: // for_parser Chris@16: template Chris@16: < Chris@16: typename InitF, typename CondT, typename StepF, Chris@16: typename ParsableT Chris@16: > Chris@16: struct for_parser Chris@16: : private for_init_functor Chris@16: , private for_step_functor Chris@16: , private condition_evaluator::type> Chris@16: , public unary Chris@16: < Chris@16: typename as_parser::type, Chris@16: parser< for_parser > Chris@16: > Chris@16: { Chris@16: typedef for_parser self_t; Chris@16: typedef as_parser cond_as_parser_t; Chris@16: typedef typename cond_as_parser_t::type condition_t; Chris@16: typedef condition_evaluator eval_t; Chris@16: typedef as_parser as_parser_t; Chris@16: typedef typename as_parser_t::type parser_t; Chris@16: typedef unary< parser_t, parser< self_t > > base_t; Chris@16: Chris@16: Chris@16: ////////////////////////////// Chris@16: // constructor, saves init, condition and step functors Chris@16: // for later use the parse member function Chris@16: for_parser Chris@16: ( Chris@16: InitF const &i, CondT const &c, StepF const &s, Chris@16: ParsableT const &p Chris@16: ) Chris@16: : for_init_functor(i) Chris@16: , for_step_functor(s) Chris@16: , eval_t(cond_as_parser_t::convert(c)) Chris@16: , base_t(as_parser_t::convert(p)) Chris@16: { } Chris@16: Chris@16: for_parser() Chris@16: : for_init_functor() Chris@16: , for_step_functor() Chris@16: , eval_t() Chris@16: , base_t() Chris@16: {} Chris@16: Chris@16: ////////////////////////////// Chris@16: // parse member function Chris@16: template Chris@16: typename parser_result::type Chris@16: parse(ScannerT const &scan) const Chris@16: { Chris@16: typedef typename parser_result::type Chris@16: result_t; Chris@16: typedef typename parser_result::type Chris@16: body_result_t; Chris@16: Chris@16: typename ScannerT::iterator_t save(scan.first); Chris@16: Chris@16: std::size_t length = 0; Chris@16: int eval_length = 0; Chris@16: Chris@16: this->init(); Chris@16: while ((eval_length = this->evaluate(scan))>=0) Chris@16: { Chris@16: length += eval_length; Chris@16: body_result_t tmp(this->subject().parse(scan)); Chris@16: if (tmp) Chris@16: { Chris@16: length+=tmp.length(); Chris@16: } Chris@16: else Chris@16: { Chris@16: return scan.no_match(); Chris@16: } Chris@16: this->step(); Chris@16: } Chris@16: Chris@16: BOOST_SPIRIT_CLASSIC_NS::nil_t attr; Chris@16: return scan.create_match Chris@16: (length, attr, save, scan.first); Chris@16: } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////// Chris@16: // for_parser_gen generates takes the body parser in brackets Chris@16: // and returns the for_parser Chris@16: template Chris@16: struct for_parser_gen Chris@16: { Chris@16: for_parser_gen(InitF const &i, CondT const &c, StepF const &s) Chris@16: : init(i) Chris@16: , condition(c) Chris@16: , step(s) Chris@16: {} Chris@16: Chris@16: template Chris@16: for_parser Chris@16: operator[](ParsableT const &p) const Chris@16: { Chris@16: return for_parser Chris@16: (init, condition, step, p); Chris@16: } Chris@16: Chris@16: InitF const &init; Chris@16: CondT const &condition; Chris@16: StepF const &step; Chris@16: }; Chris@16: } // namespace impl Chris@16: Chris@16: ////////////////////////////// Chris@16: // for_p, returns for-parser generator Chris@16: // Usage: spirit::for_p(init-ftor, condition, step-ftor)[body] Chris@16: template Chris@16: < Chris@16: typename InitF, typename ConditionT, typename StepF Chris@16: > Chris@16: impl::for_parser_gen Chris@16: for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f) Chris@16: { Chris@16: return impl::for_parser_gen Chris@16: (init_f, condition, step_f); Chris@16: } Chris@16: Chris@16: BOOST_SPIRIT_CLASSIC_NAMESPACE_END Chris@16: Chris@16: }} // namespace BOOST_SPIRIT_CLASSIC_NS Chris@16: Chris@16: #endif // BOOST_SPIRIT_FOR_HPP