/*============================================================================= Copyright (c) 2001-2014 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) ==============================================================================*/ #if !defined(BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM) #define BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM #include #include #include #include #include #include #if !defined(BOOST_SPIRIT_X3_NO_RTTI) #include #endif namespace boost { namespace spirit { namespace x3 { // default parse_rule implementation template inline detail::default_parse_rule_result parse_rule( rule /* rule_ */ , Iterator& first, Iterator const& last , Context const& context, ActualAttribute& attr) { static_assert(!is_same(context)), unused_type>::value, "BOOST_SPIRIT_DEFINE undefined for this rule."); return get(context).parse(first, last, context, unused, attr); } template struct rule_definition : parser> { typedef rule_definition this_type; typedef ID id; typedef RHS rhs_type; typedef rule lhs_type; typedef Attribute attribute_type; static bool const has_attribute = !is_same::value; static bool const handles_container = traits::is_container::value; static bool const force_attribute = force_attribute_; rule_definition(RHS const& rhs, char const* name) : rhs(rhs), name(name) {} template bool parse(Iterator& first, Iterator const& last , Context const& context, unused_type, Attribute_& attr) const { return detail::rule_parser ::call_rule_definition( rhs, name, first, last , context , attr , mpl::bool_()); } RHS rhs; char const* name; }; template struct rule : parser> { typedef ID id; typedef Attribute attribute_type; static bool const has_attribute = !is_same::value; static bool const handles_container = traits::is_container::value; static bool const force_attribute = force_attribute_; #if !defined(BOOST_SPIRIT_X3_NO_RTTI) rule() : name(typeid(rule).name()) {} #else rule() : name("unnamed") {} #endif rule(char const* name) : name(name) {} template rule_definition< ID, typename extension::as_parser::value_type, Attribute, force_attribute_> operator=(RHS const& rhs) const { return { as_parser(rhs), name }; } template rule_definition< ID, typename extension::as_parser::value_type, Attribute, true> operator%=(RHS const& rhs) const { return { as_parser(rhs), name }; } template bool parse(Iterator& first, Iterator const& last , Context const& context, unused_type, Attribute_& attr) const { return parse_rule(*this, first, last, context, attr); } char const* name; }; namespace traits { template struct is_rule : mpl::false_ {}; template struct is_rule> : mpl::true_ {}; template struct is_rule> : mpl::true_ {}; } template struct get_info>::type> { typedef std::string result_type; std::string operator()(T const& r) const { BOOST_ASSERT_MSG(r.name, "uninitialized rule"); // static initialization order fiasco return r.name? r.name : "uninitialized"; } }; #define BOOST_SPIRIT_DECLARE_(r, data, rule_type) \ template \ bool parse_rule( \ rule_type rule_ \ , Iterator& first, Iterator const& last \ , Context const& context, Attribute& attr); \ /***/ #define BOOST_SPIRIT_DECLARE(...) BOOST_PP_SEQ_FOR_EACH( \ BOOST_SPIRIT_DECLARE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \ /***/ #define BOOST_SPIRIT_DEFINE_(r, data, rule_name) \ template \ inline bool parse_rule( \ decltype(rule_name) /* rule_ */ \ , Iterator& first, Iterator const& last \ , Context const& context, Attribute& attr) \ { \ using boost::spirit::x3::unused; \ static auto const def_ = (rule_name = BOOST_PP_CAT(rule_name, _def)); \ return def_.parse(first, last, context, unused, attr); \ } \ /***/ #define BOOST_SPIRIT_DEFINE(...) BOOST_PP_SEQ_FOR_EACH( \ BOOST_SPIRIT_DEFINE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \ /***/ #define BOOST_SPIRIT_INSTANTIATE(rule_type, Iterator, Context) \ template bool parse_rule( \ rule_type rule_ \ , Iterator& first, Iterator const& last \ , Context const& context, rule_type::attribute_type& attr); \ /***/ }}} #endif