as_quantifier.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // as_quantifier.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_QUANTIFIER_HPP_EAN_04_01_2007
  8. #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007
  9. // MS compatible compilers support #pragma once
  10. #if defined(_MSC_VER)
  11. # pragma once
  12. #endif
  13. #include <boost/mpl/assert.hpp>
  14. #include <boost/type_traits/is_same.hpp>
  15. #include <boost/xpressive/detail/detail_fwd.hpp>
  16. #include <boost/xpressive/detail/static/static.hpp>
  17. #include <boost/proto/core.hpp>
  18. namespace boost { namespace xpressive { namespace detail
  19. {
  20. ///////////////////////////////////////////////////////////////////////////////
  21. // generic_quant_tag
  22. template<uint_t Min, uint_t Max>
  23. struct generic_quant_tag
  24. {
  25. typedef mpl::integral_c<uint_t, Min> min_type;
  26. typedef mpl::integral_c<uint_t, Max> max_type;
  27. };
  28. }}}
  29. namespace boost { namespace xpressive { namespace grammar_detail
  30. {
  31. using detail::uint_t;
  32. ///////////////////////////////////////////////////////////////////////////////
  33. // min_type / max_type
  34. template<typename Tag>
  35. struct min_type : Tag::min_type {};
  36. template<>
  37. struct min_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, 1> {};
  38. template<>
  39. struct min_type<proto::tag::dereference> : mpl::integral_c<uint_t, 0> {};
  40. template<>
  41. struct min_type<proto::tag::logical_not> : mpl::integral_c<uint_t, 0> {};
  42. template<typename Tag>
  43. struct max_type : Tag::max_type {};
  44. template<>
  45. struct max_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, UINT_MAX-1> {};
  46. template<>
  47. struct max_type<proto::tag::dereference> : mpl::integral_c<uint_t, UINT_MAX-1> {};
  48. template<>
  49. struct max_type<proto::tag::logical_not> : mpl::integral_c<uint_t, 1> {};
  50. ///////////////////////////////////////////////////////////////////////////////
  51. // as_simple_quantifier
  52. template<typename Grammar, typename Greedy, typename Callable = proto::callable>
  53. struct as_simple_quantifier : proto::transform<as_simple_quantifier<Grammar, Greedy, Callable> >
  54. {
  55. template<typename Expr, typename State, typename Data>
  56. struct impl : proto::transform_impl<Expr, State, Data>
  57. {
  58. typedef
  59. typename proto::result_of::child<Expr>::type
  60. arg_type;
  61. typedef
  62. typename Grammar::template impl<arg_type, detail::true_xpression, Data>::result_type
  63. xpr_type;
  64. typedef
  65. detail::simple_repeat_matcher<xpr_type, Greedy>
  66. matcher_type;
  67. typedef
  68. typename proto::terminal<matcher_type>::type
  69. result_type;
  70. result_type operator ()(
  71. typename impl::expr_param expr
  72. , typename impl::state_param
  73. , typename impl::data_param data
  74. ) const
  75. {
  76. xpr_type xpr = typename Grammar::template impl<arg_type, detail::true_xpression, Data>()(
  77. proto::child(expr)
  78. , detail::true_xpression()
  79. , data
  80. );
  81. typedef typename impl::expr expr_type;
  82. matcher_type matcher(
  83. xpr
  84. , (uint_t)min_type<typename expr_type::proto_tag>::value
  85. , (uint_t)max_type<typename expr_type::proto_tag>::value
  86. , xpr.get_width().value()
  87. );
  88. return result_type::make(matcher);
  89. }
  90. };
  91. };
  92. ///////////////////////////////////////////////////////////////////////////////
  93. // add_hidden_mark
  94. struct add_hidden_mark : proto::transform<add_hidden_mark>
  95. {
  96. template<typename Expr, typename State, typename Data>
  97. struct impl : proto::transform_impl<Expr, State, Data>
  98. {
  99. typedef typename impl::expr expr_type;
  100. typedef
  101. typename shift_right<
  102. terminal<detail::mark_begin_matcher>::type
  103. , typename shift_right<
  104. Expr
  105. , terminal<detail::mark_end_matcher>::type
  106. >::type
  107. >::type
  108. result_type;
  109. result_type operator ()(
  110. typename impl::expr_param expr
  111. , typename impl::state_param
  112. , typename impl::data_param data
  113. ) const
  114. {
  115. // we're inserting a hidden mark ... so grab the next hidden mark number.
  116. int mark_nbr = data.get_hidden_mark();
  117. detail::mark_begin_matcher begin(mark_nbr);
  118. detail::mark_end_matcher end(mark_nbr);
  119. result_type that = {{begin}, {expr, {end}}};
  120. return that;
  121. }
  122. };
  123. };
  124. ///////////////////////////////////////////////////////////////////////////////
  125. // InsertMark
  126. struct InsertMark
  127. : or_<
  128. when<proto::assign<detail::basic_mark_tag, _>, _>
  129. , otherwise<add_hidden_mark>
  130. >
  131. {};
  132. ///////////////////////////////////////////////////////////////////////////////
  133. // as_default_quantifier_impl
  134. template<typename Greedy, uint_t Min, uint_t Max>
  135. struct as_default_quantifier_impl : proto::transform<as_default_quantifier_impl<Greedy, Min, Max> >
  136. {
  137. template<typename Expr, typename State, typename Data>
  138. struct impl : proto::transform_impl<Expr, State, Data>
  139. {
  140. typedef
  141. typename proto::result_of::child<Expr>::type
  142. xpr_type;
  143. typedef
  144. typename InsertMark::impl<xpr_type, State, Data>::result_type
  145. marked_sub_type;
  146. typedef
  147. typename shift_right<
  148. terminal<detail::repeat_begin_matcher>::type
  149. , typename shift_right<
  150. marked_sub_type
  151. , typename terminal<detail::repeat_end_matcher<Greedy> >::type
  152. >::type
  153. >::type
  154. result_type;
  155. result_type operator ()(
  156. typename impl::expr_param expr
  157. , typename impl::state_param state
  158. , typename impl::data_param data
  159. ) const
  160. {
  161. // Ensure this sub-expression is book-ended with mark matchers
  162. marked_sub_type marked_sub =
  163. InsertMark::impl<xpr_type, State, Data>()(proto::child(expr), state, data);
  164. // Get the mark_number from the begin_mark_matcher
  165. int mark_number = proto::value(proto::left(marked_sub)).mark_number_;
  166. BOOST_ASSERT(0 != mark_number);
  167. typedef typename impl::expr expr_type;
  168. uint_t min_ = (uint_t)min_type<typename expr_type::proto_tag>();
  169. uint_t max_ = (uint_t)max_type<typename expr_type::proto_tag>();
  170. detail::repeat_begin_matcher begin(mark_number);
  171. detail::repeat_end_matcher<Greedy> end(mark_number, min_, max_);
  172. result_type that = {{begin}, {marked_sub, {end}}};
  173. return that;
  174. }
  175. };
  176. };
  177. ///////////////////////////////////////////////////////////////////////////////
  178. // optional_tag
  179. template<typename Greedy>
  180. struct optional_tag
  181. {};
  182. ///////////////////////////////////////////////////////////////////////////////
  183. // as_default_optional
  184. template<typename Grammar, typename Greedy, typename Callable = proto::callable>
  185. struct as_default_optional : proto::transform<as_default_optional<Grammar, Greedy, Callable> >
  186. {
  187. template<typename Expr, typename State, typename Data>
  188. struct impl : proto::transform_impl<Expr, State, Data>
  189. {
  190. typedef
  191. detail::alternate_end_xpression
  192. end_xpr;
  193. typedef
  194. detail::optional_matcher<
  195. typename Grammar::template impl<Expr, end_xpr, Data>::result_type
  196. , Greedy
  197. >
  198. result_type;
  199. result_type operator ()(
  200. typename impl::expr_param expr
  201. , typename impl::state_param
  202. , typename impl::data_param data
  203. ) const
  204. {
  205. return result_type(
  206. typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data)
  207. );
  208. }
  209. };
  210. };
  211. ///////////////////////////////////////////////////////////////////////////////
  212. // as_mark_optional
  213. template<typename Grammar, typename Greedy, typename Callable = proto::callable>
  214. struct as_mark_optional : proto::transform<as_mark_optional<Grammar, Greedy, Callable> >
  215. {
  216. template<typename Expr, typename State, typename Data>
  217. struct impl : proto::transform_impl<Expr, State, Data>
  218. {
  219. typedef
  220. detail::alternate_end_xpression
  221. end_xpr;
  222. typedef
  223. detail::optional_mark_matcher<
  224. typename Grammar::template impl<Expr, end_xpr, Data>::result_type
  225. , Greedy
  226. >
  227. result_type;
  228. result_type operator ()(
  229. typename impl::expr_param expr
  230. , typename impl::state_param
  231. , typename impl::data_param data
  232. ) const
  233. {
  234. int mark_number = proto::value(proto::left(expr)).mark_number_;
  235. return result_type(
  236. typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data)
  237. , mark_number
  238. );
  239. }
  240. };
  241. };
  242. ///////////////////////////////////////////////////////////////////////////////
  243. // IsMarkerOrRepeater
  244. struct IsMarkerOrRepeater
  245. : or_<
  246. shift_right<terminal<detail::repeat_begin_matcher>, _>
  247. , assign<terminal<detail::mark_placeholder>, _>
  248. >
  249. {};
  250. ///////////////////////////////////////////////////////////////////////////////
  251. // as_optional
  252. template<typename Grammar, typename Greedy>
  253. struct as_optional
  254. : or_<
  255. when<IsMarkerOrRepeater, as_mark_optional<Grammar, Greedy> >
  256. , otherwise<as_default_optional<Grammar, Greedy> >
  257. >
  258. {};
  259. ///////////////////////////////////////////////////////////////////////////////
  260. // make_optional_
  261. template<typename Greedy, typename Callable = proto::callable>
  262. struct make_optional_ : proto::transform<make_optional_<Greedy, Callable> >
  263. {
  264. template<typename Expr, typename State, typename Data>
  265. struct impl : proto::transform_impl<Expr, State, Data>
  266. {
  267. typedef typename impl::expr expr_type;
  268. typedef
  269. typename unary_expr<
  270. optional_tag<Greedy>
  271. , Expr
  272. >::type
  273. result_type;
  274. result_type operator ()(
  275. typename impl::expr_param expr
  276. , typename impl::state_param
  277. , typename impl::data_param
  278. ) const
  279. {
  280. result_type that = {expr};
  281. return that;
  282. }
  283. };
  284. };
  285. ///////////////////////////////////////////////////////////////////////////////
  286. // as_default_quantifier_impl
  287. template<typename Greedy, uint_t Max>
  288. struct as_default_quantifier_impl<Greedy, 0, Max>
  289. : call<make_optional_<Greedy>(as_default_quantifier_impl<Greedy, 1, Max>)>
  290. {};
  291. ///////////////////////////////////////////////////////////////////////////////
  292. // as_default_quantifier_impl
  293. template<typename Greedy>
  294. struct as_default_quantifier_impl<Greedy, 0, 1>
  295. : call<make_optional_<Greedy>(_child)>
  296. {};
  297. ///////////////////////////////////////////////////////////////////////////////
  298. // as_default_quantifier
  299. template<typename Greedy, typename Callable = proto::callable>
  300. struct as_default_quantifier : proto::transform<as_default_quantifier<Greedy, Callable> >
  301. {
  302. template<typename Expr, typename State, typename Data>
  303. struct impl : proto::transform_impl<Expr, State, Data>
  304. {
  305. typedef typename impl::expr expr_type;
  306. typedef
  307. as_default_quantifier_impl<
  308. Greedy
  309. , min_type<typename expr_type::proto_tag>::value
  310. , max_type<typename expr_type::proto_tag>::value
  311. >
  312. other;
  313. typedef
  314. typename other::template impl<Expr, State, Data>::result_type
  315. result_type;
  316. result_type operator ()(
  317. typename impl::expr_param expr
  318. , typename impl::state_param state
  319. , typename impl::data_param data
  320. ) const
  321. {
  322. return typename other::template impl<Expr, State, Data>()(expr, state, data);
  323. }
  324. };
  325. };
  326. }}}
  327. #endif