1<?php
2
3declare(strict_types=1);
4
5namespace Antlr\Antlr4\Runtime\Error\Exceptions;
6
7use Antlr\Antlr4\Runtime\Atn\ATNConfigSet;
8use Antlr\Antlr4\Runtime\Parser;
9use Antlr\Antlr4\Runtime\ParserRuleContext;
10use Antlr\Antlr4\Runtime\Token;
11use Antlr\Antlr4\Runtime\TokenStream;
12
13/**
14 * Indicates that the parser could not decide which of two or more paths
15 * to take based upon the remaining input. It tracks the starting token
16 * of the offending input and also knows where the parser was
17 * in the various paths when the error. Reported by reportNoViableAlternative()
18 */
19class NoViableAltException extends RecognitionException
20{
21    /**
22     * The token object at the start index; the input stream might
23     * not be buffering tokens so get a reference to it. (At the
24     * time the error occurred, of course the stream needs to keep a
25     * buffer all of the tokens but later we might not have access to those.)
26     *
27     * @var Token|null
28     */
29    private $startToken;
30
31    /**
32     * Which configurations did we try at $input->index() that couldn't
33     * match $input->LT(1)?
34     *
35     * @var ATNConfigSet|null
36     */
37    private $deadEndConfigs;
38
39    public function __construct(
40        Parser $recognizer,
41        ?TokenStream $input = null,
42        ?Token $startToken = null,
43        ?Token $offendingToken = null,
44        ?ATNConfigSet $deadEndConfigs = null,
45        ?ParserRuleContext $ctx = null
46    ) {
47        if ($ctx === null) {
48            $ctx = $recognizer->getContext();
49        }
50
51        if ($offendingToken === null) {
52            $offendingToken = $recognizer->getCurrentToken();
53        }
54
55        if ($startToken === null) {
56            $startToken = $recognizer->getCurrentToken();
57        }
58
59        if ($input === null) {
60            $input = $recognizer->getInputStream();
61        }
62
63        parent::__construct($recognizer, $input, $ctx);
64
65        $this->deadEndConfigs = $deadEndConfigs;
66        $this->startToken = $startToken;
67        $this->setOffendingToken($offendingToken);
68    }
69
70    public function getStartToken() : ?Token
71    {
72        return $this->startToken;
73    }
74
75    public function getDeadEndConfigs() : ?ATNConfigSet
76    {
77        return $this->deadEndConfigs;
78    }
79}
80