2 // This software is now distributed according to
\r
3 // the Lesser Gnu Public License. Please see
\r
4 // http://www.gnu.org/copyleft/lesser.txt for
\r
6 // -- Happy Computing!
\r
8 package com.stevesoft.pat;
\r
9 import java.util.Hashtable;
\r
11 /** A special case of Multi, implemented when minChars().equals(maxChars()),
\r
12 * and some other conditions spelled out in RegOpt.safe4fm "Safe for
\r
13 * FastMulti." It avoids stack growth problems as well as being slightly
\r
16 class FastMulti extends PatternSub {
\r
17 patInt fewestMatches,mostMatches;
\r
18 public patInt minChars() {
\r
19 return sub.countMinChars().mul(fewestMatches);
\r
21 public patInt maxChars() {
\r
22 return sub.countMaxChars().mul(mostMatches);
\r
24 public boolean matchFewest = false;
\r
26 FastMulti(patInt a,patInt b,Pattern p) throws RegSyntax {
\r
27 if(p == null) RegSyntaxError.endItAll("Null length pattern "+
\r
28 "followed by *, +, or other Multi.");
\r
32 step = p.countMinChars().intValue();
\r
33 sub.setParent(null);
\r
35 public String toString() {
\r
36 return sub.toString()+"{"
\r
37 +fewestMatches+","+mostMatches+"}"+
\r
38 (matchFewest ? "?" : "")+"(?# <= fast multi)"+
\r
42 public int matchInternal(int pos,Pthings pt) {
\r
45 int endstr = pt.src.length()-step;
\r
46 patInt matches = new patInt(0);
\r
48 if(fewestMatches.lessEq(matches)) {
\r
49 int ii = nextMatch(i,pt);
\r
50 if(ii >= 0) return ii;
\r
52 while(i >= 0 && i <= endstr) {
\r
53 i=sub.matchInternal(i,pt);
\r
56 if(fewestMatches.lessEq(matches)) {
\r
57 int ii = nextMatch(i,pt);
\r
58 if(ii >= 0) return ii;
\r
60 if(matches.equals(mostMatches))
\r
67 while(fewestMatches.intValue() > nMatches) {
\r
68 i=sub.matchInternal(i,pt);
\r
75 if(mostMatches.finite()) {
\r
76 while(nMatches < mostMatches.intValue()) {
\r
77 i = sub.matchInternal(i,pt);
\r
85 i = sub.matchInternal(i,pt);
\r
93 int r=nextMatch(m,pt);
\r
94 if(r >= 0) return r;
\r
97 if(nMatches < fewestMatches.intValue())
\r
102 public Pattern clone1(Hashtable h) {
\r
104 FastMulti fm = new FastMulti(fewestMatches,mostMatches,sub.clone(h));
\r
105 fm.matchFewest = matchFewest;
\r
107 } catch(RegSyntax rs) {
\r