1 /*============================================================================= 2 Copyright (c) 1998-2003 Joel de Guzman 3 Copyright (c) 2001 Daniel Nuffer 4 http://spirit.sourceforge.net/ 5 6 Distributed under the Boost Software License, Version 1.0. (See accompanying 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 =============================================================================*/ 9 #if !defined(BOOST_SPIRIT_DIRECTIVES_HPP) 10 #define BOOST_SPIRIT_DIRECTIVES_HPP 11 12 /////////////////////////////////////////////////////////////////////////////// 13 #include <algorithm> 14 15 #include <boost/spirit/home/classic/namespace.hpp> 16 #include <boost/spirit/home/classic/core/parser.hpp> 17 #include <boost/spirit/home/classic/core/scanner/skipper.hpp> 18 #include <boost/spirit/home/classic/core/primitives/primitives.hpp> 19 #include <boost/spirit/home/classic/core/composite/composite.hpp> 20 #include <boost/spirit/home/classic/core/composite/impl/directives.ipp> 21 22 namespace boost { namespace spirit { 23 24 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 25 26 /////////////////////////////////////////////////////////////////////////// 27 // 28 // contiguous class 29 // 30 /////////////////////////////////////////////////////////////////////////// 31 struct lexeme_parser_gen; 32 33 template <typename ParserT> 34 struct contiguous 35 : public unary<ParserT, parser<contiguous<ParserT> > > 36 { 37 typedef contiguous<ParserT> self_t; 38 typedef unary_parser_category parser_category_t; 39 typedef lexeme_parser_gen parser_generator_t; 40 typedef unary<ParserT, parser<self_t> > base_t; 41 42 template <typename ScannerT> 43 struct result 44 { 45 typedef typename parser_result<ParserT, ScannerT>::type type; 46 }; 47 contiguousboost::spirit::contiguous48 contiguous(ParserT const& p) 49 : base_t(p) {} 50 51 template <typename ScannerT> 52 typename parser_result<self_t, ScannerT>::type parseboost::spirit::contiguous53 parse(ScannerT const& scan) const 54 { 55 typedef typename parser_result<self_t, ScannerT>::type result_t; 56 return impl::contiguous_parser_parse<result_t> 57 (this->subject(), scan, scan); 58 } 59 }; 60 61 struct lexeme_parser_gen 62 { 63 template <typename ParserT> 64 struct result { 65 66 typedef contiguous<ParserT> type; 67 }; 68 69 template <typename ParserT> 70 static contiguous<ParserT> generateboost::spirit::lexeme_parser_gen71 generate(parser<ParserT> const& subject) 72 { 73 return contiguous<ParserT>(subject.derived()); 74 } 75 76 template <typename ParserT> 77 contiguous<ParserT> operator []boost::spirit::lexeme_parser_gen78 operator[](parser<ParserT> const& subject) const 79 { 80 return contiguous<ParserT>(subject.derived()); 81 } 82 }; 83 84 ////////////////////////////////// 85 const lexeme_parser_gen lexeme_d = lexeme_parser_gen(); 86 87 /////////////////////////////////////////////////////////////////////////// 88 // 89 // lexeme_scanner 90 // 91 // Given a Scanner, return the correct scanner type that 92 // the lexeme_d uses. Scanner is assumed to be a phrase 93 // level scanner (see skipper.hpp) 94 // 95 /////////////////////////////////////////////////////////////////////////// 96 template <typename ScannerT> 97 struct lexeme_scanner 98 { 99 typedef scanner_policies< 100 no_skipper_iteration_policy< 101 typename ScannerT::iteration_policy_t>, 102 typename ScannerT::match_policy_t, 103 typename ScannerT::action_policy_t 104 > policies_t; 105 106 typedef typename 107 rebind_scanner_policies<ScannerT, policies_t>::type type; 108 }; 109 110 /////////////////////////////////////////////////////////////////////////// 111 // 112 // inhibit_case_iteration_policy class 113 // 114 /////////////////////////////////////////////////////////////////////////// 115 template <typename BaseT> 116 struct inhibit_case_iteration_policy : public BaseT 117 { 118 typedef BaseT base_t; 119 inhibit_case_iteration_policyboost::spirit::inhibit_case_iteration_policy120 inhibit_case_iteration_policy() 121 : BaseT() {} 122 123 template <typename PolicyT> inhibit_case_iteration_policyboost::spirit::inhibit_case_iteration_policy124 inhibit_case_iteration_policy(PolicyT const& other) 125 : BaseT(other) {} 126 127 template <typename CharT> filterboost::spirit::inhibit_case_iteration_policy128 CharT filter(CharT ch) const 129 { return impl::tolower_(ch); } 130 }; 131 132 /////////////////////////////////////////////////////////////////////////// 133 // 134 // inhibit_case class 135 // 136 /////////////////////////////////////////////////////////////////////////// 137 struct inhibit_case_parser_gen; 138 139 template <typename ParserT> 140 struct inhibit_case 141 : public unary<ParserT, parser<inhibit_case<ParserT> > > 142 { 143 typedef inhibit_case<ParserT> self_t; 144 typedef unary_parser_category parser_category_t; 145 typedef inhibit_case_parser_gen parser_generator_t; 146 typedef unary<ParserT, parser<self_t> > base_t; 147 148 template <typename ScannerT> 149 struct result 150 { 151 typedef typename parser_result<ParserT, ScannerT>::type type; 152 }; 153 inhibit_caseboost::spirit::inhibit_case154 inhibit_case(ParserT const& p) 155 : base_t(p) {} 156 157 template <typename ScannerT> 158 typename parser_result<self_t, ScannerT>::type parseboost::spirit::inhibit_case159 parse(ScannerT const& scan) const 160 { 161 typedef typename parser_result<self_t, ScannerT>::type result_t; 162 return impl::inhibit_case_parser_parse<result_t> 163 (this->subject(), scan, scan); 164 } 165 }; 166 167 template <int N> 168 struct inhibit_case_parser_gen_base 169 { 170 // This hack is needed to make borland happy. 171 // If these member operators were defined in the 172 // inhibit_case_parser_gen class, or if this class 173 // is non-templated, borland ICEs. 174 175 static inhibit_case<strlit<char const*> > generateboost::spirit::inhibit_case_parser_gen_base176 generate(char const* str) 177 { return inhibit_case<strlit<char const*> >(str); } 178 179 static inhibit_case<strlit<wchar_t const*> > generateboost::spirit::inhibit_case_parser_gen_base180 generate(wchar_t const* str) 181 { return inhibit_case<strlit<wchar_t const*> >(str); } 182 183 static inhibit_case<chlit<char> > generateboost::spirit::inhibit_case_parser_gen_base184 generate(char ch) 185 { return inhibit_case<chlit<char> >(ch); } 186 187 static inhibit_case<chlit<wchar_t> > generateboost::spirit::inhibit_case_parser_gen_base188 generate(wchar_t ch) 189 { return inhibit_case<chlit<wchar_t> >(ch); } 190 191 template <typename ParserT> 192 static inhibit_case<ParserT> generateboost::spirit::inhibit_case_parser_gen_base193 generate(parser<ParserT> const& subject) 194 { return inhibit_case<ParserT>(subject.derived()); } 195 196 inhibit_case<strlit<char const*> > operator []boost::spirit::inhibit_case_parser_gen_base197 operator[](char const* str) const 198 { return inhibit_case<strlit<char const*> >(str); } 199 200 inhibit_case<strlit<wchar_t const*> > operator []boost::spirit::inhibit_case_parser_gen_base201 operator[](wchar_t const* str) const 202 { return inhibit_case<strlit<wchar_t const*> >(str); } 203 204 inhibit_case<chlit<char> > operator []boost::spirit::inhibit_case_parser_gen_base205 operator[](char ch) const 206 { return inhibit_case<chlit<char> >(ch); } 207 208 inhibit_case<chlit<wchar_t> > operator []boost::spirit::inhibit_case_parser_gen_base209 operator[](wchar_t ch) const 210 { return inhibit_case<chlit<wchar_t> >(ch); } 211 212 template <typename ParserT> 213 inhibit_case<ParserT> operator []boost::spirit::inhibit_case_parser_gen_base214 operator[](parser<ParserT> const& subject) const 215 { return inhibit_case<ParserT>(subject.derived()); } 216 }; 217 218 ////////////////////////////////// 219 struct inhibit_case_parser_gen : public inhibit_case_parser_gen_base<0> 220 { inhibit_case_parser_genboost::spirit::inhibit_case_parser_gen221 inhibit_case_parser_gen() {} 222 }; 223 224 ////////////////////////////////// 225 // Depracated 226 const inhibit_case_parser_gen nocase_d = inhibit_case_parser_gen(); 227 228 // Preferred syntax 229 const inhibit_case_parser_gen as_lower_d = inhibit_case_parser_gen(); 230 231 /////////////////////////////////////////////////////////////////////////// 232 // 233 // as_lower_scanner 234 // 235 // Given a Scanner, return the correct scanner type that 236 // the as_lower_d uses. Scanner is assumed to be a scanner 237 // with an inhibit_case_iteration_policy. 238 // 239 /////////////////////////////////////////////////////////////////////////// 240 template <typename ScannerT> 241 struct as_lower_scanner 242 { 243 typedef scanner_policies< 244 inhibit_case_iteration_policy< 245 typename ScannerT::iteration_policy_t>, 246 typename ScannerT::match_policy_t, 247 typename ScannerT::action_policy_t 248 > policies_t; 249 250 typedef typename 251 rebind_scanner_policies<ScannerT, policies_t>::type type; 252 }; 253 254 /////////////////////////////////////////////////////////////////////////// 255 // 256 // longest_alternative class 257 // 258 /////////////////////////////////////////////////////////////////////////// 259 struct longest_parser_gen; 260 261 template <typename A, typename B> 262 struct longest_alternative 263 : public binary<A, B, parser<longest_alternative<A, B> > > 264 { 265 typedef longest_alternative<A, B> self_t; 266 typedef binary_parser_category parser_category_t; 267 typedef longest_parser_gen parser_generator_t; 268 typedef binary<A, B, parser<self_t> > base_t; 269 longest_alternativeboost::spirit::longest_alternative270 longest_alternative(A const& a, B const& b) 271 : base_t(a, b) {} 272 273 template <typename ScannerT> 274 typename parser_result<self_t, ScannerT>::type parseboost::spirit::longest_alternative275 parse(ScannerT const& scan) const 276 { 277 typedef typename parser_result<self_t, ScannerT>::type result_t; 278 typename ScannerT::iterator_t save = scan.first; 279 result_t l = this->left().parse(scan); 280 std::swap(scan.first, save); 281 result_t r = this->right().parse(scan); 282 283 if (l || r) 284 { 285 if (l.length() > r.length()) 286 { 287 scan.first = save; 288 return l; 289 } 290 return r; 291 } 292 293 return scan.no_match(); 294 } 295 }; 296 297 struct longest_parser_gen 298 { 299 template <typename A, typename B> 300 struct result { 301 302 typedef typename 303 impl::to_longest_alternative<alternative<A, B> >::result_t 304 type; 305 }; 306 307 template <typename A, typename B> 308 static typename 309 impl::to_longest_alternative<alternative<A, B> >::result_t generateboost::spirit::longest_parser_gen310 generate(alternative<A, B> const& alt) 311 { 312 return impl::to_longest_alternative<alternative<A, B> >:: 313 convert(alt); 314 } 315 316 //'generate' for binary composite 317 template <typename A, typename B> 318 static 319 longest_alternative<A, B> generateboost::spirit::longest_parser_gen320 generate(A const &left, B const &right) 321 { 322 return longest_alternative<A, B>(left, right); 323 } 324 325 template <typename A, typename B> 326 typename impl::to_longest_alternative<alternative<A, B> >::result_t operator []boost::spirit::longest_parser_gen327 operator[](alternative<A, B> const& alt) const 328 { 329 return impl::to_longest_alternative<alternative<A, B> >:: 330 convert(alt); 331 } 332 }; 333 334 const longest_parser_gen longest_d = longest_parser_gen(); 335 336 /////////////////////////////////////////////////////////////////////////// 337 // 338 // shortest_alternative class 339 // 340 /////////////////////////////////////////////////////////////////////////// 341 struct shortest_parser_gen; 342 343 template <typename A, typename B> 344 struct shortest_alternative 345 : public binary<A, B, parser<shortest_alternative<A, B> > > 346 { 347 typedef shortest_alternative<A, B> self_t; 348 typedef binary_parser_category parser_category_t; 349 typedef shortest_parser_gen parser_generator_t; 350 typedef binary<A, B, parser<self_t> > base_t; 351 shortest_alternativeboost::spirit::shortest_alternative352 shortest_alternative(A const& a, B const& b) 353 : base_t(a, b) {} 354 355 template <typename ScannerT> 356 typename parser_result<self_t, ScannerT>::type parseboost::spirit::shortest_alternative357 parse(ScannerT const& scan) const 358 { 359 typedef typename parser_result<self_t, ScannerT>::type result_t; 360 typename ScannerT::iterator_t save = scan.first; 361 result_t l = this->left().parse(scan); 362 std::swap(scan.first, save); 363 result_t r = this->right().parse(scan); 364 365 if (l || r) 366 { 367 if ((l.length() < r.length() && l) || !r) 368 { 369 scan.first = save; 370 return l; 371 } 372 return r; 373 } 374 375 return scan.no_match(); 376 } 377 }; 378 379 struct shortest_parser_gen 380 { 381 template <typename A, typename B> 382 struct result { 383 384 typedef typename 385 impl::to_shortest_alternative<alternative<A, B> >::result_t 386 type; 387 }; 388 389 template <typename A, typename B> 390 static typename 391 impl::to_shortest_alternative<alternative<A, B> >::result_t generateboost::spirit::shortest_parser_gen392 generate(alternative<A, B> const& alt) 393 { 394 return impl::to_shortest_alternative<alternative<A, B> >:: 395 convert(alt); 396 } 397 398 //'generate' for binary composite 399 template <typename A, typename B> 400 static 401 shortest_alternative<A, B> generateboost::spirit::shortest_parser_gen402 generate(A const &left, B const &right) 403 { 404 return shortest_alternative<A, B>(left, right); 405 } 406 407 template <typename A, typename B> 408 typename impl::to_shortest_alternative<alternative<A, B> >::result_t operator []boost::spirit::shortest_parser_gen409 operator[](alternative<A, B> const& alt) const 410 { 411 return impl::to_shortest_alternative<alternative<A, B> >:: 412 convert(alt); 413 } 414 }; 415 416 const shortest_parser_gen shortest_d = shortest_parser_gen(); 417 418 /////////////////////////////////////////////////////////////////////////// 419 // 420 // min_bounded class 421 // 422 /////////////////////////////////////////////////////////////////////////// 423 template <typename BoundsT> 424 struct min_bounded_gen; 425 426 template <typename ParserT, typename BoundsT> 427 struct min_bounded 428 : public unary<ParserT, parser<min_bounded<ParserT, BoundsT> > > 429 { 430 typedef min_bounded<ParserT, BoundsT> self_t; 431 typedef unary_parser_category parser_category_t; 432 typedef min_bounded_gen<BoundsT> parser_generator_t; 433 typedef unary<ParserT, parser<self_t> > base_t; 434 435 template <typename ScannerT> 436 struct result 437 { 438 typedef typename parser_result<ParserT, ScannerT>::type type; 439 }; 440 min_boundedboost::spirit::min_bounded441 min_bounded(ParserT const& p, BoundsT const& min__) 442 : base_t(p) 443 , min_(min__) {} 444 445 template <typename ScannerT> 446 typename parser_result<self_t, ScannerT>::type parseboost::spirit::min_bounded447 parse(ScannerT const& scan) const 448 { 449 typedef typename parser_result<self_t, ScannerT>::type result_t; 450 result_t hit = this->subject().parse(scan); 451 if (hit.has_valid_attribute() && hit.value() < min_) 452 return scan.no_match(); 453 return hit; 454 } 455 456 BoundsT min_; 457 }; 458 459 template <typename BoundsT> 460 struct min_bounded_gen 461 { min_bounded_genboost::spirit::min_bounded_gen462 min_bounded_gen(BoundsT const& min__) 463 : min_(min__) {} 464 465 template <typename DerivedT> 466 min_bounded<DerivedT, BoundsT> operator []boost::spirit::min_bounded_gen467 operator[](parser<DerivedT> const& p) const 468 { return min_bounded<DerivedT, BoundsT>(p.derived(), min_); } 469 470 BoundsT min_; 471 }; 472 473 template <typename BoundsT> 474 inline min_bounded_gen<BoundsT> min_limit_d(BoundsT const & min_)475 min_limit_d(BoundsT const& min_) 476 { return min_bounded_gen<BoundsT>(min_); } 477 478 /////////////////////////////////////////////////////////////////////////// 479 // 480 // max_bounded class 481 // 482 /////////////////////////////////////////////////////////////////////////// 483 template <typename BoundsT> 484 struct max_bounded_gen; 485 486 template <typename ParserT, typename BoundsT> 487 struct max_bounded 488 : public unary<ParserT, parser<max_bounded<ParserT, BoundsT> > > 489 { 490 typedef max_bounded<ParserT, BoundsT> self_t; 491 typedef unary_parser_category parser_category_t; 492 typedef max_bounded_gen<BoundsT> parser_generator_t; 493 typedef unary<ParserT, parser<self_t> > base_t; 494 495 template <typename ScannerT> 496 struct result 497 { 498 typedef typename parser_result<ParserT, ScannerT>::type type; 499 }; 500 max_boundedboost::spirit::max_bounded501 max_bounded(ParserT const& p, BoundsT const& max__) 502 : base_t(p) 503 , max_(max__) {} 504 505 template <typename ScannerT> 506 typename parser_result<self_t, ScannerT>::type parseboost::spirit::max_bounded507 parse(ScannerT const& scan) const 508 { 509 typedef typename parser_result<self_t, ScannerT>::type result_t; 510 result_t hit = this->subject().parse(scan); 511 if (hit.has_valid_attribute() && hit.value() > max_) 512 return scan.no_match(); 513 return hit; 514 } 515 516 BoundsT max_; 517 }; 518 519 template <typename BoundsT> 520 struct max_bounded_gen 521 { max_bounded_genboost::spirit::max_bounded_gen522 max_bounded_gen(BoundsT const& max__) 523 : max_(max__) {} 524 525 template <typename DerivedT> 526 max_bounded<DerivedT, BoundsT> operator []boost::spirit::max_bounded_gen527 operator[](parser<DerivedT> const& p) const 528 { return max_bounded<DerivedT, BoundsT>(p.derived(), max_); } 529 530 BoundsT max_; 531 }; 532 533 ////////////////////////////////// 534 template <typename BoundsT> 535 inline max_bounded_gen<BoundsT> max_limit_d(BoundsT const & max_)536 max_limit_d(BoundsT const& max_) 537 { return max_bounded_gen<BoundsT>(max_); } 538 539 /////////////////////////////////////////////////////////////////////////// 540 // 541 // bounded class 542 // 543 /////////////////////////////////////////////////////////////////////////// 544 template <typename BoundsT> 545 struct bounded_gen; 546 547 template <typename ParserT, typename BoundsT> 548 struct bounded 549 : public unary<ParserT, parser<bounded<ParserT, BoundsT> > > 550 { 551 typedef bounded<ParserT, BoundsT> self_t; 552 typedef unary_parser_category parser_category_t; 553 typedef bounded_gen<BoundsT> parser_generator_t; 554 typedef unary<ParserT, parser<self_t> > base_t; 555 556 template <typename ScannerT> 557 struct result 558 { 559 typedef typename parser_result<ParserT, ScannerT>::type type; 560 }; 561 boundedboost::spirit::bounded562 bounded(ParserT const& p, BoundsT const& min__, BoundsT const& max__) 563 : base_t(p) 564 , min_(min__) 565 , max_(max__) {} 566 567 template <typename ScannerT> 568 typename parser_result<self_t, ScannerT>::type parseboost::spirit::bounded569 parse(ScannerT const& scan) const 570 { 571 typedef typename parser_result<self_t, ScannerT>::type result_t; 572 result_t hit = this->subject().parse(scan); 573 if (hit.has_valid_attribute() && 574 (hit.value() < min_ || hit.value() > max_)) 575 return scan.no_match(); 576 return hit; 577 } 578 579 BoundsT min_, max_; 580 }; 581 582 template <typename BoundsT> 583 struct bounded_gen 584 { bounded_genboost::spirit::bounded_gen585 bounded_gen(BoundsT const& min__, BoundsT const& max__) 586 : min_(min__) 587 , max_(max__) {} 588 589 template <typename DerivedT> 590 bounded<DerivedT, BoundsT> operator []boost::spirit::bounded_gen591 operator[](parser<DerivedT> const& p) const 592 { return bounded<DerivedT, BoundsT>(p.derived(), min_, max_); } 593 594 BoundsT min_, max_; 595 }; 596 597 template <typename BoundsT> 598 inline bounded_gen<BoundsT> limit_d(BoundsT const & min_,BoundsT const & max_)599 limit_d(BoundsT const& min_, BoundsT const& max_) 600 { return bounded_gen<BoundsT>(min_, max_); } 601 602 BOOST_SPIRIT_CLASSIC_NAMESPACE_END 603 604 }} // namespace BOOST_SPIRIT_CLASSIC_NS 605 606 #endif 607 608