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