Chris@16: /*============================================================================= Chris@16: Copyright (c) 2001-2011 Joel de Guzman Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ==============================================================================*/ Chris@16: #if !defined(BOOST_SPIRIT_CHAR_PARSER_APR_16_2006_0906AM) Chris@16: #define BOOST_SPIRIT_CHAR_PARSER_APR_16_2006_0906AM Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace spirit Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Enablers Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template <> Chris@16: struct use_operator // enables ~ Chris@16: : mpl::true_ {}; Chris@16: }} Chris@16: Chris@16: namespace boost { namespace spirit { namespace traits // classification Chris@16: { Chris@16: namespace detail Chris@16: { Chris@16: BOOST_MPL_HAS_XXX_TRAIT_DEF(char_parser_id) Chris@16: } Chris@16: Chris@16: template Chris@16: struct is_char_parser : detail::has_char_parser_id {}; Chris@16: }}} Chris@16: Chris@16: namespace boost { namespace spirit { namespace qi Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // The base char_parser Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct char_parser : primitive_parser Chris@16: { Chris@16: typedef Char char_type; Chris@16: struct char_parser_id; Chris@16: Chris@16: // if Attr is unused_type, Derived must supply its own attribute Chris@16: // metafunction Chris@16: template Chris@16: struct attribute Chris@16: { Chris@16: typedef Attr type; Chris@16: }; Chris@16: Chris@16: template Chris@16: bool parse(Iterator& first, Iterator const& last Chris@16: , Context& context, Skipper const& skipper, Attribute& attr_) const Chris@16: { Chris@16: qi::skip_over(first, last, skipper); Chris@16: Chris@16: if (first != last && this->derived().test(*first, context)) Chris@16: { Chris@16: spirit::traits::assign_to(*first, attr_); Chris@16: ++first; Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: Chris@16: // Requirement: p.test(ch, context) -> bool Chris@16: // Chris@16: // ch: character being parsed Chris@16: // context: enclosing rule context Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // negated_char_parser handles ~cp expressions (cp is a char_parser) Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct negated_char_parser : Chris@16: char_parser, typename Positive::char_type> Chris@16: { Chris@16: negated_char_parser(Positive const& positive_) Chris@16: : positive(positive_) {} Chris@16: Chris@16: template Chris@16: bool test(CharParam ch, Context& context) const Chris@16: { Chris@16: return !positive.test(ch, context); Chris@16: } Chris@16: Chris@16: template Chris@16: info what(Context& context) const Chris@16: { Chris@16: return info("not", positive.what(context)); Chris@16: } Chris@16: Chris@16: Positive positive; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Parser generators: make_xxx function (objects) Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: namespace detail Chris@16: { Chris@16: template Chris@16: struct make_negated_char_parser Chris@16: { Chris@16: typedef negated_char_parser result_type; Chris@16: result_type operator()(Positive const& positive) const Chris@16: { Chris@16: return result_type(positive); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct make_negated_char_parser > Chris@16: { Chris@16: typedef Positive result_type; Chris@16: result_type operator()(negated_char_parser const& ncp) const Chris@16: { Chris@16: return ncp.positive; Chris@16: } Chris@16: }; Chris@16: } Chris@16: Chris@16: template Chris@16: struct make_composite Chris@16: { Chris@16: typedef typename Chris@16: fusion::result_of::value_at_c::type Chris@16: subject; Chris@16: Chris@16: BOOST_SPIRIT_ASSERT_MSG(( Chris@16: traits::is_char_parser::value Chris@16: ), subject_is_not_negatable, (subject)); Chris@16: Chris@16: typedef typename Chris@16: detail::make_negated_char_parser::result_type Chris@16: result_type; Chris@16: Chris@16: result_type operator()(Elements const& elements, unused_type) const Chris@16: { Chris@16: return detail::make_negated_char_parser()( Chris@16: fusion::at_c<0>(elements)); Chris@16: } Chris@16: }; Chris@16: }}} Chris@16: Chris@16: #endif