// // This software is now distributed according to // the Lesser Gnu Public License. Please see // http://www.gnu.org/copyleft/lesser.txt for // the details. // -- Happy Computing! // package com.stevesoft.pat; import java.util.*; /** * If Multi were not split into a second stage, then a nested Multi would try to * re-use the same count variable and the whole thing would break. */ class Multi_stage2 extends PatternSub { Pattern nextRet; patInt count; patInt matchMin, matchMax; public boolean matchFewest = false; public String toString() { String ret = ""; ret += sub.toString(); ret += "{" + matchMin + "," + matchMax + "}"; if (matchFewest) { ret += "?"; } ret += parent.nextString(); return ret; } Multi_stage2(patInt a, patInt b, Pattern p) throws RegSyntax { if (p == null) { RegSyntaxError.endItAll("Multiple match of Null pattern requested."); } sub = p; nextRet = this; sub.setParent(this); matchMin = a; matchMax = b; count = new patInt(0); // we must have b > a > -1 for this // to make sense. if (!a.lessEq(b)) { // throw new BadMultiArgs(); RegSyntaxError.endItAll("Bad Multi Args: " + a + ">" + b); } patInt i = new patInt(-1); if (a.lessEq(i)) { // throw new BadMultiArgs(); RegSyntaxError.endItAll("Bad Multi Args: " + a + "< 0"); } } public Pattern getNext() { return nextRet; } int pos_old = -1; public int matchInternal(int pos, Pthings pt) { sub.setParent(this); int canUse = -1; // check for some forms of infinite recursion... if (pos_old >= 0 && pos == pos_old) { return -1; } pos_old = pos; if (matchMin.lessEq(count)) { canUse = pos; } if (!count.lessEq(matchMax) || pos > pt.src.length()) { return -1; } if ((matchFewest || count.equals(matchMax)) && canUse >= 0) { Pattern n = super.getNext(); if (n == null) { return canUse; } int ret = testMatch(n, pos, pt); if (ret >= 0) { return ret; } else { canUse = -1; } } count.inc(); try { if (count.lessEq(matchMax)) { int r = testMatch(sub, pos, pt); if (r >= 0) { return r; } } } finally { count.dec(); } if (!matchFewest && canUse >= 0) { Pattern n = super.getNext(); if (n == null) { return canUse; } int ret = testMatch(n, pos, pt); return ret; } else { return canUse; } } public Pattern clone1(Hashtable h) { try { Multi_stage2 m = new Multi_stage2(matchMin, matchMax, sub.clone(h)); m.matchFewest = matchFewest; return m; } catch (RegSyntax rs) { return null; } } };