Skip to main content

dbt_antlr4/
error_strategy.rs

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