1 /* 2 * Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. 3 * Use of this file is governed by the BSD 3-clause license that 4 * can be found in the LICENSE.txt file in the project root. 5 */ 6 7 package org.antlr.v4.runtime.atn; 8 9 import org.antlr.v4.runtime.Token; 10 import org.antlr.v4.runtime.misc.IntervalSet; 11 import org.antlr.v4.runtime.misc.Pair; 12 13 import java.io.InvalidClassException; 14 import java.util.ArrayList; 15 import java.util.List; 16 import java.util.Locale; 17 import java.util.UUID; 18 19 /** 20 * 21 * @author Sam Harwell 22 */ 23 public class ATNDeserializer { 24 public static final int SERIALIZED_VERSION; 25 static { 26 /* This value should never change. Updates following this version are 27 * reflected as change in the unique ID SERIALIZED_UUID. 28 */ 29 SERIALIZED_VERSION = 3; 30 } 31 32 /** 33 * This is the earliest supported serialized UUID. 34 */ 35 private static final UUID BASE_SERIALIZED_UUID; 36 /** 37 * This UUID indicates an extension of {@link BASE_SERIALIZED_UUID} for the 38 * addition of precedence predicates. 39 */ 40 private static final UUID ADDED_PRECEDENCE_TRANSITIONS; 41 /** 42 * This UUID indicates an extension of {@link #ADDED_PRECEDENCE_TRANSITIONS} 43 * for the addition of lexer actions encoded as a sequence of 44 * {@link LexerAction} instances. 45 */ 46 private static final UUID ADDED_LEXER_ACTIONS; 47 /** 48 * This UUID indicates the serialized ATN contains two sets of 49 * IntervalSets, where the second set's values are encoded as 50 * 32-bit integers to support the full Unicode SMP range up to U+10FFFF. 51 */ 52 private static final UUID ADDED_UNICODE_SMP; 53 /** 54 * This list contains all of the currently supported UUIDs, ordered by when 55 * the feature first appeared in this branch. 56 */ 57 private static final List<UUID> SUPPORTED_UUIDS; 58 59 /** 60 * This is the current serialized UUID. 61 */ 62 public static final UUID SERIALIZED_UUID; 63 static { 64 /* WARNING: DO NOT MERGE THESE LINES. If UUIDs differ during a merge, 65 * resolve the conflict by generating a new ID! 66 */ 67 BASE_SERIALIZED_UUID = UUID.fromString("33761B2D-78BB-4A43-8B0B-4F5BEE8AACF3"); 68 ADDED_PRECEDENCE_TRANSITIONS = UUID.fromString("1DA0C57D-6C06-438A-9B27-10BCB3CE0F61"); 69 ADDED_LEXER_ACTIONS = UUID.fromString("AADB8D7E-AEEF-4415-AD2B-8204D6CF042E"); 70 ADDED_UNICODE_SMP = UUID.fromString("59627784-3BE5-417A-B9EB-8131A7286089"); 71 72 SUPPORTED_UUIDS = new ArrayList<UUID>(); 73 SUPPORTED_UUIDS.add(BASE_SERIALIZED_UUID); 74 SUPPORTED_UUIDS.add(ADDED_PRECEDENCE_TRANSITIONS); 75 SUPPORTED_UUIDS.add(ADDED_LEXER_ACTIONS); 76 SUPPORTED_UUIDS.add(ADDED_UNICODE_SMP); 77 78 SERIALIZED_UUID = ADDED_UNICODE_SMP; 79 } 80 81 interface UnicodeDeserializer { 82 // Wrapper for readInt() or readInt32() readUnicode(char[] data, int p)83 int readUnicode(char[] data, int p); 84 85 // Work around Java not allowing mutation of captured variables 86 // by returning amount by which to increment p after each read size()87 int size(); 88 } 89 90 enum UnicodeDeserializingMode { 91 UNICODE_BMP, 92 UNICODE_SMP 93 } 94 getUnicodeDeserializer(UnicodeDeserializingMode mode)95 static UnicodeDeserializer getUnicodeDeserializer(UnicodeDeserializingMode mode) { 96 if (mode == UnicodeDeserializingMode.UNICODE_BMP) { 97 return new UnicodeDeserializer() { 98 @Override 99 public int readUnicode(char[] data, int p) { 100 return toInt(data[p]); 101 } 102 103 @Override 104 public int size() { 105 return 1; 106 } 107 }; 108 } 109 else { 110 return new UnicodeDeserializer() { 111 @Override 112 public int readUnicode(char[] data, int p) { 113 return toInt32(data, p); 114 } 115 116 @Override 117 public int size() { 118 return 2; 119 } 120 }; 121 } 122 } 123 124 private final ATNDeserializationOptions deserializationOptions; 125 126 public ATNDeserializer() { 127 this(ATNDeserializationOptions.getDefaultOptions()); 128 } 129 130 public ATNDeserializer(ATNDeserializationOptions deserializationOptions) { 131 if (deserializationOptions == null) { 132 deserializationOptions = ATNDeserializationOptions.getDefaultOptions(); 133 } 134 135 this.deserializationOptions = deserializationOptions; 136 } 137 138 /** 139 * Determines if a particular serialized representation of an ATN supports 140 * a particular feature, identified by the {@link UUID} used for serializing 141 * the ATN at the time the feature was first introduced. 142 * 143 * @param feature The {@link UUID} marking the first time the feature was 144 * supported in the serialized ATN. 145 * @param actualUuid The {@link UUID} of the actual serialized ATN which is 146 * currently being deserialized. 147 * @return {@code true} if the {@code actualUuid} value represents a 148 * serialized ATN at or after the feature identified by {@code feature} was 149 * introduced; otherwise, {@code false}. 150 */ 151 static protected boolean isFeatureSupported(UUID feature, UUID actualUuid) { 152 int featureIndex = SUPPORTED_UUIDS.indexOf(feature); 153 if (featureIndex < 0) { 154 return false; 155 } 156 157 return SUPPORTED_UUIDS.indexOf(actualUuid) >= featureIndex; 158 } 159 160 @SuppressWarnings("deprecation") 161 public ATN deserialize(char[] data) { 162 data = data.clone(); 163 164 // Each char value in data is shifted by +2 at the entry to this method. 165 // This is an encoding optimization targeting the serialized values 0 166 // and -1 (serialized to 0xFFFF), each of which are very common in the 167 // serialized form of the ATN. In the modified UTF-8 that Java uses for 168 // compiled string literals, these two character values have multi-byte 169 // forms. By shifting each value by +2, they become characters 2 and 1 170 // prior to writing the string, each of which have single-byte 171 // representations. Since the shift occurs in the tool during ATN 172 // serialization, each target is responsible for adjusting the values 173 // during deserialization. 174 // 175 // As a special case, note that the first element of data is not 176 // adjusted because it contains the major version number of the 177 // serialized ATN, which was fixed at 3 at the time the value shifting 178 // was implemented. 179 for (int i = 1; i < data.length; i++) { 180 data[i] = (char)(data[i] - 2); 181 } 182 183 int p = 0; 184 int version = toInt(data[p++]); 185 if (version != SERIALIZED_VERSION) { 186 String reason = String.format(Locale.getDefault(), "Could not deserialize ATN with version %d (expected %d).", version, SERIALIZED_VERSION); 187 throw new UnsupportedOperationException(new InvalidClassException(ATN.class.getName(), reason)); 188 } 189 190 UUID uuid = toUUID(data, p); 191 p += 8; 192 if (!SUPPORTED_UUIDS.contains(uuid)) { 193 String reason = String.format(Locale.getDefault(), "Could not deserialize ATN with UUID %s (expected %s or a legacy UUID).", uuid, SERIALIZED_UUID); 194 throw new UnsupportedOperationException(new InvalidClassException(ATN.class.getName(), reason)); 195 } 196 197 boolean supportsPrecedencePredicates = isFeatureSupported(ADDED_PRECEDENCE_TRANSITIONS, uuid); 198 boolean supportsLexerActions = isFeatureSupported(ADDED_LEXER_ACTIONS, uuid); 199 200 ATNType grammarType = ATNType.values()[toInt(data[p++])]; 201 int maxTokenType = toInt(data[p++]); 202 ATN atn = new ATN(grammarType, maxTokenType); 203 204 // 205 // STATES 206 // 207 List<Pair<LoopEndState, Integer>> loopBackStateNumbers = new ArrayList<Pair<LoopEndState, Integer>>(); 208 List<Pair<BlockStartState, Integer>> endStateNumbers = new ArrayList<Pair<BlockStartState, Integer>>(); 209 int nstates = toInt(data[p++]); 210 for (int i=0; i<nstates; i++) { 211 int stype = toInt(data[p++]); 212 // ignore bad type of states 213 if ( stype==ATNState.INVALID_TYPE ) { 214 atn.addState(null); 215 continue; 216 } 217 218 int ruleIndex = toInt(data[p++]); 219 if (ruleIndex == Character.MAX_VALUE) { 220 ruleIndex = -1; 221 } 222 223 ATNState s = stateFactory(stype, ruleIndex); 224 if ( stype == ATNState.LOOP_END ) { // special case 225 int loopBackStateNumber = toInt(data[p++]); 226 loopBackStateNumbers.add(new Pair<LoopEndState, Integer>((LoopEndState)s, loopBackStateNumber)); 227 } 228 else if (s instanceof BlockStartState) { 229 int endStateNumber = toInt(data[p++]); 230 endStateNumbers.add(new Pair<BlockStartState, Integer>((BlockStartState)s, endStateNumber)); 231 } 232 atn.addState(s); 233 } 234 235 // delay the assignment of loop back and end states until we know all the state instances have been initialized 236 for (Pair<LoopEndState, Integer> pair : loopBackStateNumbers) { 237 pair.a.loopBackState = atn.states.get(pair.b); 238 } 239 240 for (Pair<BlockStartState, Integer> pair : endStateNumbers) { 241 pair.a.endState = (BlockEndState)atn.states.get(pair.b); 242 } 243 244 int numNonGreedyStates = toInt(data[p++]); 245 for (int i = 0; i < numNonGreedyStates; i++) { 246 int stateNumber = toInt(data[p++]); 247 ((DecisionState)atn.states.get(stateNumber)).nonGreedy = true; 248 } 249 250 if (supportsPrecedencePredicates) { 251 int numPrecedenceStates = toInt(data[p++]); 252 for (int i = 0; i < numPrecedenceStates; i++) { 253 int stateNumber = toInt(data[p++]); 254 ((RuleStartState)atn.states.get(stateNumber)).isLeftRecursiveRule = true; 255 } 256 } 257 258 // 259 // RULES 260 // 261 int nrules = toInt(data[p++]); 262 if ( atn.grammarType == ATNType.LEXER ) { 263 atn.ruleToTokenType = new int[nrules]; 264 } 265 266 atn.ruleToStartState = new RuleStartState[nrules]; 267 for (int i=0; i<nrules; i++) { 268 int s = toInt(data[p++]); 269 RuleStartState startState = (RuleStartState)atn.states.get(s); 270 atn.ruleToStartState[i] = startState; 271 if ( atn.grammarType == ATNType.LEXER ) { 272 int tokenType = toInt(data[p++]); 273 if (tokenType == 0xFFFF) { 274 tokenType = Token.EOF; 275 } 276 277 atn.ruleToTokenType[i] = tokenType; 278 279 if (!isFeatureSupported(ADDED_LEXER_ACTIONS, uuid)) { 280 // this piece of unused metadata was serialized prior to the 281 // addition of LexerAction 282 int actionIndexIgnored = toInt(data[p++]); 283 } 284 } 285 } 286 287 atn.ruleToStopState = new RuleStopState[nrules]; 288 for (ATNState state : atn.states) { 289 if (!(state instanceof RuleStopState)) { 290 continue; 291 } 292 293 RuleStopState stopState = (RuleStopState)state; 294 atn.ruleToStopState[state.ruleIndex] = stopState; 295 atn.ruleToStartState[state.ruleIndex].stopState = stopState; 296 } 297 298 // 299 // MODES 300 // 301 int nmodes = toInt(data[p++]); 302 for (int i=0; i<nmodes; i++) { 303 int s = toInt(data[p++]); 304 atn.modeToStartState.add((TokensStartState)atn.states.get(s)); 305 } 306 307 // 308 // SETS 309 // 310 List<IntervalSet> sets = new ArrayList<IntervalSet>(); 311 312 // First, read all sets with 16-bit Unicode code points <= U+FFFF. 313 p = deserializeSets(data, p, sets, getUnicodeDeserializer(UnicodeDeserializingMode.UNICODE_BMP)); 314 315 // Next, if the ATN was serialized with the Unicode SMP feature, 316 // deserialize sets with 32-bit arguments <= U+10FFFF. 317 if (isFeatureSupported(ADDED_UNICODE_SMP, uuid)) { 318 p = deserializeSets(data, p, sets, getUnicodeDeserializer(UnicodeDeserializingMode.UNICODE_SMP)); 319 } 320 321 // 322 // EDGES 323 // 324 int nedges = toInt(data[p++]); 325 for (int i=0; i<nedges; i++) { 326 int src = toInt(data[p]); 327 int trg = toInt(data[p+1]); 328 int ttype = toInt(data[p+2]); 329 int arg1 = toInt(data[p+3]); 330 int arg2 = toInt(data[p+4]); 331 int arg3 = toInt(data[p+5]); 332 Transition trans = edgeFactory(atn, ttype, src, trg, arg1, arg2, arg3, sets); 333 // System.out.println("EDGE "+trans.getClass().getSimpleName()+" "+ 334 // src+"->"+trg+ 335 // " "+Transition.serializationNames[ttype]+ 336 // " "+arg1+","+arg2+","+arg3); 337 ATNState srcState = atn.states.get(src); 338 srcState.addTransition(trans); 339 p += 6; 340 } 341 342 // edges for rule stop states can be derived, so they aren't serialized 343 for (ATNState state : atn.states) { 344 for (int i = 0; i < state.getNumberOfTransitions(); i++) { 345 Transition t = state.transition(i); 346 if (!(t instanceof RuleTransition)) { 347 continue; 348 } 349 350 RuleTransition ruleTransition = (RuleTransition)t; 351 int outermostPrecedenceReturn = -1; 352 if (atn.ruleToStartState[ruleTransition.target.ruleIndex].isLeftRecursiveRule) { 353 if (ruleTransition.precedence == 0) { 354 outermostPrecedenceReturn = ruleTransition.target.ruleIndex; 355 } 356 } 357 358 EpsilonTransition returnTransition = new EpsilonTransition(ruleTransition.followState, outermostPrecedenceReturn); 359 atn.ruleToStopState[ruleTransition.target.ruleIndex].addTransition(returnTransition); 360 } 361 } 362 363 for (ATNState state : atn.states) { 364 if (state instanceof BlockStartState) { 365 // we need to know the end state to set its start state 366 if (((BlockStartState)state).endState == null) { 367 throw new IllegalStateException(); 368 } 369 370 // block end states can only be associated to a single block start state 371 if (((BlockStartState)state).endState.startState != null) { 372 throw new IllegalStateException(); 373 } 374 375 ((BlockStartState)state).endState.startState = (BlockStartState)state; 376 } 377 378 if (state instanceof PlusLoopbackState) { 379 PlusLoopbackState loopbackState = (PlusLoopbackState)state; 380 for (int i = 0; i < loopbackState.getNumberOfTransitions(); i++) { 381 ATNState target = loopbackState.transition(i).target; 382 if (target instanceof PlusBlockStartState) { 383 ((PlusBlockStartState)target).loopBackState = loopbackState; 384 } 385 } 386 } 387 else if (state instanceof StarLoopbackState) { 388 StarLoopbackState loopbackState = (StarLoopbackState)state; 389 for (int i = 0; i < loopbackState.getNumberOfTransitions(); i++) { 390 ATNState target = loopbackState.transition(i).target; 391 if (target instanceof StarLoopEntryState) { 392 ((StarLoopEntryState)target).loopBackState = loopbackState; 393 } 394 } 395 } 396 } 397 398 // 399 // DECISIONS 400 // 401 int ndecisions = toInt(data[p++]); 402 for (int i=1; i<=ndecisions; i++) { 403 int s = toInt(data[p++]); 404 DecisionState decState = (DecisionState)atn.states.get(s); 405 atn.decisionToState.add(decState); 406 decState.decision = i-1; 407 } 408 409 // 410 // LEXER ACTIONS 411 // 412 if (atn.grammarType == ATNType.LEXER) { 413 if (supportsLexerActions) { 414 atn.lexerActions = new LexerAction[toInt(data[p++])]; 415 for (int i = 0; i < atn.lexerActions.length; i++) { 416 LexerActionType actionType = LexerActionType.values()[toInt(data[p++])]; 417 int data1 = toInt(data[p++]); 418 if (data1 == 0xFFFF) { 419 data1 = -1; 420 } 421 422 int data2 = toInt(data[p++]); 423 if (data2 == 0xFFFF) { 424 data2 = -1; 425 } 426 427 LexerAction lexerAction = lexerActionFactory(actionType, data1, data2); 428 429 atn.lexerActions[i] = lexerAction; 430 } 431 } 432 else { 433 // for compatibility with older serialized ATNs, convert the old 434 // serialized action index for action transitions to the new 435 // form, which is the index of a LexerCustomAction 436 List<LexerAction> legacyLexerActions = new ArrayList<LexerAction>(); 437 for (ATNState state : atn.states) { 438 for (int i = 0; i < state.getNumberOfTransitions(); i++) { 439 Transition transition = state.transition(i); 440 if (!(transition instanceof ActionTransition)) { 441 continue; 442 } 443 444 int ruleIndex = ((ActionTransition)transition).ruleIndex; 445 int actionIndex = ((ActionTransition)transition).actionIndex; 446 LexerCustomAction lexerAction = new LexerCustomAction(ruleIndex, actionIndex); 447 state.setTransition(i, new ActionTransition(transition.target, ruleIndex, legacyLexerActions.size(), false)); 448 legacyLexerActions.add(lexerAction); 449 } 450 } 451 452 atn.lexerActions = legacyLexerActions.toArray(new LexerAction[legacyLexerActions.size()]); 453 } 454 } 455 456 markPrecedenceDecisions(atn); 457 458 if (deserializationOptions.isVerifyATN()) { 459 verifyATN(atn); 460 } 461 462 if (deserializationOptions.isGenerateRuleBypassTransitions() && atn.grammarType == ATNType.PARSER) { 463 atn.ruleToTokenType = new int[atn.ruleToStartState.length]; 464 for (int i = 0; i < atn.ruleToStartState.length; i++) { 465 atn.ruleToTokenType[i] = atn.maxTokenType + i + 1; 466 } 467 468 for (int i = 0; i < atn.ruleToStartState.length; i++) { 469 BasicBlockStartState bypassStart = new BasicBlockStartState(); 470 bypassStart.ruleIndex = i; 471 atn.addState(bypassStart); 472 473 BlockEndState bypassStop = new BlockEndState(); 474 bypassStop.ruleIndex = i; 475 atn.addState(bypassStop); 476 477 bypassStart.endState = bypassStop; 478 atn.defineDecisionState(bypassStart); 479 480 bypassStop.startState = bypassStart; 481 482 ATNState endState; 483 Transition excludeTransition = null; 484 if (atn.ruleToStartState[i].isLeftRecursiveRule) { 485 // wrap from the beginning of the rule to the StarLoopEntryState 486 endState = null; 487 for (ATNState state : atn.states) { 488 if (state.ruleIndex != i) { 489 continue; 490 } 491 492 if (!(state instanceof StarLoopEntryState)) { 493 continue; 494 } 495 496 ATNState maybeLoopEndState = state.transition(state.getNumberOfTransitions() - 1).target; 497 if (!(maybeLoopEndState instanceof LoopEndState)) { 498 continue; 499 } 500 501 if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.transition(0).target instanceof RuleStopState) { 502 endState = state; 503 break; 504 } 505 } 506 507 if (endState == null) { 508 throw new UnsupportedOperationException("Couldn't identify final state of the precedence rule prefix section."); 509 } 510 511 excludeTransition = ((StarLoopEntryState)endState).loopBackState.transition(0); 512 } 513 else { 514 endState = atn.ruleToStopState[i]; 515 } 516 517 // all non-excluded transitions that currently target end state need to target blockEnd instead 518 for (ATNState state : atn.states) { 519 for (Transition transition : state.transitions) { 520 if (transition == excludeTransition) { 521 continue; 522 } 523 524 if (transition.target == endState) { 525 transition.target = bypassStop; 526 } 527 } 528 } 529 530 // all transitions leaving the rule start state need to leave blockStart instead 531 while (atn.ruleToStartState[i].getNumberOfTransitions() > 0) { 532 Transition transition = atn.ruleToStartState[i].removeTransition(atn.ruleToStartState[i].getNumberOfTransitions() - 1); 533 bypassStart.addTransition(transition); 534 } 535 536 // link the new states 537 atn.ruleToStartState[i].addTransition(new EpsilonTransition(bypassStart)); 538 bypassStop.addTransition(new EpsilonTransition(endState)); 539 540 ATNState matchState = new BasicState(); 541 atn.addState(matchState); 542 matchState.addTransition(new AtomTransition(bypassStop, atn.ruleToTokenType[i])); 543 bypassStart.addTransition(new EpsilonTransition(matchState)); 544 } 545 546 if (deserializationOptions.isVerifyATN()) { 547 // reverify after modification 548 verifyATN(atn); 549 } 550 } 551 552 return atn; 553 } 554 555 private int deserializeSets(char[] data, int p, List<IntervalSet> sets, UnicodeDeserializer unicodeDeserializer) { 556 int nsets = toInt(data[p++]); 557 for (int i=0; i<nsets; i++) { 558 int nintervals = toInt(data[p]); 559 p++; 560 IntervalSet set = new IntervalSet(); 561 sets.add(set); 562 563 boolean containsEof = toInt(data[p++]) != 0; 564 if (containsEof) { 565 set.add(-1); 566 } 567 568 for (int j=0; j<nintervals; j++) { 569 int a = unicodeDeserializer.readUnicode(data, p); 570 p += unicodeDeserializer.size(); 571 int b = unicodeDeserializer.readUnicode(data, p); 572 p += unicodeDeserializer.size(); 573 set.add(a, b); 574 } 575 } 576 return p; 577 } 578 579 /** 580 * Analyze the {@link StarLoopEntryState} states in the specified ATN to set 581 * the {@link StarLoopEntryState#isPrecedenceDecision} field to the 582 * correct value. 583 * 584 * @param atn The ATN. 585 */ 586 protected void markPrecedenceDecisions(ATN atn) { 587 for (ATNState state : atn.states) { 588 if (!(state instanceof StarLoopEntryState)) { 589 continue; 590 } 591 592 /* We analyze the ATN to determine if this ATN decision state is the 593 * decision for the closure block that determines whether a 594 * precedence rule should continue or complete. 595 */ 596 if (atn.ruleToStartState[state.ruleIndex].isLeftRecursiveRule) { 597 ATNState maybeLoopEndState = state.transition(state.getNumberOfTransitions() - 1).target; 598 if (maybeLoopEndState instanceof LoopEndState) { 599 if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.transition(0).target instanceof RuleStopState) { 600 ((StarLoopEntryState)state).isPrecedenceDecision = true; 601 } 602 } 603 } 604 } 605 } 606 607 protected void verifyATN(ATN atn) { 608 // verify assumptions 609 for (ATNState state : atn.states) { 610 if (state == null) { 611 continue; 612 } 613 614 checkCondition(state.onlyHasEpsilonTransitions() || state.getNumberOfTransitions() <= 1); 615 616 if (state instanceof PlusBlockStartState) { 617 checkCondition(((PlusBlockStartState)state).loopBackState != null); 618 } 619 620 if (state instanceof StarLoopEntryState) { 621 StarLoopEntryState starLoopEntryState = (StarLoopEntryState)state; 622 checkCondition(starLoopEntryState.loopBackState != null); 623 checkCondition(starLoopEntryState.getNumberOfTransitions() == 2); 624 625 if (starLoopEntryState.transition(0).target instanceof StarBlockStartState) { 626 checkCondition(starLoopEntryState.transition(1).target instanceof LoopEndState); 627 checkCondition(!starLoopEntryState.nonGreedy); 628 } 629 else if (starLoopEntryState.transition(0).target instanceof LoopEndState) { 630 checkCondition(starLoopEntryState.transition(1).target instanceof StarBlockStartState); 631 checkCondition(starLoopEntryState.nonGreedy); 632 } 633 else { 634 throw new IllegalStateException(); 635 } 636 } 637 638 if (state instanceof StarLoopbackState) { 639 checkCondition(state.getNumberOfTransitions() == 1); 640 checkCondition(state.transition(0).target instanceof StarLoopEntryState); 641 } 642 643 if (state instanceof LoopEndState) { 644 checkCondition(((LoopEndState)state).loopBackState != null); 645 } 646 647 if (state instanceof RuleStartState) { 648 checkCondition(((RuleStartState)state).stopState != null); 649 } 650 651 if (state instanceof BlockStartState) { 652 checkCondition(((BlockStartState)state).endState != null); 653 } 654 655 if (state instanceof BlockEndState) { 656 checkCondition(((BlockEndState)state).startState != null); 657 } 658 659 if (state instanceof DecisionState) { 660 DecisionState decisionState = (DecisionState)state; 661 checkCondition(decisionState.getNumberOfTransitions() <= 1 || decisionState.decision >= 0); 662 } 663 else { 664 checkCondition(state.getNumberOfTransitions() <= 1 || state instanceof RuleStopState); 665 } 666 } 667 } 668 669 protected void checkCondition(boolean condition) { 670 checkCondition(condition, null); 671 } 672 673 protected void checkCondition(boolean condition, String message) { 674 if (!condition) { 675 throw new IllegalStateException(message); 676 } 677 } 678 679 protected static int toInt(char c) { 680 return c; 681 } 682 683 protected static int toInt32(char[] data, int offset) { 684 return (int)data[offset] | ((int)data[offset + 1] << 16); 685 } 686 687 protected static long toLong(char[] data, int offset) { 688 long lowOrder = toInt32(data, offset) & 0x00000000FFFFFFFFL; 689 return lowOrder | ((long)toInt32(data, offset + 2) << 32); 690 } 691 692 protected static UUID toUUID(char[] data, int offset) { 693 long leastSigBits = toLong(data, offset); 694 long mostSigBits = toLong(data, offset + 4); 695 return new UUID(mostSigBits, leastSigBits); 696 } 697 698 699 protected Transition edgeFactory(ATN atn, 700 int type, int src, int trg, 701 int arg1, int arg2, int arg3, 702 List<IntervalSet> sets) 703 { 704 ATNState target = atn.states.get(trg); 705 switch (type) { 706 case Transition.EPSILON : return new EpsilonTransition(target); 707 case Transition.RANGE : 708 if (arg3 != 0) { 709 return new RangeTransition(target, Token.EOF, arg2); 710 } 711 else { 712 return new RangeTransition(target, arg1, arg2); 713 } 714 case Transition.RULE : 715 RuleTransition rt = new RuleTransition((RuleStartState)atn.states.get(arg1), arg2, arg3, target); 716 return rt; 717 case Transition.PREDICATE : 718 PredicateTransition pt = new PredicateTransition(target, arg1, arg2, arg3 != 0); 719 return pt; 720 case Transition.PRECEDENCE: 721 return new PrecedencePredicateTransition(target, arg1); 722 case Transition.ATOM : 723 if (arg3 != 0) { 724 return new AtomTransition(target, Token.EOF); 725 } 726 else { 727 return new AtomTransition(target, arg1); 728 } 729 case Transition.ACTION : 730 ActionTransition a = new ActionTransition(target, arg1, arg2, arg3 != 0); 731 return a; 732 case Transition.SET : return new SetTransition(target, sets.get(arg1)); 733 case Transition.NOT_SET : return new NotSetTransition(target, sets.get(arg1)); 734 case Transition.WILDCARD : return new WildcardTransition(target); 735 } 736 737 throw new IllegalArgumentException("The specified transition type is not valid."); 738 } 739 740 protected ATNState stateFactory(int type, int ruleIndex) { 741 ATNState s; 742 switch (type) { 743 case ATNState.INVALID_TYPE: return null; 744 case ATNState.BASIC : s = new BasicState(); break; 745 case ATNState.RULE_START : s = new RuleStartState(); break; 746 case ATNState.BLOCK_START : s = new BasicBlockStartState(); break; 747 case ATNState.PLUS_BLOCK_START : s = new PlusBlockStartState(); break; 748 case ATNState.STAR_BLOCK_START : s = new StarBlockStartState(); break; 749 case ATNState.TOKEN_START : s = new TokensStartState(); break; 750 case ATNState.RULE_STOP : s = new RuleStopState(); break; 751 case ATNState.BLOCK_END : s = new BlockEndState(); break; 752 case ATNState.STAR_LOOP_BACK : s = new StarLoopbackState(); break; 753 case ATNState.STAR_LOOP_ENTRY : s = new StarLoopEntryState(); break; 754 case ATNState.PLUS_LOOP_BACK : s = new PlusLoopbackState(); break; 755 case ATNState.LOOP_END : s = new LoopEndState(); break; 756 default : 757 String message = String.format(Locale.getDefault(), "The specified state type %d is not valid.", type); 758 throw new IllegalArgumentException(message); 759 } 760 761 s.ruleIndex = ruleIndex; 762 return s; 763 } 764 765 protected LexerAction lexerActionFactory(LexerActionType type, int data1, int data2) { 766 switch (type) { 767 case CHANNEL: 768 return new LexerChannelAction(data1); 769 770 case CUSTOM: 771 return new LexerCustomAction(data1, data2); 772 773 case MODE: 774 return new LexerModeAction(data1); 775 776 case MORE: 777 return LexerMoreAction.INSTANCE; 778 779 case POP_MODE: 780 return LexerPopModeAction.INSTANCE; 781 782 case PUSH_MODE: 783 return new LexerPushModeAction(data1); 784 785 case SKIP: 786 return LexerSkipAction.INSTANCE; 787 788 case TYPE: 789 return new LexerTypeAction(data1); 790 791 default: 792 String message = String.format(Locale.getDefault(), "The specified lexer action type %d is not valid.", type); 793 throw new IllegalArgumentException(message); 794 } 795 } 796 } 797