diff DEPENDENCIES/generic/include/boost/spirit/home/classic/tree/common.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/spirit/home/classic/tree/common.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,1588 @@
+/*=============================================================================
+    Copyright (c) 2001-2003 Daniel Nuffer
+    Copyright (c) 2001-2007 Hartmut Kaiser
+    Revised 2007, Copyright (c) Tobias Schwinger
+    http://spirit.sourceforge.net/
+
+  Distributed under the Boost Software License, Version 1.0. (See accompanying
+  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#ifndef BOOST_SPIRIT_TREE_COMMON_HPP
+#define BOOST_SPIRIT_TREE_COMMON_HPP
+
+#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
+#include <vector>
+#else
+#include <list>
+#endif
+
+#if defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)
+#include <boost/pool/pool_alloc.hpp>
+#endif
+
+#include <algorithm>
+
+#include <boost/ref.hpp>
+#include <boost/call_traits.hpp>
+#include <boost/spirit/home/classic/namespace.hpp>
+#include <boost/spirit/home/classic/core.hpp>
+#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
+#include <boost/assert.hpp>
+
+#if defined(BOOST_SPIRIT_DEBUG) && \
+    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
+#include <iostream>
+#include <boost/spirit/home/classic/debug/debug_node.hpp>
+#endif
+
+#include <boost/spirit/home/classic/tree/common_fwd.hpp>
+
+namespace boost { namespace spirit {
+
+BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
+
+template <typename T>
+void swap(tree_node<T>& a, tree_node<T>& b);
+
+template <typename T, typename V>
+void swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b);
+
+namespace impl {
+    template <typename T>
+    inline void cp_swap(T& t1, T& t2);
+}
+
+template <typename T>
+struct tree_node
+{
+    typedef T parse_node_t;
+    
+#if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)
+    typedef std::allocator<tree_node<T> > allocator_type;
+#elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
+    typedef boost::pool_allocator<tree_node<T> > allocator_type;
+#else
+    typedef boost::fast_pool_allocator<tree_node<T> > allocator_type;
+#endif
+
+#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
+    typedef std::vector<tree_node<T>, allocator_type> children_t;
+#else
+    typedef std::list<tree_node<T>, allocator_type> children_t;
+#endif  // BOOST_SPIRIT_USE_LIST_FOR_TREES
+
+    typedef typename children_t::iterator tree_iterator;
+    typedef typename children_t::const_iterator const_tree_iterator;
+
+    T value;
+    children_t children;
+
+    tree_node()
+        : value()
+        , children()
+    {}
+
+    explicit tree_node(T const& v)
+        : value(v)
+        , children()
+    {}
+
+    tree_node(T const& v, children_t const& c)
+        : value(v)
+        , children(c)
+    {}
+
+    void swap(tree_node<T>& x)
+    {
+        impl::cp_swap(value, x.value);
+        impl::cp_swap(children, x.children);
+    }
+
+// Intel V5.0.1 has a problem without this explicit operator=
+    tree_node &operator= (tree_node const &rhs)
+    {
+        tree_node(rhs).swap(*this);
+        return *this;
+    }
+};
+
+#if defined(BOOST_SPIRIT_DEBUG) && \
+    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
+template <typename T>
+inline std::ostream&
+operator<<(std::ostream& o, tree_node<T> const& n)
+{
+    static int depth = 0;
+    o << "\n";
+    for (int i = 0; i <= depth; ++i)
+    {
+        o << "\t";
+    }
+    o << "(depth = " << depth++ << " value = " << n.value;
+    int c = 0;
+    for (typename tree_node<T>::children_t::const_iterator it = n.children.begin();
+         it != n.children.end(); ++it)
+    {
+        o << " children[" << c++ << "] = " << *it;
+    }
+    o << ")";
+    --depth;
+    return o;
+}
+#endif
+
+//////////////////////////////////
+template <typename IteratorT, typename ValueT>
+struct node_iter_data
+{
+    typedef IteratorT iterator_t;
+    typedef IteratorT /*const*/ const_iterator_t;
+
+    node_iter_data()
+        : first(), last(), is_root_(false), parser_id_(), value_()
+        {}
+
+    node_iter_data(IteratorT const& _first, IteratorT const& _last)
+        : first(_first), last(_last), is_root_(false), parser_id_(), value_()
+        {}
+
+    void swap(node_iter_data& x)
+    {
+        impl::cp_swap(first, x.first);
+        impl::cp_swap(last, x.last);
+        impl::cp_swap(parser_id_, x.parser_id_);
+        impl::cp_swap(is_root_, x.is_root_);
+        impl::cp_swap(value_, x.value_);
+    }
+
+    IteratorT begin()
+    {
+        return first;
+    }
+
+    IteratorT const& begin() const
+    {
+        return first;
+    }
+
+    IteratorT end()
+    {
+        return last;
+    }
+
+    IteratorT const& end() const
+    {
+        return last;
+    }
+
+    bool is_root() const
+    {
+        return is_root_;
+    }
+
+    void is_root(bool b)
+    {
+        is_root_ = b;
+    }
+
+    parser_id id() const
+    {
+        return parser_id_;
+    }
+
+    void id(parser_id r)
+    {
+        parser_id_ = r;
+    }
+
+    ValueT const& value() const
+    {
+        return value_;
+    }
+
+    void value(ValueT const& v)
+    {
+        value_ = v;
+    }
+private:
+    IteratorT first, last;
+    bool is_root_;
+    parser_id parser_id_;
+    ValueT value_;
+
+public:
+};
+
+#if defined(BOOST_SPIRIT_DEBUG) && \
+    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
+// value is default nil_t, so provide an operator<< for nil_t
+inline std::ostream&
+operator<<(std::ostream& o, nil_t const&)
+{
+    return o;
+}
+
+template <typename IteratorT, typename ValueT>
+inline std::ostream&
+operator<<(std::ostream& o, node_iter_data<IteratorT, ValueT> const& n)
+{
+    o << "(id = " << n.id() << " text = \"";
+    typedef typename node_iter_data<IteratorT, ValueT>::const_iterator_t
+        iterator_t;
+    for (iterator_t it = n.begin(); it != n.end(); ++it)
+        impl::token_printer(o, *it);
+    o << "\" is_root = " << n.is_root()
+        << /*" value = " << n.value() << */")";
+    return o;
+}
+#endif
+
+//////////////////////////////////
+template <typename IteratorT = char const*, typename ValueT = nil_t>
+struct node_val_data
+{
+    typedef
+        typename boost::detail::iterator_traits<IteratorT>::value_type
+        value_type;
+
+#if !defined(BOOST_SPIRIT_USE_BOOST_ALLOCATOR_FOR_TREES)
+    typedef std::allocator<value_type> allocator_type;
+#elif !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
+    typedef boost::pool_allocator<value_type> allocator_type;
+#else
+    typedef boost::fast_pool_allocator<value_type> allocator_type;
+#endif
+
+#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
+    typedef std::vector<value_type, allocator_type> container_t;
+#else
+    typedef std::list<value_type, allocator_type> container_t;
+#endif
+
+    typedef typename container_t::iterator iterator_t;
+    typedef typename container_t::const_iterator const_iterator_t;
+
+    node_val_data()
+        : text(), is_root_(false), parser_id_(), value_()
+        {}
+
+#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
+    node_val_data(IteratorT const& _first, IteratorT const& _last)
+        : text(), is_root_(false), parser_id_(), value_()
+        {
+            std::copy(_first, _last, std::inserter(text, text.end()));
+        }
+
+    // This constructor is for building text out of iterators
+    template <typename IteratorT2>
+    node_val_data(IteratorT2 const& _first, IteratorT2 const& _last)
+        : text(), is_root_(false), parser_id_(), value_()
+        {
+            std::copy(_first, _last, std::inserter(text, text.end()));
+        }
+#else
+    node_val_data(IteratorT const& _first, IteratorT const& _last)
+        : text(_first, _last), is_root_(false), parser_id_(), value_()
+        {}
+
+    // This constructor is for building text out of iterators
+    template <typename IteratorT2>
+    node_val_data(IteratorT2 const& _first, IteratorT2 const& _last)
+        : text(_first, _last), is_root_(false), parser_id_(), value_()
+        {}
+#endif
+
+    void swap(node_val_data& x)
+    {
+        impl::cp_swap(text, x.text);
+        impl::cp_swap(is_root_, x.is_root_);
+        impl::cp_swap(parser_id_, x.parser_id_);
+        impl::cp_swap(value_, x.value_);
+    }
+
+    typename container_t::iterator begin()
+    {
+        return text.begin();
+    }
+
+    typename container_t::const_iterator begin() const
+    {
+        return text.begin();
+    }
+
+    typename container_t::iterator end()
+    {
+        return text.end();
+    }
+
+    typename container_t::const_iterator end() const
+    {
+        return text.end();
+    }
+
+    bool is_root() const
+    {
+        return is_root_;
+    }
+
+    void is_root(bool b)
+    {
+        is_root_ = b;
+    }
+
+    parser_id id() const
+    {
+        return parser_id_;
+    }
+
+    void id(parser_id r)
+    {
+        parser_id_ = r;
+    }
+
+    ValueT const& value() const
+    {
+        return value_;
+    }
+
+    void value(ValueT const& v)
+    {
+        value_ = v;
+    }
+
+private:
+    container_t text;
+    bool is_root_;
+    parser_id parser_id_;
+    ValueT value_;
+};
+
+#if defined(BOOST_SPIRIT_DEBUG) && \
+    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
+template <typename IteratorT, typename ValueT>
+inline std::ostream&
+operator<<(std::ostream& o, node_val_data<IteratorT, ValueT> const& n)
+{
+    o << "(id = " << n.id() << " text = \"";
+    typedef typename node_val_data<IteratorT, ValueT>::const_iterator_t
+        iterator_t;
+    for (iterator_t it = n.begin(); it != n.end(); ++it)
+        impl::token_printer(o, *it);
+    o << "\" is_root = " << n.is_root()
+        << " value = " << n.value() << ")";
+    return o;
+}
+#endif
+
+template <typename T>
+inline void
+swap(tree_node<T>& a, tree_node<T>& b)
+{
+    a.swap(b);
+}
+
+template <typename T, typename V>
+inline void
+swap(node_iter_data<T, V>& a, node_iter_data<T, V>& b)
+{
+    a.swap(b);
+}
+
+//////////////////////////////////
+template <typename ValueT>
+class node_iter_data_factory
+{
+public:
+    // This inner class is so that node_iter_data_factory can simulate
+    // a template template parameter
+    template <typename IteratorT>
+    class factory
+    {
+    public:
+        typedef IteratorT iterator_t;
+        typedef node_iter_data<iterator_t, ValueT> node_t;
+
+        static node_t create_node(iterator_t const& first, iterator_t const& last,
+                bool /*is_leaf_node*/)
+        {
+            return node_t(first, last);
+        }
+
+        static node_t empty_node()
+        {
+            return node_t();
+        }
+
+        // precondition: ContainerT contains a tree_node<node_t>.  And all
+        // iterators in the container point to the same sequence.
+        template <typename ContainerT>
+        static node_t group_nodes(ContainerT const& nodes)
+        {
+            return node_t(nodes.begin()->value.begin(),
+                    nodes.back().value.end());
+        }
+    };
+};
+
+//////////////////////////////////
+template <typename ValueT>
+class node_val_data_factory 
+{
+public:
+    // This inner class is so that node_val_data_factory can simulate
+    // a template template parameter
+    template <typename IteratorT>
+    class factory
+    {
+    public:
+        typedef IteratorT iterator_t;
+        typedef node_val_data<iterator_t, ValueT> node_t;
+
+        static node_t create_node(iterator_t const& first, iterator_t const& last,
+                bool is_leaf_node)
+        {
+            if (is_leaf_node)
+                return node_t(first, last);
+            else
+                return node_t();
+        }
+
+        static node_t empty_node()
+        {
+            return node_t();
+        }
+
+        template <typename ContainerT>
+        static node_t group_nodes(ContainerT const& nodes)
+        {
+            typename node_t::container_t c;
+            typename ContainerT::const_iterator i_end = nodes.end();
+            // copy all the nodes text into a new one
+            for (typename ContainerT::const_iterator i = nodes.begin();
+                 i != i_end; ++i)
+            {
+                // See docs: reduced_node_d cannot be used with a
+                // rule inside the [].
+                BOOST_ASSERT(i->children.size() == 0);
+                c.insert(c.end(), i->value.begin(), i->value.end());
+            }
+            return node_t(c.begin(), c.end());
+        }
+    };
+};
+
+//////////////////////////////////
+template <typename ValueT>
+class node_all_val_data_factory
+{
+public:
+    // This inner class is so that node_all_val_data_factory can simulate
+    // a template template parameter
+    template <typename IteratorT>
+    class factory
+    {
+    public:
+        typedef IteratorT iterator_t;
+        typedef node_val_data<iterator_t, ValueT> node_t;
+
+        static node_t create_node(iterator_t const& first, iterator_t const& last,
+                bool /*is_leaf_node*/)
+        {
+            return node_t(first, last);
+        }
+
+        static node_t empty_node()
+        {
+            return node_t();
+        }
+
+        template <typename ContainerT>
+        static node_t group_nodes(ContainerT const& nodes)
+        {
+            typename node_t::container_t c;
+            typename ContainerT::const_iterator i_end = nodes.end();
+            // copy all the nodes text into a new one
+            for (typename ContainerT::const_iterator i = nodes.begin();
+                    i != i_end; ++i)
+            {
+                BOOST_ASSERT(i->children.size() == 0);
+                c.insert(c.end(), i->value.begin(), i->value.end());
+            }
+            return node_t(c.begin(), c.end());
+        }
+    };
+};
+
+namespace impl {
+
+    ///////////////////////////////////////////////////////////////////////////
+    // can't call unqualified swap from within classname::swap
+    // as Koenig lookup rules will find only the classname::swap
+    // member function not the global declaration, so use cp_swap
+    // as a forwarding function (JM):
+#if __GNUC__ == 2
+    using ::std::swap;
+#endif
+    template <typename T>
+    inline void cp_swap(T& t1, T& t2)
+    {
+        using std::swap;
+        using BOOST_SPIRIT_CLASSIC_NS::swap;
+        using boost::swap;
+        swap(t1, t2);
+    }
+}
+
+//////////////////////////////////
+template <typename IteratorT, typename NodeFactoryT, typename T>
+class tree_match : public match<T>
+{
+public:
+
+    typedef typename NodeFactoryT::template factory<IteratorT> node_factory_t;
+    typedef typename node_factory_t::node_t parse_node_t;
+    typedef tree_node<parse_node_t> node_t;
+    typedef typename node_t::children_t container_t;
+    typedef typename container_t::iterator tree_iterator;
+    typedef typename container_t::const_iterator const_tree_iterator;
+
+    typedef T attr_t;
+    typedef typename boost::call_traits<T>::param_type      param_type;
+    typedef typename boost::call_traits<T>::reference       reference;
+    typedef typename boost::call_traits<T>::const_reference const_reference;
+
+    tree_match()
+    : match<T>(), trees()
+    {}
+
+    explicit
+    tree_match(std::size_t length_)
+    : match<T>(length_), trees()
+    {}
+
+    tree_match(std::size_t length_, parse_node_t const& n)
+    : match<T>(length_), trees()
+    { 
+        trees.push_back(node_t(n)); 
+    }
+
+    tree_match(std::size_t length_, param_type val, parse_node_t const& n)
+    : match<T>(length_, val), trees()
+    {
+#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
+        trees.reserve(10); // this is more or less an arbitrary number...
+#endif
+        trees.push_back(node_t(n));
+    }
+
+    // attention, these constructors will change the second parameter!
+    tree_match(std::size_t length_, container_t& c)
+    : match<T>(length_), trees()
+    { 
+        impl::cp_swap(trees, c);
+    }
+
+    tree_match(std::size_t length_, param_type val, container_t& c)
+    : match<T>(length_, val), trees()
+    {
+        impl::cp_swap(trees, c);
+    }
+
+    template <typename T2>
+    tree_match(match<T2> const& other)
+    : match<T>(other), trees()
+    {}
+
+    template <typename T2, typename T3, typename T4>
+    tree_match(tree_match<T2, T3, T4> const& other)
+    : match<T>(other), trees()
+    { impl::cp_swap(trees, other.trees); }
+
+    template <typename T2>
+    tree_match&
+    operator=(match<T2> const& other)
+    {
+        match<T>::operator=(other);
+        return *this;
+    }
+
+    template <typename T2, typename T3, typename T4>
+    tree_match&
+    operator=(tree_match<T2, T3, T4> const& other)
+    {
+        match<T>::operator=(other);
+        impl::cp_swap(trees, other.trees);
+        return *this;
+    }
+
+    tree_match(tree_match const& x)
+    : match<T>(x), trees()
+    {
+        // use auto_ptr like ownership for the trees data member
+        impl::cp_swap(trees, x.trees);
+    }
+
+    tree_match& operator=(tree_match const& x)
+    {
+        tree_match tmp(x);
+        this->swap(tmp);
+        return *this;
+    }
+
+    void swap(tree_match& x)
+    {
+        match<T>::swap(x);
+        impl::cp_swap(trees, x.trees);
+    }
+
+    mutable container_t trees;
+};
+
+#if defined(BOOST_SPIRIT_DEBUG) && \
+    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
+template <typename IteratorT, typename NodeFactoryT, typename T>
+inline std::ostream&
+operator<<(std::ostream& o, tree_match<IteratorT, NodeFactoryT, T> const& m)
+{
+    typedef
+        typename tree_match<IteratorT, NodeFactoryT, T>::container_t::iterator
+        iterator;
+
+    o << "(length = " << (int)m.length();
+    int c = 0;
+    for (iterator i = m.trees.begin(); i != m.trees.end(); ++i)
+    {
+        o << " trees[" << c++ << "] = " << *i;
+    }
+    o << "\n)";
+    return o;
+}
+#endif
+
+//////////////////////////////////
+struct tree_policy
+{
+    template <typename FunctorT, typename MatchT>
+    static void apply_op_to_match(FunctorT const& /*op*/, MatchT& /*m*/)
+    {}
+
+    template <typename MatchT, typename Iterator1T, typename Iterator2T>
+    static void group_match(MatchT& /*m*/, parser_id const& /*id*/,
+            Iterator1T const& /*first*/, Iterator2T const& /*last*/)
+    {}
+
+    template <typename MatchT>
+    static void concat(MatchT& /*a*/, MatchT const& /*b*/)
+    {}
+};
+
+//////////////////////////////////
+template <
+    typename MatchPolicyT,
+    typename IteratorT,
+    typename NodeFactoryT,
+    typename TreePolicyT, 
+    typename T
+>
+struct common_tree_match_policy : public match_policy
+{
+    common_tree_match_policy()
+    {
+    }
+
+    template <typename PolicyT>
+    common_tree_match_policy(PolicyT const & policies)
+        : match_policy((match_policy const &)policies)
+    {
+    }
+
+    template <typename U>
+    struct result { typedef tree_match<IteratorT, NodeFactoryT, U> type; };
+
+    typedef tree_match<IteratorT, NodeFactoryT, T> match_t;
+    typedef IteratorT iterator_t;
+    typedef TreePolicyT tree_policy_t;
+    typedef NodeFactoryT factory_t;
+
+    static const match_t no_match() { return match_t(); }
+    static const match_t empty_match()
+    { return match_t(0, tree_policy_t::empty_node()); }
+
+    template <typename AttrT, typename Iterator1T, typename Iterator2T>
+    static tree_match<IteratorT, NodeFactoryT, AttrT> create_match(
+        std::size_t length,
+        AttrT const& val,
+        Iterator1T const& first,
+        Iterator2T const& last)
+    {
+#if defined(BOOST_SPIRIT_DEBUG) && \
+    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
+
+        BOOST_SPIRIT_DEBUG_OUT << "\n>>> create_node(begin) <<<\n" 
+            "creating node text: \"";
+        for (Iterator1T it = first; it != last; ++it)
+            impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it);
+        BOOST_SPIRIT_DEBUG_OUT << "\"\n";
+        BOOST_SPIRIT_DEBUG_OUT << ">>> create_node(end) <<<\n\n"; 
+#endif
+        return tree_match<IteratorT, NodeFactoryT, AttrT>(length, val,
+            tree_policy_t::create_node(length, first, last, true));
+    }
+
+    template <typename Match1T, typename Match2T>
+    static void concat_match(Match1T& a, Match2T const& b)
+    {
+#if defined(BOOST_SPIRIT_DEBUG) && \
+    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES)
+
+        BOOST_SPIRIT_DEBUG_OUT << "\n>>> concat_match(begin) <<<\n";
+        BOOST_SPIRIT_DEBUG_OUT << "tree a:\n" << a << "\n";
+        BOOST_SPIRIT_DEBUG_OUT << "tree b:\n" << b << "\n";
+        BOOST_SPIRIT_DEBUG_OUT << ">>> concat_match(end) <<<\n\n";
+#endif
+        BOOST_SPIRIT_ASSERT(a && b);
+        if (a.length() == 0)
+        {
+            a = b;
+            return;
+        }
+        else if (b.length() == 0
+#ifdef BOOST_SPIRIT_NO_TREE_NODE_COLLAPSING
+            && !b.trees.begin()->value.id().to_long()
+#endif
+            )
+        {
+            return;
+        }
+        a.concat(b);
+        tree_policy_t::concat(a, b);
+    }
+
+    template <typename MatchT, typename IteratorT2>
+    void
+    group_match(
+        MatchT&             m,
+        parser_id const&    id,
+        IteratorT2 const&   first,
+        IteratorT2 const&   last) const
+    {
+        if (!m) return;
+        
+#if defined(BOOST_SPIRIT_DEBUG) && \
+    (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_TREES)
+
+        BOOST_SPIRIT_DEBUG_OUT << "\n>>> group_match(begin) <<<\n"
+            "new node(" << id << ") \"";
+        for (IteratorT2 it = first; it != last; ++it)
+            impl::token_printer(BOOST_SPIRIT_DEBUG_OUT, *it);
+        BOOST_SPIRIT_DEBUG_OUT << "\"\n";
+        BOOST_SPIRIT_DEBUG_OUT << "new child tree (before grouping):\n" << m << "\n";
+
+        tree_policy_t::group_match(m, id, first, last);
+
+        BOOST_SPIRIT_DEBUG_OUT << "new child tree (after grouping):\n" << m << "\n";
+        BOOST_SPIRIT_DEBUG_OUT << ">>> group_match(end) <<<\n\n";
+#else
+        tree_policy_t::group_match(m, id, first, last);
+#endif
+    }
+};
+
+//////////////////////////////////
+template <typename MatchPolicyT, typename NodeFactoryT>
+struct common_tree_tree_policy
+{
+    typedef typename MatchPolicyT::iterator_t iterator_t;
+    typedef typename MatchPolicyT::match_t match_t;
+    typedef typename NodeFactoryT::template factory<iterator_t> factory_t;
+    typedef typename factory_t::node_t node_t;
+
+    template <typename Iterator1T, typename Iterator2T>
+        static node_t
+        create_node(std::size_t /*length*/, Iterator1T const& first,
+            Iterator2T const& last, bool leaf_node)
+    {
+        return factory_t::create_node(first, last, leaf_node);
+    }
+
+    static node_t
+        empty_node()
+    {
+        return factory_t::empty_node();
+    }
+
+    template <typename FunctorT>
+        static void apply_op_to_match(FunctorT const& op, match_t& m)
+    {
+        op(m);
+    }
+};
+
+//////////////////////////////////
+// directives to modify how the parse tree is generated
+
+struct no_tree_gen_node_parser_gen;
+
+template <typename T>
+struct no_tree_gen_node_parser
+:   public unary<T, parser<no_tree_gen_node_parser<T> > >
+{
+    typedef no_tree_gen_node_parser<T> self_t;
+    typedef no_tree_gen_node_parser_gen parser_generator_t;
+    typedef unary_parser_category parser_category_t;
+
+    no_tree_gen_node_parser(T const& a)
+    : unary<T, parser<no_tree_gen_node_parser<T> > >(a) {}
+
+    template <typename ScannerT>
+    typename parser_result<self_t, ScannerT>::type
+    parse(ScannerT const& scanner) const
+    {
+        typedef typename ScannerT::iteration_policy_t iteration_policy_t;
+        typedef match_policy match_policy_t;
+        typedef typename ScannerT::action_policy_t action_policy_t;
+        typedef scanner_policies<
+            iteration_policy_t,
+            match_policy_t,
+            action_policy_t
+        > policies_t;
+
+        return this->subject().parse(scanner.change_policies(policies_t(scanner)));
+    }
+};
+
+struct no_tree_gen_node_parser_gen
+{
+    template <typename T>
+    struct result {
+
+        typedef no_tree_gen_node_parser<T> type;
+    };
+
+    template <typename T>
+    static no_tree_gen_node_parser<T>
+    generate(parser<T> const& s)
+    {
+        return no_tree_gen_node_parser<T>(s.derived());
+    }
+
+    template <typename T>
+    no_tree_gen_node_parser<T>
+    operator[](parser<T> const& s) const
+    {
+        return no_tree_gen_node_parser<T>(s.derived());
+    }
+};
+
+const no_tree_gen_node_parser_gen no_node_d = no_tree_gen_node_parser_gen();
+
+//////////////////////////////////
+
+struct leaf_node_parser_gen;
+
+template<typename T>
+struct leaf_node_parser
+:   public unary<T, parser<leaf_node_parser<T> > >
+{
+    typedef leaf_node_parser<T> self_t;
+    typedef leaf_node_parser_gen parser_generator_t;
+    typedef unary_parser_category parser_category_t;
+
+    leaf_node_parser(T const& a)
+    : unary<T, parser<leaf_node_parser<T> > >(a) {}
+
+    template <typename ScannerT>
+    typename parser_result<self_t, ScannerT>::type
+    parse(ScannerT const& scanner) const
+    {
+        typedef scanner_policies< typename ScannerT::iteration_policy_t,
+            match_policy, typename ScannerT::action_policy_t > policies_t;
+
+        typedef typename ScannerT::iterator_t iterator_t;
+        typedef typename parser_result<self_t, ScannerT>::type result_t;
+        typedef typename result_t::node_factory_t factory_t;
+
+        iterator_t from = scanner.first;
+        result_t hit = impl::contiguous_parser_parse<result_t>(this->subject(),
+            scanner.change_policies(policies_t(scanner,match_policy(),scanner)),
+            scanner);
+
+        if (hit)
+            return result_t(hit.length(), 
+                factory_t::create_node(from, scanner.first, true));
+        else
+            return result_t(hit.length());
+    }
+};
+
+struct leaf_node_parser_gen
+{
+    template <typename T>
+    struct result {
+
+        typedef leaf_node_parser<T> type;
+    };
+
+    template <typename T>
+    static leaf_node_parser<T>
+    generate(parser<T> const& s)
+    {
+        return leaf_node_parser<T>(s.derived());
+    }
+
+    template <typename T>
+    leaf_node_parser<T>
+    operator[](parser<T> const& s) const
+    {
+        return leaf_node_parser<T>(s.derived());
+    }
+};
+
+const leaf_node_parser_gen leaf_node_d = leaf_node_parser_gen();
+const leaf_node_parser_gen token_node_d = leaf_node_parser_gen();
+
+//////////////////////////////////
+namespace impl {
+
+    template <typename MatchPolicyT>
+    struct tree_policy_selector
+    {
+        typedef tree_policy type;
+    };
+
+} // namespace impl
+
+//////////////////////////////////
+template <typename NodeParserT>
+struct node_parser_gen;
+
+template <typename T, typename NodeParserT>
+struct node_parser
+:   public unary<T, parser<node_parser<T, NodeParserT> > >
+{
+    typedef node_parser<T, NodeParserT> self_t;
+    typedef node_parser_gen<NodeParserT> parser_generator_t;
+    typedef unary_parser_category parser_category_t;
+
+    node_parser(T const& a)
+    : unary<T, parser<node_parser<T, NodeParserT> > >(a) {}
+
+    template <typename ScannerT>
+    struct result
+    {
+        typedef typename parser_result<T, ScannerT>::type type;
+    };
+
+    template <typename ScannerT>
+    typename parser_result<self_t, ScannerT>::type
+    parse(ScannerT const& scanner) const
+    {
+        typename parser_result<self_t, ScannerT>::type hit = this->subject().parse(scanner);
+        if (hit)
+        {
+            impl::tree_policy_selector<typename ScannerT::match_policy_t>::type::apply_op_to_match(NodeParserT(), hit);
+        }
+        return hit;
+    }
+};
+
+template <typename NodeParserT>
+struct node_parser_gen
+{
+    template <typename T>
+    struct result {
+
+        typedef node_parser<T, NodeParserT> type;
+    };
+
+    template <typename T>
+    static node_parser<T, NodeParserT>
+    generate(parser<T> const& s)
+    {
+        return node_parser<T, NodeParserT>(s.derived());
+    }
+
+    template <typename T>
+    node_parser<T, NodeParserT>
+    operator[](parser<T> const& s) const
+    {
+        return node_parser<T, NodeParserT>(s.derived());
+    }
+};
+//////////////////////////////////
+struct reduced_node_op
+{
+    template <typename MatchT>
+    void operator()(MatchT& m) const
+    {
+        if (m.trees.size() == 1)
+        {
+            m.trees.begin()->children.clear();
+        }
+        else if (m.trees.size() > 1)
+        {
+            typedef typename MatchT::node_factory_t node_factory_t;
+            m = MatchT(m.length(), node_factory_t::group_nodes(m.trees));
+        }
+    }
+};
+
+const node_parser_gen<reduced_node_op> reduced_node_d =
+    node_parser_gen<reduced_node_op>();
+
+
+struct discard_node_op
+{
+    template <typename MatchT>
+    void operator()(MatchT& m) const
+    {
+        m.trees.clear();
+    }
+};
+
+const node_parser_gen<discard_node_op> discard_node_d =
+    node_parser_gen<discard_node_op>();
+
+struct infix_node_op
+{
+    template <typename MatchT>
+    void operator()(MatchT& m) const
+    {
+        typedef typename MatchT::container_t container_t;
+        typedef typename MatchT::container_t::iterator iter_t;
+        typedef typename MatchT::container_t::value_type value_t;
+
+        using std::swap;
+        using boost::swap;
+        using BOOST_SPIRIT_CLASSIC_NS::swap;
+
+        // copying the tree nodes is expensive, since it may copy a whole
+        // tree.  swapping them is cheap, so swap the nodes we want into
+        // a new container of children.
+        container_t new_children;
+        std::size_t length = 0;
+        std::size_t tree_size = m.trees.size();
+
+        // the infix_node_d[] make no sense for nodes with no subnodes
+        BOOST_SPIRIT_ASSERT(tree_size >= 1);
+
+        bool keep = true;
+#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
+        new_children.reserve((tree_size+1)/2);
+#endif
+        iter_t i_end = m.trees.end();
+        for (iter_t i = m.trees.begin(); i != i_end; ++i)
+        {
+            if (keep) {
+                // adjust the length
+                length += std::distance((*i).value.begin(), (*i).value.end());
+
+                // move the child node
+                new_children.push_back(value_t());
+                swap(new_children.back(), *i);
+                keep = false;
+            }
+            else {
+                // ignore this child node
+                keep = true;
+            }
+        }
+
+        m = MatchT(length, new_children);
+    }
+};
+
+const node_parser_gen<infix_node_op> infix_node_d =
+    node_parser_gen<infix_node_op>();
+
+struct discard_first_node_op
+{
+    template <typename MatchT>
+    void operator()(MatchT& m) const
+    {
+        typedef typename MatchT::container_t container_t;
+        typedef typename MatchT::container_t::iterator iter_t;
+        typedef typename MatchT::container_t::value_type value_t;
+
+        using std::swap;
+        using boost::swap;
+        using BOOST_SPIRIT_CLASSIC_NS::swap;
+
+        // copying the tree nodes is expensive, since it may copy a whole
+        // tree.  swapping them is cheap, so swap the nodes we want into
+        // a new container of children, instead of saying
+        // m.trees.erase(m.trees.begin()) because, on a container_t that will 
+        // cause all the nodes afterwards to be copied into the previous 
+        // position.
+        container_t new_children;
+        std::size_t length = 0;
+        std::size_t tree_size = m.trees.size();
+
+        // the discard_first_node_d[] make no sense for nodes with no subnodes
+        BOOST_SPIRIT_ASSERT(tree_size >= 1);
+
+        if (tree_size > 1) {
+#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
+            new_children.reserve(tree_size - 1);
+#endif
+            iter_t i = m.trees.begin(), i_end = m.trees.end();
+            for (++i; i != i_end; ++i)
+            {
+                // adjust the length
+                length += std::distance((*i).value.begin(), (*i).value.end());
+
+                // move the child node
+                new_children.push_back(value_t());
+                swap(new_children.back(), *i);
+            }
+        }
+        else {
+        // if there was a tree and now there isn't any, insert an empty node
+            iter_t i = m.trees.begin(); 
+
+        // This isn't entirely correct, since the empty node will reference
+        // the end of the discarded node, but I currently don't see any way to 
+        // get at the begin of the node following this subnode.
+        // This should be safe anyway because the it shouldn't get dereferenced
+        // under any circumstances.
+            typedef typename value_t::parse_node_t::iterator_t iterator_type;
+            iterator_type it = (*i).value.end();
+            
+            new_children.push_back(
+                value_t(typename value_t::parse_node_t(it, it)));
+        }
+        
+        m = MatchT(length, new_children);
+    }
+};
+
+const node_parser_gen<discard_first_node_op> discard_first_node_d =
+    node_parser_gen<discard_first_node_op>();
+
+struct discard_last_node_op
+{
+    template <typename MatchT>
+    void operator()(MatchT& m) const
+    {
+        typedef typename MatchT::container_t container_t;
+        typedef typename MatchT::container_t::iterator iter_t;
+        typedef typename MatchT::container_t::value_type value_t;
+
+        using std::swap;
+        using boost::swap;
+        using BOOST_SPIRIT_CLASSIC_NS::swap;
+
+        // copying the tree nodes is expensive, since it may copy a whole
+        // tree.  swapping them is cheap, so swap the nodes we want into
+        // a new container of children, instead of saying
+        // m.trees.erase(m.trees.begin()) because, on a container_t that will 
+        // cause all the nodes afterwards to be copied into the previous 
+        // position.
+        container_t new_children;
+        std::size_t length = 0;
+        std::size_t tree_size = m.trees.size();
+
+        // the discard_last_node_d[] make no sense for nodes with no subnodes
+        BOOST_SPIRIT_ASSERT(tree_size >= 1);
+
+        if (tree_size > 1) {
+            m.trees.pop_back();
+#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
+            new_children.reserve(tree_size - 1);
+#endif            
+            iter_t i_end = m.trees.end();
+            for (iter_t i = m.trees.begin(); i != i_end; ++i)
+            {
+                // adjust the length
+                length += std::distance((*i).value.begin(), (*i).value.end());
+
+                // move the child node
+                new_children.push_back(value_t());
+                swap(new_children.back(), *i);
+            }
+        }
+        else {
+        // if there was a tree and now there isn't any, insert an empty node
+            iter_t i = m.trees.begin(); 
+
+            typedef typename value_t::parse_node_t::iterator_t iterator_type;
+            iterator_type it = (*i).value.begin();
+            
+            new_children.push_back(
+                value_t(typename value_t::parse_node_t(it, it)));
+        }
+        
+        m = MatchT(length, new_children);
+    }
+};
+
+const node_parser_gen<discard_last_node_op> discard_last_node_d =
+    node_parser_gen<discard_last_node_op>();
+
+struct inner_node_op
+{
+    template <typename MatchT>
+    void operator()(MatchT& m) const
+    {
+        typedef typename MatchT::container_t container_t;
+        typedef typename MatchT::container_t::iterator iter_t;
+        typedef typename MatchT::container_t::value_type value_t;
+
+        using std::swap;
+        using boost::swap;
+        using BOOST_SPIRIT_CLASSIC_NS::swap;
+
+        // copying the tree nodes is expensive, since it may copy a whole
+        // tree.  swapping them is cheap, so swap the nodes we want into
+        // a new container of children, instead of saying
+        // m.trees.erase(m.trees.begin()) because, on a container_t that will 
+        // cause all the nodes afterwards to be copied into the previous 
+        // position.
+        container_t new_children;
+        std::size_t length = 0;
+        std::size_t tree_size = m.trees.size();
+        
+        // the inner_node_d[] make no sense for nodes with less then 2 subnodes
+        BOOST_SPIRIT_ASSERT(tree_size >= 2);
+
+        if (tree_size > 2) {
+            m.trees.pop_back(); // erase the last element
+#if !defined(BOOST_SPIRIT_USE_LIST_FOR_TREES)
+            new_children.reserve(tree_size - 1);
+#endif
+            iter_t i = m.trees.begin(); // skip over the first element
+            iter_t i_end = m.trees.end();
+            for (++i; i != i_end; ++i)
+            {
+                // adjust the length
+                length += std::distance((*i).value.begin(), (*i).value.end());
+                
+                // move the child node
+                new_children.push_back(value_t());
+                swap(new_children.back(), *i);
+            }
+        }
+        else {
+        // if there was a tree and now there isn't any, insert an empty node
+            iter_t i = m.trees.begin(); // skip over the first element
+
+            typedef typename value_t::parse_node_t::iterator_t iterator_type;
+            iterator_type it = (*++i).value.begin();
+            
+            new_children.push_back(
+                value_t(typename value_t::parse_node_t(it, it)));
+        }
+        
+        m = MatchT(length, new_children);
+    }
+};
+
+const node_parser_gen<inner_node_op> inner_node_d =
+    node_parser_gen<inner_node_op>();
+
+
+//////////////////////////////////
+// action_directive_parser and action_directive_parser_gen
+// are meant to be used as a template to create directives that
+// generate action classes.  For example access_match and
+// access_node.  The ActionParserT template parameter must be
+// a class that has an innter class called action that is templated
+// on the parser type and the action type.
+template <typename ActionParserT>
+struct action_directive_parser_gen;
+
+template <typename T, typename ActionParserT>
+struct action_directive_parser
+:   public unary<T, parser<action_directive_parser<T, ActionParserT> > >
+{
+    typedef action_directive_parser<T, ActionParserT> self_t;
+    typedef action_directive_parser_gen<ActionParserT> parser_generator_t;
+    typedef unary_parser_category parser_category_t;
+
+    action_directive_parser(T const& a)
+        : unary<T, parser<action_directive_parser<T, ActionParserT> > >(a) {}
+
+    template <typename ScannerT>
+    struct result
+    {
+        typedef typename parser_result<T, ScannerT>::type type;
+    };
+
+    template <typename ScannerT>
+    typename parser_result<self_t, ScannerT>::type
+    parse(ScannerT const& scanner) const
+    {
+        return this->subject().parse(scanner);
+    }
+
+    template <typename ActionT>
+    typename ActionParserT::template action<action_directive_parser<T, ActionParserT>, ActionT>
+    operator[](ActionT const& actor) const
+    {
+        typedef typename
+            ActionParserT::template action<action_directive_parser, ActionT>
+            action_t;
+        return action_t(*this, actor);
+    }
+};
+
+//////////////////////////////////
+template <typename ActionParserT>
+struct action_directive_parser_gen
+{
+    template <typename T>
+    struct result {
+
+        typedef action_directive_parser<T, ActionParserT> type;
+    };
+
+    template <typename T>
+    static action_directive_parser<T, ActionParserT>
+    generate(parser<T> const& s)
+    {
+        return action_directive_parser<T, ActionParserT>(s.derived());
+    }
+
+    template <typename T>
+    action_directive_parser<T, ActionParserT>
+    operator[](parser<T> const& s) const
+    {
+        return action_directive_parser<T, ActionParserT>(s.derived());
+    }
+};
+
+//////////////////////////////////
+// Calls the attached action passing it the match from the parser
+// and the first and last iterators.
+// The inner template class is used to simulate template-template parameters
+// (declared in common_fwd.hpp).
+template <typename ParserT, typename ActionT>
+struct access_match_action::action
+:   public unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > >
+{
+    typedef action_parser_category parser_category;
+    typedef action<ParserT, ActionT> self_t;
+    
+    template <typename ScannerT>
+    struct result
+    {
+        typedef typename parser_result<ParserT, ScannerT>::type type;
+    };
+
+    action( ParserT const& subject,
+            ActionT const& actor_);
+
+    template <typename ScannerT>
+    typename parser_result<self_t, ScannerT>::type
+    parse(ScannerT const& scanner) const;
+
+    ActionT const &predicate() const;
+
+    private:
+    ActionT actor;
+};
+
+//////////////////////////////////
+template <typename ParserT, typename ActionT>
+access_match_action::action<ParserT, ActionT>::action(
+    ParserT const& subject,
+    ActionT const& actor_)
+: unary<ParserT, parser<access_match_action::action<ParserT, ActionT> > >(subject)
+, actor(actor_)
+{}
+
+//////////////////////////////////
+template <typename ParserT, typename ActionT>
+template <typename ScannerT>
+typename parser_result<access_match_action::action<ParserT, ActionT>, ScannerT>::type
+access_match_action::action<ParserT, ActionT>::
+parse(ScannerT const& scan) const
+{
+    typedef typename ScannerT::iterator_t iterator_t;
+    typedef typename parser_result<self_t, ScannerT>::type result_t;
+    if (!scan.at_end())
+    {
+        iterator_t save = scan.first;
+        result_t hit = this->subject().parse(scan);
+        actor(hit, save, scan.first);
+        return hit;
+    }
+    return scan.no_match();
+}
+
+//////////////////////////////////
+template <typename ParserT, typename ActionT>
+ActionT const &access_match_action::action<ParserT, ActionT>::predicate() const
+{
+    return actor;
+}
+
+//////////////////////////////////
+const action_directive_parser_gen<access_match_action> access_match_d
+    = action_directive_parser_gen<access_match_action>();
+
+
+
+//////////////////////////////////
+// Calls the attached action passing it the node from the parser
+// and the first and last iterators
+// The inner template class is used to simulate template-template parameters
+// (declared in common_fwd.hpp).
+template <typename ParserT, typename ActionT>
+struct access_node_action::action
+:   public unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > >
+{
+    typedef action_parser_category parser_category;
+    typedef action<ParserT, ActionT> self_t;
+    
+    template <typename ScannerT>
+    struct result
+    {
+        typedef typename parser_result<ParserT, ScannerT>::type type;
+    };
+
+    action( ParserT const& subject,
+            ActionT const& actor_);
+
+    template <typename ScannerT>
+    typename parser_result<self_t, ScannerT>::type
+    parse(ScannerT const& scanner) const;
+
+    ActionT const &predicate() const;
+
+    private:
+    ActionT actor;
+};
+
+//////////////////////////////////
+template <typename ParserT, typename ActionT>
+access_node_action::action<ParserT, ActionT>::action(
+    ParserT const& subject,
+    ActionT const& actor_)
+: unary<ParserT, parser<access_node_action::action<ParserT, ActionT> > >(subject)
+, actor(actor_)
+{}
+
+//////////////////////////////////
+template <typename ParserT, typename ActionT>
+template <typename ScannerT>
+typename parser_result<access_node_action::action<ParserT, ActionT>, ScannerT>::type
+access_node_action::action<ParserT, ActionT>::
+parse(ScannerT const& scan) const
+{
+    typedef typename ScannerT::iterator_t iterator_t;
+    typedef typename parser_result<self_t, ScannerT>::type result_t;
+    if (!scan.at_end())
+    {
+        iterator_t save = scan.first;
+        result_t hit = this->subject().parse(scan);
+        if (hit && hit.trees.size() > 0)
+            actor(*hit.trees.begin(), save, scan.first);
+        return hit;
+    }
+    return scan.no_match();
+}
+
+//////////////////////////////////
+template <typename ParserT, typename ActionT>
+ActionT const &access_node_action::action<ParserT, ActionT>::predicate() const
+{
+    return actor;
+}
+
+//////////////////////////////////
+const action_directive_parser_gen<access_node_action> access_node_d
+    = action_directive_parser_gen<access_node_action>();
+
+
+
+//////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  tree_parse_info
+//
+//      Results returned by the tree parse functions:
+//
+//      stop:   points to the final parse position (i.e parsing
+//              processed the input up to this point).
+//
+//      match:  true if parsing is successful. This may be full:
+//              the parser consumed all the input, or partial:
+//              the parser consumed only a portion of the input.
+//
+//      full:   true when we have a full match (i.e the parser
+//              consumed all the input.
+//
+//      length: The number of characters consumed by the parser.
+//              This is valid only if we have a successful match
+//              (either partial or full). A negative value means
+//              that the match is unsucessful.
+//
+//     trees:   Contains the root node(s) of the tree.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <
+    typename IteratorT,
+    typename NodeFactoryT,
+    typename T
+>
+struct tree_parse_info 
+{
+    IteratorT   stop;
+    bool        match;
+    bool        full;
+    std::size_t length;
+    typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees;
+
+    tree_parse_info()
+        : stop()
+        , match(false)
+        , full(false)
+        , length(0)
+        , trees()
+    {}
+
+    template <typename IteratorT2>
+    tree_parse_info(tree_parse_info<IteratorT2> const& pi)
+        : stop(pi.stop)
+        , match(pi.match)
+        , full(pi.full)
+        , length(pi.length)
+        , trees()
+    {
+        using std::swap;
+        using boost::swap;
+        using BOOST_SPIRIT_CLASSIC_NS::swap;
+
+        // use auto_ptr like ownership for the trees data member
+        swap(trees, pi.trees);
+    }
+
+    tree_parse_info(
+        IteratorT   stop_,
+        bool        match_,
+        bool        full_,
+        std::size_t length_,
+        typename tree_match<IteratorT, NodeFactoryT, T>::container_t trees_)
+    :   stop(stop_)
+        , match(match_)
+        , full(full_)
+        , length(length_)
+        , trees()
+    {
+        using std::swap;
+        using boost::swap;
+        using BOOST_SPIRIT_CLASSIC_NS::swap;
+
+        // use auto_ptr like ownership for the trees data member
+        swap(trees, trees_);
+    }
+};
+
+BOOST_SPIRIT_CLASSIC_NAMESPACE_END
+
+}} // namespace BOOST_SPIRIT_CLASSIC_NS
+
+#endif
+