123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- /*=============================================================================
- 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 <boost/static_assert.hpp>
- #include <boost/spirit/home/classic/namespace.hpp>
- #include <boost/spirit/home/classic/meta/as_parser.hpp>
- #include <boost/spirit/home/classic/core/parser.hpp>
- #include <boost/spirit/home/classic/core/composite/composite.hpp>
- #include <boost/spirit/home/classic/meta/impl/refactoring.ipp>
- ///////////////////////////////////////////////////////////////////////////////
- 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 <typename NestedT = non_nested_refactoring>
- class refactor_unary_gen;
- template <typename BinaryT, typename NestedT = non_nested_refactoring>
- class refactor_unary_parser :
- public parser<refactor_unary_parser<BinaryT, NestedT> > {
- public:
- // the parser to refactor has to be at least a binary_parser_category
- // parser
- BOOST_STATIC_ASSERT((
- boost::is_convertible<typename BinaryT::parser_category_t,
- binary_parser_category>::value
- ));
- refactor_unary_parser(BinaryT const& binary_, NestedT const& nested_)
- : binary(binary_), nested(nested_) {}
- typedef refactor_unary_parser<BinaryT, NestedT> self_t;
- typedef refactor_unary_gen<NestedT> parser_generator_t;
- typedef typename BinaryT::left_t::parser_category_t parser_category_t;
- template <typename ScannerT>
- typename parser_result<self_t, ScannerT>::type
- parse(ScannerT const& scan) const
- {
- return impl::refactor_unary_type<NestedT>::
- parse(*this, scan, binary, nested);
- }
- private:
- typename as_parser<BinaryT>::type::embed_t binary;
- typename NestedT::embed_t nested;
- };
- //////////////////////////////////
- template <typename NestedT>
- class refactor_unary_gen {
- public:
- typedef refactor_unary_gen<NestedT> embed_t;
- refactor_unary_gen(NestedT const& nested_ = non_nested_refactoring())
- : nested(nested_) {}
- template <typename ParserT>
- refactor_unary_parser<ParserT, NestedT>
- operator[](parser<ParserT> const& subject) const
- {
- return refactor_unary_parser<ParserT, NestedT>
- (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 <typename NestedT = non_nested_refactoring>
- class refactor_action_gen;
- template <typename BinaryT, typename NestedT = non_nested_refactoring>
- class refactor_action_parser :
- public parser<refactor_action_parser<BinaryT, NestedT> > {
- public:
- // the parser to refactor has to be at least a binary_parser_category
- // parser
- BOOST_STATIC_ASSERT((
- boost::is_convertible<typename BinaryT::parser_category_t,
- binary_parser_category>::value
- ));
- refactor_action_parser(BinaryT const& binary_, NestedT const& nested_)
- : binary(binary_), nested(nested_) {}
- typedef refactor_action_parser<BinaryT, NestedT> self_t;
- typedef refactor_action_gen<NestedT> parser_generator_t;
- typedef typename BinaryT::left_t::parser_category_t parser_category_t;
- template <typename ScannerT>
- typename parser_result<self_t, ScannerT>::type
- parse(ScannerT const& scan) const
- {
- return impl::refactor_action_type<NestedT>::
- parse(*this, scan, binary, nested);
- }
- private:
- typename as_parser<BinaryT>::type::embed_t binary;
- typename NestedT::embed_t nested;
- };
- //////////////////////////////////
- template <typename NestedT>
- class refactor_action_gen {
- public:
- typedef refactor_action_gen<NestedT> embed_t;
- refactor_action_gen(NestedT const& nested_ = non_nested_refactoring())
- : nested(nested_) {}
- template <typename ParserT>
- refactor_action_parser<ParserT, NestedT>
- operator[](parser<ParserT> const& subject) const
- {
- return refactor_action_parser<ParserT, NestedT>
- (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 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 <typename NestedT = non_nested_refactoring>
- class attach_action_gen;
- template <typename ActionT, typename NestedT = non_nested_refactoring>
- class attach_action_parser :
- public parser<attach_action_parser<ActionT, NestedT> > {
- public:
- // the parser to refactor has to be at least a action_parser_category
- // parser
- BOOST_STATIC_ASSERT((
- boost::is_convertible<typename ActionT::parser_category_t,
- action_parser_category>::value
- ));
- attach_action_parser(ActionT const& actor_, NestedT const& nested_)
- : actor(actor_), nested(nested_) {}
- typedef attach_action_parser<ActionT, NestedT> self_t;
- typedef attach_action_gen<NestedT> parser_generator_t;
- typedef typename ActionT::parser_category_t parser_category_t;
- template <typename ScannerT>
- typename parser_result<self_t, ScannerT>::type
- parse(ScannerT const& scan) const
- {
- return impl::attach_action_type<NestedT>::
- parse(*this, scan, actor, nested);
- }
- private:
- typename as_parser<ActionT>::type::embed_t actor;
- typename NestedT::embed_t nested;
- };
- //////////////////////////////////
- template <typename NestedT>
- class attach_action_gen {
- public:
- typedef attach_action_gen<NestedT> embed_t;
- attach_action_gen(NestedT const& nested_ = non_nested_refactoring())
- : nested(nested_) {}
- template <typename ParserT, typename ActionT>
- attach_action_parser<action<ParserT, ActionT>, NestedT>
- operator[](action<ParserT, ActionT> const& actor) const
- {
- return attach_action_parser<action<ParserT, ActionT>, 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
|