~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to boost/boost/spirit/tree/ast.hpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*=============================================================================
 
2
    Spirit v1.6.1
 
3
    Copyright (c) 2001-2003 Daniel Nuffer
 
4
    http://spirit.sourceforge.net/
 
5
 
 
6
    Permission to copy, use, modify, sell and distribute this software is
 
7
    granted provided this copyright notice appears in all copies. This
 
8
    software is provided "as is" without express or implied warranty, and
 
9
    with no claim as to its suitability for any purpose.
 
10
=============================================================================*/
 
11
#ifndef BOOST_SPIRIT_TREE_AST_HPP
 
12
#define BOOST_SPIRIT_TREE_AST_HPP
 
13
 
 
14
#include "boost/spirit/tree/common.hpp"
 
15
#include "boost/spirit/core/scanner/scanner.hpp"
 
16
 
 
17
///////////////////////////////////////////////////////////////////////////////
 
18
namespace boost { namespace spirit {
 
19
 
 
20
template <typename MatchPolicyT, typename NodeFactoryT>
 
21
struct ast_tree_policy;
 
22
 
 
23
//////////////////////////////////
 
24
//  ast_match_policy is simply an id so the correct specialization of
 
25
//  tree_policy can be found.
 
26
template <
 
27
    typename IteratorT,
 
28
    typename NodeFactoryT = node_val_data_factory<nil_t>
 
29
>
 
30
struct ast_match_policy :
 
31
    public common_tree_match_policy<
 
32
        ast_match_policy<IteratorT, NodeFactoryT>,
 
33
        IteratorT,
 
34
        NodeFactoryT,
 
35
        ast_tree_policy<
 
36
            ast_match_policy<IteratorT, NodeFactoryT>,
 
37
            NodeFactoryT
 
38
        >
 
39
    >
 
40
{
 
41
};
 
42
 
 
43
//////////////////////////////////
 
44
template <typename MatchPolicyT, typename NodeFactoryT>
 
45
struct ast_tree_policy :
 
46
    public common_tree_tree_policy<MatchPolicyT, NodeFactoryT>
 
47
{
 
48
    typedef
 
49
        typename common_tree_tree_policy<MatchPolicyT, NodeFactoryT>::match_t
 
50
        match_t;
 
51
    typedef typename MatchPolicyT::iterator_t iterator_t;
 
52
 
 
53
    static void concat(match_t& a, match_t const& b)
 
54
    {
 
55
        BOOST_SPIRIT_ASSERT(a && b);
 
56
 
 
57
#if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS_NODES & BOOST_SPIRIT_DEBUG_FLAGS_TREES)
 
58
        BOOST_SPIRIT_DEBUG_OUT << "concat. a = " << a <<
 
59
            "\n\tb = " << b << std::endl;
 
60
#endif
 
61
        typedef typename tree_match<iterator_t, NodeFactoryT>::container_t
 
62
            container_t;
 
63
 
 
64
        // test for size() is nessecary, because no_tree_gen_node leaves a.trees
 
65
        // and/or b.trees empty
 
66
        if (0 != b.trees.size() && b.trees.begin()->value.is_root())
 
67
        {
 
68
            BOOST_SPIRIT_ASSERT(b.trees.size() == 1);
 
69
 
 
70
            container_t tmp;
 
71
            std::swap(a.trees, tmp); // save a into tmp
 
72
            std::swap(b.trees, a.trees); // make b.trees[0] be new root (a.trees[0])
 
73
            container_t* pnon_root_trees = &a.trees;
 
74
            while (pnon_root_trees->size() > 0 &&
 
75
                    pnon_root_trees->begin()->value.is_root())
 
76
            {
 
77
                pnon_root_trees = & pnon_root_trees->begin()->children;
 
78
            }
 
79
            pnon_root_trees->insert(pnon_root_trees->begin(),
 
80
                    tmp.begin(), tmp.end());
 
81
        }
 
82
        else if (0 != a.trees.size() && a.trees.begin()->value.is_root())
 
83
        {
 
84
            BOOST_SPIRIT_ASSERT(a.trees.size() == 1);
 
85
            std::copy(b.trees.begin(),
 
86
                 b.trees.end(),
 
87
                 std::back_insert_iterator<container_t>(
 
88
                     a.trees.begin()->children));
 
89
        }
 
90
        else
 
91
        {
 
92
            std::copy(b.trees.begin(),
 
93
                 b.trees.end(),
 
94
                 std::back_insert_iterator<container_t>(a.trees));
 
95
        }
 
96
 
 
97
#if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS_NODES & BOOST_SPIRIT_DEBUG_FLAGS_TREES)
 
98
        BOOST_SPIRIT_DEBUG_OUT << "after concat. a = " << a << std::endl;
 
99
#endif
 
100
 
 
101
        return;
 
102
    }
 
103
 
 
104
    template <typename Iterator1T, typename Iterator2T>
 
105
    static void group_match(match_t& m, parser_id const& id,
 
106
            Iterator1T const& first, Iterator2T const& last)
 
107
    {
 
108
        if (!m)
 
109
            return;
 
110
 
 
111
        typedef typename tree_match<iterator_t, NodeFactoryT>::container_t
 
112
            container_t;
 
113
        typedef typename container_t::iterator cont_iterator_t;
 
114
        typedef typename NodeFactoryT::template factory<iterator_t> factory_t;
 
115
        // only one node, so don't make a new level
 
116
        if (m.trees.size() == 1)
 
117
        {
 
118
            // set rule_id's.  There may have been multiple nodes created.
 
119
            // Because of root_node[] they may be left-most children of the top
 
120
            // node.
 
121
            container_t* punset_id = &m.trees;
 
122
            while (punset_id->size() > 0 &&
 
123
                    punset_id->begin()->value.id() == 0)
 
124
            {
 
125
                punset_id->begin()->value.id(id);
 
126
                punset_id = &punset_id->begin()->children;
 
127
            }
 
128
 
 
129
            m.trees.begin()->value.is_root(false);
 
130
        }
 
131
        else
 
132
        {
 
133
            match_t newmatch(m.length(),
 
134
                factory_t::create_node(first, last, false));
 
135
 
 
136
            std::swap(newmatch.trees.begin()->children, m.trees);
 
137
            // set this node and all it's unset children's rule_id
 
138
            newmatch.trees.begin()->value.id(id);
 
139
            for (cont_iterator_t i = newmatch.trees.begin();
 
140
                 i != newmatch.trees.end();
 
141
                 ++i)
 
142
            {
 
143
                if (i->value.id() == 0)
 
144
                    i->value.id(id);
 
145
            }
 
146
            m = newmatch;
 
147
        }
 
148
    }
 
149
 
 
150
    template <typename FunctorT>
 
151
    static void apply_op_to_match(FunctorT const& op, match_t& m)
 
152
    {
 
153
        op(m);
 
154
    }
 
155
};
 
156
 
 
157
namespace impl {
 
158
 
 
159
    template <typename IteratorT, typename NodeFactoryT>
 
160
    struct tree_policy_selector<ast_match_policy<IteratorT, NodeFactoryT> >
 
161
    {
 
162
        typedef ast_tree_policy<
 
163
            ast_match_policy<IteratorT, NodeFactoryT>, NodeFactoryT> type;
 
164
    };
 
165
 
 
166
} // namespace impl
 
167
 
 
168
 
 
169
//////////////////////////////////
 
170
struct gen_ast_node_parser_gen;
 
171
 
 
172
template <typename T>
 
173
struct gen_ast_node_parser
 
174
:   public unary<T, parser<gen_ast_node_parser<T> > >
 
175
{
 
176
    typedef gen_ast_node_parser<T> self_t;
 
177
    typedef gen_ast_node_parser_gen parser_generator_t;
 
178
    typedef unary_parser_category parser_category_t;
 
179
//    typedef gen_ast_node_parser<T> const &embed_t;
 
180
 
 
181
    gen_ast_node_parser(T const& a)
 
182
    : unary<T, parser<gen_ast_node_parser<T> > >(a) {}
 
183
 
 
184
    template <typename ScannerT>
 
185
    typename parser_result<self_t, ScannerT>::type
 
186
    parse(ScannerT const& scan) const
 
187
    {
 
188
        typedef typename ScannerT::iteration_policy_t iteration_policy_t;
 
189
        typedef typename ScannerT::match_policy_t::iterator_t iterator_t;
 
190
        typedef typename ScannerT::match_policy_t::factory_t factory_t;
 
191
        typedef ast_match_policy<iterator_t, factory_t> match_policy_t;
 
192
        typedef typename ScannerT::action_policy_t action_policy_t;
 
193
        typedef scanner_policies<
 
194
            iteration_policy_t,
 
195
            match_policy_t,
 
196
            action_policy_t
 
197
        > policies_t;
 
198
 
 
199
        return this->subject().parse(scan.change_policies(policies_t()));
 
200
    }
 
201
};
 
202
 
 
203
//////////////////////////////////
 
204
struct gen_ast_node_parser_gen
 
205
{
 
206
    template <typename T>
 
207
    struct result {
 
208
 
 
209
        typedef gen_ast_node_parser<T> type;
 
210
    };
 
211
 
 
212
    template <typename T>
 
213
    static gen_ast_node_parser<T>
 
214
    generate(parser<T> const& s)
 
215
    {
 
216
        return gen_ast_node_parser<T>(s.derived());
 
217
    }
 
218
 
 
219
    template <typename T>
 
220
    gen_ast_node_parser<T>
 
221
    operator[](parser<T> const& s) const
 
222
    {
 
223
        return gen_ast_node_parser<T>(s.derived());
 
224
    }
 
225
};
 
226
 
 
227
//////////////////////////////////
 
228
const gen_ast_node_parser_gen gen_ast_node_d = gen_ast_node_parser_gen();
 
229
 
 
230
 
 
231
//////////////////////////////////
 
232
struct root_node_op
 
233
{
 
234
    template <typename MatchT>
 
235
    void operator()(MatchT& m) const
 
236
    {
 
237
        BOOST_SPIRIT_ASSERT(m.trees.size() > 0);
 
238
        m.trees.begin()->value.is_root(true);
 
239
    }
 
240
};
 
241
 
 
242
const node_parser_gen<root_node_op> root_node_d =
 
243
    node_parser_gen<root_node_op>();
 
244
 
 
245
///////////////////////////////////////////////////////////////////////////////
 
246
//
 
247
//  Parse functions for ASTs
 
248
//
 
249
///////////////////////////////////////////////////////////////////////////////
 
250
template <
 
251
    typename AstFactoryT, typename IteratorT, typename ParserT, 
 
252
    typename SkipT
 
253
>
 
254
inline tree_parse_info<IteratorT, AstFactoryT>
 
255
ast_parse(
 
256
    IteratorT const&        first_,
 
257
    IteratorT const&        last_,
 
258
    parser<ParserT> const&  parser,
 
259
    SkipT const&            skip_,
 
260
    AstFactoryT const &     dummy_ = AstFactoryT())
 
261
{
 
262
    typedef skip_parser_iteration_policy<SkipT> iter_policy_t;
 
263
    typedef ast_match_policy<IteratorT, AstFactoryT> ast_match_policy_t;
 
264
    typedef
 
265
        scanner_policies<iter_policy_t, ast_match_policy_t>
 
266
        scanner_policies_t;
 
267
    typedef scanner<IteratorT, scanner_policies_t> scanner_t;
 
268
 
 
269
    iter_policy_t iter_policy(skip_);
 
270
    scanner_policies_t policies(iter_policy);
 
271
    IteratorT first = first_;
 
272
    scanner_t scan(first, last_, policies);
 
273
    tree_match<IteratorT, AstFactoryT> hit = parser.derived().parse(scan);
 
274
    scan.skip(scan);
 
275
    return tree_parse_info<IteratorT, AstFactoryT>(
 
276
        first, hit, hit && (first == last_), hit.length(), hit.trees);
 
277
}
 
278
 
 
279
//////////////////////////////////
 
280
template <typename IteratorT, typename ParserT, typename SkipT>
 
281
inline tree_parse_info<IteratorT>
 
282
ast_parse(
 
283
    IteratorT const&        first_,
 
284
    IteratorT const&        last_,
 
285
    parser<ParserT> const&  parser,
 
286
    SkipT const&            skip_)
 
287
{
 
288
    typedef node_val_data_factory<nil_t> default_factory_t;
 
289
    return ast_parse(first_, last_, parser, skip_, default_factory_t());
 
290
}
 
291
  
 
292
//////////////////////////////////
 
293
template <typename IteratorT, typename ParserT>
 
294
inline tree_parse_info<IteratorT>
 
295
ast_parse(
 
296
    IteratorT const&        first_,
 
297
    IteratorT const&        last,
 
298
    parser<ParserT> const&  parser)
 
299
{
 
300
    IteratorT first = first_;
 
301
    scanner<
 
302
        IteratorT,
 
303
        scanner_policies<iteration_policy, ast_match_policy<IteratorT> >
 
304
    > scan(first, last);
 
305
    tree_match<IteratorT> hit = parser.derived().parse(scan);
 
306
    return tree_parse_info<IteratorT>(first, hit, hit && (first == last),
 
307
        hit.length(), hit.trees);
 
308
}
 
309
 
 
310
//////////////////////////////////
 
311
template <typename CharT, typename ParserT, typename SkipT>
 
312
inline tree_parse_info<CharT const*>
 
313
ast_parse(
 
314
    CharT const*            str,
 
315
    parser<ParserT> const&  parser,
 
316
    SkipT const&            skip)
 
317
{
 
318
    CharT const* last = str;
 
319
    while (*last)
 
320
        last++;
 
321
    return ast_parse(str, last, parser, skip);
 
322
}
 
323
 
 
324
//////////////////////////////////
 
325
template <typename CharT, typename ParserT>
 
326
inline tree_parse_info<CharT const*>
 
327
ast_parse(
 
328
    CharT const*            str,
 
329
    parser<ParserT> const&  parser)
 
330
{
 
331
    CharT const* last = str;
 
332
    while (*last)
 
333
    {
 
334
        last++;
 
335
    }
 
336
    return ast_parse(str, last, parser);
 
337
}
 
338
 
 
339
///////////////////////////////////////////////////////////////////////////////
 
340
}} // namespace boost::spirit
 
341
 
 
342
#endif
 
343