• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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///////////////////////////////////////////////////////////////////////////////
13namespace boost { namespace spirit {
14
15BOOST_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
27struct non_nested_refactoring { typedef non_nested_refactoring embed_t; };
28struct self_nested_refactoring { typedef self_nested_refactoring embed_t; };
29
30///////////////////////////////////////////////////////////////////////////////
31namespace 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///////////////////////////////////////////////////////////////////////////////
446BOOST_SPIRIT_CLASSIC_NAMESPACE_END
447
448}} // namespace boost::spirit
449
450#endif
451
452