123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- ///////////////////////////////////////////////////////////////////////////////
- // 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)
- # 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
|