1 12 13 package org.eclipse.jface.text.rules; 14 15 import java.util.Arrays ; 16 import java.util.Comparator ; 17 18 import org.eclipse.core.runtime.Assert; 19 20 21 22 23 24 33 public class PatternRule implements IPredicateRule { 34 35 40 private static class DecreasingCharArrayLengthComparator implements Comparator { 41 public int compare(Object o1, Object o2) { 42 return ((char[]) o2).length - ((char[]) o1).length; 43 } 44 } 45 46 47 protected static final int UNDEFINED= -1; 48 49 50 protected IToken fToken; 51 52 protected char[] fStartSequence; 53 54 protected char[] fEndSequence; 55 56 protected int fColumn= UNDEFINED; 57 58 protected char fEscapeCharacter; 59 63 protected boolean fEscapeContinuesLine; 64 65 protected boolean fBreaksOnEOL; 66 67 protected boolean fBreaksOnEOF; 68 69 73 private Comparator fLineDelimiterComparator= new DecreasingCharArrayLengthComparator(); 74 78 private char[][] fLineDelimiters; 79 83 private char[][] fSortedLineDelimiters; 84 85 97 public PatternRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOL) { 98 Assert.isTrue(startSequence != null && startSequence.length() > 0); 99 Assert.isTrue(endSequence != null || breaksOnEOL); 100 Assert.isNotNull(token); 101 102 fStartSequence= startSequence.toCharArray(); 103 fEndSequence= (endSequence == null ? new char[0] : endSequence.toCharArray()); 104 fToken= token; 105 fEscapeCharacter= escapeCharacter; 106 fBreaksOnEOL= breaksOnEOL; 107 } 108 109 123 public PatternRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOL, boolean breaksOnEOF) { 124 this(startSequence, endSequence, token, escapeCharacter, breaksOnEOL); 125 fBreaksOnEOF= breaksOnEOF; 126 } 127 128 147 public PatternRule(String startSequence, String endSequence, IToken token, char escapeCharacter, boolean breaksOnEOL, boolean breaksOnEOF, boolean escapeContinuesLine) { 148 this(startSequence, endSequence, token, escapeCharacter, breaksOnEOL, breaksOnEOF); 149 fEscapeContinuesLine= escapeContinuesLine; 150 } 151 152 160 public void setColumnConstraint(int column) { 161 if (column < 0) 162 column= UNDEFINED; 163 fColumn= column; 164 } 165 166 167 173 protected IToken doEvaluate(ICharacterScanner scanner) { 174 return doEvaluate(scanner, false); 175 } 176 177 187 protected IToken doEvaluate(ICharacterScanner scanner, boolean resume) { 188 189 if (resume) { 190 191 if (endSequenceDetected(scanner)) 192 return fToken; 193 194 } else { 195 196 int c= scanner.read(); 197 if (c == fStartSequence[0]) { 198 if (sequenceDetected(scanner, fStartSequence, false)) { 199 if (endSequenceDetected(scanner)) 200 return fToken; 201 } 202 } 203 } 204 205 scanner.unread(); 206 return Token.UNDEFINED; 207 } 208 209 212 public IToken evaluate(ICharacterScanner scanner) { 213 return evaluate(scanner, false); 214 } 215 216 224 protected boolean endSequenceDetected(ICharacterScanner scanner) { 225 226 char[][] originalDelimiters= scanner.getLegalLineDelimiters(); 227 int count= originalDelimiters.length; 228 if (fLineDelimiters == null || originalDelimiters.length != count) { 229 fSortedLineDelimiters= new char[count][]; 230 } else { 231 while (count > 0 && fLineDelimiters[count-1] == originalDelimiters[count-1]) 232 count--; 233 } 234 if (count != 0) { 235 fLineDelimiters= originalDelimiters; 236 System.arraycopy(fLineDelimiters, 0, fSortedLineDelimiters, 0, fLineDelimiters.length); 237 Arrays.sort(fSortedLineDelimiters, fLineDelimiterComparator); 238 } 239 240 int readCount= 1; 241 int c; 242 while ((c= scanner.read()) != ICharacterScanner.EOF) { 243 if (c == fEscapeCharacter) { 244 if (fEscapeContinuesLine) { 246 c= scanner.read(); 247 for (int i= 0; i < fSortedLineDelimiters.length; i++) { 248 if (c == fSortedLineDelimiters[i][0] && sequenceDetected(scanner, fSortedLineDelimiters[i], true)) 249 break; 250 } 251 } else 252 scanner.read(); 253 254 } else if (fEndSequence.length > 0 && c == fEndSequence[0]) { 255 if (sequenceDetected(scanner, fEndSequence, true)) 257 return true; 258 } else if (fBreaksOnEOL) { 259 for (int i= 0; i < fSortedLineDelimiters.length; i++) { 261 if (c == fSortedLineDelimiters[i][0] && sequenceDetected(scanner, fSortedLineDelimiters[i], true)) 262 return true; 263 } 264 } 265 readCount++; 266 } 267 268 if (fBreaksOnEOF) 269 return true; 270 271 for (; readCount > 0; readCount--) 272 scanner.unread(); 273 274 return false; 275 } 276 277 288 protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) { 289 for (int i= 1; i < sequence.length; i++) { 290 int c= scanner.read(); 291 if (c == ICharacterScanner.EOF && eofAllowed) { 292 return true; 293 } else if (c != sequence[i]) { 294 scanner.unread(); 297 for (int j= i-1; j > 0; j--) 298 scanner.unread(); 299 return false; 300 } 301 } 302 303 return true; 304 } 305 306 310 public IToken evaluate(ICharacterScanner scanner, boolean resume) { 311 if (fColumn == UNDEFINED) 312 return doEvaluate(scanner, resume); 313 314 int c= scanner.read(); 315 scanner.unread(); 316 if (c == fStartSequence[0]) 317 return (fColumn == scanner.getColumn() ? doEvaluate(scanner, resume) : Token.UNDEFINED); 318 return Token.UNDEFINED; 319 } 320 321 325 public IToken getSuccessToken() { 326 return fToken; 327 } 328 } 329 | Popular Tags |