1 // Copyright Abel Sinkovics (abel@sinkovics.hu) 2012.
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)
6 #include <boost/metaparse/repeated.hpp>
7 #include <boost/metaparse/sequence.hpp>
8 #include <boost/metaparse/lit_c.hpp>
9 #include <boost/metaparse/last_of.hpp>
10 #include <boost/metaparse/space.hpp>
11 #include <boost/metaparse/int_.hpp>
12 #include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp>
13 #include <boost/metaparse/one_of.hpp>
14 #include <boost/metaparse/get_result.hpp>
15 #include <boost/metaparse/token.hpp>
16 #include <boost/metaparse/entire_input.hpp>
17 #include <boost/metaparse/string.hpp>
18 #include <boost/metaparse/transform.hpp>
19 #include <boost/metaparse/always.hpp>
20 #include <boost/metaparse/build_parser.hpp>
22 #include <boost/mpl/apply_wrap.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/bool.hpp>
30 #include <boost/mpl/equal_to.hpp>
31 #include <boost/mpl/if.hpp>
33 using boost::metaparse::sequence
;
34 using boost::metaparse::lit_c
;
35 using boost::metaparse::last_of
;
36 using boost::metaparse::space
;
37 using boost::metaparse::repeated
;
38 using boost::metaparse::build_parser
;
39 using boost::metaparse::int_
;
40 using boost::metaparse::foldl_reject_incomplete_start_with_parser
;
41 using boost::metaparse::get_result
;
42 using boost::metaparse::one_of
;
43 using boost::metaparse::token
;
44 using boost::metaparse::entire_input
;
45 using boost::metaparse::transform
;
46 using boost::metaparse::always
;
48 using boost::mpl::apply_wrap1
;
49 using boost::mpl::front
;
50 using boost::mpl::back
;
51 using boost::mpl::plus
;
52 using boost::mpl::minus
;
53 using boost::mpl::times
;
54 using boost::mpl::divides
;
55 using boost::mpl::if_
;
56 using boost::mpl::bool_
;
57 using boost::mpl::equal_to
;
62 * expression ::= plus_exp
63 * plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)*
64 * prod_exp ::= value_exp ((mult_token | div_token) value_exp)*
65 * value_exp ::= int_token | '_'
68 typedef token
<lit_c
<'+'> > plus_token
;
69 typedef token
<lit_c
<'-'> > minus_token
;
70 typedef token
<lit_c
<'*'> > mult_token
;
71 typedef token
<lit_c
<'/'> > div_token
;
73 typedef token
<int_
> int_token
;
74 typedef token
<lit_c
<'_'> > arg_token
;
76 template <class T
, char C
>
77 struct is_c
: bool_
<T::type::value
== C
> {};
81 template <class A
, class B
>
88 plus
<typename apply_wrap1
<A
, T
>::type
, typename apply_wrap1
<B
, T
>::type
>
92 template <class A
, class B
>
99 minus
<typename apply_wrap1
<A
, T
>::type
, typename apply_wrap1
<B
, T
>::type
>
103 template <class State
, class C
>
106 typename is_c
<front
<C
>, '+'>::type
,
107 _plus
<State
, typename back
<C
>::type
>,
108 _minus
<State
, typename back
<C
>::type
>
115 template <class A
, class B
>
122 times
<typename apply_wrap1
<A
, T
>::type
, typename apply_wrap1
<B
, T
>::type
>
126 template <class A
, class B
>
134 typename apply_wrap1
<A
, T
>::type
,
135 typename apply_wrap1
<B
, T
>::type
140 template <class State
, class C
>
143 typename is_c
<front
<C
>, '*'>::type
,
144 _mult
<State
, typename back
<C
>::type
>,
145 _div
<State
, typename back
<C
>::type
>
163 typedef build_value type
;
166 struct apply
: impl
<typename
V::type
> {};
181 one_of
<transform
<int_token
, build_value
>, always
<arg_token
, arg
> >
185 foldl_reject_incomplete_start_with_parser
<
186 sequence
<one_of
<mult_token
, div_token
>, value_exp
>,
193 foldl_reject_incomplete_start_with_parser
<
194 sequence
<one_of
<plus_token
, minus_token
>, prod_exp
>,
200 typedef last_of
<repeated
<space
>, plus_exp
> expression
;
202 typedef build_parser
<entire_input
<expression
> > metafunction_parser
;
204 #if BOOST_METAPARSE_STD < 2011
207 struct meta_lambda
: apply_wrap1
<metafunction_parser
, Exp
> {};
213 using boost::metaparse::string
;
215 typedef meta_lambda
<string
<'1','3'> >::type metafunction_class_1
;
216 typedef meta_lambda
<string
<'2',' ','+',' ','3'> >::type metafunction_class_2
;
217 typedef meta_lambda
<string
<'2',' ','*',' ','2'> >::type metafunction_class_3
;
219 meta_lambda
<string
<' ','1','+',' ','2','*','4','-','6','/','2'> >::type
220 metafunction_class_4
;
221 typedef meta_lambda
<string
<'2',' ','*',' ','_'> >::type metafunction_class_5
;
223 typedef boost::mpl::int_
<11> int11
;
226 << apply_wrap1
<metafunction_class_1
, int11
>::type::value
<< endl
227 << apply_wrap1
<metafunction_class_2
, int11
>::type::value
<< endl
228 << apply_wrap1
<metafunction_class_3
, int11
>::type::value
<< endl
229 << apply_wrap1
<metafunction_class_4
, int11
>::type::value
<< endl
230 << apply_wrap1
<metafunction_class_5
, int11
>::type::value
<< endl
237 #error META_LAMBDA already defined
239 #define META_LAMBDA(exp) \
240 apply_wrap1<metafunction_parser, BOOST_METAPARSE_STRING(#exp)>::type
247 typedef META_LAMBDA(13) metafunction_class_1
;
248 typedef META_LAMBDA(2 + 3) metafunction_class_2
;
249 typedef META_LAMBDA(2 * 2) metafunction_class_3
;
250 typedef META_LAMBDA( 1+ 2*4-6/2) metafunction_class_4
;
251 typedef META_LAMBDA(2 * _
) metafunction_class_5
;
253 typedef boost::mpl::int_
<11> int11
;
256 << apply_wrap1
<metafunction_class_1
, int11
>::type::value
<< endl
257 << apply_wrap1
<metafunction_class_2
, int11
>::type::value
<< endl
258 << apply_wrap1
<metafunction_class_3
, int11
>::type::value
<< endl
259 << apply_wrap1
<metafunction_class_4
, int11
>::type::value
<< endl
260 << apply_wrap1
<metafunction_class_5
, int11
>::type::value
<< endl