1 // 2 // This software is now distributed according to 3 // the Lesser Gnu Public License. Please see 4 // http://www.gnu.org/copyleft/lesser.txt for 5 // the details. 6 // -- Happy Computing! 7 // 8 package com.stevesoft.pat; 9 10 import java.util.Hashtable; 11 12 /** 13 * If Multi were not split into a second stage, then a nested Multi would try to 14 * re-use the same count variable and the whole thing would break. 15 */ 16 class Multi_stage2 extends PatternSub 17 { 18 Pattern nextRet; 19 20 patInt count; 21 22 patInt matchMin, matchMax; 23 24 public boolean matchFewest = false; 25 toString()26 public String toString() 27 { 28 String ret = ""; 29 ret += sub.toString(); 30 ret += "{" + matchMin + "," + matchMax + "}"; 31 if (matchFewest) 32 { 33 ret += "?"; 34 } 35 ret += parent.nextString(); 36 return ret; 37 } 38 Multi_stage2(patInt a, patInt b, Pattern p)39 Multi_stage2(patInt a, patInt b, Pattern p) throws RegSyntax 40 { 41 if (p == null) 42 { 43 RegSyntaxError.endItAll("Multiple match of Null pattern requested."); 44 } 45 sub = p; 46 nextRet = this; 47 sub.setParent(this); 48 matchMin = a; 49 matchMax = b; 50 count = new patInt(0); 51 // we must have b > a > -1 for this 52 // to make sense. 53 if (!a.lessEq(b)) 54 { 55 // throw new BadMultiArgs(); 56 RegSyntaxError.endItAll("Bad Multi Args: " + a + ">" + b); 57 } 58 patInt i = new patInt(-1); 59 if (a.lessEq(i)) 60 { 61 // throw new BadMultiArgs(); 62 RegSyntaxError.endItAll("Bad Multi Args: " + a + "< 0"); 63 } 64 } 65 getNext()66 public Pattern getNext() 67 { 68 return nextRet; 69 } 70 71 int pos_old = -1; 72 matchInternal(int pos, Pthings pt)73 public int matchInternal(int pos, Pthings pt) 74 { 75 sub.setParent(this); 76 77 int canUse = -1; 78 79 // check for some forms of infinite recursion... 80 if (pos_old >= 0 && pos == pos_old) 81 { 82 return -1; 83 } 84 pos_old = pos; 85 86 if (matchMin.lessEq(count)) 87 { 88 canUse = pos; 89 } 90 if (!count.lessEq(matchMax) || pos > pt.src.length()) 91 { 92 return -1; 93 } 94 95 if ((matchFewest || count.equals(matchMax)) && canUse >= 0) 96 { 97 Pattern n = super.getNext(); 98 if (n == null) 99 { 100 return canUse; 101 } 102 int ret = testMatch(n, pos, pt); 103 if (ret >= 0) 104 { 105 return ret; 106 } 107 else 108 { 109 canUse = -1; 110 } 111 } 112 113 count.inc(); 114 try 115 { 116 if (count.lessEq(matchMax)) 117 { 118 int r = testMatch(sub, pos, pt); 119 if (r >= 0) 120 { 121 return r; 122 } 123 } 124 } finally 125 { 126 count.dec(); 127 } 128 129 if (!matchFewest && canUse >= 0) 130 { 131 Pattern n = super.getNext(); 132 if (n == null) 133 { 134 return canUse; 135 } 136 int ret = testMatch(n, pos, pt); 137 return ret; 138 } 139 else 140 { 141 return canUse; 142 } 143 } 144 clone1(Hashtable h)145 public Pattern clone1(Hashtable h) 146 { 147 try 148 { 149 Multi_stage2 m = new Multi_stage2(matchMin, matchMax, sub.clone(h)); 150 m.matchFewest = matchFewest; 151 return m; 152 } catch (RegSyntax rs) 153 { 154 return null; 155 } 156 } 157 }; 158