1*37748cd8SNickeau<?php 2*37748cd8SNickeau 3*37748cd8SNickeaudeclare(strict_types=1); 4*37748cd8SNickeau 5*37748cd8SNickeaunamespace Antlr\Antlr4\Runtime; 6*37748cd8SNickeau 7*37748cd8SNickeauuse Antlr\Antlr4\Runtime\Atn\ATN; 8*37748cd8SNickeauuse Antlr\Antlr4\Runtime\Atn\ATNSimulator; 9*37748cd8SNickeauuse Antlr\Antlr4\Runtime\Error\Exceptions\RecognitionException; 10*37748cd8SNickeauuse Antlr\Antlr4\Runtime\Error\Listeners\ANTLRErrorListener; 11*37748cd8SNickeauuse Antlr\Antlr4\Runtime\Error\Listeners\ProxyErrorListener; 12*37748cd8SNickeau 13*37748cd8SNickeauabstract class Recognizer 14*37748cd8SNickeau{ 15*37748cd8SNickeau public const EOF = -1; 16*37748cd8SNickeau 17*37748cd8SNickeau /** @var array<string> */ 18*37748cd8SNickeau public $log = []; 19*37748cd8SNickeau 20*37748cd8SNickeau /** @var array<string, array<string, int>> */ 21*37748cd8SNickeau private static $tokenTypeMapCache = []; 22*37748cd8SNickeau 23*37748cd8SNickeau /** @var array<string, array<int, string>> */ 24*37748cd8SNickeau private static $ruleIndexMapCache = []; 25*37748cd8SNickeau 26*37748cd8SNickeau /** @var array<ANTLRErrorListener> */ 27*37748cd8SNickeau private $listeners; 28*37748cd8SNickeau 29*37748cd8SNickeau /** @var ATNSimulator|null */ 30*37748cd8SNickeau protected $interp; 31*37748cd8SNickeau 32*37748cd8SNickeau /** @var int */ 33*37748cd8SNickeau private $stateNumber = -1; 34*37748cd8SNickeau 35*37748cd8SNickeau public function __construct() 36*37748cd8SNickeau { 37*37748cd8SNickeau $this->listeners = []; 38*37748cd8SNickeau } 39*37748cd8SNickeau 40*37748cd8SNickeau /** 41*37748cd8SNickeau * Get the vocabulary used by the recognizer. 42*37748cd8SNickeau * 43*37748cd8SNickeau * @return Vocabulary A {@see Vocabulary} instance providing information 44*37748cd8SNickeau * about the vocabulary used by the grammar. 45*37748cd8SNickeau */ 46*37748cd8SNickeau abstract public function getVocabulary() : Vocabulary; 47*37748cd8SNickeau 48*37748cd8SNickeau /** 49*37748cd8SNickeau * Get a map from token names to token types. 50*37748cd8SNickeau * 51*37748cd8SNickeau * Used for XPath and tree pattern compilation. 52*37748cd8SNickeau * 53*37748cd8SNickeau * @return array<string, int> 54*37748cd8SNickeau */ 55*37748cd8SNickeau public function getTokenTypeMap() : array 56*37748cd8SNickeau { 57*37748cd8SNickeau $vocabulary = $this->getVocabulary(); 58*37748cd8SNickeau 59*37748cd8SNickeau $key = \spl_object_hash($vocabulary); 60*37748cd8SNickeau $result = self::$tokenTypeMapCache[$key] ?? null; 61*37748cd8SNickeau 62*37748cd8SNickeau if ($result === null) { 63*37748cd8SNickeau $result = []; 64*37748cd8SNickeau 65*37748cd8SNickeau for ($i = 0; $i <= $this->getATN()->maxTokenType; $i++) { 66*37748cd8SNickeau $literalName = $vocabulary->getLiteralName($i); 67*37748cd8SNickeau 68*37748cd8SNickeau if ($literalName !== null) { 69*37748cd8SNickeau $result[$literalName] = $i; 70*37748cd8SNickeau } 71*37748cd8SNickeau 72*37748cd8SNickeau $symbolicName = $vocabulary->getSymbolicName($i); 73*37748cd8SNickeau 74*37748cd8SNickeau if ($symbolicName !== null) { 75*37748cd8SNickeau $result[$symbolicName] = $i; 76*37748cd8SNickeau } 77*37748cd8SNickeau } 78*37748cd8SNickeau 79*37748cd8SNickeau $result['EOF'] = Token::EOF; 80*37748cd8SNickeau 81*37748cd8SNickeau self::$tokenTypeMapCache[$key] = $result; 82*37748cd8SNickeau } 83*37748cd8SNickeau 84*37748cd8SNickeau return $result; 85*37748cd8SNickeau } 86*37748cd8SNickeau 87*37748cd8SNickeau /** 88*37748cd8SNickeau * Get a map from rule names to rule indexes. 89*37748cd8SNickeau * 90*37748cd8SNickeau * Used for XPath and tree pattern compilation. 91*37748cd8SNickeau * 92*37748cd8SNickeau * @return array<int, string>|null 93*37748cd8SNickeau */ 94*37748cd8SNickeau public function getRuleIndexMap() : ?array 95*37748cd8SNickeau { 96*37748cd8SNickeau $result = self::$ruleIndexMapCache[static::class] ?? null; 97*37748cd8SNickeau 98*37748cd8SNickeau if ($result === null) { 99*37748cd8SNickeau self::$ruleIndexMapCache[static::class] = $this->getRuleNames(); 100*37748cd8SNickeau } 101*37748cd8SNickeau 102*37748cd8SNickeau return $result; 103*37748cd8SNickeau } 104*37748cd8SNickeau 105*37748cd8SNickeau public function getTokenType(string $tokenName) : int 106*37748cd8SNickeau { 107*37748cd8SNickeau $map = $this->getTokenTypeMap(); 108*37748cd8SNickeau 109*37748cd8SNickeau return $map[$tokenName] ?? Token::INVALID_TYPE; 110*37748cd8SNickeau } 111*37748cd8SNickeau 112*37748cd8SNickeau /** 113*37748cd8SNickeau * If this recognizer was generated, it will have a serialized ATN 114*37748cd8SNickeau * representation of the grammar. For interpreters, we don't know 115*37748cd8SNickeau * their serialized ATN despite having created the interpreter from it. 116*37748cd8SNickeau */ 117*37748cd8SNickeau public function getSerializedATN() : string 118*37748cd8SNickeau { 119*37748cd8SNickeau throw new \InvalidArgumentException('there is no serialized ATN'); 120*37748cd8SNickeau } 121*37748cd8SNickeau 122*37748cd8SNickeau /** 123*37748cd8SNickeau * Get the ATN interpreter used by the recognizer for prediction. 124*37748cd8SNickeau * 125*37748cd8SNickeau * @return ATNSimulator|null The ATN interpreter used by the recognizer 126*37748cd8SNickeau * for prediction. 127*37748cd8SNickeau */ 128*37748cd8SNickeau public function getInterpreter() : ?ATNSimulator 129*37748cd8SNickeau { 130*37748cd8SNickeau return $this->interp; 131*37748cd8SNickeau } 132*37748cd8SNickeau 133*37748cd8SNickeau protected function interpreter() : ATNSimulator 134*37748cd8SNickeau { 135*37748cd8SNickeau if ($this->interp === null) { 136*37748cd8SNickeau throw new \RuntimeException('Unexpected null interpreter.'); 137*37748cd8SNickeau } 138*37748cd8SNickeau 139*37748cd8SNickeau return $this->interp; 140*37748cd8SNickeau } 141*37748cd8SNickeau 142*37748cd8SNickeau /** 143*37748cd8SNickeau * Set the ATN interpreter used by the recognizer for prediction. 144*37748cd8SNickeau * 145*37748cd8SNickeau * @param ATNSimulator|null $interpreter The ATN interpreter used 146*37748cd8SNickeau * by the recognizer for prediction. 147*37748cd8SNickeau */ 148*37748cd8SNickeau public function setInterpreter(?ATNSimulator $interpreter) : void 149*37748cd8SNickeau { 150*37748cd8SNickeau $this->interp = $interpreter; 151*37748cd8SNickeau } 152*37748cd8SNickeau 153*37748cd8SNickeau /** 154*37748cd8SNickeau * What is the error header, normally line/character position information? 155*37748cd8SNickeau */ 156*37748cd8SNickeau public function getErrorHeader(RecognitionException $e) : string 157*37748cd8SNickeau { 158*37748cd8SNickeau $token = $e->getOffendingToken(); 159*37748cd8SNickeau 160*37748cd8SNickeau if ($token === null) { 161*37748cd8SNickeau return ''; 162*37748cd8SNickeau } 163*37748cd8SNickeau 164*37748cd8SNickeau return \sprintf('line %d:%d', $token->getLine(), $token->getCharPositionInLine()); 165*37748cd8SNickeau } 166*37748cd8SNickeau 167*37748cd8SNickeau public function addErrorListener(ANTLRErrorListener $listener) : void 168*37748cd8SNickeau { 169*37748cd8SNickeau $this->listeners[] = $listener; 170*37748cd8SNickeau } 171*37748cd8SNickeau 172*37748cd8SNickeau public function removeErrorListeners() : void 173*37748cd8SNickeau { 174*37748cd8SNickeau $this->listeners = []; 175*37748cd8SNickeau } 176*37748cd8SNickeau 177*37748cd8SNickeau public function getErrorListenerDispatch() : ANTLRErrorListener 178*37748cd8SNickeau { 179*37748cd8SNickeau return new ProxyErrorListener($this->listeners); 180*37748cd8SNickeau } 181*37748cd8SNickeau 182*37748cd8SNickeau /** 183*37748cd8SNickeau * Subclass needs to override these if there are sempreds or actions 184*37748cd8SNickeau * that the ATN interp needs to execute 185*37748cd8SNickeau */ 186*37748cd8SNickeau public function sempred(?RuleContext $localctx, int $ruleIndex, int $actionIndex) : bool 187*37748cd8SNickeau { 188*37748cd8SNickeau return true; 189*37748cd8SNickeau } 190*37748cd8SNickeau 191*37748cd8SNickeau public function precpred(RuleContext $localctx, int $precedence) : bool 192*37748cd8SNickeau { 193*37748cd8SNickeau return true; 194*37748cd8SNickeau } 195*37748cd8SNickeau 196*37748cd8SNickeau public function action(?RuleContext $localctx, int $ruleIndex, int $actionIndex) : void 197*37748cd8SNickeau { 198*37748cd8SNickeau } 199*37748cd8SNickeau 200*37748cd8SNickeau public function getState() : int 201*37748cd8SNickeau { 202*37748cd8SNickeau return $this->stateNumber; 203*37748cd8SNickeau } 204*37748cd8SNickeau 205*37748cd8SNickeau /** 206*37748cd8SNickeau * Indicate that the recognizer has changed internal state that is 207*37748cd8SNickeau * consistent with the ATN state passed in. This way we always know 208*37748cd8SNickeau * where we are in the ATN as the parser goes along. The rule 209*37748cd8SNickeau * context objects form a stack that lets us see the stack of 210*37748cd8SNickeau * invoking rules. Combine this and we have complete ATN 211*37748cd8SNickeau * configuration information. 212*37748cd8SNickeau */ 213*37748cd8SNickeau public function setState(int $atnState) : void 214*37748cd8SNickeau { 215*37748cd8SNickeau $this->stateNumber = $atnState; 216*37748cd8SNickeau } 217*37748cd8SNickeau 218*37748cd8SNickeau abstract public function getInputStream() : ?IntStream; 219*37748cd8SNickeau abstract public function setInputStream(IntStream $input) : void; 220*37748cd8SNickeau abstract public function getTokenFactory() : TokenFactory; 221*37748cd8SNickeau abstract public function setTokenFactory(TokenFactory $input) : void; 222*37748cd8SNickeau 223*37748cd8SNickeau /** 224*37748cd8SNickeau * @return array<int, string> 225*37748cd8SNickeau */ 226*37748cd8SNickeau abstract public function getRuleNames() : array; 227*37748cd8SNickeau 228*37748cd8SNickeau /** 229*37748cd8SNickeau * Get the {@see ATN} used by the recognizer for prediction. 230*37748cd8SNickeau * 231*37748cd8SNickeau * @return ATN The {@see ATN} used by the recognizer for prediction. 232*37748cd8SNickeau */ 233*37748cd8SNickeau abstract public function getATN() : ATN; 234*37748cd8SNickeau} 235