📄 subrule.ipp
字号:
/*============================================================================= Copyright (c) 2002-2003 Joel de Guzman Copyright (c) 2002-2003 Hartmut Kaiser http://spirit.sourceforge.net/ Use, modification and distribution is subject to 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_SUBRULE_IPP)#define BOOST_SPIRIT_SUBRULE_IPPnamespace boost { namespace spirit {BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN template <typename FirstT, typename RestT> struct subrule_list; template <int ID, typename DefT, typename ContextT> struct subrule_parser; namespace impl { #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template <int N, typename ListT> struct get_subrule; template <int N, typename ListT> struct get_subrule_chooser { static ListT t(); static char test(nil_t); static int test(...); // Set value to // 0: ListT is empty // 1: ListT's first item has same ID // 2: ListT's first item has a different ID enum { id = ListT::first_t::id, is_same_id = N == id, is_nil_t = sizeof(char) == sizeof(test(t())), value = is_nil_t ? 0 : (is_same_id ? 1 : 2) }; }; template <int N> struct subrule_chooser; template <> struct subrule_chooser<0> { // First case. ListT is empty template <int N, typename ListT> struct result { typedef nil_t type; }; }; template <> struct subrule_chooser<1> { // Second case. ListT is non-empty and the list's // first item has the ID we are looking for. template <int N, typename ListT> struct result { typedef typename ListT::first_t::def_t type; }; }; template <> struct subrule_chooser<2> { // Third case. ListT is non-empty but the list's // first item does not have the ID we are looking for. template <int N, typename ListT> struct result { typedef typename get_subrule<N, ListT::rest_t>::type type; }; }; template <int N, typename ListT> struct get_subrule { enum { n = get_subrule_chooser<N, ListT>::value }; typedef typename subrule_chooser<n>::template result<N, ListT>::type type; }; #else template <int N, typename ListT> struct get_subrule { // First case. ListT is non-empty but the list's // first item does not have the ID we are looking for. typedef typename get_subrule<N, typename ListT::rest_t>::type type; }; template <int ID, typename DefT, typename ContextT, typename RestT> struct get_subrule< ID, subrule_list< subrule_parser<ID, DefT, ContextT>, RestT> > { // Second case. ListT is non-empty and the list's // first item has the ID we are looking for. typedef DefT type; }; template <int ID> struct get_subrule<ID, nil_t> { // Third case. ListT is empty typedef nil_t type; }; #endif template <typename T1, typename T2> struct get_result_t { // If the result type dictated by the context is nil_t (no closures // present), then the whole subrule_parser return type is equal to // the return type of the right hand side of this subrule_parser, // otherwise it is equal to the dictated return value. typedef typename mpl::if_< boost::is_same<T1, nil_t>, T2, T1 >::type type; }; template <int ID, typename ScannerT, typename ContextResultT> struct get_subrule_result { typedef typename impl::get_subrule<ID, typename ScannerT::list_t>::type parser_t; typedef typename parser_result<parser_t, ScannerT>::type def_result_t; typedef typename match_result<ScannerT, ContextResultT>::type context_result_t; typedef typename get_result_t<context_result_t, def_result_t>::type type; }; template <typename DefT, typename ScannerT, typename ContextResultT> struct get_subrule_parser_result { typedef typename parser_result<DefT, ScannerT>::type def_result_t; typedef typename match_result<ScannerT, ContextResultT>::type context_result_t; typedef typename get_result_t<context_result_t, def_result_t>::type type; }; template <typename SubruleT, int ID> struct same_subrule_id { BOOST_STATIC_CONSTANT(bool, value = (SubruleT::id == ID)); }; template <typename RT, typename ScannerT, int ID> struct parse_subrule { template <typename ListT> static void do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::true_) { r = list.first.rhs.parse(scan); } template <typename ListT> static void do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::false_) { typedef typename ListT::rest_t::first_t subrule_t; mpl::bool_<same_subrule_id<subrule_t, ID>::value> same_id; do_parse(r, scan, list.rest, same_id); } static void do_(RT& r, ScannerT const& scan) { typedef typename ScannerT::list_t::first_t subrule_t; mpl::bool_<same_subrule_id<subrule_t, ID>::value> same_id; do_parse(r, scan, scan.list, same_id); } };}BOOST_SPIRIT_CLASSIC_NAMESPACE_END}} // namespace boost::spirit::impl#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -