Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/spirit/home/classic/tree/common.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /*============================================================================= | |
2 Copyright (c) 2001-2003 Daniel Nuffer | |
3 Copyright (c) 2001-2007 Hartmut Kaiser | |
4 Revised 2007, Copyright (c) Tobias Schwinger | |
5 http://spirit.sourceforge.net/ | |
6 | |
7 Distributed under the Boost Software License, Version 1.0. (See accompanying | |
8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 =============================================================================*/ | |
10 #ifndef BOOST_SPIRIT_TREE_COMMON_HPP | |
11 #define BOOST_SPIRIT_TREE_COMMON_HPP | |
12 | |
13 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) | |
14 #include <vector> | |
15 #else | |
16 #include <list> | |
17 #endif | |
18 | |
19 #if defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES) | |
20 #include <boost/pool/pool_alloc.hpp> | |
21 #endif | |
22 | |
23 #include <algorithm> | |
24 | |
25 #include <boost/ref.hpp> | |
26 #include <boost/call_traits.hpp> | |
27 #include <boost/spirit/home/classic/namespace.hpp> | |
28 #include <boost/spirit/home/classic/core.hpp> | |
29 #include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits | |
30 #include <boost/assert.hpp> | |
31 | |
32 #if defined(BOOST_SPIRIT_DEBUG) && \ | |
33 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) | |
34 #include <iostream> | |
35 #include <boost/spirit/home/classic/debug/debug_node.hpp> | |
36 #endif | |
37 | |
38 #include <boost/spirit/home/classic/tree/common_fwd.hpp> | |
39 | |
40 namespace boost { namespace spirit { | |
41 | |
42 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | |
43 | |
44 template <typename T> | |
45 void swap(tree_node<T>& a, tree_node<T>& b); | |
46 | |
47 template <typename T, typename V> | |
48 void swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b); | |
49 | |
50 namespace impl { | |
51 template <typename T> | |
52 inline void cp_swap(T& t1, T& t2); | |
53 } | |
54 | |
55 template <typename T> | |
56 struct tree_node | |
57 { | |
58 typedef T parse_node_t; | |
59 | |
60 #if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES) | |
61 typedef std::allocator<tree_node<T> > allocator_type; | |
62 #elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) | |
63 typedef boost::pool_allocator<tree_node<T> > allocator_type; | |
64 #else | |
65 typedef boost::fast_pool_allocator<tree_node<T> > allocator_type; | |
66 #endif | |
67 | |
68 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) | |
69 typedef std::vector<tree_node<T>, allocator_type> children_t; | |
70 #else | |
71 typedef std::list<tree_node<T>, allocator_type> children_t; | |
72 #endif // BOOST_SPIRIT_USE_LIST_FOR_TREES | |
73 | |
74 typedef typename children_t::iterator tree_iterator; | |
75 typedef typename children_t::const_iterator const_tree_iterator; | |
76 | |
77 T value; | |
78 children_t children; | |
79 | |
80 tree_node() | |
81 : value() | |
82 , children() | |
83 {} | |
84 | |
85 explicit tree_node(T const& v) | |
86 : value(v) | |
87 , children() | |
88 {} | |
89 | |
90 tree_node(T const& v, children_t const& c) | |
91 : value(v) | |
92 , children(c) | |
93 {} | |
94 | |
95 void swap(tree_node<T>& x) | |
96 { | |
97 impl::cp_swap(value, x.value); | |
98 impl::cp_swap(children, x.children); | |
99 } | |
100 | |
101 // Intel V5.0.1 has a problem without this explicit operator= | |
102 tree_node &operator= (tree_node const &rhs) | |
103 { | |
104 tree_node(rhs).swap(*this); | |
105 return *this; | |
106 } | |
107 }; | |
108 | |
109 #if defined(BOOST_SPIRIT_DEBUG) && \ | |
110 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) | |
111 template <typename T> | |
112 inline std::ostream& | |
113 operator<<(std::ostream& o, tree_node<T> const& n) | |
114 { | |
115 static int depth = 0; | |
116 o << "\n"; | |
117 for (int i = 0; i <= depth; ++i) | |
118 { | |
119 o << "\t"; | |
120 } | |
121 o << "(depth = " << depth++ << " value = " << n.value; | |
122 int c = 0; | |
123 for (typename tree_node<T>::children_t::const_iterator it = n.children.begin(); | |
124 it != n.children.end(); ++it) | |
125 { | |
126 o << " children[" << c++ << "] = " << *it; | |
127 } | |
128 o << ")"; | |
129 --depth; | |
130 return o; | |
131 } | |
132 #endif | |
133 | |
134 ////////////////////////////////// | |
135 template <typename IteratorT, typename ValueT> | |
136 struct node_iter_data | |
137 { | |
138 typedef IteratorT iterator_t; | |
139 typedef IteratorT /*const*/ const_iterator_t; | |
140 | |
141 node_iter_data() | |
142 : first(), last(), is_root_(false), parser_id_(), value_() | |
143 {} | |
144 | |
145 node_iter_data(IteratorT const& _first, IteratorT const& _last) | |
146 : first(_first), last(_last), is_root_(false), parser_id_(), value_() | |
147 {} | |
148 | |
149 void swap(node_iter_data& x) | |
150 { | |
151 impl::cp_swap(first, x.first); | |
152 impl::cp_swap(last, x.last); | |
153 impl::cp_swap(parser_id_, x.parser_id_); | |
154 impl::cp_swap(is_root_, x.is_root_); | |
155 impl::cp_swap(value_, x.value_); | |
156 } | |
157 | |
158 IteratorT begin() | |
159 { | |
160 return first; | |
161 } | |
162 | |
163 IteratorT const& begin() const | |
164 { | |
165 return first; | |
166 } | |
167 | |
168 IteratorT end() | |
169 { | |
170 return last; | |
171 } | |
172 | |
173 IteratorT const& end() const | |
174 { | |
175 return last; | |
176 } | |
177 | |
178 bool is_root() const | |
179 { | |
180 return is_root_; | |
181 } | |
182 | |
183 void is_root(bool b) | |
184 { | |
185 is_root_ = b; | |
186 } | |
187 | |
188 parser_id id() const | |
189 { | |
190 return parser_id_; | |
191 } | |
192 | |
193 void id(parser_id r) | |
194 { | |
195 parser_id_ = r; | |
196 } | |
197 | |
198 ValueT const& value() const | |
199 { | |
200 return value_; | |
201 } | |
202 | |
203 void value(ValueT const& v) | |
204 { | |
205 value_ = v; | |
206 } | |
207 private: | |
208 IteratorT first, last; | |
209 bool is_root_; | |
210 parser_id parser_id_; | |
211 ValueT value_; | |
212 | |
213 public: | |
214 }; | |
215 | |
216 #if defined(BOOST_SPIRIT_DEBUG) && \ | |
217 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) | |
218 // value is default nil_t, so provide an operator<< for nil_t | |
219 inline std::ostream& | |
220 operator<<(std::ostream& o, nil_t const&) | |
221 { | |
222 return o; | |
223 } | |
224 | |
225 template <typename IteratorT, typename ValueT> | |
226 inline std::ostream& | |
227 operator<<(std::ostream& o, node_iter_data<IteratorT, ValueT> const& n) | |
228 { | |
229 o << "(id = " << n.id() << " text = \""; | |
230 typedef typename node_iter_data<IteratorT, ValueT>::const_iterator_t | |
231 iterator_t; | |
232 for (iterator_t it = n.begin(); it != n.end(); ++it) | |
233 impl::token_printer(o, *it); | |
234 o << "\" is_root = " << n.is_root() | |
235 << /*" value = " << n.value() << */")"; | |
236 return o; | |
237 } | |
238 #endif | |
239 | |
240 ////////////////////////////////// | |
241 template <typename IteratorT = char const*, typename ValueT = nil_t> | |
242 struct node_val_data | |
243 { | |
244 typedef | |
245 typename boost::detail::iterator_traits<IteratorT>::value_type | |
246 value_type; | |
247 | |
248 #if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES) | |
249 typedef std::allocator<value_type> allocator_type; | |
250 #elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) | |
251 typedef boost::pool_allocator<value_type> allocator_type; | |
252 #else | |
253 typedef boost::fast_pool_allocator<value_type> allocator_type; | |
254 #endif | |
255 | |
256 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) | |
257 typedef std::vector<value_type, allocator_type> container_t; | |
258 #else | |
259 typedef std::list<value_type, allocator_type> container_t; | |
260 #endif | |
261 | |
262 typedef typename container_t::iterator iterator_t; | |
263 typedef typename container_t::const_iterator const_iterator_t; | |
264 | |
265 node_val_data() | |
266 : text(), is_root_(false), parser_id_(), value_() | |
267 {} | |
268 | |
269 #if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) | |
270 node_val_data(IteratorT const& _first, IteratorT const& _last) | |
271 : text(), is_root_(false), parser_id_(), value_() | |
272 { | |
273 std::copy(_first, _last, std::inserter(text, text.end())); | |
274 } | |
275 | |
276 // This constructor is for building text out of iterators | |
277 template <typename IteratorT2> | |
278 node_val_data(IteratorT2 const& _first, IteratorT2 const& _last) | |
279 : text(), is_root_(false), parser_id_(), value_() | |
280 { | |
281 std::copy(_first, _last, std::inserter(text, text.end())); | |
282 } | |
283 #else | |
284 node_val_data(IteratorT const& _first, IteratorT const& _last) | |
285 : text(_first, _last), is_root_(false), parser_id_(), value_() | |
286 {} | |
287 | |
288 // This constructor is for building text out of iterators | |
289 template <typename IteratorT2> | |
290 node_val_data(IteratorT2 const& _first, IteratorT2 const& _last) | |
291 : text(_first, _last), is_root_(false), parser_id_(), value_() | |
292 {} | |
293 #endif | |
294 | |
295 void swap(node_val_data& x) | |
296 { | |
297 impl::cp_swap(text, x.text); | |
298 impl::cp_swap(is_root_, x.is_root_); | |
299 impl::cp_swap(parser_id_, x.parser_id_); | |
300 impl::cp_swap(value_, x.value_); | |
301 } | |
302 | |
303 typename container_t::iterator begin() | |
304 { | |
305 return text.begin(); | |
306 } | |
307 | |
308 typename container_t::const_iterator begin() const | |
309 { | |
310 return text.begin(); | |
311 } | |
312 | |
313 typename container_t::iterator end() | |
314 { | |
315 return text.end(); | |
316 } | |
317 | |
318 typename container_t::const_iterator end() const | |
319 { | |
320 return text.end(); | |
321 } | |
322 | |
323 bool is_root() const | |
324 { | |
325 return is_root_; | |
326 } | |
327 | |
328 void is_root(bool b) | |
329 { | |
330 is_root_ = b; | |
331 } | |
332 | |
333 parser_id id() const | |
334 { | |
335 return parser_id_; | |
336 } | |
337 | |
338 void id(parser_id r) | |
339 { | |
340 parser_id_ = r; | |
341 } | |
342 | |
343 ValueT const& value() const | |
344 { | |
345 return value_; | |
346 } | |
347 | |
348 void value(ValueT const& v) | |
349 { | |
350 value_ = v; | |
351 } | |
352 | |
353 private: | |
354 container_t text; | |
355 bool is_root_; | |
356 parser_id parser_id_; | |
357 ValueT value_; | |
358 }; | |
359 | |
360 #if defined(BOOST_SPIRIT_DEBUG) && \ | |
361 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) | |
362 template <typename IteratorT, typename ValueT> | |
363 inline std::ostream& | |
364 operator<<(std::ostream& o, node_val_data<IteratorT, ValueT> const& n) | |
365 { | |
366 o << "(id = " << n.id() << " text = \""; | |
367 typedef typename node_val_data<IteratorT, ValueT>::const_iterator_t | |
368 iterator_t; | |
369 for (iterator_t it = n.begin(); it != n.end(); ++it) | |
370 impl::token_printer(o, *it); | |
371 o << "\" is_root = " << n.is_root() | |
372 << " value = " << n.value() << ")"; | |
373 return o; | |
374 } | |
375 #endif | |
376 | |
377 template <typename T> | |
378 inline void | |
379 swap(tree_node<T>& a, tree_node<T>& b) | |
380 { | |
381 a.swap(b); | |
382 } | |
383 | |
384 template <typename T, typename V> | |
385 inline void | |
386 swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b) | |
387 { | |
388 a.swap(b); | |
389 } | |
390 | |
391 ////////////////////////////////// | |
392 template <typename ValueT> | |
393 class node_iter_data_factory | |
394 { | |
395 public: | |
396 // This inner class is so that node_iter_data_factory can simulate | |
397 // a template template parameter | |
398 template <typename IteratorT> | |
399 class factory | |
400 { | |
401 public: | |
402 typedef IteratorT iterator_t; | |
403 typedef node_iter_data<iterator_t, ValueT> node_t; | |
404 | |
405 static node_t create_node(iterator_t const& first, iterator_t const& last, | |
406 bool /*is_leaf_node*/) | |
407 { | |
408 return node_t(first, last); | |
409 } | |
410 | |
411 static node_t empty_node() | |
412 { | |
413 return node_t(); | |
414 } | |
415 | |
416 // precondition: ContainerT contains a tree_node<node_t>. And all | |
417 // iterators in the container point to the same sequence. | |
418 template <typename ContainerT> | |
419 static node_t group_nodes(ContainerT const& nodes) | |
420 { | |
421 return node_t(nodes.begin()->value.begin(), | |
422 nodes.back().value.end()); | |
423 } | |
424 }; | |
425 }; | |
426 | |
427 ////////////////////////////////// | |
428 template <typename ValueT> | |
429 class node_val_data_factory | |
430 { | |
431 public: | |
432 // This inner class is so that node_val_data_factory can simulate | |
433 // a template template parameter | |
434 template <typename IteratorT> | |
435 class factory | |
436 { | |
437 public: | |
438 typedef IteratorT iterator_t; | |
439 typedef node_val_data<iterator_t, ValueT> node_t; | |
440 | |
441 static node_t create_node(iterator_t const& first, iterator_t const& last, | |
442 bool is_leaf_node) | |
443 { | |
444 if (is_leaf_node) | |
445 return node_t(first, last); | |
446 else | |
447 return node_t(); | |
448 } | |
449 | |
450 static node_t empty_node() | |
451 { | |
452 return node_t(); | |
453 } | |
454 | |
455 template <typename ContainerT> | |
456 static node_t group_nodes(ContainerT const& nodes) | |
457 { | |
458 typename node_t::container_t c; | |
459 typename ContainerT::const_iterator i_end = nodes.end(); | |
460 // copy all the nodes text into a new one | |
461 for (typename ContainerT::const_iterator i = nodes.begin(); | |
462 i != i_end; ++i) | |
463 { | |
464 // See docs: reduced_node_d cannot be used with a | |
465 // rule inside the []. | |
466 BOOST_ASSERT(i->children.size() == 0); | |
467 c.insert(c.end(), i->value.begin(), i->value.end()); | |
468 } | |
469 return node_t(c.begin(), c.end()); | |
470 } | |
471 }; | |
472 }; | |
473 | |
474 ////////////////////////////////// | |
475 template <typename ValueT> | |
476 class node_all_val_data_factory | |
477 { | |
478 public: | |
479 // This inner class is so that node_all_val_data_factory can simulate | |
480 // a template template parameter | |
481 template <typename IteratorT> | |
482 class factory | |
483 { | |
484 public: | |
485 typedef IteratorT iterator_t; | |
486 typedef node_val_data<iterator_t, ValueT> node_t; | |
487 | |
488 static node_t create_node(iterator_t const& first, iterator_t const& last, | |
489 bool /*is_leaf_node*/) | |
490 { | |
491 return node_t(first, last); | |
492 } | |
493 | |
494 static node_t empty_node() | |
495 { | |
496 return node_t(); | |
497 } | |
498 | |
499 template <typename ContainerT> | |
500 static node_t group_nodes(ContainerT const& nodes) | |
501 { | |
502 typename node_t::container_t c; | |
503 typename ContainerT::const_iterator i_end = nodes.end(); | |
504 // copy all the nodes text into a new one | |
505 for (typename ContainerT::const_iterator i = nodes.begin(); | |
506 i != i_end; ++i) | |
507 { | |
508 BOOST_ASSERT(i->children.size() == 0); | |
509 c.insert(c.end(), i->value.begin(), i->value.end()); | |
510 } | |
511 return node_t(c.begin(), c.end()); | |
512 } | |
513 }; | |
514 }; | |
515 | |
516 namespace impl { | |
517 | |
518 /////////////////////////////////////////////////////////////////////////// | |
519 // can't call unqualified swap from within classname::swap | |
520 // as Koenig lookup rules will find only the classname::swap | |
521 // member function not the global declaration, so use cp_swap | |
522 // as a forwarding function (JM): | |
523 #if __GNUC__ == 2 | |
524 using ::std::swap; | |
525 #endif | |
526 template <typename T> | |
527 inline void cp_swap(T& t1, T& t2) | |
528 { | |
529 using std::swap; | |
530 using BOOST_SPIRIT_CLASSIC_NS::swap; | |
531 using boost::swap; | |
532 swap(t1, t2); | |
533 } | |
534 } | |
535 | |
536 ////////////////////////////////// | |
537 template <typename IteratorT, typename NodeFactoryT, typename T> | |
538 class tree_match : public match<T> | |
539 { | |
540 public: | |
541 | |
542 typedef typename NodeFactoryT::template factory<IteratorT> node_factory_t; | |
543 typedef typename node_factory_t::node_t parse_node_t; | |
544 typedef tree_node<parse_node_t> node_t; | |
545 typedef typename node_t::children_t container_t; | |
546 typedef typename container_t::iterator tree_iterator; | |
547 typedef typename container_t::const_iterator const_tree_iterator; | |
548 | |
549 typedef T attr_t; | |
550 typedef typename boost::call_traits<T>::param_type param_type; | |
551 typedef typename boost::call_traits<T>::reference reference; | |
552 typedef typename boost::call_traits<T>::const_reference const_reference; | |
553 | |
554 tree_match() | |
555 : match<T>(), trees() | |
556 {} | |
557 | |
558 explicit | |
559 tree_match(std::size_t length_) | |
560 : match<T>(length_), trees() | |
561 {} | |
562 | |
563 tree_match(std::size_t length_, parse_node_t const& n) | |
564 : match<T>(length_), trees() | |
565 { | |
566 trees.push_back(node_t(n)); | |
567 } | |
568 | |
569 tree_match(std::size_t length_, param_type val, parse_node_t const& n) | |
570 : match<T>(length_, val), trees() | |
571 { | |
572 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) | |
573 trees.reserve(10); // this is more or less an arbitrary number... | |
574 #endif | |
575 trees.push_back(node_t(n)); | |
576 } | |
577 | |
578 // attention, these constructors will change the second parameter! | |
579 tree_match(std::size_t length_, container_t& c) | |
580 : match<T>(length_), trees() | |
581 { | |
582 impl::cp_swap(trees, c); | |
583 } | |
584 | |
585 tree_match(std::size_t length_, param_type val, container_t& c) | |
586 : match<T>(length_, val), trees() | |
587 { | |
588 impl::cp_swap(trees, c); | |
589 } | |
590 | |
591 template <typename T2> | |
592 tree_match(match<T2> const& other) | |
593 : match<T>(other), trees() | |
594 {} | |
595 | |
596 template <typename T2, typename T3, typename T4> | |
597 tree_match(tree_match<T2, T3, T4> const& other) | |
598 : match<T>(other), trees() | |
599 { impl::cp_swap(trees, other.trees); } | |
600 | |
601 template <typename T2> | |
602 tree_match& | |
603 operator=(match<T2> const& other) | |
604 { | |
605 match<T>::operator=(other); | |
606 return *this; | |
607 } | |
608 | |
609 template <typename T2, typename T3, typename T4> | |
610 tree_match& | |
611 operator=(tree_match<T2, T3, T4> const& other) | |
612 { | |
613 match<T>::operator=(other); | |
614 impl::cp_swap(trees, other.trees); | |
615 return *this; | |
616 } | |
617 | |
618 tree_match(tree_match const& x) | |
619 : match<T>(x), trees() | |
620 { | |
621 // use auto_ptr like ownership for the trees data member | |
622 impl::cp_swap(trees, x.trees); | |
623 } | |
624 | |
625 tree_match& operator=(tree_match const& x) | |
626 { | |
627 tree_match tmp(x); | |
628 this->swap(tmp); | |
629 return *this; | |
630 } | |
631 | |
632 void swap(tree_match& x) | |
633 { | |
634 match<T>::swap(x); | |
635 impl::cp_swap(trees, x.trees); | |
636 } | |
637 | |
638 mutable container_t trees; | |
639 }; | |
640 | |
641 #if defined(BOOST_SPIRIT_DEBUG) && \ | |
642 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) | |
643 template <typename IteratorT, typename NodeFactoryT, typename T> | |
644 inline std::ostream& | |
645 operator<<(std::ostream& o, tree_match<IteratorT, NodeFactoryT, T> const& m) | |
646 { | |
647 typedef | |
648 typename tree_match<IteratorT, NodeFactoryT, T>::container_t::iterator | |
649 iterator; | |
650 | |
651 o << "(length = " << (int)m.length(); | |
652 int c = 0; | |
653 for (iterator i = m.trees.begin(); i != m.trees.end(); ++i) | |
654 { | |
655 o << " trees[" << c++ << "] = " << *i; | |
656 } | |
657 o << "\n)"; | |
658 return o; | |
659 } | |
660 #endif | |
661 | |
662 ////////////////////////////////// | |
663 struct tree_policy | |
664 { | |
665 template <typename FunctorT, typename MatchT> | |
666 static void apply_op_to_match(FunctorT const& /*op*/, MatchT& /*m*/) | |
667 {} | |
668 | |
669 template <typename MatchT, typename Iterator1T, typename Iterator2T> | |
670 static void group_match(MatchT& /*m*/, parser_id const& /*id*/, | |
671 Iterator1T const& /*first*/, Iterator2T const& /*last*/) | |
672 {} | |
673 | |
674 template <typename MatchT> | |
675 static void concat(MatchT& /*a*/, MatchT const& /*b*/) | |
676 {} | |
677 }; | |
678 | |
679 ////////////////////////////////// | |
680 template < | |
681 typename MatchPolicyT, | |
682 typename IteratorT, | |
683 typename NodeFactoryT, | |
684 typename TreePolicyT, | |
685 typename T | |
686 > | |
687 struct common_tree_match_policy : public match_policy | |
688 { | |
689 common_tree_match_policy() | |
690 { | |
691 } | |
692 | |
693 template <typename PolicyT> | |
694 common_tree_match_policy(PolicyT const & policies) | |
695 : match_policy((match_policy const &)policies) | |
696 { | |
697 } | |
698 | |
699 template <typename U> | |
700 struct result { typedef tree_match<IteratorT, NodeFactoryT, U> type; }; | |
701 | |
702 typedef tree_match<IteratorT, NodeFactoryT, T> match_t; | |
703 typedef IteratorT iterator_t; | |
704 typedef TreePolicyT tree_policy_t; | |
705 typedef NodeFactoryT factory_t; | |
706 | |
707 static const match_t no_match() { return match_t(); } | |
708 static const match_t empty_match() | |
709 { return match_t(0, tree_policy_t::empty_node()); } | |
710 | |
711 template <typename AttrT, typename Iterator1T, typename Iterator2T> | |
712 static tree_match<IteratorT, NodeFactoryT, AttrT> create_match( | |
713 std::size_t length, | |
714 AttrT const& val, | |
715 Iterator1T const& first, | |
716 Iterator2T const& last) | |
717 { | |
718 #if defined(BOOST_SPIRIT_DEBUG) && \ | |
719 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) | |
720 | |
721 BOOST_SPIRIT_DEBUG_OUT << "\n>>> create_node(begin) <<<\n" | |
722 "creating node text: \""; | |
723 for (Iterator1T it = first; it != last; ++it) | |
724 impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it); | |
725 BOOST_SPIRIT_DEBUG_OUT << "\"\n"; | |
726 BOOST_SPIRIT_DEBUG_OUT << ">>> create_node(end) <<<\n\n"; | |
727 #endif | |
728 return tree_match<IteratorT, NodeFactoryT, AttrT>(length, val, | |
729 tree_policy_t::create_node(length, first, last, true)); | |
730 } | |
731 | |
732 template <typename Match1T, typename Match2T> | |
733 static void concat_match(Match1T& a, Match2T const& b) | |
734 { | |
735 #if defined(BOOST_SPIRIT_DEBUG) && \ | |
736 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES) | |
737 | |
738 BOOST_SPIRIT_DEBUG_OUT << "\n>>> concat_match(begin) <<<\n"; | |
739 BOOST_SPIRIT_DEBUG_OUT << "tree a:\n" << a << "\n"; | |
740 BOOST_SPIRIT_DEBUG_OUT << "tree b:\n" << b << "\n"; | |
741 BOOST_SPIRIT_DEBUG_OUT << ">>> concat_match(end) <<<\n\n"; | |
742 #endif | |
743 BOOST_SPIRIT_ASSERT(a && b); | |
744 if (a.length() == 0) | |
745 { | |
746 a = b; | |
747 return; | |
748 } | |
749 else if (b.length() == 0 | |
750 #ifdef BOOST_SPIRIT_NO_TREE_NODE_COLLAPSING | |
751 && !b.trees.begin()->value.id().to_long() | |
752 #endif | |
753 ) | |
754 { | |
755 return; | |
756 } | |
757 a.concat(b); | |
758 tree_policy_t::concat(a, b); | |
759 } | |
760 | |
761 template <typename MatchT, typename IteratorT2> | |
762 void | |
763 group_match( | |
764 MatchT& m, | |
765 parser_id const& id, | |
766 IteratorT2 const& first, | |
767 IteratorT2 const& last) const | |
768 { | |
769 if (!m) return; | |
770 | |
771 #if defined(BOOST_SPIRIT_DEBUG) && \ | |
772 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_TREES) | |
773 | |
774 BOOST_SPIRIT_DEBUG_OUT << "\n>>> group_match(begin) <<<\n" | |
775 "new node(" << id << ") \""; | |
776 for (IteratorT2 it = first; it != last; ++it) | |
777 impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it); | |
778 BOOST_SPIRIT_DEBUG_OUT << "\"\n"; | |
779 BOOST_SPIRIT_DEBUG_OUT << "new child tree (before grouping):\n" << m << "\n"; | |
780 | |
781 tree_policy_t::group_match(m, id, first, last); | |
782 | |
783 BOOST_SPIRIT_DEBUG_OUT << "new child tree (after grouping):\n" << m << "\n"; | |
784 BOOST_SPIRIT_DEBUG_OUT << ">>> group_match(end) <<<\n\n"; | |
785 #else | |
786 tree_policy_t::group_match(m, id, first, last); | |
787 #endif | |
788 } | |
789 }; | |
790 | |
791 ////////////////////////////////// | |
792 template <typename MatchPolicyT, typename NodeFactoryT> | |
793 struct common_tree_tree_policy | |
794 { | |
795 typedef typename MatchPolicyT::iterator_t iterator_t; | |
796 typedef typename MatchPolicyT::match_t match_t; | |
797 typedef typename NodeFactoryT::template factory<iterator_t> factory_t; | |
798 typedef typename factory_t::node_t node_t; | |
799 | |
800 template <typename Iterator1T, typename Iterator2T> | |
801 static node_t | |
802 create_node(std::size_t /*length*/, Iterator1T const& first, | |
803 Iterator2T const& last, bool leaf_node) | |
804 { | |
805 return factory_t::create_node(first, last, leaf_node); | |
806 } | |
807 | |
808 static node_t | |
809 empty_node() | |
810 { | |
811 return factory_t::empty_node(); | |
812 } | |
813 | |
814 template <typename FunctorT> | |
815 static void apply_op_to_match(FunctorT const& op, match_t& m) | |
816 { | |
817 op(m); | |
818 } | |
819 }; | |
820 | |
821 ////////////////////////////////// | |
822 // directives to modify how the parse tree is generated | |
823 | |
824 struct no_tree_gen_node_parser_gen; | |
825 | |
826 template <typename T> | |
827 struct no_tree_gen_node_parser | |
828 : public unary<T, parser<no_tree_gen_node_parser<T> > > | |
829 { | |
830 typedef no_tree_gen_node_parser<T> self_t; | |
831 typedef no_tree_gen_node_parser_gen parser_generator_t; | |
832 typedef unary_parser_category parser_category_t; | |
833 | |
834 no_tree_gen_node_parser(T const& a) | |
835 : unary<T, parser<no_tree_gen_node_parser<T> > >(a) {} | |
836 | |
837 template <typename ScannerT> | |
838 typename parser_result<self_t, ScannerT>::type | |
839 parse(ScannerT const& scanner) const | |
840 { | |
841 typedef typename ScannerT::iteration_policy_t iteration_policy_t; | |
842 typedef match_policy match_policy_t; | |
843 typedef typename ScannerT::action_policy_t action_policy_t; | |
844 typedef scanner_policies< | |
845 iteration_policy_t, | |
846 match_policy_t, | |
847 action_policy_t | |
848 > policies_t; | |
849 | |
850 return this->subject().parse(scanner.change_policies(policies_t(scanner))); | |
851 } | |
852 }; | |
853 | |
854 struct no_tree_gen_node_parser_gen | |
855 { | |
856 template <typename T> | |
857 struct result { | |
858 | |
859 typedef no_tree_gen_node_parser<T> type; | |
860 }; | |
861 | |
862 template <typename T> | |
863 static no_tree_gen_node_parser<T> | |
864 generate(parser<T> const& s) | |
865 { | |
866 return no_tree_gen_node_parser<T>(s.derived()); | |
867 } | |
868 | |
869 template <typename T> | |
870 no_tree_gen_node_parser<T> | |
871 operator[](parser<T> const& s) const | |
872 { | |
873 return no_tree_gen_node_parser<T>(s.derived()); | |
874 } | |
875 }; | |
876 | |
877 const no_tree_gen_node_parser_gen no_node_d = no_tree_gen_node_parser_gen(); | |
878 | |
879 ////////////////////////////////// | |
880 | |
881 struct leaf_node_parser_gen; | |
882 | |
883 template<typename T> | |
884 struct leaf_node_parser | |
885 : public unary<T, parser<leaf_node_parser<T> > > | |
886 { | |
887 typedef leaf_node_parser<T> self_t; | |
888 typedef leaf_node_parser_gen parser_generator_t; | |
889 typedef unary_parser_category parser_category_t; | |
890 | |
891 leaf_node_parser(T const& a) | |
892 : unary<T, parser<leaf_node_parser<T> > >(a) {} | |
893 | |
894 template <typename ScannerT> | |
895 typename parser_result<self_t, ScannerT>::type | |
896 parse(ScannerT const& scanner) const | |
897 { | |
898 typedef scanner_policies< typename ScannerT::iteration_policy_t, | |
899 match_policy, typename ScannerT::action_policy_t > policies_t; | |
900 | |
901 typedef typename ScannerT::iterator_t iterator_t; | |
902 typedef typename parser_result<self_t, ScannerT>::type result_t; | |
903 typedef typename result_t::node_factory_t factory_t; | |
904 | |
905 iterator_t from = scanner.first; | |
906 result_t hit = impl::contiguous_parser_parse<result_t>(this->subject(), | |
907 scanner.change_policies(policies_t(scanner,match_policy(),scanner)), | |
908 scanner); | |
909 | |
910 if (hit) | |
911 return result_t(hit.length(), | |
912 factory_t::create_node(from, scanner.first, true)); | |
913 else | |
914 return result_t(hit.length()); | |
915 } | |
916 }; | |
917 | |
918 struct leaf_node_parser_gen | |
919 { | |
920 template <typename T> | |
921 struct result { | |
922 | |
923 typedef leaf_node_parser<T> type; | |
924 }; | |
925 | |
926 template <typename T> | |
927 static leaf_node_parser<T> | |
928 generate(parser<T> const& s) | |
929 { | |
930 return leaf_node_parser<T>(s.derived()); | |
931 } | |
932 | |
933 template <typename T> | |
934 leaf_node_parser<T> | |
935 operator[](parser<T> const& s) const | |
936 { | |
937 return leaf_node_parser<T>(s.derived()); | |
938 } | |
939 }; | |
940 | |
941 const leaf_node_parser_gen leaf_node_d = leaf_node_parser_gen(); | |
942 const leaf_node_parser_gen token_node_d = leaf_node_parser_gen(); | |
943 | |
944 ////////////////////////////////// | |
945 namespace impl { | |
946 | |
947 template <typename MatchPolicyT> | |
948 struct tree_policy_selector | |
949 { | |
950 typedef tree_policy type; | |
951 }; | |
952 | |
953 } // namespace impl | |
954 | |
955 ////////////////////////////////// | |
956 template <typename NodeParserT> | |
957 struct node_parser_gen; | |
958 | |
959 template <typename T, typename NodeParserT> | |
960 struct node_parser | |
961 : public unary<T, parser<node_parser<T, NodeParserT> > > | |
962 { | |
963 typedef node_parser<T, NodeParserT> self_t; | |
964 typedef node_parser_gen<NodeParserT> parser_generator_t; | |
965 typedef unary_parser_category parser_category_t; | |
966 | |
967 node_parser(T const& a) | |
968 : unary<T, parser<node_parser<T, NodeParserT> > >(a) {} | |
969 | |
970 template <typename ScannerT> | |
971 struct result | |
972 { | |
973 typedef typename parser_result<T, ScannerT>::type type; | |
974 }; | |
975 | |
976 template <typename ScannerT> | |
977 typename parser_result<self_t, ScannerT>::type | |
978 parse(ScannerT const& scanner) const | |
979 { | |
980 typename parser_result<self_t, ScannerT>::type hit = this->subject().parse(scanner); | |
981 if (hit) | |
982 { | |
983 impl::tree_policy_selector<typename ScannerT::match_policy_t>::type::apply_op_to_match(NodeParserT(), hit); | |
984 } | |
985 return hit; | |
986 } | |
987 }; | |
988 | |
989 template <typename NodeParserT> | |
990 struct node_parser_gen | |
991 { | |
992 template <typename T> | |
993 struct result { | |
994 | |
995 typedef node_parser<T, NodeParserT> type; | |
996 }; | |
997 | |
998 template <typename T> | |
999 static node_parser<T, NodeParserT> | |
1000 generate(parser<T> const& s) | |
1001 { | |
1002 return node_parser<T, NodeParserT>(s.derived()); | |
1003 } | |
1004 | |
1005 template <typename T> | |
1006 node_parser<T, NodeParserT> | |
1007 operator[](parser<T> const& s) const | |
1008 { | |
1009 return node_parser<T, NodeParserT>(s.derived()); | |
1010 } | |
1011 }; | |
1012 ////////////////////////////////// | |
1013 struct reduced_node_op | |
1014 { | |
1015 template <typename MatchT> | |
1016 void operator()(MatchT& m) const | |
1017 { | |
1018 if (m.trees.size() == 1) | |
1019 { | |
1020 m.trees.begin()->children.clear(); | |
1021 } | |
1022 else if (m.trees.size() > 1) | |
1023 { | |
1024 typedef typename MatchT::node_factory_t node_factory_t; | |
1025 m = MatchT(m.length(), node_factory_t::group_nodes(m.trees)); | |
1026 } | |
1027 } | |
1028 }; | |
1029 | |
1030 const node_parser_gen<reduced_node_op> reduced_node_d = | |
1031 node_parser_gen<reduced_node_op>(); | |
1032 | |
1033 | |
1034 struct discard_node_op | |
1035 { | |
1036 template <typename MatchT> | |
1037 void operator()(MatchT& m) const | |
1038 { | |
1039 m.trees.clear(); | |
1040 } | |
1041 }; | |
1042 | |
1043 const node_parser_gen<discard_node_op> discard_node_d = | |
1044 node_parser_gen<discard_node_op>(); | |
1045 | |
1046 struct infix_node_op | |
1047 { | |
1048 template <typename MatchT> | |
1049 void operator()(MatchT& m) const | |
1050 { | |
1051 typedef typename MatchT::container_t container_t; | |
1052 typedef typename MatchT::container_t::iterator iter_t; | |
1053 typedef typename MatchT::container_t::value_type value_t; | |
1054 | |
1055 using std::swap; | |
1056 using boost::swap; | |
1057 using BOOST_SPIRIT_CLASSIC_NS::swap; | |
1058 | |
1059 // copying the tree nodes is expensive, since it may copy a whole | |
1060 // tree. swapping them is cheap, so swap the nodes we want into | |
1061 // a new container of children. | |
1062 container_t new_children; | |
1063 std::size_t length = 0; | |
1064 std::size_t tree_size = m.trees.size(); | |
1065 | |
1066 // the infix_node_d[] make no sense for nodes with no subnodes | |
1067 BOOST_SPIRIT_ASSERT(tree_size >= 1); | |
1068 | |
1069 bool keep = true; | |
1070 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) | |
1071 new_children.reserve((tree_size+1)/2); | |
1072 #endif | |
1073 iter_t i_end = m.trees.end(); | |
1074 for (iter_t i = m.trees.begin(); i != i_end; ++i) | |
1075 { | |
1076 if (keep) { | |
1077 // adjust the length | |
1078 length += std::distance((*i).value.begin(), (*i).value.end()); | |
1079 | |
1080 // move the child node | |
1081 new_children.push_back(value_t()); | |
1082 swap(new_children.back(), *i); | |
1083 keep = false; | |
1084 } | |
1085 else { | |
1086 // ignore this child node | |
1087 keep = true; | |
1088 } | |
1089 } | |
1090 | |
1091 m = MatchT(length, new_children); | |
1092 } | |
1093 }; | |
1094 | |
1095 const node_parser_gen<infix_node_op> infix_node_d = | |
1096 node_parser_gen<infix_node_op>(); | |
1097 | |
1098 struct discard_first_node_op | |
1099 { | |
1100 template <typename MatchT> | |
1101 void operator()(MatchT& m) const | |
1102 { | |
1103 typedef typename MatchT::container_t container_t; | |
1104 typedef typename MatchT::container_t::iterator iter_t; | |
1105 typedef typename MatchT::container_t::value_type value_t; | |
1106 | |
1107 using std::swap; | |
1108 using boost::swap; | |
1109 using BOOST_SPIRIT_CLASSIC_NS::swap; | |
1110 | |
1111 // copying the tree nodes is expensive, since it may copy a whole | |
1112 // tree. swapping them is cheap, so swap the nodes we want into | |
1113 // a new container of children, instead of saying | |
1114 // m.trees.erase(m.trees.begin()) because, on a container_t that will | |
1115 // cause all the nodes afterwards to be copied into the previous | |
1116 // position. | |
1117 container_t new_children; | |
1118 std::size_t length = 0; | |
1119 std::size_t tree_size = m.trees.size(); | |
1120 | |
1121 // the discard_first_node_d[] make no sense for nodes with no subnodes | |
1122 BOOST_SPIRIT_ASSERT(tree_size >= 1); | |
1123 | |
1124 if (tree_size > 1) { | |
1125 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) | |
1126 new_children.reserve(tree_size - 1); | |
1127 #endif | |
1128 iter_t i = m.trees.begin(), i_end = m.trees.end(); | |
1129 for (++i; i != i_end; ++i) | |
1130 { | |
1131 // adjust the length | |
1132 length += std::distance((*i).value.begin(), (*i).value.end()); | |
1133 | |
1134 // move the child node | |
1135 new_children.push_back(value_t()); | |
1136 swap(new_children.back(), *i); | |
1137 } | |
1138 } | |
1139 else { | |
1140 // if there was a tree and now there isn't any, insert an empty node | |
1141 iter_t i = m.trees.begin(); | |
1142 | |
1143 // This isn't entirely correct, since the empty node will reference | |
1144 // the end of the discarded node, but I currently don't see any way to | |
1145 // get at the begin of the node following this subnode. | |
1146 // This should be safe anyway because the it shouldn't get dereferenced | |
1147 // under any circumstances. | |
1148 typedef typename value_t::parse_node_t::iterator_t iterator_type; | |
1149 iterator_type it = (*i).value.end(); | |
1150 | |
1151 new_children.push_back( | |
1152 value_t(typename value_t::parse_node_t(it, it))); | |
1153 } | |
1154 | |
1155 m = MatchT(length, new_children); | |
1156 } | |
1157 }; | |
1158 | |
1159 const node_parser_gen<discard_first_node_op> discard_first_node_d = | |
1160 node_parser_gen<discard_first_node_op>(); | |
1161 | |
1162 struct discard_last_node_op | |
1163 { | |
1164 template <typename MatchT> | |
1165 void operator()(MatchT& m) const | |
1166 { | |
1167 typedef typename MatchT::container_t container_t; | |
1168 typedef typename MatchT::container_t::iterator iter_t; | |
1169 typedef typename MatchT::container_t::value_type value_t; | |
1170 | |
1171 using std::swap; | |
1172 using boost::swap; | |
1173 using BOOST_SPIRIT_CLASSIC_NS::swap; | |
1174 | |
1175 // copying the tree nodes is expensive, since it may copy a whole | |
1176 // tree. swapping them is cheap, so swap the nodes we want into | |
1177 // a new container of children, instead of saying | |
1178 // m.trees.erase(m.trees.begin()) because, on a container_t that will | |
1179 // cause all the nodes afterwards to be copied into the previous | |
1180 // position. | |
1181 container_t new_children; | |
1182 std::size_t length = 0; | |
1183 std::size_t tree_size = m.trees.size(); | |
1184 | |
1185 // the discard_last_node_d[] make no sense for nodes with no subnodes | |
1186 BOOST_SPIRIT_ASSERT(tree_size >= 1); | |
1187 | |
1188 if (tree_size > 1) { | |
1189 m.trees.pop_back(); | |
1190 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) | |
1191 new_children.reserve(tree_size - 1); | |
1192 #endif | |
1193 iter_t i_end = m.trees.end(); | |
1194 for (iter_t i = m.trees.begin(); i != i_end; ++i) | |
1195 { | |
1196 // adjust the length | |
1197 length += std::distance((*i).value.begin(), (*i).value.end()); | |
1198 | |
1199 // move the child node | |
1200 new_children.push_back(value_t()); | |
1201 swap(new_children.back(), *i); | |
1202 } | |
1203 } | |
1204 else { | |
1205 // if there was a tree and now there isn't any, insert an empty node | |
1206 iter_t i = m.trees.begin(); | |
1207 | |
1208 typedef typename value_t::parse_node_t::iterator_t iterator_type; | |
1209 iterator_type it = (*i).value.begin(); | |
1210 | |
1211 new_children.push_back( | |
1212 value_t(typename value_t::parse_node_t(it, it))); | |
1213 } | |
1214 | |
1215 m = MatchT(length, new_children); | |
1216 } | |
1217 }; | |
1218 | |
1219 const node_parser_gen<discard_last_node_op> discard_last_node_d = | |
1220 node_parser_gen<discard_last_node_op>(); | |
1221 | |
1222 struct inner_node_op | |
1223 { | |
1224 template <typename MatchT> | |
1225 void operator()(MatchT& m) const | |
1226 { | |
1227 typedef typename MatchT::container_t container_t; | |
1228 typedef typename MatchT::container_t::iterator iter_t; | |
1229 typedef typename MatchT::container_t::value_type value_t; | |
1230 | |
1231 using std::swap; | |
1232 using boost::swap; | |
1233 using BOOST_SPIRIT_CLASSIC_NS::swap; | |
1234 | |
1235 // copying the tree nodes is expensive, since it may copy a whole | |
1236 // tree. swapping them is cheap, so swap the nodes we want into | |
1237 // a new container of children, instead of saying | |
1238 // m.trees.erase(m.trees.begin()) because, on a container_t that will | |
1239 // cause all the nodes afterwards to be copied into the previous | |
1240 // position. | |
1241 container_t new_children; | |
1242 std::size_t length = 0; | |
1243 std::size_t tree_size = m.trees.size(); | |
1244 | |
1245 // the inner_node_d[] make no sense for nodes with less then 2 subnodes | |
1246 BOOST_SPIRIT_ASSERT(tree_size >= 2); | |
1247 | |
1248 if (tree_size > 2) { | |
1249 m.trees.pop_back(); // erase the last element | |
1250 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES) | |
1251 new_children.reserve(tree_size - 1); | |
1252 #endif | |
1253 iter_t i = m.trees.begin(); // skip over the first element | |
1254 iter_t i_end = m.trees.end(); | |
1255 for (++i; i != i_end; ++i) | |
1256 { | |
1257 // adjust the length | |
1258 length += std::distance((*i).value.begin(), (*i).value.end()); | |
1259 | |
1260 // move the child node | |
1261 new_children.push_back(value_t()); | |
1262 swap(new_children.back(), *i); | |
1263 } | |
1264 } | |
1265 else { | |
1266 // if there was a tree and now there isn't any, insert an empty node | |
1267 iter_t i = m.trees.begin(); // skip over the first element | |
1268 | |
1269 typedef typename value_t::parse_node_t::iterator_t iterator_type; | |
1270 iterator_type it = (*++i).value.begin(); | |
1271 | |
1272 new_children.push_back( | |
1273 value_t(typename value_t::parse_node_t(it, it))); | |
1274 } | |
1275 | |
1276 m = MatchT(length, new_children); | |
1277 } | |
1278 }; | |
1279 | |
1280 const node_parser_gen<inner_node_op> inner_node_d = | |
1281 node_parser_gen<inner_node_op>(); | |
1282 | |
1283 | |
1284 ////////////////////////////////// | |
1285 // action_directive_parser and action_directive_parser_gen | |
1286 // are meant to be used as a template to create directives that | |
1287 // generate action classes. For example access_match and | |
1288 // access_node. The ActionParserT template parameter must be | |
1289 // a class that has an innter class called action that is templated | |
1290 // on the parser type and the action type. | |
1291 template <typename ActionParserT> | |
1292 struct action_directive_parser_gen; | |
1293 | |
1294 template <typename T, typename ActionParserT> | |
1295 struct action_directive_parser | |
1296 : public unary<T, parser<action_directive_parser<T, ActionParserT> > > | |
1297 { | |
1298 typedef action_directive_parser<T, ActionParserT> self_t; | |
1299 typedef action_directive_parser_gen<ActionParserT> parser_generator_t; | |
1300 typedef unary_parser_category parser_category_t; | |
1301 | |
1302 action_directive_parser(T const& a) | |
1303 : unary<T, parser<action_directive_parser<T, ActionParserT> > >(a) {} | |
1304 | |
1305 template <typename ScannerT> | |
1306 struct result | |
1307 { | |
1308 typedef typename parser_result<T, ScannerT>::type type; | |
1309 }; | |
1310 | |
1311 template <typename ScannerT> | |
1312 typename parser_result<self_t, ScannerT>::type | |
1313 parse(ScannerT const& scanner) const | |
1314 { | |
1315 return this->subject().parse(scanner); | |
1316 } | |
1317 | |
1318 template <typename ActionT> | |
1319 typename ActionParserT::template action<action_directive_parser<T, ActionParserT>, ActionT> | |
1320 operator[](ActionT const& actor) const | |
1321 { | |
1322 typedef typename | |
1323 ActionParserT::template action<action_directive_parser, ActionT> | |
1324 action_t; | |
1325 return action_t(*this, actor); | |
1326 } | |
1327 }; | |
1328 | |
1329 ////////////////////////////////// | |
1330 template <typename ActionParserT> | |
1331 struct action_directive_parser_gen | |
1332 { | |
1333 template <typename T> | |
1334 struct result { | |
1335 | |
1336 typedef action_directive_parser<T, ActionParserT> type; | |
1337 }; | |
1338 | |
1339 template <typename T> | |
1340 static action_directive_parser<T, ActionParserT> | |
1341 generate(parser<T> const& s) | |
1342 { | |
1343 return action_directive_parser<T, ActionParserT>(s.derived()); | |
1344 } | |
1345 | |
1346 template <typename T> | |
1347 action_directive_parser<T, ActionParserT> | |
1348 operator[](parser<T> const& s) const | |
1349 { | |
1350 return action_directive_parser<T, ActionParserT>(s.derived()); | |
1351 } | |
1352 }; | |
1353 | |
1354 ////////////////////////////////// | |
1355 // Calls the attached action passing it the match from the parser | |
1356 // and the first and last iterators. | |
1357 // The inner template class is used to simulate template-template parameters | |
1358 // (declared in common_fwd.hpp). | |
1359 template <typename ParserT, typename ActionT> | |
1360 struct access_match_action::action | |
1361 : public unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > > | |
1362 { | |
1363 typedef action_parser_category parser_category; | |
1364 typedef action<ParserT, ActionT> self_t; | |
1365 | |
1366 template <typename ScannerT> | |
1367 struct result | |
1368 { | |
1369 typedef typename parser_result<ParserT, ScannerT>::type type; | |
1370 }; | |
1371 | |
1372 action( ParserT const& subject, | |
1373 ActionT const& actor_); | |
1374 | |
1375 template <typename ScannerT> | |
1376 typename parser_result<self_t, ScannerT>::type | |
1377 parse(ScannerT const& scanner) const; | |
1378 | |
1379 ActionT const &predicate() const; | |
1380 | |
1381 private: | |
1382 ActionT actor; | |
1383 }; | |
1384 | |
1385 ////////////////////////////////// | |
1386 template <typename ParserT, typename ActionT> | |
1387 access_match_action::action<ParserT, ActionT>::action( | |
1388 ParserT const& subject, | |
1389 ActionT const& actor_) | |
1390 : unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > >(subject) | |
1391 , actor(actor_) | |
1392 {} | |
1393 | |
1394 ////////////////////////////////// | |
1395 template <typename ParserT, typename ActionT> | |
1396 template <typename ScannerT> | |
1397 typename parser_result<access_match_action::action<ParserT, ActionT>, ScannerT>::type | |
1398 access_match_action::action<ParserT, ActionT>:: | |
1399 parse(ScannerT const& scan) const | |
1400 { | |
1401 typedef typename ScannerT::iterator_t iterator_t; | |
1402 typedef typename parser_result<self_t, ScannerT>::type result_t; | |
1403 if (!scan.at_end()) | |
1404 { | |
1405 iterator_t save = scan.first; | |
1406 result_t hit = this->subject().parse(scan); | |
1407 actor(hit, save, scan.first); | |
1408 return hit; | |
1409 } | |
1410 return scan.no_match(); | |
1411 } | |
1412 | |
1413 ////////////////////////////////// | |
1414 template <typename ParserT, typename ActionT> | |
1415 ActionT const &access_match_action::action<ParserT, ActionT>::predicate() const | |
1416 { | |
1417 return actor; | |
1418 } | |
1419 | |
1420 ////////////////////////////////// | |
1421 const action_directive_parser_gen<access_match_action> access_match_d | |
1422 = action_directive_parser_gen<access_match_action>(); | |
1423 | |
1424 | |
1425 | |
1426 ////////////////////////////////// | |
1427 // Calls the attached action passing it the node from the parser | |
1428 // and the first and last iterators | |
1429 // The inner template class is used to simulate template-template parameters | |
1430 // (declared in common_fwd.hpp). | |
1431 template <typename ParserT, typename ActionT> | |
1432 struct access_node_action::action | |
1433 : public unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > > | |
1434 { | |
1435 typedef action_parser_category parser_category; | |
1436 typedef action<ParserT, ActionT> self_t; | |
1437 | |
1438 template <typename ScannerT> | |
1439 struct result | |
1440 { | |
1441 typedef typename parser_result<ParserT, ScannerT>::type type; | |
1442 }; | |
1443 | |
1444 action( ParserT const& subject, | |
1445 ActionT const& actor_); | |
1446 | |
1447 template <typename ScannerT> | |
1448 typename parser_result<self_t, ScannerT>::type | |
1449 parse(ScannerT const& scanner) const; | |
1450 | |
1451 ActionT const &predicate() const; | |
1452 | |
1453 private: | |
1454 ActionT actor; | |
1455 }; | |
1456 | |
1457 ////////////////////////////////// | |
1458 template <typename ParserT, typename ActionT> | |
1459 access_node_action::action<ParserT, ActionT>::action( | |
1460 ParserT const& subject, | |
1461 ActionT const& actor_) | |
1462 : unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > >(subject) | |
1463 , actor(actor_) | |
1464 {} | |
1465 | |
1466 ////////////////////////////////// | |
1467 template <typename ParserT, typename ActionT> | |
1468 template <typename ScannerT> | |
1469 typename parser_result<access_node_action::action<ParserT, ActionT>, ScannerT>::type | |
1470 access_node_action::action<ParserT, ActionT>:: | |
1471 parse(ScannerT const& scan) const | |
1472 { | |
1473 typedef typename ScannerT::iterator_t iterator_t; | |
1474 typedef typename parser_result<self_t, ScannerT>::type result_t; | |
1475 if (!scan.at_end()) | |
1476 { | |
1477 iterator_t save = scan.first; | |
1478 result_t hit = this->subject().parse(scan); | |
1479 if (hit && hit.trees.size() > 0) | |
1480 actor(*hit.trees.begin(), save, scan.first); | |
1481 return hit; | |
1482 } | |
1483 return scan.no_match(); | |
1484 } | |
1485 | |
1486 ////////////////////////////////// | |
1487 template <typename ParserT, typename ActionT> | |
1488 ActionT const &access_node_action::action<ParserT, ActionT>::predicate() const | |
1489 { | |
1490 return actor; | |
1491 } | |
1492 | |
1493 ////////////////////////////////// | |
1494 const action_directive_parser_gen<access_node_action> access_node_d | |
1495 = action_directive_parser_gen<access_node_action>(); | |
1496 | |
1497 | |
1498 | |
1499 ////////////////////////////////// | |
1500 | |
1501 /////////////////////////////////////////////////////////////////////////////// | |
1502 // | |
1503 // tree_parse_info | |
1504 // | |
1505 // Results returned by the tree parse functions: | |
1506 // | |
1507 // stop: points to the final parse position (i.e parsing | |
1508 // processed the input up to this point). | |
1509 // | |
1510 // match: true if parsing is successful. This may be full: | |
1511 // the parser consumed all the input, or partial: | |
1512 // the parser consumed only a portion of the input. | |
1513 // | |
1514 // full: true when we have a full match (i.e the parser | |
1515 // consumed all the input. | |
1516 // | |
1517 // length: The number of characters consumed by the parser. | |
1518 // This is valid only if we have a successful match | |
1519 // (either partial or full). A negative value means | |
1520 // that the match is unsucessful. | |
1521 // | |
1522 // trees: Contains the root node(s) of the tree. | |
1523 // | |
1524 /////////////////////////////////////////////////////////////////////////////// | |
1525 template < | |
1526 typename IteratorT, | |
1527 typename NodeFactoryT, | |
1528 typename T | |
1529 > | |
1530 struct tree_parse_info | |
1531 { | |
1532 IteratorT stop; | |
1533 bool match; | |
1534 bool full; | |
1535 std::size_t length; | |
1536 typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees; | |
1537 | |
1538 tree_parse_info() | |
1539 : stop() | |
1540 , match(false) | |
1541 , full(false) | |
1542 , length(0) | |
1543 , trees() | |
1544 {} | |
1545 | |
1546 template <typename IteratorT2> | |
1547 tree_parse_info(tree_parse_info<IteratorT2> const& pi) | |
1548 : stop(pi.stop) | |
1549 , match(pi.match) | |
1550 , full(pi.full) | |
1551 , length(pi.length) | |
1552 , trees() | |
1553 { | |
1554 using std::swap; | |
1555 using boost::swap; | |
1556 using BOOST_SPIRIT_CLASSIC_NS::swap; | |
1557 | |
1558 // use auto_ptr like ownership for the trees data member | |
1559 swap(trees, pi.trees); | |
1560 } | |
1561 | |
1562 tree_parse_info( | |
1563 IteratorT stop_, | |
1564 bool match_, | |
1565 bool full_, | |
1566 std::size_t length_, | |
1567 typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees_) | |
1568 : stop(stop_) | |
1569 , match(match_) | |
1570 , full(full_) | |
1571 , length(length_) | |
1572 , trees() | |
1573 { | |
1574 using std::swap; | |
1575 using boost::swap; | |
1576 using BOOST_SPIRIT_CLASSIC_NS::swap; | |
1577 | |
1578 // use auto_ptr like ownership for the trees data member | |
1579 swap(trees, trees_); | |
1580 } | |
1581 }; | |
1582 | |
1583 BOOST_SPIRIT_CLASSIC_NAMESPACE_END | |
1584 | |
1585 }} // namespace BOOST_SPIRIT_CLASSIC_NS | |
1586 | |
1587 #endif | |
1588 |