| /*============================================================================= |
| 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 |
| |
| #if defined(_MSC_VER) |
| #pragma once |
| #endif |
| |
| #include <boost/spirit/home/x3/nonterminal/detail/rule.hpp> |
| #include <boost/type_traits/is_same.hpp> |
| #include <boost/spirit/home/x3/support/context.hpp> |
| #include <boost/preprocessor/variadic/to_seq.hpp> |
| #include <boost/preprocessor/variadic/elem.hpp> |
| #include <boost/preprocessor/seq/for_each.hpp> |
| |
| #if !defined(BOOST_SPIRIT_X3_NO_RTTI) |
| #include <typeinfo> |
| #endif |
| |
| namespace boost { namespace spirit { namespace x3 |
| { |
| template <typename ID> |
| struct identity {}; |
| |
| // default parse_rule implementation |
| template <typename ID, typename Attribute, typename Iterator |
| , typename Context, typename ActualAttribute> |
| inline detail::default_parse_rule_result |
| parse_rule( |
| rule<ID, Attribute> rule_ |
| , Iterator& first, Iterator const& last |
| , Context const& context, ActualAttribute& attr) |
| { |
| static_assert(!is_same<decltype(get<ID>(context)), unused_type>::value, |
| "BOOST_SPIRIT_DEFINE undefined for this rule."); |
| return get<ID>(context).parse(first, last, context, unused, attr); |
| } |
| |
| template <typename ID, typename RHS, typename Attribute, bool force_attribute_> |
| struct rule_definition : parser<rule_definition<ID, RHS, Attribute, force_attribute_>> |
| { |
| typedef rule_definition<ID, RHS, Attribute, force_attribute_> this_type; |
| typedef ID id; |
| typedef RHS rhs_type; |
| typedef rule<ID, Attribute> lhs_type; |
| typedef Attribute attribute_type; |
| |
| static bool const has_attribute = |
| !is_same<Attribute, unused_type>::value; |
| static bool const handles_container = |
| traits::is_container<Attribute>::value; |
| static bool const force_attribute = |
| force_attribute_; |
| |
| rule_definition(RHS rhs, char const* name) |
| : rhs(rhs), name(name) {} |
| |
| template <typename Iterator, typename Context, typename Attribute_> |
| bool parse(Iterator& first, Iterator const& last |
| , Context const& context, unused_type, Attribute_& attr) const |
| { |
| return detail::rule_parser<attribute_type, ID> |
| ::call_rule_definition( |
| rhs, name, first, last |
| , context |
| , attr |
| , mpl::bool_<force_attribute>()); |
| } |
| |
| RHS rhs; |
| char const* name; |
| }; |
| |
| template <typename ID, typename Attribute> |
| struct rule : parser<rule<ID, Attribute>> |
| { |
| typedef ID id; |
| typedef Attribute attribute_type; |
| static bool const has_attribute = |
| !is_same<Attribute, unused_type>::value; |
| static bool const handles_container = |
| traits::is_container<Attribute>::value; |
| |
| #if !defined(BOOST_SPIRIT_X3_NO_RTTI) |
| rule() : name(typeid(rule).name()) {} |
| #else |
| rule() : name("unnamed") {} |
| #endif |
| |
| rule(char const* name) |
| : name(name) {} |
| |
| template <typename RHS> |
| rule_definition< |
| ID, typename extension::as_parser<RHS>::value_type, Attribute, false> |
| operator=(RHS const& rhs) const |
| { |
| return {as_parser(rhs), name}; |
| } |
| |
| template <typename RHS> |
| rule_definition< |
| ID, typename extension::as_parser<RHS>::value_type, Attribute, true> |
| operator%=(RHS const& rhs) const |
| { |
| return {as_parser(rhs), name}; |
| } |
| |
| |
| template <typename Iterator, typename Context, typename Attribute_> |
| 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 <typename T, typename Enable = void> |
| struct is_rule : mpl::false_ {}; |
| |
| template <typename ID, typename Attribute> |
| struct is_rule<rule<ID, Attribute>> : mpl::true_ {}; |
| |
| template <typename ID, typename Attribute, typename RHS, bool force_attribute> |
| struct is_rule<rule_definition<ID, RHS, Attribute, force_attribute>> : mpl::true_ {}; |
| } |
| |
| template <typename T> |
| struct get_info<T, typename enable_if<traits::is_rule<T>>::type> |
| { |
| typedef std::string result_type; |
| std::string operator()(T const& r) const |
| { |
| return r.name; |
| } |
| }; |
| |
| #define BOOST_SPIRIT_DECLARE_(r, data, rule_type) \ |
| template <typename Iterator, typename Context, typename Attribute> \ |
| 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, def) \ |
| template <typename Iterator, typename Context, typename Attribute> \ |
| inline bool parse_rule( \ |
| decltype(def)::lhs_type rule_ \ |
| , Iterator& first, Iterator const& last \ |
| , Context const& context, Attribute& attr) \ |
| { \ |
| using boost::spirit::x3::unused; \ |
| auto const& def_ = (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<Iterator, Context, rule_type::attribute_type>( \ |
| rule_type rule_ \ |
| , Iterator& first, Iterator const& last \ |
| , Context const& context, rule_type::attribute_type& attr); \ |
| /***/ |
| |
| |
| }}} |
| |
| #endif |