def readStates(self, atn:ATN): loopBackStateNumbers = [] endStateNumbers = [] nstates = self.readInt() for i in range(0, nstates): stype = self.readInt() # ignore bad type of states if stype==ATNState.INVALID_TYPE: atn.addState(None) continue ruleIndex = self.readInt() if ruleIndex == 0xFFFF: ruleIndex = -1 s = self.stateFactory(stype, ruleIndex) if stype == ATNState.LOOP_END: # special case loopBackStateNumber = self.readInt() loopBackStateNumbers.append((s, loopBackStateNumber)) elif isinstance(s, BlockStartState): endStateNumber = self.readInt() endStateNumbers.append((s, endStateNumber)) atn.addState(s) # delay the assignment of loop back and end states until we know all the state instances have been initialized for pair in loopBackStateNumbers: pair[0].loopBackState = atn.states[pair[1]] for pair in endStateNumbers: pair[0].endState = atn.states[pair[1]] numNonGreedyStates = self.readInt() for i in range(0, numNonGreedyStates): stateNumber = self.readInt() atn.states[stateNumber].nonGreedy = True numPrecedenceStates = self.readInt() for i in range(0, numPrecedenceStates): stateNumber = self.readInt() atn.states[stateNumber].isPrecedenceRule = True
def readStates(self, atn: ATN): loopBackStateNumbers = [] endStateNumbers = [] nstates = self.readInt() for i in range(0, nstates): stype = self.readInt() # ignore bad type of states if stype == ATNState.INVALID_TYPE: atn.addState(None) continue ruleIndex = self.readInt() if ruleIndex == 0xFFFF: ruleIndex = -1 s = self.stateFactory(stype, ruleIndex) if stype == ATNState.LOOP_END: # special case loopBackStateNumber = self.readInt() loopBackStateNumbers.append((s, loopBackStateNumber)) elif isinstance(s, BlockStartState): endStateNumber = self.readInt() endStateNumbers.append((s, endStateNumber)) atn.addState(s) # delay the assignment of loop back and end states until we know all the state instances have been initialized for pair in loopBackStateNumbers: pair[0].loopBackState = atn.states[pair[1]] for pair in endStateNumbers: pair[0].endState = atn.states[pair[1]] numNonGreedyStates = self.readInt() for i in range(0, numNonGreedyStates): stateNumber = self.readInt() atn.states[stateNumber].nonGreedy = True numPrecedenceStates = self.readInt() for i in range(0, numPrecedenceStates): stateNumber = self.readInt() atn.states[stateNumber].isPrecedenceRule = True
def generateRuleBypassTransition(self, atn: ATN, idx: int): bypassStart = BasicBlockStartState() bypassStart.ruleIndex = idx atn.addState(bypassStart) bypassStop = BlockEndState() bypassStop.ruleIndex = idx atn.addState(bypassStop) bypassStart.endState = bypassStop atn.defineDecisionState(bypassStart) bypassStop.startState = bypassStart excludeTransition = None if atn.ruleToStartState[idx].isPrecedenceRule: # wrap from the beginning of the rule to the StarLoopEntryState endState = None for state in atn.states: if self.stateIsEndStateFor(state, idx): endState = state excludeTransition = state.loopBackState.transitions[0] break if excludeTransition is None: raise Exception( "Couldn't identify final state of the precedence rule prefix section." ) else: endState = atn.ruleToStopState[idx] # all non-excluded transitions that currently target end state need to target blockEnd instead for state in atn.states: for transition in state.transitions: if transition == excludeTransition: continue if transition.target == endState: transition.target = bypassStop # all transitions leaving the rule start state need to leave blockStart instead ruleToStartState = atn.ruleToStartState[idx] count = len(ruleToStartState.transitions) while count > 0: bypassStart.addTransition(ruleToStartState.transitions[count - 1]) del ruleToStartState.transitions[-1] # link the new states atn.ruleToStartState[idx].addTransition(EpsilonTransition(bypassStart)) bypassStop.addTransition(EpsilonTransition(endState)) matchState = BasicState() atn.addState(matchState) matchState.addTransition( AtomTransition(bypassStop, atn.ruleToTokenType[idx])) bypassStart.addTransition(EpsilonTransition(matchState))
def generateRuleBypassTransition(self, atn:ATN, idx:int): bypassStart = BasicBlockStartState() bypassStart.ruleIndex = idx atn.addState(bypassStart) bypassStop = BlockEndState() bypassStop.ruleIndex = idx atn.addState(bypassStop) bypassStart.endState = bypassStop atn.defineDecisionState(bypassStart) bypassStop.startState = bypassStart excludeTransition = None if atn.ruleToStartState[idx].isPrecedenceRule: # wrap from the beginning of the rule to the StarLoopEntryState endState = None for state in atn.states: if self.stateIsEndStateFor(state, idx): endState = state excludeTransition = state.loopBackState.transitions[0] break if excludeTransition is None: raise Exception("Couldn't identify final state of the precedence rule prefix section.") else: endState = atn.ruleToStopState[idx] # all non-excluded transitions that currently target end state need to target blockEnd instead for state in atn.states: for transition in state.transitions: if transition == excludeTransition: continue if transition.target == endState: transition.target = bypassStop # all transitions leaving the rule start state need to leave blockStart instead ruleToStartState = atn.ruleToStartState[idx] count = len(ruleToStartState.transitions) while count > 0: bypassStart.addTransition(ruleToStartState.transitions[count-1]) del ruleToStartState.transitions[-1] # link the new states atn.ruleToStartState[idx].addTransition(EpsilonTransition(bypassStart)) bypassStop.addTransition(EpsilonTransition(endState)) matchState = BasicState() atn.addState(matchState) matchState.addTransition(AtomTransition(bypassStop, atn.ruleToTokenType[idx])) bypassStart.addTransition(EpsilonTransition(matchState))