/*============================================================================= 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 { /////////////////////////////////////////////////////////////////////////////// // // 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 struct refactor_unary_nested { template < typename ParserT, typename NestedT, typename ScannerT, typename BinaryT > static typename parser_result::type parse(ParserT const &, ScannerT const& scan, BinaryT const& binary, NestedT const& /*nested_d*/) { return binary.parse(scan); } }; template <> struct refactor_unary_nested { template < typename ParserT, typename ScannerT, typename BinaryT, typename NestedT > static typename parser_result::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 struct refactor_unary_non_nested { template static typename parser_result::type parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) { return binary.parse(scan); } }; template <> struct refactor_unary_non_nested { template static typename parser_result::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 struct refactor_unary_type { template static typename parser_result::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:: parse(p, scan, binary, nested_d); } }; template <> struct refactor_unary_type { template static typename parser_result::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:: parse(p, scan, binary); } }; template <> struct refactor_unary_type { template static typename parser_result::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:: 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 struct refactor_action_nested { template < typename ParserT, typename ScannerT, typename BinaryT, typename NestedT > static typename parser_result::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 { template < typename ParserT, typename ScannerT, typename BinaryT, typename NestedT > static typename parser_result::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 struct refactor_action_non_nested { template static typename parser_result::type parse(ParserT const &, ScannerT const& scan, BinaryT const& binary) { return binary.parse(scan); } }; template <> struct refactor_action_non_nested { template static typename parser_result::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 struct refactor_action_type { template static typename parser_result::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:: parse(p, scan, binary, nested_d); } }; template <> struct refactor_action_type { template static typename parser_result::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:: parse(p, scan, binary); } }; template <> struct refactor_action_type { template static typename parser_result::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:: 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 struct attach_action_nested { template < typename ParserT, typename ScannerT, typename ActionT, typename NestedT > static typename parser_result::type parse(ParserT const &, ScannerT const& scan, ActionT const &action, NestedT const& nested_d) { return action.parse(scan); } }; template <> struct attach_action_nested { template < typename ParserT, typename ScannerT, typename ActionT, typename NestedT > static typename parser_result::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 struct attach_action_non_nested { template static typename parser_result::type parse(ParserT const &, ScannerT const& scan, ActionT const &action) { return action.parse(scan); } }; template <> struct attach_action_non_nested { template static typename parser_result::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 struct attach_action_type { template static typename parser_result::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:: parse(p, scan, action, nested_d); } }; template <> struct attach_action_type { template static typename parser_result::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:: parse(p, scan, action); } }; template <> struct attach_action_type { template static typename parser_result::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:: parse(p, scan, action, nested_d); } }; } // namespace impl /////////////////////////////////////////////////////////////////////////////// }} // namespace boost::spirit #endif