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/spirit/home/x3.hpp>
20#include <boost/spirit/home/x3/support/ast/variant.hpp>
21#include <boost/fusion/include/adapt_struct.hpp>
22
23#include <iostream>
24#include <string>
25#include <list>
26#include <numeric>
27
28namespace x3 = boost::spirit::x3;
29
30namespace client
31{
32 ///////////////////////////////////////////////////////////////////////////////
33 // The calculator grammar
34 ///////////////////////////////////////////////////////////////////////////////
35 namespace calculator_grammar
36 {
37 using x3::uint_;
38 using x3::char_;
39
40 x3::rule<class expression> const expression("expression");
41 x3::rule<class term> const term("term");
42 x3::rule<class factor> const factor("factor");
43
44 auto const expression_def =
45 term
46 >> *( ('+' >> term)
47 | ('-' >> term)
48 )
49 ;
50
51 auto const term_def =
52 factor
53 >> *( ('*' >> factor)
54 | ('/' >> factor)
55 )
56 ;
57
58 auto const factor_def =
59 uint_
60 | '(' >> expression >> ')'
61 | ('-' >> factor)
62 | ('+' >> factor)
63 ;
64
65 BOOST_SPIRIT_DEFINE(
66 expression
67 , term
68 , factor
69 );
70
71 auto calculator = expression;
72 }
73
74 using calculator_grammar::calculator;
75
76}
77
78///////////////////////////////////////////////////////////////////////////////
79// Main program
80///////////////////////////////////////////////////////////////////////////////
81int
82main()
83{
84 std::cout << "/////////////////////////////////////////////////////////\n\n";
85 std::cout << "Expression parser...\n\n";
86 std::cout << "/////////////////////////////////////////////////////////\n\n";
87 std::cout << "Type an expression...or [q or Q] to quit\n\n";
88
89 typedef std::string::const_iterator iterator_type;
90
91 std::string str;
92 while (std::getline(is&: std::cin, str&: str))
93 {
94 if (str.empty() || str[0] == 'q' || str[0] == 'Q')
95 break;
96
97 auto& calc = client::calculator; // Our grammar
98
99 iterator_type iter = str.begin();
100 iterator_type end = str.end();
101 boost::spirit::x3::ascii::space_type space;
102 bool r = phrase_parse(first&: iter, last: end, p: calc, s: space);
103
104 if (r && iter == end)
105 {
106 std::cout << "-------------------------\n";
107 std::cout << "Parsing succeeded\n";
108 std::cout << "-------------------------\n";
109 }
110 else
111 {
112 std::string rest(iter, end);
113 std::cout << "-------------------------\n";
114 std::cout << "Parsing failed\n";
115 std::cout << "stopped at: \"" << rest << "\"\n";
116 std::cout << "-------------------------\n";
117 }
118 }
119
120 std::cout << "Bye... :-) \n\n";
121 return 0;
122}
123

source code of boost/libs/spirit/example/x3/calc/calc1.cpp