grammar.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // grammar.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_GRAMMAR_HPP_EAN_11_12_2006
  8. #define BOOST_XPRESSIVE_DETAIL_STATIC_GRAMMAR_HPP_EAN_11_12_2006
  9. // MS compatible compilers support #pragma once
  10. #if defined(_MSC_VER)
  11. # pragma once
  12. #endif
  13. #include <boost/mpl/if.hpp>
  14. #include <boost/mpl/bool.hpp>
  15. #include <boost/mpl/assert.hpp>
  16. #include <boost/proto/core.hpp>
  17. #include <boost/xpressive/detail/static/is_pure.hpp>
  18. #include <boost/xpressive/detail/static/transforms/as_matcher.hpp>
  19. #include <boost/xpressive/detail/static/transforms/as_alternate.hpp>
  20. #include <boost/xpressive/detail/static/transforms/as_sequence.hpp>
  21. #include <boost/xpressive/detail/static/transforms/as_quantifier.hpp>
  22. #include <boost/xpressive/detail/static/transforms/as_marker.hpp>
  23. #include <boost/xpressive/detail/static/transforms/as_set.hpp>
  24. #include <boost/xpressive/detail/static/transforms/as_independent.hpp>
  25. #include <boost/xpressive/detail/static/transforms/as_modifier.hpp>
  26. #include <boost/xpressive/detail/static/transforms/as_inverse.hpp>
  27. #include <boost/xpressive/detail/static/transforms/as_action.hpp>
  28. #include <boost/xpressive/detail/detail_fwd.hpp>
  29. #define BOOST_XPRESSIVE_CHECK_REGEX(Expr, Char)\
  30. BOOST_MPL_ASSERT\
  31. ((\
  32. typename boost::mpl::if_c<\
  33. boost::xpressive::is_valid_regex<Expr, Char>::value\
  34. , boost::mpl::true_\
  35. , boost::xpressive::INVALID_REGULAR_EXPRESSION\
  36. >::type\
  37. ));
  38. //////////////////////////////////////////////////////////////////////////
  39. //**********************************************************************//
  40. //* << NOTE! >> *//
  41. //* *//
  42. //* Whenever you change this grammar, you MUST also make corresponding *//
  43. //* changes to width_of.hpp and is_pure.hpp. *//
  44. //* *//
  45. //**********************************************************************//
  46. //////////////////////////////////////////////////////////////////////////
  47. namespace boost { namespace xpressive
  48. {
  49. template<typename Char>
  50. struct Grammar;
  51. template<typename Char>
  52. struct ActionableGrammar;
  53. namespace grammar_detail
  54. {
  55. ///////////////////////////////////////////////////////////////////////////
  56. // CharLiteral
  57. template<typename Char>
  58. struct CharLiteral;
  59. ///////////////////////////////////////////////////////////////////////////
  60. // ListSet
  61. template<typename Char>
  62. struct ListSet;
  63. ///////////////////////////////////////////////////////////////////////////
  64. // as_repeat
  65. template<typename Char, typename Gram, typename Greedy>
  66. struct as_repeat
  67. : if_<
  68. make<detail::use_simple_repeat<_child, Char> >
  69. , as_simple_quantifier<Gram, Greedy>
  70. , as_default_quantifier<Greedy>
  71. >
  72. {};
  73. ///////////////////////////////////////////////////////////////////////////
  74. // NonGreedyRepeatCases
  75. template<typename Gram>
  76. struct NonGreedyRepeatCases
  77. {
  78. template<typename Tag, typename Dummy = void>
  79. struct case_
  80. : not_<_>
  81. {};
  82. template<typename Dummy>
  83. struct case_<tag::dereference, Dummy>
  84. : dereference<Gram>
  85. {};
  86. template<typename Dummy>
  87. struct case_<tag::unary_plus, Dummy>
  88. : unary_plus<Gram>
  89. {};
  90. template<typename Dummy>
  91. struct case_<tag::logical_not, Dummy>
  92. : logical_not<Gram>
  93. {};
  94. template<uint_t Min, uint_t Max, typename Dummy>
  95. struct case_<detail::generic_quant_tag<Min, Max>, Dummy>
  96. : unary_expr<detail::generic_quant_tag<Min, Max>, Gram>
  97. {};
  98. };
  99. ///////////////////////////////////////////////////////////////////////////
  100. // InvertibleCases
  101. template<typename Char, typename Gram>
  102. struct InvertibleCases
  103. {
  104. template<typename Tag, typename Dummy = void>
  105. struct case_
  106. : not_<_>
  107. {};
  108. template<typename Dummy>
  109. struct case_<tag::comma, Dummy>
  110. : when<ListSet<Char>, as_list_set_matcher<Char> >
  111. {};
  112. template<typename Dummy>
  113. struct case_<tag::assign, Dummy>
  114. : when<ListSet<Char>, as_list_set_matcher<Char> >
  115. {};
  116. template<typename Dummy>
  117. struct case_<tag::subscript, Dummy>
  118. : when<subscript<detail::set_initializer_type, Gram>, call<as_set_matcher<Gram>(_right)> >
  119. {};
  120. template<typename Dummy>
  121. struct case_<detail::lookahead_tag, Dummy>
  122. : when<
  123. unary_expr<detail::lookahead_tag, Gram>
  124. , as_lookahead<Gram>
  125. >
  126. {};
  127. template<typename Dummy>
  128. struct case_<detail::lookbehind_tag, Dummy>
  129. : when<
  130. unary_expr<detail::lookbehind_tag, Gram>
  131. , as_lookbehind<Gram>
  132. >
  133. {};
  134. template<typename Dummy>
  135. struct case_<tag::terminal, Dummy>
  136. : when<
  137. or_<
  138. CharLiteral<Char>
  139. , terminal<detail::posix_charset_placeholder>
  140. , terminal<detail::range_placeholder<_> >
  141. , terminal<detail::logical_newline_placeholder>
  142. , terminal<detail::assert_word_placeholder<detail::word_boundary<mpl::true_> > >
  143. >
  144. , as_matcher
  145. >
  146. {};
  147. };
  148. ///////////////////////////////////////////////////////////////////////////
  149. // Cases
  150. template<typename Char, typename Gram>
  151. struct Cases
  152. {
  153. template<typename Tag, typename Dummy = void>
  154. struct case_
  155. : not_<_>
  156. {};
  157. template<typename Dummy>
  158. struct case_<tag::terminal, Dummy>
  159. : when<
  160. _
  161. , in_sequence<as_matcher>
  162. >
  163. {};
  164. template<typename Dummy>
  165. struct case_<tag::shift_right, Dummy>
  166. : when<
  167. shift_right<Gram, Gram>
  168. , reverse_fold<_, _state, Gram>
  169. >
  170. {};
  171. template<typename Dummy>
  172. struct case_<tag::bitwise_or, Dummy>
  173. : when<
  174. bitwise_or<Gram, Gram>
  175. , in_sequence<
  176. as_alternate_matcher<
  177. reverse_fold_tree<_, make<fusion::nil>, in_alternate_list<Gram> >
  178. >
  179. >
  180. >
  181. {};
  182. template<typename Dummy, typename Greedy>
  183. struct case_<optional_tag<Greedy> , Dummy>
  184. : when<
  185. unary_expr<optional_tag<Greedy>, Gram>
  186. , in_sequence<call<as_optional<Gram, Greedy>(_child)> >
  187. >
  188. {};
  189. template<typename Dummy>
  190. struct case_<tag::dereference, Dummy>
  191. : when<
  192. dereference<Gram>
  193. , call<Gram(as_repeat<Char, Gram, mpl::true_>)>
  194. >
  195. {};
  196. template<typename Dummy>
  197. struct case_<tag::unary_plus, Dummy>
  198. : when<
  199. unary_plus<Gram>
  200. , call<Gram(as_repeat<Char, Gram, mpl::true_>)>
  201. >
  202. {};
  203. template<typename Dummy>
  204. struct case_<tag::logical_not, Dummy>
  205. : when<
  206. logical_not<Gram>
  207. , call<Gram(as_repeat<Char, Gram, mpl::true_>)>
  208. >
  209. {};
  210. template<uint_t Min, uint_t Max, typename Dummy>
  211. struct case_<detail::generic_quant_tag<Min, Max>, Dummy>
  212. : when<
  213. unary_expr<detail::generic_quant_tag<Min, Max>, Gram>
  214. , call<Gram(as_repeat<Char, Gram, mpl::true_>)>
  215. >
  216. {};
  217. template<typename Dummy>
  218. struct case_<tag::negate, Dummy>
  219. : when<
  220. negate<switch_<NonGreedyRepeatCases<Gram> > >
  221. , call<Gram(call<as_repeat<Char, Gram, mpl::false_>(_child)>)>
  222. >
  223. {};
  224. template<typename Dummy>
  225. struct case_<tag::complement, Dummy>
  226. : when<
  227. complement<switch_<InvertibleCases<Char, Gram> > >
  228. , in_sequence<call<as_inverse(call<switch_<InvertibleCases<Char, Gram> >(_child)>)> >
  229. >
  230. {};
  231. template<typename Dummy>
  232. struct case_<detail::modifier_tag, Dummy>
  233. : when<binary_expr<detail::modifier_tag, _, Gram>, as_modifier<Gram> >
  234. {};
  235. template<typename Dummy>
  236. struct case_<detail::lookahead_tag, Dummy>
  237. : when<
  238. unary_expr<detail::lookahead_tag, Gram>
  239. , in_sequence<as_lookahead<Gram> >
  240. >
  241. {};
  242. template<typename Dummy>
  243. struct case_<detail::lookbehind_tag, Dummy>
  244. : when<
  245. unary_expr<detail::lookbehind_tag, Gram>
  246. , in_sequence<as_lookbehind<Gram> >
  247. >
  248. {};
  249. template<typename Dummy>
  250. struct case_<detail::keeper_tag, Dummy>
  251. : when<
  252. unary_expr<detail::keeper_tag, Gram>
  253. , in_sequence<as_keeper<Gram> >
  254. >
  255. {};
  256. template<typename Dummy>
  257. struct case_<tag::comma, Dummy>
  258. : when<ListSet<Char>, in_sequence<as_list_set_matcher<Char> > >
  259. {};
  260. template<typename Dummy>
  261. struct case_<tag::assign, Dummy>
  262. : or_<
  263. when<assign<detail::basic_mark_tag, Gram>, call<Gram(as_marker)> >
  264. , when<ListSet<Char>, in_sequence<as_list_set_matcher<Char> > >
  265. >
  266. {};
  267. template<typename Dummy>
  268. struct case_<tag::subscript, Dummy>
  269. : or_<
  270. when<subscript<detail::set_initializer_type, Gram>, in_sequence<call<as_set_matcher<Gram>(_right)> > >
  271. , when<subscript<ActionableGrammar<Char>, _>, call<ActionableGrammar<Char>(as_action)> >
  272. >
  273. {};
  274. };
  275. ///////////////////////////////////////////////////////////////////////////
  276. // ActionableCases
  277. template<typename Char, typename Gram>
  278. struct ActionableCases
  279. {
  280. template<typename Tag, typename Dummy = void>
  281. struct case_
  282. : Cases<Char, Gram>::template case_<Tag>
  283. {};
  284. // Only in sub-expressions with actions attached do we allow attribute assignements
  285. template<typename Dummy>
  286. struct case_<proto::tag::assign, Dummy>
  287. : or_<
  288. typename Cases<Char, Gram>::template case_<proto::tag::assign>
  289. , when<proto::assign<terminal<detail::attribute_placeholder<_> >, _>, in_sequence<as_attr_matcher> >
  290. >
  291. {};
  292. };
  293. } // namespace detail
  294. ///////////////////////////////////////////////////////////////////////////
  295. // Grammar
  296. template<typename Char>
  297. struct Grammar
  298. : proto::switch_<grammar_detail::Cases<Char, Grammar<Char> > >
  299. {};
  300. template<typename Char>
  301. struct ActionableGrammar
  302. : proto::switch_<grammar_detail::ActionableCases<Char, ActionableGrammar<Char> > >
  303. {};
  304. ///////////////////////////////////////////////////////////////////////////
  305. // INVALID_REGULAR_EXPRESSION
  306. struct INVALID_REGULAR_EXPRESSION
  307. : mpl::false_
  308. {};
  309. ///////////////////////////////////////////////////////////////////////////
  310. // is_valid_regex
  311. template<typename Expr, typename Char>
  312. struct is_valid_regex
  313. : proto::matches<Expr, Grammar<Char> >
  314. {};
  315. }} // namespace boost::xpressive
  316. #endif