File indexing completed on 2025-01-31 10:01:56
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_SPIRIT_SWITCH_IPP
0010 #define BOOST_SPIRIT_SWITCH_IPP
0011
0012 #include <boost/mpl/if.hpp>
0013 #include <boost/type_traits/is_same.hpp>
0014 #include <boost/static_assert.hpp>
0015 #include <boost/core/ignore_unused.hpp>
0016
0017 #include <boost/preprocessor/cat.hpp>
0018 #include <boost/preprocessor/inc.hpp>
0019 #include <boost/preprocessor/repeat.hpp>
0020 #include <boost/preprocessor/repeat_from_to.hpp>
0021
0022 #include <boost/spirit/home/classic/core/parser.hpp>
0023 #include <boost/spirit/home/classic/core/primitives/primitives.hpp>
0024 #include <boost/spirit/home/classic/core/composite/composite.hpp>
0025 #include <boost/spirit/home/classic/meta/as_parser.hpp>
0026
0027 #include <boost/spirit/home/classic/phoenix/actor.hpp>
0028 #include <boost/spirit/home/classic/phoenix/tuples.hpp>
0029
0030
0031 namespace boost { namespace spirit {
0032
0033 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0034
0035
0036 template <int N, typename ParserT, bool IsDefault> struct case_parser;
0037
0038
0039 namespace impl {
0040
0041
0042
0043 template <typename ParserT, typename ScannerT>
0044 inline typename parser_result<ParserT, ScannerT>::type
0045 delegate_parse(ParserT const &p, ScannerT const &scan,
0046 typename ScannerT::iterator_t const save)
0047 {
0048 typedef typename parser_result<ParserT, ScannerT>::type result_t;
0049
0050 result_t result (p.subject().parse(scan));
0051 if (!result)
0052 scan.first = save;
0053 return result;
0054 }
0055
0056
0057
0058
0059
0060 template <int N, bool IsDefault, bool HasDefault>
0061 struct default_delegate_parse {
0062
0063 template <
0064 typename ParserT, typename DefaultT,
0065 typename ValueT, typename ScannerT
0066 >
0067 static typename parser_result<ParserT, ScannerT>::type
0068 parse (ValueT const &value, ParserT const &p, DefaultT const &,
0069 ScannerT const &scan, typename ScannerT::iterator_t const save)
0070 {
0071 if (value == N)
0072 return delegate_parse(p, scan, save);
0073 return scan.no_match();
0074 }
0075 };
0076
0077
0078
0079 template <int N, bool HasDefault>
0080 struct default_delegate_parse<N, true, HasDefault> {
0081
0082 template <
0083 typename ParserT, typename DefaultT,
0084 typename ValueT, typename ScannerT
0085 >
0086 static typename parser_result<ParserT, ScannerT>::type
0087 parse (ValueT const& , ParserT const &, DefaultT const &d,
0088 ScannerT const &scan, typename ScannerT::iterator_t const save)
0089 {
0090
0091
0092 BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
0093 return delegate_parse(d, scan, save);
0094 }
0095 };
0096
0097
0098
0099
0100
0101 template <int N>
0102 struct default_delegate_parse<N, false, true> {
0103
0104 template <
0105 typename ParserT, typename DefaultT,
0106 typename ValueT, typename ScannerT
0107 >
0108 static typename parser_result<ParserT, ScannerT>::type
0109 parse (ValueT const &value, ParserT const &p, DefaultT const &d,
0110 ScannerT const &scan, typename ScannerT::iterator_t const save)
0111 {
0112
0113
0114 BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
0115 if (value == N)
0116 return delegate_parse(p, scan, save);
0117
0118 return delegate_parse(d, scan, save);
0119 }
0120 };
0121
0122
0123
0124
0125 template <typename CaseT, bool IsSimple = CaseT::is_simple>
0126 struct default_case;
0127
0128
0129 template <typename ResultT, bool IsDefault>
0130 struct get_default_parser {
0131
0132 template <typename ParserT>
0133 static ResultT
0134 get(parser<ParserT> const &p)
0135 {
0136 return default_case<typename ParserT::derived_t::left_t>::
0137 get(p.derived().left());
0138 }
0139 };
0140
0141 template <typename ResultT>
0142 struct get_default_parser<ResultT, true> {
0143
0144 template <typename ParserT>
0145 static ResultT
0146 get(parser<ParserT> const &p) { return p.derived().right(); }
0147 };
0148
0149
0150 template <typename CaseT, bool IsSimple>
0151 struct default_case {
0152
0153
0154
0155 BOOST_STATIC_CONSTANT(bool, value =
0156 (CaseT::is_default || default_case<typename CaseT::left_t>::value));
0157
0158
0159
0160
0161 BOOST_STATIC_CONSTANT(bool, is_epsilon = (
0162 (CaseT::is_default && CaseT::is_epsilon) ||
0163 default_case<typename CaseT::left_t>::is_epsilon
0164 ));
0165
0166
0167
0168
0169 typedef typename boost::mpl::if_c<
0170 CaseT::is_default, typename CaseT::right_embed_t,
0171 typename default_case<typename CaseT::left_t>::type
0172 >::type type;
0173
0174
0175
0176
0177 template <typename ParserT>
0178 static type
0179 get(parser<ParserT> const &p)
0180 { return get_default_parser<type, CaseT::is_default>::get(p); }
0181 };
0182
0183
0184 template <typename ResultT, bool IsDefault>
0185 struct get_default_parser_simple {
0186
0187 template <typename ParserT>
0188 static ResultT
0189 get(parser<ParserT> const &p) { return p.derived(); }
0190 };
0191
0192 template <typename ResultT>
0193 struct get_default_parser_simple<ResultT, false> {
0194
0195 template <typename ParserT>
0196 static nothing_parser
0197 get(parser<ParserT> const &) { return nothing_p; }
0198 };
0199
0200
0201
0202
0203 template <typename CaseT>
0204 struct default_case<CaseT, true> {
0205
0206
0207
0208
0209 BOOST_STATIC_CONSTANT(bool, value = CaseT::is_default);
0210 BOOST_STATIC_CONSTANT(bool, is_epsilon = (
0211 CaseT::is_default && CaseT::is_epsilon
0212 ));
0213
0214 typedef typename boost::mpl::if_c<
0215 CaseT::is_default, CaseT, nothing_parser
0216 >::type type;
0217
0218 template <typename ParserT>
0219 static type
0220 get(parser<ParserT> const &p)
0221 { return get_default_parser_simple<type, value>::get(p); }
0222 };
0223
0224
0225
0226
0227 template <typename CaseT, bool IsSimple = CaseT::is_simple>
0228 struct case_chain {
0229
0230 BOOST_STATIC_CONSTANT(int, depth = (
0231 case_chain<typename CaseT::left_t>::depth + 1
0232 ));
0233 };
0234
0235 template <typename CaseT>
0236 struct case_chain<CaseT, true> {
0237
0238 BOOST_STATIC_CONSTANT(int, depth = 0);
0239 };
0240
0241
0242
0243
0244
0245 template <int Depth, typename CaseT>
0246 struct chain_parser {
0247
0248 typedef typename CaseT::left_t our_left_t;
0249
0250 typedef typename chain_parser<Depth-1, our_left_t>::left_t left_t;
0251 typedef typename chain_parser<Depth-1, our_left_t>::right_t right_t;
0252
0253 static left_t
0254 left(CaseT const &p)
0255 { return chain_parser<Depth-1, our_left_t>::left(p.left()); }
0256
0257 static right_t
0258 right(CaseT const &p)
0259 { return chain_parser<Depth-1, our_left_t>::right(p.left()); }
0260 };
0261
0262 template <typename CaseT>
0263 struct chain_parser<1, CaseT> {
0264
0265 typedef typename CaseT::left_t left_t;
0266 typedef typename CaseT::right_t right_t;
0267
0268 static left_t left(CaseT const &p) { return p.left(); }
0269 static right_t right(CaseT const &p) { return p.right(); }
0270 };
0271
0272 template <typename CaseT>
0273 struct chain_parser<0, CaseT>;
0274
0275
0276
0277
0278 template <typename TargetT, typename ScannerT>
0279 struct condition_result {
0280
0281 typedef typename TargetT::template result<ScannerT>::type type;
0282 };
0283
0284
0285 template <typename LeftT, typename RightT, bool IsDefault>
0286 struct compound_case_parser
0287 : public binary<LeftT, RightT,
0288 parser<compound_case_parser<LeftT, RightT, IsDefault> > >
0289 {
0290 typedef compound_case_parser<LeftT, RightT, IsDefault> self_t;
0291 typedef binary_parser_category parser_category_t;
0292 typedef binary<LeftT, RightT, parser<self_t> > base_t;
0293
0294 BOOST_STATIC_CONSTANT(int, value = RightT::value);
0295 BOOST_STATIC_CONSTANT(bool, is_default = IsDefault);
0296 BOOST_STATIC_CONSTANT(bool, is_simple = false);
0297 BOOST_STATIC_CONSTANT(bool, is_epsilon = (
0298 is_default &&
0299 boost::is_same<typename RightT::subject_t, epsilon_parser>::value
0300 ));
0301
0302 compound_case_parser(parser<LeftT> const &lhs, parser<RightT> const &rhs)
0303 : base_t(lhs.derived(), rhs.derived())
0304 {}
0305
0306 template <typename ScannerT>
0307 struct result
0308 {
0309 typedef typename match_result<ScannerT, nil_t>::type type;
0310 };
0311
0312 template <typename ScannerT, typename CondT>
0313 typename parser_result<self_t, ScannerT>::type
0314 parse(ScannerT const& scan, CondT const &cond) const;
0315
0316 template <int N1, typename ParserT1, bool IsDefault1>
0317 compound_case_parser<
0318 self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1
0319 >
0320 operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const
0321 {
0322
0323
0324 BOOST_STATIC_ASSERT(!default_case<self_t>::value || !IsDefault1);
0325
0326
0327
0328 BOOST_STATIC_ASSERT(
0329 case_chain<self_t>::depth < BOOST_SPIRIT_SWITCH_CASE_LIMIT
0330 );
0331
0332 typedef case_parser<N1, ParserT1, IsDefault1> rhs_t;
0333 return compound_case_parser<self_t, rhs_t, IsDefault1>(*this, p);
0334 }
0335 };
0336
0337
0338
0339
0340 template <int Value, int Depth, bool IsDefault>
0341 struct parse_switch;
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385 #define BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS(z, N, _) \
0386 typedef typename BOOST_PP_CAT(left_t, N)::left_t \
0387 BOOST_PP_CAT(left_t, BOOST_PP_INC(N)); \
0388
0389
0390 #define BOOST_SPIRIT_PARSE_SWITCH_CASES(z, N, _) \
0391 case (long)(BOOST_PP_CAT(left_t, N)::value): \
0392 return delegate_parse(chain_parser<N, left_t1>::right(p.left()), \
0393 scan, save); \
0394
0395
0396 #define BOOST_SPIRIT_PARSE_SWITCHES(z, N, _) \
0397 template <int Value, bool IsDefault> \
0398 struct parse_switch<Value, BOOST_PP_INC(N), IsDefault> { \
0399 \
0400 template <typename ParserT, typename ScannerT> \
0401 static typename parser_result<ParserT, ScannerT>::type \
0402 do_(ParserT const &p, ScannerT const &scan, long cond_value, \
0403 typename ScannerT::iterator_t const &save) \
0404 { \
0405 typedef ParserT left_t0; \
0406 BOOST_PP_REPEAT_FROM_TO_ ## z(0, BOOST_PP_INC(N), \
0407 BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS, _) \
0408 \
0409 switch (cond_value) { \
0410 case (long)(BOOST_PP_CAT(left_t, BOOST_PP_INC(N))::value): \
0411 return delegate_parse( \
0412 chain_parser< \
0413 case_chain<ParserT>::depth, ParserT \
0414 >::left(p), scan, save); \
0415 \
0416 BOOST_PP_REPEAT_FROM_TO_ ## z(1, BOOST_PP_INC(N), \
0417 BOOST_SPIRIT_PARSE_SWITCH_CASES, _) \
0418 \
0419 case (long)(left_t0::value): \
0420 default: \
0421 typedef default_case<ParserT> default_t; \
0422 typedef \
0423 default_delegate_parse<Value, IsDefault, default_t::value> \
0424 default_parse_t; \
0425 \
0426 return default_parse_t::parse(cond_value, p.right(), \
0427 default_t::get(p), scan, save); \
0428 } \
0429 } \
0430 }; \
0431
0432
0433 BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_SPIRIT_SWITCH_CASE_LIMIT),
0434 BOOST_SPIRIT_PARSE_SWITCHES, _)
0435
0436 #undef BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS
0437 #undef BOOST_SPIRIT_PARSE_SWITCH_CASES
0438 #undef BOOST_SPIRIT_PARSE_SWITCHES
0439
0440
0441 template <typename LeftT, typename RightT, bool IsDefault>
0442 template <typename ScannerT, typename CondT>
0443 inline typename parser_result<
0444 compound_case_parser<LeftT, RightT, IsDefault>, ScannerT
0445 >::type
0446 compound_case_parser<LeftT, RightT, IsDefault>::
0447 parse(ScannerT const& scan, CondT const &cond) const
0448 {
0449 ignore_unused(scan.at_end());
0450 return parse_switch<value, case_chain<self_t>::depth, is_default>::
0451 do_(*this, scan, cond(scan), scan.first);
0452 }
0453
0454
0455
0456 template <typename ParserT>
0457 struct cond_functor {
0458
0459 typedef cond_functor<ParserT> self_t;
0460
0461 cond_functor(ParserT const &p_)
0462 : p(p_)
0463 {}
0464
0465 template <typename ScannerT>
0466 struct result
0467 {
0468 typedef typename parser_result<ParserT, ScannerT>::type::attr_t type;
0469 };
0470
0471 template <typename ScannerT>
0472 typename condition_result<self_t, ScannerT>::type
0473 operator()(ScannerT const &scan) const
0474 {
0475 typedef typename parser_result<ParserT, ScannerT>::type result_t;
0476 typedef typename result_t::attr_t attr_t;
0477
0478 result_t result(p.parse(scan));
0479 return !result ? attr_t() : result.value();
0480 }
0481
0482 typename ParserT::embed_t p;
0483 };
0484
0485 template <typename ParserT>
0486 struct make_cond_functor {
0487
0488 typedef as_parser<ParserT> as_parser_t;
0489
0490 static cond_functor<typename as_parser_t::type>
0491 do_(ParserT const &cond)
0492 {
0493 return cond_functor<typename as_parser_t::type>(
0494 as_parser_t::convert(cond));
0495 }
0496 };
0497
0498
0499
0500 template <typename ActorT>
0501 struct cond_actor {
0502
0503 typedef cond_actor<ActorT> self_t;
0504
0505 cond_actor(ActorT const &actor_)
0506 : actor(actor_)
0507 {}
0508
0509 template <typename ScannerT>
0510 struct result
0511 {
0512 typedef typename ::phoenix::actor_result<ActorT, ::phoenix::tuple<> >::type
0513 type;
0514 };
0515
0516 template <typename ScannerT>
0517 typename condition_result<self_t, ScannerT>::type
0518 operator()(ScannerT const& ) const
0519 {
0520 return actor();
0521 }
0522
0523 ActorT const &actor;
0524 };
0525
0526 template <typename ActorT>
0527 struct make_cond_functor< ::phoenix::actor<ActorT> > {
0528
0529 static cond_actor< ::phoenix::actor<ActorT> >
0530 do_(::phoenix::actor<ActorT> const &actor)
0531 {
0532 return cond_actor< ::phoenix::actor<ActorT> >(actor);
0533 }
0534 };
0535
0536
0537
0538 struct get_next_token_cond {
0539
0540 typedef get_next_token_cond self_t;
0541
0542 template <typename ScannerT>
0543 struct result
0544 {
0545 typedef typename ScannerT::value_t type;
0546 };
0547
0548 template <typename ScannerT>
0549 typename condition_result<self_t, ScannerT>::type
0550 operator()(ScannerT const &scan) const
0551 {
0552 typename ScannerT::value_t val(*scan);
0553 ++scan.first;
0554 return val;
0555 }
0556 };
0557
0558 template <>
0559 struct make_cond_functor<get_next_token_cond> {
0560
0561 static get_next_token_cond
0562 do_(get_next_token_cond const &cond)
0563 {
0564 return cond;
0565 }
0566 };
0567
0568
0569 }
0570
0571 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0572
0573 }}
0574
0575 #endif