1use crate::atn_simulator::IATNSimulator;
3use crate::interval_set::IntervalSet;
4use crate::parser::{Parser, ParserNodeType};
5use crate::rule_context::states_stack;
6use crate::token::{OwningToken, Token};
7use crate::transition::PredicateTransition;
8use crate::transition::TransitionType::TRANSITION_PREDICATE;
9use std::borrow::Borrow;
10use std::error::Error;
11use std::fmt;
12use std::fmt::Formatter;
13use std::fmt::{Debug, Display};
14use std::ops::Deref;
15use std::rc::Rc;
16use std::sync::Arc;
17
18#[derive(Debug, Clone)]
20pub enum ANTLRError {
21 LexerNoAltError {
29 start_index: isize,
31 },
32
33 NoAltError(NoViableAltError),
38
39 InputMismatchError(InputMisMatchError),
42
43 PredicateError(FailedPredicateError),
48
49 IllegalStateError(String),
52
53 FallThrough(Arc<dyn Error + Send + Sync + 'static>),
56
57 OtherError(Arc<dyn Error + Send + Sync + 'static>),
61}
62
63impl Display for ANTLRError {
80 fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result {
81 <Self as Debug>::fmt(self, _f)
82 }
83}
84
85impl Error for ANTLRError {
86 fn source(&self) -> Option<&(dyn Error + 'static)> {
87 match self {
88 ANTLRError::FallThrough(x) => Some(x.as_ref()),
89 ANTLRError::OtherError(x) => Some(x.as_ref()),
90 _ => None,
91 }
92 }
93}
94
95impl ANTLRError {
96 pub fn get_offending_token(&self) -> Option<&OwningToken> {
98 Some(match self {
99 ANTLRError::NoAltError(e) => &e.base.offending_token,
100 ANTLRError::InputMismatchError(e) => &e.base.offending_token,
101 ANTLRError::PredicateError(e) => &e.base.offending_token,
102 _ => return None,
103 })
104 }
105}
106
107#[derive(Debug, Clone)]
116#[allow(missing_docs)]
117pub struct BaseRecognitionError {
118 pub message: String,
119 pub offending_token: OwningToken,
121 pub offending_state: i32,
122 states_stack: Vec<i32>, }
125
126impl BaseRecognitionError {
127 pub fn get_expected_tokens<'a, T: Parser<'a>>(&self, recognizer: &T) -> IntervalSet {
129 recognizer
130 .get_interpreter()
131 .atn()
132 .get_expected_tokens(self.offending_state, self.states_stack.iter().copied())
133 }
134
135 fn new<'a, T: Parser<'a>>(recog: &mut T) -> BaseRecognitionError {
136 BaseRecognitionError {
137 message: "".to_string(),
138 offending_token: recog.get_current_token().borrow().to_owned(),
139 offending_state: recog.get_state(),
140 states_stack: states_stack(recog.get_parser_rule_context().clone()).collect(),
142 }
143 }
144}
145
146#[derive(Debug, Clone)]
148#[allow(missing_docs)]
149pub struct NoViableAltError {
150 pub base: BaseRecognitionError,
151 pub start_token: OwningToken,
152 }
155
156#[allow(missing_docs)]
157impl NoViableAltError {
158 pub fn new<'a, T: Parser<'a>>(recog: &mut T) -> NoViableAltError {
159 Self {
160 base: BaseRecognitionError {
161 message: "".to_string(),
162 offending_token: recog.get_current_token().borrow().to_owned(),
163 offending_state: recog.get_state(),
164 states_stack: states_stack(recog.get_parser_rule_context().clone()).collect(),
166 },
167 start_token: recog.get_current_token().borrow().to_owned(),
168 }
170 }
171 pub fn new_full<'a, T: Parser<'a>>(
172 recog: &mut T,
173 start_token: OwningToken,
174 offending_token: OwningToken,
175 ) -> NoViableAltError {
176 Self {
177 base: BaseRecognitionError {
178 message: "".to_string(),
179 offending_token,
180 offending_state: recog.get_state(),
181 states_stack: states_stack(recog.get_parser_rule_context().clone()).collect(), },
183 start_token,
184 }
186 }
187}
188
189#[derive(Debug, Clone)]
191#[allow(missing_docs)]
192pub struct InputMisMatchError {
193 pub base: BaseRecognitionError,
194}
195
196#[allow(missing_docs)]
197impl InputMisMatchError {
198 pub fn new<'a, T: Parser<'a>>(recognizer: &mut T) -> InputMisMatchError {
199 InputMisMatchError {
200 base: BaseRecognitionError::new(recognizer),
201 }
202 }
203
204 pub fn with_state<'a, T: Parser<'a>>(
205 recognizer: &mut T,
206 offending_state: i32,
207 ctx: Rc<<T::Node as ParserNodeType<'a>>::Type>,
208 ) -> InputMisMatchError {
209 let mut a = Self::new(recognizer);
210 a.base.offending_state = offending_state;
212 a.base.states_stack = states_stack(ctx).collect();
213 a
214 }
215}
216
217#[derive(Debug, Clone)]
221#[allow(missing_docs)]
222pub struct FailedPredicateError {
223 pub base: BaseRecognitionError,
224 pub rule_index: i32,
225 pub predicate: String,
226}
227
228#[allow(missing_docs)]
229impl FailedPredicateError {
230 pub fn new<'a, T: Parser<'a>>(
231 recog: &mut T,
232 predicate: Option<String>,
233 msg: Option<String>,
234 ) -> ANTLRError {
235 let tr = recog.get_interpreter().atn().states[recog.get_state() as usize]
236 .get_transitions()
237 .first()
238 .unwrap();
239 let (rule_index, _) = if tr.get_serialization_type() == TRANSITION_PREDICATE {
240 let pr = tr.deref().cast::<PredicateTransition>();
241 (pr.rule_index, pr.pred_index)
242 } else {
243 (0, 0)
244 };
245
246 ANTLRError::PredicateError(FailedPredicateError {
247 base: BaseRecognitionError {
248 message: msg.unwrap_or_else(|| {
249 format!(
250 "failed predicate: {}",
251 predicate.as_deref().unwrap_or("None")
252 )
253 }),
254 offending_token: recog.get_current_token().borrow().to_owned(),
255 offending_state: recog.get_state(),
256 states_stack: states_stack(recog.get_parser_rule_context().clone()).collect(), },
258 rule_index,
259 predicate: predicate.unwrap_or_default(),
260 })
261 }
262}