Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / spirit / example / x3 / calc1.cpp
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 = expression_def
68           , term = term_def
69           , factor = factor_def
70         );
71
72         auto calculator = expression;
73     }
74
75     using calculator_grammar::calculator;
76
77 }
78
79 ///////////////////////////////////////////////////////////////////////////////
80 //  Main program
81 ///////////////////////////////////////////////////////////////////////////////
82 int
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 }