1 /*=============================================================================
2 Copyright (c) 2002-2003 Hartmut Kaiser
3 http://spirit.sourceforge.net/
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
12 ///////////////////////////////////////////////////////////////////////////////
13 namespace boost { namespace spirit {
15 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
17 ///////////////////////////////////////////////////////////////////////////////
19 // The struct 'self_nested_refactoring' is used to indicate, that the
20 // refactoring algorithm should be 'self-nested'.
22 // The struct 'non_nested_refactoring' is used to indicate, that no nesting
23 // of refactoring algorithms is reqired.
25 ///////////////////////////////////////////////////////////////////////////////
27 struct non_nested_refactoring { typedef non_nested_refactoring embed_t; };
28 struct self_nested_refactoring { typedef self_nested_refactoring embed_t; };
30 ///////////////////////////////////////////////////////////////////////////////
33 ///////////////////////////////////////////////////////////////////////////////
35 // Helper templates for refactoring parsers
37 ///////////////////////////////////////////////////////////////////////////////
39 ///////////////////////////////////////////////////////////////////////////
41 // refactor the left unary operand of a binary parser
43 // The refactoring should be done only if the left operand is an
44 // unary_parser_category parser.
46 ///////////////////////////////////////////////////////////////////////////
48 ///////////////////////////////////////////////////////////////////////////
49 template <typename CategoryT>
50 struct refactor_unary_nested {
53 typename ParserT, typename NestedT,
54 typename ScannerT, typename BinaryT
56 static typename parser_result<ParserT, ScannerT>::type
57 parse(ParserT const &, ScannerT const& scan, BinaryT const& binary,
58 NestedT const& /*nested_d*/)
60 return binary.parse(scan);
65 struct refactor_unary_nested<unary_parser_category> {
68 typename ParserT, typename ScannerT, typename BinaryT,
71 static typename parser_result<ParserT, ScannerT>::type
72 parse(ParserT const &, ScannerT const& scan, BinaryT const& binary,
73 NestedT const& nested_d)
75 typedef typename BinaryT::parser_generator_t op_t;
77 typename BinaryT::left_t::parser_generator_t
83 op_t::generate(binary.left().subject(), binary.right())
89 ///////////////////////////////////////////////////////////////////////////
90 template <typename CategoryT>
91 struct refactor_unary_non_nested {
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)
97 return binary.parse(scan);
102 struct refactor_unary_non_nested<unary_parser_category> {
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)
108 typedef typename BinaryT::parser_generator_t op_t;
110 typename BinaryT::left_t::parser_generator_t
113 return unary_t::generate(
114 op_t::generate(binary.left().subject(), binary.right())
119 ///////////////////////////////////////////////////////////////////////////
120 template <typename NestedT>
121 struct refactor_unary_type {
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)
129 typename BinaryT::left_t::parser_category_t
132 return refactor_unary_nested<parser_category_t>::
133 parse(p, scan, binary, nested_d);
138 struct refactor_unary_type<non_nested_refactoring> {
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&)
146 typename BinaryT::left_t::parser_category_t
149 return refactor_unary_non_nested<parser_category_t>::
150 parse(p, scan, binary);
156 struct refactor_unary_type<self_nested_refactoring> {
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)
164 typename BinaryT::left_t::parser_category_t
166 typedef typename ParserT::parser_generator_t parser_generator_t;
168 parser_generator_t nested_d(nested_tag);
169 return refactor_unary_nested<parser_category_t>::
170 parse(p, scan, binary, nested_d);
175 ///////////////////////////////////////////////////////////////////////////
177 // refactor the action on the left operand of a binary parser
179 // The refactoring should be done only if the left operand is an
180 // action_parser_category parser.
182 ///////////////////////////////////////////////////////////////////////////
184 ///////////////////////////////////////////////////////////////////////////
185 template <typename CategoryT>
186 struct refactor_action_nested {
189 typename ParserT, typename ScannerT, typename BinaryT,
192 static typename parser_result<ParserT, ScannerT>::type
193 parse(ParserT const &, ScannerT const& scan, BinaryT const& binary,
194 NestedT const& nested_d)
196 return nested_d[binary].parse(scan);
201 struct refactor_action_nested<action_parser_category> {
204 typename ParserT, typename ScannerT, typename BinaryT,
207 static typename parser_result<ParserT, ScannerT>::type
208 parse(ParserT const &, ScannerT const& scan, BinaryT const& binary,
209 NestedT const& nested_d)
211 typedef typename BinaryT::parser_generator_t binary_gen_t;
215 binary_gen_t::generate(
216 binary.left().subject(),
219 ][binary.left().predicate()]
224 ///////////////////////////////////////////////////////////////////////////
225 template <typename CategoryT>
226 struct refactor_action_non_nested {
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)
232 return binary.parse(scan);
237 struct refactor_action_non_nested<action_parser_category> {
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)
243 typedef typename BinaryT::parser_generator_t binary_gen_t;
246 binary_gen_t::generate(
247 binary.left().subject(),
249 )[binary.left().predicate()]
254 ///////////////////////////////////////////////////////////////////////////
255 template <typename NestedT>
256 struct refactor_action_type {
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)
264 typename BinaryT::left_t::parser_category_t
267 return refactor_action_nested<parser_category_t>::
268 parse(p, scan, binary, nested_d);
273 struct refactor_action_type<non_nested_refactoring> {
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&)
281 typename BinaryT::left_t::parser_category_t
284 return refactor_action_non_nested<parser_category_t>::
285 parse(p, scan, binary);
290 struct refactor_action_type<self_nested_refactoring> {
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)
297 typedef typename ParserT::parser_generator_t parser_generator_t;
299 typename BinaryT::left_t::parser_category_t
302 parser_generator_t nested_d(nested_tag);
303 return refactor_action_nested<parser_category_t>::
304 parse(p, scan, binary, nested_d);
308 ///////////////////////////////////////////////////////////////////////////
310 // refactor the action attached to a binary parser
312 // The refactoring should be done only if the given parser is an
313 // binary_parser_category parser.
315 ///////////////////////////////////////////////////////////////////////////
317 ///////////////////////////////////////////////////////////////////////////
318 template <typename CategoryT>
319 struct attach_action_nested {
322 typename ParserT, typename ScannerT, typename ActionT,
325 static typename parser_result<ParserT, ScannerT>::type
326 parse(ParserT const &, ScannerT const& scan, ActionT const &action,
327 NestedT const& nested_d)
329 return action.parse(scan);
334 struct attach_action_nested<binary_parser_category> {
337 typename ParserT, typename ScannerT, typename ActionT,
340 static typename parser_result<ParserT, ScannerT>::type
341 parse(ParserT const &, ScannerT const& scan, ActionT const &action,
342 NestedT const& nested_d)
345 typename ActionT::subject_t::parser_generator_t
349 binary_gen_t::generate(
350 nested_d[action.subject().left()[action.predicate()]],
351 nested_d[action.subject().right()[action.predicate()]]
357 ///////////////////////////////////////////////////////////////////////////
358 template <typename CategoryT>
359 struct attach_action_non_nested {
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)
365 return action.parse(scan);
370 struct attach_action_non_nested<binary_parser_category> {
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)
377 typename ActionT::subject_t::parser_generator_t
381 binary_gen_t::generate(
382 action.subject().left()[action.predicate()],
383 action.subject().right()[action.predicate()]
389 ///////////////////////////////////////////////////////////////////////////
390 template <typename NestedT>
391 struct attach_action_type {
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)
399 typename ActionT::subject_t::parser_category_t
402 return attach_action_nested<parser_category_t>::
403 parse(p, scan, action, nested_d);
408 struct attach_action_type<non_nested_refactoring> {
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&)
416 typename ActionT::subject_t::parser_category_t
419 return attach_action_non_nested<parser_category_t>::
420 parse(p, scan, action);
425 struct attach_action_type<self_nested_refactoring> {
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)
432 typedef typename ParserT::parser_generator_t parser_generator_t;
434 typename ActionT::subject_t::parser_category_t
437 parser_generator_t nested_d(nested_tag);
438 return attach_action_nested<parser_category_t>::
439 parse(p, scan, action, nested_d);
445 ///////////////////////////////////////////////////////////////////////////////
446 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
448 }} // namespace boost::spirit