1 /*=============================================================================
2 Copyright (c) 2002-2003 Joel de Guzman
3 Copyright (c) 2002-2003 Martin Wille
4 http://spirit.sourceforge.net/
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 #ifndef BOOST_SPIRIT_FOR_HPP
10 #define BOOST_SPIRIT_FOR_HPP
11 ////////////////////////////////////////////////////////////////////////////////
12 #include <boost/spirit/home/classic/namespace.hpp>
13 #include <boost/spirit/home/classic/core/parser.hpp>
14 #include <boost/spirit/home/classic/core/composite/composite.hpp>
15 #include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
17 ////////////////////////////////////////////////////////////////////////////////
19 namespace boost { namespace spirit {
21 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
26 template <typename FuncT>
29 typedef typename boost::call_traits<FuncT>::param_type param_t;
31 for_functor(param_t f) : func(f) {}
36 template <typename InitF>
37 struct for_init_functor : for_functor<InitF>
39 typedef for_functor<InitF> base_t;
40 typedef typename base_t::param_t param_t;
42 for_init_functor(param_t f) : base_t(f) {}
43 for_init_functor() : base_t() {}
44 void init() const { /*return*/ this->func(); }
47 template <typename StepF>
48 struct for_step_functor : for_functor<StepF>
50 typedef for_functor<StepF> base_t;
51 typedef typename base_t::param_t param_t;
53 for_step_functor(param_t f) : base_t(f) {}
54 for_step_functor() : base_t() {}
55 void step() const { /*return*/ this->func(); }
58 //////////////////////////////////
62 typename InitF, typename CondT, typename StepF,
66 : private for_init_functor<InitF>
67 , private for_step_functor<StepF>
68 , private condition_evaluator<typename as_parser<CondT>::type>
71 typename as_parser<ParsableT>::type,
72 parser< for_parser<InitF, CondT, StepF, ParsableT> >
75 typedef for_parser<InitF, CondT, StepF, ParsableT> self_t;
76 typedef as_parser<CondT> cond_as_parser_t;
77 typedef typename cond_as_parser_t::type condition_t;
78 typedef condition_evaluator<condition_t> eval_t;
79 typedef as_parser<ParsableT> as_parser_t;
80 typedef typename as_parser_t::type parser_t;
81 typedef unary< parser_t, parser< self_t > > base_t;
84 //////////////////////////////
85 // constructor, saves init, condition and step functors
86 // for later use the parse member function
89 InitF const &i, CondT const &c, StepF const &s,
92 : for_init_functor<InitF>(i)
93 , for_step_functor<StepF>(s)
94 , eval_t(cond_as_parser_t::convert(c))
95 , base_t(as_parser_t::convert(p))
99 : for_init_functor<InitF>()
100 , for_step_functor<StepF>()
105 //////////////////////////////
106 // parse member function
107 template <typename ScannerT>
108 typename parser_result<self_t, ScannerT>::type
109 parse(ScannerT const &scan) const
111 typedef typename parser_result<self_t, ScannerT>::type
113 typedef typename parser_result<parser_t, ScannerT>::type
116 typename ScannerT::iterator_t save(scan.first);
118 std::size_t length = 0;
122 while ((eval_length = this->evaluate(scan))>=0)
124 length += eval_length;
125 body_result_t tmp(this->subject().parse(scan));
128 length+=tmp.length();
132 return scan.no_match();
137 BOOST_SPIRIT_CLASSIC_NS::nil_t attr;
138 return scan.create_match
139 (length, attr, save, scan.first);
143 //////////////////////////////////
144 // for_parser_gen generates takes the body parser in brackets
145 // and returns the for_parser
146 template <typename InitF, typename CondT, typename StepF>
147 struct for_parser_gen
149 for_parser_gen(InitF const &i, CondT const &c, StepF const &s)
155 template <typename ParsableT>
156 for_parser<InitF, CondT, StepF, ParsableT>
157 operator[](ParsableT const &p) const
159 return for_parser<InitF, CondT, StepF, ParsableT>
160 (init, condition, step, p);
164 CondT const &condition;
169 //////////////////////////////
170 // for_p, returns for-parser generator
171 // Usage: spirit::for_p(init-ftor, condition, step-ftor)[body]
174 typename InitF, typename ConditionT, typename StepF
176 impl::for_parser_gen<InitF, ConditionT, StepF>
177 for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f)
179 return impl::for_parser_gen<InitF, ConditionT, StepF>
180 (init_f, condition, step_f);
183 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
185 }} // namespace BOOST_SPIRIT_CLASSIC_NS
187 #endif // BOOST_SPIRIT_FOR_HPP