/*============================================================================= Copyright (c) 2001-2015 Joel de Guzman 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) =============================================================================*/ #include #include #include #include #include #include #include #include "test.hpp" namespace x3 = boost::spirit::x3; int got_it = 0; struct my_rule_class { template x3::error_handler_result on_error(Iterator&, Iterator const& last, Exception const& x, Context const&) { std::cout << "Error! Expecting: " << x.which() << ", got: \"" << std::string(x.where(), last) << "\"" << std::endl ; return x3::error_handler_result::fail; } template inline void on_success(Iterator const&, Iterator const&, Attribute&, Context const&) { ++got_it; } }; int main() { using spirit_test::test_attr; using spirit_test::test; using namespace boost::spirit::x3::ascii; using boost::spirit::x3::rule; using boost::spirit::x3::int_; using boost::spirit::x3::lit; { // show that ra = rb and ra %= rb works as expected rule ra; rule rb; int attr; auto ra_def = (ra %= int_); BOOST_TEST(test_attr("123", ra_def, attr)); BOOST_TEST(attr == 123); auto rb_def = (rb %= ra_def); BOOST_TEST(test_attr("123", rb_def, attr)); BOOST_TEST(attr == 123); auto rb_def2 = (rb = ra_def); BOOST_TEST(test_attr("123", rb_def2, attr)); BOOST_TEST(attr == 123); } { // show that ra %= rb works as expected with semantic actions rule ra; rule rb; int attr; auto f = [](auto&){}; auto ra_def = (ra %= int_[f]); BOOST_TEST(test_attr("123", ra_def, attr)); BOOST_TEST(attr == 123); auto ra_def2 = (rb = (ra %= int_[f])); BOOST_TEST(test_attr("123", ra_def2, attr)); BOOST_TEST(attr == 123); } { // std::string as container attribute with auto rules std::string attr; // test deduced auto rule behavior auto text = rule() = +(!char_(')') >> !char_('>') >> char_); attr.clear(); BOOST_TEST(test_attr("x", text, attr)); BOOST_TEST(attr == "x"); } { // error handling auto r = rule() = '(' > int_ > ',' > int_ > ')'; BOOST_TEST(test("(123,456)", r)); BOOST_TEST(!test("(abc,def)", r)); BOOST_TEST(!test("(123,456]", r)); BOOST_TEST(!test("(123;456)", r)); BOOST_TEST(!test("[123,456]", r)); BOOST_TEST(got_it == 1); } { typedef boost::variant v_type; auto r1 = rule() = int_; v_type v; BOOST_TEST(test_attr("1", r1, v) && v.which() == 1 && boost::get(v) == 1); typedef boost::optional ov_type; auto r2 = rule() = int_; ov_type ov; BOOST_TEST(test_attr("1", r2, ov) && ov && boost::get(ov) == 1); } // test handling of single element fusion sequences { using boost::fusion::vector; using boost::fusion::at_c; auto r = rule>() = int_; vector v(0); BOOST_TEST(test_attr("1", r, v) && at_c<0>(v) == 1); } { // attribute compatibility test using boost::spirit::x3::rule; using boost::spirit::x3::int_; auto const expr = int_; short i; BOOST_TEST(test_attr("1", expr, i) && i == 1); // ok const rule< class int_rule, int > int_rule( "int_rule" ); auto const int_rule_def = int_; auto const start = int_rule = int_rule_def; short j; BOOST_TEST(test_attr("1", start, j) && j == 1); // error } return boost::report_errors(); }