1 /////////////////////////////////////////////////////////////////////////////// 2 // as_independent.hpp 3 // 4 // Copyright 2008 Eric Niebler. Distributed under the Boost 5 // Software License, Version 1.0. (See accompanying file 6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8 #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_INDEPENDENT_HPP_EAN_04_05_2007 9 #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_INDEPENDENT_HPP_EAN_04_05_2007 10 11 // MS compatible compilers support #pragma once 12 #if defined(_MSC_VER) 13 # pragma once 14 #endif 15 16 #include <boost/mpl/sizeof.hpp> 17 #include <boost/xpressive/detail/detail_fwd.hpp> 18 #include <boost/xpressive/detail/static/static.hpp> 19 #include <boost/proto/core.hpp> 20 #include <boost/proto/transform/arg.hpp> 21 #include <boost/proto/transform/when.hpp> 22 #include <boost/proto/transform/fold.hpp> 23 #include <boost/proto/transform/fold_tree.hpp> 24 25 namespace boost { namespace xpressive { namespace detail 26 { 27 struct keeper_tag 28 {}; 29 30 struct lookahead_tag 31 {}; 32 33 struct lookbehind_tag 34 {}; 35 }}} 36 37 namespace boost { namespace xpressive { namespace grammar_detail 38 { 39 // A grammar that only accepts static regexes that 40 // don't have semantic actions. 41 struct NotHasAction 42 : proto::switch_<struct NotHasActionCases> 43 {}; 44 45 struct NotHasActionCases 46 { 47 template<typename Tag, int Dummy = 0> 48 struct case_ 49 : proto::nary_expr<Tag, proto::vararg<NotHasAction> > 50 {}; 51 52 template<int Dummy> 53 struct case_<proto::tag::terminal, Dummy> 54 : not_< or_< 55 proto::terminal<detail::tracking_ptr<detail::regex_impl<_> > >, 56 proto::terminal<reference_wrapper<_> > 57 > > 58 {}; 59 60 template<int Dummy> 61 struct case_<proto::tag::comma, Dummy> 62 : proto::_ // because (set='a','b') can't contain an action 63 {}; 64 65 template<int Dummy> 66 struct case_<proto::tag::complement, Dummy> 67 : proto::_ // because in ~X, X can't contain an unscoped action 68 {}; 69 70 template<int Dummy> 71 struct case_<detail::lookahead_tag, Dummy> 72 : proto::_ // because actions in lookaheads are scoped 73 {}; 74 75 template<int Dummy> 76 struct case_<detail::lookbehind_tag, Dummy> 77 : proto::_ // because actions in lookbehinds are scoped 78 {}; 79 80 template<int Dummy> 81 struct case_<detail::keeper_tag, Dummy> 82 : proto::_ // because actions in keepers are scoped 83 {}; 84 85 template<int Dummy> 86 struct case_<proto::tag::subscript, Dummy> 87 : proto::subscript<detail::set_initializer_type, _> 88 {}; // only accept set[...], not actions! 89 }; 90 91 struct IndependentEndXpression 92 : or_< 93 when<NotHasAction, detail::true_xpression()> 94 , otherwise<detail::independent_end_xpression()> 95 > 96 {}; 97 98 template<typename Grammar, typename Callable = proto::callable> 99 struct as_lookahead : proto::transform<as_lookahead<Grammar, Callable> > 100 { 101 template<typename Expr, typename State, typename Data> 102 struct impl : proto::transform_impl<Expr, State, Data> 103 { 104 typedef typename proto::result_of::child<Expr>::type arg_type; 105 106 typedef 107 typename IndependentEndXpression::impl<arg_type, int, int>::result_type 108 end_xpr_type; 109 110 typedef 111 typename Grammar::template impl<arg_type, end_xpr_type, Data>::result_type 112 xpr_type; 113 114 typedef 115 detail::lookahead_matcher<xpr_type> 116 result_type; 117 operator ()boost::xpressive::grammar_detail::as_lookahead::impl118 result_type operator ()( 119 typename impl::expr_param expr 120 , typename impl::state_param 121 , typename impl::data_param data 122 ) const 123 { 124 int i = 0; 125 return result_type( 126 typename Grammar::template impl<arg_type, end_xpr_type, Data>()( 127 proto::child(expr) 128 , IndependentEndXpression::impl<arg_type, int, int>()(proto::child(expr), i, i) 129 , data 130 ) 131 , false 132 ); 133 } 134 }; 135 }; 136 137 template<typename Grammar, typename Callable = proto::callable> 138 struct as_lookbehind : proto::transform<as_lookbehind<Grammar, Callable> > 139 { 140 template<typename Expr, typename State, typename Data> 141 struct impl : proto::transform_impl<Expr, State, Data> 142 { 143 typedef typename proto::result_of::child<Expr>::type arg_type; 144 145 typedef 146 typename IndependentEndXpression::impl<arg_type, int, int>::result_type 147 end_xpr_type; 148 149 typedef 150 typename Grammar::template impl<arg_type, end_xpr_type, Data>::result_type 151 xpr_type; 152 153 typedef 154 detail::lookbehind_matcher<xpr_type> 155 result_type; 156 operator ()boost::xpressive::grammar_detail::as_lookbehind::impl157 result_type operator ()( 158 typename impl::expr_param expr 159 , typename impl::state_param 160 , typename impl::data_param data 161 ) const 162 { 163 int i = 0; 164 xpr_type expr2 = typename Grammar::template impl<arg_type, end_xpr_type, Data>()( 165 proto::child(expr) 166 , IndependentEndXpression::impl<arg_type, int, int>()(proto::child(expr), i, i) 167 , data 168 ); 169 std::size_t width = expr2.get_width().value(); 170 return result_type(expr2, width, false); 171 } 172 }; 173 }; 174 175 template<typename Grammar, typename Callable = proto::callable> 176 struct as_keeper : proto::transform<as_keeper<Grammar, Callable> > 177 { 178 template<typename Expr, typename State, typename Data> 179 struct impl : proto::transform_impl<Expr, State, Data> 180 { 181 typedef typename proto::result_of::child<Expr>::type arg_type; 182 183 typedef 184 typename IndependentEndXpression::impl<arg_type, int, int>::result_type 185 end_xpr_type; 186 187 typedef 188 typename Grammar::template impl<arg_type, end_xpr_type, Data>::result_type 189 xpr_type; 190 191 typedef 192 detail::keeper_matcher<xpr_type> 193 result_type; 194 operator ()boost::xpressive::grammar_detail::as_keeper::impl195 result_type operator ()( 196 typename impl::expr_param expr 197 , typename impl::state_param 198 , typename impl::data_param data 199 ) const 200 { 201 int i = 0; 202 return result_type( 203 typename Grammar::template impl<arg_type, end_xpr_type, Data>()( 204 proto::child(expr) 205 , IndependentEndXpression::impl<arg_type, int, int>()(proto::child(expr), i, i) 206 , data 207 ) 208 ); 209 } 210 }; 211 }; 212 213 }}} 214 215 #endif 216