1use 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
25pub trait ErrorStrategy<'input, 'arena, TF, P>
37where
38 'input: 'arena,
39 TF: TokenFactory<'input, 'arena> + 'arena,
40 P: Parser<'input, 'arena, TF>,
41{
42 fn reset(&mut self, recognizer: &mut P);
44
45 fn recover_inline(&mut self, recognizer: &mut P) -> Result<&'arena TF::Tok, ANTLRError>;
60
61 fn recover(&mut self, recognizer: &mut P, e: &ANTLRError) -> Result<(), ANTLRError>;
67
68 fn sync(&mut self, recognizer: &mut P) -> Result<(), ANTLRError>;
76
77 fn in_error_recovery_mode(&mut self, recognizer: &mut P) -> bool;
81
82 fn report_error(&mut self, recognizer: &mut P, e: &ANTLRError);
85
86 fn report_match(&mut self, recognizer: &mut P);
89}
90
91#[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 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 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 }
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 }
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 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 }
457}
458
459#[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 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#[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 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
574pub 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 _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 pub unsafe fn new(s: Box<dyn ErrorStrategy<'input, 'arena, TF, P> + 'arena>) -> Self {
603 let raw = Box::into_raw(s);
604 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 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}