// Copyright Abel Sinkovics (abel@sinkovics.hu) 2011. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #if BOOST_METAPARSE_STD < 2011 #include int main() { std::cout << "Please use a compiler that supports constexpr" << std::endl; } #else #define BOOST_MPL_LIMIT_STRING_SIZE 64 #define BOOST_METAPARSE_LIMIT_STRING_SIZE BOOST_MPL_LIMIT_STRING_SIZE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using boost::metaparse::build_parser; using boost::metaparse::entire_input; using boost::metaparse::token; using boost::metaparse::grammar; using boost::metaparse::util::digit_to_int; using boost::mpl::apply_wrap1; using boost::mpl::fold; using boost::mpl::front; using boost::mpl::back; using boost::mpl::plus; using boost::mpl::minus; using boost::mpl::times; using boost::mpl::divides; using boost::mpl::eval_if; using boost::mpl::equal_to; using boost::mpl::_1; using boost::mpl::_2; using boost::mpl::char_; using boost::mpl::lambda; using boost::mpl::int_; #ifdef _STR #error _STR already defined #endif #define _STR BOOST_METAPARSE_STRING template struct lazy_plus : plus {}; template struct lazy_minus : minus {}; template struct lazy_times : times {}; template struct lazy_divides : divides {}; template struct lazy_eval_if : eval_if {}; template struct lazy_equal_to : equal_to {}; template struct lazy_fold : fold {}; typedef lazy_fold< back<_1>, front<_1>, lambda< lazy_eval_if< lazy_equal_to, char_<'*'>>, lazy_times<_1, back<_2>>, lazy_divides<_1, back<_2>> > >::type > prod_action; typedef lazy_fold< back<_1>, front<_1>, lambda< lazy_eval_if< lazy_equal_to, char_<'+'>>, lazy_plus<_1, back<_2>>, lazy_minus<_1, back<_2>> > >::type > plus_action; typedef lambda< lazy_fold< _1, int_<0>, lambda< lazy_plus>, apply_wrap1, _2>> >::type > >::type int_action; typedef grammar<_STR("plus_exp")> ::rule<_STR("int ::= ('0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9')+"), int_action>::type ::rule<_STR("ws ::= (' ' | '\n' | '\r' | '\t')*")>::type ::rule<_STR("int_token ::= int ws"), front<_1>>::type ::rule<_STR("plus_token ::= '+' ws"), front<_1>>::type ::rule<_STR("minus_token ::= '-' ws"), front<_1>>::type ::rule<_STR("mult_token ::= '*' ws"), front<_1>>::type ::rule<_STR("div_token ::= '/' ws"), front<_1>>::type ::rule<_STR("plus_token ::= '+' ws")>::type ::rule<_STR("plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)*"), plus_action>::type ::rule<_STR("prod_exp ::= int_token ((mult_token | div_token) int_token)*"), prod_action>::type expression; typedef build_parser> calculator_parser; int main() { using std::cout; using std::endl; cout << apply_wrap1::type::value << endl << apply_wrap1::type::value << endl ; } #endif