Chris@102: /*============================================================================= Chris@102: Copyright (c) 2001-2014 Joel de Guzman Chris@102: Chris@102: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@102: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@102: ==============================================================================*/ Chris@102: #if !defined(BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM) Chris@102: #define BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM Chris@102: Chris@102: #if defined(_MSC_VER) Chris@102: #pragma once Chris@102: #endif Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: #if !defined(BOOST_SPIRIT_X3_NO_RTTI) Chris@102: #include Chris@102: #endif Chris@102: Chris@102: namespace boost { namespace spirit { namespace x3 Chris@102: { Chris@102: template Chris@102: struct identity {}; Chris@102: Chris@102: // default parse_rule implementation Chris@102: template Chris@102: inline detail::default_parse_rule_result Chris@102: parse_rule( Chris@102: rule rule_ Chris@102: , Iterator& first, Iterator const& last Chris@102: , Context const& context, ActualAttribute& attr) Chris@102: { Chris@102: static_assert(!is_same(context)), unused_type>::value, Chris@102: "BOOST_SPIRIT_DEFINE undefined for this rule."); Chris@102: return get(context).parse(first, last, context, unused, attr); Chris@102: } Chris@102: Chris@102: template Chris@102: struct rule_definition : parser> Chris@102: { Chris@102: typedef rule_definition this_type; Chris@102: typedef ID id; Chris@102: typedef RHS rhs_type; Chris@102: typedef rule lhs_type; Chris@102: typedef Attribute attribute_type; Chris@102: Chris@102: static bool const has_attribute = Chris@102: !is_same::value; Chris@102: static bool const handles_container = Chris@102: traits::is_container::value; Chris@102: static bool const force_attribute = Chris@102: force_attribute_; Chris@102: Chris@102: rule_definition(RHS rhs, char const* name) Chris@102: : rhs(rhs), name(name) {} Chris@102: Chris@102: template Chris@102: bool parse(Iterator& first, Iterator const& last Chris@102: , Context const& context, unused_type, Attribute_& attr) const Chris@102: { Chris@102: return detail::rule_parser Chris@102: ::call_rule_definition( Chris@102: rhs, name, first, last Chris@102: , context Chris@102: , attr Chris@102: , mpl::bool_()); Chris@102: } Chris@102: Chris@102: RHS rhs; Chris@102: char const* name; Chris@102: }; Chris@102: Chris@102: template Chris@102: struct rule : parser> Chris@102: { Chris@102: typedef ID id; Chris@102: typedef Attribute attribute_type; Chris@102: static bool const has_attribute = Chris@102: !is_same::value; Chris@102: static bool const handles_container = Chris@102: traits::is_container::value; Chris@102: Chris@102: #if !defined(BOOST_SPIRIT_X3_NO_RTTI) Chris@102: rule() : name(typeid(rule).name()) {} Chris@102: #else Chris@102: rule() : name("unnamed") {} Chris@102: #endif Chris@102: Chris@102: rule(char const* name) Chris@102: : name(name) {} Chris@102: Chris@102: template Chris@102: rule_definition< Chris@102: ID, typename extension::as_parser::value_type, Attribute, false> Chris@102: operator=(RHS const& rhs) const Chris@102: { Chris@102: return {as_parser(rhs), name}; Chris@102: } Chris@102: Chris@102: template Chris@102: rule_definition< Chris@102: ID, typename extension::as_parser::value_type, Attribute, true> Chris@102: operator%=(RHS const& rhs) const Chris@102: { Chris@102: return {as_parser(rhs), name}; Chris@102: } Chris@102: Chris@102: Chris@102: template Chris@102: bool parse(Iterator& first, Iterator const& last Chris@102: , Context const& context, unused_type, Attribute_& attr) const Chris@102: { Chris@102: return parse_rule(*this, first, last, context, attr); Chris@102: } Chris@102: Chris@102: char const* name; Chris@102: }; Chris@102: Chris@102: namespace traits Chris@102: { Chris@102: template Chris@102: struct is_rule : mpl::false_ {}; Chris@102: Chris@102: template Chris@102: struct is_rule> : mpl::true_ {}; Chris@102: Chris@102: template Chris@102: struct is_rule> : mpl::true_ {}; Chris@102: } Chris@102: Chris@102: template Chris@102: struct get_info>::type> Chris@102: { Chris@102: typedef std::string result_type; Chris@102: std::string operator()(T const& r) const Chris@102: { Chris@102: return r.name; Chris@102: } Chris@102: }; Chris@102: Chris@102: #define BOOST_SPIRIT_DECLARE_(r, data, rule_type) \ Chris@102: template \ Chris@102: bool parse_rule( \ Chris@102: rule_type rule_ \ Chris@102: , Iterator& first, Iterator const& last \ Chris@102: , Context const& context, Attribute& attr); \ Chris@102: /***/ Chris@102: Chris@102: #define BOOST_SPIRIT_DECLARE(...) BOOST_PP_SEQ_FOR_EACH( \ Chris@102: BOOST_SPIRIT_DECLARE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \ Chris@102: /***/ Chris@102: Chris@102: #define BOOST_SPIRIT_DEFINE_(r, data, def) \ Chris@102: template \ Chris@102: inline bool parse_rule( \ Chris@102: decltype(def)::lhs_type rule_ \ Chris@102: , Iterator& first, Iterator const& last \ Chris@102: , Context const& context, Attribute& attr) \ Chris@102: { \ Chris@102: using boost::spirit::x3::unused; \ Chris@102: auto const& def_ = (def); \ Chris@102: return def_.parse(first, last, context, unused, attr); \ Chris@102: } \ Chris@102: /***/ Chris@102: Chris@102: #define BOOST_SPIRIT_DEFINE(...) BOOST_PP_SEQ_FOR_EACH( \ Chris@102: BOOST_SPIRIT_DEFINE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \ Chris@102: /***/ Chris@102: Chris@102: #define BOOST_SPIRIT_INSTANTIATE(rule_type, Iterator, Context) \ Chris@102: template bool parse_rule( \ Chris@102: rule_type rule_ \ Chris@102: , Iterator& first, Iterator const& last \ Chris@102: , Context const& context, rule_type::attribute_type& attr); \ Chris@102: /***/ Chris@102: Chris@102: Chris@102: }}} Chris@102: Chris@102: #endif