(StringIterator t)
| 1613 | // Pre: at '['; Post: after ']'. |
| 1614 | // Mutates stack. Advances iterator. May throw. |
| 1615 | private void parseClass(StringIterator t) throws PatternSyntaxException { |
| 1616 | int startPos = t.pos(); |
| 1617 | t.skip(1); // '[' |
| 1618 | Regexp re = newRegexp(Regexp.Op.CHAR_CLASS); |
| 1619 | re.flags = flags; |
| 1620 | CharClass cc = new CharClass(); |
| 1621 | |
| 1622 | int sign = +1; |
| 1623 | if (t.more() && t.lookingAt('^')) { |
| 1624 | sign = -1; |
| 1625 | t.skip(1); // '^' |
| 1626 | |
| 1627 | // If character class does not match \n, add it here, |
| 1628 | // so that negation later will do the right thing. |
| 1629 | if ((flags & RE2.CLASS_NL) == 0) { |
| 1630 | cc.appendRange('\n', '\n'); |
| 1631 | } |
| 1632 | } |
| 1633 | |
| 1634 | boolean first = true; // ']' and '-' are okay as first char in class |
| 1635 | while (!t.more() || t.peek() != ']' || first) { |
| 1636 | // POSIX: - is only okay unescaped as first or last in class. |
| 1637 | // Perl: - is okay anywhere. |
| 1638 | if (t.more() && t.lookingAt('-') && (flags & RE2.PERL_X) == 0 && !first) { |
| 1639 | String s = t.rest(); |
| 1640 | if (s.equals("-") || !s.startsWith("-]")) { |
| 1641 | t.rewindTo(startPos); |
| 1642 | throw new PatternSyntaxException(ERR_INVALID_CHAR_RANGE, t.rest()); |
| 1643 | } |
| 1644 | } |
| 1645 | first = false; |
| 1646 | |
| 1647 | int beforePos = t.pos(); |
| 1648 | |
| 1649 | // Look for POSIX [:alnum:] etc. |
| 1650 | if (t.lookingAt("[:")) { |
| 1651 | if (parseNamedClass(t, cc)) { |
| 1652 | continue; |
| 1653 | } |
| 1654 | t.rewindTo(beforePos); |
| 1655 | } |
| 1656 | |
| 1657 | // Look for Unicode character group like \p{Han}. |
| 1658 | if (parseUnicodeClass(t, cc)) { |
| 1659 | continue; |
| 1660 | } |
| 1661 | |
| 1662 | // Look for Perl character class symbols (extension). |
| 1663 | if (parsePerlClassEscape(t, cc)) { |
| 1664 | continue; |
| 1665 | } |
| 1666 | t.rewindTo(beforePos); |
| 1667 | |
| 1668 | // Single character or simple range. |
| 1669 | int lo = parseClassChar(t, startPos); |
| 1670 | int hi = lo; |
| 1671 | if (t.more() && t.lookingAt('-')) { |
| 1672 | t.skip(1); // '-' |
no test coverage detected