a9131015e6
Now that the "using namespace std" has been removed, endl has to be qualified with "std::".
265 lines
6.5 KiB
C++
265 lines
6.5 KiB
C++
/*=============================================================================
|
|
Copyright (c) 1998-2003 Joel de Guzman
|
|
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)
|
|
=============================================================================*/
|
|
#include <iostream>
|
|
#include <boost/detail/lightweight_test.hpp>
|
|
|
|
|
|
//#define BOOST_SPIRIT_DEBUG
|
|
#define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 3
|
|
|
|
#include <boost/spirit/include/classic_core.hpp>
|
|
#include <boost/spirit/include/classic_stored_rule.hpp>
|
|
using namespace BOOST_SPIRIT_CLASSIC_NS;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Rule tests
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
aliasing_tests()
|
|
{
|
|
rule<> a = ch_p('a');
|
|
rule<> b = ch_p('b');
|
|
rule<> c = ch_p('c');
|
|
|
|
std::cout << "sizeof(rule<>): " << sizeof(rule<>) << std::endl;
|
|
|
|
BOOST_SPIRIT_DEBUG_RULE(a);
|
|
BOOST_SPIRIT_DEBUG_RULE(b);
|
|
BOOST_SPIRIT_DEBUG_RULE(c);
|
|
|
|
rule<> start;
|
|
BOOST_SPIRIT_DEBUG_RULE(start);
|
|
|
|
rule<> d;
|
|
d = start; // aliasing
|
|
|
|
parse_info<char const*> pi;
|
|
|
|
start = *(a | b | c);
|
|
pi = parse("abcabcacb", d);
|
|
BOOST_TEST(pi.hit);
|
|
BOOST_TEST(pi.full);
|
|
BOOST_TEST(pi.length == 9);
|
|
BOOST_TEST(*pi.stop == 0);
|
|
|
|
start = (a | b) >> (start | b);
|
|
pi = parse("aaaabababaaabbb", d);
|
|
BOOST_TEST(pi.hit);
|
|
BOOST_TEST(pi.full);
|
|
BOOST_TEST(pi.length == 15);
|
|
BOOST_TEST(*pi.stop == 0);
|
|
}
|
|
|
|
void
|
|
rule_template_param_tests()
|
|
{
|
|
// test that rules can be issued its template params in any order:
|
|
|
|
rule<> rx1;
|
|
rule<scanner<> > rx2;
|
|
rule<scanner<>, parser_context<> > rx3;
|
|
rule<scanner<>, parser_context<>, parser_address_tag> rx4;
|
|
|
|
rule<parser_context<> > rx5;
|
|
rule<parser_context<>, parser_address_tag> rx6;
|
|
rule<parser_context<>, parser_address_tag, scanner<> > rx7;
|
|
|
|
rule<parser_address_tag> rx8;
|
|
rule<parser_address_tag, scanner<> > rx9;
|
|
rule<parser_address_tag, scanner<>, parser_context<> > rx10;
|
|
|
|
rule<parser_address_tag, parser_context<> > rx11;
|
|
rule<parser_address_tag, parser_context<>, scanner<> > rx12;
|
|
|
|
rule<parser_context<>, scanner<> > rx13;
|
|
rule<parser_context<>, scanner<>, parser_address_tag> rx14;
|
|
}
|
|
|
|
struct my_grammar : public grammar<my_grammar>
|
|
{
|
|
template <typename ScannerT>
|
|
struct definition
|
|
{
|
|
definition(my_grammar const& /*self*/)
|
|
{
|
|
r = lower_p;
|
|
rr = +(lexeme_d[r] >> as_lower_d[r] >> r);
|
|
}
|
|
|
|
typedef scanner_list<
|
|
ScannerT
|
|
, typename lexeme_scanner<ScannerT>::type
|
|
, typename as_lower_scanner<ScannerT>::type
|
|
> scanners;
|
|
|
|
rule<scanners> r;
|
|
rule<ScannerT> rr;
|
|
rule<ScannerT> const& start() const { return rr; }
|
|
};
|
|
};
|
|
|
|
void
|
|
rule_2_or_more_scanners_tests()
|
|
{
|
|
{ // 2 scanners
|
|
typedef scanner_list<scanner<>, phrase_scanner_t> scanners;
|
|
|
|
rule<scanners> r = +anychar_p;
|
|
BOOST_TEST(parse("abcdefghijk", r).full);
|
|
BOOST_TEST(parse("a b c d e f g h i j k", r, space_p).full);
|
|
}
|
|
|
|
{ // 3 scanners
|
|
my_grammar g;
|
|
BOOST_TEST(parse("abcdef aBc d e f aBc d E f", g, space_p).full);
|
|
}
|
|
}
|
|
|
|
void
|
|
rule_basic_tests()
|
|
{
|
|
rule<> a = ch_p('a');
|
|
rule<> b = ch_p('b');
|
|
rule<> c = ch_p('c');
|
|
|
|
BOOST_SPIRIT_DEBUG_RULE(a);
|
|
BOOST_SPIRIT_DEBUG_RULE(b);
|
|
BOOST_SPIRIT_DEBUG_RULE(c);
|
|
|
|
parse_info<char const*> pi;
|
|
|
|
rule<> start = *(a | b | c);
|
|
|
|
BOOST_SPIRIT_DEBUG_RULE(start);
|
|
|
|
pi = parse("abcabcacb", start);
|
|
BOOST_TEST(pi.hit);
|
|
BOOST_TEST(pi.full);
|
|
BOOST_TEST(pi.length == 9);
|
|
BOOST_TEST(*pi.stop == 0);
|
|
|
|
start = (a | b) >> (start | b);
|
|
pi = parse("aaaabababaaabbb", start);
|
|
BOOST_TEST(pi.hit);
|
|
BOOST_TEST(pi.full);
|
|
BOOST_TEST(pi.length == 15);
|
|
BOOST_TEST(*pi.stop == 0);
|
|
|
|
pi = parse("aaaabababaaabba", start);
|
|
BOOST_TEST(pi.hit);
|
|
BOOST_TEST(!pi.full);
|
|
BOOST_TEST(pi.length == 14);
|
|
|
|
rule<> r = anychar_p;
|
|
r.copy(); // copy test (compile only)
|
|
}
|
|
|
|
void
|
|
stored_rule_basic_tests()
|
|
{
|
|
stored_rule<> a = ch_p('a');
|
|
stored_rule<> b = ch_p('b');
|
|
stored_rule<> c = ch_p('c');
|
|
|
|
BOOST_SPIRIT_DEBUG_RULE(a);
|
|
BOOST_SPIRIT_DEBUG_RULE(b);
|
|
BOOST_SPIRIT_DEBUG_RULE(c);
|
|
|
|
parse_info<char const*> pi;
|
|
|
|
stored_rule<> start = *(a | b | c);
|
|
|
|
BOOST_SPIRIT_DEBUG_RULE(start);
|
|
|
|
pi = parse("abcabcacb", start);
|
|
BOOST_TEST(pi.hit);
|
|
BOOST_TEST(pi.full);
|
|
BOOST_TEST(pi.length == 9);
|
|
BOOST_TEST(*pi.stop == 0);
|
|
|
|
start = (a | b) >> (start | b);
|
|
pi = parse("aaaabababaaabbb", start);
|
|
BOOST_TEST(pi.hit);
|
|
BOOST_TEST(pi.full);
|
|
BOOST_TEST(pi.length == 15);
|
|
BOOST_TEST(*pi.stop == 0);
|
|
|
|
pi = parse("aaaabababaaabba", start);
|
|
BOOST_TEST(pi.hit);
|
|
BOOST_TEST(!pi.full);
|
|
BOOST_TEST(pi.length == 14);
|
|
}
|
|
|
|
void
|
|
stored_rule_dynamic_tests()
|
|
{
|
|
rule<> a = ch_p('a');
|
|
rule<> b = ch_p('b');
|
|
rule<> c = ch_p('c');
|
|
|
|
BOOST_SPIRIT_DEBUG_RULE(a);
|
|
BOOST_SPIRIT_DEBUG_RULE(b);
|
|
BOOST_SPIRIT_DEBUG_RULE(c);
|
|
|
|
parse_info<char const*> pi;
|
|
|
|
// The FF is the dynamic equivalent of start = *(a | b | c);
|
|
stored_rule<> start = a;
|
|
start = start.copy() | b;
|
|
start = start.copy() | c;
|
|
start = *(start.copy());
|
|
|
|
std::cout << "sizeof(stored_rule<>): " << sizeof(stored_rule<>) << std::endl;
|
|
|
|
BOOST_SPIRIT_DEBUG_RULE(start);
|
|
|
|
pi = parse("abcabcacb", start);
|
|
BOOST_TEST(pi.hit);
|
|
BOOST_TEST(pi.full);
|
|
BOOST_TEST(pi.length == 9);
|
|
BOOST_TEST(*pi.stop == 0);
|
|
|
|
// The FF is the dynamic equivalent of start = (a | b) >> (start | b);
|
|
start = b;
|
|
start = a | start.copy();
|
|
start = start.copy() >> (start | b);
|
|
|
|
pi = parse("aaaabababaaabbb", start);
|
|
BOOST_TEST(pi.hit);
|
|
BOOST_TEST(pi.full);
|
|
BOOST_TEST(pi.length == 15);
|
|
BOOST_TEST(*pi.stop == 0);
|
|
|
|
pi = parse("aaaabababaaabba", start);
|
|
BOOST_TEST(pi.hit);
|
|
BOOST_TEST(!pi.full);
|
|
BOOST_TEST(pi.length == 14);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Main
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
int
|
|
main()
|
|
{
|
|
rule_basic_tests();
|
|
aliasing_tests();
|
|
rule_template_param_tests();
|
|
rule_2_or_more_scanners_tests();
|
|
stored_rule_basic_tests();
|
|
stored_rule_dynamic_tests();
|
|
|
|
return boost::report_errors();
|
|
}
|
|
|