Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2001-2011 Joel de Guzman
|
Chris@16
|
3 Copyright (c) 2001-2011 Hartmut Kaiser
|
Chris@16
|
4 Copyright (c) 2010 Bryce Lelbach
|
Chris@16
|
5
|
Chris@16
|
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 ==============================================================================*/
|
Chris@16
|
9 #if !defined(BOOST_SPIRIT_CHAR_APRIL_16_2006_1051AM)
|
Chris@16
|
10 #define BOOST_SPIRIT_CHAR_APRIL_16_2006_1051AM
|
Chris@16
|
11
|
Chris@16
|
12 #if defined(_MSC_VER)
|
Chris@16
|
13 #pragma once
|
Chris@16
|
14 #endif
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/spirit/home/support/common_terminals.hpp>
|
Chris@16
|
17 #include <boost/spirit/home/support/string_traits.hpp>
|
Chris@16
|
18 #include <boost/spirit/home/support/info.hpp>
|
Chris@16
|
19 #include <boost/spirit/home/support/detail/get_encoding.hpp>
|
Chris@16
|
20 #include <boost/spirit/home/support/char_set/basic_chset.hpp>
|
Chris@16
|
21 #include <boost/spirit/home/qi/char/char_parser.hpp>
|
Chris@16
|
22 #include <boost/spirit/home/qi/char/char_class.hpp>
|
Chris@16
|
23 #include <boost/spirit/home/qi/meta_compiler.hpp>
|
Chris@16
|
24 #include <boost/spirit/home/qi/auxiliary/lazy.hpp>
|
Chris@16
|
25 #include <boost/spirit/home/qi/detail/enable_lit.hpp>
|
Chris@16
|
26 #include <boost/fusion/include/at.hpp>
|
Chris@16
|
27 #include <boost/mpl/if.hpp>
|
Chris@16
|
28 #include <boost/mpl/assert.hpp>
|
Chris@16
|
29 #include <boost/mpl/identity.hpp>
|
Chris@16
|
30 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
31 #include <boost/type_traits/remove_const.hpp>
|
Chris@16
|
32 #include <string>
|
Chris@16
|
33
|
Chris@16
|
34 #if defined(_MSC_VER)
|
Chris@16
|
35 #pragma once
|
Chris@16
|
36 #endif
|
Chris@16
|
37
|
Chris@16
|
38 namespace boost { namespace spirit
|
Chris@16
|
39 {
|
Chris@16
|
40 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
41 // Enablers
|
Chris@16
|
42 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
43 template <typename CharEncoding>
|
Chris@16
|
44 struct use_terminal<qi::domain
|
Chris@16
|
45 , terminal<
|
Chris@16
|
46 tag::char_code<tag::char_, CharEncoding> // enables char_
|
Chris@16
|
47 >
|
Chris@16
|
48 > : mpl::true_ {};
|
Chris@16
|
49
|
Chris@16
|
50 template <typename CharEncoding, typename A0>
|
Chris@16
|
51 struct use_terminal<qi::domain
|
Chris@16
|
52 , terminal_ex<
|
Chris@16
|
53 tag::char_code<tag::char_, CharEncoding> // enables char_('x'), char_("x")
|
Chris@16
|
54 , fusion::vector1<A0> // and char_("a-z0-9")
|
Chris@16
|
55 >
|
Chris@16
|
56 > : mpl::true_ {};
|
Chris@16
|
57
|
Chris@16
|
58 template <typename CharEncoding, typename A0, typename A1>
|
Chris@16
|
59 struct use_terminal<qi::domain
|
Chris@16
|
60 , terminal_ex<
|
Chris@16
|
61 tag::char_code<tag::char_, CharEncoding> // enables char_('a','z')
|
Chris@16
|
62 , fusion::vector2<A0, A1>
|
Chris@16
|
63 >
|
Chris@16
|
64 > : mpl::true_ {};
|
Chris@16
|
65
|
Chris@16
|
66 template <typename CharEncoding> // enables *lazy* char_('x'), char_("x")
|
Chris@16
|
67 struct use_lazy_terminal< // and char_("a-z0-9")
|
Chris@16
|
68 qi::domain
|
Chris@16
|
69 , tag::char_code<tag::char_, CharEncoding>
|
Chris@16
|
70 , 1 // arity
|
Chris@16
|
71 > : mpl::true_ {};
|
Chris@16
|
72
|
Chris@16
|
73 template <typename CharEncoding> // enables *lazy* char_('a','z')
|
Chris@16
|
74 struct use_lazy_terminal<
|
Chris@16
|
75 qi::domain
|
Chris@16
|
76 , tag::char_code<tag::char_, CharEncoding>
|
Chris@16
|
77 , 2 // arity
|
Chris@16
|
78 > : mpl::true_ {};
|
Chris@16
|
79
|
Chris@16
|
80 template <>
|
Chris@16
|
81 struct use_terminal<qi::domain, char> // enables 'x'
|
Chris@16
|
82 : mpl::true_ {};
|
Chris@16
|
83
|
Chris@16
|
84 template <>
|
Chris@16
|
85 struct use_terminal<qi::domain, char[2]> // enables "x"
|
Chris@16
|
86 : mpl::true_ {};
|
Chris@16
|
87
|
Chris@16
|
88 template <>
|
Chris@16
|
89 struct use_terminal<qi::domain, wchar_t> // enables wchar_t
|
Chris@16
|
90 : mpl::true_ {};
|
Chris@16
|
91
|
Chris@16
|
92 template <>
|
Chris@16
|
93 struct use_terminal<qi::domain, wchar_t[2]> // enables L"x"
|
Chris@16
|
94 : mpl::true_ {};
|
Chris@16
|
95
|
Chris@16
|
96 // enables lit(...)
|
Chris@16
|
97 template <typename A0>
|
Chris@16
|
98 struct use_terminal<qi::domain
|
Chris@16
|
99 , terminal_ex<tag::lit, fusion::vector1<A0> >
|
Chris@16
|
100 , typename enable_if<traits::is_char<A0> >::type>
|
Chris@16
|
101 : mpl::true_ {};
|
Chris@16
|
102 }}
|
Chris@16
|
103
|
Chris@16
|
104 namespace boost { namespace spirit { namespace qi
|
Chris@16
|
105 {
|
Chris@16
|
106 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
Chris@16
|
107 using spirit::lit; // lit('x') is equivalent to 'x'
|
Chris@16
|
108 #endif
|
Chris@16
|
109 using spirit::lit_type;
|
Chris@16
|
110
|
Chris@16
|
111 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
112 // Parser for a single character
|
Chris@16
|
113 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
114 template <typename CharEncoding, bool no_attribute, bool no_case = false>
|
Chris@16
|
115 struct literal_char
|
Chris@16
|
116 : char_parser<
|
Chris@16
|
117 literal_char<CharEncoding, no_attribute, false>
|
Chris@16
|
118 , typename CharEncoding::char_type
|
Chris@16
|
119 , typename mpl::if_c<no_attribute, unused_type
|
Chris@16
|
120 , typename CharEncoding::char_type>::type>
|
Chris@16
|
121 {
|
Chris@16
|
122 typedef typename CharEncoding::char_type char_type;
|
Chris@16
|
123 typedef CharEncoding char_encoding;
|
Chris@16
|
124
|
Chris@16
|
125 template <typename Char>
|
Chris@16
|
126 literal_char(Char ch_)
|
Chris@16
|
127 : ch(static_cast<char_type>(ch_)) {}
|
Chris@16
|
128
|
Chris@16
|
129 template <typename Context, typename Iterator>
|
Chris@16
|
130 struct attribute
|
Chris@16
|
131 {
|
Chris@16
|
132 typedef typename mpl::if_c<
|
Chris@16
|
133 no_attribute, unused_type, char_type>::type
|
Chris@16
|
134 type;
|
Chris@16
|
135 };
|
Chris@16
|
136
|
Chris@16
|
137 template <typename CharParam, typename Context>
|
Chris@16
|
138 bool test(CharParam ch_, Context&) const
|
Chris@16
|
139 {
|
Chris@16
|
140 return traits::ischar<CharParam, char_encoding>::call(ch_) &&
|
Chris@16
|
141 ch == char_type(ch_);
|
Chris@16
|
142 }
|
Chris@16
|
143
|
Chris@16
|
144 template <typename Context>
|
Chris@16
|
145 info what(Context& /*context*/) const
|
Chris@16
|
146 {
|
Chris@16
|
147 return info("literal-char", char_encoding::toucs4(ch));
|
Chris@16
|
148 }
|
Chris@16
|
149
|
Chris@16
|
150 char_type ch;
|
Chris@16
|
151 };
|
Chris@16
|
152
|
Chris@16
|
153 template <typename CharEncoding, bool no_attribute>
|
Chris@16
|
154 struct literal_char<CharEncoding, no_attribute, true> // case insensitive
|
Chris@16
|
155 : char_parser<
|
Chris@16
|
156 literal_char<CharEncoding, no_attribute, true>
|
Chris@16
|
157 , typename mpl::if_c<no_attribute, unused_type
|
Chris@16
|
158 , typename CharEncoding::char_type>::type>
|
Chris@16
|
159 {
|
Chris@16
|
160 typedef typename CharEncoding::char_type char_type;
|
Chris@16
|
161 typedef CharEncoding char_encoding;
|
Chris@16
|
162
|
Chris@16
|
163 literal_char(char_type ch)
|
Chris@16
|
164 : lo(static_cast<char_type>(char_encoding::tolower(ch)))
|
Chris@16
|
165 , hi(static_cast<char_type>(char_encoding::toupper(ch))) {}
|
Chris@16
|
166
|
Chris@16
|
167 template <typename Context, typename Iterator>
|
Chris@16
|
168 struct attribute
|
Chris@16
|
169 {
|
Chris@16
|
170 typedef typename mpl::if_c<
|
Chris@16
|
171 no_attribute, unused_type, char_type>::type
|
Chris@16
|
172 type;
|
Chris@16
|
173 };
|
Chris@16
|
174
|
Chris@16
|
175 template <typename CharParam, typename Context>
|
Chris@16
|
176 bool test(CharParam ch_, Context&) const
|
Chris@16
|
177 {
|
Chris@16
|
178 if (!traits::ischar<CharParam, char_encoding>::call(ch_))
|
Chris@16
|
179 return false;
|
Chris@16
|
180
|
Chris@16
|
181 char_type ch = char_type(ch_); // optimize for token based parsing
|
Chris@16
|
182 return this->lo == ch || this->hi == ch;
|
Chris@16
|
183 }
|
Chris@16
|
184
|
Chris@16
|
185 template <typename Context>
|
Chris@16
|
186 info what(Context& /*context*/) const
|
Chris@16
|
187 {
|
Chris@16
|
188 return info("no-case-literal-char", char_encoding::toucs4(lo));
|
Chris@16
|
189 }
|
Chris@16
|
190
|
Chris@16
|
191 char_type lo, hi;
|
Chris@16
|
192 };
|
Chris@16
|
193
|
Chris@16
|
194 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
195 // Parser for a character range
|
Chris@16
|
196 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
197 template <typename CharEncoding, bool no_case = false>
|
Chris@16
|
198 struct char_range
|
Chris@16
|
199 : char_parser<char_range<CharEncoding, false>, typename CharEncoding::char_type>
|
Chris@16
|
200 {
|
Chris@16
|
201 typedef typename CharEncoding::char_type char_type;
|
Chris@16
|
202 typedef CharEncoding char_encoding;
|
Chris@16
|
203
|
Chris@16
|
204 char_range(char_type from_, char_type to_)
|
Chris@16
|
205 : from(from_), to(to_) {}
|
Chris@16
|
206
|
Chris@16
|
207 template <typename CharParam, typename Context>
|
Chris@16
|
208 bool test(CharParam ch_, Context&) const
|
Chris@16
|
209 {
|
Chris@16
|
210 if (!traits::ischar<CharParam, char_encoding>::call(ch_))
|
Chris@16
|
211 return false;
|
Chris@16
|
212
|
Chris@16
|
213 char_type ch = char_type(ch_); // optimize for token based parsing
|
Chris@16
|
214 return !(ch < from) && !(to < ch);
|
Chris@16
|
215 }
|
Chris@16
|
216
|
Chris@16
|
217 template <typename Context>
|
Chris@16
|
218 info what(Context& /*context*/) const
|
Chris@16
|
219 {
|
Chris@16
|
220 info result("char-range", char_encoding::toucs4(from));
|
Chris@16
|
221 boost::get<std::string>(result.value) += '-';
|
Chris@16
|
222 boost::get<std::string>(result.value) += to_utf8(char_encoding::toucs4(to));
|
Chris@16
|
223 return result;
|
Chris@16
|
224 }
|
Chris@16
|
225
|
Chris@16
|
226 char_type from, to;
|
Chris@16
|
227 };
|
Chris@16
|
228
|
Chris@16
|
229 template <typename CharEncoding>
|
Chris@16
|
230 struct char_range<CharEncoding, true> // case insensitive
|
Chris@16
|
231 : char_parser<char_range<CharEncoding, true>, typename CharEncoding::char_type>
|
Chris@16
|
232 {
|
Chris@16
|
233 typedef typename CharEncoding::char_type char_type;
|
Chris@16
|
234 typedef CharEncoding char_encoding;
|
Chris@16
|
235
|
Chris@16
|
236 char_range(char_type from, char_type to)
|
Chris@16
|
237 : from_lo(static_cast<char_type>(char_encoding::tolower(from)))
|
Chris@16
|
238 , to_lo(static_cast<char_type>(char_encoding::tolower(to)))
|
Chris@16
|
239 , from_hi(static_cast<char_type>(char_encoding::toupper(from)))
|
Chris@16
|
240 , to_hi(static_cast<char_type>(char_encoding::toupper(to)))
|
Chris@16
|
241 {}
|
Chris@16
|
242
|
Chris@16
|
243 template <typename CharParam, typename Context>
|
Chris@16
|
244 bool test(CharParam ch_, Context&) const
|
Chris@16
|
245 {
|
Chris@16
|
246 if (!traits::ischar<CharParam, char_encoding>::call(ch_))
|
Chris@16
|
247 return false;
|
Chris@16
|
248
|
Chris@16
|
249 char_type ch = char_type(ch_); // optimize for token based parsing
|
Chris@16
|
250 return (!(ch < from_lo) && !(to_lo < ch))
|
Chris@16
|
251 || (!(ch < from_hi) && !(to_hi < ch))
|
Chris@16
|
252 ;
|
Chris@16
|
253 }
|
Chris@16
|
254
|
Chris@16
|
255 template <typename Context>
|
Chris@16
|
256 info what(Context& /*context*/) const
|
Chris@16
|
257 {
|
Chris@16
|
258 info result("no-case-char-range", char_encoding::toucs4(from_lo));
|
Chris@16
|
259 boost::get<std::string>(result.value) += '-';
|
Chris@16
|
260 boost::get<std::string>(result.value) += to_utf8(char_encoding::toucs4(to_lo));
|
Chris@16
|
261 return result;
|
Chris@16
|
262 }
|
Chris@16
|
263
|
Chris@16
|
264 char_type from_lo, to_lo, from_hi, to_hi;
|
Chris@16
|
265 };
|
Chris@16
|
266
|
Chris@16
|
267 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
268 // Parser for a character set
|
Chris@16
|
269 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
270 template <typename CharEncoding, bool no_attribute, bool no_case = false>
|
Chris@16
|
271 struct char_set
|
Chris@16
|
272 : char_parser<char_set<CharEncoding, no_attribute, false>
|
Chris@16
|
273 , typename mpl::if_c<no_attribute, unused_type
|
Chris@16
|
274 , typename CharEncoding::char_type>::type>
|
Chris@16
|
275 {
|
Chris@16
|
276 typedef typename CharEncoding::char_type char_type;
|
Chris@16
|
277 typedef CharEncoding char_encoding;
|
Chris@16
|
278
|
Chris@16
|
279 template <typename String>
|
Chris@16
|
280 char_set(String const& str)
|
Chris@16
|
281 {
|
Chris@16
|
282 using spirit::detail::cast_char;
|
Chris@16
|
283
|
Chris@16
|
284 typedef typename
|
Chris@16
|
285 remove_const<
|
Chris@16
|
286 typename traits::char_type_of<String>::type
|
Chris@16
|
287 >::type
|
Chris@16
|
288 in_type;
|
Chris@16
|
289
|
Chris@16
|
290 BOOST_SPIRIT_ASSERT_MSG((
|
Chris@16
|
291 (sizeof(char_type) >= sizeof(in_type))
|
Chris@16
|
292 ), cannot_convert_string, (String));
|
Chris@16
|
293
|
Chris@16
|
294 in_type const* definition =
|
Chris@16
|
295 (in_type const*)traits::get_c_string(str);
|
Chris@16
|
296 in_type ch = *definition++;
|
Chris@16
|
297 while (ch)
|
Chris@16
|
298 {
|
Chris@16
|
299 in_type next = *definition++;
|
Chris@16
|
300 if (next == '-')
|
Chris@16
|
301 {
|
Chris@16
|
302 next = *definition++;
|
Chris@16
|
303 if (next == 0)
|
Chris@16
|
304 {
|
Chris@16
|
305 chset.set(cast_char<char_type>(ch));
|
Chris@16
|
306 chset.set('-');
|
Chris@16
|
307 break;
|
Chris@16
|
308 }
|
Chris@16
|
309 chset.set(
|
Chris@16
|
310 cast_char<char_type>(ch),
|
Chris@16
|
311 cast_char<char_type>(next)
|
Chris@16
|
312 );
|
Chris@16
|
313 }
|
Chris@16
|
314 else
|
Chris@16
|
315 {
|
Chris@16
|
316 chset.set(cast_char<char_type>(ch));
|
Chris@16
|
317 }
|
Chris@16
|
318 ch = next;
|
Chris@16
|
319 }
|
Chris@16
|
320 }
|
Chris@16
|
321
|
Chris@16
|
322 template <typename CharParam, typename Context>
|
Chris@16
|
323 bool test(CharParam ch, Context&) const
|
Chris@16
|
324 {
|
Chris@16
|
325 return traits::ischar<CharParam, char_encoding>::call(ch) &&
|
Chris@16
|
326 chset.test(char_type(ch));
|
Chris@16
|
327 }
|
Chris@16
|
328
|
Chris@16
|
329 template <typename Context>
|
Chris@16
|
330 info what(Context& /*context*/) const
|
Chris@16
|
331 {
|
Chris@16
|
332 return info("char-set");
|
Chris@16
|
333 }
|
Chris@16
|
334
|
Chris@16
|
335 support::detail::basic_chset<char_type> chset;
|
Chris@16
|
336 };
|
Chris@16
|
337
|
Chris@16
|
338 template <typename CharEncoding, bool no_attribute>
|
Chris@16
|
339 struct char_set<CharEncoding, no_attribute, true> // case insensitive
|
Chris@16
|
340 : char_parser<char_set<CharEncoding, no_attribute, true>
|
Chris@16
|
341 , typename mpl::if_c<no_attribute, unused_type
|
Chris@16
|
342 , typename CharEncoding::char_type>::type>
|
Chris@16
|
343 {
|
Chris@16
|
344 typedef typename CharEncoding::char_type char_type;
|
Chris@16
|
345 typedef CharEncoding char_encoding;
|
Chris@16
|
346
|
Chris@16
|
347 template <typename String>
|
Chris@16
|
348 char_set(String const& str)
|
Chris@16
|
349 {
|
Chris@16
|
350 typedef typename traits::char_type_of<String>::type in_type;
|
Chris@16
|
351
|
Chris@16
|
352 BOOST_SPIRIT_ASSERT_MSG((
|
Chris@16
|
353 (sizeof(char_type) == sizeof(in_type))
|
Chris@16
|
354 ), cannot_convert_string, (String));
|
Chris@16
|
355
|
Chris@16
|
356 char_type const* definition =
|
Chris@16
|
357 (char_type const*)traits::get_c_string(str);
|
Chris@16
|
358 char_type ch = *definition++;
|
Chris@16
|
359 while (ch)
|
Chris@16
|
360 {
|
Chris@16
|
361 char_type next = *definition++;
|
Chris@16
|
362 if (next == '-')
|
Chris@16
|
363 {
|
Chris@16
|
364 next = *definition++;
|
Chris@16
|
365 if (next == 0)
|
Chris@16
|
366 {
|
Chris@16
|
367 chset.set(static_cast<char_type>(CharEncoding::tolower(ch)));
|
Chris@16
|
368 chset.set(static_cast<char_type>(CharEncoding::toupper(ch)));
|
Chris@16
|
369 chset.set('-');
|
Chris@16
|
370 break;
|
Chris@16
|
371 }
|
Chris@16
|
372 chset.set(static_cast<char_type>(CharEncoding::tolower(ch))
|
Chris@16
|
373 , static_cast<char_type>(CharEncoding::tolower(next)));
|
Chris@16
|
374 chset.set(static_cast<char_type>(CharEncoding::toupper(ch))
|
Chris@16
|
375 , static_cast<char_type>(CharEncoding::toupper(next)));
|
Chris@16
|
376 }
|
Chris@16
|
377 else
|
Chris@16
|
378 {
|
Chris@16
|
379 chset.set(static_cast<char_type>(CharEncoding::tolower(ch)));
|
Chris@16
|
380 chset.set(static_cast<char_type>(CharEncoding::toupper(ch)));
|
Chris@16
|
381 }
|
Chris@16
|
382 ch = next;
|
Chris@16
|
383 }
|
Chris@16
|
384 }
|
Chris@16
|
385
|
Chris@16
|
386 template <typename CharParam, typename Context>
|
Chris@16
|
387 bool test(CharParam ch, Context&) const
|
Chris@16
|
388 {
|
Chris@16
|
389 return traits::ischar<CharParam, char_encoding>::call(ch) &&
|
Chris@16
|
390 chset.test(char_type(ch));
|
Chris@16
|
391 }
|
Chris@16
|
392
|
Chris@16
|
393 template <typename Context>
|
Chris@16
|
394 info what(Context& /*context*/) const
|
Chris@16
|
395 {
|
Chris@16
|
396 return info("no-case-char-set");
|
Chris@16
|
397 }
|
Chris@16
|
398
|
Chris@16
|
399 support::detail::basic_chset<char_type> chset;
|
Chris@16
|
400 };
|
Chris@16
|
401
|
Chris@16
|
402 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
403 // Parser generators: make_xxx function (objects)
|
Chris@16
|
404 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
405 namespace detail
|
Chris@16
|
406 {
|
Chris@16
|
407 template <typename Modifiers, typename Encoding>
|
Chris@16
|
408 struct basic_literal
|
Chris@16
|
409 {
|
Chris@16
|
410 static bool const no_case =
|
Chris@16
|
411 has_modifier<
|
Chris@16
|
412 Modifiers
|
Chris@16
|
413 , tag::char_code_base<tag::no_case>
|
Chris@16
|
414 >::value;
|
Chris@16
|
415
|
Chris@16
|
416 static bool const no_attr =
|
Chris@16
|
417 !has_modifier<
|
Chris@16
|
418 Modifiers
|
Chris@16
|
419 , tag::lazy_eval
|
Chris@16
|
420 >::value;
|
Chris@16
|
421
|
Chris@16
|
422 typedef literal_char<
|
Chris@16
|
423 typename spirit::detail::get_encoding_with_case<
|
Chris@16
|
424 Modifiers, Encoding, no_case>::type
|
Chris@16
|
425 , no_attr
|
Chris@16
|
426 , no_case>
|
Chris@16
|
427 result_type;
|
Chris@16
|
428
|
Chris@16
|
429 template <typename Char>
|
Chris@16
|
430 result_type operator()(Char ch, unused_type) const
|
Chris@16
|
431 {
|
Chris@16
|
432 return result_type(ch);
|
Chris@16
|
433 }
|
Chris@16
|
434
|
Chris@16
|
435 template <typename Char>
|
Chris@16
|
436 result_type operator()(Char const* str, unused_type) const
|
Chris@16
|
437 {
|
Chris@16
|
438 return result_type(str[0]);
|
Chris@16
|
439 }
|
Chris@16
|
440 };
|
Chris@16
|
441 }
|
Chris@16
|
442
|
Chris@16
|
443 template <typename Modifiers>
|
Chris@16
|
444 struct make_primitive<char, Modifiers>
|
Chris@16
|
445 : detail::basic_literal<Modifiers, char_encoding::standard> {};
|
Chris@16
|
446
|
Chris@16
|
447 template <typename Modifiers>
|
Chris@16
|
448 struct make_primitive<char const(&)[2], Modifiers>
|
Chris@16
|
449 : detail::basic_literal<Modifiers, char_encoding::standard> {};
|
Chris@16
|
450
|
Chris@16
|
451 template <typename Modifiers>
|
Chris@16
|
452 struct make_primitive<wchar_t, Modifiers>
|
Chris@16
|
453 : detail::basic_literal<Modifiers, char_encoding::standard_wide> {};
|
Chris@16
|
454
|
Chris@16
|
455 template <typename Modifiers>
|
Chris@16
|
456 struct make_primitive<wchar_t const(&)[2], Modifiers>
|
Chris@16
|
457 : detail::basic_literal<Modifiers, char_encoding::standard_wide> {};
|
Chris@16
|
458
|
Chris@16
|
459 template <typename CharEncoding, typename Modifiers>
|
Chris@16
|
460 struct make_primitive<
|
Chris@16
|
461 terminal<tag::char_code<tag::char_, CharEncoding> >, Modifiers>
|
Chris@16
|
462 {
|
Chris@16
|
463 typedef typename
|
Chris@16
|
464 spirit::detail::get_encoding<Modifiers, CharEncoding>::type
|
Chris@16
|
465 char_encoding;
|
Chris@16
|
466
|
Chris@16
|
467 typedef tag::char_code<tag::char_, char_encoding> tag;
|
Chris@16
|
468 typedef char_class<tag> result_type;
|
Chris@16
|
469 result_type operator()(unused_type, unused_type) const
|
Chris@16
|
470 {
|
Chris@16
|
471 return result_type();
|
Chris@16
|
472 }
|
Chris@16
|
473 };
|
Chris@16
|
474
|
Chris@16
|
475 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
476 // char_('x')
|
Chris@16
|
477 template <typename CharEncoding, typename Modifiers, typename A0>
|
Chris@16
|
478 struct make_primitive<
|
Chris@16
|
479 terminal_ex<
|
Chris@16
|
480 tag::char_code<tag::char_, CharEncoding>
|
Chris@16
|
481 , fusion::vector1<A0> >
|
Chris@16
|
482 , Modifiers>
|
Chris@16
|
483 {
|
Chris@16
|
484 static bool const no_case =
|
Chris@16
|
485 has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
|
Chris@16
|
486
|
Chris@16
|
487 typedef typename
|
Chris@16
|
488 spirit::detail::get_encoding<Modifiers, CharEncoding>::type
|
Chris@16
|
489 char_encoding;
|
Chris@16
|
490
|
Chris@16
|
491 typedef typename
|
Chris@16
|
492 mpl::if_<
|
Chris@16
|
493 traits::is_string<A0>
|
Chris@16
|
494 , char_set<char_encoding, false, no_case>
|
Chris@16
|
495 , literal_char<char_encoding, false, no_case>
|
Chris@16
|
496 >::type
|
Chris@16
|
497 result_type;
|
Chris@16
|
498
|
Chris@16
|
499 template <typename Terminal>
|
Chris@16
|
500 result_type operator()(Terminal const& term, unused_type) const
|
Chris@16
|
501 {
|
Chris@16
|
502 return result_type(fusion::at_c<0>(term.args));
|
Chris@16
|
503 }
|
Chris@16
|
504 };
|
Chris@16
|
505
|
Chris@16
|
506 // lit('x')
|
Chris@16
|
507 template <typename Modifiers, typename A0>
|
Chris@16
|
508 struct make_primitive<
|
Chris@16
|
509 terminal_ex<tag::lit, fusion::vector1<A0> >
|
Chris@16
|
510 , Modifiers
|
Chris@16
|
511 , typename enable_if<traits::is_char<A0> >::type>
|
Chris@16
|
512 {
|
Chris@16
|
513 static bool const no_case =
|
Chris@16
|
514 has_modifier<
|
Chris@16
|
515 Modifiers
|
Chris@16
|
516 , tag::char_code_base<tag::no_case>
|
Chris@16
|
517 >::value;
|
Chris@16
|
518
|
Chris@16
|
519 typedef typename traits::char_encoding_from_char<
|
Chris@16
|
520 typename traits::char_type_of<A0>::type>::type encoding;
|
Chris@16
|
521
|
Chris@16
|
522 typedef literal_char<
|
Chris@16
|
523 typename spirit::detail::get_encoding_with_case<
|
Chris@16
|
524 Modifiers, encoding, no_case>::type
|
Chris@16
|
525 , true, no_case>
|
Chris@16
|
526 result_type;
|
Chris@16
|
527
|
Chris@16
|
528 template <typename Terminal>
|
Chris@16
|
529 result_type operator()(Terminal const& term, unused_type) const
|
Chris@16
|
530 {
|
Chris@16
|
531 return result_type(fusion::at_c<0>(term.args));
|
Chris@16
|
532 }
|
Chris@16
|
533 };
|
Chris@16
|
534
|
Chris@16
|
535 ///////////////////////////////////////////////////////////////////////////
|
Chris@16
|
536 template <typename CharEncoding, typename Modifiers, typename Char>
|
Chris@16
|
537 struct make_primitive<
|
Chris@16
|
538 terminal_ex<
|
Chris@16
|
539 tag::char_code<tag::char_, CharEncoding>
|
Chris@16
|
540 , fusion::vector1<Char(&)[2]> // For single char strings
|
Chris@16
|
541 >
|
Chris@16
|
542 , Modifiers>
|
Chris@16
|
543 {
|
Chris@16
|
544 static bool const no_case =
|
Chris@16
|
545 has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
|
Chris@16
|
546
|
Chris@16
|
547 typedef typename
|
Chris@16
|
548 spirit::detail::get_encoding<Modifiers, CharEncoding>::type
|
Chris@16
|
549 char_encoding;
|
Chris@16
|
550
|
Chris@16
|
551 typedef literal_char<char_encoding, false, no_case> result_type;
|
Chris@16
|
552
|
Chris@16
|
553 template <typename Terminal>
|
Chris@16
|
554 result_type operator()(Terminal const& term, unused_type) const
|
Chris@16
|
555 {
|
Chris@16
|
556 return result_type(fusion::at_c<0>(term.args)[0]);
|
Chris@16
|
557 }
|
Chris@16
|
558 };
|
Chris@16
|
559
|
Chris@16
|
560 template <typename CharEncoding, typename Modifiers, typename A0, typename A1>
|
Chris@16
|
561 struct make_primitive<
|
Chris@16
|
562 terminal_ex<
|
Chris@16
|
563 tag::char_code<tag::char_, CharEncoding>
|
Chris@16
|
564 , fusion::vector2<A0, A1>
|
Chris@16
|
565 >
|
Chris@16
|
566 , Modifiers>
|
Chris@16
|
567 {
|
Chris@16
|
568 static bool const no_case =
|
Chris@16
|
569 has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
|
Chris@16
|
570
|
Chris@16
|
571 typedef typename
|
Chris@16
|
572 spirit::detail::get_encoding<Modifiers, CharEncoding>::type
|
Chris@16
|
573 char_encoding;
|
Chris@16
|
574
|
Chris@16
|
575 typedef char_range<char_encoding, no_case> result_type;
|
Chris@16
|
576
|
Chris@16
|
577 template <typename Terminal>
|
Chris@16
|
578 result_type operator()(Terminal const& term, unused_type) const
|
Chris@16
|
579 {
|
Chris@16
|
580 return result_type(
|
Chris@16
|
581 fusion::at_c<0>(term.args)
|
Chris@16
|
582 , fusion::at_c<1>(term.args)
|
Chris@16
|
583 );
|
Chris@16
|
584 }
|
Chris@16
|
585 };
|
Chris@16
|
586
|
Chris@16
|
587 template <typename CharEncoding, typename Modifiers, typename Char>
|
Chris@16
|
588 struct make_primitive<
|
Chris@16
|
589 terminal_ex<
|
Chris@16
|
590 tag::char_code<tag::char_, CharEncoding>
|
Chris@16
|
591 , fusion::vector2<Char(&)[2], Char(&)[2]> // For single char strings
|
Chris@16
|
592 >
|
Chris@16
|
593 , Modifiers>
|
Chris@16
|
594 {
|
Chris@16
|
595 static bool const no_case =
|
Chris@16
|
596 has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
|
Chris@16
|
597
|
Chris@16
|
598 typedef typename
|
Chris@16
|
599 spirit::detail::get_encoding<Modifiers, CharEncoding>::type
|
Chris@16
|
600 char_encoding;
|
Chris@16
|
601
|
Chris@16
|
602 typedef char_range<char_encoding, no_case> result_type;
|
Chris@16
|
603
|
Chris@16
|
604 template <typename Terminal>
|
Chris@16
|
605 result_type operator()(Terminal const& term, unused_type) const
|
Chris@16
|
606 {
|
Chris@16
|
607 return result_type(
|
Chris@16
|
608 fusion::at_c<0>(term.args)[0]
|
Chris@16
|
609 , fusion::at_c<1>(term.args)[0]
|
Chris@16
|
610 );
|
Chris@16
|
611 }
|
Chris@16
|
612 };
|
Chris@16
|
613 }}}
|
Chris@16
|
614
|
Chris@16
|
615 #endif
|