// Copyright Abel Sinkovics (abel@sinkovics.hu) 2014. // 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using boost::metaparse::sequence; using boost::metaparse::lit_c; using boost::metaparse::last_of; using boost::metaparse::first_of; using boost::metaparse::middle_of; using boost::metaparse::space; using boost::metaparse::repeated; using boost::metaparse::build_parser; using boost::metaparse::int_; using boost::metaparse::foldl_reject_incomplete_start_with_parser; using boost::metaparse::foldr_start_with_parser; using boost::metaparse::get_result; using boost::metaparse::one_of; using boost::metaparse::token; using boost::metaparse::entire_input; 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::bool_; using boost::mpl::equal_to; using boost::mpl::bool_; using boost::mpl::negate; using boost::mpl::char_; /* * The grammar * * expression ::= plus_exp * plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)* * prod_exp ::= int_token ((mult_token | div_token) simple_exp)* * simple_exp ::= (plus_token | minus_token)* (int_token | paren_exp) * paren_exp ::= open_paren_token expression close_paren_token */ typedef token > plus_token; typedef token > minus_token; typedef token > mult_token; typedef token > div_token; typedef token > open_paren_token; typedef token > close_paren_token; typedef token int_token; template struct is_c : bool_ {}; struct eval_plus { template struct apply : eval_if< is_c, '+'>, plus::type>, minus::type> > {}; }; struct eval_mult { template struct apply : eval_if< is_c, '*'>, times::type>, divides::type> > {}; }; struct eval_unary_plus { template struct apply : eval_if< typename equal_to, typename C::type>::type, State, // +State is State negate > {}; }; struct plus_exp; typedef middle_of paren_exp; typedef foldr_start_with_parser< one_of, one_of, eval_unary_plus > simple_exp; typedef foldl_reject_incomplete_start_with_parser< sequence, simple_exp>, simple_exp, eval_mult > prod_exp; struct plus_exp : foldl_reject_incomplete_start_with_parser< sequence, prod_exp>, prod_exp, eval_plus > {}; typedef last_of, plus_exp> expression; typedef build_parser > calculator_parser; #ifdef _STR # error _STR already defined #endif #define _STR BOOST_METAPARSE_STRING #if BOOST_METAPARSE_STD < 2011 int main() { std::cout << "Please use a compiler that support constexpr" << std::endl; } #else int main() { using std::cout; using std::endl; cout << apply_wrap1::type::value << endl << apply_wrap1::type::value << endl << apply_wrap1::type::value << endl << apply_wrap1::type::value << endl << apply_wrap1::type::value << endl << apply_wrap1::type::value << endl << apply_wrap1::type::value << endl << apply_wrap1::type::value << endl << apply_wrap1::type::value << endl << apply_wrap1::type::value << endl << apply_wrap1::type::value << endl << apply_wrap1::type::value << endl ; } #endif