1<?php 2 3declare(strict_types=1); 4 5namespace Antlr\Antlr4\Runtime\PredictionContexts; 6 7use Antlr\Antlr4\Runtime\Comparison\Equality; 8use Antlr\Antlr4\Runtime\Comparison\Hasher; 9 10/** 11 * Used to cache {@see PredictionContext} objects. Its used for 12 * the shared context cash associated with contexts in DFA states. 13 * This cache can be used for both lexers and parsers. 14 */ 15class SingletonPredictionContext extends PredictionContext 16{ 17 /** @var PredictionContext|null */ 18 public $parent; 19 20 /** @var int */ 21 public $returnState; 22 23 public function __construct(int $returnState, ?PredictionContext $parent = null) 24 { 25 parent::__construct(); 26 27 $this->parent = $parent; 28 $this->returnState = $returnState; 29 } 30 31 public static function create(?PredictionContext $parent, int $returnState) : PredictionContext 32 { 33 // someone can pass in the bits of an array ctx that mean $ 34 if ($returnState === PredictionContext::EMPTY_RETURN_STATE && $parent === null) { 35 return PredictionContext::empty(); 36 } 37 38 return new SingletonPredictionContext($returnState, $parent); 39 } 40 41 public function getLength() : int 42 { 43 return 1; 44 } 45 46 public function getParent(int $index) : ?PredictionContext 47 { 48 if ($index !== 0) { 49 throw new \InvalidArgumentException('Singleton prediction context has only one parent.'); 50 } 51 52 return $this->parent; 53 } 54 55 public function getReturnState(int $index) : int 56 { 57 if ($index !== 0) { 58 throw new \InvalidArgumentException('Singleton prediction context has only one parent.'); 59 } 60 61 return $this->returnState; 62 } 63 64 public function equals(object $other) : bool 65 { 66 if ($this === $other) { 67 return true; 68 } 69 70 if (!$other instanceof static) { 71 return false; 72 } 73 74 if ($this->returnState !== $other->returnState) { 75 return false; 76 } 77 78 return Equality::equals($this->parent, $other->parent); 79 } 80 81 public function __toString() : string 82 { 83 $up = $this->parent === null ? '' : (string) $this->parent; 84 85 if ($up === '') { 86 if ($this->returnState === PredictionContext::EMPTY_RETURN_STATE) { 87 return '$'; 88 } 89 90 return '' . $this->returnState; 91 } 92 93 return '' . $this->returnState . ' ' . $up; 94 } 95 96 protected function computeHashCode() : int 97 { 98 if ($this->parent === null) { 99 return Hasher::hash(0); 100 } 101 102 return Hasher::hash($this->parent, $this->returnState); 103 } 104} 105