source: NonGTP/Boost/boost/spirit/core/non_terminal/subrule.hpp @ 857

Revision 857, 10.1 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Copyright (c) 2002-2003 Joel de Guzman
3    Copyright (c) 2002-2003 Hartmut Kaiser
4    http://spirit.sourceforge.net/
5
6    Use, modification and distribution is subject to the Boost Software
7    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8    http://www.boost.org/LICENSE_1_0.txt)
9=============================================================================*/
10#if !defined(BOOST_SPIRIT_SUBRULE_HPP)
11#define BOOST_SPIRIT_SUBRULE_HPP
12
13#include <boost/config.hpp>
14#include <boost/static_assert.hpp>
15
16#include <boost/spirit/core/parser.hpp>
17#include <boost/spirit/core/non_terminal/parser_context.hpp>
18#include <boost/spirit/core/non_terminal/impl/subrule.ipp>
19
20namespace boost { namespace spirit {
21
22    ///////////////////////////////////////////////////////////////////////////
23    //
24    //  subrules_scanner class
25    //
26    ///////////////////////////////////////////////////////////////////////////
27    template <typename ScannerT, typename ListT>
28    struct subrules_scanner : public ScannerT
29    {
30        typedef ScannerT                            scanner_t;
31        typedef ListT                               list_t;
32        typedef subrules_scanner<ScannerT, ListT>   self_t;
33
34        subrules_scanner(ScannerT const& scan, ListT const& list_)
35        : ScannerT(scan), list(list_) {}
36
37        template <typename PoliciesT>
38        struct rebind_policies
39        {
40            typedef typename rebind_scanner_policies<ScannerT, PoliciesT>::type
41                rebind_scanner;
42            typedef subrules_scanner<rebind_scanner, ListT> type;
43        };
44
45        template <typename PoliciesT>
46        subrules_scanner<
47            typename rebind_scanner_policies<ScannerT, PoliciesT>::type,
48            ListT>
49        change_policies(PoliciesT const& policies) const
50        {
51            typedef subrules_scanner<
52                BOOST_DEDUCED_TYPENAME
53                    rebind_scanner_policies<ScannerT, PoliciesT>::type,
54                ListT>
55            subrules_scanner_t;
56
57            return subrules_scanner_t(
58                    ScannerT::change_policies(policies),
59                    list);
60        }
61
62        template <typename IteratorT>
63        struct rebind_iterator
64        {
65            typedef typename rebind_scanner_iterator<ScannerT, IteratorT>::type
66                rebind_scanner;
67            typedef subrules_scanner<rebind_scanner, ListT> type;
68        };
69
70        template <typename IteratorT>
71        subrules_scanner<
72            typename rebind_scanner_iterator<ScannerT, IteratorT>::type,
73            ListT>
74        change_iterator(IteratorT const& first, IteratorT const &last) const
75        {
76            typedef subrules_scanner<
77                BOOST_DEDUCED_TYPENAME
78                    rebind_scanner_iterator<ScannerT, IteratorT>::type,
79                ListT>
80            subrules_scanner_t;
81
82            return subrules_scanner_t(
83                    ScannerT::change_iterator(first, last),
84                    list);
85        }
86
87        ListT const& list;
88    };
89
90    ///////////////////////////////////////////////////////////////////////////
91    //
92    //  subrule_scanner type computer class
93    //
94    //      This computer ensures that the scanner will not be recursively
95    //      instantiated if it's not needed.
96    //
97    ///////////////////////////////////////////////////////////////////////////
98    template <typename ScannerT, typename ListT>
99    struct subrules_scanner_finder
100    {
101          typedef subrules_scanner<ScannerT, ListT> type;
102    };
103
104    template <typename ScannerT, typename ListT>
105    struct subrules_scanner_finder<subrules_scanner<ScannerT, ListT>, ListT>
106    {
107          typedef subrules_scanner<ScannerT, ListT> type;
108    };
109
110    ///////////////////////////////////////////////////////////////////////////
111    //
112    //  subrule_list class
113    //
114    ///////////////////////////////////////////////////////////////////////////
115    template <typename FirstT, typename RestT>
116    struct subrule_list : public parser<subrule_list<FirstT, RestT> >
117    {
118        typedef subrule_list<FirstT, RestT> self_t;
119        typedef FirstT                      first_t;
120        typedef RestT                       rest_t;
121
122        subrule_list(FirstT const& first_, RestT const& rest_)
123        : first(first_), rest(rest_) {}
124
125        template <typename ScannerT>
126        struct result
127        {
128            typedef typename parser_result<FirstT, ScannerT>::type type;
129        };
130
131        template <typename ScannerT>
132        typename parser_result<self_t, ScannerT>::type
133        parse(ScannerT const& scan) const
134        {
135            typedef typename subrules_scanner_finder<ScannerT, self_t>::type
136            subrules_scanner_t;
137            subrules_scanner_t g_arg(scan, *this);
138            return first.start.parse(g_arg);
139        }
140
141        template <int ID, typename DefT, typename ContextT>
142        subrule_list<
143            FirstT,
144            subrule_list<
145                subrule_parser<ID, DefT, ContextT>,
146                RestT> >
147        operator,(subrule_parser<ID, DefT, ContextT> const& rhs)
148        {
149            return subrule_list<
150                FirstT,
151                subrule_list<
152                    subrule_parser<ID, DefT, ContextT>,
153                    RestT> >(
154                        first,
155                        subrule_list<
156                            subrule_parser<ID, DefT, ContextT>,
157                            RestT>(rhs, rest));
158        }
159
160        FirstT first;
161        RestT rest;
162    };
163
164    ///////////////////////////////////////////////////////////////////////////
165    //
166    //  subrule_parser class
167    //
168    ///////////////////////////////////////////////////////////////////////////
169    template <int ID, typename ContextT = parser_context<> >
170    struct subrule; // Forward declaration
171
172    template <int ID, typename DefT, typename ContextT>
173    struct subrule_parser
174    : public parser<subrule_parser<ID, DefT, ContextT> >
175    {
176        typedef subrule_parser<ID, DefT, ContextT> self_t;
177        typedef subrule<ID, ContextT> subrule_t;
178        typedef DefT def_t;
179
180        BOOST_STATIC_CONSTANT(int, id = ID);
181
182        template <typename ScannerT>
183        struct result
184        {
185            typedef typename
186                impl::get_subrule_parser_result<
187                    DefT, ScannerT, typename subrule_t::attr_t>::type type;
188        };
189
190        subrule_parser(subrule_t const& start_, DefT const& rhs_)
191        : rhs(rhs_), start(start_) {}
192
193        template <typename ScannerT>
194        typename parser_result<self_t, ScannerT>::type
195        parse(ScannerT const& scan) const
196        {
197            // This will only be called when parsing single subrules.
198            typedef subrule_list<self_t, nil_t> list_t;
199            typedef subrules_scanner<ScannerT, list_t> scanner_t;
200
201            list_t    list(*this, nil_t());
202            scanner_t g_arg(scan, list);
203            return start.parse(g_arg);
204        }
205
206        template <int ID2, typename DefT2, typename ContextT2>
207        inline subrule_list<
208            self_t,
209            subrule_list<
210                subrule_parser<ID2, DefT2, ContextT2>,
211                nil_t> >
212        operator,(subrule_parser<ID2, DefT2, ContextT2> const& rhs) const
213        {
214            return subrule_list<
215                self_t,
216                subrule_list<
217                    subrule_parser<ID2, DefT2, ContextT2>,
218                    nil_t> >(
219                        *this,
220                        subrule_list<
221                            subrule_parser<ID2, DefT2, ContextT2>, nil_t>(
222                                rhs, nil_t()));
223        }
224
225        typename DefT::embed_t rhs;
226        subrule_t const& start;
227    };
228
229    ///////////////////////////////////////////////////////////////////////////
230    //
231    //  subrule class
232    //
233    ///////////////////////////////////////////////////////////////////////////
234    template <int ID, typename ContextT>
235    struct subrule
236        : public parser<subrule<ID, ContextT> >
237        , public ContextT::base_t
238        , public context_aux<ContextT, subrule<ID, ContextT> >
239    {
240        typedef subrule<ID, ContextT> self_t;
241        typedef subrule<ID, ContextT> const&  embed_t;
242
243        typedef typename ContextT::context_linker_t context_t;
244        typedef typename context_t::attr_t attr_t;
245
246        BOOST_STATIC_CONSTANT(int, id = ID);
247
248        template <typename ScannerT>
249        struct result
250        {
251            typedef typename
252                impl::get_subrule_result<ID, ScannerT, attr_t>::type type;
253        };
254
255        template <typename ScannerT>
256        typename parser_result<self_t, ScannerT>::type
257        parse_main(ScannerT const& scan) const
258        {
259            typedef typename parser_result<self_t, ScannerT>::type result_t;
260            result_t result;
261            impl::parse_subrule<result_t, ScannerT, ID>::
262                do_(result, scan);
263            return result;
264        }
265
266        template <typename ScannerT>
267        typename parser_result<self_t, ScannerT>::type
268        parse(ScannerT const& scan) const
269        {
270            typedef typename parser_result<self_t, ScannerT>::type result_t;
271            typedef parser_scanner_linker<ScannerT> scanner_t;
272            BOOST_SPIRIT_CONTEXT_PARSE(
273                scan, *this, scanner_t, context_t, result_t);
274        }
275
276        template <typename DefT>
277        subrule_parser<ID, DefT, ContextT>
278        operator=(parser<DefT> const& rhs) const
279        {
280            return subrule_parser<ID, DefT, ContextT>(*this, rhs.derived());
281        }
282
283    private:
284
285        //  assignment of subrules is not allowed. Use subrules
286        //  with identical IDs if you want to have aliases.
287
288        subrule& operator=(subrule const&);
289
290        template <int ID2, typename ContextT2>
291        subrule& operator=(subrule<ID2, ContextT2> const&);
292    };
293
294}} // namespace boost::spirit
295
296#endif
297
Note: See TracBrowser for help on using the repository browser.