]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/example/qi/calc_utree_ast.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / spirit / example / qi / calc_utree_ast.cpp
CommitLineData
7c673cae
FG
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
7c673cae
FG
21#include <boost/spirit/include/support_utree.hpp>
22#include <boost/spirit/include/qi.hpp>
1e59de90
TL
23#include <boost/phoenix/operator.hpp>
24#include <boost/phoenix/function.hpp>
7c673cae
FG
25
26#include <iostream>
27#include <string>
28
29namespace client
30{
31 namespace qi = boost::spirit::qi;
32 namespace ascii = boost::spirit::ascii;
33 namespace spirit = boost::spirit;
34
35 struct expr
36 {
37 template <typename T1, typename T2 = void>
38 struct result { typedef void type; };
39
40 expr(char op) : op(op) {}
41
42 void operator()(spirit::utree& expr, spirit::utree const& rhs) const
43 {
44 spirit::utree lhs;
45 lhs.swap(expr);
46 expr.push_back(spirit::utf8_symbol_range_type(&op, &op+1));
47 expr.push_back(lhs);
48 expr.push_back(rhs);
49 }
50
51 char const op;
52 };
53 boost::phoenix::function<expr> const plus = expr('+');
54 boost::phoenix::function<expr> const minus = expr('-');
55 boost::phoenix::function<expr> const times = expr('*');
56 boost::phoenix::function<expr> const divide = expr('/');
57
58 struct negate_expr
59 {
60 template <typename T1, typename T2 = void>
61 struct result { typedef void type; };
62
63 void operator()(spirit::utree& expr, spirit::utree const& rhs) const
64 {
65 char const op = '-';
66 expr.clear();
67 expr.push_back(spirit::utf8_symbol_range_type(&op, &op+1));
68 expr.push_back(rhs);
69 }
70 };
71 boost::phoenix::function<negate_expr> neg;
72
73 ///////////////////////////////////////////////////////////////////////////////
74 // Our calculator grammar
75 ///////////////////////////////////////////////////////////////////////////////
76 template <typename Iterator>
77 struct calculator : qi::grammar<Iterator, ascii::space_type, spirit::utree()>
78 {
79 calculator() : calculator::base_type(expression)
80 {
81 using qi::uint_;
82 using qi::_val;
83 using qi::_1;
84
85 expression =
86 term [_val = _1]
87 >> *( ('+' >> term [plus(_val, _1)])
88 | ('-' >> term [minus(_val, _1)])
89 )
90 ;
91
92 term =
93 factor [_val = _1]
94 >> *( ('*' >> factor [times(_val, _1)])
95 | ('/' >> factor [divide(_val, _1)])
96 )
97 ;
98
99 factor =
100 uint_ [_val = _1]
101 | '(' >> expression [_val = _1] >> ')'
102 | ('-' >> factor [neg(_val, _1)])
103 | ('+' >> factor [_val = _1])
104 ;
105
106 BOOST_SPIRIT_DEBUG_NODE(expression);
107 BOOST_SPIRIT_DEBUG_NODE(term);
108 BOOST_SPIRIT_DEBUG_NODE(factor);
109 }
110
111 qi::rule<Iterator, ascii::space_type, spirit::utree()> expression, term, factor;
112 };
113}
114
115///////////////////////////////////////////////////////////////////////////////
116// Main program
117///////////////////////////////////////////////////////////////////////////////
118int main()
119{
120 std::cout << "/////////////////////////////////////////////////////////\n\n";
121 std::cout << "Expression parser...\n\n";
122 std::cout << "/////////////////////////////////////////////////////////\n\n";
123 std::cout << "Type an expression...or [q or Q] to quit\n\n";
124
125 using boost::spirit::ascii::space;
126 using boost::spirit::utree;
127 typedef std::string::const_iterator iterator_type;
128 typedef client::calculator<iterator_type> calculator;
129
130 calculator calc; // Our grammar
131
132 std::string str;
133 while (std::getline(std::cin, str))
134 {
135 if (str.empty() || str[0] == 'q' || str[0] == 'Q')
136 break;
137
138 std::string::const_iterator iter = str.begin();
139 std::string::const_iterator end = str.end();
140 utree ut;
141 bool r = phrase_parse(iter, end, calc, space, ut);
142
143 if (r && iter == end)
144 {
145 std::cout << "-------------------------\n";
146 std::cout << "Parsing succeeded: " << ut << "\n";
147 std::cout << "-------------------------\n";
148 }
149 else
150 {
151 std::string rest(iter, end);
152 std::cout << "-------------------------\n";
153 std::cout << "Parsing failed\n";
154 std::cout << "stopped at: \": " << rest << "\"\n";
155 std::cout << "-------------------------\n";
156 }
157 }
158
159 std::cout << "Bye... :-) \n\n";
160 return 0;
161}
162
163