1use std::cell::RefCell;
7#[allow(clippy::disallowed_types)]
8use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
9use std::hash::{BuildHasherDefault, Hash, Hasher};
10use std::rc::Rc;
11
12#[derive(Clone, Copy, Default)]
19struct FxHasher {
20 hash: u64,
21}
22
23const FX_ROT: u32 = 5;
24const FX_SEED: u64 = 0x51_7c_c1_b7_27_22_0a_95;
25
26impl Hasher for FxHasher {
27 #[inline]
35 fn write(&mut self, mut bytes: &[u8]) {
36 while bytes.len() >= 8 {
37 let (head, rest) = bytes.split_at(8);
38 let word = u64::from_le_bytes(head.try_into().expect("8-byte chunk"));
39 self.hash = (self.hash.rotate_left(FX_ROT) ^ word).wrapping_mul(FX_SEED);
40 bytes = rest;
41 }
42 for byte in bytes {
43 self.hash = (self.hash.rotate_left(FX_ROT) ^ u64::from(*byte)).wrapping_mul(FX_SEED);
44 }
45 }
46 #[inline]
47 fn write_u64(&mut self, value: u64) {
48 self.hash = (self.hash.rotate_left(FX_ROT) ^ value).wrapping_mul(FX_SEED);
49 }
50 #[inline]
51 fn write_usize(&mut self, value: usize) {
52 self.write_u64(value as u64);
53 }
54 #[inline]
55 fn write_u32(&mut self, value: u32) {
56 self.write_u64(u64::from(value));
57 }
58 #[inline]
59 fn write_i32(&mut self, value: i32) {
60 self.write_u64(u64::from(i32::cast_unsigned(value)));
61 }
62 #[inline]
63 fn finish(&self) -> u64 {
64 self.hash
65 }
66}
67
68type FxBuildHasher = BuildHasherDefault<FxHasher>;
69#[allow(clippy::disallowed_types)]
70type FxHashMap<K, V> = HashMap<K, V, FxBuildHasher>;
71#[allow(clippy::disallowed_types)]
72type FxHashSet<K> = HashSet<K, FxBuildHasher>;
73
74use crate::atn::parser::{
75 ParserAtnPrediction, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
76};
77use crate::atn::{Atn, AtnState, AtnStateKind, Transition};
78use crate::errors::AntlrError;
79use crate::int_stream::IntStream;
80use crate::prediction::{EMPTY_RETURN_STATE, PredictionContext};
81use crate::recognizer::{Recognizer, RecognizerData};
82use crate::token::{CommonToken, TOKEN_EOF, Token, TokenRef, TokenSource, TokenSourceError};
83use crate::token_stream::CommonTokenStream;
84use crate::tree::{ErrorNode, ParseTree, ParserRuleContext, RuleNode, TerminalNode};
85use crate::vocabulary::Vocabulary;
86
87const RECOGNITION_DEPTH_LIMIT: usize = 32_768;
91const ADAPTIVE_DIRECT_STEP_LIMIT: usize = RECOGNITION_DEPTH_LIMIT;
95const CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT: usize = 4096;
99const CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT: usize = 8;
100
101#[derive(Clone, Copy, Debug, Eq, PartialEq)]
102enum SingleOutcomeMemoMode {
103 Probe,
104 Promote,
105 Sparse,
106}
107
108fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
109 intervals
110 .iter()
111 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
112}
113
114fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
115 let mut symbols = BTreeSet::new();
116 for (start, stop) in intervals {
117 symbols.extend(*start..=*stop);
118 }
119 symbols
120}
121
122fn interval_complement_symbols(
123 intervals: &[(i32, i32)],
124 min_vocabulary: i32,
125 max_vocabulary: i32,
126) -> BTreeSet<i32> {
127 (min_vocabulary..=max_vocabulary)
128 .filter(|symbol| !interval_set_contains(intervals, *symbol))
129 .collect()
130}
131
132#[cfg(feature = "perf-counters")]
133mod perf_counters {
134 use std::cell::Cell;
135 thread_local! {
136 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
137 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
138 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
139 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
140 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
141 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
142 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
143 }
144 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
145 c.with(|v| v.set(v.get() + n));
146 }
147 thread_local! {
148 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
149 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
150 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
151 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
152 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
153 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
154 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
155 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
156 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
157 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
158 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
159 }
160 pub(super) fn snapshot() -> [(&'static str, u64); 18] {
161 [
162 ("rfs_calls", RFS_CALLS.with(Cell::get)),
163 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
164 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
165 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
166 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
167 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
168 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
169 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
170 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
171 (
172 "atom_range_transitions",
173 ATOM_RANGE_TRANSITIONS.with(Cell::get),
174 ),
175 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
176 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
177 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
178 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
179 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
180 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
181 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
182 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
183 ]
184 }
185 pub fn reset() {
186 RFS_CALLS.with(|c| c.set(0));
187 RFS_MEMO_HITS.with(|c| c.set(0));
188 RFS_MEMO_MISSES.with(|c| c.set(0));
189 RFS_VISITING_CYCLE.with(|c| c.set(0));
190 MEMO_INSERTED.with(|c| c.set(0));
191 OUTCOMES_PUSHED.with(|c| c.set(0));
192 OUTCOMES_CLONED.with(|c| c.set(0));
193 EPSILON_TRANSITIONS.with(|c| c.set(0));
194 RULE_TRANSITIONS.with(|c| c.set(0));
195 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
196 SINGLE_TRANS_BODY.with(|c| c.set(0));
197 MULTI_TRANS_BODY.with(|c| c.set(0));
198 SINGLE_TRANS_RULE.with(|c| c.set(0));
199 SINGLE_TRANS_ATOM.with(|c| c.set(0));
200 SINGLE_TRANS_OTHER.with(|c| c.set(0));
201 OUTCOMES_RETURN_0.with(|c| c.set(0));
202 OUTCOMES_RETURN_1.with(|c| c.set(0));
203 OUTCOMES_RETURN_N.with(|c| c.set(0));
204 }
205 pub fn dump() {
206 for (name, value) in snapshot() {
207 #[allow(clippy::print_stderr)]
208 {
209 eprintln!("perf {name}={value}");
210 }
211 }
212 }
213}
214
215#[cfg(feature = "perf-counters")]
216pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
217const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
222#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
231pub struct ParserAction {
232 source_state: usize,
233 rule_index: usize,
234 start_index: usize,
235 stop_index: Option<usize>,
236 rule_init: bool,
237 expected_state: Option<usize>,
238}
239
240impl ParserAction {
241 pub const fn new(
243 source_state: usize,
244 rule_index: usize,
245 start_index: usize,
246 stop_index: Option<usize>,
247 ) -> Self {
248 Self {
249 source_state,
250 rule_index,
251 start_index,
252 stop_index,
253 rule_init: false,
254 expected_state: None,
255 }
256 }
257
258 pub const fn new_rule_init(
260 rule_index: usize,
261 start_index: usize,
262 expected_state: Option<usize>,
263 ) -> Self {
264 Self {
265 source_state: usize::MAX,
266 rule_index,
267 start_index,
268 stop_index: None,
269 rule_init: true,
270 expected_state,
271 }
272 }
273
274 pub const fn source_state(&self) -> usize {
276 self.source_state
277 }
278
279 pub const fn rule_index(&self) -> usize {
281 self.rule_index
282 }
283
284 pub const fn start_index(&self) -> usize {
286 self.start_index
287 }
288
289 pub const fn stop_index(&self) -> Option<usize> {
291 self.stop_index
292 }
293
294 pub const fn is_rule_init(&self) -> bool {
296 self.rule_init
297 }
298
299 pub const fn expected_state(&self) -> Option<usize> {
301 self.expected_state
302 }
303}
304
305#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
312pub enum ParserPredicate {
313 True,
314 False,
315 FalseWithMessage {
317 message: &'static str,
318 },
319 Invoke {
322 value: bool,
323 },
324 LookaheadTextEquals {
325 offset: isize,
326 text: &'static str,
327 },
328 LookaheadNotEquals {
329 offset: isize,
330 token_type: i32,
331 },
332 TokenPairAdjacent,
335 ContextChildRuleTextNotEquals {
340 rule_index: usize,
341 text: &'static str,
342 },
343 LocalIntEquals {
346 value: i64,
347 },
348 LocalIntLessOrEqual {
351 value: i64,
352 },
353 MemberModuloEquals {
355 member: usize,
356 modulus: i64,
357 value: i64,
358 equals: bool,
359 },
360 MemberEquals {
362 member: usize,
363 value: i64,
364 equals: bool,
365 },
366}
367
368#[derive(Clone, Copy, Debug, Eq, PartialEq)]
370pub enum PredictionMode {
371 Ll,
374 Sll,
377 LlExactAmbigDetection,
379}
380
381#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
387pub struct ParserRuleArg {
388 pub source_state: usize,
390 pub rule_index: usize,
392 pub value: i64,
394 pub inherit_local: bool,
396}
397
398#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
400pub struct ParserMemberAction {
401 pub source_state: usize,
403 pub member: usize,
405 pub delta: i64,
407}
408
409#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
416pub struct ParserReturnAction {
417 pub source_state: usize,
419 pub rule_index: usize,
421 pub name: &'static str,
423 pub value: i64,
425}
426
427#[derive(Clone, Copy, Debug, Default)]
429pub struct ParserRuntimeOptions<'a> {
430 pub init_action_rules: &'a [usize],
432 pub track_alt_numbers: bool,
434 pub predicates: &'a [(usize, usize, ParserPredicate)],
436 pub rule_args: &'a [ParserRuleArg],
438 pub member_actions: &'a [ParserMemberAction],
440 pub return_actions: &'a [ParserReturnAction],
442}
443
444pub trait Parser: Recognizer {
445 fn build_parse_trees(&self) -> bool;
448
449 fn set_build_parse_trees(&mut self, build: bool);
451
452 fn number_of_syntax_errors(&self) -> usize {
455 0
456 }
457
458 fn report_diagnostic_errors(&self) -> bool {
461 false
462 }
463
464 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
467
468 fn prediction_mode(&self) -> PredictionMode {
470 PredictionMode::Ll
471 }
472
473 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
475}
476
477#[derive(Debug)]
478struct CachedPredictionContext {
479 version: usize,
480 atn_key: usize,
481 context: Rc<PredictionContext>,
482}
483
484#[derive(Debug)]
485pub struct BaseParser<S> {
486 input: CommonTokenStream<S>,
487 data: RecognizerData,
488 build_parse_trees: bool,
489 syntax_errors: usize,
490 report_diagnostic_errors: bool,
491 prediction_mode: PredictionMode,
492 prediction_diagnostics: Vec<ParserDiagnostic>,
493 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
494 generated_parser_diagnostics: Vec<ParserDiagnostic>,
495 generated_sync_expected: Option<TokenBitSet>,
496 int_members: BTreeMap<usize, i64>,
497 rule_context_stack: Vec<RuleContextFrame>,
498 rule_context_version: usize,
499 prediction_context_cache: Option<CachedPredictionContext>,
500 pending_invoking_states: Vec<isize>,
501 precedence_stack: Vec<i32>,
502 invoked_predicates: Vec<(usize, usize)>,
506 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
511 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
517 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
522 rule_stop_reach_cache: Vec<Option<bool>>,
527 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
532 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
538 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
544 empty_cycle_cache: Vec<Option<bool>>,
548 single_outcome_memo_mode: SingleOutcomeMemoMode,
551 single_outcome_probe_seen: FxHashSet<FastRecognizeKey>,
552 single_outcome_probe_samples: usize,
553 single_outcome_probe_repeats: usize,
554 empty_recovery_symbols: Rc<BTreeSet<i32>>,
557 fast_first_set_prefilter: bool,
565 fast_recovery_enabled: bool,
569 fast_token_nodes_enabled: bool,
574}
575
576#[derive(Clone, Copy, Debug, Eq, PartialEq)]
578pub struct GeneratedDiagnosticsCheckpoint {
579 diagnostics_len: usize,
580 syntax_errors: usize,
581}
582
583#[derive(Clone, Copy, Debug, Eq, PartialEq)]
584struct RuleContextFrame {
585 rule_index: usize,
586 invoking_state: isize,
587}
588
589#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
590struct RecognizeOutcome {
591 index: usize,
592 consumed_eof: bool,
593 alt_number: usize,
594 member_values: BTreeMap<usize, i64>,
595 return_values: BTreeMap<String, i64>,
596 diagnostics: Vec<ParserDiagnostic>,
597 decisions: Vec<usize>,
598 actions: Vec<ParserAction>,
599 nodes: Vec<RecognizedNode>,
600}
601
602#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
603enum RecognizedNode {
604 Token {
605 index: usize,
606 },
607 ErrorToken {
608 index: usize,
609 },
610 MissingToken {
611 token_type: i32,
612 at_index: usize,
613 text: String,
614 },
615 Rule {
616 rule_index: usize,
617 invoking_state: isize,
618 alt_number: usize,
619 start_index: usize,
620 stop_index: Option<usize>,
621 return_values: BTreeMap<String, i64>,
622 children: Vec<Self>,
623 },
624 LeftRecursiveBoundary {
625 rule_index: usize,
626 },
627}
628
629#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
630struct FastRecognizeOutcome {
631 index: usize,
632 consumed_eof: bool,
633 diagnostics: FastDiagnostics,
634 nodes: NodeList,
643}
644
645#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
646#[allow(clippy::box_collection)]
647struct FastDiagnostics(Option<Box<Vec<ParserDiagnostic>>>);
648
649impl FastDiagnostics {
650 const fn new() -> Self {
651 Self(None)
652 }
653
654 #[cfg(test)]
655 fn from_vec(diagnostics: Vec<ParserDiagnostic>) -> Self {
656 if diagnostics.is_empty() {
657 Self::new()
658 } else {
659 Self(Some(Box::new(diagnostics)))
660 }
661 }
662
663 fn is_empty(&self) -> bool {
664 self.0
665 .as_ref()
666 .is_none_or(|diagnostics| diagnostics.is_empty())
667 }
668
669 fn as_slice(&self) -> &[ParserDiagnostic] {
670 self.0.as_deref().map_or(&[], Vec::as_slice)
671 }
672
673 fn insert(&mut self, index: usize, diagnostic: ParserDiagnostic) {
674 self.0
675 .get_or_insert_with(Box::default)
676 .insert(index, diagnostic);
677 }
678
679 fn append(&mut self, other: &mut Self) {
680 if other.is_empty() {
681 return;
682 }
683 self.0
684 .get_or_insert_with(Box::default)
685 .append(other.0.get_or_insert_with(Box::default));
686 if other.is_empty() {
687 other.0 = None;
688 }
689 }
690}
691
692impl std::ops::Deref for FastDiagnostics {
693 type Target = [ParserDiagnostic];
694
695 fn deref(&self) -> &Self::Target {
696 self.as_slice()
697 }
698}
699
700#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
709enum NodeList {
710 #[default]
711 Empty,
712 One(Rc<FastRecognizedNode>),
713 Cons {
714 head: Rc<FastRecognizedNode>,
715 tail: Rc<Self>,
716 },
717}
718
719impl NodeList {
720 const fn new() -> Self {
722 Self::Empty
723 }
724
725 fn cons(self, node: Rc<FastRecognizedNode>) -> Self {
728 match self {
729 Self::Empty => Self::One(node),
730 existing @ (Self::One(_) | Self::Cons { .. }) => Self::Cons {
731 head: node,
732 tail: Rc::new(existing),
733 },
734 }
735 }
736
737 fn prepend(&mut self, node: Rc<FastRecognizedNode>) {
740 let owned = std::mem::take(self);
741 *self = owned.cons(node);
742 }
743
744 fn to_vec(&self) -> Vec<Rc<FastRecognizedNode>> {
749 let mut out = Vec::new();
750 let mut cursor = self;
751 loop {
752 match cursor {
753 Self::Empty => break,
754 Self::One(node) => {
755 out.push(Rc::clone(node));
756 break;
757 }
758 Self::Cons { head, tail } => {
759 out.push(Rc::clone(head));
760 cursor = tail.as_ref();
761 }
762 }
763 }
764 out
765 }
766
767 const fn iter(&self) -> NodeListIter<'_> {
768 NodeListIter { cursor: self }
769 }
770
771 fn len(&self) -> usize {
772 self.iter().count()
773 }
774
775 fn has_left_recursive_boundary(&self) -> bool {
776 self.iter()
777 .any(|node| fast_node_has_left_recursive_boundary(node.as_ref()))
778 }
779
780 fn has_explicit_token_node(&self) -> bool {
781 self.iter().any(|node| {
782 matches!(
783 node.as_ref(),
784 FastRecognizedNode::Token { .. }
785 | FastRecognizedNode::ErrorToken { .. }
786 | FastRecognizedNode::MissingToken { .. }
787 )
788 })
789 }
790
791 fn from_vec(nodes: Vec<Rc<FastRecognizedNode>>) -> Self {
793 let mut list = Self::new();
794 for node in nodes.into_iter().rev() {
795 list.prepend(node);
796 }
797 list
798 }
799}
800
801struct NodeListIter<'a> {
802 cursor: &'a NodeList,
803}
804
805impl<'a> Iterator for NodeListIter<'a> {
806 type Item = &'a Rc<FastRecognizedNode>;
807
808 fn next(&mut self) -> Option<Self::Item> {
809 match self.cursor {
810 NodeList::Empty => None,
811 NodeList::One(node) => {
812 self.cursor = &NodeList::Empty;
813 Some(node)
814 }
815 NodeList::Cons { head, tail } => {
816 self.cursor = tail.as_ref();
817 Some(head)
818 }
819 }
820 }
821}
822
823#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
827enum FastRecognizedNode {
828 Token {
829 index: usize,
830 },
831 ErrorToken {
832 index: usize,
833 },
834 MissingToken {
835 token_type: i32,
836 at_index: usize,
837 text: String,
838 },
839 Rule {
840 rule_index: usize,
841 invoking_state: isize,
842 start_index: usize,
843 stop_index: Option<usize>,
844 children: NodeList,
845 },
846 LeftRecursiveBoundary {
850 rule_index: usize,
851 },
852}
853
854#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
855struct ParserDiagnostic {
856 line: usize,
857 column: usize,
858 message: String,
859}
860
861#[derive(Clone, Debug, Default, Eq, PartialEq)]
862struct ExpectedTokens {
863 index: Option<usize>,
864 symbols: BTreeSet<i32>,
865 no_viable: Option<NoViableAlternative>,
866}
867
868#[derive(Clone, Copy, Debug, Eq, PartialEq)]
869struct NoViableAlternative {
870 start_index: usize,
871 error_index: usize,
872}
873
874impl ExpectedTokens {
875 fn record_transition(&mut self, index: usize, transition: &Transition, max_token_type: i32) {
878 let symbols = transition_expected_symbols(transition, max_token_type);
879 match self.index {
880 Some(current) if index < current => {}
881 Some(current) if index == current => self.symbols.extend(symbols),
882 _ => {
883 self.index = Some(index);
884 self.symbols = symbols;
885 }
886 }
887 }
888
889 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
892 match self.no_viable {
893 Some(current) if error_index < current.error_index => {}
894 _ => {
895 self.no_viable = Some(NoViableAlternative {
896 start_index,
897 error_index,
898 });
899 }
900 }
901 }
902}
903
904#[derive(Clone, Debug, Default, Eq, PartialEq)]
911struct TokenBitSet {
912 words: Vec<u64>,
913}
914
915impl TokenBitSet {
916 fn insert(&mut self, symbol: i32) {
917 let Some(slot) = token_bit_slot(symbol) else {
918 return;
919 };
920 let word = slot / u64::BITS as usize;
921 if word >= self.words.len() {
922 self.words.resize(word + 1, 0);
923 }
924 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
925 }
926
927 fn extend_range(&mut self, start: i32, stop: i32) {
928 let (start, stop) = if start <= stop {
929 (start, stop)
930 } else {
931 (stop, start)
932 };
933 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
934 self.insert(TOKEN_EOF);
935 }
936 let positive_start = start.max(1);
937 if positive_start > stop {
938 return;
939 }
940 let Some(start_slot) = token_bit_slot(positive_start) else {
941 return;
942 };
943 let Some(stop_slot) = token_bit_slot(stop) else {
944 return;
945 };
946 self.extend_slot_range(start_slot, stop_slot);
947 }
948
949 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
950 if start_slot > stop_slot {
951 return;
952 }
953 let start_word = start_slot / u64::BITS as usize;
954 let stop_word = stop_slot / u64::BITS as usize;
955 if stop_word >= self.words.len() {
956 self.words.resize(stop_word + 1, 0);
957 }
958 let start_offset = start_slot % u64::BITS as usize;
959 let stop_offset = stop_slot % u64::BITS as usize;
960 if start_word == stop_word {
961 self.words[start_word] |=
962 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
963 return;
964 }
965 self.words[start_word] |= !0_u64 << start_offset;
966 for word in &mut self.words[(start_word + 1)..stop_word] {
967 *word = !0_u64;
968 }
969 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
970 }
971
972 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
973 for symbol in symbols {
974 self.insert(symbol);
975 }
976 }
977
978 fn extend_from(&mut self, other: &Self) {
979 if other.words.len() > self.words.len() {
980 self.words.resize(other.words.len(), 0);
981 }
982 for (left, right) in self.words.iter_mut().zip(&other.words) {
983 *left |= *right;
984 }
985 }
986
987 fn contains(&self, symbol: i32) -> bool {
988 let Some(slot) = token_bit_slot(symbol) else {
989 return false;
990 };
991 let word = slot / u64::BITS as usize;
992 self.words
993 .get(word)
994 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
995 }
996
997 fn is_empty(&self) -> bool {
998 self.words.iter().all(|word| *word == 0)
999 }
1000
1001 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
1002 for (word_index, word) in self.words.iter().copied().enumerate() {
1003 let mut bits = word;
1004 while bits != 0 {
1005 let bit = bits.trailing_zeros() as usize;
1006 if let Some(symbol) = token_bit_symbol(word_index * u64::BITS as usize + bit) {
1007 target.insert(symbol);
1008 }
1009 bits &= bits - 1;
1010 }
1011 }
1012 }
1013
1014 fn to_btree_set(&self) -> BTreeSet<i32> {
1015 let mut out = BTreeSet::new();
1016 self.extend_btree_set(&mut out);
1017 out
1018 }
1019}
1020
1021fn token_bit_slot(symbol: i32) -> Option<usize> {
1022 if symbol == TOKEN_EOF {
1023 Some(0)
1024 } else if symbol > 0 {
1025 usize::try_from(symbol).ok()
1026 } else {
1027 None
1028 }
1029}
1030
1031fn token_bit_symbol(slot: usize) -> Option<i32> {
1032 if slot == 0 {
1033 Some(TOKEN_EOF)
1034 } else {
1035 i32::try_from(slot).ok()
1036 }
1037}
1038
1039fn transition_expected_symbols(transition: &Transition, max_token_type: i32) -> BTreeSet<i32> {
1042 let mut symbols = BTreeSet::new();
1043 match transition {
1044 Transition::Atom { label, .. } => {
1045 symbols.insert(*label);
1046 }
1047 Transition::Range { start, stop, .. } => {
1048 symbols.extend(*start..=*stop);
1049 }
1050 Transition::Set { set, .. } => {
1051 for (start, stop) in set.ranges() {
1052 symbols.extend(*start..=*stop);
1053 }
1054 }
1055 Transition::NotSet { set, .. } => {
1056 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
1057 }
1058 Transition::Wildcard { .. } => {
1059 symbols.extend(1..=max_token_type);
1060 }
1061 Transition::Epsilon { .. }
1062 | Transition::Rule { .. }
1063 | Transition::Predicate { .. }
1064 | Transition::Action { .. }
1065 | Transition::Precedence { .. } => {}
1066 }
1067 symbols
1068}
1069
1070fn transition_expected_token_set(transition: &Transition, max_token_type: i32) -> TokenBitSet {
1071 let mut symbols = TokenBitSet::default();
1072 match transition {
1073 Transition::Atom { label, .. } => {
1074 symbols.insert(*label);
1075 }
1076 Transition::Range { start, stop, .. } => {
1077 symbols.extend_range(*start, *stop);
1078 }
1079 Transition::Set { set, .. } => {
1080 for (start, stop) in set.ranges() {
1081 symbols.extend_range(*start, *stop);
1082 }
1083 }
1084 Transition::NotSet { set, .. } => {
1085 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
1086 }
1087 Transition::Wildcard { .. } => {
1088 symbols.extend_range(1, max_token_type);
1089 }
1090 Transition::Epsilon { .. }
1091 | Transition::Rule { .. }
1092 | Transition::Predicate { .. }
1093 | Transition::Action { .. }
1094 | Transition::Precedence { .. } => {}
1095 }
1096 symbols
1097}
1098
1099fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
1103 let mut symbols = BTreeSet::new();
1104 let mut stack = vec![state_number];
1105 let mut visited = BTreeSet::new();
1106 while let Some(current) = stack.pop() {
1107 if !visited.insert(current) {
1108 continue;
1109 }
1110 let Some(state) = atn.state(current) else {
1111 continue;
1112 };
1113 for transition in &state.transitions {
1114 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
1115 if transition_symbols.is_empty() {
1116 if transition.is_epsilon() {
1117 stack.push(transition.target());
1118 }
1119 } else {
1120 symbols.extend(transition_symbols);
1121 }
1122 }
1123 }
1124 symbols
1125}
1126
1127fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
1128 let mut symbols = TokenBitSet::default();
1129 let mut stack = vec![state_number];
1130 let mut visited = BTreeSet::new();
1131 while let Some(current) = stack.pop() {
1132 if !visited.insert(current) {
1133 continue;
1134 }
1135 let Some(state) = atn.state(current) else {
1136 continue;
1137 };
1138 for transition in &state.transitions {
1139 let transition_symbols =
1140 transition_expected_token_set(transition, atn.max_token_type());
1141 if transition_symbols.is_empty() {
1142 if transition.is_epsilon() {
1143 stack.push(transition.target());
1144 }
1145 } else {
1146 symbols.extend_from(&transition_symbols);
1147 }
1148 }
1149 }
1150 symbols
1151}
1152
1153fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
1154 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
1155 return false;
1156 };
1157 let Some(&stop_state) = atn.rule_to_stop_state().get(rule_index) else {
1158 return false;
1159 };
1160 epsilon_reaches_state(atn, state_number, stop_state)
1161}
1162
1163fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
1164 let mut stack = vec![start];
1165 let mut visited = BTreeSet::new();
1166 while let Some(current) = stack.pop() {
1167 if current == target {
1168 return true;
1169 }
1170 if !visited.insert(current) {
1171 continue;
1172 }
1173 let Some(state) = atn.state(current) else {
1174 continue;
1175 };
1176 stack.extend(
1177 state
1178 .transitions
1179 .iter()
1180 .filter(|transition| transition.is_epsilon())
1181 .map(Transition::target),
1182 );
1183 }
1184 false
1185}
1186
1187#[derive(Clone, Debug, Default, Eq, PartialEq)]
1194struct FirstSet {
1195 symbols: TokenBitSet,
1196 nullable: bool,
1197}
1198
1199type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
1206
1207type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
1214
1215#[derive(Default)]
1216struct SharedAtnCache {
1217 first_set: FirstSetCache,
1218 decision_lookahead: DecisionLookaheadCache,
1219 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
1220 rule_stop_reach: FxHashMap<usize, bool>,
1221}
1222
1223thread_local! {
1224 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
1225 RefCell::new(FxHashMap::default());
1226}
1227
1228#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1239struct SharedAtnCacheKey {
1240 atn: usize,
1241 states: usize,
1242 state_count: usize,
1243 max_token_type: i32,
1244}
1245
1246impl SharedAtnCacheKey {
1247 fn for_atn(atn: &Atn) -> Self {
1248 Self {
1249 atn: std::ptr::from_ref::<Atn>(atn) as usize,
1250 states: atn.states().as_ptr() as usize,
1251 state_count: atn.states().len(),
1252 max_token_type: atn.max_token_type(),
1253 }
1254 }
1255}
1256
1257fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
1258 SHARED_ATN_CACHES.with(|cell| {
1259 let key = SharedAtnCacheKey::for_atn(atn);
1260 let mut map = cell.borrow_mut();
1261 let cache = map.entry(key).or_default();
1262 f(&mut cache.first_set)
1263 })
1264}
1265
1266fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
1267 SHARED_ATN_CACHES.with(|cell| {
1268 let key = SharedAtnCacheKey::for_atn(atn);
1269 let mut map = cell.borrow_mut();
1270 let cache = map.entry(key).or_default();
1271 f(cache)
1272 })
1273}
1274
1275#[derive(Debug, Default)]
1284struct DecisionLookahead {
1285 transitions: Vec<TransitionLookSet>,
1286}
1287
1288#[derive(Clone, Debug, Default)]
1295struct TransitionLookSet {
1296 symbols: TokenBitSet,
1297 nullable: bool,
1298}
1299
1300struct FirstSetCtx<'a> {
1304 cache: &'a mut FirstSetCache,
1305 in_progress: BTreeSet<(usize, usize)>,
1306 hit_cycle: bool,
1307}
1308
1309fn rule_first_set(
1318 atn: &Atn,
1319 target: usize,
1320 rule_stop_state: usize,
1321 cache: &mut FirstSetCache,
1322) -> Rc<FirstSet> {
1323 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
1324 return Rc::clone(cached);
1325 }
1326 let mut ctx = FirstSetCtx {
1327 cache,
1328 in_progress: BTreeSet::new(),
1329 hit_cycle: false,
1330 };
1331 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
1332}
1333
1334fn rule_first_set_cached(
1335 atn: &Atn,
1336 target: usize,
1337 rule_stop_state: usize,
1338 ctx: &mut FirstSetCtx<'_>,
1339) -> Rc<FirstSet> {
1340 let key = (target, rule_stop_state);
1341 if let Some(cached) = ctx.cache.get(&key) {
1342 return Rc::clone(cached);
1343 }
1344 if !ctx.in_progress.insert(key) {
1345 return Rc::new(FirstSet::default());
1349 }
1350 let saved_hit_cycle = ctx.hit_cycle;
1351 ctx.hit_cycle = false;
1352 let mut first = FirstSet::default();
1353 let mut visited = BTreeSet::new();
1354 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
1355 ctx.in_progress.remove(&key);
1356 let entry = Rc::new(first);
1357 if !ctx.hit_cycle {
1358 ctx.cache.insert(key, Rc::clone(&entry));
1359 }
1360 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
1361 entry
1362}
1363
1364fn transition_first_set(
1368 atn: &Atn,
1369 transition: &Transition,
1370 rule_stop_state: usize,
1371 cache: &mut FirstSetCache,
1372) -> TransitionLookSet {
1373 match transition {
1374 Transition::Atom { label, .. } => {
1375 let mut symbols = TokenBitSet::default();
1376 symbols.insert(*label);
1377 TransitionLookSet {
1378 symbols,
1379 nullable: false,
1380 }
1381 }
1382 Transition::Range { start, stop, .. } => {
1383 let mut symbols = TokenBitSet::default();
1384 symbols.extend_range(*start, *stop);
1385 TransitionLookSet {
1386 symbols,
1387 nullable: false,
1388 }
1389 }
1390 Transition::Set { set, .. } => {
1391 let mut symbols = TokenBitSet::default();
1392 for (start, stop) in set.ranges() {
1393 symbols.extend_range(*start, *stop);
1394 }
1395 TransitionLookSet {
1396 symbols,
1397 nullable: false,
1398 }
1399 }
1400 Transition::NotSet { set, .. } => {
1401 let max = atn.max_token_type();
1402 let mut symbols = TokenBitSet::default();
1403 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
1404 TransitionLookSet {
1405 symbols,
1406 nullable: false,
1407 }
1408 }
1409 Transition::Wildcard { .. } => {
1410 let mut symbols = TokenBitSet::default();
1411 symbols.extend_range(1, atn.max_token_type());
1412 TransitionLookSet {
1413 symbols,
1414 nullable: false,
1415 }
1416 }
1417 Transition::Epsilon { target }
1418 | Transition::Action { target, .. }
1419 | Transition::Predicate { target, .. }
1420 | Transition::Precedence { target, .. } => {
1421 let first = rule_first_set(atn, *target, rule_stop_state, cache);
1424 TransitionLookSet {
1425 symbols: first.symbols.clone(),
1426 nullable: first.nullable,
1427 }
1428 }
1429 Transition::Rule {
1430 target,
1431 rule_index,
1432 follow_state,
1433 ..
1434 } => {
1435 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
1436 return TransitionLookSet::default();
1437 };
1438 let child = rule_first_set(atn, *target, child_stop, cache);
1439 let mut symbols = child.symbols.clone();
1440 let nullable = if child.nullable {
1441 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
1442 symbols.extend_from(&follow.symbols);
1443 follow.nullable
1444 } else {
1445 false
1446 };
1447 TransitionLookSet { symbols, nullable }
1448 }
1449 }
1450}
1451
1452fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
1473 let mut chosen: Option<usize> = None;
1474 for (index, transition) in entry.transitions.iter().enumerate() {
1475 if transition.nullable {
1476 return None;
1477 }
1478 if transition.symbols.contains(symbol) {
1479 if chosen.is_some() {
1480 return None;
1481 }
1482 chosen = Some(index);
1483 }
1484 }
1485 chosen
1486}
1487
1488fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
1497 let mut matching_non_nullable_alt = None;
1498 let mut nullable_alt = None;
1499 for (index, transition) in entry.transitions.iter().enumerate() {
1500 if transition.nullable {
1501 if nullable_alt.is_some() {
1502 return None;
1503 }
1504 nullable_alt = Some(index);
1505 }
1506 if transition.symbols.contains(symbol) {
1507 if transition.nullable {
1508 continue;
1509 }
1510 if matching_non_nullable_alt.is_some() {
1511 return None;
1512 }
1513 matching_non_nullable_alt = Some(index);
1514 }
1515 }
1516 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
1517 return None;
1518 }
1519 if non_greedy {
1520 nullable_alt.or(matching_non_nullable_alt)
1521 } else {
1522 matching_non_nullable_alt.or(nullable_alt)
1523 }
1524}
1525
1526fn should_skip_via_lookahead(
1527 transition: &Transition,
1528 transition_index: usize,
1529 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
1530 index: usize,
1531 record_expected: bool,
1532 expected: &mut ExpectedTokens,
1533) -> bool {
1534 let prune_non_consuming = matches!(
1535 transition,
1536 Transition::Epsilon { .. }
1537 | Transition::Action { .. }
1538 | Transition::Predicate { .. }
1539 | Transition::Rule { .. }
1540 | Transition::Precedence { .. }
1541 );
1542 if !prune_non_consuming {
1543 return false;
1544 }
1545 let Some((symbol, entry)) = lookahead_filter else {
1546 return false;
1547 };
1548 let Some(set) = entry.transitions.get(transition_index) else {
1549 return false;
1550 };
1551 if set.symbols.contains(*symbol) || set.nullable {
1552 return false;
1553 }
1554 if record_expected && !set.symbols.is_empty() {
1555 record_pruned_transition_expected(set, index, expected);
1556 }
1557 true
1558}
1559
1560fn should_skip_rule_via_first_set(
1561 first: &FirstSet,
1562 symbol: i32,
1563 record_expected: bool,
1564 index: usize,
1565 expected: &mut ExpectedTokens,
1566) -> bool {
1567 if first.nullable || first.symbols.contains(symbol) {
1568 return false;
1569 }
1570 if record_expected && !first.symbols.is_empty() {
1571 record_token_bit_expected(&first.symbols, index, expected);
1572 }
1573 true
1574}
1575
1576fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
1577 match expected.index {
1578 Some(current) if index < current => {}
1579 Some(current) if index == current => {
1580 symbols.extend_btree_set(&mut expected.symbols);
1581 }
1582 _ => {
1583 expected.index = Some(index);
1584 expected.symbols = symbols.to_btree_set();
1585 }
1586 }
1587}
1588
1589fn record_pruned_transition_expected(
1591 set: &TransitionLookSet,
1592 index: usize,
1593 expected: &mut ExpectedTokens,
1594) {
1595 match expected.index {
1596 Some(current) if index < current => {}
1597 Some(current) if index == current => {
1598 set.symbols.extend_btree_set(&mut expected.symbols);
1599 }
1600 _ => {
1601 expected.index = Some(index);
1602 expected.symbols = set.symbols.to_btree_set();
1603 }
1604 }
1605}
1606
1607fn rule_first_set_inner(
1608 atn: &Atn,
1609 state_number: usize,
1610 rule_stop_state: usize,
1611 ctx: &mut FirstSetCtx<'_>,
1612 visited: &mut BTreeSet<usize>,
1613 first: &mut FirstSet,
1614) {
1615 if !visited.insert(state_number) {
1616 return;
1617 }
1618 if state_number == rule_stop_state {
1619 first.nullable = true;
1620 return;
1621 }
1622 let Some(state) = atn.state(state_number) else {
1623 return;
1624 };
1625 for transition in &state.transitions {
1626 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
1627 if !transition_symbols.is_empty() {
1628 first.symbols.extend_iter(transition_symbols);
1629 continue;
1630 }
1631 match transition {
1632 Transition::Epsilon { target }
1633 | Transition::Action { target, .. }
1634 | Transition::Predicate { target, .. }
1635 | Transition::Precedence { target, .. } => {
1636 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
1637 }
1638 Transition::Rule {
1639 target,
1640 rule_index,
1641 follow_state,
1642 ..
1643 } => {
1644 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
1645 continue;
1646 };
1647 let child_key = (*target, child_stop);
1648 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
1649 ctx.hit_cycle = true;
1650 }
1651 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
1652 first.symbols.extend_from(&child.symbols);
1653 if child.nullable {
1654 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
1655 }
1656 }
1657 Transition::Atom { .. }
1658 | Transition::Range { .. }
1659 | Transition::Set { .. }
1660 | Transition::NotSet { .. }
1661 | Transition::Wildcard { .. } => {}
1662 }
1663 }
1664}
1665
1666fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
1669 let mut symbols = BTreeSet::new();
1670 state_sync_symbols_inner(
1671 atn,
1672 state_number,
1673 stop_state,
1674 &mut BTreeSet::new(),
1675 &mut symbols,
1676 );
1677 symbols
1678}
1679
1680fn state_sync_symbols_inner(
1683 atn: &Atn,
1684 state_number: usize,
1685 stop_state: usize,
1686 visited: &mut BTreeSet<usize>,
1687 symbols: &mut BTreeSet<i32>,
1688) {
1689 if !visited.insert(state_number) {
1690 return;
1691 }
1692 if state_number == stop_state {
1693 symbols.insert(TOKEN_EOF);
1694 return;
1695 }
1696 let Some(state) = atn.state(state_number) else {
1697 return;
1698 };
1699 for transition in &state.transitions {
1700 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
1701 if transition_symbols.is_empty() {
1702 match transition {
1703 Transition::Rule { target, .. }
1704 | Transition::Epsilon { target }
1705 | Transition::Action { target, .. }
1706 | Transition::Predicate { target, .. }
1707 | Transition::Precedence { target, .. } => {
1708 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
1709 }
1710 Transition::Atom { .. }
1711 | Transition::Range { .. }
1712 | Transition::Set { .. }
1713 | Transition::NotSet { .. }
1714 | Transition::Wildcard { .. } => {}
1715 }
1716 } else {
1717 symbols.extend(transition_symbols);
1718 }
1719 }
1720}
1721
1722fn state_can_reach_symbol_with_precedence(
1723 atn: &Atn,
1724 state_number: usize,
1725 symbol: i32,
1726 precedence: i32,
1727 visited: &mut BTreeSet<usize>,
1728) -> bool {
1729 if !visited.insert(state_number) {
1730 return false;
1731 }
1732 let Some(state) = atn.state(state_number) else {
1733 return false;
1734 };
1735 state.transitions.iter().any(|transition| {
1736 if transition.matches(symbol, 1, atn.max_token_type()) {
1737 return true;
1738 }
1739 if !transition.is_epsilon() {
1740 return false;
1741 }
1742 if matches!(
1743 transition,
1744 Transition::Precedence {
1745 precedence: transition_precedence,
1746 ..
1747 } if *transition_precedence < precedence
1748 ) {
1749 return false;
1750 }
1751 state_can_reach_symbol_with_precedence(
1752 atn,
1753 transition.target(),
1754 symbol,
1755 precedence,
1756 visited,
1757 )
1758 })
1759}
1760
1761fn context_can_match_symbol_before_state(
1762 atn: &Atn,
1763 context: &PredictionContext,
1764 stop_state_number: usize,
1765 symbol: i32,
1766) -> bool {
1767 (0..context.len()).any(|index| {
1768 context.return_state(index).is_some_and(|return_state| {
1769 let parent = context
1770 .parent(index)
1771 .unwrap_or_else(PredictionContext::empty);
1772 state_or_parent_can_match_symbol_before_state(
1773 atn,
1774 return_state,
1775 &parent,
1776 stop_state_number,
1777 symbol,
1778 &mut BTreeSet::new(),
1779 )
1780 })
1781 })
1782}
1783
1784fn state_or_parent_can_match_symbol_before_state(
1785 atn: &Atn,
1786 state_number: usize,
1787 parent: &Rc<PredictionContext>,
1788 stop_state_number: usize,
1789 symbol: i32,
1790 visited: &mut BTreeSet<usize>,
1791) -> bool {
1792 if state_number == EMPTY_RETURN_STATE {
1793 return false;
1794 }
1795 if state_number == stop_state_number {
1796 return context_can_match_symbol_before_state(atn, parent, stop_state_number, symbol);
1797 }
1798 if !visited.insert(state_number) {
1799 return false;
1800 }
1801 let Some(state) = atn.state(state_number) else {
1802 return false;
1803 };
1804 state.transitions.iter().any(|transition| {
1805 if transition.matches(symbol, 1, atn.max_token_type()) {
1806 return true;
1807 }
1808 transition.is_epsilon()
1809 && state_or_parent_can_match_symbol_before_state(
1810 atn,
1811 transition.target(),
1812 parent,
1813 stop_state_number,
1814 symbol,
1815 visited,
1816 )
1817 })
1818}
1819
1820fn next_recovery_context(
1824 atn: &Atn,
1825 state: &AtnState,
1826 inherited: &BTreeSet<i32>,
1827 inherited_state: Option<usize>,
1828) -> (BTreeSet<i32>, Option<usize>) {
1829 let state_symbols = state_expected_symbols(atn, state.state_number);
1830 if state.transitions.len() > 1 && !state_symbols.is_empty() {
1831 let mut symbols = state_symbols;
1832 symbols.extend(inherited.iter().copied());
1833 return (symbols, Some(state.state_number));
1834 }
1835 (inherited.clone(), inherited_state)
1836}
1837
1838fn recovery_expected_symbols(
1839 atn: &Atn,
1840 state_number: usize,
1841 inherited: &BTreeSet<i32>,
1842) -> BTreeSet<i32> {
1843 let mut symbols = state_expected_symbols(atn, state_number);
1844 symbols.extend(inherited.iter().copied());
1845 symbols
1846}
1847
1848fn fast_next_recovery_context<S>(
1852 parser: &mut BaseParser<S>,
1853 atn: &Atn,
1854 state: &AtnState,
1855 inherited: &Rc<BTreeSet<i32>>,
1856 inherited_state: Option<usize>,
1857) -> (Rc<BTreeSet<i32>>, Option<usize>)
1858where
1859 S: TokenSource,
1860{
1861 if state.transitions.len() <= 1 {
1862 return (Rc::clone(inherited), inherited_state);
1863 }
1864 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number);
1865 if state_symbols.is_empty() {
1866 return (Rc::clone(inherited), inherited_state);
1867 }
1868 if inherited.is_empty() {
1869 return (state_symbols, Some(state.state_number));
1870 }
1871 if Rc::ptr_eq(&state_symbols, inherited) {
1872 return (state_symbols, Some(state.state_number));
1873 }
1874 let mut combined = (*state_symbols).clone();
1875 combined.extend(inherited.iter().copied());
1876 (
1877 parser.intern_recovery_symbols(combined),
1878 Some(state.state_number),
1879 )
1880}
1881
1882fn fast_recovery_expected_symbols<S>(
1886 parser: &mut BaseParser<S>,
1887 atn: &Atn,
1888 state_number: usize,
1889 inherited: &Rc<BTreeSet<i32>>,
1890) -> Rc<BTreeSet<i32>>
1891where
1892 S: TokenSource,
1893{
1894 let cached = parser.cached_state_expected_symbols(atn, state_number);
1895 if inherited.is_empty() {
1896 return cached;
1897 }
1898 if cached.is_empty() {
1899 return Rc::clone(inherited);
1900 }
1901 if Rc::ptr_eq(&cached, inherited) {
1902 return cached;
1903 }
1904 let mut combined = (*cached).clone();
1905 combined.extend(inherited.iter().copied());
1906 parser.intern_recovery_symbols(combined)
1907}
1908
1909fn apply_member_actions(
1911 source_state: usize,
1912 actions: &[ParserMemberAction],
1913 values: &mut BTreeMap<usize, i64>,
1914) {
1915 for action in actions
1916 .iter()
1917 .filter(|action| action.source_state == source_state)
1918 {
1919 *values.entry(action.member).or_default() += action.delta;
1920 }
1921}
1922
1923fn member_values_after_action(
1925 source_state: usize,
1926 actions: &[ParserMemberAction],
1927 values: &BTreeMap<usize, i64>,
1928) -> BTreeMap<usize, i64> {
1929 let mut values = values.clone();
1930 apply_member_actions(source_state, actions, &mut values);
1931 values
1932}
1933
1934fn return_values_after_action(
1936 source_state: usize,
1937 rule_index: usize,
1938 actions: &[ParserReturnAction],
1939 values: &BTreeMap<String, i64>,
1940) -> BTreeMap<String, i64> {
1941 let mut values = values.clone();
1942 for action in actions
1943 .iter()
1944 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
1945 {
1946 values.insert(action.name.to_owned(), action.value);
1947 }
1948 values
1949}
1950
1951fn rule_local_int_arg(
1953 rule_args: &[ParserRuleArg],
1954 source_state: usize,
1955 rule_index: usize,
1956 local_int_arg: Option<(usize, i64)>,
1957) -> Option<(usize, i64)> {
1958 rule_args
1959 .iter()
1960 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
1961 .map(|arg| {
1962 let value = if arg.inherit_local {
1963 local_int_arg.map_or(arg.value, |(_, value)| value)
1964 } else {
1965 arg.value
1966 };
1967 (rule_index, value)
1968 })
1969}
1970
1971fn stop_outcome(
1974 index: usize,
1975 consumed_eof: bool,
1976 rule_alt_number: usize,
1977 member_values: BTreeMap<usize, i64>,
1978 return_values: BTreeMap<String, i64>,
1979) -> Vec<RecognizeOutcome> {
1980 vec![RecognizeOutcome {
1981 index,
1982 consumed_eof,
1983 alt_number: rule_alt_number,
1984 member_values,
1985 return_values,
1986 diagnostics: Vec::new(),
1987 decisions: Vec::new(),
1988 actions: Vec::new(),
1989 nodes: Vec::new(),
1990 }]
1991}
1992
1993#[derive(Clone, Debug, Eq, PartialEq)]
1994struct RecognizeRequest<'a> {
1995 state_number: usize,
1996 stop_state: usize,
1997 index: usize,
1998 rule_start_index: usize,
1999 decision_start_index: Option<usize>,
2000 init_action_rules: &'a BTreeSet<usize>,
2001 predicates: &'a [(usize, usize, ParserPredicate)],
2002 rule_args: &'a [ParserRuleArg],
2003 member_actions: &'a [ParserMemberAction],
2004 return_actions: &'a [ParserReturnAction],
2005 local_int_arg: Option<(usize, i64)>,
2006 member_values: BTreeMap<usize, i64>,
2007 return_values: BTreeMap<String, i64>,
2008 rule_alt_number: usize,
2009 track_alt_numbers: bool,
2010 consumed_eof: bool,
2011 precedence: i32,
2014 depth: usize,
2015 recovery_symbols: BTreeSet<i32>,
2016 recovery_state: Option<usize>,
2017}
2018
2019#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2020struct RecognizeKey {
2021 state_number: usize,
2022 stop_state: usize,
2023 index: usize,
2024 rule_start_index: usize,
2025 decision_start_index: Option<usize>,
2026 local_int_arg: Option<(usize, i64)>,
2027 member_values: BTreeMap<usize, i64>,
2028 return_values: BTreeMap<String, i64>,
2029 rule_alt_number: usize,
2030 track_alt_numbers: bool,
2031 consumed_eof: bool,
2032 precedence: i32,
2033 recovery_symbols: BTreeSet<i32>,
2034 recovery_state: Option<usize>,
2035}
2036
2037#[derive(Clone, Debug, Eq, PartialEq)]
2038struct EpsilonActionStep {
2039 source_state: usize,
2040 target: usize,
2041 action_rule_index: Option<usize>,
2042 left_recursive_boundary: Option<usize>,
2043 decision: Option<usize>,
2044 decision_start_index: Option<usize>,
2045 alt_number: usize,
2046 recovery_symbols: BTreeSet<i32>,
2047 recovery_state: Option<usize>,
2048}
2049
2050struct RecognizeScratch<'a> {
2051 visiting: &'a mut BTreeSet<RecognizeKey>,
2052 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2053 expected: &'a mut ExpectedTokens,
2054}
2055
2056#[derive(Clone, Debug, Eq, PartialEq)]
2057struct FastRecognizeRequest {
2058 state_number: usize,
2059 stop_state: usize,
2060 index: usize,
2061 rule_start_index: usize,
2062 decision_start_index: Option<usize>,
2063 precedence: i32,
2064 depth: usize,
2065 recovery_symbols: Rc<BTreeSet<i32>>,
2066 recovery_state: Option<usize>,
2067}
2068
2069#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2070struct FastRecognizeTopRequest {
2071 start_state: usize,
2072 stop_state: usize,
2073 start_index: usize,
2074 precedence: i32,
2075 caller_follow_state: Option<usize>,
2076}
2077
2078#[derive(Clone, Debug)]
2085struct FastRecognizeKey {
2086 state_number: usize,
2087 stop_state: usize,
2088 index: usize,
2089 rule_start_index: usize,
2090 decision_start_index: Option<usize>,
2091 precedence: i32,
2092 recovery_symbols_id: usize,
2093 recovery_state: Option<usize>,
2094}
2095
2096impl PartialEq for FastRecognizeKey {
2097 fn eq(&self, other: &Self) -> bool {
2098 if self.state_number != other.state_number
2099 || self.stop_state != other.stop_state
2100 || self.index != other.index
2101 || self.rule_start_index != other.rule_start_index
2102 || self.decision_start_index != other.decision_start_index
2103 || self.precedence != other.precedence
2104 || self.recovery_state != other.recovery_state
2105 || self.recovery_symbols_id != other.recovery_symbols_id
2106 {
2107 return false;
2108 }
2109 true
2110 }
2111}
2112
2113impl Eq for FastRecognizeKey {}
2114
2115impl Hash for FastRecognizeKey {
2116 fn hash<H: Hasher>(&self, hasher: &mut H) {
2117 self.state_number.hash(hasher);
2118 self.stop_state.hash(hasher);
2119 self.index.hash(hasher);
2120 self.rule_start_index.hash(hasher);
2121 self.decision_start_index.hash(hasher);
2122 self.precedence.hash(hasher);
2123 self.recovery_state.hash(hasher);
2124 self.recovery_symbols_id.hash(hasher);
2125 }
2126}
2127
2128struct FastRecoveryRequest<'a, 'b> {
2129 atn: &'a Atn,
2130 transition: &'a Transition,
2131 expected_symbols: Rc<BTreeSet<i32>>,
2132 target: usize,
2133 request: FastRecognizeRequest,
2134 visiting: &'b mut FxHashSet<(usize, usize)>,
2135 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
2136 expected: &'b mut ExpectedTokens,
2137}
2138
2139struct FastCurrentTokenDeletionRequest<'a, 'b> {
2140 atn: &'a Atn,
2141 expected_symbols: Rc<BTreeSet<i32>>,
2142 request: FastRecognizeRequest,
2143 visiting: &'b mut FxHashSet<(usize, usize)>,
2144 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
2145 expected: &'b mut ExpectedTokens,
2146}
2147
2148#[derive(Clone, Copy)]
2149struct FastChildRuleFailureRecoveryRequest<'a> {
2150 atn: &'a Atn,
2151 rule_index: usize,
2152 start_index: usize,
2153 follow_state: usize,
2154 stop_state: usize,
2155 expected: &'a ExpectedTokens,
2156}
2157
2158struct RecoveryRequest<'a, 'b> {
2159 atn: &'a Atn,
2160 transition: &'a Transition,
2161 expected_symbols: BTreeSet<i32>,
2162 target: usize,
2163 request: RecognizeRequest<'a>,
2164 visiting: &'b mut BTreeSet<RecognizeKey>,
2165 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2166 expected: &'b mut ExpectedTokens,
2167}
2168
2169struct CurrentTokenDeletionRequest<'a, 'b> {
2170 atn: &'a Atn,
2171 expected_symbols: BTreeSet<i32>,
2172 request: RecognizeRequest<'a>,
2173 visiting: &'b mut BTreeSet<RecognizeKey>,
2174 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2175 expected: &'b mut ExpectedTokens,
2176}
2177
2178struct ConsumingFailureFallback<'a> {
2181 atn: &'a Atn,
2182 target: usize,
2183 request: RecognizeRequest<'a>,
2184 symbol: i32,
2185 expected_symbols: BTreeSet<i32>,
2186 decision_start_index: Option<usize>,
2187 decision: Option<usize>,
2188}
2189
2190struct ChildRuleFailureRecovery<'a> {
2193 atn: &'a Atn,
2194 rule_index: usize,
2195 start_index: usize,
2196 follow_state: usize,
2197 stop_state: usize,
2198 member_values: BTreeMap<usize, i64>,
2199 expected: &'a ExpectedTokens,
2200}
2201
2202#[derive(Clone, Copy, Debug)]
2204struct PredicateEval<'a> {
2205 index: usize,
2206 rule_index: usize,
2207 pred_index: usize,
2208 predicates: &'a [(usize, usize, ParserPredicate)],
2209 context: Option<&'a ParserRuleContext>,
2210 local_int_arg: Option<(usize, i64)>,
2211 member_values: &'a BTreeMap<usize, i64>,
2212}
2213
2214struct PredicateFailureRecovery<'a> {
2216 rule_index: usize,
2217 index: usize,
2218 message: &'a str,
2219 member_values: BTreeMap<usize, i64>,
2220 return_values: BTreeMap<String, i64>,
2221 rule_alt_number: usize,
2222}
2223
2224#[derive(Debug)]
2225enum DirectAdaptiveParseControl {
2226 Fallback(DirectAdaptiveFallback),
2227}
2228
2229#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2230enum DirectAdaptiveFallback {
2231 Action,
2232 InvalidAlt,
2233 LeftRecursiveBoundary,
2234 MissingAtn,
2235 NoTransition,
2236 Predicate,
2237 Prediction,
2238 Precedence,
2239 RuleStop,
2240 SemanticContext,
2241 StepLimit,
2242 TokenMismatch,
2243 UnknownDecision,
2244}
2245
2246type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
2247
2248struct DirectAdaptiveParser<'atn, 'sim, S>
2249where
2250 S: TokenSource,
2251{
2252 parser: &'sim mut BaseParser<S>,
2253 atn: &'atn Atn,
2254 simulator: &'sim mut ParserAtnSimulator<'atn>,
2255 decision_by_state: Vec<Option<usize>>,
2256 steps: usize,
2257}
2258
2259#[derive(Clone, Debug, Eq, PartialEq)]
2269pub struct GeneratedMatch {
2270 children: Vec<ParseTree>,
2271 consumed_eof: bool,
2272}
2273
2274impl GeneratedMatch {
2275 #[must_use]
2279 pub fn children(&self) -> &[ParseTree] {
2280 &self.children
2281 }
2282
2283 #[must_use]
2286 pub fn into_children(self) -> Vec<ParseTree> {
2287 self.children
2288 }
2289
2290 #[must_use]
2292 pub const fn consumed_eof(&self) -> bool {
2293 self.consumed_eof
2294 }
2295}
2296
2297impl<S> BaseParser<S>
2298where
2299 S: TokenSource,
2300{
2301 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
2304 Self {
2305 input,
2306 data,
2307 build_parse_trees: true,
2308 syntax_errors: 0,
2309 report_diagnostic_errors: false,
2310 prediction_mode: PredictionMode::Ll,
2311 prediction_diagnostics: Vec::new(),
2312 reported_prediction_diagnostics: BTreeSet::new(),
2313 generated_parser_diagnostics: Vec::new(),
2314 generated_sync_expected: None,
2315 int_members: BTreeMap::new(),
2316 rule_context_stack: Vec::new(),
2317 rule_context_version: 0,
2318 prediction_context_cache: None,
2319 pending_invoking_states: Vec::new(),
2320 precedence_stack: vec![0],
2321 invoked_predicates: Vec::new(),
2322 rule_first_set_cache: Vec::new(),
2323 state_expected_cache: FxHashMap::default(),
2324 state_expected_token_cache: FxHashMap::default(),
2325 rule_stop_reach_cache: Vec::new(),
2326 recovery_symbols_intern: FxHashMap::default(),
2327 decision_lookahead_cache: FxHashMap::default(),
2328 ll1_decision_cache: FxHashMap::default(),
2329 empty_cycle_cache: Vec::new(),
2330 single_outcome_memo_mode: SingleOutcomeMemoMode::Probe,
2331 single_outcome_probe_seen: FxHashSet::default(),
2332 single_outcome_probe_samples: 0,
2333 single_outcome_probe_repeats: 0,
2334 empty_recovery_symbols: Rc::new(BTreeSet::new()),
2335 fast_first_set_prefilter: true,
2336 fast_recovery_enabled: true,
2337 fast_token_nodes_enabled: true,
2338 }
2339 }
2340
2341 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
2342 &mut self.input
2343 }
2344
2345 #[must_use]
2347 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
2348 &self.input
2349 }
2350
2351 #[must_use]
2353 pub fn into_token_stream(self) -> CommonTokenStream<S> {
2354 self.input
2355 }
2356
2357 pub const fn number_of_syntax_errors(&self) -> usize {
2360 self.syntax_errors
2361 }
2362
2363 pub const fn record_generated_syntax_error(&mut self) {
2366 self.record_syntax_errors(1);
2367 }
2368
2369 const fn record_syntax_errors(&mut self, count: usize) {
2370 self.syntax_errors = self.syntax_errors.saturating_add(count);
2371 }
2372
2373 pub fn report_token_source_errors(&mut self) {
2376 report_token_source_errors(&self.input.drain_source_errors());
2377 }
2378
2379 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
2382 GeneratedDiagnosticsCheckpoint {
2383 diagnostics_len: self.generated_parser_diagnostics.len(),
2384 syntax_errors: self.syntax_errors,
2385 }
2386 }
2387
2388 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
2390 self.generated_parser_diagnostics
2391 .truncate(marker.diagnostics_len);
2392 self.syntax_errors = marker.syntax_errors;
2393 self.generated_sync_expected = None;
2394 }
2395
2396 pub fn report_generated_parser_diagnostics(&mut self) {
2398 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
2399 let token_errors = self.input.drain_source_errors();
2400 report_generated_diagnostics(&parser_diagnostics, &token_errors);
2401 }
2402
2403 pub fn record_generated_ambiguity_diagnostic(
2406 &mut self,
2407 atn: &Atn,
2408 state_number: usize,
2409 start_index: usize,
2410 stop_index: usize,
2411 alts: &[usize],
2412 ) {
2413 if !self.report_diagnostic_errors || alts.len() < 2 {
2414 return;
2415 }
2416 let Some(decision) = atn
2417 .decision_to_state()
2418 .iter()
2419 .position(|candidate| *candidate == state_number)
2420 else {
2421 return;
2422 };
2423 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
2424 return;
2425 };
2426 let rule_name = self
2427 .rule_names()
2428 .get(rule_index)
2429 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
2430 let input = display_input_text(&self.input.text(start_index, stop_index));
2431 let alts = alts
2432 .iter()
2433 .map(usize::to_string)
2434 .collect::<Vec<_>>()
2435 .join(", ");
2436 let key = (decision, start_index, format!("{alts}:{input}"));
2437 if !self.reported_prediction_diagnostics.insert(key) {
2438 return;
2439 }
2440 let start_token = self.token_at(start_index);
2441 let stop_token = self.token_at(stop_index);
2442 self.generated_parser_diagnostics.push(diagnostic_for_token(
2443 start_token.as_ref(),
2444 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
2445 ));
2446 self.generated_parser_diagnostics.push(diagnostic_for_token(
2447 stop_token.as_ref(),
2448 format!(
2449 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
2450 ),
2451 ));
2452 }
2453
2454 pub fn record_generated_prediction_diagnostic(
2457 &mut self,
2458 atn: &Atn,
2459 state_number: usize,
2460 prediction: &ParserAtnPrediction,
2461 ) {
2462 let Some(diagnostic) = &prediction.diagnostic else {
2463 return;
2464 };
2465 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
2466 return;
2467 }
2468 let Some(decision) = atn
2469 .decision_to_state()
2470 .iter()
2471 .position(|candidate| *candidate == state_number)
2472 else {
2473 return;
2474 };
2475 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
2476 return;
2477 };
2478 let rule_name = self
2479 .rule_names()
2480 .get(rule_index)
2481 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
2482 let attempt_input = display_input_text(
2483 &self
2484 .input
2485 .text(diagnostic.start_index, diagnostic.sll_stop_index),
2486 );
2487 let result_input = display_input_text(
2488 &self
2489 .input
2490 .text(diagnostic.start_index, diagnostic.ll_stop_index),
2491 );
2492 let alts = diagnostic
2493 .conflicting_alts
2494 .iter()
2495 .map(usize::to_string)
2496 .collect::<Vec<_>>()
2497 .join(", ");
2498 let key = (
2499 decision,
2500 diagnostic.start_index,
2501 format!(
2502 "{:?}:{alts}:{attempt_input}:{result_input}",
2503 diagnostic.kind
2504 ),
2505 );
2506 if !self.reported_prediction_diagnostics.insert(key) {
2507 return;
2508 }
2509 let attempt_token = self.token_at(diagnostic.sll_stop_index);
2510 self.generated_parser_diagnostics.push(diagnostic_for_token(
2511 attempt_token.as_ref(),
2512 format!(
2513 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
2514 ),
2515 ));
2516 let result_token = self.token_at(diagnostic.ll_stop_index);
2517 let message = match diagnostic.kind {
2518 ParserAtnPredictionDiagnosticKind::Ambiguity => {
2519 format!(
2520 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
2521 )
2522 }
2523 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
2524 format!(
2525 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
2526 )
2527 }
2528 };
2529 self.generated_parser_diagnostics
2530 .push(diagnostic_for_token(result_token.as_ref(), message));
2531 }
2532
2533 pub fn la(&mut self, offset: isize) -> i32 {
2534 self.input.la_token(offset)
2535 }
2536
2537 pub fn consume(&mut self) {
2538 IntStream::consume(&mut self.input);
2539 }
2540
2541 pub fn set_int_member(&mut self, member: usize, value: i64) {
2543 self.int_members.insert(member, value);
2544 }
2545
2546 pub fn int_member(&self, member: usize) -> Option<i64> {
2548 self.int_members.get(&member).copied()
2549 }
2550
2551 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
2554 self.int_members.clone()
2555 }
2556
2557 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
2559 self.int_members = members;
2560 }
2561
2562 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
2564 let value = self.int_members.entry(member).or_default();
2565 *value += delta;
2566 *value
2567 }
2568
2569 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
2576 let current = self
2577 .input
2578 .lt_ref(1)
2579 .ok_or_else(|| AntlrError::ParserError {
2580 line: 0,
2581 column: 0,
2582 message: "missing current token".to_owned(),
2583 })?;
2584 if current.token_type() == token_type {
2585 self.consume();
2586 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
2587 } else {
2588 Err(AntlrError::MismatchedInput {
2589 expected: self.vocabulary().display_name(token_type),
2590 found: self.vocabulary().display_name(current.token_type()),
2591 })
2592 }
2593 }
2594
2595 pub fn match_token_recovering(
2599 &mut self,
2600 token_type: i32,
2601 follow_state: usize,
2602 atn: &Atn,
2603 ) -> Result<GeneratedMatch, AntlrError> {
2604 let current = self
2605 .input
2606 .lt_ref(1)
2607 .ok_or_else(|| AntlrError::ParserError {
2608 line: 0,
2609 column: 0,
2610 message: "missing current token".to_owned(),
2611 })?;
2612 if current.token_type() == token_type {
2613 self.generated_sync_expected = None;
2614 let consumed_eof = current.token_type() == TOKEN_EOF;
2615 self.consume();
2616 return Ok(GeneratedMatch {
2617 children: vec![ParseTree::Terminal(TerminalNode::from_ref(current))],
2618 consumed_eof,
2619 });
2620 }
2621 let mut expected_symbols = BTreeSet::new();
2622 expected_symbols.insert(token_type);
2623 self.recover_generated_match(
2624 current.as_ref().clone(),
2625 &expected_symbols,
2626 follow_state,
2627 atn,
2628 |symbol| symbol == token_type,
2629 )
2630 }
2631
2632 pub fn match_set_recovering(
2633 &mut self,
2634 intervals: &[(i32, i32)],
2635 follow_state: usize,
2636 atn: &Atn,
2637 ) -> Result<GeneratedMatch, AntlrError> {
2638 let current = self
2639 .input
2640 .lt_ref(1)
2641 .ok_or_else(|| AntlrError::ParserError {
2642 line: 0,
2643 column: 0,
2644 message: "missing current token".to_owned(),
2645 })?;
2646 if interval_set_contains(intervals, current.token_type()) {
2647 self.generated_sync_expected = None;
2648 let consumed_eof = current.token_type() == TOKEN_EOF;
2649 self.consume();
2650 return Ok(GeneratedMatch {
2651 children: vec![ParseTree::Terminal(TerminalNode::from_ref(current))],
2652 consumed_eof,
2653 });
2654 }
2655 let expected_symbols = interval_symbols(intervals);
2656 self.recover_generated_match(
2657 current.as_ref().clone(),
2658 &expected_symbols,
2659 follow_state,
2660 atn,
2661 |symbol| interval_set_contains(intervals, symbol),
2662 )
2663 }
2664
2665 pub fn match_not_set_recovering(
2666 &mut self,
2667 intervals: &[(i32, i32)],
2668 min_vocabulary: i32,
2669 max_vocabulary: i32,
2670 follow_state: usize,
2671 atn: &Atn,
2672 ) -> Result<GeneratedMatch, AntlrError> {
2673 let current = self
2674 .input
2675 .lt_ref(1)
2676 .ok_or_else(|| AntlrError::ParserError {
2677 line: 0,
2678 column: 0,
2679 message: "missing current token".to_owned(),
2680 })?;
2681 if (min_vocabulary..=max_vocabulary).contains(¤t.token_type())
2682 && !interval_set_contains(intervals, current.token_type())
2683 {
2684 self.generated_sync_expected = None;
2685 let consumed_eof = current.token_type() == TOKEN_EOF;
2686 self.consume();
2687 return Ok(GeneratedMatch {
2688 children: vec![ParseTree::Terminal(TerminalNode::from_ref(current))],
2689 consumed_eof,
2690 });
2691 }
2692 let expected_symbols =
2693 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
2694 self.recover_generated_match(
2695 current.as_ref().clone(),
2696 &expected_symbols,
2697 follow_state,
2698 atn,
2699 |symbol| {
2700 (min_vocabulary..=max_vocabulary).contains(&symbol)
2701 && !interval_set_contains(intervals, symbol)
2702 },
2703 )
2704 }
2705
2706 fn recover_generated_match(
2707 &mut self,
2708 current: CommonToken,
2709 expected_symbols: &BTreeSet<i32>,
2710 follow_state: usize,
2711 atn: &Atn,
2712 matches: impl Fn(i32) -> bool,
2713 ) -> Result<GeneratedMatch, AntlrError> {
2714 let expected_display = self.expected_symbols_display(expected_symbols);
2715 if current.token_type() != TOKEN_EOF
2716 && let Some(next) = self.input.lt(2).cloned()
2717 && matches(next.token_type())
2718 {
2719 let message = format!(
2720 "extraneous input {} expecting {expected_display}",
2721 token_input_display(¤t)
2722 );
2723 self.push_generated_parser_diagnostic(diagnostic_for_token(Some(¤t), message));
2724 self.record_syntax_errors(1);
2725 self.generated_sync_expected = None;
2726 let consumed_eof = next.token_type() == TOKEN_EOF;
2729 self.consume();
2730 self.consume();
2731 return Ok(GeneratedMatch {
2732 children: vec![
2733 ParseTree::Error(ErrorNode::new(current)),
2734 ParseTree::Terminal(TerminalNode::new(next)),
2735 ],
2736 consumed_eof,
2737 });
2738 }
2739 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
2740 let follow_explicitly_expects_eof = current.token_type() == TOKEN_EOF
2749 && self
2750 .cached_state_expected_symbols(atn, follow_state)
2751 .contains(&TOKEN_EOF);
2752 if follow_symbols.contains(¤t.token_type())
2753 && (current.token_type() != TOKEN_EOF
2754 || self.rule_context_stack.len() > 1
2755 || expected_symbols.is_empty()
2756 || follow_explicitly_expects_eof)
2757 {
2758 let message = format!(
2759 "missing {expected_display} at {}",
2760 token_input_display(¤t)
2761 );
2762 self.push_generated_parser_diagnostic(diagnostic_for_token(Some(¤t), message));
2763 self.record_syntax_errors(1);
2764 self.generated_sync_expected = None;
2765 let token_type = expected_symbols.iter().next().copied().unwrap_or(TOKEN_EOF);
2766 let mut missing_symbol = BTreeSet::new();
2767 missing_symbol.insert(token_type);
2768 let missing_display = self.expected_symbols_display(&missing_symbol);
2769 let token = CommonToken::new(token_type)
2770 .with_text(format!("<missing {missing_display}>"))
2771 .with_span(usize::MAX, usize::MAX)
2772 .with_position(current.line(), current.column());
2773 return Ok(GeneratedMatch {
2778 children: vec![ParseTree::Error(ErrorNode::new(token))],
2779 consumed_eof: false,
2780 });
2781 }
2782 let mismatch_expected = self.generated_sync_expected.take().map_or_else(
2783 || expected_symbols.clone(),
2784 |symbols| symbols.to_btree_set(),
2785 );
2786 let mismatch_expected_display = self.expected_symbols_display(&mismatch_expected);
2787 Err(AntlrError::ParserError {
2788 line: current.line(),
2789 column: current.column(),
2790 message: format!(
2791 "mismatched input {} expecting {mismatch_expected_display}",
2792 token_input_display(¤t)
2793 ),
2794 })
2795 }
2796
2797 fn generated_recovery_follow_symbols(
2798 &mut self,
2799 atn: &Atn,
2800 follow_state: usize,
2801 ) -> BTreeSet<i32> {
2802 let mut follow = self
2803 .cached_state_expected_symbols(atn, follow_state)
2804 .as_ref()
2805 .clone();
2806 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
2807 follow.extend(self.context_expected_symbols(atn));
2808 }
2809 follow
2810 }
2811
2812 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
2813 self.match_token(TOKEN_EOF)
2814 }
2815
2816 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
2817 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
2818 }
2819
2820 pub fn match_not_set(
2821 &mut self,
2822 intervals: &[(i32, i32)],
2823 min_vocabulary: i32,
2824 max_vocabulary: i32,
2825 ) -> Result<ParseTree, AntlrError> {
2826 self.match_interval_condition(intervals, |symbol| {
2827 (min_vocabulary..=max_vocabulary).contains(&symbol)
2828 && !interval_set_contains(intervals, symbol)
2829 })
2830 }
2831
2832 fn match_interval_condition(
2833 &mut self,
2834 intervals: &[(i32, i32)],
2835 matches: impl FnOnce(i32) -> bool,
2836 ) -> Result<ParseTree, AntlrError> {
2837 let current = self
2838 .input
2839 .lt_ref(1)
2840 .ok_or_else(|| AntlrError::ParserError {
2841 line: 0,
2842 column: 0,
2843 message: "missing current token".to_owned(),
2844 })?;
2845 if matches(current.token_type()) {
2846 self.consume();
2847 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
2848 } else {
2849 Err(AntlrError::MismatchedInput {
2850 expected: self.interval_display(intervals),
2851 found: self.vocabulary().display_name(current.token_type()),
2852 })
2853 }
2854 }
2855
2856 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
2857 let values = intervals
2858 .iter()
2859 .map(|(start, stop)| {
2860 if start == stop {
2861 self.vocabulary().display_name(*start)
2862 } else {
2863 format!(
2864 "{}..{}",
2865 self.vocabulary().display_name(*start),
2866 self.vocabulary().display_name(*stop)
2867 )
2868 }
2869 })
2870 .collect::<Vec<_>>()
2871 .join(", ");
2872 format!("{{{values}}}")
2873 }
2874
2875 pub const fn rule_node(&self, context: ParserRuleContext) -> ParseTree {
2876 ParseTree::Rule(RuleNode::new(context))
2877 }
2878
2879 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
2882 self.set_state(state);
2883 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
2884 self.rule_context_stack.push(RuleContextFrame {
2885 rule_index,
2886 invoking_state,
2887 });
2888 self.invalidate_prediction_context_cache();
2889 let start_index = self.current_visible_index();
2890 let mut context = ParserRuleContext::new(rule_index, invoking_state);
2891 if let Some(token) = self.token_ref_at(start_index) {
2892 context.set_start_ref(token);
2893 }
2894 context
2895 }
2896
2897 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
2904 let marker = self.pending_invoking_states.len();
2905 self.pending_invoking_states.push(invoking_state);
2906 marker
2907 }
2908
2909 pub fn discard_invoking_state(&mut self, marker: usize) {
2911 self.pending_invoking_states.truncate(marker);
2912 }
2913
2914 pub fn exit_rule(&mut self) {
2916 self.rule_context_stack.pop();
2917 self.invalidate_prediction_context_cache();
2918 }
2919
2920 pub fn prediction_context(&mut self, atn: &Atn) -> Rc<PredictionContext> {
2923 let atn_ptr: *const Atn = atn;
2924 let atn_key = atn_ptr as usize;
2925 if let Some(cached) = &self.prediction_context_cache
2926 && cached.version == self.rule_context_version
2927 && cached.atn_key == atn_key
2928 {
2929 return Rc::clone(&cached.context);
2930 }
2931 let mut context = PredictionContext::empty();
2932 for frame in self.rule_context_stack.iter().skip(1) {
2933 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
2934 continue;
2935 };
2936 let Some(Transition::Rule { follow_state, .. }) = atn
2937 .state(state_number)
2938 .and_then(|state| state.transitions.first())
2939 else {
2940 continue;
2941 };
2942 context = PredictionContext::singleton(context, *follow_state);
2943 }
2944 self.prediction_context_cache = Some(CachedPredictionContext {
2945 version: self.rule_context_version,
2946 atn_key,
2947 context: Rc::clone(&context),
2948 });
2949 context
2950 }
2951
2952 fn invalidate_prediction_context_cache(&mut self) {
2953 self.rule_context_version = self.rule_context_version.wrapping_add(1);
2954 self.prediction_context_cache = None;
2955 }
2956
2957 pub fn add_parse_child(&self, context: &mut ParserRuleContext, child: ParseTree) {
2962 if self.build_parse_trees {
2963 context.add_child(child);
2964 } else {
2965 context.note_matched_child();
2966 }
2967 }
2968
2969 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
2971 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
2972 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
2973 context.set_stop_ref(token);
2974 }
2975 self.exit_rule();
2976 self.rule_node(context)
2977 }
2978
2979 pub fn recover_generated_rule(
2986 &mut self,
2987 context: &mut ParserRuleContext,
2988 atn: &Atn,
2989 error: AntlrError,
2990 ) {
2991 let diagnostic = self.generated_rule_error_diagnostic(error);
2992 self.push_generated_parser_diagnostic(diagnostic);
2993 self.generated_sync_expected = None;
2994 let recovery_symbols = self.context_expected_symbols(atn);
2995 loop {
2996 let symbol = self.la(1);
2997 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
2998 break;
2999 }
3000 let Some(token) = self.input.lt(1).cloned() else {
3001 break;
3002 };
3003 self.consume();
3004 self.add_parse_child(context, ParseTree::Error(ErrorNode::new(token)));
3005 }
3006 self.record_syntax_errors(1);
3007 }
3008
3009 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
3010 if self
3011 .generated_parser_diagnostics
3012 .iter()
3013 .any(|existing| existing == &diagnostic)
3014 {
3015 return;
3016 }
3017 self.generated_parser_diagnostics.push(diagnostic);
3018 }
3019
3020 fn generated_rule_error_diagnostic(&mut self, error: AntlrError) -> ParserDiagnostic {
3021 match error {
3022 AntlrError::ParserError {
3023 line,
3024 column,
3025 message,
3026 } => ParserDiagnostic {
3027 line,
3028 column,
3029 message,
3030 },
3031 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
3032 self.input.lt(1),
3033 format!("mismatched input {found} expecting {expected}"),
3034 ),
3035 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
3036 self.input.lt(1),
3037 format!("no viable alternative at input {input}"),
3038 ),
3039 AntlrError::LexerError {
3040 line,
3041 column,
3042 message,
3043 } => ParserDiagnostic {
3044 line,
3045 column,
3046 message,
3047 },
3048 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
3049 }
3050 }
3051
3052 pub fn finish_recursion_rule(
3054 &mut self,
3055 mut context: ParserRuleContext,
3056 consumed_eof: bool,
3057 ) -> ParseTree {
3058 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
3059 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
3060 context.set_stop_ref(token);
3061 }
3062 self.unroll_recursion_context();
3063 self.rule_node(context)
3064 }
3065
3066 pub fn enter_recursion_rule(
3068 &mut self,
3069 state: isize,
3070 rule_index: usize,
3071 precedence: i32,
3072 ) -> ParserRuleContext {
3073 self.precedence_stack.push(precedence);
3074 self.enter_rule(state, rule_index)
3075 }
3076
3077 pub fn push_new_recursion_context(
3079 &mut self,
3080 state: isize,
3081 rule_index: usize,
3082 ) -> ParserRuleContext {
3083 self.set_state(state);
3084 ParserRuleContext::new(rule_index, state)
3085 }
3086
3087 pub fn push_new_recursion_context_with_previous(
3090 &mut self,
3091 state: isize,
3092 rule_index: usize,
3093 current: &mut ParserRuleContext,
3094 ) {
3095 self.set_state(state);
3096 if let Some(stop) = self
3097 .rule_stop_token_index(self.input.index(), false)
3098 .and_then(|index| self.token_ref_at(index))
3099 {
3100 current.set_stop_ref(stop);
3101 }
3102 let invoking_state = current.invoking_state();
3103 let start = current.start_ref();
3104 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
3105 if let Some(start) = start {
3106 replacement.set_start_ref(start);
3107 }
3108 let previous = std::mem::replace(current, replacement);
3109 if self.build_parse_trees {
3110 current.add_child(self.rule_node(previous));
3111 }
3112 }
3113
3114 pub fn unroll_recursion_context(&mut self) {
3116 if self.precedence_stack.len() > 1 {
3117 self.precedence_stack.pop();
3118 }
3119 self.exit_rule();
3120 }
3121
3122 pub fn left_recursive_loop_enter_matches(
3127 &mut self,
3128 atn: &Atn,
3129 state_number: usize,
3130 precedence: i32,
3131 ) -> bool {
3132 let symbol = self.la(1);
3133 if symbol == TOKEN_EOF {
3134 return false;
3135 }
3136 let Some(state) = atn.state(state_number) else {
3137 return false;
3138 };
3139 let context = self.prediction_context(atn);
3140 if context_can_match_symbol_before_state(atn, &context, state_number, symbol) {
3141 return false;
3142 }
3143 state.transitions.iter().any(|transition| {
3144 let target = transition.target();
3145 if atn
3146 .state(target)
3147 .is_some_and(|state| state.kind == AtnStateKind::LoopEnd)
3148 {
3149 return false;
3150 }
3151 state_can_reach_symbol_with_precedence(
3152 atn,
3153 target,
3154 symbol,
3155 precedence,
3156 &mut BTreeSet::new(),
3157 )
3158 })
3159 }
3160
3161 pub fn precpred(&self, precedence: i32) -> bool {
3163 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
3164 }
3165
3166 pub fn parser_semantic_predicate_matches(
3169 &mut self,
3170 predicates: &[(usize, usize, ParserPredicate)],
3171 rule_index: usize,
3172 pred_index: usize,
3173 ) -> bool {
3174 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
3175 }
3176
3177 pub fn parser_semantic_predicate_matches_with_local(
3180 &mut self,
3181 predicates: &[(usize, usize, ParserPredicate)],
3182 rule_index: usize,
3183 pred_index: usize,
3184 local_int_arg: i32,
3185 ) -> bool {
3186 self.parser_semantic_predicate_matches_inner(
3187 predicates,
3188 rule_index,
3189 pred_index,
3190 Some((rule_index, i64::from(local_int_arg))),
3191 )
3192 }
3193
3194 fn parser_semantic_predicate_matches_inner(
3195 &mut self,
3196 predicates: &[(usize, usize, ParserPredicate)],
3197 rule_index: usize,
3198 pred_index: usize,
3199 local_int_arg: Option<(usize, i64)>,
3200 ) -> bool {
3201 let index = self.input.index();
3202 let member_values = self.int_members.clone();
3203 self.parser_predicate_matches(PredicateEval {
3204 index,
3205 rule_index,
3206 pred_index,
3207 predicates,
3208 context: None,
3209 local_int_arg,
3210 member_values: &member_values,
3211 })
3212 }
3213
3214 pub fn parser_semantic_predicate_matches_with_context_and_local(
3217 &mut self,
3218 predicates: &[(usize, usize, ParserPredicate)],
3219 rule_index: usize,
3220 pred_index: usize,
3221 context: &ParserRuleContext,
3222 local_int_arg: i32,
3223 ) -> bool {
3224 let index = self.input.index();
3225 let member_values = self.int_members.clone();
3226 self.parser_predicate_matches(PredicateEval {
3227 index,
3228 rule_index,
3229 pred_index,
3230 predicates,
3231 context: Some(context),
3232 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
3233 member_values: &member_values,
3234 })
3235 }
3236
3237 pub fn parser_semantic_predicate_failure_message(
3240 &self,
3241 rule_index: usize,
3242 pred_index: usize,
3243 predicates: &[(usize, usize, ParserPredicate)],
3244 ) -> Option<&'static str> {
3245 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
3246 }
3247
3248 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
3250 let current = self
3251 .input
3252 .lt_ref(1)
3253 .ok_or_else(|| AntlrError::ParserError {
3254 line: 0,
3255 column: 0,
3256 message: "missing current token".to_owned(),
3257 })?;
3258 if current.token_type() == TOKEN_EOF {
3259 return Err(AntlrError::MismatchedInput {
3260 expected: "wildcard".to_owned(),
3261 found: self.vocabulary().display_name(TOKEN_EOF),
3262 });
3263 }
3264 self.consume();
3265 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
3266 }
3267
3268 #[allow(clippy::unnecessary_wraps)]
3272 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
3273 self.set_state(state);
3274 Ok(())
3275 }
3276
3277 pub fn sync_decision(
3285 &mut self,
3286 atn: &Atn,
3287 state_number: usize,
3288 current_context_empty: bool,
3289 loop_back: bool,
3290 ) -> Result<Vec<ParseTree>, AntlrError> {
3291 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
3292 self.generated_sync_expected = None;
3293 let Some(state) = atn.state(state_number) else {
3294 return Ok(Vec::new());
3295 };
3296 let Some(rule_index) = state.rule_index else {
3297 return Ok(Vec::new());
3298 };
3299 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index).copied() else {
3300 return Ok(Vec::new());
3301 };
3302 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
3303 let symbol = self.la(1);
3304 let mut has_expected_symbols = false;
3305 let mut nullable = false;
3306 let mut explicit_eof_expected = false;
3314 for transition in &entry.transitions {
3315 if transition.symbols.contains(symbol) {
3316 return Ok(Vec::new());
3317 }
3318 has_expected_symbols |= !transition.symbols.is_empty();
3319 nullable |= transition.nullable;
3320 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
3321 }
3322 if nullable && self.context_expected_contains(atn, symbol) {
3327 return Ok(Vec::new());
3328 }
3329 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
3330 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
3331 return Ok(Vec::new());
3332 }
3333 let mut expected = TokenBitSet::default();
3334 for transition in &entry.transitions {
3335 expected.extend_from(&transition.symbols);
3336 }
3337 if let Some(context_expected) = context_expected {
3338 expected.extend_from(&context_expected);
3339 }
3340 let can_delete_in_place =
3341 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
3342 let loop_sync = loop_back;
3359 if symbol != TOKEN_EOF && can_delete_in_place {
3360 let mut cursor = self.input.index();
3361 let mut skipped = Vec::new();
3362 loop {
3363 let current = self.token_type_at(cursor);
3364 if current == TOKEN_EOF {
3365 break;
3366 }
3367 skipped.push(cursor);
3368 let next = self.consume_index(cursor, current);
3369 if next == cursor {
3370 break;
3371 }
3372 let next_symbol = self.token_type_at(next);
3373 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
3381 explicit_eof_expected
3382 } else {
3383 expected.contains(next_symbol)
3384 };
3385 if next_is_expected_stop {
3386 let current_token = self.input.lt(1).cloned();
3387 let expected_symbols = expected.to_btree_set();
3388 let message = format!(
3389 "extraneous input {} expecting {}",
3390 current_token
3391 .as_ref()
3392 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
3393 self.expected_symbols_display(&expected_symbols)
3394 );
3395 self.push_generated_parser_diagnostic(diagnostic_for_token(
3396 current_token.as_ref(),
3397 message,
3398 ));
3399 self.record_syntax_errors(1);
3400 let mut children = Vec::with_capacity(skipped.len());
3401 for index in skipped {
3402 if let Some(token) = self.token_at(index) {
3403 self.consume();
3404 children.push(ParseTree::Error(ErrorNode::new(token)));
3405 }
3406 }
3407 return Ok(children);
3408 }
3409 if !loop_sync {
3413 break;
3414 }
3415 cursor = next;
3416 }
3417 }
3418 if nullable {
3419 self.generated_sync_expected = Some(expected);
3420 return Ok(Vec::new());
3421 }
3422 let current = self.input.lt(1).cloned();
3423 let expected_symbols = expected.to_btree_set();
3424 Err(AntlrError::ParserError {
3425 line: current.as_ref().map(Token::line).unwrap_or_default(),
3426 column: current.as_ref().map(Token::column).unwrap_or_default(),
3427 message: format!(
3428 "mismatched input {} expecting {}",
3429 current
3430 .as_ref()
3431 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
3432 self.expected_symbols_display(&expected_symbols)
3433 ),
3434 })
3435 }
3436
3437 pub fn ll1_decision_prediction(
3444 &mut self,
3445 atn: &Atn,
3446 state_number: usize,
3447 ) -> Option<ParserAtnPrediction> {
3448 let state = atn.state(state_number)?;
3449 if state.precedence_rule_decision {
3450 return None;
3451 }
3452 let rule_stop = state
3453 .rule_index
3454 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index).copied())?;
3455 let symbol = self.la(1);
3456 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
3457 ll1_greedy_alt(&entry, symbol, state.non_greedy).map(|alt| ParserAtnPrediction {
3458 alt: alt + 1,
3459 requires_full_context: false,
3460 has_semantic_context: false,
3461 diagnostic: None,
3462 })
3463 }
3464
3465 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
3466 let context = self.prediction_context(atn);
3467 let mut expected = BTreeSet::new();
3468 self.collect_context_expected_symbols(atn, &context, &mut expected);
3469 expected
3470 }
3471
3472 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
3473 let context = self.prediction_context(atn);
3474 let mut expected = TokenBitSet::default();
3475 self.collect_context_expected_token_set(atn, &context, &mut expected);
3476 expected
3477 }
3478
3479 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
3490 for index in (1..self.rule_context_stack.len()).rev() {
3491 let invoking_state = self.rule_context_stack[index].invoking_state;
3492 let Ok(state_number) = usize::try_from(invoking_state) else {
3493 continue;
3494 };
3495 let Some(Transition::Rule { follow_state, .. }) = atn
3496 .state(state_number)
3497 .and_then(|state| state.transitions.first())
3498 else {
3499 continue;
3500 };
3501 let follow_state = *follow_state;
3502 if self
3503 .cached_state_expected_token_set(atn, follow_state)
3504 .contains(symbol)
3505 {
3506 return true;
3507 }
3508 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
3509 return false;
3510 }
3511 }
3512 symbol == TOKEN_EOF
3513 }
3514
3515 fn collect_context_expected_symbols(
3516 &mut self,
3517 atn: &Atn,
3518 context: &Rc<PredictionContext>,
3519 expected: &mut BTreeSet<i32>,
3520 ) {
3521 if context.is_empty() {
3522 expected.insert(TOKEN_EOF);
3523 return;
3524 }
3525 for index in 0..context.len() {
3526 let Some(return_state) = context.return_state(index) else {
3527 continue;
3528 };
3529 if return_state == EMPTY_RETURN_STATE {
3530 expected.insert(TOKEN_EOF);
3531 continue;
3532 }
3533 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
3534 if self.cached_state_can_reach_rule_stop(atn, return_state)
3535 && let Some(parent) = context.parent(index)
3536 {
3537 self.collect_context_expected_symbols(atn, &parent, expected);
3538 }
3539 }
3540 }
3541
3542 fn collect_context_expected_token_set(
3543 &mut self,
3544 atn: &Atn,
3545 context: &Rc<PredictionContext>,
3546 expected: &mut TokenBitSet,
3547 ) {
3548 if context.is_empty() {
3549 expected.insert(TOKEN_EOF);
3550 return;
3551 }
3552 for index in 0..context.len() {
3553 let Some(return_state) = context.return_state(index) else {
3554 continue;
3555 };
3556 if return_state == EMPTY_RETURN_STATE {
3557 expected.insert(TOKEN_EOF);
3558 continue;
3559 }
3560 let state_expected = self.cached_state_expected_token_set(atn, return_state);
3561 expected.extend_from(&state_expected);
3562 if self.cached_state_can_reach_rule_stop(atn, return_state)
3563 && let Some(parent) = context.parent(index)
3564 {
3565 self.collect_context_expected_token_set(atn, &parent, expected);
3566 }
3567 }
3568 }
3569
3570 pub fn no_viable_alternative_error(&mut self, start_index: usize) -> AntlrError {
3572 let error_index = self.input.index();
3573 self.no_viable_alternative_error_at(start_index, error_index)
3574 }
3575
3576 pub fn no_viable_alternative_error_at(
3581 &mut self,
3582 start_index: usize,
3583 error_index: usize,
3584 ) -> AntlrError {
3585 let diagnostic = self.no_viable_alternative(start_index, error_index);
3586 AntlrError::ParserError {
3587 line: diagnostic.line,
3588 column: diagnostic.column,
3589 message: diagnostic.message,
3590 }
3591 }
3592
3593 pub fn failed_predicate_error(&mut self, message: impl Into<String>) -> AntlrError {
3595 let current = self.input.lt(1).cloned();
3596 AntlrError::ParserError {
3597 line: current.as_ref().map(Token::line).unwrap_or_default(),
3598 column: current.as_ref().map(Token::column).unwrap_or_default(),
3599 message: format!("rule failed predicate: {}", message.into()),
3600 }
3601 }
3602
3603 pub fn failed_predicate_option_error(
3606 &mut self,
3607 rule_index: usize,
3608 message: impl Into<String>,
3609 ) -> AntlrError {
3610 let current = self.input.lt(1).cloned();
3611 let rule_name = self
3612 .rule_names()
3613 .get(rule_index)
3614 .map_or_else(|| rule_index.to_string(), Clone::clone);
3615 AntlrError::ParserError {
3616 line: current.as_ref().map(Token::line).unwrap_or_default(),
3617 column: current.as_ref().map(Token::column).unwrap_or_default(),
3618 message: format!("rule {rule_name} {}", message.into()),
3619 }
3620 }
3621
3622 pub fn parser_action_at_current(
3624 &mut self,
3625 source_state: usize,
3626 rule_index: usize,
3627 start_index: usize,
3628 consumed_eof: bool,
3629 ) -> ParserAction {
3630 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
3631 ParserAction::new(source_state, rule_index, start_index, stop_index)
3632 }
3633
3634 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
3639 &mut self,
3640 atn: &'atn Atn,
3641 simulator: &mut ParserAtnSimulator<'atn>,
3642 rule_index: usize,
3643 ) -> Result<ParseTree, AntlrError> {
3644 let start_index = self.current_visible_index();
3645 self.clear_prediction_diagnostics();
3646 self.reset_per_parse_caches();
3647 let mut decision_by_state = vec![None; atn.states().len()];
3648 for (decision, &state_number) in atn.decision_to_state().iter().enumerate() {
3649 if let Some(slot) = decision_by_state.get_mut(state_number) {
3650 *slot = Some(decision);
3651 }
3652 }
3653
3654 let result = DirectAdaptiveParser {
3655 parser: self,
3656 atn,
3657 simulator,
3658 decision_by_state,
3659 steps: 0,
3660 }
3661 .parse_rule(rule_index, -1, 0);
3662
3663 match result {
3664 Ok(tree) => {
3665 report_token_source_errors(&self.input.drain_source_errors());
3666 Ok(tree)
3667 }
3668 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
3669 let _ = reason;
3670 self.input.seek(start_index);
3671 self.parse_atn_rule(atn, rule_index)
3672 }
3673 }
3674 }
3675
3676 pub fn parse_atn_rule(
3686 &mut self,
3687 atn: &Atn,
3688 rule_index: usize,
3689 ) -> Result<ParseTree, AntlrError> {
3690 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
3691 }
3692
3693 pub fn parse_atn_rule_with_precedence(
3696 &mut self,
3697 atn: &Atn,
3698 rule_index: usize,
3699 precedence: i32,
3700 ) -> Result<ParseTree, AntlrError> {
3701 let start_state = atn
3702 .rule_to_start_state()
3703 .get(rule_index)
3704 .copied()
3705 .ok_or_else(|| {
3706 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
3707 })?;
3708 let stop_state = atn
3709 .rule_to_stop_state()
3710 .get(rule_index)
3711 .copied()
3712 .filter(|state| *state != usize::MAX)
3713 .ok_or_else(|| {
3714 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
3715 })?;
3716
3717 let start_index = self.current_visible_index();
3718 self.clear_prediction_diagnostics();
3719 self.reset_per_parse_caches();
3720 let caller_follow_state = self.pending_invoking_follow_state(atn);
3721 self.fast_recovery_enabled = false;
3722 self.fast_token_nodes_enabled = false;
3723 let top_request = FastRecognizeTopRequest {
3724 start_state,
3725 stop_state,
3726 start_index,
3727 precedence,
3728 caller_follow_state,
3729 };
3730 let first_pass = self.fast_recognize_top(atn, top_request);
3731 self.fast_token_nodes_enabled = true;
3732 self.fast_recovery_enabled = true;
3733 let needs_tree_retry = matches!(
3734 &first_pass,
3735 Ok((outcome, _)) if self.build_parse_trees && outcome.nodes.has_left_recursive_boundary()
3736 );
3737 let needs_retry = match &first_pass {
3738 Err(_) => true,
3751 Ok((outcome, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
3752 };
3753 let (outcome, _expected) = if needs_retry {
3754 self.fast_first_set_prefilter = false;
3755 let retry = self.fast_recognize_top(atn, top_request);
3756 self.fast_first_set_prefilter = true;
3757 let selected = if needs_tree_retry {
3758 match retry {
3759 ok @ Ok(_) => ok,
3760 Err(_) => first_pass,
3761 }
3762 } else {
3763 select_better_top_outcome(first_pass, retry)
3764 };
3765 selected.map_err(|expected| {
3766 let error = self.recognition_error(rule_index, start_index, &expected);
3767 self.record_syntax_errors(1);
3768 report_token_source_errors(&self.input.drain_source_errors());
3769 error
3770 })?
3771 } else {
3772 first_pass.expect("first_pass is Ok in the no-retry branch")
3773 };
3774 self.record_syntax_errors(outcome.diagnostics.len());
3775 report_parser_diagnostics(&self.prediction_diagnostics);
3776 report_parser_diagnostics(&outcome.diagnostics);
3777 report_token_source_errors(&self.input.drain_source_errors());
3778 let mut context = ParserRuleContext::with_child_capacity(
3779 rule_index,
3780 self.state(),
3781 if self.build_parse_trees {
3782 outcome.nodes.len()
3783 } else {
3784 0
3785 },
3786 );
3787 if let Some(token) = self.token_ref_at(start_index) {
3788 context.set_start_ref(token);
3789 }
3790 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
3791 if let Some(token) = stop_index.and_then(|token_index| self.token_ref_at(token_index)) {
3792 context.set_stop_ref(token);
3793 }
3794 if self.build_parse_trees {
3795 if outcome.nodes.has_left_recursive_boundary() {
3796 let folded = fold_fast_left_recursive_boundaries(outcome.nodes.to_vec());
3797 if folded.iter().any(|node| {
3798 matches!(
3799 node.as_ref(),
3800 FastRecognizedNode::Token { .. }
3801 | FastRecognizedNode::ErrorToken { .. }
3802 | FastRecognizedNode::MissingToken { .. }
3803 )
3804 }) {
3805 for node in &folded {
3806 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
3807 }
3808 } else {
3809 self.add_fast_implicit_token_children(
3810 &mut context,
3811 start_index,
3812 stop_index,
3813 &folded,
3814 )?;
3815 }
3816 } else if outcome.nodes.has_explicit_token_node() {
3817 for node in outcome.nodes.iter() {
3818 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
3819 }
3820 } else {
3821 self.add_fast_implicit_token_children_iter(
3822 &mut context,
3823 start_index,
3824 stop_index,
3825 outcome.nodes.iter(),
3826 )?;
3827 }
3828 }
3829 self.input.seek(outcome.index);
3830
3831 Ok(self.rule_node(context))
3832 }
3833
3834 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
3835 let invoking_state = self.pending_invoking_states.last().copied()?;
3836 let state_number = usize::try_from(invoking_state).ok()?;
3837 match atn.state(state_number)?.transitions.first()? {
3838 Transition::Rule { follow_state, .. } => Some(*follow_state),
3839 _ => None,
3840 }
3841 }
3842
3843 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
3844 let token_type = self.token_type_at(index);
3847 let visible_channel = self.input.channel();
3848 let token = self.token_at(index);
3849 let is_boundary = token
3850 .as_ref()
3851 .and_then(Token::text)
3852 .is_some_and(is_caller_follow_boundary_text);
3853 let is_boundary_gap = token.as_ref().is_some_and(|token| {
3854 token.channel() != visible_channel
3855 || token.text().is_some_and(is_caller_follow_boundary_gap_text)
3856 });
3857 (token_type, is_boundary, is_boundary_gap)
3858 }
3859
3860 fn fast_recognize_top(
3865 &mut self,
3866 atn: &Atn,
3867 request: FastRecognizeTopRequest,
3868 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
3869 let FastRecognizeTopRequest {
3870 start_state,
3871 stop_state,
3872 start_index,
3873 precedence,
3874 caller_follow_state,
3875 } = request;
3876 let memo_capacity = self.input.size().saturating_mul(8).clamp(65_536, 524_288);
3885 let mut visiting = FxHashSet::with_capacity_and_hasher(256, FxBuildHasher::default());
3886 let mut memo = FxHashMap::with_capacity_and_hasher(memo_capacity, FxBuildHasher::default());
3887 let mut expected = ExpectedTokens::default();
3888 let empty_recovery = self.empty_recovery_symbols();
3889 let outcomes = self.recognize_state_fast(
3890 atn,
3891 FastRecognizeRequest {
3892 state_number: start_state,
3893 stop_state,
3894 index: start_index,
3895 rule_start_index: start_index,
3896 decision_start_index: None,
3897 precedence,
3898 depth: 0,
3899 recovery_symbols: empty_recovery,
3900 recovery_state: None,
3901 },
3902 &mut visiting,
3903 &mut memo,
3904 &mut expected,
3905 );
3906 #[cfg(feature = "perf-counters")]
3907 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
3908 perf_counters::dump();
3909 perf_counters::reset();
3910 }
3911 let caller_follow =
3912 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
3913 match select_best_fast_outcome(
3914 outcomes.into_iter(),
3915 self.prediction_mode,
3916 caller_follow.as_deref(),
3917 |index| self.caller_follow_token_info(index),
3918 ) {
3919 Some(outcome) => Ok((outcome, expected)),
3920 None => Err(expected),
3921 }
3922 }
3923
3924 fn fast_recognized_node_tree(
3927 &mut self,
3928 node: &FastRecognizedNode,
3929 ) -> Result<ParseTree, AntlrError> {
3930 match node {
3931 FastRecognizedNode::Token { index } => {
3932 let token = self
3933 .input
3934 .get_ref(*index)
3935 .ok_or_else(|| AntlrError::ParserError {
3936 line: 0,
3937 column: 0,
3938 message: format!("missing token at index {index}"),
3939 })?;
3940 Ok(ParseTree::Terminal(TerminalNode::from_ref(token)))
3941 }
3942 FastRecognizedNode::ErrorToken { index } => {
3943 let token = self
3944 .input
3945 .get_ref(*index)
3946 .ok_or_else(|| AntlrError::ParserError {
3947 line: 0,
3948 column: 0,
3949 message: format!("missing error token at index {index}"),
3950 })?;
3951 Ok(ParseTree::Error(ErrorNode::from_ref(token)))
3952 }
3953 FastRecognizedNode::MissingToken {
3954 token_type,
3955 at_index,
3956 text,
3957 } => {
3958 let current = self.token_at(*at_index);
3959 let token = CommonToken::new(*token_type)
3960 .with_text(text.as_str())
3961 .with_span(usize::MAX, usize::MAX)
3962 .with_position(
3963 current.as_ref().map(Token::line).unwrap_or_default(),
3964 current.as_ref().map(Token::column).unwrap_or_default(),
3965 );
3966 Ok(ParseTree::Error(ErrorNode::new(token)))
3967 }
3968 FastRecognizedNode::Rule {
3969 rule_index,
3970 invoking_state,
3971 start_index,
3972 stop_index,
3973 children,
3974 } => {
3975 let mut context = ParserRuleContext::with_child_capacity(
3976 *rule_index,
3977 *invoking_state,
3978 children.len(),
3979 );
3980 if let Some(token) = self.token_ref_at(*start_index) {
3981 context.set_start_ref(token);
3982 }
3983 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
3984 context.set_stop_ref(token);
3985 }
3986 if children.has_left_recursive_boundary() {
3987 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
3988 for child in &folded {
3989 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
3990 }
3991 } else {
3992 for child in children.iter() {
3993 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
3994 }
3995 }
3996 Ok(self.rule_node(context))
3997 }
3998 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
3999 Err(AntlrError::Unsupported(format!(
4000 "unfolded left-recursive boundary for rule {rule_index}"
4001 )))
4002 }
4003 }
4004 }
4005
4006 fn fast_recognized_node_tree_with_implicit_tokens(
4007 &mut self,
4008 node: &FastRecognizedNode,
4009 ) -> Result<ParseTree, AntlrError> {
4010 match node {
4011 FastRecognizedNode::Rule {
4012 rule_index,
4013 invoking_state,
4014 start_index,
4015 stop_index,
4016 children,
4017 } => {
4018 let mut context = ParserRuleContext::with_child_capacity(
4019 *rule_index,
4020 *invoking_state,
4021 children.len(),
4022 );
4023 if let Some(token) = self.token_ref_at(*start_index) {
4024 context.set_start_ref(token);
4025 }
4026 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
4027 context.set_stop_ref(token);
4028 }
4029 if children.has_left_recursive_boundary() {
4030 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
4031 self.add_fast_implicit_token_children(
4032 &mut context,
4033 *start_index,
4034 *stop_index,
4035 &folded,
4036 )?;
4037 } else {
4038 self.add_fast_implicit_token_children_iter(
4039 &mut context,
4040 *start_index,
4041 *stop_index,
4042 children.iter(),
4043 )?;
4044 }
4045 Ok(self.rule_node(context))
4046 }
4047 _ => self.fast_recognized_node_tree(node),
4048 }
4049 }
4050
4051 fn add_fast_implicit_token_children(
4052 &mut self,
4053 context: &mut ParserRuleContext,
4054 start_index: usize,
4055 stop_index: Option<usize>,
4056 children: &[Rc<FastRecognizedNode>],
4057 ) -> Result<(), AntlrError> {
4058 self.add_fast_implicit_token_children_iter(
4059 context,
4060 start_index,
4061 stop_index,
4062 children.iter(),
4063 )
4064 }
4065
4066 fn add_fast_implicit_token_children_iter<'a>(
4067 &mut self,
4068 context: &mut ParserRuleContext,
4069 start_index: usize,
4070 stop_index: Option<usize>,
4071 children: impl IntoIterator<Item = &'a Rc<FastRecognizedNode>>,
4072 ) -> Result<(), AntlrError> {
4073 let mut cursor = Some(start_index);
4074 for child in children {
4075 if let Some((child_start, child_stop)) = fast_recognized_node_span(child.as_ref()) {
4076 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
4077 context.add_child(
4078 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
4079 );
4080 if let Some(child_stop) = child_stop {
4081 cursor = self.next_visible_after_token(child_stop);
4082 }
4083 } else {
4084 context.add_child(
4085 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
4086 );
4087 }
4088 }
4089 if let Some(stop) = stop_index {
4090 self.add_visible_terminals_through(context, cursor, stop)?;
4091 }
4092 Ok(())
4093 }
4094
4095 fn add_visible_terminals_before(
4096 &mut self,
4097 context: &mut ParserRuleContext,
4098 cursor: &mut Option<usize>,
4099 before: usize,
4100 ) -> Result<(), AntlrError> {
4101 let Some(stop) = before.checked_sub(1) else {
4102 return Ok(());
4103 };
4104 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
4105 *cursor = next;
4106 Ok(())
4107 }
4108
4109 fn add_visible_terminals_through(
4110 &mut self,
4111 context: &mut ParserRuleContext,
4112 mut cursor: Option<usize>,
4113 stop: usize,
4114 ) -> Result<Option<usize>, AntlrError> {
4115 while let Some(index) = cursor {
4116 if index > stop {
4117 return Ok(Some(index));
4118 }
4119 let token = self
4120 .input
4121 .get_ref(index)
4122 .ok_or_else(|| AntlrError::ParserError {
4123 line: 0,
4124 column: 0,
4125 message: format!("missing token at index {index}"),
4126 })?;
4127 let is_eof = token.token_type() == TOKEN_EOF;
4128 context.add_child(ParseTree::Terminal(TerminalNode::from_ref(token)));
4129 if is_eof {
4130 return Ok(None);
4131 }
4132 cursor = self.next_visible_after_token(index);
4133 }
4134 Ok(None)
4135 }
4136
4137 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
4138 let next = self.input.next_visible_after(index);
4139 (next != index).then_some(next)
4140 }
4141
4142 pub fn parse_atn_rule_with_actions(
4149 &mut self,
4150 atn: &Atn,
4151 rule_index: usize,
4152 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4153 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
4154 }
4155
4156 pub fn parse_atn_rule_with_action_inits(
4164 &mut self,
4165 atn: &Atn,
4166 rule_index: usize,
4167 init_action_rules: &[usize],
4168 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4169 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
4170 }
4171
4172 pub fn parse_atn_rule_with_action_options(
4178 &mut self,
4179 atn: &Atn,
4180 rule_index: usize,
4181 init_action_rules: &[usize],
4182 track_alt_numbers: bool,
4183 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4184 self.parse_atn_rule_with_runtime_options(
4185 atn,
4186 rule_index,
4187 ParserRuntimeOptions {
4188 init_action_rules,
4189 track_alt_numbers,
4190 ..ParserRuntimeOptions::default()
4191 },
4192 )
4193 }
4194
4195 pub fn parse_atn_rule_with_runtime_options(
4202 &mut self,
4203 atn: &Atn,
4204 rule_index: usize,
4205 options: ParserRuntimeOptions<'_>,
4206 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4207 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
4208 }
4209
4210 pub fn parse_atn_rule_with_runtime_options_and_precedence(
4213 &mut self,
4214 atn: &Atn,
4215 rule_index: usize,
4216 precedence: i32,
4217 options: ParserRuntimeOptions<'_>,
4218 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4219 let ParserRuntimeOptions {
4220 init_action_rules,
4221 track_alt_numbers,
4222 predicates,
4223 rule_args,
4224 member_actions,
4225 return_actions,
4226 } = options;
4227 let start_state = atn
4228 .rule_to_start_state()
4229 .get(rule_index)
4230 .copied()
4231 .ok_or_else(|| {
4232 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
4233 })?;
4234 let stop_state = atn
4235 .rule_to_stop_state()
4236 .get(rule_index)
4237 .copied()
4238 .filter(|state| *state != usize::MAX)
4239 .ok_or_else(|| {
4240 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
4241 })?;
4242
4243 let start_index = self.current_visible_index();
4244 self.clear_prediction_diagnostics();
4245 self.reset_per_parse_caches();
4246 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
4247 let invoking_state = self.pending_invoking_states.pop();
4248 let local_int_arg = invoking_state
4249 .and_then(|state| usize::try_from(state).ok())
4250 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
4251 let mut visiting = BTreeSet::new();
4252 let mut memo = BTreeMap::new();
4253 let mut expected = ExpectedTokens::default();
4254 let member_values = self.int_members.clone();
4255 let return_values = BTreeMap::new();
4256 let outcomes = self.recognize_state(
4257 atn,
4258 RecognizeRequest {
4259 state_number: start_state,
4260 stop_state,
4261 index: start_index,
4262 rule_start_index: start_index,
4263 decision_start_index: None,
4264 init_action_rules: &init_action_rules,
4265 predicates,
4266 rule_args,
4267 member_actions,
4268 return_actions,
4269 local_int_arg,
4270 member_values,
4271 return_values,
4272 rule_alt_number: 0,
4273 track_alt_numbers,
4274 consumed_eof: false,
4275 precedence,
4276 depth: 0,
4277 recovery_symbols: BTreeSet::new(),
4278 recovery_state: None,
4279 },
4280 &mut visiting,
4281 &mut memo,
4282 &mut expected,
4283 );
4284 let Some(outcome) = select_best_outcome(outcomes.into_iter(), self.prediction_mode) else {
4285 let error = self.recognition_error(rule_index, start_index, &expected);
4286 self.record_syntax_errors(1);
4287 report_token_source_errors(&self.input.drain_source_errors());
4288 return Err(error);
4289 };
4290
4291 self.record_syntax_errors(outcome.diagnostics.len());
4292 report_parser_diagnostics(&self.prediction_diagnostics);
4293 report_parser_diagnostics(&outcome.diagnostics);
4294 report_token_source_errors(&self.input.drain_source_errors());
4295 let mut actions = outcome.actions;
4296 if init_action_rules.contains(&rule_index) {
4297 actions.insert(
4298 0,
4299 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
4300 );
4301 }
4302 let mut context =
4303 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
4304 if track_alt_numbers {
4305 context.set_alt_number(outcome.alt_number);
4306 }
4307 for (name, value) in outcome.return_values {
4308 context.set_int_return(name, value);
4309 }
4310 if let Some(token) = self.token_ref_at(start_index) {
4311 context.set_start_ref(token);
4312 }
4313 if let Some(token) = self.rule_stop_token_ref(outcome.index, outcome.consumed_eof) {
4314 context.set_stop_ref(token);
4315 }
4316 if self.build_parse_trees {
4317 let nodes = fold_left_recursive_boundaries(outcome.nodes);
4318 for node in &nodes {
4319 context.add_child(self.recognized_node_tree(node, track_alt_numbers)?);
4320 }
4321 }
4322 self.input.seek(outcome.index);
4323
4324 Ok((self.rule_node(context), actions))
4325 }
4326
4327 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
4334 let mut context = ParserRuleContext::new(rule_index, self.state());
4335 while self.la(1) != TOKEN_EOF {
4336 let token_type = self.la(1);
4337 let child = self.match_token(token_type)?;
4338 if self.build_parse_trees {
4339 context.add_child(child);
4340 }
4341 }
4342 if self.build_parse_trees {
4343 context.add_child(self.match_eof()?);
4344 }
4345 Ok(self.rule_node(context))
4346 }
4347
4348 fn recognition_error(
4351 &mut self,
4352 rule_index: usize,
4353 start_index: usize,
4354 expected: &ExpectedTokens,
4355 ) -> AntlrError {
4356 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
4357 self.input.seek(index);
4358 let current = self.input.lt(1).cloned();
4359 let line = current.as_ref().map(Token::line).unwrap_or_default();
4360 let column = current.as_ref().map(Token::column).unwrap_or_default();
4361 AntlrError::ParserError {
4362 line,
4363 column,
4364 message,
4365 }
4366 }
4367
4368 fn expected_error_message(
4370 &mut self,
4371 rule_index: usize,
4372 start_index: usize,
4373 expected: &ExpectedTokens,
4374 ) -> (usize, String) {
4375 let index = expected
4376 .index
4377 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
4378 .unwrap_or_else(|| self.input.index());
4379 self.input.seek(index);
4380 let current = self.input.lt(1).cloned();
4381 let message = if expected
4382 .no_viable
4383 .as_ref()
4384 .is_some_and(|no_viable| no_viable.error_index == index)
4385 {
4386 let start = expected
4387 .no_viable
4388 .as_ref()
4389 .map_or(start_index, |no_viable| no_viable.start_index);
4390 let text = display_input_text(&self.input.text(start, index));
4391 format!("no viable alternative at input '{text}'")
4392 } else if expected.symbols.is_empty() {
4393 if expected.index.is_some() {
4394 let found = current
4395 .as_ref()
4396 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
4397 if current
4398 .as_ref()
4399 .is_some_and(|token| token.token_type() == TOKEN_EOF)
4400 {
4401 format!(
4402 "missing {} at {found}",
4403 self.expected_symbols_display(&expected.symbols)
4404 )
4405 } else {
4406 format!("mismatched input {found}")
4407 }
4408 } else {
4409 format!("no viable alternative while parsing rule {rule_index}")
4410 }
4411 } else {
4412 format!(
4413 "mismatched input {} expecting {}",
4414 current
4415 .as_ref()
4416 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
4417 self.expected_symbols_display(&expected.symbols)
4418 )
4419 };
4420 (index, message)
4421 }
4422
4423 fn child_rule_failure_recovery(
4426 &mut self,
4427 rule_index: usize,
4428 start_index: usize,
4429 sync_symbols: &BTreeSet<i32>,
4430 member_values: BTreeMap<usize, i64>,
4431 expected: &ExpectedTokens,
4432 ) -> Option<RecognizeOutcome> {
4433 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
4434 let token = self.token_at(error_index);
4435 let mut next_index = error_index;
4436 loop {
4437 let symbol = self.token_type_at(next_index);
4438 if sync_symbols.contains(&symbol) {
4439 if next_index == error_index {
4440 return None;
4441 }
4442 break;
4443 }
4444 if symbol == TOKEN_EOF {
4445 break;
4446 }
4447 let after = self.consume_index(next_index, symbol);
4448 if after == next_index {
4449 break;
4450 }
4451 next_index = after;
4452 }
4453 Some(RecognizeOutcome {
4454 index: next_index,
4455 consumed_eof: false,
4456 alt_number: 0,
4457 member_values,
4458 return_values: BTreeMap::new(),
4459 diagnostics: vec![diagnostic_for_token(token.as_ref(), message)],
4460 decisions: Vec::new(),
4461 actions: Vec::new(),
4462 nodes: vec![RecognizedNode::ErrorToken { index: error_index }],
4463 })
4464 }
4465
4466 fn child_rule_failure_recovery_outcomes(
4469 &mut self,
4470 request: ChildRuleFailureRecovery<'_>,
4471 ) -> Vec<RecognizeOutcome> {
4472 let sync_symbols =
4473 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
4474 self.child_rule_failure_recovery(
4475 request.rule_index,
4476 request.start_index,
4477 &sync_symbols,
4478 request.member_values,
4479 request.expected,
4480 )
4481 .into_iter()
4482 .collect()
4483 }
4484
4485 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
4487 expected_symbols_display(symbols, self.vocabulary())
4488 }
4489
4490 fn single_token_deletion(
4493 &mut self,
4494 transition: &Transition,
4495 index: usize,
4496 max_token_type: i32,
4497 expected_symbols: &BTreeSet<i32>,
4498 ) -> Option<(ParserDiagnostic, usize, i32)> {
4499 let current_symbol = self.token_type_at(index);
4500 if current_symbol == TOKEN_EOF {
4501 return None;
4502 }
4503 let next_index = self.consume_index(index, current_symbol);
4504 if next_index == index {
4505 return None;
4506 }
4507 let next_symbol = self.token_type_at(next_index);
4508 if !transition.matches(next_symbol, 1, max_token_type) {
4509 return None;
4510 }
4511 let transition_expected = transition_expected_symbols(transition, max_token_type);
4512 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
4513 &transition_expected
4514 } else {
4515 expected_symbols
4516 });
4517 let current = self.token_at(index);
4518 let message = format!(
4519 "extraneous input {} expecting {expected_display}",
4520 current
4521 .as_ref()
4522 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
4523 );
4524 Some((
4525 diagnostic_for_token(current.as_ref(), message),
4526 next_index,
4527 next_symbol,
4528 ))
4529 }
4530
4531 fn current_token_deletion(
4534 &mut self,
4535 index: usize,
4536 expected_symbols: &BTreeSet<i32>,
4537 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
4538 if expected_symbols.is_empty() {
4539 return None;
4540 }
4541 let current_symbol = self.token_type_at(index);
4542 if current_symbol == TOKEN_EOF {
4543 return None;
4544 }
4545 let current = self.token_at(index);
4546 let message = format!(
4547 "extraneous input {} expecting {}",
4548 current
4549 .as_ref()
4550 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
4551 self.expected_symbols_display(expected_symbols)
4552 );
4553 let diagnostic = diagnostic_for_token(current.as_ref(), message);
4554 let mut skipped = Vec::new();
4555 let mut cursor = index;
4556 loop {
4557 let symbol = self.token_type_at(cursor);
4558 if symbol == TOKEN_EOF {
4559 return None;
4560 }
4561 skipped.push(cursor);
4562 let next_index = self.consume_index(cursor, symbol);
4563 if next_index == cursor {
4564 return None;
4565 }
4566 let next_symbol = self.token_type_at(next_index);
4567 if expected_symbols.contains(&next_symbol) {
4568 return Some((diagnostic, next_index, skipped));
4569 }
4570 cursor = next_index;
4571 }
4572 }
4573
4574 fn single_token_insertion(
4578 &mut self,
4579 transition: &Transition,
4580 index: usize,
4581 max_token_type: i32,
4582 expected_symbols: &BTreeSet<i32>,
4583 follow_symbols: &BTreeSet<i32>,
4584 ) -> Option<(ParserDiagnostic, i32, String)> {
4585 let current_symbol = self.token_type_at(index);
4586 if !follow_symbols.contains(¤t_symbol) {
4587 return None;
4588 }
4589 let transition_expected = transition_expected_symbols(transition, max_token_type);
4590 let token_type = transition_expected.iter().next().copied()?;
4591 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
4592 &transition_expected
4593 } else {
4594 expected_symbols
4595 });
4596 let mut token_symbols = BTreeSet::new();
4597 token_symbols.insert(token_type);
4598 let missing_token_display = self.expected_symbols_display(&token_symbols);
4599 let current = self.token_at(index);
4600 let message = format!(
4601 "missing {expected_display} at {}",
4602 current
4603 .as_ref()
4604 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
4605 );
4606 let text = format!("<missing {missing_token_display}>");
4607 Some((
4608 diagnostic_for_token(current.as_ref(), message),
4609 token_type,
4610 text,
4611 ))
4612 }
4613
4614 fn fast_single_token_deletion_recovery(
4618 &mut self,
4619 recovery: FastRecoveryRequest<'_, '_>,
4620 ) -> Vec<FastRecognizeOutcome> {
4621 let FastRecoveryRequest {
4622 atn,
4623 transition,
4624 expected_symbols,
4625 target,
4626 request,
4627 visiting,
4628 memo,
4629 expected,
4630 } = recovery;
4631 let FastRecognizeRequest {
4632 stop_state,
4633 index,
4634 rule_start_index,
4635 decision_start_index,
4636 precedence,
4637 depth,
4638 ..
4639 } = request;
4640 let Some((diagnostic, next_index, next_symbol)) =
4641 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
4642 else {
4643 return Vec::new();
4644 };
4645 let after_next = self.consume_index(next_index, next_symbol);
4646 let empty_recovery = self.empty_recovery_symbols();
4647 self.recognize_state_fast(
4648 atn,
4649 FastRecognizeRequest {
4650 state_number: target,
4651 stop_state,
4652 index: after_next,
4653 rule_start_index,
4654 decision_start_index,
4655 precedence,
4656 depth: depth + 1,
4657 recovery_symbols: empty_recovery,
4658 recovery_state: None,
4659 },
4660 visiting,
4661 memo,
4662 expected,
4663 )
4664 .into_iter()
4665 .map(|mut outcome| {
4666 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
4667 outcome.diagnostics.insert(0, diagnostic.clone());
4668 if self.fast_token_nodes_enabled {
4669 outcome
4670 .nodes
4671 .prepend(Rc::new(FastRecognizedNode::Token { index: next_index }));
4672 outcome
4673 .nodes
4674 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index }));
4675 }
4676 outcome
4677 })
4678 .collect()
4679 }
4680
4681 fn fast_single_token_insertion_recovery(
4685 &mut self,
4686 recovery: FastRecoveryRequest<'_, '_>,
4687 ) -> Vec<FastRecognizeOutcome> {
4688 let FastRecoveryRequest {
4689 atn,
4690 transition,
4691 expected_symbols,
4692 target,
4693 request,
4694 visiting,
4695 memo,
4696 expected,
4697 } = recovery;
4698 let FastRecognizeRequest {
4699 stop_state,
4700 index,
4701 rule_start_index,
4702 decision_start_index,
4703 precedence,
4704 depth,
4705 ..
4706 } = request;
4707 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
4708 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
4709 transition,
4710 index,
4711 atn.max_token_type(),
4712 &expected_symbols,
4713 &follow_symbols,
4714 ) else {
4715 return Vec::new();
4716 };
4717 let empty_recovery = self.empty_recovery_symbols();
4718 self.recognize_state_fast(
4719 atn,
4720 FastRecognizeRequest {
4721 state_number: target,
4722 stop_state,
4723 index,
4724 rule_start_index,
4725 decision_start_index,
4726 precedence,
4727 depth: depth + 1,
4728 recovery_symbols: empty_recovery,
4729 recovery_state: None,
4730 },
4731 visiting,
4732 memo,
4733 expected,
4734 )
4735 .into_iter()
4736 .map(|mut outcome| {
4737 outcome.diagnostics.insert(0, diagnostic.clone());
4738 outcome
4739 .nodes
4740 .prepend(Rc::new(FastRecognizedNode::MissingToken {
4741 token_type,
4742 at_index: index,
4743 text: text.clone(),
4744 }));
4745 outcome
4746 })
4747 .collect()
4748 }
4749
4750 fn fast_current_token_deletion_recovery(
4753 &mut self,
4754 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
4755 ) -> Vec<FastRecognizeOutcome> {
4756 let FastCurrentTokenDeletionRequest {
4757 atn,
4758 expected_symbols,
4759 mut request,
4760 visiting,
4761 memo,
4762 expected,
4763 } = recovery;
4764 if request.index == request.rule_start_index {
4765 return Vec::new();
4766 }
4767 let Some((diagnostic, next_index, skipped)) =
4768 self.current_token_deletion(request.index, &expected_symbols)
4769 else {
4770 return Vec::new();
4771 };
4772 request.state_number = request.recovery_state.unwrap_or(request.state_number);
4773 request.index = next_index;
4774 request.depth += 1;
4775 request.recovery_state = None;
4776 self.recognize_state_fast(atn, request, visiting, memo, expected)
4777 .into_iter()
4778 .map(|mut outcome| {
4779 outcome.diagnostics.insert(0, diagnostic.clone());
4780 for index in skipped.iter().rev() {
4781 outcome
4782 .nodes
4783 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index: *index }));
4784 }
4785 outcome
4786 })
4787 .collect()
4788 }
4789
4790 fn fast_child_rule_failure_recovery(
4793 &mut self,
4794 rule_index: usize,
4795 start_index: usize,
4796 sync_symbols: &BTreeSet<i32>,
4797 expected: &ExpectedTokens,
4798 ) -> Option<FastRecognizeOutcome> {
4799 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
4800 let token = self.token_at(error_index);
4801 let mut next_index = error_index;
4802 loop {
4803 let symbol = self.token_type_at(next_index);
4804 if sync_symbols.contains(&symbol) {
4805 if next_index == error_index {
4806 return None;
4807 }
4808 break;
4809 }
4810 if symbol == TOKEN_EOF {
4811 break;
4812 }
4813 let after = self.consume_index(next_index, symbol);
4814 if after == next_index {
4815 break;
4816 }
4817 next_index = after;
4818 }
4819 let mut diagnostics = FastDiagnostics::new();
4820 diagnostics.insert(0, diagnostic_for_token(token.as_ref(), message));
4821 let mut nodes = NodeList::new();
4822 if self.fast_token_nodes_enabled {
4823 nodes.prepend(Rc::new(FastRecognizedNode::ErrorToken {
4824 index: error_index,
4825 }));
4826 }
4827 Some(FastRecognizeOutcome {
4828 index: next_index,
4829 consumed_eof: false,
4830 diagnostics,
4831 nodes,
4832 })
4833 }
4834
4835 fn fast_child_rule_failure_recovery_outcomes(
4838 &mut self,
4839 request: FastChildRuleFailureRecoveryRequest<'_>,
4840 ) -> Vec<FastRecognizeOutcome> {
4841 let FastChildRuleFailureRecoveryRequest {
4842 atn,
4843 rule_index,
4844 start_index,
4845 follow_state,
4846 stop_state,
4847 expected,
4848 } = request;
4849 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
4850 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
4851 .into_iter()
4852 .collect()
4853 }
4854
4855 #[allow(clippy::too_many_lines)]
4858 fn recognize_state_fast(
4859 &mut self,
4860 atn: &Atn,
4861 request: FastRecognizeRequest,
4862 visiting: &mut FxHashSet<(usize, usize)>,
4863 memo: &mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4864 expected: &mut ExpectedTokens,
4865 ) -> Vec<FastRecognizeOutcome> {
4866 #[cfg(feature = "perf-counters")]
4867 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
4868 let FastRecognizeRequest {
4869 mut state_number,
4870 stop_state,
4871 mut index,
4872 rule_start_index,
4873 decision_start_index,
4874 precedence,
4875 mut depth,
4876 recovery_symbols,
4877 recovery_state,
4878 } = request;
4879 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
4898 let mut inline_consumed_eof = false;
4899 loop {
4900 if depth > RECOGNITION_DEPTH_LIMIT {
4901 return Vec::new();
4902 }
4903 if state_number == stop_state {
4904 let mut nodes = NodeList::new();
4905 if self.fast_token_nodes_enabled {
4906 for token_index in inline_consumed_tokens.iter().rev() {
4907 nodes.prepend(Rc::new(FastRecognizedNode::Token {
4908 index: *token_index,
4909 }));
4910 }
4911 }
4912 return vec![FastRecognizeOutcome {
4913 index,
4914 consumed_eof: inline_consumed_eof,
4915 diagnostics: FastDiagnostics::new(),
4916 nodes,
4917 }];
4918 }
4919 let Some(state) = atn.state(state_number) else {
4920 return Vec::new();
4921 };
4922 if state.transitions.len() == 1
4923 && !starts_prediction_decision(state)
4924 && !state.precedence_rule_decision
4925 {
4926 match &state.transitions[0] {
4927 Transition::Epsilon { target }
4928 | Transition::Predicate { target, .. }
4929 | Transition::Action { target, .. }
4930 if left_recursive_boundary(atn, state, *target).is_none() =>
4931 {
4932 #[cfg(feature = "perf-counters")]
4933 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
4934 state_number = *target;
4935 depth += 1;
4936 continue;
4937 }
4938 Transition::Precedence {
4939 target,
4940 precedence: transition_precedence,
4941 } if *transition_precedence >= precedence
4942 && left_recursive_boundary(atn, state, *target).is_none() =>
4943 {
4944 #[cfg(feature = "perf-counters")]
4945 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
4946 state_number = *target;
4947 depth += 1;
4948 continue;
4949 }
4950 Transition::Atom { target, .. }
4960 | Transition::Range { target, .. }
4961 | Transition::Set { target, .. }
4962 | Transition::NotSet { target, .. }
4963 | Transition::Wildcard { target, .. }
4964 if !self.fast_recovery_enabled =>
4965 {
4966 let symbol = self.token_type_at(index);
4967 let transition = &state.transitions[0];
4968 if transition.matches(symbol, 1, atn.max_token_type()) {
4969 #[cfg(feature = "perf-counters")]
4970 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
4971 if self.fast_token_nodes_enabled {
4972 inline_consumed_tokens.push(index);
4973 }
4974 inline_consumed_eof |= symbol == TOKEN_EOF;
4975 index = self.consume_index(index, symbol);
4976 state_number = *target;
4977 depth += 1;
4978 continue;
4979 }
4980 }
4983 _ => {}
4984 }
4985 }
4986 break;
4987 }
4988 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
4992 let Some(state) = atn.state(state_number) else {
4993 return Vec::new();
4994 };
4995 let transition_count = state.transitions.len();
4996 let memo_lookup_enabled = self.fast_recovery_enabled || transition_count > 1;
4997 let key = if self.fast_recovery_enabled {
5007 FastRecognizeKey {
5008 state_number,
5009 stop_state,
5010 index,
5011 rule_start_index,
5012 decision_start_index,
5013 precedence,
5014 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
5015 recovery_state,
5016 }
5017 } else {
5018 FastRecognizeKey {
5019 state_number,
5020 stop_state,
5021 index,
5022 rule_start_index: 0,
5023 decision_start_index: None,
5024 precedence,
5025 recovery_symbols_id: 0,
5026 recovery_state: None,
5027 }
5028 };
5029 if memo_lookup_enabled {
5030 if let Some(outcomes) = memo.get(&key) {
5031 #[cfg(feature = "perf-counters")]
5032 {
5033 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
5034 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
5035 }
5036 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
5040 let inline_eof = inline_consumed_eof;
5041 let inline_tokens = &inline_consumed_tokens;
5042 return outcomes
5043 .iter()
5044 .cloned()
5045 .map(|mut outcome| {
5046 if inline_eof {
5047 outcome.consumed_eof = true;
5048 }
5049 if self.fast_token_nodes_enabled {
5050 for token_index in inline_tokens.iter().rev() {
5051 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
5052 index: *token_index,
5053 }));
5054 }
5055 }
5056 outcome
5057 })
5058 .collect();
5059 }
5060 return outcomes.to_vec();
5061 }
5062 #[cfg(feature = "perf-counters")]
5063 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
5064 }
5065
5066 let needs_cycle_guard =
5074 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number);
5075 #[cfg(feature = "perf-counters")]
5076 if needs_cycle_guard {
5077 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
5078 } else {
5079 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
5080 match &state.transitions[0] {
5081 Transition::Rule { .. } => {
5082 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
5083 }
5084 Transition::Atom { .. }
5085 | Transition::Range { .. }
5086 | Transition::Set { .. }
5087 | Transition::NotSet { .. }
5088 | Transition::Wildcard { .. } => {
5089 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
5090 }
5091 _ => {
5092 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
5093 }
5094 }
5095 }
5096 let visit_id = (state_number, index);
5097 if needs_cycle_guard && !visiting.insert(visit_id) {
5098 #[cfg(feature = "perf-counters")]
5099 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
5100 return Vec::new();
5101 }
5102 let next_decision_start_index = if starts_prediction_decision(state) {
5103 Some(index)
5104 } else {
5105 decision_start_index
5106 };
5107 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
5108 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
5109 } else {
5110 (Rc::clone(&recovery_symbols), recovery_state)
5111 };
5112
5113 let transition_count = state.transitions.len();
5132 let lookahead_filter = if transition_count > 1
5133 && self.fast_first_set_prefilter
5134 && !state.precedence_rule_decision
5135 && (!self.fast_recovery_enabled || state.kind != AtnStateKind::RuleStart)
5136 {
5137 state
5138 .rule_index
5139 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index).copied())
5140 .map(|rule_stop| {
5141 let symbol = self.token_type_at(index);
5142 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
5143 (symbol, entry)
5144 })
5145 } else {
5146 None
5147 };
5148 let ll1_only_alt: Option<usize> = if transition_count > 1
5157 && let Some((symbol, entry)) = lookahead_filter.as_ref()
5158 {
5159 let key = (state.state_number, *symbol);
5160 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
5161 cached
5162 } else {
5163 let result = ll1_unique_alt(entry, *symbol);
5164 self.ll1_decision_cache.insert(key, result);
5165 result
5166 }
5167 } else {
5168 None
5169 };
5170 let lookahead_filter = lookahead_filter.as_ref();
5171 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
5177 for (transition_index, transition) in state.transitions.iter().enumerate() {
5178 if let Some(alt) = ll1_only_alt {
5179 if alt != transition_index {
5181 continue;
5182 }
5183 } else if should_skip_via_lookahead(
5184 transition,
5185 transition_index,
5186 lookahead_filter,
5187 index,
5188 self.fast_recovery_enabled,
5189 expected,
5190 ) {
5191 continue;
5192 }
5193 match transition {
5194 Transition::Epsilon { target }
5195 | Transition::Predicate { target, .. }
5196 | Transition::Action { target, .. } => {
5197 #[cfg(feature = "perf-counters")]
5198 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
5199 let boundary = left_recursive_boundary(atn, state, *target);
5200 outcomes.extend(
5201 self.recognize_state_fast(
5202 atn,
5203 FastRecognizeRequest {
5204 state_number: *target,
5205 stop_state,
5206 index,
5207 rule_start_index,
5208 decision_start_index: next_decision_start_index,
5209 precedence,
5210 depth: depth + 1,
5211 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
5212 recovery_state: epsilon_recovery_state,
5213 },
5214 visiting,
5215 memo,
5216 expected,
5217 )
5218 .into_iter()
5219 .map(|mut outcome| {
5220 if let Some(rule_index) = boundary {
5221 outcome.nodes.prepend(Rc::new(
5222 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
5223 ));
5224 }
5225 outcome
5226 }),
5227 );
5228 }
5229 Transition::Precedence {
5230 target,
5231 precedence: transition_precedence,
5232 } => {
5233 if *transition_precedence >= precedence {
5234 let boundary = left_recursive_boundary(atn, state, *target);
5235 outcomes.extend(
5236 self.recognize_state_fast(
5237 atn,
5238 FastRecognizeRequest {
5239 state_number: *target,
5240 stop_state,
5241 index,
5242 rule_start_index,
5243 decision_start_index: next_decision_start_index,
5244 precedence,
5245 depth: depth + 1,
5246 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
5247 recovery_state: epsilon_recovery_state,
5248 },
5249 visiting,
5250 memo,
5251 expected,
5252 )
5253 .into_iter()
5254 .map(|mut outcome| {
5255 if let Some(rule_index) = boundary {
5256 outcome.nodes.prepend(Rc::new(
5257 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
5258 ));
5259 }
5260 outcome
5261 }),
5262 );
5263 }
5264 }
5265 Transition::Rule {
5266 target,
5267 rule_index,
5268 follow_state,
5269 precedence: rule_precedence,
5270 ..
5271 } => {
5272 #[cfg(feature = "perf-counters")]
5273 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
5274 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
5275 else {
5276 continue;
5277 };
5278 let symbol = self.token_type_at(index);
5290 if self.fast_first_set_prefilter {
5291 let first = self.cached_rule_first_set(atn, *target, child_stop);
5304 if should_skip_rule_via_first_set(
5305 &first,
5306 symbol,
5307 self.fast_recovery_enabled,
5308 index,
5309 expected,
5310 ) {
5311 continue;
5312 }
5313 }
5314 let expected_before_child =
5315 self.fast_recovery_enabled.then(|| expected.clone());
5316 let mut children = self.recognize_state_fast(
5317 atn,
5318 FastRecognizeRequest {
5319 state_number: *target,
5320 stop_state: child_stop,
5321 index,
5322 rule_start_index: index,
5323 decision_start_index: None,
5324 precedence: *rule_precedence,
5325 depth: depth + 1,
5326 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
5327 recovery_state: epsilon_recovery_state,
5328 },
5329 visiting,
5330 memo,
5331 expected,
5332 );
5333 if children.is_empty() && self.fast_recovery_enabled {
5334 children = self.fast_child_rule_failure_recovery_outcomes(
5335 FastChildRuleFailureRecoveryRequest {
5336 atn,
5337 rule_index: *rule_index,
5338 start_index: index,
5339 follow_state: *follow_state,
5340 stop_state,
5341 expected,
5342 },
5343 );
5344 }
5345 if let Some(expected_before_child) = expected_before_child {
5346 if children
5347 .iter()
5348 .any(|child| child.diagnostics.is_empty() && child.index > index)
5349 {
5350 *expected = expected_before_child;
5351 }
5352 }
5353 for child in children {
5354 let child_index = child.index;
5355 let child_consumed_eof = child.consumed_eof;
5356 let child_diagnostics = child.diagnostics;
5357 let empty_recovery = self.empty_recovery_symbols();
5358 let follow_outcomes = self.recognize_state_fast(
5359 atn,
5360 FastRecognizeRequest {
5361 state_number: *follow_state,
5362 stop_state,
5363 index: child_index,
5364 rule_start_index,
5365 decision_start_index: next_decision_start_index,
5366 precedence,
5367 depth: depth + 1,
5368 recovery_symbols: empty_recovery,
5369 recovery_state: None,
5370 },
5371 visiting,
5372 memo,
5373 expected,
5374 );
5375 if follow_outcomes.is_empty() {
5376 continue;
5377 }
5378 let child_node = Rc::new(FastRecognizedNode::Rule {
5379 rule_index: *rule_index,
5380 invoking_state: invoking_state_number(state_number),
5381 start_index: index,
5382 stop_index: self.rule_stop_token_index(child_index, child_consumed_eof),
5383 children: child.nodes,
5384 });
5385 let child_diags_empty = child_diagnostics.is_empty();
5386 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
5387 outcome.consumed_eof |= child_consumed_eof;
5388 if !child_diags_empty {
5391 let mut diagnostics = child_diagnostics.clone();
5392 diagnostics.append(&mut outcome.diagnostics);
5393 outcome.diagnostics = diagnostics;
5394 }
5395 outcome.nodes.prepend(Rc::clone(&child_node));
5396 outcome
5397 }));
5398 }
5399 }
5400 Transition::Atom { target, .. }
5401 | Transition::Range { target, .. }
5402 | Transition::Set { target, .. }
5403 | Transition::NotSet { target, .. }
5404 | Transition::Wildcard { target, .. } => {
5405 #[cfg(feature = "perf-counters")]
5406 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
5407 let symbol = self.token_type_at(index);
5408 if transition.matches(symbol, 1, atn.max_token_type()) {
5409 let next_index = self.consume_index(index, symbol);
5410 let empty_recovery = self.empty_recovery_symbols();
5411 outcomes.extend(
5412 self.recognize_state_fast(
5413 atn,
5414 FastRecognizeRequest {
5415 state_number: *target,
5416 stop_state,
5417 index: next_index,
5418 rule_start_index,
5419 decision_start_index: next_decision_start_index,
5420 precedence,
5421 depth: depth + 1,
5422 recovery_symbols: empty_recovery,
5423 recovery_state: None,
5424 },
5425 visiting,
5426 memo,
5427 expected,
5428 )
5429 .into_iter()
5430 .map(|mut outcome| {
5431 outcome.consumed_eof |= symbol == TOKEN_EOF;
5432 if self.fast_token_nodes_enabled {
5433 outcome
5434 .nodes
5435 .prepend(Rc::new(FastRecognizedNode::Token { index }));
5436 }
5437 outcome
5438 }),
5439 );
5440 } else {
5441 if !self.fast_recovery_enabled {
5442 continue;
5450 }
5451 let expected_symbols = fast_recovery_expected_symbols(
5452 self,
5453 atn,
5454 state.state_number,
5455 &recovery_symbols,
5456 );
5457 if expected_symbols.contains(&symbol) {
5458 continue;
5459 }
5460 {
5461 expected.record_transition(index, transition, atn.max_token_type());
5462 record_no_viable_if_ambiguous(
5463 expected,
5464 next_decision_start_index,
5465 index,
5466 );
5467 outcomes.extend(self.fast_single_token_deletion_recovery(
5468 FastRecoveryRequest {
5469 atn,
5470 transition,
5471 expected_symbols: Rc::clone(&expected_symbols),
5472 target: *target,
5473 request: FastRecognizeRequest {
5474 state_number,
5475 stop_state,
5476 index,
5477 rule_start_index,
5478 decision_start_index,
5479 precedence,
5480 depth,
5481 recovery_symbols: Rc::clone(&recovery_symbols),
5482 recovery_state,
5483 },
5484 visiting,
5485 memo,
5486 expected,
5487 },
5488 ));
5489 if !state_is_left_recursive_rule(atn, state) {
5490 outcomes.extend(self.fast_single_token_insertion_recovery(
5491 FastRecoveryRequest {
5492 atn,
5493 transition,
5494 expected_symbols: Rc::clone(&expected_symbols),
5495 target: *target,
5496 request: FastRecognizeRequest {
5497 state_number,
5498 stop_state,
5499 index,
5500 rule_start_index,
5501 decision_start_index,
5502 precedence,
5503 depth,
5504 recovery_symbols: Rc::clone(&recovery_symbols),
5505 recovery_state,
5506 },
5507 visiting,
5508 memo,
5509 expected,
5510 },
5511 ));
5512 }
5513 outcomes.extend(self.fast_current_token_deletion_recovery(
5514 FastCurrentTokenDeletionRequest {
5515 atn,
5516 expected_symbols,
5517 request: FastRecognizeRequest {
5518 state_number,
5519 stop_state,
5520 index,
5521 rule_start_index,
5522 decision_start_index,
5523 precedence,
5524 depth,
5525 recovery_symbols: Rc::clone(&recovery_symbols),
5526 recovery_state,
5527 },
5528 visiting,
5529 memo,
5530 expected,
5531 },
5532 ));
5533 }
5534 }
5535 }
5536 }
5537 }
5538
5539 if needs_cycle_guard {
5540 visiting.remove(&visit_id);
5541 }
5542 if matches!(
5543 self.prediction_mode,
5544 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
5545 ) && self.fast_recovery_enabled
5546 {
5547 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
5551 }
5552 if self.fast_recovery_enabled {
5553 dedupe_fast_outcomes(&mut outcomes);
5554 } else {
5555 dedupe_clean_fast_outcomes(&mut outcomes);
5556 }
5557 let should_memoize = self.fast_recovery_enabled
5567 || (transition_count > 1
5568 && (outcomes.is_empty()
5569 || outcomes.len() > 1
5570 || (outcomes.len() == 1 && self.should_memoize_single_outcome(&key))));
5571 let apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
5575 if inline_consumed_eof {
5576 outcome.consumed_eof = true;
5577 }
5578 if !inline_consumed_tokens.is_empty() {
5579 for token_index in inline_consumed_tokens.iter().rev() {
5580 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
5581 index: *token_index,
5582 }));
5583 }
5584 }
5585 outcome
5586 };
5587 if should_memoize {
5588 #[cfg(feature = "perf-counters")]
5589 {
5590 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
5591 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
5592 match outcomes.len() {
5593 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
5594 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
5595 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
5596 }
5597 }
5598 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
5603 memo.insert(key, Rc::clone(&stored));
5604 if inline_pending {
5605 return stored.iter().cloned().map(apply_inline_pending).collect();
5606 }
5607 return stored.to_vec();
5608 }
5609 #[cfg(feature = "perf-counters")]
5610 match outcomes.len() {
5611 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
5612 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
5613 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
5614 }
5615 if inline_pending {
5616 return outcomes.into_iter().map(apply_inline_pending).collect();
5617 }
5618 outcomes
5619 }
5620
5621 fn single_token_deletion_recovery(
5624 &mut self,
5625 recovery: RecoveryRequest<'_, '_>,
5626 ) -> Vec<RecognizeOutcome> {
5627 let RecoveryRequest {
5628 atn,
5629 transition,
5630 expected_symbols,
5631 target,
5632 request,
5633 visiting,
5634 memo,
5635 expected,
5636 } = recovery;
5637 let RecognizeRequest {
5638 stop_state,
5639 index,
5640 rule_start_index,
5641 decision_start_index,
5642 init_action_rules,
5643 predicates,
5644 rule_args,
5645 member_actions,
5646 return_actions,
5647 local_int_arg,
5648 member_values,
5649 return_values,
5650 rule_alt_number,
5651 track_alt_numbers,
5652 consumed_eof,
5653 precedence,
5654 depth,
5655 ..
5656 } = request;
5657 let Some((diagnostic, next_index, next_symbol)) =
5658 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
5659 else {
5660 return Vec::new();
5661 };
5662 let after_next = self.consume_index(next_index, next_symbol);
5663 self.recognize_state(
5664 atn,
5665 RecognizeRequest {
5666 state_number: target,
5667 stop_state,
5668 index: after_next,
5669 rule_start_index,
5670 decision_start_index,
5671 init_action_rules,
5672 predicates,
5673 rule_args,
5674 member_actions,
5675 return_actions,
5676 local_int_arg,
5677 member_values,
5678 return_values,
5679 rule_alt_number,
5680 track_alt_numbers,
5681 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
5682 precedence,
5683 depth: depth + 1,
5684 recovery_symbols: BTreeSet::new(),
5685 recovery_state: None,
5686 },
5687 visiting,
5688 memo,
5689 expected,
5690 )
5691 .into_iter()
5692 .map(|mut outcome| {
5693 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
5694 outcome.diagnostics.insert(0, diagnostic.clone());
5695 outcome
5696 .nodes
5697 .insert(0, RecognizedNode::Token { index: next_index });
5698 outcome
5699 .nodes
5700 .insert(0, RecognizedNode::ErrorToken { index });
5701 outcome
5702 })
5703 .collect()
5704 }
5705
5706 fn current_token_deletion_recovery(
5709 &mut self,
5710 recovery: CurrentTokenDeletionRequest<'_, '_>,
5711 ) -> Vec<RecognizeOutcome> {
5712 let CurrentTokenDeletionRequest {
5713 atn,
5714 expected_symbols,
5715 mut request,
5716 visiting,
5717 memo,
5718 expected,
5719 } = recovery;
5720 let error_index = request.index;
5721 if error_index == request.rule_start_index {
5722 return Vec::new();
5723 }
5724 let Some((diagnostic, next_index, skipped)) =
5725 self.current_token_deletion(error_index, &expected_symbols)
5726 else {
5727 return Vec::new();
5728 };
5729 request.state_number = request.recovery_state.unwrap_or(request.state_number);
5730 request.index = next_index;
5731 request.depth += 1;
5732 request.recovery_state = None;
5733 self.recognize_state(atn, request, visiting, memo, expected)
5734 .into_iter()
5735 .map(|mut outcome| {
5736 outcome.diagnostics.insert(0, diagnostic.clone());
5737 for index in skipped.iter().rev() {
5738 outcome
5739 .nodes
5740 .insert(0, RecognizedNode::ErrorToken { index: *index });
5741 }
5742 outcome
5743 })
5744 .collect()
5745 }
5746
5747 fn consuming_failure_fallback(
5750 &mut self,
5751 fallback: ConsumingFailureFallback<'_>,
5752 visiting: &mut BTreeSet<RecognizeKey>,
5753 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
5754 expected: &mut ExpectedTokens,
5755 ) -> Vec<RecognizeOutcome> {
5756 if fallback.expected_symbols.is_empty() {
5757 return Vec::new();
5758 }
5759 if fallback.symbol == TOKEN_EOF {
5760 return self.eof_consuming_failure_fallback(fallback, expected);
5761 }
5762 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
5763 }
5764
5765 fn non_eof_consuming_failure_fallback(
5768 &mut self,
5769 fallback: ConsumingFailureFallback<'_>,
5770 visiting: &mut BTreeSet<RecognizeKey>,
5771 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
5772 expected: &mut ExpectedTokens,
5773 ) -> Vec<RecognizeOutcome> {
5774 let ConsumingFailureFallback {
5775 atn,
5776 target,
5777 request,
5778 symbol,
5779 expected_symbols,
5780 decision_start_index,
5781 decision,
5782 } = fallback;
5783 let error_index = request.index;
5784 let diagnostic =
5785 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
5786 let next_index = self.consume_index(error_index, symbol);
5787 self.recognize_state(
5788 atn,
5789 RecognizeRequest {
5790 state_number: target,
5791 stop_state: request.stop_state,
5792 index: next_index,
5793 rule_start_index: request.rule_start_index,
5794 decision_start_index,
5795 init_action_rules: request.init_action_rules,
5796 predicates: request.predicates,
5797 rule_args: request.rule_args,
5798 member_actions: request.member_actions,
5799 return_actions: request.return_actions,
5800 local_int_arg: request.local_int_arg,
5801 member_values: request.member_values,
5802 return_values: request.return_values,
5803 rule_alt_number: request.rule_alt_number,
5804 track_alt_numbers: request.track_alt_numbers,
5805 consumed_eof: request.consumed_eof,
5806 precedence: request.precedence,
5807 depth: request.depth + 1,
5808 recovery_symbols: BTreeSet::new(),
5809 recovery_state: None,
5810 },
5811 visiting,
5812 memo,
5813 expected,
5814 )
5815 .into_iter()
5816 .map(|mut outcome| {
5817 prepend_decision(&mut outcome, decision);
5818 outcome.diagnostics.insert(0, diagnostic.clone());
5819 outcome
5820 .nodes
5821 .insert(0, RecognizedNode::ErrorToken { index: error_index });
5822 outcome
5823 })
5824 .collect()
5825 }
5826
5827 fn eof_consuming_failure_fallback(
5830 &mut self,
5831 fallback: ConsumingFailureFallback<'_>,
5832 expected: &ExpectedTokens,
5833 ) -> Vec<RecognizeOutcome> {
5834 let request = fallback.request;
5835 if request.index == request.rule_start_index {
5836 return Vec::new();
5837 }
5838 let diagnostic =
5839 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
5840 vec![RecognizeOutcome {
5841 index: request.index,
5842 consumed_eof: request.consumed_eof,
5843 alt_number: request.rule_alt_number,
5844 member_values: request.member_values,
5845 return_values: request.return_values,
5846 diagnostics: vec![diagnostic],
5847 decisions: Vec::new(),
5848 actions: Vec::new(),
5849 nodes: Vec::new(),
5850 }]
5851 }
5852
5853 fn single_token_insertion_recovery(
5856 &mut self,
5857 recovery: RecoveryRequest<'_, '_>,
5858 ) -> Vec<RecognizeOutcome> {
5859 let RecoveryRequest {
5860 atn,
5861 transition,
5862 expected_symbols,
5863 target,
5864 request,
5865 visiting,
5866 memo,
5867 expected,
5868 } = recovery;
5869 let RecognizeRequest {
5870 stop_state,
5871 index,
5872 rule_start_index,
5873 decision_start_index,
5874 init_action_rules,
5875 predicates,
5876 rule_args,
5877 member_actions,
5878 return_actions,
5879 local_int_arg,
5880 member_values,
5881 return_values,
5882 rule_alt_number,
5883 track_alt_numbers,
5884 consumed_eof,
5885 precedence,
5886 depth,
5887 ..
5888 } = request;
5889 let follow_symbols = state_expected_symbols(atn, transition.target());
5890 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
5891 transition,
5892 index,
5893 atn.max_token_type(),
5894 &expected_symbols,
5895 &follow_symbols,
5896 ) else {
5897 return Vec::new();
5898 };
5899 self.recognize_state(
5900 atn,
5901 RecognizeRequest {
5902 state_number: target,
5903 stop_state,
5904 index,
5905 rule_start_index,
5906 decision_start_index,
5907 init_action_rules,
5908 predicates,
5909 rule_args,
5910 member_actions,
5911 return_actions,
5912 local_int_arg,
5913 member_values,
5914 return_values,
5915 rule_alt_number,
5916 track_alt_numbers,
5917 consumed_eof,
5918 precedence,
5919 depth: depth + 1,
5920 recovery_symbols: BTreeSet::new(),
5921 recovery_state: None,
5922 },
5923 visiting,
5924 memo,
5925 expected,
5926 )
5927 .into_iter()
5928 .map(|mut outcome| {
5929 outcome.diagnostics.insert(0, diagnostic.clone());
5930 outcome.nodes.insert(
5931 0,
5932 RecognizedNode::MissingToken {
5933 token_type,
5934 at_index: index,
5935 text: text.clone(),
5936 },
5937 );
5938 outcome
5939 })
5940 .collect()
5941 }
5942
5943 #[allow(clippy::too_many_lines)]
5946 fn recognize_state(
5947 &mut self,
5948 atn: &Atn,
5949 request: RecognizeRequest<'_>,
5950 visiting: &mut BTreeSet<RecognizeKey>,
5951 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
5952 expected: &mut ExpectedTokens,
5953 ) -> Vec<RecognizeOutcome> {
5954 let request_template = request.clone();
5955 let RecognizeRequest {
5956 state_number,
5957 stop_state,
5958 index,
5959 rule_start_index,
5960 decision_start_index,
5961 init_action_rules,
5962 predicates,
5963 rule_args,
5964 member_actions,
5965 return_actions,
5966 local_int_arg,
5967 member_values,
5968 return_values,
5969 rule_alt_number,
5970 track_alt_numbers,
5971 consumed_eof,
5972 precedence,
5973 depth,
5974 recovery_symbols,
5975 recovery_state,
5976 } = request;
5977 if depth > RECOGNITION_DEPTH_LIMIT {
5978 return Vec::new();
5979 }
5980 if state_number == stop_state {
5981 return stop_outcome(
5982 index,
5983 consumed_eof,
5984 rule_alt_number,
5985 member_values,
5986 return_values,
5987 );
5988 }
5989 let key = RecognizeKey {
5990 state_number,
5991 stop_state,
5992 index,
5993 rule_start_index,
5994 decision_start_index,
5995 local_int_arg,
5996 member_values: member_values.clone(),
5997 return_values: return_values.clone(),
5998 rule_alt_number,
5999 track_alt_numbers,
6000 consumed_eof,
6001 precedence,
6002 recovery_symbols: recovery_symbols.clone(),
6003 recovery_state,
6004 };
6005 if let Some(outcomes) = memo.get(&key) {
6006 return outcomes.clone();
6007 }
6008
6009 let visit_key = key.clone();
6010 if !visiting.insert(visit_key.clone()) {
6011 return Vec::new();
6012 }
6013
6014 let Some(state) = atn.state(state_number) else {
6015 visiting.remove(&visit_key);
6016 return Vec::new();
6017 };
6018 let next_decision_start_index = if starts_prediction_decision(state) {
6019 Some(index)
6020 } else {
6021 decision_start_index
6022 };
6023 let (epsilon_recovery_symbols, epsilon_recovery_state) =
6024 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
6025 let mut outcomes = Vec::new();
6026 for (transition_index, transition) in state.transitions.iter().enumerate() {
6027 let decision = transition_decision(atn, state, transition_index, predicates);
6028 let next_alt_number =
6029 next_alt_number(state, transition_index, rule_alt_number, track_alt_numbers);
6030 match transition {
6031 Transition::Epsilon { target } | Transition::Action { target, .. } => {
6032 let action_rule_index = match transition {
6033 Transition::Action { rule_index, .. } => Some(*rule_index),
6034 _ => None,
6035 };
6036 outcomes.extend(self.recognize_epsilon_or_action_step(
6037 atn,
6038 &request_template,
6039 EpsilonActionStep {
6040 source_state: state_number,
6041 target: *target,
6042 action_rule_index,
6043 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
6044 decision,
6045 decision_start_index: next_decision_start_index,
6046 alt_number: next_alt_number,
6047 recovery_symbols: epsilon_recovery_symbols.clone(),
6048 recovery_state: epsilon_recovery_state,
6049 },
6050 RecognizeScratch {
6051 visiting,
6052 memo,
6053 expected,
6054 },
6055 ));
6056 }
6057 Transition::Predicate {
6058 target,
6059 rule_index,
6060 pred_index,
6061 ..
6062 } => {
6063 let predicate = PredicateEval {
6064 index,
6065 rule_index: *rule_index,
6066 pred_index: *pred_index,
6067 predicates,
6068 context: None,
6069 local_int_arg,
6070 member_values: &member_values,
6071 };
6072 if self.parser_predicate_matches(predicate) {
6073 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
6074 outcomes.extend(
6075 self.recognize_state(
6076 atn,
6077 RecognizeRequest {
6078 state_number: *target,
6079 stop_state,
6080 index,
6081 rule_start_index,
6082 decision_start_index: next_decision_start_index,
6083 init_action_rules,
6084 predicates,
6085 rule_args,
6086 member_actions,
6087 return_actions,
6088 local_int_arg,
6089 member_values: member_values.clone(),
6090 return_values: return_values.clone(),
6091 rule_alt_number: next_alt_number,
6092 track_alt_numbers,
6093 consumed_eof,
6094 precedence,
6095 depth: depth + 1,
6096 recovery_symbols: epsilon_recovery_symbols.clone(),
6097 recovery_state: epsilon_recovery_state,
6098 },
6099 visiting,
6100 memo,
6101 expected,
6102 )
6103 .into_iter()
6104 .map(|mut outcome| {
6105 prepend_decision(&mut outcome, decision);
6106 if let Some(rule_index) = left_recursive_boundary {
6107 outcome.nodes.insert(
6108 0,
6109 RecognizedNode::LeftRecursiveBoundary { rule_index },
6110 );
6111 }
6112 outcome
6113 }),
6114 );
6115 } else if let Some(message) =
6116 self.parser_predicate_failure_message(*rule_index, *pred_index, predicates)
6117 {
6118 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
6119 rule_index: *rule_index,
6120 index,
6121 message,
6122 member_values: member_values.clone(),
6123 return_values: return_values.clone(),
6124 rule_alt_number,
6125 }));
6126 } else {
6127 record_predicate_no_viable(expected, next_decision_start_index, index);
6128 }
6129 }
6130 Transition::Precedence {
6131 target,
6132 precedence: transition_precedence,
6133 } => {
6134 if *transition_precedence >= precedence {
6135 outcomes.extend(
6136 self.recognize_state(
6137 atn,
6138 RecognizeRequest {
6139 state_number: *target,
6140 stop_state,
6141 index,
6142 rule_start_index,
6143 decision_start_index: next_decision_start_index,
6144 init_action_rules,
6145 predicates,
6146 rule_args,
6147 member_actions,
6148 return_actions,
6149 local_int_arg,
6150 member_values: member_values.clone(),
6151 return_values: return_values.clone(),
6152 rule_alt_number: next_alt_number,
6153 track_alt_numbers,
6154 consumed_eof,
6155 precedence,
6156 depth: depth + 1,
6157 recovery_symbols: epsilon_recovery_symbols.clone(),
6158 recovery_state: epsilon_recovery_state,
6159 },
6160 visiting,
6161 memo,
6162 expected,
6163 )
6164 .into_iter()
6165 .map(|mut outcome| {
6166 prepend_decision(&mut outcome, decision);
6167 outcome
6168 }),
6169 );
6170 }
6171 }
6172 Transition::Rule {
6173 target,
6174 rule_index,
6175 follow_state,
6176 precedence: rule_precedence,
6177 ..
6178 } => {
6179 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
6180 else {
6181 continue;
6182 };
6183 let child_local_int_arg =
6184 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
6185 let expected_before_child = expected.clone();
6186 let children = self.recognize_state(
6187 atn,
6188 RecognizeRequest {
6189 state_number: *target,
6190 stop_state: child_stop,
6191 index,
6192 rule_start_index: index,
6193 decision_start_index: None,
6194 init_action_rules,
6195 predicates,
6196 rule_args,
6197 member_actions,
6198 return_actions,
6199 local_int_arg: child_local_int_arg,
6200 member_values: member_values.clone(),
6201 return_values: BTreeMap::new(),
6202 rule_alt_number: 0,
6203 track_alt_numbers,
6204 consumed_eof: false,
6205 precedence: *rule_precedence,
6206 depth: depth + 1,
6207 recovery_symbols: epsilon_recovery_symbols.clone(),
6208 recovery_state: epsilon_recovery_state,
6209 },
6210 visiting,
6211 memo,
6212 expected,
6213 );
6214 let children = if children.is_empty() {
6215 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
6216 atn,
6217 rule_index: *rule_index,
6218 start_index: index,
6219 follow_state: *follow_state,
6220 stop_state,
6221 member_values: member_values.clone(),
6222 expected,
6223 })
6224 } else {
6225 children
6226 };
6227 let preserve_child_expected =
6228 self.child_expected_reaches_clean_eof(&children, expected);
6229 restore_expected(
6230 &children,
6231 index,
6232 expected,
6233 expected_before_child,
6234 preserve_child_expected,
6235 );
6236 for child in children {
6237 let child_node = RecognizedNode::Rule {
6238 rule_index: *rule_index,
6239 invoking_state: invoking_state_number(state_number),
6240 alt_number: child.alt_number,
6241 start_index: index,
6242 stop_index: self.rule_stop_token_index(child.index, child.consumed_eof),
6243 return_values: child.return_values.clone(),
6244 children: fold_left_recursive_boundaries(child.nodes.clone()),
6245 };
6246 outcomes.extend(
6247 self.recognize_state(
6248 atn,
6249 RecognizeRequest {
6250 state_number: *follow_state,
6251 stop_state,
6252 index: child.index,
6253 rule_start_index,
6254 decision_start_index: next_decision_start_index,
6255 init_action_rules,
6256 predicates,
6257 rule_args,
6258 member_actions,
6259 return_actions,
6260 local_int_arg,
6261 member_values: child.member_values.clone(),
6262 return_values: return_values.clone(),
6263 rule_alt_number,
6264 track_alt_numbers,
6265 consumed_eof: consumed_eof || child.consumed_eof,
6266 precedence,
6267 depth: depth + 1,
6268 recovery_symbols: BTreeSet::new(),
6269 recovery_state: None,
6270 },
6271 visiting,
6272 memo,
6273 expected,
6274 )
6275 .into_iter()
6276 .map(|mut outcome| {
6277 outcome.consumed_eof |= child.consumed_eof;
6278 let mut diagnostics = child.diagnostics.clone();
6279 diagnostics.append(&mut outcome.diagnostics);
6280 outcome.diagnostics = diagnostics;
6281 let mut decisions = child.decisions.clone();
6282 decisions.append(&mut outcome.decisions);
6283 outcome.decisions = decisions;
6284 prepend_decision(&mut outcome, decision);
6285 let mut actions = child.actions.clone();
6286 if init_action_rules.contains(rule_index) {
6287 actions.insert(
6288 0,
6289 ParserAction::new_rule_init(
6290 *rule_index,
6291 index,
6292 Some(*follow_state),
6293 ),
6294 );
6295 }
6296 actions.append(&mut outcome.actions);
6297 outcome.actions = actions;
6298 outcome.nodes.insert(0, child_node.clone());
6299 outcome
6300 }),
6301 );
6302 }
6303 }
6304 Transition::Atom { target, .. }
6305 | Transition::Range { target, .. }
6306 | Transition::Set { target, .. }
6307 | Transition::NotSet { target, .. }
6308 | Transition::Wildcard { target, .. } => {
6309 let symbol = self.token_type_at(index);
6310 if transition.matches(symbol, 1, atn.max_token_type()) {
6311 let next_index = self.consume_index(index, symbol);
6312 outcomes.extend(
6313 self.recognize_state(
6314 atn,
6315 RecognizeRequest {
6316 state_number: *target,
6317 stop_state,
6318 index: next_index,
6319 rule_start_index,
6320 decision_start_index: next_decision_start_index,
6321 init_action_rules,
6322 predicates,
6323 rule_args,
6324 member_actions,
6325 return_actions,
6326 local_int_arg,
6327 member_values: member_values.clone(),
6328 return_values: return_values.clone(),
6329 rule_alt_number: next_alt_number,
6330 track_alt_numbers,
6331 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
6332 precedence,
6333 depth: depth + 1,
6334 recovery_symbols: BTreeSet::new(),
6335 recovery_state: None,
6336 },
6337 visiting,
6338 memo,
6339 expected,
6340 )
6341 .into_iter()
6342 .map(|mut outcome| {
6343 prepend_decision(&mut outcome, decision);
6344 outcome.consumed_eof |= symbol == TOKEN_EOF;
6345 outcome.nodes.insert(0, RecognizedNode::Token { index });
6346 outcome
6347 }),
6348 );
6349 } else {
6350 let expected_symbols =
6351 recovery_expected_symbols(atn, state.state_number, &recovery_symbols);
6352 if expected_symbols.contains(&symbol) {
6353 continue;
6354 }
6355 expected.record_transition(index, transition, atn.max_token_type());
6356 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
6357 let before_recovery = outcomes.len();
6358 let recovery_request = request_template.clone();
6359 outcomes.extend(
6360 self.single_token_deletion_recovery(RecoveryRequest {
6361 atn,
6362 transition,
6363 expected_symbols: expected_symbols.clone(),
6364 target: *target,
6365 request: recovery_request.clone(),
6366 visiting,
6367 memo,
6368 expected,
6369 })
6370 .into_iter()
6371 .map(|mut outcome| {
6372 prepend_decision(&mut outcome, decision);
6373 outcome
6374 }),
6375 );
6376 if !state_is_left_recursive_rule(atn, state) {
6377 outcomes.extend(
6378 self.single_token_insertion_recovery(RecoveryRequest {
6379 atn,
6380 transition,
6381 expected_symbols: expected_symbols.clone(),
6382 target: *target,
6383 request: recovery_request.clone(),
6384 visiting,
6385 memo,
6386 expected,
6387 })
6388 .into_iter()
6389 .map(|mut outcome| {
6390 prepend_decision(&mut outcome, decision);
6391 outcome
6392 }),
6393 );
6394 }
6395 outcomes.extend(self.current_token_deletion_recovery(
6396 CurrentTokenDeletionRequest {
6397 atn,
6398 expected_symbols: expected_symbols.clone(),
6399 request: recovery_request.clone(),
6400 visiting,
6401 memo,
6402 expected,
6403 },
6404 ));
6405 if outcomes.len() == before_recovery {
6406 outcomes.extend(self.consuming_failure_fallback(
6407 ConsumingFailureFallback {
6408 atn,
6409 target: *target,
6410 request: recovery_request,
6411 symbol,
6412 expected_symbols,
6413 decision_start_index: next_decision_start_index,
6414 decision,
6415 },
6416 visiting,
6417 memo,
6418 expected,
6419 ));
6420 }
6421 }
6422 }
6423 }
6424 }
6425
6426 visiting.remove(&visit_key);
6427 self.record_prediction_diagnostics(atn, state, index, &outcomes);
6428 if matches!(
6429 self.prediction_mode,
6430 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
6431 ) {
6432 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes);
6433 }
6434 dedupe_outcomes(&mut outcomes);
6435 memo.insert(key, outcomes.clone());
6436 outcomes
6437 }
6438
6439 fn recognize_epsilon_or_action_step(
6442 &mut self,
6443 atn: &Atn,
6444 request: &RecognizeRequest<'_>,
6445 step: EpsilonActionStep,
6446 scratch: RecognizeScratch<'_>,
6447 ) -> Vec<RecognizeOutcome> {
6448 let RecognizeScratch {
6449 visiting,
6450 memo,
6451 expected,
6452 } = scratch;
6453 let action = step.action_rule_index.map(|rule_index| {
6454 ParserAction::new(
6455 step.source_state,
6456 rule_index,
6457 request.rule_start_index,
6458 self.rule_stop_token_index(request.index, request.consumed_eof),
6459 )
6460 });
6461 let next_member_values = if action.is_some() {
6462 member_values_after_action(
6463 step.source_state,
6464 request.member_actions,
6465 &request.member_values,
6466 )
6467 } else {
6468 request.member_values.clone()
6469 };
6470 let next_return_values = action.map_or_else(
6471 || request.return_values.clone(),
6472 |action| {
6473 return_values_after_action(
6474 step.source_state,
6475 action.rule_index(),
6476 request.return_actions,
6477 &request.return_values,
6478 )
6479 },
6480 );
6481
6482 self.recognize_state(
6483 atn,
6484 RecognizeRequest {
6485 state_number: step.target,
6486 stop_state: request.stop_state,
6487 index: request.index,
6488 rule_start_index: request.rule_start_index,
6489 decision_start_index: step.decision_start_index,
6490 init_action_rules: request.init_action_rules,
6491 predicates: request.predicates,
6492 rule_args: request.rule_args,
6493 member_actions: request.member_actions,
6494 return_actions: request.return_actions,
6495 local_int_arg: request.local_int_arg,
6496 member_values: next_member_values,
6497 return_values: next_return_values,
6498 rule_alt_number: step.alt_number,
6499 track_alt_numbers: request.track_alt_numbers,
6500 consumed_eof: request.consumed_eof,
6501 precedence: request.precedence,
6502 depth: request.depth + 1,
6503 recovery_symbols: step.recovery_symbols,
6504 recovery_state: step.recovery_state,
6505 },
6506 visiting,
6507 memo,
6508 expected,
6509 )
6510 .into_iter()
6511 .map(|mut outcome| {
6512 prepend_decision(&mut outcome, step.decision);
6513 if let Some(rule_index) = step.left_recursive_boundary {
6514 outcome
6515 .nodes
6516 .insert(0, RecognizedNode::LeftRecursiveBoundary { rule_index });
6517 }
6518 if let Some(action) = action {
6519 outcome.actions.insert(0, action);
6520 }
6521 outcome
6522 })
6523 .collect()
6524 }
6525
6526 fn token_type_at(&mut self, index: usize) -> i32 {
6531 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
6532 self.input.fill();
6533 }
6534 self.input.token_type_at_index(index)
6535 }
6536
6537 fn cached_state_expected_symbols(
6549 &mut self,
6550 atn: &Atn,
6551 state_number: usize,
6552 ) -> Rc<BTreeSet<i32>> {
6553 if let Some(cached) = self.state_expected_cache.get(&state_number) {
6554 return Rc::clone(cached);
6555 }
6556 let symbols = state_expected_symbols(atn, state_number);
6557 let entry = self.intern_recovery_symbols(symbols);
6558 self.state_expected_cache
6559 .insert(state_number, Rc::clone(&entry));
6560 entry
6561 }
6562
6563 fn cached_state_expected_token_set(
6564 &mut self,
6565 atn: &Atn,
6566 state_number: usize,
6567 ) -> Rc<TokenBitSet> {
6568 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
6569 return Rc::clone(cached);
6570 }
6571 let symbols = with_shared_atn_caches(atn, |cache| {
6575 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
6576 return Rc::clone(cached);
6577 }
6578 let symbols = Rc::new(state_expected_token_set(atn, state_number));
6579 cache
6580 .state_expected_tokens
6581 .insert(state_number, Rc::clone(&symbols));
6582 symbols
6583 });
6584 self.state_expected_token_cache
6585 .insert(state_number, Rc::clone(&symbols));
6586 symbols
6587 }
6588
6589 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
6590 if self.rule_stop_reach_cache.len() <= state_number {
6591 self.rule_stop_reach_cache
6592 .resize_with(atn.states().len().max(state_number + 1), || None);
6593 }
6594 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
6595 return reaches;
6596 }
6597 let reaches = with_shared_atn_caches(atn, |cache| {
6598 *cache
6599 .rule_stop_reach
6600 .entry(state_number)
6601 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
6602 });
6603 self.rule_stop_reach_cache[state_number] = Some(reaches);
6604 reaches
6605 }
6606
6607 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
6610 Rc::clone(&self.empty_recovery_symbols)
6611 }
6612
6613 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
6622 if set.is_empty() {
6623 return Rc::clone(&self.empty_recovery_symbols);
6624 }
6625 let candidate = Rc::new(set);
6626 match self.recovery_symbols_intern.get(&candidate) {
6627 Some(existing) => Rc::clone(existing),
6628 None => {
6629 self.recovery_symbols_intern
6630 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
6631 candidate
6632 }
6633 }
6634 }
6635
6636 fn cached_decision_lookahead(
6641 &mut self,
6642 atn: &Atn,
6643 state: &AtnState,
6644 rule_stop_state: usize,
6645 ) -> Rc<DecisionLookahead> {
6646 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number) {
6653 return Rc::clone(cached);
6654 }
6655 let entry = with_shared_atn_caches(atn, |cache| {
6656 if let Some(cached) = cache.decision_lookahead.get(&state.state_number) {
6657 return Rc::clone(cached);
6658 }
6659 let mut entry = DecisionLookahead {
6660 transitions: Vec::with_capacity(state.transitions.len()),
6661 };
6662 for transition in &state.transitions {
6663 entry.transitions.push(transition_first_set(
6664 atn,
6665 transition,
6666 rule_stop_state,
6667 &mut cache.first_set,
6668 ));
6669 }
6670 let entry = Rc::new(entry);
6671 cache
6672 .decision_lookahead
6673 .insert(state.state_number, Rc::clone(&entry));
6674 entry
6675 });
6676 self.decision_lookahead_cache
6677 .insert(state.state_number, Rc::clone(&entry));
6678 entry
6679 }
6680
6681 fn cached_rule_first_set(
6682 &mut self,
6683 atn: &Atn,
6684 target: usize,
6685 child_stop: usize,
6686 ) -> Rc<FirstSet> {
6687 if self.rule_first_set_cache.len() <= target {
6688 self.rule_first_set_cache
6689 .resize_with(atn.states().len().max(target + 1), || None);
6690 }
6691 if let Some(cached) = self
6692 .rule_first_set_cache
6693 .get(target)
6694 .and_then(Option::as_ref)
6695 {
6696 return Rc::clone(cached);
6697 }
6698 let first = with_shared_first_set_cache(atn, |cache| {
6699 rule_first_set(atn, target, child_stop, cache)
6700 });
6701 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
6702 first
6703 }
6704
6705 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
6706 if self.empty_cycle_cache.len() <= state_number {
6707 self.empty_cycle_cache
6708 .resize_with(atn.states().len().max(state_number + 1), || None);
6709 }
6710 if let Some(cached) = self.empty_cycle_cache[state_number] {
6711 return cached;
6712 }
6713 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
6714 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
6715 self.empty_cycle_cache[state_number] = Some(result);
6716 result
6717 }
6718
6719 fn empty_path_reaches_state(
6720 &mut self,
6721 atn: &Atn,
6722 state_number: usize,
6723 target_state: usize,
6724 visited: &mut FxHashSet<usize>,
6725 ) -> bool {
6726 if !visited.insert(state_number) {
6727 return false;
6728 }
6729 let Some(state) = atn.state(state_number) else {
6730 return false;
6731 };
6732 for transition in &state.transitions {
6733 match transition {
6734 Transition::Atom { .. }
6735 | Transition::Range { .. }
6736 | Transition::Set { .. }
6737 | Transition::NotSet { .. }
6738 | Transition::Wildcard { .. } => {}
6739 Transition::Rule {
6740 target,
6741 rule_index,
6742 follow_state,
6743 ..
6744 } => {
6745 if *target == target_state
6746 || self.empty_path_reaches_state(atn, *target, target_state, visited)
6747 {
6748 return true;
6749 }
6750 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
6751 else {
6752 continue;
6753 };
6754 if self
6755 .cached_rule_first_set(atn, *target, child_stop)
6756 .nullable
6757 && (*follow_state == target_state
6758 || self.empty_path_reaches_state(
6759 atn,
6760 *follow_state,
6761 target_state,
6762 visited,
6763 ))
6764 {
6765 return true;
6766 }
6767 }
6768 Transition::Epsilon { target }
6769 | Transition::Predicate { target, .. }
6770 | Transition::Action { target, .. }
6771 | Transition::Precedence { target, .. } => {
6772 if *target == target_state
6773 || self.empty_path_reaches_state(atn, *target, target_state, visited)
6774 {
6775 return true;
6776 }
6777 }
6778 }
6779 }
6780 false
6781 }
6782
6783 fn should_memoize_single_outcome(&mut self, key: &FastRecognizeKey) -> bool {
6786 match self.single_outcome_memo_mode {
6787 SingleOutcomeMemoMode::Promote => true,
6788 SingleOutcomeMemoMode::Sparse => false,
6789 SingleOutcomeMemoMode::Probe => {
6790 self.single_outcome_probe_samples += 1;
6791 if !self.single_outcome_probe_seen.insert(key.clone()) {
6792 self.single_outcome_probe_repeats += 1;
6793 }
6794 if self.single_outcome_probe_repeats >= CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
6795 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Promote;
6796 self.single_outcome_probe_seen.clear();
6797 return true;
6798 }
6799 if self.single_outcome_probe_samples >= CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT {
6800 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Sparse;
6801 self.single_outcome_probe_seen.clear();
6802 return false;
6803 }
6804 true
6805 }
6806 }
6807 }
6808
6809 fn token_at(&mut self, index: usize) -> Option<CommonToken> {
6811 self.input.get(index).cloned()
6812 }
6813
6814 fn token_ref_at(&mut self, index: usize) -> Option<TokenRef> {
6816 self.input.get_ref(index)
6817 }
6818
6819 fn current_visible_index(&mut self) -> usize {
6822 let index = self.input.index();
6823 self.input.seek(index);
6824 self.input.index()
6825 }
6826
6827 fn child_expected_reaches_clean_eof(
6830 &mut self,
6831 children: &[RecognizeOutcome],
6832 expected: &ExpectedTokens,
6833 ) -> bool {
6834 let Some(index) = expected.index else {
6835 return false;
6836 };
6837 self.token_type_at(index) == TOKEN_EOF
6838 && children
6839 .iter()
6840 .any(|child| child.diagnostics.is_empty() && child.index == index)
6841 }
6842
6843 fn previous_token_index(&mut self, index: usize) -> Option<usize> {
6850 self.input.previous_visible_token_index(index)
6851 }
6852
6853 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
6858 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
6859 Some(index)
6860 } else {
6861 self.previous_token_index(index)
6862 }
6863 }
6864
6865 #[must_use]
6882 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
6883 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
6884 self.rule_stop_token_index(current_index, consumed_eof)
6885 }
6886
6887 #[must_use]
6896 pub fn after_action_stop_index_for_tree(
6897 &mut self,
6898 tree: &ParseTree,
6899 current_index: usize,
6900 ) -> Option<usize> {
6901 if let ParseTree::Rule(rule) = tree {
6902 if let Some(stop) = rule.context().stop() {
6903 let token_index = stop.token_index();
6904 if token_index >= 0 {
6905 return Some(token_index.unsigned_abs());
6906 }
6907 }
6908 }
6909 self.after_action_stop_index(current_index)
6910 }
6911
6912 #[must_use]
6922 pub fn after_action_start_index_for_tree(
6923 &self,
6924 tree: &ParseTree,
6925 fallback_index: usize,
6926 ) -> usize {
6927 if let ParseTree::Rule(rule) = tree {
6928 if let Some(start) = rule.context().start() {
6929 let token_index = start.token_index();
6930 if token_index >= 0 {
6931 return token_index.unsigned_abs();
6932 }
6933 }
6934 }
6935 fallback_index
6936 }
6937
6938 fn rule_stop_token_ref(&mut self, index: usize, consumed_eof: bool) -> Option<TokenRef> {
6943 self.rule_stop_token_index(index, consumed_eof)
6944 .and_then(|token_index| self.token_ref_at(token_index))
6945 }
6946
6947 fn predicate_failure_recovery(
6954 &mut self,
6955 request: PredicateFailureRecovery<'_>,
6956 ) -> RecognizeOutcome {
6957 let PredicateFailureRecovery {
6958 rule_index,
6959 index,
6960 message,
6961 member_values,
6962 return_values,
6963 rule_alt_number,
6964 } = request;
6965 let rule_name = self
6966 .rule_names()
6967 .get(rule_index)
6968 .map_or_else(|| rule_index.to_string(), Clone::clone);
6969 let diagnostic = diagnostic_for_token(
6970 self.token_at(index).as_ref(),
6971 format!("rule {rule_name} {message}"),
6972 );
6973 let mut nodes = Vec::new();
6974 let mut next_index = index;
6975 loop {
6976 let symbol = self.token_type_at(next_index);
6977 if symbol == TOKEN_EOF {
6978 break;
6979 }
6980 nodes.push(RecognizedNode::ErrorToken { index: next_index });
6981 let after = self.consume_index(next_index, symbol);
6982 if after == next_index {
6983 break;
6984 }
6985 next_index = after;
6986 }
6987 RecognizeOutcome {
6988 index: next_index,
6989 consumed_eof: false,
6990 alt_number: rule_alt_number,
6991 member_values,
6992 return_values,
6993 diagnostics: vec![diagnostic],
6994 decisions: Vec::new(),
6995 actions: Vec::new(),
6996 nodes,
6997 }
6998 }
6999
7000 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
7007 let PredicateEval {
7008 index,
7009 rule_index,
7010 pred_index,
7011 predicates,
7012 context,
7013 local_int_arg,
7014 member_values,
7015 } = eval;
7016 let Some((_, _, predicate)) = predicates
7017 .iter()
7018 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
7019 else {
7020 return true;
7021 };
7022 self.input.seek(index);
7023 match predicate {
7024 ParserPredicate::True => true,
7025 ParserPredicate::False => false,
7026 ParserPredicate::FalseWithMessage { .. } => false,
7027 ParserPredicate::Invoke { value } => {
7028 let key = (rule_index, pred_index);
7029 if !self.invoked_predicates.contains(&key) {
7030 self.invoked_predicates.push(key);
7031 use std::io::Write as _;
7032 let mut stdout = std::io::stdout().lock();
7033 let _ = writeln!(stdout, "eval={value}");
7034 }
7035 *value
7036 }
7037 ParserPredicate::LookaheadTextEquals { offset, text } => {
7038 self.input.lt(*offset).and_then(Token::text) == Some(*text)
7039 }
7040 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
7041 self.la(*offset) != *token_type
7042 }
7043 ParserPredicate::TokenPairAdjacent => {
7044 let Some(first) = self.input.lt(-2).map(Token::token_index) else {
7045 return false;
7046 };
7047 let Some(second) = self.input.lt(-1).map(Token::token_index) else {
7048 return false;
7049 };
7050 first + 1 == second
7051 }
7052 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
7053 .and_then(|context| {
7054 context.children().iter().find_map(|child| match child {
7055 ParseTree::Rule(rule) if rule.context().rule_index() == *rule_index => {
7056 Some(child.text())
7057 }
7058 ParseTree::Rule(_) | ParseTree::Terminal(_) | ParseTree::Error(_) => None,
7059 })
7060 })
7061 .is_none_or(|actual| actual != *text),
7062 ParserPredicate::LocalIntEquals { value } => {
7063 local_int_arg.is_none_or(|(_, actual)| actual == *value)
7064 }
7065 ParserPredicate::LocalIntLessOrEqual { value } => {
7066 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
7067 }
7068 ParserPredicate::MemberModuloEquals {
7069 member,
7070 modulus,
7071 value,
7072 equals,
7073 } => {
7074 if *modulus == 0 {
7075 return false;
7076 }
7077 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
7078 (actual == *value) == *equals
7079 }
7080 ParserPredicate::MemberEquals {
7081 member,
7082 value,
7083 equals,
7084 } => {
7085 let actual = member_values.get(member).copied().unwrap_or_default();
7086 (actual == *value) == *equals
7087 }
7088 }
7089 }
7090
7091 fn parser_predicate_failure_message(
7093 &self,
7094 rule_index: usize,
7095 pred_index: usize,
7096 predicates: &[(usize, usize, ParserPredicate)],
7097 ) -> Option<&'static str> {
7098 predicates
7099 .iter()
7100 .find_map(|(rule, pred, predicate)| match predicate {
7101 ParserPredicate::FalseWithMessage { message }
7102 if *rule == rule_index && *pred == pred_index =>
7103 {
7104 Some(*message)
7105 }
7106 _ => None,
7107 })
7108 }
7109
7110 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
7119 if symbol == TOKEN_EOF {
7120 return index;
7121 }
7122 self.input.next_visible_after(index)
7123 }
7124
7125 fn no_viable_alternative(
7128 &mut self,
7129 start_index: usize,
7130 error_index: usize,
7131 ) -> ParserDiagnostic {
7132 let text = display_input_text(&self.input.text(start_index, error_index));
7133 diagnostic_for_token(
7134 self.token_at(error_index).as_ref(),
7135 format!("no viable alternative at input '{text}'"),
7136 )
7137 }
7138
7139 fn recovery_failure_diagnostic(
7142 &mut self,
7143 index: usize,
7144 decision_start_index: Option<usize>,
7145 expected_symbols: &BTreeSet<i32>,
7146 ) -> ParserDiagnostic {
7147 if expected_symbols.len() > 1 {
7148 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
7149 return self.no_viable_alternative(decision_start, index);
7150 }
7151 }
7152 diagnostic_for_token(
7153 self.token_at(index).as_ref(),
7154 format!(
7155 "mismatched input {} expecting {}",
7156 self.token_at(index)
7157 .as_ref()
7158 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7159 self.expected_symbols_display(expected_symbols)
7160 ),
7161 )
7162 }
7163
7164 fn eof_rule_recovery_diagnostic(
7167 &mut self,
7168 index: usize,
7169 expected_symbols: &BTreeSet<i32>,
7170 expected: &ExpectedTokens,
7171 ) -> ParserDiagnostic {
7172 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
7173 &expected.symbols
7174 } else {
7175 expected_symbols
7176 };
7177 diagnostic_for_token(
7178 self.token_at(index).as_ref(),
7179 format!(
7180 "mismatched input {} expecting {}",
7181 self.token_at(index)
7182 .as_ref()
7183 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7184 self.expected_symbols_display(symbols)
7185 ),
7186 )
7187 }
7188
7189 pub fn text_interval(&mut self, start: usize, stop: Option<usize>) -> String {
7195 let Some(stop) = stop else {
7196 return String::new();
7197 };
7198 let stop = if self
7199 .token_at(stop)
7200 .is_some_and(|token| token.token_type() == TOKEN_EOF)
7201 {
7202 let Some(previous) = self.previous_token_index(stop) else {
7203 return String::new();
7204 };
7205 previous
7206 } else {
7207 stop
7208 };
7209 self.input.text(start, stop)
7210 }
7211
7212 fn clear_prediction_diagnostics(&mut self) {
7215 self.prediction_diagnostics.clear();
7216 self.reported_prediction_diagnostics.clear();
7217 }
7218
7219 fn reset_per_parse_caches(&mut self) {
7241 self.rule_first_set_cache.clear();
7242 self.decision_lookahead_cache.clear();
7243 self.ll1_decision_cache.clear();
7244 self.empty_cycle_cache.clear();
7245 self.rule_stop_reach_cache.clear();
7246 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Probe;
7247 self.single_outcome_probe_seen.clear();
7248 self.single_outcome_probe_samples = 0;
7249 self.single_outcome_probe_repeats = 0;
7250 self.recovery_symbols_intern.clear();
7251 self.state_expected_cache.clear();
7252 self.state_expected_token_cache.clear();
7253 }
7254
7255 fn record_prediction_diagnostics(
7258 &mut self,
7259 atn: &Atn,
7260 state: &AtnState,
7261 start_index: usize,
7262 outcomes: &[RecognizeOutcome],
7263 ) {
7264 if !self.report_diagnostic_errors || state.transitions.len() < 2 {
7265 return;
7266 }
7267 let Some(decision) = atn
7268 .decision_to_state()
7269 .iter()
7270 .position(|state_number| *state_number == state.state_number)
7271 else {
7272 return;
7273 };
7274 let Some(rule_index) = state.rule_index else {
7275 return;
7276 };
7277 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
7278 for outcome in outcomes
7279 .iter()
7280 .filter(|outcome| outcome.diagnostics.is_empty())
7281 {
7282 let Some(alt) = outcome.decisions.first() else {
7283 continue;
7284 };
7285 alts_by_end
7286 .entry(outcome.index)
7287 .or_default()
7288 .insert(alt + 1);
7289 }
7290 let Some((&end_index, ambig_alts)) = alts_by_end
7291 .iter()
7292 .filter(|(_, alts)| alts.len() > 1)
7293 .max_by_key(|(end, _)| *end)
7294 else {
7295 return;
7296 };
7297 let rule_name = self
7298 .rule_names()
7299 .get(rule_index)
7300 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
7301 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
7302 let input = display_input_text(&self.input.text(start_index, stop_index));
7303 let alts = ambig_alts
7304 .iter()
7305 .map(usize::to_string)
7306 .collect::<Vec<_>>()
7307 .join(", ");
7308 let key = (decision, start_index, format!("{alts}:{input}"));
7309 if !self.reported_prediction_diagnostics.insert(key) {
7310 return;
7311 }
7312 let start_token = self.token_at(start_index);
7313 let stop_token = self.token_at(stop_index);
7314 self.prediction_diagnostics.push(diagnostic_for_token(
7315 start_token.as_ref(),
7316 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
7317 ));
7318 self.prediction_diagnostics.push(diagnostic_for_token(
7319 stop_token.as_ref(),
7320 format!(
7321 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
7322 ),
7323 ));
7324 }
7325
7326 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
7328 expected_symbols_display(
7329 &state_expected_symbols(atn, state_number),
7330 self.vocabulary(),
7331 )
7332 }
7333
7334 pub fn token_display_at(&mut self, index: usize) -> Option<String> {
7336 self.token_at(index).map(|token| format!("{token}"))
7337 }
7338
7339 fn recognized_node_tree(
7341 &mut self,
7342 node: &RecognizedNode,
7343 track_alt_numbers: bool,
7344 ) -> Result<ParseTree, AntlrError> {
7345 match node {
7346 RecognizedNode::Token { index } => {
7347 let token = self
7348 .input
7349 .get_ref(*index)
7350 .ok_or_else(|| AntlrError::ParserError {
7351 line: 0,
7352 column: 0,
7353 message: format!("missing token at index {index}"),
7354 })?;
7355 Ok(ParseTree::Terminal(TerminalNode::from_ref(token)))
7356 }
7357 RecognizedNode::ErrorToken { index } => {
7358 let token = self
7359 .input
7360 .get_ref(*index)
7361 .ok_or_else(|| AntlrError::ParserError {
7362 line: 0,
7363 column: 0,
7364 message: format!("missing error token at index {index}"),
7365 })?;
7366 Ok(ParseTree::Error(ErrorNode::from_ref(token)))
7367 }
7368 RecognizedNode::MissingToken {
7369 token_type,
7370 at_index,
7371 text,
7372 } => {
7373 let current = self.token_at(*at_index);
7374 let token = CommonToken::new(*token_type)
7375 .with_text(text.as_str())
7376 .with_span(usize::MAX, usize::MAX)
7377 .with_position(
7378 current.as_ref().map(Token::line).unwrap_or_default(),
7379 current.as_ref().map(Token::column).unwrap_or_default(),
7380 );
7381 Ok(ParseTree::Error(ErrorNode::new(token)))
7382 }
7383 RecognizedNode::Rule {
7384 rule_index,
7385 invoking_state,
7386 alt_number,
7387 start_index,
7388 stop_index,
7389 return_values,
7390 children,
7391 } => {
7392 let mut context = ParserRuleContext::new(*rule_index, *invoking_state);
7393 if track_alt_numbers {
7394 context.set_alt_number(*alt_number);
7395 }
7396 for (name, value) in return_values {
7397 context.set_int_return(name.clone(), *value);
7398 }
7399 if let Some(token) = self.token_ref_at(*start_index) {
7400 context.set_start_ref(token);
7401 }
7402 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
7403 context.set_stop_ref(token);
7404 }
7405 for child in children {
7406 context.add_child(self.recognized_node_tree(child, track_alt_numbers)?);
7407 }
7408 Ok(self.rule_node(context))
7409 }
7410 RecognizedNode::LeftRecursiveBoundary { rule_index } => Err(AntlrError::Unsupported(
7411 format!("unfolded left-recursive boundary for rule {rule_index}"),
7412 )),
7413 }
7414 }
7415}
7416
7417impl<S> DirectAdaptiveParser<'_, '_, S>
7418where
7419 S: TokenSource,
7420{
7421 fn parse_rule(
7422 &mut self,
7423 rule_index: usize,
7424 invoking_state: isize,
7425 precedence: i32,
7426 ) -> DirectAdaptiveParseResult<ParseTree> {
7427 let start_state = *self.atn.rule_to_start_state().get(rule_index).ok_or(
7428 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
7429 )?;
7430 let stop_state = *self
7431 .atn
7432 .rule_to_stop_state()
7433 .get(rule_index)
7434 .filter(|state| **state != usize::MAX)
7435 .ok_or(DirectAdaptiveParseControl::Fallback(
7436 DirectAdaptiveFallback::MissingAtn,
7437 ))?;
7438 let start_index = self.parser.current_visible_index();
7439 let mut children = Vec::new();
7440 let mut state_number = start_state;
7441 let mut consumed_eof = false;
7442 while state_number != stop_state {
7443 self.step()?;
7444 let (transition, boundary) = self.next_transition(state_number, precedence)?;
7445 if boundary.is_some() {
7446 return Err(DirectAdaptiveParseControl::Fallback(
7447 DirectAdaptiveFallback::LeftRecursiveBoundary,
7448 ));
7449 }
7450 match transition {
7451 Transition::Epsilon { target } => {
7452 state_number = target;
7453 }
7454 Transition::Precedence {
7455 target,
7456 precedence: transition_precedence,
7457 } => {
7458 if transition_precedence < precedence {
7459 return Err(DirectAdaptiveParseControl::Fallback(
7460 DirectAdaptiveFallback::Precedence,
7461 ));
7462 }
7463 state_number = target;
7464 }
7465 Transition::Rule {
7466 rule_index,
7467 follow_state,
7468 precedence: rule_precedence,
7469 ..
7470 } => {
7471 let child = self.parse_rule(
7472 rule_index,
7473 invoking_state_number(state_number),
7474 rule_precedence,
7475 )?;
7476 if self.parser.build_parse_trees {
7477 children.push(child);
7478 }
7479 state_number = follow_state;
7480 }
7481 Transition::Atom { .. }
7482 | Transition::Range { .. }
7483 | Transition::Set { .. }
7484 | Transition::NotSet { .. }
7485 | Transition::Wildcard { .. } => {
7486 let (matched_eof, child) = self.consume_transition(&transition)?;
7487 consumed_eof |= matched_eof;
7488 if let Some(child) = child {
7489 children.push(child);
7490 }
7491 state_number = transition.target();
7492 }
7493 Transition::Predicate { .. } => {
7494 return Err(DirectAdaptiveParseControl::Fallback(
7495 DirectAdaptiveFallback::Predicate,
7496 ));
7497 }
7498 Transition::Action { .. } => {
7499 return Err(DirectAdaptiveParseControl::Fallback(
7500 DirectAdaptiveFallback::Action,
7501 ));
7502 }
7503 }
7504 }
7505
7506 let mut context = ParserRuleContext::with_child_capacity(
7507 rule_index,
7508 invoking_state,
7509 if self.parser.build_parse_trees {
7510 children.len()
7511 } else {
7512 0
7513 },
7514 );
7515 if let Some(token) = self.parser.token_ref_at(start_index) {
7516 context.set_start_ref(token);
7517 }
7518 let stop_index = self
7519 .parser
7520 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
7521 if let Some(token) = stop_index.and_then(|index| self.parser.token_ref_at(index)) {
7522 context.set_stop_ref(token);
7523 }
7524 if self.parser.build_parse_trees {
7525 for child in children {
7526 context.add_child(child);
7527 }
7528 }
7529 Ok(self.parser.rule_node(context))
7530 }
7531
7532 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
7533 self.steps += 1;
7534 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
7535 return Err(DirectAdaptiveParseControl::Fallback(
7536 DirectAdaptiveFallback::StepLimit,
7537 ));
7538 }
7539 Ok(())
7540 }
7541
7542 fn next_transition(
7543 &mut self,
7544 state_number: usize,
7545 precedence: i32,
7546 ) -> DirectAdaptiveParseResult<(Transition, Option<usize>)> {
7547 let state = self
7548 .atn
7549 .state(state_number)
7550 .ok_or(DirectAdaptiveParseControl::Fallback(
7551 DirectAdaptiveFallback::MissingAtn,
7552 ))?;
7553 if state.is_rule_stop() {
7554 return Err(DirectAdaptiveParseControl::Fallback(
7555 DirectAdaptiveFallback::RuleStop,
7556 ));
7557 }
7558 let transition_index =
7559 self.transition_index(state_number, state.transitions.len(), precedence)?;
7560 let transition = state.transitions.get(transition_index).cloned().ok_or(
7561 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
7562 )?;
7563 let boundary = match &transition {
7564 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
7565 left_recursive_boundary(self.atn, state, *target)
7566 }
7567 _ => None,
7568 };
7569 Ok((transition, boundary))
7570 }
7571
7572 fn transition_index(
7573 &mut self,
7574 state_number: usize,
7575 transition_count: usize,
7576 precedence: i32,
7577 ) -> DirectAdaptiveParseResult<usize> {
7578 match transition_count {
7579 0 => Err(DirectAdaptiveParseControl::Fallback(
7580 DirectAdaptiveFallback::NoTransition,
7581 )),
7582 1 => Ok(0),
7583 _ => {
7584 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
7585 return Ok(alt);
7586 }
7587 let decision = self
7588 .decision_by_state
7589 .get(state_number)
7590 .and_then(|decision| *decision)
7591 .ok_or(DirectAdaptiveParseControl::Fallback(
7592 DirectAdaptiveFallback::UnknownDecision,
7593 ))?;
7594 let prediction = self
7595 .simulator
7596 .adaptive_predict_stream_info_with_precedence(
7597 decision,
7598 direct_precedence(precedence),
7599 &mut self.parser.input,
7600 )
7601 .map_err(|_| {
7602 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
7603 })?;
7604 if prediction.has_semantic_context {
7605 return Err(DirectAdaptiveParseControl::Fallback(
7606 DirectAdaptiveFallback::SemanticContext,
7607 ));
7608 }
7609 prediction
7610 .alt
7611 .checked_sub(1)
7612 .filter(|index| *index < transition_count)
7613 .ok_or(DirectAdaptiveParseControl::Fallback(
7614 DirectAdaptiveFallback::InvalidAlt,
7615 ))
7616 }
7617 }
7618 }
7619
7620 fn ll1_transition_index(
7621 &mut self,
7622 state_number: usize,
7623 transition_count: usize,
7624 ) -> DirectAdaptiveParseResult<Option<usize>> {
7625 let state = self
7626 .atn
7627 .state(state_number)
7628 .ok_or(DirectAdaptiveParseControl::Fallback(
7629 DirectAdaptiveFallback::MissingAtn,
7630 ))?;
7631 if state.precedence_rule_decision {
7632 return Ok(None);
7633 }
7634 let Some(rule_stop) = state
7635 .rule_index
7636 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index).copied())
7637 else {
7638 return Ok(None);
7639 };
7640 let symbol = self.parser.input.la_token(1);
7641 let entry = self
7642 .parser
7643 .cached_decision_lookahead(self.atn, state, rule_stop);
7644 Ok(ll1_greedy_alt(&entry, symbol, state.non_greedy).filter(|alt| *alt < transition_count))
7645 }
7646
7647 fn consume_transition(
7648 &mut self,
7649 transition: &Transition,
7650 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
7651 let symbol = self.parser.input.la_token(1);
7652 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
7653 return Err(DirectAdaptiveParseControl::Fallback(
7654 DirectAdaptiveFallback::TokenMismatch,
7655 ));
7656 }
7657 let token = self
7658 .parser
7659 .input
7660 .lt_ref(1)
7661 .ok_or(DirectAdaptiveParseControl::Fallback(
7662 DirectAdaptiveFallback::TokenMismatch,
7663 ))?;
7664 let matched_eof = symbol == TOKEN_EOF;
7665 if !matched_eof {
7666 self.parser.consume();
7667 }
7668 let child = self
7669 .parser
7670 .build_parse_trees
7671 .then(|| ParseTree::Terminal(TerminalNode::from_ref(token)));
7672 Ok((matched_eof, child))
7673 }
7674}
7675
7676fn left_recursive_boundary(atn: &Atn, state: &AtnState, target: usize) -> Option<usize> {
7679 if !state.precedence_rule_decision {
7680 return None;
7681 }
7682 let target_state = atn.state(target)?;
7683 if target_state.kind == AtnStateKind::LoopEnd {
7684 return None;
7685 }
7686 state.rule_index
7687}
7688
7689const fn next_alt_number(
7696 state: &AtnState,
7697 transition_index: usize,
7698 current_alt_number: usize,
7699 track_alt_numbers: bool,
7700) -> usize {
7701 if !track_alt_numbers || current_alt_number != 0 || state.transitions.len() <= 1 {
7702 return current_alt_number;
7703 }
7704 if matches!(
7705 state.kind,
7706 AtnStateKind::Basic
7707 | AtnStateKind::BlockStart
7708 | AtnStateKind::PlusBlockStart
7709 | AtnStateKind::StarBlockStart
7710 | AtnStateKind::StarLoopEntry
7711 ) && !state.precedence_rule_decision
7712 {
7713 return transition_index + 1;
7714 }
7715 current_alt_number
7716}
7717
7718fn fold_left_recursive_boundaries(nodes: Vec<RecognizedNode>) -> Vec<RecognizedNode> {
7721 let mut folded = Vec::new();
7722 for node in nodes {
7723 match node {
7724 RecognizedNode::LeftRecursiveBoundary { rule_index } => {
7725 if !folded.is_empty() {
7726 let children = std::mem::take(&mut folded);
7727 let start_index = recognized_nodes_start_index(&children).unwrap_or_default();
7728 let stop_index = recognized_nodes_stop_index(&children);
7729 folded.push(RecognizedNode::Rule {
7730 rule_index,
7731 invoking_state: -1,
7732 alt_number: 0,
7733 start_index,
7734 stop_index,
7735 return_values: BTreeMap::new(),
7736 children,
7737 });
7738 }
7739 }
7740 node => folded.push(node),
7741 }
7742 }
7743 folded
7744}
7745
7746fn fold_fast_left_recursive_boundaries(
7748 nodes: Vec<Rc<FastRecognizedNode>>,
7749) -> Vec<Rc<FastRecognizedNode>> {
7750 if !nodes.iter().any(|node| {
7755 matches!(
7756 node.as_ref(),
7757 FastRecognizedNode::LeftRecursiveBoundary { .. }
7758 )
7759 }) {
7760 return nodes;
7761 }
7762 let mut folded: Vec<Rc<FastRecognizedNode>> = Vec::with_capacity(nodes.len());
7763 for node in nodes {
7764 match node.as_ref() {
7765 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
7766 if !folded.is_empty() {
7767 let children = std::mem::take(&mut folded);
7768 let start_index =
7769 fast_recognized_nodes_start_index(&children).unwrap_or_default();
7770 let stop_index = fast_recognized_nodes_stop_index(&children);
7771 folded.push(Rc::new(FastRecognizedNode::Rule {
7772 rule_index: *rule_index,
7773 invoking_state: -1,
7774 start_index,
7775 stop_index,
7776 children: NodeList::from_vec(children),
7777 }));
7778 }
7779 }
7780 _ => folded.push(node),
7781 }
7782 }
7783 folded
7784}
7785
7786fn fast_node_has_left_recursive_boundary(node: &FastRecognizedNode) -> bool {
7787 match node {
7788 FastRecognizedNode::LeftRecursiveBoundary { .. } => true,
7789 FastRecognizedNode::Rule { children, .. } => children.has_left_recursive_boundary(),
7790 FastRecognizedNode::Token { .. }
7791 | FastRecognizedNode::ErrorToken { .. }
7792 | FastRecognizedNode::MissingToken { .. } => false,
7793 }
7794}
7795
7796fn fast_recognized_nodes_start_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
7797 nodes
7798 .iter()
7799 .find_map(|node| fast_recognized_node_start_index(node.as_ref()))
7800}
7801
7802const fn fast_recognized_node_start_index(node: &FastRecognizedNode) -> Option<usize> {
7803 match node {
7804 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
7805 Some(*index)
7806 }
7807 FastRecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
7808 FastRecognizedNode::Rule { start_index, .. } => Some(*start_index),
7809 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
7810 }
7811}
7812
7813const fn fast_recognized_node_span(node: &FastRecognizedNode) -> Option<(usize, Option<usize>)> {
7814 match node {
7815 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
7816 Some((*index, Some(*index)))
7817 }
7818 FastRecognizedNode::MissingToken { at_index, .. } => Some((*at_index, None)),
7819 FastRecognizedNode::Rule {
7820 start_index,
7821 stop_index,
7822 ..
7823 } => Some((*start_index, *stop_index)),
7824 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
7825 }
7826}
7827
7828fn fast_recognized_nodes_stop_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
7829 nodes
7830 .iter()
7831 .rev()
7832 .find_map(|node| fast_recognized_node_stop_index(node.as_ref()))
7833}
7834
7835const fn fast_recognized_node_stop_index(node: &FastRecognizedNode) -> Option<usize> {
7836 match node {
7837 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
7838 Some(*index)
7839 }
7840 FastRecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
7841 FastRecognizedNode::Rule { stop_index, .. } => *stop_index,
7842 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
7843 }
7844}
7845
7846fn recognized_nodes_start_index(nodes: &[RecognizedNode]) -> Option<usize> {
7847 nodes.iter().find_map(recognized_node_start_index)
7848}
7849
7850const fn recognized_node_start_index(node: &RecognizedNode) -> Option<usize> {
7851 match node {
7852 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
7853 RecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
7854 RecognizedNode::Rule { start_index, .. } => Some(*start_index),
7855 RecognizedNode::LeftRecursiveBoundary { .. } => None,
7856 }
7857}
7858
7859fn recognized_nodes_stop_index(nodes: &[RecognizedNode]) -> Option<usize> {
7860 nodes.iter().rev().find_map(recognized_node_stop_index)
7861}
7862
7863fn invoking_state_number(state_number: usize) -> isize {
7866 isize::try_from(state_number).unwrap_or(isize::MAX)
7867}
7868
7869fn direct_precedence(precedence: i32) -> usize {
7870 usize::try_from(precedence.max(0)).unwrap_or_default()
7871}
7872
7873const fn recognized_node_stop_index(node: &RecognizedNode) -> Option<usize> {
7874 match node {
7875 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
7876 RecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
7877 RecognizedNode::Rule { stop_index, .. } => *stop_index,
7878 RecognizedNode::LeftRecursiveBoundary { .. } => None,
7879 }
7880}
7881
7882fn token_input_display(token: &impl Token) -> String {
7883 format!("'{}'", token.text().unwrap_or("<EOF>"))
7884}
7885
7886fn display_input_text(text: &str) -> String {
7887 let mut out = String::new();
7888 for ch in text.chars() {
7889 match ch {
7890 '\n' => out.push_str("\\n"),
7891 '\r' => out.push_str("\\r"),
7892 '\t' => out.push_str("\\t"),
7893 other => out.push(other),
7894 }
7895 }
7896 out
7897}
7898
7899fn diagnostic_for_token(token: Option<&impl Token>, message: String) -> ParserDiagnostic {
7900 ParserDiagnostic {
7901 line: token.map(Token::line).unwrap_or_default(),
7902 column: token.map(Token::column).unwrap_or_default(),
7903 message,
7904 }
7905}
7906
7907#[allow(clippy::print_stderr)]
7909fn report_parser_diagnostics(diagnostics: &[ParserDiagnostic]) {
7910 for diagnostic in diagnostics {
7911 eprintln!(
7912 "line {}:{} {}",
7913 diagnostic.line, diagnostic.column, diagnostic.message
7914 );
7915 }
7916}
7917
7918#[allow(clippy::print_stderr)]
7921fn report_generated_diagnostics(
7922 parser_diagnostics: &[ParserDiagnostic],
7923 token_errors: &[TokenSourceError],
7924) {
7925 #[derive(Clone, Copy)]
7926 enum DiagnosticSource {
7927 Token(usize),
7928 Parser(usize),
7929 }
7930
7931 let mut ordered = Vec::with_capacity(parser_diagnostics.len() + token_errors.len());
7932 ordered.extend(token_errors.iter().enumerate().map(|(index, error)| {
7933 (
7934 error.line,
7935 error.column,
7936 0_usize,
7937 index,
7938 DiagnosticSource::Token(index),
7939 )
7940 }));
7941 ordered.extend(
7942 parser_diagnostics
7943 .iter()
7944 .enumerate()
7945 .map(|(index, diagnostic)| {
7946 (
7947 diagnostic.line,
7948 diagnostic.column,
7949 1_usize,
7950 index,
7951 DiagnosticSource::Parser(index),
7952 )
7953 }),
7954 );
7955 ordered.sort_by_key(|(line, column, source_order, index, _)| {
7956 (*line, *column, *source_order, *index)
7957 });
7958
7959 for (_, _, _, _, source) in ordered {
7960 match source {
7961 DiagnosticSource::Token(index) => {
7962 let error = &token_errors[index];
7963 eprintln!("line {}:{} {}", error.line, error.column, error.message);
7964 }
7965 DiagnosticSource::Parser(index) => {
7966 let diagnostic = &parser_diagnostics[index];
7967 eprintln!(
7968 "line {}:{} {}",
7969 diagnostic.line, diagnostic.column, diagnostic.message
7970 );
7971 }
7972 }
7973 }
7974}
7975
7976#[allow(clippy::print_stderr)]
7979fn report_token_source_errors(errors: &[TokenSourceError]) {
7980 for error in errors {
7981 eprintln!("line {}:{} {}", error.line, error.column, error.message);
7982 }
7983}
7984
7985fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
7986 let items = symbols
7987 .iter()
7988 .map(|symbol| expected_symbol_display(*symbol, vocabulary))
7989 .collect::<Vec<_>>();
7990 if let [single] = items.as_slice() {
7991 return single.clone();
7992 }
7993 format!("{{{}}}", items.join(", "))
7994}
7995
7996fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
7997 if symbol == TOKEN_EOF {
7998 return "<EOF>".to_owned();
7999 }
8000 vocabulary.display_name(symbol)
8001}
8002
8003fn is_caller_follow_boundary_text(text: &str) -> bool {
8004 text.chars().any(|ch| ch == ';' || ch == '\n')
8005 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
8006}
8007
8008fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
8009 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
8010}
8011
8012fn state_is_left_recursive_rule(atn: &Atn, state: &AtnState) -> bool {
8016 let Some(rule_index) = state.rule_index else {
8017 return false;
8018 };
8019 atn.rule_to_start_state()
8020 .get(rule_index)
8021 .and_then(|state_number| atn.state(*state_number))
8022 .is_some_and(|rule_start| rule_start.left_recursive_rule)
8023}
8024
8025fn select_better_top_outcome(
8032 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
8033 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
8034) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
8035 match (first, second) {
8036 (Ok(first), Ok(second)) => {
8037 if first.0.diagnostics.is_empty() {
8038 Ok(first)
8039 } else {
8040 Ok(second)
8041 }
8042 }
8043 (Ok(first), Err(_)) => Ok(first),
8044 (Err(_), Ok(second)) => Ok(second),
8045 (Err(_), Err(second_expected)) => Err(second_expected),
8046 }
8047}
8048
8049fn select_best_fast_outcome(
8055 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
8056 prediction_mode: PredictionMode,
8057 caller_follow: Option<&TokenBitSet>,
8058 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
8059) -> Option<FastRecognizeOutcome> {
8060 let mut best = None;
8061 let mut best_caller_follow = None;
8062 for outcome in outcomes {
8063 if matches!(
8064 prediction_mode,
8065 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
8066 ) && outcome.diagnostics.is_empty()
8067 && let Some(follow) = caller_follow
8068 {
8069 let (token_type, is_boundary, _) = token_info_at(outcome.index);
8070 if is_boundary && follow.contains(token_type) {
8071 let replace =
8072 best_caller_follow
8073 .as_ref()
8074 .is_none_or(|existing: &FastRecognizeOutcome| {
8075 (outcome.index, outcome.consumed_eof)
8076 < (existing.index, existing.consumed_eof)
8077 });
8078 if replace {
8079 best_caller_follow = Some(outcome.clone());
8080 }
8081 }
8082 }
8083 let Some(existing) = best else {
8084 best = Some(outcome);
8085 continue;
8086 };
8087 let outcome_position = (outcome.index, outcome.consumed_eof);
8088 let best_position = (existing.index, existing.consumed_eof);
8089 let better = match prediction_mode {
8090 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
8091 outcome_position,
8092 &outcome.diagnostics,
8093 best_position,
8094 &existing.diagnostics,
8095 ),
8096 PredictionMode::Sll => outcome.index > existing.index,
8097 };
8098 best = Some(if better { outcome } else { existing });
8099 }
8100 let should_use_caller_follow =
8101 best_caller_follow
8102 .as_ref()
8103 .zip(best.as_ref())
8104 .is_some_and(|(candidate, selected)| {
8105 if !selected.diagnostics.is_empty() {
8106 return true;
8107 }
8108 candidate.index < selected.index
8109 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
8110 });
8111 if should_use_caller_follow {
8112 best_caller_follow
8113 } else {
8114 best
8115 }
8116}
8117
8118fn select_best_outcome(
8119 outcomes: impl Iterator<Item = RecognizeOutcome>,
8120 prediction_mode: PredictionMode,
8121) -> Option<RecognizeOutcome> {
8122 let outcomes = outcomes.collect::<Vec<_>>();
8123 let prefer_first_tie = outcomes
8124 .iter()
8125 .any(|outcome| nodes_need_stable_tie(&outcome.nodes));
8126 outcomes.into_iter().reduce(|best, outcome| {
8127 let outcome_position = (outcome.index, outcome.consumed_eof);
8128 let best_position = (best.index, best.consumed_eof);
8129 let better = match prediction_mode {
8130 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
8131 outcome_is_better(
8132 outcome_position,
8133 &outcome.diagnostics,
8134 best_position,
8135 &best.diagnostics,
8136 ) || (!prefer_first_tie
8137 && outcome_position == best_position
8138 && outcome.diagnostics.len() == best.diagnostics.len()
8139 && diagnostic_recovery_rank(&outcome.diagnostics)
8140 == diagnostic_recovery_rank(&best.diagnostics)
8141 && (outcome.decisions < best.decisions
8142 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
8143 }
8144 PredictionMode::Sll => {
8145 outcome_position > best_position
8146 || (outcome_position == best_position
8147 && !prefer_first_tie
8148 && (outcome.decisions < best.decisions
8149 || (outcome.decisions == best.decisions
8150 && outcome_is_better(
8151 outcome_position,
8152 &outcome.diagnostics,
8153 best_position,
8154 &best.diagnostics,
8155 ))))
8156 }
8157 };
8158 if better {
8159 return outcome;
8160 }
8161 best
8162 })
8163}
8164
8165fn transition_decision(
8172 atn: &Atn,
8173 state: &AtnState,
8174 transition_index: usize,
8175 predicates: &[(usize, usize, ParserPredicate)],
8176) -> Option<usize> {
8177 if state.transitions.len() <= 1
8178 || state.precedence_rule_decision
8179 || decision_reaches_unsupported_predicate(atn, state, predicates)
8180 {
8181 return None;
8182 }
8183 Some(transition_index)
8184}
8185
8186const fn starts_prediction_decision(state: &AtnState) -> bool {
8192 state.transitions.len() > 1
8193 && !matches!(
8194 state.kind,
8195 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
8196 )
8197}
8198
8199fn record_no_viable_if_ambiguous(
8202 expected: &mut ExpectedTokens,
8203 decision_start_index: Option<usize>,
8204 index: usize,
8205) {
8206 if expected.index == Some(index) && expected.symbols.len() > 1 {
8207 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
8208 expected.record_no_viable(decision_start, index);
8209 }
8210 }
8211}
8212
8213const fn record_predicate_no_viable(
8216 expected: &mut ExpectedTokens,
8217 decision_start_index: Option<usize>,
8218 index: usize,
8219) {
8220 if let Some(decision_start) = decision_start_index {
8221 expected.record_no_viable(decision_start, index);
8222 }
8223}
8224
8225const fn no_viable_decision_start(
8227 decision_start_index: Option<usize>,
8228 index: usize,
8229) -> Option<usize> {
8230 match decision_start_index {
8231 Some(start) if index > start => Some(start),
8232 _ => None,
8233 }
8234}
8235
8236fn restore_expected(
8240 children: &[RecognizeOutcome],
8241 child_start_index: usize,
8242 expected: &mut ExpectedTokens,
8243 snapshot: ExpectedTokens,
8244 preserve_child_expected: bool,
8245) {
8246 if preserve_child_expected {
8247 return;
8248 }
8249 if children
8250 .iter()
8251 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
8252 {
8253 *expected = snapshot;
8254 }
8255}
8256
8257fn decision_reaches_unsupported_predicate(
8260 atn: &Atn,
8261 state: &AtnState,
8262 predicates: &[(usize, usize, ParserPredicate)],
8263) -> bool {
8264 state.transitions.iter().any(|transition| {
8265 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
8266 })
8267}
8268
8269fn transition_reaches_unsupported_predicate(
8271 atn: &Atn,
8272 transition: &Transition,
8273 predicates: &[(usize, usize, ParserPredicate)],
8274 visited: &mut BTreeSet<usize>,
8275) -> bool {
8276 match transition {
8277 Transition::Predicate {
8278 rule_index,
8279 pred_index,
8280 ..
8281 } => !predicates
8282 .iter()
8283 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
8284 Transition::Epsilon { target }
8285 | Transition::Action { target, .. }
8286 | Transition::Rule { target, .. } => {
8287 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
8288 }
8289 Transition::Precedence { .. }
8290 | Transition::Atom { .. }
8291 | Transition::Range { .. }
8292 | Transition::Set { .. }
8293 | Transition::NotSet { .. }
8294 | Transition::Wildcard { .. } => false,
8295 }
8296}
8297
8298fn state_reaches_unsupported_predicate(
8300 atn: &Atn,
8301 state_number: usize,
8302 predicates: &[(usize, usize, ParserPredicate)],
8303 visited: &mut BTreeSet<usize>,
8304) -> bool {
8305 if !visited.insert(state_number) {
8306 return false;
8307 }
8308 let Some(state) = atn.state(state_number) else {
8309 return false;
8310 };
8311 state.transitions.iter().any(|transition| {
8312 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
8313 })
8314}
8315
8316fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
8318 if let Some(decision) = decision {
8319 outcome.decisions.insert(0, decision);
8320 }
8321}
8322
8323fn outcome_is_better(
8324 outcome_position: (usize, bool),
8325 outcome_diagnostics: &[ParserDiagnostic],
8326 best_position: (usize, bool),
8327 best_diagnostics: &[ParserDiagnostic],
8328) -> bool {
8329 outcome_position > best_position
8330 || (outcome_position == best_position
8331 && (outcome_diagnostics.len() < best_diagnostics.len()
8332 || (outcome_diagnostics.len() == best_diagnostics.len()
8333 && diagnostic_recovery_rank(outcome_diagnostics)
8334 < diagnostic_recovery_rank(best_diagnostics))))
8335}
8336
8337fn diagnostic_recovery_rank(diagnostics: &[ParserDiagnostic]) -> usize {
8340 diagnostics
8341 .iter()
8342 .filter(|diagnostic| {
8343 diagnostic.message.starts_with("mismatched input ")
8344 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
8345 })
8346 .count()
8347}
8348
8349fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
8350 if outcomes
8351 .iter()
8352 .any(|outcome| outcome.diagnostics.is_empty())
8353 {
8354 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
8355 }
8356}
8357
8358fn discard_recovered_outcomes_if_clean_path_exists(outcomes: &mut Vec<RecognizeOutcome>) {
8359 if outcomes.iter().any(outcome_has_rule_failure_diagnostic) {
8360 return;
8361 }
8362 if outcomes
8363 .iter()
8364 .any(|outcome| outcome.diagnostics.is_empty())
8365 {
8366 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
8367 }
8368}
8369
8370fn outcome_has_rule_failure_diagnostic(outcome: &RecognizeOutcome) -> bool {
8373 outcome
8374 .diagnostics
8375 .iter()
8376 .any(|diagnostic| diagnostic.message.starts_with("rule "))
8377}
8378
8379fn nodes_need_stable_tie(nodes: &[RecognizedNode]) -> bool {
8382 nodes.iter().any(node_needs_stable_tie)
8383}
8384
8385fn node_needs_stable_tie(node: &RecognizedNode) -> bool {
8386 match node {
8387 RecognizedNode::Token { .. }
8388 | RecognizedNode::ErrorToken { .. }
8389 | RecognizedNode::MissingToken { .. } => false,
8390 RecognizedNode::LeftRecursiveBoundary { .. } => true,
8391 RecognizedNode::Rule {
8392 rule_index,
8393 children,
8394 ..
8395 } => children.iter().any(|child| {
8396 matches!(
8397 child,
8398 RecognizedNode::Rule {
8399 rule_index: child_rule,
8400 ..
8401 } if child_rule == rule_index
8402 ) || node_needs_stable_tie(child)
8403 }),
8404 }
8405}
8406
8407fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
8421 if outcomes.len() < 2 {
8422 return;
8423 }
8424 let mut keep = Vec::with_capacity(outcomes.len());
8425 let mut seen: BTreeMap<(usize, bool), Vec<usize>> = BTreeMap::new();
8426 'outcomes: for (index, outcome) in outcomes.iter().enumerate() {
8427 let bucket = seen
8428 .entry((outcome.index, outcome.consumed_eof))
8429 .or_default();
8430 for &previous in bucket.iter() {
8431 if outcomes[previous].diagnostics == outcome.diagnostics {
8432 continue 'outcomes;
8433 }
8434 }
8435 bucket.push(index);
8436 keep.push(index);
8437 }
8438 if keep.len() == outcomes.len() {
8439 return;
8440 }
8441 let mut iter = keep.into_iter();
8442 let mut next_keep = iter.next();
8443 let mut current = 0_usize;
8444 outcomes.retain(|_| {
8445 let result = next_keep == Some(current);
8446 if result {
8447 next_keep = iter.next();
8448 }
8449 current += 1;
8450 result
8451 });
8452}
8453
8454fn dedupe_clean_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
8455 if outcomes.len() < 2 {
8456 return;
8457 }
8458 let mut inline_keys: [(usize, bool); 8] = [(0, false); 8];
8468 let mut inline_len = 0_usize;
8469 let mut overflow: Vec<(usize, bool)> = Vec::new();
8470 outcomes.retain(|outcome| {
8471 let key = (outcome.index, outcome.consumed_eof);
8472 for &existing in &inline_keys[..inline_len] {
8473 if existing == key {
8474 return false;
8475 }
8476 }
8477 if !overflow.is_empty() {
8478 for &existing in &overflow {
8479 if existing == key {
8480 return false;
8481 }
8482 }
8483 }
8484 if inline_len < inline_keys.len() {
8485 inline_keys[inline_len] = key;
8486 inline_len += 1;
8487 } else {
8488 overflow.push(key);
8489 }
8490 true
8491 });
8492}
8493
8494fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>) {
8496 outcomes.sort_unstable();
8497 outcomes.dedup();
8498}
8499
8500impl<S> Recognizer for BaseParser<S>
8501where
8502 S: TokenSource,
8503{
8504 fn data(&self) -> &RecognizerData {
8505 &self.data
8506 }
8507
8508 fn data_mut(&mut self) -> &mut RecognizerData {
8509 &mut self.data
8510 }
8511}
8512
8513impl<S> Parser for BaseParser<S>
8514where
8515 S: TokenSource,
8516{
8517 fn build_parse_trees(&self) -> bool {
8518 self.build_parse_trees
8519 }
8520
8521 fn set_build_parse_trees(&mut self, build: bool) {
8522 self.build_parse_trees = build;
8523 }
8524
8525 fn number_of_syntax_errors(&self) -> usize {
8526 Self::number_of_syntax_errors(self)
8527 }
8528
8529 fn report_diagnostic_errors(&self) -> bool {
8530 self.report_diagnostic_errors
8531 }
8532
8533 fn set_report_diagnostic_errors(&mut self, report: bool) {
8534 self.report_diagnostic_errors = report;
8535 }
8536
8537 fn prediction_mode(&self) -> PredictionMode {
8538 self.prediction_mode
8539 }
8540
8541 fn set_prediction_mode(&mut self, mode: PredictionMode) {
8542 self.prediction_mode = mode;
8543 }
8544}
8545
8546#[cfg(test)]
8547mod tests {
8548 use super::*;
8549 use crate::atn::AtnType;
8550 use crate::atn::IntervalSet;
8551 use crate::atn::parser::{
8552 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
8553 };
8554 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
8555 use crate::token::{CommonToken, HIDDEN_CHANNEL, Token};
8556 use crate::token_stream::CommonTokenStream;
8557 use crate::vocabulary::Vocabulary;
8558
8559 #[test]
8560 fn fx_hasher_write_matches_typed_methods_for_full_words() {
8561 let value: u64 = 0x0102_0304_0506_0708;
8568 let mut typed = FxHasher::default();
8569 typed.write_u64(value);
8570 let mut bytewise = FxHasher::default();
8571 bytewise.write(&value.to_le_bytes());
8572 assert_eq!(typed.finish(), bytewise.finish());
8573 }
8574
8575 #[derive(Debug)]
8576 struct Source {
8577 tokens: Vec<CommonToken>,
8578 index: usize,
8579 }
8580
8581 impl TokenSource for Source {
8582 fn next_token(&mut self) -> CommonToken {
8583 let token = self
8584 .tokens
8585 .get(self.index)
8586 .cloned()
8587 .unwrap_or_else(|| CommonToken::eof("parser-test", self.index, 1, self.index));
8588 self.index += 1;
8589 token
8590 }
8591
8592 fn line(&self) -> usize {
8593 1
8594 }
8595
8596 fn column(&self) -> usize {
8597 self.index
8598 }
8599
8600 fn source_name(&self) -> &'static str {
8601 "parser-test"
8602 }
8603 }
8604
8605 fn mini_parser(tokens: Vec<CommonToken>) -> BaseParser<Source> {
8606 let data = RecognizerData::new(
8607 "Mini.g4",
8608 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
8609 );
8610 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
8611 }
8612
8613 fn token_then_eof_atn() -> Atn {
8614 AtnDeserializer::new(&SerializedAtn::from_i32(&[
8615 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, ]))
8631 .deserialize()
8632 .expect("artificial parser ATN should deserialize")
8633 }
8634
8635 fn eof_then_action_atn() -> Atn {
8636 AtnDeserializer::new(&SerializedAtn::from_i32(&[
8637 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, ]))
8653 .deserialize()
8654 .expect("artificial parser ATN should deserialize")
8655 }
8656
8657 fn two_alt_decision_atn() -> Atn {
8658 let mut atn = Atn::new(AtnType::Parser, 2);
8659 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8660 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
8661 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8662 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
8663 atn.add_state(AtnState::new(4, AtnStateKind::BlockEnd).with_rule_index(0));
8664 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
8665 atn.set_rule_to_start_state(vec![0]);
8666 atn.set_rule_to_stop_state(vec![5]);
8667 atn.add_decision_state(1);
8668 atn.state_mut(0)
8669 .expect("state 0")
8670 .add_transition(Transition::Epsilon { target: 1 });
8671 atn.state_mut(1)
8672 .expect("state 1")
8673 .add_transition(Transition::Atom {
8674 target: 2,
8675 label: 1,
8676 });
8677 atn.state_mut(1)
8678 .expect("state 1")
8679 .add_transition(Transition::Atom {
8680 target: 3,
8681 label: 2,
8682 });
8683 atn.state_mut(2)
8684 .expect("state 2")
8685 .add_transition(Transition::Epsilon { target: 4 });
8686 atn.state_mut(3)
8687 .expect("state 3")
8688 .add_transition(Transition::Epsilon { target: 4 });
8689 atn.state_mut(4)
8690 .expect("state 4")
8691 .add_transition(Transition::Epsilon { target: 5 });
8692 atn
8693 }
8694
8695 fn optional_then_b_eof_atn() -> Atn {
8698 let mut atn = Atn::new(AtnType::Parser, 3);
8699 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8700 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
8701 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8702 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
8703 atn.add_state(AtnState::new(4, AtnStateKind::Basic).with_rule_index(0));
8704 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
8705 atn.set_rule_to_start_state(vec![0]);
8706 atn.set_rule_to_stop_state(vec![5]);
8707 atn.add_decision_state(1);
8708 atn.state_mut(0)
8709 .expect("state 0")
8710 .add_transition(Transition::Epsilon { target: 1 });
8711 atn.state_mut(1)
8713 .expect("state 1")
8714 .add_transition(Transition::Atom {
8715 target: 3,
8716 label: 1,
8717 });
8718 atn.state_mut(1)
8719 .expect("state 1")
8720 .add_transition(Transition::Epsilon { target: 3 });
8721 atn.state_mut(3)
8723 .expect("state 3")
8724 .add_transition(Transition::Atom {
8725 target: 4,
8726 label: 2,
8727 });
8728 atn.state_mut(4)
8729 .expect("state 4")
8730 .add_transition(Transition::Atom {
8731 target: 5,
8732 label: TOKEN_EOF,
8733 });
8734 atn
8735 }
8736
8737 #[test]
8738 fn sync_decision_deletes_only_a_single_token() {
8739 let atn = optional_then_b_eof_atn();
8747
8748 let mut single = mini_parser(vec![
8749 CommonToken::new(3).with_text("c"),
8750 CommonToken::new(2).with_text("b"),
8751 CommonToken::eof("parser-test", 1, 2, 2),
8752 ]);
8753 single.rule_context_stack = vec![RuleContextFrame {
8754 rule_index: 0,
8755 invoking_state: 0,
8756 }];
8757 let children = single
8758 .sync_decision(&atn, 1, true, false)
8759 .expect("single extraneous token recovers");
8760 assert_eq!(children.len(), 1);
8761 assert!(matches!(children[0], ParseTree::Error(_)));
8762 assert_eq!(single.number_of_syntax_errors(), 1);
8763 assert_eq!(single.la(1), 2);
8765
8766 let mut double = mini_parser(vec![
8767 CommonToken::new(3).with_text("c"),
8768 CommonToken::new(3).with_text("c"),
8769 CommonToken::new(2).with_text("b"),
8770 CommonToken::eof("parser-test", 1, 3, 3),
8771 ]);
8772 double.rule_context_stack = vec![RuleContextFrame {
8773 rule_index: 0,
8774 invoking_state: 0,
8775 }];
8776 let result = double.sync_decision(&atn, 1, true, false);
8777 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
8782 match error {
8783 AntlrError::ParserError { message, .. } => {
8784 assert!(message.starts_with("mismatched input"), "got: {message}");
8785 }
8786 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
8787 }
8788 assert_eq!(double.la(1), 3);
8789 }
8790
8791 fn star_loop_then_eof_atn() -> Atn {
8795 AtnDeserializer::new(&SerializedAtn::from_i32(&[
8796 4, 1, 3, 11, 2, 0, 7, 0, 1, 0, 5, 0, 4, 8, 0, 10, 0, 12, 0, 7, 9, 0, 1, 0, 1, 0, 1, 0,
8797 0, 0, 1, 0, 0, 0, 10, 0, 5, 1, 0, 0, 0, 2, 4, 5, 1, 0, 0, 3, 2, 1, 0, 0, 0, 4, 7, 1, 0,
8798 0, 0, 5, 3, 1, 0, 0, 0, 5, 6, 1, 0, 0, 0, 6, 8, 1, 0, 0, 0, 7, 5, 1, 0, 0, 0, 8, 9, 5,
8799 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
8800 ]))
8801 .deserialize()
8802 .expect("star-loop-then-EOF ATN should deserialize")
8803 }
8804
8805 #[test]
8806 fn sync_decision_deletes_token_before_eof_at_loop_back() {
8807 let atn = star_loop_then_eof_atn();
8813 let mut parser = mini_parser(vec![
8814 CommonToken::new(2).with_text("c"),
8815 CommonToken::eof("parser-test", 1, 1, 1),
8816 ]);
8817 parser.rule_context_stack = vec![RuleContextFrame {
8818 rule_index: 0,
8819 invoking_state: 0,
8820 }];
8821 let children = parser
8822 .sync_decision(&atn, 5, true, false)
8823 .expect("single token before EOF recovers");
8824 assert_eq!(children.len(), 1);
8825 assert!(matches!(children[0], ParseTree::Error(_)));
8826 assert_eq!(parser.number_of_syntax_errors(), 1);
8827 assert_eq!(
8828 parser.la(1),
8829 TOKEN_EOF,
8830 "EOF is left for the rule's EOF match"
8831 );
8832 }
8833
8834 #[test]
8835 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
8836 let atn = star_loop_then_eof_atn();
8841 let mut parser = mini_parser(vec![
8842 CommonToken::new(2).with_text("c"),
8843 CommonToken::new(2).with_text("c"),
8844 CommonToken::eof("parser-test", 1, 2, 2),
8845 ]);
8846 parser.rule_context_stack = vec![RuleContextFrame {
8847 rule_index: 0,
8848 invoking_state: 0,
8849 }];
8850 let error = parser
8851 .sync_decision(&atn, 5, true, false)
8852 .expect_err("two tokens at the loop entry must not be deleted");
8853 match error {
8854 AntlrError::ParserError { message, .. } => {
8855 assert!(message.starts_with("mismatched input"), "got: {message}");
8856 }
8857 other => panic!("expected mismatched-input ParserError, got {other:?}"),
8858 }
8859 assert_eq!(
8860 parser.la(1),
8861 2,
8862 "nothing consumed; cursor still on first `c`"
8863 );
8864 }
8865
8866 #[test]
8867 fn sync_decision_consumes_until_eof_at_loop_back() {
8868 let atn = star_loop_then_eof_atn();
8874 let mut parser = mini_parser(vec![
8875 CommonToken::new(2).with_text("c"),
8876 CommonToken::new(2).with_text("c"),
8877 CommonToken::eof("parser-test", 1, 2, 2),
8878 ]);
8879 parser.rule_context_stack = vec![RuleContextFrame {
8880 rule_index: 0,
8881 invoking_state: 0,
8882 }];
8883 let children = parser
8884 .sync_decision(&atn, 5, false, true)
8885 .expect("loop-back multi-token deletion recovers onto EOF");
8886 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
8887 assert!(children.iter().all(|c| matches!(c, ParseTree::Error(_))));
8888 assert_eq!(parser.number_of_syntax_errors(), 1);
8889 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
8890 }
8891
8892 fn predicate_after_token_atn() -> Atn {
8893 let mut atn = Atn::new(AtnType::Parser, 2);
8894 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8895 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
8896 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8897 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
8898 atn.add_state(AtnState::new(4, AtnStateKind::RuleStop).with_rule_index(0));
8899 atn.set_rule_to_start_state(vec![0]);
8900 atn.set_rule_to_stop_state(vec![4]);
8901 atn.state_mut(0)
8902 .expect("state 0")
8903 .add_transition(Transition::Atom {
8904 target: 1,
8905 label: 1,
8906 });
8907 atn.state_mut(1)
8908 .expect("state 1")
8909 .add_transition(Transition::Predicate {
8910 target: 2,
8911 rule_index: 0,
8912 pred_index: 0,
8913 context_dependent: false,
8914 });
8915 atn.state_mut(2)
8916 .expect("state 2")
8917 .add_transition(Transition::Atom {
8918 target: 3,
8919 label: 2,
8920 });
8921 atn.state_mut(3)
8922 .expect("state 3")
8923 .add_transition(Transition::Epsilon { target: 4 });
8924 atn
8925 }
8926
8927 fn nested_nullable_context_atn() -> Atn {
8928 let mut atn = Atn::new(AtnType::Parser, 1);
8929 for state_number in 0..=20 {
8930 let kind = match state_number {
8931 0 | 10 | 16 => AtnStateKind::RuleStart,
8932 9 | 15 | 20 => AtnStateKind::RuleStop,
8933 _ => AtnStateKind::Basic,
8934 };
8935 let rule_index = match state_number {
8936 0..=9 => 0,
8937 10..=15 => 1,
8938 _ => 2,
8939 };
8940 atn.add_state(AtnState::new(state_number, kind).with_rule_index(rule_index));
8941 }
8942 atn.set_rule_to_start_state(vec![0, 10, 16]);
8943 atn.set_rule_to_stop_state(vec![9, 15, 20]);
8944 atn.state_mut(1)
8945 .expect("state 1")
8946 .add_transition(Transition::Rule {
8947 target: 10,
8948 rule_index: 1,
8949 follow_state: 8,
8950 precedence: 0,
8951 });
8952 atn.state_mut(8)
8953 .expect("state 8")
8954 .add_transition(Transition::Atom {
8955 target: 9,
8956 label: 1,
8957 });
8958 atn.state_mut(8)
8959 .expect("state 8")
8960 .add_transition(Transition::Epsilon { target: 9 });
8961 atn.state_mut(2)
8962 .expect("state 2")
8963 .add_transition(Transition::Rule {
8964 target: 16,
8965 rule_index: 2,
8966 follow_state: 14,
8967 precedence: 0,
8968 });
8969 atn.state_mut(14)
8970 .expect("state 14")
8971 .add_transition(Transition::Epsilon { target: 15 });
8972 atn
8973 }
8974
8975 fn generated_match_recovery_atn() -> Atn {
8976 let mut atn = Atn::new(AtnType::Parser, 2);
8977 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8978 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
8979 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8980 atn.add_state(AtnState::new(3, AtnStateKind::RuleStop).with_rule_index(0));
8981 atn.add_state(AtnState::new(4, AtnStateKind::RuleStart).with_rule_index(1));
8982 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(1));
8983 atn.set_rule_to_start_state(vec![0, 4]);
8984 atn.set_rule_to_stop_state(vec![3, 5]);
8985 atn.state_mut(1)
8986 .expect("state 1")
8987 .add_transition(Transition::Rule {
8988 target: 4,
8989 rule_index: 1,
8990 follow_state: 2,
8991 precedence: 0,
8992 });
8993 atn.state_mut(2)
8994 .expect("state 2")
8995 .add_transition(Transition::Atom {
8996 target: 3,
8997 label: TOKEN_EOF,
8998 });
8999 atn
9000 }
9001
9002 fn complement_set_atn() -> Atn {
9003 let mut atn = Atn::new(AtnType::Parser, 1);
9004 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
9005 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
9006 atn.set_rule_to_start_state(vec![0]);
9007 atn.set_rule_to_stop_state(vec![1]);
9008 let mut excluded = IntervalSet::new();
9009 excluded.add(1);
9010 atn.state_mut(0)
9011 .expect("state 0")
9012 .add_transition(Transition::NotSet {
9013 target: 1,
9014 set: excluded,
9015 });
9016 atn
9017 }
9018
9019 fn wildcard_then_eof_atn() -> Atn {
9022 let mut atn = Atn::new(AtnType::Parser, 1);
9023 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
9024 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
9025 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
9026 atn.set_rule_to_start_state(vec![0]);
9027 atn.set_rule_to_stop_state(vec![1]);
9028 atn.state_mut(0)
9029 .expect("state 0")
9030 .add_transition(Transition::Wildcard { target: 2 });
9031 atn.state_mut(2)
9032 .expect("state 2")
9033 .add_transition(Transition::Atom {
9034 target: 1,
9035 label: TOKEN_EOF,
9036 });
9037 atn
9038 }
9039
9040 #[test]
9041 fn parser_matches_token_and_reports_mismatch() {
9042 let source = Source {
9043 tokens: vec![
9044 CommonToken::new(1).with_text("x"),
9045 CommonToken::eof("parser-test", 1, 1, 1),
9046 ],
9047 index: 0,
9048 };
9049 let data = RecognizerData::new(
9050 "Mini.g4",
9051 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
9052 );
9053 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
9054 assert_eq!(
9055 parser.match_token(1).expect("token 1 should match").text(),
9056 "x"
9057 );
9058 assert!(parser.match_token(1).is_err());
9059 }
9060
9061 #[test]
9062 fn parser_matches_token_sets() {
9063 let mut parser = mini_parser(vec![
9064 CommonToken::new(1).with_text("x"),
9065 CommonToken::eof("parser-test", 1, 1, 1),
9066 ]);
9067
9068 assert_eq!(
9069 parser
9070 .match_set(&[(1, 1), (3, 4)])
9071 .expect("token set should match")
9072 .text(),
9073 "x"
9074 );
9075 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
9076 }
9077
9078 #[test]
9079 fn generated_rule_api_tracks_state_and_precedence() {
9080 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9081
9082 let context = parser.enter_rule(7, 2);
9083 assert_eq!(context.rule_index(), 2);
9084 assert_eq!(parser.state(), 7);
9085 assert_eq!(
9086 parser.rule_context_stack,
9087 vec![RuleContextFrame {
9088 rule_index: 2,
9089 invoking_state: 7
9090 }]
9091 );
9092
9093 let recursive = parser.enter_recursion_rule(11, 3, 4);
9094 assert_eq!(recursive.rule_index(), 3);
9095 assert!(parser.precpred(4));
9096 assert!(parser.precpred(5));
9097 assert!(!parser.precpred(3));
9098
9099 let next = parser.push_new_recursion_context(13, 3);
9100 assert_eq!(next.invoking_state(), 13);
9101 parser.unroll_recursion_context();
9102 assert_eq!(parser.precedence_stack, vec![0]);
9103 assert_eq!(
9104 parser.rule_context_stack,
9105 vec![RuleContextFrame {
9106 rule_index: 2,
9107 invoking_state: 7
9108 }]
9109 );
9110
9111 parser.exit_rule();
9112 assert!(parser.rule_context_stack.is_empty());
9113 }
9114
9115 #[test]
9116 fn parser_predicates_support_token_adjacency() {
9117 let mut parser = mini_parser(vec![
9118 CommonToken::new(1).with_text("=").with_span(0, 0),
9119 CommonToken::new(1).with_text(">").with_span(1, 1),
9120 CommonToken::eof("parser-test", 2, 1, 2),
9121 ]);
9122 parser.consume();
9123 parser.consume();
9124
9125 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
9126
9127 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
9128
9129 let mut parser = mini_parser(vec![
9130 CommonToken::new(1).with_text("=").with_span(0, 0),
9131 CommonToken::new(1)
9132 .with_text(" ")
9133 .with_channel(HIDDEN_CHANNEL)
9134 .with_span(1, 1),
9135 CommonToken::new(1).with_text(">").with_span(2, 2),
9136 CommonToken::eof("parser-test", 3, 1, 3),
9137 ]);
9138 parser.consume();
9139 parser.consume();
9140
9141 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
9142 }
9143
9144 #[test]
9145 fn parser_predicates_support_context_child_text_checks() {
9146 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9147 let mut context = ParserRuleContext::new(1, 0);
9148 let mut child_context = ParserRuleContext::new(2, 0);
9149 child_context.add_child(ParseTree::Terminal(TerminalNode::new(
9150 CommonToken::new(1).with_text("var"),
9151 )));
9152 context.add_child(ParseTree::Rule(RuleNode::new(child_context)));
9153 let predicates = [(
9154 1,
9155 0,
9156 ParserPredicate::ContextChildRuleTextNotEquals {
9157 rule_index: 2,
9158 text: "var",
9159 },
9160 )];
9161
9162 assert!(
9163 !parser.parser_semantic_predicate_matches_with_context_and_local(
9164 &predicates,
9165 1,
9166 0,
9167 &context,
9168 0,
9169 )
9170 );
9171 }
9172
9173 #[test]
9174 fn context_expected_symbols_walks_nullable_parent_contexts() {
9175 let atn = nested_nullable_context_atn();
9176 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9177 parser.rule_context_stack = vec![
9178 RuleContextFrame {
9179 rule_index: 0,
9180 invoking_state: 0,
9181 },
9182 RuleContextFrame {
9183 rule_index: 1,
9184 invoking_state: 1,
9185 },
9186 RuleContextFrame {
9187 rule_index: 2,
9188 invoking_state: 2,
9189 },
9190 ];
9191
9192 let expected = parser.context_expected_symbols(&atn);
9193
9194 assert!(expected.contains(&1));
9195 assert!(expected.contains(&TOKEN_EOF));
9196 }
9197
9198 #[test]
9199 fn prediction_context_reuses_cached_stack_until_rule_stack_changes() {
9200 let atn = nested_nullable_context_atn();
9201 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9202 parser.rule_context_stack = vec![
9203 RuleContextFrame {
9204 rule_index: 0,
9205 invoking_state: 0,
9206 },
9207 RuleContextFrame {
9208 rule_index: 1,
9209 invoking_state: 1,
9210 },
9211 RuleContextFrame {
9212 rule_index: 2,
9213 invoking_state: 2,
9214 },
9215 ];
9216
9217 let first = parser.prediction_context(&atn);
9218 let second = parser.prediction_context(&atn);
9219 assert!(Rc::ptr_eq(&first, &second));
9220
9221 parser.exit_rule();
9222 let after_pop = parser.prediction_context(&atn);
9223 assert!(!Rc::ptr_eq(&first, &after_pop));
9224 }
9225
9226 #[test]
9227 fn generated_match_token_recovers_missing_token_from_context_follow() {
9228 let atn = generated_match_recovery_atn();
9229 let data = RecognizerData::new(
9230 "Mini.g4",
9231 Vocabulary::new(
9232 [None, Some("'X'"), Some("'Y'")],
9233 [None, Some("X"), Some("Y")],
9234 [None::<&str>, None, None],
9235 ),
9236 );
9237 let mut parser = BaseParser::new(
9238 CommonTokenStream::new(Source {
9239 tokens: vec![CommonToken::eof("parser-test", 3, 1, 3)],
9240 index: 0,
9241 }),
9242 data,
9243 );
9244 parser.rule_context_stack = vec![
9245 RuleContextFrame {
9246 rule_index: 0,
9247 invoking_state: 0,
9248 },
9249 RuleContextFrame {
9250 rule_index: 1,
9251 invoking_state: 1,
9252 },
9253 ];
9254 assert_eq!(parser.number_of_syntax_errors(), 0);
9255
9256 let node = parser
9257 .match_token_recovering(2, 5, &atn)
9258 .expect("generated match should insert missing token");
9259
9260 assert_eq!(node.children().len(), 1);
9261 assert_eq!(node.children()[0].text(), "<missing 'Y'>");
9262 assert!(!node.consumed_eof());
9265 assert_eq!(parser.la(1), TOKEN_EOF);
9266 assert_eq!(parser.number_of_syntax_errors(), 1);
9267 assert_eq!(
9268 parser.generated_parser_diagnostics,
9269 [ParserDiagnostic {
9270 line: 1,
9271 column: 3,
9272 message: "missing 'Y' at '<EOF>'".to_owned(),
9273 }]
9274 );
9275 }
9276
9277 #[test]
9278 fn generated_match_token_counts_single_token_deletion_recovery() {
9279 let atn = generated_match_recovery_atn();
9280 let data = RecognizerData::new(
9281 "Mini.g4",
9282 Vocabulary::new(
9283 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
9284 [None, Some("X"), Some("Y"), Some("Z")],
9285 [None::<&str>, None, None, None],
9286 ),
9287 );
9288 let mut parser = BaseParser::new(
9289 CommonTokenStream::new(Source {
9290 tokens: vec![
9291 CommonToken::new(3).with_text("z"),
9292 CommonToken::new(2).with_text("y"),
9293 CommonToken::eof("parser-test", 3, 1, 3),
9294 ],
9295 index: 0,
9296 }),
9297 data,
9298 );
9299
9300 let node = parser
9301 .match_token_recovering(2, 5, &atn)
9302 .expect("generated match should delete the extraneous token");
9303
9304 assert_eq!(node.children().len(), 2);
9305 assert!(matches!(node.children()[0], ParseTree::Error(_)));
9306 assert_eq!(node.children()[0].text(), "z");
9307 assert_eq!(node.children()[1].text(), "y");
9308 assert_eq!(parser.number_of_syntax_errors(), 1);
9309 }
9310
9311 #[test]
9312 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
9313 let atn = generated_match_recovery_atn();
9314 let data = RecognizerData::new(
9315 "Mini.g4",
9316 Vocabulary::new(
9317 [None, Some("'X'"), Some("'Y'")],
9318 [None, Some("X"), Some("Y")],
9319 [None::<&str>, None, None],
9320 ),
9321 );
9322 let mut parser = BaseParser::new(
9323 CommonTokenStream::new(Source {
9324 tokens: vec![CommonToken::eof("parser-test", 3, 1, 3)],
9325 index: 0,
9326 }),
9327 data,
9328 );
9329 parser.rule_context_stack = vec![
9330 RuleContextFrame {
9331 rule_index: 0,
9332 invoking_state: 0,
9333 },
9334 RuleContextFrame {
9335 rule_index: 1,
9336 invoking_state: 1,
9337 },
9338 ];
9339 let marker = parser.generated_diagnostics_checkpoint();
9340
9341 let _ = parser
9342 .match_token_recovering(2, 5, &atn)
9343 .expect("generated match should insert missing token");
9344 assert_eq!(parser.number_of_syntax_errors(), 1);
9345
9346 parser.restore_generated_diagnostics(marker);
9347
9348 assert_eq!(parser.number_of_syntax_errors(), 0);
9349 assert!(parser.generated_parser_diagnostics.is_empty());
9350 }
9351
9352 #[test]
9353 fn generated_prediction_diagnostics_use_adaptive_context() {
9354 let atn = two_alt_decision_atn();
9355 let data = RecognizerData::new(
9356 "Mini.g4",
9357 Vocabulary::new(
9358 [None, Some("'x'"), Some("'y'")],
9359 [None, Some("X"), Some("Y")],
9360 [None::<&str>, None, None],
9361 ),
9362 )
9363 .with_rule_names(["s"]);
9364 let mut parser = BaseParser::new(
9365 CommonTokenStream::new(Source {
9366 tokens: vec![
9367 CommonToken::new(1)
9368 .with_text("x")
9369 .with_position(1, 0)
9370 .with_span(0, 0),
9371 CommonToken::new(2)
9372 .with_text("y")
9373 .with_position(1, 2)
9374 .with_span(1, 1),
9375 CommonToken::eof("parser-test", 2, 1, 3),
9376 ],
9377 index: 0,
9378 }),
9379 data,
9380 );
9381 parser.set_report_diagnostic_errors(true);
9382
9383 parser.record_generated_prediction_diagnostic(
9384 &atn,
9385 1,
9386 &ParserAtnPrediction {
9387 alt: 1,
9388 requires_full_context: true,
9389 has_semantic_context: false,
9390 diagnostic: Some(ParserAtnPredictionDiagnostic {
9391 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
9392 start_index: 0,
9393 sll_stop_index: 1,
9394 ll_stop_index: 0,
9395 conflicting_alts: vec![1, 2],
9396 }),
9397 },
9398 );
9399 parser.record_generated_prediction_diagnostic(
9400 &atn,
9401 1,
9402 &ParserAtnPrediction {
9403 alt: 1,
9404 requires_full_context: true,
9405 has_semantic_context: false,
9406 diagnostic: Some(ParserAtnPredictionDiagnostic {
9407 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
9408 start_index: 0,
9409 sll_stop_index: 1,
9410 ll_stop_index: 1,
9411 conflicting_alts: vec![1, 2],
9412 }),
9413 },
9414 );
9415
9416 assert_eq!(
9417 parser.generated_parser_diagnostics,
9418 [
9419 ParserDiagnostic {
9420 line: 1,
9421 column: 2,
9422 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
9423 },
9424 ParserDiagnostic {
9425 line: 1,
9426 column: 0,
9427 message: "reportContextSensitivity d=0 (s), input='x'".to_owned(),
9428 },
9429 ParserDiagnostic {
9430 line: 1,
9431 column: 2,
9432 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
9433 },
9434 ParserDiagnostic {
9435 line: 1,
9436 column: 2,
9437 message: "reportAmbiguity d=0 (s): ambigAlts={1, 2}, input='xy'".to_owned(),
9438 },
9439 ]
9440 );
9441 }
9442
9443 #[test]
9444 fn generated_match_not_set_recovers_empty_complement_at_eof() {
9445 let atn = complement_set_atn();
9446 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9447 parser.rule_context_stack = vec![RuleContextFrame {
9448 rule_index: 0,
9449 invoking_state: 0,
9450 }];
9451
9452 let node = parser
9453 .match_not_set_recovering(&[(1, 1)], 1, 1, 1, &atn)
9454 .expect("empty complement should recover at EOF");
9455
9456 assert_eq!(node.children().len(), 1);
9457 assert!(!node.consumed_eof());
9460 assert_eq!(parser.la(1), TOKEN_EOF);
9461 assert_eq!(
9462 parser.generated_parser_diagnostics,
9463 [ParserDiagnostic {
9464 line: 1,
9465 column: 1,
9466 message: "missing {} at '<EOF>'".to_owned(),
9467 }]
9468 );
9469 }
9470
9471 #[test]
9472 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
9473 let atn = wildcard_then_eof_atn();
9479 let data = RecognizerData::new(
9480 "Mini.g4",
9481 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
9482 );
9483 let mut parser = BaseParser::new(
9484 CommonTokenStream::new(Source {
9485 tokens: vec![CommonToken::eof("parser-test", 1, 1, 1)],
9486 index: 0,
9487 }),
9488 data,
9489 );
9490 parser.rule_context_stack = vec![RuleContextFrame {
9491 rule_index: 0,
9492 invoking_state: 0,
9493 }];
9494
9495 let node = parser
9496 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
9497 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
9498
9499 assert_eq!(node.children().len(), 1);
9501 assert!(!node.consumed_eof());
9502 assert!(node.children()[0].text().starts_with("<missing"));
9503 assert_eq!(parser.la(1), TOKEN_EOF);
9504 assert_eq!(
9505 parser.generated_parser_diagnostics,
9506 [ParserDiagnostic {
9507 line: 1,
9508 column: 1,
9509 message: "missing 'x' at '<EOF>'".to_owned(),
9510 }]
9511 );
9512 }
9513
9514 #[test]
9515 fn generated_rule_recovery_consumes_to_parent_follow() {
9516 let atn = generated_match_recovery_atn();
9517 let data = RecognizerData::new(
9518 "Mini.g4",
9519 Vocabulary::new(
9520 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
9521 [None, Some("X"), Some("Y"), Some("Z")],
9522 [None::<&str>, None, None, None],
9523 ),
9524 );
9525 let mut parser = BaseParser::new(
9526 CommonTokenStream::new(Source {
9527 tokens: vec![
9528 CommonToken::new(3).with_text("z"),
9529 CommonToken::eof("parser-test", 1, 1, 1),
9530 ],
9531 index: 0,
9532 }),
9533 data,
9534 );
9535 let _parent = parser.enter_rule(0, 0);
9536 let marker = parser.push_invoking_state(1);
9537 let mut child = parser.enter_rule(4, 1);
9538 parser.discard_invoking_state(marker);
9539
9540 parser.recover_generated_rule(
9541 &mut child,
9542 &atn,
9543 AntlrError::ParserError {
9544 line: 1,
9545 column: 0,
9546 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
9547 },
9548 );
9549 let tree = parser.finish_rule(child, false);
9550
9551 assert_eq!(parser.la(1), TOKEN_EOF);
9552 assert_eq!(tree.to_string_tree(&["s", "a"]), "(a z)");
9553 assert_eq!(parser.number_of_syntax_errors(), 1);
9554 assert_eq!(
9555 parser.generated_parser_diagnostics,
9556 [ParserDiagnostic {
9557 line: 1,
9558 column: 0,
9559 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
9560 }]
9561 );
9562 parser.exit_rule();
9563 }
9564
9565 #[test]
9566 fn greedy_ll1_alt_handles_nullable_loop_exit() {
9567 let mut body_symbols = TokenBitSet::default();
9568 body_symbols.insert(1);
9569 let entry = DecisionLookahead {
9570 transitions: vec![
9571 TransitionLookSet {
9572 symbols: body_symbols,
9573 nullable: false,
9574 },
9575 TransitionLookSet {
9576 symbols: TokenBitSet::default(),
9577 nullable: true,
9578 },
9579 ],
9580 };
9581
9582 assert_eq!(ll1_unique_alt(&entry, 2), None);
9583 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
9584 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
9585 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
9586 }
9587
9588 #[test]
9589 fn single_outcome_memo_probe_selects_sparse_or_promote_mode() {
9590 let key = |state_number| FastRecognizeKey {
9591 state_number,
9592 stop_state: 10,
9593 index: state_number,
9594 rule_start_index: 0,
9595 decision_start_index: None,
9596 precedence: 0,
9597 recovery_symbols_id: 0,
9598 recovery_state: None,
9599 };
9600
9601 let mut sparse = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9602 for state_number in 0..(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT - 1) {
9603 assert!(sparse.should_memoize_single_outcome(&key(state_number)));
9604 }
9605 assert!(!sparse.should_memoize_single_outcome(&key(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT)));
9606 assert_eq!(
9607 sparse.single_outcome_memo_mode,
9608 SingleOutcomeMemoMode::Sparse
9609 );
9610
9611 let mut promote = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9612 let repeated = key(1);
9613 for _ in 0..=CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
9614 assert!(promote.should_memoize_single_outcome(&repeated));
9615 }
9616 assert_eq!(
9617 promote.single_outcome_memo_mode,
9618 SingleOutcomeMemoMode::Promote
9619 );
9620 }
9621
9622 #[test]
9623 fn clean_empty_multi_alt_outcomes_are_memoized() {
9624 let mut atn = Atn::new(AtnType::Parser, 2);
9625 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
9626 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
9627 atn.add_state(AtnState::new(2, AtnStateKind::RuleStop).with_rule_index(0));
9628 atn.set_rule_to_start_state(vec![0]);
9629 atn.set_rule_to_stop_state(vec![2]);
9630 atn.state_mut(0)
9631 .expect("state 0")
9632 .add_transition(Transition::Epsilon { target: 1 });
9633 atn.state_mut(1)
9634 .expect("state 1")
9635 .add_transition(Transition::Atom {
9636 target: 2,
9637 label: 1,
9638 });
9639 atn.state_mut(1)
9640 .expect("state 1")
9641 .add_transition(Transition::Atom {
9642 target: 2,
9643 label: 2,
9644 });
9645
9646 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
9647 parser.fast_recovery_enabled = false;
9648 let mut visiting = FxHashSet::default();
9649 let mut memo = FxHashMap::default();
9650 let mut expected = ExpectedTokens::default();
9651 let outcomes = parser.recognize_state_fast(
9652 &atn,
9653 FastRecognizeRequest {
9654 state_number: 1,
9655 stop_state: 2,
9656 index: 0,
9657 rule_start_index: 0,
9658 decision_start_index: None,
9659 precedence: 0,
9660 depth: 0,
9661 recovery_symbols: parser.empty_recovery_symbols(),
9662 recovery_state: None,
9663 },
9664 &mut visiting,
9665 &mut memo,
9666 &mut expected,
9667 );
9668
9669 assert!(outcomes.is_empty());
9670 assert_eq!(memo.len(), 1);
9671 assert!(memo.values().next().expect("memo entry").is_empty());
9672 }
9673
9674 #[test]
9675 fn wildcard_matches_non_eof_only() {
9676 let mut parser = mini_parser(vec![
9677 CommonToken::new(1).with_text("x"),
9678 CommonToken::eof("parser-test", 1, 1, 1),
9679 ]);
9680 assert_eq!(parser.match_wildcard().expect("wildcard").text(), "x");
9681 assert!(parser.match_wildcard().is_err());
9682 }
9683
9684 #[test]
9685 fn add_parse_child_records_match_even_without_tree_building() {
9686 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9691 let token = CommonToken::new(1).with_text("x");
9692
9693 parser.set_build_parse_trees(false);
9694 let mut ctx = ParserRuleContext::new(0, 0);
9695 assert!(!ctx.has_matched_child());
9696 parser.add_parse_child(
9697 &mut ctx,
9698 ParseTree::Terminal(TerminalNode::new(token.clone())),
9699 );
9700 assert!(ctx.children().is_empty());
9702 assert!(ctx.has_matched_child());
9704
9705 parser.set_build_parse_trees(true);
9707 let mut ctx = ParserRuleContext::new(0, 0);
9708 parser.add_parse_child(&mut ctx, ParseTree::Terminal(TerminalNode::new(token)));
9709 assert_eq!(ctx.children().len(), 1);
9710 assert!(ctx.has_matched_child());
9711 }
9712
9713 #[test]
9714 fn parser_interprets_simple_atn_rule() {
9715 let atn = token_then_eof_atn();
9716 let mut parser = mini_parser(vec![
9717 CommonToken::new(1).with_text("x"),
9718 CommonToken::eof("parser-test", 1, 1, 1),
9719 ]);
9720
9721 let tree = parser
9722 .parse_atn_rule(&atn, 0)
9723 .expect("artificial parser rule should parse");
9724 assert_eq!(tree.text(), "x<EOF>");
9725 assert_eq!(parser.number_of_syntax_errors(), 0);
9726 assert_eq!(
9727 tree.first_rule_stop(0)
9728 .expect("rule should stop at EOF")
9729 .token_type(),
9730 TOKEN_EOF
9731 );
9732
9733 let mut parser = mini_parser(vec![
9734 CommonToken::new(1).with_text("x"),
9735 CommonToken::eof("parser-test", 1, 1, 1),
9736 ]);
9737 let (tree, actions) = parser
9738 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
9739 .expect("runtime-option parser rule should parse");
9740 assert!(actions.is_empty());
9741 assert_eq!(
9742 tree.first_rule_stop(0)
9743 .expect("rule should stop at EOF")
9744 .token_type(),
9745 TOKEN_EOF
9746 );
9747 }
9748
9749 #[test]
9750 fn parser_exposes_buffered_token_stream_after_parse() {
9751 let atn = token_then_eof_atn();
9752 let mut parser = mini_parser(vec![
9753 CommonToken::new(1).with_text("x"),
9754 CommonToken::eof("parser-test", 1, 1, 1),
9755 ]);
9756
9757 let tree = parser
9758 .parse_atn_rule(&atn, 0)
9759 .expect("artificial parser rule should parse");
9760 assert_eq!(tree.text(), "x<EOF>");
9761
9762 let stream = parser.token_stream();
9763 let source_index_after_parse = stream.token_source().index;
9764 let buffered = stream.tokens();
9765 assert_eq!(buffered.len(), 2);
9766 assert_eq!(buffered[0].text(), Some("x"));
9767 assert_eq!(buffered[0].token_index(), 0);
9768 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
9769 assert_eq!(stream.token_source().index, source_index_after_parse);
9770
9771 let stream = parser.into_token_stream();
9772 assert_eq!(stream.token_source().index, source_index_after_parse);
9773 assert_eq!(stream.tokens()[0].text(), Some("x"));
9774 assert_eq!(stream.tokens()[1].token_type(), TOKEN_EOF);
9775 }
9776
9777 #[test]
9778 fn parser_syntax_error_count_tracks_interpreted_recovery() {
9779 let atn = token_then_eof_atn();
9780 let mut parser = mini_parser(vec![
9781 CommonToken::new(1).with_text("x"),
9782 CommonToken::new(2).with_text("y"),
9783 CommonToken::eof("parser-test", 2, 1, 2),
9784 ]);
9785
9786 let tree = parser
9787 .parse_atn_rule(&atn, 0)
9788 .expect("invalid token should recover into an error node");
9789
9790 assert_eq!(parser.number_of_syntax_errors(), 1);
9791 assert_eq!(
9792 tree.first_error_token()
9793 .expect("recovery should embed an error token")
9794 .text(),
9795 Some("y")
9796 );
9797 }
9798
9799 #[test]
9800 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
9801 let atn = token_then_eof_atn();
9802 let mut parser = mini_parser(vec![
9803 CommonToken::new(2).with_text("y"),
9804 CommonToken::eof("parser-test", 1, 1, 1),
9805 ]);
9806
9807 let error = parser
9808 .parse_atn_rule(&atn, 0)
9809 .expect_err("start-rule mismatch should remain a parser error");
9810
9811 assert_eq!(parser.number_of_syntax_errors(), 1);
9812 assert!(matches!(error, AntlrError::ParserError { .. }));
9813 }
9814
9815 #[test]
9816 fn adaptive_direct_rule_uses_simulator_decision() {
9817 let atn = two_alt_decision_atn();
9818 let mut simulator = ParserAtnSimulator::new(&atn);
9819 let mut parser = mini_parser(vec![
9820 CommonToken::new(2).with_text("y"),
9821 CommonToken::eof("parser-test", 1, 1, 1),
9822 ]);
9823
9824 let tree = parser
9825 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
9826 .expect("direct adaptive rule should parse");
9827
9828 assert_eq!(tree.text(), "y");
9829 assert_eq!(parser.input.index(), 1);
9830 }
9831
9832 #[test]
9833 fn adaptive_direct_rule_restores_input_on_fallback() {
9834 let atn = predicate_after_token_atn();
9835 let mut simulator = ParserAtnSimulator::new(&atn);
9836 let mut parser = mini_parser(vec![
9837 CommonToken::new(1).with_text("x"),
9838 CommonToken::new(2).with_text("y"),
9839 CommonToken::eof("parser-test", 2, 1, 2),
9840 ]);
9841
9842 let tree = parser
9843 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
9844 .expect("fallback recognizer should parse");
9845
9846 assert_eq!(tree.text(), "xy");
9847 assert_eq!(parser.input.index(), 2);
9848 }
9849
9850 #[test]
9851 fn parser_rule_start_skips_leading_hidden_tokens() {
9852 let atn = token_then_eof_atn();
9853 let mut parser = mini_parser(vec![
9854 CommonToken::new(99)
9855 .with_text(" ")
9856 .with_channel(HIDDEN_CHANNEL),
9857 CommonToken::new(1).with_text("x"),
9858 CommonToken::eof("parser-test", 2, 1, 2),
9859 ]);
9860
9861 let tree = parser
9862 .parse_atn_rule(&atn, 0)
9863 .expect("artificial parser rule should parse");
9864 let Some(ParseTree::Rule(rule)) = tree.first_rule(0) else {
9865 panic!("rule node should be present");
9866 };
9867 assert_eq!(
9868 rule.context()
9869 .start()
9870 .expect("rule should have a start token")
9871 .token_type(),
9872 1
9873 );
9874 }
9875
9876 #[test]
9877 fn parser_action_after_eof_stops_at_eof_token() {
9878 let atn = eof_then_action_atn();
9879 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
9880
9881 let (_, actions) = parser
9882 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
9883 .expect("EOF action rule should parse");
9884
9885 assert_eq!(actions.len(), 1);
9886 assert_eq!(actions[0].stop_index(), Some(0));
9887 assert_eq!(
9888 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
9889 ""
9890 );
9891 }
9892
9893 #[test]
9894 fn after_action_stop_uses_rule_context_stop_not_cursor() {
9895 let mut id = CommonToken::new(1).with_text("x");
9900 id.set_token_index(0);
9901 let mut eof = CommonToken::eof("parser-test", 1, 1, 1);
9902 eof.set_token_index(1);
9903 let mut parser = mini_parser(vec![id.clone(), eof]);
9904 parser.consume();
9906 assert_eq!(parser.la(1), TOKEN_EOF);
9907
9908 let mut ctx = ParserRuleContext::new(0, 0);
9911 ctx.set_stop(id);
9912 let tree = ParseTree::Rule(RuleNode::new(ctx));
9913
9914 let current_index = parser.input.index();
9915 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
9917 assert_eq!(
9919 parser.after_action_stop_index_for_tree(&tree, current_index),
9920 Some(0)
9921 );
9922 }
9923
9924 #[test]
9925 fn after_action_start_uses_rule_context_start_not_cursor() {
9926 let parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9931 let mut id = CommonToken::new(1).with_text("x");
9932 id.set_token_index(2);
9934
9935 let mut ctx = ParserRuleContext::new(0, 0);
9936 ctx.set_start(id);
9937 let tree = ParseTree::Rule(RuleNode::new(ctx));
9938
9939 assert_eq!(parser.after_action_start_index_for_tree(&tree, 0), 2);
9942
9943 let empty = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, 0)));
9945 assert_eq!(parser.after_action_start_index_for_tree(&empty, 7), 7);
9946 }
9947
9948 #[test]
9949 fn fast_outcome_selection_respects_sll_tie_order() {
9950 let first = FastRecognizeOutcome {
9951 index: 1,
9952 consumed_eof: false,
9953 diagnostics: FastDiagnostics::from_vec(vec![ParserDiagnostic {
9954 line: 1,
9955 column: 0,
9956 message: "mismatched input 'x'".to_owned(),
9957 }]),
9958 nodes: NodeList::new(),
9959 };
9960 let second = FastRecognizeOutcome {
9961 index: first.index,
9962 consumed_eof: first.consumed_eof,
9963 diagnostics: FastDiagnostics::new(),
9964 nodes: NodeList::new(),
9965 };
9966
9967 let selected = select_best_fast_outcome(
9968 [first.clone(), second.clone()].into_iter(),
9969 PredictionMode::Sll,
9970 None,
9971 |_| panic!("caller-follow token probe should not run"),
9972 )
9973 .expect("one outcome should be selected");
9974 assert_eq!(selected.diagnostics.len(), 1);
9975 let eof_second = FastRecognizeOutcome {
9976 index: second.index,
9977 consumed_eof: true,
9978 diagnostics: FastDiagnostics::new(),
9979 nodes: NodeList::new(),
9980 };
9981 let selected = select_best_fast_outcome(
9982 [first.clone(), eof_second].into_iter(),
9983 PredictionMode::Sll,
9984 None,
9985 |_| panic!("caller-follow token probe should not run"),
9986 )
9987 .expect("one outcome should be selected");
9988 assert!(!selected.consumed_eof);
9989 let selected = select_best_fast_outcome(
9990 [first, second].into_iter(),
9991 PredictionMode::Ll,
9992 None,
9993 |_| panic!("caller-follow token probe should not run"),
9994 )
9995 .expect("one outcome should be selected");
9996 assert!(selected.diagnostics.is_empty());
9997 }
9998
9999 #[test]
10000 fn fast_outcome_selection_prefers_generated_caller_follow() {
10001 let earlier = FastRecognizeOutcome {
10002 index: 7,
10003 consumed_eof: false,
10004 diagnostics: FastDiagnostics::new(),
10005 nodes: NodeList::new(),
10006 };
10007 let later = FastRecognizeOutcome {
10008 index: 8,
10009 consumed_eof: false,
10010 diagnostics: FastDiagnostics::new(),
10011 nodes: NodeList::new(),
10012 };
10013 let mut follow = TokenBitSet::default();
10014 follow.insert(5);
10015
10016 let selected = select_best_fast_outcome(
10017 [later.clone(), earlier.clone()].into_iter(),
10018 PredictionMode::Ll,
10019 Some(&follow),
10020 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
10021 )
10022 .expect("one outcome should be selected");
10023 assert_eq!(selected.index, 7);
10024
10025 let selected = select_best_fast_outcome(
10026 [later.clone(), earlier.clone()].into_iter(),
10027 PredictionMode::Ll,
10028 Some(&follow),
10029 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
10030 )
10031 .expect("one outcome should be selected");
10032 assert_eq!(selected.index, 8);
10033
10034 let indented_next_statement = FastRecognizeOutcome {
10035 index: 9,
10036 consumed_eof: false,
10037 diagnostics: FastDiagnostics::new(),
10038 nodes: NodeList::new(),
10039 };
10040 let selected = select_best_fast_outcome(
10041 [indented_next_statement, earlier.clone()].into_iter(),
10042 PredictionMode::Ll,
10043 Some(&follow),
10044 |index| {
10045 let is_boundary = index == 7;
10046 let is_boundary_gap = matches!(index, 7 | 8);
10047 (
10048 if index == 7 { 5 } else { TOKEN_EOF },
10049 is_boundary,
10050 is_boundary_gap,
10051 )
10052 },
10053 )
10054 .expect("one outcome should be selected");
10055 assert_eq!(selected.index, 7);
10056
10057 let continuation = FastRecognizeOutcome {
10058 index: 10,
10059 consumed_eof: false,
10060 diagnostics: FastDiagnostics::new(),
10061 nodes: NodeList::new(),
10062 };
10063 let selected = select_best_fast_outcome(
10064 [continuation, earlier.clone()].into_iter(),
10065 PredictionMode::Ll,
10066 Some(&follow),
10067 |index| {
10068 let is_boundary = matches!(index, 7 | 9);
10069 (
10070 if index == 7 { 5 } else { TOKEN_EOF },
10071 is_boundary,
10072 is_boundary,
10073 )
10074 },
10075 )
10076 .expect("one outcome should be selected");
10077 assert_eq!(selected.index, 10);
10078
10079 let selected = select_best_fast_outcome(
10080 [earlier, later].into_iter(),
10081 PredictionMode::Sll,
10082 Some(&follow),
10083 |_| panic!("caller-follow token probe should not run in SLL mode"),
10084 )
10085 .expect("one outcome should be selected");
10086 assert_eq!(selected.index, 8);
10087 }
10088
10089 #[test]
10090 fn caller_follow_boundary_text_requires_separator_shape() {
10091 assert!(is_caller_follow_boundary_text(";"));
10092 assert!(is_caller_follow_boundary_text("\n"));
10093 assert!(is_caller_follow_boundary_text("\r\n "));
10094 assert!(is_caller_follow_boundary_text(";\n"));
10095 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
10096 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
10097 assert!(!is_caller_follow_boundary_text("identifier"));
10098 assert!(is_caller_follow_boundary_gap_text(" \t "));
10099 assert!(is_caller_follow_boundary_gap_text("\n "));
10100 assert!(is_caller_follow_boundary_gap_text(";\t"));
10101 assert!(!is_caller_follow_boundary_gap_text(
10102 "\"\"\"line1\nline2\"\"\""
10103 ));
10104 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
10105 }
10106
10107 #[test]
10108 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
10109 let mut parser = mini_parser(vec![
10110 CommonToken::new(5).with_text("\n"),
10111 CommonToken::new(6)
10112 .with_text("// comment\n")
10113 .with_channel(HIDDEN_CHANNEL),
10114 CommonToken::new(1).with_text("x"),
10115 CommonToken::eof("parser-test", 1, 2, 0),
10116 ]);
10117
10118 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
10119 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
10120 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
10121 }
10122
10123 #[test]
10124 fn caller_follow_token_info_uses_stream_visible_channel() {
10125 let source = Source {
10126 tokens: vec![
10127 CommonToken::new(5).with_text("\n").with_channel(2),
10128 CommonToken::new(1).with_text("x").with_channel(2),
10129 CommonToken::new(6)
10130 .with_text("// comment\n")
10131 .with_channel(HIDDEN_CHANNEL),
10132 CommonToken::eof("parser-test", 1, 2, 0),
10133 ],
10134 index: 0,
10135 };
10136 let data = RecognizerData::new(
10137 "Mini.g4",
10138 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
10139 );
10140 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
10141
10142 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
10143 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
10144 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
10145 }
10146
10147 #[test]
10148 fn reset_per_parse_caches_clears_state_expected_token_cache() {
10149 let atn = token_then_eof_atn();
10150 let mut parser = mini_parser(Vec::new());
10151
10152 let _ = parser.cached_state_expected_token_set(&atn, 0);
10153 assert!(!parser.state_expected_token_cache.is_empty());
10154
10155 parser.reset_per_parse_caches();
10156 assert!(parser.state_expected_token_cache.is_empty());
10157 }
10158
10159 #[test]
10160 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
10161 let source = Source {
10162 tokens: vec![
10163 CommonToken::new(1).with_text("x"),
10164 CommonToken::eof("parser-test", 1, 1, 1),
10165 ],
10166 index: 0,
10167 };
10168 let data = RecognizerData::new(
10169 "Mini.g4",
10170 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
10171 );
10172 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
10173 let expected = ExpectedTokens {
10174 index: Some(0),
10175 symbols: BTreeSet::new(),
10176 no_viable: None,
10177 };
10178
10179 let (_, message) = parser.expected_error_message(0, 0, &expected);
10180
10181 assert_eq!(message, "mismatched input 'x'");
10182 }
10183
10184 #[test]
10185 fn eof_rule_stop_index_points_at_eof_token() {
10186 let source = Source {
10187 tokens: vec![
10188 CommonToken::new(1).with_text("x"),
10189 CommonToken::eof("parser-test", 1, 1, 1),
10190 ],
10191 index: 0,
10192 };
10193 let data = RecognizerData::new(
10194 "Mini.g4",
10195 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
10196 );
10197 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
10198
10199 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
10200 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
10201 }
10202
10203 #[test]
10204 fn generated_parser_action_uses_current_rule_stop_boundary() {
10205 let mut parser = mini_parser(vec![
10206 CommonToken::new(1).with_text("x"),
10207 CommonToken::eof("parser-test", 1, 1, 1),
10208 ]);
10209
10210 parser.match_token(1).expect("token should match");
10211 let action = parser.parser_action_at_current(7, 0, 0, false);
10212 assert_eq!(action.source_state(), 7);
10213 assert_eq!(action.rule_index(), 0);
10214 assert_eq!(action.start_index(), 0);
10215 assert_eq!(action.stop_index(), Some(0));
10216
10217 parser.match_eof().expect("EOF should match");
10218 let action = parser.parser_action_at_current(8, 0, 0, true);
10219 assert_eq!(action.stop_index(), Some(1));
10220 }
10221
10222 #[test]
10223 fn folds_left_recursive_boundary_into_rule_node() {
10224 let nodes = fold_left_recursive_boundaries(vec![
10225 RecognizedNode::Token { index: 0 },
10226 RecognizedNode::LeftRecursiveBoundary { rule_index: 1 },
10227 RecognizedNode::Token { index: 1 },
10228 ]);
10229
10230 assert_eq!(
10231 nodes,
10232 vec![
10233 RecognizedNode::Rule {
10234 rule_index: 1,
10235 invoking_state: -1,
10236 alt_number: 0,
10237 start_index: 0,
10238 stop_index: Some(0),
10239 return_values: BTreeMap::new(),
10240 children: vec![RecognizedNode::Token { index: 0 }],
10241 },
10242 RecognizedNode::Token { index: 1 },
10243 ]
10244 );
10245 }
10246
10247 #[test]
10248 fn outcome_ties_keep_later_non_recursive_alternative() {
10249 let first = RecognizeOutcome {
10250 index: 1,
10251 consumed_eof: false,
10252 alt_number: 0,
10253 member_values: BTreeMap::new(),
10254 return_values: BTreeMap::new(),
10255 diagnostics: Vec::new(),
10256 decisions: Vec::new(),
10257 actions: vec![ParserAction::new(1, 0, 0, None)],
10258 nodes: vec![RecognizedNode::Token { index: 0 }],
10259 };
10260 let second = RecognizeOutcome {
10261 actions: vec![ParserAction::new(2, 0, 0, None)],
10262 ..first.clone()
10263 };
10264
10265 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
10266 .expect("one outcome should be selected");
10267 assert_eq!(selected.actions[0].source_state(), 2);
10268 }
10269
10270 #[test]
10271 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
10272 let first = RecognizeOutcome {
10273 index: 1,
10274 consumed_eof: false,
10275 alt_number: 0,
10276 member_values: BTreeMap::new(),
10277 return_values: BTreeMap::new(),
10278 diagnostics: Vec::new(),
10279 decisions: Vec::new(),
10280 actions: vec![ParserAction::new(1, 0, 0, None)],
10281 nodes: vec![RecognizedNode::Token { index: 0 }],
10282 };
10283 let second = RecognizeOutcome {
10284 actions: vec![
10285 ParserAction::new(2, 0, 0, None),
10286 ParserAction::new(3, 0, 0, None),
10287 ],
10288 ..first.clone()
10289 };
10290
10291 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll)
10292 .expect("one outcome should be selected");
10293 assert_eq!(selected.actions.len(), 2);
10294 }
10295
10296 #[test]
10297 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
10298 let first = RecognizeOutcome {
10299 index: 7,
10300 consumed_eof: false,
10301 alt_number: 0,
10302 member_values: BTreeMap::new(),
10303 return_values: BTreeMap::new(),
10304 diagnostics: Vec::new(),
10305 decisions: vec![1, 0],
10306 actions: vec![
10307 ParserAction::new(23, 2, 2, Some(4)),
10308 ParserAction::new(23, 2, 0, Some(6)),
10309 ],
10310 nodes: vec![RecognizedNode::Token { index: 0 }],
10311 };
10312 let second = RecognizeOutcome {
10313 decisions: vec![0, 1],
10314 actions: vec![
10315 ParserAction::new(23, 2, 2, Some(6)),
10316 ParserAction::new(23, 2, 0, Some(6)),
10317 ],
10318 ..first.clone()
10319 };
10320
10321 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
10322 .expect("one outcome should be selected");
10323 assert_eq!(selected.actions[0].stop_index(), Some(6));
10324 }
10325
10326 #[test]
10327 fn outcome_ties_keep_first_recursive_tree_shape() {
10328 let recursive_nodes = vec![RecognizedNode::Rule {
10329 rule_index: 1,
10330 invoking_state: -1,
10331 alt_number: 0,
10332 start_index: 0,
10333 stop_index: Some(0),
10334 return_values: BTreeMap::new(),
10335 children: vec![RecognizedNode::Rule {
10336 rule_index: 1,
10337 invoking_state: -1,
10338 alt_number: 0,
10339 start_index: 0,
10340 stop_index: Some(0),
10341 return_values: BTreeMap::new(),
10342 children: vec![RecognizedNode::Token { index: 0 }],
10343 }],
10344 }];
10345 let first = RecognizeOutcome {
10346 index: 1,
10347 consumed_eof: false,
10348 alt_number: 0,
10349 member_values: BTreeMap::new(),
10350 return_values: BTreeMap::new(),
10351 diagnostics: Vec::new(),
10352 decisions: Vec::new(),
10353 actions: vec![ParserAction::new(1, 0, 0, None)],
10354 nodes: recursive_nodes.clone(),
10355 };
10356 let second = RecognizeOutcome {
10357 index: 1,
10358 consumed_eof: false,
10359 alt_number: 0,
10360 member_values: BTreeMap::new(),
10361 return_values: BTreeMap::new(),
10362 diagnostics: Vec::new(),
10363 decisions: Vec::new(),
10364 actions: vec![ParserAction::new(2, 0, 0, None)],
10365 nodes: recursive_nodes,
10366 };
10367
10368 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
10369 .expect("one outcome should be selected");
10370 assert_eq!(selected.actions[0].source_state(), 1);
10371 }
10372
10373 #[test]
10374 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
10375 let first_alt = RecognizeOutcome {
10376 index: 2,
10377 consumed_eof: true,
10378 alt_number: 0,
10379 member_values: BTreeMap::new(),
10380 return_values: BTreeMap::new(),
10381 diagnostics: vec![ParserDiagnostic {
10382 line: 1,
10383 column: 3,
10384 message: "missing 'Y' at '<EOF>'".to_owned(),
10385 }],
10386 decisions: vec![0],
10387 actions: vec![ParserAction::new(1, 0, 0, None)],
10388 nodes: vec![RecognizedNode::Token { index: 0 }],
10389 };
10390 let second_alt = RecognizeOutcome {
10391 diagnostics: Vec::new(),
10392 decisions: vec![1],
10393 actions: vec![ParserAction::new(2, 0, 0, None)],
10394 ..first_alt.clone()
10395 };
10396
10397 let selected =
10398 select_best_outcome([second_alt, first_alt].into_iter(), PredictionMode::Sll)
10399 .expect("one outcome should be selected");
10400 assert_eq!(selected.diagnostics.len(), 1);
10401 assert_eq!(selected.decisions, [0]);
10402 }
10403}