1 8 9 package net.sourceforge.chaperon.process; 10 11 import net.sourceforge.chaperon.common.IntegerList; 12 13 19 public class PatternProcessor 20 { 21 private PatternAutomaton automaton; 22 private IntegerList states = new IntegerList(); 23 private IntegerList statekeys = new IntegerList(); 24 private IntegerList newstates = new IntegerList(); 25 private IntegerList newstatekeys = new IntegerList(); 26 27 private IntegerList historystates = new IntegerList(); 29 private IntegerList dependencies = new IntegerList(); 30 31 private String [] groups = new String [10]; 33 private int[] groupstarts = new int[10]; 34 private int[] groupends = new int[10]; 35 private int groupcount = 0; 36 37 40 public PatternProcessor() {} 41 42 47 public PatternProcessor(PatternAutomaton automaton) 48 { 49 setPatternAutomaton(automaton); 50 } 51 52 57 public void setPatternAutomaton(PatternAutomaton automaton) 58 { 59 if (automaton==null) 60 throw new NullPointerException (); 61 62 this.automaton = automaton; 63 if (groupstarts.length<=(automaton.getGroupCount())) 64 { 65 groups = new String [automaton.getGroupCount()+1]; 66 groupstarts = new int[automaton.getGroupCount()+1]; 67 groupends = new int[automaton.getGroupCount()+1]; 68 } 69 } 70 71 78 public boolean search(char[] text) 79 { 80 return search(text, 0); 81 } 82 83 91 public boolean search(char[] text, int start) 92 { 93 for (int position = start; position<=text.length; position++) 94 if (match(text, position)) 95 return true; 96 97 return false; 98 } 99 100 private boolean verbose = false; 101 102 public void setVerbose(boolean verbose) 103 { 104 this.verbose = verbose; 105 } 106 107 114 public boolean match(char[] text) 115 { 116 return match(text, 0); 117 } 118 119 127 public boolean match(char[] text, int start) 128 { 129 if (automaton==null) 130 throw new NullPointerException ("PatternAutomaton is null"); 131 132 if (automaton.getStateCount()<=0) 133 return false; 134 135 for (int i = 0; i<=automaton.getGroupCount(); i++) 136 { 137 groupstarts[i] = start; 138 groupends[i] = start; 139 groups[i] = null; 140 } 141 142 int position = start; 143 int state; 144 int key; 145 boolean found = false; 146 int foundkey = 0; 147 int foundPosition = start; 148 149 states.clear(); 150 states.push(automaton.getFirstState()); 151 152 newstates.clear(); 153 154 statekeys.clear(); 155 statekeys.push(0); 156 157 historystates.clear(); 158 historystates.push(automaton.getFirstState()); 159 160 dependencies.clear(); 161 dependencies.push(0); 162 163 while ((!states.isEmpty()) && (position<=text.length)) 164 { 165 state = states.pop(); 166 key = statekeys.pop(); 167 168 if (automaton.isFinalState(state)) 169 { 170 found = true; 171 foundkey = key; 172 foundPosition = position; 173 } 174 else 175 { 176 switch (automaton.getType(state)) 177 { 178 case PatternAutomaton.TYPE_NOMATCH: 179 pushState(states, statekeys, state, key); 180 break; 181 case PatternAutomaton.TYPE_MATCH: 182 if ((position<text.length) && (automaton.getIntervalBegin(state)<=text[position]) && 183 (automaton.getIntervalEnd(state)>=text[position])) 184 pushState(newstates, newstatekeys, state, key); 185 186 break; 187 case PatternAutomaton.TYPE_EXMATCH: 188 if ((position<text.length) && 189 ((automaton.getIntervalBegin(state)>text[position]) || 190 (automaton.getIntervalEnd(state)<text[position]))) 191 pushState(states, statekeys, state, key); 192 193 break; 194 case PatternAutomaton.TYPE_MATCHANY: 195 pushState(newstates, newstatekeys, state, key); 196 break; 197 case PatternAutomaton.TYPE_BOL: 198 if (position==0) 199 pushState(states, statekeys, state, key); 200 else if ((position==1) && 201 (((text[position-1]=='\n') && (text[position]!='\r')) || 202 (text[position-1]=='\r'))) 203 pushState(states, statekeys, state, key); 204 else if ((text[position-1]=='\r') || 205 ((text[position-1]=='\n') && (text[position]!='\r'))) 206 pushState(states, statekeys, state, key); 207 208 break; 209 case PatternAutomaton.TYPE_EOL: 210 if (position>=text.length) 211 pushState(states, statekeys, state, key); 212 else if (((position+1)==text.length) && 213 ((text[position]=='\r') || (text[position]=='\n'))) 214 pushState(states, statekeys, state, key); 215 else if ((text[position]=='\r') || (text[position]=='\n')) 216 pushState(states, statekeys, state, key); 217 218 break; 219 case PatternAutomaton.TYPE_GROUPSTART: 220 pushState(states, statekeys, state, key); 221 break; 222 case PatternAutomaton.TYPE_GROUPEND: 223 pushState(states, statekeys, state, key); 224 break; 225 } 226 } 227 228 if (states.isEmpty()) 229 { 230 IntegerList temp = newstates; 231 newstates = states; 232 states = temp; 233 234 temp = newstatekeys; 235 newstatekeys = statekeys; 236 statekeys = temp; 237 238 position++; } 240 } 241 242 position = foundPosition; 243 key = foundkey; 244 while (key!=0) 245 { 246 key = dependencies.get(key); 247 state = historystates.get(key); 248 249 switch (automaton.getType(state)) 250 { 251 case PatternAutomaton.TYPE_NOMATCH: 252 break; 253 case PatternAutomaton.TYPE_MATCH: 254 position--; 255 break; 256 case PatternAutomaton.TYPE_EXMATCH: 257 break; 258 case PatternAutomaton.TYPE_MATCHANY: 259 position--; 260 break; 261 case PatternAutomaton.TYPE_BOL: 262 break; 263 case PatternAutomaton.TYPE_EOL: 264 break; 265 case PatternAutomaton.TYPE_GROUPSTART: 266 if (groups[automaton.getGroupIndex(state)]==null) 267 { 268 groupstarts[automaton.getGroupIndex(state)] = position; 269 groups[automaton.getGroupIndex(state)] = 270 new String (text, position, groupends[automaton.getGroupIndex(state)]-position); 271 } 272 273 break; 274 case PatternAutomaton.TYPE_GROUPEND: 275 if (groups[automaton.getGroupIndex(state)]==null) 276 groupends[automaton.getGroupIndex(state)] = position; 277 278 break; 279 } 280 } 281 282 groupcount = automaton.getGroupCount(); 283 for (int i = groupcount-1; (i>=0) && (groups[i]==null); i--) 284 groupcount--; 285 286 return found; 287 } 288 289 297 private void pushState(IntegerList states, IntegerList keys, int state, int key) 298 { 299 states.push(automaton.getTransitions(state)); 300 historystates.push(automaton.getTransitions(state)); 301 for (int i = automaton.getTransitions(state).length; i>0; i--) 302 { 303 keys.push(dependencies.getCount()); 304 dependencies.push(key); 305 } 306 } 307 308 313 public String getGroup() 314 { 315 return groups[0]; 316 } 317 318 325 public String getGroup(int group) 326 { 327 return groups[group]; 328 } 329 330 335 public int getGroupCount() 336 { 337 return groupcount; 338 } 339 340 345 public int getGroupStart() 346 { 347 return groupstarts[0]; 348 } 349 350 357 public int getGroupStart(int group) 358 { 359 return groupstarts[group]; 360 } 361 362 367 public int getGroupEnd() 368 { 369 return groupends[0]; 370 } 371 372 379 public int getGroupEnd(int group) 380 { 381 return groupends[group]; 382 } 383 } 384 | Popular Tags |