0ac381dcf3
[SVN r44371]
215 lines
6.1 KiB
C++
215 lines
6.1 KiB
C++
/*=============================================================================
|
|
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;
|
|
}
|
|
|