1*37748cd8SNickeau<?php 2*37748cd8SNickeau 3*37748cd8SNickeaudeclare(strict_types=1); 4*37748cd8SNickeau 5*37748cd8SNickeaunamespace Antlr\Antlr4\Runtime\Error\Exceptions; 6*37748cd8SNickeau 7*37748cd8SNickeauuse Antlr\Antlr4\Runtime\IntervalSet; 8*37748cd8SNickeauuse Antlr\Antlr4\Runtime\IntStream; 9*37748cd8SNickeauuse Antlr\Antlr4\Runtime\ParserRuleContext; 10*37748cd8SNickeauuse Antlr\Antlr4\Runtime\Recognizer; 11*37748cd8SNickeauuse Antlr\Antlr4\Runtime\RuleContext; 12*37748cd8SNickeauuse Antlr\Antlr4\Runtime\Token; 13*37748cd8SNickeau 14*37748cd8SNickeau/** 15*37748cd8SNickeau * The root of the ANTLR exception hierarchy. In general, ANTLR tracks just 16*37748cd8SNickeau * 3 kinds of errors: prediction errors, failed predicate errors, and 17*37748cd8SNickeau * mismatched input errors. In each case, the parser knows where it is 18*37748cd8SNickeau * in the input, where it is in the ATN, the rule invocation stack, 19*37748cd8SNickeau * and what kind of problem occurred. 20*37748cd8SNickeau */ 21*37748cd8SNickeauclass RecognitionException extends \RuntimeException 22*37748cd8SNickeau{ 23*37748cd8SNickeau /** 24*37748cd8SNickeau * The {@see Recognizer} where this exception originated. 25*37748cd8SNickeau * 26*37748cd8SNickeau * @var Recognizer|null 27*37748cd8SNickeau */ 28*37748cd8SNickeau private $recognizer; 29*37748cd8SNickeau 30*37748cd8SNickeau /** @var RuleContext|null */ 31*37748cd8SNickeau private $ctx; 32*37748cd8SNickeau 33*37748cd8SNickeau /** @var IntStream|null */ 34*37748cd8SNickeau private $input; 35*37748cd8SNickeau 36*37748cd8SNickeau /** 37*37748cd8SNickeau * The current {@see Token} when an error occurred. Since not all streams 38*37748cd8SNickeau * support accessing symbols by index, we have to track the {@see Token} 39*37748cd8SNickeau * instance itself. 40*37748cd8SNickeau * 41*37748cd8SNickeau * @var Token|null 42*37748cd8SNickeau */ 43*37748cd8SNickeau private $offendingToken; 44*37748cd8SNickeau 45*37748cd8SNickeau /** @var int */ 46*37748cd8SNickeau private $offendingState = -1; 47*37748cd8SNickeau 48*37748cd8SNickeau public function __construct( 49*37748cd8SNickeau ?Recognizer $recognizer, 50*37748cd8SNickeau ?IntStream $input, 51*37748cd8SNickeau ?ParserRuleContext $ctx, 52*37748cd8SNickeau string $message = '' 53*37748cd8SNickeau ) { 54*37748cd8SNickeau parent::__construct($message); 55*37748cd8SNickeau 56*37748cd8SNickeau $this->recognizer = $recognizer; 57*37748cd8SNickeau $this->input = $input; 58*37748cd8SNickeau $this->ctx = $ctx; 59*37748cd8SNickeau 60*37748cd8SNickeau if ($this->recognizer !== null) { 61*37748cd8SNickeau $this->offendingState = $this->recognizer->getState(); 62*37748cd8SNickeau } 63*37748cd8SNickeau } 64*37748cd8SNickeau 65*37748cd8SNickeau /** 66*37748cd8SNickeau * Get the ATN state number the parser was in at the time the error 67*37748cd8SNickeau * occurred. For {@see NoViableAltException} and 68*37748cd8SNickeau * {@see LexerNoViableAltException} exceptions, this is the 69*37748cd8SNickeau * {@see DecisionState} number. For others, it is the state whose outgoing 70*37748cd8SNickeau * edge we couldn't match. 71*37748cd8SNickeau * 72*37748cd8SNickeau * If the state number is not known, this method returns -1. 73*37748cd8SNickeau */ 74*37748cd8SNickeau public function getOffendingState() : int 75*37748cd8SNickeau { 76*37748cd8SNickeau return $this->offendingState; 77*37748cd8SNickeau } 78*37748cd8SNickeau 79*37748cd8SNickeau public function setOffendingState(int $offendingState) : void 80*37748cd8SNickeau { 81*37748cd8SNickeau $this->offendingState = $offendingState; 82*37748cd8SNickeau } 83*37748cd8SNickeau 84*37748cd8SNickeau /** 85*37748cd8SNickeau * If the state number is not known, this method returns -1. 86*37748cd8SNickeau * 87*37748cd8SNickeau * Gets the set of input symbols which could potentially follow the 88*37748cd8SNickeau * previously matched symbol at the time this exception was thrown. 89*37748cd8SNickeau * 90*37748cd8SNickeau * If the set of expected tokens is not known and could not be computed, 91*37748cd8SNickeau * this method returns `null`. 92*37748cd8SNickeau * 93*37748cd8SNickeau * @return IntervalSet|null The set of token types that could potentially follow 94*37748cd8SNickeau * the current state in the ATN, or `null` if 95*37748cd8SNickeau * the information is not available. 96*37748cd8SNickeau */ 97*37748cd8SNickeau public function getExpectedTokens() : ?IntervalSet 98*37748cd8SNickeau { 99*37748cd8SNickeau if ($this->recognizer === null) { 100*37748cd8SNickeau return null; 101*37748cd8SNickeau } 102*37748cd8SNickeau 103*37748cd8SNickeau if ($this->ctx === null) { 104*37748cd8SNickeau throw new \RuntimeException('Unexpected null context.'); 105*37748cd8SNickeau } 106*37748cd8SNickeau 107*37748cd8SNickeau return $this->recognizer->getATN()->getExpectedTokens($this->offendingState, $this->ctx); 108*37748cd8SNickeau } 109*37748cd8SNickeau 110*37748cd8SNickeau /** 111*37748cd8SNickeau * Gets the {@see RuleContext} at the time this exception was thrown. 112*37748cd8SNickeau * 113*37748cd8SNickeau * If the context is not available, this method returns `null`. 114*37748cd8SNickeau * 115*37748cd8SNickeau * @return RuleContext|null The {@see RuleContext} at the time this exception 116*37748cd8SNickeau * was thrown. If the context is not available, this 117*37748cd8SNickeau * method returns `null`. 118*37748cd8SNickeau */ 119*37748cd8SNickeau public function getCtx() : ?RuleContext 120*37748cd8SNickeau { 121*37748cd8SNickeau return $this->ctx; 122*37748cd8SNickeau } 123*37748cd8SNickeau 124*37748cd8SNickeau /** 125*37748cd8SNickeau * Gets the input stream which is the symbol source for the recognizer where 126*37748cd8SNickeau * this exception was thrown. 127*37748cd8SNickeau * 128*37748cd8SNickeau * If the input stream is not available, this method returns `null`. 129*37748cd8SNickeau * 130*37748cd8SNickeau * @return IntStream|null The input stream which is the symbol source for 131*37748cd8SNickeau * the recognizer where this exception was thrown, or 132*37748cd8SNickeau * `null` if the stream is not available. 133*37748cd8SNickeau */ 134*37748cd8SNickeau public function getInputStream() : ?IntStream 135*37748cd8SNickeau { 136*37748cd8SNickeau return $this->input; 137*37748cd8SNickeau } 138*37748cd8SNickeau 139*37748cd8SNickeau public function getOffendingToken() : ?Token 140*37748cd8SNickeau { 141*37748cd8SNickeau return $this->offendingToken; 142*37748cd8SNickeau } 143*37748cd8SNickeau 144*37748cd8SNickeau public function setOffendingToken(?Token $offendingToken) : void 145*37748cd8SNickeau { 146*37748cd8SNickeau $this->offendingToken = $offendingToken; 147*37748cd8SNickeau } 148*37748cd8SNickeau 149*37748cd8SNickeau /** 150*37748cd8SNickeau * Gets the {@see Recognizer} where this exception occurred. 151*37748cd8SNickeau * 152*37748cd8SNickeau * If the recognizer is not available, this method returns `null`. 153*37748cd8SNickeau * 154*37748cd8SNickeau * @return Recognizer|null The recognizer where this exception occurred, or 155*37748cd8SNickeau * `null` if the recognizer is not available. 156*37748cd8SNickeau */ 157*37748cd8SNickeau public function getRecognizer() : ?Recognizer 158*37748cd8SNickeau { 159*37748cd8SNickeau return $this->recognizer; 160*37748cd8SNickeau } 161*37748cd8SNickeau 162*37748cd8SNickeau public function __toString() : string 163*37748cd8SNickeau { 164*37748cd8SNickeau return $this->message; 165*37748cd8SNickeau } 166*37748cd8SNickeau} 167