antlr_rust_sleagon/
errors.rs1use std::borrow::Borrow;
3use std::error::Error;
4use std::fmt;
5use std::fmt::Formatter;
6use std::fmt::{Debug, Display};
7use std::ops::Deref;
8use std::rc::Rc;
9
10use crate::atn_simulator::IATNSimulator;
11use crate::interval_set::IntervalSet;
12use crate::parser::{Parser, ParserNodeType};
13use crate::rule_context::states_stack;
14use crate::token::{OwningToken, Token};
15use crate::transition::PredicateTransition;
16use crate::transition::TransitionType::TRANSITION_PREDICATE;
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(Rc<dyn Error>),
56
57 OtherError(Rc<dyn Error>),
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: isize,
122 states_stack: Vec<isize>, }
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: isize,
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: isize,
225 predicate_index: isize,
226 pub predicate: String,
227}
228
229#[allow(missing_docs)]
230impl FailedPredicateError {
231 pub fn new<'a, T: Parser<'a>>(
232 recog: &mut T,
233 predicate: Option<String>,
234 msg: Option<String>,
235 ) -> ANTLRError {
236 let tr = recog.get_interpreter().atn().states[recog.get_state() as usize]
237 .get_transitions()
238 .first()
239 .unwrap();
240 let (rule_index, predicate_index) = if tr.get_serialization_type() == TRANSITION_PREDICATE {
241 let pr = tr.deref().cast::<PredicateTransition>();
242 (pr.rule_index, pr.pred_index)
243 } else {
244 (0, 0)
245 };
246
247 ANTLRError::PredicateError(FailedPredicateError {
248 base: BaseRecognitionError {
249 message: msg.unwrap_or_else(|| {
250 format!(
251 "failed predicate: {}",
252 predicate.as_deref().unwrap_or("None")
253 )
254 }),
255 offending_token: recog.get_current_token().borrow().to_owned(),
256 offending_state: recog.get_state(),
257 states_stack: states_stack(recog.get_parser_rule_context().clone()).collect(), },
259 rule_index,
260 predicate_index,
261 predicate: predicate.unwrap_or_default(),
262 })
263 }
264}