1 /*=============================================================================
2 Copyright (c) 2001-2014 Joel de Guzman
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 ///////////////////////////////////////////////////////////////////////////////
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.
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)
18 ///////////////////////////////////////////////////////////////////////////////
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>
29 namespace x3
= boost::spirit::x3
;
33 ///////////////////////////////////////////////////////////////////////////////
35 ////////////////////////////////////////////////////////1///////////////////////
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"; };
48 ///////////////////////////////////////////////////////////////////////////////
49 // The calculator grammar
50 ///////////////////////////////////////////////////////////////////////////////
51 namespace calculator_grammar
56 x3::rule
<class expression
> const expression("expression");
57 x3::rule
<class term
> const term("term");
58 x3::rule
<class factor
> const factor("factor");
60 auto const expression_def
=
62 >> *( ('+' >> term
[do_add
])
63 | ('-' >> term
[do_subt
])
69 >> *( ('*' >> factor
[do_mult
])
70 | ('/' >> factor
[do_div
])
74 auto const factor_def
=
76 | '(' >> expression
>> ')'
77 | ('-' >> factor
[do_neg
])
87 auto calculator
= expression
;
90 using calculator_grammar::calculator
;
94 ///////////////////////////////////////////////////////////////////////////////
96 ///////////////////////////////////////////////////////////////////////////////
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";
105 typedef std::string::const_iterator iterator_type
;
108 while (std::getline(std::cin
, str
))
110 if (str
.empty() || str
[0] == 'q' || str
[0] == 'Q')
113 auto& calc
= client::calculator
; // Our grammar
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
);
120 if (r
&& iter
== end
)
122 std::cout
<< "-------------------------\n";
123 std::cout
<< "Parsing succeeded\n";
124 std::cout
<< "-------------------------\n";
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";
136 std::cout
<< "Bye... :-) \n\n";