123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 |
- /*=============================================================================
- Copyright (c) 2002-2003 Hartmut Kaiser
- http://spirit.sourceforge.net/
- Use, modification and distribution is subject to 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_IPP
- #define BOOST_SPIRIT_REFACTORING_IPP
- ///////////////////////////////////////////////////////////////////////////////
- namespace boost { namespace spirit {
- BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
- ///////////////////////////////////////////////////////////////////////////////
- //
- // The struct 'self_nested_refactoring' is used to indicate, that the
- // refactoring algorithm should be 'self-nested'.
- //
- // The struct 'non_nested_refactoring' is used to indicate, that no nesting
- // of refactoring algorithms is reqired.
- //
- ///////////////////////////////////////////////////////////////////////////////
- struct non_nested_refactoring { typedef non_nested_refactoring embed_t; };
- struct self_nested_refactoring { typedef self_nested_refactoring embed_t; };
- ///////////////////////////////////////////////////////////////////////////////
- namespace impl {
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Helper templates for refactoring parsers
- //
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////
- //
- // refactor the left unary operand of a binary parser
- //
- // The refactoring should be done only if the left operand is an
- // unary_parser_category parser.
- //
- ///////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////
- template <typename CategoryT>
- struct refactor_unary_nested {
- template <
- typename ParserT, typename NestedT,
- typename ScannerT, typename BinaryT
- >
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &, ScannerT const& scan, BinaryT const& binary,
- NestedT const& /*nested_d*/)
- {
- return binary.parse(scan);
- }
- };
- template <>
- struct refactor_unary_nested<unary_parser_category> {
- template <
- typename ParserT, typename ScannerT, typename BinaryT,
- typename NestedT
- >
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &, ScannerT const& scan, BinaryT const& binary,
- NestedT const& nested_d)
- {
- typedef typename BinaryT::parser_generator_t op_t;
- typedef
- typename BinaryT::left_t::parser_generator_t
- unary_t;
- return
- unary_t::generate(
- nested_d[
- op_t::generate(binary.left().subject(), binary.right())
- ]
- ).parse(scan);
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename CategoryT>
- struct refactor_unary_non_nested {
- template <typename ParserT, typename ScannerT, typename BinaryT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &, ScannerT const& scan, BinaryT const& binary)
- {
- return binary.parse(scan);
- }
- };
- template <>
- struct refactor_unary_non_nested<unary_parser_category> {
- template <typename ParserT, typename ScannerT, typename BinaryT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &, ScannerT const& scan, BinaryT const& binary)
- {
- typedef typename BinaryT::parser_generator_t op_t;
- typedef
- typename BinaryT::left_t::parser_generator_t
- unary_t;
- return unary_t::generate(
- op_t::generate(binary.left().subject(), binary.right())
- ).parse(scan);
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename NestedT>
- struct refactor_unary_type {
- template <typename ParserT, typename ScannerT, typename BinaryT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary,
- NestedT const& nested_d)
- {
- typedef
- typename BinaryT::left_t::parser_category_t
- parser_category_t;
- return refactor_unary_nested<parser_category_t>::
- parse(p, scan, binary, nested_d);
- }
- };
- template <>
- struct refactor_unary_type<non_nested_refactoring> {
- template <typename ParserT, typename ScannerT, typename BinaryT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary,
- non_nested_refactoring const&)
- {
- typedef
- typename BinaryT::left_t::parser_category_t
- parser_category_t;
- return refactor_unary_non_nested<parser_category_t>::
- parse(p, scan, binary);
- }
- };
- template <>
- struct refactor_unary_type<self_nested_refactoring> {
- template <typename ParserT, typename ScannerT, typename BinaryT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary,
- self_nested_refactoring const &nested_tag)
- {
- typedef
- typename BinaryT::left_t::parser_category_t
- parser_category_t;
- typedef typename ParserT::parser_generator_t parser_generator_t;
- parser_generator_t nested_d(nested_tag);
- return refactor_unary_nested<parser_category_t>::
- parse(p, scan, binary, nested_d);
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- //
- // refactor the action on the left operand of a binary parser
- //
- // The refactoring should be done only if the left operand is an
- // action_parser_category parser.
- //
- ///////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////
- template <typename CategoryT>
- struct refactor_action_nested {
- template <
- typename ParserT, typename ScannerT, typename BinaryT,
- typename NestedT
- >
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &, ScannerT const& scan, BinaryT const& binary,
- NestedT const& nested_d)
- {
- return nested_d[binary].parse(scan);
- }
- };
- template <>
- struct refactor_action_nested<action_parser_category> {
- template <
- typename ParserT, typename ScannerT, typename BinaryT,
- typename NestedT
- >
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &, ScannerT const& scan, BinaryT const& binary,
- NestedT const& nested_d)
- {
- typedef typename BinaryT::parser_generator_t binary_gen_t;
- return (
- nested_d[
- binary_gen_t::generate(
- binary.left().subject(),
- binary.right()
- )
- ][binary.left().predicate()]
- ).parse(scan);
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename CategoryT>
- struct refactor_action_non_nested {
- template <typename ParserT, typename ScannerT, typename BinaryT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &, ScannerT const& scan, BinaryT const& binary)
- {
- return binary.parse(scan);
- }
- };
- template <>
- struct refactor_action_non_nested<action_parser_category> {
- template <typename ParserT, typename ScannerT, typename BinaryT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &, ScannerT const& scan, BinaryT const& binary)
- {
- typedef typename BinaryT::parser_generator_t binary_gen_t;
- return (
- binary_gen_t::generate(
- binary.left().subject(),
- binary.right()
- )[binary.left().predicate()]
- ).parse(scan);
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename NestedT>
- struct refactor_action_type {
- template <typename ParserT, typename ScannerT, typename BinaryT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary,
- NestedT const& nested_d)
- {
- typedef
- typename BinaryT::left_t::parser_category_t
- parser_category_t;
- return refactor_action_nested<parser_category_t>::
- parse(p, scan, binary, nested_d);
- }
- };
- template <>
- struct refactor_action_type<non_nested_refactoring> {
- template <typename ParserT, typename ScannerT, typename BinaryT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary,
- non_nested_refactoring const&)
- {
- typedef
- typename BinaryT::left_t::parser_category_t
- parser_category_t;
- return refactor_action_non_nested<parser_category_t>::
- parse(p, scan, binary);
- }
- };
- template <>
- struct refactor_action_type<self_nested_refactoring> {
- template <typename ParserT, typename ScannerT, typename BinaryT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary,
- self_nested_refactoring const &nested_tag)
- {
- typedef typename ParserT::parser_generator_t parser_generator_t;
- typedef
- typename BinaryT::left_t::parser_category_t
- parser_category_t;
- parser_generator_t nested_d(nested_tag);
- return refactor_action_nested<parser_category_t>::
- parse(p, scan, binary, nested_d);
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- //
- // refactor the action attached to a binary parser
- //
- // The refactoring should be done only if the given parser is an
- // binary_parser_category parser.
- //
- ///////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////
- template <typename CategoryT>
- struct attach_action_nested {
- template <
- typename ParserT, typename ScannerT, typename ActionT,
- typename NestedT
- >
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &, ScannerT const& scan, ActionT const &action,
- NestedT const& /*nested_d*/)
- {
- return action.parse(scan);
- }
- };
- template <>
- struct attach_action_nested<binary_parser_category> {
- template <
- typename ParserT, typename ScannerT, typename ActionT,
- typename NestedT
- >
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &, ScannerT const& scan, ActionT const &action,
- NestedT const& nested_d)
- {
- typedef
- typename ActionT::subject_t::parser_generator_t
- binary_gen_t;
- return (
- binary_gen_t::generate(
- nested_d[action.subject().left()[action.predicate()]],
- nested_d[action.subject().right()[action.predicate()]]
- )
- ).parse(scan);
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename CategoryT>
- struct attach_action_non_nested {
- template <typename ParserT, typename ScannerT, typename ActionT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &, ScannerT const& scan, ActionT const &action)
- {
- return action.parse(scan);
- }
- };
- template <>
- struct attach_action_non_nested<binary_parser_category> {
- template <typename ParserT, typename ScannerT, typename ActionT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &, ScannerT const& scan, ActionT const &action)
- {
- typedef
- typename ActionT::subject_t::parser_generator_t
- binary_gen_t;
- return (
- binary_gen_t::generate(
- action.subject().left()[action.predicate()],
- action.subject().right()[action.predicate()]
- )
- ).parse(scan);
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename NestedT>
- struct attach_action_type {
- template <typename ParserT, typename ScannerT, typename ActionT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &p, ScannerT const& scan, ActionT const& action,
- NestedT const& nested_d)
- {
- typedef
- typename ActionT::subject_t::parser_category_t
- parser_category_t;
- return attach_action_nested<parser_category_t>::
- parse(p, scan, action, nested_d);
- }
- };
- template <>
- struct attach_action_type<non_nested_refactoring> {
- template <typename ParserT, typename ScannerT, typename ActionT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &p, ScannerT const& scan, ActionT const &action,
- non_nested_refactoring const&)
- {
- typedef
- typename ActionT::subject_t::parser_category_t
- parser_category_t;
- return attach_action_non_nested<parser_category_t>::
- parse(p, scan, action);
- }
- };
- template <>
- struct attach_action_type<self_nested_refactoring> {
- template <typename ParserT, typename ScannerT, typename ActionT>
- static typename parser_result<ParserT, ScannerT>::type
- parse(ParserT const &p, ScannerT const& scan, ActionT const &action,
- self_nested_refactoring const& nested_tag)
- {
- typedef typename ParserT::parser_generator_t parser_generator_t;
- typedef
- typename ActionT::subject_t::parser_category_t
- parser_category_t;
- parser_generator_t nested_d(nested_tag);
- return attach_action_nested<parser_category_t>::
- parse(p, scan, action, nested_d);
- }
- };
- } // namespace impl
- ///////////////////////////////////////////////////////////////////////////////
- BOOST_SPIRIT_CLASSIC_NAMESPACE_END
- }} // namespace boost::spirit
- #endif
|