do_not_use_antlr_rust/
errors.rs

1//! Error types
2use 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/// Main ANTLR4 Rust runtime error
19#[derive(Debug, Clone)]
20pub enum ANTLRError {
21    /// Returned from Lexer when it fails to find matching token type for current input
22    ///
23    /// Usually Lexers contain last rule that captures all invalid tokens like:
24    /// ```text
25    /// ERROR_TOKEN: . ;
26    /// ```
27    /// to prevent lexer from throwing errors and have all error handling in parser.
28    LexerNoAltError {
29        /// Index at which error has happened
30        start_index: isize,
31    },
32
33    /// Indicates that the parser could not decide which of two or more paths
34    /// to take based upon the remaining input. It tracks the starting token
35    /// of the offending input and also knows where the parser was
36    /// in the various paths when the error. Reported by reportNoViableAlternative()
37    NoAltError(NoViableAltError),
38
39    /// This signifies any kind of mismatched input exceptions such as
40    /// when the current input does not match the expected token.
41    InputMismatchError(InputMisMatchError),
42
43    /// A semantic predicate failed during validation. Validation of predicates
44    /// occurs when normally parsing the alternative just like matching a token.
45    /// Disambiguating predicate evaluation occurs when we test a predicate during
46    /// prediction.
47    PredicateError(FailedPredicateError),
48
49    /// Internal error. Or user provided type returned data that is
50    /// incompatible with current parser state
51    IllegalStateError(String),
52
53    /// Unrecoverable error. Indicates that error should not be processed by parser/error strategy
54    /// and it should abort parsing and immediately return to caller.
55    FallThrough(Rc<dyn Error>),
56
57    /// Potentially recoverable error.
58    /// Used to allow user to emit his own errors from parser actions or from custom error strategy.
59    /// Parser will try to recover with provided `ErrorStrategy`
60    OtherError(Rc<dyn Error>),
61}
62
63// impl Clone for ANTLRError {
64//     fn clone(&self) -> Self {
65//         match self {
66//             ANTLRError::LexerNoAltError { start_index } => ANTLRError::LexerNoAltError {
67//                 start_index: *start_index,
68//             },
69//             ANTLRError::NoAltError(e) => ANTLRError::NoAltError(e.clone()),
70//             ANTLRError::InputMismatchError(e) => ANTLRError::InputMismatchError(e.clone()),
71//             ANTLRError::PredicateError(e) => ANTLRError::PredicateError(e.clone()),
72//             ANTLRError::IllegalStateError(e) => ANTLRError::IllegalStateError(e.clone()),
73//             ANTLRError::FallThrough(_) => panic!("clone not supported"),
74//             ANTLRError::OtherError(_) => panic!("clone not supported"),
75//         }
76//     }
77// }
78
79impl Display for ANTLRError {
80    fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result { <Self as Debug>::fmt(self, _f) }
81}
82
83impl Error for ANTLRError {
84    fn source(&self) -> Option<&(dyn Error + 'static)> {
85        match self {
86            ANTLRError::FallThrough(x) => Some(x.as_ref()),
87            ANTLRError::OtherError(x) => Some(x.as_ref()),
88            _ => None,
89        }
90    }
91}
92
93impl ANTLRError {
94    /// Returns first token that caused parser to fail.
95    pub fn get_offending_token(&self) -> Option<&OwningToken> {
96        Some(match self {
97            ANTLRError::NoAltError(e) => &e.base.offending_token,
98            ANTLRError::InputMismatchError(e) => &e.base.offending_token,
99            ANTLRError::PredicateError(e) => &e.base.offending_token,
100            _ => return None,
101        })
102    }
103}
104
105//impl ANTLRError {
106//    fn get_expected_tokens(&self, _atn: &ATN) -> IntervalSet {
107////        atn.get_expected_tokens(se)
108//        unimplemented!()
109//    }
110//}
111
112/// Common part of ANTLR parser errors
113#[derive(Debug, Clone)]
114#[allow(missing_docs)]
115pub struct BaseRecognitionError {
116    pub message: String,
117    //    recognizer: Box<Recognizer>,
118    pub offending_token: OwningToken,
119    pub offending_state: isize,
120    states_stack: Vec<isize>, // ctx: Rc<dyn ParserRuleContext>
121                              //    input: Box<IntStream>
122}
123
124impl BaseRecognitionError {
125    /// Returns tokens that were expected by parser in error place
126    pub fn get_expected_tokens<'a, T: Parser<'a>>(&self, recognizer: &T) -> IntervalSet {
127        recognizer
128            .get_interpreter()
129            .atn()
130            .get_expected_tokens(self.offending_state, self.states_stack.iter().copied())
131    }
132
133    fn new<'a, T: Parser<'a>>(recog: &mut T) -> BaseRecognitionError {
134        BaseRecognitionError {
135            message: "".to_string(),
136            offending_token: recog.get_current_token().borrow().to_owned(),
137            offending_state: recog.get_state(),
138            // ctx: recog.get_parser_rule_context().clone(),
139            states_stack: states_stack(recog.get_parser_rule_context().clone()).collect(),
140        }
141    }
142}
143
144/// See `ANTLRError::NoAltError`
145#[derive(Debug, Clone)]
146#[allow(missing_docs)]
147pub struct NoViableAltError {
148    pub base: BaseRecognitionError,
149    pub start_token: OwningToken,
150    //    ctx: Rc<dyn ParserRuleContext>,
151    //    dead_end_configs: BaseATNConfigSet,
152}
153
154#[allow(missing_docs)]
155impl NoViableAltError {
156    pub fn new<'a, T: Parser<'a>>(recog: &mut T) -> NoViableAltError {
157        Self {
158            base: BaseRecognitionError {
159                message: "".to_string(),
160                offending_token: recog.get_current_token().borrow().to_owned(),
161                offending_state: recog.get_state(),
162                // ctx: recog.get_parser_rule_context().clone(),
163                states_stack: states_stack(recog.get_parser_rule_context().clone()).collect(),
164            },
165            start_token: recog.get_current_token().borrow().to_owned(),
166            //            ctx: recog.get_parser_rule_context().clone()
167        }
168    }
169    pub fn new_full<'a, T: Parser<'a>>(
170        recog: &mut T,
171        start_token: OwningToken,
172        offending_token: OwningToken,
173    ) -> NoViableAltError {
174        Self {
175            base: BaseRecognitionError {
176                message: "".to_string(),
177                offending_token,
178                offending_state: recog.get_state(),
179                states_stack: states_stack(recog.get_parser_rule_context().clone()).collect(), // ctx: recog.get_parser_rule_context().clone(),
180            },
181            start_token,
182            //            ctx
183        }
184    }
185}
186
187/// See `ANTLRError::InputMismatchError`
188#[derive(Debug, Clone)]
189#[allow(missing_docs)]
190pub struct InputMisMatchError {
191    pub base: BaseRecognitionError,
192}
193
194#[allow(missing_docs)]
195impl InputMisMatchError {
196    pub fn new<'a, T: Parser<'a>>(recognizer: &mut T) -> InputMisMatchError {
197        InputMisMatchError {
198            base: BaseRecognitionError::new(recognizer),
199        }
200    }
201
202    pub fn with_state<'a, T: Parser<'a>>(
203        recognizer: &mut T,
204        offending_state: isize,
205        ctx: Rc<<T::Node as ParserNodeType<'a>>::Type>,
206    ) -> InputMisMatchError {
207        let mut a = Self::new(recognizer);
208        // a.base.ctx = ctx;
209        a.base.offending_state = offending_state;
210        a.base.states_stack = states_stack(ctx).collect();
211        a
212    }
213}
214
215//fn new_input_mis_match_exception(recognizer: Parser) -> InputMisMatchError { unimplemented!() }
216
217/// See `ANTLRError::PredicateError`
218#[derive(Debug, Clone)]
219#[allow(missing_docs)]
220pub struct FailedPredicateError {
221    pub base: BaseRecognitionError,
222    pub rule_index: isize,
223    predicate_index: isize,
224    pub predicate: String,
225}
226
227#[allow(missing_docs)]
228impl FailedPredicateError {
229    pub fn new<'a, T: Parser<'a>>(
230        recog: &mut T,
231        predicate: Option<String>,
232        msg: Option<String>,
233    ) -> ANTLRError {
234        let tr = recog.get_interpreter().atn().states[recog.get_state() as usize]
235            .get_transitions()
236            .first()
237            .unwrap();
238        let (rule_index, predicate_index) = if tr.get_serialization_type() == TRANSITION_PREDICATE {
239            let pr = tr.deref().cast::<PredicateTransition>();
240            (pr.rule_index, pr.pred_index)
241        } else {
242            (0, 0)
243        };
244
245        ANTLRError::PredicateError(FailedPredicateError {
246            base: BaseRecognitionError {
247                message: msg.unwrap_or_else(|| {
248                    format!(
249                        "failed predicate: {}",
250                        predicate.as_deref().unwrap_or("None")
251                    )
252                }),
253                offending_token: recog.get_current_token().borrow().to_owned(),
254                offending_state: recog.get_state(),
255                states_stack: states_stack(recog.get_parser_rule_context().clone()).collect(), // ctx: recog.get_parser_rule_context().clone()
256            },
257            rule_index,
258            predicate_index,
259            predicate: predicate.unwrap_or_default(),
260        })
261    }
262}