11 #include "util/util.h"
12 #include "util/logging.h"
15 #include "re2/regexp.h"
16 #include "re2/walker-inl.h"
28 Regexp* sre = re->Simplify();
33 status->set_error_arg(src);
37 *
dst = sre->ToString();
76 return subs[0]->simple();
97 LOG(DFATAL) <<
"Case not handled in ComputeSimple: " <<
op_;
106 class CoalesceWalker :
public Regexp::Walker<Regexp*> {
110 Regexp** child_args,
int nchild_args);
136 class SimplifyWalker :
public Regexp::Walker<Regexp*> {
141 Regexp** child_args,
int nchild_args);
179 Regexp* cre = cw.Walk(
this, NULL);
182 if (cw.stopped_early()) {
187 Regexp* sre = sw.Walk(cre, NULL);
191 if (sw.stopped_early()) {
198 #define Simplify DontCallSimplify // Avoid accidental recursion
205 for (
int i = 0;
i < re->
nsub();
i++) {
207 Regexp* newsub = child_args[
i];
211 for (
int i = 0;
i < re->
nsub();
i++) {
212 Regexp* newsub = child_args[
i];
224 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
225 LOG(DFATAL) <<
"CoalesceWalker::ShortVisit called";
243 Regexp* nre =
new Regexp(re->op(), re->parse_flags());
244 nre->AllocSub(re->nsub());
245 Regexp** nre_subs = nre->sub();
246 for (
int i = 0;
i < re->nsub();
i++)
247 nre_subs[i] = child_args[i];
250 nre->min_ = re->min();
251 nre->max_ = re->max();
253 nre->cap_ = re->cap();
258 bool can_coalesce =
false;
259 for (
int i = 0;
i < re->nsub();
i++) {
260 if (i+1 < re->nsub() &&
271 Regexp* nre =
new Regexp(re->op(), re->parse_flags());
272 nre->AllocSub(re->nsub());
273 Regexp** nre_subs = nre->sub();
274 for (
int i = 0;
i < re->nsub();
i++)
275 nre_subs[i] = child_args[i];
279 for (
int i = 0;
i < re->nsub();
i++) {
280 if (i+1 < re->nsub() &&
286 for (
int i = n;
i < re->nsub();
i++) {
291 Regexp* nre =
new Regexp(re->op(), re->parse_flags());
292 nre->AllocSub(re->nsub() - n);
293 Regexp** nre_subs = nre->sub();
294 for (
int i = 0, j = 0;
i < re->nsub();
i++) {
296 child_args[
i]->Decref();
299 nre_subs[
j] = child_args[
i];
335 r2->runes()[0] == r1->sub()[0]->rune() &&
350 r1->sub()[0]->Incref(), r1->parse_flags(), 0, 0);
369 nre->min_ = r1->min();
370 nre->max_ = r1->max();
374 LOG(DFATAL) <<
"DoCoalesce failed: r1->op() is " << r1->op();
390 if (nre->max() != -1)
395 nre->min_ += r2->min();
398 else if (nre->max() != -1)
399 nre->max_ += r2->max();
407 if (nre->max() != -1)
417 Rune r = r1->sub()[0]->rune();
421 while (n < r2->nrunes() && r2->runes()[n] ==
r)
424 if (nre->max() != -1)
426 if (n == r2->nrunes())
430 &r2->runes()[n], r2->nrunes() - n, r2->parse_flags());
435 LOG(DFATAL) <<
"DoCoalesce failed: r2->op() is " << r2->op();
450 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
451 LOG(DFATAL) <<
"SimplifyWalker::ShortVisit called";
494 Regexp* nre =
new Regexp(re->op(), re->parse_flags());
495 nre->AllocSub(re->nsub());
496 Regexp** nre_subs = nre->sub();
497 for (
int i = 0;
i < re->nsub();
i++)
498 nre_subs[i] = child_args[i];
504 Regexp* newsub = child_args[0];
505 if (newsub == re->sub()[0]) {
512 nre->sub()[0] = newsub;
513 nre->cap_ = re->cap();
521 Regexp* newsub = child_args[0];
528 if (newsub == re->sub()[0]) {
535 if (re->op() == newsub->op() &&
536 re->parse_flags() == newsub->parse_flags())
539 Regexp* nre =
new Regexp(re->op(), re->parse_flags());
541 nre->sub()[0] = newsub;
547 Regexp* newsub = child_args[0];
567 LOG(
ERROR) <<
"Simplify case not handled: " << re->op();
577 Regexp**
subs = re->sub();
602 PODArray<Regexp*> nre_subs(
min);
603 for (
int i = 0;
i <
min-1;
i++)
604 nre_subs[i] = re->Incref();
624 PODArray<Regexp*> nre_subs(
min);
625 for (
int i = 0;
i <
min;
i++)
626 nre_subs[i] = re->Incref();
644 LOG(DFATAL) <<
"Malformed repeat " << re->ToString() <<
" " <<
min <<
" " <<
max;
654 CharClass* cc = re->
cc();