1<?php 2 3declare(strict_types=1); 4 5namespace Antlr\Antlr4\Runtime\Atn\States; 6 7use Antlr\Antlr4\Runtime\Atn\ATN; 8use Antlr\Antlr4\Runtime\Atn\Transitions\Transition; 9use Antlr\Antlr4\Runtime\Comparison\Hashable; 10use Antlr\Antlr4\Runtime\IntervalSet; 11 12abstract class ATNState implements Hashable 13{ 14 public const INVALID_TYPE = 0; 15 public const BASIC = 1; 16 public const RULE_START = 2; 17 public const BLOCK_START = 3; 18 public const PLUS_BLOCK_START = 4; 19 public const STAR_BLOCK_START = 5; 20 public const TOKEN_START = 6; 21 public const RULE_STOP = 7; 22 public const BLOCK_END = 8; 23 public const STAR_LOOP_BACK = 9; 24 public const STAR_LOOP_ENTRY = 10; 25 public const PLUS_LOOP_BACK = 11; 26 public const LOOP_END = 12; 27 28 public const SERIALIZATION_NAMES = [ 29 'INVALID', 30 'BASIC', 31 'RULE_START', 32 'BLOCK_START', 33 'PLUS_BLOCK_START', 34 'STAR_BLOCK_START', 35 'TOKEN_START', 36 'RULE_STOP', 37 'BLOCK_END', 38 'STAR_LOOP_BACK', 39 'STAR_LOOP_ENTRY', 40 'PLUS_LOOP_BACK', 41 'LOOP_END', 42 ]; 43 44 public const INVALID_STATE_NUMBER = -1; 45 46 /** 47 * Which ATN are we in? 48 * 49 * @var ATN|null 50 */ 51 public $atn; 52 53 /** @var int */ 54 public $stateNumber = self::INVALID_STATE_NUMBER; 55 56 /** 57 * Initially, at runtime, we don't have Rule objects. 58 * 59 * @var int 60 */ 61 public $ruleIndex = 0; 62 63 /** @var bool */ 64 public $epsilonOnlyTransitions = false; 65 66 /** 67 * Track the transitions emanating from this ATN state. 68 * 69 * @var array<Transition> 70 */ 71 protected $transitions = []; 72 73 /** 74 * Used to cache lookahead during parsing, not used during construction. 75 * 76 * @var IntervalSet|null 77 */ 78 public $nextTokenWithinRule; 79 80 public function equals(object $other) : bool 81 { 82 if ($this === $other) { 83 return true; 84 } 85 86 return $other instanceof static 87 && $this->stateNumber === $other->stateNumber; 88 } 89 90 public function isNonGreedyExitState() : bool 91 { 92 return false; 93 } 94 95 /** 96 * @return array<Transition> 97 */ 98 public function getTransitions() : array 99 { 100 return $this->transitions; 101 } 102 103 public function getNumberOfTransitions() : int 104 { 105 return \count($this->transitions); 106 } 107 108 public function addTransition(Transition $trans, int $index = -1) : void 109 { 110 if (\count($this->transitions) === 0) { 111 $this->epsilonOnlyTransitions = $trans->isEpsilon(); 112 } elseif ($this->epsilonOnlyTransitions !== $trans->isEpsilon()) { 113 $this->epsilonOnlyTransitions = false; 114 } 115 116 if ($index === -1) { 117 $this->transitions[] = $trans; 118 } else { 119 \array_splice($this->transitions, $index, 1, [$trans]); 120 } 121 } 122 123 public function getTransition(int $index) : Transition 124 { 125 return $this->transitions[$index]; 126 } 127 128 public function setTransition(Transition $trans, int $index) : void 129 { 130 $this->transitions[$index] = $trans; 131 } 132 133 /** 134 * @param array<Transition> $transitions 135 */ 136 public function setTransitions(array $transitions) : void 137 { 138 $this->transitions = $transitions; 139 } 140 141 public function removeTransition(int $index) : void 142 { 143 \array_splice($this->transitions, $index, 1); 144 } 145 146 public function onlyHasEpsilonTransitions() : bool 147 { 148 return $this->epsilonOnlyTransitions; 149 } 150 151 public function setRuleIndex(int $ruleIndex) : void 152 { 153 $this->ruleIndex = $ruleIndex; 154 } 155 156 public function __toString() : string 157 { 158 return (string) $this->stateNumber; 159 } 160 161 public function hashCode() : int 162 { 163 return $this->getStateType(); 164 } 165 166 abstract public function getStateType() : int; 167} 168