/*============================================================================= 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 #include #include #include #include #include #include namespace boost { namespace spirit { BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN /////////////////////////////////////////////////////////////////////////// // // contiguous class // /////////////////////////////////////////////////////////////////////////// struct lexeme_parser_gen; template struct contiguous : public unary > > { typedef contiguous self_t; typedef unary_parser_category parser_category_t; typedef lexeme_parser_gen parser_generator_t; typedef unary > base_t; template struct result { typedef typename parser_result::type type; }; contiguous(ParserT const& p) : base_t(p) {} template typename parser_result::type parse(ScannerT const& scan) const { typedef typename parser_result::type result_t; return impl::contiguous_parser_parse (this->subject(), scan, scan); } }; struct lexeme_parser_gen { template struct result { typedef contiguous type; }; template static contiguous generate(parser const& subject) { return contiguous(subject.derived()); } template contiguous operator[](parser const& subject) const { return contiguous(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 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::type type; }; /////////////////////////////////////////////////////////////////////////// // // inhibit_case_iteration_policy class // /////////////////////////////////////////////////////////////////////////// template struct inhibit_case_iteration_policy : public BaseT { typedef BaseT base_t; inhibit_case_iteration_policy() : BaseT() {} template inhibit_case_iteration_policy(PolicyT const& other) : BaseT(other) {} template CharT filter(CharT ch) const { return impl::tolower_(ch); } }; /////////////////////////////////////////////////////////////////////////// // // inhibit_case class // /////////////////////////////////////////////////////////////////////////// struct inhibit_case_parser_gen; template struct inhibit_case : public unary > > { typedef inhibit_case self_t; typedef unary_parser_category parser_category_t; typedef inhibit_case_parser_gen parser_generator_t; typedef unary > base_t; template struct result { typedef typename parser_result::type type; }; inhibit_case(ParserT const& p) : base_t(p) {} template typename parser_result::type parse(ScannerT const& scan) const { typedef typename parser_result::type result_t; return impl::inhibit_case_parser_parse (this->subject(), scan, scan); } }; template 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 > generate(char const* str) { return inhibit_case >(str); } static inhibit_case > generate(wchar_t const* str) { return inhibit_case >(str); } static inhibit_case > generate(char ch) { return inhibit_case >(ch); } static inhibit_case > generate(wchar_t ch) { return inhibit_case >(ch); } template static inhibit_case generate(parser const& subject) { return inhibit_case(subject.derived()); } inhibit_case > operator[](char const* str) const { return inhibit_case >(str); } inhibit_case > operator[](wchar_t const* str) const { return inhibit_case >(str); } inhibit_case > operator[](char ch) const { return inhibit_case >(ch); } inhibit_case > operator[](wchar_t ch) const { return inhibit_case >(ch); } template inhibit_case operator[](parser const& subject) const { return inhibit_case(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 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::type type; }; /////////////////////////////////////////////////////////////////////////// // // longest_alternative class // /////////////////////////////////////////////////////////////////////////// struct longest_parser_gen; template struct longest_alternative : public binary > > { typedef longest_alternative self_t; typedef binary_parser_category parser_category_t; typedef longest_parser_gen parser_generator_t; typedef binary > base_t; longest_alternative(A const& a, B const& b) : base_t(a, b) {} template typename parser_result::type parse(ScannerT const& scan) const { typedef typename parser_result::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 struct result { typedef typename impl::to_longest_alternative >::result_t type; }; template static typename impl::to_longest_alternative >::result_t generate(alternative const& alt) { return impl::to_longest_alternative >:: convert(alt); } //'generate' for binary composite template static longest_alternative generate(A const &left, B const &right) { return longest_alternative(left, right); } template typename impl::to_longest_alternative >::result_t operator[](alternative const& alt) const { return impl::to_longest_alternative >:: convert(alt); } }; const longest_parser_gen longest_d = longest_parser_gen(); /////////////////////////////////////////////////////////////////////////// // // shortest_alternative class // /////////////////////////////////////////////////////////////////////////// struct shortest_parser_gen; template struct shortest_alternative : public binary > > { typedef shortest_alternative self_t; typedef binary_parser_category parser_category_t; typedef shortest_parser_gen parser_generator_t; typedef binary > base_t; shortest_alternative(A const& a, B const& b) : base_t(a, b) {} template typename parser_result::type parse(ScannerT const& scan) const { typedef typename parser_result::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 struct result { typedef typename impl::to_shortest_alternative >::result_t type; }; template static typename impl::to_shortest_alternative >::result_t generate(alternative const& alt) { return impl::to_shortest_alternative >:: convert(alt); } //'generate' for binary composite template static shortest_alternative generate(A const &left, B const &right) { return shortest_alternative(left, right); } template typename impl::to_shortest_alternative >::result_t operator[](alternative const& alt) const { return impl::to_shortest_alternative >:: convert(alt); } }; const shortest_parser_gen shortest_d = shortest_parser_gen(); /////////////////////////////////////////////////////////////////////////// // // min_bounded class // /////////////////////////////////////////////////////////////////////////// template struct min_bounded_gen; template struct min_bounded : public unary > > { typedef min_bounded self_t; typedef unary_parser_category parser_category_t; typedef min_bounded_gen parser_generator_t; typedef unary > base_t; template struct result { typedef typename parser_result::type type; }; min_bounded(ParserT const& p, BoundsT const& min__) : base_t(p) , min_(min__) {} template typename parser_result::type parse(ScannerT const& scan) const { typedef typename parser_result::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 struct min_bounded_gen { min_bounded_gen(BoundsT const& min__) : min_(min__) {} template min_bounded operator[](parser const& p) const { return min_bounded(p.derived(), min_); } BoundsT min_; }; template inline min_bounded_gen min_limit_d(BoundsT const& min_) { return min_bounded_gen(min_); } /////////////////////////////////////////////////////////////////////////// // // max_bounded class // /////////////////////////////////////////////////////////////////////////// template struct max_bounded_gen; template struct max_bounded : public unary > > { typedef max_bounded self_t; typedef unary_parser_category parser_category_t; typedef max_bounded_gen parser_generator_t; typedef unary > base_t; template struct result { typedef typename parser_result::type type; }; max_bounded(ParserT const& p, BoundsT const& max__) : base_t(p) , max_(max__) {} template typename parser_result::type parse(ScannerT const& scan) const { typedef typename parser_result::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 struct max_bounded_gen { max_bounded_gen(BoundsT const& max__) : max_(max__) {} template max_bounded operator[](parser const& p) const { return max_bounded(p.derived(), max_); } BoundsT max_; }; ////////////////////////////////// template inline max_bounded_gen max_limit_d(BoundsT const& max_) { return max_bounded_gen(max_); } /////////////////////////////////////////////////////////////////////////// // // bounded class // /////////////////////////////////////////////////////////////////////////// template struct bounded_gen; template struct bounded : public unary > > { typedef bounded self_t; typedef unary_parser_category parser_category_t; typedef bounded_gen parser_generator_t; typedef unary > base_t; template struct result { typedef typename parser_result::type type; }; bounded(ParserT const& p, BoundsT const& min__, BoundsT const& max__) : base_t(p) , min_(min__) , max_(max__) {} template typename parser_result::type parse(ScannerT const& scan) const { typedef typename parser_result::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 struct bounded_gen { bounded_gen(BoundsT const& min__, BoundsT const& max__) : min_(min__) , max_(max__) {} template bounded operator[](parser const& p) const { return bounded(p.derived(), min_, max_); } BoundsT min_, max_; }; template inline bounded_gen limit_d(BoundsT const& min_, BoundsT const& max_) { return bounded_gen(min_, max_); } BOOST_SPIRIT_CLASSIC_NAMESPACE_END }} // namespace BOOST_SPIRIT_CLASSIC_NS #endif