do_not_use_antlr_rust/
error_strategy.rs

1//! Error handling and recovery
2use std::borrow::Borrow;
3use std::error::Error;
4use std::fmt;
5use std::fmt::{Display, Formatter};
6use std::ops::{Deref, DerefMut};
7use std::rc::Rc;
8
9use crate::atn_simulator::IATNSimulator;
10use crate::atn_state::*;
11use crate::char_stream::{CharStream, InputData};
12use crate::dfa::ScopeExt;
13use crate::errors::{ANTLRError, FailedPredicateError, InputMisMatchError, NoViableAltError};
14use crate::interval_set::IntervalSet;
15use crate::parser::{Parser, ParserNodeType};
16use crate::parser_rule_context::ParserRuleContext;
17use crate::rule_context::{CustomRuleContext, RuleContext};
18use crate::token::{Token, TOKEN_DEFAULT_CHANNEL, TOKEN_EOF, TOKEN_EPSILON, TOKEN_INVALID_TYPE};
19use crate::token_factory::TokenFactory;
20use crate::transition::RuleTransition;
21use crate::tree::Tree;
22use crate::utils::escape_whitespaces;
23use better_any::{Tid, TidAble};
24
25/// The interface for defining strategies to deal with syntax errors encountered
26/// during a parse by ANTLR-generated parsers. We distinguish between three
27/// different kinds of errors:
28///  - The parser could not figure out which path to take in the ATN (none of
29/// the available alternatives could possibly match)
30///  - The current input does not match what we were looking for
31///  - A predicate evaluated to false
32///
33/// Implementations of this interface should report syntax errors by calling [`Parser::notifyErrorListeners`]
34///
35/// [`Parser::notifyErrorListeners`]: crate::parser::Parser::notifyErrorListeners
36pub trait ErrorStrategy<'a, T: Parser<'a>>: Tid<'a> {
37    ///Reset the error handler state for the specified `recognizer`.
38    fn reset(&mut self, recognizer: &mut T);
39
40    /// This method is called when an unexpected symbol is encountered during an
41    /// inline match operation, such as `Parser::match`. If the error
42    /// strategy successfully recovers from the match failure, this method
43    /// returns the `Token` instance which should be treated as the
44    /// successful result of the match.
45    ///
46    /// This method handles the consumption of any tokens - the caller should
47    /// **not** call `Parser::consume` after a successful recovery.
48    ///
49    /// Note that the calling code will not report an error if this method
50    /// returns successfully. The error strategy implementation is responsible
51    /// for calling `Parser::notifyErrorListeners` as appropriate.
52    ///
53    /// Returns `ANTLRError` if can't recover from unexpected input symbol
54    fn recover_inline(
55        &mut self,
56        recognizer: &mut T,
57    ) -> Result<<T::TF as TokenFactory<'a>>::Tok, ANTLRError>;
58
59    /// This method is called to recover from error `e`. This method is
60    /// called after `ErrorStrategy::reportError` by the default error handler
61    /// generated for a rule method.
62    ///
63    ///
64    fn recover(&mut self, recognizer: &mut T, e: &ANTLRError) -> Result<(), ANTLRError>;
65
66    /// This method provides the error handler with an opportunity to handle
67    /// syntactic or semantic errors in the input stream before they result in a
68    /// error.
69    ///
70    /// The generated code currently contains calls to `ErrorStrategy::sync` after
71    /// entering the decision state of a closure block ({@code (...)*} or
72    /// {@code (...)+}).</p>
73    fn sync(&mut self, recognizer: &mut T) -> Result<(), ANTLRError>;
74
75    /// Tests whether or not {@code recognizer} is in the process of recovering
76    /// from an error. In error recovery mode, `Parser::consume` will create
77    /// `ErrorNode` leaf instead of `TerminalNode` one  
78    fn in_error_recovery_mode(&mut self, recognizer: &mut T) -> bool;
79
80    /// Report any kind of `ANTLRError`. This method is called by
81    /// the default exception handler generated for a rule method.
82    fn report_error(&mut self, recognizer: &mut T, e: &ANTLRError);
83
84    /// This method is called when the parser successfully matches an input
85    /// symbol.
86    fn report_match(&mut self, recognizer: &mut T);
87}
88//
89// impl<'a, T: Parser<'a>> Default for Box<dyn ErrorStrategy<'a, T> + 'a> {
90//     fn default() -> Self { Box::new(DefaultErrorStrategy::new()) }
91// }
92//
93// /// Error strategy trait object if there is a need to change error strategy at runtime
94// /// Supports downcasting.
95// pub type DynHandler<'a, T> = Box<dyn ErrorStrategy<'a, T> + 'a>;
96
97// impl<'a, T: Parser<'a> + TidAble<'a>> TidAble<'a> for Box<dyn ErrorStrategy<'a, T> + 'a> {}
98better_any::tid! { impl<'a, T> TidAble<'a> for Box<dyn ErrorStrategy<'a, T> + 'a> where T: Parser<'a>}
99
100impl<'a, T: Parser<'a> + TidAble<'a>> ErrorStrategy<'a, T> for Box<dyn ErrorStrategy<'a, T> + 'a> {
101    #[inline(always)]
102    fn reset(&mut self, recognizer: &mut T) { self.deref_mut().reset(recognizer) }
103
104    #[inline(always)]
105    fn recover_inline(
106        &mut self,
107        recognizer: &mut T,
108    ) -> Result<<T::TF as TokenFactory<'a>>::Tok, ANTLRError> {
109        self.deref_mut().recover_inline(recognizer)
110    }
111
112    #[inline(always)]
113    fn recover(&mut self, recognizer: &mut T, e: &ANTLRError) -> Result<(), ANTLRError> {
114        self.deref_mut().recover(recognizer, e)
115    }
116
117    #[inline(always)]
118    fn sync(&mut self, recognizer: &mut T) -> Result<(), ANTLRError> {
119        self.deref_mut().sync(recognizer)
120    }
121
122    #[inline(always)]
123    fn in_error_recovery_mode(&mut self, recognizer: &mut T) -> bool {
124        self.deref_mut().in_error_recovery_mode(recognizer)
125    }
126
127    #[inline(always)]
128    fn report_error(&mut self, recognizer: &mut T, e: &ANTLRError) {
129        self.deref_mut().report_error(recognizer, e)
130    }
131
132    #[inline(always)]
133    fn report_match(&mut self, recognizer: &mut T) { self.deref_mut().report_match(recognizer) }
134}
135
136/// This is the default implementation of `ErrorStrategy` used for
137/// error reporting and recovery in ANTLR parsers.
138#[derive(Debug)]
139pub struct DefaultErrorStrategy<'input, Ctx: ParserNodeType<'input>> {
140    error_recovery_mode: bool,
141    last_error_index: isize,
142    last_error_states: Option<IntervalSet>,
143    next_tokens_state: isize,
144    next_tokens_ctx: Option<Rc<Ctx::Type>>,
145}
146
147better_any::tid! { impl<'i,Ctx> TidAble<'i> for DefaultErrorStrategy<'i,Ctx> where Ctx: ParserNodeType<'i>}
148
149impl<'input, Ctx: ParserNodeType<'input>> Default for DefaultErrorStrategy<'input, Ctx> {
150    fn default() -> Self { Self::new() }
151}
152
153impl<'input, Ctx: ParserNodeType<'input>> DefaultErrorStrategy<'input, Ctx> {
154    /// Creates new instance of `DefaultErrorStrategy`
155    pub fn new() -> Self {
156        Self {
157            error_recovery_mode: false,
158            last_error_index: -1,
159            last_error_states: None,
160            next_tokens_state: ATNSTATE_INVALID_STATE_NUMBER,
161            next_tokens_ctx: None,
162        }
163    }
164
165    fn begin_error_condition<T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
166        &mut self,
167        _recognizer: &T,
168    ) {
169        self.error_recovery_mode = true;
170    }
171
172    fn end_error_condition<T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
173        &mut self,
174        _recognizer: &T,
175    ) {
176        self.error_recovery_mode = false;
177        self.last_error_index = -1;
178        self.last_error_states = None;
179    }
180
181    fn report_no_viable_alternative<T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
182        &self,
183        recognizer: &mut T,
184        e: &NoViableAltError,
185    ) -> String {
186        let input = if e.start_token.token_type == TOKEN_EOF {
187            "<EOF>".to_owned()
188        } else {
189            recognizer.get_input_stream_mut().get_text_from_interval(
190                e.start_token.get_token_index(),
191                e.base.offending_token.get_token_index(),
192            )
193        };
194
195        format!("no viable alternative at input '{}'", input)
196    }
197
198    fn report_input_mismatch<T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
199        &self,
200        recognizer: &T,
201        e: &InputMisMatchError,
202    ) -> String {
203        format!(
204            "mismatched input {} expecting {}",
205            self.get_token_error_display(&e.base.offending_token),
206            e.base
207                .get_expected_tokens(recognizer)
208                .to_token_string(recognizer.get_vocabulary())
209        )
210    }
211
212    fn report_failed_predicate<T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
213        &self,
214        recognizer: &T,
215        e: &FailedPredicateError,
216    ) -> String {
217        format!(
218            "rule {} {}",
219            recognizer.get_rule_names()[recognizer.get_parser_rule_context().get_rule_index()],
220            e.base.message
221        )
222    }
223
224    fn report_unwanted_token<T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
225        &mut self,
226        recognizer: &mut T,
227    ) {
228        if self.in_error_recovery_mode(recognizer) {
229            return;
230        }
231
232        self.begin_error_condition(recognizer);
233        let expecting = self.get_expected_tokens(recognizer);
234        let expecting = expecting.to_token_string(recognizer.get_vocabulary());
235        let t = recognizer.get_current_token().borrow();
236        let token_name = self.get_token_error_display(t);
237        let msg = format!("extraneous input {} expecting {}", token_name, expecting);
238        let t = t.get_token_index();
239        recognizer.notify_error_listeners(msg, Some(t), None);
240    }
241
242    fn report_missing_token<T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
243        &mut self,
244        recognizer: &mut T,
245    ) {
246        if self.in_error_recovery_mode(recognizer) {
247            return;
248        }
249
250        self.begin_error_condition(recognizer);
251        let expecting = self.get_expected_tokens(recognizer);
252        let expecting = expecting.to_token_string(recognizer.get_vocabulary());
253        let t = recognizer.get_current_token().borrow();
254        let _token_name = self.get_token_error_display(t);
255        let msg = format!(
256            "missing {} at {}",
257            expecting,
258            self.get_token_error_display(t)
259        );
260        let t = t.get_token_index();
261        recognizer.notify_error_listeners(msg, Some(t), None);
262    }
263
264    fn single_token_insertion<T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
265        &mut self,
266        recognizer: &mut T,
267    ) -> bool {
268        let current_token = recognizer.get_input_stream_mut().la(1);
269
270        let atn = recognizer.get_interpreter().atn();
271        let current_state = atn.states[recognizer.get_state() as usize].as_ref();
272        let next = current_state
273            .get_transitions()
274            .first()
275            .unwrap()
276            .get_target();
277        let expect_at_ll2 = atn.next_tokens_in_ctx::<Ctx>(
278            atn.states[next].as_ref(),
279            Some(recognizer.get_parser_rule_context().deref()),
280        );
281        if expect_at_ll2.contains(current_token) {
282            self.report_missing_token(recognizer);
283            return true;
284        }
285        false
286    }
287
288    fn single_token_deletion<'a, T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
289        &mut self,
290        recognizer: &'a mut T,
291    ) -> Option<&'a <T::TF as TokenFactory<'input>>::Tok> {
292        let next_token_type = recognizer.get_input_stream_mut().la(2);
293        let expecting = self.get_expected_tokens(recognizer);
294        //        println!("expecting {}", expecting.to_token_string(recognizer.get_vocabulary()));
295        if expecting.contains(next_token_type) {
296            self.report_unwanted_token(recognizer);
297            recognizer.consume(self);
298            self.report_match(recognizer);
299            let matched_symbol = recognizer.get_current_token();
300            return Some(matched_symbol);
301        }
302        None
303    }
304
305    fn get_missing_symbol<T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
306        &self,
307        recognizer: &mut T,
308    ) -> <T::TF as TokenFactory<'input>>::Tok {
309        let expected = self.get_expected_tokens(recognizer);
310        let expected_token_type = expected.get_min().unwrap_or(TOKEN_INVALID_TYPE);
311        let token_text = if expected_token_type == TOKEN_EOF {
312            "<missing EOF>".to_owned()
313        } else {
314            format!(
315                "<missing {}>",
316                recognizer
317                    .get_vocabulary()
318                    .get_display_name(expected_token_type)
319            )
320        };
321        let token_text = <T::TF as TokenFactory<'input>>::Data::from_text(&token_text);
322        let mut curr = recognizer.get_current_token().borrow();
323        if curr.get_token_type() == TOKEN_EOF {
324            curr = recognizer
325                .get_input_stream()
326                .run(|it| it.get((it.index() - 1).max(0)).borrow());
327        }
328        let (line, column) = (curr.get_line(), curr.get_column());
329        recognizer.get_token_factory().create(
330            None::<&mut dyn CharStream<<Ctx::TF as TokenFactory<'input>>::From>>,
331            expected_token_type,
332            Some(token_text),
333            TOKEN_DEFAULT_CHANNEL,
334            -1,
335            -1,
336            line,
337            column,
338        )
339        // Token::to_owned(token.borrow())
340        // .modify_with(|it| it.text = token_text)
341    }
342
343    fn get_expected_tokens<T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
344        &self,
345        recognizer: &T,
346    ) -> IntervalSet {
347        recognizer.get_expected_tokens()
348    }
349
350    fn get_token_error_display<T: Token + ?Sized>(&self, t: &T) -> String {
351        let text = t.get_text().to_display();
352        self.escape_ws_and_quote(&text)
353    }
354
355    fn escape_ws_and_quote(&self, s: &str) -> String {
356        format!("'{}'", escape_whitespaces(s, false))
357    }
358
359    fn get_error_recovery_set<T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
360        &self,
361        recognizer: &T,
362    ) -> IntervalSet {
363        let atn = recognizer.get_interpreter().atn();
364        let mut ctx = Some(recognizer.get_parser_rule_context().clone());
365        let mut recover_set = IntervalSet::new();
366        while let Some(c) = ctx {
367            if c.get_invoking_state() < 0 {
368                break;
369            }
370
371            let invoking_state = atn.states[c.get_invoking_state() as usize].as_ref();
372            let tr = invoking_state.get_transitions().first().unwrap().as_ref();
373            let tr = tr.cast::<RuleTransition>();
374            let follow = atn.next_tokens(atn.states[tr.follow_state].as_ref());
375            recover_set.add_set(follow);
376            ctx = c.get_parent_ctx();
377        }
378        recover_set.remove_one(TOKEN_EPSILON);
379        return recover_set;
380    }
381
382    fn consume_until<T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
383        &mut self,
384        recognizer: &mut T,
385        set: &IntervalSet,
386    ) {
387        let mut ttype = recognizer.get_input_stream_mut().la(1);
388        while ttype != TOKEN_EOF && !set.contains(ttype) {
389            recognizer.consume(self);
390            ttype = recognizer.get_input_stream_mut().la(1);
391        }
392    }
393}
394
395impl<'a, T: Parser<'a>> ErrorStrategy<'a, T> for DefaultErrorStrategy<'a, T::Node> {
396    fn reset(&mut self, recognizer: &mut T) { self.end_error_condition(recognizer) }
397
398    fn recover_inline(
399        &mut self,
400        recognizer: &mut T,
401    ) -> Result<<T::TF as TokenFactory<'a>>::Tok, ANTLRError> {
402        let t = self
403            .single_token_deletion(recognizer)
404            .map(|it| it.to_owned());
405        if let Some(t) = t {
406            recognizer.consume(self);
407            return Ok(t);
408        }
409
410        if self.single_token_insertion(recognizer) {
411            return Ok(self.get_missing_symbol(recognizer));
412        }
413
414        if let Some(next_tokens_ctx) = &self.next_tokens_ctx {
415            Err(ANTLRError::InputMismatchError(
416                InputMisMatchError::with_state(
417                    recognizer,
418                    self.next_tokens_state,
419                    next_tokens_ctx.clone(),
420                ),
421            ))
422        } else {
423            Err(ANTLRError::InputMismatchError(InputMisMatchError::new(
424                recognizer,
425            )))
426        }
427        //        Err(ANTLRError::IllegalStateError("aaa".to_string()))
428    }
429
430    fn recover(&mut self, recognizer: &mut T, _e: &ANTLRError) -> Result<(), ANTLRError> {
431        if self.last_error_index == recognizer.get_input_stream_mut().index()
432            && self.last_error_states.is_some()
433            && self
434                .last_error_states
435                .as_ref()
436                .unwrap()
437                .contains(recognizer.get_state())
438        {
439            recognizer.consume(self)
440        }
441
442        self.last_error_index = recognizer.get_input_stream_mut().index();
443        self.last_error_states
444            .get_or_insert(IntervalSet::new())
445            .apply(|x| x.add_one(recognizer.get_state()));
446        let follow_set = self.get_error_recovery_set(recognizer);
447        self.consume_until(recognizer, &follow_set);
448        Ok(())
449    }
450
451    fn sync(&mut self, recognizer: &mut T) -> Result<(), ANTLRError> {
452        if self.in_error_recovery_mode(recognizer) {
453            return Ok(());
454        }
455        let next = recognizer.get_input_stream_mut().la(1);
456        let state =
457            recognizer.get_interpreter().atn().states[recognizer.get_state() as usize].as_ref();
458
459        let next_tokens = recognizer.get_interpreter().atn().next_tokens(state);
460        //        println!("{:?}",next_tokens);
461
462        if next_tokens.contains(next) {
463            self.next_tokens_state = ATNSTATE_INVALID_STATE_NUMBER;
464            self.next_tokens_ctx = None;
465            return Ok(());
466        }
467
468        if next_tokens.contains(TOKEN_EPSILON) {
469            if self.next_tokens_ctx.is_none() {
470                self.next_tokens_state = recognizer.get_state();
471                self.next_tokens_ctx = Some(recognizer.get_parser_rule_context().clone());
472            }
473            return Ok(());
474        }
475
476        match state.get_state_type_id() {
477            ATNSTATE_BLOCK_START
478            | ATNSTATE_PLUS_BLOCK_START
479            | ATNSTATE_STAR_BLOCK_START
480            | ATNSTATE_STAR_LOOP_ENTRY => {
481                if self.single_token_deletion(recognizer).is_none() {
482                    return Err(ANTLRError::InputMismatchError(InputMisMatchError::new(
483                        recognizer,
484                    )));
485                }
486            }
487            ATNSTATE_PLUS_LOOP_BACK | ATNSTATE_STAR_LOOP_BACK => {
488                self.report_unwanted_token(recognizer);
489                let mut expecting = recognizer.get_expected_tokens();
490                expecting.add_set(&self.get_error_recovery_set(recognizer));
491                self.consume_until(recognizer, &expecting);
492            }
493            _ => panic!("invalid ANTState type id"),
494        }
495
496        Ok(())
497    }
498
499    fn in_error_recovery_mode(&mut self, _recognizer: &mut T) -> bool { self.error_recovery_mode }
500
501    fn report_error(&mut self, recognizer: &mut T, e: &ANTLRError) {
502        if self.in_error_recovery_mode(recognizer) {
503            return;
504        }
505
506        self.begin_error_condition(recognizer);
507        let msg = match e {
508            ANTLRError::NoAltError(e) => self.report_no_viable_alternative(recognizer, e),
509            ANTLRError::InputMismatchError(e) => self.report_input_mismatch(recognizer, e),
510            ANTLRError::PredicateError(e) => self.report_failed_predicate(recognizer, e),
511            _ => e.to_string(),
512        };
513        let offending_token_index = e.get_offending_token().map(|it| it.get_token_index());
514        recognizer.notify_error_listeners(msg, offending_token_index, Some(&e))
515    }
516
517    fn report_match(&mut self, recognizer: &mut T) {
518        self.end_error_condition(recognizer);
519        //println!("matched token succesfully {}", recognizer.get_input_stream().la(1))
520    }
521}
522
523/// This implementation of `ANTLRErrorStrategy` responds to syntax errors
524/// by immediately canceling the parse operation with a
525/// `ParseCancellationException`. The implementation ensures that the
526/// [`ParserRuleContext.exception`] field is set for all parse tree nodes
527/// that were not completed prior to encountering the error.
528///
529/// <p> This error strategy is useful in the following scenarios.</p>
530///
531///  - Two-stage parsing: This error strategy allows the first
532/// stage of two-stage parsing to immediately terminate if an error is
533/// encountered, and immediately fall back to the second stage. In addition to
534/// avoiding wasted work by attempting to recover from errors here, the empty
535/// implementation of `sync` improves the performance of
536/// the first stage.
537///  - Silent validation: When syntax errors are not being
538/// reported or logged, and the parse result is simply ignored if errors occur,
539/// the `BailErrorStrategy` avoids wasting work on recovering from errors
540/// when the result will be ignored either way.
541///
542/// # Usage
543/// ```ignore
544/// use antlr_rust::error_strategy::BailErrorStrategy;
545/// myparser.err_handler = BailErrorStrategy::new();
546/// ```
547///
548/// [`ParserRuleContext.exception`]: todo
549/// */
550#[derive(Default, Debug)]
551pub struct BailErrorStrategy<'input, Ctx: ParserNodeType<'input>>(
552    DefaultErrorStrategy<'input, Ctx>,
553);
554
555better_any::tid! {impl<'i,Ctx> TidAble<'i> for BailErrorStrategy<'i,Ctx> where Ctx:ParserNodeType<'i> }
556
557impl<'input, Ctx: ParserNodeType<'input>> BailErrorStrategy<'input, Ctx> {
558    /// Creates new instance of `BailErrorStrategy`
559    pub fn new() -> Self { Self(DefaultErrorStrategy::new()) }
560
561    fn process_error<T: Parser<'input, Node = Ctx, TF = Ctx::TF>>(
562        &self,
563        recognizer: &mut T,
564        e: &ANTLRError,
565    ) -> ANTLRError {
566        let mut ctx = recognizer.get_parser_rule_context().clone();
567        let _: Option<()> = (|| {
568            loop {
569                ctx.set_exception(e.clone());
570                ctx = ctx.get_parent()?
571            }
572            Some(())
573        })();
574        return ANTLRError::FallThrough(Rc::new(ParseCancelledError(e.clone())));
575    }
576}
577
578/// `ANTLRError::FallThrough` Error returned `BailErrorStrategy` to bail out from parsing
579#[derive(Debug)]
580pub struct ParseCancelledError(ANTLRError);
581
582impl Error for ParseCancelledError {
583    fn source(&self) -> Option<&(dyn Error + 'static)> { Some(&self.0) }
584}
585
586impl Display for ParseCancelledError {
587    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
588        f.write_str("ParseCancelledError, caused by ")?;
589        self.0.fmt(f)
590    }
591}
592
593impl<'a, T: Parser<'a>> ErrorStrategy<'a, T> for BailErrorStrategy<'a, T::Node> {
594    #[inline(always)]
595    fn reset(&mut self, recognizer: &mut T) { self.0.reset(recognizer) }
596
597    #[cold]
598    fn recover_inline(
599        &mut self,
600        recognizer: &mut T,
601    ) -> Result<<T::TF as TokenFactory<'a>>::Tok, ANTLRError> {
602        let err = ANTLRError::InputMismatchError(InputMisMatchError::new(recognizer));
603
604        Err(self.process_error(recognizer, &err))
605    }
606
607    #[cold]
608    fn recover(&mut self, recognizer: &mut T, e: &ANTLRError) -> Result<(), ANTLRError> {
609        Err(self.process_error(recognizer, &e))
610    }
611
612    #[inline(always)]
613    fn sync(&mut self, _recognizer: &mut T) -> Result<(), ANTLRError> {
614        /* empty */
615        Ok(())
616    }
617
618    #[inline(always)]
619    fn in_error_recovery_mode(&mut self, recognizer: &mut T) -> bool {
620        self.0.in_error_recovery_mode(recognizer)
621    }
622
623    #[inline(always)]
624    fn report_error(&mut self, recognizer: &mut T, e: &ANTLRError) {
625        self.0.report_error(recognizer, e)
626    }
627
628    #[inline(always)]
629    fn report_match(&mut self, _recognizer: &mut T) {}
630}