File indexing completed on 2025-01-31 10:02:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_SPIRIT_TREE_COMMON_HPP
0011 #define BOOST_SPIRIT_TREE_COMMON_HPP
0012
0013 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
0014 #include <vector>
0015 #else
0016 #include <list>
0017 #endif
0018
0019 #if defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)
0020 #include <boost/pool/pool_alloc.hpp>
0021 #endif
0022
0023 #include <algorithm>
0024
0025 #include <boost/ref.hpp>
0026 #include <boost/call_traits.hpp>
0027 #include <boost/spirit/home/classic/namespace.hpp>
0028 #include <boost/spirit/home/classic/core.hpp>
0029 #include <boost/assert.hpp>
0030
0031 #if defined(BOOST_SPIRIT_DEBUG) && \
0032 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
0033 #include <iostream>
0034 #include <boost/spirit/home/classic/debug/debug_node.hpp>
0035 #endif
0036
0037 #include <boost/spirit/home/classic/tree/common_fwd.hpp>
0038
0039 #include <iterator> // for std::iterator_traits, std::distance
0040
0041 namespace boost { namespace spirit {
0042
0043 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0044
0045 template <typename T>
0046 void swap(tree_node<T>& a, tree_node<T>& b);
0047
0048 template <typename T, typename V>
0049 void swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b);
0050
0051 namespace impl {
0052 template <typename T>
0053 inline void cp_swap(T& t1, T& t2);
0054 }
0055
0056 template <typename T>
0057 struct tree_node
0058 {
0059 typedef T parse_node_t;
0060
0061 #if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)
0062 typedef std::allocator<tree_node<T> > allocator_type;
0063 #elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
0064 typedef boost::pool_allocator<tree_node<T> > allocator_type;
0065 #else
0066 typedef boost::fast_pool_allocator<tree_node<T> > allocator_type;
0067 #endif
0068
0069 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
0070 typedef std::vector<tree_node<T>, allocator_type> children_t;
0071 #else
0072 typedef std::list<tree_node<T>, allocator_type> children_t;
0073 #endif
0074
0075 typedef typename children_t::iterator tree_iterator;
0076 typedef typename children_t::const_iterator const_tree_iterator;
0077
0078 T value;
0079 children_t children;
0080
0081 tree_node()
0082 : value()
0083 , children()
0084 {}
0085
0086 explicit tree_node(T const& v)
0087 : value(v)
0088 , children()
0089 {}
0090
0091 tree_node(T const& v, children_t const& c)
0092 : value(v)
0093 , children(c)
0094 {}
0095
0096 void swap(tree_node<T>& x)
0097 {
0098 impl::cp_swap(value, x.value);
0099 impl::cp_swap(children, x.children);
0100 }
0101 };
0102
0103 #if defined(BOOST_SPIRIT_DEBUG) && \
0104 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
0105 template <typename T>
0106 inline std::ostream&
0107 operator<<(std::ostream& o, tree_node<T> const& n)
0108 {
0109 static int depth = 0;
0110 o << "\n";
0111 for (int i = 0; i <= depth; ++i)
0112 {
0113 o << "\t";
0114 }
0115 o << "(depth = " << depth++ << " value = " << n.value;
0116 int c = 0;
0117 for (typename tree_node<T>::children_t::const_iterator it = n.children.begin();
0118 it != n.children.end(); ++it)
0119 {
0120 o << " children[" << c++ << "] = " << *it;
0121 }
0122 o << ")";
0123 --depth;
0124 return o;
0125 }
0126 #endif
0127
0128
0129 template <typename IteratorT, typename ValueT>
0130 struct node_iter_data
0131 {
0132 typedef IteratorT iterator_t;
0133 typedef IteratorT const_iterator_t;
0134
0135 node_iter_data()
0136 : first(), last(), is_root_(false), parser_id_(), value_()
0137 {}
0138
0139 node_iter_data(IteratorT const& _first, IteratorT const& _last)
0140 : first(_first), last(_last), is_root_(false), parser_id_(), value_()
0141 {}
0142
0143 void swap(node_iter_data& x)
0144 {
0145 impl::cp_swap(first, x.first);
0146 impl::cp_swap(last, x.last);
0147 impl::cp_swap(parser_id_, x.parser_id_);
0148 impl::cp_swap(is_root_, x.is_root_);
0149 impl::cp_swap(value_, x.value_);
0150 }
0151
0152 IteratorT begin()
0153 {
0154 return first;
0155 }
0156
0157 IteratorT const& begin() const
0158 {
0159 return first;
0160 }
0161
0162 IteratorT end()
0163 {
0164 return last;
0165 }
0166
0167 IteratorT const& end() const
0168 {
0169 return last;
0170 }
0171
0172 bool is_root() const
0173 {
0174 return is_root_;
0175 }
0176
0177 void is_root(bool b)
0178 {
0179 is_root_ = b;
0180 }
0181
0182 parser_id id() const
0183 {
0184 return parser_id_;
0185 }
0186
0187 void id(parser_id r)
0188 {
0189 parser_id_ = r;
0190 }
0191
0192 ValueT const& value() const
0193 {
0194 return value_;
0195 }
0196
0197 void value(ValueT const& v)
0198 {
0199 value_ = v;
0200 }
0201 private:
0202 IteratorT first, last;
0203 bool is_root_;
0204 parser_id parser_id_;
0205 ValueT value_;
0206
0207 public:
0208 };
0209
0210 #if defined(BOOST_SPIRIT_DEBUG) && \
0211 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
0212
0213 inline std::ostream&
0214 operator<<(std::ostream& o, nil_t const&)
0215 {
0216 return o;
0217 }
0218
0219 template <typename IteratorT, typename ValueT>
0220 inline std::ostream&
0221 operator<<(std::ostream& o, node_iter_data<IteratorT, ValueT> const& n)
0222 {
0223 o << "(id = " << n.id() << " text = \"";
0224 typedef typename node_iter_data<IteratorT, ValueT>::const_iterator_t
0225 iterator_t;
0226 for (iterator_t it = n.begin(); it != n.end(); ++it)
0227 impl::token_printer(o, *it);
0228 o << "\" is_root = " << n.is_root()
0229 << ")";
0230 return o;
0231 }
0232 #endif
0233
0234
0235 template <typename IteratorT = char const*, typename ValueT = nil_t>
0236 struct node_val_data
0237 {
0238 typedef
0239 typename std::iterator_traits<IteratorT>::value_type
0240 value_type;
0241
0242 #if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)
0243 typedef std::allocator<value_type> allocator_type;
0244 #elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
0245 typedef boost::pool_allocator<value_type> allocator_type;
0246 #else
0247 typedef boost::fast_pool_allocator<value_type> allocator_type;
0248 #endif
0249
0250 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
0251 typedef std::vector<value_type, allocator_type> container_t;
0252 #else
0253 typedef std::list<value_type, allocator_type> container_t;
0254 #endif
0255
0256 typedef typename container_t::iterator iterator_t;
0257 typedef typename container_t::const_iterator const_iterator_t;
0258
0259 node_val_data()
0260 : text(), is_root_(false), parser_id_(), value_()
0261 {}
0262
0263 #if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
0264 node_val_data(IteratorT const& _first, IteratorT const& _last)
0265 : text(), is_root_(false), parser_id_(), value_()
0266 {
0267 std::copy(_first, _last, std::inserter(text, text.end()));
0268 }
0269
0270
0271 template <typename IteratorT2>
0272 node_val_data(IteratorT2 const& _first, IteratorT2 const& _last)
0273 : text(), is_root_(false), parser_id_(), value_()
0274 {
0275 std::copy(_first, _last, std::inserter(text, text.end()));
0276 }
0277 #else
0278 node_val_data(IteratorT const& _first, IteratorT const& _last)
0279 : text(_first, _last), is_root_(false), parser_id_(), value_()
0280 {}
0281
0282
0283 template <typename IteratorT2>
0284 node_val_data(IteratorT2 const& _first, IteratorT2 const& _last)
0285 : text(_first, _last), is_root_(false), parser_id_(), value_()
0286 {}
0287 #endif
0288
0289 void swap(node_val_data& x)
0290 {
0291 impl::cp_swap(text, x.text);
0292 impl::cp_swap(is_root_, x.is_root_);
0293 impl::cp_swap(parser_id_, x.parser_id_);
0294 impl::cp_swap(value_, x.value_);
0295 }
0296
0297 typename container_t::iterator begin()
0298 {
0299 return text.begin();
0300 }
0301
0302 typename container_t::const_iterator begin() const
0303 {
0304 return text.begin();
0305 }
0306
0307 typename container_t::iterator end()
0308 {
0309 return text.end();
0310 }
0311
0312 typename container_t::const_iterator end() const
0313 {
0314 return text.end();
0315 }
0316
0317 bool is_root() const
0318 {
0319 return is_root_;
0320 }
0321
0322 void is_root(bool b)
0323 {
0324 is_root_ = b;
0325 }
0326
0327 parser_id id() const
0328 {
0329 return parser_id_;
0330 }
0331
0332 void id(parser_id r)
0333 {
0334 parser_id_ = r;
0335 }
0336
0337 ValueT const& value() const
0338 {
0339 return value_;
0340 }
0341
0342 void value(ValueT const& v)
0343 {
0344 value_ = v;
0345 }
0346
0347 private:
0348 container_t text;
0349 bool is_root_;
0350 parser_id parser_id_;
0351 ValueT value_;
0352 };
0353
0354 #if defined(BOOST_SPIRIT_DEBUG) && \
0355 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
0356 template <typename IteratorT, typename ValueT>
0357 inline std::ostream&
0358 operator<<(std::ostream& o, node_val_data<IteratorT, ValueT> const& n)
0359 {
0360 o << "(id = " << n.id() << " text = \"";
0361 typedef typename node_val_data<IteratorT, ValueT>::const_iterator_t
0362 iterator_t;
0363 for (iterator_t it = n.begin(); it != n.end(); ++it)
0364 impl::token_printer(o, *it);
0365 o << "\" is_root = " << n.is_root()
0366 << " value = " << n.value() << ")";
0367 return o;
0368 }
0369 #endif
0370
0371 template <typename T>
0372 inline void
0373 swap(tree_node<T>& a, tree_node<T>& b)
0374 {
0375 a.swap(b);
0376 }
0377
0378 template <typename T, typename V>
0379 inline void
0380 swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b)
0381 {
0382 a.swap(b);
0383 }
0384
0385
0386 template <typename ValueT>
0387 class node_iter_data_factory
0388 {
0389 public:
0390
0391
0392 template <typename IteratorT>
0393 class factory
0394 {
0395 public:
0396 typedef IteratorT iterator_t;
0397 typedef node_iter_data<iterator_t, ValueT> node_t;
0398
0399 static node_t create_node(iterator_t const& first, iterator_t const& last,
0400 bool )
0401 {
0402 return node_t(first, last);
0403 }
0404
0405 static node_t empty_node()
0406 {
0407 return node_t();
0408 }
0409
0410
0411
0412 template <typename ContainerT>
0413 static node_t group_nodes(ContainerT const& nodes)
0414 {
0415 return node_t(nodes.begin()->value.begin(),
0416 nodes.back().value.end());
0417 }
0418 };
0419 };
0420
0421
0422 template <typename ValueT>
0423 class node_val_data_factory
0424 {
0425 public:
0426
0427
0428 template <typename IteratorT>
0429 class factory
0430 {
0431 public:
0432 typedef IteratorT iterator_t;
0433 typedef node_val_data<iterator_t, ValueT> node_t;
0434
0435 static node_t create_node(iterator_t const& first, iterator_t const& last,
0436 bool is_leaf_node)
0437 {
0438 if (is_leaf_node)
0439 return node_t(first, last);
0440 else
0441 return node_t();
0442 }
0443
0444 static node_t empty_node()
0445 {
0446 return node_t();
0447 }
0448
0449 template <typename ContainerT>
0450 static node_t group_nodes(ContainerT const& nodes)
0451 {
0452 typename node_t::container_t c;
0453 typename ContainerT::const_iterator i_end = nodes.end();
0454
0455 for (typename ContainerT::const_iterator i = nodes.begin();
0456 i != i_end; ++i)
0457 {
0458
0459
0460 BOOST_ASSERT(i->children.size() == 0);
0461 c.insert(c.end(), i->value.begin(), i->value.end());
0462 }
0463 return node_t(c.begin(), c.end());
0464 }
0465 };
0466 };
0467
0468
0469 template <typename ValueT>
0470 class node_all_val_data_factory
0471 {
0472 public:
0473
0474
0475 template <typename IteratorT>
0476 class factory
0477 {
0478 public:
0479 typedef IteratorT iterator_t;
0480 typedef node_val_data<iterator_t, ValueT> node_t;
0481
0482 static node_t create_node(iterator_t const& first, iterator_t const& last,
0483 bool )
0484 {
0485 return node_t(first, last);
0486 }
0487
0488 static node_t empty_node()
0489 {
0490 return node_t();
0491 }
0492
0493 template <typename ContainerT>
0494 static node_t group_nodes(ContainerT const& nodes)
0495 {
0496 typename node_t::container_t c;
0497 typename ContainerT::const_iterator i_end = nodes.end();
0498
0499 for (typename ContainerT::const_iterator i = nodes.begin();
0500 i != i_end; ++i)
0501 {
0502 BOOST_ASSERT(i->children.size() == 0);
0503 c.insert(c.end(), i->value.begin(), i->value.end());
0504 }
0505 return node_t(c.begin(), c.end());
0506 }
0507 };
0508 };
0509
0510 namespace impl {
0511
0512
0513
0514
0515
0516
0517 template <typename T>
0518 inline void cp_swap(T& t1, T& t2)
0519 {
0520 using std::swap;
0521 using BOOST_SPIRIT_CLASSIC_NS::swap;
0522 swap(t1, t2);
0523 }
0524 }
0525
0526
0527 template <typename IteratorT, typename NodeFactoryT, typename T>
0528 class tree_match : public match<T>
0529 {
0530 public:
0531
0532 typedef typename NodeFactoryT::template factory<IteratorT> node_factory_t;
0533 typedef typename node_factory_t::node_t parse_node_t;
0534 typedef tree_node<parse_node_t> node_t;
0535 typedef typename node_t::children_t container_t;
0536 typedef typename container_t::iterator tree_iterator;
0537 typedef typename container_t::const_iterator const_tree_iterator;
0538
0539 typedef T attr_t;
0540 typedef typename boost::call_traits<T>::param_type param_type;
0541 typedef typename boost::call_traits<T>::reference reference;
0542 typedef typename boost::call_traits<T>::const_reference const_reference;
0543
0544 tree_match()
0545 : match<T>(), trees()
0546 {}
0547
0548 explicit
0549 tree_match(std::size_t length_)
0550 : match<T>(length_), trees()
0551 {}
0552
0553 tree_match(std::size_t length_, parse_node_t const& n)
0554 : match<T>(length_), trees()
0555 {
0556 trees.push_back(node_t(n));
0557 }
0558
0559 tree_match(std::size_t length_, param_type val, parse_node_t const& n)
0560 : match<T>(length_, val), trees()
0561 {
0562 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
0563 trees.reserve(10);
0564 #endif
0565 trees.push_back(node_t(n));
0566 }
0567
0568
0569 tree_match(std::size_t length_, container_t& c)
0570 : match<T>(length_), trees()
0571 {
0572 impl::cp_swap(trees, c);
0573 }
0574
0575 tree_match(std::size_t length_, param_type val, container_t& c)
0576 : match<T>(length_, val), trees()
0577 {
0578 impl::cp_swap(trees, c);
0579 }
0580
0581 template <typename T2>
0582 tree_match(match<T2> const& other)
0583 : match<T>(other), trees()
0584 {}
0585
0586 template <typename T2, typename T3, typename T4>
0587 tree_match(tree_match<T2, T3, T4> const& other)
0588 : match<T>(other), trees()
0589 { impl::cp_swap(trees, other.trees); }
0590
0591 template <typename T2>
0592 tree_match&
0593 operator=(match<T2> const& other)
0594 {
0595 match<T>::operator=(other);
0596 return *this;
0597 }
0598
0599 template <typename T2, typename T3, typename T4>
0600 tree_match&
0601 operator=(tree_match<T2, T3, T4> const& other)
0602 {
0603 match<T>::operator=(other);
0604 impl::cp_swap(trees, other.trees);
0605 return *this;
0606 }
0607
0608 tree_match(tree_match const& x)
0609 : match<T>(x), trees()
0610 {
0611
0612 impl::cp_swap(trees, x.trees);
0613 }
0614
0615 tree_match& operator=(tree_match const& x)
0616 {
0617 tree_match tmp(x);
0618 this->swap(tmp);
0619 return *this;
0620 }
0621
0622 void swap(tree_match& x)
0623 {
0624 match<T>::swap(x);
0625 impl::cp_swap(trees, x.trees);
0626 }
0627
0628 mutable container_t trees;
0629 };
0630
0631 #if defined(BOOST_SPIRIT_DEBUG) && \
0632 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
0633 template <typename IteratorT, typename NodeFactoryT, typename T>
0634 inline std::ostream&
0635 operator<<(std::ostream& o, tree_match<IteratorT, NodeFactoryT, T> const& m)
0636 {
0637 typedef
0638 typename tree_match<IteratorT, NodeFactoryT, T>::container_t::iterator
0639 iterator;
0640
0641 o << "(length = " << (int)m.length();
0642 int c = 0;
0643 for (iterator i = m.trees.begin(); i != m.trees.end(); ++i)
0644 {
0645 o << " trees[" << c++ << "] = " << *i;
0646 }
0647 o << "\n)";
0648 return o;
0649 }
0650 #endif
0651
0652
0653 struct tree_policy
0654 {
0655 template <typename FunctorT, typename MatchT>
0656 static void apply_op_to_match(FunctorT const& , MatchT& )
0657 {}
0658
0659 template <typename MatchT, typename Iterator1T, typename Iterator2T>
0660 static void group_match(MatchT& , parser_id const& ,
0661 Iterator1T const& , Iterator2T const& )
0662 {}
0663
0664 template <typename MatchT>
0665 static void concat(MatchT& , MatchT const& )
0666 {}
0667 };
0668
0669
0670 template <
0671 typename MatchPolicyT,
0672 typename IteratorT,
0673 typename NodeFactoryT,
0674 typename TreePolicyT,
0675 typename T
0676 >
0677 struct common_tree_match_policy : public match_policy
0678 {
0679 common_tree_match_policy()
0680 {
0681 }
0682
0683 template <typename PolicyT>
0684 common_tree_match_policy(PolicyT const & policies)
0685 : match_policy((match_policy const &)policies)
0686 {
0687 }
0688
0689 template <typename U>
0690 struct result { typedef tree_match<IteratorT, NodeFactoryT, U> type; };
0691
0692 typedef tree_match<IteratorT, NodeFactoryT, T> match_t;
0693 typedef IteratorT iterator_t;
0694 typedef TreePolicyT tree_policy_t;
0695 typedef NodeFactoryT factory_t;
0696
0697 static const match_t no_match() { return match_t(); }
0698 static const match_t empty_match()
0699 { return match_t(0, tree_policy_t::empty_node()); }
0700
0701 template <typename AttrT, typename Iterator1T, typename Iterator2T>
0702 static tree_match<IteratorT, NodeFactoryT, AttrT> create_match(
0703 std::size_t length,
0704 AttrT const& val,
0705 Iterator1T const& first,
0706 Iterator2T const& last)
0707 {
0708 #if defined(BOOST_SPIRIT_DEBUG) && \
0709 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
0710
0711 BOOST_SPIRIT_DEBUG_OUT << "\n>>> create_node(begin) <<<\n"
0712 "creating node text: \"";
0713 for (Iterator1T it = first; it != last; ++it)
0714 impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it);
0715 BOOST_SPIRIT_DEBUG_OUT << "\"\n";
0716 BOOST_SPIRIT_DEBUG_OUT << ">>> create_node(end) <<<\n\n";
0717 #endif
0718 return tree_match<IteratorT, NodeFactoryT, AttrT>(length, val,
0719 tree_policy_t::create_node(length, first, last, true));
0720 }
0721
0722 template <typename Match1T, typename Match2T>
0723 static void concat_match(Match1T& a, Match2T const& b)
0724 {
0725 #if defined(BOOST_SPIRIT_DEBUG) && \
0726 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
0727
0728 BOOST_SPIRIT_DEBUG_OUT << "\n>>> concat_match(begin) <<<\n";
0729 BOOST_SPIRIT_DEBUG_OUT << "tree a:\n" << a << "\n";
0730 BOOST_SPIRIT_DEBUG_OUT << "tree b:\n" << b << "\n";
0731 BOOST_SPIRIT_DEBUG_OUT << ">>> concat_match(end) <<<\n\n";
0732 #endif
0733 BOOST_SPIRIT_ASSERT(a && b);
0734 if (a.length() == 0)
0735 {
0736 a = b;
0737 return;
0738 }
0739 else if (b.length() == 0
0740 #ifdef BOOST_SPIRIT_NO_TREE_NODE_COLLAPSING
0741 && !b.trees.begin()->value.id().to_long()
0742 #endif
0743 )
0744 {
0745 return;
0746 }
0747 a.concat(b);
0748 tree_policy_t::concat(a, b);
0749 }
0750
0751 template <typename MatchT, typename IteratorT2>
0752 void
0753 group_match(
0754 MatchT& m,
0755 parser_id const& id,
0756 IteratorT2 const& first,
0757 IteratorT2 const& last) const
0758 {
0759 if (!m) return;
0760
0761 #if defined(BOOST_SPIRIT_DEBUG) && \
0762 (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_TREES)
0763
0764 BOOST_SPIRIT_DEBUG_OUT << "\n>>> group_match(begin) <<<\n"
0765 "new node(" << id << ") \"";
0766 for (IteratorT2 it = first; it != last; ++it)
0767 impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it);
0768 BOOST_SPIRIT_DEBUG_OUT << "\"\n";
0769 BOOST_SPIRIT_DEBUG_OUT << "new child tree (before grouping):\n" << m << "\n";
0770
0771 tree_policy_t::group_match(m, id, first, last);
0772
0773 BOOST_SPIRIT_DEBUG_OUT << "new child tree (after grouping):\n" << m << "\n";
0774 BOOST_SPIRIT_DEBUG_OUT << ">>> group_match(end) <<<\n\n";
0775 #else
0776 tree_policy_t::group_match(m, id, first, last);
0777 #endif
0778 }
0779 };
0780
0781
0782 template <typename MatchPolicyT, typename NodeFactoryT>
0783 struct common_tree_tree_policy
0784 {
0785 typedef typename MatchPolicyT::iterator_t iterator_t;
0786 typedef typename MatchPolicyT::match_t match_t;
0787 typedef typename NodeFactoryT::template factory<iterator_t> factory_t;
0788 typedef typename factory_t::node_t node_t;
0789
0790 template <typename Iterator1T, typename Iterator2T>
0791 static node_t
0792 create_node(std::size_t , Iterator1T const& first,
0793 Iterator2T const& last, bool leaf_node)
0794 {
0795 return factory_t::create_node(first, last, leaf_node);
0796 }
0797
0798 static node_t
0799 empty_node()
0800 {
0801 return factory_t::empty_node();
0802 }
0803
0804 template <typename FunctorT>
0805 static void apply_op_to_match(FunctorT const& op, match_t& m)
0806 {
0807 op(m);
0808 }
0809 };
0810
0811
0812
0813
0814 struct no_tree_gen_node_parser_gen;
0815
0816 template <typename T>
0817 struct no_tree_gen_node_parser
0818 : public unary<T, parser<no_tree_gen_node_parser<T> > >
0819 {
0820 typedef no_tree_gen_node_parser<T> self_t;
0821 typedef no_tree_gen_node_parser_gen parser_generator_t;
0822 typedef unary_parser_category parser_category_t;
0823
0824 no_tree_gen_node_parser(T const& a)
0825 : unary<T, parser<no_tree_gen_node_parser<T> > >(a) {}
0826
0827 template <typename ScannerT>
0828 typename parser_result<self_t, ScannerT>::type
0829 parse(ScannerT const& scanner) const
0830 {
0831 typedef typename ScannerT::iteration_policy_t iteration_policy_t;
0832 typedef match_policy match_policy_t;
0833 typedef typename ScannerT::action_policy_t action_policy_t;
0834 typedef scanner_policies<
0835 iteration_policy_t,
0836 match_policy_t,
0837 action_policy_t
0838 > policies_t;
0839
0840 return this->subject().parse(scanner.change_policies(policies_t(scanner)));
0841 }
0842 };
0843
0844 struct no_tree_gen_node_parser_gen
0845 {
0846 template <typename T>
0847 struct result {
0848
0849 typedef no_tree_gen_node_parser<T> type;
0850 };
0851
0852 template <typename T>
0853 static no_tree_gen_node_parser<T>
0854 generate(parser<T> const& s)
0855 {
0856 return no_tree_gen_node_parser<T>(s.derived());
0857 }
0858
0859 template <typename T>
0860 no_tree_gen_node_parser<T>
0861 operator[](parser<T> const& s) const
0862 {
0863 return no_tree_gen_node_parser<T>(s.derived());
0864 }
0865 };
0866
0867 const no_tree_gen_node_parser_gen no_node_d = no_tree_gen_node_parser_gen();
0868
0869
0870
0871 struct leaf_node_parser_gen;
0872
0873 template<typename T>
0874 struct leaf_node_parser
0875 : public unary<T, parser<leaf_node_parser<T> > >
0876 {
0877 typedef leaf_node_parser<T> self_t;
0878 typedef leaf_node_parser_gen parser_generator_t;
0879 typedef unary_parser_category parser_category_t;
0880
0881 leaf_node_parser(T const& a)
0882 : unary<T, parser<leaf_node_parser<T> > >(a) {}
0883
0884 template <typename ScannerT>
0885 typename parser_result<self_t, ScannerT>::type
0886 parse(ScannerT const& scanner) const
0887 {
0888 typedef scanner_policies< typename ScannerT::iteration_policy_t,
0889 match_policy, typename ScannerT::action_policy_t > policies_t;
0890
0891 typedef typename ScannerT::iterator_t iterator_t;
0892 typedef typename parser_result<self_t, ScannerT>::type result_t;
0893 typedef typename result_t::node_factory_t factory_t;
0894
0895 iterator_t from = scanner.first;
0896 result_t hit = impl::contiguous_parser_parse<result_t>(this->subject(),
0897 scanner.change_policies(policies_t(scanner,match_policy(),scanner)),
0898 scanner);
0899
0900 if (hit)
0901 return result_t(hit.length(),
0902 factory_t::create_node(from, scanner.first, true));
0903 else
0904 return result_t(hit.length());
0905 }
0906 };
0907
0908 struct leaf_node_parser_gen
0909 {
0910 template <typename T>
0911 struct result {
0912
0913 typedef leaf_node_parser<T> type;
0914 };
0915
0916 template <typename T>
0917 static leaf_node_parser<T>
0918 generate(parser<T> const& s)
0919 {
0920 return leaf_node_parser<T>(s.derived());
0921 }
0922
0923 template <typename T>
0924 leaf_node_parser<T>
0925 operator[](parser<T> const& s) const
0926 {
0927 return leaf_node_parser<T>(s.derived());
0928 }
0929 };
0930
0931 const leaf_node_parser_gen leaf_node_d = leaf_node_parser_gen();
0932 const leaf_node_parser_gen token_node_d = leaf_node_parser_gen();
0933
0934
0935 namespace impl {
0936
0937 template <typename MatchPolicyT>
0938 struct tree_policy_selector
0939 {
0940 typedef tree_policy type;
0941 };
0942
0943 }
0944
0945
0946 template <typename NodeParserT>
0947 struct node_parser_gen;
0948
0949 template <typename T, typename NodeParserT>
0950 struct node_parser
0951 : public unary<T, parser<node_parser<T, NodeParserT> > >
0952 {
0953 typedef node_parser<T, NodeParserT> self_t;
0954 typedef node_parser_gen<NodeParserT> parser_generator_t;
0955 typedef unary_parser_category parser_category_t;
0956
0957 node_parser(T const& a)
0958 : unary<T, parser<node_parser<T, NodeParserT> > >(a) {}
0959
0960 template <typename ScannerT>
0961 struct result
0962 {
0963 typedef typename parser_result<T, ScannerT>::type type;
0964 };
0965
0966 template <typename ScannerT>
0967 typename parser_result<self_t, ScannerT>::type
0968 parse(ScannerT const& scanner) const
0969 {
0970 typename parser_result<self_t, ScannerT>::type hit = this->subject().parse(scanner);
0971 if (hit)
0972 {
0973 impl::tree_policy_selector<typename ScannerT::match_policy_t>::type::apply_op_to_match(NodeParserT(), hit);
0974 }
0975 return hit;
0976 }
0977 };
0978
0979 template <typename NodeParserT>
0980 struct node_parser_gen
0981 {
0982 template <typename T>
0983 struct result {
0984
0985 typedef node_parser<T, NodeParserT> type;
0986 };
0987
0988 template <typename T>
0989 static node_parser<T, NodeParserT>
0990 generate(parser<T> const& s)
0991 {
0992 return node_parser<T, NodeParserT>(s.derived());
0993 }
0994
0995 template <typename T>
0996 node_parser<T, NodeParserT>
0997 operator[](parser<T> const& s) const
0998 {
0999 return node_parser<T, NodeParserT>(s.derived());
1000 }
1001 };
1002
1003 struct reduced_node_op
1004 {
1005 template <typename MatchT>
1006 void operator()(MatchT& m) const
1007 {
1008 if (m.trees.size() == 1)
1009 {
1010 m.trees.begin()->children.clear();
1011 }
1012 else if (m.trees.size() > 1)
1013 {
1014 typedef typename MatchT::node_factory_t node_factory_t;
1015 m = MatchT(m.length(), node_factory_t::group_nodes(m.trees));
1016 }
1017 }
1018 };
1019
1020 const node_parser_gen<reduced_node_op> reduced_node_d =
1021 node_parser_gen<reduced_node_op>();
1022
1023
1024 struct discard_node_op
1025 {
1026 template <typename MatchT>
1027 void operator()(MatchT& m) const
1028 {
1029 m.trees.clear();
1030 }
1031 };
1032
1033 const node_parser_gen<discard_node_op> discard_node_d =
1034 node_parser_gen<discard_node_op>();
1035
1036 struct infix_node_op
1037 {
1038 template <typename MatchT>
1039 void operator()(MatchT& m) const
1040 {
1041 typedef typename MatchT::container_t container_t;
1042 typedef typename MatchT::container_t::iterator iter_t;
1043 typedef typename MatchT::container_t::value_type value_t;
1044
1045 using std::swap;
1046 using BOOST_SPIRIT_CLASSIC_NS::swap;
1047
1048
1049
1050
1051 container_t new_children;
1052 std::size_t length = 0;
1053 std::size_t tree_size = m.trees.size();
1054
1055
1056 BOOST_SPIRIT_ASSERT(tree_size >= 1);
1057
1058 bool keep = true;
1059 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
1060 new_children.reserve((tree_size+1)/2);
1061 #endif
1062 iter_t i_end = m.trees.end();
1063 for (iter_t i = m.trees.begin(); i != i_end; ++i)
1064 {
1065 if (keep) {
1066
1067 length += std::distance((*i).value.begin(), (*i).value.end());
1068
1069
1070 new_children.push_back(value_t());
1071 swap(new_children.back(), *i);
1072 keep = false;
1073 }
1074 else {
1075
1076 keep = true;
1077 }
1078 }
1079
1080 m = MatchT(length, new_children);
1081 }
1082 };
1083
1084 const node_parser_gen<infix_node_op> infix_node_d =
1085 node_parser_gen<infix_node_op>();
1086
1087 struct discard_first_node_op
1088 {
1089 template <typename MatchT>
1090 void operator()(MatchT& m) const
1091 {
1092 typedef typename MatchT::container_t container_t;
1093 typedef typename MatchT::container_t::iterator iter_t;
1094 typedef typename MatchT::container_t::value_type value_t;
1095
1096 using std::swap;
1097 using BOOST_SPIRIT_CLASSIC_NS::swap;
1098
1099
1100
1101
1102
1103
1104
1105 container_t new_children;
1106 std::size_t length = 0;
1107 std::size_t tree_size = m.trees.size();
1108
1109
1110 BOOST_SPIRIT_ASSERT(tree_size >= 1);
1111
1112 if (tree_size > 1) {
1113 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
1114 new_children.reserve(tree_size - 1);
1115 #endif
1116 iter_t i = m.trees.begin(), i_end = m.trees.end();
1117 for (++i; i != i_end; ++i)
1118 {
1119
1120 length += std::distance((*i).value.begin(), (*i).value.end());
1121
1122
1123 new_children.push_back(value_t());
1124 swap(new_children.back(), *i);
1125 }
1126 }
1127 else {
1128
1129 iter_t i = m.trees.begin();
1130
1131
1132
1133
1134
1135
1136 typedef typename value_t::parse_node_t::iterator_t iterator_type;
1137 iterator_type it = (*i).value.end();
1138
1139 new_children.push_back(
1140 value_t(typename value_t::parse_node_t(it, it)));
1141 }
1142
1143 m = MatchT(length, new_children);
1144 }
1145 };
1146
1147 const node_parser_gen<discard_first_node_op> discard_first_node_d =
1148 node_parser_gen<discard_first_node_op>();
1149
1150 struct discard_last_node_op
1151 {
1152 template <typename MatchT>
1153 void operator()(MatchT& m) const
1154 {
1155 typedef typename MatchT::container_t container_t;
1156 typedef typename MatchT::container_t::iterator iter_t;
1157 typedef typename MatchT::container_t::value_type value_t;
1158
1159 using std::swap;
1160 using BOOST_SPIRIT_CLASSIC_NS::swap;
1161
1162
1163
1164
1165
1166
1167
1168 container_t new_children;
1169 std::size_t length = 0;
1170 std::size_t tree_size = m.trees.size();
1171
1172
1173 BOOST_SPIRIT_ASSERT(tree_size >= 1);
1174
1175 if (tree_size > 1) {
1176 m.trees.pop_back();
1177 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
1178 new_children.reserve(tree_size - 1);
1179 #endif
1180 iter_t i_end = m.trees.end();
1181 for (iter_t i = m.trees.begin(); i != i_end; ++i)
1182 {
1183
1184 length += std::distance((*i).value.begin(), (*i).value.end());
1185
1186
1187 new_children.push_back(value_t());
1188 swap(new_children.back(), *i);
1189 }
1190 }
1191 else {
1192
1193 iter_t i = m.trees.begin();
1194
1195 typedef typename value_t::parse_node_t::iterator_t iterator_type;
1196 iterator_type it = (*i).value.begin();
1197
1198 new_children.push_back(
1199 value_t(typename value_t::parse_node_t(it, it)));
1200 }
1201
1202 m = MatchT(length, new_children);
1203 }
1204 };
1205
1206 const node_parser_gen<discard_last_node_op> discard_last_node_d =
1207 node_parser_gen<discard_last_node_op>();
1208
1209 struct inner_node_op
1210 {
1211 template <typename MatchT>
1212 void operator()(MatchT& m) const
1213 {
1214 typedef typename MatchT::container_t container_t;
1215 typedef typename MatchT::container_t::iterator iter_t;
1216 typedef typename MatchT::container_t::value_type value_t;
1217
1218 using std::swap;
1219 using BOOST_SPIRIT_CLASSIC_NS::swap;
1220
1221
1222
1223
1224
1225
1226
1227 container_t new_children;
1228 std::size_t length = 0;
1229 std::size_t tree_size = m.trees.size();
1230
1231
1232 BOOST_SPIRIT_ASSERT(tree_size >= 2);
1233
1234 if (tree_size > 2) {
1235 m.trees.pop_back();
1236 #if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
1237 new_children.reserve(tree_size - 1);
1238 #endif
1239 iter_t i = m.trees.begin();
1240 iter_t i_end = m.trees.end();
1241 for (++i; i != i_end; ++i)
1242 {
1243
1244 length += std::distance((*i).value.begin(), (*i).value.end());
1245
1246
1247 new_children.push_back(value_t());
1248 swap(new_children.back(), *i);
1249 }
1250 }
1251 else {
1252
1253 iter_t i = m.trees.begin();
1254
1255 typedef typename value_t::parse_node_t::iterator_t iterator_type;
1256 iterator_type it = (*++i).value.begin();
1257
1258 new_children.push_back(
1259 value_t(typename value_t::parse_node_t(it, it)));
1260 }
1261
1262 m = MatchT(length, new_children);
1263 }
1264 };
1265
1266 const node_parser_gen<inner_node_op> inner_node_d =
1267 node_parser_gen<inner_node_op>();
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277 template <typename ActionParserT>
1278 struct action_directive_parser_gen;
1279
1280 template <typename T, typename ActionParserT>
1281 struct action_directive_parser
1282 : public unary<T, parser<action_directive_parser<T, ActionParserT> > >
1283 {
1284 typedef action_directive_parser<T, ActionParserT> self_t;
1285 typedef action_directive_parser_gen<ActionParserT> parser_generator_t;
1286 typedef unary_parser_category parser_category_t;
1287
1288 action_directive_parser(T const& a)
1289 : unary<T, parser<action_directive_parser<T, ActionParserT> > >(a) {}
1290
1291 template <typename ScannerT>
1292 struct result
1293 {
1294 typedef typename parser_result<T, ScannerT>::type type;
1295 };
1296
1297 template <typename ScannerT>
1298 typename parser_result<self_t, ScannerT>::type
1299 parse(ScannerT const& scanner) const
1300 {
1301 return this->subject().parse(scanner);
1302 }
1303
1304 template <typename ActionT>
1305 typename ActionParserT::template action<action_directive_parser<T, ActionParserT>, ActionT>
1306 operator[](ActionT const& actor) const
1307 {
1308 typedef typename
1309 ActionParserT::template action<action_directive_parser, ActionT>
1310 action_t;
1311 return action_t(*this, actor);
1312 }
1313 };
1314
1315
1316 template <typename ActionParserT>
1317 struct action_directive_parser_gen
1318 {
1319 template <typename T>
1320 struct result {
1321
1322 typedef action_directive_parser<T, ActionParserT> type;
1323 };
1324
1325 template <typename T>
1326 static action_directive_parser<T, ActionParserT>
1327 generate(parser<T> const& s)
1328 {
1329 return action_directive_parser<T, ActionParserT>(s.derived());
1330 }
1331
1332 template <typename T>
1333 action_directive_parser<T, ActionParserT>
1334 operator[](parser<T> const& s) const
1335 {
1336 return action_directive_parser<T, ActionParserT>(s.derived());
1337 }
1338 };
1339
1340
1341
1342
1343
1344
1345 template <typename ParserT, typename ActionT>
1346 struct access_match_action::action
1347 : public unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > >
1348 {
1349 typedef action_parser_category parser_category;
1350 typedef action<ParserT, ActionT> self_t;
1351
1352 template <typename ScannerT>
1353 struct result
1354 {
1355 typedef typename parser_result<ParserT, ScannerT>::type type;
1356 };
1357
1358 action( ParserT const& subject,
1359 ActionT const& actor_);
1360
1361 template <typename ScannerT>
1362 typename parser_result<self_t, ScannerT>::type
1363 parse(ScannerT const& scanner) const;
1364
1365 ActionT const &predicate() const;
1366
1367 private:
1368 ActionT actor;
1369 };
1370
1371
1372 template <typename ParserT, typename ActionT>
1373 access_match_action::action<ParserT, ActionT>::action(
1374 ParserT const& subject,
1375 ActionT const& actor_)
1376 : unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > >(subject)
1377 , actor(actor_)
1378 {}
1379
1380
1381 template <typename ParserT, typename ActionT>
1382 template <typename ScannerT>
1383 typename parser_result<access_match_action::action<ParserT, ActionT>, ScannerT>::type
1384 access_match_action::action<ParserT, ActionT>::
1385 parse(ScannerT const& scan) const
1386 {
1387 typedef typename ScannerT::iterator_t iterator_t;
1388 typedef typename parser_result<self_t, ScannerT>::type result_t;
1389 if (!scan.at_end())
1390 {
1391 iterator_t save = scan.first;
1392 result_t hit = this->subject().parse(scan);
1393 actor(hit, save, scan.first);
1394 return hit;
1395 }
1396 return scan.no_match();
1397 }
1398
1399
1400 template <typename ParserT, typename ActionT>
1401 ActionT const &access_match_action::action<ParserT, ActionT>::predicate() const
1402 {
1403 return actor;
1404 }
1405
1406
1407 const action_directive_parser_gen<access_match_action> access_match_d
1408 = action_directive_parser_gen<access_match_action>();
1409
1410
1411
1412
1413
1414
1415
1416
1417 template <typename ParserT, typename ActionT>
1418 struct access_node_action::action
1419 : public unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > >
1420 {
1421 typedef action_parser_category parser_category;
1422 typedef action<ParserT, ActionT> self_t;
1423
1424 template <typename ScannerT>
1425 struct result
1426 {
1427 typedef typename parser_result<ParserT, ScannerT>::type type;
1428 };
1429
1430 action( ParserT const& subject,
1431 ActionT const& actor_);
1432
1433 template <typename ScannerT>
1434 typename parser_result<self_t, ScannerT>::type
1435 parse(ScannerT const& scanner) const;
1436
1437 ActionT const &predicate() const;
1438
1439 private:
1440 ActionT actor;
1441 };
1442
1443
1444 template <typename ParserT, typename ActionT>
1445 access_node_action::action<ParserT, ActionT>::action(
1446 ParserT const& subject,
1447 ActionT const& actor_)
1448 : unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > >(subject)
1449 , actor(actor_)
1450 {}
1451
1452
1453 template <typename ParserT, typename ActionT>
1454 template <typename ScannerT>
1455 typename parser_result<access_node_action::action<ParserT, ActionT>, ScannerT>::type
1456 access_node_action::action<ParserT, ActionT>::
1457 parse(ScannerT const& scan) const
1458 {
1459 typedef typename ScannerT::iterator_t iterator_t;
1460 typedef typename parser_result<self_t, ScannerT>::type result_t;
1461 if (!scan.at_end())
1462 {
1463 iterator_t save = scan.first;
1464 result_t hit = this->subject().parse(scan);
1465 if (hit && hit.trees.size() > 0)
1466 actor(*hit.trees.begin(), save, scan.first);
1467 return hit;
1468 }
1469 return scan.no_match();
1470 }
1471
1472
1473 template <typename ParserT, typename ActionT>
1474 ActionT const &access_node_action::action<ParserT, ActionT>::predicate() const
1475 {
1476 return actor;
1477 }
1478
1479
1480 const action_directive_parser_gen<access_node_action> access_node_d
1481 = action_directive_parser_gen<access_node_action>();
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511 template <
1512 typename IteratorT,
1513 typename NodeFactoryT,
1514 typename T
1515 >
1516 struct tree_parse_info
1517 {
1518 IteratorT stop;
1519 bool match;
1520 bool full;
1521 std::size_t length;
1522 typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees;
1523
1524 tree_parse_info()
1525 : stop()
1526 , match(false)
1527 , full(false)
1528 , length(0)
1529 , trees()
1530 {}
1531
1532 template <typename IteratorT2>
1533 tree_parse_info(tree_parse_info<IteratorT2> const& pi)
1534 : stop(pi.stop)
1535 , match(pi.match)
1536 , full(pi.full)
1537 , length(pi.length)
1538 , trees()
1539 {
1540 using std::swap;
1541 using BOOST_SPIRIT_CLASSIC_NS::swap;
1542
1543
1544 swap(trees, pi.trees);
1545 }
1546
1547 tree_parse_info(
1548 IteratorT stop_,
1549 bool match_,
1550 bool full_,
1551 std::size_t length_,
1552 typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees_)
1553 : stop(stop_)
1554 , match(match_)
1555 , full(full_)
1556 , length(length_)
1557 , trees()
1558 {
1559 using std::swap;
1560 using BOOST_SPIRIT_CLASSIC_NS::swap;
1561
1562
1563 swap(trees, trees_);
1564 }
1565 };
1566
1567 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
1568
1569 }}
1570
1571 #endif
1572