ATNState.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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. # The following images show the relation of states and
  7. # {@link ATNState#transitions} for various grammar constructs.
  8. #
  9. # <ul>
  10. #
  11. # <li>Solid edges marked with an &#0949; indicate a required
  12. # {@link EpsilonTransition}.</li>
  13. #
  14. # <li>Dashed edges indicate locations where any transition derived from
  15. # {@link Transition} might appear.</li>
  16. #
  17. # <li>Dashed nodes are place holders for either a sequence of linked
  18. # {@link BasicState} states or the inclusion of a block representing a nested
  19. # construct in one of the forms below.</li>
  20. #
  21. # <li>Nodes showing multiple outgoing alternatives with a {@code ...} support
  22. # any number of alternatives (one or more). Nodes without the {@code ...} only
  23. # support the exact number of alternatives shown in the diagram.</li>
  24. #
  25. # </ul>
  26. #
  27. # <h2>Basic Blocks</h2>
  28. #
  29. # <h3>Rule</h3>
  30. #
  31. # <embed src="images/Rule.svg" type="image/svg+xml"/>
  32. #
  33. # <h3>Block of 1 or more alternatives</h3>
  34. #
  35. # <embed src="images/Block.svg" type="image/svg+xml"/>
  36. #
  37. # <h2>Greedy Loops</h2>
  38. #
  39. # <h3>Greedy Closure: {@code (...)*}</h3>
  40. #
  41. # <embed src="images/ClosureGreedy.svg" type="image/svg+xml"/>
  42. #
  43. # <h3>Greedy Positive Closure: {@code (...)+}</h3>
  44. #
  45. # <embed src="images/PositiveClosureGreedy.svg" type="image/svg+xml"/>
  46. #
  47. # <h3>Greedy Optional: {@code (...)?}</h3>
  48. #
  49. # <embed src="images/OptionalGreedy.svg" type="image/svg+xml"/>
  50. #
  51. # <h2>Non-Greedy Loops</h2>
  52. #
  53. # <h3>Non-Greedy Closure: {@code (...)*?}</h3>
  54. #
  55. # <embed src="images/ClosureNonGreedy.svg" type="image/svg+xml"/>
  56. #
  57. # <h3>Non-Greedy Positive Closure: {@code (...)+?}</h3>
  58. #
  59. # <embed src="images/PositiveClosureNonGreedy.svg" type="image/svg+xml"/>
  60. #
  61. # <h3>Non-Greedy Optional: {@code (...)??}</h3>
  62. #
  63. # <embed src="images/OptionalNonGreedy.svg" type="image/svg+xml"/>
  64. #
  65. from antlr4.atn.Transition import Transition
  66. INITIAL_NUM_TRANSITIONS = 4
  67. class ATNState(object):
  68. __slots__ = (
  69. 'atn', 'stateNumber', 'stateType', 'ruleIndex', 'epsilonOnlyTransitions',
  70. 'transitions', 'nextTokenWithinRule',
  71. )
  72. # constants for serialization
  73. INVALID_TYPE = 0
  74. BASIC = 1
  75. RULE_START = 2
  76. BLOCK_START = 3
  77. PLUS_BLOCK_START = 4
  78. STAR_BLOCK_START = 5
  79. TOKEN_START = 6
  80. RULE_STOP = 7
  81. BLOCK_END = 8
  82. STAR_LOOP_BACK = 9
  83. STAR_LOOP_ENTRY = 10
  84. PLUS_LOOP_BACK = 11
  85. LOOP_END = 12
  86. serializationNames = [
  87. "INVALID",
  88. "BASIC",
  89. "RULE_START",
  90. "BLOCK_START",
  91. "PLUS_BLOCK_START",
  92. "STAR_BLOCK_START",
  93. "TOKEN_START",
  94. "RULE_STOP",
  95. "BLOCK_END",
  96. "STAR_LOOP_BACK",
  97. "STAR_LOOP_ENTRY",
  98. "PLUS_LOOP_BACK",
  99. "LOOP_END" ]
  100. INVALID_STATE_NUMBER = -1
  101. def __init__(self):
  102. # Which ATN are we in?
  103. self.atn = None
  104. self.stateNumber = ATNState.INVALID_STATE_NUMBER
  105. self.stateType = None
  106. self.ruleIndex = 0 # at runtime, we don't have Rule objects
  107. self.epsilonOnlyTransitions = False
  108. # Track the transitions emanating from this ATN state.
  109. self.transitions = []
  110. # Used to cache lookahead during parsing, not used during construction
  111. self.nextTokenWithinRule = None
  112. def __hash__(self):
  113. return self.stateNumber
  114. def __eq__(self, other):
  115. return isinstance(other, ATNState) and self.stateNumber==other.stateNumber
  116. def onlyHasEpsilonTransitions(self):
  117. return self.epsilonOnlyTransitions
  118. def isNonGreedyExitState(self):
  119. return False
  120. def __str__(self):
  121. return str(self.stateNumber)
  122. def addTransition(self, trans:Transition, index:int=-1):
  123. if len(self.transitions)==0:
  124. self.epsilonOnlyTransitions = trans.isEpsilon
  125. elif self.epsilonOnlyTransitions != trans.isEpsilon:
  126. self.epsilonOnlyTransitions = False
  127. # TODO System.err.format(Locale.getDefault(), "ATN state %d has both epsilon and non-epsilon transitions.\n", stateNumber);
  128. if index==-1:
  129. self.transitions.append(trans)
  130. else:
  131. self.transitions.insert(index, trans)
  132. class BasicState(ATNState):
  133. def __init__(self):
  134. super().__init__()
  135. self.stateType = self.BASIC
  136. class DecisionState(ATNState):
  137. __slots__ = ('decision', 'nonGreedy')
  138. def __init__(self):
  139. super().__init__()
  140. self.decision = -1
  141. self.nonGreedy = False
  142. # The start of a regular {@code (...)} block.
  143. class BlockStartState(DecisionState):
  144. __slots__ = 'endState'
  145. def __init__(self):
  146. super().__init__()
  147. self.endState = None
  148. class BasicBlockStartState(BlockStartState):
  149. def __init__(self):
  150. super().__init__()
  151. self.stateType = self.BLOCK_START
  152. # Terminal node of a simple {@code (a|b|c)} block.
  153. class BlockEndState(ATNState):
  154. __slots__ = 'startState'
  155. def __init__(self):
  156. super().__init__()
  157. self.stateType = self.BLOCK_END
  158. self.startState = None
  159. # The last node in the ATN for a rule, unless that rule is the start symbol.
  160. # In that case, there is one transition to EOF. Later, we might encode
  161. # references to all calls to this rule to compute FOLLOW sets for
  162. # error handling.
  163. #
  164. class RuleStopState(ATNState):
  165. def __init__(self):
  166. super().__init__()
  167. self.stateType = self.RULE_STOP
  168. class RuleStartState(ATNState):
  169. __slots__ = ('stopState', 'isPrecedenceRule')
  170. def __init__(self):
  171. super().__init__()
  172. self.stateType = self.RULE_START
  173. self.stopState = None
  174. self.isPrecedenceRule = False
  175. # Decision state for {@code A+} and {@code (A|B)+}. It has two transitions:
  176. # one to the loop back to start of the block and one to exit.
  177. #
  178. class PlusLoopbackState(DecisionState):
  179. def __init__(self):
  180. super().__init__()
  181. self.stateType = self.PLUS_LOOP_BACK
  182. # Start of {@code (A|B|...)+} loop. Technically a decision state, but
  183. # we don't use for code generation; somebody might need it, so I'm defining
  184. # it for completeness. In reality, the {@link PlusLoopbackState} node is the
  185. # real decision-making note for {@code A+}.
  186. #
  187. class PlusBlockStartState(BlockStartState):
  188. __slots__ = 'loopBackState'
  189. def __init__(self):
  190. super().__init__()
  191. self.stateType = self.PLUS_BLOCK_START
  192. self.loopBackState = None
  193. # The block that begins a closure loop.
  194. class StarBlockStartState(BlockStartState):
  195. def __init__(self):
  196. super().__init__()
  197. self.stateType = self.STAR_BLOCK_START
  198. class StarLoopbackState(ATNState):
  199. def __init__(self):
  200. super().__init__()
  201. self.stateType = self.STAR_LOOP_BACK
  202. class StarLoopEntryState(DecisionState):
  203. __slots__ = ('loopBackState', 'isPrecedenceDecision')
  204. def __init__(self):
  205. super().__init__()
  206. self.stateType = self.STAR_LOOP_ENTRY
  207. self.loopBackState = None
  208. # Indicates whether this state can benefit from a precedence DFA during SLL decision making.
  209. self.isPrecedenceDecision = None
  210. # Mark the end of a * or + loop.
  211. class LoopEndState(ATNState):
  212. __slots__ = 'loopBackState'
  213. def __init__(self):
  214. super().__init__()
  215. self.stateType = self.LOOP_END
  216. self.loopBackState = None
  217. # The Tokens rule start state linking to each lexer rule start state */
  218. class TokensStartState(DecisionState):
  219. def __init__(self):
  220. super().__init__()
  221. self.stateType = self.TOKEN_START