/////////////////////////////////////////////////////////////////////////////// | |
// as_quantifier.hpp | |
// | |
// Copyright 2008 Eric Niebler. Distributed under 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_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007 | |
#define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007 | |
// MS compatible compilers support #pragma once | |
#if defined(_MSC_VER) && (_MSC_VER >= 1020) | |
# pragma once | |
#endif | |
#include <boost/mpl/assert.hpp> | |
#include <boost/type_traits/is_same.hpp> | |
#include <boost/xpressive/detail/detail_fwd.hpp> | |
#include <boost/xpressive/detail/static/static.hpp> | |
#include <boost/proto/core.hpp> | |
namespace boost { namespace xpressive { namespace detail | |
{ | |
/////////////////////////////////////////////////////////////////////////////// | |
// generic_quant_tag | |
template<uint_t Min, uint_t Max> | |
struct generic_quant_tag | |
{ | |
typedef mpl::integral_c<uint_t, Min> min_type; | |
typedef mpl::integral_c<uint_t, Max> max_type; | |
}; | |
}}} | |
namespace boost { namespace xpressive { namespace grammar_detail | |
{ | |
using detail::uint_t; | |
/////////////////////////////////////////////////////////////////////////////// | |
// min_type / max_type | |
template<typename Tag> | |
struct min_type : Tag::min_type {}; | |
template<> | |
struct min_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, 1> {}; | |
template<> | |
struct min_type<proto::tag::dereference> : mpl::integral_c<uint_t, 0> {}; | |
template<> | |
struct min_type<proto::tag::logical_not> : mpl::integral_c<uint_t, 0> {}; | |
template<typename Tag> | |
struct max_type : Tag::max_type {}; | |
template<> | |
struct max_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, UINT_MAX-1> {}; | |
template<> | |
struct max_type<proto::tag::dereference> : mpl::integral_c<uint_t, UINT_MAX-1> {}; | |
template<> | |
struct max_type<proto::tag::logical_not> : mpl::integral_c<uint_t, 1> {}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// as_simple_quantifier | |
template<typename Grammar, typename Greedy, typename Callable = proto::callable> | |
struct as_simple_quantifier : proto::transform<as_simple_quantifier<Grammar, Greedy, Callable> > | |
{ | |
template<typename Expr, typename State, typename Data> | |
struct impl : proto::transform_impl<Expr, State, Data> | |
{ | |
typedef | |
typename proto::result_of::child<Expr>::type | |
arg_type; | |
typedef | |
typename Grammar::template impl<arg_type, detail::true_xpression, Data>::result_type | |
xpr_type; | |
typedef | |
detail::simple_repeat_matcher<xpr_type, Greedy> | |
matcher_type; | |
typedef | |
typename proto::terminal<matcher_type>::type | |
result_type; | |
result_type operator ()( | |
typename impl::expr_param expr | |
, typename impl::state_param | |
, typename impl::data_param data | |
) const | |
{ | |
xpr_type xpr = typename Grammar::template impl<arg_type, detail::true_xpression, Data>()( | |
proto::child(expr) | |
, detail::true_xpression() | |
, data | |
); | |
typedef typename impl::expr expr_type; | |
matcher_type matcher( | |
xpr | |
, (uint_t)min_type<typename expr_type::proto_tag>::value | |
, (uint_t)max_type<typename expr_type::proto_tag>::value | |
, xpr.get_width().value() | |
); | |
return result_type::make(matcher); | |
} | |
}; | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// add_hidden_mark | |
struct add_hidden_mark : proto::transform<add_hidden_mark> | |
{ | |
template<typename Expr, typename State, typename Data> | |
struct impl : proto::transform_impl<Expr, State, Data> | |
{ | |
typedef typename impl::expr expr_type; | |
typedef | |
typename shift_right< | |
terminal<detail::mark_begin_matcher>::type | |
, typename shift_right< | |
Expr | |
, terminal<detail::mark_end_matcher>::type | |
>::type | |
>::type | |
result_type; | |
result_type operator ()( | |
typename impl::expr_param expr | |
, typename impl::state_param | |
, typename impl::data_param data | |
) const | |
{ | |
// we're inserting a hidden mark ... so grab the next hidden mark number. | |
int mark_nbr = data.get_hidden_mark(); | |
detail::mark_begin_matcher begin(mark_nbr); | |
detail::mark_end_matcher end(mark_nbr); | |
result_type that = {{begin}, {expr, {end}}}; | |
return that; | |
} | |
}; | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// InsertMark | |
struct InsertMark | |
: or_< | |
when<proto::assign<detail::basic_mark_tag, _>, _> | |
, otherwise<add_hidden_mark> | |
> | |
{}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// as_default_quantifier_impl | |
template<typename Greedy, uint_t Min, uint_t Max> | |
struct as_default_quantifier_impl : proto::transform<as_default_quantifier_impl<Greedy, Min, Max> > | |
{ | |
template<typename Expr, typename State, typename Data> | |
struct impl : proto::transform_impl<Expr, State, Data> | |
{ | |
typedef | |
typename proto::result_of::child<Expr>::type | |
xpr_type; | |
typedef | |
typename InsertMark::impl<xpr_type, State, Data>::result_type | |
marked_sub_type; | |
typedef | |
typename shift_right< | |
terminal<detail::repeat_begin_matcher>::type | |
, typename shift_right< | |
marked_sub_type | |
, typename terminal<detail::repeat_end_matcher<Greedy> >::type | |
>::type | |
>::type | |
result_type; | |
result_type operator ()( | |
typename impl::expr_param expr | |
, typename impl::state_param state | |
, typename impl::data_param data | |
) const | |
{ | |
// Ensure this sub-expression is book-ended with mark matchers | |
marked_sub_type marked_sub = | |
InsertMark::impl<xpr_type, State, Data>()(proto::child(expr), state, data); | |
// Get the mark_number from the begin_mark_matcher | |
int mark_number = proto::value(proto::left(marked_sub)).mark_number_; | |
BOOST_ASSERT(0 != mark_number); | |
typedef typename impl::expr expr_type; | |
uint_t min_ = (uint_t)min_type<typename expr_type::proto_tag>(); | |
uint_t max_ = (uint_t)max_type<typename expr_type::proto_tag>(); | |
detail::repeat_begin_matcher begin(mark_number); | |
detail::repeat_end_matcher<Greedy> end(mark_number, min_, max_); | |
result_type that = {{begin}, {marked_sub, {end}}}; | |
return that; | |
} | |
}; | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// optional_tag | |
template<typename Greedy> | |
struct optional_tag | |
{}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// as_default_optional | |
template<typename Grammar, typename Greedy, typename Callable = proto::callable> | |
struct as_default_optional : proto::transform<as_default_optional<Grammar, Greedy, Callable> > | |
{ | |
template<typename Expr, typename State, typename Data> | |
struct impl : proto::transform_impl<Expr, State, Data> | |
{ | |
typedef | |
detail::alternate_end_xpression | |
end_xpr; | |
typedef | |
detail::optional_matcher< | |
typename Grammar::template impl<Expr, end_xpr, Data>::result_type | |
, Greedy | |
> | |
result_type; | |
result_type operator ()( | |
typename impl::expr_param expr | |
, typename impl::state_param | |
, typename impl::data_param data | |
) const | |
{ | |
return result_type( | |
typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data) | |
); | |
} | |
}; | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// as_mark_optional | |
template<typename Grammar, typename Greedy, typename Callable = proto::callable> | |
struct as_mark_optional : proto::transform<as_mark_optional<Grammar, Greedy, Callable> > | |
{ | |
template<typename Expr, typename State, typename Data> | |
struct impl : proto::transform_impl<Expr, State, Data> | |
{ | |
typedef | |
detail::alternate_end_xpression | |
end_xpr; | |
typedef | |
detail::optional_mark_matcher< | |
typename Grammar::template impl<Expr, end_xpr, Data>::result_type | |
, Greedy | |
> | |
result_type; | |
result_type operator ()( | |
typename impl::expr_param expr | |
, typename impl::state_param | |
, typename impl::data_param data | |
) const | |
{ | |
int mark_number = proto::value(proto::left(expr)).mark_number_; | |
return result_type( | |
typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data) | |
, mark_number | |
); | |
} | |
}; | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// IsMarkerOrRepeater | |
struct IsMarkerOrRepeater | |
: or_< | |
shift_right<terminal<detail::repeat_begin_matcher>, _> | |
, assign<terminal<detail::mark_placeholder>, _> | |
> | |
{}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// as_optional | |
template<typename Grammar, typename Greedy> | |
struct as_optional | |
: or_< | |
when<IsMarkerOrRepeater, as_mark_optional<Grammar, Greedy> > | |
, otherwise<as_default_optional<Grammar, Greedy> > | |
> | |
{}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// make_optional_ | |
template<typename Greedy, typename Callable = proto::callable> | |
struct make_optional_ : proto::transform<make_optional_<Greedy, Callable> > | |
{ | |
template<typename Expr, typename State, typename Data> | |
struct impl : proto::transform_impl<Expr, State, Data> | |
{ | |
typedef typename impl::expr expr_type; | |
typedef | |
typename unary_expr< | |
optional_tag<Greedy> | |
, Expr | |
>::type | |
result_type; | |
result_type operator ()( | |
typename impl::expr_param expr | |
, typename impl::state_param | |
, typename impl::data_param | |
) const | |
{ | |
result_type that = {expr}; | |
return that; | |
} | |
}; | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// as_default_quantifier_impl | |
template<typename Greedy, uint_t Max> | |
struct as_default_quantifier_impl<Greedy, 0, Max> | |
: call<make_optional_<Greedy>(as_default_quantifier_impl<Greedy, 1, Max>)> | |
{}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// as_default_quantifier_impl | |
template<typename Greedy> | |
struct as_default_quantifier_impl<Greedy, 0, 1> | |
: call<make_optional_<Greedy>(_child)> | |
{}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// as_default_quantifier | |
template<typename Greedy, typename Callable = proto::callable> | |
struct as_default_quantifier : proto::transform<as_default_quantifier<Greedy, Callable> > | |
{ | |
template<typename Expr, typename State, typename Data> | |
struct impl : proto::transform_impl<Expr, State, Data> | |
{ | |
typedef typename impl::expr expr_type; | |
typedef | |
as_default_quantifier_impl< | |
Greedy | |
, min_type<typename expr_type::proto_tag>::value | |
, max_type<typename expr_type::proto_tag>::value | |
> | |
other; | |
typedef | |
typename other::template impl<Expr, State, Data>::result_type | |
result_type; | |
result_type operator ()( | |
typename impl::expr_param expr | |
, typename impl::state_param state | |
, typename impl::data_param data | |
) const | |
{ | |
return typename other::template impl<Expr, State, Data>()(expr, state, data); | |
} | |
}; | |
}; | |
}}} | |
#endif |