]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (c) 2001-2010 Hartmut Kaiser |
2 | // Copyright (c) 2001-2010 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 | // A complex number micro generator - take 3. | |
10 | // | |
11 | // Look'ma, still no semantic actions! And no explicit access to member | |
12 | // functions any more. | |
13 | // | |
14 | // [ HK April 6, 2010 ] spirit2 | |
15 | // | |
16 | /////////////////////////////////////////////////////////////////////////////// | |
17 | ||
18 | #include <boost/config/warning_disable.hpp> | |
19 | #include <boost/spirit/include/qi.hpp> | |
20 | #include <boost/spirit/include/karma.hpp> | |
21 | #include <boost/spirit/include/phoenix_core.hpp> | |
22 | #include <boost/spirit/include/phoenix_operator.hpp> | |
23 | #include <boost/fusion/include/std_pair.hpp> | |
24 | #include <boost/fusion/include/adapt_adt.hpp> | |
11fdf7f2 | 25 | #include <boost/spirit/include/support_adapt_adt_attributes.hpp> |
7c673cae FG |
26 | |
27 | #include <iostream> | |
28 | #include <string> | |
29 | #include <complex> | |
30 | ||
31 | /////////////////////////////////////////////////////////////////////////////// | |
32 | // The following macro adapts the type std::complex<double> as a fusion | |
33 | // sequence. | |
34 | //[tutorial_karma_complex_number_adapt_class | |
35 | // We can leave off the setters as Karma does not need them. | |
36 | BOOST_FUSION_ADAPT_ADT( | |
37 | std::complex<double>, | |
38 | (bool, bool, obj.imag() != 0, /**/) | |
39 | (double, double, obj.real(), /**/) | |
40 | (double, double, obj.imag(), /**/) | |
41 | ) | |
42 | //] | |
43 | ||
44 | namespace client | |
45 | { | |
46 | /////////////////////////////////////////////////////////////////////////// | |
47 | // Our complex number parser/compiler (that's just a copy of the complex | |
48 | // number example from Qi (see examples/qi/complex_number.cpp) | |
49 | /////////////////////////////////////////////////////////////////////////// | |
50 | template <typename Iterator> | |
51 | bool parse_complex(Iterator first, Iterator last, std::complex<double>& c) | |
52 | { | |
53 | using boost::spirit::qi::double_; | |
54 | using boost::spirit::qi::_1; | |
55 | using boost::spirit::qi::phrase_parse; | |
56 | using boost::spirit::ascii::space; | |
57 | using boost::phoenix::ref; | |
58 | ||
59 | double rN = 0.0; | |
60 | double iN = 0.0; | |
61 | bool r = phrase_parse(first, last, | |
62 | ( | |
63 | '(' >> double_[ref(rN) = _1] | |
64 | >> -(',' >> double_[ref(iN) = _1]) >> ')' | |
65 | | double_[ref(rN) = _1] | |
66 | ), | |
67 | space); | |
68 | ||
69 | if (!r || first != last) // fail if we did not get a full match | |
70 | return false; | |
71 | c = std::complex<double>(rN, iN); | |
72 | return r; | |
73 | } | |
74 | ||
75 | /////////////////////////////////////////////////////////////////////////// | |
76 | // Our complex number generator | |
77 | /////////////////////////////////////////////////////////////////////////// | |
78 | //[tutorial_karma_complex_number_adapt | |
79 | template <typename OutputIterator> | |
80 | bool generate_complex(OutputIterator sink, std::complex<double> const& c) | |
81 | { | |
82 | using boost::spirit::karma::double_; | |
83 | using boost::spirit::karma::bool_; | |
84 | using boost::spirit::karma::true_; | |
85 | using boost::spirit::karma::omit; | |
86 | using boost::spirit::karma::generate; | |
87 | ||
88 | return generate(sink, | |
89 | ||
90 | // Begin grammar | |
91 | ( | |
92 | &true_ << '(' << double_ << ", " << double_ << ')' | |
93 | | omit[bool_] << double_ | |
94 | ), | |
95 | // End grammar | |
96 | ||
97 | c // Data to output | |
98 | ); | |
99 | } | |
100 | //] | |
101 | } | |
102 | ||
103 | /////////////////////////////////////////////////////////////////////////////// | |
104 | // Main program | |
105 | /////////////////////////////////////////////////////////////////////////////// | |
106 | int main() | |
107 | { | |
108 | std::cout << "/////////////////////////////////////////////////////////\n\n"; | |
109 | std::cout << "\t\tA complex number micro generator for Spirit...\n\n"; | |
110 | std::cout << "/////////////////////////////////////////////////////////\n\n"; | |
111 | ||
112 | std::cout << "Give me a complex number of the form r or (r) or (r,i) \n"; | |
113 | std::cout << "Type [q or Q] to quit\n\n"; | |
114 | ||
115 | std::string str; | |
116 | while (getline(std::cin, str)) | |
117 | { | |
118 | if (str.empty() || str[0] == 'q' || str[0] == 'Q') | |
119 | break; | |
120 | ||
121 | std::complex<double> c; | |
122 | if (client::parse_complex(str.begin(), str.end(), c)) | |
123 | { | |
124 | std::cout << "-------------------------\n"; | |
125 | ||
126 | std::string generated; | |
127 | std::back_insert_iterator<std::string> sink(generated); | |
128 | if (!client::generate_complex(sink, c)) | |
129 | { | |
130 | std::cout << "-------------------------\n"; | |
131 | std::cout << "Generating failed\n"; | |
132 | std::cout << "-------------------------\n"; | |
133 | } | |
134 | else | |
135 | { | |
136 | std::cout << "-------------------------\n"; | |
137 | std::cout << "Generated: " << generated << "\n"; | |
138 | std::cout << "-------------------------\n"; | |
139 | } | |
140 | } | |
141 | else | |
142 | { | |
143 | std::cout << "-------------------------\n"; | |
144 | std::cout << "Parsing failed\n"; | |
145 | std::cout << "-------------------------\n"; | |
146 | } | |
147 | } | |
148 | ||
149 | std::cout << "Bye... :-) \n\n"; | |
150 | return 0; | |
151 | } | |
152 | ||
153 |