]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/example/x3/calc/calc2.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / spirit / example / x3 / calc / calc2.cpp
1 /*=============================================================================
2 Copyright (c) 2001-2014 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 =============================================================================*/
7 ///////////////////////////////////////////////////////////////////////////////
8 //
9 // A Calculator example demonstrating the grammar and semantic actions
10 // using lambda functions. The parser prints code suitable for a stack
11 // based virtual machine.
12 //
13 // [ JDG May 10, 2002 ] spirit 1
14 // [ JDG March 4, 2007 ] spirit 2
15 // [ JDG February 21, 2011 ] spirit 2.5
16 // [ JDG June 6, 2014 ] spirit x3 (from qi calc2, but using lambda functions)
17 //
18 ///////////////////////////////////////////////////////////////////////////////
19
20 #include <boost/spirit/home/x3.hpp>
21 #include <boost/spirit/home/x3/support/ast/variant.hpp>
22 #include <boost/fusion/include/adapt_struct.hpp>
23
24 #include <iostream>
25 #include <string>
26 #include <list>
27 #include <numeric>
28
29 namespace x3 = boost::spirit::x3;
30
31 namespace client
32 {
33 ///////////////////////////////////////////////////////////////////////////////
34 // Semantic actions
35 ////////////////////////////////////////////////////////1///////////////////////
36 namespace
37 {
38 using x3::_attr;
39
40 auto do_int = [](auto& ctx) { std::cout << "push " << _attr(ctx) << std::endl; };
41 auto do_add = []{ std::cout << "add\n"; };
42 auto do_subt = []{ std::cout << "subtract\n"; };
43 auto do_mult = []{ std::cout << "mult\n"; };
44 auto do_div = []{ std::cout << "divide\n"; };
45 auto do_neg = []{ std::cout << "negate\n"; };
46 }
47
48 ///////////////////////////////////////////////////////////////////////////////
49 // The calculator grammar
50 ///////////////////////////////////////////////////////////////////////////////
51 namespace calculator_grammar
52 {
53 using x3::uint_;
54 using x3::char_;
55
56 x3::rule<class expression> const expression("expression");
57 x3::rule<class term> const term("term");
58 x3::rule<class factor> const factor("factor");
59
60 auto const expression_def =
61 term
62 >> *( ('+' >> term [do_add])
63 | ('-' >> term [do_subt])
64 )
65 ;
66
67 auto const term_def =
68 factor
69 >> *( ('*' >> factor [do_mult])
70 | ('/' >> factor [do_div])
71 )
72 ;
73
74 auto const factor_def =
75 uint_ [do_int]
76 | '(' >> expression >> ')'
77 | ('-' >> factor [do_neg])
78 | ('+' >> factor)
79 ;
80
81 BOOST_SPIRIT_DEFINE(
82 expression
83 , term
84 , factor
85 );
86
87 auto calculator = expression;
88 }
89
90 using calculator_grammar::calculator;
91
92 }
93
94 ///////////////////////////////////////////////////////////////////////////////
95 // Main program
96 ///////////////////////////////////////////////////////////////////////////////
97 int
98 main()
99 {
100 std::cout << "/////////////////////////////////////////////////////////\n\n";
101 std::cout << "Expression parser...\n\n";
102 std::cout << "/////////////////////////////////////////////////////////\n\n";
103 std::cout << "Type an expression...or [q or Q] to quit\n\n";
104
105 typedef std::string::const_iterator iterator_type;
106
107 std::string str;
108 while (std::getline(std::cin, str))
109 {
110 if (str.empty() || str[0] == 'q' || str[0] == 'Q')
111 break;
112
113 auto& calc = client::calculator; // Our grammar
114
115 iterator_type iter = str.begin();
116 iterator_type end = str.end();
117 boost::spirit::x3::ascii::space_type space;
118 bool r = phrase_parse(iter, end, calc, space);
119
120 if (r && iter == end)
121 {
122 std::cout << "-------------------------\n";
123 std::cout << "Parsing succeeded\n";
124 std::cout << "-------------------------\n";
125 }
126 else
127 {
128 std::string rest(iter, end);
129 std::cout << "-------------------------\n";
130 std::cout << "Parsing failed\n";
131 std::cout << "stopped at: \"" << rest << "\"\n";
132 std::cout << "-------------------------\n";
133 }
134 }
135
136 std::cout << "Bye... :-) \n\n";
137 return 0;
138 }