📄 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>::typecompound_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 actortemplate <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 streamstruct 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 implBOOST_SPIRIT_CLASSIC_NAMESPACE_END}} // namespace boost::spirit#endif // BOOST_SPIRIT_SWITCH_IPP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -