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