1use std::collections::{BTreeMap, BTreeSet};
2
3use crate::atn::{Atn, AtnState, AtnStateKind, Transition};
4use crate::errors::AntlrError;
5use crate::int_stream::IntStream;
6use crate::recognizer::{Recognizer, RecognizerData};
7use crate::token::{CommonToken, TOKEN_EOF, Token, TokenSource, TokenSourceError};
8use crate::token_stream::CommonTokenStream;
9use crate::tree::{ErrorNode, ParseTree, ParserRuleContext, RuleNode, TerminalNode};
10use crate::vocabulary::Vocabulary;
11
12const RECOGNITION_DEPTH_LIMIT: usize = 100_000;
16
17#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
26pub struct ParserAction {
27 source_state: usize,
28 rule_index: usize,
29 start_index: usize,
30 stop_index: Option<usize>,
31 rule_init: bool,
32 expected_state: Option<usize>,
33}
34
35impl ParserAction {
36 pub const fn new(
38 source_state: usize,
39 rule_index: usize,
40 start_index: usize,
41 stop_index: Option<usize>,
42 ) -> Self {
43 Self {
44 source_state,
45 rule_index,
46 start_index,
47 stop_index,
48 rule_init: false,
49 expected_state: None,
50 }
51 }
52
53 pub const fn new_rule_init(
55 rule_index: usize,
56 start_index: usize,
57 expected_state: Option<usize>,
58 ) -> Self {
59 Self {
60 source_state: usize::MAX,
61 rule_index,
62 start_index,
63 stop_index: None,
64 rule_init: true,
65 expected_state,
66 }
67 }
68
69 pub const fn source_state(&self) -> usize {
71 self.source_state
72 }
73
74 pub const fn rule_index(&self) -> usize {
76 self.rule_index
77 }
78
79 pub const fn start_index(&self) -> usize {
81 self.start_index
82 }
83
84 pub const fn stop_index(&self) -> Option<usize> {
86 self.stop_index
87 }
88
89 pub const fn is_rule_init(&self) -> bool {
91 self.rule_init
92 }
93
94 pub const fn expected_state(&self) -> Option<usize> {
96 self.expected_state
97 }
98}
99
100#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
107pub enum ParserPredicate {
108 True,
109 False,
110 FalseWithMessage {
112 message: &'static str,
113 },
114 Invoke {
117 value: bool,
118 },
119 LookaheadTextEquals {
120 offset: isize,
121 text: &'static str,
122 },
123 LookaheadNotEquals {
124 offset: isize,
125 token_type: i32,
126 },
127 LocalIntEquals {
130 value: i64,
131 },
132 LocalIntLessOrEqual {
135 value: i64,
136 },
137 MemberModuloEquals {
139 member: usize,
140 modulus: i64,
141 value: i64,
142 equals: bool,
143 },
144}
145
146#[derive(Clone, Copy, Debug, Eq, PartialEq)]
148pub enum PredictionMode {
149 Ll,
152 Sll,
155}
156
157#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
163pub struct ParserRuleArg {
164 pub source_state: usize,
166 pub rule_index: usize,
168 pub value: i64,
170 pub inherit_local: bool,
172}
173
174#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
176pub struct ParserMemberAction {
177 pub source_state: usize,
179 pub member: usize,
181 pub delta: i64,
183}
184
185#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
192pub struct ParserReturnAction {
193 pub source_state: usize,
195 pub rule_index: usize,
197 pub name: &'static str,
199 pub value: i64,
201}
202
203#[derive(Clone, Copy, Debug, Default)]
205pub struct ParserRuntimeOptions<'a> {
206 pub init_action_rules: &'a [usize],
208 pub track_alt_numbers: bool,
210 pub predicates: &'a [(usize, usize, ParserPredicate)],
212 pub rule_args: &'a [ParserRuleArg],
214 pub member_actions: &'a [ParserMemberAction],
216 pub return_actions: &'a [ParserReturnAction],
218}
219
220pub trait Parser: Recognizer {
221 fn build_parse_trees(&self) -> bool;
224
225 fn set_build_parse_trees(&mut self, build: bool);
227
228 fn report_diagnostic_errors(&self) -> bool {
231 false
232 }
233
234 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
237
238 fn prediction_mode(&self) -> PredictionMode {
240 PredictionMode::Ll
241 }
242
243 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
245}
246
247#[derive(Debug)]
248pub struct BaseParser<S> {
249 input: CommonTokenStream<S>,
250 data: RecognizerData,
251 build_parse_trees: bool,
252 report_diagnostic_errors: bool,
253 prediction_mode: PredictionMode,
254 prediction_diagnostics: Vec<ParserDiagnostic>,
255 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
256 int_members: BTreeMap<usize, i64>,
257 invoked_predicates: Vec<(usize, usize)>,
261}
262
263#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
264struct RecognizeOutcome {
265 index: usize,
266 consumed_eof: bool,
267 alt_number: usize,
268 member_values: BTreeMap<usize, i64>,
269 return_values: BTreeMap<String, i64>,
270 diagnostics: Vec<ParserDiagnostic>,
271 decisions: Vec<usize>,
272 actions: Vec<ParserAction>,
273 nodes: Vec<RecognizedNode>,
274}
275
276#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
277enum RecognizedNode {
278 Token {
279 index: usize,
280 },
281 ErrorToken {
282 index: usize,
283 },
284 MissingToken {
285 token_type: i32,
286 at_index: usize,
287 text: String,
288 },
289 Rule {
290 rule_index: usize,
291 invoking_state: isize,
292 alt_number: usize,
293 start_index: usize,
294 stop_index: Option<usize>,
295 return_values: BTreeMap<String, i64>,
296 children: Vec<Self>,
297 },
298 LeftRecursiveBoundary {
299 rule_index: usize,
300 },
301}
302
303#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
304struct FastRecognizeOutcome {
305 index: usize,
306 consumed_eof: bool,
307 diagnostics: Vec<ParserDiagnostic>,
308}
309
310#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
311struct ParserDiagnostic {
312 line: usize,
313 column: usize,
314 message: String,
315}
316
317#[derive(Clone, Debug, Default, Eq, PartialEq)]
318struct ExpectedTokens {
319 index: Option<usize>,
320 symbols: BTreeSet<i32>,
321 no_viable: Option<NoViableAlternative>,
322}
323
324#[derive(Clone, Copy, Debug, Eq, PartialEq)]
325struct NoViableAlternative {
326 start_index: usize,
327 error_index: usize,
328}
329
330impl ExpectedTokens {
331 fn record_transition(&mut self, index: usize, transition: &Transition, max_token_type: i32) {
334 let symbols = transition_expected_symbols(transition, max_token_type);
335 match self.index {
336 Some(current) if index < current => {}
337 Some(current) if index == current => self.symbols.extend(symbols),
338 _ => {
339 self.index = Some(index);
340 self.symbols = symbols;
341 }
342 }
343 }
344
345 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
348 match self.no_viable {
349 Some(current) if error_index < current.error_index => {}
350 _ => {
351 self.no_viable = Some(NoViableAlternative {
352 start_index,
353 error_index,
354 });
355 }
356 }
357 }
358}
359
360fn transition_expected_symbols(transition: &Transition, max_token_type: i32) -> BTreeSet<i32> {
363 let mut symbols = BTreeSet::new();
364 match transition {
365 Transition::Atom { label, .. } => {
366 symbols.insert(*label);
367 }
368 Transition::Range { start, stop, .. } => {
369 symbols.extend(*start..=*stop);
370 }
371 Transition::Set { set, .. } => {
372 for (start, stop) in set.ranges() {
373 symbols.extend(*start..=*stop);
374 }
375 }
376 Transition::NotSet { set, .. } => {
377 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
378 }
379 Transition::Wildcard { .. } => {
380 symbols.extend(1..=max_token_type);
381 }
382 Transition::Epsilon { .. }
383 | Transition::Rule { .. }
384 | Transition::Predicate { .. }
385 | Transition::Action { .. }
386 | Transition::Precedence { .. } => {}
387 }
388 symbols
389}
390
391fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
395 let mut symbols = BTreeSet::new();
396 let mut stack = vec![state_number];
397 let mut visited = BTreeSet::new();
398 while let Some(current) = stack.pop() {
399 if !visited.insert(current) {
400 continue;
401 }
402 let Some(state) = atn.state(current) else {
403 continue;
404 };
405 for transition in &state.transitions {
406 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
407 if transition_symbols.is_empty() {
408 if transition.is_epsilon() {
409 stack.push(transition.target());
410 }
411 } else {
412 symbols.extend(transition_symbols);
413 }
414 }
415 }
416 symbols
417}
418
419fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
422 let mut symbols = BTreeSet::new();
423 state_sync_symbols_inner(
424 atn,
425 state_number,
426 stop_state,
427 &mut BTreeSet::new(),
428 &mut symbols,
429 );
430 symbols
431}
432
433fn state_sync_symbols_inner(
436 atn: &Atn,
437 state_number: usize,
438 stop_state: usize,
439 visited: &mut BTreeSet<usize>,
440 symbols: &mut BTreeSet<i32>,
441) {
442 if !visited.insert(state_number) {
443 return;
444 }
445 if state_number == stop_state {
446 symbols.insert(TOKEN_EOF);
447 return;
448 }
449 let Some(state) = atn.state(state_number) else {
450 return;
451 };
452 for transition in &state.transitions {
453 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
454 if transition_symbols.is_empty() {
455 match transition {
456 Transition::Rule { target, .. }
457 | Transition::Epsilon { target }
458 | Transition::Action { target, .. }
459 | Transition::Predicate { target, .. }
460 | Transition::Precedence { target, .. } => {
461 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
462 }
463 Transition::Atom { .. }
464 | Transition::Range { .. }
465 | Transition::Set { .. }
466 | Transition::NotSet { .. }
467 | Transition::Wildcard { .. } => {}
468 }
469 } else {
470 symbols.extend(transition_symbols);
471 }
472 }
473}
474
475fn next_recovery_context(
479 atn: &Atn,
480 state: &AtnState,
481 inherited: &BTreeSet<i32>,
482 inherited_state: Option<usize>,
483) -> (BTreeSet<i32>, Option<usize>) {
484 let state_symbols = state_expected_symbols(atn, state.state_number);
485 if state.transitions.len() > 1 && !state_symbols.is_empty() {
486 let mut symbols = state_symbols;
487 symbols.extend(inherited.iter().copied());
488 return (symbols, Some(state.state_number));
489 }
490 (inherited.clone(), inherited_state)
491}
492
493fn recovery_expected_symbols(
494 atn: &Atn,
495 state_number: usize,
496 inherited: &BTreeSet<i32>,
497) -> BTreeSet<i32> {
498 let mut symbols = state_expected_symbols(atn, state_number);
499 symbols.extend(inherited.iter().copied());
500 symbols
501}
502
503fn apply_member_actions(
505 source_state: usize,
506 actions: &[ParserMemberAction],
507 values: &mut BTreeMap<usize, i64>,
508) {
509 for action in actions
510 .iter()
511 .filter(|action| action.source_state == source_state)
512 {
513 *values.entry(action.member).or_default() += action.delta;
514 }
515}
516
517fn member_values_after_action(
519 source_state: usize,
520 actions: &[ParserMemberAction],
521 values: &BTreeMap<usize, i64>,
522) -> BTreeMap<usize, i64> {
523 let mut values = values.clone();
524 apply_member_actions(source_state, actions, &mut values);
525 values
526}
527
528fn return_values_after_action(
530 source_state: usize,
531 rule_index: usize,
532 actions: &[ParserReturnAction],
533 values: &BTreeMap<String, i64>,
534) -> BTreeMap<String, i64> {
535 let mut values = values.clone();
536 for action in actions
537 .iter()
538 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
539 {
540 values.insert(action.name.to_owned(), action.value);
541 }
542 values
543}
544
545fn rule_local_int_arg(
547 rule_args: &[ParserRuleArg],
548 source_state: usize,
549 rule_index: usize,
550 local_int_arg: Option<(usize, i64)>,
551) -> Option<(usize, i64)> {
552 rule_args
553 .iter()
554 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
555 .map(|arg| {
556 let value = if arg.inherit_local {
557 local_int_arg.map_or(arg.value, |(_, value)| value)
558 } else {
559 arg.value
560 };
561 (rule_index, value)
562 })
563}
564
565fn stop_outcome(
568 index: usize,
569 consumed_eof: bool,
570 rule_alt_number: usize,
571 member_values: BTreeMap<usize, i64>,
572 return_values: BTreeMap<String, i64>,
573) -> Vec<RecognizeOutcome> {
574 vec![RecognizeOutcome {
575 index,
576 consumed_eof,
577 alt_number: rule_alt_number,
578 member_values,
579 return_values,
580 diagnostics: Vec::new(),
581 decisions: Vec::new(),
582 actions: Vec::new(),
583 nodes: Vec::new(),
584 }]
585}
586
587#[derive(Clone, Debug, Eq, PartialEq)]
588struct RecognizeRequest<'a> {
589 state_number: usize,
590 stop_state: usize,
591 index: usize,
592 rule_start_index: usize,
593 decision_start_index: Option<usize>,
594 init_action_rules: &'a BTreeSet<usize>,
595 predicates: &'a [(usize, usize, ParserPredicate)],
596 rule_args: &'a [ParserRuleArg],
597 member_actions: &'a [ParserMemberAction],
598 return_actions: &'a [ParserReturnAction],
599 local_int_arg: Option<(usize, i64)>,
600 member_values: BTreeMap<usize, i64>,
601 return_values: BTreeMap<String, i64>,
602 rule_alt_number: usize,
603 track_alt_numbers: bool,
604 consumed_eof: bool,
605 precedence: i32,
608 depth: usize,
609 recovery_symbols: BTreeSet<i32>,
610 recovery_state: Option<usize>,
611}
612
613#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
614struct RecognizeKey {
615 state_number: usize,
616 stop_state: usize,
617 index: usize,
618 rule_start_index: usize,
619 decision_start_index: Option<usize>,
620 local_int_arg: Option<(usize, i64)>,
621 member_values: BTreeMap<usize, i64>,
622 return_values: BTreeMap<String, i64>,
623 rule_alt_number: usize,
624 track_alt_numbers: bool,
625 consumed_eof: bool,
626 precedence: i32,
627 recovery_symbols: BTreeSet<i32>,
628 recovery_state: Option<usize>,
629}
630
631#[derive(Clone, Debug, Eq, PartialEq)]
632struct EpsilonActionStep {
633 source_state: usize,
634 target: usize,
635 action_rule_index: Option<usize>,
636 left_recursive_boundary: Option<usize>,
637 decision: Option<usize>,
638 decision_start_index: Option<usize>,
639 alt_number: usize,
640 recovery_symbols: BTreeSet<i32>,
641 recovery_state: Option<usize>,
642}
643
644struct RecognizeScratch<'a> {
645 visiting: &'a mut BTreeSet<RecognizeKey>,
646 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
647 expected: &'a mut ExpectedTokens,
648}
649
650#[derive(Clone, Debug, Eq, PartialEq)]
651struct FastRecognizeRequest {
652 state_number: usize,
653 stop_state: usize,
654 index: usize,
655 rule_start_index: usize,
656 decision_start_index: Option<usize>,
657 precedence: i32,
658 depth: usize,
659 recovery_symbols: BTreeSet<i32>,
660 recovery_state: Option<usize>,
661}
662
663#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
664struct FastRecognizeKey {
665 state_number: usize,
666 stop_state: usize,
667 index: usize,
668 rule_start_index: usize,
669 decision_start_index: Option<usize>,
670 precedence: i32,
671 recovery_symbols: BTreeSet<i32>,
672 recovery_state: Option<usize>,
673}
674
675struct FastRecoveryRequest<'a, 'b> {
676 atn: &'a Atn,
677 transition: &'a Transition,
678 expected_symbols: BTreeSet<i32>,
679 target: usize,
680 request: FastRecognizeRequest,
681 visiting: &'b mut BTreeSet<FastRecognizeKey>,
682 memo: &'b mut BTreeMap<FastRecognizeKey, Vec<FastRecognizeOutcome>>,
683 expected: &'b mut ExpectedTokens,
684}
685
686struct FastCurrentTokenDeletionRequest<'a, 'b> {
687 atn: &'a Atn,
688 expected_symbols: BTreeSet<i32>,
689 request: FastRecognizeRequest,
690 visiting: &'b mut BTreeSet<FastRecognizeKey>,
691 memo: &'b mut BTreeMap<FastRecognizeKey, Vec<FastRecognizeOutcome>>,
692 expected: &'b mut ExpectedTokens,
693}
694
695struct RecoveryRequest<'a, 'b> {
696 atn: &'a Atn,
697 transition: &'a Transition,
698 expected_symbols: BTreeSet<i32>,
699 target: usize,
700 request: RecognizeRequest<'a>,
701 visiting: &'b mut BTreeSet<RecognizeKey>,
702 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
703 expected: &'b mut ExpectedTokens,
704}
705
706struct CurrentTokenDeletionRequest<'a, 'b> {
707 atn: &'a Atn,
708 expected_symbols: BTreeSet<i32>,
709 request: RecognizeRequest<'a>,
710 visiting: &'b mut BTreeSet<RecognizeKey>,
711 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
712 expected: &'b mut ExpectedTokens,
713}
714
715struct ConsumingFailureFallback<'a> {
718 atn: &'a Atn,
719 target: usize,
720 request: RecognizeRequest<'a>,
721 symbol: i32,
722 expected_symbols: BTreeSet<i32>,
723 decision_start_index: Option<usize>,
724 decision: Option<usize>,
725}
726
727struct ChildRuleFailureRecovery<'a> {
730 atn: &'a Atn,
731 rule_index: usize,
732 start_index: usize,
733 follow_state: usize,
734 stop_state: usize,
735 member_values: BTreeMap<usize, i64>,
736 expected: &'a ExpectedTokens,
737}
738
739#[derive(Clone, Copy, Debug)]
741struct PredicateEval<'a> {
742 index: usize,
743 rule_index: usize,
744 pred_index: usize,
745 predicates: &'a [(usize, usize, ParserPredicate)],
746 local_int_arg: Option<(usize, i64)>,
747 member_values: &'a BTreeMap<usize, i64>,
748}
749
750struct PredicateFailureRecovery<'a> {
752 rule_index: usize,
753 index: usize,
754 message: &'a str,
755 member_values: BTreeMap<usize, i64>,
756 return_values: BTreeMap<String, i64>,
757 rule_alt_number: usize,
758}
759
760impl<S> BaseParser<S>
761where
762 S: TokenSource,
763{
764 pub const fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
767 Self {
768 input,
769 data,
770 build_parse_trees: true,
771 report_diagnostic_errors: false,
772 prediction_mode: PredictionMode::Ll,
773 prediction_diagnostics: Vec::new(),
774 reported_prediction_diagnostics: BTreeSet::new(),
775 int_members: BTreeMap::new(),
776 invoked_predicates: Vec::new(),
777 }
778 }
779
780 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
781 &mut self.input
782 }
783
784 pub fn la(&mut self, offset: isize) -> i32 {
785 self.input.la_token(offset)
786 }
787
788 pub fn consume(&mut self) {
789 IntStream::consume(&mut self.input);
790 }
791
792 pub fn set_int_member(&mut self, member: usize, value: i64) {
794 self.int_members.insert(member, value);
795 }
796
797 pub fn int_member(&self, member: usize) -> Option<i64> {
799 self.int_members.get(&member).copied()
800 }
801
802 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
804 let value = self.int_members.entry(member).or_default();
805 *value += delta;
806 *value
807 }
808
809 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
816 let current = self
817 .input
818 .lt(1)
819 .cloned()
820 .ok_or_else(|| AntlrError::ParserError {
821 line: 0,
822 column: 0,
823 message: "missing current token".to_owned(),
824 })?;
825 if current.token_type() == token_type {
826 self.consume();
827 Ok(ParseTree::Terminal(TerminalNode::new(current)))
828 } else {
829 Err(AntlrError::MismatchedInput {
830 expected: self.vocabulary().display_name(token_type),
831 found: self.vocabulary().display_name(current.token_type()),
832 })
833 }
834 }
835
836 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
837 self.match_token(TOKEN_EOF)
838 }
839
840 pub const fn rule_node(&self, context: ParserRuleContext) -> ParseTree {
841 ParseTree::Rule(RuleNode::new(context))
842 }
843
844 pub fn parse_atn_rule(
854 &mut self,
855 atn: &Atn,
856 rule_index: usize,
857 ) -> Result<ParseTree, AntlrError> {
858 let start_state = atn
859 .rule_to_start_state()
860 .get(rule_index)
861 .copied()
862 .ok_or_else(|| {
863 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
864 })?;
865 let stop_state = atn
866 .rule_to_stop_state()
867 .get(rule_index)
868 .copied()
869 .filter(|state| *state != usize::MAX)
870 .ok_or_else(|| {
871 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
872 })?;
873
874 let start_index = self.current_visible_index();
875 self.clear_prediction_diagnostics();
876 let mut visiting = BTreeSet::new();
877 let mut memo = BTreeMap::new();
878 let mut expected = ExpectedTokens::default();
879 let outcomes = self.recognize_state_fast(
880 atn,
881 FastRecognizeRequest {
882 state_number: start_state,
883 stop_state,
884 index: start_index,
885 rule_start_index: start_index,
886 decision_start_index: None,
887 precedence: 0,
888 depth: 0,
889 recovery_symbols: BTreeSet::new(),
890 recovery_state: None,
891 },
892 &mut visiting,
893 &mut memo,
894 &mut expected,
895 );
896 let Some(outcome) = select_best_fast_outcome(outcomes.into_iter(), self.prediction_mode)
897 else {
898 let error = self.recognition_error(rule_index, start_index, &expected);
899 report_token_source_errors(&self.input.drain_source_errors());
900 return Err(error);
901 };
902
903 report_parser_diagnostics(&self.prediction_diagnostics);
904 report_parser_diagnostics(&outcome.diagnostics);
905 report_token_source_errors(&self.input.drain_source_errors());
906 let mut context = ParserRuleContext::new(rule_index, self.state());
907 if let Some(token) = self.token_at(start_index) {
908 context.set_start(token);
909 }
910 if let Some(token) = self.rule_stop_token(outcome.index, outcome.consumed_eof) {
911 context.set_stop(token);
912 }
913 self.input.seek(start_index);
914 while self.input.index() < outcome.index {
915 let token_type = self.la(1);
916 let child = self.match_token(token_type)?;
917 if self.build_parse_trees {
918 context.add_child(child);
919 }
920 }
921 if outcome.consumed_eof && self.la(1) == TOKEN_EOF && self.build_parse_trees {
922 context.add_child(self.match_eof()?);
923 }
924
925 Ok(self.rule_node(context))
926 }
927
928 pub fn parse_atn_rule_with_actions(
935 &mut self,
936 atn: &Atn,
937 rule_index: usize,
938 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
939 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
940 }
941
942 pub fn parse_atn_rule_with_action_inits(
950 &mut self,
951 atn: &Atn,
952 rule_index: usize,
953 init_action_rules: &[usize],
954 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
955 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
956 }
957
958 pub fn parse_atn_rule_with_action_options(
964 &mut self,
965 atn: &Atn,
966 rule_index: usize,
967 init_action_rules: &[usize],
968 track_alt_numbers: bool,
969 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
970 self.parse_atn_rule_with_runtime_options(
971 atn,
972 rule_index,
973 ParserRuntimeOptions {
974 init_action_rules,
975 track_alt_numbers,
976 ..ParserRuntimeOptions::default()
977 },
978 )
979 }
980
981 pub fn parse_atn_rule_with_runtime_options(
988 &mut self,
989 atn: &Atn,
990 rule_index: usize,
991 options: ParserRuntimeOptions<'_>,
992 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
993 let ParserRuntimeOptions {
994 init_action_rules,
995 track_alt_numbers,
996 predicates,
997 rule_args,
998 member_actions,
999 return_actions,
1000 } = options;
1001 let start_state = atn
1002 .rule_to_start_state()
1003 .get(rule_index)
1004 .copied()
1005 .ok_or_else(|| {
1006 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
1007 })?;
1008 let stop_state = atn
1009 .rule_to_stop_state()
1010 .get(rule_index)
1011 .copied()
1012 .filter(|state| *state != usize::MAX)
1013 .ok_or_else(|| {
1014 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
1015 })?;
1016
1017 let start_index = self.current_visible_index();
1018 self.clear_prediction_diagnostics();
1019 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
1020 let mut visiting = BTreeSet::new();
1021 let mut memo = BTreeMap::new();
1022 let mut expected = ExpectedTokens::default();
1023 let member_values = self.int_members.clone();
1024 let return_values = BTreeMap::new();
1025 let outcomes = self.recognize_state(
1026 atn,
1027 RecognizeRequest {
1028 state_number: start_state,
1029 stop_state,
1030 index: start_index,
1031 rule_start_index: start_index,
1032 decision_start_index: None,
1033 init_action_rules: &init_action_rules,
1034 predicates,
1035 rule_args,
1036 member_actions,
1037 return_actions,
1038 local_int_arg: None,
1039 member_values,
1040 return_values,
1041 rule_alt_number: 0,
1042 track_alt_numbers,
1043 consumed_eof: false,
1044 precedence: 0,
1045 depth: 0,
1046 recovery_symbols: BTreeSet::new(),
1047 recovery_state: None,
1048 },
1049 &mut visiting,
1050 &mut memo,
1051 &mut expected,
1052 );
1053 let Some(outcome) = select_best_outcome(outcomes.into_iter(), self.prediction_mode) else {
1054 let error = self.recognition_error(rule_index, start_index, &expected);
1055 report_token_source_errors(&self.input.drain_source_errors());
1056 return Err(error);
1057 };
1058
1059 report_parser_diagnostics(&self.prediction_diagnostics);
1060 report_parser_diagnostics(&outcome.diagnostics);
1061 report_token_source_errors(&self.input.drain_source_errors());
1062 let mut actions = outcome.actions;
1063 if init_action_rules.contains(&rule_index) {
1064 actions.insert(
1065 0,
1066 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
1067 );
1068 }
1069 let mut context = ParserRuleContext::new(rule_index, self.state());
1070 if track_alt_numbers {
1071 context.set_alt_number(outcome.alt_number);
1072 }
1073 for (name, value) in outcome.return_values {
1074 context.set_int_return(name, value);
1075 }
1076 if let Some(token) = self.token_at(start_index) {
1077 context.set_start(token);
1078 }
1079 if let Some(token) = self.rule_stop_token(outcome.index, outcome.consumed_eof) {
1080 context.set_stop(token);
1081 }
1082 if self.build_parse_trees {
1083 let nodes = fold_left_recursive_boundaries(outcome.nodes);
1084 for node in &nodes {
1085 context.add_child(self.recognized_node_tree(node, track_alt_numbers)?);
1086 }
1087 }
1088 self.input.seek(outcome.index);
1089
1090 Ok((self.rule_node(context), actions))
1091 }
1092
1093 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
1100 let mut context = ParserRuleContext::new(rule_index, self.state());
1101 while self.la(1) != TOKEN_EOF {
1102 let token_type = self.la(1);
1103 let child = self.match_token(token_type)?;
1104 if self.build_parse_trees {
1105 context.add_child(child);
1106 }
1107 }
1108 if self.build_parse_trees {
1109 context.add_child(self.match_eof()?);
1110 }
1111 Ok(self.rule_node(context))
1112 }
1113
1114 fn recognition_error(
1117 &mut self,
1118 rule_index: usize,
1119 start_index: usize,
1120 expected: &ExpectedTokens,
1121 ) -> AntlrError {
1122 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
1123 self.input.seek(index);
1124 let current = self.input.lt(1).cloned();
1125 let line = current.as_ref().map(Token::line).unwrap_or_default();
1126 let column = current.as_ref().map(Token::column).unwrap_or_default();
1127 AntlrError::ParserError {
1128 line,
1129 column,
1130 message,
1131 }
1132 }
1133
1134 fn expected_error_message(
1136 &mut self,
1137 rule_index: usize,
1138 start_index: usize,
1139 expected: &ExpectedTokens,
1140 ) -> (usize, String) {
1141 let index = expected
1142 .index
1143 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
1144 .unwrap_or_else(|| self.input.index());
1145 self.input.seek(index);
1146 let current = self.input.lt(1).cloned();
1147 let message = if expected
1148 .no_viable
1149 .as_ref()
1150 .is_some_and(|no_viable| no_viable.error_index == index)
1151 {
1152 let start = expected
1153 .no_viable
1154 .as_ref()
1155 .map_or(start_index, |no_viable| no_viable.start_index);
1156 let text = display_input_text(&self.input.text(start, index));
1157 format!("no viable alternative at input '{text}'")
1158 } else if expected.symbols.is_empty() {
1159 if expected.index.is_some() {
1160 let found = current
1161 .as_ref()
1162 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
1163 if current
1164 .as_ref()
1165 .is_some_and(|token| token.token_type() == TOKEN_EOF)
1166 {
1167 format!(
1168 "missing {} at {found}",
1169 self.expected_symbols_display(&expected.symbols)
1170 )
1171 } else {
1172 format!("mismatched input {found}")
1173 }
1174 } else {
1175 format!("no viable alternative while parsing rule {rule_index}")
1176 }
1177 } else {
1178 format!(
1179 "mismatched input {} expecting {}",
1180 current
1181 .as_ref()
1182 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
1183 self.expected_symbols_display(&expected.symbols)
1184 )
1185 };
1186 (index, message)
1187 }
1188
1189 fn child_rule_failure_recovery(
1192 &mut self,
1193 rule_index: usize,
1194 start_index: usize,
1195 sync_symbols: &BTreeSet<i32>,
1196 member_values: BTreeMap<usize, i64>,
1197 expected: &ExpectedTokens,
1198 ) -> Option<RecognizeOutcome> {
1199 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
1200 let token = self.token_at(error_index);
1201 let mut next_index = error_index;
1202 loop {
1203 let symbol = self.token_type_at(next_index);
1204 if sync_symbols.contains(&symbol) {
1205 if next_index == error_index {
1206 return None;
1207 }
1208 break;
1209 }
1210 if symbol == TOKEN_EOF {
1211 break;
1212 }
1213 let after = self.consume_index(next_index, symbol);
1214 if after == next_index {
1215 break;
1216 }
1217 next_index = after;
1218 }
1219 Some(RecognizeOutcome {
1220 index: next_index,
1221 consumed_eof: false,
1222 alt_number: 0,
1223 member_values,
1224 return_values: BTreeMap::new(),
1225 diagnostics: vec![diagnostic_for_token(token.as_ref(), message)],
1226 decisions: Vec::new(),
1227 actions: Vec::new(),
1228 nodes: vec![RecognizedNode::ErrorToken { index: error_index }],
1229 })
1230 }
1231
1232 fn child_rule_failure_recovery_outcomes(
1235 &mut self,
1236 request: ChildRuleFailureRecovery<'_>,
1237 ) -> Vec<RecognizeOutcome> {
1238 let sync_symbols =
1239 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
1240 self.child_rule_failure_recovery(
1241 request.rule_index,
1242 request.start_index,
1243 &sync_symbols,
1244 request.member_values,
1245 request.expected,
1246 )
1247 .into_iter()
1248 .collect()
1249 }
1250
1251 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
1253 expected_symbols_display(symbols, self.vocabulary())
1254 }
1255
1256 fn single_token_deletion(
1259 &mut self,
1260 transition: &Transition,
1261 index: usize,
1262 max_token_type: i32,
1263 expected_symbols: &BTreeSet<i32>,
1264 ) -> Option<(ParserDiagnostic, usize, i32)> {
1265 let current_symbol = self.token_type_at(index);
1266 if current_symbol == TOKEN_EOF {
1267 return None;
1268 }
1269 let next_index = self.consume_index(index, current_symbol);
1270 if next_index == index {
1271 return None;
1272 }
1273 let next_symbol = self.token_type_at(next_index);
1274 if !transition.matches(next_symbol, 1, max_token_type) {
1275 return None;
1276 }
1277 let transition_expected = transition_expected_symbols(transition, max_token_type);
1278 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
1279 &transition_expected
1280 } else {
1281 expected_symbols
1282 });
1283 let current = self.token_at(index);
1284 let message = format!(
1285 "extraneous input {} expecting {expected_display}",
1286 current
1287 .as_ref()
1288 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
1289 );
1290 Some((
1291 diagnostic_for_token(current.as_ref(), message),
1292 next_index,
1293 next_symbol,
1294 ))
1295 }
1296
1297 fn current_token_deletion(
1300 &mut self,
1301 index: usize,
1302 expected_symbols: &BTreeSet<i32>,
1303 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
1304 if expected_symbols.is_empty() {
1305 return None;
1306 }
1307 let current_symbol = self.token_type_at(index);
1308 if current_symbol == TOKEN_EOF {
1309 return None;
1310 }
1311 let current = self.token_at(index);
1312 let message = format!(
1313 "extraneous input {} expecting {}",
1314 current
1315 .as_ref()
1316 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
1317 self.expected_symbols_display(expected_symbols)
1318 );
1319 let diagnostic = diagnostic_for_token(current.as_ref(), message);
1320 let mut skipped = Vec::new();
1321 let mut cursor = index;
1322 loop {
1323 let symbol = self.token_type_at(cursor);
1324 if symbol == TOKEN_EOF {
1325 return None;
1326 }
1327 skipped.push(cursor);
1328 let next_index = self.consume_index(cursor, symbol);
1329 if next_index == cursor {
1330 return None;
1331 }
1332 let next_symbol = self.token_type_at(next_index);
1333 if expected_symbols.contains(&next_symbol) {
1334 return Some((diagnostic, next_index, skipped));
1335 }
1336 cursor = next_index;
1337 }
1338 }
1339
1340 fn single_token_insertion(
1344 &mut self,
1345 transition: &Transition,
1346 index: usize,
1347 max_token_type: i32,
1348 expected_symbols: &BTreeSet<i32>,
1349 follow_symbols: &BTreeSet<i32>,
1350 ) -> Option<(ParserDiagnostic, i32, String)> {
1351 let current_symbol = self.token_type_at(index);
1352 if !follow_symbols.contains(¤t_symbol) {
1353 return None;
1354 }
1355 let transition_expected = transition_expected_symbols(transition, max_token_type);
1356 let token_type = transition_expected.iter().next().copied()?;
1357 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
1358 &transition_expected
1359 } else {
1360 expected_symbols
1361 });
1362 let mut token_symbols = BTreeSet::new();
1363 token_symbols.insert(token_type);
1364 let missing_token_display = self.expected_symbols_display(&token_symbols);
1365 let current = self.token_at(index);
1366 let message = format!(
1367 "missing {expected_display} at {}",
1368 current
1369 .as_ref()
1370 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
1371 );
1372 let text = format!("<missing {missing_token_display}>");
1373 Some((
1374 diagnostic_for_token(current.as_ref(), message),
1375 token_type,
1376 text,
1377 ))
1378 }
1379
1380 fn fast_single_token_deletion_recovery(
1384 &mut self,
1385 recovery: FastRecoveryRequest<'_, '_>,
1386 ) -> Vec<FastRecognizeOutcome> {
1387 let FastRecoveryRequest {
1388 atn,
1389 transition,
1390 expected_symbols,
1391 target,
1392 request,
1393 visiting,
1394 memo,
1395 expected,
1396 } = recovery;
1397 let FastRecognizeRequest {
1398 stop_state,
1399 index,
1400 rule_start_index,
1401 decision_start_index,
1402 precedence,
1403 depth,
1404 ..
1405 } = request;
1406 let Some((diagnostic, next_index, next_symbol)) =
1407 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
1408 else {
1409 return Vec::new();
1410 };
1411 let after_next = self.consume_index(next_index, next_symbol);
1412 self.recognize_state_fast(
1413 atn,
1414 FastRecognizeRequest {
1415 state_number: target,
1416 stop_state,
1417 index: after_next,
1418 rule_start_index,
1419 decision_start_index,
1420 precedence,
1421 depth: depth + 1,
1422 recovery_symbols: BTreeSet::new(),
1423 recovery_state: None,
1424 },
1425 visiting,
1426 memo,
1427 expected,
1428 )
1429 .into_iter()
1430 .map(|mut outcome| {
1431 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
1432 outcome.diagnostics.insert(0, diagnostic.clone());
1433 outcome
1434 })
1435 .collect()
1436 }
1437
1438 fn fast_single_token_insertion_recovery(
1442 &mut self,
1443 recovery: FastRecoveryRequest<'_, '_>,
1444 ) -> Vec<FastRecognizeOutcome> {
1445 let FastRecoveryRequest {
1446 atn,
1447 transition,
1448 expected_symbols,
1449 target,
1450 request,
1451 visiting,
1452 memo,
1453 expected,
1454 } = recovery;
1455 let FastRecognizeRequest {
1456 stop_state,
1457 index,
1458 rule_start_index,
1459 decision_start_index,
1460 precedence,
1461 depth,
1462 ..
1463 } = request;
1464 let follow_symbols = state_expected_symbols(atn, transition.target());
1465 let Some((diagnostic, _token_type, _text)) = self.single_token_insertion(
1466 transition,
1467 index,
1468 atn.max_token_type(),
1469 &expected_symbols,
1470 &follow_symbols,
1471 ) else {
1472 return Vec::new();
1473 };
1474 self.recognize_state_fast(
1475 atn,
1476 FastRecognizeRequest {
1477 state_number: target,
1478 stop_state,
1479 index,
1480 rule_start_index,
1481 decision_start_index,
1482 precedence,
1483 depth: depth + 1,
1484 recovery_symbols: BTreeSet::new(),
1485 recovery_state: None,
1486 },
1487 visiting,
1488 memo,
1489 expected,
1490 )
1491 .into_iter()
1492 .map(|mut outcome| {
1493 outcome.diagnostics.insert(0, diagnostic.clone());
1494 outcome
1495 })
1496 .collect()
1497 }
1498
1499 fn fast_current_token_deletion_recovery(
1502 &mut self,
1503 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
1504 ) -> Vec<FastRecognizeOutcome> {
1505 let FastCurrentTokenDeletionRequest {
1506 atn,
1507 expected_symbols,
1508 mut request,
1509 visiting,
1510 memo,
1511 expected,
1512 } = recovery;
1513 if request.index == request.rule_start_index {
1514 return Vec::new();
1515 }
1516 let Some((diagnostic, next_index, _skipped)) =
1517 self.current_token_deletion(request.index, &expected_symbols)
1518 else {
1519 return Vec::new();
1520 };
1521 request.state_number = request.recovery_state.unwrap_or(request.state_number);
1522 request.index = next_index;
1523 request.depth += 1;
1524 request.recovery_state = None;
1525 self.recognize_state_fast(atn, request, visiting, memo, expected)
1526 .into_iter()
1527 .map(|mut outcome| {
1528 outcome.diagnostics.insert(0, diagnostic.clone());
1529 outcome
1530 })
1531 .collect()
1532 }
1533
1534 fn recognize_state_fast(
1537 &mut self,
1538 atn: &Atn,
1539 request: FastRecognizeRequest,
1540 visiting: &mut BTreeSet<FastRecognizeKey>,
1541 memo: &mut BTreeMap<FastRecognizeKey, Vec<FastRecognizeOutcome>>,
1542 expected: &mut ExpectedTokens,
1543 ) -> Vec<FastRecognizeOutcome> {
1544 let FastRecognizeRequest {
1545 state_number,
1546 stop_state,
1547 index,
1548 rule_start_index,
1549 decision_start_index,
1550 precedence,
1551 depth,
1552 recovery_symbols,
1553 recovery_state,
1554 } = request;
1555 if depth > RECOGNITION_DEPTH_LIMIT {
1556 return Vec::new();
1557 }
1558 if state_number == stop_state {
1559 return vec![FastRecognizeOutcome {
1560 index,
1561 consumed_eof: false,
1562 diagnostics: Vec::new(),
1563 }];
1564 }
1565 let key = FastRecognizeKey {
1566 state_number,
1567 stop_state,
1568 index,
1569 rule_start_index,
1570 decision_start_index,
1571 precedence,
1572 recovery_symbols: recovery_symbols.clone(),
1573 recovery_state,
1574 };
1575 if let Some(outcomes) = memo.get(&key) {
1576 return outcomes.clone();
1577 }
1578
1579 let visit_key = key.clone();
1580 if !visiting.insert(visit_key.clone()) {
1581 return Vec::new();
1582 }
1583
1584 let Some(state) = atn.state(state_number) else {
1585 visiting.remove(&visit_key);
1586 return Vec::new();
1587 };
1588 let next_decision_start_index = if starts_prediction_decision(state) {
1589 Some(index)
1590 } else {
1591 decision_start_index
1592 };
1593 let (epsilon_recovery_symbols, epsilon_recovery_state) =
1594 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
1595 let mut outcomes = Vec::new();
1596 for transition in &state.transitions {
1597 match transition {
1598 Transition::Epsilon { target }
1599 | Transition::Predicate { target, .. }
1600 | Transition::Action { target, .. } => {
1601 outcomes.extend(self.recognize_state_fast(
1602 atn,
1603 FastRecognizeRequest {
1604 state_number: *target,
1605 stop_state,
1606 index,
1607 rule_start_index,
1608 decision_start_index: next_decision_start_index,
1609 precedence,
1610 depth: depth + 1,
1611 recovery_symbols: epsilon_recovery_symbols.clone(),
1612 recovery_state: epsilon_recovery_state,
1613 },
1614 visiting,
1615 memo,
1616 expected,
1617 ));
1618 }
1619 Transition::Precedence {
1620 target,
1621 precedence: transition_precedence,
1622 } => {
1623 if *transition_precedence >= precedence {
1624 outcomes.extend(self.recognize_state_fast(
1625 atn,
1626 FastRecognizeRequest {
1627 state_number: *target,
1628 stop_state,
1629 index,
1630 rule_start_index,
1631 decision_start_index: next_decision_start_index,
1632 precedence,
1633 depth: depth + 1,
1634 recovery_symbols: epsilon_recovery_symbols.clone(),
1635 recovery_state: epsilon_recovery_state,
1636 },
1637 visiting,
1638 memo,
1639 expected,
1640 ));
1641 }
1642 }
1643 Transition::Rule {
1644 target,
1645 rule_index,
1646 follow_state,
1647 precedence: rule_precedence,
1648 ..
1649 } => {
1650 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
1651 else {
1652 continue;
1653 };
1654 let expected_before_child = expected.clone();
1655 let children = self.recognize_state_fast(
1656 atn,
1657 FastRecognizeRequest {
1658 state_number: *target,
1659 stop_state: child_stop,
1660 index,
1661 rule_start_index: index,
1662 decision_start_index: None,
1663 precedence: *rule_precedence,
1664 depth: depth + 1,
1665 recovery_symbols: epsilon_recovery_symbols.clone(),
1666 recovery_state: epsilon_recovery_state,
1667 },
1668 visiting,
1669 memo,
1670 expected,
1671 );
1672 if children
1673 .iter()
1674 .any(|child| child.diagnostics.is_empty() && child.index > index)
1675 {
1676 *expected = expected_before_child;
1677 }
1678 for child in children {
1679 outcomes.extend(
1680 self.recognize_state_fast(
1681 atn,
1682 FastRecognizeRequest {
1683 state_number: *follow_state,
1684 stop_state,
1685 index: child.index,
1686 rule_start_index,
1687 decision_start_index: next_decision_start_index,
1688 precedence,
1689 depth: depth + 1,
1690 recovery_symbols: BTreeSet::new(),
1691 recovery_state: None,
1692 },
1693 visiting,
1694 memo,
1695 expected,
1696 )
1697 .into_iter()
1698 .map(|mut outcome| {
1699 outcome.consumed_eof |= child.consumed_eof;
1700 let mut diagnostics = child.diagnostics.clone();
1701 diagnostics.append(&mut outcome.diagnostics);
1702 outcome.diagnostics = diagnostics;
1703 outcome
1704 }),
1705 );
1706 }
1707 }
1708 Transition::Atom { target, .. }
1709 | Transition::Range { target, .. }
1710 | Transition::Set { target, .. }
1711 | Transition::NotSet { target, .. }
1712 | Transition::Wildcard { target, .. } => {
1713 let symbol = self.token_type_at(index);
1714 if transition.matches(symbol, 1, atn.max_token_type()) {
1715 let next_index = self.consume_index(index, symbol);
1716 outcomes.extend(
1717 self.recognize_state_fast(
1718 atn,
1719 FastRecognizeRequest {
1720 state_number: *target,
1721 stop_state,
1722 index: next_index,
1723 rule_start_index,
1724 decision_start_index: next_decision_start_index,
1725 precedence,
1726 depth: depth + 1,
1727 recovery_symbols: BTreeSet::new(),
1728 recovery_state: None,
1729 },
1730 visiting,
1731 memo,
1732 expected,
1733 )
1734 .into_iter()
1735 .map(|mut outcome| {
1736 outcome.consumed_eof |= symbol == TOKEN_EOF;
1737 outcome
1738 }),
1739 );
1740 } else {
1741 let expected_symbols =
1742 recovery_expected_symbols(atn, state.state_number, &recovery_symbols);
1743 if expected_symbols.contains(&symbol) {
1744 continue;
1745 }
1746 expected.record_transition(index, transition, atn.max_token_type());
1747 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
1748 outcomes.extend(self.fast_single_token_deletion_recovery(
1749 FastRecoveryRequest {
1750 atn,
1751 transition,
1752 expected_symbols: expected_symbols.clone(),
1753 target: *target,
1754 request: FastRecognizeRequest {
1755 state_number,
1756 stop_state,
1757 index,
1758 rule_start_index,
1759 decision_start_index,
1760 precedence,
1761 depth,
1762 recovery_symbols: recovery_symbols.clone(),
1763 recovery_state,
1764 },
1765 visiting,
1766 memo,
1767 expected,
1768 },
1769 ));
1770 if !state_is_left_recursive_rule(atn, state) {
1771 outcomes.extend(self.fast_single_token_insertion_recovery(
1772 FastRecoveryRequest {
1773 atn,
1774 transition,
1775 expected_symbols: expected_symbols.clone(),
1776 target: *target,
1777 request: FastRecognizeRequest {
1778 state_number,
1779 stop_state,
1780 index,
1781 rule_start_index,
1782 decision_start_index,
1783 precedence,
1784 depth,
1785 recovery_symbols: recovery_symbols.clone(),
1786 recovery_state,
1787 },
1788 visiting,
1789 memo,
1790 expected,
1791 },
1792 ));
1793 }
1794 outcomes.extend(self.fast_current_token_deletion_recovery(
1795 FastCurrentTokenDeletionRequest {
1796 atn,
1797 expected_symbols,
1798 request: FastRecognizeRequest {
1799 state_number,
1800 stop_state,
1801 index,
1802 rule_start_index,
1803 decision_start_index,
1804 precedence,
1805 depth,
1806 recovery_symbols: recovery_symbols.clone(),
1807 recovery_state,
1808 },
1809 visiting,
1810 memo,
1811 expected,
1812 },
1813 ));
1814 }
1815 }
1816 }
1817 }
1818
1819 visiting.remove(&visit_key);
1820 if self.prediction_mode == PredictionMode::Ll {
1821 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
1822 }
1823 dedupe_fast_outcomes(&mut outcomes);
1824 memo.insert(key, outcomes.clone());
1825 outcomes
1826 }
1827
1828 fn single_token_deletion_recovery(
1831 &mut self,
1832 recovery: RecoveryRequest<'_, '_>,
1833 ) -> Vec<RecognizeOutcome> {
1834 let RecoveryRequest {
1835 atn,
1836 transition,
1837 expected_symbols,
1838 target,
1839 request,
1840 visiting,
1841 memo,
1842 expected,
1843 } = recovery;
1844 let RecognizeRequest {
1845 stop_state,
1846 index,
1847 rule_start_index,
1848 decision_start_index,
1849 init_action_rules,
1850 predicates,
1851 rule_args,
1852 member_actions,
1853 return_actions,
1854 local_int_arg,
1855 member_values,
1856 return_values,
1857 rule_alt_number,
1858 track_alt_numbers,
1859 consumed_eof,
1860 precedence,
1861 depth,
1862 ..
1863 } = request;
1864 let Some((diagnostic, next_index, next_symbol)) =
1865 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
1866 else {
1867 return Vec::new();
1868 };
1869 let after_next = self.consume_index(next_index, next_symbol);
1870 self.recognize_state(
1871 atn,
1872 RecognizeRequest {
1873 state_number: target,
1874 stop_state,
1875 index: after_next,
1876 rule_start_index,
1877 decision_start_index,
1878 init_action_rules,
1879 predicates,
1880 rule_args,
1881 member_actions,
1882 return_actions,
1883 local_int_arg,
1884 member_values,
1885 return_values,
1886 rule_alt_number,
1887 track_alt_numbers,
1888 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
1889 precedence,
1890 depth: depth + 1,
1891 recovery_symbols: BTreeSet::new(),
1892 recovery_state: None,
1893 },
1894 visiting,
1895 memo,
1896 expected,
1897 )
1898 .into_iter()
1899 .map(|mut outcome| {
1900 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
1901 outcome.diagnostics.insert(0, diagnostic.clone());
1902 outcome
1903 .nodes
1904 .insert(0, RecognizedNode::Token { index: next_index });
1905 outcome
1906 .nodes
1907 .insert(0, RecognizedNode::ErrorToken { index });
1908 outcome
1909 })
1910 .collect()
1911 }
1912
1913 fn current_token_deletion_recovery(
1916 &mut self,
1917 recovery: CurrentTokenDeletionRequest<'_, '_>,
1918 ) -> Vec<RecognizeOutcome> {
1919 let CurrentTokenDeletionRequest {
1920 atn,
1921 expected_symbols,
1922 mut request,
1923 visiting,
1924 memo,
1925 expected,
1926 } = recovery;
1927 let error_index = request.index;
1928 if error_index == request.rule_start_index {
1929 return Vec::new();
1930 }
1931 let Some((diagnostic, next_index, skipped)) =
1932 self.current_token_deletion(error_index, &expected_symbols)
1933 else {
1934 return Vec::new();
1935 };
1936 request.state_number = request.recovery_state.unwrap_or(request.state_number);
1937 request.index = next_index;
1938 request.depth += 1;
1939 request.recovery_state = None;
1940 self.recognize_state(atn, request, visiting, memo, expected)
1941 .into_iter()
1942 .map(|mut outcome| {
1943 outcome.diagnostics.insert(0, diagnostic.clone());
1944 for index in skipped.iter().rev() {
1945 outcome
1946 .nodes
1947 .insert(0, RecognizedNode::ErrorToken { index: *index });
1948 }
1949 outcome
1950 })
1951 .collect()
1952 }
1953
1954 fn consuming_failure_fallback(
1957 &mut self,
1958 fallback: ConsumingFailureFallback<'_>,
1959 visiting: &mut BTreeSet<RecognizeKey>,
1960 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
1961 expected: &mut ExpectedTokens,
1962 ) -> Vec<RecognizeOutcome> {
1963 if fallback.expected_symbols.is_empty() {
1964 return Vec::new();
1965 }
1966 if fallback.symbol == TOKEN_EOF {
1967 return self.eof_consuming_failure_fallback(fallback, expected);
1968 }
1969 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
1970 }
1971
1972 fn non_eof_consuming_failure_fallback(
1975 &mut self,
1976 fallback: ConsumingFailureFallback<'_>,
1977 visiting: &mut BTreeSet<RecognizeKey>,
1978 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
1979 expected: &mut ExpectedTokens,
1980 ) -> Vec<RecognizeOutcome> {
1981 let ConsumingFailureFallback {
1982 atn,
1983 target,
1984 request,
1985 symbol,
1986 expected_symbols,
1987 decision_start_index,
1988 decision,
1989 } = fallback;
1990 let error_index = request.index;
1991 let diagnostic =
1992 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
1993 let next_index = self.consume_index(error_index, symbol);
1994 self.recognize_state(
1995 atn,
1996 RecognizeRequest {
1997 state_number: target,
1998 stop_state: request.stop_state,
1999 index: next_index,
2000 rule_start_index: request.rule_start_index,
2001 decision_start_index,
2002 init_action_rules: request.init_action_rules,
2003 predicates: request.predicates,
2004 rule_args: request.rule_args,
2005 member_actions: request.member_actions,
2006 return_actions: request.return_actions,
2007 local_int_arg: request.local_int_arg,
2008 member_values: request.member_values,
2009 return_values: request.return_values,
2010 rule_alt_number: request.rule_alt_number,
2011 track_alt_numbers: request.track_alt_numbers,
2012 consumed_eof: request.consumed_eof,
2013 precedence: request.precedence,
2014 depth: request.depth + 1,
2015 recovery_symbols: BTreeSet::new(),
2016 recovery_state: None,
2017 },
2018 visiting,
2019 memo,
2020 expected,
2021 )
2022 .into_iter()
2023 .map(|mut outcome| {
2024 prepend_decision(&mut outcome, decision);
2025 outcome.diagnostics.insert(0, diagnostic.clone());
2026 outcome
2027 .nodes
2028 .insert(0, RecognizedNode::ErrorToken { index: error_index });
2029 outcome
2030 })
2031 .collect()
2032 }
2033
2034 fn eof_consuming_failure_fallback(
2037 &mut self,
2038 fallback: ConsumingFailureFallback<'_>,
2039 expected: &ExpectedTokens,
2040 ) -> Vec<RecognizeOutcome> {
2041 let request = fallback.request;
2042 if request.index == request.rule_start_index {
2043 return Vec::new();
2044 }
2045 let diagnostic =
2046 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
2047 vec![RecognizeOutcome {
2048 index: request.index,
2049 consumed_eof: request.consumed_eof,
2050 alt_number: request.rule_alt_number,
2051 member_values: request.member_values,
2052 return_values: request.return_values,
2053 diagnostics: vec![diagnostic],
2054 decisions: Vec::new(),
2055 actions: Vec::new(),
2056 nodes: Vec::new(),
2057 }]
2058 }
2059
2060 fn single_token_insertion_recovery(
2063 &mut self,
2064 recovery: RecoveryRequest<'_, '_>,
2065 ) -> Vec<RecognizeOutcome> {
2066 let RecoveryRequest {
2067 atn,
2068 transition,
2069 expected_symbols,
2070 target,
2071 request,
2072 visiting,
2073 memo,
2074 expected,
2075 } = recovery;
2076 let RecognizeRequest {
2077 stop_state,
2078 index,
2079 rule_start_index,
2080 decision_start_index,
2081 init_action_rules,
2082 predicates,
2083 rule_args,
2084 member_actions,
2085 return_actions,
2086 local_int_arg,
2087 member_values,
2088 return_values,
2089 rule_alt_number,
2090 track_alt_numbers,
2091 consumed_eof,
2092 precedence,
2093 depth,
2094 ..
2095 } = request;
2096 let follow_symbols = state_expected_symbols(atn, transition.target());
2097 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
2098 transition,
2099 index,
2100 atn.max_token_type(),
2101 &expected_symbols,
2102 &follow_symbols,
2103 ) else {
2104 return Vec::new();
2105 };
2106 self.recognize_state(
2107 atn,
2108 RecognizeRequest {
2109 state_number: target,
2110 stop_state,
2111 index,
2112 rule_start_index,
2113 decision_start_index,
2114 init_action_rules,
2115 predicates,
2116 rule_args,
2117 member_actions,
2118 return_actions,
2119 local_int_arg,
2120 member_values,
2121 return_values,
2122 rule_alt_number,
2123 track_alt_numbers,
2124 consumed_eof,
2125 precedence,
2126 depth: depth + 1,
2127 recovery_symbols: BTreeSet::new(),
2128 recovery_state: None,
2129 },
2130 visiting,
2131 memo,
2132 expected,
2133 )
2134 .into_iter()
2135 .map(|mut outcome| {
2136 outcome.diagnostics.insert(0, diagnostic.clone());
2137 outcome.nodes.insert(
2138 0,
2139 RecognizedNode::MissingToken {
2140 token_type,
2141 at_index: index,
2142 text: text.clone(),
2143 },
2144 );
2145 outcome
2146 })
2147 .collect()
2148 }
2149
2150 fn recognize_state(
2153 &mut self,
2154 atn: &Atn,
2155 request: RecognizeRequest<'_>,
2156 visiting: &mut BTreeSet<RecognizeKey>,
2157 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2158 expected: &mut ExpectedTokens,
2159 ) -> Vec<RecognizeOutcome> {
2160 let request_template = request.clone();
2161 let RecognizeRequest {
2162 state_number,
2163 stop_state,
2164 index,
2165 rule_start_index,
2166 decision_start_index,
2167 init_action_rules,
2168 predicates,
2169 rule_args,
2170 member_actions,
2171 return_actions,
2172 local_int_arg,
2173 member_values,
2174 return_values,
2175 rule_alt_number,
2176 track_alt_numbers,
2177 consumed_eof,
2178 precedence,
2179 depth,
2180 recovery_symbols,
2181 recovery_state,
2182 } = request;
2183 if depth > RECOGNITION_DEPTH_LIMIT {
2184 return Vec::new();
2185 }
2186 if state_number == stop_state {
2187 return stop_outcome(
2188 index,
2189 consumed_eof,
2190 rule_alt_number,
2191 member_values,
2192 return_values,
2193 );
2194 }
2195 let key = RecognizeKey {
2196 state_number,
2197 stop_state,
2198 index,
2199 rule_start_index,
2200 decision_start_index,
2201 local_int_arg,
2202 member_values: member_values.clone(),
2203 return_values: return_values.clone(),
2204 rule_alt_number,
2205 track_alt_numbers,
2206 consumed_eof,
2207 precedence,
2208 recovery_symbols: recovery_symbols.clone(),
2209 recovery_state,
2210 };
2211 if let Some(outcomes) = memo.get(&key) {
2212 return outcomes.clone();
2213 }
2214
2215 let visit_key = key.clone();
2216 if !visiting.insert(visit_key.clone()) {
2217 return Vec::new();
2218 }
2219
2220 let Some(state) = atn.state(state_number) else {
2221 visiting.remove(&visit_key);
2222 return Vec::new();
2223 };
2224 let next_decision_start_index = if starts_prediction_decision(state) {
2225 Some(index)
2226 } else {
2227 decision_start_index
2228 };
2229 let (epsilon_recovery_symbols, epsilon_recovery_state) =
2230 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
2231 let mut outcomes = Vec::new();
2232 for (transition_index, transition) in state.transitions.iter().enumerate() {
2233 let decision = transition_decision(atn, state, transition_index, predicates);
2234 let next_alt_number =
2235 next_alt_number(state, transition_index, rule_alt_number, track_alt_numbers);
2236 match transition {
2237 Transition::Epsilon { target } | Transition::Action { target, .. } => {
2238 let action_rule_index = match transition {
2239 Transition::Action { rule_index, .. } => Some(*rule_index),
2240 _ => None,
2241 };
2242 outcomes.extend(self.recognize_epsilon_or_action_step(
2243 atn,
2244 &request_template,
2245 EpsilonActionStep {
2246 source_state: state_number,
2247 target: *target,
2248 action_rule_index,
2249 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
2250 decision,
2251 decision_start_index: next_decision_start_index,
2252 alt_number: next_alt_number,
2253 recovery_symbols: epsilon_recovery_symbols.clone(),
2254 recovery_state: epsilon_recovery_state,
2255 },
2256 RecognizeScratch {
2257 visiting,
2258 memo,
2259 expected,
2260 },
2261 ));
2262 }
2263 Transition::Predicate {
2264 target,
2265 rule_index,
2266 pred_index,
2267 ..
2268 } => {
2269 let predicate = PredicateEval {
2270 index,
2271 rule_index: *rule_index,
2272 pred_index: *pred_index,
2273 predicates,
2274 local_int_arg,
2275 member_values: &member_values,
2276 };
2277 if self.parser_predicate_matches(predicate) {
2278 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
2279 outcomes.extend(
2280 self.recognize_state(
2281 atn,
2282 RecognizeRequest {
2283 state_number: *target,
2284 stop_state,
2285 index,
2286 rule_start_index,
2287 decision_start_index: next_decision_start_index,
2288 init_action_rules,
2289 predicates,
2290 rule_args,
2291 member_actions,
2292 return_actions,
2293 local_int_arg,
2294 member_values: member_values.clone(),
2295 return_values: return_values.clone(),
2296 rule_alt_number: next_alt_number,
2297 track_alt_numbers,
2298 consumed_eof,
2299 precedence,
2300 depth: depth + 1,
2301 recovery_symbols: epsilon_recovery_symbols.clone(),
2302 recovery_state: epsilon_recovery_state,
2303 },
2304 visiting,
2305 memo,
2306 expected,
2307 )
2308 .into_iter()
2309 .map(|mut outcome| {
2310 prepend_decision(&mut outcome, decision);
2311 if let Some(rule_index) = left_recursive_boundary {
2312 outcome.nodes.insert(
2313 0,
2314 RecognizedNode::LeftRecursiveBoundary { rule_index },
2315 );
2316 }
2317 outcome
2318 }),
2319 );
2320 } else if let Some(message) =
2321 self.parser_predicate_failure_message(*rule_index, *pred_index, predicates)
2322 {
2323 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
2324 rule_index: *rule_index,
2325 index,
2326 message,
2327 member_values: member_values.clone(),
2328 return_values: return_values.clone(),
2329 rule_alt_number,
2330 }));
2331 } else {
2332 record_predicate_no_viable(expected, next_decision_start_index, index);
2333 }
2334 }
2335 Transition::Precedence {
2336 target,
2337 precedence: transition_precedence,
2338 } => {
2339 if *transition_precedence >= precedence {
2340 outcomes.extend(
2341 self.recognize_state(
2342 atn,
2343 RecognizeRequest {
2344 state_number: *target,
2345 stop_state,
2346 index,
2347 rule_start_index,
2348 decision_start_index: next_decision_start_index,
2349 init_action_rules,
2350 predicates,
2351 rule_args,
2352 member_actions,
2353 return_actions,
2354 local_int_arg,
2355 member_values: member_values.clone(),
2356 return_values: return_values.clone(),
2357 rule_alt_number: next_alt_number,
2358 track_alt_numbers,
2359 consumed_eof,
2360 precedence,
2361 depth: depth + 1,
2362 recovery_symbols: epsilon_recovery_symbols.clone(),
2363 recovery_state: epsilon_recovery_state,
2364 },
2365 visiting,
2366 memo,
2367 expected,
2368 )
2369 .into_iter()
2370 .map(|mut outcome| {
2371 prepend_decision(&mut outcome, decision);
2372 outcome
2373 }),
2374 );
2375 }
2376 }
2377 Transition::Rule {
2378 target,
2379 rule_index,
2380 follow_state,
2381 precedence: rule_precedence,
2382 ..
2383 } => {
2384 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
2385 else {
2386 continue;
2387 };
2388 let child_local_int_arg =
2389 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
2390 let expected_before_child = expected.clone();
2391 let children = self.recognize_state(
2392 atn,
2393 RecognizeRequest {
2394 state_number: *target,
2395 stop_state: child_stop,
2396 index,
2397 rule_start_index: index,
2398 decision_start_index: None,
2399 init_action_rules,
2400 predicates,
2401 rule_args,
2402 member_actions,
2403 return_actions,
2404 local_int_arg: child_local_int_arg,
2405 member_values: member_values.clone(),
2406 return_values: BTreeMap::new(),
2407 rule_alt_number: 0,
2408 track_alt_numbers,
2409 consumed_eof: false,
2410 precedence: *rule_precedence,
2411 depth: depth + 1,
2412 recovery_symbols: epsilon_recovery_symbols.clone(),
2413 recovery_state: epsilon_recovery_state,
2414 },
2415 visiting,
2416 memo,
2417 expected,
2418 );
2419 let children = if children.is_empty() {
2420 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
2421 atn,
2422 rule_index: *rule_index,
2423 start_index: index,
2424 follow_state: *follow_state,
2425 stop_state,
2426 member_values: member_values.clone(),
2427 expected,
2428 })
2429 } else {
2430 children
2431 };
2432 let preserve_child_expected =
2433 self.child_expected_reaches_clean_eof(&children, expected);
2434 restore_expected(
2435 &children,
2436 index,
2437 expected,
2438 expected_before_child,
2439 preserve_child_expected,
2440 );
2441 for child in children {
2442 let child_node = RecognizedNode::Rule {
2443 rule_index: *rule_index,
2444 invoking_state: invoking_state_number(state_number),
2445 alt_number: child.alt_number,
2446 start_index: index,
2447 stop_index: self.rule_stop_token_index(child.index, child.consumed_eof),
2448 return_values: child.return_values.clone(),
2449 children: fold_left_recursive_boundaries(child.nodes.clone()),
2450 };
2451 outcomes.extend(
2452 self.recognize_state(
2453 atn,
2454 RecognizeRequest {
2455 state_number: *follow_state,
2456 stop_state,
2457 index: child.index,
2458 rule_start_index,
2459 decision_start_index: next_decision_start_index,
2460 init_action_rules,
2461 predicates,
2462 rule_args,
2463 member_actions,
2464 return_actions,
2465 local_int_arg,
2466 member_values: child.member_values.clone(),
2467 return_values: return_values.clone(),
2468 rule_alt_number,
2469 track_alt_numbers,
2470 consumed_eof: consumed_eof || child.consumed_eof,
2471 precedence,
2472 depth: depth + 1,
2473 recovery_symbols: BTreeSet::new(),
2474 recovery_state: None,
2475 },
2476 visiting,
2477 memo,
2478 expected,
2479 )
2480 .into_iter()
2481 .map(|mut outcome| {
2482 outcome.consumed_eof |= child.consumed_eof;
2483 let mut diagnostics = child.diagnostics.clone();
2484 diagnostics.append(&mut outcome.diagnostics);
2485 outcome.diagnostics = diagnostics;
2486 let mut decisions = child.decisions.clone();
2487 decisions.append(&mut outcome.decisions);
2488 outcome.decisions = decisions;
2489 prepend_decision(&mut outcome, decision);
2490 let mut actions = child.actions.clone();
2491 if init_action_rules.contains(rule_index) {
2492 actions.insert(
2493 0,
2494 ParserAction::new_rule_init(
2495 *rule_index,
2496 index,
2497 Some(*follow_state),
2498 ),
2499 );
2500 }
2501 actions.append(&mut outcome.actions);
2502 outcome.actions = actions;
2503 outcome.nodes.insert(0, child_node.clone());
2504 outcome
2505 }),
2506 );
2507 }
2508 }
2509 Transition::Atom { target, .. }
2510 | Transition::Range { target, .. }
2511 | Transition::Set { target, .. }
2512 | Transition::NotSet { target, .. }
2513 | Transition::Wildcard { target, .. } => {
2514 let symbol = self.token_type_at(index);
2515 if transition.matches(symbol, 1, atn.max_token_type()) {
2516 let next_index = self.consume_index(index, symbol);
2517 outcomes.extend(
2518 self.recognize_state(
2519 atn,
2520 RecognizeRequest {
2521 state_number: *target,
2522 stop_state,
2523 index: next_index,
2524 rule_start_index,
2525 decision_start_index: next_decision_start_index,
2526 init_action_rules,
2527 predicates,
2528 rule_args,
2529 member_actions,
2530 return_actions,
2531 local_int_arg,
2532 member_values: member_values.clone(),
2533 return_values: return_values.clone(),
2534 rule_alt_number: next_alt_number,
2535 track_alt_numbers,
2536 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
2537 precedence,
2538 depth: depth + 1,
2539 recovery_symbols: BTreeSet::new(),
2540 recovery_state: None,
2541 },
2542 visiting,
2543 memo,
2544 expected,
2545 )
2546 .into_iter()
2547 .map(|mut outcome| {
2548 prepend_decision(&mut outcome, decision);
2549 outcome.consumed_eof |= symbol == TOKEN_EOF;
2550 outcome.nodes.insert(0, RecognizedNode::Token { index });
2551 outcome
2552 }),
2553 );
2554 } else {
2555 let expected_symbols =
2556 recovery_expected_symbols(atn, state.state_number, &recovery_symbols);
2557 if expected_symbols.contains(&symbol) {
2558 continue;
2559 }
2560 expected.record_transition(index, transition, atn.max_token_type());
2561 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
2562 let before_recovery = outcomes.len();
2563 let recovery_request = request_template.clone();
2564 outcomes.extend(
2565 self.single_token_deletion_recovery(RecoveryRequest {
2566 atn,
2567 transition,
2568 expected_symbols: expected_symbols.clone(),
2569 target: *target,
2570 request: recovery_request.clone(),
2571 visiting,
2572 memo,
2573 expected,
2574 })
2575 .into_iter()
2576 .map(|mut outcome| {
2577 prepend_decision(&mut outcome, decision);
2578 outcome
2579 }),
2580 );
2581 if !state_is_left_recursive_rule(atn, state) {
2582 outcomes.extend(
2583 self.single_token_insertion_recovery(RecoveryRequest {
2584 atn,
2585 transition,
2586 expected_symbols: expected_symbols.clone(),
2587 target: *target,
2588 request: recovery_request.clone(),
2589 visiting,
2590 memo,
2591 expected,
2592 })
2593 .into_iter()
2594 .map(|mut outcome| {
2595 prepend_decision(&mut outcome, decision);
2596 outcome
2597 }),
2598 );
2599 }
2600 outcomes.extend(self.current_token_deletion_recovery(
2601 CurrentTokenDeletionRequest {
2602 atn,
2603 expected_symbols: expected_symbols.clone(),
2604 request: recovery_request.clone(),
2605 visiting,
2606 memo,
2607 expected,
2608 },
2609 ));
2610 if outcomes.len() == before_recovery {
2611 outcomes.extend(self.consuming_failure_fallback(
2612 ConsumingFailureFallback {
2613 atn,
2614 target: *target,
2615 request: recovery_request,
2616 symbol,
2617 expected_symbols,
2618 decision_start_index: next_decision_start_index,
2619 decision,
2620 },
2621 visiting,
2622 memo,
2623 expected,
2624 ));
2625 }
2626 }
2627 }
2628 }
2629 }
2630
2631 visiting.remove(&visit_key);
2632 self.record_prediction_diagnostics(atn, state, index, &outcomes);
2633 if self.prediction_mode == PredictionMode::Ll {
2634 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes);
2635 }
2636 dedupe_outcomes(&mut outcomes);
2637 memo.insert(key, outcomes.clone());
2638 outcomes
2639 }
2640
2641 fn recognize_epsilon_or_action_step(
2644 &mut self,
2645 atn: &Atn,
2646 request: &RecognizeRequest<'_>,
2647 step: EpsilonActionStep,
2648 scratch: RecognizeScratch<'_>,
2649 ) -> Vec<RecognizeOutcome> {
2650 let RecognizeScratch {
2651 visiting,
2652 memo,
2653 expected,
2654 } = scratch;
2655 let action = step.action_rule_index.map(|rule_index| {
2656 ParserAction::new(
2657 step.source_state,
2658 rule_index,
2659 request.rule_start_index,
2660 self.rule_stop_token_index(request.index, request.consumed_eof),
2661 )
2662 });
2663 let next_member_values = if action.is_some() {
2664 member_values_after_action(
2665 step.source_state,
2666 request.member_actions,
2667 &request.member_values,
2668 )
2669 } else {
2670 request.member_values.clone()
2671 };
2672 let next_return_values = action.map_or_else(
2673 || request.return_values.clone(),
2674 |action| {
2675 return_values_after_action(
2676 step.source_state,
2677 action.rule_index(),
2678 request.return_actions,
2679 &request.return_values,
2680 )
2681 },
2682 );
2683
2684 self.recognize_state(
2685 atn,
2686 RecognizeRequest {
2687 state_number: step.target,
2688 stop_state: request.stop_state,
2689 index: request.index,
2690 rule_start_index: request.rule_start_index,
2691 decision_start_index: step.decision_start_index,
2692 init_action_rules: request.init_action_rules,
2693 predicates: request.predicates,
2694 rule_args: request.rule_args,
2695 member_actions: request.member_actions,
2696 return_actions: request.return_actions,
2697 local_int_arg: request.local_int_arg,
2698 member_values: next_member_values,
2699 return_values: next_return_values,
2700 rule_alt_number: step.alt_number,
2701 track_alt_numbers: request.track_alt_numbers,
2702 consumed_eof: request.consumed_eof,
2703 precedence: request.precedence,
2704 depth: request.depth + 1,
2705 recovery_symbols: step.recovery_symbols,
2706 recovery_state: step.recovery_state,
2707 },
2708 visiting,
2709 memo,
2710 expected,
2711 )
2712 .into_iter()
2713 .map(|mut outcome| {
2714 prepend_decision(&mut outcome, step.decision);
2715 if let Some(rule_index) = step.left_recursive_boundary {
2716 outcome
2717 .nodes
2718 .insert(0, RecognizedNode::LeftRecursiveBoundary { rule_index });
2719 }
2720 if let Some(action) = action {
2721 outcome.actions.insert(0, action);
2722 }
2723 outcome
2724 })
2725 .collect()
2726 }
2727
2728 fn token_type_at(&mut self, index: usize) -> i32 {
2730 self.input.seek(index);
2731 self.input.la_token(1)
2732 }
2733
2734 fn token_at(&mut self, index: usize) -> Option<CommonToken> {
2736 self.input.get(index).cloned()
2737 }
2738
2739 fn current_visible_index(&mut self) -> usize {
2742 let index = self.input.index();
2743 self.input.seek(index);
2744 self.input.index()
2745 }
2746
2747 fn child_expected_reaches_clean_eof(
2750 &mut self,
2751 children: &[RecognizeOutcome],
2752 expected: &ExpectedTokens,
2753 ) -> bool {
2754 let Some(index) = expected.index else {
2755 return false;
2756 };
2757 self.token_type_at(index) == TOKEN_EOF
2758 && children
2759 .iter()
2760 .any(|child| child.diagnostics.is_empty() && child.index == index)
2761 }
2762
2763 fn previous_token_index(&mut self, index: usize) -> Option<usize> {
2770 self.input.previous_visible_token_index(index)
2771 }
2772
2773 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
2778 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
2779 Some(index)
2780 } else {
2781 self.previous_token_index(index)
2782 }
2783 }
2784
2785 fn rule_stop_token(&mut self, index: usize, consumed_eof: bool) -> Option<CommonToken> {
2790 self.rule_stop_token_index(index, consumed_eof)
2791 .and_then(|token_index| self.token_at(token_index))
2792 }
2793
2794 fn predicate_failure_recovery(
2801 &mut self,
2802 request: PredicateFailureRecovery<'_>,
2803 ) -> RecognizeOutcome {
2804 let PredicateFailureRecovery {
2805 rule_index,
2806 index,
2807 message,
2808 member_values,
2809 return_values,
2810 rule_alt_number,
2811 } = request;
2812 let rule_name = self
2813 .rule_names()
2814 .get(rule_index)
2815 .map_or_else(|| rule_index.to_string(), Clone::clone);
2816 let diagnostic = diagnostic_for_token(
2817 self.token_at(index).as_ref(),
2818 format!("rule {rule_name} {message}"),
2819 );
2820 let mut nodes = Vec::new();
2821 let mut next_index = index;
2822 loop {
2823 let symbol = self.token_type_at(next_index);
2824 if symbol == TOKEN_EOF {
2825 break;
2826 }
2827 nodes.push(RecognizedNode::ErrorToken { index: next_index });
2828 let after = self.consume_index(next_index, symbol);
2829 if after == next_index {
2830 break;
2831 }
2832 next_index = after;
2833 }
2834 RecognizeOutcome {
2835 index: next_index,
2836 consumed_eof: false,
2837 alt_number: rule_alt_number,
2838 member_values,
2839 return_values,
2840 diagnostics: vec![diagnostic],
2841 decisions: Vec::new(),
2842 actions: Vec::new(),
2843 nodes,
2844 }
2845 }
2846
2847 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
2854 let PredicateEval {
2855 index,
2856 rule_index,
2857 pred_index,
2858 predicates,
2859 local_int_arg,
2860 member_values,
2861 } = eval;
2862 let Some((_, _, predicate)) = predicates
2863 .iter()
2864 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
2865 else {
2866 return true;
2867 };
2868 self.input.seek(index);
2869 match predicate {
2870 ParserPredicate::True => true,
2871 ParserPredicate::False => false,
2872 ParserPredicate::FalseWithMessage { .. } => false,
2873 ParserPredicate::Invoke { value } => {
2874 let key = (rule_index, pred_index);
2875 if !self.invoked_predicates.contains(&key) {
2876 self.invoked_predicates.push(key);
2877 use std::io::Write as _;
2878 let mut stdout = std::io::stdout().lock();
2879 let _ = writeln!(stdout, "eval={value}");
2880 }
2881 *value
2882 }
2883 ParserPredicate::LookaheadTextEquals { offset, text } => {
2884 self.input.lt(*offset).and_then(Token::text) == Some(*text)
2885 }
2886 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
2887 self.la(*offset) != *token_type
2888 }
2889 ParserPredicate::LocalIntEquals { value } => {
2890 local_int_arg.is_none_or(|(_, actual)| actual == *value)
2891 }
2892 ParserPredicate::LocalIntLessOrEqual { value } => {
2893 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
2894 }
2895 ParserPredicate::MemberModuloEquals {
2896 member,
2897 modulus,
2898 value,
2899 equals,
2900 } => {
2901 if *modulus == 0 {
2902 return false;
2903 }
2904 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
2905 (actual == *value) == *equals
2906 }
2907 }
2908 }
2909
2910 fn parser_predicate_failure_message(
2912 &self,
2913 rule_index: usize,
2914 pred_index: usize,
2915 predicates: &[(usize, usize, ParserPredicate)],
2916 ) -> Option<&'static str> {
2917 predicates
2918 .iter()
2919 .find_map(|(rule, pred, predicate)| match predicate {
2920 ParserPredicate::FalseWithMessage { message }
2921 if *rule == rule_index && *pred == pred_index =>
2922 {
2923 Some(*message)
2924 }
2925 _ => None,
2926 })
2927 }
2928
2929 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
2934 self.input.seek(index);
2935 if symbol != TOKEN_EOF {
2936 self.consume();
2937 }
2938 self.input.index()
2939 }
2940
2941 fn no_viable_alternative(
2944 &mut self,
2945 start_index: usize,
2946 error_index: usize,
2947 ) -> ParserDiagnostic {
2948 let text = display_input_text(&self.input.text(start_index, error_index));
2949 diagnostic_for_token(
2950 self.token_at(error_index).as_ref(),
2951 format!("no viable alternative at input '{text}'"),
2952 )
2953 }
2954
2955 fn recovery_failure_diagnostic(
2958 &mut self,
2959 index: usize,
2960 decision_start_index: Option<usize>,
2961 expected_symbols: &BTreeSet<i32>,
2962 ) -> ParserDiagnostic {
2963 if expected_symbols.len() > 1 {
2964 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
2965 return self.no_viable_alternative(decision_start, index);
2966 }
2967 }
2968 diagnostic_for_token(
2969 self.token_at(index).as_ref(),
2970 format!(
2971 "mismatched input {} expecting {}",
2972 self.token_at(index)
2973 .as_ref()
2974 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
2975 self.expected_symbols_display(expected_symbols)
2976 ),
2977 )
2978 }
2979
2980 fn eof_rule_recovery_diagnostic(
2983 &mut self,
2984 index: usize,
2985 expected_symbols: &BTreeSet<i32>,
2986 expected: &ExpectedTokens,
2987 ) -> ParserDiagnostic {
2988 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
2989 &expected.symbols
2990 } else {
2991 expected_symbols
2992 };
2993 diagnostic_for_token(
2994 self.token_at(index).as_ref(),
2995 format!(
2996 "mismatched input {} expecting {}",
2997 self.token_at(index)
2998 .as_ref()
2999 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
3000 self.expected_symbols_display(symbols)
3001 ),
3002 )
3003 }
3004
3005 pub fn text_interval(&mut self, start: usize, stop: Option<usize>) -> String {
3011 let Some(stop) = stop else {
3012 return String::new();
3013 };
3014 let stop = if self
3015 .token_at(stop)
3016 .is_some_and(|token| token.token_type() == TOKEN_EOF)
3017 {
3018 let Some(previous) = self.previous_token_index(stop) else {
3019 return String::new();
3020 };
3021 previous
3022 } else {
3023 stop
3024 };
3025 self.input.text(start, stop)
3026 }
3027
3028 fn clear_prediction_diagnostics(&mut self) {
3031 self.prediction_diagnostics.clear();
3032 self.reported_prediction_diagnostics.clear();
3033 }
3034
3035 fn record_prediction_diagnostics(
3038 &mut self,
3039 atn: &Atn,
3040 state: &AtnState,
3041 start_index: usize,
3042 outcomes: &[RecognizeOutcome],
3043 ) {
3044 if !self.report_diagnostic_errors || state.transitions.len() < 2 {
3045 return;
3046 }
3047 let Some(decision) = atn
3048 .decision_to_state()
3049 .iter()
3050 .position(|state_number| *state_number == state.state_number)
3051 else {
3052 return;
3053 };
3054 let Some(rule_index) = state.rule_index else {
3055 return;
3056 };
3057 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
3058 for outcome in outcomes
3059 .iter()
3060 .filter(|outcome| outcome.diagnostics.is_empty())
3061 {
3062 let Some(alt) = outcome.decisions.first() else {
3063 continue;
3064 };
3065 alts_by_end
3066 .entry(outcome.index)
3067 .or_default()
3068 .insert(alt + 1);
3069 }
3070 let Some((&end_index, ambig_alts)) = alts_by_end
3071 .iter()
3072 .filter(|(_, alts)| alts.len() > 1)
3073 .max_by_key(|(end, _)| *end)
3074 else {
3075 return;
3076 };
3077 let rule_name = self
3078 .rule_names()
3079 .get(rule_index)
3080 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
3081 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
3082 let input = display_input_text(&self.input.text(start_index, stop_index));
3083 let alts = ambig_alts
3084 .iter()
3085 .map(usize::to_string)
3086 .collect::<Vec<_>>()
3087 .join(", ");
3088 let key = (decision, start_index, format!("{alts}:{input}"));
3089 if !self.reported_prediction_diagnostics.insert(key) {
3090 return;
3091 }
3092 let start_token = self.token_at(start_index);
3093 let stop_token = self.token_at(stop_index);
3094 self.prediction_diagnostics.push(diagnostic_for_token(
3095 start_token.as_ref(),
3096 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
3097 ));
3098 self.prediction_diagnostics.push(diagnostic_for_token(
3099 stop_token.as_ref(),
3100 format!(
3101 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
3102 ),
3103 ));
3104 }
3105
3106 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
3108 expected_symbols_display(
3109 &state_expected_symbols(atn, state_number),
3110 self.vocabulary(),
3111 )
3112 }
3113
3114 pub fn token_display_at(&mut self, index: usize) -> Option<String> {
3116 self.token_at(index).map(|token| format!("{token}"))
3117 }
3118
3119 fn recognized_node_tree(
3121 &mut self,
3122 node: &RecognizedNode,
3123 track_alt_numbers: bool,
3124 ) -> Result<ParseTree, AntlrError> {
3125 match node {
3126 RecognizedNode::Token { index } => {
3127 let token =
3128 self.input
3129 .get(*index)
3130 .cloned()
3131 .ok_or_else(|| AntlrError::ParserError {
3132 line: 0,
3133 column: 0,
3134 message: format!("missing token at index {index}"),
3135 })?;
3136 Ok(ParseTree::Terminal(TerminalNode::new(token)))
3137 }
3138 RecognizedNode::ErrorToken { index } => {
3139 let token =
3140 self.input
3141 .get(*index)
3142 .cloned()
3143 .ok_or_else(|| AntlrError::ParserError {
3144 line: 0,
3145 column: 0,
3146 message: format!("missing error token at index {index}"),
3147 })?;
3148 Ok(ParseTree::Error(ErrorNode::new(token)))
3149 }
3150 RecognizedNode::MissingToken {
3151 token_type,
3152 at_index,
3153 text,
3154 } => {
3155 let current = self.token_at(*at_index);
3156 let token = CommonToken::new(*token_type)
3157 .with_text(text)
3158 .with_span(usize::MAX, usize::MAX)
3159 .with_position(
3160 current.as_ref().map(Token::line).unwrap_or_default(),
3161 current.as_ref().map(Token::column).unwrap_or_default(),
3162 );
3163 Ok(ParseTree::Error(ErrorNode::new(token)))
3164 }
3165 RecognizedNode::Rule {
3166 rule_index,
3167 invoking_state,
3168 alt_number,
3169 start_index,
3170 stop_index,
3171 return_values,
3172 children,
3173 } => {
3174 let mut context = ParserRuleContext::new(*rule_index, *invoking_state);
3175 if track_alt_numbers {
3176 context.set_alt_number(*alt_number);
3177 }
3178 for (name, value) in return_values {
3179 context.set_int_return(name.clone(), *value);
3180 }
3181 if let Some(token) = self.token_at(*start_index) {
3182 context.set_start(token);
3183 }
3184 if let Some(token) = stop_index.and_then(|index| self.token_at(index)) {
3185 context.set_stop(token);
3186 }
3187 for child in children {
3188 context.add_child(self.recognized_node_tree(child, track_alt_numbers)?);
3189 }
3190 Ok(self.rule_node(context))
3191 }
3192 RecognizedNode::LeftRecursiveBoundary { rule_index } => Err(AntlrError::Unsupported(
3193 format!("unfolded left-recursive boundary for rule {rule_index}"),
3194 )),
3195 }
3196 }
3197}
3198
3199fn left_recursive_boundary(atn: &Atn, state: &AtnState, target: usize) -> Option<usize> {
3202 if !state.precedence_rule_decision {
3203 return None;
3204 }
3205 let target_state = atn.state(target)?;
3206 if target_state.kind == AtnStateKind::LoopEnd {
3207 return None;
3208 }
3209 state.rule_index
3210}
3211
3212const fn next_alt_number(
3219 state: &AtnState,
3220 transition_index: usize,
3221 current_alt_number: usize,
3222 track_alt_numbers: bool,
3223) -> usize {
3224 if !track_alt_numbers || current_alt_number != 0 || state.transitions.len() <= 1 {
3225 return current_alt_number;
3226 }
3227 if matches!(
3228 state.kind,
3229 AtnStateKind::Basic
3230 | AtnStateKind::BlockStart
3231 | AtnStateKind::PlusBlockStart
3232 | AtnStateKind::StarBlockStart
3233 | AtnStateKind::StarLoopEntry
3234 ) && !state.precedence_rule_decision
3235 {
3236 return transition_index + 1;
3237 }
3238 current_alt_number
3239}
3240
3241fn fold_left_recursive_boundaries(nodes: Vec<RecognizedNode>) -> Vec<RecognizedNode> {
3244 let mut folded = Vec::new();
3245 for node in nodes {
3246 match node {
3247 RecognizedNode::LeftRecursiveBoundary { rule_index } => {
3248 if !folded.is_empty() {
3249 let children = std::mem::take(&mut folded);
3250 let start_index = recognized_nodes_start_index(&children).unwrap_or_default();
3251 let stop_index = recognized_nodes_stop_index(&children);
3252 folded.push(RecognizedNode::Rule {
3253 rule_index,
3254 invoking_state: -1,
3255 alt_number: 0,
3256 start_index,
3257 stop_index,
3258 return_values: BTreeMap::new(),
3259 children,
3260 });
3261 }
3262 }
3263 node => folded.push(node),
3264 }
3265 }
3266 folded
3267}
3268
3269fn recognized_nodes_start_index(nodes: &[RecognizedNode]) -> Option<usize> {
3270 nodes.iter().find_map(recognized_node_start_index)
3271}
3272
3273const fn recognized_node_start_index(node: &RecognizedNode) -> Option<usize> {
3274 match node {
3275 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
3276 RecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
3277 RecognizedNode::Rule { start_index, .. } => Some(*start_index),
3278 RecognizedNode::LeftRecursiveBoundary { .. } => None,
3279 }
3280}
3281
3282fn recognized_nodes_stop_index(nodes: &[RecognizedNode]) -> Option<usize> {
3283 nodes.iter().rev().find_map(recognized_node_stop_index)
3284}
3285
3286fn invoking_state_number(state_number: usize) -> isize {
3289 isize::try_from(state_number).unwrap_or(isize::MAX)
3290}
3291
3292const fn recognized_node_stop_index(node: &RecognizedNode) -> Option<usize> {
3293 match node {
3294 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
3295 RecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
3296 RecognizedNode::Rule { stop_index, .. } => *stop_index,
3297 RecognizedNode::LeftRecursiveBoundary { .. } => None,
3298 }
3299}
3300
3301fn token_input_display(token: &impl Token) -> String {
3302 format!("'{}'", token.text().unwrap_or("<EOF>"))
3303}
3304
3305fn display_input_text(text: &str) -> String {
3306 let mut out = String::new();
3307 for ch in text.chars() {
3308 match ch {
3309 '\n' => out.push_str("\\n"),
3310 '\r' => out.push_str("\\r"),
3311 '\t' => out.push_str("\\t"),
3312 other => out.push(other),
3313 }
3314 }
3315 out
3316}
3317
3318fn diagnostic_for_token(token: Option<&impl Token>, message: String) -> ParserDiagnostic {
3319 ParserDiagnostic {
3320 line: token.map(Token::line).unwrap_or_default(),
3321 column: token.map(Token::column).unwrap_or_default(),
3322 message,
3323 }
3324}
3325
3326#[allow(clippy::print_stderr)]
3328fn report_parser_diagnostics(diagnostics: &[ParserDiagnostic]) {
3329 for diagnostic in diagnostics {
3330 eprintln!(
3331 "line {}:{} {}",
3332 diagnostic.line, diagnostic.column, diagnostic.message
3333 );
3334 }
3335}
3336
3337#[allow(clippy::print_stderr)]
3340fn report_token_source_errors(errors: &[TokenSourceError]) {
3341 for error in errors {
3342 eprintln!("line {}:{} {}", error.line, error.column, error.message);
3343 }
3344}
3345
3346fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
3347 let items = symbols
3348 .iter()
3349 .map(|symbol| expected_symbol_display(*symbol, vocabulary))
3350 .collect::<Vec<_>>();
3351 if let [single] = items.as_slice() {
3352 return single.clone();
3353 }
3354 format!("{{{}}}", items.join(", "))
3355}
3356
3357fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
3358 if symbol == TOKEN_EOF {
3359 return "<EOF>".to_owned();
3360 }
3361 vocabulary.display_name(symbol)
3362}
3363
3364fn state_is_left_recursive_rule(atn: &Atn, state: &AtnState) -> bool {
3368 let Some(rule_index) = state.rule_index else {
3369 return false;
3370 };
3371 atn.rule_to_start_state()
3372 .get(rule_index)
3373 .and_then(|state_number| atn.state(*state_number))
3374 .is_some_and(|rule_start| rule_start.left_recursive_rule)
3375}
3376
3377fn select_best_fast_outcome(
3383 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
3384 prediction_mode: PredictionMode,
3385) -> Option<FastRecognizeOutcome> {
3386 outcomes.reduce(|best, outcome| {
3387 let outcome_position = (outcome.index, outcome.consumed_eof);
3388 let best_position = (best.index, best.consumed_eof);
3389 let better = match prediction_mode {
3390 PredictionMode::Ll => outcome_is_better(
3391 outcome_position,
3392 &outcome.diagnostics,
3393 best_position,
3394 &best.diagnostics,
3395 ),
3396 PredictionMode::Sll => outcome.index > best.index,
3397 };
3398 if better {
3399 return outcome;
3400 }
3401 best
3402 })
3403}
3404
3405fn select_best_outcome(
3406 outcomes: impl Iterator<Item = RecognizeOutcome>,
3407 prediction_mode: PredictionMode,
3408) -> Option<RecognizeOutcome> {
3409 let outcomes = outcomes.collect::<Vec<_>>();
3410 let prefer_first_tie = outcomes
3411 .iter()
3412 .any(|outcome| nodes_need_stable_tie(&outcome.nodes));
3413 outcomes.into_iter().reduce(|best, outcome| {
3414 let outcome_position = (outcome.index, outcome.consumed_eof);
3415 let best_position = (best.index, best.consumed_eof);
3416 let better = match prediction_mode {
3417 PredictionMode::Ll => {
3418 outcome_is_better(
3419 outcome_position,
3420 &outcome.diagnostics,
3421 best_position,
3422 &best.diagnostics,
3423 ) || (!prefer_first_tie
3424 && outcome_position == best_position
3425 && outcome.diagnostics.len() == best.diagnostics.len()
3426 && diagnostic_recovery_rank(&outcome.diagnostics)
3427 == diagnostic_recovery_rank(&best.diagnostics)
3428 && (outcome.decisions < best.decisions
3429 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
3430 }
3431 PredictionMode::Sll => {
3432 outcome_position > best_position
3433 || (outcome_position == best_position
3434 && !prefer_first_tie
3435 && (outcome.decisions < best.decisions
3436 || (outcome.decisions == best.decisions
3437 && outcome_is_better(
3438 outcome_position,
3439 &outcome.diagnostics,
3440 best_position,
3441 &best.diagnostics,
3442 ))))
3443 }
3444 };
3445 if better {
3446 return outcome;
3447 }
3448 best
3449 })
3450}
3451
3452fn transition_decision(
3459 atn: &Atn,
3460 state: &AtnState,
3461 transition_index: usize,
3462 predicates: &[(usize, usize, ParserPredicate)],
3463) -> Option<usize> {
3464 if state.transitions.len() <= 1
3465 || state.precedence_rule_decision
3466 || decision_reaches_unsupported_predicate(atn, state, predicates)
3467 {
3468 return None;
3469 }
3470 Some(transition_index)
3471}
3472
3473const fn starts_prediction_decision(state: &AtnState) -> bool {
3479 state.transitions.len() > 1
3480 && !matches!(
3481 state.kind,
3482 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
3483 )
3484}
3485
3486fn record_no_viable_if_ambiguous(
3489 expected: &mut ExpectedTokens,
3490 decision_start_index: Option<usize>,
3491 index: usize,
3492) {
3493 if expected.index == Some(index) && expected.symbols.len() > 1 {
3494 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
3495 expected.record_no_viable(decision_start, index);
3496 }
3497 }
3498}
3499
3500const fn record_predicate_no_viable(
3503 expected: &mut ExpectedTokens,
3504 decision_start_index: Option<usize>,
3505 index: usize,
3506) {
3507 if let Some(decision_start) = decision_start_index {
3508 expected.record_no_viable(decision_start, index);
3509 }
3510}
3511
3512const fn no_viable_decision_start(
3514 decision_start_index: Option<usize>,
3515 index: usize,
3516) -> Option<usize> {
3517 match decision_start_index {
3518 Some(start) if index > start => Some(start),
3519 _ => None,
3520 }
3521}
3522
3523fn restore_expected(
3527 children: &[RecognizeOutcome],
3528 child_start_index: usize,
3529 expected: &mut ExpectedTokens,
3530 snapshot: ExpectedTokens,
3531 preserve_child_expected: bool,
3532) {
3533 if preserve_child_expected {
3534 return;
3535 }
3536 if children
3537 .iter()
3538 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
3539 {
3540 *expected = snapshot;
3541 }
3542}
3543
3544fn decision_reaches_unsupported_predicate(
3547 atn: &Atn,
3548 state: &AtnState,
3549 predicates: &[(usize, usize, ParserPredicate)],
3550) -> bool {
3551 state.transitions.iter().any(|transition| {
3552 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
3553 })
3554}
3555
3556fn transition_reaches_unsupported_predicate(
3558 atn: &Atn,
3559 transition: &Transition,
3560 predicates: &[(usize, usize, ParserPredicate)],
3561 visited: &mut BTreeSet<usize>,
3562) -> bool {
3563 match transition {
3564 Transition::Predicate {
3565 rule_index,
3566 pred_index,
3567 ..
3568 } => !predicates
3569 .iter()
3570 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
3571 Transition::Epsilon { target }
3572 | Transition::Action { target, .. }
3573 | Transition::Rule { target, .. } => {
3574 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
3575 }
3576 Transition::Precedence { .. }
3577 | Transition::Atom { .. }
3578 | Transition::Range { .. }
3579 | Transition::Set { .. }
3580 | Transition::NotSet { .. }
3581 | Transition::Wildcard { .. } => false,
3582 }
3583}
3584
3585fn state_reaches_unsupported_predicate(
3587 atn: &Atn,
3588 state_number: usize,
3589 predicates: &[(usize, usize, ParserPredicate)],
3590 visited: &mut BTreeSet<usize>,
3591) -> bool {
3592 if !visited.insert(state_number) {
3593 return false;
3594 }
3595 let Some(state) = atn.state(state_number) else {
3596 return false;
3597 };
3598 state.transitions.iter().any(|transition| {
3599 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
3600 })
3601}
3602
3603fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
3605 if let Some(decision) = decision {
3606 outcome.decisions.insert(0, decision);
3607 }
3608}
3609
3610fn outcome_is_better(
3611 outcome_position: (usize, bool),
3612 outcome_diagnostics: &[ParserDiagnostic],
3613 best_position: (usize, bool),
3614 best_diagnostics: &[ParserDiagnostic],
3615) -> bool {
3616 outcome_position > best_position
3617 || (outcome_position == best_position
3618 && (outcome_diagnostics.len() < best_diagnostics.len()
3619 || (outcome_diagnostics.len() == best_diagnostics.len()
3620 && diagnostic_recovery_rank(outcome_diagnostics)
3621 < diagnostic_recovery_rank(best_diagnostics))))
3622}
3623
3624fn diagnostic_recovery_rank(diagnostics: &[ParserDiagnostic]) -> usize {
3627 diagnostics
3628 .iter()
3629 .filter(|diagnostic| {
3630 diagnostic.message.starts_with("mismatched input ")
3631 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
3632 })
3633 .count()
3634}
3635
3636fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
3637 if outcomes
3638 .iter()
3639 .any(|outcome| outcome.diagnostics.is_empty())
3640 {
3641 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
3642 }
3643}
3644
3645fn discard_recovered_outcomes_if_clean_path_exists(outcomes: &mut Vec<RecognizeOutcome>) {
3646 if outcomes.iter().any(outcome_has_rule_failure_diagnostic) {
3647 return;
3648 }
3649 if outcomes
3650 .iter()
3651 .any(|outcome| outcome.diagnostics.is_empty())
3652 {
3653 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
3654 }
3655}
3656
3657fn outcome_has_rule_failure_diagnostic(outcome: &RecognizeOutcome) -> bool {
3660 outcome
3661 .diagnostics
3662 .iter()
3663 .any(|diagnostic| diagnostic.message.starts_with("rule "))
3664}
3665
3666fn nodes_need_stable_tie(nodes: &[RecognizedNode]) -> bool {
3669 nodes.iter().any(node_needs_stable_tie)
3670}
3671
3672fn node_needs_stable_tie(node: &RecognizedNode) -> bool {
3673 match node {
3674 RecognizedNode::Token { .. }
3675 | RecognizedNode::ErrorToken { .. }
3676 | RecognizedNode::MissingToken { .. } => false,
3677 RecognizedNode::LeftRecursiveBoundary { .. } => true,
3678 RecognizedNode::Rule {
3679 rule_index,
3680 children,
3681 ..
3682 } => children.iter().any(|child| {
3683 matches!(
3684 child,
3685 RecognizedNode::Rule {
3686 rule_index: child_rule,
3687 ..
3688 } if child_rule == rule_index
3689 ) || node_needs_stable_tie(child)
3690 }),
3691 }
3692}
3693
3694fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
3696 outcomes.sort_unstable();
3697 outcomes.dedup();
3698}
3699
3700fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>) {
3702 outcomes.sort_unstable();
3703 outcomes.dedup();
3704}
3705
3706impl<S> Recognizer for BaseParser<S>
3707where
3708 S: TokenSource,
3709{
3710 fn data(&self) -> &RecognizerData {
3711 &self.data
3712 }
3713
3714 fn data_mut(&mut self) -> &mut RecognizerData {
3715 &mut self.data
3716 }
3717}
3718
3719impl<S> Parser for BaseParser<S>
3720where
3721 S: TokenSource,
3722{
3723 fn build_parse_trees(&self) -> bool {
3724 self.build_parse_trees
3725 }
3726
3727 fn set_build_parse_trees(&mut self, build: bool) {
3728 self.build_parse_trees = build;
3729 }
3730
3731 fn report_diagnostic_errors(&self) -> bool {
3732 self.report_diagnostic_errors
3733 }
3734
3735 fn set_report_diagnostic_errors(&mut self, report: bool) {
3736 self.report_diagnostic_errors = report;
3737 }
3738
3739 fn prediction_mode(&self) -> PredictionMode {
3740 self.prediction_mode
3741 }
3742
3743 fn set_prediction_mode(&mut self, mode: PredictionMode) {
3744 self.prediction_mode = mode;
3745 }
3746}
3747
3748#[cfg(test)]
3749mod tests {
3750 use super::*;
3751 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
3752 use crate::token::{CommonToken, HIDDEN_CHANNEL, Token};
3753 use crate::token_stream::CommonTokenStream;
3754 use crate::vocabulary::Vocabulary;
3755
3756 #[derive(Debug)]
3757 struct Source {
3758 tokens: Vec<CommonToken>,
3759 index: usize,
3760 }
3761
3762 impl TokenSource for Source {
3763 fn next_token(&mut self) -> CommonToken {
3764 let token = self
3765 .tokens
3766 .get(self.index)
3767 .cloned()
3768 .unwrap_or_else(|| CommonToken::eof("parser-test", self.index, 1, self.index));
3769 self.index += 1;
3770 token
3771 }
3772
3773 fn line(&self) -> usize {
3774 1
3775 }
3776
3777 fn column(&self) -> usize {
3778 self.index
3779 }
3780
3781 fn source_name(&self) -> &'static str {
3782 "parser-test"
3783 }
3784 }
3785
3786 fn mini_parser(tokens: Vec<CommonToken>) -> BaseParser<Source> {
3787 let data = RecognizerData::new(
3788 "Mini.g4",
3789 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
3790 );
3791 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
3792 }
3793
3794 fn token_then_eof_atn() -> Atn {
3795 AtnDeserializer::new(&SerializedAtn::from_i32(&[
3796 4, 1, 2, 3, 2, 0, 1, 0, 7, 0, 0, 0, 1, 0, 0, 0, 2, 0, 1, 5, 1, 0, 0, 1, 2, 5, -1, 0, 0, 0, ]))
3812 .deserialize()
3813 .expect("artificial parser ATN should deserialize")
3814 }
3815
3816 fn eof_then_action_atn() -> Atn {
3817 AtnDeserializer::new(&SerializedAtn::from_i32(&[
3818 4, 1, 1, 3, 2, 0, 1, 0, 7, 0, 0, 0, 1, 0, 0, 0, 2, 0, 1, 5, -1, 0, 0, 1, 2, 6, 0, 0, 0, 0, ]))
3834 .deserialize()
3835 .expect("artificial parser ATN should deserialize")
3836 }
3837
3838 #[test]
3839 fn parser_matches_token_and_reports_mismatch() {
3840 let source = Source {
3841 tokens: vec![
3842 CommonToken::new(1).with_text("x"),
3843 CommonToken::eof("parser-test", 1, 1, 1),
3844 ],
3845 index: 0,
3846 };
3847 let data = RecognizerData::new(
3848 "Mini.g4",
3849 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
3850 );
3851 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
3852 assert_eq!(
3853 parser.match_token(1).expect("token 1 should match").text(),
3854 "x"
3855 );
3856 assert!(parser.match_token(1).is_err());
3857 }
3858
3859 #[test]
3860 fn parser_interprets_simple_atn_rule() {
3861 let atn = token_then_eof_atn();
3862 let mut parser = mini_parser(vec![
3863 CommonToken::new(1).with_text("x"),
3864 CommonToken::eof("parser-test", 1, 1, 1),
3865 ]);
3866
3867 let tree = parser
3868 .parse_atn_rule(&atn, 0)
3869 .expect("artificial parser rule should parse");
3870 assert_eq!(tree.text(), "x<EOF>");
3871 assert_eq!(
3872 tree.first_rule_stop(0)
3873 .expect("rule should stop at EOF")
3874 .token_type(),
3875 TOKEN_EOF
3876 );
3877
3878 let mut parser = mini_parser(vec![
3879 CommonToken::new(1).with_text("x"),
3880 CommonToken::eof("parser-test", 1, 1, 1),
3881 ]);
3882 let (tree, actions) = parser
3883 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
3884 .expect("runtime-option parser rule should parse");
3885 assert!(actions.is_empty());
3886 assert_eq!(
3887 tree.first_rule_stop(0)
3888 .expect("rule should stop at EOF")
3889 .token_type(),
3890 TOKEN_EOF
3891 );
3892 }
3893
3894 #[test]
3895 fn parser_rule_start_skips_leading_hidden_tokens() {
3896 let atn = token_then_eof_atn();
3897 let mut parser = mini_parser(vec![
3898 CommonToken::new(99)
3899 .with_text(" ")
3900 .with_channel(HIDDEN_CHANNEL),
3901 CommonToken::new(1).with_text("x"),
3902 CommonToken::eof("parser-test", 2, 1, 2),
3903 ]);
3904
3905 let tree = parser
3906 .parse_atn_rule(&atn, 0)
3907 .expect("artificial parser rule should parse");
3908 let Some(ParseTree::Rule(rule)) = tree.first_rule(0) else {
3909 panic!("rule node should be present");
3910 };
3911 assert_eq!(
3912 rule.context()
3913 .start()
3914 .expect("rule should have a start token")
3915 .token_type(),
3916 1
3917 );
3918 }
3919
3920 #[test]
3921 fn parser_action_after_eof_stops_at_eof_token() {
3922 let atn = eof_then_action_atn();
3923 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
3924
3925 let (_, actions) = parser
3926 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
3927 .expect("EOF action rule should parse");
3928
3929 assert_eq!(actions.len(), 1);
3930 assert_eq!(actions[0].stop_index(), Some(0));
3931 assert_eq!(
3932 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
3933 ""
3934 );
3935 }
3936
3937 #[test]
3938 fn fast_outcome_selection_respects_sll_tie_order() {
3939 let first = FastRecognizeOutcome {
3940 index: 1,
3941 consumed_eof: false,
3942 diagnostics: vec![ParserDiagnostic {
3943 line: 1,
3944 column: 0,
3945 message: "mismatched input 'x'".to_owned(),
3946 }],
3947 };
3948 let second = FastRecognizeOutcome {
3949 index: first.index,
3950 consumed_eof: first.consumed_eof,
3951 diagnostics: Vec::new(),
3952 };
3953
3954 let selected = select_best_fast_outcome(
3955 [first.clone(), second.clone()].into_iter(),
3956 PredictionMode::Sll,
3957 )
3958 .expect("one outcome should be selected");
3959 assert_eq!(selected.diagnostics.len(), 1);
3960 let eof_second = FastRecognizeOutcome {
3961 index: second.index,
3962 consumed_eof: true,
3963 diagnostics: Vec::new(),
3964 };
3965 let selected =
3966 select_best_fast_outcome([first.clone(), eof_second].into_iter(), PredictionMode::Sll)
3967 .expect("one outcome should be selected");
3968 assert!(!selected.consumed_eof);
3969 let selected = select_best_fast_outcome([first, second].into_iter(), PredictionMode::Ll)
3970 .expect("one outcome should be selected");
3971 assert!(selected.diagnostics.is_empty());
3972 }
3973
3974 #[test]
3975 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
3976 let source = Source {
3977 tokens: vec![
3978 CommonToken::new(1).with_text("x"),
3979 CommonToken::eof("parser-test", 1, 1, 1),
3980 ],
3981 index: 0,
3982 };
3983 let data = RecognizerData::new(
3984 "Mini.g4",
3985 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
3986 );
3987 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
3988 let expected = ExpectedTokens {
3989 index: Some(0),
3990 symbols: BTreeSet::new(),
3991 no_viable: None,
3992 };
3993
3994 let (_, message) = parser.expected_error_message(0, 0, &expected);
3995
3996 assert_eq!(message, "mismatched input 'x'");
3997 }
3998
3999 #[test]
4000 fn eof_rule_stop_index_points_at_eof_token() {
4001 let source = Source {
4002 tokens: vec![
4003 CommonToken::new(1).with_text("x"),
4004 CommonToken::eof("parser-test", 1, 1, 1),
4005 ],
4006 index: 0,
4007 };
4008 let data = RecognizerData::new(
4009 "Mini.g4",
4010 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
4011 );
4012 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
4013
4014 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
4015 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
4016 }
4017
4018 #[test]
4019 fn folds_left_recursive_boundary_into_rule_node() {
4020 let nodes = fold_left_recursive_boundaries(vec![
4021 RecognizedNode::Token { index: 0 },
4022 RecognizedNode::LeftRecursiveBoundary { rule_index: 1 },
4023 RecognizedNode::Token { index: 1 },
4024 ]);
4025
4026 assert_eq!(
4027 nodes,
4028 vec![
4029 RecognizedNode::Rule {
4030 rule_index: 1,
4031 invoking_state: -1,
4032 alt_number: 0,
4033 start_index: 0,
4034 stop_index: Some(0),
4035 return_values: BTreeMap::new(),
4036 children: vec![RecognizedNode::Token { index: 0 }],
4037 },
4038 RecognizedNode::Token { index: 1 },
4039 ]
4040 );
4041 }
4042
4043 #[test]
4044 fn outcome_ties_keep_later_non_recursive_alternative() {
4045 let first = RecognizeOutcome {
4046 index: 1,
4047 consumed_eof: false,
4048 alt_number: 0,
4049 member_values: BTreeMap::new(),
4050 return_values: BTreeMap::new(),
4051 diagnostics: Vec::new(),
4052 decisions: Vec::new(),
4053 actions: vec![ParserAction::new(1, 0, 0, None)],
4054 nodes: vec![RecognizedNode::Token { index: 0 }],
4055 };
4056 let second = RecognizeOutcome {
4057 actions: vec![ParserAction::new(2, 0, 0, None)],
4058 ..first.clone()
4059 };
4060
4061 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
4062 .expect("one outcome should be selected");
4063 assert_eq!(selected.actions[0].source_state(), 2);
4064 }
4065
4066 #[test]
4067 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
4068 let first = RecognizeOutcome {
4069 index: 1,
4070 consumed_eof: false,
4071 alt_number: 0,
4072 member_values: BTreeMap::new(),
4073 return_values: BTreeMap::new(),
4074 diagnostics: Vec::new(),
4075 decisions: Vec::new(),
4076 actions: vec![ParserAction::new(1, 0, 0, None)],
4077 nodes: vec![RecognizedNode::Token { index: 0 }],
4078 };
4079 let second = RecognizeOutcome {
4080 actions: vec![
4081 ParserAction::new(2, 0, 0, None),
4082 ParserAction::new(3, 0, 0, None),
4083 ],
4084 ..first.clone()
4085 };
4086
4087 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll)
4088 .expect("one outcome should be selected");
4089 assert_eq!(selected.actions.len(), 2);
4090 }
4091
4092 #[test]
4093 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
4094 let first = RecognizeOutcome {
4095 index: 7,
4096 consumed_eof: false,
4097 alt_number: 0,
4098 member_values: BTreeMap::new(),
4099 return_values: BTreeMap::new(),
4100 diagnostics: Vec::new(),
4101 decisions: vec![1, 0],
4102 actions: vec![
4103 ParserAction::new(23, 2, 2, Some(4)),
4104 ParserAction::new(23, 2, 0, Some(6)),
4105 ],
4106 nodes: vec![RecognizedNode::Token { index: 0 }],
4107 };
4108 let second = RecognizeOutcome {
4109 decisions: vec![0, 1],
4110 actions: vec![
4111 ParserAction::new(23, 2, 2, Some(6)),
4112 ParserAction::new(23, 2, 0, Some(6)),
4113 ],
4114 ..first.clone()
4115 };
4116
4117 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
4118 .expect("one outcome should be selected");
4119 assert_eq!(selected.actions[0].stop_index(), Some(6));
4120 }
4121
4122 #[test]
4123 fn outcome_ties_keep_first_recursive_tree_shape() {
4124 let recursive_nodes = vec![RecognizedNode::Rule {
4125 rule_index: 1,
4126 invoking_state: -1,
4127 alt_number: 0,
4128 start_index: 0,
4129 stop_index: Some(0),
4130 return_values: BTreeMap::new(),
4131 children: vec![RecognizedNode::Rule {
4132 rule_index: 1,
4133 invoking_state: -1,
4134 alt_number: 0,
4135 start_index: 0,
4136 stop_index: Some(0),
4137 return_values: BTreeMap::new(),
4138 children: vec![RecognizedNode::Token { index: 0 }],
4139 }],
4140 }];
4141 let first = RecognizeOutcome {
4142 index: 1,
4143 consumed_eof: false,
4144 alt_number: 0,
4145 member_values: BTreeMap::new(),
4146 return_values: BTreeMap::new(),
4147 diagnostics: Vec::new(),
4148 decisions: Vec::new(),
4149 actions: vec![ParserAction::new(1, 0, 0, None)],
4150 nodes: recursive_nodes.clone(),
4151 };
4152 let second = RecognizeOutcome {
4153 index: 1,
4154 consumed_eof: false,
4155 alt_number: 0,
4156 member_values: BTreeMap::new(),
4157 return_values: BTreeMap::new(),
4158 diagnostics: Vec::new(),
4159 decisions: Vec::new(),
4160 actions: vec![ParserAction::new(2, 0, 0, None)],
4161 nodes: recursive_nodes,
4162 };
4163
4164 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
4165 .expect("one outcome should be selected");
4166 assert_eq!(selected.actions[0].source_state(), 1);
4167 }
4168
4169 #[test]
4170 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
4171 let first_alt = RecognizeOutcome {
4172 index: 2,
4173 consumed_eof: true,
4174 alt_number: 0,
4175 member_values: BTreeMap::new(),
4176 return_values: BTreeMap::new(),
4177 diagnostics: vec![ParserDiagnostic {
4178 line: 1,
4179 column: 3,
4180 message: "missing 'Y' at '<EOF>'".to_owned(),
4181 }],
4182 decisions: vec![0],
4183 actions: vec![ParserAction::new(1, 0, 0, None)],
4184 nodes: vec![RecognizedNode::Token { index: 0 }],
4185 };
4186 let second_alt = RecognizeOutcome {
4187 diagnostics: Vec::new(),
4188 decisions: vec![1],
4189 actions: vec![ParserAction::new(2, 0, 0, None)],
4190 ..first_alt.clone()
4191 };
4192
4193 let selected =
4194 select_best_outcome([second_alt, first_alt].into_iter(), PredictionMode::Sll)
4195 .expect("one outcome should be selected");
4196 assert_eq!(selected.diagnostics.len(), 1);
4197 assert_eq!(selected.decisions, [0]);
4198 }
4199}