| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 | 535 |
| 536 // Whether there is a line terminator whitespace character after | 536 // Whether there is a line terminator whitespace character after |
| 537 // the current token, and before the next. Does not count newlines | 537 // the current token, and before the next. Does not count newlines |
| 538 // inside multiline comments. | 538 // inside multiline comments. |
| 539 bool has_line_terminator_before_next_; | 539 bool has_line_terminator_before_next_; |
| 540 // Whether there is a multi-line comment that contains a | 540 // Whether there is a multi-line comment that contains a |
| 541 // line-terminator after the current token, and before the next. | 541 // line-terminator after the current token, and before the next. |
| 542 bool has_multiline_comment_before_next_; | 542 bool has_multiline_comment_before_next_; |
| 543 }; | 543 }; |
| 544 | 544 |
| 545 | |
| 546 // ---------------------------------------------------------------------------- | |
| 547 // Keyword matching state machine. | |
| 548 | |
| 549 class KeywordMatcher { | |
| 550 // Incrementally recognize keywords. | |
| 551 // | |
| 552 // We distinguish between normal future reserved words and words that are | |
| 553 // considered to be future reserved words only in strict mode as required by | |
| 554 // ECMA-262 7.6.1.2. | |
| 555 // | |
| 556 // Recognized as keywords: | |
| 557 // break, case, catch, const*, continue, debugger, default, delete, do, | |
| 558 // else, finally, false, for, function, if, in, instanceof, new, null, | |
| 559 // return, switch, this, throw, true, try, typeof, var, void, while, with. | |
| 560 // | |
| 561 // Recognized as Future Reserved Keywords: | |
| 562 // class, enum, export, extends, import, super. | |
| 563 // | |
| 564 // Recognized as Future Reserved Keywords (strict mode only): | |
| 565 // implements, interface, let, package, private, protected, public, | |
| 566 // static, yield. | |
| 567 // | |
| 568 // *: Actually a "future reserved keyword". It's the only one we are | |
| 569 // recognizing outside of ES5 strict mode, the remaining are allowed | |
| 570 // as identifiers. | |
| 571 // | |
| 572 public: | |
| 573 KeywordMatcher() | |
| 574 : state_(INITIAL), | |
| 575 token_(Token::IDENTIFIER), | |
| 576 keyword_(NULL), | |
| 577 counter_(0), | |
| 578 keyword_token_(Token::ILLEGAL) {} | |
| 579 | |
| 580 Token::Value token() { return token_; } | |
| 581 | |
| 582 inline bool AddChar(unibrow::uchar input) { | |
| 583 if (state_ != UNMATCHABLE) { | |
| 584 Step(input); | |
| 585 } | |
| 586 return state_ != UNMATCHABLE; | |
| 587 } | |
| 588 | |
| 589 void Fail() { | |
| 590 token_ = Token::IDENTIFIER; | |
| 591 state_ = UNMATCHABLE; | |
| 592 } | |
| 593 | |
| 594 private: | |
| 595 enum State { | |
| 596 UNMATCHABLE, | |
| 597 INITIAL, | |
| 598 KEYWORD_PREFIX, | |
| 599 KEYWORD_MATCHED, | |
| 600 C, | |
| 601 CA, | |
| 602 CO, | |
| 603 CON, | |
| 604 D, | |
| 605 DE, | |
| 606 E, | |
| 607 EX, | |
| 608 F, | |
| 609 I, | |
| 610 IM, | |
| 611 IMP, | |
| 612 IN, | |
| 613 N, | |
| 614 P, | |
| 615 PR, | |
| 616 S, | |
| 617 T, | |
| 618 TH, | |
| 619 TR, | |
| 620 V, | |
| 621 W | |
| 622 }; | |
| 623 | |
| 624 struct FirstState { | |
| 625 const char* keyword; | |
| 626 State state; | |
| 627 Token::Value token; | |
| 628 }; | |
| 629 | |
| 630 // Range of possible first characters of a keyword. | |
| 631 static const unsigned int kFirstCharRangeMin = 'b'; | |
| 632 static const unsigned int kFirstCharRangeMax = 'y'; | |
| 633 static const unsigned int kFirstCharRangeLength = | |
| 634 kFirstCharRangeMax - kFirstCharRangeMin + 1; | |
| 635 // State map for first keyword character range. | |
| 636 static const FirstState first_states_[kFirstCharRangeLength]; | |
| 637 | |
| 638 // If input equals keyword's character at position, continue matching keyword | |
| 639 // from that position. | |
| 640 inline bool MatchKeywordStart(unibrow::uchar input, | |
| 641 const char* keyword, | |
| 642 int position, | |
| 643 Token::Value token_if_match) { | |
| 644 if (input != static_cast<unibrow::uchar>(keyword[position])) { | |
| 645 return false; | |
| 646 } | |
| 647 state_ = KEYWORD_PREFIX; | |
| 648 this->keyword_ = keyword; | |
| 649 this->counter_ = position + 1; | |
| 650 this->keyword_token_ = token_if_match; | |
| 651 return true; | |
| 652 } | |
| 653 | |
| 654 // If input equals match character, transition to new state and return true. | |
| 655 inline bool MatchState(unibrow::uchar input, char match, State new_state) { | |
| 656 if (input != static_cast<unibrow::uchar>(match)) { | |
| 657 return false; | |
| 658 } | |
| 659 state_ = new_state; | |
| 660 return true; | |
| 661 } | |
| 662 | |
| 663 inline bool MatchKeyword(unibrow::uchar input, | |
| 664 char match, | |
| 665 State new_state, | |
| 666 Token::Value keyword_token) { | |
| 667 if (input != static_cast<unibrow::uchar>(match)) { | |
| 668 return false; | |
| 669 } | |
| 670 state_ = new_state; | |
| 671 token_ = keyword_token; | |
| 672 return true; | |
| 673 } | |
| 674 | |
| 675 void Step(unibrow::uchar input); | |
| 676 | |
| 677 // Current state. | |
| 678 State state_; | |
| 679 // Token for currently added characters. | |
| 680 Token::Value token_; | |
| 681 | |
| 682 // Matching a specific keyword string (there is only one possible valid | |
| 683 // keyword with the current prefix). | |
| 684 const char* keyword_; | |
| 685 int counter_; | |
| 686 Token::Value keyword_token_; | |
| 687 }; | |
| 688 | |
| 689 | |
| 690 } } // namespace v8::internal | 545 } } // namespace v8::internal |
| 691 | 546 |
| 692 #endif // V8_SCANNER_BASE_H_ | 547 #endif // V8_SCANNER_BASE_H_ |
| OLD | NEW |