| /////////////////////////////////////////////////////////////////////////////// |
| // as_independent.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_INDEPENDENT_HPP_EAN_04_05_2007 |
| #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_INDEPENDENT_HPP_EAN_04_05_2007 |
| |
| // MS compatible compilers support #pragma once |
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
| # pragma once |
| #endif |
| |
| #include <boost/mpl/sizeof.hpp> |
| #include <boost/xpressive/detail/detail_fwd.hpp> |
| #include <boost/xpressive/detail/static/static.hpp> |
| #include <boost/proto/core.hpp> |
| #include <boost/proto/transform/arg.hpp> |
| #include <boost/proto/transform/when.hpp> |
| #include <boost/proto/transform/fold.hpp> |
| #include <boost/proto/transform/fold_tree.hpp> |
| |
| namespace boost { namespace xpressive { namespace detail |
| { |
| struct keeper_tag |
| {}; |
| |
| struct lookahead_tag |
| {}; |
| |
| struct lookbehind_tag |
| {}; |
| }}} |
| |
| namespace boost { namespace xpressive { namespace grammar_detail |
| { |
| // A grammar that only accepts static regexes that |
| // don't have semantic actions. |
| struct NotHasAction |
| : proto::switch_<struct NotHasActionCases> |
| {}; |
| |
| struct NotHasActionCases |
| { |
| template<typename Tag, int Dummy = 0> |
| struct case_ |
| : proto::nary_expr<Tag, proto::vararg<NotHasAction> > |
| {}; |
| |
| template<int Dummy> |
| struct case_<proto::tag::terminal, Dummy> |
| : not_< or_< |
| proto::terminal<detail::tracking_ptr<detail::regex_impl<_> > >, |
| proto::terminal<reference_wrapper<_> > |
| > > |
| {}; |
| |
| template<int Dummy> |
| struct case_<proto::tag::comma, Dummy> |
| : proto::_ // because (set='a','b') can't contain an action |
| {}; |
| |
| template<int Dummy> |
| struct case_<proto::tag::complement, Dummy> |
| : proto::_ // because in ~X, X can't contain an unscoped action |
| {}; |
| |
| template<int Dummy> |
| struct case_<detail::lookahead_tag, Dummy> |
| : proto::_ // because actions in lookaheads are scoped |
| {}; |
| |
| template<int Dummy> |
| struct case_<detail::lookbehind_tag, Dummy> |
| : proto::_ // because actions in lookbehinds are scoped |
| {}; |
| |
| template<int Dummy> |
| struct case_<detail::keeper_tag, Dummy> |
| : proto::_ // because actions in keepers are scoped |
| {}; |
| |
| template<int Dummy> |
| struct case_<proto::tag::subscript, Dummy> |
| : proto::subscript<detail::set_initializer_type, _> |
| {}; // only accept set[...], not actions! |
| }; |
| |
| struct IndependentEndXpression |
| : or_< |
| when<NotHasAction, detail::true_xpression()> |
| , otherwise<detail::independent_end_xpression()> |
| > |
| {}; |
| |
| template<typename Grammar, typename Callable = proto::callable> |
| struct as_lookahead : proto::transform<as_lookahead<Grammar, 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 IndependentEndXpression::impl<arg_type, int, int>::result_type |
| end_xpr_type; |
| |
| typedef |
| typename Grammar::template impl<arg_type, end_xpr_type, Data>::result_type |
| xpr_type; |
| |
| typedef |
| detail::lookahead_matcher<xpr_type> |
| result_type; |
| |
| result_type operator ()( |
| typename impl::expr_param expr |
| , typename impl::state_param |
| , typename impl::data_param data |
| ) const |
| { |
| int i = 0; |
| return result_type( |
| typename Grammar::template impl<arg_type, end_xpr_type, Data>()( |
| proto::child(expr) |
| , IndependentEndXpression::impl<arg_type, int, int>()(proto::child(expr), i, i) |
| , data |
| ) |
| , false |
| ); |
| } |
| }; |
| }; |
| |
| template<typename Grammar, typename Callable = proto::callable> |
| struct as_lookbehind : proto::transform<as_lookbehind<Grammar, 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 IndependentEndXpression::impl<arg_type, int, int>::result_type |
| end_xpr_type; |
| |
| typedef |
| typename Grammar::template impl<arg_type, end_xpr_type, Data>::result_type |
| xpr_type; |
| |
| typedef |
| detail::lookbehind_matcher<xpr_type> |
| result_type; |
| |
| result_type operator ()( |
| typename impl::expr_param expr |
| , typename impl::state_param |
| , typename impl::data_param data |
| ) const |
| { |
| int i = 0; |
| xpr_type expr2 = typename Grammar::template impl<arg_type, end_xpr_type, Data>()( |
| proto::child(expr) |
| , IndependentEndXpression::impl<arg_type, int, int>()(proto::child(expr), i, i) |
| , data |
| ); |
| std::size_t width = expr2.get_width().value(); |
| return result_type(expr2, width, false); |
| } |
| }; |
| }; |
| |
| template<typename Grammar, typename Callable = proto::callable> |
| struct as_keeper : proto::transform<as_keeper<Grammar, 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 IndependentEndXpression::impl<arg_type, int, int>::result_type |
| end_xpr_type; |
| |
| typedef |
| typename Grammar::template impl<arg_type, end_xpr_type, Data>::result_type |
| xpr_type; |
| |
| typedef |
| detail::keeper_matcher<xpr_type> |
| result_type; |
| |
| result_type operator ()( |
| typename impl::expr_param expr |
| , typename impl::state_param |
| , typename impl::data_param data |
| ) const |
| { |
| int i = 0; |
| return result_type( |
| typename Grammar::template impl<arg_type, end_xpr_type, Data>()( |
| proto::child(expr) |
| , IndependentEndXpression::impl<arg_type, int, int>()(proto::child(expr), i, i) |
| , data |
| ) |
| ); |
| } |
| }; |
| }; |
| |
| }}} |
| |
| #endif |