main.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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/config.hpp>
  6. #if BOOST_METAPARSE_STD < 2011
  7. #include <iostream>
  8. int main()
  9. {
  10. std::cout << "Please use a compiler that supports constexpr" << std::endl;
  11. }
  12. #else
  13. #define BOOST_MPL_LIMIT_STRING_SIZE 64
  14. #define BOOST_METAPARSE_LIMIT_STRING_SIZE BOOST_MPL_LIMIT_STRING_SIZE
  15. #include <boost/metaparse/grammar.hpp>
  16. #include <boost/metaparse/entire_input.hpp>
  17. #include <boost/metaparse/build_parser.hpp>
  18. #include <boost/metaparse/token.hpp>
  19. #include <boost/metaparse/string.hpp>
  20. #include <boost/metaparse/util/digit_to_int.hpp>
  21. #include <boost/mpl/apply_wrap.hpp>
  22. #include <boost/mpl/fold.hpp>
  23. #include <boost/mpl/front.hpp>
  24. #include <boost/mpl/back.hpp>
  25. #include <boost/mpl/plus.hpp>
  26. #include <boost/mpl/minus.hpp>
  27. #include <boost/mpl/times.hpp>
  28. #include <boost/mpl/divides.hpp>
  29. #include <boost/mpl/equal_to.hpp>
  30. #include <boost/mpl/eval_if.hpp>
  31. #include <boost/mpl/lambda.hpp>
  32. #include <boost/mpl/char.hpp>
  33. #include <boost/mpl/int.hpp>
  34. using boost::metaparse::build_parser;
  35. using boost::metaparse::entire_input;
  36. using boost::metaparse::token;
  37. using boost::metaparse::grammar;
  38. using boost::metaparse::util::digit_to_int;
  39. using boost::mpl::apply_wrap1;
  40. using boost::mpl::fold;
  41. using boost::mpl::front;
  42. using boost::mpl::back;
  43. using boost::mpl::plus;
  44. using boost::mpl::minus;
  45. using boost::mpl::times;
  46. using boost::mpl::divides;
  47. using boost::mpl::eval_if;
  48. using boost::mpl::equal_to;
  49. using boost::mpl::_1;
  50. using boost::mpl::_2;
  51. using boost::mpl::char_;
  52. using boost::mpl::lambda;
  53. using boost::mpl::int_;
  54. #ifdef _STR
  55. #error _STR already defined
  56. #endif
  57. #define _STR BOOST_METAPARSE_STRING
  58. template <class A, class B>
  59. struct lazy_plus : plus<typename A::type, typename B::type> {};
  60. template <class A, class B>
  61. struct lazy_minus : minus<typename A::type, typename B::type> {};
  62. template <class A, class B>
  63. struct lazy_times : times<typename A::type, typename B::type> {};
  64. template <class A, class B>
  65. struct lazy_divides : divides<typename A::type, typename B::type> {};
  66. template <class C, class T, class F>
  67. struct lazy_eval_if : eval_if<typename C::type, T, F> {};
  68. template <class A, class B>
  69. struct lazy_equal_to : equal_to<typename A::type, typename B::type> {};
  70. template <class Sequence, class State, class ForwardOp>
  71. struct lazy_fold :
  72. fold<typename Sequence::type, typename State::type, typename ForwardOp::type>
  73. {};
  74. typedef
  75. lazy_fold<
  76. back<_1>,
  77. front<_1>,
  78. lambda<
  79. lazy_eval_if<
  80. lazy_equal_to<front<_2>, char_<'*'>>,
  81. lazy_times<_1, back<_2>>,
  82. lazy_divides<_1, back<_2>>
  83. >
  84. >::type
  85. >
  86. prod_action;
  87. typedef
  88. lazy_fold<
  89. back<_1>,
  90. front<_1>,
  91. lambda<
  92. lazy_eval_if<
  93. lazy_equal_to<front<_2>, char_<'+'>>,
  94. lazy_plus<_1, back<_2>>,
  95. lazy_minus<_1, back<_2>>
  96. >
  97. >::type
  98. >
  99. plus_action;
  100. typedef
  101. lambda<
  102. lazy_fold<
  103. _1,
  104. int_<0>,
  105. lambda<
  106. lazy_plus<lazy_times<_1, int_<10>>, apply_wrap1<digit_to_int<>, _2>>
  107. >::type
  108. >
  109. >::type
  110. int_action;
  111. typedef
  112. grammar<_STR("plus_exp")>
  113. ::rule<_STR("int ::= ('0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9')+"), int_action>::type
  114. ::rule<_STR("ws ::= (' ' | '\n' | '\r' | '\t')*")>::type
  115. ::rule<_STR("int_token ::= int ws"), front<_1>>::type
  116. ::rule<_STR("plus_token ::= '+' ws"), front<_1>>::type
  117. ::rule<_STR("minus_token ::= '-' ws"), front<_1>>::type
  118. ::rule<_STR("mult_token ::= '*' ws"), front<_1>>::type
  119. ::rule<_STR("div_token ::= '/' ws"), front<_1>>::type
  120. ::rule<_STR("plus_token ::= '+' ws")>::type
  121. ::rule<_STR("plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)*"), plus_action>::type
  122. ::rule<_STR("prod_exp ::= int_token ((mult_token | div_token) int_token)*"), prod_action>::type
  123. expression;
  124. typedef build_parser<entire_input<expression>> calculator_parser;
  125. int main()
  126. {
  127. using std::cout;
  128. using std::endl;
  129. cout
  130. << apply_wrap1<calculator_parser, _STR("13")>::type::value << endl
  131. << apply_wrap1<calculator_parser, _STR("1+ 2*4-6/2")>::type::value << endl
  132. ;
  133. }
  134. #endif