1 23 24 package org.gjt.sp.jedit.syntax; 25 26 import java.util.Arrays ; 27 import java.util.HashSet ; 28 import java.util.Set ; 29 import java.util.regex.Pattern ; 30 import java.util.regex.PatternSyntaxException ; 31 32 37 public class ParserRule 38 { 39 40 public static final int MAJOR_ACTIONS = 0x000000FF; 42 public static final int SEQ = 0; 43 public static final int SPAN = 1 << 1; 44 public static final int MARK_PREVIOUS = 1 << 2; 45 public static final int MARK_FOLLOWING = 1 << 3; 46 public static final int EOL_SPAN = 1 << 4; 47 49 public static final int ACTION_HINTS = 0x0000FF00; 51 public static final int EXCLUDE_MATCH = 1 << 8; 52 public static final int NO_LINE_BREAK = 1 << 9; 53 public static final int NO_WORD_BREAK = 1 << 10; 54 public static final int IS_ESCAPE = 1 << 11; 55 public static final int NO_ESCAPE = 1 << 12; 56 public static final int REGEXP = 1 << 13; 57 59 public static final int AT_LINE_START = 1 << 1; 61 public static final int AT_WHITESPACE_END = 1 << 2; 62 public static final int AT_WORD_START = 1 << 3; 63 65 public final String hashChar; 67 68 public final String upHashChar; 69 public final char[] hashChars; 70 71 public final char[] upHashChars; 72 public final int startPosMatch; 73 public final char[] start; 74 public final Pattern startRegexp; 75 76 public final int endPosMatch; 77 public final char[] end; 78 79 public final int action; 80 public final byte token; 81 82 public ParserRuleSet delegate; 83 84 87 public ParserRule next; 88 90 public static final ParserRule createSequenceRule( 92 int posMatch, String seq, ParserRuleSet delegate, byte id) 93 { 94 return new ParserRule(SEQ, seq.substring(0,1), 95 posMatch, seq.toCharArray(), null, 96 0, null, delegate, id); 97 } 99 103 public static final ParserRule createRegexpSequenceRule( 104 char hashChar, int posMatch, String seq, 105 ParserRuleSet delegate, byte id, boolean ignoreCase) 106 throws PatternSyntaxException 107 { 108 return createRegexpSequenceRule(String.valueOf(hashChar), posMatch, 109 seq, delegate, id, ignoreCase); 110 } 112 public static final ParserRule createRegexpSequenceRule( 114 String hashChar, int posMatch, String seq, 115 ParserRuleSet delegate, byte id, boolean ignoreCase) 116 throws PatternSyntaxException 117 { 118 return new ParserRule(SEQ | REGEXP, hashChar, posMatch, 119 null, Pattern.compile(seq,(ignoreCase ? Pattern.CASE_INSENSITIVE : 0)), 120 0, null, delegate, id); 121 } 123 public static final ParserRule createRegexpSequenceRule( 125 int posMatch, char[] hashChars, String seq, 126 ParserRuleSet delegate, byte id, boolean ignoreCase) 127 throws PatternSyntaxException 128 { 129 return new ParserRule(hashChars, SEQ | REGEXP, posMatch, 130 null, Pattern.compile(seq,(ignoreCase ? Pattern.CASE_INSENSITIVE : 0)), 131 0, null, delegate, id); 132 } 134 public static final ParserRule createSpanRule( 136 int startPosMatch, String start, int endPosMatch, String end, 137 ParserRuleSet delegate, byte id, boolean excludeMatch, 138 boolean noLineBreak, boolean noWordBreak, boolean noEscape) 139 { 140 int ruleAction = SPAN | 141 ((noLineBreak) ? NO_LINE_BREAK : 0) | 142 ((excludeMatch) ? EXCLUDE_MATCH : 0) | 143 ((noWordBreak) ? NO_WORD_BREAK : 0) | 144 ((noEscape) ? NO_ESCAPE : 0); 145 146 return new ParserRule(ruleAction, start.substring(0,1), startPosMatch, 147 start.toCharArray(), null, 148 endPosMatch, end.toCharArray(), 149 delegate, id); 150 } 152 156 public static final ParserRule createRegexpSpanRule( 157 char hashChar, int startPosMatch, String start, 158 int endPosMatch, String end, ParserRuleSet delegate, byte id, 159 boolean excludeMatch, boolean noLineBreak, boolean noWordBreak, 160 boolean ignoreCase, boolean noEscape) 161 throws PatternSyntaxException 162 { 163 return createRegexpSpanRule(String.valueOf(hashChar),startPosMatch, 164 start,endPosMatch,end,delegate,id,excludeMatch, 165 noLineBreak,noWordBreak,ignoreCase,noEscape); 166 } 168 public static final ParserRule createRegexpSpanRule( 170 String hashChar, int startPosMatch, String start, 171 int endPosMatch, String end, ParserRuleSet delegate, byte id, 172 boolean excludeMatch, boolean noLineBreak, boolean noWordBreak, 173 boolean ignoreCase, boolean noEscape) 174 throws PatternSyntaxException 175 { 176 int ruleAction = SPAN | REGEXP | 177 ((noLineBreak) ? NO_LINE_BREAK : 0) | 178 ((excludeMatch) ? EXCLUDE_MATCH : 0) | 179 ((noWordBreak) ? NO_WORD_BREAK : 0) | 180 ((noEscape) ? NO_ESCAPE : 0); 181 182 return new ParserRule(ruleAction, hashChar, startPosMatch, null, 183 Pattern.compile(start,(ignoreCase ? Pattern.CASE_INSENSITIVE : 0)), 184 endPosMatch, end.toCharArray(), delegate, id); 185 } 187 public static final ParserRule createRegexpSpanRule( 189 int startPosMatch, char[] hashChars, String start, 190 int endPosMatch, String end, ParserRuleSet delegate, byte id, 191 boolean excludeMatch, boolean noLineBreak, boolean noWordBreak, 192 boolean ignoreCase, boolean noEscape) 193 throws PatternSyntaxException 194 { 195 int ruleAction = SPAN | REGEXP | 196 ((noLineBreak) ? NO_LINE_BREAK : 0) | 197 ((excludeMatch) ? EXCLUDE_MATCH : 0) | 198 ((noWordBreak) ? NO_WORD_BREAK : 0) | 199 ((noEscape) ? NO_ESCAPE : 0); 200 201 return new ParserRule(hashChars, ruleAction, startPosMatch, null, 202 Pattern.compile(start,(ignoreCase ? Pattern.CASE_INSENSITIVE : 0)), 203 endPosMatch, end.toCharArray(), delegate, id); 204 } 206 public static final ParserRule createEOLSpanRule( 208 int posMatch, String seq, ParserRuleSet delegate, byte id, 209 boolean excludeMatch) 210 { 211 int ruleAction = EOL_SPAN | 212 ((excludeMatch) ? EXCLUDE_MATCH : 0) 213 | NO_LINE_BREAK; 214 215 return new ParserRule(ruleAction, seq.substring(0,1), posMatch, 216 seq.toCharArray(), null, 0, null, 217 delegate, id); 218 } 220 224 public static final ParserRule createRegexpEOLSpanRule( 225 char hashChar, int posMatch, String seq, ParserRuleSet delegate, 226 byte id, boolean excludeMatch, boolean ignoreCase) 227 throws PatternSyntaxException 228 { 229 return createRegexpEOLSpanRule(String.valueOf(hashChar), 230 posMatch,seq,delegate,id,excludeMatch,ignoreCase); 231 } 233 public static final ParserRule createRegexpEOLSpanRule( 235 String hashChar, int posMatch, String seq, ParserRuleSet delegate, 236 byte id, boolean excludeMatch, boolean ignoreCase) 237 throws PatternSyntaxException 238 { 239 int ruleAction = EOL_SPAN | REGEXP | 240 ((excludeMatch) ? EXCLUDE_MATCH : 0) 241 | NO_LINE_BREAK; 242 243 return new ParserRule(ruleAction, hashChar, posMatch, 244 null, Pattern.compile(seq,(ignoreCase ? Pattern.CASE_INSENSITIVE : 0)), 245 0, null, delegate, id); 246 } 248 public static final ParserRule createRegexpEOLSpanRule( 250 int posMatch, char[] hashChars, String seq, ParserRuleSet delegate, 251 byte id, boolean excludeMatch, boolean ignoreCase) 252 throws PatternSyntaxException 253 { 254 int ruleAction = EOL_SPAN | REGEXP | 255 ((excludeMatch) ? EXCLUDE_MATCH : 0) 256 | NO_LINE_BREAK; 257 258 return new ParserRule(hashChars, ruleAction, posMatch, 259 null, Pattern.compile(seq,(ignoreCase ? Pattern.CASE_INSENSITIVE : 0)), 260 0, null, delegate, id); 261 } 263 public static final ParserRule createMarkFollowingRule( 265 int posMatch, String seq, byte id, boolean excludeMatch) 266 { 267 int ruleAction = MARK_FOLLOWING | 268 ((excludeMatch) ? EXCLUDE_MATCH : 0); 269 270 return new ParserRule(ruleAction, seq.substring(0,1), posMatch, 271 seq.toCharArray(), null, 0, null, null, id); 272 } 274 public static final ParserRule createMarkPreviousRule( 276 int posMatch, String seq, byte id, boolean excludeMatch) 277 { 278 int ruleAction = MARK_PREVIOUS | 279 ((excludeMatch) ? EXCLUDE_MATCH : 0); 280 281 return new ParserRule(ruleAction, seq.substring(0,1), posMatch, 282 seq.toCharArray(), null, 0, null, null, id); 283 } 285 public static final ParserRule createEscapeRule(String seq) 287 { 288 int ruleAction = IS_ESCAPE; 289 290 return new ParserRule(ruleAction, seq.substring(0,1), 291 0, seq.toCharArray(), null, 0, null, 292 null, Token.NULL); 293 } 295 public String toString() 297 { 298 StringBuffer result = new StringBuffer (); 299 result.append(getClass().getName()).append("[action="); 300 switch (action & MAJOR_ACTIONS) 301 { 302 case SEQ: result.append("SEQ"); break; 303 case SPAN: result.append("SPAN"); break; 304 case MARK_PREVIOUS: result.append("MARK_PREVIOUS"); break; 305 case MARK_FOLLOWING: result.append("MARK_FOLLOWING"); break; 306 case EOL_SPAN: result.append("EOL_SPAN"); break; 307 default: result.append("UNKNOWN"); break; 308 } 309 int actionHints = action & ACTION_HINTS; 310 result.append("[EXCLUDE_MATCH=").append((actionHints & EXCLUDE_MATCH) != 0); 311 result.append(",NO_LINE_BREAK=").append((actionHints & NO_LINE_BREAK) != 0); 312 result.append(",NO_WORD_BREAK=").append((actionHints & NO_WORD_BREAK) != 0); 313 result.append(",IS_ESCAPE=").append((actionHints & IS_ESCAPE) != 0); 314 result.append(",NO_ESCAPE=").append((actionHints & NO_ESCAPE) != 0); 315 result.append(",REGEXP=").append((actionHints & REGEXP) != 0); 316 result.append("],hashChar=").append(hashChar); 317 result.append(",upHashChar=").append(upHashChar); 318 result.append(",hashChars=").append(Arrays.toString(hashChars)); 319 result.append(",upHashChars=").append(Arrays.toString(upHashChars)); 320 result.append(",startPosMatch="); 321 result.append("[AT_LINE_START=").append((startPosMatch & AT_LINE_START) != 0); 322 result.append(",AT_WHITESPACE_END=").append((startPosMatch & AT_WHITESPACE_END) != 0); 323 result.append(",AT_WORD_START=").append((startPosMatch & AT_WORD_START) != 0); 324 result.append("],start=").append(null==start?null:String.valueOf(start)); 325 result.append(",startRegexp=").append(startRegexp); 326 result.append(",endPosMatch="); 327 result.append("[AT_LINE_START=").append((endPosMatch & AT_LINE_START) != 0); 328 result.append(",AT_WHITESPACE_END=").append((endPosMatch & AT_WHITESPACE_END) != 0); 329 result.append(",AT_WORD_START=").append((endPosMatch & AT_WORD_START) != 0); 330 result.append("],end=").append(null==end?null:String.valueOf(end)); 331 result.append(",delegate=").append(delegate); 332 result.append(",token=").append(Token.tokenToString(token)).append(']'); 333 return result.toString(); 334 } 336 private ParserRule(int action, String hashChar, 338 int startPosMatch, char[] start, Pattern startRegexp, 339 int endPosMatch, char[] end, 340 ParserRuleSet delegate, byte token) 341 { 342 this.action = action; 343 this.hashChar = hashChar; 344 this.upHashChar = null == hashChar ? null : hashChar.toUpperCase(); 345 this.hashChars = null; 346 this.upHashChars = null; 347 this.startPosMatch = startPosMatch; 348 this.start = start; 349 this.startRegexp = startRegexp; 350 this.endPosMatch = endPosMatch; 351 this.end = end; 352 this.delegate = delegate; 353 this.token = token; 354 355 if(this.delegate == null) 356 { 357 if((action & MAJOR_ACTIONS) != SEQ) 358 { 359 this.delegate = ParserRuleSet.getStandardRuleSet(token); 360 } 361 } 362 } 363 364 private ParserRule(char[] hashChars, int action, 365 int startPosMatch, char[] start, Pattern startRegexp, 366 int endPosMatch, char[] end, 367 ParserRuleSet delegate, byte token) 368 { 369 this.action = action; 370 this.hashChar = null; 371 this.upHashChar = null; 372 Set <Character > hashCharsSet = new HashSet <Character >(); 373 for (char c : hashChars) 374 { 375 hashCharsSet.add(c); 376 } 377 this.hashChars = new char[hashCharsSet.size()]; 378 int i = 0; 379 for (Character c : hashCharsSet) 380 { 381 this.hashChars[i++] = c; 382 } 383 hashCharsSet = new HashSet <Character >(); 384 for (char c : hashChars) 385 { 386 hashCharsSet.add(Character.toUpperCase(c)); 387 } 388 this.upHashChars = new char[hashCharsSet.size()]; 389 i = 0; 390 for (Character c : hashCharsSet) 391 { 392 this.upHashChars[i++] = c; 393 } 394 this.startPosMatch = startPosMatch; 395 this.start = start; 396 this.startRegexp = startRegexp; 397 this.endPosMatch = endPosMatch; 398 this.end = end; 399 this.delegate = delegate; 400 this.token = token; 401 402 if(this.delegate == null) 403 { 404 if((action & MAJOR_ACTIONS) != SEQ) 405 { 406 this.delegate = ParserRuleSet.getStandardRuleSet(token); 407 } 408 } 409 } } 411 | Popular Tags |