main.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // Copyright Abel Sinkovics (abel@sinkovics.hu) 2011.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #include <boost/metaparse/foldl_reject_incomplete.hpp>
  6. #include <boost/metaparse/foldl_reject_incomplete1.hpp>
  7. #include <boost/metaparse/lit_c.hpp>
  8. #include <boost/metaparse/transform.hpp>
  9. #include <boost/metaparse/one_char_except_c.hpp>
  10. #include <boost/metaparse/one_of.hpp>
  11. #include <boost/metaparse/always_c.hpp>
  12. #include <boost/metaparse/build_parser.hpp>
  13. #include <boost/metaparse/middle_of.hpp>
  14. #include <boost/metaparse/entire_input.hpp>
  15. #include <boost/metaparse/string.hpp>
  16. #include <boost/detail/iterator.hpp>
  17. #include <boost/xpressive/xpressive.hpp>
  18. #include <boost/mpl/bool.hpp>
  19. #include <boost/mpl/string.hpp>
  20. using boost::metaparse::foldl_reject_incomplete;
  21. using boost::metaparse::foldl_reject_incomplete1;
  22. using boost::metaparse::lit_c;
  23. using boost::metaparse::transform;
  24. using boost::metaparse::build_parser;
  25. using boost::metaparse::one_of;
  26. using boost::metaparse::always_c;
  27. using boost::metaparse::middle_of;
  28. using boost::metaparse::one_char_except_c;
  29. using boost::metaparse::entire_input;
  30. using boost::mpl::c_str;
  31. using boost::mpl::true_;
  32. using boost::mpl::false_;
  33. using boost::xpressive::sregex;
  34. using boost::xpressive::as_xpr;
  35. /*
  36. * Results of parsing
  37. */
  38. template <class T>
  39. struct has_value
  40. {
  41. typedef T type;
  42. static const sregex value;
  43. };
  44. template <class T>
  45. const sregex has_value<T>::value = T::run();
  46. struct r_epsilon : has_value<r_epsilon>
  47. {
  48. static sregex run()
  49. {
  50. return as_xpr("");
  51. }
  52. };
  53. struct r_any_char : has_value<r_any_char>
  54. {
  55. static sregex run()
  56. {
  57. return boost::xpressive::_;
  58. }
  59. };
  60. struct r_char_lit
  61. {
  62. template <class C>
  63. struct apply : has_value<apply<C> >
  64. {
  65. static sregex run()
  66. {
  67. return as_xpr(C::type::value);
  68. }
  69. };
  70. };
  71. struct r_append
  72. {
  73. template <class A, class B>
  74. struct apply : has_value<apply<B, A> >
  75. {
  76. static sregex run()
  77. {
  78. return A::type::run() >> B::type::run();
  79. }
  80. };
  81. };
  82. /*
  83. * The grammar
  84. *
  85. * regexp ::= (bracket_expr | non_bracket_expr)*
  86. * non_bracket_expr ::= '.' | char_lit
  87. * bracket_expr ::= '(' regexp ')'
  88. * char_lit ::= any character except: . ( )
  89. */
  90. typedef
  91. foldl_reject_incomplete1<
  92. one_of<
  93. always_c<'.', r_any_char>,
  94. transform<one_char_except_c<'.', '(', ')'>, r_char_lit>
  95. >,
  96. r_epsilon,
  97. r_append
  98. >
  99. non_bracket_expr;
  100. typedef middle_of<lit_c<'('>, non_bracket_expr, lit_c<')'> > bracket_expr;
  101. typedef
  102. foldl_reject_incomplete<
  103. one_of<bracket_expr, non_bracket_expr>,
  104. r_epsilon,
  105. r_append
  106. >
  107. regexp;
  108. typedef build_parser<entire_input<regexp> > regexp_parser;
  109. void test_string(const std::string& s)
  110. {
  111. using boost::xpressive::regex_match;
  112. using boost::xpressive::smatch;
  113. using boost::mpl::apply_wrap1;
  114. using std::cout;
  115. using std::endl;
  116. #if BOOST_METAPARSE_STD < 2011
  117. typedef boost::metaparse::string<'.','(','b','c',')'> regexp;
  118. #else
  119. typedef BOOST_METAPARSE_STRING(".(bc)") regexp;
  120. #endif
  121. const sregex re = apply_wrap1<regexp_parser, regexp>::type::value;
  122. smatch w;
  123. cout
  124. << s << (regex_match(s, w, re) ? " matches " : " doesn't match ")
  125. << c_str<regexp>::type::value
  126. << endl;
  127. }
  128. int main()
  129. {
  130. test_string("abc");
  131. test_string("aba");
  132. }