Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:06

0001 /*=============================================================================
0002     Copyright (c) 2001-2003 Daniel Nuffer
0003     Copyright (c) 2001-2007 Hartmut Kaiser
0004     Revised 2007, Copyright (c) Tobias Schwinger
0005     http://spirit.sourceforge.net/
0006 
0007   Distributed under the Boost Software License, Version 1.0. (See accompanying
0008   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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  // BOOST_SPIRIT_USE_LIST_FOR_TREES
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*/ 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 // value is default nil_t, so provide an operator<< for nil_t
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         << /*" value = " << n.value() << */")";
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     // This constructor is for building text out of iterators
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     // This constructor is for building text out of iterators
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     // This inner class is so that node_iter_data_factory can simulate
0391     // a template template parameter
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 /*is_leaf_node*/)
0401         {
0402             return node_t(first, last);
0403         }
0404 
0405         static node_t empty_node()
0406         {
0407             return node_t();
0408         }
0409 
0410         // precondition: ContainerT contains a tree_node<node_t>.  And all
0411         // iterators in the container point to the same sequence.
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     // This inner class is so that node_val_data_factory can simulate
0427     // a template template parameter
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             // copy all the nodes text into a new one
0455             for (typename ContainerT::const_iterator i = nodes.begin();
0456                  i != i_end; ++i)
0457             {
0458                 // See docs: reduced_node_d cannot be used with a
0459                 // rule inside the [].
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     // This inner class is so that node_all_val_data_factory can simulate
0474     // a template template parameter
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 /*is_leaf_node*/)
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             // copy all the nodes text into a new one
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     // can't call unqualified swap from within classname::swap
0514     // as Koenig lookup rules will find only the classname::swap
0515     // member function not the global declaration, so use cp_swap
0516     // as a forwarding function (JM):
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); // this is more or less an arbitrary number...
0564 #endif
0565         trees.push_back(node_t(n));
0566     }
0567 
0568     // attention, these constructors will change the second parameter!
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         // use auto_ptr like ownership for the trees data member
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& /*op*/, MatchT& /*m*/)
0657     {}
0658 
0659     template <typename MatchT, typename Iterator1T, typename Iterator2T>
0660     static void group_match(MatchT& /*m*/, parser_id const& /*id*/,
0661             Iterator1T const& /*first*/, Iterator2T const& /*last*/)
0662     {}
0663 
0664     template <typename MatchT>
0665     static void concat(MatchT& /*a*/, MatchT const& /*b*/)
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 /*length*/, 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 // directives to modify how the parse tree is generated
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 } // namespace impl
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         // copying the tree nodes is expensive, since it may copy a whole
1049         // tree.  swapping them is cheap, so swap the nodes we want into
1050         // a new container of children.
1051         container_t new_children;
1052         std::size_t length = 0;
1053         std::size_t tree_size = m.trees.size();
1054 
1055         // the infix_node_d[] make no sense for nodes with no subnodes
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                 // adjust the length
1067                 length += std::distance((*i).value.begin(), (*i).value.end());
1068 
1069                 // move the child node
1070                 new_children.push_back(value_t());
1071                 swap(new_children.back(), *i);
1072                 keep = false;
1073             }
1074             else {
1075                 // ignore this child node
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         // copying the tree nodes is expensive, since it may copy a whole
1100         // tree.  swapping them is cheap, so swap the nodes we want into
1101         // a new container of children, instead of saying
1102         // m.trees.erase(m.trees.begin()) because, on a container_t that will 
1103         // cause all the nodes afterwards to be copied into the previous 
1104         // position.
1105         container_t new_children;
1106         std::size_t length = 0;
1107         std::size_t tree_size = m.trees.size();
1108 
1109         // the discard_first_node_d[] make no sense for nodes with no subnodes
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                 // adjust the length
1120                 length += std::distance((*i).value.begin(), (*i).value.end());
1121 
1122                 // move the child node
1123                 new_children.push_back(value_t());
1124                 swap(new_children.back(), *i);
1125             }
1126         }
1127         else {
1128         // if there was a tree and now there isn't any, insert an empty node
1129             iter_t i = m.trees.begin(); 
1130 
1131         // This isn't entirely correct, since the empty node will reference
1132         // the end of the discarded node, but I currently don't see any way to 
1133         // get at the begin of the node following this subnode.
1134         // This should be safe anyway because the it shouldn't get dereferenced
1135         // under any circumstances.
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         // copying the tree nodes is expensive, since it may copy a whole
1163         // tree.  swapping them is cheap, so swap the nodes we want into
1164         // a new container of children, instead of saying
1165         // m.trees.erase(m.trees.begin()) because, on a container_t that will 
1166         // cause all the nodes afterwards to be copied into the previous 
1167         // position.
1168         container_t new_children;
1169         std::size_t length = 0;
1170         std::size_t tree_size = m.trees.size();
1171 
1172         // the discard_last_node_d[] make no sense for nodes with no subnodes
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                 // adjust the length
1184                 length += std::distance((*i).value.begin(), (*i).value.end());
1185 
1186                 // move the child node
1187                 new_children.push_back(value_t());
1188                 swap(new_children.back(), *i);
1189             }
1190         }
1191         else {
1192         // if there was a tree and now there isn't any, insert an empty node
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         // copying the tree nodes is expensive, since it may copy a whole
1222         // tree.  swapping them is cheap, so swap the nodes we want into
1223         // a new container of children, instead of saying
1224         // m.trees.erase(m.trees.begin()) because, on a container_t that will 
1225         // cause all the nodes afterwards to be copied into the previous 
1226         // position.
1227         container_t new_children;
1228         std::size_t length = 0;
1229         std::size_t tree_size = m.trees.size();
1230         
1231         // the inner_node_d[] make no sense for nodes with less then 2 subnodes
1232         BOOST_SPIRIT_ASSERT(tree_size >= 2);
1233 
1234         if (tree_size > 2) {
1235             m.trees.pop_back(); // erase the last element
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(); // skip over the first element
1240             iter_t i_end = m.trees.end();
1241             for (++i; i != i_end; ++i)
1242             {
1243                 // adjust the length
1244                 length += std::distance((*i).value.begin(), (*i).value.end());
1245                 
1246                 // move the child node
1247                 new_children.push_back(value_t());
1248                 swap(new_children.back(), *i);
1249             }
1250         }
1251         else {
1252         // if there was a tree and now there isn't any, insert an empty node
1253             iter_t i = m.trees.begin(); // skip over the first element
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 // action_directive_parser and action_directive_parser_gen
1272 // are meant to be used as a template to create directives that
1273 // generate action classes.  For example access_match and
1274 // access_node.  The ActionParserT template parameter must be
1275 // a class that has an innter class called action that is templated
1276 // on the parser type and the action type.
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 // Calls the attached action passing it the match from the parser
1342 // and the first and last iterators.
1343 // The inner template class is used to simulate template-template parameters
1344 // (declared in common_fwd.hpp).
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 // Calls the attached action passing it the node from the parser
1414 // and the first and last iterators
1415 // The inner template class is used to simulate template-template parameters
1416 // (declared in common_fwd.hpp).
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 //  tree_parse_info
1490 //
1491 //      Results returned by the tree parse functions:
1492 //
1493 //      stop:   points to the final parse position (i.e parsing
1494 //              processed the input up to this point).
1495 //
1496 //      match:  true if parsing is successful. This may be full:
1497 //              the parser consumed all the input, or partial:
1498 //              the parser consumed only a portion of the input.
1499 //
1500 //      full:   true when we have a full match (i.e the parser
1501 //              consumed all the input.
1502 //
1503 //      length: The number of characters consumed by the parser.
1504 //              This is valid only if we have a successful match
1505 //              (either partial or full). A negative value means
1506 //              that the match is unsuccessful.
1507 //
1508 //     trees:   Contains the root node(s) of the tree.
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         // use auto_ptr like ownership for the trees data member
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         // use auto_ptr like ownership for the trees data member
1563         swap(trees, trees_);
1564     }
1565 };
1566 
1567 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
1568 
1569 }} // namespace BOOST_SPIRIT_CLASSIC_NS
1570 
1571 #endif
1572