blob: 77976276fe391e0fd0e79728d95bab09920b5e46 [file] [log] [blame]
/*=============================================================================
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