xref: /plugin/combo/vendor/antlr/antlr4-php-runtime/src/Error/Exceptions/RecognitionException.php (revision 37748cd8654635afbeca80942126742f0f4cc346)
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