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# An ATN transition between any two ATN states. Subclasses define 8# atom, set, epsilon, action, predicate, rule transitions. 9# 10# <p>This is a one way link. It emanates from a state (usually via a list of 11# transitions) and has a target state.</p> 12# 13# <p>Since we never have to change the ATN transitions once we construct it, 14# we can fix these transitions as specific classes. The DFA transitions 15# on the other hand need to update the labels as it adds transitions to 16# the states. We'll use the term Edge for the DFA to distinguish them from 17# ATN transitions.</p> 18# 19from antlr4.IntervalSet import IntervalSet 20from antlr4.Token import Token 21 22# need forward declarations 23from antlr4.atn.SemanticContext import Predicate, PrecedencePredicate 24 25ATNState = None 26RuleStartState = None 27 28class Transition (object): 29 # constants for serialization 30 EPSILON = 1 31 RANGE = 2 32 RULE = 3 33 PREDICATE = 4 # e.g., {isType(input.LT(1))}? 34 ATOM = 5 35 ACTION = 6 36 SET = 7 # ~(A|B) or ~atom, wildcard, which convert to next 2 37 NOT_SET = 8 38 WILDCARD = 9 39 PRECEDENCE = 10 40 41 serializationNames = [ 42 "INVALID", 43 "EPSILON", 44 "RANGE", 45 "RULE", 46 "PREDICATE", 47 "ATOM", 48 "ACTION", 49 "SET", 50 "NOT_SET", 51 "WILDCARD", 52 "PRECEDENCE" 53 ] 54 55 serializationTypes = dict() 56 57 def __init__(self, target:ATNState): 58 # The target of this transition. 59 if target is None: 60 raise Exception("target cannot be null.") 61 self.target = target 62 # Are we epsilon, action, sempred? 63 self.isEpsilon = False 64 self.label = None 65 66 67# TODO: make all transitions sets? no, should remove set edges 68class AtomTransition(Transition): 69 70 def __init__(self, target:ATNState, label:int): 71 super().__init__(target) 72 self.label_ = label # The token type or character value; or, signifies special label. 73 self.label = self.makeLabel() 74 self.serializationType = self.ATOM 75 76 def makeLabel(self): 77 s = IntervalSet() 78 s.addOne(self.label_) 79 return s 80 81 def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int): 82 return self.label_ == symbol 83 84 def __str__(self): 85 return str(self.label_) 86 87class RuleTransition(Transition): 88 89 def __init__(self, ruleStart:RuleStartState, ruleIndex:int, precedence:int, followState:ATNState): 90 super().__init__(ruleStart) 91 self.ruleIndex = ruleIndex # ptr to the rule definition object for this rule ref 92 self.precedence = precedence 93 self.followState = followState # what node to begin computations following ref to rule 94 self.serializationType = self.RULE 95 self.isEpsilon = True 96 97 def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int): 98 return False 99 100 101class EpsilonTransition(Transition): 102 103 def __init__(self, target, outermostPrecedenceReturn=-1): 104 super(EpsilonTransition, self).__init__(target) 105 self.serializationType = self.EPSILON 106 self.isEpsilon = True 107 self.outermostPrecedenceReturn = outermostPrecedenceReturn 108 109 def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int): 110 return False 111 112 def __str__(self): 113 return "epsilon" 114 115class RangeTransition(Transition): 116 117 def __init__(self, target:ATNState, start:int, stop:int): 118 super().__init__(target) 119 self.serializationType = self.RANGE 120 self.start = start 121 self.stop = stop 122 self.label = self.makeLabel() 123 124 def makeLabel(self): 125 s = IntervalSet() 126 s.addRange(range(self.start, self.stop + 1)) 127 return s 128 129 def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int): 130 return symbol >= self.start and symbol <= self.stop 131 132 def __str__(self): 133 return "'" + chr(self.start) + "'..'" + chr(self.stop) + "'" 134 135class AbstractPredicateTransition(Transition): 136 137 def __init__(self, target:ATNState): 138 super().__init__(target) 139 140 141class PredicateTransition(AbstractPredicateTransition): 142 143 def __init__(self, target:ATNState, ruleIndex:int, predIndex:int, isCtxDependent:bool): 144 super().__init__(target) 145 self.serializationType = self.PREDICATE 146 self.ruleIndex = ruleIndex 147 self.predIndex = predIndex 148 self.isCtxDependent = isCtxDependent # e.g., $i ref in pred 149 self.isEpsilon = True 150 151 def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int): 152 return False 153 154 def getPredicate(self): 155 return Predicate(self.ruleIndex, self.predIndex, self.isCtxDependent) 156 157 def __str__(self): 158 return "pred_" + str(self.ruleIndex) + ":" + str(self.predIndex) 159 160class ActionTransition(Transition): 161 162 def __init__(self, target:ATNState, ruleIndex:int, actionIndex:int=-1, isCtxDependent:bool=False): 163 super().__init__(target) 164 self.serializationType = self.ACTION 165 self.ruleIndex = ruleIndex 166 self.actionIndex = actionIndex 167 self.isCtxDependent = isCtxDependent # e.g., $i ref in pred 168 self.isEpsilon = True 169 170 def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int): 171 return False 172 173 def __str__(self): 174 return "action_"+self.ruleIndex+":"+self.actionIndex 175 176# A transition containing a set of values. 177class SetTransition(Transition): 178 179 def __init__(self, target:ATNState, set:IntervalSet): 180 super().__init__(target) 181 self.serializationType = self.SET 182 if set is not None: 183 self.label = set 184 else: 185 self.label = IntervalSet() 186 self.label.addRange(range(Token.INVALID_TYPE, Token.INVALID_TYPE + 1)) 187 188 def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int): 189 return symbol in self.label 190 191 def __str__(self): 192 return str(self.label) 193 194class NotSetTransition(SetTransition): 195 196 def __init__(self, target:ATNState, set:IntervalSet): 197 super().__init__(target, set) 198 self.serializationType = self.NOT_SET 199 200 def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int): 201 return symbol >= minVocabSymbol \ 202 and symbol <= maxVocabSymbol \ 203 and not super(type(self), self).matches(symbol, minVocabSymbol, maxVocabSymbol) 204 205 def __str__(self): 206 return '~' + super(type(self), self).__str__() 207 208 209class WildcardTransition(Transition): 210 211 def __init__(self, target:ATNState): 212 super().__init__(target) 213 self.serializationType = self.WILDCARD 214 215 def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int): 216 return symbol >= minVocabSymbol and symbol <= maxVocabSymbol 217 218 def __str__(self): 219 return "." 220 221 222class PrecedencePredicateTransition(AbstractPredicateTransition): 223 224 def __init__(self, target:ATNState, precedence:int): 225 super().__init__(target) 226 self.serializationType = self.PRECEDENCE 227 self.precedence = precedence 228 self.isEpsilon = True 229 230 def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int): 231 return False 232 233 234 def getPredicate(self): 235 return PrecedencePredicate(self.precedence) 236 237 def __str__(self): 238 return self.precedence + " >= _p" 239 240 241Transition.serializationTypes = { 242 EpsilonTransition: Transition.EPSILON, 243 RangeTransition: Transition.RANGE, 244 RuleTransition: Transition.RULE, 245 PredicateTransition: Transition.PREDICATE, 246 AtomTransition: Transition.ATOM, 247 ActionTransition: Transition.ACTION, 248 SetTransition: Transition.SET, 249 NotSetTransition: Transition.NOT_SET, 250 WildcardTransition: Transition.WILDCARD, 251 PrecedencePredicateTransition: Transition.PRECEDENCE 252 } 253 254del ATNState 255del RuleStartState 256 257from antlr4.atn.ATNState import *