]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/metaparse/example/calculator_with_parens_and_unary_ops/main.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / metaparse / example / calculator_with_parens_and_unary_ops / main.cpp
1 // Copyright Abel Sinkovics (abel@sinkovics.hu) 2014.
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
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/first_of.hpp>
11 #include <boost/metaparse/middle_of.hpp>
12 #include <boost/metaparse/space.hpp>
13 #include <boost/metaparse/int_.hpp>
14 #include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp>
15 #include <boost/metaparse/foldr_start_with_parser.hpp>
16 #include <boost/metaparse/one_of.hpp>
17 #include <boost/metaparse/get_result.hpp>
18 #include <boost/metaparse/token.hpp>
19 #include <boost/metaparse/entire_input.hpp>
20 #include <boost/metaparse/string.hpp>
21 #include <boost/metaparse/build_parser.hpp>
22
23 #include <boost/mpl/apply_wrap.hpp>
24 #include <boost/mpl/fold.hpp>
25 #include <boost/mpl/front.hpp>
26 #include <boost/mpl/back.hpp>
27 #include <boost/mpl/plus.hpp>
28 #include <boost/mpl/minus.hpp>
29 #include <boost/mpl/times.hpp>
30 #include <boost/mpl/divides.hpp>
31 #include <boost/mpl/bool.hpp>
32 #include <boost/mpl/equal_to.hpp>
33 #include <boost/mpl/eval_if.hpp>
34 #include <boost/mpl/bool.hpp>
35 #include <boost/mpl/negate.hpp>
36 #include <boost/mpl/char.hpp>
37
38 using boost::metaparse::sequence;
39 using boost::metaparse::lit_c;
40 using boost::metaparse::last_of;
41 using boost::metaparse::first_of;
42 using boost::metaparse::middle_of;
43 using boost::metaparse::space;
44 using boost::metaparse::repeated;
45 using boost::metaparse::build_parser;
46 using boost::metaparse::int_;
47 using boost::metaparse::foldl_reject_incomplete_start_with_parser;
48 using boost::metaparse::foldr_start_with_parser;
49 using boost::metaparse::get_result;
50 using boost::metaparse::one_of;
51 using boost::metaparse::token;
52 using boost::metaparse::entire_input;
53
54 using boost::mpl::apply_wrap1;
55 using boost::mpl::fold;
56 using boost::mpl::front;
57 using boost::mpl::back;
58 using boost::mpl::plus;
59 using boost::mpl::minus;
60 using boost::mpl::times;
61 using boost::mpl::divides;
62 using boost::mpl::eval_if;
63 using boost::mpl::bool_;
64 using boost::mpl::equal_to;
65 using boost::mpl::bool_;
66 using boost::mpl::negate;
67 using boost::mpl::char_;
68
69 /*
70 * The grammar
71 *
72 * expression ::= plus_exp
73 * plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)*
74 * prod_exp ::= int_token ((mult_token | div_token) simple_exp)*
75 * simple_exp ::= (plus_token | minus_token)* (int_token | paren_exp)
76 * paren_exp ::= open_paren_token expression close_paren_token
77 */
78
79 typedef token<lit_c<'+'> > plus_token;
80 typedef token<lit_c<'-'> > minus_token;
81 typedef token<lit_c<'*'> > mult_token;
82 typedef token<lit_c<'/'> > div_token;
83
84 typedef token<lit_c<'('> > open_paren_token;
85 typedef token<lit_c<')'> > close_paren_token;
86
87 typedef token<int_> int_token;
88
89 template <class T, char C>
90 struct is_c : bool_<T::type::value == C> {};
91
92 struct eval_plus
93 {
94 template <class State, class C>
95 struct apply :
96 eval_if<
97 is_c<front<C>, '+'>,
98 plus<typename State::type, typename back<C>::type>,
99 minus<typename State::type, typename back<C>::type>
100 >
101 {};
102 };
103
104 struct eval_mult
105 {
106 template <class State, class C>
107 struct apply :
108 eval_if<
109 is_c<front<C>, '*'>,
110 times<typename State::type, typename back<C>::type>,
111 divides<typename State::type, typename back<C>::type>
112 >
113 {};
114 };
115
116 struct eval_unary_plus
117 {
118 template <class State, class C>
119 struct apply :
120 eval_if<
121 typename equal_to<char_<'+'>, typename C::type>::type,
122 State, // +State is State
123 negate<typename State::type>
124 >
125 {};
126 };
127
128 struct plus_exp;
129
130 typedef middle_of<open_paren_token, plus_exp, close_paren_token> paren_exp;
131
132 typedef
133 foldr_start_with_parser<
134 one_of<plus_token, minus_token>,
135 one_of<int_token, paren_exp>,
136 eval_unary_plus
137 >
138 simple_exp;
139
140 typedef
141 foldl_reject_incomplete_start_with_parser<
142 sequence<one_of<mult_token, div_token>, simple_exp>,
143 simple_exp,
144 eval_mult
145 >
146 prod_exp;
147
148 struct plus_exp :
149 foldl_reject_incomplete_start_with_parser<
150 sequence<one_of<plus_token, minus_token>, prod_exp>,
151 prod_exp,
152 eval_plus
153 >
154 {};
155
156 typedef last_of<repeated<space>, plus_exp> expression;
157
158 typedef build_parser<entire_input<expression> > calculator_parser;
159
160 #ifdef _STR
161 # error _STR already defined
162 #endif
163 #define _STR BOOST_METAPARSE_STRING
164
165 #if BOOST_METAPARSE_STD < 2011
166 int main()
167 {
168 std::cout << "Please use a compiler that support constexpr" << std::endl;
169 }
170 #else
171 int main()
172 {
173 using std::cout;
174 using std::endl;
175
176 cout
177 << apply_wrap1<calculator_parser, _STR("13")>::type::value << endl
178 << apply_wrap1<calculator_parser, _STR(" 1+ 2*4-6/2")>::type::value << endl
179 << apply_wrap1<calculator_parser, _STR("1+2*3+4")>::type::value << endl
180 << apply_wrap1<calculator_parser, _STR("(1+2)*(3+4)")>::type::value << endl
181 << apply_wrap1<calculator_parser, _STR("(2*3)+(4*5)")>::type::value << endl
182 << apply_wrap1<calculator_parser, _STR("2 * 3 + 4")>::type::value << endl
183 << apply_wrap1<calculator_parser, _STR("2 + (3 * 4)")>::type::value << endl
184 << apply_wrap1<calculator_parser, _STR("+3")>::type::value << endl
185 << apply_wrap1<calculator_parser, _STR("-21")>::type::value << endl
186 << apply_wrap1<calculator_parser, _STR("24 + - 21")>::type::value << endl
187 << apply_wrap1<calculator_parser, _STR("- - 21")>::type::value << endl
188 << apply_wrap1<calculator_parser, _STR("-(3 * 4)")>::type::value << endl
189 ;
190 }
191 #endif
192