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