PageRenderTime 157ms CodeModel.GetById 22ms app.highlight 124ms RepoModel.GetById 1ms app.codeStats 1ms

/src/contrib/boost/spirit/home/classic/tree/common.hpp

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