Chris@16: /*============================================================================= Chris@16: Copyright (c) 2002-2003 Joel de Guzman Chris@16: Copyright (c) 2002-2003 Hartmut Kaiser Chris@16: Copyright (c) 2003 Martin Wille Chris@16: http://spirit.sourceforge.net/ 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_PARSER_TRAITS_HPP) Chris@16: #define BOOST_SPIRIT_PARSER_TRAITS_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { namespace spirit { Chris@16: Chris@16: BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // Parser traits templates Chris@16: // Chris@16: // Used to determine the type and several other characteristics of a given Chris@16: // parser type. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The is_parser traits template can be used to tell wether a given Chris@16: // class is a parser. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct is_parser Chris@16: { Chris@16: BOOST_STATIC_CONSTANT(bool, value = Chris@16: (::boost::is_base_and_derived, T>::value)); Chris@16: Chris@16: // [JDG 2/3/03] simplified implementation by Chris@16: // using boost::is_base_and_derived Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The is_unary_composite traits template can be used to tell if a given Chris@16: // parser is a unary parser as for instance kleene_star or optional. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct is_unary_composite { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible< Chris@16: typename UnaryT::parser_category_t, unary_parser_category>::value)); Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The is_acction_parser traits template can be used to tell if a given Chris@16: // parser is a action parser, i.e. it is a composite consisting of a Chris@16: // auxilliary parser and an attached semantic action. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct is_action_parser { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible< Chris@16: typename ActionT::parser_category_t, action_parser_category>::value)); Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The is_binary_composite traits template can be used to tell if a given Chris@16: // parser is a binary parser as for instance sequence or difference. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct is_binary_composite { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible< Chris@16: typename BinaryT::parser_category_t, binary_parser_category>::value)); Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The is_composite_parser traits template can be used to tell if a given Chris@16: // parser is a unary or a binary parser composite type. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct is_composite_parser { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, value = ( Chris@16: ::BOOST_SPIRIT_CLASSIC_NS::is_unary_composite::value || Chris@16: ::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite::value)); Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct is_alternative { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, value = ( Chris@16: ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits::is_alternative)); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_sequence { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, value = ( Chris@16: ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits::is_sequence)); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_sequential_or { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, value = ( Chris@16: ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits::is_sequential_or)); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_intersection { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, value = ( Chris@16: ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits::is_intersection)); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_difference { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, value = ( Chris@16: ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits::is_difference)); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_exclusive_or { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, value = ( Chris@16: ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits::is_exclusive_or)); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_optional { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, value = ( Chris@16: ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits::is_optional)); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_kleene_star { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, value = ( Chris@16: ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits::is_kleene_star)); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_positive { Chris@16: Chris@16: BOOST_STATIC_CONSTANT(bool, value = ( Chris@16: ::BOOST_SPIRIT_CLASSIC_NS::impl::parser_type_traits::is_positive)); Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // Parser extraction templates Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The unary_subject template can be used to return the type of the Chris@16: // parser used as the subject of an unary parser. Chris@16: // If the parser under inspection is not an unary type parser the compilation Chris@16: // will fail. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct unary_subject { Chris@16: Chris@16: BOOST_STATIC_ASSERT(BOOST_SPIRIT_CLASSIC_NS::is_unary_composite::value); Chris@16: typedef typename UnaryT::subject_t type; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The get_unary_subject template function returns the parser object, which Chris@16: // is used as the subject of an unary parser. Chris@16: // If the parser under inspection is not an unary type parser the compilation Chris@16: // will fail. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: inline typename unary_subject::type const & Chris@16: get_unary_subject(UnaryT const &unary_) Chris@16: { Chris@16: BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_unary_composite::value); Chris@16: return unary_.subject(); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The binary_left_subject and binary_right_subject templates can be used to Chris@16: // return the types of the parsers used as the left and right subject of an Chris@16: // binary parser. Chris@16: // If the parser under inspection is not a binary type parser the compilation Chris@16: // will fail. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct binary_left_subject { Chris@16: Chris@16: BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite::value); Chris@16: typedef typename BinaryT::left_t type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct binary_right_subject { Chris@16: Chris@16: BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite::value); Chris@16: typedef typename BinaryT::right_t type; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The get_binary_left_subject and get_binary_right_subject template functions Chris@16: // return the parser object, which is used as the left or right subject of a Chris@16: // binary parser. Chris@16: // If the parser under inspection is not a binary type parser the compilation Chris@16: // will fail. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: inline typename binary_left_subject::type const & Chris@16: get_binary_left_subject(BinaryT const &binary_) Chris@16: { Chris@16: BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite::value); Chris@16: return binary_.left(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename binary_right_subject::type const & Chris@16: get_binary_right_subject(BinaryT const &binary_) Chris@16: { Chris@16: BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_binary_composite::value); Chris@16: return binary_.right(); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The action_subject template can be used to return the type of the Chris@16: // parser used as the subject of an action parser. Chris@16: // If the parser under inspection is not an action type parser the compilation Chris@16: // will fail. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct action_subject { Chris@16: Chris@16: BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_action_parser::value); Chris@16: typedef typename ActionT::subject_t type; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The get_action_subject template function returns the parser object, which Chris@16: // is used as the subject of an action parser. Chris@16: // If the parser under inspection is not an action type parser the compilation Chris@16: // will fail. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: inline typename action_subject::type const & Chris@16: get_action_subject(ActionT const &action_) Chris@16: { Chris@16: BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_action_parser::value); Chris@16: return action_.subject(); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The semantic_action template can be used to return the type of the Chris@16: // attached semantic action of an action parser. Chris@16: // If the parser under inspection is not an action type parser the compilation Chris@16: // will fail. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct semantic_action { Chris@16: Chris@16: BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_action_parser::value); Chris@16: typedef typename ActionT::predicate_t type; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The get_semantic_action template function returns the attached semantic Chris@16: // action of an action parser. Chris@16: // If the parser under inspection is not an action type parser the compilation Chris@16: // will fail. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: inline typename semantic_action::type const & Chris@16: get_semantic_action(ActionT const &action_) Chris@16: { Chris@16: BOOST_STATIC_ASSERT(::BOOST_SPIRIT_CLASSIC_NS::is_action_parser::value); Chris@16: return action_.predicate(); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: BOOST_SPIRIT_CLASSIC_NAMESPACE_END Chris@16: Chris@16: }} // namespace BOOST_SPIRIT_CLASSIC_NS Chris@16: Chris@16: #endif // !defined(BOOST_SPIRIT_PARSER_TRAITS_HPP)