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