1 /*============================================================================= 2 Copyright (c) 1998-2003 Joel de Guzman 3 Copyright (c) 2003 Martin Wille 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_PRIMITIVES_HPP) 10 #define BOOST_SPIRIT_PRIMITIVES_HPP 11 12 #include <boost/ref.hpp> 13 #include <boost/spirit/home/classic/namespace.hpp> 14 #include <boost/spirit/home/classic/core/assert.hpp> 15 #include <boost/spirit/home/classic/core/parser.hpp> 16 #include <boost/spirit/home/classic/core/composite/impl/directives.ipp> 17 #include <boost/spirit/home/classic/core/primitives/impl/primitives.ipp> 18 19 #ifdef BOOST_MSVC 20 #pragma warning (push) 21 #pragma warning(disable : 4512) 22 #endif 23 24 namespace boost { namespace spirit { 25 26 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 27 28 /////////////////////////////////////////////////////////////////////////// 29 // 30 // char_parser class 31 // 32 /////////////////////////////////////////////////////////////////////////// 33 template <typename DerivedT> 34 struct char_parser : public parser<DerivedT> 35 { 36 typedef DerivedT self_t; 37 template <typename ScannerT> 38 struct result 39 { 40 typedef typename match_result< 41 ScannerT, 42 typename ScannerT::value_t 43 >::type type; 44 }; 45 46 template <typename ScannerT> 47 typename parser_result<self_t, ScannerT>::type parseboost::spirit::char_parser48 parse(ScannerT const& scan) const 49 { 50 typedef typename ScannerT::value_t value_t; 51 typedef typename ScannerT::iterator_t iterator_t; 52 typedef scanner_policies< 53 no_skipper_iteration_policy< 54 BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, 55 BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, 56 BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t 57 > policies_t; 58 59 if (!scan.at_end()) 60 { 61 value_t ch = *scan; 62 if (this->derived().test(ch)) 63 { 64 iterator_t save(scan.first); 65 ++scan.change_policies(policies_t(scan)); 66 return scan.create_match(1, ch, save, scan.first); 67 } 68 } 69 return scan.no_match(); 70 } 71 }; 72 73 /////////////////////////////////////////////////////////////////////////// 74 // 75 // negation of char_parsers 76 // 77 /////////////////////////////////////////////////////////////////////////// 78 template <typename PositiveT> 79 struct negated_char_parser 80 : public char_parser<negated_char_parser<PositiveT> > 81 { 82 typedef negated_char_parser<PositiveT> self_t; 83 typedef PositiveT positive_t; 84 negated_char_parserboost::spirit::negated_char_parser85 negated_char_parser(positive_t const& p) 86 : positive(p.derived()) {} 87 88 template <typename T> testboost::spirit::negated_char_parser89 bool test(T ch) const 90 { 91 return !positive.test(ch); 92 } 93 94 positive_t const positive; 95 }; 96 97 template <typename ParserT> 98 inline negated_char_parser<ParserT> operator ~(char_parser<ParserT> const & p)99 operator~(char_parser<ParserT> const& p) 100 { 101 return negated_char_parser<ParserT>(p.derived()); 102 } 103 104 template <typename ParserT> 105 inline ParserT operator ~(negated_char_parser<ParserT> const & n)106 operator~(negated_char_parser<ParserT> const& n) 107 { 108 return n.positive; 109 } 110 111 /////////////////////////////////////////////////////////////////////////// 112 // 113 // chlit class 114 // 115 /////////////////////////////////////////////////////////////////////////// 116 template <typename CharT = char> 117 struct chlit : public char_parser<chlit<CharT> > 118 { chlitboost::spirit::chlit119 chlit(CharT ch_) 120 : ch(ch_) {} 121 122 template <typename T> testboost::spirit::chlit123 bool test(T ch_) const 124 { 125 return ch_ == ch; 126 } 127 128 CharT ch; 129 }; 130 131 template <typename CharT> 132 inline chlit<CharT> ch_p(CharT ch)133 ch_p(CharT ch) 134 { 135 return chlit<CharT>(ch); 136 } 137 138 // This should take care of ch_p("a") "bugs" 139 template <typename CharT, std::size_t N> 140 inline chlit<CharT> ch_p(CharT const (& str)[N])141 ch_p(CharT const (& str)[N]) 142 { 143 // ch_p's argument should be a single character or a null-terminated 144 // string with a single character 145 BOOST_STATIC_ASSERT(N < 3); 146 return chlit<CharT>(str[0]); 147 } 148 149 /////////////////////////////////////////////////////////////////////////// 150 // 151 // range class 152 // 153 /////////////////////////////////////////////////////////////////////////// 154 template <typename CharT = char> 155 struct range : public char_parser<range<CharT> > 156 { rangeboost::spirit::range157 range(CharT first_, CharT last_) 158 : first(first_), last(last_) 159 { 160 BOOST_SPIRIT_ASSERT(!(last < first)); 161 } 162 163 template <typename T> testboost::spirit::range164 bool test(T ch) const 165 { 166 return !(CharT(ch) < first) && !(last < CharT(ch)); 167 } 168 169 CharT first; 170 CharT last; 171 }; 172 173 template <typename CharT> 174 inline range<CharT> range_p(CharT first,CharT last)175 range_p(CharT first, CharT last) 176 { 177 return range<CharT>(first, last); 178 } 179 180 /////////////////////////////////////////////////////////////////////////// 181 // 182 // chseq class 183 // 184 /////////////////////////////////////////////////////////////////////////// 185 template <typename IteratorT = char const*> 186 class chseq : public parser<chseq<IteratorT> > 187 { 188 public: 189 190 typedef chseq<IteratorT> self_t; 191 chseq(IteratorT first_,IteratorT last_)192 chseq(IteratorT first_, IteratorT last_) 193 : first(first_), last(last_) {} 194 chseq(IteratorT first_)195 chseq(IteratorT first_) 196 : first(first_), last(impl::get_last(first_)) {} 197 198 template <typename ScannerT> 199 typename parser_result<self_t, ScannerT>::type parse(ScannerT const & scan) const200 parse(ScannerT const& scan) const 201 { 202 typedef typename boost::unwrap_reference<IteratorT>::type striter_t; 203 typedef typename parser_result<self_t, ScannerT>::type result_t; 204 return impl::string_parser_parse<result_t>( 205 striter_t(first), 206 striter_t(last), 207 scan); 208 } 209 210 private: 211 212 IteratorT first; 213 IteratorT last; 214 }; 215 216 template <typename CharT> 217 inline chseq<CharT const*> chseq_p(CharT const * str)218 chseq_p(CharT const* str) 219 { 220 return chseq<CharT const*>(str); 221 } 222 223 template <typename IteratorT> 224 inline chseq<IteratorT> chseq_p(IteratorT first,IteratorT last)225 chseq_p(IteratorT first, IteratorT last) 226 { 227 return chseq<IteratorT>(first, last); 228 } 229 230 /////////////////////////////////////////////////////////////////////////// 231 // 232 // strlit class 233 // 234 /////////////////////////////////////////////////////////////////////////// 235 template <typename IteratorT = char const*> 236 class strlit : public parser<strlit<IteratorT> > 237 { 238 public: 239 240 typedef strlit<IteratorT> self_t; 241 strlit(IteratorT first,IteratorT last)242 strlit(IteratorT first, IteratorT last) 243 : seq(first, last) {} 244 strlit(IteratorT first)245 strlit(IteratorT first) 246 : seq(first) {} 247 248 template <typename ScannerT> 249 typename parser_result<self_t, ScannerT>::type parse(ScannerT const & scan) const250 parse(ScannerT const& scan) const 251 { 252 typedef typename parser_result<self_t, ScannerT>::type result_t; 253 return impl::contiguous_parser_parse<result_t> 254 (seq, scan, scan); 255 } 256 257 private: 258 259 chseq<IteratorT> seq; 260 }; 261 262 template <typename CharT> 263 inline strlit<CharT const*> str_p(CharT const * str)264 str_p(CharT const* str) 265 { 266 return strlit<CharT const*>(str); 267 } 268 269 template <typename CharT> 270 inline strlit<CharT *> str_p(CharT * str)271 str_p(CharT * str) 272 { 273 return strlit<CharT *>(str); 274 } 275 276 template <typename IteratorT> 277 inline strlit<IteratorT> str_p(IteratorT first,IteratorT last)278 str_p(IteratorT first, IteratorT last) 279 { 280 return strlit<IteratorT>(first, last); 281 } 282 283 // This should take care of str_p('a') "bugs" 284 template <typename CharT> 285 inline chlit<CharT> str_p(CharT ch)286 str_p(CharT ch) 287 { 288 return chlit<CharT>(ch); 289 } 290 291 /////////////////////////////////////////////////////////////////////////// 292 // 293 // nothing_parser class 294 // 295 /////////////////////////////////////////////////////////////////////////// 296 struct nothing_parser : public parser<nothing_parser> 297 { 298 typedef nothing_parser self_t; 299 nothing_parserboost::spirit::nothing_parser300 nothing_parser() {} 301 302 template <typename ScannerT> 303 typename parser_result<self_t, ScannerT>::type parseboost::spirit::nothing_parser304 parse(ScannerT const& scan) const 305 { 306 return scan.no_match(); 307 } 308 }; 309 310 nothing_parser const nothing_p = nothing_parser(); 311 312 /////////////////////////////////////////////////////////////////////////// 313 // 314 // anychar_parser class 315 // 316 /////////////////////////////////////////////////////////////////////////// 317 struct anychar_parser : public char_parser<anychar_parser> 318 { 319 typedef anychar_parser self_t; 320 anychar_parserboost::spirit::anychar_parser321 anychar_parser() {} 322 323 template <typename CharT> testboost::spirit::anychar_parser324 bool test(CharT) const 325 { 326 return true; 327 } 328 }; 329 330 anychar_parser const anychar_p = anychar_parser(); 331 332 inline nothing_parser operator ~(anychar_parser)333 operator~(anychar_parser) 334 { 335 return nothing_p; 336 } 337 338 /////////////////////////////////////////////////////////////////////////// 339 // 340 // alnum_parser class 341 // 342 /////////////////////////////////////////////////////////////////////////// 343 struct alnum_parser : public char_parser<alnum_parser> 344 { 345 typedef alnum_parser self_t; 346 alnum_parserboost::spirit::alnum_parser347 alnum_parser() {} 348 349 template <typename CharT> testboost::spirit::alnum_parser350 bool test(CharT ch) const 351 { 352 return impl::isalnum_(ch); 353 } 354 }; 355 356 alnum_parser const alnum_p = alnum_parser(); 357 358 /////////////////////////////////////////////////////////////////////////// 359 // 360 // alpha_parser class 361 // 362 /////////////////////////////////////////////////////////////////////////// 363 struct alpha_parser : public char_parser<alpha_parser> 364 { 365 typedef alpha_parser self_t; 366 alpha_parserboost::spirit::alpha_parser367 alpha_parser() {} 368 369 template <typename CharT> testboost::spirit::alpha_parser370 bool test(CharT ch) const 371 { 372 return impl::isalpha_(ch); 373 } 374 }; 375 376 alpha_parser const alpha_p = alpha_parser(); 377 378 /////////////////////////////////////////////////////////////////////////// 379 // 380 // cntrl_parser class 381 // 382 /////////////////////////////////////////////////////////////////////////// 383 struct cntrl_parser : public char_parser<cntrl_parser> 384 { 385 typedef cntrl_parser self_t; 386 cntrl_parserboost::spirit::cntrl_parser387 cntrl_parser() {} 388 389 template <typename CharT> testboost::spirit::cntrl_parser390 bool test(CharT ch) const 391 { 392 return impl::iscntrl_(ch); 393 } 394 }; 395 396 cntrl_parser const cntrl_p = cntrl_parser(); 397 398 /////////////////////////////////////////////////////////////////////////// 399 // 400 // digit_parser class 401 // 402 /////////////////////////////////////////////////////////////////////////// 403 struct digit_parser : public char_parser<digit_parser> 404 { 405 typedef digit_parser self_t; 406 digit_parserboost::spirit::digit_parser407 digit_parser() {} 408 409 template <typename CharT> testboost::spirit::digit_parser410 bool test(CharT ch) const 411 { 412 return impl::isdigit_(ch); 413 } 414 }; 415 416 digit_parser const digit_p = digit_parser(); 417 418 /////////////////////////////////////////////////////////////////////////// 419 // 420 // graph_parser class 421 // 422 /////////////////////////////////////////////////////////////////////////// 423 struct graph_parser : public char_parser<graph_parser> 424 { 425 typedef graph_parser self_t; 426 graph_parserboost::spirit::graph_parser427 graph_parser() {} 428 429 template <typename CharT> testboost::spirit::graph_parser430 bool test(CharT ch) const 431 { 432 return impl::isgraph_(ch); 433 } 434 }; 435 436 graph_parser const graph_p = graph_parser(); 437 438 /////////////////////////////////////////////////////////////////////////// 439 // 440 // lower_parser class 441 // 442 /////////////////////////////////////////////////////////////////////////// 443 struct lower_parser : public char_parser<lower_parser> 444 { 445 typedef lower_parser self_t; 446 lower_parserboost::spirit::lower_parser447 lower_parser() {} 448 449 template <typename CharT> testboost::spirit::lower_parser450 bool test(CharT ch) const 451 { 452 return impl::islower_(ch); 453 } 454 }; 455 456 lower_parser const lower_p = lower_parser(); 457 458 /////////////////////////////////////////////////////////////////////////// 459 // 460 // print_parser class 461 // 462 /////////////////////////////////////////////////////////////////////////// 463 struct print_parser : public char_parser<print_parser> 464 { 465 typedef print_parser self_t; 466 print_parserboost::spirit::print_parser467 print_parser() {} 468 469 template <typename CharT> testboost::spirit::print_parser470 bool test(CharT ch) const 471 { 472 return impl::isprint_(ch); 473 } 474 }; 475 476 print_parser const print_p = print_parser(); 477 478 /////////////////////////////////////////////////////////////////////////// 479 // 480 // punct_parser class 481 // 482 /////////////////////////////////////////////////////////////////////////// 483 struct punct_parser : public char_parser<punct_parser> 484 { 485 typedef punct_parser self_t; 486 punct_parserboost::spirit::punct_parser487 punct_parser() {} 488 489 template <typename CharT> testboost::spirit::punct_parser490 bool test(CharT ch) const 491 { 492 return impl::ispunct_(ch); 493 } 494 }; 495 496 punct_parser const punct_p = punct_parser(); 497 498 /////////////////////////////////////////////////////////////////////////// 499 // 500 // blank_parser class 501 // 502 /////////////////////////////////////////////////////////////////////////// 503 struct blank_parser : public char_parser<blank_parser> 504 { 505 typedef blank_parser self_t; 506 blank_parserboost::spirit::blank_parser507 blank_parser() {} 508 509 template <typename CharT> testboost::spirit::blank_parser510 bool test(CharT ch) const 511 { 512 return impl::isblank_(ch); 513 } 514 }; 515 516 blank_parser const blank_p = blank_parser(); 517 518 /////////////////////////////////////////////////////////////////////////// 519 // 520 // space_parser class 521 // 522 /////////////////////////////////////////////////////////////////////////// 523 struct space_parser : public char_parser<space_parser> 524 { 525 typedef space_parser self_t; 526 space_parserboost::spirit::space_parser527 space_parser() {} 528 529 template <typename CharT> testboost::spirit::space_parser530 bool test(CharT ch) const 531 { 532 return impl::isspace_(ch); 533 } 534 }; 535 536 space_parser const space_p = space_parser(); 537 538 /////////////////////////////////////////////////////////////////////////// 539 // 540 // upper_parser class 541 // 542 /////////////////////////////////////////////////////////////////////////// 543 struct upper_parser : public char_parser<upper_parser> 544 { 545 typedef upper_parser self_t; 546 upper_parserboost::spirit::upper_parser547 upper_parser() {} 548 549 template <typename CharT> testboost::spirit::upper_parser550 bool test(CharT ch) const 551 { 552 return impl::isupper_(ch); 553 } 554 }; 555 556 upper_parser const upper_p = upper_parser(); 557 558 /////////////////////////////////////////////////////////////////////////// 559 // 560 // xdigit_parser class 561 // 562 /////////////////////////////////////////////////////////////////////////// 563 struct xdigit_parser : public char_parser<xdigit_parser> 564 { 565 typedef xdigit_parser self_t; 566 xdigit_parserboost::spirit::xdigit_parser567 xdigit_parser() {} 568 569 template <typename CharT> testboost::spirit::xdigit_parser570 bool test(CharT ch) const 571 { 572 return impl::isxdigit_(ch); 573 } 574 }; 575 576 xdigit_parser const xdigit_p = xdigit_parser(); 577 578 /////////////////////////////////////////////////////////////////////////// 579 // 580 // eol_parser class (contributed by Martin Wille) 581 // 582 /////////////////////////////////////////////////////////////////////////// 583 struct eol_parser : public parser<eol_parser> 584 { 585 typedef eol_parser self_t; 586 eol_parserboost::spirit::eol_parser587 eol_parser() {} 588 589 template <typename ScannerT> 590 typename parser_result<self_t, ScannerT>::type parseboost::spirit::eol_parser591 parse(ScannerT const& scan) const 592 { 593 typedef scanner_policies< 594 no_skipper_iteration_policy< 595 BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, 596 BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, 597 BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t 598 > policies_t; 599 600 typename ScannerT::iterator_t save = scan.first; 601 std::size_t len = 0; 602 603 if (!scan.at_end() && *scan == '\r') // CR 604 { 605 ++scan.change_policies(policies_t(scan)); 606 ++len; 607 } 608 609 // Don't call skipper here 610 if (scan.first != scan.last && *scan == '\n') // LF 611 { 612 ++scan.change_policies(policies_t(scan)); 613 ++len; 614 } 615 616 if (len) 617 return scan.create_match(len, nil_t(), save, scan.first); 618 return scan.no_match(); 619 } 620 }; 621 622 eol_parser const eol_p = eol_parser(); 623 624 /////////////////////////////////////////////////////////////////////////// 625 // 626 // end_parser class (suggested by Markus Schoepflin) 627 // 628 /////////////////////////////////////////////////////////////////////////// 629 struct end_parser : public parser<end_parser> 630 { 631 typedef end_parser self_t; 632 end_parserboost::spirit::end_parser633 end_parser() {} 634 635 template <typename ScannerT> 636 typename parser_result<self_t, ScannerT>::type parseboost::spirit::end_parser637 parse(ScannerT const& scan) const 638 { 639 if (scan.at_end()) 640 return scan.empty_match(); 641 return scan.no_match(); 642 } 643 }; 644 645 end_parser const end_p = end_parser(); 646 647 /////////////////////////////////////////////////////////////////////////// 648 // 649 // the pizza_p parser :-) 650 // 651 /////////////////////////////////////////////////////////////////////////// 652 inline strlit<char const*> const pizza_p(char const * your_favorite_pizza)653 pizza_p(char const* your_favorite_pizza) 654 { 655 return your_favorite_pizza; 656 } 657 658 BOOST_SPIRIT_CLASSIC_NAMESPACE_END 659 660 }} // namespace BOOST_SPIRIT_CLASSIC_NS 661 662 #ifdef BOOST_MSVC 663 #pragma warning (pop) 664 #endif 665 666 #endif 667