1use crate::atn_simulator::IATNSimulator;
3use crate::interval_set::IntervalSet;
4use crate::parser::Parser;
5use crate::rule_context::states_stack;
6use crate::token::{OwningToken, Token};
7use crate::token_factory::TokenFactory;
8use crate::transition::Transition;
9use std::error::Error;
10use std::fmt;
11use std::fmt::Formatter;
12use std::fmt::{Debug, Display};
13use std::ops::Deref;
14use std::sync::Arc;
15
16#[derive(Debug, Clone)]
18pub enum ANTLRErrorKind {
19 LexerNoAltError {
27 start_index: isize,
29 },
30
31 NoAltError(NoViableAltError),
36
37 InputMismatchError(InputMisMatchError),
40
41 PredicateError(FailedPredicateError),
46
47 IllegalStateError(String),
50
51 CustomError(String),
52
53 FallThrough(Arc<dyn Error + Send + Sync + 'static>),
56
57 OtherError(Arc<dyn Error + Send + Sync + 'static>),
61}
62
63#[derive(Debug, Clone)]
64pub struct ANTLRError(pub Box<ANTLRErrorKind>);
65
66impl Display for ANTLRError {
67 fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result {
68 <Self as Debug>::fmt(self, _f)
69 }
70}
71
72impl Error for ANTLRError {
73 fn source(&self) -> Option<&(dyn Error + 'static)> {
74 match self.0.as_ref() {
75 ANTLRErrorKind::FallThrough(x) => Some(x.as_ref()),
76 ANTLRErrorKind::OtherError(x) => Some(x.as_ref()),
77 _ => None,
78 }
79 }
80}
81
82impl From<ANTLRErrorKind> for ANTLRError {
83 fn from(value: ANTLRErrorKind) -> Self {
84 ANTLRError(Box::new(value))
85 }
86}
87
88impl From<Box<dyn Error + Send + Sync + 'static>> for ANTLRError {
89 fn from(value: Box<dyn Error + Send + Sync + 'static>) -> Self {
90 ANTLRErrorKind::OtherError(Arc::from(value)).into()
91 }
92}
93
94impl AsRef<ANTLRErrorKind> for ANTLRError {
95 fn as_ref(&self) -> &ANTLRErrorKind {
96 self.0.as_ref()
97 }
98}
99
100impl Deref for ANTLRError {
101 type Target = ANTLRErrorKind;
102
103 fn deref(&self) -> &Self::Target {
104 self.0.as_ref()
105 }
106}
107
108impl ANTLRError {
109 pub fn custom_error(msg: String) -> Self {
110 ANTLRErrorKind::CustomError(msg).into()
111 }
112
113 pub fn lexer_no_alt(start_index: isize) -> Self {
114 ANTLRErrorKind::LexerNoAltError { start_index }.into()
115 }
116
117 pub fn illegal_state(msg: String) -> Self {
118 ANTLRErrorKind::IllegalStateError(msg).into()
119 }
120
121 pub fn fall_through<E: Error + Send + Sync + 'static>(err: E) -> Self {
122 ANTLRErrorKind::FallThrough(Arc::new(err)).into()
123 }
124
125 pub fn no_alt<'input, 'arena, TF, P>(recog: &mut P) -> Self
126 where
127 'input: 'arena,
128 TF: TokenFactory<'input, 'arena> + 'arena,
129 P: Parser<'input, 'arena, TF>,
130 {
131 ANTLRErrorKind::NoAltError(NoViableAltError {
132 base: BaseRecognitionError {
133 message: "".to_string(),
134 offending_token: OwningToken::from(recog.get_current_token() as &dyn Token),
135 offending_state: recog.get_state(),
136 states_stack: states_stack(recog.get_current_context()).collect(),
138 },
139 start_token: OwningToken::from(recog.get_current_token() as &dyn Token),
140 })
142 .into()
143 }
144
145 pub fn no_alt_full<'input, 'arena, TF, P>(
146 recog: &mut P,
147 start_token: OwningToken,
148 offending_token: OwningToken,
149 ) -> Self
150 where
151 'input: 'arena,
152 TF: TokenFactory<'input, 'arena> + 'arena,
153 P: Parser<'input, 'arena, TF>,
154 {
155 ANTLRErrorKind::NoAltError(NoViableAltError {
156 base: BaseRecognitionError {
157 message: "".to_string(),
158 offending_token,
159 offending_state: recog.get_state(),
160 states_stack: states_stack(recog.get_current_context()).collect(), },
162 start_token,
163 })
165 .into()
166 }
167
168 pub fn input_mismatch<'input, 'arena, TF, P>(recognizer: &mut P) -> Self
169 where
170 'input: 'arena,
171 TF: TokenFactory<'input, 'arena> + 'arena,
172 P: Parser<'input, 'arena, TF>,
173 {
174 ANTLRErrorKind::InputMismatchError(InputMisMatchError {
175 base: BaseRecognitionError::new(recognizer),
176 })
177 .into()
178 }
179
180 pub fn input_mismatch_with_state<'input, 'arena, TF, P>(
181 recognizer: &mut P,
182 offending_state: i32,
183 ctx: &'arena P::Node,
184 ) -> Self
185 where
186 'input: 'arena,
187 TF: TokenFactory<'input, 'arena> + 'arena,
188 P: Parser<'input, 'arena, TF>,
189 {
190 let mut a = InputMisMatchError {
191 base: BaseRecognitionError::new(recognizer),
192 };
193 a.base.offending_state = offending_state;
195 a.base.states_stack = states_stack(ctx).collect();
196 ANTLRErrorKind::InputMismatchError(a).into()
197 }
198
199 pub fn failed_predicate<'input, 'arena, TF, P>(
200 recog: &mut P,
201 predicate: Option<String>,
202 msg: Option<String>,
203 ) -> Self
204 where
205 'input: 'arena,
206 TF: TokenFactory<'input, 'arena> + 'arena,
207 P: Parser<'input, 'arena, TF>,
208 {
209 let tr = recog
210 .get_interpreter()
211 .atn()
212 .get_state(recog.get_state())
213 .get_transitions()
214 .first()
215 .unwrap();
216 let (rule_index, _) = if let Transition::Predicate(pr) = tr {
217 (pr.rule_index, pr.pred_index)
218 } else {
219 (0, 0)
220 };
221
222 ANTLRErrorKind::PredicateError(FailedPredicateError {
223 base: BaseRecognitionError {
224 message: msg.unwrap_or_else(|| {
225 format!(
226 "failed predicate: {}",
227 predicate.as_deref().unwrap_or("None")
228 )
229 }),
230 offending_token: OwningToken::from(recog.get_current_token() as &dyn Token),
231 offending_state: recog.get_state(),
232 states_stack: states_stack(recog.get_current_context()).collect(), },
234 rule_index,
235 predicate: predicate.unwrap_or_default(),
236 })
237 .into()
238 }
239
240 pub fn is_recoverable(&self) -> bool {
241 !matches!(self.0.as_ref(), ANTLRErrorKind::FallThrough(_))
242 }
243
244 pub fn get_offending_token(&self) -> Option<&OwningToken> {
246 Some(match self.0.as_ref() {
247 ANTLRErrorKind::NoAltError(e) => &e.base.offending_token,
248 ANTLRErrorKind::InputMismatchError(e) => &e.base.offending_token,
249 ANTLRErrorKind::PredicateError(e) => &e.base.offending_token,
250 _ => return None,
251 })
252 }
253}
254
255#[derive(Debug, Clone)]
264#[allow(missing_docs)]
265pub struct BaseRecognitionError {
266 pub message: String,
267 pub offending_token: OwningToken,
269 pub offending_state: i32,
270 states_stack: Vec<i32>, }
273
274impl BaseRecognitionError {
275 pub fn get_expected_tokens<'input, 'arena, TF, P>(&self, recognizer: &P) -> IntervalSet
277 where
278 'input: 'arena,
279 TF: TokenFactory<'input, 'arena> + 'arena,
280 P: Parser<'input, 'arena, TF>,
281 {
282 recognizer
283 .get_interpreter()
284 .atn()
285 .get_expected_tokens(self.offending_state, self.states_stack.iter().copied())
286 }
287
288 fn new<'input, 'arena, TF, P>(recog: &mut P) -> BaseRecognitionError
289 where
290 'input: 'arena,
291 TF: TokenFactory<'input, 'arena> + 'arena,
292 P: Parser<'input, 'arena, TF>,
293 {
294 BaseRecognitionError {
295 message: "".to_string(),
296 offending_token: OwningToken::from(recog.get_current_token() as &dyn Token),
297 offending_state: recog.get_state(),
298 states_stack: states_stack(recog.get_current_context()).collect(),
300 }
301 }
302}
303
304#[derive(Debug, Clone)]
306#[allow(missing_docs)]
307pub struct NoViableAltError {
308 pub base: BaseRecognitionError,
309 pub start_token: OwningToken,
310 }
313
314#[derive(Debug, Clone)]
316#[allow(missing_docs)]
317pub struct InputMisMatchError {
318 pub base: BaseRecognitionError,
319}
320
321#[derive(Debug, Clone)]
323#[allow(missing_docs)]
324pub struct FailedPredicateError {
325 pub base: BaseRecognitionError,
326 pub rule_index: i32,
327 pub predicate: String,
328}