]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/metaparse/example/grammar_calculator/main.cpp
95ca139c0173ce7cede4f7a9d6bc6d03ba2368fd
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)
6 #include <boost/config.hpp>
8 #if BOOST_METAPARSE_STD < 2011
13 std::cout
<< "Please use a compiler that supports constexpr" << std::endl
;
17 #define BOOST_MPL_LIMIT_STRING_SIZE 64
18 #define BOOST_METAPARSE_LIMIT_STRING_SIZE BOOST_MPL_LIMIT_STRING_SIZE
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>
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>
41 using boost::metaparse::build_parser
;
42 using boost::metaparse::entire_input
;
43 using boost::metaparse::token
;
44 using boost::metaparse::grammar
;
46 using boost::metaparse::util::digit_to_int
;
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
;
60 using boost::mpl::char_
;
61 using boost::mpl::lambda
;
62 using boost::mpl::int_
;
65 #error _STR already defined
67 #define _STR BOOST_METAPARSE_STRING
69 template <class A
, class B
>
70 struct lazy_plus
: plus
<typename
A::type
, typename
B::type
> {};
72 template <class A
, class B
>
73 struct lazy_minus
: minus
<typename
A::type
, typename
B::type
> {};
75 template <class A
, class B
>
76 struct lazy_times
: times
<typename
A::type
, typename
B::type
> {};
78 template <class A
, class B
>
79 struct lazy_divides
: divides
<typename
A::type
, typename
B::type
> {};
81 template <class C
, class T
, class F
>
82 struct lazy_eval_if
: eval_if
<typename
C::type
, T
, F
> {};
84 template <class A
, class B
>
85 struct lazy_equal_to
: equal_to
<typename
A::type
, typename
B::type
> {};
87 template <class Sequence
, class State
, class ForwardOp
>
89 fold
<typename
Sequence::type
, typename
State::type
, typename
ForwardOp::type
>
98 lazy_equal_to
<front
<_2
>, char_
<'*'>>,
99 lazy_times
<_1
, back
<_2
>>,
100 lazy_divides
<_1
, back
<_2
>>
112 lazy_equal_to
<front
<_2
>, char_
<'+'>>,
113 lazy_plus
<_1
, back
<_2
>>,
114 lazy_minus
<_1
, back
<_2
>>
126 lazy_plus
<lazy_times
<_1
, int_
<10>>, apply_wrap1
<digit_to_int
<>, _2
>>
133 grammar
<_STR("plus_exp")>
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
147 typedef build_parser
<entire_input
<expression
>> calculator_parser
;
155 << apply_wrap1
<calculator_parser
, _STR("13")>::type::value
<< endl
156 << apply_wrap1
<calculator_parser
, _STR("1+ 2*4-6/2")>::type::value
<< endl