1use std::collections::{BTreeMap, BTreeSet};
2use std::rc::Rc;
3
4use crate::atn::{Atn, AtnState, AtnStateKind, Transition};
5use crate::errors::AntlrError;
6use crate::int_stream::IntStream;
7use crate::recognizer::{Recognizer, RecognizerData};
8use crate::token::{CommonToken, TOKEN_EOF, Token, TokenSource, TokenSourceError};
9use crate::token_stream::CommonTokenStream;
10use crate::tree::{ErrorNode, ParseTree, ParserRuleContext, RuleNode, TerminalNode};
11use crate::vocabulary::Vocabulary;
12
13const RECOGNITION_DEPTH_LIMIT: usize = 100_000;
17
18#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
27pub struct ParserAction {
28 source_state: usize,
29 rule_index: usize,
30 start_index: usize,
31 stop_index: Option<usize>,
32 rule_init: bool,
33 expected_state: Option<usize>,
34}
35
36impl ParserAction {
37 pub const fn new(
39 source_state: usize,
40 rule_index: usize,
41 start_index: usize,
42 stop_index: Option<usize>,
43 ) -> Self {
44 Self {
45 source_state,
46 rule_index,
47 start_index,
48 stop_index,
49 rule_init: false,
50 expected_state: None,
51 }
52 }
53
54 pub const fn new_rule_init(
56 rule_index: usize,
57 start_index: usize,
58 expected_state: Option<usize>,
59 ) -> Self {
60 Self {
61 source_state: usize::MAX,
62 rule_index,
63 start_index,
64 stop_index: None,
65 rule_init: true,
66 expected_state,
67 }
68 }
69
70 pub const fn source_state(&self) -> usize {
72 self.source_state
73 }
74
75 pub const fn rule_index(&self) -> usize {
77 self.rule_index
78 }
79
80 pub const fn start_index(&self) -> usize {
82 self.start_index
83 }
84
85 pub const fn stop_index(&self) -> Option<usize> {
87 self.stop_index
88 }
89
90 pub const fn is_rule_init(&self) -> bool {
92 self.rule_init
93 }
94
95 pub const fn expected_state(&self) -> Option<usize> {
97 self.expected_state
98 }
99}
100
101#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
108pub enum ParserPredicate {
109 True,
110 False,
111 FalseWithMessage {
113 message: &'static str,
114 },
115 Invoke {
118 value: bool,
119 },
120 LookaheadTextEquals {
121 offset: isize,
122 text: &'static str,
123 },
124 LookaheadNotEquals {
125 offset: isize,
126 token_type: i32,
127 },
128 LocalIntEquals {
131 value: i64,
132 },
133 LocalIntLessOrEqual {
136 value: i64,
137 },
138 MemberModuloEquals {
140 member: usize,
141 modulus: i64,
142 value: i64,
143 equals: bool,
144 },
145}
146
147#[derive(Clone, Copy, Debug, Eq, PartialEq)]
149pub enum PredictionMode {
150 Ll,
153 Sll,
156}
157
158#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
164pub struct ParserRuleArg {
165 pub source_state: usize,
167 pub rule_index: usize,
169 pub value: i64,
171 pub inherit_local: bool,
173}
174
175#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
177pub struct ParserMemberAction {
178 pub source_state: usize,
180 pub member: usize,
182 pub delta: i64,
184}
185
186#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
193pub struct ParserReturnAction {
194 pub source_state: usize,
196 pub rule_index: usize,
198 pub name: &'static str,
200 pub value: i64,
202}
203
204#[derive(Clone, Copy, Debug, Default)]
206pub struct ParserRuntimeOptions<'a> {
207 pub init_action_rules: &'a [usize],
209 pub track_alt_numbers: bool,
211 pub predicates: &'a [(usize, usize, ParserPredicate)],
213 pub rule_args: &'a [ParserRuleArg],
215 pub member_actions: &'a [ParserMemberAction],
217 pub return_actions: &'a [ParserReturnAction],
219}
220
221pub trait Parser: Recognizer {
222 fn build_parse_trees(&self) -> bool;
225
226 fn set_build_parse_trees(&mut self, build: bool);
228
229 fn report_diagnostic_errors(&self) -> bool {
232 false
233 }
234
235 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
238
239 fn prediction_mode(&self) -> PredictionMode {
241 PredictionMode::Ll
242 }
243
244 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
246}
247
248#[derive(Debug)]
249pub struct BaseParser<S> {
250 input: CommonTokenStream<S>,
251 data: RecognizerData,
252 build_parse_trees: bool,
253 report_diagnostic_errors: bool,
254 prediction_mode: PredictionMode,
255 prediction_diagnostics: Vec<ParserDiagnostic>,
256 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
257 int_members: BTreeMap<usize, i64>,
258 invoked_predicates: Vec<(usize, usize)>,
262 first_set_cache: FirstSetCache,
267 fast_first_set_prefilter: bool,
275}
276
277#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
278struct RecognizeOutcome {
279 index: usize,
280 consumed_eof: bool,
281 alt_number: usize,
282 member_values: BTreeMap<usize, i64>,
283 return_values: BTreeMap<String, i64>,
284 diagnostics: Vec<ParserDiagnostic>,
285 decisions: Vec<usize>,
286 actions: Vec<ParserAction>,
287 nodes: Vec<RecognizedNode>,
288}
289
290#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
291enum RecognizedNode {
292 Token {
293 index: usize,
294 },
295 ErrorToken {
296 index: usize,
297 },
298 MissingToken {
299 token_type: i32,
300 at_index: usize,
301 text: String,
302 },
303 Rule {
304 rule_index: usize,
305 invoking_state: isize,
306 alt_number: usize,
307 start_index: usize,
308 stop_index: Option<usize>,
309 return_values: BTreeMap<String, i64>,
310 children: Vec<Self>,
311 },
312 LeftRecursiveBoundary {
313 rule_index: usize,
314 },
315}
316
317#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
318struct FastRecognizeOutcome {
319 index: usize,
320 consumed_eof: bool,
321 diagnostics: Vec<ParserDiagnostic>,
322 nodes: NodeList,
331}
332
333#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
338enum NodeList {
339 #[default]
340 Empty,
341 Cons {
342 head: Rc<FastRecognizedNode>,
343 tail: Rc<Self>,
344 },
345}
346
347impl NodeList {
348 const fn new() -> Self {
350 Self::Empty
351 }
352
353 fn cons(self, node: Rc<FastRecognizedNode>) -> Self {
356 Self::Cons {
357 head: node,
358 tail: Rc::new(self),
359 }
360 }
361
362 fn prepend(&mut self, node: Rc<FastRecognizedNode>) {
365 let owned = std::mem::take(self);
366 *self = owned.cons(node);
367 }
368
369 fn to_vec(&self) -> Vec<Rc<FastRecognizedNode>> {
374 let mut out = Vec::new();
375 let mut cursor = self;
376 while let Self::Cons { head, tail } = cursor {
377 out.push(Rc::clone(head));
378 cursor = tail.as_ref();
379 }
380 out
381 }
382}
383
384#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
388enum FastRecognizedNode {
389 Token {
390 index: usize,
391 },
392 ErrorToken {
393 index: usize,
394 },
395 MissingToken {
396 token_type: i32,
397 at_index: usize,
398 text: String,
399 },
400 Rule {
401 rule_index: usize,
402 invoking_state: isize,
403 start_index: usize,
404 stop_index: Option<usize>,
405 children: Vec<Rc<Self>>,
406 },
407 LeftRecursiveBoundary {
411 rule_index: usize,
412 },
413}
414
415#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
416struct ParserDiagnostic {
417 line: usize,
418 column: usize,
419 message: String,
420}
421
422#[derive(Clone, Debug, Default, Eq, PartialEq)]
423struct ExpectedTokens {
424 index: Option<usize>,
425 symbols: BTreeSet<i32>,
426 no_viable: Option<NoViableAlternative>,
427}
428
429#[derive(Clone, Copy, Debug, Eq, PartialEq)]
430struct NoViableAlternative {
431 start_index: usize,
432 error_index: usize,
433}
434
435impl ExpectedTokens {
436 fn record_transition(&mut self, index: usize, transition: &Transition, max_token_type: i32) {
439 let symbols = transition_expected_symbols(transition, max_token_type);
440 match self.index {
441 Some(current) if index < current => {}
442 Some(current) if index == current => self.symbols.extend(symbols),
443 _ => {
444 self.index = Some(index);
445 self.symbols = symbols;
446 }
447 }
448 }
449
450 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
453 match self.no_viable {
454 Some(current) if error_index < current.error_index => {}
455 _ => {
456 self.no_viable = Some(NoViableAlternative {
457 start_index,
458 error_index,
459 });
460 }
461 }
462 }
463}
464
465fn transition_expected_symbols(transition: &Transition, max_token_type: i32) -> BTreeSet<i32> {
468 let mut symbols = BTreeSet::new();
469 match transition {
470 Transition::Atom { label, .. } => {
471 symbols.insert(*label);
472 }
473 Transition::Range { start, stop, .. } => {
474 symbols.extend(*start..=*stop);
475 }
476 Transition::Set { set, .. } => {
477 for (start, stop) in set.ranges() {
478 symbols.extend(*start..=*stop);
479 }
480 }
481 Transition::NotSet { set, .. } => {
482 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
483 }
484 Transition::Wildcard { .. } => {
485 symbols.extend(1..=max_token_type);
486 }
487 Transition::Epsilon { .. }
488 | Transition::Rule { .. }
489 | Transition::Predicate { .. }
490 | Transition::Action { .. }
491 | Transition::Precedence { .. } => {}
492 }
493 symbols
494}
495
496fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
500 let mut symbols = BTreeSet::new();
501 let mut stack = vec![state_number];
502 let mut visited = BTreeSet::new();
503 while let Some(current) = stack.pop() {
504 if !visited.insert(current) {
505 continue;
506 }
507 let Some(state) = atn.state(current) else {
508 continue;
509 };
510 for transition in &state.transitions {
511 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
512 if transition_symbols.is_empty() {
513 if transition.is_epsilon() {
514 stack.push(transition.target());
515 }
516 } else {
517 symbols.extend(transition_symbols);
518 }
519 }
520 }
521 symbols
522}
523
524#[derive(Clone, Debug, Default, Eq, PartialEq)]
531struct FirstSet {
532 symbols: BTreeSet<i32>,
533 nullable: bool,
534}
535
536type FirstSetCache = BTreeMap<(usize, usize), FirstSet>;
541
542struct FirstSetCtx<'a> {
546 cache: &'a mut FirstSetCache,
547 in_progress: BTreeSet<(usize, usize)>,
548 hit_cycle: bool,
549}
550
551fn rule_first_set(
557 atn: &Atn,
558 target: usize,
559 rule_stop_state: usize,
560 cache: &mut FirstSetCache,
561) -> FirstSet {
562 let mut ctx = FirstSetCtx {
563 cache,
564 in_progress: BTreeSet::new(),
565 hit_cycle: false,
566 };
567 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
568}
569
570fn rule_first_set_cached(
571 atn: &Atn,
572 target: usize,
573 rule_stop_state: usize,
574 ctx: &mut FirstSetCtx<'_>,
575) -> FirstSet {
576 let key = (target, rule_stop_state);
577 if let Some(cached) = ctx.cache.get(&key) {
578 return cached.clone();
579 }
580 if !ctx.in_progress.insert(key) {
581 return FirstSet::default();
585 }
586 let saved_hit_cycle = ctx.hit_cycle;
587 ctx.hit_cycle = false;
588 let mut first = FirstSet::default();
589 let mut visited = BTreeSet::new();
590 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
591 ctx.in_progress.remove(&key);
592 if !ctx.hit_cycle {
593 ctx.cache.insert(key, first.clone());
594 }
595 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
596 first
597}
598
599fn rule_first_set_inner(
600 atn: &Atn,
601 state_number: usize,
602 rule_stop_state: usize,
603 ctx: &mut FirstSetCtx<'_>,
604 visited: &mut BTreeSet<usize>,
605 first: &mut FirstSet,
606) {
607 if !visited.insert(state_number) {
608 return;
609 }
610 if state_number == rule_stop_state {
611 first.nullable = true;
612 return;
613 }
614 let Some(state) = atn.state(state_number) else {
615 return;
616 };
617 for transition in &state.transitions {
618 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
619 if !transition_symbols.is_empty() {
620 first.symbols.extend(transition_symbols);
621 continue;
622 }
623 match transition {
624 Transition::Epsilon { target }
625 | Transition::Action { target, .. }
626 | Transition::Predicate { target, .. }
627 | Transition::Precedence { target, .. } => {
628 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
629 }
630 Transition::Rule {
631 target,
632 rule_index,
633 follow_state,
634 ..
635 } => {
636 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
637 continue;
638 };
639 let child_key = (*target, child_stop);
640 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
641 ctx.hit_cycle = true;
642 }
643 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
644 first.symbols.extend(child.symbols);
645 if child.nullable {
646 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
647 }
648 }
649 Transition::Atom { .. }
650 | Transition::Range { .. }
651 | Transition::Set { .. }
652 | Transition::NotSet { .. }
653 | Transition::Wildcard { .. } => {}
654 }
655 }
656}
657
658fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
661 let mut symbols = BTreeSet::new();
662 state_sync_symbols_inner(
663 atn,
664 state_number,
665 stop_state,
666 &mut BTreeSet::new(),
667 &mut symbols,
668 );
669 symbols
670}
671
672fn state_sync_symbols_inner(
675 atn: &Atn,
676 state_number: usize,
677 stop_state: usize,
678 visited: &mut BTreeSet<usize>,
679 symbols: &mut BTreeSet<i32>,
680) {
681 if !visited.insert(state_number) {
682 return;
683 }
684 if state_number == stop_state {
685 symbols.insert(TOKEN_EOF);
686 return;
687 }
688 let Some(state) = atn.state(state_number) else {
689 return;
690 };
691 for transition in &state.transitions {
692 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
693 if transition_symbols.is_empty() {
694 match transition {
695 Transition::Rule { target, .. }
696 | Transition::Epsilon { target }
697 | Transition::Action { target, .. }
698 | Transition::Predicate { target, .. }
699 | Transition::Precedence { target, .. } => {
700 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
701 }
702 Transition::Atom { .. }
703 | Transition::Range { .. }
704 | Transition::Set { .. }
705 | Transition::NotSet { .. }
706 | Transition::Wildcard { .. } => {}
707 }
708 } else {
709 symbols.extend(transition_symbols);
710 }
711 }
712}
713
714fn next_recovery_context(
718 atn: &Atn,
719 state: &AtnState,
720 inherited: &BTreeSet<i32>,
721 inherited_state: Option<usize>,
722) -> (BTreeSet<i32>, Option<usize>) {
723 let state_symbols = state_expected_symbols(atn, state.state_number);
724 if state.transitions.len() > 1 && !state_symbols.is_empty() {
725 let mut symbols = state_symbols;
726 symbols.extend(inherited.iter().copied());
727 return (symbols, Some(state.state_number));
728 }
729 (inherited.clone(), inherited_state)
730}
731
732fn recovery_expected_symbols(
733 atn: &Atn,
734 state_number: usize,
735 inherited: &BTreeSet<i32>,
736) -> BTreeSet<i32> {
737 let mut symbols = state_expected_symbols(atn, state_number);
738 symbols.extend(inherited.iter().copied());
739 symbols
740}
741
742fn apply_member_actions(
744 source_state: usize,
745 actions: &[ParserMemberAction],
746 values: &mut BTreeMap<usize, i64>,
747) {
748 for action in actions
749 .iter()
750 .filter(|action| action.source_state == source_state)
751 {
752 *values.entry(action.member).or_default() += action.delta;
753 }
754}
755
756fn member_values_after_action(
758 source_state: usize,
759 actions: &[ParserMemberAction],
760 values: &BTreeMap<usize, i64>,
761) -> BTreeMap<usize, i64> {
762 let mut values = values.clone();
763 apply_member_actions(source_state, actions, &mut values);
764 values
765}
766
767fn return_values_after_action(
769 source_state: usize,
770 rule_index: usize,
771 actions: &[ParserReturnAction],
772 values: &BTreeMap<String, i64>,
773) -> BTreeMap<String, i64> {
774 let mut values = values.clone();
775 for action in actions
776 .iter()
777 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
778 {
779 values.insert(action.name.to_owned(), action.value);
780 }
781 values
782}
783
784fn rule_local_int_arg(
786 rule_args: &[ParserRuleArg],
787 source_state: usize,
788 rule_index: usize,
789 local_int_arg: Option<(usize, i64)>,
790) -> Option<(usize, i64)> {
791 rule_args
792 .iter()
793 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
794 .map(|arg| {
795 let value = if arg.inherit_local {
796 local_int_arg.map_or(arg.value, |(_, value)| value)
797 } else {
798 arg.value
799 };
800 (rule_index, value)
801 })
802}
803
804fn stop_outcome(
807 index: usize,
808 consumed_eof: bool,
809 rule_alt_number: usize,
810 member_values: BTreeMap<usize, i64>,
811 return_values: BTreeMap<String, i64>,
812) -> Vec<RecognizeOutcome> {
813 vec![RecognizeOutcome {
814 index,
815 consumed_eof,
816 alt_number: rule_alt_number,
817 member_values,
818 return_values,
819 diagnostics: Vec::new(),
820 decisions: Vec::new(),
821 actions: Vec::new(),
822 nodes: Vec::new(),
823 }]
824}
825
826#[derive(Clone, Debug, Eq, PartialEq)]
827struct RecognizeRequest<'a> {
828 state_number: usize,
829 stop_state: usize,
830 index: usize,
831 rule_start_index: usize,
832 decision_start_index: Option<usize>,
833 init_action_rules: &'a BTreeSet<usize>,
834 predicates: &'a [(usize, usize, ParserPredicate)],
835 rule_args: &'a [ParserRuleArg],
836 member_actions: &'a [ParserMemberAction],
837 return_actions: &'a [ParserReturnAction],
838 local_int_arg: Option<(usize, i64)>,
839 member_values: BTreeMap<usize, i64>,
840 return_values: BTreeMap<String, i64>,
841 rule_alt_number: usize,
842 track_alt_numbers: bool,
843 consumed_eof: bool,
844 precedence: i32,
847 depth: usize,
848 recovery_symbols: BTreeSet<i32>,
849 recovery_state: Option<usize>,
850}
851
852#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
853struct RecognizeKey {
854 state_number: usize,
855 stop_state: usize,
856 index: usize,
857 rule_start_index: usize,
858 decision_start_index: Option<usize>,
859 local_int_arg: Option<(usize, i64)>,
860 member_values: BTreeMap<usize, i64>,
861 return_values: BTreeMap<String, i64>,
862 rule_alt_number: usize,
863 track_alt_numbers: bool,
864 consumed_eof: bool,
865 precedence: i32,
866 recovery_symbols: BTreeSet<i32>,
867 recovery_state: Option<usize>,
868}
869
870#[derive(Clone, Debug, Eq, PartialEq)]
871struct EpsilonActionStep {
872 source_state: usize,
873 target: usize,
874 action_rule_index: Option<usize>,
875 left_recursive_boundary: Option<usize>,
876 decision: Option<usize>,
877 decision_start_index: Option<usize>,
878 alt_number: usize,
879 recovery_symbols: BTreeSet<i32>,
880 recovery_state: Option<usize>,
881}
882
883struct RecognizeScratch<'a> {
884 visiting: &'a mut BTreeSet<RecognizeKey>,
885 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
886 expected: &'a mut ExpectedTokens,
887}
888
889#[derive(Clone, Debug, Eq, PartialEq)]
890struct FastRecognizeRequest {
891 state_number: usize,
892 stop_state: usize,
893 index: usize,
894 rule_start_index: usize,
895 decision_start_index: Option<usize>,
896 precedence: i32,
897 depth: usize,
898 recovery_symbols: BTreeSet<i32>,
899 recovery_state: Option<usize>,
900}
901
902#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
903struct FastRecognizeKey {
904 state_number: usize,
905 stop_state: usize,
906 index: usize,
907 rule_start_index: usize,
908 decision_start_index: Option<usize>,
909 precedence: i32,
910 recovery_symbols: BTreeSet<i32>,
911 recovery_state: Option<usize>,
912}
913
914struct FastRecoveryRequest<'a, 'b> {
915 atn: &'a Atn,
916 transition: &'a Transition,
917 expected_symbols: BTreeSet<i32>,
918 target: usize,
919 request: FastRecognizeRequest,
920 visiting: &'b mut BTreeSet<FastRecognizeKey>,
921 memo: &'b mut BTreeMap<FastRecognizeKey, Vec<FastRecognizeOutcome>>,
922 expected: &'b mut ExpectedTokens,
923}
924
925struct FastCurrentTokenDeletionRequest<'a, 'b> {
926 atn: &'a Atn,
927 expected_symbols: BTreeSet<i32>,
928 request: FastRecognizeRequest,
929 visiting: &'b mut BTreeSet<FastRecognizeKey>,
930 memo: &'b mut BTreeMap<FastRecognizeKey, Vec<FastRecognizeOutcome>>,
931 expected: &'b mut ExpectedTokens,
932}
933
934struct RecoveryRequest<'a, 'b> {
935 atn: &'a Atn,
936 transition: &'a Transition,
937 expected_symbols: BTreeSet<i32>,
938 target: usize,
939 request: RecognizeRequest<'a>,
940 visiting: &'b mut BTreeSet<RecognizeKey>,
941 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
942 expected: &'b mut ExpectedTokens,
943}
944
945struct CurrentTokenDeletionRequest<'a, 'b> {
946 atn: &'a Atn,
947 expected_symbols: BTreeSet<i32>,
948 request: RecognizeRequest<'a>,
949 visiting: &'b mut BTreeSet<RecognizeKey>,
950 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
951 expected: &'b mut ExpectedTokens,
952}
953
954struct ConsumingFailureFallback<'a> {
957 atn: &'a Atn,
958 target: usize,
959 request: RecognizeRequest<'a>,
960 symbol: i32,
961 expected_symbols: BTreeSet<i32>,
962 decision_start_index: Option<usize>,
963 decision: Option<usize>,
964}
965
966struct ChildRuleFailureRecovery<'a> {
969 atn: &'a Atn,
970 rule_index: usize,
971 start_index: usize,
972 follow_state: usize,
973 stop_state: usize,
974 member_values: BTreeMap<usize, i64>,
975 expected: &'a ExpectedTokens,
976}
977
978#[derive(Clone, Copy, Debug)]
980struct PredicateEval<'a> {
981 index: usize,
982 rule_index: usize,
983 pred_index: usize,
984 predicates: &'a [(usize, usize, ParserPredicate)],
985 local_int_arg: Option<(usize, i64)>,
986 member_values: &'a BTreeMap<usize, i64>,
987}
988
989struct PredicateFailureRecovery<'a> {
991 rule_index: usize,
992 index: usize,
993 message: &'a str,
994 member_values: BTreeMap<usize, i64>,
995 return_values: BTreeMap<String, i64>,
996 rule_alt_number: usize,
997}
998
999impl<S> BaseParser<S>
1000where
1001 S: TokenSource,
1002{
1003 pub const fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
1006 Self {
1007 input,
1008 data,
1009 build_parse_trees: true,
1010 report_diagnostic_errors: false,
1011 prediction_mode: PredictionMode::Ll,
1012 prediction_diagnostics: Vec::new(),
1013 reported_prediction_diagnostics: BTreeSet::new(),
1014 int_members: BTreeMap::new(),
1015 invoked_predicates: Vec::new(),
1016 first_set_cache: BTreeMap::new(),
1017 fast_first_set_prefilter: true,
1018 }
1019 }
1020
1021 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
1022 &mut self.input
1023 }
1024
1025 pub fn la(&mut self, offset: isize) -> i32 {
1026 self.input.la_token(offset)
1027 }
1028
1029 pub fn consume(&mut self) {
1030 IntStream::consume(&mut self.input);
1031 }
1032
1033 pub fn set_int_member(&mut self, member: usize, value: i64) {
1035 self.int_members.insert(member, value);
1036 }
1037
1038 pub fn int_member(&self, member: usize) -> Option<i64> {
1040 self.int_members.get(&member).copied()
1041 }
1042
1043 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
1045 let value = self.int_members.entry(member).or_default();
1046 *value += delta;
1047 *value
1048 }
1049
1050 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
1057 let current = self
1058 .input
1059 .lt(1)
1060 .cloned()
1061 .ok_or_else(|| AntlrError::ParserError {
1062 line: 0,
1063 column: 0,
1064 message: "missing current token".to_owned(),
1065 })?;
1066 if current.token_type() == token_type {
1067 self.consume();
1068 Ok(ParseTree::Terminal(TerminalNode::new(current)))
1069 } else {
1070 Err(AntlrError::MismatchedInput {
1071 expected: self.vocabulary().display_name(token_type),
1072 found: self.vocabulary().display_name(current.token_type()),
1073 })
1074 }
1075 }
1076
1077 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
1078 self.match_token(TOKEN_EOF)
1079 }
1080
1081 pub const fn rule_node(&self, context: ParserRuleContext) -> ParseTree {
1082 ParseTree::Rule(RuleNode::new(context))
1083 }
1084
1085 pub fn parse_atn_rule(
1095 &mut self,
1096 atn: &Atn,
1097 rule_index: usize,
1098 ) -> Result<ParseTree, AntlrError> {
1099 let start_state = atn
1100 .rule_to_start_state()
1101 .get(rule_index)
1102 .copied()
1103 .ok_or_else(|| {
1104 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
1105 })?;
1106 let stop_state = atn
1107 .rule_to_stop_state()
1108 .get(rule_index)
1109 .copied()
1110 .filter(|state| *state != usize::MAX)
1111 .ok_or_else(|| {
1112 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
1113 })?;
1114
1115 let start_index = self.current_visible_index();
1116 self.clear_prediction_diagnostics();
1117 let first_pass = self.fast_recognize_top(atn, start_state, stop_state, start_index);
1118 let needs_retry = match &first_pass {
1119 Err(_) => true,
1130 Ok((outcome, _)) => !outcome.diagnostics.is_empty(),
1131 };
1132 let (outcome, _expected) = if needs_retry {
1133 self.fast_first_set_prefilter = false;
1134 let retry = self.fast_recognize_top(atn, start_state, stop_state, start_index);
1135 self.fast_first_set_prefilter = true;
1136 select_better_top_outcome(first_pass, retry).map_err(|expected| {
1137 let error = self.recognition_error(rule_index, start_index, &expected);
1138 report_token_source_errors(&self.input.drain_source_errors());
1139 error
1140 })?
1141 } else {
1142 first_pass.expect("first_pass is Ok in the no-retry branch")
1143 };
1144
1145 report_parser_diagnostics(&self.prediction_diagnostics);
1146 report_parser_diagnostics(&outcome.diagnostics);
1147 report_token_source_errors(&self.input.drain_source_errors());
1148 let mut context = ParserRuleContext::new(rule_index, self.state());
1149 if let Some(token) = self.token_at(start_index) {
1150 context.set_start(token);
1151 }
1152 if let Some(token) = self.rule_stop_token(outcome.index, outcome.consumed_eof) {
1153 context.set_stop(token);
1154 }
1155 if self.build_parse_trees {
1156 let folded = fold_fast_left_recursive_boundaries(outcome.nodes.to_vec());
1157 for node in &folded {
1158 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
1159 }
1160 }
1161 self.input.seek(outcome.index);
1162
1163 Ok(self.rule_node(context))
1164 }
1165
1166 fn fast_recognize_top(
1171 &mut self,
1172 atn: &Atn,
1173 start_state: usize,
1174 stop_state: usize,
1175 start_index: usize,
1176 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
1177 let mut visiting = BTreeSet::new();
1178 let mut memo = BTreeMap::new();
1179 let mut expected = ExpectedTokens::default();
1180 let outcomes = self.recognize_state_fast(
1181 atn,
1182 FastRecognizeRequest {
1183 state_number: start_state,
1184 stop_state,
1185 index: start_index,
1186 rule_start_index: start_index,
1187 decision_start_index: None,
1188 precedence: 0,
1189 depth: 0,
1190 recovery_symbols: BTreeSet::new(),
1191 recovery_state: None,
1192 },
1193 &mut visiting,
1194 &mut memo,
1195 &mut expected,
1196 );
1197 match select_best_fast_outcome(outcomes.into_iter(), self.prediction_mode) {
1198 Some(outcome) => Ok((outcome, expected)),
1199 None => Err(expected),
1200 }
1201 }
1202
1203 fn fast_recognized_node_tree(
1206 &mut self,
1207 node: &FastRecognizedNode,
1208 ) -> Result<ParseTree, AntlrError> {
1209 match node {
1210 FastRecognizedNode::Token { index } => {
1211 let token =
1212 self.input
1213 .get(*index)
1214 .cloned()
1215 .ok_or_else(|| AntlrError::ParserError {
1216 line: 0,
1217 column: 0,
1218 message: format!("missing token at index {index}"),
1219 })?;
1220 Ok(ParseTree::Terminal(TerminalNode::new(token)))
1221 }
1222 FastRecognizedNode::ErrorToken { index } => {
1223 let token =
1224 self.input
1225 .get(*index)
1226 .cloned()
1227 .ok_or_else(|| AntlrError::ParserError {
1228 line: 0,
1229 column: 0,
1230 message: format!("missing error token at index {index}"),
1231 })?;
1232 Ok(ParseTree::Error(ErrorNode::new(token)))
1233 }
1234 FastRecognizedNode::MissingToken {
1235 token_type,
1236 at_index,
1237 text,
1238 } => {
1239 let current = self.token_at(*at_index);
1240 let token = CommonToken::new(*token_type)
1241 .with_text(text)
1242 .with_span(usize::MAX, usize::MAX)
1243 .with_position(
1244 current.as_ref().map(Token::line).unwrap_or_default(),
1245 current.as_ref().map(Token::column).unwrap_or_default(),
1246 );
1247 Ok(ParseTree::Error(ErrorNode::new(token)))
1248 }
1249 FastRecognizedNode::Rule {
1250 rule_index,
1251 invoking_state,
1252 start_index,
1253 stop_index,
1254 children,
1255 } => {
1256 let mut context = ParserRuleContext::new(*rule_index, *invoking_state);
1257 if let Some(token) = self.token_at(*start_index) {
1258 context.set_start(token);
1259 }
1260 if let Some(token) = stop_index.and_then(|index| self.token_at(index)) {
1261 context.set_stop(token);
1262 }
1263 for child in children {
1264 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
1265 }
1266 Ok(self.rule_node(context))
1267 }
1268 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => Err(AntlrError::Unsupported(
1269 format!("unfolded left-recursive boundary for rule {rule_index}"),
1270 )),
1271 }
1272 }
1273
1274 pub fn parse_atn_rule_with_actions(
1281 &mut self,
1282 atn: &Atn,
1283 rule_index: usize,
1284 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
1285 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
1286 }
1287
1288 pub fn parse_atn_rule_with_action_inits(
1296 &mut self,
1297 atn: &Atn,
1298 rule_index: usize,
1299 init_action_rules: &[usize],
1300 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
1301 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
1302 }
1303
1304 pub fn parse_atn_rule_with_action_options(
1310 &mut self,
1311 atn: &Atn,
1312 rule_index: usize,
1313 init_action_rules: &[usize],
1314 track_alt_numbers: bool,
1315 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
1316 self.parse_atn_rule_with_runtime_options(
1317 atn,
1318 rule_index,
1319 ParserRuntimeOptions {
1320 init_action_rules,
1321 track_alt_numbers,
1322 ..ParserRuntimeOptions::default()
1323 },
1324 )
1325 }
1326
1327 pub fn parse_atn_rule_with_runtime_options(
1334 &mut self,
1335 atn: &Atn,
1336 rule_index: usize,
1337 options: ParserRuntimeOptions<'_>,
1338 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
1339 let ParserRuntimeOptions {
1340 init_action_rules,
1341 track_alt_numbers,
1342 predicates,
1343 rule_args,
1344 member_actions,
1345 return_actions,
1346 } = options;
1347 let start_state = atn
1348 .rule_to_start_state()
1349 .get(rule_index)
1350 .copied()
1351 .ok_or_else(|| {
1352 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
1353 })?;
1354 let stop_state = atn
1355 .rule_to_stop_state()
1356 .get(rule_index)
1357 .copied()
1358 .filter(|state| *state != usize::MAX)
1359 .ok_or_else(|| {
1360 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
1361 })?;
1362
1363 let start_index = self.current_visible_index();
1364 self.clear_prediction_diagnostics();
1365 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
1366 let mut visiting = BTreeSet::new();
1367 let mut memo = BTreeMap::new();
1368 let mut expected = ExpectedTokens::default();
1369 let member_values = self.int_members.clone();
1370 let return_values = BTreeMap::new();
1371 let outcomes = self.recognize_state(
1372 atn,
1373 RecognizeRequest {
1374 state_number: start_state,
1375 stop_state,
1376 index: start_index,
1377 rule_start_index: start_index,
1378 decision_start_index: None,
1379 init_action_rules: &init_action_rules,
1380 predicates,
1381 rule_args,
1382 member_actions,
1383 return_actions,
1384 local_int_arg: None,
1385 member_values,
1386 return_values,
1387 rule_alt_number: 0,
1388 track_alt_numbers,
1389 consumed_eof: false,
1390 precedence: 0,
1391 depth: 0,
1392 recovery_symbols: BTreeSet::new(),
1393 recovery_state: None,
1394 },
1395 &mut visiting,
1396 &mut memo,
1397 &mut expected,
1398 );
1399 let Some(outcome) = select_best_outcome(outcomes.into_iter(), self.prediction_mode) else {
1400 let error = self.recognition_error(rule_index, start_index, &expected);
1401 report_token_source_errors(&self.input.drain_source_errors());
1402 return Err(error);
1403 };
1404
1405 report_parser_diagnostics(&self.prediction_diagnostics);
1406 report_parser_diagnostics(&outcome.diagnostics);
1407 report_token_source_errors(&self.input.drain_source_errors());
1408 let mut actions = outcome.actions;
1409 if init_action_rules.contains(&rule_index) {
1410 actions.insert(
1411 0,
1412 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
1413 );
1414 }
1415 let mut context = ParserRuleContext::new(rule_index, self.state());
1416 if track_alt_numbers {
1417 context.set_alt_number(outcome.alt_number);
1418 }
1419 for (name, value) in outcome.return_values {
1420 context.set_int_return(name, value);
1421 }
1422 if let Some(token) = self.token_at(start_index) {
1423 context.set_start(token);
1424 }
1425 if let Some(token) = self.rule_stop_token(outcome.index, outcome.consumed_eof) {
1426 context.set_stop(token);
1427 }
1428 if self.build_parse_trees {
1429 let nodes = fold_left_recursive_boundaries(outcome.nodes);
1430 for node in &nodes {
1431 context.add_child(self.recognized_node_tree(node, track_alt_numbers)?);
1432 }
1433 }
1434 self.input.seek(outcome.index);
1435
1436 Ok((self.rule_node(context), actions))
1437 }
1438
1439 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
1446 let mut context = ParserRuleContext::new(rule_index, self.state());
1447 while self.la(1) != TOKEN_EOF {
1448 let token_type = self.la(1);
1449 let child = self.match_token(token_type)?;
1450 if self.build_parse_trees {
1451 context.add_child(child);
1452 }
1453 }
1454 if self.build_parse_trees {
1455 context.add_child(self.match_eof()?);
1456 }
1457 Ok(self.rule_node(context))
1458 }
1459
1460 fn recognition_error(
1463 &mut self,
1464 rule_index: usize,
1465 start_index: usize,
1466 expected: &ExpectedTokens,
1467 ) -> AntlrError {
1468 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
1469 self.input.seek(index);
1470 let current = self.input.lt(1).cloned();
1471 let line = current.as_ref().map(Token::line).unwrap_or_default();
1472 let column = current.as_ref().map(Token::column).unwrap_or_default();
1473 AntlrError::ParserError {
1474 line,
1475 column,
1476 message,
1477 }
1478 }
1479
1480 fn expected_error_message(
1482 &mut self,
1483 rule_index: usize,
1484 start_index: usize,
1485 expected: &ExpectedTokens,
1486 ) -> (usize, String) {
1487 let index = expected
1488 .index
1489 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
1490 .unwrap_or_else(|| self.input.index());
1491 self.input.seek(index);
1492 let current = self.input.lt(1).cloned();
1493 let message = if expected
1494 .no_viable
1495 .as_ref()
1496 .is_some_and(|no_viable| no_viable.error_index == index)
1497 {
1498 let start = expected
1499 .no_viable
1500 .as_ref()
1501 .map_or(start_index, |no_viable| no_viable.start_index);
1502 let text = display_input_text(&self.input.text(start, index));
1503 format!("no viable alternative at input '{text}'")
1504 } else if expected.symbols.is_empty() {
1505 if expected.index.is_some() {
1506 let found = current
1507 .as_ref()
1508 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
1509 if current
1510 .as_ref()
1511 .is_some_and(|token| token.token_type() == TOKEN_EOF)
1512 {
1513 format!(
1514 "missing {} at {found}",
1515 self.expected_symbols_display(&expected.symbols)
1516 )
1517 } else {
1518 format!("mismatched input {found}")
1519 }
1520 } else {
1521 format!("no viable alternative while parsing rule {rule_index}")
1522 }
1523 } else {
1524 format!(
1525 "mismatched input {} expecting {}",
1526 current
1527 .as_ref()
1528 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
1529 self.expected_symbols_display(&expected.symbols)
1530 )
1531 };
1532 (index, message)
1533 }
1534
1535 fn child_rule_failure_recovery(
1538 &mut self,
1539 rule_index: usize,
1540 start_index: usize,
1541 sync_symbols: &BTreeSet<i32>,
1542 member_values: BTreeMap<usize, i64>,
1543 expected: &ExpectedTokens,
1544 ) -> Option<RecognizeOutcome> {
1545 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
1546 let token = self.token_at(error_index);
1547 let mut next_index = error_index;
1548 loop {
1549 let symbol = self.token_type_at(next_index);
1550 if sync_symbols.contains(&symbol) {
1551 if next_index == error_index {
1552 return None;
1553 }
1554 break;
1555 }
1556 if symbol == TOKEN_EOF {
1557 break;
1558 }
1559 let after = self.consume_index(next_index, symbol);
1560 if after == next_index {
1561 break;
1562 }
1563 next_index = after;
1564 }
1565 Some(RecognizeOutcome {
1566 index: next_index,
1567 consumed_eof: false,
1568 alt_number: 0,
1569 member_values,
1570 return_values: BTreeMap::new(),
1571 diagnostics: vec![diagnostic_for_token(token.as_ref(), message)],
1572 decisions: Vec::new(),
1573 actions: Vec::new(),
1574 nodes: vec![RecognizedNode::ErrorToken { index: error_index }],
1575 })
1576 }
1577
1578 fn child_rule_failure_recovery_outcomes(
1581 &mut self,
1582 request: ChildRuleFailureRecovery<'_>,
1583 ) -> Vec<RecognizeOutcome> {
1584 let sync_symbols =
1585 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
1586 self.child_rule_failure_recovery(
1587 request.rule_index,
1588 request.start_index,
1589 &sync_symbols,
1590 request.member_values,
1591 request.expected,
1592 )
1593 .into_iter()
1594 .collect()
1595 }
1596
1597 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
1599 expected_symbols_display(symbols, self.vocabulary())
1600 }
1601
1602 fn single_token_deletion(
1605 &mut self,
1606 transition: &Transition,
1607 index: usize,
1608 max_token_type: i32,
1609 expected_symbols: &BTreeSet<i32>,
1610 ) -> Option<(ParserDiagnostic, usize, i32)> {
1611 let current_symbol = self.token_type_at(index);
1612 if current_symbol == TOKEN_EOF {
1613 return None;
1614 }
1615 let next_index = self.consume_index(index, current_symbol);
1616 if next_index == index {
1617 return None;
1618 }
1619 let next_symbol = self.token_type_at(next_index);
1620 if !transition.matches(next_symbol, 1, max_token_type) {
1621 return None;
1622 }
1623 let transition_expected = transition_expected_symbols(transition, max_token_type);
1624 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
1625 &transition_expected
1626 } else {
1627 expected_symbols
1628 });
1629 let current = self.token_at(index);
1630 let message = format!(
1631 "extraneous input {} expecting {expected_display}",
1632 current
1633 .as_ref()
1634 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
1635 );
1636 Some((
1637 diagnostic_for_token(current.as_ref(), message),
1638 next_index,
1639 next_symbol,
1640 ))
1641 }
1642
1643 fn current_token_deletion(
1646 &mut self,
1647 index: usize,
1648 expected_symbols: &BTreeSet<i32>,
1649 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
1650 if expected_symbols.is_empty() {
1651 return None;
1652 }
1653 let current_symbol = self.token_type_at(index);
1654 if current_symbol == TOKEN_EOF {
1655 return None;
1656 }
1657 let current = self.token_at(index);
1658 let message = format!(
1659 "extraneous input {} expecting {}",
1660 current
1661 .as_ref()
1662 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
1663 self.expected_symbols_display(expected_symbols)
1664 );
1665 let diagnostic = diagnostic_for_token(current.as_ref(), message);
1666 let mut skipped = Vec::new();
1667 let mut cursor = index;
1668 loop {
1669 let symbol = self.token_type_at(cursor);
1670 if symbol == TOKEN_EOF {
1671 return None;
1672 }
1673 skipped.push(cursor);
1674 let next_index = self.consume_index(cursor, symbol);
1675 if next_index == cursor {
1676 return None;
1677 }
1678 let next_symbol = self.token_type_at(next_index);
1679 if expected_symbols.contains(&next_symbol) {
1680 return Some((diagnostic, next_index, skipped));
1681 }
1682 cursor = next_index;
1683 }
1684 }
1685
1686 fn single_token_insertion(
1690 &mut self,
1691 transition: &Transition,
1692 index: usize,
1693 max_token_type: i32,
1694 expected_symbols: &BTreeSet<i32>,
1695 follow_symbols: &BTreeSet<i32>,
1696 ) -> Option<(ParserDiagnostic, i32, String)> {
1697 let current_symbol = self.token_type_at(index);
1698 if !follow_symbols.contains(¤t_symbol) {
1699 return None;
1700 }
1701 let transition_expected = transition_expected_symbols(transition, max_token_type);
1702 let token_type = transition_expected.iter().next().copied()?;
1703 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
1704 &transition_expected
1705 } else {
1706 expected_symbols
1707 });
1708 let mut token_symbols = BTreeSet::new();
1709 token_symbols.insert(token_type);
1710 let missing_token_display = self.expected_symbols_display(&token_symbols);
1711 let current = self.token_at(index);
1712 let message = format!(
1713 "missing {expected_display} at {}",
1714 current
1715 .as_ref()
1716 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
1717 );
1718 let text = format!("<missing {missing_token_display}>");
1719 Some((
1720 diagnostic_for_token(current.as_ref(), message),
1721 token_type,
1722 text,
1723 ))
1724 }
1725
1726 fn fast_single_token_deletion_recovery(
1730 &mut self,
1731 recovery: FastRecoveryRequest<'_, '_>,
1732 ) -> Vec<FastRecognizeOutcome> {
1733 let FastRecoveryRequest {
1734 atn,
1735 transition,
1736 expected_symbols,
1737 target,
1738 request,
1739 visiting,
1740 memo,
1741 expected,
1742 } = recovery;
1743 let FastRecognizeRequest {
1744 stop_state,
1745 index,
1746 rule_start_index,
1747 decision_start_index,
1748 precedence,
1749 depth,
1750 ..
1751 } = request;
1752 let Some((diagnostic, next_index, next_symbol)) =
1753 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
1754 else {
1755 return Vec::new();
1756 };
1757 let after_next = self.consume_index(next_index, next_symbol);
1758 self.recognize_state_fast(
1759 atn,
1760 FastRecognizeRequest {
1761 state_number: target,
1762 stop_state,
1763 index: after_next,
1764 rule_start_index,
1765 decision_start_index,
1766 precedence,
1767 depth: depth + 1,
1768 recovery_symbols: BTreeSet::new(),
1769 recovery_state: None,
1770 },
1771 visiting,
1772 memo,
1773 expected,
1774 )
1775 .into_iter()
1776 .map(|mut outcome| {
1777 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
1778 outcome.diagnostics.insert(0, diagnostic.clone());
1779 outcome
1780 .nodes
1781 .prepend(Rc::new(FastRecognizedNode::Token { index: next_index }));
1782 outcome
1783 .nodes
1784 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index }));
1785 outcome
1786 })
1787 .collect()
1788 }
1789
1790 fn fast_single_token_insertion_recovery(
1794 &mut self,
1795 recovery: FastRecoveryRequest<'_, '_>,
1796 ) -> Vec<FastRecognizeOutcome> {
1797 let FastRecoveryRequest {
1798 atn,
1799 transition,
1800 expected_symbols,
1801 target,
1802 request,
1803 visiting,
1804 memo,
1805 expected,
1806 } = recovery;
1807 let FastRecognizeRequest {
1808 stop_state,
1809 index,
1810 rule_start_index,
1811 decision_start_index,
1812 precedence,
1813 depth,
1814 ..
1815 } = request;
1816 let follow_symbols = state_expected_symbols(atn, transition.target());
1817 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
1818 transition,
1819 index,
1820 atn.max_token_type(),
1821 &expected_symbols,
1822 &follow_symbols,
1823 ) else {
1824 return Vec::new();
1825 };
1826 self.recognize_state_fast(
1827 atn,
1828 FastRecognizeRequest {
1829 state_number: target,
1830 stop_state,
1831 index,
1832 rule_start_index,
1833 decision_start_index,
1834 precedence,
1835 depth: depth + 1,
1836 recovery_symbols: BTreeSet::new(),
1837 recovery_state: None,
1838 },
1839 visiting,
1840 memo,
1841 expected,
1842 )
1843 .into_iter()
1844 .map(|mut outcome| {
1845 outcome.diagnostics.insert(0, diagnostic.clone());
1846 outcome.nodes.prepend(Rc::new(FastRecognizedNode::MissingToken {
1847 token_type,
1848 at_index: index,
1849 text: text.clone(),
1850 }));
1851 outcome
1852 })
1853 .collect()
1854 }
1855
1856 fn fast_current_token_deletion_recovery(
1859 &mut self,
1860 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
1861 ) -> Vec<FastRecognizeOutcome> {
1862 let FastCurrentTokenDeletionRequest {
1863 atn,
1864 expected_symbols,
1865 mut request,
1866 visiting,
1867 memo,
1868 expected,
1869 } = recovery;
1870 if request.index == request.rule_start_index {
1871 return Vec::new();
1872 }
1873 let Some((diagnostic, next_index, skipped)) =
1874 self.current_token_deletion(request.index, &expected_symbols)
1875 else {
1876 return Vec::new();
1877 };
1878 request.state_number = request.recovery_state.unwrap_or(request.state_number);
1879 request.index = next_index;
1880 request.depth += 1;
1881 request.recovery_state = None;
1882 self.recognize_state_fast(atn, request, visiting, memo, expected)
1883 .into_iter()
1884 .map(|mut outcome| {
1885 outcome.diagnostics.insert(0, diagnostic.clone());
1886 for index in skipped.iter().rev() {
1887 outcome
1888 .nodes
1889 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index: *index }));
1890 }
1891 outcome
1892 })
1893 .collect()
1894 }
1895
1896 fn recognize_state_fast(
1899 &mut self,
1900 atn: &Atn,
1901 request: FastRecognizeRequest,
1902 visiting: &mut BTreeSet<FastRecognizeKey>,
1903 memo: &mut BTreeMap<FastRecognizeKey, Vec<FastRecognizeOutcome>>,
1904 expected: &mut ExpectedTokens,
1905 ) -> Vec<FastRecognizeOutcome> {
1906 let FastRecognizeRequest {
1907 state_number,
1908 stop_state,
1909 index,
1910 rule_start_index,
1911 decision_start_index,
1912 precedence,
1913 depth,
1914 recovery_symbols,
1915 recovery_state,
1916 } = request;
1917 if depth > RECOGNITION_DEPTH_LIMIT {
1918 return Vec::new();
1919 }
1920 if state_number == stop_state {
1921 return vec![FastRecognizeOutcome {
1922 index,
1923 consumed_eof: false,
1924 diagnostics: Vec::new(),
1925 nodes: NodeList::new(),
1926 }];
1927 }
1928 let key = FastRecognizeKey {
1929 state_number,
1930 stop_state,
1931 index,
1932 rule_start_index,
1933 decision_start_index,
1934 precedence,
1935 recovery_symbols: recovery_symbols.clone(),
1936 recovery_state,
1937 };
1938 if let Some(outcomes) = memo.get(&key) {
1939 return outcomes.clone();
1940 }
1941
1942 let visit_key = key.clone();
1943 if !visiting.insert(visit_key.clone()) {
1944 return Vec::new();
1945 }
1946
1947 let Some(state) = atn.state(state_number) else {
1948 visiting.remove(&visit_key);
1949 return Vec::new();
1950 };
1951 let next_decision_start_index = if starts_prediction_decision(state) {
1952 Some(index)
1953 } else {
1954 decision_start_index
1955 };
1956 let (epsilon_recovery_symbols, epsilon_recovery_state) =
1957 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
1958 let mut outcomes = Vec::new();
1959 for transition in &state.transitions {
1960 match transition {
1961 Transition::Epsilon { target }
1962 | Transition::Predicate { target, .. }
1963 | Transition::Action { target, .. } => {
1964 let boundary = left_recursive_boundary(atn, state, *target);
1965 outcomes.extend(
1966 self.recognize_state_fast(
1967 atn,
1968 FastRecognizeRequest {
1969 state_number: *target,
1970 stop_state,
1971 index,
1972 rule_start_index,
1973 decision_start_index: next_decision_start_index,
1974 precedence,
1975 depth: depth + 1,
1976 recovery_symbols: epsilon_recovery_symbols.clone(),
1977 recovery_state: epsilon_recovery_state,
1978 },
1979 visiting,
1980 memo,
1981 expected,
1982 )
1983 .into_iter()
1984 .map(|mut outcome| {
1985 if let Some(rule_index) = boundary {
1986 outcome.nodes.prepend(Rc::new(
1987 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
1988 ));
1989 }
1990 outcome
1991 }),
1992 );
1993 }
1994 Transition::Precedence {
1995 target,
1996 precedence: transition_precedence,
1997 } => {
1998 if *transition_precedence >= precedence {
1999 let boundary = left_recursive_boundary(atn, state, *target);
2000 outcomes.extend(
2001 self.recognize_state_fast(
2002 atn,
2003 FastRecognizeRequest {
2004 state_number: *target,
2005 stop_state,
2006 index,
2007 rule_start_index,
2008 decision_start_index: next_decision_start_index,
2009 precedence,
2010 depth: depth + 1,
2011 recovery_symbols: epsilon_recovery_symbols.clone(),
2012 recovery_state: epsilon_recovery_state,
2013 },
2014 visiting,
2015 memo,
2016 expected,
2017 )
2018 .into_iter()
2019 .map(|mut outcome| {
2020 if let Some(rule_index) = boundary {
2021 outcome.nodes.prepend(Rc::new(
2022 FastRecognizedNode::LeftRecursiveBoundary {
2023 rule_index,
2024 },
2025 ));
2026 }
2027 outcome
2028 }),
2029 );
2030 }
2031 }
2032 Transition::Rule {
2033 target,
2034 rule_index,
2035 follow_state,
2036 precedence: rule_precedence,
2037 ..
2038 } => {
2039 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
2040 else {
2041 continue;
2042 };
2043 let symbol = self.token_type_at(index);
2055 let first =
2056 rule_first_set(atn, *target, child_stop, &mut self.first_set_cache);
2057 if self.fast_first_set_prefilter
2058 && !first.nullable
2059 && !first.symbols.contains(&symbol)
2060 {
2061 if !first.symbols.is_empty() {
2062 match expected.index {
2063 Some(current) if index < current => {}
2064 Some(current) if index == current => {
2065 expected.symbols.extend(first.symbols);
2066 }
2067 _ => {
2068 expected.index = Some(index);
2069 expected.symbols = first.symbols;
2070 }
2071 }
2072 }
2073 continue;
2074 }
2075 let expected_before_child = expected.clone();
2076 let children = self.recognize_state_fast(
2077 atn,
2078 FastRecognizeRequest {
2079 state_number: *target,
2080 stop_state: child_stop,
2081 index,
2082 rule_start_index: index,
2083 decision_start_index: None,
2084 precedence: *rule_precedence,
2085 depth: depth + 1,
2086 recovery_symbols: epsilon_recovery_symbols.clone(),
2087 recovery_state: epsilon_recovery_state,
2088 },
2089 visiting,
2090 memo,
2091 expected,
2092 );
2093 if children
2094 .iter()
2095 .any(|child| child.diagnostics.is_empty() && child.index > index)
2096 {
2097 *expected = expected_before_child;
2098 }
2099 for child in children {
2100 let child_index = child.index;
2101 let child_consumed_eof = child.consumed_eof;
2102 let child_diagnostics = child.diagnostics;
2103 let child_node = Rc::new(FastRecognizedNode::Rule {
2104 rule_index: *rule_index,
2105 invoking_state: invoking_state_number(state_number),
2106 start_index: index,
2107 stop_index: self.rule_stop_token_index(child_index, child_consumed_eof),
2108 children: fold_fast_left_recursive_boundaries(child.nodes.to_vec()),
2109 });
2110 outcomes.extend(
2111 self.recognize_state_fast(
2112 atn,
2113 FastRecognizeRequest {
2114 state_number: *follow_state,
2115 stop_state,
2116 index: child_index,
2117 rule_start_index,
2118 decision_start_index: next_decision_start_index,
2119 precedence,
2120 depth: depth + 1,
2121 recovery_symbols: BTreeSet::new(),
2122 recovery_state: None,
2123 },
2124 visiting,
2125 memo,
2126 expected,
2127 )
2128 .into_iter()
2129 .map(|mut outcome| {
2130 outcome.consumed_eof |= child_consumed_eof;
2131 let mut diagnostics = child_diagnostics.clone();
2132 diagnostics.append(&mut outcome.diagnostics);
2133 outcome.diagnostics = diagnostics;
2134 outcome.nodes.prepend(Rc::clone(&child_node));
2135 outcome
2136 }),
2137 );
2138 }
2139 }
2140 Transition::Atom { target, .. }
2141 | Transition::Range { target, .. }
2142 | Transition::Set { target, .. }
2143 | Transition::NotSet { target, .. }
2144 | Transition::Wildcard { target, .. } => {
2145 let symbol = self.token_type_at(index);
2146 if transition.matches(symbol, 1, atn.max_token_type()) {
2147 let next_index = self.consume_index(index, symbol);
2148 outcomes.extend(
2149 self.recognize_state_fast(
2150 atn,
2151 FastRecognizeRequest {
2152 state_number: *target,
2153 stop_state,
2154 index: next_index,
2155 rule_start_index,
2156 decision_start_index: next_decision_start_index,
2157 precedence,
2158 depth: depth + 1,
2159 recovery_symbols: BTreeSet::new(),
2160 recovery_state: None,
2161 },
2162 visiting,
2163 memo,
2164 expected,
2165 )
2166 .into_iter()
2167 .map(|mut outcome| {
2168 outcome.consumed_eof |= symbol == TOKEN_EOF;
2169 outcome
2170 .nodes
2171 .prepend(Rc::new(FastRecognizedNode::Token { index }));
2172 outcome
2173 }),
2174 );
2175 } else {
2176 let expected_symbols =
2177 recovery_expected_symbols(atn, state.state_number, &recovery_symbols);
2178 if expected_symbols.contains(&symbol) {
2179 continue;
2180 }
2181 expected.record_transition(index, transition, atn.max_token_type());
2182 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
2183 outcomes.extend(self.fast_single_token_deletion_recovery(
2184 FastRecoveryRequest {
2185 atn,
2186 transition,
2187 expected_symbols: expected_symbols.clone(),
2188 target: *target,
2189 request: FastRecognizeRequest {
2190 state_number,
2191 stop_state,
2192 index,
2193 rule_start_index,
2194 decision_start_index,
2195 precedence,
2196 depth,
2197 recovery_symbols: recovery_symbols.clone(),
2198 recovery_state,
2199 },
2200 visiting,
2201 memo,
2202 expected,
2203 },
2204 ));
2205 if !state_is_left_recursive_rule(atn, state) {
2206 outcomes.extend(self.fast_single_token_insertion_recovery(
2207 FastRecoveryRequest {
2208 atn,
2209 transition,
2210 expected_symbols: expected_symbols.clone(),
2211 target: *target,
2212 request: FastRecognizeRequest {
2213 state_number,
2214 stop_state,
2215 index,
2216 rule_start_index,
2217 decision_start_index,
2218 precedence,
2219 depth,
2220 recovery_symbols: recovery_symbols.clone(),
2221 recovery_state,
2222 },
2223 visiting,
2224 memo,
2225 expected,
2226 },
2227 ));
2228 }
2229 outcomes.extend(self.fast_current_token_deletion_recovery(
2230 FastCurrentTokenDeletionRequest {
2231 atn,
2232 expected_symbols,
2233 request: FastRecognizeRequest {
2234 state_number,
2235 stop_state,
2236 index,
2237 rule_start_index,
2238 decision_start_index,
2239 precedence,
2240 depth,
2241 recovery_symbols: recovery_symbols.clone(),
2242 recovery_state,
2243 },
2244 visiting,
2245 memo,
2246 expected,
2247 },
2248 ));
2249 }
2250 }
2251 }
2252 }
2253
2254 visiting.remove(&visit_key);
2255 if self.prediction_mode == PredictionMode::Ll {
2256 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
2257 }
2258 dedupe_fast_outcomes(&mut outcomes);
2259 memo.insert(key, outcomes.clone());
2260 outcomes
2261 }
2262
2263 fn single_token_deletion_recovery(
2266 &mut self,
2267 recovery: RecoveryRequest<'_, '_>,
2268 ) -> Vec<RecognizeOutcome> {
2269 let RecoveryRequest {
2270 atn,
2271 transition,
2272 expected_symbols,
2273 target,
2274 request,
2275 visiting,
2276 memo,
2277 expected,
2278 } = recovery;
2279 let RecognizeRequest {
2280 stop_state,
2281 index,
2282 rule_start_index,
2283 decision_start_index,
2284 init_action_rules,
2285 predicates,
2286 rule_args,
2287 member_actions,
2288 return_actions,
2289 local_int_arg,
2290 member_values,
2291 return_values,
2292 rule_alt_number,
2293 track_alt_numbers,
2294 consumed_eof,
2295 precedence,
2296 depth,
2297 ..
2298 } = request;
2299 let Some((diagnostic, next_index, next_symbol)) =
2300 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
2301 else {
2302 return Vec::new();
2303 };
2304 let after_next = self.consume_index(next_index, next_symbol);
2305 self.recognize_state(
2306 atn,
2307 RecognizeRequest {
2308 state_number: target,
2309 stop_state,
2310 index: after_next,
2311 rule_start_index,
2312 decision_start_index,
2313 init_action_rules,
2314 predicates,
2315 rule_args,
2316 member_actions,
2317 return_actions,
2318 local_int_arg,
2319 member_values,
2320 return_values,
2321 rule_alt_number,
2322 track_alt_numbers,
2323 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
2324 precedence,
2325 depth: depth + 1,
2326 recovery_symbols: BTreeSet::new(),
2327 recovery_state: None,
2328 },
2329 visiting,
2330 memo,
2331 expected,
2332 )
2333 .into_iter()
2334 .map(|mut outcome| {
2335 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
2336 outcome.diagnostics.insert(0, diagnostic.clone());
2337 outcome
2338 .nodes
2339 .insert(0, RecognizedNode::Token { index: next_index });
2340 outcome
2341 .nodes
2342 .insert(0, RecognizedNode::ErrorToken { index });
2343 outcome
2344 })
2345 .collect()
2346 }
2347
2348 fn current_token_deletion_recovery(
2351 &mut self,
2352 recovery: CurrentTokenDeletionRequest<'_, '_>,
2353 ) -> Vec<RecognizeOutcome> {
2354 let CurrentTokenDeletionRequest {
2355 atn,
2356 expected_symbols,
2357 mut request,
2358 visiting,
2359 memo,
2360 expected,
2361 } = recovery;
2362 let error_index = request.index;
2363 if error_index == request.rule_start_index {
2364 return Vec::new();
2365 }
2366 let Some((diagnostic, next_index, skipped)) =
2367 self.current_token_deletion(error_index, &expected_symbols)
2368 else {
2369 return Vec::new();
2370 };
2371 request.state_number = request.recovery_state.unwrap_or(request.state_number);
2372 request.index = next_index;
2373 request.depth += 1;
2374 request.recovery_state = None;
2375 self.recognize_state(atn, request, visiting, memo, expected)
2376 .into_iter()
2377 .map(|mut outcome| {
2378 outcome.diagnostics.insert(0, diagnostic.clone());
2379 for index in skipped.iter().rev() {
2380 outcome
2381 .nodes
2382 .insert(0, RecognizedNode::ErrorToken { index: *index });
2383 }
2384 outcome
2385 })
2386 .collect()
2387 }
2388
2389 fn consuming_failure_fallback(
2392 &mut self,
2393 fallback: ConsumingFailureFallback<'_>,
2394 visiting: &mut BTreeSet<RecognizeKey>,
2395 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2396 expected: &mut ExpectedTokens,
2397 ) -> Vec<RecognizeOutcome> {
2398 if fallback.expected_symbols.is_empty() {
2399 return Vec::new();
2400 }
2401 if fallback.symbol == TOKEN_EOF {
2402 return self.eof_consuming_failure_fallback(fallback, expected);
2403 }
2404 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
2405 }
2406
2407 fn non_eof_consuming_failure_fallback(
2410 &mut self,
2411 fallback: ConsumingFailureFallback<'_>,
2412 visiting: &mut BTreeSet<RecognizeKey>,
2413 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2414 expected: &mut ExpectedTokens,
2415 ) -> Vec<RecognizeOutcome> {
2416 let ConsumingFailureFallback {
2417 atn,
2418 target,
2419 request,
2420 symbol,
2421 expected_symbols,
2422 decision_start_index,
2423 decision,
2424 } = fallback;
2425 let error_index = request.index;
2426 let diagnostic =
2427 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
2428 let next_index = self.consume_index(error_index, symbol);
2429 self.recognize_state(
2430 atn,
2431 RecognizeRequest {
2432 state_number: target,
2433 stop_state: request.stop_state,
2434 index: next_index,
2435 rule_start_index: request.rule_start_index,
2436 decision_start_index,
2437 init_action_rules: request.init_action_rules,
2438 predicates: request.predicates,
2439 rule_args: request.rule_args,
2440 member_actions: request.member_actions,
2441 return_actions: request.return_actions,
2442 local_int_arg: request.local_int_arg,
2443 member_values: request.member_values,
2444 return_values: request.return_values,
2445 rule_alt_number: request.rule_alt_number,
2446 track_alt_numbers: request.track_alt_numbers,
2447 consumed_eof: request.consumed_eof,
2448 precedence: request.precedence,
2449 depth: request.depth + 1,
2450 recovery_symbols: BTreeSet::new(),
2451 recovery_state: None,
2452 },
2453 visiting,
2454 memo,
2455 expected,
2456 )
2457 .into_iter()
2458 .map(|mut outcome| {
2459 prepend_decision(&mut outcome, decision);
2460 outcome.diagnostics.insert(0, diagnostic.clone());
2461 outcome
2462 .nodes
2463 .insert(0, RecognizedNode::ErrorToken { index: error_index });
2464 outcome
2465 })
2466 .collect()
2467 }
2468
2469 fn eof_consuming_failure_fallback(
2472 &mut self,
2473 fallback: ConsumingFailureFallback<'_>,
2474 expected: &ExpectedTokens,
2475 ) -> Vec<RecognizeOutcome> {
2476 let request = fallback.request;
2477 if request.index == request.rule_start_index {
2478 return Vec::new();
2479 }
2480 let diagnostic =
2481 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
2482 vec![RecognizeOutcome {
2483 index: request.index,
2484 consumed_eof: request.consumed_eof,
2485 alt_number: request.rule_alt_number,
2486 member_values: request.member_values,
2487 return_values: request.return_values,
2488 diagnostics: vec![diagnostic],
2489 decisions: Vec::new(),
2490 actions: Vec::new(),
2491 nodes: Vec::new(),
2492 }]
2493 }
2494
2495 fn single_token_insertion_recovery(
2498 &mut self,
2499 recovery: RecoveryRequest<'_, '_>,
2500 ) -> Vec<RecognizeOutcome> {
2501 let RecoveryRequest {
2502 atn,
2503 transition,
2504 expected_symbols,
2505 target,
2506 request,
2507 visiting,
2508 memo,
2509 expected,
2510 } = recovery;
2511 let RecognizeRequest {
2512 stop_state,
2513 index,
2514 rule_start_index,
2515 decision_start_index,
2516 init_action_rules,
2517 predicates,
2518 rule_args,
2519 member_actions,
2520 return_actions,
2521 local_int_arg,
2522 member_values,
2523 return_values,
2524 rule_alt_number,
2525 track_alt_numbers,
2526 consumed_eof,
2527 precedence,
2528 depth,
2529 ..
2530 } = request;
2531 let follow_symbols = state_expected_symbols(atn, transition.target());
2532 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
2533 transition,
2534 index,
2535 atn.max_token_type(),
2536 &expected_symbols,
2537 &follow_symbols,
2538 ) else {
2539 return Vec::new();
2540 };
2541 self.recognize_state(
2542 atn,
2543 RecognizeRequest {
2544 state_number: target,
2545 stop_state,
2546 index,
2547 rule_start_index,
2548 decision_start_index,
2549 init_action_rules,
2550 predicates,
2551 rule_args,
2552 member_actions,
2553 return_actions,
2554 local_int_arg,
2555 member_values,
2556 return_values,
2557 rule_alt_number,
2558 track_alt_numbers,
2559 consumed_eof,
2560 precedence,
2561 depth: depth + 1,
2562 recovery_symbols: BTreeSet::new(),
2563 recovery_state: None,
2564 },
2565 visiting,
2566 memo,
2567 expected,
2568 )
2569 .into_iter()
2570 .map(|mut outcome| {
2571 outcome.diagnostics.insert(0, diagnostic.clone());
2572 outcome.nodes.insert(
2573 0,
2574 RecognizedNode::MissingToken {
2575 token_type,
2576 at_index: index,
2577 text: text.clone(),
2578 },
2579 );
2580 outcome
2581 })
2582 .collect()
2583 }
2584
2585 fn recognize_state(
2588 &mut self,
2589 atn: &Atn,
2590 request: RecognizeRequest<'_>,
2591 visiting: &mut BTreeSet<RecognizeKey>,
2592 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2593 expected: &mut ExpectedTokens,
2594 ) -> Vec<RecognizeOutcome> {
2595 let request_template = request.clone();
2596 let RecognizeRequest {
2597 state_number,
2598 stop_state,
2599 index,
2600 rule_start_index,
2601 decision_start_index,
2602 init_action_rules,
2603 predicates,
2604 rule_args,
2605 member_actions,
2606 return_actions,
2607 local_int_arg,
2608 member_values,
2609 return_values,
2610 rule_alt_number,
2611 track_alt_numbers,
2612 consumed_eof,
2613 precedence,
2614 depth,
2615 recovery_symbols,
2616 recovery_state,
2617 } = request;
2618 if depth > RECOGNITION_DEPTH_LIMIT {
2619 return Vec::new();
2620 }
2621 if state_number == stop_state {
2622 return stop_outcome(
2623 index,
2624 consumed_eof,
2625 rule_alt_number,
2626 member_values,
2627 return_values,
2628 );
2629 }
2630 let key = RecognizeKey {
2631 state_number,
2632 stop_state,
2633 index,
2634 rule_start_index,
2635 decision_start_index,
2636 local_int_arg,
2637 member_values: member_values.clone(),
2638 return_values: return_values.clone(),
2639 rule_alt_number,
2640 track_alt_numbers,
2641 consumed_eof,
2642 precedence,
2643 recovery_symbols: recovery_symbols.clone(),
2644 recovery_state,
2645 };
2646 if let Some(outcomes) = memo.get(&key) {
2647 return outcomes.clone();
2648 }
2649
2650 let visit_key = key.clone();
2651 if !visiting.insert(visit_key.clone()) {
2652 return Vec::new();
2653 }
2654
2655 let Some(state) = atn.state(state_number) else {
2656 visiting.remove(&visit_key);
2657 return Vec::new();
2658 };
2659 let next_decision_start_index = if starts_prediction_decision(state) {
2660 Some(index)
2661 } else {
2662 decision_start_index
2663 };
2664 let (epsilon_recovery_symbols, epsilon_recovery_state) =
2665 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
2666 let mut outcomes = Vec::new();
2667 for (transition_index, transition) in state.transitions.iter().enumerate() {
2668 let decision = transition_decision(atn, state, transition_index, predicates);
2669 let next_alt_number =
2670 next_alt_number(state, transition_index, rule_alt_number, track_alt_numbers);
2671 match transition {
2672 Transition::Epsilon { target } | Transition::Action { target, .. } => {
2673 let action_rule_index = match transition {
2674 Transition::Action { rule_index, .. } => Some(*rule_index),
2675 _ => None,
2676 };
2677 outcomes.extend(self.recognize_epsilon_or_action_step(
2678 atn,
2679 &request_template,
2680 EpsilonActionStep {
2681 source_state: state_number,
2682 target: *target,
2683 action_rule_index,
2684 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
2685 decision,
2686 decision_start_index: next_decision_start_index,
2687 alt_number: next_alt_number,
2688 recovery_symbols: epsilon_recovery_symbols.clone(),
2689 recovery_state: epsilon_recovery_state,
2690 },
2691 RecognizeScratch {
2692 visiting,
2693 memo,
2694 expected,
2695 },
2696 ));
2697 }
2698 Transition::Predicate {
2699 target,
2700 rule_index,
2701 pred_index,
2702 ..
2703 } => {
2704 let predicate = PredicateEval {
2705 index,
2706 rule_index: *rule_index,
2707 pred_index: *pred_index,
2708 predicates,
2709 local_int_arg,
2710 member_values: &member_values,
2711 };
2712 if self.parser_predicate_matches(predicate) {
2713 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
2714 outcomes.extend(
2715 self.recognize_state(
2716 atn,
2717 RecognizeRequest {
2718 state_number: *target,
2719 stop_state,
2720 index,
2721 rule_start_index,
2722 decision_start_index: next_decision_start_index,
2723 init_action_rules,
2724 predicates,
2725 rule_args,
2726 member_actions,
2727 return_actions,
2728 local_int_arg,
2729 member_values: member_values.clone(),
2730 return_values: return_values.clone(),
2731 rule_alt_number: next_alt_number,
2732 track_alt_numbers,
2733 consumed_eof,
2734 precedence,
2735 depth: depth + 1,
2736 recovery_symbols: epsilon_recovery_symbols.clone(),
2737 recovery_state: epsilon_recovery_state,
2738 },
2739 visiting,
2740 memo,
2741 expected,
2742 )
2743 .into_iter()
2744 .map(|mut outcome| {
2745 prepend_decision(&mut outcome, decision);
2746 if let Some(rule_index) = left_recursive_boundary {
2747 outcome.nodes.insert(
2748 0,
2749 RecognizedNode::LeftRecursiveBoundary { rule_index },
2750 );
2751 }
2752 outcome
2753 }),
2754 );
2755 } else if let Some(message) =
2756 self.parser_predicate_failure_message(*rule_index, *pred_index, predicates)
2757 {
2758 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
2759 rule_index: *rule_index,
2760 index,
2761 message,
2762 member_values: member_values.clone(),
2763 return_values: return_values.clone(),
2764 rule_alt_number,
2765 }));
2766 } else {
2767 record_predicate_no_viable(expected, next_decision_start_index, index);
2768 }
2769 }
2770 Transition::Precedence {
2771 target,
2772 precedence: transition_precedence,
2773 } => {
2774 if *transition_precedence >= precedence {
2775 outcomes.extend(
2776 self.recognize_state(
2777 atn,
2778 RecognizeRequest {
2779 state_number: *target,
2780 stop_state,
2781 index,
2782 rule_start_index,
2783 decision_start_index: next_decision_start_index,
2784 init_action_rules,
2785 predicates,
2786 rule_args,
2787 member_actions,
2788 return_actions,
2789 local_int_arg,
2790 member_values: member_values.clone(),
2791 return_values: return_values.clone(),
2792 rule_alt_number: next_alt_number,
2793 track_alt_numbers,
2794 consumed_eof,
2795 precedence,
2796 depth: depth + 1,
2797 recovery_symbols: epsilon_recovery_symbols.clone(),
2798 recovery_state: epsilon_recovery_state,
2799 },
2800 visiting,
2801 memo,
2802 expected,
2803 )
2804 .into_iter()
2805 .map(|mut outcome| {
2806 prepend_decision(&mut outcome, decision);
2807 outcome
2808 }),
2809 );
2810 }
2811 }
2812 Transition::Rule {
2813 target,
2814 rule_index,
2815 follow_state,
2816 precedence: rule_precedence,
2817 ..
2818 } => {
2819 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
2820 else {
2821 continue;
2822 };
2823 let child_local_int_arg =
2824 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
2825 let expected_before_child = expected.clone();
2826 let children = self.recognize_state(
2827 atn,
2828 RecognizeRequest {
2829 state_number: *target,
2830 stop_state: child_stop,
2831 index,
2832 rule_start_index: index,
2833 decision_start_index: None,
2834 init_action_rules,
2835 predicates,
2836 rule_args,
2837 member_actions,
2838 return_actions,
2839 local_int_arg: child_local_int_arg,
2840 member_values: member_values.clone(),
2841 return_values: BTreeMap::new(),
2842 rule_alt_number: 0,
2843 track_alt_numbers,
2844 consumed_eof: false,
2845 precedence: *rule_precedence,
2846 depth: depth + 1,
2847 recovery_symbols: epsilon_recovery_symbols.clone(),
2848 recovery_state: epsilon_recovery_state,
2849 },
2850 visiting,
2851 memo,
2852 expected,
2853 );
2854 let children = if children.is_empty() {
2855 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
2856 atn,
2857 rule_index: *rule_index,
2858 start_index: index,
2859 follow_state: *follow_state,
2860 stop_state,
2861 member_values: member_values.clone(),
2862 expected,
2863 })
2864 } else {
2865 children
2866 };
2867 let preserve_child_expected =
2868 self.child_expected_reaches_clean_eof(&children, expected);
2869 restore_expected(
2870 &children,
2871 index,
2872 expected,
2873 expected_before_child,
2874 preserve_child_expected,
2875 );
2876 for child in children {
2877 let child_node = RecognizedNode::Rule {
2878 rule_index: *rule_index,
2879 invoking_state: invoking_state_number(state_number),
2880 alt_number: child.alt_number,
2881 start_index: index,
2882 stop_index: self.rule_stop_token_index(child.index, child.consumed_eof),
2883 return_values: child.return_values.clone(),
2884 children: fold_left_recursive_boundaries(child.nodes.clone()),
2885 };
2886 outcomes.extend(
2887 self.recognize_state(
2888 atn,
2889 RecognizeRequest {
2890 state_number: *follow_state,
2891 stop_state,
2892 index: child.index,
2893 rule_start_index,
2894 decision_start_index: next_decision_start_index,
2895 init_action_rules,
2896 predicates,
2897 rule_args,
2898 member_actions,
2899 return_actions,
2900 local_int_arg,
2901 member_values: child.member_values.clone(),
2902 return_values: return_values.clone(),
2903 rule_alt_number,
2904 track_alt_numbers,
2905 consumed_eof: consumed_eof || child.consumed_eof,
2906 precedence,
2907 depth: depth + 1,
2908 recovery_symbols: BTreeSet::new(),
2909 recovery_state: None,
2910 },
2911 visiting,
2912 memo,
2913 expected,
2914 )
2915 .into_iter()
2916 .map(|mut outcome| {
2917 outcome.consumed_eof |= child.consumed_eof;
2918 let mut diagnostics = child.diagnostics.clone();
2919 diagnostics.append(&mut outcome.diagnostics);
2920 outcome.diagnostics = diagnostics;
2921 let mut decisions = child.decisions.clone();
2922 decisions.append(&mut outcome.decisions);
2923 outcome.decisions = decisions;
2924 prepend_decision(&mut outcome, decision);
2925 let mut actions = child.actions.clone();
2926 if init_action_rules.contains(rule_index) {
2927 actions.insert(
2928 0,
2929 ParserAction::new_rule_init(
2930 *rule_index,
2931 index,
2932 Some(*follow_state),
2933 ),
2934 );
2935 }
2936 actions.append(&mut outcome.actions);
2937 outcome.actions = actions;
2938 outcome.nodes.insert(0, child_node.clone());
2939 outcome
2940 }),
2941 );
2942 }
2943 }
2944 Transition::Atom { target, .. }
2945 | Transition::Range { target, .. }
2946 | Transition::Set { target, .. }
2947 | Transition::NotSet { target, .. }
2948 | Transition::Wildcard { target, .. } => {
2949 let symbol = self.token_type_at(index);
2950 if transition.matches(symbol, 1, atn.max_token_type()) {
2951 let next_index = self.consume_index(index, symbol);
2952 outcomes.extend(
2953 self.recognize_state(
2954 atn,
2955 RecognizeRequest {
2956 state_number: *target,
2957 stop_state,
2958 index: next_index,
2959 rule_start_index,
2960 decision_start_index: next_decision_start_index,
2961 init_action_rules,
2962 predicates,
2963 rule_args,
2964 member_actions,
2965 return_actions,
2966 local_int_arg,
2967 member_values: member_values.clone(),
2968 return_values: return_values.clone(),
2969 rule_alt_number: next_alt_number,
2970 track_alt_numbers,
2971 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
2972 precedence,
2973 depth: depth + 1,
2974 recovery_symbols: BTreeSet::new(),
2975 recovery_state: None,
2976 },
2977 visiting,
2978 memo,
2979 expected,
2980 )
2981 .into_iter()
2982 .map(|mut outcome| {
2983 prepend_decision(&mut outcome, decision);
2984 outcome.consumed_eof |= symbol == TOKEN_EOF;
2985 outcome.nodes.insert(0, RecognizedNode::Token { index });
2986 outcome
2987 }),
2988 );
2989 } else {
2990 let expected_symbols =
2991 recovery_expected_symbols(atn, state.state_number, &recovery_symbols);
2992 if expected_symbols.contains(&symbol) {
2993 continue;
2994 }
2995 expected.record_transition(index, transition, atn.max_token_type());
2996 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
2997 let before_recovery = outcomes.len();
2998 let recovery_request = request_template.clone();
2999 outcomes.extend(
3000 self.single_token_deletion_recovery(RecoveryRequest {
3001 atn,
3002 transition,
3003 expected_symbols: expected_symbols.clone(),
3004 target: *target,
3005 request: recovery_request.clone(),
3006 visiting,
3007 memo,
3008 expected,
3009 })
3010 .into_iter()
3011 .map(|mut outcome| {
3012 prepend_decision(&mut outcome, decision);
3013 outcome
3014 }),
3015 );
3016 if !state_is_left_recursive_rule(atn, state) {
3017 outcomes.extend(
3018 self.single_token_insertion_recovery(RecoveryRequest {
3019 atn,
3020 transition,
3021 expected_symbols: expected_symbols.clone(),
3022 target: *target,
3023 request: recovery_request.clone(),
3024 visiting,
3025 memo,
3026 expected,
3027 })
3028 .into_iter()
3029 .map(|mut outcome| {
3030 prepend_decision(&mut outcome, decision);
3031 outcome
3032 }),
3033 );
3034 }
3035 outcomes.extend(self.current_token_deletion_recovery(
3036 CurrentTokenDeletionRequest {
3037 atn,
3038 expected_symbols: expected_symbols.clone(),
3039 request: recovery_request.clone(),
3040 visiting,
3041 memo,
3042 expected,
3043 },
3044 ));
3045 if outcomes.len() == before_recovery {
3046 outcomes.extend(self.consuming_failure_fallback(
3047 ConsumingFailureFallback {
3048 atn,
3049 target: *target,
3050 request: recovery_request,
3051 symbol,
3052 expected_symbols,
3053 decision_start_index: next_decision_start_index,
3054 decision,
3055 },
3056 visiting,
3057 memo,
3058 expected,
3059 ));
3060 }
3061 }
3062 }
3063 }
3064 }
3065
3066 visiting.remove(&visit_key);
3067 self.record_prediction_diagnostics(atn, state, index, &outcomes);
3068 if self.prediction_mode == PredictionMode::Ll {
3069 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes);
3070 }
3071 dedupe_outcomes(&mut outcomes);
3072 memo.insert(key, outcomes.clone());
3073 outcomes
3074 }
3075
3076 fn recognize_epsilon_or_action_step(
3079 &mut self,
3080 atn: &Atn,
3081 request: &RecognizeRequest<'_>,
3082 step: EpsilonActionStep,
3083 scratch: RecognizeScratch<'_>,
3084 ) -> Vec<RecognizeOutcome> {
3085 let RecognizeScratch {
3086 visiting,
3087 memo,
3088 expected,
3089 } = scratch;
3090 let action = step.action_rule_index.map(|rule_index| {
3091 ParserAction::new(
3092 step.source_state,
3093 rule_index,
3094 request.rule_start_index,
3095 self.rule_stop_token_index(request.index, request.consumed_eof),
3096 )
3097 });
3098 let next_member_values = if action.is_some() {
3099 member_values_after_action(
3100 step.source_state,
3101 request.member_actions,
3102 &request.member_values,
3103 )
3104 } else {
3105 request.member_values.clone()
3106 };
3107 let next_return_values = action.map_or_else(
3108 || request.return_values.clone(),
3109 |action| {
3110 return_values_after_action(
3111 step.source_state,
3112 action.rule_index(),
3113 request.return_actions,
3114 &request.return_values,
3115 )
3116 },
3117 );
3118
3119 self.recognize_state(
3120 atn,
3121 RecognizeRequest {
3122 state_number: step.target,
3123 stop_state: request.stop_state,
3124 index: request.index,
3125 rule_start_index: request.rule_start_index,
3126 decision_start_index: step.decision_start_index,
3127 init_action_rules: request.init_action_rules,
3128 predicates: request.predicates,
3129 rule_args: request.rule_args,
3130 member_actions: request.member_actions,
3131 return_actions: request.return_actions,
3132 local_int_arg: request.local_int_arg,
3133 member_values: next_member_values,
3134 return_values: next_return_values,
3135 rule_alt_number: step.alt_number,
3136 track_alt_numbers: request.track_alt_numbers,
3137 consumed_eof: request.consumed_eof,
3138 precedence: request.precedence,
3139 depth: request.depth + 1,
3140 recovery_symbols: step.recovery_symbols,
3141 recovery_state: step.recovery_state,
3142 },
3143 visiting,
3144 memo,
3145 expected,
3146 )
3147 .into_iter()
3148 .map(|mut outcome| {
3149 prepend_decision(&mut outcome, step.decision);
3150 if let Some(rule_index) = step.left_recursive_boundary {
3151 outcome
3152 .nodes
3153 .insert(0, RecognizedNode::LeftRecursiveBoundary { rule_index });
3154 }
3155 if let Some(action) = action {
3156 outcome.actions.insert(0, action);
3157 }
3158 outcome
3159 })
3160 .collect()
3161 }
3162
3163 fn token_type_at(&mut self, index: usize) -> i32 {
3165 self.input.seek(index);
3166 self.input.la_token(1)
3167 }
3168
3169 fn token_at(&mut self, index: usize) -> Option<CommonToken> {
3171 self.input.get(index).cloned()
3172 }
3173
3174 fn current_visible_index(&mut self) -> usize {
3177 let index = self.input.index();
3178 self.input.seek(index);
3179 self.input.index()
3180 }
3181
3182 fn child_expected_reaches_clean_eof(
3185 &mut self,
3186 children: &[RecognizeOutcome],
3187 expected: &ExpectedTokens,
3188 ) -> bool {
3189 let Some(index) = expected.index else {
3190 return false;
3191 };
3192 self.token_type_at(index) == TOKEN_EOF
3193 && children
3194 .iter()
3195 .any(|child| child.diagnostics.is_empty() && child.index == index)
3196 }
3197
3198 fn previous_token_index(&mut self, index: usize) -> Option<usize> {
3205 self.input.previous_visible_token_index(index)
3206 }
3207
3208 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
3213 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
3214 Some(index)
3215 } else {
3216 self.previous_token_index(index)
3217 }
3218 }
3219
3220 fn rule_stop_token(&mut self, index: usize, consumed_eof: bool) -> Option<CommonToken> {
3225 self.rule_stop_token_index(index, consumed_eof)
3226 .and_then(|token_index| self.token_at(token_index))
3227 }
3228
3229 fn predicate_failure_recovery(
3236 &mut self,
3237 request: PredicateFailureRecovery<'_>,
3238 ) -> RecognizeOutcome {
3239 let PredicateFailureRecovery {
3240 rule_index,
3241 index,
3242 message,
3243 member_values,
3244 return_values,
3245 rule_alt_number,
3246 } = request;
3247 let rule_name = self
3248 .rule_names()
3249 .get(rule_index)
3250 .map_or_else(|| rule_index.to_string(), Clone::clone);
3251 let diagnostic = diagnostic_for_token(
3252 self.token_at(index).as_ref(),
3253 format!("rule {rule_name} {message}"),
3254 );
3255 let mut nodes = Vec::new();
3256 let mut next_index = index;
3257 loop {
3258 let symbol = self.token_type_at(next_index);
3259 if symbol == TOKEN_EOF {
3260 break;
3261 }
3262 nodes.push(RecognizedNode::ErrorToken { index: next_index });
3263 let after = self.consume_index(next_index, symbol);
3264 if after == next_index {
3265 break;
3266 }
3267 next_index = after;
3268 }
3269 RecognizeOutcome {
3270 index: next_index,
3271 consumed_eof: false,
3272 alt_number: rule_alt_number,
3273 member_values,
3274 return_values,
3275 diagnostics: vec![diagnostic],
3276 decisions: Vec::new(),
3277 actions: Vec::new(),
3278 nodes,
3279 }
3280 }
3281
3282 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
3289 let PredicateEval {
3290 index,
3291 rule_index,
3292 pred_index,
3293 predicates,
3294 local_int_arg,
3295 member_values,
3296 } = eval;
3297 let Some((_, _, predicate)) = predicates
3298 .iter()
3299 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
3300 else {
3301 return true;
3302 };
3303 self.input.seek(index);
3304 match predicate {
3305 ParserPredicate::True => true,
3306 ParserPredicate::False => false,
3307 ParserPredicate::FalseWithMessage { .. } => false,
3308 ParserPredicate::Invoke { value } => {
3309 let key = (rule_index, pred_index);
3310 if !self.invoked_predicates.contains(&key) {
3311 self.invoked_predicates.push(key);
3312 use std::io::Write as _;
3313 let mut stdout = std::io::stdout().lock();
3314 let _ = writeln!(stdout, "eval={value}");
3315 }
3316 *value
3317 }
3318 ParserPredicate::LookaheadTextEquals { offset, text } => {
3319 self.input.lt(*offset).and_then(Token::text) == Some(*text)
3320 }
3321 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
3322 self.la(*offset) != *token_type
3323 }
3324 ParserPredicate::LocalIntEquals { value } => {
3325 local_int_arg.is_none_or(|(_, actual)| actual == *value)
3326 }
3327 ParserPredicate::LocalIntLessOrEqual { value } => {
3328 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
3329 }
3330 ParserPredicate::MemberModuloEquals {
3331 member,
3332 modulus,
3333 value,
3334 equals,
3335 } => {
3336 if *modulus == 0 {
3337 return false;
3338 }
3339 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
3340 (actual == *value) == *equals
3341 }
3342 }
3343 }
3344
3345 fn parser_predicate_failure_message(
3347 &self,
3348 rule_index: usize,
3349 pred_index: usize,
3350 predicates: &[(usize, usize, ParserPredicate)],
3351 ) -> Option<&'static str> {
3352 predicates
3353 .iter()
3354 .find_map(|(rule, pred, predicate)| match predicate {
3355 ParserPredicate::FalseWithMessage { message }
3356 if *rule == rule_index && *pred == pred_index =>
3357 {
3358 Some(*message)
3359 }
3360 _ => None,
3361 })
3362 }
3363
3364 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
3369 self.input.seek(index);
3370 if symbol != TOKEN_EOF {
3371 self.consume();
3372 }
3373 self.input.index()
3374 }
3375
3376 fn no_viable_alternative(
3379 &mut self,
3380 start_index: usize,
3381 error_index: usize,
3382 ) -> ParserDiagnostic {
3383 let text = display_input_text(&self.input.text(start_index, error_index));
3384 diagnostic_for_token(
3385 self.token_at(error_index).as_ref(),
3386 format!("no viable alternative at input '{text}'"),
3387 )
3388 }
3389
3390 fn recovery_failure_diagnostic(
3393 &mut self,
3394 index: usize,
3395 decision_start_index: Option<usize>,
3396 expected_symbols: &BTreeSet<i32>,
3397 ) -> ParserDiagnostic {
3398 if expected_symbols.len() > 1 {
3399 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
3400 return self.no_viable_alternative(decision_start, index);
3401 }
3402 }
3403 diagnostic_for_token(
3404 self.token_at(index).as_ref(),
3405 format!(
3406 "mismatched input {} expecting {}",
3407 self.token_at(index)
3408 .as_ref()
3409 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
3410 self.expected_symbols_display(expected_symbols)
3411 ),
3412 )
3413 }
3414
3415 fn eof_rule_recovery_diagnostic(
3418 &mut self,
3419 index: usize,
3420 expected_symbols: &BTreeSet<i32>,
3421 expected: &ExpectedTokens,
3422 ) -> ParserDiagnostic {
3423 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
3424 &expected.symbols
3425 } else {
3426 expected_symbols
3427 };
3428 diagnostic_for_token(
3429 self.token_at(index).as_ref(),
3430 format!(
3431 "mismatched input {} expecting {}",
3432 self.token_at(index)
3433 .as_ref()
3434 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
3435 self.expected_symbols_display(symbols)
3436 ),
3437 )
3438 }
3439
3440 pub fn text_interval(&mut self, start: usize, stop: Option<usize>) -> String {
3446 let Some(stop) = stop else {
3447 return String::new();
3448 };
3449 let stop = if self
3450 .token_at(stop)
3451 .is_some_and(|token| token.token_type() == TOKEN_EOF)
3452 {
3453 let Some(previous) = self.previous_token_index(stop) else {
3454 return String::new();
3455 };
3456 previous
3457 } else {
3458 stop
3459 };
3460 self.input.text(start, stop)
3461 }
3462
3463 fn clear_prediction_diagnostics(&mut self) {
3466 self.prediction_diagnostics.clear();
3467 self.reported_prediction_diagnostics.clear();
3468 }
3469
3470 fn record_prediction_diagnostics(
3473 &mut self,
3474 atn: &Atn,
3475 state: &AtnState,
3476 start_index: usize,
3477 outcomes: &[RecognizeOutcome],
3478 ) {
3479 if !self.report_diagnostic_errors || state.transitions.len() < 2 {
3480 return;
3481 }
3482 let Some(decision) = atn
3483 .decision_to_state()
3484 .iter()
3485 .position(|state_number| *state_number == state.state_number)
3486 else {
3487 return;
3488 };
3489 let Some(rule_index) = state.rule_index else {
3490 return;
3491 };
3492 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
3493 for outcome in outcomes
3494 .iter()
3495 .filter(|outcome| outcome.diagnostics.is_empty())
3496 {
3497 let Some(alt) = outcome.decisions.first() else {
3498 continue;
3499 };
3500 alts_by_end
3501 .entry(outcome.index)
3502 .or_default()
3503 .insert(alt + 1);
3504 }
3505 let Some((&end_index, ambig_alts)) = alts_by_end
3506 .iter()
3507 .filter(|(_, alts)| alts.len() > 1)
3508 .max_by_key(|(end, _)| *end)
3509 else {
3510 return;
3511 };
3512 let rule_name = self
3513 .rule_names()
3514 .get(rule_index)
3515 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
3516 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
3517 let input = display_input_text(&self.input.text(start_index, stop_index));
3518 let alts = ambig_alts
3519 .iter()
3520 .map(usize::to_string)
3521 .collect::<Vec<_>>()
3522 .join(", ");
3523 let key = (decision, start_index, format!("{alts}:{input}"));
3524 if !self.reported_prediction_diagnostics.insert(key) {
3525 return;
3526 }
3527 let start_token = self.token_at(start_index);
3528 let stop_token = self.token_at(stop_index);
3529 self.prediction_diagnostics.push(diagnostic_for_token(
3530 start_token.as_ref(),
3531 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
3532 ));
3533 self.prediction_diagnostics.push(diagnostic_for_token(
3534 stop_token.as_ref(),
3535 format!(
3536 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
3537 ),
3538 ));
3539 }
3540
3541 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
3543 expected_symbols_display(
3544 &state_expected_symbols(atn, state_number),
3545 self.vocabulary(),
3546 )
3547 }
3548
3549 pub fn token_display_at(&mut self, index: usize) -> Option<String> {
3551 self.token_at(index).map(|token| format!("{token}"))
3552 }
3553
3554 fn recognized_node_tree(
3556 &mut self,
3557 node: &RecognizedNode,
3558 track_alt_numbers: bool,
3559 ) -> Result<ParseTree, AntlrError> {
3560 match node {
3561 RecognizedNode::Token { index } => {
3562 let token =
3563 self.input
3564 .get(*index)
3565 .cloned()
3566 .ok_or_else(|| AntlrError::ParserError {
3567 line: 0,
3568 column: 0,
3569 message: format!("missing token at index {index}"),
3570 })?;
3571 Ok(ParseTree::Terminal(TerminalNode::new(token)))
3572 }
3573 RecognizedNode::ErrorToken { index } => {
3574 let token =
3575 self.input
3576 .get(*index)
3577 .cloned()
3578 .ok_or_else(|| AntlrError::ParserError {
3579 line: 0,
3580 column: 0,
3581 message: format!("missing error token at index {index}"),
3582 })?;
3583 Ok(ParseTree::Error(ErrorNode::new(token)))
3584 }
3585 RecognizedNode::MissingToken {
3586 token_type,
3587 at_index,
3588 text,
3589 } => {
3590 let current = self.token_at(*at_index);
3591 let token = CommonToken::new(*token_type)
3592 .with_text(text)
3593 .with_span(usize::MAX, usize::MAX)
3594 .with_position(
3595 current.as_ref().map(Token::line).unwrap_or_default(),
3596 current.as_ref().map(Token::column).unwrap_or_default(),
3597 );
3598 Ok(ParseTree::Error(ErrorNode::new(token)))
3599 }
3600 RecognizedNode::Rule {
3601 rule_index,
3602 invoking_state,
3603 alt_number,
3604 start_index,
3605 stop_index,
3606 return_values,
3607 children,
3608 } => {
3609 let mut context = ParserRuleContext::new(*rule_index, *invoking_state);
3610 if track_alt_numbers {
3611 context.set_alt_number(*alt_number);
3612 }
3613 for (name, value) in return_values {
3614 context.set_int_return(name.clone(), *value);
3615 }
3616 if let Some(token) = self.token_at(*start_index) {
3617 context.set_start(token);
3618 }
3619 if let Some(token) = stop_index.and_then(|index| self.token_at(index)) {
3620 context.set_stop(token);
3621 }
3622 for child in children {
3623 context.add_child(self.recognized_node_tree(child, track_alt_numbers)?);
3624 }
3625 Ok(self.rule_node(context))
3626 }
3627 RecognizedNode::LeftRecursiveBoundary { rule_index } => Err(AntlrError::Unsupported(
3628 format!("unfolded left-recursive boundary for rule {rule_index}"),
3629 )),
3630 }
3631 }
3632}
3633
3634fn left_recursive_boundary(atn: &Atn, state: &AtnState, target: usize) -> Option<usize> {
3637 if !state.precedence_rule_decision {
3638 return None;
3639 }
3640 let target_state = atn.state(target)?;
3641 if target_state.kind == AtnStateKind::LoopEnd {
3642 return None;
3643 }
3644 state.rule_index
3645}
3646
3647const fn next_alt_number(
3654 state: &AtnState,
3655 transition_index: usize,
3656 current_alt_number: usize,
3657 track_alt_numbers: bool,
3658) -> usize {
3659 if !track_alt_numbers || current_alt_number != 0 || state.transitions.len() <= 1 {
3660 return current_alt_number;
3661 }
3662 if matches!(
3663 state.kind,
3664 AtnStateKind::Basic
3665 | AtnStateKind::BlockStart
3666 | AtnStateKind::PlusBlockStart
3667 | AtnStateKind::StarBlockStart
3668 | AtnStateKind::StarLoopEntry
3669 ) && !state.precedence_rule_decision
3670 {
3671 return transition_index + 1;
3672 }
3673 current_alt_number
3674}
3675
3676fn fold_left_recursive_boundaries(nodes: Vec<RecognizedNode>) -> Vec<RecognizedNode> {
3679 let mut folded = Vec::new();
3680 for node in nodes {
3681 match node {
3682 RecognizedNode::LeftRecursiveBoundary { rule_index } => {
3683 if !folded.is_empty() {
3684 let children = std::mem::take(&mut folded);
3685 let start_index = recognized_nodes_start_index(&children).unwrap_or_default();
3686 let stop_index = recognized_nodes_stop_index(&children);
3687 folded.push(RecognizedNode::Rule {
3688 rule_index,
3689 invoking_state: -1,
3690 alt_number: 0,
3691 start_index,
3692 stop_index,
3693 return_values: BTreeMap::new(),
3694 children,
3695 });
3696 }
3697 }
3698 node => folded.push(node),
3699 }
3700 }
3701 folded
3702}
3703
3704fn fold_fast_left_recursive_boundaries(
3706 nodes: Vec<Rc<FastRecognizedNode>>,
3707) -> Vec<Rc<FastRecognizedNode>> {
3708 let mut folded: Vec<Rc<FastRecognizedNode>> = Vec::new();
3709 for node in nodes {
3710 match node.as_ref() {
3711 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
3712 if !folded.is_empty() {
3713 let children = std::mem::take(&mut folded);
3714 let start_index =
3715 fast_recognized_nodes_start_index(&children).unwrap_or_default();
3716 let stop_index = fast_recognized_nodes_stop_index(&children);
3717 folded.push(Rc::new(FastRecognizedNode::Rule {
3718 rule_index: *rule_index,
3719 invoking_state: -1,
3720 start_index,
3721 stop_index,
3722 children,
3723 }));
3724 }
3725 }
3726 _ => folded.push(node),
3727 }
3728 }
3729 folded
3730}
3731
3732fn fast_recognized_nodes_start_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
3733 nodes
3734 .iter()
3735 .find_map(|node| fast_recognized_node_start_index(node.as_ref()))
3736}
3737
3738const fn fast_recognized_node_start_index(node: &FastRecognizedNode) -> Option<usize> {
3739 match node {
3740 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
3741 Some(*index)
3742 }
3743 FastRecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
3744 FastRecognizedNode::Rule { start_index, .. } => Some(*start_index),
3745 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
3746 }
3747}
3748
3749fn fast_recognized_nodes_stop_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
3750 nodes
3751 .iter()
3752 .rev()
3753 .find_map(|node| fast_recognized_node_stop_index(node.as_ref()))
3754}
3755
3756const fn fast_recognized_node_stop_index(node: &FastRecognizedNode) -> Option<usize> {
3757 match node {
3758 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
3759 Some(*index)
3760 }
3761 FastRecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
3762 FastRecognizedNode::Rule { stop_index, .. } => *stop_index,
3763 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
3764 }
3765}
3766
3767fn recognized_nodes_start_index(nodes: &[RecognizedNode]) -> Option<usize> {
3768 nodes.iter().find_map(recognized_node_start_index)
3769}
3770
3771const fn recognized_node_start_index(node: &RecognizedNode) -> Option<usize> {
3772 match node {
3773 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
3774 RecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
3775 RecognizedNode::Rule { start_index, .. } => Some(*start_index),
3776 RecognizedNode::LeftRecursiveBoundary { .. } => None,
3777 }
3778}
3779
3780fn recognized_nodes_stop_index(nodes: &[RecognizedNode]) -> Option<usize> {
3781 nodes.iter().rev().find_map(recognized_node_stop_index)
3782}
3783
3784fn invoking_state_number(state_number: usize) -> isize {
3787 isize::try_from(state_number).unwrap_or(isize::MAX)
3788}
3789
3790const fn recognized_node_stop_index(node: &RecognizedNode) -> Option<usize> {
3791 match node {
3792 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
3793 RecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
3794 RecognizedNode::Rule { stop_index, .. } => *stop_index,
3795 RecognizedNode::LeftRecursiveBoundary { .. } => None,
3796 }
3797}
3798
3799fn token_input_display(token: &impl Token) -> String {
3800 format!("'{}'", token.text().unwrap_or("<EOF>"))
3801}
3802
3803fn display_input_text(text: &str) -> String {
3804 let mut out = String::new();
3805 for ch in text.chars() {
3806 match ch {
3807 '\n' => out.push_str("\\n"),
3808 '\r' => out.push_str("\\r"),
3809 '\t' => out.push_str("\\t"),
3810 other => out.push(other),
3811 }
3812 }
3813 out
3814}
3815
3816fn diagnostic_for_token(token: Option<&impl Token>, message: String) -> ParserDiagnostic {
3817 ParserDiagnostic {
3818 line: token.map(Token::line).unwrap_or_default(),
3819 column: token.map(Token::column).unwrap_or_default(),
3820 message,
3821 }
3822}
3823
3824#[allow(clippy::print_stderr)]
3826fn report_parser_diagnostics(diagnostics: &[ParserDiagnostic]) {
3827 for diagnostic in diagnostics {
3828 eprintln!(
3829 "line {}:{} {}",
3830 diagnostic.line, diagnostic.column, diagnostic.message
3831 );
3832 }
3833}
3834
3835#[allow(clippy::print_stderr)]
3838fn report_token_source_errors(errors: &[TokenSourceError]) {
3839 for error in errors {
3840 eprintln!("line {}:{} {}", error.line, error.column, error.message);
3841 }
3842}
3843
3844fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
3845 let items = symbols
3846 .iter()
3847 .map(|symbol| expected_symbol_display(*symbol, vocabulary))
3848 .collect::<Vec<_>>();
3849 if let [single] = items.as_slice() {
3850 return single.clone();
3851 }
3852 format!("{{{}}}", items.join(", "))
3853}
3854
3855fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
3856 if symbol == TOKEN_EOF {
3857 return "<EOF>".to_owned();
3858 }
3859 vocabulary.display_name(symbol)
3860}
3861
3862fn state_is_left_recursive_rule(atn: &Atn, state: &AtnState) -> bool {
3866 let Some(rule_index) = state.rule_index else {
3867 return false;
3868 };
3869 atn.rule_to_start_state()
3870 .get(rule_index)
3871 .and_then(|state_number| atn.state(*state_number))
3872 .is_some_and(|rule_start| rule_start.left_recursive_rule)
3873}
3874
3875fn select_better_top_outcome(
3885 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
3886 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
3887) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
3888 match (first, second) {
3889 (Ok(first), Ok(second)) => {
3890 if first.0.diagnostics.is_empty() {
3891 Ok(first)
3892 } else {
3893 Ok(second)
3894 }
3895 }
3896 (Ok(first), Err(_)) => Ok(first),
3897 (Err(_), Ok(second)) => Ok(second),
3898 (Err(_), Err(second_expected)) => Err(second_expected),
3899 }
3900}
3901
3902fn select_best_fast_outcome(
3905 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
3906 prediction_mode: PredictionMode,
3907) -> Option<FastRecognizeOutcome> {
3908 outcomes.reduce(|best, outcome| {
3909 let outcome_position = (outcome.index, outcome.consumed_eof);
3910 let best_position = (best.index, best.consumed_eof);
3911 let better = match prediction_mode {
3912 PredictionMode::Ll => outcome_is_better(
3913 outcome_position,
3914 &outcome.diagnostics,
3915 best_position,
3916 &best.diagnostics,
3917 ),
3918 PredictionMode::Sll => outcome.index > best.index,
3919 };
3920 if better {
3921 return outcome;
3922 }
3923 best
3924 })
3925}
3926
3927fn select_best_outcome(
3928 outcomes: impl Iterator<Item = RecognizeOutcome>,
3929 prediction_mode: PredictionMode,
3930) -> Option<RecognizeOutcome> {
3931 let outcomes = outcomes.collect::<Vec<_>>();
3932 let prefer_first_tie = outcomes
3933 .iter()
3934 .any(|outcome| nodes_need_stable_tie(&outcome.nodes));
3935 outcomes.into_iter().reduce(|best, outcome| {
3936 let outcome_position = (outcome.index, outcome.consumed_eof);
3937 let best_position = (best.index, best.consumed_eof);
3938 let better = match prediction_mode {
3939 PredictionMode::Ll => {
3940 outcome_is_better(
3941 outcome_position,
3942 &outcome.diagnostics,
3943 best_position,
3944 &best.diagnostics,
3945 ) || (!prefer_first_tie
3946 && outcome_position == best_position
3947 && outcome.diagnostics.len() == best.diagnostics.len()
3948 && diagnostic_recovery_rank(&outcome.diagnostics)
3949 == diagnostic_recovery_rank(&best.diagnostics)
3950 && (outcome.decisions < best.decisions
3951 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
3952 }
3953 PredictionMode::Sll => {
3954 outcome_position > best_position
3955 || (outcome_position == best_position
3956 && !prefer_first_tie
3957 && (outcome.decisions < best.decisions
3958 || (outcome.decisions == best.decisions
3959 && outcome_is_better(
3960 outcome_position,
3961 &outcome.diagnostics,
3962 best_position,
3963 &best.diagnostics,
3964 ))))
3965 }
3966 };
3967 if better {
3968 return outcome;
3969 }
3970 best
3971 })
3972}
3973
3974fn transition_decision(
3981 atn: &Atn,
3982 state: &AtnState,
3983 transition_index: usize,
3984 predicates: &[(usize, usize, ParserPredicate)],
3985) -> Option<usize> {
3986 if state.transitions.len() <= 1
3987 || state.precedence_rule_decision
3988 || decision_reaches_unsupported_predicate(atn, state, predicates)
3989 {
3990 return None;
3991 }
3992 Some(transition_index)
3993}
3994
3995const fn starts_prediction_decision(state: &AtnState) -> bool {
4001 state.transitions.len() > 1
4002 && !matches!(
4003 state.kind,
4004 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
4005 )
4006}
4007
4008fn record_no_viable_if_ambiguous(
4011 expected: &mut ExpectedTokens,
4012 decision_start_index: Option<usize>,
4013 index: usize,
4014) {
4015 if expected.index == Some(index) && expected.symbols.len() > 1 {
4016 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
4017 expected.record_no_viable(decision_start, index);
4018 }
4019 }
4020}
4021
4022const fn record_predicate_no_viable(
4025 expected: &mut ExpectedTokens,
4026 decision_start_index: Option<usize>,
4027 index: usize,
4028) {
4029 if let Some(decision_start) = decision_start_index {
4030 expected.record_no_viable(decision_start, index);
4031 }
4032}
4033
4034const fn no_viable_decision_start(
4036 decision_start_index: Option<usize>,
4037 index: usize,
4038) -> Option<usize> {
4039 match decision_start_index {
4040 Some(start) if index > start => Some(start),
4041 _ => None,
4042 }
4043}
4044
4045fn restore_expected(
4049 children: &[RecognizeOutcome],
4050 child_start_index: usize,
4051 expected: &mut ExpectedTokens,
4052 snapshot: ExpectedTokens,
4053 preserve_child_expected: bool,
4054) {
4055 if preserve_child_expected {
4056 return;
4057 }
4058 if children
4059 .iter()
4060 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
4061 {
4062 *expected = snapshot;
4063 }
4064}
4065
4066fn decision_reaches_unsupported_predicate(
4069 atn: &Atn,
4070 state: &AtnState,
4071 predicates: &[(usize, usize, ParserPredicate)],
4072) -> bool {
4073 state.transitions.iter().any(|transition| {
4074 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
4075 })
4076}
4077
4078fn transition_reaches_unsupported_predicate(
4080 atn: &Atn,
4081 transition: &Transition,
4082 predicates: &[(usize, usize, ParserPredicate)],
4083 visited: &mut BTreeSet<usize>,
4084) -> bool {
4085 match transition {
4086 Transition::Predicate {
4087 rule_index,
4088 pred_index,
4089 ..
4090 } => !predicates
4091 .iter()
4092 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
4093 Transition::Epsilon { target }
4094 | Transition::Action { target, .. }
4095 | Transition::Rule { target, .. } => {
4096 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
4097 }
4098 Transition::Precedence { .. }
4099 | Transition::Atom { .. }
4100 | Transition::Range { .. }
4101 | Transition::Set { .. }
4102 | Transition::NotSet { .. }
4103 | Transition::Wildcard { .. } => false,
4104 }
4105}
4106
4107fn state_reaches_unsupported_predicate(
4109 atn: &Atn,
4110 state_number: usize,
4111 predicates: &[(usize, usize, ParserPredicate)],
4112 visited: &mut BTreeSet<usize>,
4113) -> bool {
4114 if !visited.insert(state_number) {
4115 return false;
4116 }
4117 let Some(state) = atn.state(state_number) else {
4118 return false;
4119 };
4120 state.transitions.iter().any(|transition| {
4121 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
4122 })
4123}
4124
4125fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
4127 if let Some(decision) = decision {
4128 outcome.decisions.insert(0, decision);
4129 }
4130}
4131
4132fn outcome_is_better(
4133 outcome_position: (usize, bool),
4134 outcome_diagnostics: &[ParserDiagnostic],
4135 best_position: (usize, bool),
4136 best_diagnostics: &[ParserDiagnostic],
4137) -> bool {
4138 outcome_position > best_position
4139 || (outcome_position == best_position
4140 && (outcome_diagnostics.len() < best_diagnostics.len()
4141 || (outcome_diagnostics.len() == best_diagnostics.len()
4142 && diagnostic_recovery_rank(outcome_diagnostics)
4143 < diagnostic_recovery_rank(best_diagnostics))))
4144}
4145
4146fn diagnostic_recovery_rank(diagnostics: &[ParserDiagnostic]) -> usize {
4149 diagnostics
4150 .iter()
4151 .filter(|diagnostic| {
4152 diagnostic.message.starts_with("mismatched input ")
4153 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
4154 })
4155 .count()
4156}
4157
4158fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
4159 if outcomes
4160 .iter()
4161 .any(|outcome| outcome.diagnostics.is_empty())
4162 {
4163 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
4164 }
4165}
4166
4167fn discard_recovered_outcomes_if_clean_path_exists(outcomes: &mut Vec<RecognizeOutcome>) {
4168 if outcomes.iter().any(outcome_has_rule_failure_diagnostic) {
4169 return;
4170 }
4171 if outcomes
4172 .iter()
4173 .any(|outcome| outcome.diagnostics.is_empty())
4174 {
4175 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
4176 }
4177}
4178
4179fn outcome_has_rule_failure_diagnostic(outcome: &RecognizeOutcome) -> bool {
4182 outcome
4183 .diagnostics
4184 .iter()
4185 .any(|diagnostic| diagnostic.message.starts_with("rule "))
4186}
4187
4188fn nodes_need_stable_tie(nodes: &[RecognizedNode]) -> bool {
4191 nodes.iter().any(node_needs_stable_tie)
4192}
4193
4194fn node_needs_stable_tie(node: &RecognizedNode) -> bool {
4195 match node {
4196 RecognizedNode::Token { .. }
4197 | RecognizedNode::ErrorToken { .. }
4198 | RecognizedNode::MissingToken { .. } => false,
4199 RecognizedNode::LeftRecursiveBoundary { .. } => true,
4200 RecognizedNode::Rule {
4201 rule_index,
4202 children,
4203 ..
4204 } => children.iter().any(|child| {
4205 matches!(
4206 child,
4207 RecognizedNode::Rule {
4208 rule_index: child_rule,
4209 ..
4210 } if child_rule == rule_index
4211 ) || node_needs_stable_tie(child)
4212 }),
4213 }
4214}
4215
4216fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
4230 if outcomes.len() < 2 {
4231 return;
4232 }
4233 let mut keep = Vec::with_capacity(outcomes.len());
4234 let mut seen: BTreeMap<(usize, bool), Vec<usize>> = BTreeMap::new();
4235 'outcomes: for (index, outcome) in outcomes.iter().enumerate() {
4236 let bucket = seen
4237 .entry((outcome.index, outcome.consumed_eof))
4238 .or_default();
4239 for &previous in bucket.iter() {
4240 if outcomes[previous].diagnostics == outcome.diagnostics {
4241 continue 'outcomes;
4242 }
4243 }
4244 bucket.push(index);
4245 keep.push(index);
4246 }
4247 if keep.len() == outcomes.len() {
4248 return;
4249 }
4250 let mut iter = keep.into_iter();
4251 let mut next_keep = iter.next();
4252 let mut current = 0_usize;
4253 outcomes.retain(|_| {
4254 let result = next_keep == Some(current);
4255 if result {
4256 next_keep = iter.next();
4257 }
4258 current += 1;
4259 result
4260 });
4261}
4262
4263fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>) {
4265 outcomes.sort_unstable();
4266 outcomes.dedup();
4267}
4268
4269impl<S> Recognizer for BaseParser<S>
4270where
4271 S: TokenSource,
4272{
4273 fn data(&self) -> &RecognizerData {
4274 &self.data
4275 }
4276
4277 fn data_mut(&mut self) -> &mut RecognizerData {
4278 &mut self.data
4279 }
4280}
4281
4282impl<S> Parser for BaseParser<S>
4283where
4284 S: TokenSource,
4285{
4286 fn build_parse_trees(&self) -> bool {
4287 self.build_parse_trees
4288 }
4289
4290 fn set_build_parse_trees(&mut self, build: bool) {
4291 self.build_parse_trees = build;
4292 }
4293
4294 fn report_diagnostic_errors(&self) -> bool {
4295 self.report_diagnostic_errors
4296 }
4297
4298 fn set_report_diagnostic_errors(&mut self, report: bool) {
4299 self.report_diagnostic_errors = report;
4300 }
4301
4302 fn prediction_mode(&self) -> PredictionMode {
4303 self.prediction_mode
4304 }
4305
4306 fn set_prediction_mode(&mut self, mode: PredictionMode) {
4307 self.prediction_mode = mode;
4308 }
4309}
4310
4311#[cfg(test)]
4312mod tests {
4313 use super::*;
4314 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
4315 use crate::token::{CommonToken, HIDDEN_CHANNEL, Token};
4316 use crate::token_stream::CommonTokenStream;
4317 use crate::vocabulary::Vocabulary;
4318
4319 #[derive(Debug)]
4320 struct Source {
4321 tokens: Vec<CommonToken>,
4322 index: usize,
4323 }
4324
4325 impl TokenSource for Source {
4326 fn next_token(&mut self) -> CommonToken {
4327 let token = self
4328 .tokens
4329 .get(self.index)
4330 .cloned()
4331 .unwrap_or_else(|| CommonToken::eof("parser-test", self.index, 1, self.index));
4332 self.index += 1;
4333 token
4334 }
4335
4336 fn line(&self) -> usize {
4337 1
4338 }
4339
4340 fn column(&self) -> usize {
4341 self.index
4342 }
4343
4344 fn source_name(&self) -> &'static str {
4345 "parser-test"
4346 }
4347 }
4348
4349 fn mini_parser(tokens: Vec<CommonToken>) -> BaseParser<Source> {
4350 let data = RecognizerData::new(
4351 "Mini.g4",
4352 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
4353 );
4354 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
4355 }
4356
4357 fn token_then_eof_atn() -> Atn {
4358 AtnDeserializer::new(&SerializedAtn::from_i32(&[
4359 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, ]))
4375 .deserialize()
4376 .expect("artificial parser ATN should deserialize")
4377 }
4378
4379 fn eof_then_action_atn() -> Atn {
4380 AtnDeserializer::new(&SerializedAtn::from_i32(&[
4381 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, ]))
4397 .deserialize()
4398 .expect("artificial parser ATN should deserialize")
4399 }
4400
4401 #[test]
4402 fn parser_matches_token_and_reports_mismatch() {
4403 let source = Source {
4404 tokens: vec![
4405 CommonToken::new(1).with_text("x"),
4406 CommonToken::eof("parser-test", 1, 1, 1),
4407 ],
4408 index: 0,
4409 };
4410 let data = RecognizerData::new(
4411 "Mini.g4",
4412 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
4413 );
4414 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
4415 assert_eq!(
4416 parser.match_token(1).expect("token 1 should match").text(),
4417 "x"
4418 );
4419 assert!(parser.match_token(1).is_err());
4420 }
4421
4422 #[test]
4423 fn parser_interprets_simple_atn_rule() {
4424 let atn = token_then_eof_atn();
4425 let mut parser = mini_parser(vec![
4426 CommonToken::new(1).with_text("x"),
4427 CommonToken::eof("parser-test", 1, 1, 1),
4428 ]);
4429
4430 let tree = parser
4431 .parse_atn_rule(&atn, 0)
4432 .expect("artificial parser rule should parse");
4433 assert_eq!(tree.text(), "x<EOF>");
4434 assert_eq!(
4435 tree.first_rule_stop(0)
4436 .expect("rule should stop at EOF")
4437 .token_type(),
4438 TOKEN_EOF
4439 );
4440
4441 let mut parser = mini_parser(vec![
4442 CommonToken::new(1).with_text("x"),
4443 CommonToken::eof("parser-test", 1, 1, 1),
4444 ]);
4445 let (tree, actions) = parser
4446 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
4447 .expect("runtime-option parser rule should parse");
4448 assert!(actions.is_empty());
4449 assert_eq!(
4450 tree.first_rule_stop(0)
4451 .expect("rule should stop at EOF")
4452 .token_type(),
4453 TOKEN_EOF
4454 );
4455 }
4456
4457 #[test]
4458 fn parser_rule_start_skips_leading_hidden_tokens() {
4459 let atn = token_then_eof_atn();
4460 let mut parser = mini_parser(vec![
4461 CommonToken::new(99)
4462 .with_text(" ")
4463 .with_channel(HIDDEN_CHANNEL),
4464 CommonToken::new(1).with_text("x"),
4465 CommonToken::eof("parser-test", 2, 1, 2),
4466 ]);
4467
4468 let tree = parser
4469 .parse_atn_rule(&atn, 0)
4470 .expect("artificial parser rule should parse");
4471 let Some(ParseTree::Rule(rule)) = tree.first_rule(0) else {
4472 panic!("rule node should be present");
4473 };
4474 assert_eq!(
4475 rule.context()
4476 .start()
4477 .expect("rule should have a start token")
4478 .token_type(),
4479 1
4480 );
4481 }
4482
4483 #[test]
4484 fn parser_action_after_eof_stops_at_eof_token() {
4485 let atn = eof_then_action_atn();
4486 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
4487
4488 let (_, actions) = parser
4489 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
4490 .expect("EOF action rule should parse");
4491
4492 assert_eq!(actions.len(), 1);
4493 assert_eq!(actions[0].stop_index(), Some(0));
4494 assert_eq!(
4495 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
4496 ""
4497 );
4498 }
4499
4500 #[test]
4501 fn fast_outcome_selection_respects_sll_tie_order() {
4502 let first = FastRecognizeOutcome {
4503 index: 1,
4504 consumed_eof: false,
4505 diagnostics: vec![ParserDiagnostic {
4506 line: 1,
4507 column: 0,
4508 message: "mismatched input 'x'".to_owned(),
4509 }],
4510 nodes: NodeList::new(),
4511 };
4512 let second = FastRecognizeOutcome {
4513 index: first.index,
4514 consumed_eof: first.consumed_eof,
4515 diagnostics: Vec::new(),
4516 nodes: NodeList::new(),
4517 };
4518
4519 let selected = select_best_fast_outcome(
4520 [first.clone(), second.clone()].into_iter(),
4521 PredictionMode::Sll,
4522 )
4523 .expect("one outcome should be selected");
4524 assert_eq!(selected.diagnostics.len(), 1);
4525 let eof_second = FastRecognizeOutcome {
4526 index: second.index,
4527 consumed_eof: true,
4528 diagnostics: Vec::new(),
4529 nodes: NodeList::new(),
4530 };
4531 let selected =
4532 select_best_fast_outcome([first.clone(), eof_second].into_iter(), PredictionMode::Sll)
4533 .expect("one outcome should be selected");
4534 assert!(!selected.consumed_eof);
4535 let selected = select_best_fast_outcome([first, second].into_iter(), PredictionMode::Ll)
4536 .expect("one outcome should be selected");
4537 assert!(selected.diagnostics.is_empty());
4538 }
4539
4540 #[test]
4541 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
4542 let source = Source {
4543 tokens: vec![
4544 CommonToken::new(1).with_text("x"),
4545 CommonToken::eof("parser-test", 1, 1, 1),
4546 ],
4547 index: 0,
4548 };
4549 let data = RecognizerData::new(
4550 "Mini.g4",
4551 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
4552 );
4553 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
4554 let expected = ExpectedTokens {
4555 index: Some(0),
4556 symbols: BTreeSet::new(),
4557 no_viable: None,
4558 };
4559
4560 let (_, message) = parser.expected_error_message(0, 0, &expected);
4561
4562 assert_eq!(message, "mismatched input 'x'");
4563 }
4564
4565 #[test]
4566 fn eof_rule_stop_index_points_at_eof_token() {
4567 let source = Source {
4568 tokens: vec![
4569 CommonToken::new(1).with_text("x"),
4570 CommonToken::eof("parser-test", 1, 1, 1),
4571 ],
4572 index: 0,
4573 };
4574 let data = RecognizerData::new(
4575 "Mini.g4",
4576 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
4577 );
4578 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
4579
4580 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
4581 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
4582 }
4583
4584 #[test]
4585 fn folds_left_recursive_boundary_into_rule_node() {
4586 let nodes = fold_left_recursive_boundaries(vec![
4587 RecognizedNode::Token { index: 0 },
4588 RecognizedNode::LeftRecursiveBoundary { rule_index: 1 },
4589 RecognizedNode::Token { index: 1 },
4590 ]);
4591
4592 assert_eq!(
4593 nodes,
4594 vec![
4595 RecognizedNode::Rule {
4596 rule_index: 1,
4597 invoking_state: -1,
4598 alt_number: 0,
4599 start_index: 0,
4600 stop_index: Some(0),
4601 return_values: BTreeMap::new(),
4602 children: vec![RecognizedNode::Token { index: 0 }],
4603 },
4604 RecognizedNode::Token { index: 1 },
4605 ]
4606 );
4607 }
4608
4609 #[test]
4610 fn outcome_ties_keep_later_non_recursive_alternative() {
4611 let first = RecognizeOutcome {
4612 index: 1,
4613 consumed_eof: false,
4614 alt_number: 0,
4615 member_values: BTreeMap::new(),
4616 return_values: BTreeMap::new(),
4617 diagnostics: Vec::new(),
4618 decisions: Vec::new(),
4619 actions: vec![ParserAction::new(1, 0, 0, None)],
4620 nodes: vec![RecognizedNode::Token { index: 0 }],
4621 };
4622 let second = RecognizeOutcome {
4623 actions: vec![ParserAction::new(2, 0, 0, None)],
4624 ..first.clone()
4625 };
4626
4627 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
4628 .expect("one outcome should be selected");
4629 assert_eq!(selected.actions[0].source_state(), 2);
4630 }
4631
4632 #[test]
4633 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
4634 let first = RecognizeOutcome {
4635 index: 1,
4636 consumed_eof: false,
4637 alt_number: 0,
4638 member_values: BTreeMap::new(),
4639 return_values: BTreeMap::new(),
4640 diagnostics: Vec::new(),
4641 decisions: Vec::new(),
4642 actions: vec![ParserAction::new(1, 0, 0, None)],
4643 nodes: vec![RecognizedNode::Token { index: 0 }],
4644 };
4645 let second = RecognizeOutcome {
4646 actions: vec![
4647 ParserAction::new(2, 0, 0, None),
4648 ParserAction::new(3, 0, 0, None),
4649 ],
4650 ..first.clone()
4651 };
4652
4653 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll)
4654 .expect("one outcome should be selected");
4655 assert_eq!(selected.actions.len(), 2);
4656 }
4657
4658 #[test]
4659 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
4660 let first = RecognizeOutcome {
4661 index: 7,
4662 consumed_eof: false,
4663 alt_number: 0,
4664 member_values: BTreeMap::new(),
4665 return_values: BTreeMap::new(),
4666 diagnostics: Vec::new(),
4667 decisions: vec![1, 0],
4668 actions: vec![
4669 ParserAction::new(23, 2, 2, Some(4)),
4670 ParserAction::new(23, 2, 0, Some(6)),
4671 ],
4672 nodes: vec![RecognizedNode::Token { index: 0 }],
4673 };
4674 let second = RecognizeOutcome {
4675 decisions: vec![0, 1],
4676 actions: vec![
4677 ParserAction::new(23, 2, 2, Some(6)),
4678 ParserAction::new(23, 2, 0, Some(6)),
4679 ],
4680 ..first.clone()
4681 };
4682
4683 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
4684 .expect("one outcome should be selected");
4685 assert_eq!(selected.actions[0].stop_index(), Some(6));
4686 }
4687
4688 #[test]
4689 fn outcome_ties_keep_first_recursive_tree_shape() {
4690 let recursive_nodes = vec![RecognizedNode::Rule {
4691 rule_index: 1,
4692 invoking_state: -1,
4693 alt_number: 0,
4694 start_index: 0,
4695 stop_index: Some(0),
4696 return_values: BTreeMap::new(),
4697 children: vec![RecognizedNode::Rule {
4698 rule_index: 1,
4699 invoking_state: -1,
4700 alt_number: 0,
4701 start_index: 0,
4702 stop_index: Some(0),
4703 return_values: BTreeMap::new(),
4704 children: vec![RecognizedNode::Token { index: 0 }],
4705 }],
4706 }];
4707 let first = RecognizeOutcome {
4708 index: 1,
4709 consumed_eof: false,
4710 alt_number: 0,
4711 member_values: BTreeMap::new(),
4712 return_values: BTreeMap::new(),
4713 diagnostics: Vec::new(),
4714 decisions: Vec::new(),
4715 actions: vec![ParserAction::new(1, 0, 0, None)],
4716 nodes: recursive_nodes.clone(),
4717 };
4718 let second = RecognizeOutcome {
4719 index: 1,
4720 consumed_eof: false,
4721 alt_number: 0,
4722 member_values: BTreeMap::new(),
4723 return_values: BTreeMap::new(),
4724 diagnostics: Vec::new(),
4725 decisions: Vec::new(),
4726 actions: vec![ParserAction::new(2, 0, 0, None)],
4727 nodes: recursive_nodes,
4728 };
4729
4730 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
4731 .expect("one outcome should be selected");
4732 assert_eq!(selected.actions[0].source_state(), 1);
4733 }
4734
4735 #[test]
4736 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
4737 let first_alt = RecognizeOutcome {
4738 index: 2,
4739 consumed_eof: true,
4740 alt_number: 0,
4741 member_values: BTreeMap::new(),
4742 return_values: BTreeMap::new(),
4743 diagnostics: vec![ParserDiagnostic {
4744 line: 1,
4745 column: 3,
4746 message: "missing 'Y' at '<EOF>'".to_owned(),
4747 }],
4748 decisions: vec![0],
4749 actions: vec![ParserAction::new(1, 0, 0, None)],
4750 nodes: vec![RecognizedNode::Token { index: 0 }],
4751 };
4752 let second_alt = RecognizeOutcome {
4753 diagnostics: Vec::new(),
4754 decisions: vec![1],
4755 actions: vec![ParserAction::new(2, 0, 0, None)],
4756 ..first_alt.clone()
4757 };
4758
4759 let selected =
4760 select_best_outcome([second_alt, first_alt].into_iter(), PredictionMode::Sll)
4761 .expect("one outcome should be selected");
4762 assert_eq!(selected.diagnostics.len(), 1);
4763 assert_eq!(selected.decisions, [0]);
4764 }
4765}