1 /*=============================================================================
2 Copyright (c) 1998-2003 Joel de Guzman
3 Copyright (c) 2001 Daniel Nuffer
4 http://spirit.sourceforge.net/
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
12 ///////////////////////////////////////////////////////////////////////////////
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>
22 namespace boost { namespace spirit {
24 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
26 ///////////////////////////////////////////////////////////////////////////
30 ///////////////////////////////////////////////////////////////////////////
31 struct lexeme_parser_gen;
33 template <typename ParserT>
35 : public unary<ParserT, parser<contiguous<ParserT> > >
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;
42 template <typename ScannerT>
45 typedef typename parser_result<ParserT, ScannerT>::type type;
48 contiguous(ParserT const& p)
51 template <typename ScannerT>
52 typename parser_result<self_t, ScannerT>::type
53 parse(ScannerT const& scan) const
55 typedef typename parser_result<self_t, ScannerT>::type result_t;
56 return impl::contiguous_parser_parse<result_t>
57 (this->subject(), scan, scan);
61 struct lexeme_parser_gen
63 template <typename ParserT>
66 typedef contiguous<ParserT> type;
69 template <typename ParserT>
70 static contiguous<ParserT>
71 generate(parser<ParserT> const& subject)
73 return contiguous<ParserT>(subject.derived());
76 template <typename ParserT>
78 operator[](parser<ParserT> const& subject) const
80 return contiguous<ParserT>(subject.derived());
84 //////////////////////////////////
85 const lexeme_parser_gen lexeme_d = lexeme_parser_gen();
87 ///////////////////////////////////////////////////////////////////////////
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)
95 ///////////////////////////////////////////////////////////////////////////
96 template <typename ScannerT>
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
107 rebind_scanner_policies<ScannerT, policies_t>::type type;
110 ///////////////////////////////////////////////////////////////////////////
112 // inhibit_case_iteration_policy class
114 ///////////////////////////////////////////////////////////////////////////
115 template <typename BaseT>
116 struct inhibit_case_iteration_policy : public BaseT
118 typedef BaseT base_t;
120 inhibit_case_iteration_policy()
123 template <typename PolicyT>
124 inhibit_case_iteration_policy(PolicyT const& other)
127 template <typename CharT>
128 CharT filter(CharT ch) const
129 { return impl::tolower_(ch); }
132 ///////////////////////////////////////////////////////////////////////////
134 // inhibit_case class
136 ///////////////////////////////////////////////////////////////////////////
137 struct inhibit_case_parser_gen;
139 template <typename ParserT>
141 : public unary<ParserT, parser<inhibit_case<ParserT> > >
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;
148 template <typename ScannerT>
151 typedef typename parser_result<ParserT, ScannerT>::type type;
154 inhibit_case(ParserT const& p)
157 template <typename ScannerT>
158 typename parser_result<self_t, ScannerT>::type
159 parse(ScannerT const& scan) const
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);
168 struct inhibit_case_parser_gen_base
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.
175 static inhibit_case<strlit<char const*> >
176 generate(char const* str)
177 { return inhibit_case<strlit<char const*> >(str); }
179 static inhibit_case<strlit<wchar_t const*> >
180 generate(wchar_t const* str)
181 { return inhibit_case<strlit<wchar_t const*> >(str); }
183 static inhibit_case<chlit<char> >
185 { return inhibit_case<chlit<char> >(ch); }
187 static inhibit_case<chlit<wchar_t> >
189 { return inhibit_case<chlit<wchar_t> >(ch); }
191 template <typename ParserT>
192 static inhibit_case<ParserT>
193 generate(parser<ParserT> const& subject)
194 { return inhibit_case<ParserT>(subject.derived()); }
196 inhibit_case<strlit<char const*> >
197 operator[](char const* str) const
198 { return inhibit_case<strlit<char const*> >(str); }
200 inhibit_case<strlit<wchar_t const*> >
201 operator[](wchar_t const* str) const
202 { return inhibit_case<strlit<wchar_t const*> >(str); }
204 inhibit_case<chlit<char> >
205 operator[](char ch) const
206 { return inhibit_case<chlit<char> >(ch); }
208 inhibit_case<chlit<wchar_t> >
209 operator[](wchar_t ch) const
210 { return inhibit_case<chlit<wchar_t> >(ch); }
212 template <typename ParserT>
213 inhibit_case<ParserT>
214 operator[](parser<ParserT> const& subject) const
215 { return inhibit_case<ParserT>(subject.derived()); }
218 //////////////////////////////////
219 struct inhibit_case_parser_gen : public inhibit_case_parser_gen_base<0>
221 inhibit_case_parser_gen() {}
224 //////////////////////////////////
226 const inhibit_case_parser_gen nocase_d = inhibit_case_parser_gen();
229 const inhibit_case_parser_gen as_lower_d = inhibit_case_parser_gen();
231 ///////////////////////////////////////////////////////////////////////////
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.
239 ///////////////////////////////////////////////////////////////////////////
240 template <typename ScannerT>
241 struct as_lower_scanner
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
251 rebind_scanner_policies<ScannerT, policies_t>::type type;
254 ///////////////////////////////////////////////////////////////////////////
256 // longest_alternative class
258 ///////////////////////////////////////////////////////////////////////////
259 struct longest_parser_gen;
261 template <typename A, typename B>
262 struct longest_alternative
263 : public binary<A, B, parser<longest_alternative<A, B> > >
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;
270 longest_alternative(A const& a, B const& b)
273 template <typename ScannerT>
274 typename parser_result<self_t, ScannerT>::type
275 parse(ScannerT const& scan) const
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);
285 if (l.length() > r.length())
293 return scan.no_match();
297 struct longest_parser_gen
299 template <typename A, typename B>
303 impl::to_longest_alternative<alternative<A, B> >::result_t
307 template <typename A, typename B>
309 impl::to_longest_alternative<alternative<A, B> >::result_t
310 generate(alternative<A, B> const& alt)
312 return impl::to_longest_alternative<alternative<A, B> >::
316 //'generate' for binary composite
317 template <typename A, typename B>
319 longest_alternative<A, B>
320 generate(A const &left, B const &right)
322 return longest_alternative<A, B>(left, right);
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
329 return impl::to_longest_alternative<alternative<A, B> >::
334 const longest_parser_gen longest_d = longest_parser_gen();
336 ///////////////////////////////////////////////////////////////////////////
338 // shortest_alternative class
340 ///////////////////////////////////////////////////////////////////////////
341 struct shortest_parser_gen;
343 template <typename A, typename B>
344 struct shortest_alternative
345 : public binary<A, B, parser<shortest_alternative<A, B> > >
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;
352 shortest_alternative(A const& a, B const& b)
355 template <typename ScannerT>
356 typename parser_result<self_t, ScannerT>::type
357 parse(ScannerT const& scan) const
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);
367 if ((l.length() < r.length() && l) || !r)
375 return scan.no_match();
379 struct shortest_parser_gen
381 template <typename A, typename B>
385 impl::to_shortest_alternative<alternative<A, B> >::result_t
389 template <typename A, typename B>
391 impl::to_shortest_alternative<alternative<A, B> >::result_t
392 generate(alternative<A, B> const& alt)
394 return impl::to_shortest_alternative<alternative<A, B> >::
398 //'generate' for binary composite
399 template <typename A, typename B>
401 shortest_alternative<A, B>
402 generate(A const &left, B const &right)
404 return shortest_alternative<A, B>(left, right);
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
411 return impl::to_shortest_alternative<alternative<A, B> >::
416 const shortest_parser_gen shortest_d = shortest_parser_gen();
418 ///////////////////////////////////////////////////////////////////////////
422 ///////////////////////////////////////////////////////////////////////////
423 template <typename BoundsT>
424 struct min_bounded_gen;
426 template <typename ParserT, typename BoundsT>
428 : public unary<ParserT, parser<min_bounded<ParserT, BoundsT> > >
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;
435 template <typename ScannerT>
438 typedef typename parser_result<ParserT, ScannerT>::type type;
441 min_bounded(ParserT const& p, BoundsT const& min__)
445 template <typename ScannerT>
446 typename parser_result<self_t, ScannerT>::type
447 parse(ScannerT const& scan) const
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();
459 template <typename BoundsT>
460 struct min_bounded_gen
462 min_bounded_gen(BoundsT const& min__)
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_); }
473 template <typename BoundsT>
474 inline min_bounded_gen<BoundsT>
475 min_limit_d(BoundsT const& min_)
476 { return min_bounded_gen<BoundsT>(min_); }
478 ///////////////////////////////////////////////////////////////////////////
482 ///////////////////////////////////////////////////////////////////////////
483 template <typename BoundsT>
484 struct max_bounded_gen;
486 template <typename ParserT, typename BoundsT>
488 : public unary<ParserT, parser<max_bounded<ParserT, BoundsT> > >
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;
495 template <typename ScannerT>
498 typedef typename parser_result<ParserT, ScannerT>::type type;
501 max_bounded(ParserT const& p, BoundsT const& max__)
505 template <typename ScannerT>
506 typename parser_result<self_t, ScannerT>::type
507 parse(ScannerT const& scan) const
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();
519 template <typename BoundsT>
520 struct max_bounded_gen
522 max_bounded_gen(BoundsT const& max__)
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_); }
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_); }
539 ///////////////////////////////////////////////////////////////////////////
543 ///////////////////////////////////////////////////////////////////////////
544 template <typename BoundsT>
547 template <typename ParserT, typename BoundsT>
549 : public unary<ParserT, parser<bounded<ParserT, BoundsT> > >
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;
556 template <typename ScannerT>
559 typedef typename parser_result<ParserT, ScannerT>::type type;
562 bounded(ParserT const& p, BoundsT const& min__, BoundsT const& max__)
567 template <typename ScannerT>
568 typename parser_result<self_t, ScannerT>::type
569 parse(ScannerT const& scan) const
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();
582 template <typename BoundsT>
585 bounded_gen(BoundsT const& min__, BoundsT const& max__)
589 template <typename DerivedT>
590 bounded<DerivedT, BoundsT>
591 operator[](parser<DerivedT> const& p) const
592 { return bounded<DerivedT, BoundsT>(p.derived(), min_, max_); }
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_); }
602 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
604 }} // namespace BOOST_SPIRIT_CLASSIC_NS