• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
contiguousboost::spirit::contiguous48         contiguous(ParserT const& p)
49         : base_t(p) {}
50 
51         template <typename ScannerT>
52         typename parser_result<self_t, ScannerT>::type
parseboost::spirit::contiguous53         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>
generateboost::spirit::lexeme_parser_gen71         generate(parser<ParserT> const& subject)
72         {
73             return contiguous<ParserT>(subject.derived());
74         }
75 
76         template <typename ParserT>
77         contiguous<ParserT>
operator []boost::spirit::lexeme_parser_gen78         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 
inhibit_case_iteration_policyboost::spirit::inhibit_case_iteration_policy120         inhibit_case_iteration_policy()
121         : BaseT() {}
122 
123         template <typename PolicyT>
inhibit_case_iteration_policyboost::spirit::inhibit_case_iteration_policy124         inhibit_case_iteration_policy(PolicyT const& other)
125         : BaseT(other) {}
126 
127         template <typename CharT>
filterboost::spirit::inhibit_case_iteration_policy128         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 
inhibit_caseboost::spirit::inhibit_case154         inhibit_case(ParserT const& p)
155         : base_t(p) {}
156 
157         template <typename ScannerT>
158         typename parser_result<self_t, ScannerT>::type
parseboost::spirit::inhibit_case159         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*> >
generateboost::spirit::inhibit_case_parser_gen_base176         generate(char const* str)
177         { return inhibit_case<strlit<char const*> >(str); }
178 
179         static inhibit_case<strlit<wchar_t const*> >
generateboost::spirit::inhibit_case_parser_gen_base180         generate(wchar_t const* str)
181         { return inhibit_case<strlit<wchar_t const*> >(str); }
182 
183         static inhibit_case<chlit<char> >
generateboost::spirit::inhibit_case_parser_gen_base184         generate(char ch)
185         { return inhibit_case<chlit<char> >(ch); }
186 
187         static inhibit_case<chlit<wchar_t> >
generateboost::spirit::inhibit_case_parser_gen_base188         generate(wchar_t ch)
189         { return inhibit_case<chlit<wchar_t> >(ch); }
190 
191         template <typename ParserT>
192         static inhibit_case<ParserT>
generateboost::spirit::inhibit_case_parser_gen_base193         generate(parser<ParserT> const& subject)
194         { return inhibit_case<ParserT>(subject.derived()); }
195 
196         inhibit_case<strlit<char const*> >
operator []boost::spirit::inhibit_case_parser_gen_base197         operator[](char const* str) const
198         { return inhibit_case<strlit<char const*> >(str); }
199 
200         inhibit_case<strlit<wchar_t const*> >
operator []boost::spirit::inhibit_case_parser_gen_base201         operator[](wchar_t const* str) const
202         { return inhibit_case<strlit<wchar_t const*> >(str); }
203 
204         inhibit_case<chlit<char> >
operator []boost::spirit::inhibit_case_parser_gen_base205         operator[](char ch) const
206         { return inhibit_case<chlit<char> >(ch); }
207 
208         inhibit_case<chlit<wchar_t> >
operator []boost::spirit::inhibit_case_parser_gen_base209         operator[](wchar_t ch) const
210         { return inhibit_case<chlit<wchar_t> >(ch); }
211 
212         template <typename ParserT>
213         inhibit_case<ParserT>
operator []boost::spirit::inhibit_case_parser_gen_base214         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     {
inhibit_case_parser_genboost::spirit::inhibit_case_parser_gen221         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 
longest_alternativeboost::spirit::longest_alternative270         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
parseboost::spirit::longest_alternative275         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
generateboost::spirit::longest_parser_gen310         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>
generateboost::spirit::longest_parser_gen320         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
operator []boost::spirit::longest_parser_gen327         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 
shortest_alternativeboost::spirit::shortest_alternative352         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
parseboost::spirit::shortest_alternative357         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
generateboost::spirit::shortest_parser_gen392         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>
generateboost::spirit::shortest_parser_gen402         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
operator []boost::spirit::shortest_parser_gen409         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 
min_boundedboost::spirit::min_bounded441         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
parseboost::spirit::min_bounded447         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     {
min_bounded_genboost::spirit::min_bounded_gen462         min_bounded_gen(BoundsT const& min__)
463         : min_(min__) {}
464 
465         template <typename DerivedT>
466         min_bounded<DerivedT, BoundsT>
operator []boost::spirit::min_bounded_gen467         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>
min_limit_d(BoundsT const & min_)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 
max_boundedboost::spirit::max_bounded501         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
parseboost::spirit::max_bounded507         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     {
max_bounded_genboost::spirit::max_bounded_gen522         max_bounded_gen(BoundsT const& max__)
523         : max_(max__) {}
524 
525         template <typename DerivedT>
526         max_bounded<DerivedT, BoundsT>
operator []boost::spirit::max_bounded_gen527         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>
max_limit_d(BoundsT const & max_)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 
boundedboost::spirit::bounded562         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
parseboost::spirit::bounded569         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     {
bounded_genboost::spirit::bounded_gen585         bounded_gen(BoundsT const& min__, BoundsT const& max__)
586         : min_(min__)
587         , max_(max__) {}
588 
589         template <typename DerivedT>
590         bounded<DerivedT, BoundsT>
operator []boost::spirit::bounded_gen591         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>
limit_d(BoundsT const & min_,BoundsT const & max_)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 
608