1 /*=============================================================================
2 Copyright (c) 2001-2010 Joel de Guzman
3 Copyright (c) 2009 Francois Barel
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 //
16 ///////////////////////////////////////////////////////////////////////////////
17
18 #include <boost/config/warning_disable.hpp>
19 #include <boost/spirit/include/qi.hpp>
20 #include <boost/spirit/repository/include/qi_subrule.hpp>
21 #include <iostream>
22 #include <string>
23
24 namespace client
25 {
26 namespace qi = boost::spirit::qi;
27 namespace repo = boost::spirit::repository;
28 namespace ascii = boost::spirit::ascii;
29
30 ///////////////////////////////////////////////////////////////////////////////
31 // Our calculator grammar
32 ///////////////////////////////////////////////////////////////////////////////
33 template <typename Iterator>
34 struct calculator : qi::grammar<Iterator, ascii::space_type>
35 {
calculatorclient::calculator36 calculator() : calculator::base_type(entry)
37 {
38 using qi::uint_;
39
40 //[calc1_sr_def
41 entry = (
42 expression =
43 term
44 >> *( ('+' >> term)
45 | ('-' >> term)
46 )
47
48 , term =
49 factor
50 >> *( ('*' >> factor)
51 | ('/' >> factor)
52 )
53
54 , factor =
55 uint_
56 | '(' >> expression >> ')'
57 | ('-' >> factor)
58 | ('+' >> factor)
59 );
60 //]
61 }
62
63 qi::rule<Iterator, ascii::space_type> entry;
64
65 repo::qi::subrule<0> expression;
66 repo::qi::subrule<1> term;
67 repo::qi::subrule<2> 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 using boost::spirit::ascii::space;
83 typedef std::string::const_iterator iterator_type;
84 typedef client::calculator<iterator_type> calculator;
85
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