]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*============================================================================= |
2 | Copyright (c) 1998-2003 Joel de Guzman | |
3 | Copyright (c) 2001 Daniel Nuffer | |
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_DIRECTIVES_HPP) | |
10 | #define BOOST_SPIRIT_DIRECTIVES_HPP | |
11 | ||
12 | /////////////////////////////////////////////////////////////////////////////// | |
13 | #include <algorithm> | |
14 | ||
15 | #include <boost/spirit/home/classic/namespace.hpp> | |
16 | #include <boost/spirit/home/classic/core/parser.hpp> | |
17 | #include <boost/spirit/home/classic/core/scanner/skipper.hpp> | |
18 | #include <boost/spirit/home/classic/core/primitives/primitives.hpp> | |
19 | #include <boost/spirit/home/classic/core/composite/composite.hpp> | |
20 | #include <boost/spirit/home/classic/core/composite/impl/directives.ipp> | |
21 | ||
22 | namespace boost { namespace spirit { | |
23 | ||
24 | BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | |
25 | ||
26 | /////////////////////////////////////////////////////////////////////////// | |
27 | // | |
28 | // contiguous class | |
29 | // | |
30 | /////////////////////////////////////////////////////////////////////////// | |
31 | struct lexeme_parser_gen; | |
32 | ||
33 | template <typename ParserT> | |
34 | struct contiguous | |
35 | : public unary<ParserT, parser<contiguous<ParserT> > > | |
36 | { | |
37 | typedef contiguous<ParserT> self_t; | |
38 | typedef unary_parser_category parser_category_t; | |
39 | typedef lexeme_parser_gen parser_generator_t; | |
40 | typedef unary<ParserT, parser<self_t> > base_t; | |
41 | ||
42 | template <typename ScannerT> | |
43 | struct result | |
44 | { | |
45 | typedef typename parser_result<ParserT, ScannerT>::type type; | |
46 | }; | |
47 | ||
48 | contiguous(ParserT const& p) | |
49 | : base_t(p) {} | |
50 | ||
51 | template <typename ScannerT> | |
52 | typename parser_result<self_t, ScannerT>::type | |
53 | parse(ScannerT const& scan) const | |
54 | { | |
55 | typedef typename parser_result<self_t, ScannerT>::type result_t; | |
56 | return impl::contiguous_parser_parse<result_t> | |
57 | (this->subject(), scan, scan); | |
58 | } | |
59 | }; | |
60 | ||
61 | struct lexeme_parser_gen | |
62 | { | |
63 | template <typename ParserT> | |
64 | struct result { | |
65 | ||
66 | typedef contiguous<ParserT> type; | |
67 | }; | |
68 | ||
69 | template <typename ParserT> | |
70 | static contiguous<ParserT> | |
71 | generate(parser<ParserT> const& subject) | |
72 | { | |
73 | return contiguous<ParserT>(subject.derived()); | |
74 | } | |
75 | ||
76 | template <typename ParserT> | |
77 | contiguous<ParserT> | |
78 | operator[](parser<ParserT> const& subject) const | |
79 | { | |
80 | return contiguous<ParserT>(subject.derived()); | |
81 | } | |
82 | }; | |
83 | ||
84 | ////////////////////////////////// | |
85 | const lexeme_parser_gen lexeme_d = lexeme_parser_gen(); | |
86 | ||
87 | /////////////////////////////////////////////////////////////////////////// | |
88 | // | |
89 | // lexeme_scanner | |
90 | // | |
91 | // Given a Scanner, return the correct scanner type that | |
92 | // the lexeme_d uses. Scanner is assumed to be a phrase | |
93 | // level scanner (see skipper.hpp) | |
94 | // | |
95 | /////////////////////////////////////////////////////////////////////////// | |
96 | template <typename ScannerT> | |
97 | struct lexeme_scanner | |
98 | { | |
99 | typedef scanner_policies< | |
100 | no_skipper_iteration_policy< | |
101 | typename ScannerT::iteration_policy_t>, | |
102 | typename ScannerT::match_policy_t, | |
103 | typename ScannerT::action_policy_t | |
104 | > policies_t; | |
105 | ||
106 | typedef typename | |
107 | rebind_scanner_policies<ScannerT, policies_t>::type type; | |
108 | }; | |
109 | ||
110 | /////////////////////////////////////////////////////////////////////////// | |
111 | // | |
112 | // inhibit_case_iteration_policy class | |
113 | // | |
114 | /////////////////////////////////////////////////////////////////////////// | |
115 | template <typename BaseT> | |
116 | struct inhibit_case_iteration_policy : public BaseT | |
117 | { | |
118 | typedef BaseT base_t; | |
119 | ||
120 | inhibit_case_iteration_policy() | |
121 | : BaseT() {} | |
122 | ||
123 | template <typename PolicyT> | |
124 | inhibit_case_iteration_policy(PolicyT const& other) | |
125 | : BaseT(other) {} | |
126 | ||
127 | template <typename CharT> | |
128 | CharT filter(CharT ch) const | |
129 | { return impl::tolower_(ch); } | |
130 | }; | |
131 | ||
132 | /////////////////////////////////////////////////////////////////////////// | |
133 | // | |
134 | // inhibit_case class | |
135 | // | |
136 | /////////////////////////////////////////////////////////////////////////// | |
137 | struct inhibit_case_parser_gen; | |
138 | ||
139 | template <typename ParserT> | |
140 | struct inhibit_case | |
141 | : public unary<ParserT, parser<inhibit_case<ParserT> > > | |
142 | { | |
143 | typedef inhibit_case<ParserT> self_t; | |
144 | typedef unary_parser_category parser_category_t; | |
145 | typedef inhibit_case_parser_gen parser_generator_t; | |
146 | typedef unary<ParserT, parser<self_t> > base_t; | |
147 | ||
148 | template <typename ScannerT> | |
149 | struct result | |
150 | { | |
151 | typedef typename parser_result<ParserT, ScannerT>::type type; | |
152 | }; | |
153 | ||
154 | inhibit_case(ParserT const& p) | |
155 | : base_t(p) {} | |
156 | ||
157 | template <typename ScannerT> | |
158 | typename parser_result<self_t, ScannerT>::type | |
159 | parse(ScannerT const& scan) const | |
160 | { | |
161 | typedef typename parser_result<self_t, ScannerT>::type result_t; | |
162 | return impl::inhibit_case_parser_parse<result_t> | |
163 | (this->subject(), scan, scan); | |
164 | } | |
165 | }; | |
166 | ||
167 | template <int N> | |
168 | struct inhibit_case_parser_gen_base | |
169 | { | |
170 | // This hack is needed to make borland happy. | |
171 | // If these member operators were defined in the | |
172 | // inhibit_case_parser_gen class, or if this class | |
173 | // is non-templated, borland ICEs. | |
174 | ||
175 | static inhibit_case<strlit<char const*> > | |
176 | generate(char const* str) | |
177 | { return inhibit_case<strlit<char const*> >(str); } | |
178 | ||
179 | static inhibit_case<strlit<wchar_t const*> > | |
180 | generate(wchar_t const* str) | |
181 | { return inhibit_case<strlit<wchar_t const*> >(str); } | |
182 | ||
183 | static inhibit_case<chlit<char> > | |
184 | generate(char ch) | |
185 | { return inhibit_case<chlit<char> >(ch); } | |
186 | ||
187 | static inhibit_case<chlit<wchar_t> > | |
188 | generate(wchar_t ch) | |
189 | { return inhibit_case<chlit<wchar_t> >(ch); } | |
190 | ||
191 | template <typename ParserT> | |
192 | static inhibit_case<ParserT> | |
193 | generate(parser<ParserT> const& subject) | |
194 | { return inhibit_case<ParserT>(subject.derived()); } | |
195 | ||
196 | inhibit_case<strlit<char const*> > | |
197 | operator[](char const* str) const | |
198 | { return inhibit_case<strlit<char const*> >(str); } | |
199 | ||
200 | inhibit_case<strlit<wchar_t const*> > | |
201 | operator[](wchar_t const* str) const | |
202 | { return inhibit_case<strlit<wchar_t const*> >(str); } | |
203 | ||
204 | inhibit_case<chlit<char> > | |
205 | operator[](char ch) const | |
206 | { return inhibit_case<chlit<char> >(ch); } | |
207 | ||
208 | inhibit_case<chlit<wchar_t> > | |
209 | operator[](wchar_t ch) const | |
210 | { return inhibit_case<chlit<wchar_t> >(ch); } | |
211 | ||
212 | template <typename ParserT> | |
213 | inhibit_case<ParserT> | |
214 | operator[](parser<ParserT> const& subject) const | |
215 | { return inhibit_case<ParserT>(subject.derived()); } | |
216 | }; | |
217 | ||
218 | ////////////////////////////////// | |
219 | struct inhibit_case_parser_gen : public inhibit_case_parser_gen_base<0> | |
220 | { | |
221 | inhibit_case_parser_gen() {} | |
222 | }; | |
223 | ||
224 | ////////////////////////////////// | |
225 | // Depracated | |
226 | const inhibit_case_parser_gen nocase_d = inhibit_case_parser_gen(); | |
227 | ||
228 | // Preferred syntax | |
229 | const inhibit_case_parser_gen as_lower_d = inhibit_case_parser_gen(); | |
230 | ||
231 | /////////////////////////////////////////////////////////////////////////// | |
232 | // | |
233 | // as_lower_scanner | |
234 | // | |
235 | // Given a Scanner, return the correct scanner type that | |
236 | // the as_lower_d uses. Scanner is assumed to be a scanner | |
237 | // with an inhibit_case_iteration_policy. | |
238 | // | |
239 | /////////////////////////////////////////////////////////////////////////// | |
240 | template <typename ScannerT> | |
241 | struct as_lower_scanner | |
242 | { | |
243 | typedef scanner_policies< | |
244 | inhibit_case_iteration_policy< | |
245 | typename ScannerT::iteration_policy_t>, | |
246 | typename ScannerT::match_policy_t, | |
247 | typename ScannerT::action_policy_t | |
248 | > policies_t; | |
249 | ||
250 | typedef typename | |
251 | rebind_scanner_policies<ScannerT, policies_t>::type type; | |
252 | }; | |
253 | ||
254 | /////////////////////////////////////////////////////////////////////////// | |
255 | // | |
256 | // longest_alternative class | |
257 | // | |
258 | /////////////////////////////////////////////////////////////////////////// | |
259 | struct longest_parser_gen; | |
260 | ||
261 | template <typename A, typename B> | |
262 | struct longest_alternative | |
263 | : public binary<A, B, parser<longest_alternative<A, B> > > | |
264 | { | |
265 | typedef longest_alternative<A, B> self_t; | |
266 | typedef binary_parser_category parser_category_t; | |
267 | typedef longest_parser_gen parser_generator_t; | |
268 | typedef binary<A, B, parser<self_t> > base_t; | |
269 | ||
270 | longest_alternative(A const& a, B const& b) | |
271 | : base_t(a, b) {} | |
272 | ||
273 | template <typename ScannerT> | |
274 | typename parser_result<self_t, ScannerT>::type | |
275 | parse(ScannerT const& scan) const | |
276 | { | |
277 | typedef typename parser_result<self_t, ScannerT>::type result_t; | |
278 | typename ScannerT::iterator_t save = scan.first; | |
279 | result_t l = this->left().parse(scan); | |
280 | std::swap(scan.first, save); | |
281 | result_t r = this->right().parse(scan); | |
282 | ||
283 | if (l || r) | |
284 | { | |
285 | if (l.length() > r.length()) | |
286 | { | |
287 | scan.first = save; | |
288 | return l; | |
289 | } | |
290 | return r; | |
291 | } | |
292 | ||
293 | return scan.no_match(); | |
294 | } | |
295 | }; | |
296 | ||
297 | struct longest_parser_gen | |
298 | { | |
299 | template <typename A, typename B> | |
300 | struct result { | |
301 | ||
302 | typedef typename | |
303 | impl::to_longest_alternative<alternative<A, B> >::result_t | |
304 | type; | |
305 | }; | |
306 | ||
307 | template <typename A, typename B> | |
308 | static typename | |
309 | impl::to_longest_alternative<alternative<A, B> >::result_t | |
310 | generate(alternative<A, B> const& alt) | |
311 | { | |
312 | return impl::to_longest_alternative<alternative<A, B> >:: | |
313 | convert(alt); | |
314 | } | |
315 | ||
316 | //'generate' for binary composite | |
317 | template <typename A, typename B> | |
318 | static | |
319 | longest_alternative<A, B> | |
320 | generate(A const &left, B const &right) | |
321 | { | |
322 | return longest_alternative<A, B>(left, right); | |
323 | } | |
324 | ||
325 | template <typename A, typename B> | |
326 | typename impl::to_longest_alternative<alternative<A, B> >::result_t | |
327 | operator[](alternative<A, B> const& alt) const | |
328 | { | |
329 | return impl::to_longest_alternative<alternative<A, B> >:: | |
330 | convert(alt); | |
331 | } | |
332 | }; | |
333 | ||
334 | const longest_parser_gen longest_d = longest_parser_gen(); | |
335 | ||
336 | /////////////////////////////////////////////////////////////////////////// | |
337 | // | |
338 | // shortest_alternative class | |
339 | // | |
340 | /////////////////////////////////////////////////////////////////////////// | |
341 | struct shortest_parser_gen; | |
342 | ||
343 | template <typename A, typename B> | |
344 | struct shortest_alternative | |
345 | : public binary<A, B, parser<shortest_alternative<A, B> > > | |
346 | { | |
347 | typedef shortest_alternative<A, B> self_t; | |
348 | typedef binary_parser_category parser_category_t; | |
349 | typedef shortest_parser_gen parser_generator_t; | |
350 | typedef binary<A, B, parser<self_t> > base_t; | |
351 | ||
352 | shortest_alternative(A const& a, B const& b) | |
353 | : base_t(a, b) {} | |
354 | ||
355 | template <typename ScannerT> | |
356 | typename parser_result<self_t, ScannerT>::type | |
357 | parse(ScannerT const& scan) const | |
358 | { | |
359 | typedef typename parser_result<self_t, ScannerT>::type result_t; | |
360 | typename ScannerT::iterator_t save = scan.first; | |
361 | result_t l = this->left().parse(scan); | |
362 | std::swap(scan.first, save); | |
363 | result_t r = this->right().parse(scan); | |
364 | ||
365 | if (l || r) | |
366 | { | |
367 | if ((l.length() < r.length() && l) || !r) | |
368 | { | |
369 | scan.first = save; | |
370 | return l; | |
371 | } | |
372 | return r; | |
373 | } | |
374 | ||
375 | return scan.no_match(); | |
376 | } | |
377 | }; | |
378 | ||
379 | struct shortest_parser_gen | |
380 | { | |
381 | template <typename A, typename B> | |
382 | struct result { | |
383 | ||
384 | typedef typename | |
385 | impl::to_shortest_alternative<alternative<A, B> >::result_t | |
386 | type; | |
387 | }; | |
388 | ||
389 | template <typename A, typename B> | |
390 | static typename | |
391 | impl::to_shortest_alternative<alternative<A, B> >::result_t | |
392 | generate(alternative<A, B> const& alt) | |
393 | { | |
394 | return impl::to_shortest_alternative<alternative<A, B> >:: | |
395 | convert(alt); | |
396 | } | |
397 | ||
398 | //'generate' for binary composite | |
399 | template <typename A, typename B> | |
400 | static | |
401 | shortest_alternative<A, B> | |
402 | generate(A const &left, B const &right) | |
403 | { | |
404 | return shortest_alternative<A, B>(left, right); | |
405 | } | |
406 | ||
407 | template <typename A, typename B> | |
408 | typename impl::to_shortest_alternative<alternative<A, B> >::result_t | |
409 | operator[](alternative<A, B> const& alt) const | |
410 | { | |
411 | return impl::to_shortest_alternative<alternative<A, B> >:: | |
412 | convert(alt); | |
413 | } | |
414 | }; | |
415 | ||
416 | const shortest_parser_gen shortest_d = shortest_parser_gen(); | |
417 | ||
418 | /////////////////////////////////////////////////////////////////////////// | |
419 | // | |
420 | // min_bounded class | |
421 | // | |
422 | /////////////////////////////////////////////////////////////////////////// | |
423 | template <typename BoundsT> | |
424 | struct min_bounded_gen; | |
425 | ||
426 | template <typename ParserT, typename BoundsT> | |
427 | struct min_bounded | |
428 | : public unary<ParserT, parser<min_bounded<ParserT, BoundsT> > > | |
429 | { | |
430 | typedef min_bounded<ParserT, BoundsT> self_t; | |
431 | typedef unary_parser_category parser_category_t; | |
432 | typedef min_bounded_gen<BoundsT> parser_generator_t; | |
433 | typedef unary<ParserT, parser<self_t> > base_t; | |
434 | ||
435 | template <typename ScannerT> | |
436 | struct result | |
437 | { | |
438 | typedef typename parser_result<ParserT, ScannerT>::type type; | |
439 | }; | |
440 | ||
441 | min_bounded(ParserT const& p, BoundsT const& min__) | |
442 | : base_t(p) | |
443 | , min_(min__) {} | |
444 | ||
445 | template <typename ScannerT> | |
446 | typename parser_result<self_t, ScannerT>::type | |
447 | parse(ScannerT const& scan) const | |
448 | { | |
449 | typedef typename parser_result<self_t, ScannerT>::type result_t; | |
450 | result_t hit = this->subject().parse(scan); | |
451 | if (hit.has_valid_attribute() && hit.value() < min_) | |
452 | return scan.no_match(); | |
453 | return hit; | |
454 | } | |
455 | ||
456 | BoundsT min_; | |
457 | }; | |
458 | ||
459 | template <typename BoundsT> | |
460 | struct min_bounded_gen | |
461 | { | |
462 | min_bounded_gen(BoundsT const& min__) | |
463 | : min_(min__) {} | |
464 | ||
465 | template <typename DerivedT> | |
466 | min_bounded<DerivedT, BoundsT> | |
467 | operator[](parser<DerivedT> const& p) const | |
468 | { return min_bounded<DerivedT, BoundsT>(p.derived(), min_); } | |
469 | ||
470 | BoundsT min_; | |
471 | }; | |
472 | ||
473 | template <typename BoundsT> | |
474 | inline min_bounded_gen<BoundsT> | |
475 | min_limit_d(BoundsT const& min_) | |
476 | { return min_bounded_gen<BoundsT>(min_); } | |
477 | ||
478 | /////////////////////////////////////////////////////////////////////////// | |
479 | // | |
480 | // max_bounded class | |
481 | // | |
482 | /////////////////////////////////////////////////////////////////////////// | |
483 | template <typename BoundsT> | |
484 | struct max_bounded_gen; | |
485 | ||
486 | template <typename ParserT, typename BoundsT> | |
487 | struct max_bounded | |
488 | : public unary<ParserT, parser<max_bounded<ParserT, BoundsT> > > | |
489 | { | |
490 | typedef max_bounded<ParserT, BoundsT> self_t; | |
491 | typedef unary_parser_category parser_category_t; | |
492 | typedef max_bounded_gen<BoundsT> parser_generator_t; | |
493 | typedef unary<ParserT, parser<self_t> > base_t; | |
494 | ||
495 | template <typename ScannerT> | |
496 | struct result | |
497 | { | |
498 | typedef typename parser_result<ParserT, ScannerT>::type type; | |
499 | }; | |
500 | ||
501 | max_bounded(ParserT const& p, BoundsT const& max__) | |
502 | : base_t(p) | |
503 | , max_(max__) {} | |
504 | ||
505 | template <typename ScannerT> | |
506 | typename parser_result<self_t, ScannerT>::type | |
507 | parse(ScannerT const& scan) const | |
508 | { | |
509 | typedef typename parser_result<self_t, ScannerT>::type result_t; | |
510 | result_t hit = this->subject().parse(scan); | |
511 | if (hit.has_valid_attribute() && hit.value() > max_) | |
512 | return scan.no_match(); | |
513 | return hit; | |
514 | } | |
515 | ||
516 | BoundsT max_; | |
517 | }; | |
518 | ||
519 | template <typename BoundsT> | |
520 | struct max_bounded_gen | |
521 | { | |
522 | max_bounded_gen(BoundsT const& max__) | |
523 | : max_(max__) {} | |
524 | ||
525 | template <typename DerivedT> | |
526 | max_bounded<DerivedT, BoundsT> | |
527 | operator[](parser<DerivedT> const& p) const | |
528 | { return max_bounded<DerivedT, BoundsT>(p.derived(), max_); } | |
529 | ||
530 | BoundsT max_; | |
531 | }; | |
532 | ||
533 | ////////////////////////////////// | |
534 | template <typename BoundsT> | |
535 | inline max_bounded_gen<BoundsT> | |
536 | max_limit_d(BoundsT const& max_) | |
537 | { return max_bounded_gen<BoundsT>(max_); } | |
538 | ||
539 | /////////////////////////////////////////////////////////////////////////// | |
540 | // | |
541 | // bounded class | |
542 | // | |
543 | /////////////////////////////////////////////////////////////////////////// | |
544 | template <typename BoundsT> | |
545 | struct bounded_gen; | |
546 | ||
547 | template <typename ParserT, typename BoundsT> | |
548 | struct bounded | |
549 | : public unary<ParserT, parser<bounded<ParserT, BoundsT> > > | |
550 | { | |
551 | typedef bounded<ParserT, BoundsT> self_t; | |
552 | typedef unary_parser_category parser_category_t; | |
553 | typedef bounded_gen<BoundsT> parser_generator_t; | |
554 | typedef unary<ParserT, parser<self_t> > base_t; | |
555 | ||
556 | template <typename ScannerT> | |
557 | struct result | |
558 | { | |
559 | typedef typename parser_result<ParserT, ScannerT>::type type; | |
560 | }; | |
561 | ||
562 | bounded(ParserT const& p, BoundsT const& min__, BoundsT const& max__) | |
563 | : base_t(p) | |
564 | , min_(min__) | |
565 | , max_(max__) {} | |
566 | ||
567 | template <typename ScannerT> | |
568 | typename parser_result<self_t, ScannerT>::type | |
569 | parse(ScannerT const& scan) const | |
570 | { | |
571 | typedef typename parser_result<self_t, ScannerT>::type result_t; | |
572 | result_t hit = this->subject().parse(scan); | |
573 | if (hit.has_valid_attribute() && | |
574 | (hit.value() < min_ || hit.value() > max_)) | |
575 | return scan.no_match(); | |
576 | return hit; | |
577 | } | |
578 | ||
579 | BoundsT min_, max_; | |
580 | }; | |
581 | ||
582 | template <typename BoundsT> | |
583 | struct bounded_gen | |
584 | { | |
585 | bounded_gen(BoundsT const& min__, BoundsT const& max__) | |
586 | : min_(min__) | |
587 | , max_(max__) {} | |
588 | ||
589 | template <typename DerivedT> | |
590 | bounded<DerivedT, BoundsT> | |
591 | operator[](parser<DerivedT> const& p) const | |
592 | { return bounded<DerivedT, BoundsT>(p.derived(), min_, max_); } | |
593 | ||
594 | BoundsT min_, max_; | |
595 | }; | |
596 | ||
597 | template <typename BoundsT> | |
598 | inline bounded_gen<BoundsT> | |
599 | limit_d(BoundsT const& min_, BoundsT const& max_) | |
600 | { return bounded_gen<BoundsT>(min_, max_); } | |
601 | ||
602 | BOOST_SPIRIT_CLASSIC_NAMESPACE_END | |
603 | ||
604 | }} // namespace BOOST_SPIRIT_CLASSIC_NS | |
605 | ||
606 | #endif | |
607 |