📄 switch.ipp
字号:
{
typedef compound_case_parser<LeftT, RightT, IsDefault> self_t;
typedef binary_parser_category parser_category_t;
typedef binary<LeftT, RightT, parser<self_t> > base_t;
BOOST_STATIC_CONSTANT(int, value = RightT::value);
BOOST_STATIC_CONSTANT(bool, is_default = IsDefault);
BOOST_STATIC_CONSTANT(bool, is_simple = false);
BOOST_STATIC_CONSTANT(bool, is_epsilon = (
is_default &&
boost::is_same<typename RightT::subject_t, epsilon_parser>::value
));
compound_case_parser(parser<LeftT> const &lhs, parser<RightT> const &rhs)
: base_t(lhs.derived(), rhs.derived())
{}
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, nil_t>::type type;
};
template <typename ScannerT, typename CondT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan, CondT const &cond) const;
template <int N1, typename ParserT1, bool IsDefault1>
compound_case_parser<
self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1
>
operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const
{
// If the following compile time assertion fires, you've probably used
// more than one default_p case inside the switch_p parser construct.
BOOST_STATIC_ASSERT(!default_case<self_t>::value || !IsDefault1);
// If this compile time assertion fires, you've probably want to use
// more case_p/default_p case branches, than possible.
BOOST_STATIC_ASSERT(
case_chain<self_t>::depth < BOOST_SPIRIT_SWITCH_CASE_LIMIT
);
typedef case_parser<N1, ParserT1, IsDefault1> right_t;
return compound_case_parser<self_t, right_t, IsDefault1>(*this, p);
}
};
///////////////////////////////////////////////////////////////////////////////
// The parse_switch::do_ functions dispatch to the correct parser, which is
// selected through the given conditional switch value.
template <int Value, int Depth, bool IsDefault>
struct parse_switch;
///////////////////////////////////////////////////////////////////////////////
//
// The following generates a couple of parse_switch template specializations
// with an increasing number of handled case branches (for 1..N).
//
// template <int Value, bool IsDefault>
// struct parse_switch<Value, N, IsDefault> {
//
// template <typename ParserT, typename ScannerT>
// static typename parser_result<ParserT, ScannerT>::type
// do_(ParserT const &p, ScannerT const &scan, long cond_value,
// typename ScannerT::iterator_t const &save)
// {
// typedef ParserT left_t0;
// typedef typename left_t0::left left_t1;
// ...
//
// switch (cond_value) {
// case left_tN::value:
// return delegate_parse(chain_parser<
// case_chain<ParserT>::depth, ParserT
// >::left(p), scan, save);
// ...
// case left_t1::value:
// return delegate_parse(chain_parser<
// 1, left_t1
// >::right(p.left()), scan, save);
//
// case left_t0::value:
// default:
// typedef default_case<ParserT> default_t;
// typedef default_delegate_parse<
// Value, IsDefault, default_t::value>
// default_parse_t;
//
// return default_parse_t::parse(cond_value, p.right(),
// default_t::get(p), scan, save);
// }
// }
// };
//
///////////////////////////////////////////////////////////////////////////////
#define BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS(z, N, _) \
typedef typename BOOST_PP_CAT(left_t, N)::left_t \
BOOST_PP_CAT(left_t, BOOST_PP_INC(N)); \
/**/
#define BOOST_SPIRIT_PARSE_SWITCH_CASES(z, N, _) \
case (long)(BOOST_PP_CAT(left_t, N)::value): \
return delegate_parse(chain_parser<N, left_t1>::right(p.left()), \
scan, save); \
/**/
#define BOOST_SPIRIT_PARSE_SWITCHES(z, N, _) \
template <int Value, bool IsDefault> \
struct parse_switch<Value, BOOST_PP_INC(N), IsDefault> { \
\
template <typename ParserT, typename ScannerT> \
static typename parser_result<ParserT, ScannerT>::type \
do_(ParserT const &p, ScannerT const &scan, long cond_value, \
typename ScannerT::iterator_t const &save) \
{ \
typedef ParserT left_t0; \
BOOST_PP_REPEAT_FROM_TO_ ## z(0, BOOST_PP_INC(N), \
BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS, _) \
\
switch (cond_value) { \
case (long)(BOOST_PP_CAT(left_t, BOOST_PP_INC(N))::value): \
return delegate_parse( \
chain_parser< \
case_chain<ParserT>::depth, ParserT \
>::left(p), scan, save); \
\
BOOST_PP_REPEAT_FROM_TO_ ## z(1, BOOST_PP_INC(N), \
BOOST_SPIRIT_PARSE_SWITCH_CASES, _) \
\
case (long)(left_t0::value): \
default: \
typedef default_case<ParserT> default_t; \
typedef \
default_delegate_parse<Value, IsDefault, default_t::value> \
default_parse_t; \
\
return default_parse_t::parse(cond_value, p.right(), \
default_t::get(p), scan, save); \
} \
} \
}; \
/**/
BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_SPIRIT_SWITCH_CASE_LIMIT),
BOOST_SPIRIT_PARSE_SWITCHES, _)
#undef BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS
#undef BOOST_SPIRIT_PARSE_SWITCH_CASES
#undef BOOST_SPIRIT_PARSE_SWITCHES
///////////////////////////////////////////////////////////////////////////////
template <typename LeftT, typename RightT, bool IsDefault>
template <typename ScannerT, typename CondT>
inline typename parser_result<
compound_case_parser<LeftT, RightT, IsDefault>, ScannerT
>::type
compound_case_parser<LeftT, RightT, IsDefault>::
parse(ScannerT const& scan, CondT const &cond) const
{
scan.at_end(); // allow skipper to take effect
return parse_switch<value, case_chain<self_t>::depth, is_default>::
do_(*this, scan, cond(scan), scan.first);
}
///////////////////////////////////////////////////////////////////////////////
// The switch condition is to be evaluated from a parser result value.
template <typename ParserT>
struct cond_functor {
typedef cond_functor<ParserT> self_t;
cond_functor(ParserT const &p_)
: p(p_)
{}
template <typename ScannerT>
struct result
{
typedef typename parser_result<ParserT, ScannerT>::type::attr_t type;
};
template <typename ScannerT>
typename condition_result<self_t, ScannerT>::type
operator()(ScannerT const &scan) const
{
typedef typename parser_result<ParserT, ScannerT>::type result_t;
typedef typename result_t::attr_t attr_t;
result_t result(p.parse(scan));
return !result ? attr_t() : result.value();
}
typename ParserT::embed_t p;
};
template <typename ParserT>
struct make_cond_functor {
typedef as_parser<ParserT> as_parser_t;
static cond_functor<typename as_parser_t::type>
do_(ParserT const &cond)
{
return cond_functor<typename as_parser_t::type>(
as_parser_t::convert(cond));
}
};
///////////////////////////////////////////////////////////////////////////////
// The switch condition is to be evaluated from a phoenix actor
template <typename ActorT>
struct cond_actor {
typedef cond_actor<ActorT> self_t;
cond_actor(ActorT const &actor_)
: actor(actor_)
{}
template <typename ScannerT>
struct result
{
typedef typename phoenix::actor_result<ActorT, phoenix::tuple<> >::type
type;
};
template <typename ScannerT>
typename condition_result<self_t, ScannerT>::type
operator()(ScannerT const& /*scan*/) const
{
return actor();
}
ActorT const &actor;
};
template <typename ActorT>
struct make_cond_functor<phoenix::actor<ActorT> > {
static cond_actor<phoenix::actor<ActorT> >
do_(phoenix::actor<ActorT> const &actor)
{
return cond_actor<phoenix::actor<ActorT> >(actor);
}
};
///////////////////////////////////////////////////////////////////////////////
// The switch condition is to be taken directly from the input stream
struct get_next_token_cond {
typedef get_next_token_cond self_t;
template <typename ScannerT>
struct result
{
typedef typename ScannerT::value_t type;
};
template <typename ScannerT>
typename condition_result<self_t, ScannerT>::type
operator()(ScannerT const &scan) const
{
typename ScannerT::value_t val(*scan);
++scan.first;
return val;
}
};
template <>
struct make_cond_functor<get_next_token_cond> {
static get_next_token_cond
do_(get_next_token_cond const &cond)
{
return cond;
}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace impl
}} // namespace boost::spirit
#endif // BOOST_SPIRIT_SWITCH_IPP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -