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