1 /*=============================================================================
2 Copyright (c) 2001-2011 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 // Plain calculator example demonstrating the grammar. The parser is a
10 // syntax checker only and does not do any semantic evaluation.
11 //
12 // [ JDG May 10, 2002 ] spirit1
13 // [ JDG March 4, 2007 ] spirit2
14 // [ JDG February 21, 2011 ] spirit2.5
15 //
16 ///////////////////////////////////////////////////////////////////////////////
17
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
24
25 #include <boost/config/warning_disable.hpp>
26 #include <boost/spirit/include/qi.hpp>
27 #include <iostream>
28 #include <string>
29
30 namespace client
31 {
32 namespace qi = boost::spirit::qi;
33 namespace ascii = boost::spirit::ascii;
34
35 ///////////////////////////////////////////////////////////////////////////////
36 // Our calculator grammar
37 ///////////////////////////////////////////////////////////////////////////////
38 template <typename Iterator>
39 struct calculator : qi::grammar<Iterator, ascii::space_type>
40 {
calculatorclient::calculator41 calculator() : calculator::base_type(expression)
42 {
43 qi::uint_type uint_;
44
45 expression =
46 term
47 >> *( ('+' >> term)
48 | ('-' >> term)
49 )
50 ;
51
52 term =
53 factor
54 >> *( ('*' >> factor)
55 | ('/' >> factor)
56 )
57 ;
58
59 factor =
60 uint_
61 | '(' >> expression >> ')'
62 | ('-' >> factor)
63 | ('+' >> factor)
64 ;
65 }
66
67 qi::rule<Iterator, ascii::space_type> expression, term, factor;
68 };
69 }
70
71 ///////////////////////////////////////////////////////////////////////////////
72 // Main program
73 ///////////////////////////////////////////////////////////////////////////////
74 int
main()75 main()
76 {
77 std::cout << "/////////////////////////////////////////////////////////\n\n";
78 std::cout << "Expression parser...\n\n";
79 std::cout << "/////////////////////////////////////////////////////////\n\n";
80 std::cout << "Type an expression...or [q or Q] to quit\n\n";
81
82 typedef std::string::const_iterator iterator_type;
83 typedef client::calculator<iterator_type> calculator;
84
85 boost::spirit::ascii::space_type space; // Our skipper
86 calculator calc; // Our grammar
87
88 std::string str;
89 while (std::getline(std::cin, str))
90 {
91 if (str.empty() || str[0] == 'q' || str[0] == 'Q')
92 break;
93
94 std::string::const_iterator iter = str.begin();
95 std::string::const_iterator end = str.end();
96 bool r = phrase_parse(iter, end, calc, space);
97
98 if (r && iter == end)
99 {
100 std::cout << "-------------------------\n";
101 std::cout << "Parsing succeeded\n";
102 std::cout << "-------------------------\n";
103 }
104 else
105 {
106 std::string rest(iter, end);
107 std::cout << "-------------------------\n";
108 std::cout << "Parsing failed\n";
109 std::cout << "stopped at: \" " << rest << "\"\n";
110 std::cout << "-------------------------\n";
111 }
112 }
113
114 std::cout << "Bye... :-) \n\n";
115 return 0;
116 }
117
118
119