]>
Commit | Line | Data |
---|---|---|
1 | /*============================================================================= | |
2 | Copyright (c) 2002-2003 Hartmut Kaiser | |
3 | http://spirit.sourceforge.net/ | |
4 | ||
5 | Use, modification and distribution is subject to the Boost Software | |
6 | License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
7 | http://www.boost.org/LICENSE_1_0.txt) | |
8 | =============================================================================*/ | |
9 | #ifndef BOOST_SPIRIT_REFACTORING_IPP | |
10 | #define BOOST_SPIRIT_REFACTORING_IPP | |
11 | ||
12 | /////////////////////////////////////////////////////////////////////////////// | |
13 | namespace boost { namespace spirit { | |
14 | ||
15 | BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | |
16 | ||
17 | /////////////////////////////////////////////////////////////////////////////// | |
18 | // | |
19 | // The struct 'self_nested_refactoring' is used to indicate, that the | |
20 | // refactoring algorithm should be 'self-nested'. | |
21 | // | |
22 | // The struct 'non_nested_refactoring' is used to indicate, that no nesting | |
23 | // of refactoring algorithms is reqired. | |
24 | // | |
25 | /////////////////////////////////////////////////////////////////////////////// | |
26 | ||
27 | struct non_nested_refactoring { typedef non_nested_refactoring embed_t; }; | |
28 | struct self_nested_refactoring { typedef self_nested_refactoring embed_t; }; | |
29 | ||
30 | /////////////////////////////////////////////////////////////////////////////// | |
31 | namespace impl { | |
32 | ||
33 | /////////////////////////////////////////////////////////////////////////////// | |
34 | // | |
35 | // Helper templates for refactoring parsers | |
36 | // | |
37 | /////////////////////////////////////////////////////////////////////////////// | |
38 | ||
39 | /////////////////////////////////////////////////////////////////////////// | |
40 | // | |
41 | // refactor the left unary operand of a binary parser | |
42 | // | |
43 | // The refactoring should be done only if the left operand is an | |
44 | // unary_parser_category parser. | |
45 | // | |
46 | /////////////////////////////////////////////////////////////////////////// | |
47 | ||
48 | /////////////////////////////////////////////////////////////////////////// | |
49 | template <typename CategoryT> | |
50 | struct refactor_unary_nested { | |
51 | ||
52 | template < | |
53 | typename ParserT, typename NestedT, | |
54 | typename ScannerT, typename BinaryT | |
55 | > | |
56 | static typename parser_result<ParserT, ScannerT>::type | |
57 | parse(ParserT const &, ScannerT const& scan, BinaryT const& binary, | |
58 | NestedT const& /*nested_d*/) | |
59 | { | |
60 | return binary.parse(scan); | |
61 | } | |
62 | }; | |
63 | ||
64 | template <> | |
65 | struct refactor_unary_nested<unary_parser_category> { | |
66 | ||
67 | template < | |
68 | typename ParserT, typename ScannerT, typename BinaryT, | |
69 | typename NestedT | |
70 | > | |
71 | static typename parser_result<ParserT, ScannerT>::type | |
72 | parse(ParserT const &, ScannerT const& scan, BinaryT const& binary, | |
73 | NestedT const& nested_d) | |
74 | { | |
75 | typedef typename BinaryT::parser_generator_t op_t; | |
76 | typedef | |
77 | typename BinaryT::left_t::parser_generator_t | |
78 | unary_t; | |
79 | ||
80 | return | |
81 | unary_t::generate( | |
82 | nested_d[ | |
83 | op_t::generate(binary.left().subject(), binary.right()) | |
84 | ] | |
85 | ).parse(scan); | |
86 | } | |
87 | }; | |
88 | ||
89 | /////////////////////////////////////////////////////////////////////////// | |
90 | template <typename CategoryT> | |
91 | struct refactor_unary_non_nested { | |
92 | ||
93 | template <typename ParserT, typename ScannerT, typename BinaryT> | |
94 | static typename parser_result<ParserT, ScannerT>::type | |
95 | parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) | |
96 | { | |
97 | return binary.parse(scan); | |
98 | } | |
99 | }; | |
100 | ||
101 | template <> | |
102 | struct refactor_unary_non_nested<unary_parser_category> { | |
103 | ||
104 | template <typename ParserT, typename ScannerT, typename BinaryT> | |
105 | static typename parser_result<ParserT, ScannerT>::type | |
106 | parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) | |
107 | { | |
108 | typedef typename BinaryT::parser_generator_t op_t; | |
109 | typedef | |
110 | typename BinaryT::left_t::parser_generator_t | |
111 | unary_t; | |
112 | ||
113 | return unary_t::generate( | |
114 | op_t::generate(binary.left().subject(), binary.right()) | |
115 | ).parse(scan); | |
116 | } | |
117 | }; | |
118 | ||
119 | /////////////////////////////////////////////////////////////////////////// | |
120 | template <typename NestedT> | |
121 | struct refactor_unary_type { | |
122 | ||
123 | template <typename ParserT, typename ScannerT, typename BinaryT> | |
124 | static typename parser_result<ParserT, ScannerT>::type | |
125 | parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, | |
126 | NestedT const& nested_d) | |
127 | { | |
128 | typedef | |
129 | typename BinaryT::left_t::parser_category_t | |
130 | parser_category_t; | |
131 | ||
132 | return refactor_unary_nested<parser_category_t>:: | |
133 | parse(p, scan, binary, nested_d); | |
134 | } | |
135 | }; | |
136 | ||
137 | template <> | |
138 | struct refactor_unary_type<non_nested_refactoring> { | |
139 | ||
140 | template <typename ParserT, typename ScannerT, typename BinaryT> | |
141 | static typename parser_result<ParserT, ScannerT>::type | |
142 | parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, | |
143 | non_nested_refactoring const&) | |
144 | { | |
145 | typedef | |
146 | typename BinaryT::left_t::parser_category_t | |
147 | parser_category_t; | |
148 | ||
149 | return refactor_unary_non_nested<parser_category_t>:: | |
150 | parse(p, scan, binary); | |
151 | } | |
152 | ||
153 | }; | |
154 | ||
155 | template <> | |
156 | struct refactor_unary_type<self_nested_refactoring> { | |
157 | ||
158 | template <typename ParserT, typename ScannerT, typename BinaryT> | |
159 | static typename parser_result<ParserT, ScannerT>::type | |
160 | parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, | |
161 | self_nested_refactoring const &nested_tag) | |
162 | { | |
163 | typedef | |
164 | typename BinaryT::left_t::parser_category_t | |
165 | parser_category_t; | |
166 | typedef typename ParserT::parser_generator_t parser_generator_t; | |
167 | ||
168 | parser_generator_t nested_d(nested_tag); | |
169 | return refactor_unary_nested<parser_category_t>:: | |
170 | parse(p, scan, binary, nested_d); | |
171 | } | |
172 | ||
173 | }; | |
174 | ||
175 | /////////////////////////////////////////////////////////////////////////// | |
176 | // | |
177 | // refactor the action on the left operand of a binary parser | |
178 | // | |
179 | // The refactoring should be done only if the left operand is an | |
180 | // action_parser_category parser. | |
181 | // | |
182 | /////////////////////////////////////////////////////////////////////////// | |
183 | ||
184 | /////////////////////////////////////////////////////////////////////////// | |
185 | template <typename CategoryT> | |
186 | struct refactor_action_nested { | |
187 | ||
188 | template < | |
189 | typename ParserT, typename ScannerT, typename BinaryT, | |
190 | typename NestedT | |
191 | > | |
192 | static typename parser_result<ParserT, ScannerT>::type | |
193 | parse(ParserT const &, ScannerT const& scan, BinaryT const& binary, | |
194 | NestedT const& nested_d) | |
195 | { | |
196 | return nested_d[binary].parse(scan); | |
197 | } | |
198 | }; | |
199 | ||
200 | template <> | |
201 | struct refactor_action_nested<action_parser_category> { | |
202 | ||
203 | template < | |
204 | typename ParserT, typename ScannerT, typename BinaryT, | |
205 | typename NestedT | |
206 | > | |
207 | static typename parser_result<ParserT, ScannerT>::type | |
208 | parse(ParserT const &, ScannerT const& scan, BinaryT const& binary, | |
209 | NestedT const& nested_d) | |
210 | { | |
211 | typedef typename BinaryT::parser_generator_t binary_gen_t; | |
212 | ||
213 | return ( | |
214 | nested_d[ | |
215 | binary_gen_t::generate( | |
216 | binary.left().subject(), | |
217 | binary.right() | |
218 | ) | |
219 | ][binary.left().predicate()] | |
220 | ).parse(scan); | |
221 | } | |
222 | }; | |
223 | ||
224 | /////////////////////////////////////////////////////////////////////////// | |
225 | template <typename CategoryT> | |
226 | struct refactor_action_non_nested { | |
227 | ||
228 | template <typename ParserT, typename ScannerT, typename BinaryT> | |
229 | static typename parser_result<ParserT, ScannerT>::type | |
230 | parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) | |
231 | { | |
232 | return binary.parse(scan); | |
233 | } | |
234 | }; | |
235 | ||
236 | template <> | |
237 | struct refactor_action_non_nested<action_parser_category> { | |
238 | ||
239 | template <typename ParserT, typename ScannerT, typename BinaryT> | |
240 | static typename parser_result<ParserT, ScannerT>::type | |
241 | parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) | |
242 | { | |
243 | typedef typename BinaryT::parser_generator_t binary_gen_t; | |
244 | ||
245 | return ( | |
246 | binary_gen_t::generate( | |
247 | binary.left().subject(), | |
248 | binary.right() | |
249 | )[binary.left().predicate()] | |
250 | ).parse(scan); | |
251 | } | |
252 | }; | |
253 | ||
254 | /////////////////////////////////////////////////////////////////////////// | |
255 | template <typename NestedT> | |
256 | struct refactor_action_type { | |
257 | ||
258 | template <typename ParserT, typename ScannerT, typename BinaryT> | |
259 | static typename parser_result<ParserT, ScannerT>::type | |
260 | parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, | |
261 | NestedT const& nested_d) | |
262 | { | |
263 | typedef | |
264 | typename BinaryT::left_t::parser_category_t | |
265 | parser_category_t; | |
266 | ||
267 | return refactor_action_nested<parser_category_t>:: | |
268 | parse(p, scan, binary, nested_d); | |
269 | } | |
270 | }; | |
271 | ||
272 | template <> | |
273 | struct refactor_action_type<non_nested_refactoring> { | |
274 | ||
275 | template <typename ParserT, typename ScannerT, typename BinaryT> | |
276 | static typename parser_result<ParserT, ScannerT>::type | |
277 | parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, | |
278 | non_nested_refactoring const&) | |
279 | { | |
280 | typedef | |
281 | typename BinaryT::left_t::parser_category_t | |
282 | parser_category_t; | |
283 | ||
284 | return refactor_action_non_nested<parser_category_t>:: | |
285 | parse(p, scan, binary); | |
286 | } | |
287 | }; | |
288 | ||
289 | template <> | |
290 | struct refactor_action_type<self_nested_refactoring> { | |
291 | ||
292 | template <typename ParserT, typename ScannerT, typename BinaryT> | |
293 | static typename parser_result<ParserT, ScannerT>::type | |
294 | parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary, | |
295 | self_nested_refactoring const &nested_tag) | |
296 | { | |
297 | typedef typename ParserT::parser_generator_t parser_generator_t; | |
298 | typedef | |
299 | typename BinaryT::left_t::parser_category_t | |
300 | parser_category_t; | |
301 | ||
302 | parser_generator_t nested_d(nested_tag); | |
303 | return refactor_action_nested<parser_category_t>:: | |
304 | parse(p, scan, binary, nested_d); | |
305 | } | |
306 | }; | |
307 | ||
308 | /////////////////////////////////////////////////////////////////////////// | |
309 | // | |
310 | // refactor the action attached to a binary parser | |
311 | // | |
312 | // The refactoring should be done only if the given parser is an | |
313 | // binary_parser_category parser. | |
314 | // | |
315 | /////////////////////////////////////////////////////////////////////////// | |
316 | ||
317 | /////////////////////////////////////////////////////////////////////////// | |
318 | template <typename CategoryT> | |
319 | struct attach_action_nested { | |
320 | ||
321 | template < | |
322 | typename ParserT, typename ScannerT, typename ActionT, | |
323 | typename NestedT | |
324 | > | |
325 | static typename parser_result<ParserT, ScannerT>::type | |
326 | parse(ParserT const &, ScannerT const& scan, ActionT const &action, | |
327 | NestedT const& nested_d) | |
328 | { | |
329 | return action.parse(scan); | |
330 | } | |
331 | }; | |
332 | ||
333 | template <> | |
334 | struct attach_action_nested<binary_parser_category> { | |
335 | ||
336 | template < | |
337 | typename ParserT, typename ScannerT, typename ActionT, | |
338 | typename NestedT | |
339 | > | |
340 | static typename parser_result<ParserT, ScannerT>::type | |
341 | parse(ParserT const &, ScannerT const& scan, ActionT const &action, | |
342 | NestedT const& nested_d) | |
343 | { | |
344 | typedef | |
345 | typename ActionT::subject_t::parser_generator_t | |
346 | binary_gen_t; | |
347 | ||
348 | return ( | |
349 | binary_gen_t::generate( | |
350 | nested_d[action.subject().left()[action.predicate()]], | |
351 | nested_d[action.subject().right()[action.predicate()]] | |
352 | ) | |
353 | ).parse(scan); | |
354 | } | |
355 | }; | |
356 | ||
357 | /////////////////////////////////////////////////////////////////////////// | |
358 | template <typename CategoryT> | |
359 | struct attach_action_non_nested { | |
360 | ||
361 | template <typename ParserT, typename ScannerT, typename ActionT> | |
362 | static typename parser_result<ParserT, ScannerT>::type | |
363 | parse(ParserT const &, ScannerT const& scan, ActionT const &action) | |
364 | { | |
365 | return action.parse(scan); | |
366 | } | |
367 | }; | |
368 | ||
369 | template <> | |
370 | struct attach_action_non_nested<binary_parser_category> { | |
371 | ||
372 | template <typename ParserT, typename ScannerT, typename ActionT> | |
373 | static typename parser_result<ParserT, ScannerT>::type | |
374 | parse(ParserT const &, ScannerT const& scan, ActionT const &action) | |
375 | { | |
376 | typedef | |
377 | typename ActionT::subject_t::parser_generator_t | |
378 | binary_gen_t; | |
379 | ||
380 | return ( | |
381 | binary_gen_t::generate( | |
382 | action.subject().left()[action.predicate()], | |
383 | action.subject().right()[action.predicate()] | |
384 | ) | |
385 | ).parse(scan); | |
386 | } | |
387 | }; | |
388 | ||
389 | /////////////////////////////////////////////////////////////////////////// | |
390 | template <typename NestedT> | |
391 | struct attach_action_type { | |
392 | ||
393 | template <typename ParserT, typename ScannerT, typename ActionT> | |
394 | static typename parser_result<ParserT, ScannerT>::type | |
395 | parse(ParserT const &p, ScannerT const& scan, ActionT const& action, | |
396 | NestedT const& nested_d) | |
397 | { | |
398 | typedef | |
399 | typename ActionT::subject_t::parser_category_t | |
400 | parser_category_t; | |
401 | ||
402 | return attach_action_nested<parser_category_t>:: | |
403 | parse(p, scan, action, nested_d); | |
404 | } | |
405 | }; | |
406 | ||
407 | template <> | |
408 | struct attach_action_type<non_nested_refactoring> { | |
409 | ||
410 | template <typename ParserT, typename ScannerT, typename ActionT> | |
411 | static typename parser_result<ParserT, ScannerT>::type | |
412 | parse(ParserT const &p, ScannerT const& scan, ActionT const &action, | |
413 | non_nested_refactoring const&) | |
414 | { | |
415 | typedef | |
416 | typename ActionT::subject_t::parser_category_t | |
417 | parser_category_t; | |
418 | ||
419 | return attach_action_non_nested<parser_category_t>:: | |
420 | parse(p, scan, action); | |
421 | } | |
422 | }; | |
423 | ||
424 | template <> | |
425 | struct attach_action_type<self_nested_refactoring> { | |
426 | ||
427 | template <typename ParserT, typename ScannerT, typename ActionT> | |
428 | static typename parser_result<ParserT, ScannerT>::type | |
429 | parse(ParserT const &p, ScannerT const& scan, ActionT const &action, | |
430 | self_nested_refactoring const& nested_tag) | |
431 | { | |
432 | typedef typename ParserT::parser_generator_t parser_generator_t; | |
433 | typedef | |
434 | typename ActionT::subject_t::parser_category_t | |
435 | parser_category_t; | |
436 | ||
437 | parser_generator_t nested_d(nested_tag); | |
438 | return attach_action_nested<parser_category_t>:: | |
439 | parse(p, scan, action, nested_d); | |
440 | } | |
441 | }; | |
442 | ||
443 | } // namespace impl | |
444 | ||
445 | /////////////////////////////////////////////////////////////////////////////// | |
446 | BOOST_SPIRIT_CLASSIC_NAMESPACE_END | |
447 | ||
448 | }} // namespace boost::spirit | |
449 | ||
450 | #endif | |
451 |