@Override public boolean containsAnchor() { for (RegExpTree alternative : alternatives) { if (alternative.containsAnchor()) { return true; } } return false; }
@Override public boolean equals(Object o) { if (!(o instanceof Repetition)) { return false; } Repetition that = (Repetition) o; return this.body.equals(that.body) && this.min == that.min && this.max == that.max && this.greedy == that.greedy; }
@Override public int hashCode() { return 0x723aba9 ^ body.hashCode(); } }
regexTree = RegExpTree.parseRegExp(pattern, flags); } catch (IllegalArgumentException ex) { regexTree = regexTree.simplify(flags); String literal = regexTree.toString(); String newPattern = literal.substring(1, literal.length() - 1); && (!RegExpTree.matchesWholeInput(regexTree, flags) || regexTree.hasCapturingGroup()) ? "g" : "") + (flags.contains("i") && regexTree.isCaseSensitive() ? "i" : "") + (flags.contains("m") && regexTree.containsAnchor() ? "m" : ""));
@Override public RegExpTree simplify(String flags) { RegExpTree body = this.body.simplify(flags); if (max == 0 && !body.hasCapturingGroup()) { return Empty.INSTANCE; } if (body instanceof Empty || NEVER_MATCHES.equals(body)) { return body; } int min = this.min; int max = this.max; if (body instanceof Repetition) { Repetition rbody = (Repetition) body; if (rbody.greedy == greedy) { long lmin = ((long) min) * rbody.min; long lmax = ((long) max) * rbody.max; if (lmin < Integer.MAX_VALUE) { body = rbody.body; min = (int) lmin; max = lmax >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) lmax; } } } if (min == 1 && max == 1) { return body; } boolean greedy = this.greedy || min == max; return body.equals(this.body) && min == this.min && max == this.max && greedy == this.greedy ? this : new Repetition(body, min, max, greedy).simplify(flags); }
private void appendBodySourceCode(StringBuilder sb) { if (body instanceof Alternation || body instanceof Concatenation || body instanceof Repetition || (body instanceof Text && ((Text) body).text.length() > 1)) { sb.append("(?:"); body.appendSourceCode(sb); sb.append(')'); } else { body.appendSourceCode(sb); } }
@Override public int numCapturingGroups() { int n = 0; for (RegExpTree alternative : alternatives) { n += alternative.numCapturingGroups(); } return n; }
@Override public boolean isCaseSensitive() { for (RegExpTree element : elements) { if (element.isCaseSensitive()) { return true; } } return false; }
private void appendDebugString(StringBuilder sb) { sb.append('(').append(getClass().getSimpleName()); int len = sb.length(); sb.append(' '); appendDebugInfo(sb); if (sb.length() == len + 1) { sb.setLength(len); } for (RegExpTree child : children()) { sb.append(' '); child.appendDebugString(sb); } sb.append(')'); }
String flags = n.hasTwoChildren() ? n.getLastChild().getString() : ""; try { RegExpTree.parseRegExp(pattern, flags); } catch (IllegalArgumentException | IndexOutOfBoundsException ex) { t.report(n, MALFORMED_REGEXP, ex.getMessage());
static void escapeRangeCharOnto( char ch, boolean startIsFlush, boolean atStart, boolean atEnd, StringBuilder sb) { switch (ch) { case '\b': sb.append("\\b"); break; case '^': sb.append(atStart && startIsFlush ? "\\^" : "^"); break; case '-': sb.append(atStart || atEnd ? "-" : "\\-"); break; case '\\': case ']': sb.append('\\').append(ch); break; default: escapeCharOnto(ch, sb); } }
int expandedSuffixLen = suffixLen(expandedMin, expandedMax); if (bodyLen * expanded + expandedSuffixLen < suffixLen && !body.hasCapturingGroup()) {
private static boolean anySubtreeMeetsPredicate(RegExpTree tree, Predicate<RegExpTree> p) { if (p.test(tree)) { return true; } for (RegExpTree subTree : tree.children()) { if (anySubtreeMeetsPredicate(subTree, p)) { return true; } } return false; }
@Override public RegExpTree simplify(String flags) { RegExpTree body = this.body.simplify(flags); if (max == 0 && !body.hasCapturingGroup()) { return Empty.INSTANCE; } if (body instanceof Empty || NEVER_MATCHES.equals(body)) { return body; } int min = this.min; int max = this.max; if (body instanceof Repetition) { Repetition rbody = (Repetition) body; if (rbody.greedy == greedy) { long lmin = ((long) min) * rbody.min; long lmax = ((long) max) * rbody.max; if (lmin < Integer.MAX_VALUE) { body = rbody.body; min = (int) lmin; max = lmax >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) lmax; } } } if (min == 1 && max == 1) { return body; } boolean greedy = this.greedy || min == max; return body.equals(this.body) && min == this.min && max == this.max && greedy == this.greedy ? this : new Repetition(body, min, max, greedy).simplify(flags); }
private void appendBodySourceCode(StringBuilder sb) { if (body instanceof Alternation || body instanceof Concatenation || body instanceof Repetition || (body instanceof Text && ((Text) body).text.length() > 1)) { sb.append("(?:"); body.appendSourceCode(sb); sb.append(')'); } else { body.appendSourceCode(sb); } }
/** * True if the regular expression contains capturing groups. */ public final boolean hasCapturingGroup() { return numCapturingGroups() != 0; }
@Override public boolean isCaseSensitive() { for (RegExpTree alternative : alternatives) { if (alternative.isCaseSensitive()) { return true; } } return false; }
? n.getLastChild().getString() : ""; try { RegExpTree.parseRegExp(pattern, flags); } catch (IllegalArgumentException ex) { t.report(n, MALFORMED_REGEXP, ex.getMessage());
static void escapeRangeCharOnto( char ch, boolean startIsFlush, boolean atStart, boolean atEnd, StringBuilder sb) { switch (ch) { case '\b': sb.append("\\b"); break; case '^': sb.append(atStart && startIsFlush ? "\\^" : "^"); break; case '-': sb.append(atStart || atEnd ? "-" : "\\-"); break; case '\\': case ']': sb.append('\\').append(ch); break; default: escapeCharOnto(ch, sb); } }
int expandedSuffixLen = suffixLen(expandedMin, expandedMax); if (bodyLen * expanded + expandedSuffixLen < suffixLen && !body.hasCapturingGroup()) {