LCOV - code coverage report
Current view: top level - usr/include/boost/spirit/home/classic/tree - common.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 7 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 0 -
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14