/*============================================================================= Copyright (c) 2001-2012 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" using boost::spirit::x3::_val; struct f { template void operator()(Context const& ctx) const { _val(ctx) += _attr(ctx); } }; struct stationary : boost::noncopyable { explicit stationary(int i) : val{i} {} stationary& operator=(int i) { val = i; return *this; } int val; }; namespace check_stationary { boost::spirit::x3::rule const a; boost::spirit::x3::rule const b; auto const a_def = '{' >> boost::spirit::x3::int_ >> '}'; auto const b_def = a; BOOST_SPIRIT_DEFINE(a, b) } namespace check_recursive { using node_t = boost::make_recursive_variant< int, std::vector >::type; boost::spirit::x3::rule const grammar; auto const grammar_def = '[' >> grammar % ',' >> ']' | boost::spirit::x3::int_; BOOST_SPIRIT_DEFINE(grammar) } 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::lit; using boost::spirit::x3::eps; using boost::spirit::x3::unused_type; { // synth attribute value-init std::string s; typedef rule rule_type; auto rdef = rule_type() = alpha [f()] ; BOOST_TEST(test_attr("abcdef", +rdef, s)); BOOST_TEST(s == "abcdef"); } { // synth attribute value-init std::string s; typedef rule rule_type; auto rdef = rule_type() = alpha / [](auto& ctx) { _val(ctx) += _attr(ctx); } ; BOOST_TEST(test_attr("abcdef", +rdef, s)); BOOST_TEST(s == "abcdef"); } { auto r = rule{} = eps[([] (auto& ctx) { using boost::spirit::x3::_val; static_assert(std::is_same, unused_type>::value, "Attribute must not be synthesized"); })]; BOOST_TEST(test("", r)); } { // ensure no unneeded synthesization, copying and moving occurred stationary st { 0 }; BOOST_TEST(test_attr("{42}", check_stationary::b, st)); BOOST_TEST_EQ(st.val, 42); } { using namespace check_recursive; node_t v; BOOST_TEST(test_attr("[4,2]", grammar, v)); BOOST_TEST((node_t{std::vector{{4}, {2}}} == v)); } return boost::report_errors(); }