📄 rule_parser.hpp
字号:
// Dependencies
//==============================================================================
# include <boost/config.hpp>
# include <boost/detail/workaround.hpp>
# include <boost/call_traits.hpp>
# include <boost/typeof/typeof.hpp>
# include <boost/spirit/core/parser.hpp>
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/seq/seq.hpp>
# include <boost/preprocessor/seq/for_each_i.hpp>
# include <boost/preprocessor/tuple/eat.hpp>
# include <boost/preprocessor/tuple/to_seq.hpp>
# include <boost/preprocessor/array/size.hpp>
# include <boost/preprocessor/control/if.hpp>
# include <boost/preprocessor/control/iif.hpp>
# include <boost/preprocessor/control/expr_iif.hpp>
# include <boost/preprocessor/logical/or.hpp>
# include <boost/preprocessor/logical/nor.hpp>
# include <boost/preprocessor/logical/not.hpp>
# include <boost/preprocessor/logical/compl.hpp>
# include <boost/preprocessor/arithmetic/inc.hpp>
# include <boost/preprocessor/arithmetic/dec.hpp>
# include <boost/preprocessor/arithmetic/add.hpp>
# include <boost/preprocessor/detail/is_unary.hpp>
# include <boost/preprocessor/detail/is_binary.hpp>
# include <boost/preprocessor/repetition/repeat.hpp>
# include <boost/preprocessor/repetition/enum_params.hpp>
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
# include <boost/preprocessor/repetition/enum_shifted_params.hpp>
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
# include <boost/preprocessor/punctuation/comma.hpp>
# include <boost/preprocessor/punctuation/comma_if.hpp>
# include <boost/preprocessor/facilities/empty.hpp>
# include <boost/preprocessor/facilities/identity.hpp>
# include <boost/preprocessor/facilities/intercept.hpp>
//==============================================================================
// Interface
//==============================================================================
// Creates a rule parser. Use at namespace scope.
# define BOOST_SPIRIT_RULE_PARSER(name,params,actions,members,rule) \
BOOST_SPIRIT_RP_IMPL_I(name,params,actions,members,rule)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Creates a non-templated rule parser. Use at namespace scope.
# define BOOST_SPIRIT_OPAQUE_RULE_PARSER(name,params,members,rule) \
BOOST_SPIRIT_RP_OPAQUE_IMPL_I(name,params,members,rule)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Defines an action placeholder. Use at namespace scope.
# define BOOST_SPIRIT_ACTION_PLACEHOLDER(name) \
BOOST_SPIRIT_RP_AP_IMPL(name,::boost::spirit::type_of)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Utilities to embed parsers by reference.
namespace boost
{
namespace spirit
{
template<class P> class parser_reference;
template<class P> parser_reference<P> embed_by_reference(parser<P> const &);
}
}
//==============================================================================
// Implementation
//==============================================================================
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// RP_REGISTER_TEMPLATE
//
// Boost.Typeof registration from within BOOST_SPIRIT__NAMESPACE
# define BOOST_SPIRIT_RP_REGISTER_TEMPLATE(name,params) \
BOOST_SPIRIT_RP_EMIT(NS_CLOSE,BOOST_SPIRIT__NAMESPACE,-) \
BOOST_TYPEOF_REGISTER_TEMPLATE( \
BOOST_SPIRIT_RP_EMIT(NS_QUALIFY,BOOST_SPIRIT__NAMESPACE,-) name, \
params) \
BOOST_SPIRIT_RP_EMIT(NS_OPEN,BOOST_SPIRIT__NAMESPACE,-)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// RP_REGISTER_TYPE
//
// Boost.Typeof registration from within BOOST_SPIRIT__NAMESPACE
# define BOOST_SPIRIT_RP_REGISTER_TYPE(name) \
BOOST_SPIRIT_RP_EMIT(NS_CLOSE,BOOST_SPIRIT__NAMESPACE,-) \
BOOST_TYPEOF_REGISTER_TYPE( \
BOOST_SPIRIT_RP_EMIT(NS_QUALIFY,BOOST_SPIRIT__NAMESPACE,-) name ) \
BOOST_SPIRIT_RP_EMIT(NS_OPEN,BOOST_SPIRIT__NAMESPACE,-)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// RP_AP_IMPL
//
// The action placeholder definition
# define BOOST_SPIRIT_RP_AP_IMPL(name,ns) \
namespace __action_placeholder \
{ \
struct name \
{ \
template<typename Action> \
ns :: action_chain< name, ns :: replace, Action> \
operator=(Action const & __a) const \
{ return ns :: action_chain< name, ns :: replace, Action>(__a); } \
\
template<typename Action> \
ns :: action_chain< name, ns :: append, Action> \
operator+=(Action const & __a) const \
{ return ns :: action_chain< name, ns :: append, Action> (__a); } \
}; \
} \
__action_placeholder:: name const name = __action_placeholder:: name ();
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// RP_IMPL_I
//
// Does some precalculation so RP_IMPL_II can look cleaner
# define BOOST_SPIRIT_RP_IMPL_I(name,pars,acts,mbrs,expr) \
BOOST_SPIRIT_RP_IMPL_II(name, name ## _t , \
pars, BOOST_SPIRIT_RP_ARRAY_SIZE(pars), \
acts, BOOST_SPIRIT_RP_ARRAY_SIZE(acts), \
mbrs, BOOST_SPIRIT_RP_ARRAY_SIZE(mbrs), expr)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// RP_IMPL_II
# define BOOST_SPIRIT_RP_IMPL_II(name,name_t,pars,np,acts,na,mbrs,nm,x) \
BOOST_PP_IIF(BOOST_PP_OR(np,na),BOOST_SPIRIT_RP_IMPL_III, \
BOOST_SPIRIT_RP_OPAQUE_IMPL_II) \
(name,name_t,pars,np,acts,na,mbrs,nm,x)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// RP_IMPL_III
//
// The rule parser definition
# define BOOST_SPIRIT_RP_IMPL_III(name,name_t,pars,np,acts,na,mbrs,nm,x) \
\
template< BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,typename __,1) > \
class name_t \
: public ::boost::spirit::parser< name_t \
< BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,__,0) > > \
{ \
class __rule \
{ \
BOOST_SPIRIT_RP_EMIT(PM_STATIC,pars,__T) \
BOOST_SPIRIT_RP_EMIT(AP_STATIC,acts,-) \
BOOST_SPIRIT_RP_EMIT(MV_STATIC,mbrs,BOOST_PP_IDENTITY(typename)) \
public: \
BOOST_TYPEOF_NESTED_TYPEDEF_TPL(__expr, \
::boost::spirit::type_of::depend_on_type<__Dummy>(x) ); \
}; \
\
public: \
\
typedef name_t self_t; \
typedef typename __rule::__expr::type::parser_category_t \
parser_category_t; \
\
BOOST_PP_EXPR_IIF(BOOST_PP_NOR(np,na),typedef self_t const & embed_t;) \
\
protected: \
\
BOOST_SPIRIT_RP_EMIT(MV_NONSTATIC,mbrs,BOOST_PP_IDENTITY(typename)) \
BOOST_SPIRIT_RP_IF(na,SPIRIT_RP_AP_EXTRA_MBRS,2)(np,na) \
\
typename __rule::__expr::type::embed_t __parser; \
\
public: \
\
explicit name_t ( BOOST_SPIRIT_RP_CTOR(PARAMS,pars,np,acts) ) \
: BOOST_SPIRIT_RP_EMIT(MV_CTOR_INIT_LIST,mbrs,-) \
BOOST_PP_COMMA_IF(nm) \
BOOST_SPIRIT_RP_IF(na,SPIRIT_RP_CTOR_COMMA,4)(INIT_LIST,pars,np,acts)\
__parser(x) \
{ } \
\
name_t( name_t const & that) \
: BOOST_SPIRIT_RP_EMIT(MV_CTOR_COPY_INIT_LIST,mbrs,that) \
BOOST_PP_COMMA_IF(nm) \
BOOST_SPIRIT_RP_IF(na,SPIRIT_RP_CTOR_COMMA,4) \
(COPY_INIT_LIST,pars,np,acts) \
__parser(that.__parser) \
{ } \
\
template<typename Scanner> struct result \
{ \
typedef typename ::boost::spirit::parser_result< \
typename __rule::__expr::type, Scanner>::type type; \
}; \
\
template<typename Scanner> \
typename ::boost::spirit::parser_result<self_t, Scanner>::type \
parse(Scanner const & s) const { return __parser.parse(s); } \
\
BOOST_SPIRIT_RP_IF(na,SPIRIT_RP_AP_HANDLER,5) \
(name_t,np,acts,na,::boost::spirit::type_of) \
}; \
\
BOOST_PP_IF(np,BOOST_SPIRIT_RP_GEN_FUNC,BOOST_SPIRIT_RP_GLOB_VAR) \
(name,name_t,np,na) \
BOOST_SPIRIT_RP_REGISTER_TEMPLATE \
(name_t,BOOST_PP_INC(BOOST_PP_ADD(np,na)))
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// RP_OPAQUE_IMPL_I
//
# define BOOST_SPIRIT_RP_OPAQUE_IMPL_I(name,pars,mbrs,expr) \
BOOST_SPIRIT_RP_OPAQUE_IMPL_II(name, name ## _t, \
pars,BOOST_SPIRIT_RP_ARRAY_SIZE(pars),-,-,\
mbrs,BOOST_SPIRIT_RP_ARRAY_SIZE(mbrs),expr)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// RP_OPAQUE_IMPL_II
//
# define BOOST_SPIRIT_RP_OPAQUE_IMPL_II(name,name_t,pars,np,_1,_2,mbrs,nm,x) \
class name_t; \
\
BOOST_SPIRIT_RP_REGISTER_TYPE(name_t) \
\
class name_t \
: public ::boost::spirit::parser< name_t > \
{ \
class __rule \
{ \
BOOST_SPIRIT_RP_EMIT(PM_OPAQUE_STATIC,pars,-) \
BOOST_SPIRIT_RP_EMIT(MV_STATIC,mbrs,BOOST_PP_EMPTY) \
public: \
BOOST_TYPEOF_NESTED_TYPEDEF(__expr,x) ; \
}; \
\
public: \
\
typedef name_t self_t; \
typedef __rule::__expr::type::parser_category_t parser_category_t; \
BOOST_PP_EXPR_IIF(BOOST_PP_NOT(np),typedef self_t const & embed_t;) \
\
protected: \
\
BOOST_SPIRIT_RP_EMIT(MV_NONSTATIC,mbrs,BOOST_PP_EMPTY) \
\
__rule::__expr::type::embed_t __parser; \
\
public: \
\
explicit name_t (BOOST_SPIRIT_RP_EMIT(PM_OPAQUE_CTOR_PARAMS,pars,-)) \
: BOOST_SPIRIT_RP_EMIT(MV_CTOR_INIT_LIST,mbrs,-) \
BOOST_PP_COMMA_IF(nm) __parser(x) \
{ } \
\
name_t(name_t const & that) \
: BOOST_SPIRIT_RP_EMIT(MV_CTOR_COPY_INIT_LIST,mbrs,that) \
BOOST_PP_COMMA_IF(nm) __parser(that.__parser) \
{ } \
\
template<typename Scanner> struct result \
{ \
typedef typename ::boost::spirit::parser_result< \
__rule::__expr::type, Scanner>::type type; \
}; \
\
template<typename Scanner> \
typename ::boost::spirit::parser_result<self_t, Scanner>::type \
parse(Scanner const & s) const { return __parser.parse(s); } \
}; \
\
BOOST_PP_IF(np,BOOST_SPIRIT_RP_GEN_OPAQUE,BOOST_SPIRIT_RP_GLOB_OPAQUE) \
(name,name_t,np,pars)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// RP_AP_HANDLER
//
// Part of the rule parser definition for handling action placeholders
# define BOOST_SPIRIT_RP_AP_HANDLER(name_t,np,acts,na,ns) \
private: \
template<typename A> struct __rebound_1st \
{ \
typedef name_t < void BOOST_PP_ENUM_TRAILING_PARAMS(np,__T) , \
typename ns ::action_concatenator<__A0,A>::type \
BOOST_PP_COMMA_IF(BOOST_PP_DEC(na)) \
BOOST_PP_ENUM_SHIFTED_PARAMS(na,__A) \
> type; \
}; \
\
template<typename X> struct __rebound \
{ \
typedef name_t < \
void BOOST_PP_ENUM_TRAILING_PARAMS(np,__T) \
BOOST_SPIRIT_RP_EMIT(AP_REBOUND_TPL_ARGS,acts,X) \
> type; \
}; \
public: \
template<typename A> \
typename __rebound_1st<A>::type const operator[](A const & a) const \
{ \
return typename __rebound_1st<A>::type ( \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -