Line data Source code
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 0 : contiguous(ParserT const& p)
49 0 : : base_t(p) {}
50 :
51 : template <typename ScannerT>
52 : typename parser_result<self_t, ScannerT>::type
53 0 : 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 0 : (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 0 : operator[](parser<ParserT> const& subject) const
79 : {
80 0 : 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 :
|