source: NonGTP/Boost/boost/spirit/tree/parse_tree.hpp @ 857

Revision 857, 8.2 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Copyright (c) 2001-2003 Daniel Nuffer
3    http://spirit.sourceforge.net/
4
5    Use, modification and distribution is subject to the Boost Software
6    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7    http://www.boost.org/LICENSE_1_0.txt)
8=============================================================================*/
9#ifndef BOOST_SPIRIT_TREE_PARSE_TREE_HPP
10#define BOOST_SPIRIT_TREE_PARSE_TREE_HPP
11
12#include <boost/spirit/tree/common.hpp>
13#include <boost/spirit/core/scanner/scanner.hpp>
14
15///////////////////////////////////////////////////////////////////////////////
16namespace boost { namespace spirit {
17
18template <typename MatchPolicyT, typename NodeFactoryT>
19struct pt_tree_policy;
20
21//////////////////////////////////
22// pt_match_policy is simply an id so the correct specialization of tree_policy can be found.
23template <
24    typename IteratorT,
25    typename NodeFactoryT = node_val_data_factory<nil_t>
26>
27struct pt_match_policy :
28    public common_tree_match_policy<
29        pt_match_policy<IteratorT, NodeFactoryT>,
30        IteratorT,
31        NodeFactoryT,
32        pt_tree_policy<
33            pt_match_policy<IteratorT, NodeFactoryT>,
34            NodeFactoryT
35        >
36    >
37{
38};
39
40//////////////////////////////////
41template <typename MatchPolicyT, typename NodeFactoryT>
42struct pt_tree_policy :
43    public common_tree_tree_policy<MatchPolicyT, NodeFactoryT>
44{
45    typedef
46        typename common_tree_tree_policy<MatchPolicyT, NodeFactoryT>::match_t
47        match_t;
48    typedef typename MatchPolicyT::iterator_t iterator_t;
49
50    static void concat(match_t& a, match_t const& b)
51    {
52        typedef typename match_t::attr_t attr_t;
53        BOOST_SPIRIT_ASSERT(a && b);
54
55        std::copy(b.trees.begin(), b.trees.end(),
56            std::back_insert_iterator<typename match_t::container_t>(a.trees));
57    }
58
59    template <typename MatchT, typename Iterator1T, typename Iterator2T>
60    static void group_match(MatchT& m, parser_id const& id,
61            Iterator1T const& first, Iterator2T const& last)
62    {
63        if (!m)
64            return;
65
66        typedef typename NodeFactoryT::template factory<iterator_t> factory_t;
67        typedef typename tree_match<iterator_t, NodeFactoryT>::container_t
68            container_t;
69        typedef typename container_t::iterator cont_iterator_t;
70
71        match_t newmatch(m.length(),
72                factory_t::create_node(first, last, false));
73
74        std::swap(newmatch.trees.begin()->children, m.trees);
75        // set this node and all it's unset children's rule_id
76        newmatch.trees.begin()->value.id(id);
77        for (cont_iterator_t i = newmatch.trees.begin()->children.begin();
78                i != newmatch.trees.begin()->children.end();
79                ++i)
80        {
81            if (i->value.id() == 0)
82                i->value.id(id);
83        }
84        m = newmatch;
85    }
86
87    template <typename FunctorT>
88    static void apply_op_to_match(FunctorT const& op, match_t& m)
89    {
90        op(m);
91    }
92};
93
94namespace impl {
95
96    template <typename IteratorT, typename NodeFactoryT>
97    struct tree_policy_selector<pt_match_policy<IteratorT, NodeFactoryT> >
98    {
99        typedef pt_tree_policy<
100            pt_match_policy<IteratorT, NodeFactoryT>, NodeFactoryT> type;
101    };
102
103} // namespace impl
104
105
106//////////////////////////////////
107struct gen_pt_node_parser_gen;
108
109template <typename T>
110struct gen_pt_node_parser
111:   public unary<T, parser<gen_pt_node_parser<T> > >
112{
113    typedef gen_pt_node_parser<T> self_t;
114    typedef gen_pt_node_parser_gen parser_generator_t;
115    typedef unary_parser_category parser_category_t;
116//    typedef gen_pt_node_parser<T> const &embed_t;
117
118    gen_pt_node_parser(T const& a)
119    : unary<T, parser<gen_pt_node_parser<T> > >(a) {}
120
121    template <typename ScannerT>
122    typename parser_result<self_t, ScannerT>::type
123    parse(ScannerT const& scan) const
124    {
125        typedef typename ScannerT::iteration_policy_t iteration_policy_t;
126        typedef typename ScannerT::match_policy_t::iterator_t iterator_t;
127        typedef typename ScannerT::match_policy_t::factory_t factory_t;
128        typedef pt_match_policy<iterator_t, factory_t> match_policy_t;
129        typedef typename ScannerT::action_policy_t action_policy_t;
130        typedef scanner_policies<
131            iteration_policy_t,
132            match_policy_t,
133            action_policy_t
134        > policies_t;
135
136        return this->subject().parse(scan.change_policies(policies_t(scan)));
137    }
138};
139
140//////////////////////////////////
141struct gen_pt_node_parser_gen
142{
143    template <typename T>
144    struct result {
145
146        typedef gen_pt_node_parser<T> type;
147    };
148
149    template <typename T>
150    static gen_pt_node_parser<T>
151    generate(parser<T> const& s)
152    {
153        return gen_pt_node_parser<T>(s.derived());
154    }
155
156    template <typename T>
157    gen_pt_node_parser<T>
158    operator[](parser<T> const& s) const
159    {
160        return gen_pt_node_parser<T>(s.derived());
161    }
162};
163
164//////////////////////////////////
165const gen_pt_node_parser_gen gen_pt_node_d = gen_pt_node_parser_gen();
166
167
168///////////////////////////////////////////////////////////////////////////////
169//
170//  Parse functions for parse trees
171//
172///////////////////////////////////////////////////////////////////////////////
173template <
174    typename NodeFactoryT, typename IteratorT, typename ParserT,
175    typename SkipT
176>
177inline tree_parse_info<IteratorT, NodeFactoryT>
178pt_parse(
179    IteratorT const&        first_,
180    IteratorT const&        last,
181    parser<ParserT> const&  p,
182    SkipT const&            skip,
183    NodeFactoryT const&   /*dummy_*/ = NodeFactoryT())
184{
185    typedef skip_parser_iteration_policy<SkipT> iter_policy_t;
186    typedef pt_match_policy<IteratorT, NodeFactoryT> pt_match_policy_t;
187    typedef
188        scanner_policies<iter_policy_t, pt_match_policy_t>
189        scanner_policies_t;
190    typedef scanner<IteratorT, scanner_policies_t> scanner_t;
191
192    iter_policy_t iter_policy(skip);
193    scanner_policies_t policies(iter_policy);
194    IteratorT first = first_;
195    scanner_t scan(first, last, policies);
196    tree_match<IteratorT, NodeFactoryT> hit = p.derived().parse(scan);
197    scan.skip(scan);
198    return tree_parse_info<IteratorT, NodeFactoryT>(
199        first, hit, hit && (first == last), hit.length(), hit.trees);
200}
201
202template <typename IteratorT, typename ParserT, typename SkipT>
203inline tree_parse_info<IteratorT>
204pt_parse(
205    IteratorT const&        first,
206    IteratorT const&        last,
207    parser<ParserT> const&  p,
208    SkipT const&            skip)
209{
210    typedef node_val_data_factory<nil_t> default_node_factory_t;
211    return pt_parse(first, last, p, skip, default_node_factory_t());
212}
213
214//////////////////////////////////
215template <typename IteratorT, typename ParserT>
216inline tree_parse_info<IteratorT>
217pt_parse(
218    IteratorT const&        first_,
219    IteratorT const&        last,
220    parser<ParserT> const&  parser)
221{
222    typedef pt_match_policy<IteratorT> pt_match_policy_t;
223    IteratorT first = first_;
224    scanner<
225        IteratorT,
226        scanner_policies<iteration_policy, pt_match_policy_t>
227    > scan(first, last);
228    tree_match<IteratorT> hit = parser.derived().parse(scan);
229    return tree_parse_info<IteratorT>(
230        first, hit, hit && (first == last), hit.length(), hit.trees);
231}
232
233//////////////////////////////////
234template <typename CharT, typename ParserT, typename SkipT>
235inline tree_parse_info<CharT const*>
236pt_parse(
237    CharT const*            str,
238    parser<ParserT> const&  p,
239    SkipT const&            skip)
240{
241    CharT const* last = str;
242    while (*last)
243        last++;
244    return pt_parse(str, last, p, skip);
245}
246
247//////////////////////////////////
248template <typename CharT, typename ParserT>
249inline tree_parse_info<CharT const*>
250pt_parse(
251    CharT const*            str,
252    parser<ParserT> const&  parser)
253{
254    CharT const* last = str;
255    while (*last)
256    {
257        last++;
258    }
259    return pt_parse(str, last, parser);
260}
261
262///////////////////////////////////////////////////////////////////////////////
263}} // namespace boost::spirit
264
265#endif
266
Note: See TracBrowser for help on using the repository browser.