]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/example/qi/calc_utree.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / example / qi / calc_utree.cpp
1 /*=============================================================================
2 Copyright (c) 2001-2011 Hartmut Kaiser
3 Copyright (c) 2001-2011 Joel de Guzman
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 ///////////////////////////////////////////////////////////////////////////////
9 //
10 // Plain calculator example demonstrating the grammar. The parser is a
11 // syntax checker only and does not do any semantic evaluation.
12 //
13 // [ JDG May 10, 2002 ] spirit1
14 // [ JDG March 4, 2007 ] spirit2
15 // [ HK November 30, 2010 ] spirit2/utree
16 //
17 ///////////////////////////////////////////////////////////////////////////////
18
19 // #define BOOST_SPIRIT_DEBUG
20
21 #include <boost/config/warning_disable.hpp>
22 #include <boost/spirit/include/qi.hpp>
23 #include <boost/spirit/include/support_utree.hpp>
24 #include <boost/spirit/include/phoenix_operator.hpp>
25 #include <boost/spirit/include/phoenix_function.hpp>
26
27 #include <iostream>
28 #include <string>
29
30 #if BOOST_PHOENIX_VERSION == 0x2000
31 namespace boost { namespace phoenix
32 {
33 // There's a bug in the Phoenix V2 type deduction mechanism that prevents
34 // correct return type deduction for the math operations below. Newer
35 // versions of Phoenix will be switching to BOOST_TYPEOF. In the meantime,
36 // we will use the specializations helping with return type deduction
37 // below:
38 template <>
39 struct result_of_plus<spirit::utree&, spirit::utree&>
40 {
41 typedef spirit::utree type;
42 };
43
44 template <>
45 struct result_of_minus<spirit::utree&, spirit::utree&>
46 {
47 typedef spirit::utree type;
48 };
49
50 template <>
51 struct result_of_multiplies<spirit::utree&, spirit::utree&>
52 {
53 typedef spirit::utree type;
54 };
55
56 template <>
57 struct result_of_divides<spirit::utree&, spirit::utree&>
58 {
59 typedef spirit::utree type;
60 };
61
62 template <>
63 struct result_of_negate<spirit::utree&>
64 {
65 typedef spirit::utree type;
66 };
67 }}
68 #endif
69
70 namespace client
71 {
72 namespace qi = boost::spirit::qi;
73 namespace ascii = boost::spirit::ascii;
74 namespace spirit = boost::spirit;
75
76 ///////////////////////////////////////////////////////////////////////////////
77 // Our calculator grammar
78 ///////////////////////////////////////////////////////////////////////////////
79 template <typename Iterator>
80 struct calculator : qi::grammar<Iterator, ascii::space_type, spirit::utree()>
81 {
82 calculator() : calculator::base_type(expression)
83 {
84 using qi::uint_;
85 using qi::_val;
86 using qi::_1;
87
88 expression =
89 term [_val = _1]
90 >> *( ('+' >> term [_val = _val + _1])
91 | ('-' >> term [_val = _val - _1])
92 )
93 ;
94
95 term =
96 factor [_val = _1]
97 >> *( ('*' >> factor [_val = _val * _1])
98 | ('/' >> factor [_val = _val / _1])
99 )
100 ;
101
102 factor =
103 uint_ [_val = _1]
104 | '(' >> expression [_val = _1] >> ')'
105 | ('-' >> factor [_val = -_1])
106 | ('+' >> factor [_val = _1])
107 ;
108
109 BOOST_SPIRIT_DEBUG_NODE(expression);
110 BOOST_SPIRIT_DEBUG_NODE(term);
111 BOOST_SPIRIT_DEBUG_NODE(factor);
112 }
113
114 qi::rule<Iterator, ascii::space_type, spirit::utree()> expression, term, factor;
115 };
116 }
117
118 ///////////////////////////////////////////////////////////////////////////////
119 // Main program
120 ///////////////////////////////////////////////////////////////////////////////
121 int main()
122 {
123 std::cout << "/////////////////////////////////////////////////////////\n\n";
124 std::cout << "Expression parser...\n\n";
125 std::cout << "/////////////////////////////////////////////////////////\n\n";
126 std::cout << "Type an expression...or [q or Q] to quit\n\n";
127
128 using boost::spirit::ascii::space;
129 using boost::spirit::utree;
130 typedef std::string::const_iterator iterator_type;
131 typedef client::calculator<iterator_type> calculator;
132
133 calculator calc; // Our grammar
134
135 std::string str;
136 while (std::getline(std::cin, str))
137 {
138 if (str.empty() || str[0] == 'q' || str[0] == 'Q')
139 break;
140
141 std::string::const_iterator iter = str.begin();
142 std::string::const_iterator end = str.end();
143 utree ut;
144 bool r = phrase_parse(iter, end, calc, space, ut);
145
146 if (r && iter == end)
147 {
148 std::cout << "-------------------------\n";
149 std::cout << "Parsing succeeded: " << ut << "\n";
150 std::cout << "-------------------------\n";
151 }
152 else
153 {
154 std::string rest(iter, end);
155 std::cout << "-------------------------\n";
156 std::cout << "Parsing failed\n";
157 std::cout << "stopped at: \": " << rest << "\"\n";
158 std::cout << "-------------------------\n";
159 }
160 }
161
162 std::cout << "Bye... :-) \n\n";
163 return 0;
164 }
165
166