/*============================================================================= 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 #include //#define BOOST_SPIRIT_DEBUG #define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 3 #include #include 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 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 > rx2; rule, parser_context<> > rx3; rule, parser_context<>, parser_address_tag> rx4; rule > rx5; rule, parser_address_tag> rx6; rule, parser_address_tag, scanner<> > rx7; rule rx8; rule > rx9; rule, parser_context<> > rx10; rule > rx11; rule, scanner<> > rx12; rule, scanner<> > rx13; rule, scanner<>, parser_address_tag> rx14; } struct my_grammar : public grammar { template 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::type , typename as_lower_scanner::type > scanners; rule r; rule rr; rule const& start() const { return rr; } }; }; void rule_2_or_more_scanners_tests() { { // 2 scanners typedef scanner_list, phrase_scanner_t> scanners; rule 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 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 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 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(); }