Processes a vertical bar in the input.
| 624 | |
| 625 | // Processes a vertical bar in the input. |
| 626 | bool Regexp::ParseState::DoVerticalBar() { |
| 627 | MaybeConcatString(-1, NoParseFlags); |
| 628 | DoConcatenation(); |
| 629 | |
| 630 | // Below the vertical bar is a list to alternate. |
| 631 | // Above the vertical bar is a list to concatenate. |
| 632 | // We just did the concatenation, so either swap |
| 633 | // the result below the vertical bar or push a new |
| 634 | // vertical bar on the stack. |
| 635 | Regexp* r1; |
| 636 | Regexp* r2; |
| 637 | if ((r1 = stacktop_) != NULL && |
| 638 | (r2 = r1->down_) != NULL && |
| 639 | r2->op() == kVerticalBar) { |
| 640 | Regexp* r3; |
| 641 | if ((r3 = r2->down_) != NULL && |
| 642 | (r1->op() == kRegexpAnyChar || r3->op() == kRegexpAnyChar)) { |
| 643 | // AnyChar is above or below the vertical bar. Let it subsume |
| 644 | // the other when the other is Literal, CharClass or AnyChar. |
| 645 | if (r3->op() == kRegexpAnyChar && |
| 646 | (r1->op() == kRegexpLiteral || |
| 647 | r1->op() == kRegexpCharClass || |
| 648 | r1->op() == kRegexpAnyChar)) { |
| 649 | // Discard r1. |
| 650 | stacktop_ = r2; |
| 651 | r1->Decref(); |
| 652 | return true; |
| 653 | } |
| 654 | if (r1->op() == kRegexpAnyChar && |
| 655 | (r3->op() == kRegexpLiteral || |
| 656 | r3->op() == kRegexpCharClass || |
| 657 | r3->op() == kRegexpAnyChar)) { |
| 658 | // Rearrange the stack and discard r3. |
| 659 | r1->down_ = r3->down_; |
| 660 | r2->down_ = r1; |
| 661 | stacktop_ = r2; |
| 662 | r3->Decref(); |
| 663 | return true; |
| 664 | } |
| 665 | } |
| 666 | // Swap r1 below vertical bar (r2). |
| 667 | r1->down_ = r2->down_; |
| 668 | r2->down_ = r1; |
| 669 | stacktop_ = r2; |
| 670 | return true; |
| 671 | } |
| 672 | return PushSimpleOp(kVerticalBar); |
| 673 | } |
| 674 | |
| 675 | // Processes a right parenthesis in the input. |
| 676 | bool Regexp::ParseState::DoRightParen() { |