as_independent.hpp 6.9 KB

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