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