as_action.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // as_action.hpp
  3. //
  4. // Copyright 2008 Eric Niebler.
  5. // Copyright 2008 David Jenkins.
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See
  8. // accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_ACTION_HPP_EAN_04_05_2007
  11. #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_ACTION_HPP_EAN_04_05_2007
  12. // MS compatible compilers support #pragma once
  13. #if defined(_MSC_VER)
  14. # pragma once
  15. #endif
  16. #include <boost/mpl/sizeof.hpp>
  17. #include <boost/mpl/min_max.hpp>
  18. #include <boost/mpl/apply_wrap.hpp>
  19. #include <boost/xpressive/detail/detail_fwd.hpp>
  20. #include <boost/xpressive/detail/core/matcher/attr_end_matcher.hpp>
  21. #include <boost/xpressive/detail/static/static.hpp>
  22. #include <boost/xpressive/detail/static/transforms/as_quantifier.hpp>
  23. #include <boost/proto/core.hpp>
  24. #include <boost/proto/transform/arg.hpp>
  25. #include <boost/proto/transform/call.hpp>
  26. #include <boost/proto/transform/make.hpp>
  27. #include <boost/proto/transform/when.hpp>
  28. #include <boost/proto/transform/fold.hpp>
  29. #include <boost/proto/transform/fold_tree.hpp>
  30. namespace boost { namespace xpressive { namespace detail
  31. {
  32. ///////////////////////////////////////////////////////////////////////////////
  33. // read_attr
  34. // Placeholder that knows the slot number of an attribute as well as the type
  35. // of the object stored in it.
  36. template<typename Nbr, typename Matcher>
  37. struct read_attr
  38. {
  39. typedef Nbr nbr_type;
  40. typedef Matcher matcher_type;
  41. static Nbr nbr() { return Nbr(); }
  42. };
  43. template<typename Nbr, typename Matcher>
  44. struct read_attr<Nbr, Matcher &>
  45. {
  46. typedef Nbr nbr_type;
  47. typedef Matcher matcher_type;
  48. };
  49. }}}
  50. namespace boost { namespace xpressive { namespace grammar_detail
  51. {
  52. ///////////////////////////////////////////////////////////////////////////////
  53. // FindAttr
  54. // Look for patterns like (a1= terminal<RHS>) and return the type of the RHS.
  55. template<typename Nbr>
  56. struct FindAttr
  57. : or_<
  58. // Ignore nested actions, because attributes are scoped
  59. when< subscript<_, _>, _state >
  60. , when< terminal<_>, _state >
  61. , when< proto::assign<terminal<detail::attribute_placeholder<Nbr> >, _>, call<_value(_right)> >
  62. , otherwise< fold<_, _state, FindAttr<Nbr> > >
  63. >
  64. {};
  65. ///////////////////////////////////////////////////////////////////////////////
  66. // as_read_attr
  67. // For patterns like (a1 = RHS)[ref(i) = a1], transform to
  68. // (a1 = RHS)[ref(i) = read_attr<1, RHS>] so that when reading the attribute
  69. // we know what type is stored in the attribute slot.
  70. struct as_read_attr : proto::transform<as_read_attr>
  71. {
  72. template<typename Expr, typename State, typename Data>
  73. struct impl : proto::transform_impl<Expr, State, Data>
  74. {
  75. typedef typename impl::expr expr_type;
  76. typedef
  77. typename FindAttr<typename expr_type::proto_child0::nbr_type>::template impl<
  78. State
  79. , mpl::void_
  80. , int
  81. >::result_type
  82. attr_type;
  83. typedef
  84. typename proto::terminal<
  85. detail::read_attr<
  86. typename expr_type::proto_child0::nbr_type
  87. , BOOST_PROTO_UNCVREF(attr_type)
  88. >
  89. >::type
  90. result_type;
  91. result_type operator ()(proto::ignore, proto::ignore, proto::ignore) const
  92. {
  93. result_type that = {{}};
  94. return that;
  95. }
  96. };
  97. };
  98. ///////////////////////////////////////////////////////////////////////////////
  99. // DeepCopy
  100. // Turn all refs into values, and also bind all attribute placeholders with
  101. // the types from which they are being assigned.
  102. struct DeepCopy
  103. : or_<
  104. when< terminal<detail::attribute_placeholder<_> >, as_read_attr>
  105. , when< terminal<_>, proto::_deep_copy>
  106. , otherwise< nary_expr<_, vararg<DeepCopy> > >
  107. >
  108. {};
  109. ///////////////////////////////////////////////////////////////////////////////
  110. // attr_nbr
  111. // For an attribute placeholder, return the attribute's slot number.
  112. struct attr_nbr : proto::transform<attr_nbr>
  113. {
  114. template<typename Expr, typename State, typename Data>
  115. struct impl : proto::transform_impl<Expr, State, Data>
  116. {
  117. typedef typename impl::expr expr_type;
  118. typedef typename expr_type::proto_child0::nbr_type::type result_type;
  119. };
  120. };
  121. struct max_attr;
  122. ///////////////////////////////////////////////////////////////////////////////
  123. // MaxAttr
  124. // In an action (rx)[act], find the largest attribute slot being used.
  125. struct MaxAttr
  126. : or_<
  127. when< terminal<detail::attribute_placeholder<_> >, attr_nbr>
  128. , when< terminal<_>, make<mpl::int_<0> > >
  129. // Ignore nested actions, because attributes are scoped:
  130. , when< subscript<_, _>, make<mpl::int_<0> > >
  131. , otherwise< fold<_, make<mpl::int_<0> >, max_attr> >
  132. >
  133. {};
  134. ///////////////////////////////////////////////////////////////////////////////
  135. // max_attr
  136. // Take the maximum of the current attr slot number and the state.
  137. struct max_attr : proto::transform<max_attr>
  138. {
  139. template<typename Expr, typename State, typename Data>
  140. struct impl : proto::transform_impl<Expr, State, Data>
  141. {
  142. typedef
  143. typename mpl::max<
  144. typename impl::state
  145. , typename MaxAttr::template impl<Expr, State, Data>::result_type
  146. >::type
  147. result_type;
  148. };
  149. };
  150. ///////////////////////////////////////////////////////////////////////////////
  151. // as_attr_matcher
  152. // turn a1=matcher into attr_matcher<Matcher>(1)
  153. struct as_attr_matcher : proto::transform<as_attr_matcher>
  154. {
  155. template<typename Expr, typename State, typename Data>
  156. struct impl : proto::transform_impl<Expr, State, Data>
  157. {
  158. typedef typename impl::expr expr_type;
  159. typedef typename impl::data data_type;
  160. typedef
  161. detail::attr_matcher<
  162. typename proto::result_of::value<typename expr_type::proto_child1>::type
  163. , typename data_type::traits_type
  164. , typename data_type::icase_type
  165. >
  166. result_type;
  167. result_type operator ()(
  168. typename impl::expr_param expr
  169. , typename impl::state_param
  170. , typename impl::data_param data
  171. ) const
  172. {
  173. return result_type(
  174. proto::value(proto::left(expr)).nbr()
  175. , proto::value(proto::right(expr))
  176. , data.traits()
  177. );
  178. }
  179. };
  180. };
  181. ///////////////////////////////////////////////////////////////////////////////
  182. // add_attrs
  183. // Wrap an expression in attr_begin_matcher/attr_end_matcher pair
  184. struct add_attrs : proto::transform<add_attrs>
  185. {
  186. template<typename Expr, typename State, typename Data>
  187. struct impl : proto::transform_impl<Expr, State, Data>
  188. {
  189. typedef
  190. detail::attr_begin_matcher<
  191. typename MaxAttr::template impl<Expr, mpl::int_<0>, int>::result_type
  192. >
  193. begin_type;
  194. typedef typename impl::expr expr_type;
  195. typedef
  196. typename shift_right<
  197. typename terminal<begin_type>::type
  198. , typename shift_right<
  199. Expr
  200. , terminal<detail::attr_end_matcher>::type
  201. >::type
  202. >::type
  203. result_type;
  204. result_type operator ()(
  205. typename impl::expr_param expr
  206. , typename impl::state_param
  207. , typename impl::data_param
  208. ) const
  209. {
  210. begin_type begin;
  211. detail::attr_end_matcher end;
  212. result_type that = {{begin}, {expr, {end}}};
  213. return that;
  214. }
  215. };
  216. };
  217. ///////////////////////////////////////////////////////////////////////////////
  218. // InsertAttrs
  219. struct InsertAttrs
  220. : if_<MaxAttr, add_attrs, _>
  221. {};
  222. ///////////////////////////////////////////////////////////////////////////////
  223. // CheckAssertion
  224. struct CheckAssertion
  225. : proto::function<terminal<detail::check_tag>, _>
  226. {};
  227. ///////////////////////////////////////////////////////////////////////////////
  228. // action_transform
  229. // Turn A[B] into (mark_begin(n) >> A >> mark_end(n) >> action_matcher<B>(n))
  230. // If A and B use attributes, wrap the above expression in
  231. // a attr_begin_matcher<Count> / attr_end_matcher pair, where Count is
  232. // the number of attribute slots used by the pattern/action.
  233. struct as_action : proto::transform<as_action>
  234. {
  235. template<typename Expr, typename State, typename Data>
  236. struct impl : proto::transform_impl<Expr, State, Data>
  237. {
  238. typedef typename proto::result_of::left<Expr>::type expr_type;
  239. typedef typename proto::result_of::right<Expr>::type action_type;
  240. typedef
  241. typename DeepCopy::impl<action_type, expr_type, int>::result_type
  242. action_copy_type;
  243. typedef
  244. typename InsertMark::impl<expr_type, State, Data>::result_type
  245. marked_expr_type;
  246. typedef
  247. typename mpl::if_c<
  248. proto::matches<action_type, CheckAssertion>::value
  249. , detail::predicate_matcher<action_copy_type>
  250. , detail::action_matcher<action_copy_type>
  251. >::type
  252. matcher_type;
  253. typedef
  254. typename proto::shift_right<
  255. marked_expr_type
  256. , typename proto::terminal<matcher_type>::type
  257. >::type
  258. no_attr_type;
  259. typedef
  260. typename InsertAttrs::impl<no_attr_type, State, Data>::result_type
  261. result_type;
  262. result_type operator ()(
  263. typename impl::expr_param expr
  264. , typename impl::state_param state
  265. , typename impl::data_param data
  266. ) const
  267. {
  268. int dummy = 0;
  269. marked_expr_type marked_expr =
  270. InsertMark::impl<expr_type, State, Data>()(proto::left(expr), state, data);
  271. no_attr_type that = {
  272. marked_expr
  273. , {
  274. matcher_type(
  275. DeepCopy::impl<action_type, expr_type, int>()(
  276. proto::right(expr)
  277. , proto::left(expr)
  278. , dummy
  279. )
  280. , proto::value(proto::left(marked_expr)).mark_number_
  281. )
  282. }
  283. };
  284. return InsertAttrs::impl<no_attr_type, State, Data>()(that, state, data);
  285. }
  286. };
  287. };
  288. }}}
  289. #endif