| 192 | } |
| 193 | |
| 194 | Regexp* Regexp::StarPlusOrQuest(RegexpOp op, Regexp* sub, ParseFlags flags) { |
| 195 | // Squash **, ++ and ??. |
| 196 | if (op == sub->op() && flags == sub->parse_flags()) |
| 197 | return sub; |
| 198 | |
| 199 | // Squash *+, *?, +*, +?, ?* and ?+. They all squash to *, so because |
| 200 | // op is Star/Plus/Quest, we just have to check that sub->op() is too. |
| 201 | if ((sub->op() == kRegexpStar || |
| 202 | sub->op() == kRegexpPlus || |
| 203 | sub->op() == kRegexpQuest) && |
| 204 | flags == sub->parse_flags()) { |
| 205 | // If sub is Star, no need to rewrite it. |
| 206 | if (sub->op() == kRegexpStar) |
| 207 | return sub; |
| 208 | |
| 209 | // Rewrite sub to Star. |
| 210 | Regexp* re = new Regexp(kRegexpStar, flags); |
| 211 | re->AllocSub(1); |
| 212 | re->sub()[0] = sub->sub()[0]->Incref(); |
| 213 | sub->Decref(); // We didn't consume the reference after all. |
| 214 | return re; |
| 215 | } |
| 216 | |
| 217 | Regexp* re = new Regexp(op, flags); |
| 218 | re->AllocSub(1); |
| 219 | re->sub()[0] = sub; |
| 220 | return re; |
| 221 | } |
| 222 | |
| 223 | Regexp* Regexp::Plus(Regexp* sub, ParseFlags flags) { |
| 224 | return StarPlusOrQuest(kRegexpPlus, sub, flags); |