]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // as_quantifier.hpp | |
3 | // | |
4 | // Copyright 2008 Eric Niebler. Distributed under the Boost | |
5 | // Software License, Version 1.0. (See accompanying file | |
6 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007 | |
9 | #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007 | |
10 | ||
11 | // MS compatible compilers support #pragma once | |
12 | #if defined(_MSC_VER) | |
13 | # pragma once | |
14 | #endif | |
15 | ||
16 | #include <boost/mpl/assert.hpp> | |
17 | #include <boost/type_traits/is_same.hpp> | |
18 | #include <boost/xpressive/detail/detail_fwd.hpp> | |
19 | #include <boost/xpressive/detail/static/static.hpp> | |
20 | #include <boost/proto/core.hpp> | |
21 | ||
22 | namespace boost { namespace xpressive { namespace detail | |
23 | { | |
24 | /////////////////////////////////////////////////////////////////////////////// | |
25 | // generic_quant_tag | |
26 | template<uint_t Min, uint_t Max> | |
27 | struct generic_quant_tag | |
28 | { | |
29 | typedef mpl::integral_c<uint_t, Min> min_type; | |
30 | typedef mpl::integral_c<uint_t, Max> max_type; | |
31 | }; | |
32 | }}} | |
33 | ||
34 | namespace boost { namespace xpressive { namespace grammar_detail | |
35 | { | |
36 | using detail::uint_t; | |
37 | ||
38 | /////////////////////////////////////////////////////////////////////////////// | |
39 | // min_type / max_type | |
40 | template<typename Tag> | |
41 | struct min_type : Tag::min_type {}; | |
42 | ||
43 | template<> | |
44 | struct min_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, 1> {}; | |
45 | ||
46 | template<> | |
47 | struct min_type<proto::tag::dereference> : mpl::integral_c<uint_t, 0> {}; | |
48 | ||
49 | template<> | |
50 | struct min_type<proto::tag::logical_not> : mpl::integral_c<uint_t, 0> {}; | |
51 | ||
52 | template<typename Tag> | |
53 | struct max_type : Tag::max_type {}; | |
54 | ||
55 | template<> | |
56 | struct max_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, UINT_MAX-1> {}; | |
57 | ||
58 | template<> | |
59 | struct max_type<proto::tag::dereference> : mpl::integral_c<uint_t, UINT_MAX-1> {}; | |
60 | ||
61 | template<> | |
62 | struct max_type<proto::tag::logical_not> : mpl::integral_c<uint_t, 1> {}; | |
63 | ||
64 | /////////////////////////////////////////////////////////////////////////////// | |
65 | // as_simple_quantifier | |
66 | template<typename Grammar, typename Greedy, typename Callable = proto::callable> | |
67 | struct as_simple_quantifier : proto::transform<as_simple_quantifier<Grammar, Greedy, Callable> > | |
68 | { | |
69 | template<typename Expr, typename State, typename Data> | |
70 | struct impl : proto::transform_impl<Expr, State, Data> | |
71 | { | |
72 | typedef | |
73 | typename proto::result_of::child<Expr>::type | |
74 | arg_type; | |
75 | ||
76 | typedef | |
77 | typename Grammar::template impl<arg_type, detail::true_xpression, Data>::result_type | |
78 | xpr_type; | |
79 | ||
80 | typedef | |
81 | detail::simple_repeat_matcher<xpr_type, Greedy> | |
82 | matcher_type; | |
83 | ||
84 | typedef | |
85 | typename proto::terminal<matcher_type>::type | |
86 | result_type; | |
87 | ||
88 | result_type operator ()( | |
89 | typename impl::expr_param expr | |
90 | , typename impl::state_param | |
91 | , typename impl::data_param data | |
92 | ) const | |
93 | { | |
94 | xpr_type xpr = typename Grammar::template impl<arg_type, detail::true_xpression, Data>()( | |
95 | proto::child(expr) | |
96 | , detail::true_xpression() | |
97 | , data | |
98 | ); | |
99 | ||
100 | typedef typename impl::expr expr_type; | |
101 | matcher_type matcher( | |
102 | xpr | |
103 | , (uint_t)min_type<typename expr_type::proto_tag>::value | |
104 | , (uint_t)max_type<typename expr_type::proto_tag>::value | |
105 | , xpr.get_width().value() | |
106 | ); | |
107 | ||
108 | return result_type::make(matcher); | |
109 | } | |
110 | }; | |
111 | }; | |
112 | ||
113 | /////////////////////////////////////////////////////////////////////////////// | |
114 | // add_hidden_mark | |
115 | struct add_hidden_mark : proto::transform<add_hidden_mark> | |
116 | { | |
117 | template<typename Expr, typename State, typename Data> | |
118 | struct impl : proto::transform_impl<Expr, State, Data> | |
119 | { | |
120 | typedef typename impl::expr expr_type; | |
121 | typedef | |
122 | typename shift_right< | |
123 | terminal<detail::mark_begin_matcher>::type | |
124 | , typename shift_right< | |
125 | Expr | |
126 | , terminal<detail::mark_end_matcher>::type | |
127 | >::type | |
128 | >::type | |
129 | result_type; | |
130 | ||
131 | result_type operator ()( | |
132 | typename impl::expr_param expr | |
133 | , typename impl::state_param | |
134 | , typename impl::data_param data | |
135 | ) const | |
136 | { | |
137 | // we're inserting a hidden mark ... so grab the next hidden mark number. | |
138 | int mark_nbr = data.get_hidden_mark(); | |
139 | detail::mark_begin_matcher begin(mark_nbr); | |
140 | detail::mark_end_matcher end(mark_nbr); | |
141 | ||
142 | result_type that = {{begin}, {expr, {end}}}; | |
143 | return that; | |
144 | } | |
145 | }; | |
146 | }; | |
147 | ||
148 | /////////////////////////////////////////////////////////////////////////////// | |
149 | // InsertMark | |
150 | struct InsertMark | |
151 | : or_< | |
152 | when<proto::assign<detail::basic_mark_tag, _>, _> | |
153 | , otherwise<add_hidden_mark> | |
154 | > | |
155 | {}; | |
156 | ||
157 | /////////////////////////////////////////////////////////////////////////////// | |
158 | // as_default_quantifier_impl | |
159 | template<typename Greedy, uint_t Min, uint_t Max> | |
160 | struct as_default_quantifier_impl : proto::transform<as_default_quantifier_impl<Greedy, Min, Max> > | |
161 | { | |
162 | template<typename Expr, typename State, typename Data> | |
163 | struct impl : proto::transform_impl<Expr, State, Data> | |
164 | { | |
165 | typedef | |
166 | typename proto::result_of::child<Expr>::type | |
167 | xpr_type; | |
168 | ||
169 | typedef | |
170 | typename InsertMark::impl<xpr_type, State, Data>::result_type | |
171 | marked_sub_type; | |
172 | ||
173 | typedef | |
174 | typename shift_right< | |
175 | terminal<detail::repeat_begin_matcher>::type | |
176 | , typename shift_right< | |
177 | marked_sub_type | |
178 | , typename terminal<detail::repeat_end_matcher<Greedy> >::type | |
179 | >::type | |
180 | >::type | |
181 | result_type; | |
182 | ||
183 | result_type operator ()( | |
184 | typename impl::expr_param expr | |
185 | , typename impl::state_param state | |
186 | , typename impl::data_param data | |
187 | ) const | |
188 | { | |
189 | // Ensure this sub-expression is book-ended with mark matchers | |
190 | marked_sub_type marked_sub = | |
191 | InsertMark::impl<xpr_type, State, Data>()(proto::child(expr), state, data); | |
192 | ||
193 | // Get the mark_number from the begin_mark_matcher | |
194 | int mark_number = proto::value(proto::left(marked_sub)).mark_number_; | |
195 | BOOST_ASSERT(0 != mark_number); | |
196 | ||
197 | typedef typename impl::expr expr_type; | |
198 | uint_t min_ = (uint_t)min_type<typename expr_type::proto_tag>(); | |
199 | uint_t max_ = (uint_t)max_type<typename expr_type::proto_tag>(); | |
200 | ||
201 | detail::repeat_begin_matcher begin(mark_number); | |
202 | detail::repeat_end_matcher<Greedy> end(mark_number, min_, max_); | |
203 | ||
204 | result_type that = {{begin}, {marked_sub, {end}}}; | |
205 | return that; | |
206 | } | |
207 | }; | |
208 | }; | |
209 | ||
210 | /////////////////////////////////////////////////////////////////////////////// | |
211 | // optional_tag | |
212 | template<typename Greedy> | |
213 | struct optional_tag | |
214 | {}; | |
215 | ||
216 | /////////////////////////////////////////////////////////////////////////////// | |
217 | // as_default_optional | |
218 | template<typename Grammar, typename Greedy, typename Callable = proto::callable> | |
219 | struct as_default_optional : proto::transform<as_default_optional<Grammar, Greedy, Callable> > | |
220 | { | |
221 | template<typename Expr, typename State, typename Data> | |
222 | struct impl : proto::transform_impl<Expr, State, Data> | |
223 | { | |
224 | typedef | |
225 | detail::alternate_end_xpression | |
226 | end_xpr; | |
227 | ||
228 | typedef | |
229 | detail::optional_matcher< | |
230 | typename Grammar::template impl<Expr, end_xpr, Data>::result_type | |
231 | , Greedy | |
232 | > | |
233 | result_type; | |
234 | ||
235 | result_type operator ()( | |
236 | typename impl::expr_param expr | |
237 | , typename impl::state_param | |
238 | , typename impl::data_param data | |
239 | ) const | |
240 | { | |
241 | return result_type( | |
242 | typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data) | |
243 | ); | |
244 | } | |
245 | }; | |
246 | }; | |
247 | ||
248 | /////////////////////////////////////////////////////////////////////////////// | |
249 | // as_mark_optional | |
250 | template<typename Grammar, typename Greedy, typename Callable = proto::callable> | |
251 | struct as_mark_optional : proto::transform<as_mark_optional<Grammar, Greedy, Callable> > | |
252 | { | |
253 | template<typename Expr, typename State, typename Data> | |
254 | struct impl : proto::transform_impl<Expr, State, Data> | |
255 | { | |
256 | typedef | |
257 | detail::alternate_end_xpression | |
258 | end_xpr; | |
259 | ||
260 | typedef | |
261 | detail::optional_mark_matcher< | |
262 | typename Grammar::template impl<Expr, end_xpr, Data>::result_type | |
263 | , Greedy | |
264 | > | |
265 | result_type; | |
266 | ||
267 | result_type operator ()( | |
268 | typename impl::expr_param expr | |
269 | , typename impl::state_param | |
270 | , typename impl::data_param data | |
271 | ) const | |
272 | { | |
273 | int mark_number = proto::value(proto::left(expr)).mark_number_; | |
274 | ||
275 | return result_type( | |
276 | typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data) | |
277 | , mark_number | |
278 | ); | |
279 | } | |
280 | }; | |
281 | }; | |
282 | ||
283 | /////////////////////////////////////////////////////////////////////////////// | |
284 | // IsMarkerOrRepeater | |
285 | struct IsMarkerOrRepeater | |
286 | : or_< | |
287 | shift_right<terminal<detail::repeat_begin_matcher>, _> | |
288 | , assign<terminal<detail::mark_placeholder>, _> | |
289 | > | |
290 | {}; | |
291 | ||
292 | /////////////////////////////////////////////////////////////////////////////// | |
293 | // as_optional | |
294 | template<typename Grammar, typename Greedy> | |
295 | struct as_optional | |
296 | : or_< | |
297 | when<IsMarkerOrRepeater, as_mark_optional<Grammar, Greedy> > | |
298 | , otherwise<as_default_optional<Grammar, Greedy> > | |
299 | > | |
300 | {}; | |
301 | ||
302 | /////////////////////////////////////////////////////////////////////////////// | |
303 | // make_optional_ | |
304 | template<typename Greedy, typename Callable = proto::callable> | |
305 | struct make_optional_ : proto::transform<make_optional_<Greedy, Callable> > | |
306 | { | |
307 | template<typename Expr, typename State, typename Data> | |
308 | struct impl : proto::transform_impl<Expr, State, Data> | |
309 | { | |
310 | typedef typename impl::expr expr_type; | |
311 | typedef | |
312 | typename unary_expr< | |
313 | optional_tag<Greedy> | |
314 | , Expr | |
315 | >::type | |
316 | result_type; | |
317 | ||
318 | result_type operator ()( | |
319 | typename impl::expr_param expr | |
320 | , typename impl::state_param | |
321 | , typename impl::data_param | |
322 | ) const | |
323 | { | |
324 | result_type that = {expr}; | |
325 | return that; | |
326 | } | |
327 | }; | |
328 | }; | |
329 | ||
330 | /////////////////////////////////////////////////////////////////////////////// | |
331 | // as_default_quantifier_impl | |
332 | template<typename Greedy, uint_t Max> | |
333 | struct as_default_quantifier_impl<Greedy, 0, Max> | |
334 | : call<make_optional_<Greedy>(as_default_quantifier_impl<Greedy, 1, Max>)> | |
335 | {}; | |
336 | ||
337 | /////////////////////////////////////////////////////////////////////////////// | |
338 | // as_default_quantifier_impl | |
339 | template<typename Greedy> | |
340 | struct as_default_quantifier_impl<Greedy, 0, 1> | |
341 | : call<make_optional_<Greedy>(_child)> | |
342 | {}; | |
343 | ||
344 | /////////////////////////////////////////////////////////////////////////////// | |
345 | // as_default_quantifier | |
346 | template<typename Greedy, typename Callable = proto::callable> | |
347 | struct as_default_quantifier : proto::transform<as_default_quantifier<Greedy, Callable> > | |
348 | { | |
349 | template<typename Expr, typename State, typename Data> | |
350 | struct impl : proto::transform_impl<Expr, State, Data> | |
351 | { | |
352 | typedef typename impl::expr expr_type; | |
353 | typedef | |
354 | as_default_quantifier_impl< | |
355 | Greedy | |
356 | , min_type<typename expr_type::proto_tag>::value | |
357 | , max_type<typename expr_type::proto_tag>::value | |
358 | > | |
359 | other; | |
360 | ||
361 | typedef | |
362 | typename other::template impl<Expr, State, Data>::result_type | |
363 | result_type; | |
364 | ||
365 | result_type operator ()( | |
366 | typename impl::expr_param expr | |
367 | , typename impl::state_param state | |
368 | , typename impl::data_param data | |
369 | ) const | |
370 | { | |
371 | return typename other::template impl<Expr, State, Data>()(expr, state, data); | |
372 | } | |
373 | }; | |
374 | }; | |
375 | ||
376 | }}} | |
377 | ||
378 | #endif |