| 599 | // removeLeadingString removes the first n leading runes |
| 600 | // from the beginning of re. It returns the replacement for re. |
| 601 | private Regexp removeLeadingString(Regexp re, int n) { |
| 602 | if (re.op == Regexp.Op.CONCAT && re.subs.length > 0) { |
| 603 | // Removing a leading string in a concatenation |
| 604 | // might simplify the concatenation. |
| 605 | Regexp sub = removeLeadingString(re.subs[0], n); |
| 606 | re.subs[0] = sub; |
| 607 | if (sub.op == Regexp.Op.EMPTY_MATCH) { |
| 608 | reuse(sub); |
| 609 | switch (re.subs.length) { |
| 610 | case 0: |
| 611 | case 1: |
| 612 | // Impossible but handle. |
| 613 | re.op = Regexp.Op.EMPTY_MATCH; |
| 614 | re.subs = null; |
| 615 | break; |
| 616 | case 2: |
| 617 | { |
| 618 | Regexp old = re; |
| 619 | re = re.subs[1]; |
| 620 | reuse(old); |
| 621 | break; |
| 622 | } |
| 623 | default: |
| 624 | re.subs = subarray(re.subs, 1, re.subs.length); |
| 625 | break; |
| 626 | } |
| 627 | } |
| 628 | return re; |
| 629 | } |
| 630 | |
| 631 | if (re.op == Regexp.Op.LITERAL) { |
| 632 | re.runes = Utils.subarray(re.runes, n, re.runes.length); |
| 633 | if (re.runes.length == 0) { |
| 634 | re.op = Regexp.Op.EMPTY_MATCH; |
| 635 | } |
| 636 | } |
| 637 | return re; |
| 638 | } |
| 639 | |
| 640 | // leadingRegexp returns the leading regexp that re begins with. |
| 641 | // The regexp refers to storage in re or its children. |