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 *