Pushes a repeat operator regexp onto the stack. A valid argument for the operator must already be on the stack. The char c is the name of the operator, for use in error messages.
| 473 | // A valid argument for the operator must already be on the stack. |
| 474 | // The char c is the name of the operator, for use in error messages. |
| 475 | bool Regexp::ParseState::PushRepeatOp(RegexpOp op, const StringPiece& s, |
| 476 | bool nongreedy) { |
| 477 | if (stacktop_ == NULL || IsMarker(stacktop_->op())) { |
| 478 | status_->set_code(kRegexpRepeatArgument); |
| 479 | status_->set_error_arg(s); |
| 480 | return false; |
| 481 | } |
| 482 | Regexp::ParseFlags fl = flags_; |
| 483 | if (nongreedy) |
| 484 | fl = fl ^ NonGreedy; |
| 485 | |
| 486 | // Squash **, ++ and ??. Regexp::Star() et al. handle this too, but |
| 487 | // they're mostly for use during simplification, not during parsing. |
| 488 | if (op == stacktop_->op() && fl == stacktop_->parse_flags()) |
| 489 | return true; |
| 490 | |
| 491 | // Squash *+, *?, +*, +?, ?* and ?+. They all squash to *, so because |
| 492 | // op is a repeat, we just have to check that stacktop_->op() is too, |
| 493 | // then adjust stacktop_. |
| 494 | if ((stacktop_->op() == kRegexpStar || |
| 495 | stacktop_->op() == kRegexpPlus || |
| 496 | stacktop_->op() == kRegexpQuest) && |
| 497 | fl == stacktop_->parse_flags()) { |
| 498 | stacktop_->op_ = kRegexpStar; |
| 499 | return true; |
| 500 | } |
| 501 | |
| 502 | Regexp* re = new Regexp(op, fl); |
| 503 | re->AllocSub(1); |
| 504 | re->down_ = stacktop_->down_; |
| 505 | re->sub()[0] = FinishRegexp(stacktop_); |
| 506 | re->simple_ = re->ComputeSimple(); |
| 507 | stacktop_ = re; |
| 508 | return true; |
| 509 | } |
| 510 | |
| 511 | // RepetitionWalker reports whether the repetition regexp is valid. |
| 512 | // Valid means that the combination of the top-level repetition |
no test coverage detected