| /*============================================================================= |
| 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 |
| |