📄 rule.ipp
字号:
/*============================================================================= Copyright (c) 1998-2003 Joel de Guzman 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_RULE_IPP)#define BOOST_SPIRIT_RULE_IPP#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1#include <boost/preprocessor/repeat.hpp>#include <boost/preprocessor/repeat_from_to.hpp>#include <boost/preprocessor/enum_params.hpp>#include <boost/preprocessor/enum_params_with_defaults.hpp>#include <boost/preprocessor/facilities/intercept.hpp>#include <boost/preprocessor/inc.hpp>#include <boost/preprocessor/cat.hpp>#endif#include <boost/spirit/home/classic/core/parser.hpp>#include <boost/spirit/home/classic/core/scanner/scanner.hpp>#include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp>#include <boost/spirit/home/classic/core/non_terminal/parser_id.hpp>#include <boost/type_traits/is_base_and_derived.hpp>///////////////////////////////////////////////////////////////////////////////namespace boost { namespace spirit {BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 template < BOOST_PP_ENUM_BINARY_PARAMS( BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT, typename ScannerT, = mpl::void_ BOOST_PP_INTERCEPT ) > struct scanner_list;#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 /////////////////////////////////////////////////////////////////////////// namespace impl { template <typename BaseT, typename DefaultT , typename T0, typename T1, typename T2> struct get_param { typedef typename mpl::if_< is_base_and_derived<BaseT, T0> , T0 , typename mpl::if_< is_base_and_derived<BaseT, T1> , T1 , typename mpl::if_< is_base_and_derived<BaseT, T2> , T2 , DefaultT >::type >::type >::type type; }; template <typename T0, typename T1, typename T2> struct get_context { typedef typename get_param< parser_context_base, parser_context<>, T0, T1, T2>::type type; }; template <typename T0, typename T1, typename T2> struct get_tag { typedef typename get_param< parser_tag_base, parser_address_tag, T0, T1, T2>::type type; }; template <typename T0, typename T1, typename T2> struct get_scanner { typedef typename get_param< scanner_base, scanner<>, T0, T1, T2>::type type; }; /////////////////////////////////////////////////////////////////////// // // rule_base class // // The rule_base class implements the basic plumbing for rules // minus the storage mechanism. It is up to the derived class // to actually store the definition somewhere. The rule_base // class assumes that the derived class provides a get() function // that will return a pointer to a parser. The get() function // may return NULL. See rule below for details. // // <<< For framework use only. Not for public consumption. >>> // /////////////////////////////////////////////////////////////////////// template < typename DerivedT // derived class , typename EmbedT // how derived class is embedded , typename T0 = nil_t // see rule class , typename T1 = nil_t // see rule class , typename T2 = nil_t // see rule class > class rule_base; // forward declaration class rule_base_access {#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) public: // YUCK!#else template < typename DerivedT , typename EmbedT , typename T0 , typename T1 , typename T2 > friend class rule_base;#endif template <typename RuleT> static typename RuleT::abstract_parser_t* get(RuleT const& r) { return r.get(); } }; template < typename DerivedT // derived class , typename EmbedT // how derived class is embedded , typename T0 // see rule class , typename T1 // see rule class , typename T2 // see rule class > class rule_base : public parser<DerivedT> , public impl::get_context<T0, T1, T2>::type::base_t , public context_aux< typename impl::get_context<T0, T1, T2>::type, DerivedT> , public impl::get_tag<T0, T1, T2>::type { public: typedef typename impl::get_scanner<T0, T1, T2>::type scanner_t; typedef typename impl::get_context<T0, T1, T2>::type context_t; typedef typename impl::get_tag<T0, T1, T2>::type tag_t; typedef EmbedT embed_t; typedef typename context_t::context_linker_t linked_context_t; typedef typename linked_context_t::attr_t attr_t; template <typename ScannerT> struct result { typedef typename match_result<ScannerT, attr_t>::type type; }; template <typename ScannerT> typename parser_result<DerivedT, ScannerT>::type parse(ScannerT const& scan) const { typedef parser_scanner_linker<ScannerT> linked_scanner_t; typedef typename parser_result<DerivedT, ScannerT>::type result_t; BOOST_SPIRIT_CONTEXT_PARSE( scan, *this, linked_scanner_t, linked_context_t, result_t); } template <typename ScannerT> typename parser_result<DerivedT, ScannerT>::type parse_main(ScannerT const& scan) const { typename parser_result<DerivedT, ScannerT>::type hit; // MWCW 8.3 needs this cast to be done through a pointer, // not a reference. Otherwise, it will silently construct // a temporary, causing an infinite runtime recursion. DerivedT const* derived_this = static_cast<DerivedT const*>(this); if (rule_base_access::get(*derived_this)) { typename ScannerT::iterator_t s(scan.first); hit = rule_base_access::get(*derived_this) ->do_parse_virtual(scan); scan.group_match(hit, this->id(), s, scan.first); } else { hit = scan.no_match(); } return hit; } }; /////////////////////////////////////////////////////////////////////// // // abstract_parser class //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -