Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2002-2003 Joel de Guzman
|
Chris@16
|
3 Copyright (c) 2002-2003 Martin Wille
|
Chris@16
|
4 http://spirit.sourceforge.net/
|
Chris@16
|
5
|
Chris@16
|
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 =============================================================================*/
|
Chris@16
|
9 #ifndef BOOST_SPIRIT_FOR_HPP
|
Chris@16
|
10 #define BOOST_SPIRIT_FOR_HPP
|
Chris@16
|
11 ////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
12 #include <boost/spirit/home/classic/namespace.hpp>
|
Chris@16
|
13 #include <boost/spirit/home/classic/core/parser.hpp>
|
Chris@16
|
14 #include <boost/spirit/home/classic/core/composite/composite.hpp>
|
Chris@16
|
15 #include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
|
Chris@16
|
16
|
Chris@16
|
17 ////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
18
|
Chris@16
|
19 namespace boost { namespace spirit {
|
Chris@16
|
20
|
Chris@16
|
21 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
Chris@16
|
22
|
Chris@16
|
23 namespace impl
|
Chris@16
|
24 {
|
Chris@16
|
25
|
Chris@16
|
26 template <typename FuncT>
|
Chris@16
|
27 struct for_functor
|
Chris@16
|
28 {
|
Chris@16
|
29 typedef typename boost::call_traits<FuncT>::param_type param_t;
|
Chris@16
|
30
|
Chris@16
|
31 for_functor(param_t f) : func(f) {}
|
Chris@16
|
32 for_functor() {}
|
Chris@16
|
33 FuncT func;
|
Chris@16
|
34 };
|
Chris@16
|
35
|
Chris@16
|
36 template <typename InitF>
|
Chris@16
|
37 struct for_init_functor : for_functor<InitF>
|
Chris@16
|
38 {
|
Chris@16
|
39 typedef for_functor<InitF> base_t;
|
Chris@16
|
40 typedef typename base_t::param_t param_t;
|
Chris@16
|
41
|
Chris@16
|
42 for_init_functor(param_t f) : base_t(f) {}
|
Chris@16
|
43 for_init_functor() : base_t() {}
|
Chris@16
|
44 void init() const { /*return*/ this->func(); }
|
Chris@16
|
45 };
|
Chris@16
|
46
|
Chris@16
|
47 template <typename StepF>
|
Chris@16
|
48 struct for_step_functor : for_functor<StepF>
|
Chris@16
|
49 {
|
Chris@16
|
50 typedef for_functor<StepF> base_t;
|
Chris@16
|
51 typedef typename base_t::param_t param_t;
|
Chris@16
|
52
|
Chris@16
|
53 for_step_functor(param_t f) : base_t(f) {}
|
Chris@16
|
54 for_step_functor() : base_t() {}
|
Chris@16
|
55 void step() const { /*return*/ this->func(); }
|
Chris@16
|
56 };
|
Chris@16
|
57
|
Chris@16
|
58 //////////////////////////////////
|
Chris@16
|
59 // for_parser
|
Chris@16
|
60 template
|
Chris@16
|
61 <
|
Chris@16
|
62 typename InitF, typename CondT, typename StepF,
|
Chris@16
|
63 typename ParsableT
|
Chris@16
|
64 >
|
Chris@16
|
65 struct for_parser
|
Chris@16
|
66 : private for_init_functor<InitF>
|
Chris@16
|
67 , private for_step_functor<StepF>
|
Chris@16
|
68 , private condition_evaluator<typename as_parser<CondT>::type>
|
Chris@16
|
69 , public unary
|
Chris@16
|
70 <
|
Chris@16
|
71 typename as_parser<ParsableT>::type,
|
Chris@16
|
72 parser< for_parser<InitF, CondT, StepF, ParsableT> >
|
Chris@16
|
73 >
|
Chris@16
|
74 {
|
Chris@16
|
75 typedef for_parser<InitF, CondT, StepF, ParsableT> self_t;
|
Chris@16
|
76 typedef as_parser<CondT> cond_as_parser_t;
|
Chris@16
|
77 typedef typename cond_as_parser_t::type condition_t;
|
Chris@16
|
78 typedef condition_evaluator<condition_t> eval_t;
|
Chris@16
|
79 typedef as_parser<ParsableT> as_parser_t;
|
Chris@16
|
80 typedef typename as_parser_t::type parser_t;
|
Chris@16
|
81 typedef unary< parser_t, parser< self_t > > base_t;
|
Chris@16
|
82
|
Chris@16
|
83
|
Chris@16
|
84 //////////////////////////////
|
Chris@16
|
85 // constructor, saves init, condition and step functors
|
Chris@16
|
86 // for later use the parse member function
|
Chris@16
|
87 for_parser
|
Chris@16
|
88 (
|
Chris@16
|
89 InitF const &i, CondT const &c, StepF const &s,
|
Chris@16
|
90 ParsableT const &p
|
Chris@16
|
91 )
|
Chris@16
|
92 : for_init_functor<InitF>(i)
|
Chris@16
|
93 , for_step_functor<StepF>(s)
|
Chris@16
|
94 , eval_t(cond_as_parser_t::convert(c))
|
Chris@16
|
95 , base_t(as_parser_t::convert(p))
|
Chris@16
|
96 { }
|
Chris@16
|
97
|
Chris@16
|
98 for_parser()
|
Chris@16
|
99 : for_init_functor<InitF>()
|
Chris@16
|
100 , for_step_functor<StepF>()
|
Chris@16
|
101 , eval_t()
|
Chris@16
|
102 , base_t()
|
Chris@16
|
103 {}
|
Chris@16
|
104
|
Chris@16
|
105 //////////////////////////////
|
Chris@16
|
106 // parse member function
|
Chris@16
|
107 template <typename ScannerT>
|
Chris@16
|
108 typename parser_result<self_t, ScannerT>::type
|
Chris@16
|
109 parse(ScannerT const &scan) const
|
Chris@16
|
110 {
|
Chris@16
|
111 typedef typename parser_result<self_t, ScannerT>::type
|
Chris@16
|
112 result_t;
|
Chris@16
|
113 typedef typename parser_result<parser_t, ScannerT>::type
|
Chris@16
|
114 body_result_t;
|
Chris@16
|
115
|
Chris@16
|
116 typename ScannerT::iterator_t save(scan.first);
|
Chris@16
|
117
|
Chris@16
|
118 std::size_t length = 0;
|
Chris@16
|
119 int eval_length = 0;
|
Chris@16
|
120
|
Chris@16
|
121 this->init();
|
Chris@16
|
122 while ((eval_length = this->evaluate(scan))>=0)
|
Chris@16
|
123 {
|
Chris@16
|
124 length += eval_length;
|
Chris@16
|
125 body_result_t tmp(this->subject().parse(scan));
|
Chris@16
|
126 if (tmp)
|
Chris@16
|
127 {
|
Chris@16
|
128 length+=tmp.length();
|
Chris@16
|
129 }
|
Chris@16
|
130 else
|
Chris@16
|
131 {
|
Chris@16
|
132 return scan.no_match();
|
Chris@16
|
133 }
|
Chris@16
|
134 this->step();
|
Chris@16
|
135 }
|
Chris@16
|
136
|
Chris@16
|
137 BOOST_SPIRIT_CLASSIC_NS::nil_t attr;
|
Chris@16
|
138 return scan.create_match
|
Chris@16
|
139 (length, attr, save, scan.first);
|
Chris@16
|
140 }
|
Chris@16
|
141 };
|
Chris@16
|
142
|
Chris@16
|
143 //////////////////////////////////
|
Chris@16
|
144 // for_parser_gen generates takes the body parser in brackets
|
Chris@16
|
145 // and returns the for_parser
|
Chris@16
|
146 template <typename InitF, typename CondT, typename StepF>
|
Chris@16
|
147 struct for_parser_gen
|
Chris@16
|
148 {
|
Chris@16
|
149 for_parser_gen(InitF const &i, CondT const &c, StepF const &s)
|
Chris@16
|
150 : init(i)
|
Chris@16
|
151 , condition(c)
|
Chris@16
|
152 , step(s)
|
Chris@16
|
153 {}
|
Chris@16
|
154
|
Chris@16
|
155 template <typename ParsableT>
|
Chris@16
|
156 for_parser<InitF, CondT, StepF, ParsableT>
|
Chris@16
|
157 operator[](ParsableT const &p) const
|
Chris@16
|
158 {
|
Chris@16
|
159 return for_parser<InitF, CondT, StepF, ParsableT>
|
Chris@16
|
160 (init, condition, step, p);
|
Chris@16
|
161 }
|
Chris@16
|
162
|
Chris@16
|
163 InitF const &init;
|
Chris@16
|
164 CondT const &condition;
|
Chris@16
|
165 StepF const &step;
|
Chris@16
|
166 };
|
Chris@16
|
167 } // namespace impl
|
Chris@16
|
168
|
Chris@16
|
169 //////////////////////////////
|
Chris@16
|
170 // for_p, returns for-parser generator
|
Chris@16
|
171 // Usage: spirit::for_p(init-ftor, condition, step-ftor)[body]
|
Chris@16
|
172 template
|
Chris@16
|
173 <
|
Chris@16
|
174 typename InitF, typename ConditionT, typename StepF
|
Chris@16
|
175 >
|
Chris@16
|
176 impl::for_parser_gen<InitF, ConditionT, StepF>
|
Chris@16
|
177 for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f)
|
Chris@16
|
178 {
|
Chris@16
|
179 return impl::for_parser_gen<InitF, ConditionT, StepF>
|
Chris@16
|
180 (init_f, condition, step_f);
|
Chris@16
|
181 }
|
Chris@16
|
182
|
Chris@16
|
183 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
Chris@16
|
184
|
Chris@16
|
185 }} // namespace BOOST_SPIRIT_CLASSIC_NS
|
Chris@16
|
186
|
Chris@16
|
187 #endif // BOOST_SPIRIT_FOR_HPP
|