source: NonGTP/Boost/boost/spirit/core/composite/directives.hpp @ 857

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