PageRenderTime 101ms CodeModel.GetById 2ms app.highlight 88ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/spirit/home/classic/tree/common.hpp

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