1 /*=============================================================================
2 Copyright (c) 2001-2011 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 phoenix to do the actual expression evaluation. The parser is
11 // essentially an "interpreter" that evaluates expressions on the fly.
13 // [ JDG June 29, 2002 ] spirit1
14 // [ JDG March 5, 2007 ] spirit2
16 ///////////////////////////////////////////////////////////////////////////////
18 // Spirit v2.5 allows you to suppress automatic generation
19 // of predefined terminals to speed up complation. With
20 // BOOST_SPIRIT_NO_PREDEFINED_TERMINALS defined, you are
21 // responsible in creating instances of the terminals that
22 // you need (e.g. see qi::uint_type uint_ below).
23 #define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
25 #include <boost/spirit/include/qi.hpp>
26 #include <boost/phoenix/operator.hpp>
33 namespace qi
= boost::spirit::qi
;
34 namespace ascii
= boost::spirit::ascii
;
36 ///////////////////////////////////////////////////////////////////////////
37 // Our calculator grammar
38 ///////////////////////////////////////////////////////////////////////////
39 template <typename Iterator
>
40 struct calculator
: qi::grammar
<Iterator
, int(), ascii::space_type
>
42 calculator() : calculator::base_type(expression
)
50 >> *( ('+' >> term
[_val
+= _1
])
51 | ('-' >> term
[_val
-= _1
])
57 >> *( ('*' >> factor
[_val
*= _1
])
58 | ('/' >> factor
[_val
/= _1
])
64 | '(' >> expression
[_val
= _1
] >> ')'
65 | ('-' >> factor
[_val
= -_1
])
66 | ('+' >> factor
[_val
= _1
])
70 qi::rule
<Iterator
, int(), ascii::space_type
> expression
, term
, factor
;
74 ///////////////////////////////////////////////////////////////////////////////
76 ///////////////////////////////////////////////////////////////////////////////
80 std::cout
<< "/////////////////////////////////////////////////////////\n\n";
81 std::cout
<< "Expression parser...\n\n";
82 std::cout
<< "/////////////////////////////////////////////////////////\n\n";
83 std::cout
<< "Type an expression...or [q or Q] to quit\n\n";
85 typedef std::string::const_iterator iterator_type
;
86 typedef client::calculator
<iterator_type
> calculator
;
88 boost::spirit::ascii::space_type space
; // Our skipper
89 calculator calc
; // Our grammar
93 while (std::getline(std::cin
, str
))
95 if (str
.empty() || str
[0] == 'q' || str
[0] == 'Q')
98 std::string::const_iterator iter
= str
.begin();
99 std::string::const_iterator end
= str
.end();
100 bool r
= phrase_parse(iter
, end
, calc
, space
, result
);
102 if (r
&& iter
== end
)
104 std::cout
<< "-------------------------\n";
105 std::cout
<< "Parsing succeeded\n";
106 std::cout
<< "result = " << result
<< std::endl
;
107 std::cout
<< "-------------------------\n";
111 std::string
rest(iter
, end
);
112 std::cout
<< "-------------------------\n";
113 std::cout
<< "Parsing failed\n";
114 std::cout
<< "stopped at: \" " << rest
<< "\"\n";
115 std::cout
<< "-------------------------\n";
119 std::cout
<< "Bye... :-) \n\n";