• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2002-2003 Hartmut Kaiser
3     http://spirit.sourceforge.net/
4 
5     Use, modification and distribution is subject to the Boost Software
6     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7     http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 ///////////////////////////////////////////////////////////////////////////////
10 //  This example shows the usage of the refactoring parser family parsers
11 //  See the "Refactoring Parsers" chapter in the User's Guide.
12 
13 #include <iostream>
14 #include <string>
15 
16 #include <boost/spirit/include/classic_core.hpp>
17 #include <boost/spirit/include/classic_refactoring.hpp>
18 
19 ///////////////////////////////////////////////////////////////////////////////
20 // used namespaces
21 using namespace std;
22 using namespace BOOST_SPIRIT_CLASSIC_NS;
23 
24 ///////////////////////////////////////////////////////////////////////////////
25 // actor, used by the refactor_action_p test
26 struct refactor_action_actor
27 {
refactor_action_actorrefactor_action_actor28     refactor_action_actor (std::string &str_) : str(str_) {}
29 
30     template <typename IteratorT>
operator ()refactor_action_actor31     void operator() (IteratorT const &first, IteratorT const &last) const
32     {
33         str = std::string(first, last-first);
34     }
35 
36     std::string &str;
37 };
38 
39 ///////////////////////////////////////////////////////////////////////////////
40 // main entry point
main()41 int main()
42 {
43     parse_info<> result;
44     char const *test_string = "Some string followed by a newline\n";
45 
46 ///////////////////////////////////////////////////////////////////////////////
47 //
48 //  1. Testing the refactor_unary_d parser
49 //
50 //  The following test should successfully parse the test string, because the
51 //
52 //      refactor_unary_d[
53 //          *anychar_p - '\n'
54 //      ]
55 //
56 //  is refactored into
57 //
58 //      *(anychar_p - '\n').
59 //
60 ///////////////////////////////////////////////////////////////////////////////
61 
62     result = parse(test_string, refactor_unary_d[*anychar_p - '\n'] >> '\n');
63 
64     if (result.full)
65     {
66         cout << "Successfully refactored an unary!" << endl;
67     }
68     else
69     {
70         cout << "Failed to refactor an unary!" << endl;
71     }
72 
73 //  Parsing the same test string without refactoring fails, because the
74 //  *anychar_p eats up all the input up to the end of the input string.
75 
76     result = parse(test_string, (*anychar_p - '\n') >> '\n');
77 
78     if (result.full)
79     {
80         cout
81             << "Successfully parsed test string (should not happen)!"
82             << endl;
83     }
84     else
85     {
86         cout
87             << "Correctly failed parsing the test string (without refactoring)!"
88             << endl;
89     }
90     cout << endl;
91 
92 ///////////////////////////////////////////////////////////////////////////////
93 //
94 //  2. Testing the refactor_action_d parser
95 //
96 //  The following test should successfully parse the test string, because the
97 //
98 //      refactor_action_d[
99 //          (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
100 //      ]
101 //
102 //  is refactored into
103 //
104 //      (*(anychar_p - '$') >> '$')[refactor_action_actor(str)].
105 //
106 ///////////////////////////////////////////////////////////////////////////////
107 
108     std::string str;
109     char const *test_string2 = "Some test string ending with a $";
110 
111     result =
112         parse(test_string2,
113             refactor_action_d[
114                 (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
115             ]
116         );
117 
118     if (result.full && str == std::string(test_string2))
119     {
120         cout << "Successfully refactored an action!" << endl;
121         cout << "Parsed: \"" << str << "\"" << endl;
122     }
123     else
124     {
125         cout << "Failed to refactor an action!" << endl;
126     }
127 
128 //  Parsing the same test string without refactoring fails, because the
129 //  the attached actor gets called only for the first part of the string
130 //  (without the '$')
131 
132     result =
133         parse(test_string2,
134             (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
135         );
136 
137     if (result.full && str == std::string(test_string2))
138     {
139         cout << "Successfully parsed test string!" << endl;
140         cout << "Parsed: \"" << str << "\"" << endl;
141     }
142     else
143     {
144         cout
145             << "Correctly failed parsing the test string (without refactoring)!"
146             << endl;
147         cout << "Parsed instead: \"" << str << "\"" << endl;
148     }
149     cout << endl;
150 
151 ///////////////////////////////////////////////////////////////////////////////
152 //
153 //  3. Testing the refactor_action_d parser with an embedded (nested)
154 //  refactor_unary_p parser
155 //
156 //  The following test should successfully parse the test string, because the
157 //
158 //      refactor_action_unary_d[
159 //          ((*anychar_p)[refactor_action_actor(str)] - '$')
160 //      ] >> '$'
161 //
162 //  is refactored into
163 //
164 //      (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'.
165 //
166 ///////////////////////////////////////////////////////////////////////////////
167 
168     const refactor_action_gen<refactor_unary_gen<> > refactor_action_unary_d =
169         refactor_action_gen<refactor_unary_gen<> >(refactor_unary_d);
170 
171     result =
172         parse(test_string2,
173             refactor_action_unary_d[
174                 ((*anychar_p)[refactor_action_actor(str)] - '$')
175             ] >> '$'
176         );
177 
178     if (result.full)
179     {
180         cout
181             << "Successfully refactored an action attached to an unary!"
182             << endl;
183         cout << "Parsed: \"" << str << "\"" << endl;
184     }
185     else
186     {
187         cout << "Failed to refactor an action!" << endl;
188     }
189 
190 //  Parsing the same test string without refactoring fails, because the
191 //  anychar_p eats up all the input up to the end of the string
192 
193     result =
194         parse(test_string2,
195             ((*anychar_p)[refactor_action_actor(str)] - '$') >> '$'
196         );
197 
198     if (result.full)
199     {
200         cout << "Successfully parsed test string!" << endl;
201         cout << "Parsed: \"" << str << "\"" << endl;
202     }
203     else
204     {
205         cout
206             << "Correctly failed parsing the test string (without refactoring)!"
207             << endl;
208         cout << "Parsed instead: \"" << str << "\"" << endl;
209     }
210     cout << endl;
211 
212     return 0;
213 }
214 
215