/*============================================================================= Copyright (c) 2001-2015 Joel de Guzman Copyright (c) 2025 Nana Sakisaka Distributed under 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) =============================================================================*/ #define BOOST_SPIRIT_X4_DEBUG #include "test.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { struct my_error_handler { template Se, class Exception, class Context> void operator()(It const&, Se const& last, Exception const& x, Context const&) const { std::cout << "Error! Expecting: " << x.which() << ", got: \"" << std::string(x.where(), last) << "\"" << std::endl; } }; struct my_attribute { bool alive = true; void access() const { CHECK(alive); } ~my_attribute() { alive = false; } friend std::ostream& operator<<(std::ostream & os, my_attribute const & attr) { attr.access(); return os << "my_attribute"; } }; } // anonymous TEST_CASE("debug") { using namespace x4::standard; using x4::rule; using x4::int_; { // basic tests constexpr auto a = rule("a") = 'a'; constexpr auto b = rule("b") = 'b'; constexpr auto c = rule("c") = 'c'; { auto start = *(a | b | c); CHECK(parse("abcabcacb", start)); } { rule start("start"); auto start_def = start = (a | b) >> (start | b); CHECK(parse("aaaabababaaabbb", start_def)); CHECK(parse("aaaabababaaabba", start_def).is_partial_match()); } } { // basic tests w/ skipper auto a = rule("a") = 'a'; auto b = rule("b") = 'b'; auto c = rule("c") = 'c'; { auto start = *(a | b | c); CHECK(parse(" a b c a b c a c b ", start, space)); } { rule start("start"); auto start_def = start = (a | b) >> (start | b); CHECK(parse(" a a a a b a b a b a a a b b b ", start_def, space)); CHECK(parse(" a a a a b a b a b a a a b b a ", start_def, space).is_partial_match()); } } { // std::container attributes using fs = boost::fusion::vector; rule> start("start"); auto start_def = start = *(int_ >> alpha); CHECK(parse("1 a 2 b 3 c", start_def, space)); } { // error handling auto r_def = '(' > int_ > ',' > int_ > ')'; my_error_handler error_handler; auto parser = x4::with(error_handler)[r_def]; CHECK( parse("(123,456)", parser)); CHECK(!parse("(abc,def)", parser)); CHECK(!parse("(123,456]", parser)); CHECK(!parse("(123;456)", parser)); CHECK(!parse("[123,456]", parser)); } { x4::shared_symbols a{{{ "a", my_attribute{} }}}; auto b = rule("b") = a; my_attribute attr; CHECK(parse("a", b, attr)); } }