608 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			608 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | /*============================================================================= | ||
|  |     Copyright (c) 1998-2003 Joel de Guzman | ||
|  |     Copyright (c) 2001 Daniel Nuffer | ||
|  |     http://spirit.sourceforge.net/ | ||
|  | 
 | ||
|  |   Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
|  |   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
|  | =============================================================================*/ | ||
|  | #if !defined(BOOST_SPIRIT_DIRECTIVES_HPP) | ||
|  | #define BOOST_SPIRIT_DIRECTIVES_HPP | ||
|  | 
 | ||
|  | /////////////////////////////////////////////////////////////////////////////// | ||
|  | #include <algorithm> | ||
|  | 
 | ||
|  | #include <boost/spirit/home/classic/namespace.hpp> | ||
|  | #include <boost/spirit/home/classic/core/parser.hpp> | ||
|  | #include <boost/spirit/home/classic/core/scanner/skipper.hpp>  | ||
|  | #include <boost/spirit/home/classic/core/primitives/primitives.hpp> | ||
|  | #include <boost/spirit/home/classic/core/composite/composite.hpp> | ||
|  | #include <boost/spirit/home/classic/core/composite/impl/directives.ipp> | ||
|  | 
 | ||
|  | namespace boost { namespace spirit { | ||
|  | 
 | ||
|  | BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  contiguous class | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     struct lexeme_parser_gen; | ||
|  | 
 | ||
|  |     template <typename ParserT> | ||
|  |     struct contiguous | ||
|  |     :   public unary<ParserT, parser<contiguous<ParserT> > > | ||
|  |     { | ||
|  |         typedef contiguous<ParserT>             self_t; | ||
|  |         typedef unary_parser_category           parser_category_t; | ||
|  |         typedef lexeme_parser_gen               parser_generator_t; | ||
|  |         typedef unary<ParserT, parser<self_t> > base_t; | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         struct result | ||
|  |         { | ||
|  |             typedef typename parser_result<ParserT, ScannerT>::type type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         contiguous(ParserT const& p) | ||
|  |         : base_t(p) {} | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         typename parser_result<self_t, ScannerT>::type | ||
|  |         parse(ScannerT const& scan) const | ||
|  |         { | ||
|  |             typedef typename parser_result<self_t, ScannerT>::type result_t; | ||
|  |             return impl::contiguous_parser_parse<result_t> | ||
|  |                 (this->subject(), scan, scan); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  |     struct lexeme_parser_gen | ||
|  |     { | ||
|  |         template <typename ParserT> | ||
|  |         struct result { | ||
|  | 
 | ||
|  |             typedef contiguous<ParserT> type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         template <typename ParserT> | ||
|  |         static contiguous<ParserT> | ||
|  |         generate(parser<ParserT> const& subject) | ||
|  |         { | ||
|  |             return contiguous<ParserT>(subject.derived()); | ||
|  |         } | ||
|  | 
 | ||
|  |         template <typename ParserT> | ||
|  |         contiguous<ParserT> | ||
|  |         operator[](parser<ParserT> const& subject) const | ||
|  |         { | ||
|  |             return contiguous<ParserT>(subject.derived()); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  |     ////////////////////////////////// | ||
|  |     const lexeme_parser_gen lexeme_d = lexeme_parser_gen(); | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  lexeme_scanner | ||
|  |     // | ||
|  |     //      Given a Scanner, return the correct scanner type that | ||
|  |     //      the lexeme_d uses. Scanner is assumed to be a phrase | ||
|  |     //      level scanner (see skipper.hpp) | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     template <typename ScannerT> | ||
|  |     struct lexeme_scanner | ||
|  |     { | ||
|  |         typedef scanner_policies< | ||
|  |             no_skipper_iteration_policy< | ||
|  |                 typename ScannerT::iteration_policy_t>, | ||
|  |             typename ScannerT::match_policy_t, | ||
|  |             typename ScannerT::action_policy_t | ||
|  |         > policies_t; | ||
|  | 
 | ||
|  |         typedef typename | ||
|  |             rebind_scanner_policies<ScannerT, policies_t>::type type; | ||
|  |     }; | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  inhibit_case_iteration_policy class | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     template <typename BaseT> | ||
|  |     struct inhibit_case_iteration_policy : public BaseT | ||
|  |     { | ||
|  |         typedef BaseT base_t; | ||
|  | 
 | ||
|  |         inhibit_case_iteration_policy() | ||
|  |         : BaseT() {} | ||
|  | 
 | ||
|  |         template <typename PolicyT> | ||
|  |         inhibit_case_iteration_policy(PolicyT const& other) | ||
|  |         : BaseT(other) {} | ||
|  | 
 | ||
|  |         template <typename CharT> | ||
|  |         CharT filter(CharT ch) const | ||
|  |         { return impl::tolower_(ch); } | ||
|  |     }; | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  inhibit_case class | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     struct inhibit_case_parser_gen; | ||
|  | 
 | ||
|  |     template <typename ParserT> | ||
|  |     struct inhibit_case | ||
|  |     :   public unary<ParserT, parser<inhibit_case<ParserT> > > | ||
|  |     { | ||
|  |         typedef inhibit_case<ParserT>           self_t; | ||
|  |         typedef unary_parser_category           parser_category_t; | ||
|  |         typedef inhibit_case_parser_gen         parser_generator_t; | ||
|  |         typedef unary<ParserT, parser<self_t> > base_t; | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         struct result | ||
|  |         { | ||
|  |             typedef typename parser_result<ParserT, ScannerT>::type type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         inhibit_case(ParserT const& p) | ||
|  |         : base_t(p) {} | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         typename parser_result<self_t, ScannerT>::type | ||
|  |         parse(ScannerT const& scan) const | ||
|  |         { | ||
|  |             typedef typename parser_result<self_t, ScannerT>::type result_t; | ||
|  |             return impl::inhibit_case_parser_parse<result_t> | ||
|  |                 (this->subject(), scan, scan); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  |     template <int N> | ||
|  |     struct inhibit_case_parser_gen_base | ||
|  |     { | ||
|  |         //  This hack is needed to make borland happy. | ||
|  |         //  If these member operators were defined in the | ||
|  |         //  inhibit_case_parser_gen class, or if this class | ||
|  |         //  is non-templated, borland ICEs. | ||
|  | 
 | ||
|  |         static inhibit_case<strlit<char const*> > | ||
|  |         generate(char const* str) | ||
|  |         { return inhibit_case<strlit<char const*> >(str); } | ||
|  | 
 | ||
|  |         static inhibit_case<strlit<wchar_t const*> > | ||
|  |         generate(wchar_t const* str) | ||
|  |         { return inhibit_case<strlit<wchar_t const*> >(str); } | ||
|  | 
 | ||
|  |         static inhibit_case<chlit<char> > | ||
|  |         generate(char ch) | ||
|  |         { return inhibit_case<chlit<char> >(ch); } | ||
|  | 
 | ||
|  |         static inhibit_case<chlit<wchar_t> > | ||
|  |         generate(wchar_t ch) | ||
|  |         { return inhibit_case<chlit<wchar_t> >(ch); } | ||
|  | 
 | ||
|  |         template <typename ParserT> | ||
|  |         static inhibit_case<ParserT> | ||
|  |         generate(parser<ParserT> const& subject) | ||
|  |         { return inhibit_case<ParserT>(subject.derived()); } | ||
|  | 
 | ||
|  |         inhibit_case<strlit<char const*> > | ||
|  |         operator[](char const* str) const | ||
|  |         { return inhibit_case<strlit<char const*> >(str); } | ||
|  | 
 | ||
|  |         inhibit_case<strlit<wchar_t const*> > | ||
|  |         operator[](wchar_t const* str) const | ||
|  |         { return inhibit_case<strlit<wchar_t const*> >(str); } | ||
|  | 
 | ||
|  |         inhibit_case<chlit<char> > | ||
|  |         operator[](char ch) const | ||
|  |         { return inhibit_case<chlit<char> >(ch); } | ||
|  | 
 | ||
|  |         inhibit_case<chlit<wchar_t> > | ||
|  |         operator[](wchar_t ch) const | ||
|  |         { return inhibit_case<chlit<wchar_t> >(ch); } | ||
|  | 
 | ||
|  |         template <typename ParserT> | ||
|  |         inhibit_case<ParserT> | ||
|  |         operator[](parser<ParserT> const& subject) const | ||
|  |         { return inhibit_case<ParserT>(subject.derived()); } | ||
|  |     }; | ||
|  | 
 | ||
|  |     ////////////////////////////////// | ||
|  |     struct inhibit_case_parser_gen : public inhibit_case_parser_gen_base<0> | ||
|  |     { | ||
|  |         inhibit_case_parser_gen() {} | ||
|  |     }; | ||
|  | 
 | ||
|  |     ////////////////////////////////// | ||
|  |     //  Depracated | ||
|  |     const inhibit_case_parser_gen nocase_d = inhibit_case_parser_gen(); | ||
|  | 
 | ||
|  |     //  Preferred syntax | ||
|  |     const inhibit_case_parser_gen as_lower_d = inhibit_case_parser_gen(); | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  as_lower_scanner | ||
|  |     // | ||
|  |     //      Given a Scanner, return the correct scanner type that | ||
|  |     //      the as_lower_d uses. Scanner is assumed to be a scanner | ||
|  |     //      with an inhibit_case_iteration_policy. | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     template <typename ScannerT> | ||
|  |     struct as_lower_scanner | ||
|  |     { | ||
|  |         typedef scanner_policies< | ||
|  |             inhibit_case_iteration_policy< | ||
|  |                 typename ScannerT::iteration_policy_t>, | ||
|  |             typename ScannerT::match_policy_t, | ||
|  |             typename ScannerT::action_policy_t | ||
|  |         > policies_t; | ||
|  | 
 | ||
|  |         typedef typename | ||
|  |             rebind_scanner_policies<ScannerT, policies_t>::type type; | ||
|  |     }; | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  longest_alternative class | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     struct longest_parser_gen; | ||
|  | 
 | ||
|  |     template <typename A, typename B> | ||
|  |     struct longest_alternative | ||
|  |     :   public binary<A, B, parser<longest_alternative<A, B> > > | ||
|  |     { | ||
|  |         typedef longest_alternative<A, B>       self_t; | ||
|  |         typedef binary_parser_category          parser_category_t; | ||
|  |         typedef longest_parser_gen              parser_generator_t; | ||
|  |         typedef binary<A, B, parser<self_t> >   base_t; | ||
|  | 
 | ||
|  |         longest_alternative(A const& a, B const& b) | ||
|  |         : base_t(a, b) {} | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         typename parser_result<self_t, ScannerT>::type | ||
|  |         parse(ScannerT const& scan) const | ||
|  |         { | ||
|  |             typedef typename parser_result<self_t, ScannerT>::type result_t; | ||
|  |             typename ScannerT::iterator_t save = scan.first; | ||
|  |             result_t l = this->left().parse(scan); | ||
|  |             std::swap(scan.first, save); | ||
|  |             result_t r = this->right().parse(scan); | ||
|  | 
 | ||
|  |             if (l || r) | ||
|  |             { | ||
|  |                 if (l.length() > r.length()) | ||
|  |                 { | ||
|  |                     scan.first = save; | ||
|  |                     return l; | ||
|  |                 } | ||
|  |                 return r; | ||
|  |             } | ||
|  | 
 | ||
|  |             return scan.no_match(); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  |     struct longest_parser_gen | ||
|  |     { | ||
|  |         template <typename A, typename B> | ||
|  |         struct result { | ||
|  | 
 | ||
|  |             typedef typename | ||
|  |                 impl::to_longest_alternative<alternative<A, B> >::result_t | ||
|  |             type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         template <typename A, typename B> | ||
|  |         static typename | ||
|  |         impl::to_longest_alternative<alternative<A, B> >::result_t | ||
|  |         generate(alternative<A, B> const& alt) | ||
|  |         { | ||
|  |             return impl::to_longest_alternative<alternative<A, B> >:: | ||
|  |                 convert(alt); | ||
|  |         } | ||
|  | 
 | ||
|  |         //'generate' for binary composite | ||
|  |         template <typename A, typename B> | ||
|  |         static | ||
|  |         longest_alternative<A, B> | ||
|  |         generate(A const &left, B const &right) | ||
|  |         { | ||
|  |             return longest_alternative<A, B>(left, right); | ||
|  |         } | ||
|  | 
 | ||
|  |         template <typename A, typename B> | ||
|  |         typename impl::to_longest_alternative<alternative<A, B> >::result_t | ||
|  |         operator[](alternative<A, B> const& alt) const | ||
|  |         { | ||
|  |             return impl::to_longest_alternative<alternative<A, B> >:: | ||
|  |                 convert(alt); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  |     const longest_parser_gen longest_d = longest_parser_gen(); | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  shortest_alternative class | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     struct shortest_parser_gen; | ||
|  | 
 | ||
|  |     template <typename A, typename B> | ||
|  |     struct shortest_alternative | ||
|  |     :   public binary<A, B, parser<shortest_alternative<A, B> > > | ||
|  |     { | ||
|  |         typedef shortest_alternative<A, B>      self_t; | ||
|  |         typedef binary_parser_category          parser_category_t; | ||
|  |         typedef shortest_parser_gen             parser_generator_t; | ||
|  |         typedef binary<A, B, parser<self_t> >   base_t; | ||
|  | 
 | ||
|  |         shortest_alternative(A const& a, B const& b) | ||
|  |         : base_t(a, b) {} | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         typename parser_result<self_t, ScannerT>::type | ||
|  |         parse(ScannerT const& scan) const | ||
|  |         { | ||
|  |             typedef typename parser_result<self_t, ScannerT>::type result_t; | ||
|  |             typename ScannerT::iterator_t save = scan.first; | ||
|  |             result_t l = this->left().parse(scan); | ||
|  |             std::swap(scan.first, save); | ||
|  |             result_t r = this->right().parse(scan); | ||
|  | 
 | ||
|  |             if (l || r) | ||
|  |             { | ||
|  |                 if ((l.length() < r.length() && l) || !r) | ||
|  |                 { | ||
|  |                     scan.first = save; | ||
|  |                     return l; | ||
|  |                 } | ||
|  |                 return r; | ||
|  |             } | ||
|  | 
 | ||
|  |             return scan.no_match(); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  |     struct shortest_parser_gen | ||
|  |     { | ||
|  |         template <typename A, typename B> | ||
|  |         struct result { | ||
|  | 
 | ||
|  |             typedef typename | ||
|  |                 impl::to_shortest_alternative<alternative<A, B> >::result_t | ||
|  |             type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         template <typename A, typename B> | ||
|  |         static typename | ||
|  |         impl::to_shortest_alternative<alternative<A, B> >::result_t | ||
|  |         generate(alternative<A, B> const& alt) | ||
|  |         { | ||
|  |             return impl::to_shortest_alternative<alternative<A, B> >:: | ||
|  |                 convert(alt); | ||
|  |         } | ||
|  | 
 | ||
|  |         //'generate' for binary composite | ||
|  |         template <typename A, typename B> | ||
|  |         static | ||
|  |         shortest_alternative<A, B> | ||
|  |         generate(A const &left, B const &right) | ||
|  |         { | ||
|  |             return shortest_alternative<A, B>(left, right); | ||
|  |         } | ||
|  | 
 | ||
|  |         template <typename A, typename B> | ||
|  |         typename impl::to_shortest_alternative<alternative<A, B> >::result_t | ||
|  |         operator[](alternative<A, B> const& alt) const | ||
|  |         { | ||
|  |             return impl::to_shortest_alternative<alternative<A, B> >:: | ||
|  |                 convert(alt); | ||
|  |         } | ||
|  |     }; | ||
|  | 
 | ||
|  |     const shortest_parser_gen shortest_d = shortest_parser_gen(); | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  min_bounded class | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     template <typename BoundsT> | ||
|  |     struct min_bounded_gen; | ||
|  | 
 | ||
|  |     template <typename ParserT, typename BoundsT> | ||
|  |     struct min_bounded | ||
|  |     :   public unary<ParserT, parser<min_bounded<ParserT, BoundsT> > > | ||
|  |     { | ||
|  |         typedef min_bounded<ParserT, BoundsT>   self_t; | ||
|  |         typedef unary_parser_category           parser_category_t; | ||
|  |         typedef min_bounded_gen<BoundsT>        parser_generator_t; | ||
|  |         typedef unary<ParserT, parser<self_t> > base_t; | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         struct result | ||
|  |         { | ||
|  |             typedef typename parser_result<ParserT, ScannerT>::type type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         min_bounded(ParserT const& p, BoundsT const& min__) | ||
|  |         : base_t(p) | ||
|  |         , min_(min__) {} | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         typename parser_result<self_t, ScannerT>::type | ||
|  |         parse(ScannerT const& scan) const | ||
|  |         { | ||
|  |             typedef typename parser_result<self_t, ScannerT>::type result_t; | ||
|  |             result_t hit = this->subject().parse(scan); | ||
|  |             if (hit.has_valid_attribute() && hit.value() < min_) | ||
|  |                 return scan.no_match(); | ||
|  |             return hit; | ||
|  |         } | ||
|  | 
 | ||
|  |         BoundsT min_; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template <typename BoundsT> | ||
|  |     struct min_bounded_gen | ||
|  |     { | ||
|  |         min_bounded_gen(BoundsT const& min__) | ||
|  |         : min_(min__) {} | ||
|  | 
 | ||
|  |         template <typename DerivedT> | ||
|  |         min_bounded<DerivedT, BoundsT> | ||
|  |         operator[](parser<DerivedT> const& p) const | ||
|  |         { return min_bounded<DerivedT, BoundsT>(p.derived(), min_); } | ||
|  | 
 | ||
|  |         BoundsT min_; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template <typename BoundsT> | ||
|  |     inline min_bounded_gen<BoundsT> | ||
|  |     min_limit_d(BoundsT const& min_) | ||
|  |     { return min_bounded_gen<BoundsT>(min_); } | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  max_bounded class | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     template <typename BoundsT> | ||
|  |     struct max_bounded_gen; | ||
|  | 
 | ||
|  |     template <typename ParserT, typename BoundsT> | ||
|  |     struct max_bounded | ||
|  |     :   public unary<ParserT, parser<max_bounded<ParserT, BoundsT> > > | ||
|  |     { | ||
|  |         typedef max_bounded<ParserT, BoundsT>   self_t; | ||
|  |         typedef unary_parser_category           parser_category_t; | ||
|  |         typedef max_bounded_gen<BoundsT>        parser_generator_t; | ||
|  |         typedef unary<ParserT, parser<self_t> > base_t; | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         struct result | ||
|  |         { | ||
|  |             typedef typename parser_result<ParserT, ScannerT>::type type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         max_bounded(ParserT const& p, BoundsT const& max__) | ||
|  |         : base_t(p) | ||
|  |         , max_(max__) {} | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         typename parser_result<self_t, ScannerT>::type | ||
|  |         parse(ScannerT const& scan) const | ||
|  |         { | ||
|  |             typedef typename parser_result<self_t, ScannerT>::type result_t; | ||
|  |             result_t hit = this->subject().parse(scan); | ||
|  |             if (hit.has_valid_attribute() && hit.value() > max_) | ||
|  |                 return scan.no_match(); | ||
|  |             return hit; | ||
|  |         } | ||
|  | 
 | ||
|  |         BoundsT max_; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template <typename BoundsT> | ||
|  |     struct max_bounded_gen | ||
|  |     { | ||
|  |         max_bounded_gen(BoundsT const& max__) | ||
|  |         : max_(max__) {} | ||
|  | 
 | ||
|  |         template <typename DerivedT> | ||
|  |         max_bounded<DerivedT, BoundsT> | ||
|  |         operator[](parser<DerivedT> const& p) const | ||
|  |         { return max_bounded<DerivedT, BoundsT>(p.derived(), max_); } | ||
|  | 
 | ||
|  |         BoundsT max_; | ||
|  |     }; | ||
|  | 
 | ||
|  |     ////////////////////////////////// | ||
|  |     template <typename BoundsT> | ||
|  |     inline max_bounded_gen<BoundsT> | ||
|  |     max_limit_d(BoundsT const& max_) | ||
|  |     { return max_bounded_gen<BoundsT>(max_); } | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  bounded class | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     template <typename BoundsT> | ||
|  |     struct bounded_gen; | ||
|  | 
 | ||
|  |     template <typename ParserT, typename BoundsT> | ||
|  |     struct bounded | ||
|  |     :   public unary<ParserT, parser<bounded<ParserT, BoundsT> > > | ||
|  |     { | ||
|  |         typedef bounded<ParserT, BoundsT>       self_t; | ||
|  |         typedef unary_parser_category           parser_category_t; | ||
|  |         typedef bounded_gen<BoundsT>            parser_generator_t; | ||
|  |         typedef unary<ParserT, parser<self_t> > base_t; | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         struct result | ||
|  |         { | ||
|  |             typedef typename parser_result<ParserT, ScannerT>::type type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         bounded(ParserT const& p, BoundsT const& min__, BoundsT const& max__) | ||
|  |         : base_t(p) | ||
|  |         , min_(min__) | ||
|  |         , max_(max__) {} | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         typename parser_result<self_t, ScannerT>::type | ||
|  |         parse(ScannerT const& scan) const | ||
|  |         { | ||
|  |             typedef typename parser_result<self_t, ScannerT>::type result_t; | ||
|  |             result_t hit = this->subject().parse(scan); | ||
|  |             if (hit.has_valid_attribute() && | ||
|  |                 (hit.value() < min_ || hit.value() > max_)) | ||
|  |                     return scan.no_match(); | ||
|  |             return hit; | ||
|  |         } | ||
|  | 
 | ||
|  |         BoundsT min_, max_; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template <typename BoundsT> | ||
|  |     struct bounded_gen | ||
|  |     { | ||
|  |         bounded_gen(BoundsT const& min__, BoundsT const& max__) | ||
|  |         : min_(min__) | ||
|  |         , max_(max__) {} | ||
|  | 
 | ||
|  |         template <typename DerivedT> | ||
|  |         bounded<DerivedT, BoundsT> | ||
|  |         operator[](parser<DerivedT> const& p) const | ||
|  |         { return bounded<DerivedT, BoundsT>(p.derived(), min_, max_); } | ||
|  | 
 | ||
|  |         BoundsT min_, max_; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template <typename BoundsT> | ||
|  |     inline bounded_gen<BoundsT> | ||
|  |     limit_d(BoundsT const& min_, BoundsT const& max_) | ||
|  |     { return bounded_gen<BoundsT>(min_, max_); } | ||
|  | 
 | ||
|  | BOOST_SPIRIT_CLASSIC_NAMESPACE_END | ||
|  | 
 | ||
|  | }} // namespace BOOST_SPIRIT_CLASSIC_NS | ||
|  | 
 | ||
|  | #endif | ||
|  | 
 |