Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2002-2003 Joel de Guzman
|
Chris@16
|
3 Copyright (c) 2002-2003 Hartmut Kaiser
|
Chris@16
|
4 Copyright (c) 2003 Martin Wille
|
Chris@16
|
5 http://spirit.sourceforge.net/
|
Chris@16
|
6
|
Chris@16
|
7 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
9 =============================================================================*/
|
Chris@16
|
10 #if !defined(BOOST_SPIRIT_PARSER_TRAITS_HPP)
|
Chris@16
|
11 #define BOOST_SPIRIT_PARSER_TRAITS_HPP
|
Chris@16
|
12
|
Chris@16
|
13 #include <boost/type_traits/is_base_and_derived.hpp>
|
Chris@16
|
14 #include <boost/static_assert.hpp>
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/spirit/home/classic/namespace.hpp>
|
Chris@16
|
17 #include <boost/spirit/home/classic/core/parser.hpp>
|
Chris@16
|
18 #include <boost/spirit/home/classic/meta/impl/parser_traits.ipp>
|
Chris@16
|
19
|
Chris@16
|
20 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
21 namespace boost { namespace spirit {
|
Chris@16
|
22
|
Chris@16
|
23 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
Chris@16
|
24
|
Chris@16
|
25 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
26 //
|
Chris@16
|
27 // Parser traits templates
|
Chris@16
|
28 //
|
Chris@16
|
29 // Used to determine the type and several other characteristics of a given
|
Chris@16
|
30 // parser type.
|
Chris@16
|
31 //
|
Chris@16
|
32 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
33
|
Chris@16
|
34 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
35 //
|
Chris@16
|
36 // The is_parser traits template can be used to tell wether a given
|
Chris@16
|
37 // class is a parser.
|
Chris@16
|
38 //
|
Chris@16
|
39 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
40 template <typename T>
|
Chris@16
|
41 struct is_parser
|
Chris@16
|
42 {
|
Chris@16
|
43 BOOST_STATIC_CONSTANT(bool, value =
|
Chris@16
|
44 (::boost::is_base_and_derived<parser<T>, T>::value));
|
Chris@16
|
45
|
Chris@16
|
46 // [JDG 2/3/03] simplified implementation by
|
Chris@16
|
47 // using boost::is_base_and_derived
|
Chris@16
|
48 };
|
Chris@16
|
49
|
Chris@16
|
50 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
51 //
|
Chris@16
|
52 // The is_unary_composite traits template can be used to tell if a given
|
Chris@16
|
53 // parser is a unary parser as for instance kleene_star or optional.
|
Chris@16
|
54 //
|
Chris@16
|
55 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
56 template <typename UnaryT>
|
Chris@16
|
57 struct is_unary_composite {
|
Chris@16
|
58
|
Chris@16
|
59 BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible<
|
Chris@16
|
60 typename UnaryT::parser_category_t, unary_parser_category>::value));
|
Chris@16
|
61 };
|
Chris@16
|
62
|
Chris@16
|
63 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
64 //
|
Chris@16
|
65 // The is_acction_parser traits template can be used to tell if a given
|
Chris@16
|
66 // parser is a action parser, i.e. it is a composite consisting of a
|
Chris@16
|
67 // auxilliary parser and an attached semantic action.
|
Chris@16
|
68 //
|
Chris@16
|
69 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
70 template <typename ActionT>
|
Chris@16
|
71 struct is_action_parser {
|
Chris@16
|
72
|
Chris@16
|
73 BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible<
|
Chris@16
|
74 typename ActionT::parser_category_t, action_parser_category>::value));
|
Chris@16
|
75 };
|
Chris@16
|
76
|
Chris@16
|
77 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
78 //
|
Chris@16
|
79 // The is_binary_composite traits template can be used to tell if a given
|
Chris@16
|
80 // parser is a binary parser as for instance sequence or difference.
|
Chris@16
|
81 //
|
Chris@16
|
82 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
83 template <typename BinaryT>
|
Chris@16
|
84 struct is_binary_composite {
|
Chris@16
|
85
|
Chris@16
|
86 BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible<
|
Chris@16
|
87 typename BinaryT::parser_category_t, binary_parser_category>::value));
|
Chris@16
|
88 };
|
Chris@16
|
89
|
Chris@16
|
90 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
91 //
|
Chris@16
|
92 // The is_composite_parser traits template can be used to tell if a given
|
Chris@16
|
93 // parser is a unary or a binary parser composite type.
|
Chris@16
|
94 //
|
Chris@16
|
95 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
96 template <typename CompositeT>
|
Chris@16
|
97 struct is_composite_parser {
|
Chris@16
|
98
|
Chris@16
|
99 BOOST_STATIC_CONSTANT(bool, value = (
|
Chris@16
|
100 ::BOOST_SPIRIT_CLASSIC_NS::is_unary_composite<CompositeT>::value ||
|
Chris@16
|
101 ::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite<CompositeT>::value));
|
Chris@16
|
102 };
|
Chris@16
|
103
|
Chris@16
|
104 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
105 template <typename ParserT>
|
Chris@16
|
106 struct is_alternative {
|
Chris@16
|
107
|
Chris@16
|
108 BOOST_STATIC_CONSTANT(bool, value = (
|
Chris@16
|
109 ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_alternative));
|
Chris@16
|
110 };
|
Chris@16
|
111
|
Chris@16
|
112 template <typename ParserT>
|
Chris@16
|
113 struct is_sequence {
|
Chris@16
|
114
|
Chris@16
|
115 BOOST_STATIC_CONSTANT(bool, value = (
|
Chris@16
|
116 ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_sequence));
|
Chris@16
|
117 };
|
Chris@16
|
118
|
Chris@16
|
119 template <typename ParserT>
|
Chris@16
|
120 struct is_sequential_or {
|
Chris@16
|
121
|
Chris@16
|
122 BOOST_STATIC_CONSTANT(bool, value = (
|
Chris@16
|
123 ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_sequential_or));
|
Chris@16
|
124 };
|
Chris@16
|
125
|
Chris@16
|
126 template <typename ParserT>
|
Chris@16
|
127 struct is_intersection {
|
Chris@16
|
128
|
Chris@16
|
129 BOOST_STATIC_CONSTANT(bool, value = (
|
Chris@16
|
130 ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_intersection));
|
Chris@16
|
131 };
|
Chris@16
|
132
|
Chris@16
|
133 template <typename ParserT>
|
Chris@16
|
134 struct is_difference {
|
Chris@16
|
135
|
Chris@16
|
136 BOOST_STATIC_CONSTANT(bool, value = (
|
Chris@16
|
137 ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_difference));
|
Chris@16
|
138 };
|
Chris@16
|
139
|
Chris@16
|
140 template <typename ParserT>
|
Chris@16
|
141 struct is_exclusive_or {
|
Chris@16
|
142
|
Chris@16
|
143 BOOST_STATIC_CONSTANT(bool, value = (
|
Chris@16
|
144 ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_exclusive_or));
|
Chris@16
|
145 };
|
Chris@16
|
146
|
Chris@16
|
147 template <typename ParserT>
|
Chris@16
|
148 struct is_optional {
|
Chris@16
|
149
|
Chris@16
|
150 BOOST_STATIC_CONSTANT(bool, value = (
|
Chris@16
|
151 ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_optional));
|
Chris@16
|
152 };
|
Chris@16
|
153
|
Chris@16
|
154 template <typename ParserT>
|
Chris@16
|
155 struct is_kleene_star {
|
Chris@16
|
156
|
Chris@16
|
157 BOOST_STATIC_CONSTANT(bool, value = (
|
Chris@16
|
158 ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_kleene_star));
|
Chris@16
|
159 };
|
Chris@16
|
160
|
Chris@16
|
161 template <typename ParserT>
|
Chris@16
|
162 struct is_positive {
|
Chris@16
|
163
|
Chris@16
|
164 BOOST_STATIC_CONSTANT(bool, value = (
|
Chris@16
|
165 ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits<ParserT>::is_positive));
|
Chris@16
|
166 };
|
Chris@16
|
167
|
Chris@16
|
168 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
169 //
|
Chris@16
|
170 // Parser extraction templates
|
Chris@16
|
171 //
|
Chris@16
|
172 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
173
|
Chris@16
|
174 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
175 //
|
Chris@16
|
176 // The unary_subject template can be used to return the type of the
|
Chris@16
|
177 // parser used as the subject of an unary parser.
|
Chris@16
|
178 // If the parser under inspection is not an unary type parser the compilation
|
Chris@16
|
179 // will fail.
|
Chris@16
|
180 //
|
Chris@16
|
181 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
182 template <typename UnaryT>
|
Chris@16
|
183 struct unary_subject {
|
Chris@16
|
184
|
Chris@16
|
185 BOOST_STATIC_ASSERT(BOOST_SPIRIT_CLASSIC_NS::is_unary_composite<UnaryT>::value);
|
Chris@16
|
186 typedef typename UnaryT::subject_t type;
|
Chris@16
|
187 };
|
Chris@16
|
188
|
Chris@16
|
189 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
190 //
|
Chris@16
|
191 // The get_unary_subject template function returns the parser object, which
|
Chris@16
|
192 // is used as the subject of an unary parser.
|
Chris@16
|
193 // If the parser under inspection is not an unary type parser the compilation
|
Chris@16
|
194 // will fail.
|
Chris@16
|
195 //
|
Chris@16
|
196 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
197 template <typename UnaryT>
|
Chris@16
|
198 inline typename unary_subject<UnaryT>::type const &
|
Chris@16
|
199 get_unary_subject(UnaryT const &unary_)
|
Chris@16
|
200 {
|
Chris@16
|
201 BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_unary_composite<UnaryT>::value);
|
Chris@16
|
202 return unary_.subject();
|
Chris@16
|
203 }
|
Chris@16
|
204
|
Chris@16
|
205 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
206 //
|
Chris@16
|
207 // The binary_left_subject and binary_right_subject templates can be used to
|
Chris@16
|
208 // return the types of the parsers used as the left and right subject of an
|
Chris@16
|
209 // binary parser.
|
Chris@16
|
210 // If the parser under inspection is not a binary type parser the compilation
|
Chris@16
|
211 // will fail.
|
Chris@16
|
212 //
|
Chris@16
|
213 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
214 template <typename BinaryT>
|
Chris@16
|
215 struct binary_left_subject {
|
Chris@16
|
216
|
Chris@16
|
217 BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite<BinaryT>::value);
|
Chris@16
|
218 typedef typename BinaryT::left_t type;
|
Chris@16
|
219 };
|
Chris@16
|
220
|
Chris@16
|
221 template <typename BinaryT>
|
Chris@16
|
222 struct binary_right_subject {
|
Chris@16
|
223
|
Chris@16
|
224 BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite<BinaryT>::value);
|
Chris@16
|
225 typedef typename BinaryT::right_t type;
|
Chris@16
|
226 };
|
Chris@16
|
227
|
Chris@16
|
228 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
229 //
|
Chris@16
|
230 // The get_binary_left_subject and get_binary_right_subject template functions
|
Chris@16
|
231 // return the parser object, which is used as the left or right subject of a
|
Chris@16
|
232 // binary parser.
|
Chris@16
|
233 // If the parser under inspection is not a binary type parser the compilation
|
Chris@16
|
234 // will fail.
|
Chris@16
|
235 //
|
Chris@16
|
236 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
237 template <typename BinaryT>
|
Chris@16
|
238 inline typename binary_left_subject<BinaryT>::type const &
|
Chris@16
|
239 get_binary_left_subject(BinaryT const &binary_)
|
Chris@16
|
240 {
|
Chris@16
|
241 BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite<BinaryT>::value);
|
Chris@16
|
242 return binary_.left();
|
Chris@16
|
243 }
|
Chris@16
|
244
|
Chris@16
|
245 template <typename BinaryT>
|
Chris@16
|
246 inline typename binary_right_subject<BinaryT>::type const &
|
Chris@16
|
247 get_binary_right_subject(BinaryT const &binary_)
|
Chris@16
|
248 {
|
Chris@16
|
249 BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite<BinaryT>::value);
|
Chris@16
|
250 return binary_.right();
|
Chris@16
|
251 }
|
Chris@16
|
252
|
Chris@16
|
253 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
254 //
|
Chris@16
|
255 // The action_subject template can be used to return the type of the
|
Chris@16
|
256 // parser used as the subject of an action parser.
|
Chris@16
|
257 // If the parser under inspection is not an action type parser the compilation
|
Chris@16
|
258 // will fail.
|
Chris@16
|
259 //
|
Chris@16
|
260 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
261 template <typename ActionT>
|
Chris@16
|
262 struct action_subject {
|
Chris@16
|
263
|
Chris@16
|
264 BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_action_parser<ActionT>::value);
|
Chris@16
|
265 typedef typename ActionT::subject_t type;
|
Chris@16
|
266 };
|
Chris@16
|
267
|
Chris@16
|
268 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
269 //
|
Chris@16
|
270 // The get_action_subject template function returns the parser object, which
|
Chris@16
|
271 // is used as the subject of an action parser.
|
Chris@16
|
272 // If the parser under inspection is not an action type parser the compilation
|
Chris@16
|
273 // will fail.
|
Chris@16
|
274 //
|
Chris@16
|
275 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
276 template <typename ActionT>
|
Chris@16
|
277 inline typename action_subject<ActionT>::type const &
|
Chris@16
|
278 get_action_subject(ActionT const &action_)
|
Chris@16
|
279 {
|
Chris@16
|
280 BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_action_parser<ActionT>::value);
|
Chris@16
|
281 return action_.subject();
|
Chris@16
|
282 }
|
Chris@16
|
283
|
Chris@16
|
284 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
285 //
|
Chris@16
|
286 // The semantic_action template can be used to return the type of the
|
Chris@16
|
287 // attached semantic action of an action parser.
|
Chris@16
|
288 // If the parser under inspection is not an action type parser the compilation
|
Chris@16
|
289 // will fail.
|
Chris@16
|
290 //
|
Chris@16
|
291 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
292 template <typename ActionT>
|
Chris@16
|
293 struct semantic_action {
|
Chris@16
|
294
|
Chris@16
|
295 BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_action_parser<ActionT>::value);
|
Chris@16
|
296 typedef typename ActionT::predicate_t type;
|
Chris@16
|
297 };
|
Chris@16
|
298
|
Chris@16
|
299 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
300 //
|
Chris@16
|
301 // The get_semantic_action template function returns the attached semantic
|
Chris@16
|
302 // action of an action parser.
|
Chris@16
|
303 // If the parser under inspection is not an action type parser the compilation
|
Chris@16
|
304 // will fail.
|
Chris@16
|
305 //
|
Chris@16
|
306 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
307 template <typename ActionT>
|
Chris@16
|
308 inline typename semantic_action<ActionT>::type const &
|
Chris@16
|
309 get_semantic_action(ActionT const &action_)
|
Chris@16
|
310 {
|
Chris@16
|
311 BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_action_parser<ActionT>::value);
|
Chris@16
|
312 return action_.predicate();
|
Chris@16
|
313 }
|
Chris@16
|
314
|
Chris@16
|
315 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
316 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
Chris@16
|
317
|
Chris@16
|
318 }} // namespace BOOST_SPIRIT_CLASSIC_NS
|
Chris@16
|
319
|
Chris@16
|
320 #endif // !defined(BOOST_SPIRIT_PARSER_TRAITS_HPP)
|