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 // 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 ] spirit 1
13 // [ JDG March 4, 2007 ] spirit 2
14 // [ JDG February 21, 2011 ] spirit 2.5
15 // [ JDG June 6, 2014 ] spirit x3
16 //
17 ///////////////////////////////////////////////////////////////////////////////
18
19 #include <boost/config/warning_disable.hpp>
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 // The calculator grammar
35 ///////////////////////////////////////////////////////////////////////////////
36 namespace calculator_grammar
37 {
38 using x3::uint_;
39 using x3::char_;
40
41 x3::rule<class expression> const expression("expression");
42 x3::rule<class term> const term("term");
43 x3::rule<class factor> const factor("factor");
44
45 auto const expression_def =
46 term
47 >> *( ('+' >> term)
48 | ('-' >> term)
49 )
50 ;
51
52 auto const term_def =
53 factor
54 >> *( ('*' >> factor)
55 | ('/' >> factor)
56 )
57 ;
58
59 auto const factor_def =
60 uint_
61 | '(' >> expression >> ')'
62 | ('-' >> factor)
63 | ('+' >> factor)
64 ;
65
66 BOOST_SPIRIT_DEFINE(
67 expression
68 , term
69 , factor
70 );
71
72 auto calculator = expression;
73 }
74
75 using calculator_grammar::calculator;
76
77 }
78
79 ///////////////////////////////////////////////////////////////////////////////
80 // Main program
81 ///////////////////////////////////////////////////////////////////////////////
82 int
main()83 main()
84 {
85 std::cout << "/////////////////////////////////////////////////////////\n\n";
86 std::cout << "Expression parser...\n\n";
87 std::cout << "/////////////////////////////////////////////////////////\n\n";
88 std::cout << "Type an expression...or [q or Q] to quit\n\n";
89
90 typedef std::string::const_iterator iterator_type;
91
92 std::string str;
93 while (std::getline(std::cin, str))
94 {
95 if (str.empty() || str[0] == 'q' || str[0] == 'Q')
96 break;
97
98 auto& calc = client::calculator; // Our grammar
99
100 iterator_type iter = str.begin();
101 iterator_type end = str.end();
102 boost::spirit::x3::ascii::space_type space;
103 bool r = phrase_parse(iter, end, calc, space);
104
105 if (r && iter == end)
106 {
107 std::cout << "-------------------------\n";
108 std::cout << "Parsing succeeded\n";
109 std::cout << "-------------------------\n";
110 }
111 else
112 {
113 std::string rest(iter, end);
114 std::cout << "-------------------------\n";
115 std::cout << "Parsing failed\n";
116 std::cout << "stopped at: \"" << rest << "\"\n";
117 std::cout << "-------------------------\n";
118 }
119 }
120
121 std::cout << "Bye... :-) \n\n";
122 return 0;
123 }
124