/*============================================================================= Copyright (c) 2002-2003 Hartmut Kaiser 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) =============================================================================*/ #ifndef BOOST_SPIRIT_REFACTORING_HPP #define BOOST_SPIRIT_REFACTORING_HPP /////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) #pragma warning(push) #pragma warning(disable:4512) //assignment operator could not be generated #endif /////////////////////////////////////////////////////////////////////////////// // // refactor_unary_parser class // // This helper template allows to attach an unary operation to a newly // constructed parser, which combines the subject of the left operand of // the original given parser (BinaryT) with the right operand of the // original binary parser through the original binary operation and // rewraps the resulting parser with the original unary operator. // // For instance given the parser: // *some_parser - another_parser // // will be refactored to: // *(some_parser - another_parser) // // If the parser to refactor is not a unary parser, no refactoring is done // at all. // // The original parser should be a binary_parser_category parser, // else the compilation will fail // /////////////////////////////////////////////////////////////////////////////// template class refactor_unary_gen; template class refactor_unary_parser : public parser > { public: // the parser to refactor has to be at least a binary_parser_category // parser BOOST_STATIC_ASSERT(( boost::is_convertible::value )); refactor_unary_parser(BinaryT const& binary_, NestedT const& nested_) : binary(binary_), nested(nested_) {} typedef refactor_unary_parser self_t; typedef refactor_unary_gen parser_generator_t; typedef typename BinaryT::left_t::parser_category_t parser_category_t; template typename parser_result::type parse(ScannerT const& scan) const { return impl::refactor_unary_type:: parse(*this, scan, binary, nested); } private: typename as_parser::type::embed_t binary; typename NestedT::embed_t nested; }; ////////////////////////////////// template class refactor_unary_gen { public: typedef refactor_unary_gen embed_t; refactor_unary_gen(NestedT const& nested_ = non_nested_refactoring()) : nested(nested_) {} template refactor_unary_parser operator[](parser const& subject) const { return refactor_unary_parser (subject.derived(), nested); } private: typename NestedT::embed_t nested; }; const refactor_unary_gen<> refactor_unary_d = refactor_unary_gen<>(); /////////////////////////////////////////////////////////////////////////////// // // refactor_action_parser class // // This helper template allows to attach an action taken from the left // operand of the given binary parser to a newly constructed parser, // which combines the subject of the left operand of the original binary // parser with the right operand of the original binary parser by means of // the original binary operator parser. // // For instance the parser: // some_parser[some_attached_functor] - another_parser // // will be refactored to: // (some_parser - another_parser)[some_attached_functor] // // If the left operand to refactor is not an action parser, no refactoring // is done at all. // // The original parser should be a binary_parser_category parser, // else the compilation will fail // /////////////////////////////////////////////////////////////////////////////// template class refactor_action_gen; template class refactor_action_parser : public parser > { public: // the parser to refactor has to be at least a binary_parser_category // parser BOOST_STATIC_ASSERT(( boost::is_convertible::value )); refactor_action_parser(BinaryT const& binary_, NestedT const& nested_) : binary(binary_), nested(nested_) {} typedef refactor_action_parser self_t; typedef refactor_action_gen parser_generator_t; typedef typename BinaryT::left_t::parser_category_t parser_category_t; template typename parser_result::type parse(ScannerT const& scan) const { return impl::refactor_action_type:: parse(*this, scan, binary, nested); } private: typename as_parser::type::embed_t binary; typename NestedT::embed_t nested; }; ////////////////////////////////// template class refactor_action_gen { public: typedef refactor_action_gen embed_t; refactor_action_gen(NestedT const& nested_ = non_nested_refactoring()) : nested(nested_) {} template refactor_action_parser operator[](parser const& subject) const { return refactor_action_parser (subject.derived(), nested); } private: typename NestedT::embed_t nested; }; const refactor_action_gen<> refactor_action_d = refactor_action_gen<>(); /////////////////////////////////////////////////////////////////////////////// // // attach_action_parser class // // This helper template allows to attach an action given separately // to to all parsers, out of which the given parser is constructed and // reconstructs a new parser having the same structure. // // For instance the parser: // (some_parser >> another_parser)[some_attached_functor] // // will be refactored to: // some_parser[some_attached_functor] // >> another_parser[some_attached_functor] // // The original parser should be a action_parser_category parser, // else the compilation will fail // // If the parser, to which the action is attached is not an binary parser, // no refactoring is done at all. // /////////////////////////////////////////////////////////////////////////////// template class attach_action_gen; template class attach_action_parser : public parser > { public: // the parser to refactor has to be at least a action_parser_category // parser BOOST_STATIC_ASSERT(( boost::is_convertible::value )); attach_action_parser(ActionT const& actor_, NestedT const& nested_) : actor(actor_), nested(nested_) {} typedef attach_action_parser self_t; typedef attach_action_gen parser_generator_t; typedef typename ActionT::parser_category_t parser_category_t; template typename parser_result::type parse(ScannerT const& scan) const { return impl::attach_action_type:: parse(*this, scan, actor, nested); } private: typename as_parser::type::embed_t actor; typename NestedT::embed_t nested; }; ////////////////////////////////// template class attach_action_gen { public: typedef attach_action_gen embed_t; attach_action_gen(NestedT const& nested_ = non_nested_refactoring()) : nested(nested_) {} template attach_action_parser, NestedT> operator[](action const& actor) const { return attach_action_parser, NestedT> (actor, nested); } private: typename NestedT::embed_t nested; }; const attach_action_gen<> attach_action_d = attach_action_gen<>(); #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) #pragma warning(pop) #endif /////////////////////////////////////////////////////////////////////////////// BOOST_SPIRIT_CLASSIC_NAMESPACE_END }} // namespace BOOST_SPIRIT_CLASSIC_NS #endif // BOOST_SPIRIT_REFACTORING_HPP