/*============================================================================= 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 #include #include #include /////////////////////////////////////////////////////////////////////////////// // 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 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_action_unary_d = refactor_action_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; }