123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- /*=============================================================================
- Copyright (c) 2002-2003 Hartmut Kaiser
- http://spirit.sourceforge.net/
- Use, modification and distribution is subject to the Boost Software
- License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- http://www.boost.org/LICENSE_1_0.txt)
- =============================================================================*/
- ///////////////////////////////////////////////////////////////////////////////
- // This example shows the usage of the refactoring parser family parsers
- // See the "Refactoring Parsers" chapter in the User's Guide.
- #include <iostream>
- #include <string>
- #include <boost/spirit/include/classic_core.hpp>
- #include <boost/spirit/include/classic_refactoring.hpp>
- ///////////////////////////////////////////////////////////////////////////////
- // used namespaces
- using namespace std;
- using namespace BOOST_SPIRIT_CLASSIC_NS;
- ///////////////////////////////////////////////////////////////////////////////
- // actor, used by the refactor_action_p test
- struct refactor_action_actor
- {
- refactor_action_actor (std::string &str_) : str(str_) {}
- template <typename IteratorT>
- void operator() (IteratorT const &first, IteratorT const &last) const
- {
- str = std::string(first, last-first);
- }
- std::string &str;
- };
- ///////////////////////////////////////////////////////////////////////////////
- // main entry point
- int main()
- {
- parse_info<> result;
- char const *test_string = "Some string followed by a newline\n";
- ///////////////////////////////////////////////////////////////////////////////
- //
- // 1. Testing the refactor_unary_d parser
- //
- // The following test should successfully parse the test string, because the
- //
- // refactor_unary_d[
- // *anychar_p - '\n'
- // ]
- //
- // is refactored into
- //
- // *(anychar_p - '\n').
- //
- ///////////////////////////////////////////////////////////////////////////////
- result = parse(test_string, refactor_unary_d[*anychar_p - '\n'] >> '\n');
- if (result.full)
- {
- cout << "Successfully refactored an unary!" << endl;
- }
- else
- {
- cout << "Failed to refactor an unary!" << endl;
- }
- // Parsing the same test string without refactoring fails, because the
- // *anychar_p eats up all the input up to the end of the input string.
- result = parse(test_string, (*anychar_p - '\n') >> '\n');
- if (result.full)
- {
- cout
- << "Successfully parsed test string (should not happen)!"
- << endl;
- }
- else
- {
- cout
- << "Correctly failed parsing the test string (without refactoring)!"
- << endl;
- }
- cout << endl;
- ///////////////////////////////////////////////////////////////////////////////
- //
- // 2. Testing the refactor_action_d parser
- //
- // The following test should successfully parse the test string, because the
- //
- // refactor_action_d[
- // (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
- // ]
- //
- // is refactored into
- //
- // (*(anychar_p - '$') >> '$')[refactor_action_actor(str)].
- //
- ///////////////////////////////////////////////////////////////////////////////
- std::string str;
- char const *test_string2 = "Some test string ending with a $";
- result =
- parse(test_string2,
- refactor_action_d[
- (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
- ]
- );
- if (result.full && str == std::string(test_string2))
- {
- cout << "Successfully refactored an action!" << endl;
- cout << "Parsed: \"" << str << "\"" << endl;
- }
- else
- {
- cout << "Failed to refactor an action!" << endl;
- }
- // Parsing the same test string without refactoring fails, because the
- // the attached actor gets called only for the first part of the string
- // (without the '$')
- result =
- parse(test_string2,
- (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
- );
- if (result.full && str == std::string(test_string2))
- {
- cout << "Successfully parsed test string!" << endl;
- cout << "Parsed: \"" << str << "\"" << endl;
- }
- else
- {
- cout
- << "Correctly failed parsing the test string (without refactoring)!"
- << endl;
- cout << "Parsed instead: \"" << str << "\"" << endl;
- }
- cout << endl;
- ///////////////////////////////////////////////////////////////////////////////
- //
- // 3. Testing the refactor_action_d parser with an embedded (nested)
- // refactor_unary_p parser
- //
- // The following test should successfully parse the test string, because the
- //
- // refactor_action_unary_d[
- // ((*anychar_p)[refactor_action_actor(str)] - '$')
- // ] >> '$'
- //
- // is refactored into
- //
- // (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'.
- //
- ///////////////////////////////////////////////////////////////////////////////
- const refactor_action_gen<refactor_unary_gen<> > refactor_action_unary_d =
- refactor_action_gen<refactor_unary_gen<> >(refactor_unary_d);
- result =
- parse(test_string2,
- refactor_action_unary_d[
- ((*anychar_p)[refactor_action_actor(str)] - '$')
- ] >> '$'
- );
- if (result.full)
- {
- cout
- << "Successfully refactored an action attached to an unary!"
- << endl;
- cout << "Parsed: \"" << str << "\"" << endl;
- }
- else
- {
- cout << "Failed to refactor an action!" << endl;
- }
- // Parsing the same test string without refactoring fails, because the
- // anychar_p eats up all the input up to the end of the string
- result =
- parse(test_string2,
- ((*anychar_p)[refactor_action_actor(str)] - '$') >> '$'
- );
- if (result.full)
- {
- cout << "Successfully parsed test string!" << endl;
- cout << "Parsed: \"" << str << "\"" << endl;
- }
- else
- {
- cout
- << "Correctly failed parsing the test string (without refactoring)!"
- << endl;
- cout << "Parsed instead: \"" << str << "\"" << endl;
- }
- cout << endl;
- return 0;
- }
|