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