diff options
Diffstat (limited to 'boost/spirit/home/x3/nonterminal/rule.hpp')
-rw-r--r-- | boost/spirit/home/x3/nonterminal/rule.hpp | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/boost/spirit/home/x3/nonterminal/rule.hpp b/boost/spirit/home/x3/nonterminal/rule.hpp new file mode 100644 index 0000000000..049c6be57b --- /dev/null +++ b/boost/spirit/home/x3/nonterminal/rule.hpp @@ -0,0 +1,186 @@ +/*============================================================================= + 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 |