X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fcom%2Fstevesoft%2Fpat%2FFastMulti.java;h=ab6a58616c4eadc742292e6861c9ebbfab6c7f22;hb=57738a1f3c19b1c3a00bd3ac5108f8cd0af32f99;hp=2a3828132c68d75425b88b768948517e6cae9a23;hpb=c40cf903f740a72ab63dd1abc10fa33450ce660d;p=jalview.git diff --git a/src/com/stevesoft/pat/FastMulti.java b/src/com/stevesoft/pat/FastMulti.java index 2a38281..ab6a586 100755 --- a/src/com/stevesoft/pat/FastMulti.java +++ b/src/com/stevesoft/pat/FastMulti.java @@ -1,111 +1,170 @@ -// -// 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.Hashtable; - -/** A special case of Multi, implemented when minChars().equals(maxChars()), - * and some other conditions spelled out in RegOpt.safe4fm "Safe for - * FastMulti." It avoids stack growth problems as well as being slightly - * faster. - */ -class FastMulti extends PatternSub { - patInt fewestMatches,mostMatches; - public patInt minChars() { - return sub.countMinChars().mul(fewestMatches); - } - public patInt maxChars() { - return sub.countMaxChars().mul(mostMatches); - } - public boolean matchFewest = false; - - FastMulti(patInt a,patInt b,Pattern p) throws RegSyntax { - if(p == null) RegSyntaxError.endItAll("Null length pattern "+ - "followed by *, +, or other Multi."); - fewestMatches = a; - mostMatches = b; - sub = p; - step = p.countMinChars().intValue(); - sub.setParent(null); - } - public String toString() { - return sub.toString()+"{" - +fewestMatches+","+mostMatches+"}"+ - (matchFewest ? "?" : "")+"(?# <= fast multi)"+ - nextString(); - } - int step = -1; - public int matchInternal(int pos,Pthings pt) { - int m=-1; - int i=pos; - int endstr = pt.src.length()-step; - patInt matches = new patInt(0); - if(matchFewest) { - if(fewestMatches.lessEq(matches)) { - int ii = nextMatch(i,pt); - if(ii >= 0) return ii; - } - while(i >= 0 && i <= endstr) { - i=sub.matchInternal(i,pt); - if(i >= 0) { - matches.inc(); - if(fewestMatches.lessEq(matches)) { - int ii = nextMatch(i,pt); - if(ii >= 0) return ii; - } - if(matches.equals(mostMatches)) - return -1; - } - } - return -1; - } - int nMatches = 0; - while(fewestMatches.intValue() > nMatches) { - i=sub.matchInternal(i,pt); - if(i >= 0) - nMatches++; - else - return -1; - } - m=i; - if(mostMatches.finite()) { - while(nMatches < mostMatches.intValue()) { - i = sub.matchInternal(i,pt); - if(i>=0) { - m=i; - nMatches++; - } else break; - } - } else { - while(true) { - i = sub.matchInternal(i,pt); - if(i>=0) { - m=i; - nMatches++; - } else break; - } - } - while(m >= pos) { - int r=nextMatch(m,pt); - if(r >= 0) return r; - m -= step; - nMatches--; - if(nMatches < fewestMatches.intValue()) - return -1; - } - return -1; - } - public Pattern clone1(Hashtable h) { - try { - FastMulti fm = new FastMulti(fewestMatches,mostMatches,sub.clone(h)); - fm.matchFewest = matchFewest; - return fm; - } catch(RegSyntax rs) { - return null; - } - } -} +// +// 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.Hashtable; + +/** + * A special case of Multi, implemented when minChars().equals(maxChars()), and + * some other conditions spelled out in RegOpt.safe4fm "Safe for FastMulti." It + * avoids stack growth problems as well as being slightly faster. + */ +class FastMulti extends PatternSub +{ + patInt fewestMatches, mostMatches; + + public patInt minChars() + { + return sub.countMinChars().mul(fewestMatches); + } + + public patInt maxChars() + { + return sub.countMaxChars().mul(mostMatches); + } + + public boolean matchFewest = false; + + FastMulti(patInt a, patInt b, Pattern p) throws RegSyntax + { + if (p == null) + { + RegSyntaxError.endItAll( + "Null length pattern " + "followed by *, +, or other Multi."); + } + fewestMatches = a; + mostMatches = b; + sub = p; + step = p.countMinChars().intValue(); + sub.setParent(null); + } + + public String toString() + { + return sub.toString() + "{" + fewestMatches + "," + mostMatches + "}" + + (matchFewest ? "?" : "") + "(?# <= fast multi)" + + nextString(); + } + + int step = -1; + + public int matchInternal(int pos, Pthings pt) + { + int m = -1; + int i = pos; + int endstr = pt.src.length() - step; + patInt matches = new patInt(0); + if (matchFewest) + { + if (fewestMatches.lessEq(matches)) + { + int ii = nextMatch(i, pt); + if (ii >= 0) + { + return ii; + } + } + while (i >= 0 && i <= endstr) + { + i = sub.matchInternal(i, pt); + if (i >= 0) + { + matches.inc(); + if (fewestMatches.lessEq(matches)) + { + int ii = nextMatch(i, pt); + if (ii >= 0) + { + return ii; + } + } + if (matches.equals(mostMatches)) + { + return -1; + } + } + } + return -1; + } + int nMatches = 0; + while (fewestMatches.intValue() > nMatches) + { + i = sub.matchInternal(i, pt); + if (i >= 0) + { + nMatches++; + } + else + { + return -1; + } + } + m = i; + if (mostMatches.finite()) + { + while (nMatches < mostMatches.intValue()) + { + i = sub.matchInternal(i, pt); + if (i >= 0) + { + m = i; + nMatches++; + } + else + { + break; + } + } + } + else + { + while (true) + { + i = sub.matchInternal(i, pt); + if (i >= 0) + { + m = i; + nMatches++; + } + else + { + break; + } + } + } + while (m >= pos) + { + int r = nextMatch(m, pt); + if (r >= 0) + { + return r; + } + m -= step; + nMatches--; + if (nMatches < fewestMatches.intValue()) + { + return -1; + } + } + return -1; + } + + public Pattern clone1(Hashtable h) + { + try + { + FastMulti fm = new FastMulti(fewestMatches, mostMatches, + sub.clone(h)); + fm.matchFewest = matchFewest; + return fm; + } catch (RegSyntax rs) + { + return null; + } + } +}