4317 int temp = info.minLength * cmin + minL;
4318 if (temp < minL) {
4319 temp = 0xFFFFFFF; // arbitrary large number
4320 }
4321 info.minLength = temp;
4322
4323 if (maxV & info.maxValid) {
4324 temp = info.maxLength * cmax + maxL;
4325 info.maxLength = temp;
4326 if (temp < maxL) {
4327 info.maxValid = false;
4328 }
4329 } else {
4330 info.maxValid = false;
4331 }
4332
4333 if (info.deterministic && cmin == cmax)
4334 info.deterministic = detm;
4335 else
4336 info.deterministic = false;
4337
4338 return next.study(info);
4339 }
4340 }
4341
4342 /**
4343 * Handles the curly-brace style repetition with a specified minimum and
4344 * maximum occurrences in deterministic cases. This is an iterative
4345 * optimization over the Prolog and Loop system which would handle this
4346 * in a recursive way. The * quantifier is handled as a special case.
4347 * If capture is true then this class saves group settings and ensures
4348 * that groups are unset when backing off of a group match.
4349 */
4350 static final class GroupCurly extends Node {
4351 Node atom;
4352 int type;
4353 int cmin;
4354 int cmax;
4355 int localIndex;
4356 int groupIndex;
4357 boolean capture;
4398 if (ret) {
4399 if (type == GREEDY) {
4400 ret = match0(matcher, i, cmin, seq);
4401 } else if (type == LAZY) {
4402 ret = match1(matcher, i, cmin, seq);
4403 } else {
4404 ret = match2(matcher, i, cmin, seq);
4405 }
4406 }
4407 if (!ret) {
4408 locals[localIndex] = save0;
4409 if (capture) {
4410 groups[groupIndex] = save1;
4411 groups[groupIndex+1] = save2;
4412 }
4413 }
4414 return ret;
4415 }
4416 // Aggressive group match
4417 boolean match0(Matcher matcher, int i, int j, CharSequence seq) {
4418 int[] groups = matcher.groups;
4419 int save0 = 0;
4420 int save1 = 0;
4421 if (capture) {
4422 save0 = groups[groupIndex];
4423 save1 = groups[groupIndex+1];
4424 }
4425 for (;;) {
4426 if (j >= cmax)
4427 break;
4428 if (!atom.match(matcher, i, seq))
4429 break;
4430 int k = matcher.last - i;
4431 if (k <= 0) {
4432 if (capture) {
4433 groups[groupIndex] = i;
4434 groups[groupIndex+1] = i + k;
4435 }
4436 i = i + k;
4437 break;
4438 }
4439 for (;;) {
4440 if (capture) {
4441 groups[groupIndex] = i;
4442 groups[groupIndex+1] = i + k;
4443 }
4444 i = i + k;
4445 if (++j >= cmax)
4446 break;
4447 if (!atom.match(matcher, i, seq))
4448 break;
4449 if (i + k != matcher.last) {
4450 if (match0(matcher, i, j, seq))
4451 return true;
4452 break;
4453 }
4454 }
4455 while (j > cmin) {
4456 if (next.match(matcher, i, seq)) {
4457 if (capture) {
4458 groups[groupIndex+1] = i;
4459 groups[groupIndex] = i - k;
4460 }
4461 i = i - k;
4462 return true;
4463 }
4464 // backing off
4465 if (capture) {
4466 groups[groupIndex+1] = i;
4467 groups[groupIndex] = i - k;
4468 }
4469 i = i - k;
4470 j--;
4471 }
4472 break;
4473 }
4474 if (capture) {
4475 groups[groupIndex] = save0;
4527 if (temp < minL) {
4528 temp = 0xFFFFFFF; // Arbitrary large number
4529 }
4530 info.minLength = temp;
4531
4532 if (maxV & info.maxValid) {
4533 temp = info.maxLength * cmax + maxL;
4534 info.maxLength = temp;
4535 if (temp < maxL) {
4536 info.maxValid = false;
4537 }
4538 } else {
4539 info.maxValid = false;
4540 }
4541
4542 if (info.deterministic && cmin == cmax) {
4543 info.deterministic = detm;
4544 } else {
4545 info.deterministic = false;
4546 }
4547
4548 return next.study(info);
4549 }
4550 }
4551
4552 /**
4553 * A Guard node at the end of each atom node in a Branch. It
4554 * serves the purpose of chaining the "match" operation to
4555 * "next" but not the "study", so we can collect the TreeInfo
4556 * of each atom node without including the TreeInfo of the
4557 * "next".
4558 */
4559 static final class BranchConn extends Node {
4560 BranchConn() {};
4561 boolean match(Matcher matcher, int i, CharSequence seq) {
4562 return next.match(matcher, i, seq);
4563 }
4564 boolean study(TreeInfo info) {
4565 return info.deterministic;
4566 }
4567 }
|
4317 int temp = info.minLength * cmin + minL;
4318 if (temp < minL) {
4319 temp = 0xFFFFFFF; // arbitrary large number
4320 }
4321 info.minLength = temp;
4322
4323 if (maxV & info.maxValid) {
4324 temp = info.maxLength * cmax + maxL;
4325 info.maxLength = temp;
4326 if (temp < maxL) {
4327 info.maxValid = false;
4328 }
4329 } else {
4330 info.maxValid = false;
4331 }
4332
4333 if (info.deterministic && cmin == cmax)
4334 info.deterministic = detm;
4335 else
4336 info.deterministic = false;
4337 return next.study(info);
4338 }
4339 }
4340
4341 /**
4342 * Handles the curly-brace style repetition with a specified minimum and
4343 * maximum occurrences in deterministic cases. This is an iterative
4344 * optimization over the Prolog and Loop system which would handle this
4345 * in a recursive way. The * quantifier is handled as a special case.
4346 * If capture is true then this class saves group settings and ensures
4347 * that groups are unset when backing off of a group match.
4348 */
4349 static final class GroupCurly extends Node {
4350 Node atom;
4351 int type;
4352 int cmin;
4353 int cmax;
4354 int localIndex;
4355 int groupIndex;
4356 boolean capture;
4397 if (ret) {
4398 if (type == GREEDY) {
4399 ret = match0(matcher, i, cmin, seq);
4400 } else if (type == LAZY) {
4401 ret = match1(matcher, i, cmin, seq);
4402 } else {
4403 ret = match2(matcher, i, cmin, seq);
4404 }
4405 }
4406 if (!ret) {
4407 locals[localIndex] = save0;
4408 if (capture) {
4409 groups[groupIndex] = save1;
4410 groups[groupIndex+1] = save2;
4411 }
4412 }
4413 return ret;
4414 }
4415 // Aggressive group match
4416 boolean match0(Matcher matcher, int i, int j, CharSequence seq) {
4417 // don't back off passing the starting "j"
4418 int min = j;
4419 int[] groups = matcher.groups;
4420 int save0 = 0;
4421 int save1 = 0;
4422 if (capture) {
4423 save0 = groups[groupIndex];
4424 save1 = groups[groupIndex+1];
4425 }
4426 for (;;) {
4427 if (j >= cmax)
4428 break;
4429 if (!atom.match(matcher, i, seq))
4430 break;
4431 int k = matcher.last - i;
4432 if (k <= 0) {
4433 if (capture) {
4434 groups[groupIndex] = i;
4435 groups[groupIndex+1] = i + k;
4436 }
4437 i = i + k;
4438 break;
4439 }
4440 for (;;) {
4441 if (capture) {
4442 groups[groupIndex] = i;
4443 groups[groupIndex+1] = i + k;
4444 }
4445 i = i + k;
4446 if (++j >= cmax)
4447 break;
4448 if (!atom.match(matcher, i, seq))
4449 break;
4450 if (i + k != matcher.last) {
4451 if (match0(matcher, i, j, seq))
4452 return true;
4453 break;
4454 }
4455 }
4456 while (j > min) {
4457 if (next.match(matcher, i, seq)) {
4458 if (capture) {
4459 groups[groupIndex+1] = i;
4460 groups[groupIndex] = i - k;
4461 }
4462 i = i - k;
4463 return true;
4464 }
4465 // backing off
4466 if (capture) {
4467 groups[groupIndex+1] = i;
4468 groups[groupIndex] = i - k;
4469 }
4470 i = i - k;
4471 j--;
4472 }
4473 break;
4474 }
4475 if (capture) {
4476 groups[groupIndex] = save0;
4528 if (temp < minL) {
4529 temp = 0xFFFFFFF; // Arbitrary large number
4530 }
4531 info.minLength = temp;
4532
4533 if (maxV & info.maxValid) {
4534 temp = info.maxLength * cmax + maxL;
4535 info.maxLength = temp;
4536 if (temp < maxL) {
4537 info.maxValid = false;
4538 }
4539 } else {
4540 info.maxValid = false;
4541 }
4542
4543 if (info.deterministic && cmin == cmax) {
4544 info.deterministic = detm;
4545 } else {
4546 info.deterministic = false;
4547 }
4548 return next.study(info);
4549 }
4550 }
4551
4552 /**
4553 * A Guard node at the end of each atom node in a Branch. It
4554 * serves the purpose of chaining the "match" operation to
4555 * "next" but not the "study", so we can collect the TreeInfo
4556 * of each atom node without including the TreeInfo of the
4557 * "next".
4558 */
4559 static final class BranchConn extends Node {
4560 BranchConn() {};
4561 boolean match(Matcher matcher, int i, CharSequence seq) {
4562 return next.match(matcher, i, seq);
4563 }
4564 boolean study(TreeInfo info) {
4565 return info.deterministic;
4566 }
4567 }
|