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}
1220
1221thread_local! {
1222 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
1223 RefCell::new(FxHashMap::default());
1224}
1225
1226#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1237struct SharedAtnCacheKey {
1238 atn: usize,
1239 states: usize,
1240 state_count: usize,
1241 max_token_type: i32,
1242}
1243
1244impl SharedAtnCacheKey {
1245 fn for_atn(atn: &Atn) -> Self {
1246 Self {
1247 atn: std::ptr::from_ref::<Atn>(atn) as usize,
1248 states: atn.states().as_ptr() as usize,
1249 state_count: atn.states().len(),
1250 max_token_type: atn.max_token_type(),
1251 }
1252 }
1253}
1254
1255fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
1256 SHARED_ATN_CACHES.with(|cell| {
1257 let key = SharedAtnCacheKey::for_atn(atn);
1258 let mut map = cell.borrow_mut();
1259 let cache = map.entry(key).or_default();
1260 f(&mut cache.first_set)
1261 })
1262}
1263
1264fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
1265 SHARED_ATN_CACHES.with(|cell| {
1266 let key = SharedAtnCacheKey::for_atn(atn);
1267 let mut map = cell.borrow_mut();
1268 let cache = map.entry(key).or_default();
1269 f(cache)
1270 })
1271}
1272
1273#[derive(Debug, Default)]
1282struct DecisionLookahead {
1283 transitions: Vec<TransitionLookSet>,
1284}
1285
1286#[derive(Clone, Debug, Default)]
1293struct TransitionLookSet {
1294 symbols: TokenBitSet,
1295 nullable: bool,
1296}
1297
1298struct FirstSetCtx<'a> {
1302 cache: &'a mut FirstSetCache,
1303 in_progress: BTreeSet<(usize, usize)>,
1304 hit_cycle: bool,
1305}
1306
1307fn rule_first_set(
1316 atn: &Atn,
1317 target: usize,
1318 rule_stop_state: usize,
1319 cache: &mut FirstSetCache,
1320) -> Rc<FirstSet> {
1321 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
1322 return Rc::clone(cached);
1323 }
1324 let mut ctx = FirstSetCtx {
1325 cache,
1326 in_progress: BTreeSet::new(),
1327 hit_cycle: false,
1328 };
1329 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
1330}
1331
1332fn rule_first_set_cached(
1333 atn: &Atn,
1334 target: usize,
1335 rule_stop_state: usize,
1336 ctx: &mut FirstSetCtx<'_>,
1337) -> Rc<FirstSet> {
1338 let key = (target, rule_stop_state);
1339 if let Some(cached) = ctx.cache.get(&key) {
1340 return Rc::clone(cached);
1341 }
1342 if !ctx.in_progress.insert(key) {
1343 return Rc::new(FirstSet::default());
1347 }
1348 let saved_hit_cycle = ctx.hit_cycle;
1349 ctx.hit_cycle = false;
1350 let mut first = FirstSet::default();
1351 let mut visited = BTreeSet::new();
1352 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
1353 ctx.in_progress.remove(&key);
1354 let entry = Rc::new(first);
1355 if !ctx.hit_cycle {
1356 ctx.cache.insert(key, Rc::clone(&entry));
1357 }
1358 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
1359 entry
1360}
1361
1362fn transition_first_set(
1366 atn: &Atn,
1367 transition: &Transition,
1368 rule_stop_state: usize,
1369 cache: &mut FirstSetCache,
1370) -> TransitionLookSet {
1371 match transition {
1372 Transition::Atom { label, .. } => {
1373 let mut symbols = TokenBitSet::default();
1374 symbols.insert(*label);
1375 TransitionLookSet {
1376 symbols,
1377 nullable: false,
1378 }
1379 }
1380 Transition::Range { start, stop, .. } => {
1381 let mut symbols = TokenBitSet::default();
1382 symbols.extend_range(*start, *stop);
1383 TransitionLookSet {
1384 symbols,
1385 nullable: false,
1386 }
1387 }
1388 Transition::Set { set, .. } => {
1389 let mut symbols = TokenBitSet::default();
1390 for (start, stop) in set.ranges() {
1391 symbols.extend_range(*start, *stop);
1392 }
1393 TransitionLookSet {
1394 symbols,
1395 nullable: false,
1396 }
1397 }
1398 Transition::NotSet { set, .. } => {
1399 let max = atn.max_token_type();
1400 let mut symbols = TokenBitSet::default();
1401 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
1402 TransitionLookSet {
1403 symbols,
1404 nullable: false,
1405 }
1406 }
1407 Transition::Wildcard { .. } => {
1408 let mut symbols = TokenBitSet::default();
1409 symbols.extend_range(1, atn.max_token_type());
1410 TransitionLookSet {
1411 symbols,
1412 nullable: false,
1413 }
1414 }
1415 Transition::Epsilon { target }
1416 | Transition::Action { target, .. }
1417 | Transition::Predicate { target, .. }
1418 | Transition::Precedence { target, .. } => {
1419 let first = rule_first_set(atn, *target, rule_stop_state, cache);
1422 TransitionLookSet {
1423 symbols: first.symbols.clone(),
1424 nullable: first.nullable,
1425 }
1426 }
1427 Transition::Rule {
1428 target,
1429 rule_index,
1430 follow_state,
1431 ..
1432 } => {
1433 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
1434 return TransitionLookSet::default();
1435 };
1436 let child = rule_first_set(atn, *target, child_stop, cache);
1437 let mut symbols = child.symbols.clone();
1438 let nullable = if child.nullable {
1439 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
1440 symbols.extend_from(&follow.symbols);
1441 follow.nullable
1442 } else {
1443 false
1444 };
1445 TransitionLookSet { symbols, nullable }
1446 }
1447 }
1448}
1449
1450fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
1471 let mut chosen: Option<usize> = None;
1472 for (index, transition) in entry.transitions.iter().enumerate() {
1473 if transition.nullable {
1474 return None;
1475 }
1476 if transition.symbols.contains(symbol) {
1477 if chosen.is_some() {
1478 return None;
1479 }
1480 chosen = Some(index);
1481 }
1482 }
1483 chosen
1484}
1485
1486fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
1495 let mut matching_non_nullable_alt = None;
1496 let mut nullable_alt = None;
1497 for (index, transition) in entry.transitions.iter().enumerate() {
1498 if transition.nullable {
1499 if nullable_alt.is_some() {
1500 return None;
1501 }
1502 nullable_alt = Some(index);
1503 }
1504 if transition.symbols.contains(symbol) {
1505 if transition.nullable {
1506 continue;
1507 }
1508 if matching_non_nullable_alt.is_some() {
1509 return None;
1510 }
1511 matching_non_nullable_alt = Some(index);
1512 }
1513 }
1514 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
1515 return None;
1516 }
1517 if non_greedy {
1518 nullable_alt.or(matching_non_nullable_alt)
1519 } else {
1520 matching_non_nullable_alt.or(nullable_alt)
1521 }
1522}
1523
1524fn should_skip_via_lookahead(
1525 transition: &Transition,
1526 transition_index: usize,
1527 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
1528 index: usize,
1529 record_expected: bool,
1530 expected: &mut ExpectedTokens,
1531) -> bool {
1532 let prune_non_consuming = matches!(
1533 transition,
1534 Transition::Epsilon { .. }
1535 | Transition::Action { .. }
1536 | Transition::Predicate { .. }
1537 | Transition::Rule { .. }
1538 | Transition::Precedence { .. }
1539 );
1540 if !prune_non_consuming {
1541 return false;
1542 }
1543 let Some((symbol, entry)) = lookahead_filter else {
1544 return false;
1545 };
1546 let Some(set) = entry.transitions.get(transition_index) else {
1547 return false;
1548 };
1549 if set.symbols.contains(*symbol) || set.nullable {
1550 return false;
1551 }
1552 if record_expected && !set.symbols.is_empty() {
1553 record_pruned_transition_expected(set, index, expected);
1554 }
1555 true
1556}
1557
1558fn should_skip_rule_via_first_set(
1559 first: &FirstSet,
1560 symbol: i32,
1561 record_expected: bool,
1562 index: usize,
1563 expected: &mut ExpectedTokens,
1564) -> bool {
1565 if first.nullable || first.symbols.contains(symbol) {
1566 return false;
1567 }
1568 if record_expected && !first.symbols.is_empty() {
1569 record_token_bit_expected(&first.symbols, index, expected);
1570 }
1571 true
1572}
1573
1574fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
1575 match expected.index {
1576 Some(current) if index < current => {}
1577 Some(current) if index == current => {
1578 symbols.extend_btree_set(&mut expected.symbols);
1579 }
1580 _ => {
1581 expected.index = Some(index);
1582 expected.symbols = symbols.to_btree_set();
1583 }
1584 }
1585}
1586
1587fn record_pruned_transition_expected(
1589 set: &TransitionLookSet,
1590 index: usize,
1591 expected: &mut ExpectedTokens,
1592) {
1593 match expected.index {
1594 Some(current) if index < current => {}
1595 Some(current) if index == current => {
1596 set.symbols.extend_btree_set(&mut expected.symbols);
1597 }
1598 _ => {
1599 expected.index = Some(index);
1600 expected.symbols = set.symbols.to_btree_set();
1601 }
1602 }
1603}
1604
1605fn rule_first_set_inner(
1606 atn: &Atn,
1607 state_number: usize,
1608 rule_stop_state: usize,
1609 ctx: &mut FirstSetCtx<'_>,
1610 visited: &mut BTreeSet<usize>,
1611 first: &mut FirstSet,
1612) {
1613 if !visited.insert(state_number) {
1614 return;
1615 }
1616 if state_number == rule_stop_state {
1617 first.nullable = true;
1618 return;
1619 }
1620 let Some(state) = atn.state(state_number) else {
1621 return;
1622 };
1623 for transition in &state.transitions {
1624 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
1625 if !transition_symbols.is_empty() {
1626 first.symbols.extend_iter(transition_symbols);
1627 continue;
1628 }
1629 match transition {
1630 Transition::Epsilon { target }
1631 | Transition::Action { target, .. }
1632 | Transition::Predicate { target, .. }
1633 | Transition::Precedence { target, .. } => {
1634 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
1635 }
1636 Transition::Rule {
1637 target,
1638 rule_index,
1639 follow_state,
1640 ..
1641 } => {
1642 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
1643 continue;
1644 };
1645 let child_key = (*target, child_stop);
1646 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
1647 ctx.hit_cycle = true;
1648 }
1649 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
1650 first.symbols.extend_from(&child.symbols);
1651 if child.nullable {
1652 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
1653 }
1654 }
1655 Transition::Atom { .. }
1656 | Transition::Range { .. }
1657 | Transition::Set { .. }
1658 | Transition::NotSet { .. }
1659 | Transition::Wildcard { .. } => {}
1660 }
1661 }
1662}
1663
1664fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
1667 let mut symbols = BTreeSet::new();
1668 state_sync_symbols_inner(
1669 atn,
1670 state_number,
1671 stop_state,
1672 &mut BTreeSet::new(),
1673 &mut symbols,
1674 );
1675 symbols
1676}
1677
1678fn state_sync_symbols_inner(
1681 atn: &Atn,
1682 state_number: usize,
1683 stop_state: usize,
1684 visited: &mut BTreeSet<usize>,
1685 symbols: &mut BTreeSet<i32>,
1686) {
1687 if !visited.insert(state_number) {
1688 return;
1689 }
1690 if state_number == stop_state {
1691 symbols.insert(TOKEN_EOF);
1692 return;
1693 }
1694 let Some(state) = atn.state(state_number) else {
1695 return;
1696 };
1697 for transition in &state.transitions {
1698 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
1699 if transition_symbols.is_empty() {
1700 match transition {
1701 Transition::Rule { target, .. }
1702 | Transition::Epsilon { target }
1703 | Transition::Action { target, .. }
1704 | Transition::Predicate { target, .. }
1705 | Transition::Precedence { target, .. } => {
1706 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
1707 }
1708 Transition::Atom { .. }
1709 | Transition::Range { .. }
1710 | Transition::Set { .. }
1711 | Transition::NotSet { .. }
1712 | Transition::Wildcard { .. } => {}
1713 }
1714 } else {
1715 symbols.extend(transition_symbols);
1716 }
1717 }
1718}
1719
1720fn state_can_reach_symbol_with_precedence(
1721 atn: &Atn,
1722 state_number: usize,
1723 symbol: i32,
1724 precedence: i32,
1725 visited: &mut BTreeSet<usize>,
1726) -> bool {
1727 if !visited.insert(state_number) {
1728 return false;
1729 }
1730 let Some(state) = atn.state(state_number) else {
1731 return false;
1732 };
1733 state.transitions.iter().any(|transition| {
1734 if transition.matches(symbol, 1, atn.max_token_type()) {
1735 return true;
1736 }
1737 if !transition.is_epsilon() {
1738 return false;
1739 }
1740 if matches!(
1741 transition,
1742 Transition::Precedence {
1743 precedence: transition_precedence,
1744 ..
1745 } if *transition_precedence < precedence
1746 ) {
1747 return false;
1748 }
1749 state_can_reach_symbol_with_precedence(
1750 atn,
1751 transition.target(),
1752 symbol,
1753 precedence,
1754 visited,
1755 )
1756 })
1757}
1758
1759fn context_can_match_symbol_before_state(
1760 atn: &Atn,
1761 context: &PredictionContext,
1762 stop_state_number: usize,
1763 symbol: i32,
1764) -> bool {
1765 (0..context.len()).any(|index| {
1766 context.return_state(index).is_some_and(|return_state| {
1767 let parent = context
1768 .parent(index)
1769 .unwrap_or_else(PredictionContext::empty);
1770 state_or_parent_can_match_symbol_before_state(
1771 atn,
1772 return_state,
1773 &parent,
1774 stop_state_number,
1775 symbol,
1776 &mut BTreeSet::new(),
1777 )
1778 })
1779 })
1780}
1781
1782fn state_or_parent_can_match_symbol_before_state(
1783 atn: &Atn,
1784 state_number: usize,
1785 parent: &Rc<PredictionContext>,
1786 stop_state_number: usize,
1787 symbol: i32,
1788 visited: &mut BTreeSet<usize>,
1789) -> bool {
1790 if state_number == EMPTY_RETURN_STATE {
1791 return false;
1792 }
1793 if state_number == stop_state_number {
1794 return context_can_match_symbol_before_state(atn, parent, stop_state_number, symbol);
1795 }
1796 if !visited.insert(state_number) {
1797 return false;
1798 }
1799 let Some(state) = atn.state(state_number) else {
1800 return false;
1801 };
1802 state.transitions.iter().any(|transition| {
1803 if transition.matches(symbol, 1, atn.max_token_type()) {
1804 return true;
1805 }
1806 transition.is_epsilon()
1807 && state_or_parent_can_match_symbol_before_state(
1808 atn,
1809 transition.target(),
1810 parent,
1811 stop_state_number,
1812 symbol,
1813 visited,
1814 )
1815 })
1816}
1817
1818fn next_recovery_context(
1822 atn: &Atn,
1823 state: &AtnState,
1824 inherited: &BTreeSet<i32>,
1825 inherited_state: Option<usize>,
1826) -> (BTreeSet<i32>, Option<usize>) {
1827 let state_symbols = state_expected_symbols(atn, state.state_number);
1828 if state.transitions.len() > 1 && !state_symbols.is_empty() {
1829 let mut symbols = state_symbols;
1830 symbols.extend(inherited.iter().copied());
1831 return (symbols, Some(state.state_number));
1832 }
1833 (inherited.clone(), inherited_state)
1834}
1835
1836fn recovery_expected_symbols(
1837 atn: &Atn,
1838 state_number: usize,
1839 inherited: &BTreeSet<i32>,
1840) -> BTreeSet<i32> {
1841 let mut symbols = state_expected_symbols(atn, state_number);
1842 symbols.extend(inherited.iter().copied());
1843 symbols
1844}
1845
1846fn fast_next_recovery_context<S>(
1850 parser: &mut BaseParser<S>,
1851 atn: &Atn,
1852 state: &AtnState,
1853 inherited: &Rc<BTreeSet<i32>>,
1854 inherited_state: Option<usize>,
1855) -> (Rc<BTreeSet<i32>>, Option<usize>)
1856where
1857 S: TokenSource,
1858{
1859 if state.transitions.len() <= 1 {
1860 return (Rc::clone(inherited), inherited_state);
1861 }
1862 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number);
1863 if state_symbols.is_empty() {
1864 return (Rc::clone(inherited), inherited_state);
1865 }
1866 if inherited.is_empty() {
1867 return (state_symbols, Some(state.state_number));
1868 }
1869 if Rc::ptr_eq(&state_symbols, inherited) {
1870 return (state_symbols, Some(state.state_number));
1871 }
1872 let mut combined = (*state_symbols).clone();
1873 combined.extend(inherited.iter().copied());
1874 (
1875 parser.intern_recovery_symbols(combined),
1876 Some(state.state_number),
1877 )
1878}
1879
1880fn fast_recovery_expected_symbols<S>(
1884 parser: &mut BaseParser<S>,
1885 atn: &Atn,
1886 state_number: usize,
1887 inherited: &Rc<BTreeSet<i32>>,
1888) -> Rc<BTreeSet<i32>>
1889where
1890 S: TokenSource,
1891{
1892 let cached = parser.cached_state_expected_symbols(atn, state_number);
1893 if inherited.is_empty() {
1894 return cached;
1895 }
1896 if cached.is_empty() {
1897 return Rc::clone(inherited);
1898 }
1899 if Rc::ptr_eq(&cached, inherited) {
1900 return cached;
1901 }
1902 let mut combined = (*cached).clone();
1903 combined.extend(inherited.iter().copied());
1904 parser.intern_recovery_symbols(combined)
1905}
1906
1907fn apply_member_actions(
1909 source_state: usize,
1910 actions: &[ParserMemberAction],
1911 values: &mut BTreeMap<usize, i64>,
1912) {
1913 for action in actions
1914 .iter()
1915 .filter(|action| action.source_state == source_state)
1916 {
1917 *values.entry(action.member).or_default() += action.delta;
1918 }
1919}
1920
1921fn member_values_after_action(
1923 source_state: usize,
1924 actions: &[ParserMemberAction],
1925 values: &BTreeMap<usize, i64>,
1926) -> BTreeMap<usize, i64> {
1927 let mut values = values.clone();
1928 apply_member_actions(source_state, actions, &mut values);
1929 values
1930}
1931
1932fn return_values_after_action(
1934 source_state: usize,
1935 rule_index: usize,
1936 actions: &[ParserReturnAction],
1937 values: &BTreeMap<String, i64>,
1938) -> BTreeMap<String, i64> {
1939 let mut values = values.clone();
1940 for action in actions
1941 .iter()
1942 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
1943 {
1944 values.insert(action.name.to_owned(), action.value);
1945 }
1946 values
1947}
1948
1949fn rule_local_int_arg(
1951 rule_args: &[ParserRuleArg],
1952 source_state: usize,
1953 rule_index: usize,
1954 local_int_arg: Option<(usize, i64)>,
1955) -> Option<(usize, i64)> {
1956 rule_args
1957 .iter()
1958 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
1959 .map(|arg| {
1960 let value = if arg.inherit_local {
1961 local_int_arg.map_or(arg.value, |(_, value)| value)
1962 } else {
1963 arg.value
1964 };
1965 (rule_index, value)
1966 })
1967}
1968
1969fn stop_outcome(
1972 index: usize,
1973 consumed_eof: bool,
1974 rule_alt_number: usize,
1975 member_values: BTreeMap<usize, i64>,
1976 return_values: BTreeMap<String, i64>,
1977) -> Vec<RecognizeOutcome> {
1978 vec![RecognizeOutcome {
1979 index,
1980 consumed_eof,
1981 alt_number: rule_alt_number,
1982 member_values,
1983 return_values,
1984 diagnostics: Vec::new(),
1985 decisions: Vec::new(),
1986 actions: Vec::new(),
1987 nodes: Vec::new(),
1988 }]
1989}
1990
1991#[derive(Clone, Debug, Eq, PartialEq)]
1992struct RecognizeRequest<'a> {
1993 state_number: usize,
1994 stop_state: usize,
1995 index: usize,
1996 rule_start_index: usize,
1997 decision_start_index: Option<usize>,
1998 init_action_rules: &'a BTreeSet<usize>,
1999 predicates: &'a [(usize, usize, ParserPredicate)],
2000 rule_args: &'a [ParserRuleArg],
2001 member_actions: &'a [ParserMemberAction],
2002 return_actions: &'a [ParserReturnAction],
2003 local_int_arg: Option<(usize, i64)>,
2004 member_values: BTreeMap<usize, i64>,
2005 return_values: BTreeMap<String, i64>,
2006 rule_alt_number: usize,
2007 track_alt_numbers: bool,
2008 consumed_eof: bool,
2009 precedence: i32,
2012 depth: usize,
2013 recovery_symbols: BTreeSet<i32>,
2014 recovery_state: Option<usize>,
2015}
2016
2017#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2018struct RecognizeKey {
2019 state_number: usize,
2020 stop_state: usize,
2021 index: usize,
2022 rule_start_index: usize,
2023 decision_start_index: Option<usize>,
2024 local_int_arg: Option<(usize, i64)>,
2025 member_values: BTreeMap<usize, i64>,
2026 return_values: BTreeMap<String, i64>,
2027 rule_alt_number: usize,
2028 track_alt_numbers: bool,
2029 consumed_eof: bool,
2030 precedence: i32,
2031 recovery_symbols: BTreeSet<i32>,
2032 recovery_state: Option<usize>,
2033}
2034
2035#[derive(Clone, Debug, Eq, PartialEq)]
2036struct EpsilonActionStep {
2037 source_state: usize,
2038 target: usize,
2039 action_rule_index: Option<usize>,
2040 left_recursive_boundary: Option<usize>,
2041 decision: Option<usize>,
2042 decision_start_index: Option<usize>,
2043 alt_number: usize,
2044 recovery_symbols: BTreeSet<i32>,
2045 recovery_state: Option<usize>,
2046}
2047
2048struct RecognizeScratch<'a> {
2049 visiting: &'a mut BTreeSet<RecognizeKey>,
2050 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2051 expected: &'a mut ExpectedTokens,
2052}
2053
2054#[derive(Clone, Debug, Eq, PartialEq)]
2055struct FastRecognizeRequest {
2056 state_number: usize,
2057 stop_state: usize,
2058 index: usize,
2059 rule_start_index: usize,
2060 decision_start_index: Option<usize>,
2061 precedence: i32,
2062 depth: usize,
2063 recovery_symbols: Rc<BTreeSet<i32>>,
2064 recovery_state: Option<usize>,
2065}
2066
2067#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2068struct FastRecognizeTopRequest {
2069 start_state: usize,
2070 stop_state: usize,
2071 start_index: usize,
2072 precedence: i32,
2073 caller_follow_state: Option<usize>,
2074}
2075
2076#[derive(Clone, Debug)]
2083struct FastRecognizeKey {
2084 state_number: usize,
2085 stop_state: usize,
2086 index: usize,
2087 rule_start_index: usize,
2088 decision_start_index: Option<usize>,
2089 precedence: i32,
2090 recovery_symbols_id: usize,
2091 recovery_state: Option<usize>,
2092}
2093
2094impl PartialEq for FastRecognizeKey {
2095 fn eq(&self, other: &Self) -> bool {
2096 if self.state_number != other.state_number
2097 || self.stop_state != other.stop_state
2098 || self.index != other.index
2099 || self.rule_start_index != other.rule_start_index
2100 || self.decision_start_index != other.decision_start_index
2101 || self.precedence != other.precedence
2102 || self.recovery_state != other.recovery_state
2103 || self.recovery_symbols_id != other.recovery_symbols_id
2104 {
2105 return false;
2106 }
2107 true
2108 }
2109}
2110
2111impl Eq for FastRecognizeKey {}
2112
2113impl Hash for FastRecognizeKey {
2114 fn hash<H: Hasher>(&self, hasher: &mut H) {
2115 self.state_number.hash(hasher);
2116 self.stop_state.hash(hasher);
2117 self.index.hash(hasher);
2118 self.rule_start_index.hash(hasher);
2119 self.decision_start_index.hash(hasher);
2120 self.precedence.hash(hasher);
2121 self.recovery_state.hash(hasher);
2122 self.recovery_symbols_id.hash(hasher);
2123 }
2124}
2125
2126struct FastRecoveryRequest<'a, 'b> {
2127 atn: &'a Atn,
2128 transition: &'a Transition,
2129 expected_symbols: Rc<BTreeSet<i32>>,
2130 target: usize,
2131 request: FastRecognizeRequest,
2132 visiting: &'b mut FxHashSet<(usize, usize)>,
2133 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
2134 expected: &'b mut ExpectedTokens,
2135}
2136
2137struct FastCurrentTokenDeletionRequest<'a, 'b> {
2138 atn: &'a Atn,
2139 expected_symbols: Rc<BTreeSet<i32>>,
2140 request: FastRecognizeRequest,
2141 visiting: &'b mut FxHashSet<(usize, usize)>,
2142 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
2143 expected: &'b mut ExpectedTokens,
2144}
2145
2146#[derive(Clone, Copy)]
2147struct FastChildRuleFailureRecoveryRequest<'a> {
2148 atn: &'a Atn,
2149 rule_index: usize,
2150 start_index: usize,
2151 follow_state: usize,
2152 stop_state: usize,
2153 expected: &'a ExpectedTokens,
2154}
2155
2156struct RecoveryRequest<'a, 'b> {
2157 atn: &'a Atn,
2158 transition: &'a Transition,
2159 expected_symbols: BTreeSet<i32>,
2160 target: usize,
2161 request: RecognizeRequest<'a>,
2162 visiting: &'b mut BTreeSet<RecognizeKey>,
2163 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2164 expected: &'b mut ExpectedTokens,
2165}
2166
2167struct CurrentTokenDeletionRequest<'a, 'b> {
2168 atn: &'a Atn,
2169 expected_symbols: BTreeSet<i32>,
2170 request: RecognizeRequest<'a>,
2171 visiting: &'b mut BTreeSet<RecognizeKey>,
2172 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2173 expected: &'b mut ExpectedTokens,
2174}
2175
2176struct ConsumingFailureFallback<'a> {
2179 atn: &'a Atn,
2180 target: usize,
2181 request: RecognizeRequest<'a>,
2182 symbol: i32,
2183 expected_symbols: BTreeSet<i32>,
2184 decision_start_index: Option<usize>,
2185 decision: Option<usize>,
2186}
2187
2188struct ChildRuleFailureRecovery<'a> {
2191 atn: &'a Atn,
2192 rule_index: usize,
2193 start_index: usize,
2194 follow_state: usize,
2195 stop_state: usize,
2196 member_values: BTreeMap<usize, i64>,
2197 expected: &'a ExpectedTokens,
2198}
2199
2200#[derive(Clone, Copy, Debug)]
2202struct PredicateEval<'a> {
2203 index: usize,
2204 rule_index: usize,
2205 pred_index: usize,
2206 predicates: &'a [(usize, usize, ParserPredicate)],
2207 context: Option<&'a ParserRuleContext>,
2208 local_int_arg: Option<(usize, i64)>,
2209 member_values: &'a BTreeMap<usize, i64>,
2210}
2211
2212struct PredicateFailureRecovery<'a> {
2214 rule_index: usize,
2215 index: usize,
2216 message: &'a str,
2217 member_values: BTreeMap<usize, i64>,
2218 return_values: BTreeMap<String, i64>,
2219 rule_alt_number: usize,
2220}
2221
2222#[derive(Debug)]
2223enum DirectAdaptiveParseControl {
2224 Fallback(DirectAdaptiveFallback),
2225}
2226
2227#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2228enum DirectAdaptiveFallback {
2229 Action,
2230 InvalidAlt,
2231 LeftRecursiveBoundary,
2232 MissingAtn,
2233 NoTransition,
2234 Predicate,
2235 Prediction,
2236 Precedence,
2237 RuleStop,
2238 SemanticContext,
2239 StepLimit,
2240 TokenMismatch,
2241 UnknownDecision,
2242}
2243
2244type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
2245
2246struct DirectAdaptiveParser<'atn, 'sim, S>
2247where
2248 S: TokenSource,
2249{
2250 parser: &'sim mut BaseParser<S>,
2251 atn: &'atn Atn,
2252 simulator: &'sim mut ParserAtnSimulator<'atn>,
2253 decision_by_state: Vec<Option<usize>>,
2254 steps: usize,
2255}
2256
2257#[derive(Clone, Debug, Eq, PartialEq)]
2267pub struct GeneratedMatch {
2268 children: Vec<ParseTree>,
2269 consumed_eof: bool,
2270}
2271
2272impl GeneratedMatch {
2273 #[must_use]
2277 pub fn children(&self) -> &[ParseTree] {
2278 &self.children
2279 }
2280
2281 #[must_use]
2284 pub fn into_children(self) -> Vec<ParseTree> {
2285 self.children
2286 }
2287
2288 #[must_use]
2290 pub const fn consumed_eof(&self) -> bool {
2291 self.consumed_eof
2292 }
2293}
2294
2295impl<S> BaseParser<S>
2296where
2297 S: TokenSource,
2298{
2299 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
2302 Self {
2303 input,
2304 data,
2305 build_parse_trees: true,
2306 syntax_errors: 0,
2307 report_diagnostic_errors: false,
2308 prediction_mode: PredictionMode::Ll,
2309 prediction_diagnostics: Vec::new(),
2310 reported_prediction_diagnostics: BTreeSet::new(),
2311 generated_parser_diagnostics: Vec::new(),
2312 generated_sync_expected: None,
2313 int_members: BTreeMap::new(),
2314 rule_context_stack: Vec::new(),
2315 rule_context_version: 0,
2316 prediction_context_cache: None,
2317 pending_invoking_states: Vec::new(),
2318 precedence_stack: vec![0],
2319 invoked_predicates: Vec::new(),
2320 rule_first_set_cache: Vec::new(),
2321 state_expected_cache: FxHashMap::default(),
2322 state_expected_token_cache: FxHashMap::default(),
2323 rule_stop_reach_cache: Vec::new(),
2324 recovery_symbols_intern: FxHashMap::default(),
2325 decision_lookahead_cache: FxHashMap::default(),
2326 ll1_decision_cache: FxHashMap::default(),
2327 empty_cycle_cache: Vec::new(),
2328 single_outcome_memo_mode: SingleOutcomeMemoMode::Probe,
2329 single_outcome_probe_seen: FxHashSet::default(),
2330 single_outcome_probe_samples: 0,
2331 single_outcome_probe_repeats: 0,
2332 empty_recovery_symbols: Rc::new(BTreeSet::new()),
2333 fast_first_set_prefilter: true,
2334 fast_recovery_enabled: true,
2335 fast_token_nodes_enabled: true,
2336 }
2337 }
2338
2339 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
2340 &mut self.input
2341 }
2342
2343 #[must_use]
2345 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
2346 &self.input
2347 }
2348
2349 #[must_use]
2351 pub fn into_token_stream(self) -> CommonTokenStream<S> {
2352 self.input
2353 }
2354
2355 pub const fn number_of_syntax_errors(&self) -> usize {
2358 self.syntax_errors
2359 }
2360
2361 pub const fn record_generated_syntax_error(&mut self) {
2364 self.record_syntax_errors(1);
2365 }
2366
2367 const fn record_syntax_errors(&mut self, count: usize) {
2368 self.syntax_errors = self.syntax_errors.saturating_add(count);
2369 }
2370
2371 pub fn report_token_source_errors(&mut self) {
2374 report_token_source_errors(&self.input.drain_source_errors());
2375 }
2376
2377 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
2380 GeneratedDiagnosticsCheckpoint {
2381 diagnostics_len: self.generated_parser_diagnostics.len(),
2382 syntax_errors: self.syntax_errors,
2383 }
2384 }
2385
2386 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
2388 self.generated_parser_diagnostics
2389 .truncate(marker.diagnostics_len);
2390 self.syntax_errors = marker.syntax_errors;
2391 self.generated_sync_expected = None;
2392 }
2393
2394 pub fn report_generated_parser_diagnostics(&mut self) {
2396 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
2397 let token_errors = self.input.drain_source_errors();
2398 report_generated_diagnostics(&parser_diagnostics, &token_errors);
2399 }
2400
2401 pub fn record_generated_ambiguity_diagnostic(
2404 &mut self,
2405 atn: &Atn,
2406 state_number: usize,
2407 start_index: usize,
2408 stop_index: usize,
2409 alts: &[usize],
2410 ) {
2411 if !self.report_diagnostic_errors || alts.len() < 2 {
2412 return;
2413 }
2414 let Some(decision) = atn
2415 .decision_to_state()
2416 .iter()
2417 .position(|candidate| *candidate == state_number)
2418 else {
2419 return;
2420 };
2421 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
2422 return;
2423 };
2424 let rule_name = self
2425 .rule_names()
2426 .get(rule_index)
2427 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
2428 let input = display_input_text(&self.input.text(start_index, stop_index));
2429 let alts = alts
2430 .iter()
2431 .map(usize::to_string)
2432 .collect::<Vec<_>>()
2433 .join(", ");
2434 let key = (decision, start_index, format!("{alts}:{input}"));
2435 if !self.reported_prediction_diagnostics.insert(key) {
2436 return;
2437 }
2438 let start_token = self.token_at(start_index);
2439 let stop_token = self.token_at(stop_index);
2440 self.generated_parser_diagnostics.push(diagnostic_for_token(
2441 start_token.as_ref(),
2442 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
2443 ));
2444 self.generated_parser_diagnostics.push(diagnostic_for_token(
2445 stop_token.as_ref(),
2446 format!(
2447 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
2448 ),
2449 ));
2450 }
2451
2452 pub fn record_generated_prediction_diagnostic(
2455 &mut self,
2456 atn: &Atn,
2457 state_number: usize,
2458 prediction: &ParserAtnPrediction,
2459 ) {
2460 let Some(diagnostic) = &prediction.diagnostic else {
2461 return;
2462 };
2463 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
2464 return;
2465 }
2466 let Some(decision) = atn
2467 .decision_to_state()
2468 .iter()
2469 .position(|candidate| *candidate == state_number)
2470 else {
2471 return;
2472 };
2473 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
2474 return;
2475 };
2476 let rule_name = self
2477 .rule_names()
2478 .get(rule_index)
2479 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
2480 let attempt_input = display_input_text(
2481 &self
2482 .input
2483 .text(diagnostic.start_index, diagnostic.sll_stop_index),
2484 );
2485 let result_input = display_input_text(
2486 &self
2487 .input
2488 .text(diagnostic.start_index, diagnostic.ll_stop_index),
2489 );
2490 let alts = diagnostic
2491 .conflicting_alts
2492 .iter()
2493 .map(usize::to_string)
2494 .collect::<Vec<_>>()
2495 .join(", ");
2496 let key = (
2497 decision,
2498 diagnostic.start_index,
2499 format!(
2500 "{:?}:{alts}:{attempt_input}:{result_input}",
2501 diagnostic.kind
2502 ),
2503 );
2504 if !self.reported_prediction_diagnostics.insert(key) {
2505 return;
2506 }
2507 let attempt_token = self.token_at(diagnostic.sll_stop_index);
2508 self.generated_parser_diagnostics.push(diagnostic_for_token(
2509 attempt_token.as_ref(),
2510 format!(
2511 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
2512 ),
2513 ));
2514 let result_token = self.token_at(diagnostic.ll_stop_index);
2515 let message = match diagnostic.kind {
2516 ParserAtnPredictionDiagnosticKind::Ambiguity => {
2517 format!(
2518 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
2519 )
2520 }
2521 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
2522 format!(
2523 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
2524 )
2525 }
2526 };
2527 self.generated_parser_diagnostics
2528 .push(diagnostic_for_token(result_token.as_ref(), message));
2529 }
2530
2531 pub fn la(&mut self, offset: isize) -> i32 {
2532 self.input.la_token(offset)
2533 }
2534
2535 pub fn consume(&mut self) {
2536 IntStream::consume(&mut self.input);
2537 }
2538
2539 pub fn set_int_member(&mut self, member: usize, value: i64) {
2541 self.int_members.insert(member, value);
2542 }
2543
2544 pub fn int_member(&self, member: usize) -> Option<i64> {
2546 self.int_members.get(&member).copied()
2547 }
2548
2549 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
2552 self.int_members.clone()
2553 }
2554
2555 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
2557 self.int_members = members;
2558 }
2559
2560 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
2562 let value = self.int_members.entry(member).or_default();
2563 *value += delta;
2564 *value
2565 }
2566
2567 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
2574 let current = self
2575 .input
2576 .lt_ref(1)
2577 .ok_or_else(|| AntlrError::ParserError {
2578 line: 0,
2579 column: 0,
2580 message: "missing current token".to_owned(),
2581 })?;
2582 if current.token_type() == token_type {
2583 self.consume();
2584 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
2585 } else {
2586 Err(AntlrError::MismatchedInput {
2587 expected: self.vocabulary().display_name(token_type),
2588 found: self.vocabulary().display_name(current.token_type()),
2589 })
2590 }
2591 }
2592
2593 pub fn match_token_recovering(
2597 &mut self,
2598 token_type: i32,
2599 follow_state: usize,
2600 atn: &Atn,
2601 ) -> Result<GeneratedMatch, AntlrError> {
2602 let current = self
2603 .input
2604 .lt_ref(1)
2605 .ok_or_else(|| AntlrError::ParserError {
2606 line: 0,
2607 column: 0,
2608 message: "missing current token".to_owned(),
2609 })?;
2610 if current.token_type() == token_type {
2611 self.generated_sync_expected = None;
2612 let consumed_eof = current.token_type() == TOKEN_EOF;
2613 self.consume();
2614 return Ok(GeneratedMatch {
2615 children: vec![ParseTree::Terminal(TerminalNode::from_ref(current))],
2616 consumed_eof,
2617 });
2618 }
2619 let mut expected_symbols = BTreeSet::new();
2620 expected_symbols.insert(token_type);
2621 self.recover_generated_match(
2622 current.as_ref().clone(),
2623 &expected_symbols,
2624 follow_state,
2625 atn,
2626 |symbol| symbol == token_type,
2627 )
2628 }
2629
2630 pub fn match_set_recovering(
2631 &mut self,
2632 intervals: &[(i32, i32)],
2633 follow_state: usize,
2634 atn: &Atn,
2635 ) -> Result<GeneratedMatch, AntlrError> {
2636 let current = self
2637 .input
2638 .lt_ref(1)
2639 .ok_or_else(|| AntlrError::ParserError {
2640 line: 0,
2641 column: 0,
2642 message: "missing current token".to_owned(),
2643 })?;
2644 if interval_set_contains(intervals, current.token_type()) {
2645 self.generated_sync_expected = None;
2646 let consumed_eof = current.token_type() == TOKEN_EOF;
2647 self.consume();
2648 return Ok(GeneratedMatch {
2649 children: vec![ParseTree::Terminal(TerminalNode::from_ref(current))],
2650 consumed_eof,
2651 });
2652 }
2653 let expected_symbols = interval_symbols(intervals);
2654 self.recover_generated_match(
2655 current.as_ref().clone(),
2656 &expected_symbols,
2657 follow_state,
2658 atn,
2659 |symbol| interval_set_contains(intervals, symbol),
2660 )
2661 }
2662
2663 pub fn match_not_set_recovering(
2664 &mut self,
2665 intervals: &[(i32, i32)],
2666 min_vocabulary: i32,
2667 max_vocabulary: i32,
2668 follow_state: usize,
2669 atn: &Atn,
2670 ) -> Result<GeneratedMatch, AntlrError> {
2671 let current = self
2672 .input
2673 .lt_ref(1)
2674 .ok_or_else(|| AntlrError::ParserError {
2675 line: 0,
2676 column: 0,
2677 message: "missing current token".to_owned(),
2678 })?;
2679 if (min_vocabulary..=max_vocabulary).contains(¤t.token_type())
2680 && !interval_set_contains(intervals, current.token_type())
2681 {
2682 self.generated_sync_expected = None;
2683 let consumed_eof = current.token_type() == TOKEN_EOF;
2684 self.consume();
2685 return Ok(GeneratedMatch {
2686 children: vec![ParseTree::Terminal(TerminalNode::from_ref(current))],
2687 consumed_eof,
2688 });
2689 }
2690 let expected_symbols =
2691 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
2692 self.recover_generated_match(
2693 current.as_ref().clone(),
2694 &expected_symbols,
2695 follow_state,
2696 atn,
2697 |symbol| {
2698 (min_vocabulary..=max_vocabulary).contains(&symbol)
2699 && !interval_set_contains(intervals, symbol)
2700 },
2701 )
2702 }
2703
2704 fn recover_generated_match(
2705 &mut self,
2706 current: CommonToken,
2707 expected_symbols: &BTreeSet<i32>,
2708 follow_state: usize,
2709 atn: &Atn,
2710 matches: impl Fn(i32) -> bool,
2711 ) -> Result<GeneratedMatch, AntlrError> {
2712 let expected_display = self.expected_symbols_display(expected_symbols);
2713 if current.token_type() != TOKEN_EOF
2714 && let Some(next) = self.input.lt(2).cloned()
2715 && matches(next.token_type())
2716 {
2717 let message = format!(
2718 "extraneous input {} expecting {expected_display}",
2719 token_input_display(¤t)
2720 );
2721 self.push_generated_parser_diagnostic(diagnostic_for_token(Some(¤t), message));
2722 self.record_syntax_errors(1);
2723 self.generated_sync_expected = None;
2724 let consumed_eof = next.token_type() == TOKEN_EOF;
2727 self.consume();
2728 self.consume();
2729 return Ok(GeneratedMatch {
2730 children: vec![
2731 ParseTree::Error(ErrorNode::new(current)),
2732 ParseTree::Terminal(TerminalNode::new(next)),
2733 ],
2734 consumed_eof,
2735 });
2736 }
2737 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
2738 let follow_explicitly_expects_eof = current.token_type() == TOKEN_EOF
2747 && self
2748 .cached_state_expected_symbols(atn, follow_state)
2749 .contains(&TOKEN_EOF);
2750 if follow_symbols.contains(¤t.token_type())
2751 && (current.token_type() != TOKEN_EOF
2752 || self.rule_context_stack.len() > 1
2753 || expected_symbols.is_empty()
2754 || follow_explicitly_expects_eof)
2755 {
2756 let message = format!(
2757 "missing {expected_display} at {}",
2758 token_input_display(¤t)
2759 );
2760 self.push_generated_parser_diagnostic(diagnostic_for_token(Some(¤t), message));
2761 self.record_syntax_errors(1);
2762 self.generated_sync_expected = None;
2763 let token_type = expected_symbols.iter().next().copied().unwrap_or(TOKEN_EOF);
2764 let mut missing_symbol = BTreeSet::new();
2765 missing_symbol.insert(token_type);
2766 let missing_display = self.expected_symbols_display(&missing_symbol);
2767 let token = CommonToken::new(token_type)
2768 .with_text(format!("<missing {missing_display}>"))
2769 .with_span(usize::MAX, usize::MAX)
2770 .with_position(current.line(), current.column());
2771 return Ok(GeneratedMatch {
2776 children: vec![ParseTree::Error(ErrorNode::new(token))],
2777 consumed_eof: false,
2778 });
2779 }
2780 let mismatch_expected = self.generated_sync_expected.take().map_or_else(
2781 || expected_symbols.clone(),
2782 |symbols| symbols.to_btree_set(),
2783 );
2784 let mismatch_expected_display = self.expected_symbols_display(&mismatch_expected);
2785 Err(AntlrError::ParserError {
2786 line: current.line(),
2787 column: current.column(),
2788 message: format!(
2789 "mismatched input {} expecting {mismatch_expected_display}",
2790 token_input_display(¤t)
2791 ),
2792 })
2793 }
2794
2795 fn generated_recovery_follow_symbols(
2796 &mut self,
2797 atn: &Atn,
2798 follow_state: usize,
2799 ) -> BTreeSet<i32> {
2800 let mut follow = self
2801 .cached_state_expected_symbols(atn, follow_state)
2802 .as_ref()
2803 .clone();
2804 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
2805 follow.extend(self.context_expected_symbols(atn));
2806 }
2807 follow
2808 }
2809
2810 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
2811 self.match_token(TOKEN_EOF)
2812 }
2813
2814 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
2815 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
2816 }
2817
2818 pub fn match_not_set(
2819 &mut self,
2820 intervals: &[(i32, i32)],
2821 min_vocabulary: i32,
2822 max_vocabulary: i32,
2823 ) -> Result<ParseTree, AntlrError> {
2824 self.match_interval_condition(intervals, |symbol| {
2825 (min_vocabulary..=max_vocabulary).contains(&symbol)
2826 && !interval_set_contains(intervals, symbol)
2827 })
2828 }
2829
2830 fn match_interval_condition(
2831 &mut self,
2832 intervals: &[(i32, i32)],
2833 matches: impl FnOnce(i32) -> bool,
2834 ) -> Result<ParseTree, AntlrError> {
2835 let current = self
2836 .input
2837 .lt_ref(1)
2838 .ok_or_else(|| AntlrError::ParserError {
2839 line: 0,
2840 column: 0,
2841 message: "missing current token".to_owned(),
2842 })?;
2843 if matches(current.token_type()) {
2844 self.consume();
2845 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
2846 } else {
2847 Err(AntlrError::MismatchedInput {
2848 expected: self.interval_display(intervals),
2849 found: self.vocabulary().display_name(current.token_type()),
2850 })
2851 }
2852 }
2853
2854 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
2855 let values = intervals
2856 .iter()
2857 .map(|(start, stop)| {
2858 if start == stop {
2859 self.vocabulary().display_name(*start)
2860 } else {
2861 format!(
2862 "{}..{}",
2863 self.vocabulary().display_name(*start),
2864 self.vocabulary().display_name(*stop)
2865 )
2866 }
2867 })
2868 .collect::<Vec<_>>()
2869 .join(", ");
2870 format!("{{{values}}}")
2871 }
2872
2873 pub const fn rule_node(&self, context: ParserRuleContext) -> ParseTree {
2874 ParseTree::Rule(RuleNode::new(context))
2875 }
2876
2877 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
2880 self.set_state(state);
2881 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
2882 self.rule_context_stack.push(RuleContextFrame {
2883 rule_index,
2884 invoking_state,
2885 });
2886 self.invalidate_prediction_context_cache();
2887 let start_index = self.current_visible_index();
2888 let mut context = ParserRuleContext::new(rule_index, invoking_state);
2889 if let Some(token) = self.token_ref_at(start_index) {
2890 context.set_start_ref(token);
2891 }
2892 context
2893 }
2894
2895 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
2902 let marker = self.pending_invoking_states.len();
2903 self.pending_invoking_states.push(invoking_state);
2904 marker
2905 }
2906
2907 pub fn discard_invoking_state(&mut self, marker: usize) {
2909 self.pending_invoking_states.truncate(marker);
2910 }
2911
2912 pub fn exit_rule(&mut self) {
2914 self.rule_context_stack.pop();
2915 self.invalidate_prediction_context_cache();
2916 }
2917
2918 pub fn prediction_context(&mut self, atn: &Atn) -> Rc<PredictionContext> {
2921 let atn_ptr: *const Atn = atn;
2922 let atn_key = atn_ptr as usize;
2923 if let Some(cached) = &self.prediction_context_cache
2924 && cached.version == self.rule_context_version
2925 && cached.atn_key == atn_key
2926 {
2927 return Rc::clone(&cached.context);
2928 }
2929 let mut context = PredictionContext::empty();
2930 for frame in self.rule_context_stack.iter().skip(1) {
2931 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
2932 continue;
2933 };
2934 let Some(Transition::Rule { follow_state, .. }) = atn
2935 .state(state_number)
2936 .and_then(|state| state.transitions.first())
2937 else {
2938 continue;
2939 };
2940 context = PredictionContext::singleton(context, *follow_state);
2941 }
2942 self.prediction_context_cache = Some(CachedPredictionContext {
2943 version: self.rule_context_version,
2944 atn_key,
2945 context: Rc::clone(&context),
2946 });
2947 context
2948 }
2949
2950 fn invalidate_prediction_context_cache(&mut self) {
2951 self.rule_context_version = self.rule_context_version.wrapping_add(1);
2952 self.prediction_context_cache = None;
2953 }
2954
2955 pub fn add_parse_child(&self, context: &mut ParserRuleContext, child: ParseTree) {
2960 if self.build_parse_trees {
2961 context.add_child(child);
2962 } else {
2963 context.note_matched_child();
2964 }
2965 }
2966
2967 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
2969 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
2970 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
2971 context.set_stop_ref(token);
2972 }
2973 self.exit_rule();
2974 self.rule_node(context)
2975 }
2976
2977 pub fn recover_generated_rule(
2984 &mut self,
2985 context: &mut ParserRuleContext,
2986 atn: &Atn,
2987 error: AntlrError,
2988 ) {
2989 let diagnostic = self.generated_rule_error_diagnostic(error);
2990 self.push_generated_parser_diagnostic(diagnostic);
2991 self.generated_sync_expected = None;
2992 let recovery_symbols = self.context_expected_symbols(atn);
2993 loop {
2994 let symbol = self.la(1);
2995 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
2996 break;
2997 }
2998 let Some(token) = self.input.lt(1).cloned() else {
2999 break;
3000 };
3001 self.consume();
3002 self.add_parse_child(context, ParseTree::Error(ErrorNode::new(token)));
3003 }
3004 self.record_syntax_errors(1);
3005 }
3006
3007 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
3008 if self
3009 .generated_parser_diagnostics
3010 .iter()
3011 .any(|existing| existing == &diagnostic)
3012 {
3013 return;
3014 }
3015 self.generated_parser_diagnostics.push(diagnostic);
3016 }
3017
3018 fn generated_rule_error_diagnostic(&mut self, error: AntlrError) -> ParserDiagnostic {
3019 match error {
3020 AntlrError::ParserError {
3021 line,
3022 column,
3023 message,
3024 } => ParserDiagnostic {
3025 line,
3026 column,
3027 message,
3028 },
3029 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
3030 self.input.lt(1),
3031 format!("mismatched input {found} expecting {expected}"),
3032 ),
3033 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
3034 self.input.lt(1),
3035 format!("no viable alternative at input {input}"),
3036 ),
3037 AntlrError::LexerError {
3038 line,
3039 column,
3040 message,
3041 } => ParserDiagnostic {
3042 line,
3043 column,
3044 message,
3045 },
3046 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
3047 }
3048 }
3049
3050 pub fn finish_recursion_rule(
3052 &mut self,
3053 mut context: ParserRuleContext,
3054 consumed_eof: bool,
3055 ) -> ParseTree {
3056 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
3057 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
3058 context.set_stop_ref(token);
3059 }
3060 self.unroll_recursion_context();
3061 self.rule_node(context)
3062 }
3063
3064 pub fn enter_recursion_rule(
3066 &mut self,
3067 state: isize,
3068 rule_index: usize,
3069 precedence: i32,
3070 ) -> ParserRuleContext {
3071 self.precedence_stack.push(precedence);
3072 self.enter_rule(state, rule_index)
3073 }
3074
3075 pub fn push_new_recursion_context(
3077 &mut self,
3078 state: isize,
3079 rule_index: usize,
3080 ) -> ParserRuleContext {
3081 self.set_state(state);
3082 ParserRuleContext::new(rule_index, state)
3083 }
3084
3085 pub fn push_new_recursion_context_with_previous(
3088 &mut self,
3089 state: isize,
3090 rule_index: usize,
3091 current: &mut ParserRuleContext,
3092 ) {
3093 self.set_state(state);
3094 if let Some(stop) = self
3095 .rule_stop_token_index(self.input.index(), false)
3096 .and_then(|index| self.token_ref_at(index))
3097 {
3098 current.set_stop_ref(stop);
3099 }
3100 let invoking_state = current.invoking_state();
3101 let start = current.start_ref();
3102 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
3103 if let Some(start) = start {
3104 replacement.set_start_ref(start);
3105 }
3106 let previous = std::mem::replace(current, replacement);
3107 if self.build_parse_trees {
3108 current.add_child(self.rule_node(previous));
3109 }
3110 }
3111
3112 pub fn unroll_recursion_context(&mut self) {
3114 if self.precedence_stack.len() > 1 {
3115 self.precedence_stack.pop();
3116 }
3117 self.exit_rule();
3118 }
3119
3120 pub fn left_recursive_loop_enter_matches(
3125 &mut self,
3126 atn: &Atn,
3127 state_number: usize,
3128 precedence: i32,
3129 ) -> bool {
3130 let symbol = self.la(1);
3131 if symbol == TOKEN_EOF {
3132 return false;
3133 }
3134 let Some(state) = atn.state(state_number) else {
3135 return false;
3136 };
3137 let context = self.prediction_context(atn);
3138 if context_can_match_symbol_before_state(atn, &context, state_number, symbol) {
3139 return false;
3140 }
3141 state.transitions.iter().any(|transition| {
3142 let target = transition.target();
3143 if atn
3144 .state(target)
3145 .is_some_and(|state| state.kind == AtnStateKind::LoopEnd)
3146 {
3147 return false;
3148 }
3149 state_can_reach_symbol_with_precedence(
3150 atn,
3151 target,
3152 symbol,
3153 precedence,
3154 &mut BTreeSet::new(),
3155 )
3156 })
3157 }
3158
3159 pub fn precpred(&self, precedence: i32) -> bool {
3161 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
3162 }
3163
3164 pub fn parser_semantic_predicate_matches(
3167 &mut self,
3168 predicates: &[(usize, usize, ParserPredicate)],
3169 rule_index: usize,
3170 pred_index: usize,
3171 ) -> bool {
3172 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
3173 }
3174
3175 pub fn parser_semantic_predicate_matches_with_local(
3178 &mut self,
3179 predicates: &[(usize, usize, ParserPredicate)],
3180 rule_index: usize,
3181 pred_index: usize,
3182 local_int_arg: i32,
3183 ) -> bool {
3184 self.parser_semantic_predicate_matches_inner(
3185 predicates,
3186 rule_index,
3187 pred_index,
3188 Some((rule_index, i64::from(local_int_arg))),
3189 )
3190 }
3191
3192 fn parser_semantic_predicate_matches_inner(
3193 &mut self,
3194 predicates: &[(usize, usize, ParserPredicate)],
3195 rule_index: usize,
3196 pred_index: usize,
3197 local_int_arg: Option<(usize, i64)>,
3198 ) -> bool {
3199 let index = self.input.index();
3200 let member_values = self.int_members.clone();
3201 self.parser_predicate_matches(PredicateEval {
3202 index,
3203 rule_index,
3204 pred_index,
3205 predicates,
3206 context: None,
3207 local_int_arg,
3208 member_values: &member_values,
3209 })
3210 }
3211
3212 pub fn parser_semantic_predicate_matches_with_context_and_local(
3215 &mut self,
3216 predicates: &[(usize, usize, ParserPredicate)],
3217 rule_index: usize,
3218 pred_index: usize,
3219 context: &ParserRuleContext,
3220 local_int_arg: i32,
3221 ) -> bool {
3222 let index = self.input.index();
3223 let member_values = self.int_members.clone();
3224 self.parser_predicate_matches(PredicateEval {
3225 index,
3226 rule_index,
3227 pred_index,
3228 predicates,
3229 context: Some(context),
3230 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
3231 member_values: &member_values,
3232 })
3233 }
3234
3235 pub fn parser_semantic_predicate_failure_message(
3238 &self,
3239 rule_index: usize,
3240 pred_index: usize,
3241 predicates: &[(usize, usize, ParserPredicate)],
3242 ) -> Option<&'static str> {
3243 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
3244 }
3245
3246 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
3248 let current = self
3249 .input
3250 .lt_ref(1)
3251 .ok_or_else(|| AntlrError::ParserError {
3252 line: 0,
3253 column: 0,
3254 message: "missing current token".to_owned(),
3255 })?;
3256 if current.token_type() == TOKEN_EOF {
3257 return Err(AntlrError::MismatchedInput {
3258 expected: "wildcard".to_owned(),
3259 found: self.vocabulary().display_name(TOKEN_EOF),
3260 });
3261 }
3262 self.consume();
3263 Ok(ParseTree::Terminal(TerminalNode::from_ref(current)))
3264 }
3265
3266 #[allow(clippy::unnecessary_wraps)]
3270 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
3271 self.set_state(state);
3272 Ok(())
3273 }
3274
3275 pub fn sync_decision(
3283 &mut self,
3284 atn: &Atn,
3285 state_number: usize,
3286 current_context_empty: bool,
3287 loop_back: bool,
3288 ) -> Result<Vec<ParseTree>, AntlrError> {
3289 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
3290 self.generated_sync_expected = None;
3291 let Some(state) = atn.state(state_number) else {
3292 return Ok(Vec::new());
3293 };
3294 let Some(rule_index) = state.rule_index else {
3295 return Ok(Vec::new());
3296 };
3297 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index).copied() else {
3298 return Ok(Vec::new());
3299 };
3300 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
3301 let symbol = self.la(1);
3302 let mut has_expected_symbols = false;
3303 let mut nullable = false;
3304 let mut explicit_eof_expected = false;
3312 for transition in &entry.transitions {
3313 if transition.symbols.contains(symbol) {
3314 return Ok(Vec::new());
3315 }
3316 has_expected_symbols |= !transition.symbols.is_empty();
3317 nullable |= transition.nullable;
3318 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
3319 }
3320 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
3321 if nullable {
3322 if context_expected
3323 .as_ref()
3324 .is_some_and(|expected| expected.contains(symbol))
3325 {
3326 return Ok(Vec::new());
3327 }
3328 }
3329 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
3330 return Ok(Vec::new());
3331 }
3332 let mut expected = TokenBitSet::default();
3333 for transition in &entry.transitions {
3334 expected.extend_from(&transition.symbols);
3335 }
3336 if let Some(context_expected) = context_expected {
3337 expected.extend_from(&context_expected);
3338 }
3339 let can_delete_in_place =
3340 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
3341 let loop_sync = loop_back;
3358 if symbol != TOKEN_EOF && can_delete_in_place {
3359 let mut cursor = self.input.index();
3360 let mut skipped = Vec::new();
3361 loop {
3362 let current = self.token_type_at(cursor);
3363 if current == TOKEN_EOF {
3364 break;
3365 }
3366 skipped.push(cursor);
3367 let next = self.consume_index(cursor, current);
3368 if next == cursor {
3369 break;
3370 }
3371 let next_symbol = self.token_type_at(next);
3372 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
3380 explicit_eof_expected
3381 } else {
3382 expected.contains(next_symbol)
3383 };
3384 if next_is_expected_stop {
3385 let current_token = self.input.lt(1).cloned();
3386 let expected_symbols = expected.to_btree_set();
3387 let message = format!(
3388 "extraneous input {} expecting {}",
3389 current_token
3390 .as_ref()
3391 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
3392 self.expected_symbols_display(&expected_symbols)
3393 );
3394 self.push_generated_parser_diagnostic(diagnostic_for_token(
3395 current_token.as_ref(),
3396 message,
3397 ));
3398 self.record_syntax_errors(1);
3399 let mut children = Vec::with_capacity(skipped.len());
3400 for index in skipped {
3401 if let Some(token) = self.token_at(index) {
3402 self.consume();
3403 children.push(ParseTree::Error(ErrorNode::new(token)));
3404 }
3405 }
3406 return Ok(children);
3407 }
3408 if !loop_sync {
3412 break;
3413 }
3414 cursor = next;
3415 }
3416 }
3417 if nullable {
3418 self.generated_sync_expected = Some(expected);
3419 return Ok(Vec::new());
3420 }
3421 let current = self.input.lt(1).cloned();
3422 let expected_symbols = expected.to_btree_set();
3423 Err(AntlrError::ParserError {
3424 line: current.as_ref().map(Token::line).unwrap_or_default(),
3425 column: current.as_ref().map(Token::column).unwrap_or_default(),
3426 message: format!(
3427 "mismatched input {} expecting {}",
3428 current
3429 .as_ref()
3430 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
3431 self.expected_symbols_display(&expected_symbols)
3432 ),
3433 })
3434 }
3435
3436 pub fn ll1_decision_prediction(
3443 &mut self,
3444 atn: &Atn,
3445 state_number: usize,
3446 ) -> Option<ParserAtnPrediction> {
3447 let state = atn.state(state_number)?;
3448 if state.precedence_rule_decision {
3449 return None;
3450 }
3451 let rule_stop = state
3452 .rule_index
3453 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index).copied())?;
3454 let symbol = self.la(1);
3455 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
3456 ll1_greedy_alt(&entry, symbol, state.non_greedy).map(|alt| ParserAtnPrediction {
3457 alt: alt + 1,
3458 requires_full_context: false,
3459 has_semantic_context: false,
3460 diagnostic: None,
3461 })
3462 }
3463
3464 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
3465 let context = self.prediction_context(atn);
3466 let mut expected = BTreeSet::new();
3467 self.collect_context_expected_symbols(atn, &context, &mut expected);
3468 expected
3469 }
3470
3471 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
3472 let context = self.prediction_context(atn);
3473 let mut expected = TokenBitSet::default();
3474 self.collect_context_expected_token_set(atn, &context, &mut expected);
3475 expected
3476 }
3477
3478 fn collect_context_expected_symbols(
3479 &mut self,
3480 atn: &Atn,
3481 context: &Rc<PredictionContext>,
3482 expected: &mut BTreeSet<i32>,
3483 ) {
3484 if context.is_empty() {
3485 expected.insert(TOKEN_EOF);
3486 return;
3487 }
3488 for index in 0..context.len() {
3489 let Some(return_state) = context.return_state(index) else {
3490 continue;
3491 };
3492 if return_state == EMPTY_RETURN_STATE {
3493 expected.insert(TOKEN_EOF);
3494 continue;
3495 }
3496 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
3497 if self.cached_state_can_reach_rule_stop(atn, return_state)
3498 && let Some(parent) = context.parent(index)
3499 {
3500 self.collect_context_expected_symbols(atn, &parent, expected);
3501 }
3502 }
3503 }
3504
3505 fn collect_context_expected_token_set(
3506 &mut self,
3507 atn: &Atn,
3508 context: &Rc<PredictionContext>,
3509 expected: &mut TokenBitSet,
3510 ) {
3511 if context.is_empty() {
3512 expected.insert(TOKEN_EOF);
3513 return;
3514 }
3515 for index in 0..context.len() {
3516 let Some(return_state) = context.return_state(index) else {
3517 continue;
3518 };
3519 if return_state == EMPTY_RETURN_STATE {
3520 expected.insert(TOKEN_EOF);
3521 continue;
3522 }
3523 let state_expected = self.cached_state_expected_token_set(atn, return_state);
3524 expected.extend_from(&state_expected);
3525 if self.cached_state_can_reach_rule_stop(atn, return_state)
3526 && let Some(parent) = context.parent(index)
3527 {
3528 self.collect_context_expected_token_set(atn, &parent, expected);
3529 }
3530 }
3531 }
3532
3533 pub fn no_viable_alternative_error(&mut self, start_index: usize) -> AntlrError {
3535 let error_index = self.input.index();
3536 self.no_viable_alternative_error_at(start_index, error_index)
3537 }
3538
3539 pub fn no_viable_alternative_error_at(
3544 &mut self,
3545 start_index: usize,
3546 error_index: usize,
3547 ) -> AntlrError {
3548 let diagnostic = self.no_viable_alternative(start_index, error_index);
3549 AntlrError::ParserError {
3550 line: diagnostic.line,
3551 column: diagnostic.column,
3552 message: diagnostic.message,
3553 }
3554 }
3555
3556 pub fn failed_predicate_error(&mut self, message: impl Into<String>) -> AntlrError {
3558 let current = self.input.lt(1).cloned();
3559 AntlrError::ParserError {
3560 line: current.as_ref().map(Token::line).unwrap_or_default(),
3561 column: current.as_ref().map(Token::column).unwrap_or_default(),
3562 message: format!("rule failed predicate: {}", message.into()),
3563 }
3564 }
3565
3566 pub fn failed_predicate_option_error(
3569 &mut self,
3570 rule_index: usize,
3571 message: impl Into<String>,
3572 ) -> AntlrError {
3573 let current = self.input.lt(1).cloned();
3574 let rule_name = self
3575 .rule_names()
3576 .get(rule_index)
3577 .map_or_else(|| rule_index.to_string(), Clone::clone);
3578 AntlrError::ParserError {
3579 line: current.as_ref().map(Token::line).unwrap_or_default(),
3580 column: current.as_ref().map(Token::column).unwrap_or_default(),
3581 message: format!("rule {rule_name} {}", message.into()),
3582 }
3583 }
3584
3585 pub fn parser_action_at_current(
3587 &mut self,
3588 source_state: usize,
3589 rule_index: usize,
3590 start_index: usize,
3591 consumed_eof: bool,
3592 ) -> ParserAction {
3593 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
3594 ParserAction::new(source_state, rule_index, start_index, stop_index)
3595 }
3596
3597 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
3602 &mut self,
3603 atn: &'atn Atn,
3604 simulator: &mut ParserAtnSimulator<'atn>,
3605 rule_index: usize,
3606 ) -> Result<ParseTree, AntlrError> {
3607 let start_index = self.current_visible_index();
3608 self.clear_prediction_diagnostics();
3609 self.reset_per_parse_caches();
3610 let mut decision_by_state = vec![None; atn.states().len()];
3611 for (decision, &state_number) in atn.decision_to_state().iter().enumerate() {
3612 if let Some(slot) = decision_by_state.get_mut(state_number) {
3613 *slot = Some(decision);
3614 }
3615 }
3616
3617 let result = DirectAdaptiveParser {
3618 parser: self,
3619 atn,
3620 simulator,
3621 decision_by_state,
3622 steps: 0,
3623 }
3624 .parse_rule(rule_index, -1, 0);
3625
3626 match result {
3627 Ok(tree) => {
3628 report_token_source_errors(&self.input.drain_source_errors());
3629 Ok(tree)
3630 }
3631 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
3632 let _ = reason;
3633 self.input.seek(start_index);
3634 self.parse_atn_rule(atn, rule_index)
3635 }
3636 }
3637 }
3638
3639 pub fn parse_atn_rule(
3649 &mut self,
3650 atn: &Atn,
3651 rule_index: usize,
3652 ) -> Result<ParseTree, AntlrError> {
3653 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
3654 }
3655
3656 pub fn parse_atn_rule_with_precedence(
3659 &mut self,
3660 atn: &Atn,
3661 rule_index: usize,
3662 precedence: i32,
3663 ) -> Result<ParseTree, AntlrError> {
3664 let start_state = atn
3665 .rule_to_start_state()
3666 .get(rule_index)
3667 .copied()
3668 .ok_or_else(|| {
3669 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
3670 })?;
3671 let stop_state = atn
3672 .rule_to_stop_state()
3673 .get(rule_index)
3674 .copied()
3675 .filter(|state| *state != usize::MAX)
3676 .ok_or_else(|| {
3677 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
3678 })?;
3679
3680 let start_index = self.current_visible_index();
3681 self.clear_prediction_diagnostics();
3682 self.reset_per_parse_caches();
3683 let caller_follow_state = self.pending_invoking_follow_state(atn);
3684 self.fast_recovery_enabled = false;
3685 self.fast_token_nodes_enabled = false;
3686 let top_request = FastRecognizeTopRequest {
3687 start_state,
3688 stop_state,
3689 start_index,
3690 precedence,
3691 caller_follow_state,
3692 };
3693 let first_pass = self.fast_recognize_top(atn, top_request);
3694 self.fast_token_nodes_enabled = true;
3695 self.fast_recovery_enabled = true;
3696 let needs_tree_retry = matches!(
3697 &first_pass,
3698 Ok((outcome, _)) if self.build_parse_trees && outcome.nodes.has_left_recursive_boundary()
3699 );
3700 let needs_retry = match &first_pass {
3701 Err(_) => true,
3714 Ok((outcome, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
3715 };
3716 let (outcome, _expected) = if needs_retry {
3717 self.fast_first_set_prefilter = false;
3718 let retry = self.fast_recognize_top(atn, top_request);
3719 self.fast_first_set_prefilter = true;
3720 let selected = if needs_tree_retry {
3721 match retry {
3722 ok @ Ok(_) => ok,
3723 Err(_) => first_pass,
3724 }
3725 } else {
3726 select_better_top_outcome(first_pass, retry)
3727 };
3728 selected.map_err(|expected| {
3729 let error = self.recognition_error(rule_index, start_index, &expected);
3730 self.record_syntax_errors(1);
3731 report_token_source_errors(&self.input.drain_source_errors());
3732 error
3733 })?
3734 } else {
3735 first_pass.expect("first_pass is Ok in the no-retry branch")
3736 };
3737 self.record_syntax_errors(outcome.diagnostics.len());
3738 report_parser_diagnostics(&self.prediction_diagnostics);
3739 report_parser_diagnostics(&outcome.diagnostics);
3740 report_token_source_errors(&self.input.drain_source_errors());
3741 let mut context = ParserRuleContext::with_child_capacity(
3742 rule_index,
3743 self.state(),
3744 if self.build_parse_trees {
3745 outcome.nodes.len()
3746 } else {
3747 0
3748 },
3749 );
3750 if let Some(token) = self.token_ref_at(start_index) {
3751 context.set_start_ref(token);
3752 }
3753 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
3754 if let Some(token) = stop_index.and_then(|token_index| self.token_ref_at(token_index)) {
3755 context.set_stop_ref(token);
3756 }
3757 if self.build_parse_trees {
3758 if outcome.nodes.has_left_recursive_boundary() {
3759 let folded = fold_fast_left_recursive_boundaries(outcome.nodes.to_vec());
3760 if folded.iter().any(|node| {
3761 matches!(
3762 node.as_ref(),
3763 FastRecognizedNode::Token { .. }
3764 | FastRecognizedNode::ErrorToken { .. }
3765 | FastRecognizedNode::MissingToken { .. }
3766 )
3767 }) {
3768 for node in &folded {
3769 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
3770 }
3771 } else {
3772 self.add_fast_implicit_token_children(
3773 &mut context,
3774 start_index,
3775 stop_index,
3776 &folded,
3777 )?;
3778 }
3779 } else if outcome.nodes.has_explicit_token_node() {
3780 for node in outcome.nodes.iter() {
3781 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
3782 }
3783 } else {
3784 self.add_fast_implicit_token_children_iter(
3785 &mut context,
3786 start_index,
3787 stop_index,
3788 outcome.nodes.iter(),
3789 )?;
3790 }
3791 }
3792 self.input.seek(outcome.index);
3793
3794 Ok(self.rule_node(context))
3795 }
3796
3797 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
3798 let invoking_state = self.pending_invoking_states.last().copied()?;
3799 let state_number = usize::try_from(invoking_state).ok()?;
3800 match atn.state(state_number)?.transitions.first()? {
3801 Transition::Rule { follow_state, .. } => Some(*follow_state),
3802 _ => None,
3803 }
3804 }
3805
3806 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
3807 let token_type = self.token_type_at(index);
3810 let visible_channel = self.input.channel();
3811 let token = self.token_at(index);
3812 let is_boundary = token
3813 .as_ref()
3814 .and_then(Token::text)
3815 .is_some_and(is_caller_follow_boundary_text);
3816 let is_boundary_gap = token.as_ref().is_some_and(|token| {
3817 token.channel() != visible_channel
3818 || token.text().is_some_and(is_caller_follow_boundary_gap_text)
3819 });
3820 (token_type, is_boundary, is_boundary_gap)
3821 }
3822
3823 fn fast_recognize_top(
3828 &mut self,
3829 atn: &Atn,
3830 request: FastRecognizeTopRequest,
3831 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
3832 let FastRecognizeTopRequest {
3833 start_state,
3834 stop_state,
3835 start_index,
3836 precedence,
3837 caller_follow_state,
3838 } = request;
3839 let memo_capacity = self.input.size().saturating_mul(8).clamp(65_536, 524_288);
3848 let mut visiting = FxHashSet::with_capacity_and_hasher(256, FxBuildHasher::default());
3849 let mut memo = FxHashMap::with_capacity_and_hasher(memo_capacity, FxBuildHasher::default());
3850 let mut expected = ExpectedTokens::default();
3851 let empty_recovery = self.empty_recovery_symbols();
3852 let outcomes = self.recognize_state_fast(
3853 atn,
3854 FastRecognizeRequest {
3855 state_number: start_state,
3856 stop_state,
3857 index: start_index,
3858 rule_start_index: start_index,
3859 decision_start_index: None,
3860 precedence,
3861 depth: 0,
3862 recovery_symbols: empty_recovery,
3863 recovery_state: None,
3864 },
3865 &mut visiting,
3866 &mut memo,
3867 &mut expected,
3868 );
3869 #[cfg(feature = "perf-counters")]
3870 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
3871 perf_counters::dump();
3872 perf_counters::reset();
3873 }
3874 let caller_follow =
3875 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
3876 match select_best_fast_outcome(
3877 outcomes.into_iter(),
3878 self.prediction_mode,
3879 caller_follow.as_deref(),
3880 |index| self.caller_follow_token_info(index),
3881 ) {
3882 Some(outcome) => Ok((outcome, expected)),
3883 None => Err(expected),
3884 }
3885 }
3886
3887 fn fast_recognized_node_tree(
3890 &mut self,
3891 node: &FastRecognizedNode,
3892 ) -> Result<ParseTree, AntlrError> {
3893 match node {
3894 FastRecognizedNode::Token { index } => {
3895 let token = self
3896 .input
3897 .get_ref(*index)
3898 .ok_or_else(|| AntlrError::ParserError {
3899 line: 0,
3900 column: 0,
3901 message: format!("missing token at index {index}"),
3902 })?;
3903 Ok(ParseTree::Terminal(TerminalNode::from_ref(token)))
3904 }
3905 FastRecognizedNode::ErrorToken { index } => {
3906 let token = self
3907 .input
3908 .get_ref(*index)
3909 .ok_or_else(|| AntlrError::ParserError {
3910 line: 0,
3911 column: 0,
3912 message: format!("missing error token at index {index}"),
3913 })?;
3914 Ok(ParseTree::Error(ErrorNode::from_ref(token)))
3915 }
3916 FastRecognizedNode::MissingToken {
3917 token_type,
3918 at_index,
3919 text,
3920 } => {
3921 let current = self.token_at(*at_index);
3922 let token = CommonToken::new(*token_type)
3923 .with_text(text.as_str())
3924 .with_span(usize::MAX, usize::MAX)
3925 .with_position(
3926 current.as_ref().map(Token::line).unwrap_or_default(),
3927 current.as_ref().map(Token::column).unwrap_or_default(),
3928 );
3929 Ok(ParseTree::Error(ErrorNode::new(token)))
3930 }
3931 FastRecognizedNode::Rule {
3932 rule_index,
3933 invoking_state,
3934 start_index,
3935 stop_index,
3936 children,
3937 } => {
3938 let mut context = ParserRuleContext::with_child_capacity(
3939 *rule_index,
3940 *invoking_state,
3941 children.len(),
3942 );
3943 if let Some(token) = self.token_ref_at(*start_index) {
3944 context.set_start_ref(token);
3945 }
3946 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
3947 context.set_stop_ref(token);
3948 }
3949 if children.has_left_recursive_boundary() {
3950 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
3951 for child in &folded {
3952 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
3953 }
3954 } else {
3955 for child in children.iter() {
3956 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
3957 }
3958 }
3959 Ok(self.rule_node(context))
3960 }
3961 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
3962 Err(AntlrError::Unsupported(format!(
3963 "unfolded left-recursive boundary for rule {rule_index}"
3964 )))
3965 }
3966 }
3967 }
3968
3969 fn fast_recognized_node_tree_with_implicit_tokens(
3970 &mut self,
3971 node: &FastRecognizedNode,
3972 ) -> Result<ParseTree, AntlrError> {
3973 match node {
3974 FastRecognizedNode::Rule {
3975 rule_index,
3976 invoking_state,
3977 start_index,
3978 stop_index,
3979 children,
3980 } => {
3981 let mut context = ParserRuleContext::with_child_capacity(
3982 *rule_index,
3983 *invoking_state,
3984 children.len(),
3985 );
3986 if let Some(token) = self.token_ref_at(*start_index) {
3987 context.set_start_ref(token);
3988 }
3989 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
3990 context.set_stop_ref(token);
3991 }
3992 if children.has_left_recursive_boundary() {
3993 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
3994 self.add_fast_implicit_token_children(
3995 &mut context,
3996 *start_index,
3997 *stop_index,
3998 &folded,
3999 )?;
4000 } else {
4001 self.add_fast_implicit_token_children_iter(
4002 &mut context,
4003 *start_index,
4004 *stop_index,
4005 children.iter(),
4006 )?;
4007 }
4008 Ok(self.rule_node(context))
4009 }
4010 _ => self.fast_recognized_node_tree(node),
4011 }
4012 }
4013
4014 fn add_fast_implicit_token_children(
4015 &mut self,
4016 context: &mut ParserRuleContext,
4017 start_index: usize,
4018 stop_index: Option<usize>,
4019 children: &[Rc<FastRecognizedNode>],
4020 ) -> Result<(), AntlrError> {
4021 self.add_fast_implicit_token_children_iter(
4022 context,
4023 start_index,
4024 stop_index,
4025 children.iter(),
4026 )
4027 }
4028
4029 fn add_fast_implicit_token_children_iter<'a>(
4030 &mut self,
4031 context: &mut ParserRuleContext,
4032 start_index: usize,
4033 stop_index: Option<usize>,
4034 children: impl IntoIterator<Item = &'a Rc<FastRecognizedNode>>,
4035 ) -> Result<(), AntlrError> {
4036 let mut cursor = Some(start_index);
4037 for child in children {
4038 if let Some((child_start, child_stop)) = fast_recognized_node_span(child.as_ref()) {
4039 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
4040 context.add_child(
4041 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
4042 );
4043 if let Some(child_stop) = child_stop {
4044 cursor = self.next_visible_after_token(child_stop);
4045 }
4046 } else {
4047 context.add_child(
4048 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
4049 );
4050 }
4051 }
4052 if let Some(stop) = stop_index {
4053 self.add_visible_terminals_through(context, cursor, stop)?;
4054 }
4055 Ok(())
4056 }
4057
4058 fn add_visible_terminals_before(
4059 &mut self,
4060 context: &mut ParserRuleContext,
4061 cursor: &mut Option<usize>,
4062 before: usize,
4063 ) -> Result<(), AntlrError> {
4064 let Some(stop) = before.checked_sub(1) else {
4065 return Ok(());
4066 };
4067 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
4068 *cursor = next;
4069 Ok(())
4070 }
4071
4072 fn add_visible_terminals_through(
4073 &mut self,
4074 context: &mut ParserRuleContext,
4075 mut cursor: Option<usize>,
4076 stop: usize,
4077 ) -> Result<Option<usize>, AntlrError> {
4078 while let Some(index) = cursor {
4079 if index > stop {
4080 return Ok(Some(index));
4081 }
4082 let token = self
4083 .input
4084 .get_ref(index)
4085 .ok_or_else(|| AntlrError::ParserError {
4086 line: 0,
4087 column: 0,
4088 message: format!("missing token at index {index}"),
4089 })?;
4090 let is_eof = token.token_type() == TOKEN_EOF;
4091 context.add_child(ParseTree::Terminal(TerminalNode::from_ref(token)));
4092 if is_eof {
4093 return Ok(None);
4094 }
4095 cursor = self.next_visible_after_token(index);
4096 }
4097 Ok(None)
4098 }
4099
4100 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
4101 let next = self.input.next_visible_after(index);
4102 (next != index).then_some(next)
4103 }
4104
4105 pub fn parse_atn_rule_with_actions(
4112 &mut self,
4113 atn: &Atn,
4114 rule_index: usize,
4115 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4116 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
4117 }
4118
4119 pub fn parse_atn_rule_with_action_inits(
4127 &mut self,
4128 atn: &Atn,
4129 rule_index: usize,
4130 init_action_rules: &[usize],
4131 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4132 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
4133 }
4134
4135 pub fn parse_atn_rule_with_action_options(
4141 &mut self,
4142 atn: &Atn,
4143 rule_index: usize,
4144 init_action_rules: &[usize],
4145 track_alt_numbers: bool,
4146 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4147 self.parse_atn_rule_with_runtime_options(
4148 atn,
4149 rule_index,
4150 ParserRuntimeOptions {
4151 init_action_rules,
4152 track_alt_numbers,
4153 ..ParserRuntimeOptions::default()
4154 },
4155 )
4156 }
4157
4158 pub fn parse_atn_rule_with_runtime_options(
4165 &mut self,
4166 atn: &Atn,
4167 rule_index: usize,
4168 options: ParserRuntimeOptions<'_>,
4169 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4170 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
4171 }
4172
4173 pub fn parse_atn_rule_with_runtime_options_and_precedence(
4176 &mut self,
4177 atn: &Atn,
4178 rule_index: usize,
4179 precedence: i32,
4180 options: ParserRuntimeOptions<'_>,
4181 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4182 let ParserRuntimeOptions {
4183 init_action_rules,
4184 track_alt_numbers,
4185 predicates,
4186 rule_args,
4187 member_actions,
4188 return_actions,
4189 } = options;
4190 let start_state = atn
4191 .rule_to_start_state()
4192 .get(rule_index)
4193 .copied()
4194 .ok_or_else(|| {
4195 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
4196 })?;
4197 let stop_state = atn
4198 .rule_to_stop_state()
4199 .get(rule_index)
4200 .copied()
4201 .filter(|state| *state != usize::MAX)
4202 .ok_or_else(|| {
4203 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
4204 })?;
4205
4206 let start_index = self.current_visible_index();
4207 self.clear_prediction_diagnostics();
4208 self.reset_per_parse_caches();
4209 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
4210 let invoking_state = self.pending_invoking_states.pop();
4211 let local_int_arg = invoking_state
4212 .and_then(|state| usize::try_from(state).ok())
4213 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
4214 let mut visiting = BTreeSet::new();
4215 let mut memo = BTreeMap::new();
4216 let mut expected = ExpectedTokens::default();
4217 let member_values = self.int_members.clone();
4218 let return_values = BTreeMap::new();
4219 let outcomes = self.recognize_state(
4220 atn,
4221 RecognizeRequest {
4222 state_number: start_state,
4223 stop_state,
4224 index: start_index,
4225 rule_start_index: start_index,
4226 decision_start_index: None,
4227 init_action_rules: &init_action_rules,
4228 predicates,
4229 rule_args,
4230 member_actions,
4231 return_actions,
4232 local_int_arg,
4233 member_values,
4234 return_values,
4235 rule_alt_number: 0,
4236 track_alt_numbers,
4237 consumed_eof: false,
4238 precedence,
4239 depth: 0,
4240 recovery_symbols: BTreeSet::new(),
4241 recovery_state: None,
4242 },
4243 &mut visiting,
4244 &mut memo,
4245 &mut expected,
4246 );
4247 let Some(outcome) = select_best_outcome(outcomes.into_iter(), self.prediction_mode) else {
4248 let error = self.recognition_error(rule_index, start_index, &expected);
4249 self.record_syntax_errors(1);
4250 report_token_source_errors(&self.input.drain_source_errors());
4251 return Err(error);
4252 };
4253
4254 self.record_syntax_errors(outcome.diagnostics.len());
4255 report_parser_diagnostics(&self.prediction_diagnostics);
4256 report_parser_diagnostics(&outcome.diagnostics);
4257 report_token_source_errors(&self.input.drain_source_errors());
4258 let mut actions = outcome.actions;
4259 if init_action_rules.contains(&rule_index) {
4260 actions.insert(
4261 0,
4262 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
4263 );
4264 }
4265 let mut context =
4266 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
4267 if track_alt_numbers {
4268 context.set_alt_number(outcome.alt_number);
4269 }
4270 for (name, value) in outcome.return_values {
4271 context.set_int_return(name, value);
4272 }
4273 if let Some(token) = self.token_ref_at(start_index) {
4274 context.set_start_ref(token);
4275 }
4276 if let Some(token) = self.rule_stop_token_ref(outcome.index, outcome.consumed_eof) {
4277 context.set_stop_ref(token);
4278 }
4279 if self.build_parse_trees {
4280 let nodes = fold_left_recursive_boundaries(outcome.nodes);
4281 for node in &nodes {
4282 context.add_child(self.recognized_node_tree(node, track_alt_numbers)?);
4283 }
4284 }
4285 self.input.seek(outcome.index);
4286
4287 Ok((self.rule_node(context), actions))
4288 }
4289
4290 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
4297 let mut context = ParserRuleContext::new(rule_index, self.state());
4298 while self.la(1) != TOKEN_EOF {
4299 let token_type = self.la(1);
4300 let child = self.match_token(token_type)?;
4301 if self.build_parse_trees {
4302 context.add_child(child);
4303 }
4304 }
4305 if self.build_parse_trees {
4306 context.add_child(self.match_eof()?);
4307 }
4308 Ok(self.rule_node(context))
4309 }
4310
4311 fn recognition_error(
4314 &mut self,
4315 rule_index: usize,
4316 start_index: usize,
4317 expected: &ExpectedTokens,
4318 ) -> AntlrError {
4319 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
4320 self.input.seek(index);
4321 let current = self.input.lt(1).cloned();
4322 let line = current.as_ref().map(Token::line).unwrap_or_default();
4323 let column = current.as_ref().map(Token::column).unwrap_or_default();
4324 AntlrError::ParserError {
4325 line,
4326 column,
4327 message,
4328 }
4329 }
4330
4331 fn expected_error_message(
4333 &mut self,
4334 rule_index: usize,
4335 start_index: usize,
4336 expected: &ExpectedTokens,
4337 ) -> (usize, String) {
4338 let index = expected
4339 .index
4340 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
4341 .unwrap_or_else(|| self.input.index());
4342 self.input.seek(index);
4343 let current = self.input.lt(1).cloned();
4344 let message = if expected
4345 .no_viable
4346 .as_ref()
4347 .is_some_and(|no_viable| no_viable.error_index == index)
4348 {
4349 let start = expected
4350 .no_viable
4351 .as_ref()
4352 .map_or(start_index, |no_viable| no_viable.start_index);
4353 let text = display_input_text(&self.input.text(start, index));
4354 format!("no viable alternative at input '{text}'")
4355 } else if expected.symbols.is_empty() {
4356 if expected.index.is_some() {
4357 let found = current
4358 .as_ref()
4359 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
4360 if current
4361 .as_ref()
4362 .is_some_and(|token| token.token_type() == TOKEN_EOF)
4363 {
4364 format!(
4365 "missing {} at {found}",
4366 self.expected_symbols_display(&expected.symbols)
4367 )
4368 } else {
4369 format!("mismatched input {found}")
4370 }
4371 } else {
4372 format!("no viable alternative while parsing rule {rule_index}")
4373 }
4374 } else {
4375 format!(
4376 "mismatched input {} expecting {}",
4377 current
4378 .as_ref()
4379 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
4380 self.expected_symbols_display(&expected.symbols)
4381 )
4382 };
4383 (index, message)
4384 }
4385
4386 fn child_rule_failure_recovery(
4389 &mut self,
4390 rule_index: usize,
4391 start_index: usize,
4392 sync_symbols: &BTreeSet<i32>,
4393 member_values: BTreeMap<usize, i64>,
4394 expected: &ExpectedTokens,
4395 ) -> Option<RecognizeOutcome> {
4396 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
4397 let token = self.token_at(error_index);
4398 let mut next_index = error_index;
4399 loop {
4400 let symbol = self.token_type_at(next_index);
4401 if sync_symbols.contains(&symbol) {
4402 if next_index == error_index {
4403 return None;
4404 }
4405 break;
4406 }
4407 if symbol == TOKEN_EOF {
4408 break;
4409 }
4410 let after = self.consume_index(next_index, symbol);
4411 if after == next_index {
4412 break;
4413 }
4414 next_index = after;
4415 }
4416 Some(RecognizeOutcome {
4417 index: next_index,
4418 consumed_eof: false,
4419 alt_number: 0,
4420 member_values,
4421 return_values: BTreeMap::new(),
4422 diagnostics: vec![diagnostic_for_token(token.as_ref(), message)],
4423 decisions: Vec::new(),
4424 actions: Vec::new(),
4425 nodes: vec![RecognizedNode::ErrorToken { index: error_index }],
4426 })
4427 }
4428
4429 fn child_rule_failure_recovery_outcomes(
4432 &mut self,
4433 request: ChildRuleFailureRecovery<'_>,
4434 ) -> Vec<RecognizeOutcome> {
4435 let sync_symbols =
4436 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
4437 self.child_rule_failure_recovery(
4438 request.rule_index,
4439 request.start_index,
4440 &sync_symbols,
4441 request.member_values,
4442 request.expected,
4443 )
4444 .into_iter()
4445 .collect()
4446 }
4447
4448 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
4450 expected_symbols_display(symbols, self.vocabulary())
4451 }
4452
4453 fn single_token_deletion(
4456 &mut self,
4457 transition: &Transition,
4458 index: usize,
4459 max_token_type: i32,
4460 expected_symbols: &BTreeSet<i32>,
4461 ) -> Option<(ParserDiagnostic, usize, i32)> {
4462 let current_symbol = self.token_type_at(index);
4463 if current_symbol == TOKEN_EOF {
4464 return None;
4465 }
4466 let next_index = self.consume_index(index, current_symbol);
4467 if next_index == index {
4468 return None;
4469 }
4470 let next_symbol = self.token_type_at(next_index);
4471 if !transition.matches(next_symbol, 1, max_token_type) {
4472 return None;
4473 }
4474 let transition_expected = transition_expected_symbols(transition, max_token_type);
4475 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
4476 &transition_expected
4477 } else {
4478 expected_symbols
4479 });
4480 let current = self.token_at(index);
4481 let message = format!(
4482 "extraneous input {} expecting {expected_display}",
4483 current
4484 .as_ref()
4485 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
4486 );
4487 Some((
4488 diagnostic_for_token(current.as_ref(), message),
4489 next_index,
4490 next_symbol,
4491 ))
4492 }
4493
4494 fn current_token_deletion(
4497 &mut self,
4498 index: usize,
4499 expected_symbols: &BTreeSet<i32>,
4500 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
4501 if expected_symbols.is_empty() {
4502 return None;
4503 }
4504 let current_symbol = self.token_type_at(index);
4505 if current_symbol == TOKEN_EOF {
4506 return None;
4507 }
4508 let current = self.token_at(index);
4509 let message = format!(
4510 "extraneous input {} expecting {}",
4511 current
4512 .as_ref()
4513 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
4514 self.expected_symbols_display(expected_symbols)
4515 );
4516 let diagnostic = diagnostic_for_token(current.as_ref(), message);
4517 let mut skipped = Vec::new();
4518 let mut cursor = index;
4519 loop {
4520 let symbol = self.token_type_at(cursor);
4521 if symbol == TOKEN_EOF {
4522 return None;
4523 }
4524 skipped.push(cursor);
4525 let next_index = self.consume_index(cursor, symbol);
4526 if next_index == cursor {
4527 return None;
4528 }
4529 let next_symbol = self.token_type_at(next_index);
4530 if expected_symbols.contains(&next_symbol) {
4531 return Some((diagnostic, next_index, skipped));
4532 }
4533 cursor = next_index;
4534 }
4535 }
4536
4537 fn single_token_insertion(
4541 &mut self,
4542 transition: &Transition,
4543 index: usize,
4544 max_token_type: i32,
4545 expected_symbols: &BTreeSet<i32>,
4546 follow_symbols: &BTreeSet<i32>,
4547 ) -> Option<(ParserDiagnostic, i32, String)> {
4548 let current_symbol = self.token_type_at(index);
4549 if !follow_symbols.contains(¤t_symbol) {
4550 return None;
4551 }
4552 let transition_expected = transition_expected_symbols(transition, max_token_type);
4553 let token_type = transition_expected.iter().next().copied()?;
4554 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
4555 &transition_expected
4556 } else {
4557 expected_symbols
4558 });
4559 let mut token_symbols = BTreeSet::new();
4560 token_symbols.insert(token_type);
4561 let missing_token_display = self.expected_symbols_display(&token_symbols);
4562 let current = self.token_at(index);
4563 let message = format!(
4564 "missing {expected_display} at {}",
4565 current
4566 .as_ref()
4567 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
4568 );
4569 let text = format!("<missing {missing_token_display}>");
4570 Some((
4571 diagnostic_for_token(current.as_ref(), message),
4572 token_type,
4573 text,
4574 ))
4575 }
4576
4577 fn fast_single_token_deletion_recovery(
4581 &mut self,
4582 recovery: FastRecoveryRequest<'_, '_>,
4583 ) -> Vec<FastRecognizeOutcome> {
4584 let FastRecoveryRequest {
4585 atn,
4586 transition,
4587 expected_symbols,
4588 target,
4589 request,
4590 visiting,
4591 memo,
4592 expected,
4593 } = recovery;
4594 let FastRecognizeRequest {
4595 stop_state,
4596 index,
4597 rule_start_index,
4598 decision_start_index,
4599 precedence,
4600 depth,
4601 ..
4602 } = request;
4603 let Some((diagnostic, next_index, next_symbol)) =
4604 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
4605 else {
4606 return Vec::new();
4607 };
4608 let after_next = self.consume_index(next_index, next_symbol);
4609 let empty_recovery = self.empty_recovery_symbols();
4610 self.recognize_state_fast(
4611 atn,
4612 FastRecognizeRequest {
4613 state_number: target,
4614 stop_state,
4615 index: after_next,
4616 rule_start_index,
4617 decision_start_index,
4618 precedence,
4619 depth: depth + 1,
4620 recovery_symbols: empty_recovery,
4621 recovery_state: None,
4622 },
4623 visiting,
4624 memo,
4625 expected,
4626 )
4627 .into_iter()
4628 .map(|mut outcome| {
4629 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
4630 outcome.diagnostics.insert(0, diagnostic.clone());
4631 if self.fast_token_nodes_enabled {
4632 outcome
4633 .nodes
4634 .prepend(Rc::new(FastRecognizedNode::Token { index: next_index }));
4635 outcome
4636 .nodes
4637 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index }));
4638 }
4639 outcome
4640 })
4641 .collect()
4642 }
4643
4644 fn fast_single_token_insertion_recovery(
4648 &mut self,
4649 recovery: FastRecoveryRequest<'_, '_>,
4650 ) -> Vec<FastRecognizeOutcome> {
4651 let FastRecoveryRequest {
4652 atn,
4653 transition,
4654 expected_symbols,
4655 target,
4656 request,
4657 visiting,
4658 memo,
4659 expected,
4660 } = recovery;
4661 let FastRecognizeRequest {
4662 stop_state,
4663 index,
4664 rule_start_index,
4665 decision_start_index,
4666 precedence,
4667 depth,
4668 ..
4669 } = request;
4670 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
4671 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
4672 transition,
4673 index,
4674 atn.max_token_type(),
4675 &expected_symbols,
4676 &follow_symbols,
4677 ) else {
4678 return Vec::new();
4679 };
4680 let empty_recovery = self.empty_recovery_symbols();
4681 self.recognize_state_fast(
4682 atn,
4683 FastRecognizeRequest {
4684 state_number: target,
4685 stop_state,
4686 index,
4687 rule_start_index,
4688 decision_start_index,
4689 precedence,
4690 depth: depth + 1,
4691 recovery_symbols: empty_recovery,
4692 recovery_state: None,
4693 },
4694 visiting,
4695 memo,
4696 expected,
4697 )
4698 .into_iter()
4699 .map(|mut outcome| {
4700 outcome.diagnostics.insert(0, diagnostic.clone());
4701 outcome
4702 .nodes
4703 .prepend(Rc::new(FastRecognizedNode::MissingToken {
4704 token_type,
4705 at_index: index,
4706 text: text.clone(),
4707 }));
4708 outcome
4709 })
4710 .collect()
4711 }
4712
4713 fn fast_current_token_deletion_recovery(
4716 &mut self,
4717 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
4718 ) -> Vec<FastRecognizeOutcome> {
4719 let FastCurrentTokenDeletionRequest {
4720 atn,
4721 expected_symbols,
4722 mut request,
4723 visiting,
4724 memo,
4725 expected,
4726 } = recovery;
4727 if request.index == request.rule_start_index {
4728 return Vec::new();
4729 }
4730 let Some((diagnostic, next_index, skipped)) =
4731 self.current_token_deletion(request.index, &expected_symbols)
4732 else {
4733 return Vec::new();
4734 };
4735 request.state_number = request.recovery_state.unwrap_or(request.state_number);
4736 request.index = next_index;
4737 request.depth += 1;
4738 request.recovery_state = None;
4739 self.recognize_state_fast(atn, request, visiting, memo, expected)
4740 .into_iter()
4741 .map(|mut outcome| {
4742 outcome.diagnostics.insert(0, diagnostic.clone());
4743 for index in skipped.iter().rev() {
4744 outcome
4745 .nodes
4746 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index: *index }));
4747 }
4748 outcome
4749 })
4750 .collect()
4751 }
4752
4753 fn fast_child_rule_failure_recovery(
4756 &mut self,
4757 rule_index: usize,
4758 start_index: usize,
4759 sync_symbols: &BTreeSet<i32>,
4760 expected: &ExpectedTokens,
4761 ) -> Option<FastRecognizeOutcome> {
4762 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
4763 let token = self.token_at(error_index);
4764 let mut next_index = error_index;
4765 loop {
4766 let symbol = self.token_type_at(next_index);
4767 if sync_symbols.contains(&symbol) {
4768 if next_index == error_index {
4769 return None;
4770 }
4771 break;
4772 }
4773 if symbol == TOKEN_EOF {
4774 break;
4775 }
4776 let after = self.consume_index(next_index, symbol);
4777 if after == next_index {
4778 break;
4779 }
4780 next_index = after;
4781 }
4782 let mut diagnostics = FastDiagnostics::new();
4783 diagnostics.insert(0, diagnostic_for_token(token.as_ref(), message));
4784 let mut nodes = NodeList::new();
4785 if self.fast_token_nodes_enabled {
4786 nodes.prepend(Rc::new(FastRecognizedNode::ErrorToken {
4787 index: error_index,
4788 }));
4789 }
4790 Some(FastRecognizeOutcome {
4791 index: next_index,
4792 consumed_eof: false,
4793 diagnostics,
4794 nodes,
4795 })
4796 }
4797
4798 fn fast_child_rule_failure_recovery_outcomes(
4801 &mut self,
4802 request: FastChildRuleFailureRecoveryRequest<'_>,
4803 ) -> Vec<FastRecognizeOutcome> {
4804 let FastChildRuleFailureRecoveryRequest {
4805 atn,
4806 rule_index,
4807 start_index,
4808 follow_state,
4809 stop_state,
4810 expected,
4811 } = request;
4812 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
4813 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
4814 .into_iter()
4815 .collect()
4816 }
4817
4818 #[allow(clippy::too_many_lines)]
4821 fn recognize_state_fast(
4822 &mut self,
4823 atn: &Atn,
4824 request: FastRecognizeRequest,
4825 visiting: &mut FxHashSet<(usize, usize)>,
4826 memo: &mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4827 expected: &mut ExpectedTokens,
4828 ) -> Vec<FastRecognizeOutcome> {
4829 #[cfg(feature = "perf-counters")]
4830 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
4831 let FastRecognizeRequest {
4832 mut state_number,
4833 stop_state,
4834 mut index,
4835 rule_start_index,
4836 decision_start_index,
4837 precedence,
4838 mut depth,
4839 recovery_symbols,
4840 recovery_state,
4841 } = request;
4842 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
4861 let mut inline_consumed_eof = false;
4862 loop {
4863 if depth > RECOGNITION_DEPTH_LIMIT {
4864 return Vec::new();
4865 }
4866 if state_number == stop_state {
4867 let mut nodes = NodeList::new();
4868 if self.fast_token_nodes_enabled {
4869 for token_index in inline_consumed_tokens.iter().rev() {
4870 nodes.prepend(Rc::new(FastRecognizedNode::Token {
4871 index: *token_index,
4872 }));
4873 }
4874 }
4875 return vec![FastRecognizeOutcome {
4876 index,
4877 consumed_eof: inline_consumed_eof,
4878 diagnostics: FastDiagnostics::new(),
4879 nodes,
4880 }];
4881 }
4882 let Some(state) = atn.state(state_number) else {
4883 return Vec::new();
4884 };
4885 if state.transitions.len() == 1
4886 && !starts_prediction_decision(state)
4887 && !state.precedence_rule_decision
4888 {
4889 match &state.transitions[0] {
4890 Transition::Epsilon { target }
4891 | Transition::Predicate { target, .. }
4892 | Transition::Action { target, .. }
4893 if left_recursive_boundary(atn, state, *target).is_none() =>
4894 {
4895 #[cfg(feature = "perf-counters")]
4896 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
4897 state_number = *target;
4898 depth += 1;
4899 continue;
4900 }
4901 Transition::Precedence {
4902 target,
4903 precedence: transition_precedence,
4904 } if *transition_precedence >= precedence
4905 && left_recursive_boundary(atn, state, *target).is_none() =>
4906 {
4907 #[cfg(feature = "perf-counters")]
4908 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
4909 state_number = *target;
4910 depth += 1;
4911 continue;
4912 }
4913 Transition::Atom { target, .. }
4923 | Transition::Range { target, .. }
4924 | Transition::Set { target, .. }
4925 | Transition::NotSet { target, .. }
4926 | Transition::Wildcard { target, .. }
4927 if !self.fast_recovery_enabled =>
4928 {
4929 let symbol = self.token_type_at(index);
4930 let transition = &state.transitions[0];
4931 if transition.matches(symbol, 1, atn.max_token_type()) {
4932 #[cfg(feature = "perf-counters")]
4933 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
4934 if self.fast_token_nodes_enabled {
4935 inline_consumed_tokens.push(index);
4936 }
4937 inline_consumed_eof |= symbol == TOKEN_EOF;
4938 index = self.consume_index(index, symbol);
4939 state_number = *target;
4940 depth += 1;
4941 continue;
4942 }
4943 }
4946 _ => {}
4947 }
4948 }
4949 break;
4950 }
4951 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
4955 let Some(state) = atn.state(state_number) else {
4956 return Vec::new();
4957 };
4958 let transition_count = state.transitions.len();
4959 let memo_lookup_enabled = self.fast_recovery_enabled || transition_count > 1;
4960 let key = if self.fast_recovery_enabled {
4970 FastRecognizeKey {
4971 state_number,
4972 stop_state,
4973 index,
4974 rule_start_index,
4975 decision_start_index,
4976 precedence,
4977 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
4978 recovery_state,
4979 }
4980 } else {
4981 FastRecognizeKey {
4982 state_number,
4983 stop_state,
4984 index,
4985 rule_start_index: 0,
4986 decision_start_index: None,
4987 precedence,
4988 recovery_symbols_id: 0,
4989 recovery_state: None,
4990 }
4991 };
4992 if memo_lookup_enabled {
4993 if let Some(outcomes) = memo.get(&key) {
4994 #[cfg(feature = "perf-counters")]
4995 {
4996 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
4997 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
4998 }
4999 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
5003 let inline_eof = inline_consumed_eof;
5004 let inline_tokens = &inline_consumed_tokens;
5005 return outcomes
5006 .iter()
5007 .cloned()
5008 .map(|mut outcome| {
5009 if inline_eof {
5010 outcome.consumed_eof = true;
5011 }
5012 if self.fast_token_nodes_enabled {
5013 for token_index in inline_tokens.iter().rev() {
5014 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
5015 index: *token_index,
5016 }));
5017 }
5018 }
5019 outcome
5020 })
5021 .collect();
5022 }
5023 return outcomes.to_vec();
5024 }
5025 #[cfg(feature = "perf-counters")]
5026 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
5027 }
5028
5029 let needs_cycle_guard =
5037 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number);
5038 #[cfg(feature = "perf-counters")]
5039 if needs_cycle_guard {
5040 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
5041 } else {
5042 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
5043 match &state.transitions[0] {
5044 Transition::Rule { .. } => {
5045 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
5046 }
5047 Transition::Atom { .. }
5048 | Transition::Range { .. }
5049 | Transition::Set { .. }
5050 | Transition::NotSet { .. }
5051 | Transition::Wildcard { .. } => {
5052 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
5053 }
5054 _ => {
5055 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
5056 }
5057 }
5058 }
5059 let visit_id = (state_number, index);
5060 if needs_cycle_guard && !visiting.insert(visit_id) {
5061 #[cfg(feature = "perf-counters")]
5062 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
5063 return Vec::new();
5064 }
5065 let next_decision_start_index = if starts_prediction_decision(state) {
5066 Some(index)
5067 } else {
5068 decision_start_index
5069 };
5070 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
5071 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
5072 } else {
5073 (Rc::clone(&recovery_symbols), recovery_state)
5074 };
5075
5076 let transition_count = state.transitions.len();
5095 let lookahead_filter = if transition_count > 1
5096 && self.fast_first_set_prefilter
5097 && !state.precedence_rule_decision
5098 && (!self.fast_recovery_enabled || state.kind != AtnStateKind::RuleStart)
5099 {
5100 state
5101 .rule_index
5102 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index).copied())
5103 .map(|rule_stop| {
5104 let symbol = self.token_type_at(index);
5105 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
5106 (symbol, entry)
5107 })
5108 } else {
5109 None
5110 };
5111 let ll1_only_alt: Option<usize> = if transition_count > 1
5120 && let Some((symbol, entry)) = lookahead_filter.as_ref()
5121 {
5122 let key = (state.state_number, *symbol);
5123 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
5124 cached
5125 } else {
5126 let result = ll1_unique_alt(entry, *symbol);
5127 self.ll1_decision_cache.insert(key, result);
5128 result
5129 }
5130 } else {
5131 None
5132 };
5133 let lookahead_filter = lookahead_filter.as_ref();
5134 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
5140 for (transition_index, transition) in state.transitions.iter().enumerate() {
5141 if let Some(alt) = ll1_only_alt {
5142 if alt != transition_index {
5144 continue;
5145 }
5146 } else if should_skip_via_lookahead(
5147 transition,
5148 transition_index,
5149 lookahead_filter,
5150 index,
5151 self.fast_recovery_enabled,
5152 expected,
5153 ) {
5154 continue;
5155 }
5156 match transition {
5157 Transition::Epsilon { target }
5158 | Transition::Predicate { target, .. }
5159 | Transition::Action { target, .. } => {
5160 #[cfg(feature = "perf-counters")]
5161 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
5162 let boundary = left_recursive_boundary(atn, state, *target);
5163 outcomes.extend(
5164 self.recognize_state_fast(
5165 atn,
5166 FastRecognizeRequest {
5167 state_number: *target,
5168 stop_state,
5169 index,
5170 rule_start_index,
5171 decision_start_index: next_decision_start_index,
5172 precedence,
5173 depth: depth + 1,
5174 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
5175 recovery_state: epsilon_recovery_state,
5176 },
5177 visiting,
5178 memo,
5179 expected,
5180 )
5181 .into_iter()
5182 .map(|mut outcome| {
5183 if let Some(rule_index) = boundary {
5184 outcome.nodes.prepend(Rc::new(
5185 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
5186 ));
5187 }
5188 outcome
5189 }),
5190 );
5191 }
5192 Transition::Precedence {
5193 target,
5194 precedence: transition_precedence,
5195 } => {
5196 if *transition_precedence >= precedence {
5197 let boundary = left_recursive_boundary(atn, state, *target);
5198 outcomes.extend(
5199 self.recognize_state_fast(
5200 atn,
5201 FastRecognizeRequest {
5202 state_number: *target,
5203 stop_state,
5204 index,
5205 rule_start_index,
5206 decision_start_index: next_decision_start_index,
5207 precedence,
5208 depth: depth + 1,
5209 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
5210 recovery_state: epsilon_recovery_state,
5211 },
5212 visiting,
5213 memo,
5214 expected,
5215 )
5216 .into_iter()
5217 .map(|mut outcome| {
5218 if let Some(rule_index) = boundary {
5219 outcome.nodes.prepend(Rc::new(
5220 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
5221 ));
5222 }
5223 outcome
5224 }),
5225 );
5226 }
5227 }
5228 Transition::Rule {
5229 target,
5230 rule_index,
5231 follow_state,
5232 precedence: rule_precedence,
5233 ..
5234 } => {
5235 #[cfg(feature = "perf-counters")]
5236 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
5237 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
5238 else {
5239 continue;
5240 };
5241 let symbol = self.token_type_at(index);
5253 if self.fast_first_set_prefilter {
5254 let first = self.cached_rule_first_set(atn, *target, child_stop);
5267 if should_skip_rule_via_first_set(
5268 &first,
5269 symbol,
5270 self.fast_recovery_enabled,
5271 index,
5272 expected,
5273 ) {
5274 continue;
5275 }
5276 }
5277 let expected_before_child =
5278 self.fast_recovery_enabled.then(|| expected.clone());
5279 let mut children = self.recognize_state_fast(
5280 atn,
5281 FastRecognizeRequest {
5282 state_number: *target,
5283 stop_state: child_stop,
5284 index,
5285 rule_start_index: index,
5286 decision_start_index: None,
5287 precedence: *rule_precedence,
5288 depth: depth + 1,
5289 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
5290 recovery_state: epsilon_recovery_state,
5291 },
5292 visiting,
5293 memo,
5294 expected,
5295 );
5296 if children.is_empty() && self.fast_recovery_enabled {
5297 children = self.fast_child_rule_failure_recovery_outcomes(
5298 FastChildRuleFailureRecoveryRequest {
5299 atn,
5300 rule_index: *rule_index,
5301 start_index: index,
5302 follow_state: *follow_state,
5303 stop_state,
5304 expected,
5305 },
5306 );
5307 }
5308 if let Some(expected_before_child) = expected_before_child {
5309 if children
5310 .iter()
5311 .any(|child| child.diagnostics.is_empty() && child.index > index)
5312 {
5313 *expected = expected_before_child;
5314 }
5315 }
5316 for child in children {
5317 let child_index = child.index;
5318 let child_consumed_eof = child.consumed_eof;
5319 let child_diagnostics = child.diagnostics;
5320 let empty_recovery = self.empty_recovery_symbols();
5321 let follow_outcomes = self.recognize_state_fast(
5322 atn,
5323 FastRecognizeRequest {
5324 state_number: *follow_state,
5325 stop_state,
5326 index: child_index,
5327 rule_start_index,
5328 decision_start_index: next_decision_start_index,
5329 precedence,
5330 depth: depth + 1,
5331 recovery_symbols: empty_recovery,
5332 recovery_state: None,
5333 },
5334 visiting,
5335 memo,
5336 expected,
5337 );
5338 if follow_outcomes.is_empty() {
5339 continue;
5340 }
5341 let child_node = Rc::new(FastRecognizedNode::Rule {
5342 rule_index: *rule_index,
5343 invoking_state: invoking_state_number(state_number),
5344 start_index: index,
5345 stop_index: self.rule_stop_token_index(child_index, child_consumed_eof),
5346 children: child.nodes,
5347 });
5348 let child_diags_empty = child_diagnostics.is_empty();
5349 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
5350 outcome.consumed_eof |= child_consumed_eof;
5351 if !child_diags_empty {
5354 let mut diagnostics = child_diagnostics.clone();
5355 diagnostics.append(&mut outcome.diagnostics);
5356 outcome.diagnostics = diagnostics;
5357 }
5358 outcome.nodes.prepend(Rc::clone(&child_node));
5359 outcome
5360 }));
5361 }
5362 }
5363 Transition::Atom { target, .. }
5364 | Transition::Range { target, .. }
5365 | Transition::Set { target, .. }
5366 | Transition::NotSet { target, .. }
5367 | Transition::Wildcard { target, .. } => {
5368 #[cfg(feature = "perf-counters")]
5369 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
5370 let symbol = self.token_type_at(index);
5371 if transition.matches(symbol, 1, atn.max_token_type()) {
5372 let next_index = self.consume_index(index, symbol);
5373 let empty_recovery = self.empty_recovery_symbols();
5374 outcomes.extend(
5375 self.recognize_state_fast(
5376 atn,
5377 FastRecognizeRequest {
5378 state_number: *target,
5379 stop_state,
5380 index: next_index,
5381 rule_start_index,
5382 decision_start_index: next_decision_start_index,
5383 precedence,
5384 depth: depth + 1,
5385 recovery_symbols: empty_recovery,
5386 recovery_state: None,
5387 },
5388 visiting,
5389 memo,
5390 expected,
5391 )
5392 .into_iter()
5393 .map(|mut outcome| {
5394 outcome.consumed_eof |= symbol == TOKEN_EOF;
5395 if self.fast_token_nodes_enabled {
5396 outcome
5397 .nodes
5398 .prepend(Rc::new(FastRecognizedNode::Token { index }));
5399 }
5400 outcome
5401 }),
5402 );
5403 } else {
5404 if !self.fast_recovery_enabled {
5405 continue;
5413 }
5414 let expected_symbols = fast_recovery_expected_symbols(
5415 self,
5416 atn,
5417 state.state_number,
5418 &recovery_symbols,
5419 );
5420 if expected_symbols.contains(&symbol) {
5421 continue;
5422 }
5423 {
5424 expected.record_transition(index, transition, atn.max_token_type());
5425 record_no_viable_if_ambiguous(
5426 expected,
5427 next_decision_start_index,
5428 index,
5429 );
5430 outcomes.extend(self.fast_single_token_deletion_recovery(
5431 FastRecoveryRequest {
5432 atn,
5433 transition,
5434 expected_symbols: Rc::clone(&expected_symbols),
5435 target: *target,
5436 request: FastRecognizeRequest {
5437 state_number,
5438 stop_state,
5439 index,
5440 rule_start_index,
5441 decision_start_index,
5442 precedence,
5443 depth,
5444 recovery_symbols: Rc::clone(&recovery_symbols),
5445 recovery_state,
5446 },
5447 visiting,
5448 memo,
5449 expected,
5450 },
5451 ));
5452 if !state_is_left_recursive_rule(atn, state) {
5453 outcomes.extend(self.fast_single_token_insertion_recovery(
5454 FastRecoveryRequest {
5455 atn,
5456 transition,
5457 expected_symbols: Rc::clone(&expected_symbols),
5458 target: *target,
5459 request: FastRecognizeRequest {
5460 state_number,
5461 stop_state,
5462 index,
5463 rule_start_index,
5464 decision_start_index,
5465 precedence,
5466 depth,
5467 recovery_symbols: Rc::clone(&recovery_symbols),
5468 recovery_state,
5469 },
5470 visiting,
5471 memo,
5472 expected,
5473 },
5474 ));
5475 }
5476 outcomes.extend(self.fast_current_token_deletion_recovery(
5477 FastCurrentTokenDeletionRequest {
5478 atn,
5479 expected_symbols,
5480 request: FastRecognizeRequest {
5481 state_number,
5482 stop_state,
5483 index,
5484 rule_start_index,
5485 decision_start_index,
5486 precedence,
5487 depth,
5488 recovery_symbols: Rc::clone(&recovery_symbols),
5489 recovery_state,
5490 },
5491 visiting,
5492 memo,
5493 expected,
5494 },
5495 ));
5496 }
5497 }
5498 }
5499 }
5500 }
5501
5502 if needs_cycle_guard {
5503 visiting.remove(&visit_id);
5504 }
5505 if matches!(
5506 self.prediction_mode,
5507 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
5508 ) && self.fast_recovery_enabled
5509 {
5510 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
5514 }
5515 if self.fast_recovery_enabled {
5516 dedupe_fast_outcomes(&mut outcomes);
5517 } else {
5518 dedupe_clean_fast_outcomes(&mut outcomes);
5519 }
5520 let should_memoize = self.fast_recovery_enabled
5530 || (transition_count > 1
5531 && (outcomes.is_empty()
5532 || outcomes.len() > 1
5533 || (outcomes.len() == 1 && self.should_memoize_single_outcome(&key))));
5534 let apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
5538 if inline_consumed_eof {
5539 outcome.consumed_eof = true;
5540 }
5541 if !inline_consumed_tokens.is_empty() {
5542 for token_index in inline_consumed_tokens.iter().rev() {
5543 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
5544 index: *token_index,
5545 }));
5546 }
5547 }
5548 outcome
5549 };
5550 if should_memoize {
5551 #[cfg(feature = "perf-counters")]
5552 {
5553 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
5554 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
5555 match outcomes.len() {
5556 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
5557 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
5558 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
5559 }
5560 }
5561 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
5566 memo.insert(key, Rc::clone(&stored));
5567 if inline_pending {
5568 return stored.iter().cloned().map(apply_inline_pending).collect();
5569 }
5570 return stored.to_vec();
5571 }
5572 #[cfg(feature = "perf-counters")]
5573 match outcomes.len() {
5574 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
5575 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
5576 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
5577 }
5578 if inline_pending {
5579 return outcomes.into_iter().map(apply_inline_pending).collect();
5580 }
5581 outcomes
5582 }
5583
5584 fn single_token_deletion_recovery(
5587 &mut self,
5588 recovery: RecoveryRequest<'_, '_>,
5589 ) -> Vec<RecognizeOutcome> {
5590 let RecoveryRequest {
5591 atn,
5592 transition,
5593 expected_symbols,
5594 target,
5595 request,
5596 visiting,
5597 memo,
5598 expected,
5599 } = recovery;
5600 let RecognizeRequest {
5601 stop_state,
5602 index,
5603 rule_start_index,
5604 decision_start_index,
5605 init_action_rules,
5606 predicates,
5607 rule_args,
5608 member_actions,
5609 return_actions,
5610 local_int_arg,
5611 member_values,
5612 return_values,
5613 rule_alt_number,
5614 track_alt_numbers,
5615 consumed_eof,
5616 precedence,
5617 depth,
5618 ..
5619 } = request;
5620 let Some((diagnostic, next_index, next_symbol)) =
5621 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
5622 else {
5623 return Vec::new();
5624 };
5625 let after_next = self.consume_index(next_index, next_symbol);
5626 self.recognize_state(
5627 atn,
5628 RecognizeRequest {
5629 state_number: target,
5630 stop_state,
5631 index: after_next,
5632 rule_start_index,
5633 decision_start_index,
5634 init_action_rules,
5635 predicates,
5636 rule_args,
5637 member_actions,
5638 return_actions,
5639 local_int_arg,
5640 member_values,
5641 return_values,
5642 rule_alt_number,
5643 track_alt_numbers,
5644 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
5645 precedence,
5646 depth: depth + 1,
5647 recovery_symbols: BTreeSet::new(),
5648 recovery_state: None,
5649 },
5650 visiting,
5651 memo,
5652 expected,
5653 )
5654 .into_iter()
5655 .map(|mut outcome| {
5656 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
5657 outcome.diagnostics.insert(0, diagnostic.clone());
5658 outcome
5659 .nodes
5660 .insert(0, RecognizedNode::Token { index: next_index });
5661 outcome
5662 .nodes
5663 .insert(0, RecognizedNode::ErrorToken { index });
5664 outcome
5665 })
5666 .collect()
5667 }
5668
5669 fn current_token_deletion_recovery(
5672 &mut self,
5673 recovery: CurrentTokenDeletionRequest<'_, '_>,
5674 ) -> Vec<RecognizeOutcome> {
5675 let CurrentTokenDeletionRequest {
5676 atn,
5677 expected_symbols,
5678 mut request,
5679 visiting,
5680 memo,
5681 expected,
5682 } = recovery;
5683 let error_index = request.index;
5684 if error_index == request.rule_start_index {
5685 return Vec::new();
5686 }
5687 let Some((diagnostic, next_index, skipped)) =
5688 self.current_token_deletion(error_index, &expected_symbols)
5689 else {
5690 return Vec::new();
5691 };
5692 request.state_number = request.recovery_state.unwrap_or(request.state_number);
5693 request.index = next_index;
5694 request.depth += 1;
5695 request.recovery_state = None;
5696 self.recognize_state(atn, request, visiting, memo, expected)
5697 .into_iter()
5698 .map(|mut outcome| {
5699 outcome.diagnostics.insert(0, diagnostic.clone());
5700 for index in skipped.iter().rev() {
5701 outcome
5702 .nodes
5703 .insert(0, RecognizedNode::ErrorToken { index: *index });
5704 }
5705 outcome
5706 })
5707 .collect()
5708 }
5709
5710 fn consuming_failure_fallback(
5713 &mut self,
5714 fallback: ConsumingFailureFallback<'_>,
5715 visiting: &mut BTreeSet<RecognizeKey>,
5716 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
5717 expected: &mut ExpectedTokens,
5718 ) -> Vec<RecognizeOutcome> {
5719 if fallback.expected_symbols.is_empty() {
5720 return Vec::new();
5721 }
5722 if fallback.symbol == TOKEN_EOF {
5723 return self.eof_consuming_failure_fallback(fallback, expected);
5724 }
5725 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
5726 }
5727
5728 fn non_eof_consuming_failure_fallback(
5731 &mut self,
5732 fallback: ConsumingFailureFallback<'_>,
5733 visiting: &mut BTreeSet<RecognizeKey>,
5734 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
5735 expected: &mut ExpectedTokens,
5736 ) -> Vec<RecognizeOutcome> {
5737 let ConsumingFailureFallback {
5738 atn,
5739 target,
5740 request,
5741 symbol,
5742 expected_symbols,
5743 decision_start_index,
5744 decision,
5745 } = fallback;
5746 let error_index = request.index;
5747 let diagnostic =
5748 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
5749 let next_index = self.consume_index(error_index, symbol);
5750 self.recognize_state(
5751 atn,
5752 RecognizeRequest {
5753 state_number: target,
5754 stop_state: request.stop_state,
5755 index: next_index,
5756 rule_start_index: request.rule_start_index,
5757 decision_start_index,
5758 init_action_rules: request.init_action_rules,
5759 predicates: request.predicates,
5760 rule_args: request.rule_args,
5761 member_actions: request.member_actions,
5762 return_actions: request.return_actions,
5763 local_int_arg: request.local_int_arg,
5764 member_values: request.member_values,
5765 return_values: request.return_values,
5766 rule_alt_number: request.rule_alt_number,
5767 track_alt_numbers: request.track_alt_numbers,
5768 consumed_eof: request.consumed_eof,
5769 precedence: request.precedence,
5770 depth: request.depth + 1,
5771 recovery_symbols: BTreeSet::new(),
5772 recovery_state: None,
5773 },
5774 visiting,
5775 memo,
5776 expected,
5777 )
5778 .into_iter()
5779 .map(|mut outcome| {
5780 prepend_decision(&mut outcome, decision);
5781 outcome.diagnostics.insert(0, diagnostic.clone());
5782 outcome
5783 .nodes
5784 .insert(0, RecognizedNode::ErrorToken { index: error_index });
5785 outcome
5786 })
5787 .collect()
5788 }
5789
5790 fn eof_consuming_failure_fallback(
5793 &mut self,
5794 fallback: ConsumingFailureFallback<'_>,
5795 expected: &ExpectedTokens,
5796 ) -> Vec<RecognizeOutcome> {
5797 let request = fallback.request;
5798 if request.index == request.rule_start_index {
5799 return Vec::new();
5800 }
5801 let diagnostic =
5802 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
5803 vec![RecognizeOutcome {
5804 index: request.index,
5805 consumed_eof: request.consumed_eof,
5806 alt_number: request.rule_alt_number,
5807 member_values: request.member_values,
5808 return_values: request.return_values,
5809 diagnostics: vec![diagnostic],
5810 decisions: Vec::new(),
5811 actions: Vec::new(),
5812 nodes: Vec::new(),
5813 }]
5814 }
5815
5816 fn single_token_insertion_recovery(
5819 &mut self,
5820 recovery: RecoveryRequest<'_, '_>,
5821 ) -> Vec<RecognizeOutcome> {
5822 let RecoveryRequest {
5823 atn,
5824 transition,
5825 expected_symbols,
5826 target,
5827 request,
5828 visiting,
5829 memo,
5830 expected,
5831 } = recovery;
5832 let RecognizeRequest {
5833 stop_state,
5834 index,
5835 rule_start_index,
5836 decision_start_index,
5837 init_action_rules,
5838 predicates,
5839 rule_args,
5840 member_actions,
5841 return_actions,
5842 local_int_arg,
5843 member_values,
5844 return_values,
5845 rule_alt_number,
5846 track_alt_numbers,
5847 consumed_eof,
5848 precedence,
5849 depth,
5850 ..
5851 } = request;
5852 let follow_symbols = state_expected_symbols(atn, transition.target());
5853 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
5854 transition,
5855 index,
5856 atn.max_token_type(),
5857 &expected_symbols,
5858 &follow_symbols,
5859 ) else {
5860 return Vec::new();
5861 };
5862 self.recognize_state(
5863 atn,
5864 RecognizeRequest {
5865 state_number: target,
5866 stop_state,
5867 index,
5868 rule_start_index,
5869 decision_start_index,
5870 init_action_rules,
5871 predicates,
5872 rule_args,
5873 member_actions,
5874 return_actions,
5875 local_int_arg,
5876 member_values,
5877 return_values,
5878 rule_alt_number,
5879 track_alt_numbers,
5880 consumed_eof,
5881 precedence,
5882 depth: depth + 1,
5883 recovery_symbols: BTreeSet::new(),
5884 recovery_state: None,
5885 },
5886 visiting,
5887 memo,
5888 expected,
5889 )
5890 .into_iter()
5891 .map(|mut outcome| {
5892 outcome.diagnostics.insert(0, diagnostic.clone());
5893 outcome.nodes.insert(
5894 0,
5895 RecognizedNode::MissingToken {
5896 token_type,
5897 at_index: index,
5898 text: text.clone(),
5899 },
5900 );
5901 outcome
5902 })
5903 .collect()
5904 }
5905
5906 #[allow(clippy::too_many_lines)]
5909 fn recognize_state(
5910 &mut self,
5911 atn: &Atn,
5912 request: RecognizeRequest<'_>,
5913 visiting: &mut BTreeSet<RecognizeKey>,
5914 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
5915 expected: &mut ExpectedTokens,
5916 ) -> Vec<RecognizeOutcome> {
5917 let request_template = request.clone();
5918 let RecognizeRequest {
5919 state_number,
5920 stop_state,
5921 index,
5922 rule_start_index,
5923 decision_start_index,
5924 init_action_rules,
5925 predicates,
5926 rule_args,
5927 member_actions,
5928 return_actions,
5929 local_int_arg,
5930 member_values,
5931 return_values,
5932 rule_alt_number,
5933 track_alt_numbers,
5934 consumed_eof,
5935 precedence,
5936 depth,
5937 recovery_symbols,
5938 recovery_state,
5939 } = request;
5940 if depth > RECOGNITION_DEPTH_LIMIT {
5941 return Vec::new();
5942 }
5943 if state_number == stop_state {
5944 return stop_outcome(
5945 index,
5946 consumed_eof,
5947 rule_alt_number,
5948 member_values,
5949 return_values,
5950 );
5951 }
5952 let key = RecognizeKey {
5953 state_number,
5954 stop_state,
5955 index,
5956 rule_start_index,
5957 decision_start_index,
5958 local_int_arg,
5959 member_values: member_values.clone(),
5960 return_values: return_values.clone(),
5961 rule_alt_number,
5962 track_alt_numbers,
5963 consumed_eof,
5964 precedence,
5965 recovery_symbols: recovery_symbols.clone(),
5966 recovery_state,
5967 };
5968 if let Some(outcomes) = memo.get(&key) {
5969 return outcomes.clone();
5970 }
5971
5972 let visit_key = key.clone();
5973 if !visiting.insert(visit_key.clone()) {
5974 return Vec::new();
5975 }
5976
5977 let Some(state) = atn.state(state_number) else {
5978 visiting.remove(&visit_key);
5979 return Vec::new();
5980 };
5981 let next_decision_start_index = if starts_prediction_decision(state) {
5982 Some(index)
5983 } else {
5984 decision_start_index
5985 };
5986 let (epsilon_recovery_symbols, epsilon_recovery_state) =
5987 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
5988 let mut outcomes = Vec::new();
5989 for (transition_index, transition) in state.transitions.iter().enumerate() {
5990 let decision = transition_decision(atn, state, transition_index, predicates);
5991 let next_alt_number =
5992 next_alt_number(state, transition_index, rule_alt_number, track_alt_numbers);
5993 match transition {
5994 Transition::Epsilon { target } | Transition::Action { target, .. } => {
5995 let action_rule_index = match transition {
5996 Transition::Action { rule_index, .. } => Some(*rule_index),
5997 _ => None,
5998 };
5999 outcomes.extend(self.recognize_epsilon_or_action_step(
6000 atn,
6001 &request_template,
6002 EpsilonActionStep {
6003 source_state: state_number,
6004 target: *target,
6005 action_rule_index,
6006 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
6007 decision,
6008 decision_start_index: next_decision_start_index,
6009 alt_number: next_alt_number,
6010 recovery_symbols: epsilon_recovery_symbols.clone(),
6011 recovery_state: epsilon_recovery_state,
6012 },
6013 RecognizeScratch {
6014 visiting,
6015 memo,
6016 expected,
6017 },
6018 ));
6019 }
6020 Transition::Predicate {
6021 target,
6022 rule_index,
6023 pred_index,
6024 ..
6025 } => {
6026 let predicate = PredicateEval {
6027 index,
6028 rule_index: *rule_index,
6029 pred_index: *pred_index,
6030 predicates,
6031 context: None,
6032 local_int_arg,
6033 member_values: &member_values,
6034 };
6035 if self.parser_predicate_matches(predicate) {
6036 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
6037 outcomes.extend(
6038 self.recognize_state(
6039 atn,
6040 RecognizeRequest {
6041 state_number: *target,
6042 stop_state,
6043 index,
6044 rule_start_index,
6045 decision_start_index: next_decision_start_index,
6046 init_action_rules,
6047 predicates,
6048 rule_args,
6049 member_actions,
6050 return_actions,
6051 local_int_arg,
6052 member_values: member_values.clone(),
6053 return_values: return_values.clone(),
6054 rule_alt_number: next_alt_number,
6055 track_alt_numbers,
6056 consumed_eof,
6057 precedence,
6058 depth: depth + 1,
6059 recovery_symbols: epsilon_recovery_symbols.clone(),
6060 recovery_state: epsilon_recovery_state,
6061 },
6062 visiting,
6063 memo,
6064 expected,
6065 )
6066 .into_iter()
6067 .map(|mut outcome| {
6068 prepend_decision(&mut outcome, decision);
6069 if let Some(rule_index) = left_recursive_boundary {
6070 outcome.nodes.insert(
6071 0,
6072 RecognizedNode::LeftRecursiveBoundary { rule_index },
6073 );
6074 }
6075 outcome
6076 }),
6077 );
6078 } else if let Some(message) =
6079 self.parser_predicate_failure_message(*rule_index, *pred_index, predicates)
6080 {
6081 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
6082 rule_index: *rule_index,
6083 index,
6084 message,
6085 member_values: member_values.clone(),
6086 return_values: return_values.clone(),
6087 rule_alt_number,
6088 }));
6089 } else {
6090 record_predicate_no_viable(expected, next_decision_start_index, index);
6091 }
6092 }
6093 Transition::Precedence {
6094 target,
6095 precedence: transition_precedence,
6096 } => {
6097 if *transition_precedence >= precedence {
6098 outcomes.extend(
6099 self.recognize_state(
6100 atn,
6101 RecognizeRequest {
6102 state_number: *target,
6103 stop_state,
6104 index,
6105 rule_start_index,
6106 decision_start_index: next_decision_start_index,
6107 init_action_rules,
6108 predicates,
6109 rule_args,
6110 member_actions,
6111 return_actions,
6112 local_int_arg,
6113 member_values: member_values.clone(),
6114 return_values: return_values.clone(),
6115 rule_alt_number: next_alt_number,
6116 track_alt_numbers,
6117 consumed_eof,
6118 precedence,
6119 depth: depth + 1,
6120 recovery_symbols: epsilon_recovery_symbols.clone(),
6121 recovery_state: epsilon_recovery_state,
6122 },
6123 visiting,
6124 memo,
6125 expected,
6126 )
6127 .into_iter()
6128 .map(|mut outcome| {
6129 prepend_decision(&mut outcome, decision);
6130 outcome
6131 }),
6132 );
6133 }
6134 }
6135 Transition::Rule {
6136 target,
6137 rule_index,
6138 follow_state,
6139 precedence: rule_precedence,
6140 ..
6141 } => {
6142 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
6143 else {
6144 continue;
6145 };
6146 let child_local_int_arg =
6147 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
6148 let expected_before_child = expected.clone();
6149 let children = self.recognize_state(
6150 atn,
6151 RecognizeRequest {
6152 state_number: *target,
6153 stop_state: child_stop,
6154 index,
6155 rule_start_index: index,
6156 decision_start_index: None,
6157 init_action_rules,
6158 predicates,
6159 rule_args,
6160 member_actions,
6161 return_actions,
6162 local_int_arg: child_local_int_arg,
6163 member_values: member_values.clone(),
6164 return_values: BTreeMap::new(),
6165 rule_alt_number: 0,
6166 track_alt_numbers,
6167 consumed_eof: false,
6168 precedence: *rule_precedence,
6169 depth: depth + 1,
6170 recovery_symbols: epsilon_recovery_symbols.clone(),
6171 recovery_state: epsilon_recovery_state,
6172 },
6173 visiting,
6174 memo,
6175 expected,
6176 );
6177 let children = if children.is_empty() {
6178 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
6179 atn,
6180 rule_index: *rule_index,
6181 start_index: index,
6182 follow_state: *follow_state,
6183 stop_state,
6184 member_values: member_values.clone(),
6185 expected,
6186 })
6187 } else {
6188 children
6189 };
6190 let preserve_child_expected =
6191 self.child_expected_reaches_clean_eof(&children, expected);
6192 restore_expected(
6193 &children,
6194 index,
6195 expected,
6196 expected_before_child,
6197 preserve_child_expected,
6198 );
6199 for child in children {
6200 let child_node = RecognizedNode::Rule {
6201 rule_index: *rule_index,
6202 invoking_state: invoking_state_number(state_number),
6203 alt_number: child.alt_number,
6204 start_index: index,
6205 stop_index: self.rule_stop_token_index(child.index, child.consumed_eof),
6206 return_values: child.return_values.clone(),
6207 children: fold_left_recursive_boundaries(child.nodes.clone()),
6208 };
6209 outcomes.extend(
6210 self.recognize_state(
6211 atn,
6212 RecognizeRequest {
6213 state_number: *follow_state,
6214 stop_state,
6215 index: child.index,
6216 rule_start_index,
6217 decision_start_index: next_decision_start_index,
6218 init_action_rules,
6219 predicates,
6220 rule_args,
6221 member_actions,
6222 return_actions,
6223 local_int_arg,
6224 member_values: child.member_values.clone(),
6225 return_values: return_values.clone(),
6226 rule_alt_number,
6227 track_alt_numbers,
6228 consumed_eof: consumed_eof || child.consumed_eof,
6229 precedence,
6230 depth: depth + 1,
6231 recovery_symbols: BTreeSet::new(),
6232 recovery_state: None,
6233 },
6234 visiting,
6235 memo,
6236 expected,
6237 )
6238 .into_iter()
6239 .map(|mut outcome| {
6240 outcome.consumed_eof |= child.consumed_eof;
6241 let mut diagnostics = child.diagnostics.clone();
6242 diagnostics.append(&mut outcome.diagnostics);
6243 outcome.diagnostics = diagnostics;
6244 let mut decisions = child.decisions.clone();
6245 decisions.append(&mut outcome.decisions);
6246 outcome.decisions = decisions;
6247 prepend_decision(&mut outcome, decision);
6248 let mut actions = child.actions.clone();
6249 if init_action_rules.contains(rule_index) {
6250 actions.insert(
6251 0,
6252 ParserAction::new_rule_init(
6253 *rule_index,
6254 index,
6255 Some(*follow_state),
6256 ),
6257 );
6258 }
6259 actions.append(&mut outcome.actions);
6260 outcome.actions = actions;
6261 outcome.nodes.insert(0, child_node.clone());
6262 outcome
6263 }),
6264 );
6265 }
6266 }
6267 Transition::Atom { target, .. }
6268 | Transition::Range { target, .. }
6269 | Transition::Set { target, .. }
6270 | Transition::NotSet { target, .. }
6271 | Transition::Wildcard { target, .. } => {
6272 let symbol = self.token_type_at(index);
6273 if transition.matches(symbol, 1, atn.max_token_type()) {
6274 let next_index = self.consume_index(index, symbol);
6275 outcomes.extend(
6276 self.recognize_state(
6277 atn,
6278 RecognizeRequest {
6279 state_number: *target,
6280 stop_state,
6281 index: next_index,
6282 rule_start_index,
6283 decision_start_index: next_decision_start_index,
6284 init_action_rules,
6285 predicates,
6286 rule_args,
6287 member_actions,
6288 return_actions,
6289 local_int_arg,
6290 member_values: member_values.clone(),
6291 return_values: return_values.clone(),
6292 rule_alt_number: next_alt_number,
6293 track_alt_numbers,
6294 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
6295 precedence,
6296 depth: depth + 1,
6297 recovery_symbols: BTreeSet::new(),
6298 recovery_state: None,
6299 },
6300 visiting,
6301 memo,
6302 expected,
6303 )
6304 .into_iter()
6305 .map(|mut outcome| {
6306 prepend_decision(&mut outcome, decision);
6307 outcome.consumed_eof |= symbol == TOKEN_EOF;
6308 outcome.nodes.insert(0, RecognizedNode::Token { index });
6309 outcome
6310 }),
6311 );
6312 } else {
6313 let expected_symbols =
6314 recovery_expected_symbols(atn, state.state_number, &recovery_symbols);
6315 if expected_symbols.contains(&symbol) {
6316 continue;
6317 }
6318 expected.record_transition(index, transition, atn.max_token_type());
6319 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
6320 let before_recovery = outcomes.len();
6321 let recovery_request = request_template.clone();
6322 outcomes.extend(
6323 self.single_token_deletion_recovery(RecoveryRequest {
6324 atn,
6325 transition,
6326 expected_symbols: expected_symbols.clone(),
6327 target: *target,
6328 request: recovery_request.clone(),
6329 visiting,
6330 memo,
6331 expected,
6332 })
6333 .into_iter()
6334 .map(|mut outcome| {
6335 prepend_decision(&mut outcome, decision);
6336 outcome
6337 }),
6338 );
6339 if !state_is_left_recursive_rule(atn, state) {
6340 outcomes.extend(
6341 self.single_token_insertion_recovery(RecoveryRequest {
6342 atn,
6343 transition,
6344 expected_symbols: expected_symbols.clone(),
6345 target: *target,
6346 request: recovery_request.clone(),
6347 visiting,
6348 memo,
6349 expected,
6350 })
6351 .into_iter()
6352 .map(|mut outcome| {
6353 prepend_decision(&mut outcome, decision);
6354 outcome
6355 }),
6356 );
6357 }
6358 outcomes.extend(self.current_token_deletion_recovery(
6359 CurrentTokenDeletionRequest {
6360 atn,
6361 expected_symbols: expected_symbols.clone(),
6362 request: recovery_request.clone(),
6363 visiting,
6364 memo,
6365 expected,
6366 },
6367 ));
6368 if outcomes.len() == before_recovery {
6369 outcomes.extend(self.consuming_failure_fallback(
6370 ConsumingFailureFallback {
6371 atn,
6372 target: *target,
6373 request: recovery_request,
6374 symbol,
6375 expected_symbols,
6376 decision_start_index: next_decision_start_index,
6377 decision,
6378 },
6379 visiting,
6380 memo,
6381 expected,
6382 ));
6383 }
6384 }
6385 }
6386 }
6387 }
6388
6389 visiting.remove(&visit_key);
6390 self.record_prediction_diagnostics(atn, state, index, &outcomes);
6391 if matches!(
6392 self.prediction_mode,
6393 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
6394 ) {
6395 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes);
6396 }
6397 dedupe_outcomes(&mut outcomes);
6398 memo.insert(key, outcomes.clone());
6399 outcomes
6400 }
6401
6402 fn recognize_epsilon_or_action_step(
6405 &mut self,
6406 atn: &Atn,
6407 request: &RecognizeRequest<'_>,
6408 step: EpsilonActionStep,
6409 scratch: RecognizeScratch<'_>,
6410 ) -> Vec<RecognizeOutcome> {
6411 let RecognizeScratch {
6412 visiting,
6413 memo,
6414 expected,
6415 } = scratch;
6416 let action = step.action_rule_index.map(|rule_index| {
6417 ParserAction::new(
6418 step.source_state,
6419 rule_index,
6420 request.rule_start_index,
6421 self.rule_stop_token_index(request.index, request.consumed_eof),
6422 )
6423 });
6424 let next_member_values = if action.is_some() {
6425 member_values_after_action(
6426 step.source_state,
6427 request.member_actions,
6428 &request.member_values,
6429 )
6430 } else {
6431 request.member_values.clone()
6432 };
6433 let next_return_values = action.map_or_else(
6434 || request.return_values.clone(),
6435 |action| {
6436 return_values_after_action(
6437 step.source_state,
6438 action.rule_index(),
6439 request.return_actions,
6440 &request.return_values,
6441 )
6442 },
6443 );
6444
6445 self.recognize_state(
6446 atn,
6447 RecognizeRequest {
6448 state_number: step.target,
6449 stop_state: request.stop_state,
6450 index: request.index,
6451 rule_start_index: request.rule_start_index,
6452 decision_start_index: step.decision_start_index,
6453 init_action_rules: request.init_action_rules,
6454 predicates: request.predicates,
6455 rule_args: request.rule_args,
6456 member_actions: request.member_actions,
6457 return_actions: request.return_actions,
6458 local_int_arg: request.local_int_arg,
6459 member_values: next_member_values,
6460 return_values: next_return_values,
6461 rule_alt_number: step.alt_number,
6462 track_alt_numbers: request.track_alt_numbers,
6463 consumed_eof: request.consumed_eof,
6464 precedence: request.precedence,
6465 depth: request.depth + 1,
6466 recovery_symbols: step.recovery_symbols,
6467 recovery_state: step.recovery_state,
6468 },
6469 visiting,
6470 memo,
6471 expected,
6472 )
6473 .into_iter()
6474 .map(|mut outcome| {
6475 prepend_decision(&mut outcome, step.decision);
6476 if let Some(rule_index) = step.left_recursive_boundary {
6477 outcome
6478 .nodes
6479 .insert(0, RecognizedNode::LeftRecursiveBoundary { rule_index });
6480 }
6481 if let Some(action) = action {
6482 outcome.actions.insert(0, action);
6483 }
6484 outcome
6485 })
6486 .collect()
6487 }
6488
6489 fn token_type_at(&mut self, index: usize) -> i32 {
6494 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
6495 self.input.fill();
6496 }
6497 self.input.token_type_at_index(index)
6498 }
6499
6500 fn cached_state_expected_symbols(
6512 &mut self,
6513 atn: &Atn,
6514 state_number: usize,
6515 ) -> Rc<BTreeSet<i32>> {
6516 if let Some(cached) = self.state_expected_cache.get(&state_number) {
6517 return Rc::clone(cached);
6518 }
6519 let symbols = state_expected_symbols(atn, state_number);
6520 let entry = self.intern_recovery_symbols(symbols);
6521 self.state_expected_cache
6522 .insert(state_number, Rc::clone(&entry));
6523 entry
6524 }
6525
6526 fn cached_state_expected_token_set(
6527 &mut self,
6528 atn: &Atn,
6529 state_number: usize,
6530 ) -> Rc<TokenBitSet> {
6531 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
6532 return Rc::clone(cached);
6533 }
6534 let symbols = Rc::new(state_expected_token_set(atn, state_number));
6535 self.state_expected_token_cache
6536 .insert(state_number, Rc::clone(&symbols));
6537 symbols
6538 }
6539
6540 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
6541 if self.rule_stop_reach_cache.len() <= state_number {
6542 self.rule_stop_reach_cache
6543 .resize_with(atn.states().len().max(state_number + 1), || None);
6544 }
6545 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
6546 return reaches;
6547 }
6548 let reaches = state_can_reach_rule_stop(atn, state_number);
6549 self.rule_stop_reach_cache[state_number] = Some(reaches);
6550 reaches
6551 }
6552
6553 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
6556 Rc::clone(&self.empty_recovery_symbols)
6557 }
6558
6559 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
6568 if set.is_empty() {
6569 return Rc::clone(&self.empty_recovery_symbols);
6570 }
6571 let candidate = Rc::new(set);
6572 match self.recovery_symbols_intern.get(&candidate) {
6573 Some(existing) => Rc::clone(existing),
6574 None => {
6575 self.recovery_symbols_intern
6576 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
6577 candidate
6578 }
6579 }
6580 }
6581
6582 fn cached_decision_lookahead(
6587 &mut self,
6588 atn: &Atn,
6589 state: &AtnState,
6590 rule_stop_state: usize,
6591 ) -> Rc<DecisionLookahead> {
6592 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number) {
6599 return Rc::clone(cached);
6600 }
6601 let entry = with_shared_atn_caches(atn, |cache| {
6602 if let Some(cached) = cache.decision_lookahead.get(&state.state_number) {
6603 return Rc::clone(cached);
6604 }
6605 let mut entry = DecisionLookahead {
6606 transitions: Vec::with_capacity(state.transitions.len()),
6607 };
6608 for transition in &state.transitions {
6609 entry.transitions.push(transition_first_set(
6610 atn,
6611 transition,
6612 rule_stop_state,
6613 &mut cache.first_set,
6614 ));
6615 }
6616 let entry = Rc::new(entry);
6617 cache
6618 .decision_lookahead
6619 .insert(state.state_number, Rc::clone(&entry));
6620 entry
6621 });
6622 self.decision_lookahead_cache
6623 .insert(state.state_number, Rc::clone(&entry));
6624 entry
6625 }
6626
6627 fn cached_rule_first_set(
6628 &mut self,
6629 atn: &Atn,
6630 target: usize,
6631 child_stop: usize,
6632 ) -> Rc<FirstSet> {
6633 if self.rule_first_set_cache.len() <= target {
6634 self.rule_first_set_cache
6635 .resize_with(atn.states().len().max(target + 1), || None);
6636 }
6637 if let Some(cached) = self
6638 .rule_first_set_cache
6639 .get(target)
6640 .and_then(Option::as_ref)
6641 {
6642 return Rc::clone(cached);
6643 }
6644 let first = with_shared_first_set_cache(atn, |cache| {
6645 rule_first_set(atn, target, child_stop, cache)
6646 });
6647 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
6648 first
6649 }
6650
6651 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
6652 if self.empty_cycle_cache.len() <= state_number {
6653 self.empty_cycle_cache
6654 .resize_with(atn.states().len().max(state_number + 1), || None);
6655 }
6656 if let Some(cached) = self.empty_cycle_cache[state_number] {
6657 return cached;
6658 }
6659 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
6660 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
6661 self.empty_cycle_cache[state_number] = Some(result);
6662 result
6663 }
6664
6665 fn empty_path_reaches_state(
6666 &mut self,
6667 atn: &Atn,
6668 state_number: usize,
6669 target_state: usize,
6670 visited: &mut FxHashSet<usize>,
6671 ) -> bool {
6672 if !visited.insert(state_number) {
6673 return false;
6674 }
6675 let Some(state) = atn.state(state_number) else {
6676 return false;
6677 };
6678 for transition in &state.transitions {
6679 match transition {
6680 Transition::Atom { .. }
6681 | Transition::Range { .. }
6682 | Transition::Set { .. }
6683 | Transition::NotSet { .. }
6684 | Transition::Wildcard { .. } => {}
6685 Transition::Rule {
6686 target,
6687 rule_index,
6688 follow_state,
6689 ..
6690 } => {
6691 if *target == target_state
6692 || self.empty_path_reaches_state(atn, *target, target_state, visited)
6693 {
6694 return true;
6695 }
6696 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
6697 else {
6698 continue;
6699 };
6700 if self
6701 .cached_rule_first_set(atn, *target, child_stop)
6702 .nullable
6703 && (*follow_state == target_state
6704 || self.empty_path_reaches_state(
6705 atn,
6706 *follow_state,
6707 target_state,
6708 visited,
6709 ))
6710 {
6711 return true;
6712 }
6713 }
6714 Transition::Epsilon { target }
6715 | Transition::Predicate { target, .. }
6716 | Transition::Action { target, .. }
6717 | Transition::Precedence { target, .. } => {
6718 if *target == target_state
6719 || self.empty_path_reaches_state(atn, *target, target_state, visited)
6720 {
6721 return true;
6722 }
6723 }
6724 }
6725 }
6726 false
6727 }
6728
6729 fn should_memoize_single_outcome(&mut self, key: &FastRecognizeKey) -> bool {
6732 match self.single_outcome_memo_mode {
6733 SingleOutcomeMemoMode::Promote => true,
6734 SingleOutcomeMemoMode::Sparse => false,
6735 SingleOutcomeMemoMode::Probe => {
6736 self.single_outcome_probe_samples += 1;
6737 if !self.single_outcome_probe_seen.insert(key.clone()) {
6738 self.single_outcome_probe_repeats += 1;
6739 }
6740 if self.single_outcome_probe_repeats >= CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
6741 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Promote;
6742 self.single_outcome_probe_seen.clear();
6743 return true;
6744 }
6745 if self.single_outcome_probe_samples >= CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT {
6746 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Sparse;
6747 self.single_outcome_probe_seen.clear();
6748 return false;
6749 }
6750 true
6751 }
6752 }
6753 }
6754
6755 fn token_at(&mut self, index: usize) -> Option<CommonToken> {
6757 self.input.get(index).cloned()
6758 }
6759
6760 fn token_ref_at(&mut self, index: usize) -> Option<TokenRef> {
6762 self.input.get_ref(index)
6763 }
6764
6765 fn current_visible_index(&mut self) -> usize {
6768 let index = self.input.index();
6769 self.input.seek(index);
6770 self.input.index()
6771 }
6772
6773 fn child_expected_reaches_clean_eof(
6776 &mut self,
6777 children: &[RecognizeOutcome],
6778 expected: &ExpectedTokens,
6779 ) -> bool {
6780 let Some(index) = expected.index else {
6781 return false;
6782 };
6783 self.token_type_at(index) == TOKEN_EOF
6784 && children
6785 .iter()
6786 .any(|child| child.diagnostics.is_empty() && child.index == index)
6787 }
6788
6789 fn previous_token_index(&mut self, index: usize) -> Option<usize> {
6796 self.input.previous_visible_token_index(index)
6797 }
6798
6799 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
6804 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
6805 Some(index)
6806 } else {
6807 self.previous_token_index(index)
6808 }
6809 }
6810
6811 #[must_use]
6828 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
6829 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
6830 self.rule_stop_token_index(current_index, consumed_eof)
6831 }
6832
6833 #[must_use]
6842 pub fn after_action_stop_index_for_tree(
6843 &mut self,
6844 tree: &ParseTree,
6845 current_index: usize,
6846 ) -> Option<usize> {
6847 if let ParseTree::Rule(rule) = tree {
6848 if let Some(stop) = rule.context().stop() {
6849 let token_index = stop.token_index();
6850 if token_index >= 0 {
6851 return Some(token_index.unsigned_abs());
6852 }
6853 }
6854 }
6855 self.after_action_stop_index(current_index)
6856 }
6857
6858 #[must_use]
6868 pub fn after_action_start_index_for_tree(
6869 &self,
6870 tree: &ParseTree,
6871 fallback_index: usize,
6872 ) -> usize {
6873 if let ParseTree::Rule(rule) = tree {
6874 if let Some(start) = rule.context().start() {
6875 let token_index = start.token_index();
6876 if token_index >= 0 {
6877 return token_index.unsigned_abs();
6878 }
6879 }
6880 }
6881 fallback_index
6882 }
6883
6884 fn rule_stop_token_ref(&mut self, index: usize, consumed_eof: bool) -> Option<TokenRef> {
6889 self.rule_stop_token_index(index, consumed_eof)
6890 .and_then(|token_index| self.token_ref_at(token_index))
6891 }
6892
6893 fn predicate_failure_recovery(
6900 &mut self,
6901 request: PredicateFailureRecovery<'_>,
6902 ) -> RecognizeOutcome {
6903 let PredicateFailureRecovery {
6904 rule_index,
6905 index,
6906 message,
6907 member_values,
6908 return_values,
6909 rule_alt_number,
6910 } = request;
6911 let rule_name = self
6912 .rule_names()
6913 .get(rule_index)
6914 .map_or_else(|| rule_index.to_string(), Clone::clone);
6915 let diagnostic = diagnostic_for_token(
6916 self.token_at(index).as_ref(),
6917 format!("rule {rule_name} {message}"),
6918 );
6919 let mut nodes = Vec::new();
6920 let mut next_index = index;
6921 loop {
6922 let symbol = self.token_type_at(next_index);
6923 if symbol == TOKEN_EOF {
6924 break;
6925 }
6926 nodes.push(RecognizedNode::ErrorToken { index: next_index });
6927 let after = self.consume_index(next_index, symbol);
6928 if after == next_index {
6929 break;
6930 }
6931 next_index = after;
6932 }
6933 RecognizeOutcome {
6934 index: next_index,
6935 consumed_eof: false,
6936 alt_number: rule_alt_number,
6937 member_values,
6938 return_values,
6939 diagnostics: vec![diagnostic],
6940 decisions: Vec::new(),
6941 actions: Vec::new(),
6942 nodes,
6943 }
6944 }
6945
6946 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
6953 let PredicateEval {
6954 index,
6955 rule_index,
6956 pred_index,
6957 predicates,
6958 context,
6959 local_int_arg,
6960 member_values,
6961 } = eval;
6962 let Some((_, _, predicate)) = predicates
6963 .iter()
6964 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
6965 else {
6966 return true;
6967 };
6968 self.input.seek(index);
6969 match predicate {
6970 ParserPredicate::True => true,
6971 ParserPredicate::False => false,
6972 ParserPredicate::FalseWithMessage { .. } => false,
6973 ParserPredicate::Invoke { value } => {
6974 let key = (rule_index, pred_index);
6975 if !self.invoked_predicates.contains(&key) {
6976 self.invoked_predicates.push(key);
6977 use std::io::Write as _;
6978 let mut stdout = std::io::stdout().lock();
6979 let _ = writeln!(stdout, "eval={value}");
6980 }
6981 *value
6982 }
6983 ParserPredicate::LookaheadTextEquals { offset, text } => {
6984 self.input.lt(*offset).and_then(Token::text) == Some(*text)
6985 }
6986 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
6987 self.la(*offset) != *token_type
6988 }
6989 ParserPredicate::TokenPairAdjacent => {
6990 let Some(first) = self.input.lt(-2).map(Token::token_index) else {
6991 return false;
6992 };
6993 let Some(second) = self.input.lt(-1).map(Token::token_index) else {
6994 return false;
6995 };
6996 first + 1 == second
6997 }
6998 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
6999 .and_then(|context| {
7000 context.children().iter().find_map(|child| match child {
7001 ParseTree::Rule(rule) if rule.context().rule_index() == *rule_index => {
7002 Some(child.text())
7003 }
7004 ParseTree::Rule(_) | ParseTree::Terminal(_) | ParseTree::Error(_) => None,
7005 })
7006 })
7007 .is_none_or(|actual| actual != *text),
7008 ParserPredicate::LocalIntEquals { value } => {
7009 local_int_arg.is_none_or(|(_, actual)| actual == *value)
7010 }
7011 ParserPredicate::LocalIntLessOrEqual { value } => {
7012 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
7013 }
7014 ParserPredicate::MemberModuloEquals {
7015 member,
7016 modulus,
7017 value,
7018 equals,
7019 } => {
7020 if *modulus == 0 {
7021 return false;
7022 }
7023 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
7024 (actual == *value) == *equals
7025 }
7026 ParserPredicate::MemberEquals {
7027 member,
7028 value,
7029 equals,
7030 } => {
7031 let actual = member_values.get(member).copied().unwrap_or_default();
7032 (actual == *value) == *equals
7033 }
7034 }
7035 }
7036
7037 fn parser_predicate_failure_message(
7039 &self,
7040 rule_index: usize,
7041 pred_index: usize,
7042 predicates: &[(usize, usize, ParserPredicate)],
7043 ) -> Option<&'static str> {
7044 predicates
7045 .iter()
7046 .find_map(|(rule, pred, predicate)| match predicate {
7047 ParserPredicate::FalseWithMessage { message }
7048 if *rule == rule_index && *pred == pred_index =>
7049 {
7050 Some(*message)
7051 }
7052 _ => None,
7053 })
7054 }
7055
7056 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
7065 if symbol == TOKEN_EOF {
7066 return index;
7067 }
7068 self.input.next_visible_after(index)
7069 }
7070
7071 fn no_viable_alternative(
7074 &mut self,
7075 start_index: usize,
7076 error_index: usize,
7077 ) -> ParserDiagnostic {
7078 let text = display_input_text(&self.input.text(start_index, error_index));
7079 diagnostic_for_token(
7080 self.token_at(error_index).as_ref(),
7081 format!("no viable alternative at input '{text}'"),
7082 )
7083 }
7084
7085 fn recovery_failure_diagnostic(
7088 &mut self,
7089 index: usize,
7090 decision_start_index: Option<usize>,
7091 expected_symbols: &BTreeSet<i32>,
7092 ) -> ParserDiagnostic {
7093 if expected_symbols.len() > 1 {
7094 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
7095 return self.no_viable_alternative(decision_start, index);
7096 }
7097 }
7098 diagnostic_for_token(
7099 self.token_at(index).as_ref(),
7100 format!(
7101 "mismatched input {} expecting {}",
7102 self.token_at(index)
7103 .as_ref()
7104 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7105 self.expected_symbols_display(expected_symbols)
7106 ),
7107 )
7108 }
7109
7110 fn eof_rule_recovery_diagnostic(
7113 &mut self,
7114 index: usize,
7115 expected_symbols: &BTreeSet<i32>,
7116 expected: &ExpectedTokens,
7117 ) -> ParserDiagnostic {
7118 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
7119 &expected.symbols
7120 } else {
7121 expected_symbols
7122 };
7123 diagnostic_for_token(
7124 self.token_at(index).as_ref(),
7125 format!(
7126 "mismatched input {} expecting {}",
7127 self.token_at(index)
7128 .as_ref()
7129 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7130 self.expected_symbols_display(symbols)
7131 ),
7132 )
7133 }
7134
7135 pub fn text_interval(&mut self, start: usize, stop: Option<usize>) -> String {
7141 let Some(stop) = stop else {
7142 return String::new();
7143 };
7144 let stop = if self
7145 .token_at(stop)
7146 .is_some_and(|token| token.token_type() == TOKEN_EOF)
7147 {
7148 let Some(previous) = self.previous_token_index(stop) else {
7149 return String::new();
7150 };
7151 previous
7152 } else {
7153 stop
7154 };
7155 self.input.text(start, stop)
7156 }
7157
7158 fn clear_prediction_diagnostics(&mut self) {
7161 self.prediction_diagnostics.clear();
7162 self.reported_prediction_diagnostics.clear();
7163 }
7164
7165 fn reset_per_parse_caches(&mut self) {
7187 self.rule_first_set_cache.clear();
7188 self.decision_lookahead_cache.clear();
7189 self.ll1_decision_cache.clear();
7190 self.empty_cycle_cache.clear();
7191 self.rule_stop_reach_cache.clear();
7192 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Probe;
7193 self.single_outcome_probe_seen.clear();
7194 self.single_outcome_probe_samples = 0;
7195 self.single_outcome_probe_repeats = 0;
7196 self.recovery_symbols_intern.clear();
7197 self.state_expected_cache.clear();
7198 self.state_expected_token_cache.clear();
7199 }
7200
7201 fn record_prediction_diagnostics(
7204 &mut self,
7205 atn: &Atn,
7206 state: &AtnState,
7207 start_index: usize,
7208 outcomes: &[RecognizeOutcome],
7209 ) {
7210 if !self.report_diagnostic_errors || state.transitions.len() < 2 {
7211 return;
7212 }
7213 let Some(decision) = atn
7214 .decision_to_state()
7215 .iter()
7216 .position(|state_number| *state_number == state.state_number)
7217 else {
7218 return;
7219 };
7220 let Some(rule_index) = state.rule_index else {
7221 return;
7222 };
7223 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
7224 for outcome in outcomes
7225 .iter()
7226 .filter(|outcome| outcome.diagnostics.is_empty())
7227 {
7228 let Some(alt) = outcome.decisions.first() else {
7229 continue;
7230 };
7231 alts_by_end
7232 .entry(outcome.index)
7233 .or_default()
7234 .insert(alt + 1);
7235 }
7236 let Some((&end_index, ambig_alts)) = alts_by_end
7237 .iter()
7238 .filter(|(_, alts)| alts.len() > 1)
7239 .max_by_key(|(end, _)| *end)
7240 else {
7241 return;
7242 };
7243 let rule_name = self
7244 .rule_names()
7245 .get(rule_index)
7246 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
7247 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
7248 let input = display_input_text(&self.input.text(start_index, stop_index));
7249 let alts = ambig_alts
7250 .iter()
7251 .map(usize::to_string)
7252 .collect::<Vec<_>>()
7253 .join(", ");
7254 let key = (decision, start_index, format!("{alts}:{input}"));
7255 if !self.reported_prediction_diagnostics.insert(key) {
7256 return;
7257 }
7258 let start_token = self.token_at(start_index);
7259 let stop_token = self.token_at(stop_index);
7260 self.prediction_diagnostics.push(diagnostic_for_token(
7261 start_token.as_ref(),
7262 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
7263 ));
7264 self.prediction_diagnostics.push(diagnostic_for_token(
7265 stop_token.as_ref(),
7266 format!(
7267 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
7268 ),
7269 ));
7270 }
7271
7272 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
7274 expected_symbols_display(
7275 &state_expected_symbols(atn, state_number),
7276 self.vocabulary(),
7277 )
7278 }
7279
7280 pub fn token_display_at(&mut self, index: usize) -> Option<String> {
7282 self.token_at(index).map(|token| format!("{token}"))
7283 }
7284
7285 fn recognized_node_tree(
7287 &mut self,
7288 node: &RecognizedNode,
7289 track_alt_numbers: bool,
7290 ) -> Result<ParseTree, AntlrError> {
7291 match node {
7292 RecognizedNode::Token { index } => {
7293 let token = self
7294 .input
7295 .get_ref(*index)
7296 .ok_or_else(|| AntlrError::ParserError {
7297 line: 0,
7298 column: 0,
7299 message: format!("missing token at index {index}"),
7300 })?;
7301 Ok(ParseTree::Terminal(TerminalNode::from_ref(token)))
7302 }
7303 RecognizedNode::ErrorToken { index } => {
7304 let token = self
7305 .input
7306 .get_ref(*index)
7307 .ok_or_else(|| AntlrError::ParserError {
7308 line: 0,
7309 column: 0,
7310 message: format!("missing error token at index {index}"),
7311 })?;
7312 Ok(ParseTree::Error(ErrorNode::from_ref(token)))
7313 }
7314 RecognizedNode::MissingToken {
7315 token_type,
7316 at_index,
7317 text,
7318 } => {
7319 let current = self.token_at(*at_index);
7320 let token = CommonToken::new(*token_type)
7321 .with_text(text.as_str())
7322 .with_span(usize::MAX, usize::MAX)
7323 .with_position(
7324 current.as_ref().map(Token::line).unwrap_or_default(),
7325 current.as_ref().map(Token::column).unwrap_or_default(),
7326 );
7327 Ok(ParseTree::Error(ErrorNode::new(token)))
7328 }
7329 RecognizedNode::Rule {
7330 rule_index,
7331 invoking_state,
7332 alt_number,
7333 start_index,
7334 stop_index,
7335 return_values,
7336 children,
7337 } => {
7338 let mut context = ParserRuleContext::new(*rule_index, *invoking_state);
7339 if track_alt_numbers {
7340 context.set_alt_number(*alt_number);
7341 }
7342 for (name, value) in return_values {
7343 context.set_int_return(name.clone(), *value);
7344 }
7345 if let Some(token) = self.token_ref_at(*start_index) {
7346 context.set_start_ref(token);
7347 }
7348 if let Some(token) = stop_index.and_then(|index| self.token_ref_at(index)) {
7349 context.set_stop_ref(token);
7350 }
7351 for child in children {
7352 context.add_child(self.recognized_node_tree(child, track_alt_numbers)?);
7353 }
7354 Ok(self.rule_node(context))
7355 }
7356 RecognizedNode::LeftRecursiveBoundary { rule_index } => Err(AntlrError::Unsupported(
7357 format!("unfolded left-recursive boundary for rule {rule_index}"),
7358 )),
7359 }
7360 }
7361}
7362
7363impl<S> DirectAdaptiveParser<'_, '_, S>
7364where
7365 S: TokenSource,
7366{
7367 fn parse_rule(
7368 &mut self,
7369 rule_index: usize,
7370 invoking_state: isize,
7371 precedence: i32,
7372 ) -> DirectAdaptiveParseResult<ParseTree> {
7373 let start_state = *self.atn.rule_to_start_state().get(rule_index).ok_or(
7374 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
7375 )?;
7376 let stop_state = *self
7377 .atn
7378 .rule_to_stop_state()
7379 .get(rule_index)
7380 .filter(|state| **state != usize::MAX)
7381 .ok_or(DirectAdaptiveParseControl::Fallback(
7382 DirectAdaptiveFallback::MissingAtn,
7383 ))?;
7384 let start_index = self.parser.current_visible_index();
7385 let mut children = Vec::new();
7386 let mut state_number = start_state;
7387 let mut consumed_eof = false;
7388 while state_number != stop_state {
7389 self.step()?;
7390 let (transition, boundary) = self.next_transition(state_number, precedence)?;
7391 if boundary.is_some() {
7392 return Err(DirectAdaptiveParseControl::Fallback(
7393 DirectAdaptiveFallback::LeftRecursiveBoundary,
7394 ));
7395 }
7396 match transition {
7397 Transition::Epsilon { target } => {
7398 state_number = target;
7399 }
7400 Transition::Precedence {
7401 target,
7402 precedence: transition_precedence,
7403 } => {
7404 if transition_precedence < precedence {
7405 return Err(DirectAdaptiveParseControl::Fallback(
7406 DirectAdaptiveFallback::Precedence,
7407 ));
7408 }
7409 state_number = target;
7410 }
7411 Transition::Rule {
7412 rule_index,
7413 follow_state,
7414 precedence: rule_precedence,
7415 ..
7416 } => {
7417 let child = self.parse_rule(
7418 rule_index,
7419 invoking_state_number(state_number),
7420 rule_precedence,
7421 )?;
7422 if self.parser.build_parse_trees {
7423 children.push(child);
7424 }
7425 state_number = follow_state;
7426 }
7427 Transition::Atom { .. }
7428 | Transition::Range { .. }
7429 | Transition::Set { .. }
7430 | Transition::NotSet { .. }
7431 | Transition::Wildcard { .. } => {
7432 let (matched_eof, child) = self.consume_transition(&transition)?;
7433 consumed_eof |= matched_eof;
7434 if let Some(child) = child {
7435 children.push(child);
7436 }
7437 state_number = transition.target();
7438 }
7439 Transition::Predicate { .. } => {
7440 return Err(DirectAdaptiveParseControl::Fallback(
7441 DirectAdaptiveFallback::Predicate,
7442 ));
7443 }
7444 Transition::Action { .. } => {
7445 return Err(DirectAdaptiveParseControl::Fallback(
7446 DirectAdaptiveFallback::Action,
7447 ));
7448 }
7449 }
7450 }
7451
7452 let mut context = ParserRuleContext::with_child_capacity(
7453 rule_index,
7454 invoking_state,
7455 if self.parser.build_parse_trees {
7456 children.len()
7457 } else {
7458 0
7459 },
7460 );
7461 if let Some(token) = self.parser.token_ref_at(start_index) {
7462 context.set_start_ref(token);
7463 }
7464 let stop_index = self
7465 .parser
7466 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
7467 if let Some(token) = stop_index.and_then(|index| self.parser.token_ref_at(index)) {
7468 context.set_stop_ref(token);
7469 }
7470 if self.parser.build_parse_trees {
7471 for child in children {
7472 context.add_child(child);
7473 }
7474 }
7475 Ok(self.parser.rule_node(context))
7476 }
7477
7478 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
7479 self.steps += 1;
7480 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
7481 return Err(DirectAdaptiveParseControl::Fallback(
7482 DirectAdaptiveFallback::StepLimit,
7483 ));
7484 }
7485 Ok(())
7486 }
7487
7488 fn next_transition(
7489 &mut self,
7490 state_number: usize,
7491 precedence: i32,
7492 ) -> DirectAdaptiveParseResult<(Transition, Option<usize>)> {
7493 let state = self
7494 .atn
7495 .state(state_number)
7496 .ok_or(DirectAdaptiveParseControl::Fallback(
7497 DirectAdaptiveFallback::MissingAtn,
7498 ))?;
7499 if state.is_rule_stop() {
7500 return Err(DirectAdaptiveParseControl::Fallback(
7501 DirectAdaptiveFallback::RuleStop,
7502 ));
7503 }
7504 let transition_index =
7505 self.transition_index(state_number, state.transitions.len(), precedence)?;
7506 let transition = state.transitions.get(transition_index).cloned().ok_or(
7507 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
7508 )?;
7509 let boundary = match &transition {
7510 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
7511 left_recursive_boundary(self.atn, state, *target)
7512 }
7513 _ => None,
7514 };
7515 Ok((transition, boundary))
7516 }
7517
7518 fn transition_index(
7519 &mut self,
7520 state_number: usize,
7521 transition_count: usize,
7522 precedence: i32,
7523 ) -> DirectAdaptiveParseResult<usize> {
7524 match transition_count {
7525 0 => Err(DirectAdaptiveParseControl::Fallback(
7526 DirectAdaptiveFallback::NoTransition,
7527 )),
7528 1 => Ok(0),
7529 _ => {
7530 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
7531 return Ok(alt);
7532 }
7533 let decision = self
7534 .decision_by_state
7535 .get(state_number)
7536 .and_then(|decision| *decision)
7537 .ok_or(DirectAdaptiveParseControl::Fallback(
7538 DirectAdaptiveFallback::UnknownDecision,
7539 ))?;
7540 let prediction = self
7541 .simulator
7542 .adaptive_predict_stream_info_with_precedence(
7543 decision,
7544 direct_precedence(precedence),
7545 &mut self.parser.input,
7546 )
7547 .map_err(|_| {
7548 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
7549 })?;
7550 if prediction.has_semantic_context {
7551 return Err(DirectAdaptiveParseControl::Fallback(
7552 DirectAdaptiveFallback::SemanticContext,
7553 ));
7554 }
7555 prediction
7556 .alt
7557 .checked_sub(1)
7558 .filter(|index| *index < transition_count)
7559 .ok_or(DirectAdaptiveParseControl::Fallback(
7560 DirectAdaptiveFallback::InvalidAlt,
7561 ))
7562 }
7563 }
7564 }
7565
7566 fn ll1_transition_index(
7567 &mut self,
7568 state_number: usize,
7569 transition_count: usize,
7570 ) -> DirectAdaptiveParseResult<Option<usize>> {
7571 let state = self
7572 .atn
7573 .state(state_number)
7574 .ok_or(DirectAdaptiveParseControl::Fallback(
7575 DirectAdaptiveFallback::MissingAtn,
7576 ))?;
7577 if state.precedence_rule_decision {
7578 return Ok(None);
7579 }
7580 let Some(rule_stop) = state
7581 .rule_index
7582 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index).copied())
7583 else {
7584 return Ok(None);
7585 };
7586 let symbol = self.parser.input.la_token(1);
7587 let entry = self
7588 .parser
7589 .cached_decision_lookahead(self.atn, state, rule_stop);
7590 Ok(ll1_greedy_alt(&entry, symbol, state.non_greedy).filter(|alt| *alt < transition_count))
7591 }
7592
7593 fn consume_transition(
7594 &mut self,
7595 transition: &Transition,
7596 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
7597 let symbol = self.parser.input.la_token(1);
7598 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
7599 return Err(DirectAdaptiveParseControl::Fallback(
7600 DirectAdaptiveFallback::TokenMismatch,
7601 ));
7602 }
7603 let token = self
7604 .parser
7605 .input
7606 .lt_ref(1)
7607 .ok_or(DirectAdaptiveParseControl::Fallback(
7608 DirectAdaptiveFallback::TokenMismatch,
7609 ))?;
7610 let matched_eof = symbol == TOKEN_EOF;
7611 if !matched_eof {
7612 self.parser.consume();
7613 }
7614 let child = self
7615 .parser
7616 .build_parse_trees
7617 .then(|| ParseTree::Terminal(TerminalNode::from_ref(token)));
7618 Ok((matched_eof, child))
7619 }
7620}
7621
7622fn left_recursive_boundary(atn: &Atn, state: &AtnState, target: usize) -> Option<usize> {
7625 if !state.precedence_rule_decision {
7626 return None;
7627 }
7628 let target_state = atn.state(target)?;
7629 if target_state.kind == AtnStateKind::LoopEnd {
7630 return None;
7631 }
7632 state.rule_index
7633}
7634
7635const fn next_alt_number(
7642 state: &AtnState,
7643 transition_index: usize,
7644 current_alt_number: usize,
7645 track_alt_numbers: bool,
7646) -> usize {
7647 if !track_alt_numbers || current_alt_number != 0 || state.transitions.len() <= 1 {
7648 return current_alt_number;
7649 }
7650 if matches!(
7651 state.kind,
7652 AtnStateKind::Basic
7653 | AtnStateKind::BlockStart
7654 | AtnStateKind::PlusBlockStart
7655 | AtnStateKind::StarBlockStart
7656 | AtnStateKind::StarLoopEntry
7657 ) && !state.precedence_rule_decision
7658 {
7659 return transition_index + 1;
7660 }
7661 current_alt_number
7662}
7663
7664fn fold_left_recursive_boundaries(nodes: Vec<RecognizedNode>) -> Vec<RecognizedNode> {
7667 let mut folded = Vec::new();
7668 for node in nodes {
7669 match node {
7670 RecognizedNode::LeftRecursiveBoundary { rule_index } => {
7671 if !folded.is_empty() {
7672 let children = std::mem::take(&mut folded);
7673 let start_index = recognized_nodes_start_index(&children).unwrap_or_default();
7674 let stop_index = recognized_nodes_stop_index(&children);
7675 folded.push(RecognizedNode::Rule {
7676 rule_index,
7677 invoking_state: -1,
7678 alt_number: 0,
7679 start_index,
7680 stop_index,
7681 return_values: BTreeMap::new(),
7682 children,
7683 });
7684 }
7685 }
7686 node => folded.push(node),
7687 }
7688 }
7689 folded
7690}
7691
7692fn fold_fast_left_recursive_boundaries(
7694 nodes: Vec<Rc<FastRecognizedNode>>,
7695) -> Vec<Rc<FastRecognizedNode>> {
7696 if !nodes.iter().any(|node| {
7701 matches!(
7702 node.as_ref(),
7703 FastRecognizedNode::LeftRecursiveBoundary { .. }
7704 )
7705 }) {
7706 return nodes;
7707 }
7708 let mut folded: Vec<Rc<FastRecognizedNode>> = Vec::with_capacity(nodes.len());
7709 for node in nodes {
7710 match node.as_ref() {
7711 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
7712 if !folded.is_empty() {
7713 let children = std::mem::take(&mut folded);
7714 let start_index =
7715 fast_recognized_nodes_start_index(&children).unwrap_or_default();
7716 let stop_index = fast_recognized_nodes_stop_index(&children);
7717 folded.push(Rc::new(FastRecognizedNode::Rule {
7718 rule_index: *rule_index,
7719 invoking_state: -1,
7720 start_index,
7721 stop_index,
7722 children: NodeList::from_vec(children),
7723 }));
7724 }
7725 }
7726 _ => folded.push(node),
7727 }
7728 }
7729 folded
7730}
7731
7732fn fast_node_has_left_recursive_boundary(node: &FastRecognizedNode) -> bool {
7733 match node {
7734 FastRecognizedNode::LeftRecursiveBoundary { .. } => true,
7735 FastRecognizedNode::Rule { children, .. } => children.has_left_recursive_boundary(),
7736 FastRecognizedNode::Token { .. }
7737 | FastRecognizedNode::ErrorToken { .. }
7738 | FastRecognizedNode::MissingToken { .. } => false,
7739 }
7740}
7741
7742fn fast_recognized_nodes_start_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
7743 nodes
7744 .iter()
7745 .find_map(|node| fast_recognized_node_start_index(node.as_ref()))
7746}
7747
7748const fn fast_recognized_node_start_index(node: &FastRecognizedNode) -> Option<usize> {
7749 match node {
7750 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
7751 Some(*index)
7752 }
7753 FastRecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
7754 FastRecognizedNode::Rule { start_index, .. } => Some(*start_index),
7755 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
7756 }
7757}
7758
7759const fn fast_recognized_node_span(node: &FastRecognizedNode) -> Option<(usize, Option<usize>)> {
7760 match node {
7761 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
7762 Some((*index, Some(*index)))
7763 }
7764 FastRecognizedNode::MissingToken { at_index, .. } => Some((*at_index, None)),
7765 FastRecognizedNode::Rule {
7766 start_index,
7767 stop_index,
7768 ..
7769 } => Some((*start_index, *stop_index)),
7770 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
7771 }
7772}
7773
7774fn fast_recognized_nodes_stop_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
7775 nodes
7776 .iter()
7777 .rev()
7778 .find_map(|node| fast_recognized_node_stop_index(node.as_ref()))
7779}
7780
7781const fn fast_recognized_node_stop_index(node: &FastRecognizedNode) -> Option<usize> {
7782 match node {
7783 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
7784 Some(*index)
7785 }
7786 FastRecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
7787 FastRecognizedNode::Rule { stop_index, .. } => *stop_index,
7788 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
7789 }
7790}
7791
7792fn recognized_nodes_start_index(nodes: &[RecognizedNode]) -> Option<usize> {
7793 nodes.iter().find_map(recognized_node_start_index)
7794}
7795
7796const fn recognized_node_start_index(node: &RecognizedNode) -> Option<usize> {
7797 match node {
7798 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
7799 RecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
7800 RecognizedNode::Rule { start_index, .. } => Some(*start_index),
7801 RecognizedNode::LeftRecursiveBoundary { .. } => None,
7802 }
7803}
7804
7805fn recognized_nodes_stop_index(nodes: &[RecognizedNode]) -> Option<usize> {
7806 nodes.iter().rev().find_map(recognized_node_stop_index)
7807}
7808
7809fn invoking_state_number(state_number: usize) -> isize {
7812 isize::try_from(state_number).unwrap_or(isize::MAX)
7813}
7814
7815fn direct_precedence(precedence: i32) -> usize {
7816 usize::try_from(precedence.max(0)).unwrap_or_default()
7817}
7818
7819const fn recognized_node_stop_index(node: &RecognizedNode) -> Option<usize> {
7820 match node {
7821 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
7822 RecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
7823 RecognizedNode::Rule { stop_index, .. } => *stop_index,
7824 RecognizedNode::LeftRecursiveBoundary { .. } => None,
7825 }
7826}
7827
7828fn token_input_display(token: &impl Token) -> String {
7829 format!("'{}'", token.text().unwrap_or("<EOF>"))
7830}
7831
7832fn display_input_text(text: &str) -> String {
7833 let mut out = String::new();
7834 for ch in text.chars() {
7835 match ch {
7836 '\n' => out.push_str("\\n"),
7837 '\r' => out.push_str("\\r"),
7838 '\t' => out.push_str("\\t"),
7839 other => out.push(other),
7840 }
7841 }
7842 out
7843}
7844
7845fn diagnostic_for_token(token: Option<&impl Token>, message: String) -> ParserDiagnostic {
7846 ParserDiagnostic {
7847 line: token.map(Token::line).unwrap_or_default(),
7848 column: token.map(Token::column).unwrap_or_default(),
7849 message,
7850 }
7851}
7852
7853#[allow(clippy::print_stderr)]
7855fn report_parser_diagnostics(diagnostics: &[ParserDiagnostic]) {
7856 for diagnostic in diagnostics {
7857 eprintln!(
7858 "line {}:{} {}",
7859 diagnostic.line, diagnostic.column, diagnostic.message
7860 );
7861 }
7862}
7863
7864#[allow(clippy::print_stderr)]
7867fn report_generated_diagnostics(
7868 parser_diagnostics: &[ParserDiagnostic],
7869 token_errors: &[TokenSourceError],
7870) {
7871 #[derive(Clone, Copy)]
7872 enum DiagnosticSource {
7873 Token(usize),
7874 Parser(usize),
7875 }
7876
7877 let mut ordered = Vec::with_capacity(parser_diagnostics.len() + token_errors.len());
7878 ordered.extend(token_errors.iter().enumerate().map(|(index, error)| {
7879 (
7880 error.line,
7881 error.column,
7882 0_usize,
7883 index,
7884 DiagnosticSource::Token(index),
7885 )
7886 }));
7887 ordered.extend(
7888 parser_diagnostics
7889 .iter()
7890 .enumerate()
7891 .map(|(index, diagnostic)| {
7892 (
7893 diagnostic.line,
7894 diagnostic.column,
7895 1_usize,
7896 index,
7897 DiagnosticSource::Parser(index),
7898 )
7899 }),
7900 );
7901 ordered.sort_by_key(|(line, column, source_order, index, _)| {
7902 (*line, *column, *source_order, *index)
7903 });
7904
7905 for (_, _, _, _, source) in ordered {
7906 match source {
7907 DiagnosticSource::Token(index) => {
7908 let error = &token_errors[index];
7909 eprintln!("line {}:{} {}", error.line, error.column, error.message);
7910 }
7911 DiagnosticSource::Parser(index) => {
7912 let diagnostic = &parser_diagnostics[index];
7913 eprintln!(
7914 "line {}:{} {}",
7915 diagnostic.line, diagnostic.column, diagnostic.message
7916 );
7917 }
7918 }
7919 }
7920}
7921
7922#[allow(clippy::print_stderr)]
7925fn report_token_source_errors(errors: &[TokenSourceError]) {
7926 for error in errors {
7927 eprintln!("line {}:{} {}", error.line, error.column, error.message);
7928 }
7929}
7930
7931fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
7932 let items = symbols
7933 .iter()
7934 .map(|symbol| expected_symbol_display(*symbol, vocabulary))
7935 .collect::<Vec<_>>();
7936 if let [single] = items.as_slice() {
7937 return single.clone();
7938 }
7939 format!("{{{}}}", items.join(", "))
7940}
7941
7942fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
7943 if symbol == TOKEN_EOF {
7944 return "<EOF>".to_owned();
7945 }
7946 vocabulary.display_name(symbol)
7947}
7948
7949fn is_caller_follow_boundary_text(text: &str) -> bool {
7950 text.chars().any(|ch| ch == ';' || ch == '\n')
7951 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
7952}
7953
7954fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
7955 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
7956}
7957
7958fn state_is_left_recursive_rule(atn: &Atn, state: &AtnState) -> bool {
7962 let Some(rule_index) = state.rule_index else {
7963 return false;
7964 };
7965 atn.rule_to_start_state()
7966 .get(rule_index)
7967 .and_then(|state_number| atn.state(*state_number))
7968 .is_some_and(|rule_start| rule_start.left_recursive_rule)
7969}
7970
7971fn select_better_top_outcome(
7978 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
7979 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
7980) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
7981 match (first, second) {
7982 (Ok(first), Ok(second)) => {
7983 if first.0.diagnostics.is_empty() {
7984 Ok(first)
7985 } else {
7986 Ok(second)
7987 }
7988 }
7989 (Ok(first), Err(_)) => Ok(first),
7990 (Err(_), Ok(second)) => Ok(second),
7991 (Err(_), Err(second_expected)) => Err(second_expected),
7992 }
7993}
7994
7995fn select_best_fast_outcome(
8001 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
8002 prediction_mode: PredictionMode,
8003 caller_follow: Option<&TokenBitSet>,
8004 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
8005) -> Option<FastRecognizeOutcome> {
8006 let mut best = None;
8007 let mut best_caller_follow = None;
8008 for outcome in outcomes {
8009 if matches!(
8010 prediction_mode,
8011 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
8012 ) && outcome.diagnostics.is_empty()
8013 && let Some(follow) = caller_follow
8014 {
8015 let (token_type, is_boundary, _) = token_info_at(outcome.index);
8016 if is_boundary && follow.contains(token_type) {
8017 let replace =
8018 best_caller_follow
8019 .as_ref()
8020 .is_none_or(|existing: &FastRecognizeOutcome| {
8021 (outcome.index, outcome.consumed_eof)
8022 < (existing.index, existing.consumed_eof)
8023 });
8024 if replace {
8025 best_caller_follow = Some(outcome.clone());
8026 }
8027 }
8028 }
8029 let Some(existing) = best else {
8030 best = Some(outcome);
8031 continue;
8032 };
8033 let outcome_position = (outcome.index, outcome.consumed_eof);
8034 let best_position = (existing.index, existing.consumed_eof);
8035 let better = match prediction_mode {
8036 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
8037 outcome_position,
8038 &outcome.diagnostics,
8039 best_position,
8040 &existing.diagnostics,
8041 ),
8042 PredictionMode::Sll => outcome.index > existing.index,
8043 };
8044 best = Some(if better { outcome } else { existing });
8045 }
8046 let should_use_caller_follow =
8047 best_caller_follow
8048 .as_ref()
8049 .zip(best.as_ref())
8050 .is_some_and(|(candidate, selected)| {
8051 if !selected.diagnostics.is_empty() {
8052 return true;
8053 }
8054 candidate.index < selected.index
8055 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
8056 });
8057 if should_use_caller_follow {
8058 best_caller_follow
8059 } else {
8060 best
8061 }
8062}
8063
8064fn select_best_outcome(
8065 outcomes: impl Iterator<Item = RecognizeOutcome>,
8066 prediction_mode: PredictionMode,
8067) -> Option<RecognizeOutcome> {
8068 let outcomes = outcomes.collect::<Vec<_>>();
8069 let prefer_first_tie = outcomes
8070 .iter()
8071 .any(|outcome| nodes_need_stable_tie(&outcome.nodes));
8072 outcomes.into_iter().reduce(|best, outcome| {
8073 let outcome_position = (outcome.index, outcome.consumed_eof);
8074 let best_position = (best.index, best.consumed_eof);
8075 let better = match prediction_mode {
8076 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
8077 outcome_is_better(
8078 outcome_position,
8079 &outcome.diagnostics,
8080 best_position,
8081 &best.diagnostics,
8082 ) || (!prefer_first_tie
8083 && outcome_position == best_position
8084 && outcome.diagnostics.len() == best.diagnostics.len()
8085 && diagnostic_recovery_rank(&outcome.diagnostics)
8086 == diagnostic_recovery_rank(&best.diagnostics)
8087 && (outcome.decisions < best.decisions
8088 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
8089 }
8090 PredictionMode::Sll => {
8091 outcome_position > best_position
8092 || (outcome_position == best_position
8093 && !prefer_first_tie
8094 && (outcome.decisions < best.decisions
8095 || (outcome.decisions == best.decisions
8096 && outcome_is_better(
8097 outcome_position,
8098 &outcome.diagnostics,
8099 best_position,
8100 &best.diagnostics,
8101 ))))
8102 }
8103 };
8104 if better {
8105 return outcome;
8106 }
8107 best
8108 })
8109}
8110
8111fn transition_decision(
8118 atn: &Atn,
8119 state: &AtnState,
8120 transition_index: usize,
8121 predicates: &[(usize, usize, ParserPredicate)],
8122) -> Option<usize> {
8123 if state.transitions.len() <= 1
8124 || state.precedence_rule_decision
8125 || decision_reaches_unsupported_predicate(atn, state, predicates)
8126 {
8127 return None;
8128 }
8129 Some(transition_index)
8130}
8131
8132const fn starts_prediction_decision(state: &AtnState) -> bool {
8138 state.transitions.len() > 1
8139 && !matches!(
8140 state.kind,
8141 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
8142 )
8143}
8144
8145fn record_no_viable_if_ambiguous(
8148 expected: &mut ExpectedTokens,
8149 decision_start_index: Option<usize>,
8150 index: usize,
8151) {
8152 if expected.index == Some(index) && expected.symbols.len() > 1 {
8153 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
8154 expected.record_no_viable(decision_start, index);
8155 }
8156 }
8157}
8158
8159const fn record_predicate_no_viable(
8162 expected: &mut ExpectedTokens,
8163 decision_start_index: Option<usize>,
8164 index: usize,
8165) {
8166 if let Some(decision_start) = decision_start_index {
8167 expected.record_no_viable(decision_start, index);
8168 }
8169}
8170
8171const fn no_viable_decision_start(
8173 decision_start_index: Option<usize>,
8174 index: usize,
8175) -> Option<usize> {
8176 match decision_start_index {
8177 Some(start) if index > start => Some(start),
8178 _ => None,
8179 }
8180}
8181
8182fn restore_expected(
8186 children: &[RecognizeOutcome],
8187 child_start_index: usize,
8188 expected: &mut ExpectedTokens,
8189 snapshot: ExpectedTokens,
8190 preserve_child_expected: bool,
8191) {
8192 if preserve_child_expected {
8193 return;
8194 }
8195 if children
8196 .iter()
8197 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
8198 {
8199 *expected = snapshot;
8200 }
8201}
8202
8203fn decision_reaches_unsupported_predicate(
8206 atn: &Atn,
8207 state: &AtnState,
8208 predicates: &[(usize, usize, ParserPredicate)],
8209) -> bool {
8210 state.transitions.iter().any(|transition| {
8211 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
8212 })
8213}
8214
8215fn transition_reaches_unsupported_predicate(
8217 atn: &Atn,
8218 transition: &Transition,
8219 predicates: &[(usize, usize, ParserPredicate)],
8220 visited: &mut BTreeSet<usize>,
8221) -> bool {
8222 match transition {
8223 Transition::Predicate {
8224 rule_index,
8225 pred_index,
8226 ..
8227 } => !predicates
8228 .iter()
8229 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
8230 Transition::Epsilon { target }
8231 | Transition::Action { target, .. }
8232 | Transition::Rule { target, .. } => {
8233 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
8234 }
8235 Transition::Precedence { .. }
8236 | Transition::Atom { .. }
8237 | Transition::Range { .. }
8238 | Transition::Set { .. }
8239 | Transition::NotSet { .. }
8240 | Transition::Wildcard { .. } => false,
8241 }
8242}
8243
8244fn state_reaches_unsupported_predicate(
8246 atn: &Atn,
8247 state_number: usize,
8248 predicates: &[(usize, usize, ParserPredicate)],
8249 visited: &mut BTreeSet<usize>,
8250) -> bool {
8251 if !visited.insert(state_number) {
8252 return false;
8253 }
8254 let Some(state) = atn.state(state_number) else {
8255 return false;
8256 };
8257 state.transitions.iter().any(|transition| {
8258 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
8259 })
8260}
8261
8262fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
8264 if let Some(decision) = decision {
8265 outcome.decisions.insert(0, decision);
8266 }
8267}
8268
8269fn outcome_is_better(
8270 outcome_position: (usize, bool),
8271 outcome_diagnostics: &[ParserDiagnostic],
8272 best_position: (usize, bool),
8273 best_diagnostics: &[ParserDiagnostic],
8274) -> bool {
8275 outcome_position > best_position
8276 || (outcome_position == best_position
8277 && (outcome_diagnostics.len() < best_diagnostics.len()
8278 || (outcome_diagnostics.len() == best_diagnostics.len()
8279 && diagnostic_recovery_rank(outcome_diagnostics)
8280 < diagnostic_recovery_rank(best_diagnostics))))
8281}
8282
8283fn diagnostic_recovery_rank(diagnostics: &[ParserDiagnostic]) -> usize {
8286 diagnostics
8287 .iter()
8288 .filter(|diagnostic| {
8289 diagnostic.message.starts_with("mismatched input ")
8290 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
8291 })
8292 .count()
8293}
8294
8295fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
8296 if outcomes
8297 .iter()
8298 .any(|outcome| outcome.diagnostics.is_empty())
8299 {
8300 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
8301 }
8302}
8303
8304fn discard_recovered_outcomes_if_clean_path_exists(outcomes: &mut Vec<RecognizeOutcome>) {
8305 if outcomes.iter().any(outcome_has_rule_failure_diagnostic) {
8306 return;
8307 }
8308 if outcomes
8309 .iter()
8310 .any(|outcome| outcome.diagnostics.is_empty())
8311 {
8312 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
8313 }
8314}
8315
8316fn outcome_has_rule_failure_diagnostic(outcome: &RecognizeOutcome) -> bool {
8319 outcome
8320 .diagnostics
8321 .iter()
8322 .any(|diagnostic| diagnostic.message.starts_with("rule "))
8323}
8324
8325fn nodes_need_stable_tie(nodes: &[RecognizedNode]) -> bool {
8328 nodes.iter().any(node_needs_stable_tie)
8329}
8330
8331fn node_needs_stable_tie(node: &RecognizedNode) -> bool {
8332 match node {
8333 RecognizedNode::Token { .. }
8334 | RecognizedNode::ErrorToken { .. }
8335 | RecognizedNode::MissingToken { .. } => false,
8336 RecognizedNode::LeftRecursiveBoundary { .. } => true,
8337 RecognizedNode::Rule {
8338 rule_index,
8339 children,
8340 ..
8341 } => children.iter().any(|child| {
8342 matches!(
8343 child,
8344 RecognizedNode::Rule {
8345 rule_index: child_rule,
8346 ..
8347 } if child_rule == rule_index
8348 ) || node_needs_stable_tie(child)
8349 }),
8350 }
8351}
8352
8353fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
8367 if outcomes.len() < 2 {
8368 return;
8369 }
8370 let mut keep = Vec::with_capacity(outcomes.len());
8371 let mut seen: BTreeMap<(usize, bool), Vec<usize>> = BTreeMap::new();
8372 'outcomes: for (index, outcome) in outcomes.iter().enumerate() {
8373 let bucket = seen
8374 .entry((outcome.index, outcome.consumed_eof))
8375 .or_default();
8376 for &previous in bucket.iter() {
8377 if outcomes[previous].diagnostics == outcome.diagnostics {
8378 continue 'outcomes;
8379 }
8380 }
8381 bucket.push(index);
8382 keep.push(index);
8383 }
8384 if keep.len() == outcomes.len() {
8385 return;
8386 }
8387 let mut iter = keep.into_iter();
8388 let mut next_keep = iter.next();
8389 let mut current = 0_usize;
8390 outcomes.retain(|_| {
8391 let result = next_keep == Some(current);
8392 if result {
8393 next_keep = iter.next();
8394 }
8395 current += 1;
8396 result
8397 });
8398}
8399
8400fn dedupe_clean_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
8401 if outcomes.len() < 2 {
8402 return;
8403 }
8404 let mut inline_keys: [(usize, bool); 8] = [(0, false); 8];
8414 let mut inline_len = 0_usize;
8415 let mut overflow: Vec<(usize, bool)> = Vec::new();
8416 outcomes.retain(|outcome| {
8417 let key = (outcome.index, outcome.consumed_eof);
8418 for &existing in &inline_keys[..inline_len] {
8419 if existing == key {
8420 return false;
8421 }
8422 }
8423 if !overflow.is_empty() {
8424 for &existing in &overflow {
8425 if existing == key {
8426 return false;
8427 }
8428 }
8429 }
8430 if inline_len < inline_keys.len() {
8431 inline_keys[inline_len] = key;
8432 inline_len += 1;
8433 } else {
8434 overflow.push(key);
8435 }
8436 true
8437 });
8438}
8439
8440fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>) {
8442 outcomes.sort_unstable();
8443 outcomes.dedup();
8444}
8445
8446impl<S> Recognizer for BaseParser<S>
8447where
8448 S: TokenSource,
8449{
8450 fn data(&self) -> &RecognizerData {
8451 &self.data
8452 }
8453
8454 fn data_mut(&mut self) -> &mut RecognizerData {
8455 &mut self.data
8456 }
8457}
8458
8459impl<S> Parser for BaseParser<S>
8460where
8461 S: TokenSource,
8462{
8463 fn build_parse_trees(&self) -> bool {
8464 self.build_parse_trees
8465 }
8466
8467 fn set_build_parse_trees(&mut self, build: bool) {
8468 self.build_parse_trees = build;
8469 }
8470
8471 fn number_of_syntax_errors(&self) -> usize {
8472 Self::number_of_syntax_errors(self)
8473 }
8474
8475 fn report_diagnostic_errors(&self) -> bool {
8476 self.report_diagnostic_errors
8477 }
8478
8479 fn set_report_diagnostic_errors(&mut self, report: bool) {
8480 self.report_diagnostic_errors = report;
8481 }
8482
8483 fn prediction_mode(&self) -> PredictionMode {
8484 self.prediction_mode
8485 }
8486
8487 fn set_prediction_mode(&mut self, mode: PredictionMode) {
8488 self.prediction_mode = mode;
8489 }
8490}
8491
8492#[cfg(test)]
8493mod tests {
8494 use super::*;
8495 use crate::atn::AtnType;
8496 use crate::atn::IntervalSet;
8497 use crate::atn::parser::{
8498 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
8499 };
8500 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
8501 use crate::token::{CommonToken, HIDDEN_CHANNEL, Token};
8502 use crate::token_stream::CommonTokenStream;
8503 use crate::vocabulary::Vocabulary;
8504
8505 #[test]
8506 fn fx_hasher_write_matches_typed_methods_for_full_words() {
8507 let value: u64 = 0x0102_0304_0506_0708;
8514 let mut typed = FxHasher::default();
8515 typed.write_u64(value);
8516 let mut bytewise = FxHasher::default();
8517 bytewise.write(&value.to_le_bytes());
8518 assert_eq!(typed.finish(), bytewise.finish());
8519 }
8520
8521 #[derive(Debug)]
8522 struct Source {
8523 tokens: Vec<CommonToken>,
8524 index: usize,
8525 }
8526
8527 impl TokenSource for Source {
8528 fn next_token(&mut self) -> CommonToken {
8529 let token = self
8530 .tokens
8531 .get(self.index)
8532 .cloned()
8533 .unwrap_or_else(|| CommonToken::eof("parser-test", self.index, 1, self.index));
8534 self.index += 1;
8535 token
8536 }
8537
8538 fn line(&self) -> usize {
8539 1
8540 }
8541
8542 fn column(&self) -> usize {
8543 self.index
8544 }
8545
8546 fn source_name(&self) -> &'static str {
8547 "parser-test"
8548 }
8549 }
8550
8551 fn mini_parser(tokens: Vec<CommonToken>) -> BaseParser<Source> {
8552 let data = RecognizerData::new(
8553 "Mini.g4",
8554 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
8555 );
8556 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
8557 }
8558
8559 fn token_then_eof_atn() -> Atn {
8560 AtnDeserializer::new(&SerializedAtn::from_i32(&[
8561 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, ]))
8577 .deserialize()
8578 .expect("artificial parser ATN should deserialize")
8579 }
8580
8581 fn eof_then_action_atn() -> Atn {
8582 AtnDeserializer::new(&SerializedAtn::from_i32(&[
8583 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, ]))
8599 .deserialize()
8600 .expect("artificial parser ATN should deserialize")
8601 }
8602
8603 fn two_alt_decision_atn() -> Atn {
8604 let mut atn = Atn::new(AtnType::Parser, 2);
8605 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8606 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
8607 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8608 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
8609 atn.add_state(AtnState::new(4, AtnStateKind::BlockEnd).with_rule_index(0));
8610 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
8611 atn.set_rule_to_start_state(vec![0]);
8612 atn.set_rule_to_stop_state(vec![5]);
8613 atn.add_decision_state(1);
8614 atn.state_mut(0)
8615 .expect("state 0")
8616 .add_transition(Transition::Epsilon { target: 1 });
8617 atn.state_mut(1)
8618 .expect("state 1")
8619 .add_transition(Transition::Atom {
8620 target: 2,
8621 label: 1,
8622 });
8623 atn.state_mut(1)
8624 .expect("state 1")
8625 .add_transition(Transition::Atom {
8626 target: 3,
8627 label: 2,
8628 });
8629 atn.state_mut(2)
8630 .expect("state 2")
8631 .add_transition(Transition::Epsilon { target: 4 });
8632 atn.state_mut(3)
8633 .expect("state 3")
8634 .add_transition(Transition::Epsilon { target: 4 });
8635 atn.state_mut(4)
8636 .expect("state 4")
8637 .add_transition(Transition::Epsilon { target: 5 });
8638 atn
8639 }
8640
8641 fn optional_then_b_eof_atn() -> Atn {
8644 let mut atn = Atn::new(AtnType::Parser, 3);
8645 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8646 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
8647 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8648 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
8649 atn.add_state(AtnState::new(4, AtnStateKind::Basic).with_rule_index(0));
8650 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
8651 atn.set_rule_to_start_state(vec![0]);
8652 atn.set_rule_to_stop_state(vec![5]);
8653 atn.add_decision_state(1);
8654 atn.state_mut(0)
8655 .expect("state 0")
8656 .add_transition(Transition::Epsilon { target: 1 });
8657 atn.state_mut(1)
8659 .expect("state 1")
8660 .add_transition(Transition::Atom {
8661 target: 3,
8662 label: 1,
8663 });
8664 atn.state_mut(1)
8665 .expect("state 1")
8666 .add_transition(Transition::Epsilon { target: 3 });
8667 atn.state_mut(3)
8669 .expect("state 3")
8670 .add_transition(Transition::Atom {
8671 target: 4,
8672 label: 2,
8673 });
8674 atn.state_mut(4)
8675 .expect("state 4")
8676 .add_transition(Transition::Atom {
8677 target: 5,
8678 label: TOKEN_EOF,
8679 });
8680 atn
8681 }
8682
8683 #[test]
8684 fn sync_decision_deletes_only_a_single_token() {
8685 let atn = optional_then_b_eof_atn();
8693
8694 let mut single = mini_parser(vec![
8695 CommonToken::new(3).with_text("c"),
8696 CommonToken::new(2).with_text("b"),
8697 CommonToken::eof("parser-test", 1, 2, 2),
8698 ]);
8699 single.rule_context_stack = vec![RuleContextFrame {
8700 rule_index: 0,
8701 invoking_state: 0,
8702 }];
8703 let children = single
8704 .sync_decision(&atn, 1, true, false)
8705 .expect("single extraneous token recovers");
8706 assert_eq!(children.len(), 1);
8707 assert!(matches!(children[0], ParseTree::Error(_)));
8708 assert_eq!(single.number_of_syntax_errors(), 1);
8709 assert_eq!(single.la(1), 2);
8711
8712 let mut double = mini_parser(vec![
8713 CommonToken::new(3).with_text("c"),
8714 CommonToken::new(3).with_text("c"),
8715 CommonToken::new(2).with_text("b"),
8716 CommonToken::eof("parser-test", 1, 3, 3),
8717 ]);
8718 double.rule_context_stack = vec![RuleContextFrame {
8719 rule_index: 0,
8720 invoking_state: 0,
8721 }];
8722 let result = double.sync_decision(&atn, 1, true, false);
8723 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
8728 match error {
8729 AntlrError::ParserError { message, .. } => {
8730 assert!(message.starts_with("mismatched input"), "got: {message}");
8731 }
8732 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
8733 }
8734 assert_eq!(double.la(1), 3);
8735 }
8736
8737 fn star_loop_then_eof_atn() -> Atn {
8741 AtnDeserializer::new(&SerializedAtn::from_i32(&[
8742 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,
8743 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,
8744 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,
8745 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
8746 ]))
8747 .deserialize()
8748 .expect("star-loop-then-EOF ATN should deserialize")
8749 }
8750
8751 #[test]
8752 fn sync_decision_deletes_token_before_eof_at_loop_back() {
8753 let atn = star_loop_then_eof_atn();
8759 let mut parser = mini_parser(vec![
8760 CommonToken::new(2).with_text("c"),
8761 CommonToken::eof("parser-test", 1, 1, 1),
8762 ]);
8763 parser.rule_context_stack = vec![RuleContextFrame {
8764 rule_index: 0,
8765 invoking_state: 0,
8766 }];
8767 let children = parser
8768 .sync_decision(&atn, 5, true, false)
8769 .expect("single token before EOF recovers");
8770 assert_eq!(children.len(), 1);
8771 assert!(matches!(children[0], ParseTree::Error(_)));
8772 assert_eq!(parser.number_of_syntax_errors(), 1);
8773 assert_eq!(
8774 parser.la(1),
8775 TOKEN_EOF,
8776 "EOF is left for the rule's EOF match"
8777 );
8778 }
8779
8780 #[test]
8781 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
8782 let atn = star_loop_then_eof_atn();
8787 let mut parser = mini_parser(vec![
8788 CommonToken::new(2).with_text("c"),
8789 CommonToken::new(2).with_text("c"),
8790 CommonToken::eof("parser-test", 1, 2, 2),
8791 ]);
8792 parser.rule_context_stack = vec![RuleContextFrame {
8793 rule_index: 0,
8794 invoking_state: 0,
8795 }];
8796 let error = parser
8797 .sync_decision(&atn, 5, true, false)
8798 .expect_err("two tokens at the loop entry must not be deleted");
8799 match error {
8800 AntlrError::ParserError { message, .. } => {
8801 assert!(message.starts_with("mismatched input"), "got: {message}");
8802 }
8803 other => panic!("expected mismatched-input ParserError, got {other:?}"),
8804 }
8805 assert_eq!(
8806 parser.la(1),
8807 2,
8808 "nothing consumed; cursor still on first `c`"
8809 );
8810 }
8811
8812 #[test]
8813 fn sync_decision_consumes_until_eof_at_loop_back() {
8814 let atn = star_loop_then_eof_atn();
8820 let mut parser = mini_parser(vec![
8821 CommonToken::new(2).with_text("c"),
8822 CommonToken::new(2).with_text("c"),
8823 CommonToken::eof("parser-test", 1, 2, 2),
8824 ]);
8825 parser.rule_context_stack = vec![RuleContextFrame {
8826 rule_index: 0,
8827 invoking_state: 0,
8828 }];
8829 let children = parser
8830 .sync_decision(&atn, 5, false, true)
8831 .expect("loop-back multi-token deletion recovers onto EOF");
8832 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
8833 assert!(children.iter().all(|c| matches!(c, ParseTree::Error(_))));
8834 assert_eq!(parser.number_of_syntax_errors(), 1);
8835 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
8836 }
8837
8838 fn predicate_after_token_atn() -> Atn {
8839 let mut atn = Atn::new(AtnType::Parser, 2);
8840 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8841 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
8842 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8843 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
8844 atn.add_state(AtnState::new(4, AtnStateKind::RuleStop).with_rule_index(0));
8845 atn.set_rule_to_start_state(vec![0]);
8846 atn.set_rule_to_stop_state(vec![4]);
8847 atn.state_mut(0)
8848 .expect("state 0")
8849 .add_transition(Transition::Atom {
8850 target: 1,
8851 label: 1,
8852 });
8853 atn.state_mut(1)
8854 .expect("state 1")
8855 .add_transition(Transition::Predicate {
8856 target: 2,
8857 rule_index: 0,
8858 pred_index: 0,
8859 context_dependent: false,
8860 });
8861 atn.state_mut(2)
8862 .expect("state 2")
8863 .add_transition(Transition::Atom {
8864 target: 3,
8865 label: 2,
8866 });
8867 atn.state_mut(3)
8868 .expect("state 3")
8869 .add_transition(Transition::Epsilon { target: 4 });
8870 atn
8871 }
8872
8873 fn nested_nullable_context_atn() -> Atn {
8874 let mut atn = Atn::new(AtnType::Parser, 1);
8875 for state_number in 0..=20 {
8876 let kind = match state_number {
8877 0 | 10 | 16 => AtnStateKind::RuleStart,
8878 9 | 15 | 20 => AtnStateKind::RuleStop,
8879 _ => AtnStateKind::Basic,
8880 };
8881 let rule_index = match state_number {
8882 0..=9 => 0,
8883 10..=15 => 1,
8884 _ => 2,
8885 };
8886 atn.add_state(AtnState::new(state_number, kind).with_rule_index(rule_index));
8887 }
8888 atn.set_rule_to_start_state(vec![0, 10, 16]);
8889 atn.set_rule_to_stop_state(vec![9, 15, 20]);
8890 atn.state_mut(1)
8891 .expect("state 1")
8892 .add_transition(Transition::Rule {
8893 target: 10,
8894 rule_index: 1,
8895 follow_state: 8,
8896 precedence: 0,
8897 });
8898 atn.state_mut(8)
8899 .expect("state 8")
8900 .add_transition(Transition::Atom {
8901 target: 9,
8902 label: 1,
8903 });
8904 atn.state_mut(8)
8905 .expect("state 8")
8906 .add_transition(Transition::Epsilon { target: 9 });
8907 atn.state_mut(2)
8908 .expect("state 2")
8909 .add_transition(Transition::Rule {
8910 target: 16,
8911 rule_index: 2,
8912 follow_state: 14,
8913 precedence: 0,
8914 });
8915 atn.state_mut(14)
8916 .expect("state 14")
8917 .add_transition(Transition::Epsilon { target: 15 });
8918 atn
8919 }
8920
8921 fn generated_match_recovery_atn() -> Atn {
8922 let mut atn = Atn::new(AtnType::Parser, 2);
8923 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8924 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
8925 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8926 atn.add_state(AtnState::new(3, AtnStateKind::RuleStop).with_rule_index(0));
8927 atn.add_state(AtnState::new(4, AtnStateKind::RuleStart).with_rule_index(1));
8928 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(1));
8929 atn.set_rule_to_start_state(vec![0, 4]);
8930 atn.set_rule_to_stop_state(vec![3, 5]);
8931 atn.state_mut(1)
8932 .expect("state 1")
8933 .add_transition(Transition::Rule {
8934 target: 4,
8935 rule_index: 1,
8936 follow_state: 2,
8937 precedence: 0,
8938 });
8939 atn.state_mut(2)
8940 .expect("state 2")
8941 .add_transition(Transition::Atom {
8942 target: 3,
8943 label: TOKEN_EOF,
8944 });
8945 atn
8946 }
8947
8948 fn complement_set_atn() -> Atn {
8949 let mut atn = Atn::new(AtnType::Parser, 1);
8950 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8951 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
8952 atn.set_rule_to_start_state(vec![0]);
8953 atn.set_rule_to_stop_state(vec![1]);
8954 let mut excluded = IntervalSet::new();
8955 excluded.add(1);
8956 atn.state_mut(0)
8957 .expect("state 0")
8958 .add_transition(Transition::NotSet {
8959 target: 1,
8960 set: excluded,
8961 });
8962 atn
8963 }
8964
8965 fn wildcard_then_eof_atn() -> Atn {
8968 let mut atn = Atn::new(AtnType::Parser, 1);
8969 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8970 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
8971 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8972 atn.set_rule_to_start_state(vec![0]);
8973 atn.set_rule_to_stop_state(vec![1]);
8974 atn.state_mut(0)
8975 .expect("state 0")
8976 .add_transition(Transition::Wildcard { target: 2 });
8977 atn.state_mut(2)
8978 .expect("state 2")
8979 .add_transition(Transition::Atom {
8980 target: 1,
8981 label: TOKEN_EOF,
8982 });
8983 atn
8984 }
8985
8986 #[test]
8987 fn parser_matches_token_and_reports_mismatch() {
8988 let source = Source {
8989 tokens: vec![
8990 CommonToken::new(1).with_text("x"),
8991 CommonToken::eof("parser-test", 1, 1, 1),
8992 ],
8993 index: 0,
8994 };
8995 let data = RecognizerData::new(
8996 "Mini.g4",
8997 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
8998 );
8999 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
9000 assert_eq!(
9001 parser.match_token(1).expect("token 1 should match").text(),
9002 "x"
9003 );
9004 assert!(parser.match_token(1).is_err());
9005 }
9006
9007 #[test]
9008 fn parser_matches_token_sets() {
9009 let mut parser = mini_parser(vec![
9010 CommonToken::new(1).with_text("x"),
9011 CommonToken::eof("parser-test", 1, 1, 1),
9012 ]);
9013
9014 assert_eq!(
9015 parser
9016 .match_set(&[(1, 1), (3, 4)])
9017 .expect("token set should match")
9018 .text(),
9019 "x"
9020 );
9021 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
9022 }
9023
9024 #[test]
9025 fn generated_rule_api_tracks_state_and_precedence() {
9026 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9027
9028 let context = parser.enter_rule(7, 2);
9029 assert_eq!(context.rule_index(), 2);
9030 assert_eq!(parser.state(), 7);
9031 assert_eq!(
9032 parser.rule_context_stack,
9033 vec![RuleContextFrame {
9034 rule_index: 2,
9035 invoking_state: 7
9036 }]
9037 );
9038
9039 let recursive = parser.enter_recursion_rule(11, 3, 4);
9040 assert_eq!(recursive.rule_index(), 3);
9041 assert!(parser.precpred(4));
9042 assert!(parser.precpred(5));
9043 assert!(!parser.precpred(3));
9044
9045 let next = parser.push_new_recursion_context(13, 3);
9046 assert_eq!(next.invoking_state(), 13);
9047 parser.unroll_recursion_context();
9048 assert_eq!(parser.precedence_stack, vec![0]);
9049 assert_eq!(
9050 parser.rule_context_stack,
9051 vec![RuleContextFrame {
9052 rule_index: 2,
9053 invoking_state: 7
9054 }]
9055 );
9056
9057 parser.exit_rule();
9058 assert!(parser.rule_context_stack.is_empty());
9059 }
9060
9061 #[test]
9062 fn parser_predicates_support_token_adjacency() {
9063 let mut parser = mini_parser(vec![
9064 CommonToken::new(1).with_text("=").with_span(0, 0),
9065 CommonToken::new(1).with_text(">").with_span(1, 1),
9066 CommonToken::eof("parser-test", 2, 1, 2),
9067 ]);
9068 parser.consume();
9069 parser.consume();
9070
9071 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
9072
9073 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
9074
9075 let mut parser = mini_parser(vec![
9076 CommonToken::new(1).with_text("=").with_span(0, 0),
9077 CommonToken::new(1)
9078 .with_text(" ")
9079 .with_channel(HIDDEN_CHANNEL)
9080 .with_span(1, 1),
9081 CommonToken::new(1).with_text(">").with_span(2, 2),
9082 CommonToken::eof("parser-test", 3, 1, 3),
9083 ]);
9084 parser.consume();
9085 parser.consume();
9086
9087 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
9088 }
9089
9090 #[test]
9091 fn parser_predicates_support_context_child_text_checks() {
9092 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9093 let mut context = ParserRuleContext::new(1, 0);
9094 let mut child_context = ParserRuleContext::new(2, 0);
9095 child_context.add_child(ParseTree::Terminal(TerminalNode::new(
9096 CommonToken::new(1).with_text("var"),
9097 )));
9098 context.add_child(ParseTree::Rule(RuleNode::new(child_context)));
9099 let predicates = [(
9100 1,
9101 0,
9102 ParserPredicate::ContextChildRuleTextNotEquals {
9103 rule_index: 2,
9104 text: "var",
9105 },
9106 )];
9107
9108 assert!(
9109 !parser.parser_semantic_predicate_matches_with_context_and_local(
9110 &predicates,
9111 1,
9112 0,
9113 &context,
9114 0,
9115 )
9116 );
9117 }
9118
9119 #[test]
9120 fn context_expected_symbols_walks_nullable_parent_contexts() {
9121 let atn = nested_nullable_context_atn();
9122 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9123 parser.rule_context_stack = vec![
9124 RuleContextFrame {
9125 rule_index: 0,
9126 invoking_state: 0,
9127 },
9128 RuleContextFrame {
9129 rule_index: 1,
9130 invoking_state: 1,
9131 },
9132 RuleContextFrame {
9133 rule_index: 2,
9134 invoking_state: 2,
9135 },
9136 ];
9137
9138 let expected = parser.context_expected_symbols(&atn);
9139
9140 assert!(expected.contains(&1));
9141 assert!(expected.contains(&TOKEN_EOF));
9142 }
9143
9144 #[test]
9145 fn prediction_context_reuses_cached_stack_until_rule_stack_changes() {
9146 let atn = nested_nullable_context_atn();
9147 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9148 parser.rule_context_stack = vec![
9149 RuleContextFrame {
9150 rule_index: 0,
9151 invoking_state: 0,
9152 },
9153 RuleContextFrame {
9154 rule_index: 1,
9155 invoking_state: 1,
9156 },
9157 RuleContextFrame {
9158 rule_index: 2,
9159 invoking_state: 2,
9160 },
9161 ];
9162
9163 let first = parser.prediction_context(&atn);
9164 let second = parser.prediction_context(&atn);
9165 assert!(Rc::ptr_eq(&first, &second));
9166
9167 parser.exit_rule();
9168 let after_pop = parser.prediction_context(&atn);
9169 assert!(!Rc::ptr_eq(&first, &after_pop));
9170 }
9171
9172 #[test]
9173 fn generated_match_token_recovers_missing_token_from_context_follow() {
9174 let atn = generated_match_recovery_atn();
9175 let data = RecognizerData::new(
9176 "Mini.g4",
9177 Vocabulary::new(
9178 [None, Some("'X'"), Some("'Y'")],
9179 [None, Some("X"), Some("Y")],
9180 [None::<&str>, None, None],
9181 ),
9182 );
9183 let mut parser = BaseParser::new(
9184 CommonTokenStream::new(Source {
9185 tokens: vec![CommonToken::eof("parser-test", 3, 1, 3)],
9186 index: 0,
9187 }),
9188 data,
9189 );
9190 parser.rule_context_stack = vec![
9191 RuleContextFrame {
9192 rule_index: 0,
9193 invoking_state: 0,
9194 },
9195 RuleContextFrame {
9196 rule_index: 1,
9197 invoking_state: 1,
9198 },
9199 ];
9200 assert_eq!(parser.number_of_syntax_errors(), 0);
9201
9202 let node = parser
9203 .match_token_recovering(2, 5, &atn)
9204 .expect("generated match should insert missing token");
9205
9206 assert_eq!(node.children().len(), 1);
9207 assert_eq!(node.children()[0].text(), "<missing 'Y'>");
9208 assert!(!node.consumed_eof());
9211 assert_eq!(parser.la(1), TOKEN_EOF);
9212 assert_eq!(parser.number_of_syntax_errors(), 1);
9213 assert_eq!(
9214 parser.generated_parser_diagnostics,
9215 [ParserDiagnostic {
9216 line: 1,
9217 column: 3,
9218 message: "missing 'Y' at '<EOF>'".to_owned(),
9219 }]
9220 );
9221 }
9222
9223 #[test]
9224 fn generated_match_token_counts_single_token_deletion_recovery() {
9225 let atn = generated_match_recovery_atn();
9226 let data = RecognizerData::new(
9227 "Mini.g4",
9228 Vocabulary::new(
9229 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
9230 [None, Some("X"), Some("Y"), Some("Z")],
9231 [None::<&str>, None, None, None],
9232 ),
9233 );
9234 let mut parser = BaseParser::new(
9235 CommonTokenStream::new(Source {
9236 tokens: vec![
9237 CommonToken::new(3).with_text("z"),
9238 CommonToken::new(2).with_text("y"),
9239 CommonToken::eof("parser-test", 3, 1, 3),
9240 ],
9241 index: 0,
9242 }),
9243 data,
9244 );
9245
9246 let node = parser
9247 .match_token_recovering(2, 5, &atn)
9248 .expect("generated match should delete the extraneous token");
9249
9250 assert_eq!(node.children().len(), 2);
9251 assert!(matches!(node.children()[0], ParseTree::Error(_)));
9252 assert_eq!(node.children()[0].text(), "z");
9253 assert_eq!(node.children()[1].text(), "y");
9254 assert_eq!(parser.number_of_syntax_errors(), 1);
9255 }
9256
9257 #[test]
9258 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
9259 let atn = generated_match_recovery_atn();
9260 let data = RecognizerData::new(
9261 "Mini.g4",
9262 Vocabulary::new(
9263 [None, Some("'X'"), Some("'Y'")],
9264 [None, Some("X"), Some("Y")],
9265 [None::<&str>, None, None],
9266 ),
9267 );
9268 let mut parser = BaseParser::new(
9269 CommonTokenStream::new(Source {
9270 tokens: vec![CommonToken::eof("parser-test", 3, 1, 3)],
9271 index: 0,
9272 }),
9273 data,
9274 );
9275 parser.rule_context_stack = vec![
9276 RuleContextFrame {
9277 rule_index: 0,
9278 invoking_state: 0,
9279 },
9280 RuleContextFrame {
9281 rule_index: 1,
9282 invoking_state: 1,
9283 },
9284 ];
9285 let marker = parser.generated_diagnostics_checkpoint();
9286
9287 let _ = parser
9288 .match_token_recovering(2, 5, &atn)
9289 .expect("generated match should insert missing token");
9290 assert_eq!(parser.number_of_syntax_errors(), 1);
9291
9292 parser.restore_generated_diagnostics(marker);
9293
9294 assert_eq!(parser.number_of_syntax_errors(), 0);
9295 assert!(parser.generated_parser_diagnostics.is_empty());
9296 }
9297
9298 #[test]
9299 fn generated_prediction_diagnostics_use_adaptive_context() {
9300 let atn = two_alt_decision_atn();
9301 let data = RecognizerData::new(
9302 "Mini.g4",
9303 Vocabulary::new(
9304 [None, Some("'x'"), Some("'y'")],
9305 [None, Some("X"), Some("Y")],
9306 [None::<&str>, None, None],
9307 ),
9308 )
9309 .with_rule_names(["s"]);
9310 let mut parser = BaseParser::new(
9311 CommonTokenStream::new(Source {
9312 tokens: vec![
9313 CommonToken::new(1)
9314 .with_text("x")
9315 .with_position(1, 0)
9316 .with_span(0, 0),
9317 CommonToken::new(2)
9318 .with_text("y")
9319 .with_position(1, 2)
9320 .with_span(1, 1),
9321 CommonToken::eof("parser-test", 2, 1, 3),
9322 ],
9323 index: 0,
9324 }),
9325 data,
9326 );
9327 parser.set_report_diagnostic_errors(true);
9328
9329 parser.record_generated_prediction_diagnostic(
9330 &atn,
9331 1,
9332 &ParserAtnPrediction {
9333 alt: 1,
9334 requires_full_context: true,
9335 has_semantic_context: false,
9336 diagnostic: Some(ParserAtnPredictionDiagnostic {
9337 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
9338 start_index: 0,
9339 sll_stop_index: 1,
9340 ll_stop_index: 0,
9341 conflicting_alts: vec![1, 2],
9342 }),
9343 },
9344 );
9345 parser.record_generated_prediction_diagnostic(
9346 &atn,
9347 1,
9348 &ParserAtnPrediction {
9349 alt: 1,
9350 requires_full_context: true,
9351 has_semantic_context: false,
9352 diagnostic: Some(ParserAtnPredictionDiagnostic {
9353 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
9354 start_index: 0,
9355 sll_stop_index: 1,
9356 ll_stop_index: 1,
9357 conflicting_alts: vec![1, 2],
9358 }),
9359 },
9360 );
9361
9362 assert_eq!(
9363 parser.generated_parser_diagnostics,
9364 [
9365 ParserDiagnostic {
9366 line: 1,
9367 column: 2,
9368 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
9369 },
9370 ParserDiagnostic {
9371 line: 1,
9372 column: 0,
9373 message: "reportContextSensitivity d=0 (s), input='x'".to_owned(),
9374 },
9375 ParserDiagnostic {
9376 line: 1,
9377 column: 2,
9378 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
9379 },
9380 ParserDiagnostic {
9381 line: 1,
9382 column: 2,
9383 message: "reportAmbiguity d=0 (s): ambigAlts={1, 2}, input='xy'".to_owned(),
9384 },
9385 ]
9386 );
9387 }
9388
9389 #[test]
9390 fn generated_match_not_set_recovers_empty_complement_at_eof() {
9391 let atn = complement_set_atn();
9392 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9393 parser.rule_context_stack = vec![RuleContextFrame {
9394 rule_index: 0,
9395 invoking_state: 0,
9396 }];
9397
9398 let node = parser
9399 .match_not_set_recovering(&[(1, 1)], 1, 1, 1, &atn)
9400 .expect("empty complement should recover at EOF");
9401
9402 assert_eq!(node.children().len(), 1);
9403 assert!(!node.consumed_eof());
9406 assert_eq!(parser.la(1), TOKEN_EOF);
9407 assert_eq!(
9408 parser.generated_parser_diagnostics,
9409 [ParserDiagnostic {
9410 line: 1,
9411 column: 1,
9412 message: "missing {} at '<EOF>'".to_owned(),
9413 }]
9414 );
9415 }
9416
9417 #[test]
9418 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
9419 let atn = wildcard_then_eof_atn();
9425 let data = RecognizerData::new(
9426 "Mini.g4",
9427 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
9428 );
9429 let mut parser = BaseParser::new(
9430 CommonTokenStream::new(Source {
9431 tokens: vec![CommonToken::eof("parser-test", 1, 1, 1)],
9432 index: 0,
9433 }),
9434 data,
9435 );
9436 parser.rule_context_stack = vec![RuleContextFrame {
9437 rule_index: 0,
9438 invoking_state: 0,
9439 }];
9440
9441 let node = parser
9442 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
9443 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
9444
9445 assert_eq!(node.children().len(), 1);
9447 assert!(!node.consumed_eof());
9448 assert!(node.children()[0].text().starts_with("<missing"));
9449 assert_eq!(parser.la(1), TOKEN_EOF);
9450 assert_eq!(
9451 parser.generated_parser_diagnostics,
9452 [ParserDiagnostic {
9453 line: 1,
9454 column: 1,
9455 message: "missing 'x' at '<EOF>'".to_owned(),
9456 }]
9457 );
9458 }
9459
9460 #[test]
9461 fn generated_rule_recovery_consumes_to_parent_follow() {
9462 let atn = generated_match_recovery_atn();
9463 let data = RecognizerData::new(
9464 "Mini.g4",
9465 Vocabulary::new(
9466 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
9467 [None, Some("X"), Some("Y"), Some("Z")],
9468 [None::<&str>, None, None, None],
9469 ),
9470 );
9471 let mut parser = BaseParser::new(
9472 CommonTokenStream::new(Source {
9473 tokens: vec![
9474 CommonToken::new(3).with_text("z"),
9475 CommonToken::eof("parser-test", 1, 1, 1),
9476 ],
9477 index: 0,
9478 }),
9479 data,
9480 );
9481 let _parent = parser.enter_rule(0, 0);
9482 let marker = parser.push_invoking_state(1);
9483 let mut child = parser.enter_rule(4, 1);
9484 parser.discard_invoking_state(marker);
9485
9486 parser.recover_generated_rule(
9487 &mut child,
9488 &atn,
9489 AntlrError::ParserError {
9490 line: 1,
9491 column: 0,
9492 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
9493 },
9494 );
9495 let tree = parser.finish_rule(child, false);
9496
9497 assert_eq!(parser.la(1), TOKEN_EOF);
9498 assert_eq!(tree.to_string_tree(&["s", "a"]), "(a z)");
9499 assert_eq!(parser.number_of_syntax_errors(), 1);
9500 assert_eq!(
9501 parser.generated_parser_diagnostics,
9502 [ParserDiagnostic {
9503 line: 1,
9504 column: 0,
9505 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
9506 }]
9507 );
9508 parser.exit_rule();
9509 }
9510
9511 #[test]
9512 fn greedy_ll1_alt_handles_nullable_loop_exit() {
9513 let mut body_symbols = TokenBitSet::default();
9514 body_symbols.insert(1);
9515 let entry = DecisionLookahead {
9516 transitions: vec![
9517 TransitionLookSet {
9518 symbols: body_symbols,
9519 nullable: false,
9520 },
9521 TransitionLookSet {
9522 symbols: TokenBitSet::default(),
9523 nullable: true,
9524 },
9525 ],
9526 };
9527
9528 assert_eq!(ll1_unique_alt(&entry, 2), None);
9529 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
9530 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
9531 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
9532 }
9533
9534 #[test]
9535 fn single_outcome_memo_probe_selects_sparse_or_promote_mode() {
9536 let key = |state_number| FastRecognizeKey {
9537 state_number,
9538 stop_state: 10,
9539 index: state_number,
9540 rule_start_index: 0,
9541 decision_start_index: None,
9542 precedence: 0,
9543 recovery_symbols_id: 0,
9544 recovery_state: None,
9545 };
9546
9547 let mut sparse = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9548 for state_number in 0..(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT - 1) {
9549 assert!(sparse.should_memoize_single_outcome(&key(state_number)));
9550 }
9551 assert!(!sparse.should_memoize_single_outcome(&key(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT)));
9552 assert_eq!(
9553 sparse.single_outcome_memo_mode,
9554 SingleOutcomeMemoMode::Sparse
9555 );
9556
9557 let mut promote = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9558 let repeated = key(1);
9559 for _ in 0..=CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
9560 assert!(promote.should_memoize_single_outcome(&repeated));
9561 }
9562 assert_eq!(
9563 promote.single_outcome_memo_mode,
9564 SingleOutcomeMemoMode::Promote
9565 );
9566 }
9567
9568 #[test]
9569 fn clean_empty_multi_alt_outcomes_are_memoized() {
9570 let mut atn = Atn::new(AtnType::Parser, 2);
9571 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
9572 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
9573 atn.add_state(AtnState::new(2, AtnStateKind::RuleStop).with_rule_index(0));
9574 atn.set_rule_to_start_state(vec![0]);
9575 atn.set_rule_to_stop_state(vec![2]);
9576 atn.state_mut(0)
9577 .expect("state 0")
9578 .add_transition(Transition::Epsilon { target: 1 });
9579 atn.state_mut(1)
9580 .expect("state 1")
9581 .add_transition(Transition::Atom {
9582 target: 2,
9583 label: 1,
9584 });
9585 atn.state_mut(1)
9586 .expect("state 1")
9587 .add_transition(Transition::Atom {
9588 target: 2,
9589 label: 2,
9590 });
9591
9592 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
9593 parser.fast_recovery_enabled = false;
9594 let mut visiting = FxHashSet::default();
9595 let mut memo = FxHashMap::default();
9596 let mut expected = ExpectedTokens::default();
9597 let outcomes = parser.recognize_state_fast(
9598 &atn,
9599 FastRecognizeRequest {
9600 state_number: 1,
9601 stop_state: 2,
9602 index: 0,
9603 rule_start_index: 0,
9604 decision_start_index: None,
9605 precedence: 0,
9606 depth: 0,
9607 recovery_symbols: parser.empty_recovery_symbols(),
9608 recovery_state: None,
9609 },
9610 &mut visiting,
9611 &mut memo,
9612 &mut expected,
9613 );
9614
9615 assert!(outcomes.is_empty());
9616 assert_eq!(memo.len(), 1);
9617 assert!(memo.values().next().expect("memo entry").is_empty());
9618 }
9619
9620 #[test]
9621 fn wildcard_matches_non_eof_only() {
9622 let mut parser = mini_parser(vec![
9623 CommonToken::new(1).with_text("x"),
9624 CommonToken::eof("parser-test", 1, 1, 1),
9625 ]);
9626 assert_eq!(parser.match_wildcard().expect("wildcard").text(), "x");
9627 assert!(parser.match_wildcard().is_err());
9628 }
9629
9630 #[test]
9631 fn add_parse_child_records_match_even_without_tree_building() {
9632 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9637 let token = CommonToken::new(1).with_text("x");
9638
9639 parser.set_build_parse_trees(false);
9640 let mut ctx = ParserRuleContext::new(0, 0);
9641 assert!(!ctx.has_matched_child());
9642 parser.add_parse_child(
9643 &mut ctx,
9644 ParseTree::Terminal(TerminalNode::new(token.clone())),
9645 );
9646 assert!(ctx.children().is_empty());
9648 assert!(ctx.has_matched_child());
9650
9651 parser.set_build_parse_trees(true);
9653 let mut ctx = ParserRuleContext::new(0, 0);
9654 parser.add_parse_child(&mut ctx, ParseTree::Terminal(TerminalNode::new(token)));
9655 assert_eq!(ctx.children().len(), 1);
9656 assert!(ctx.has_matched_child());
9657 }
9658
9659 #[test]
9660 fn parser_interprets_simple_atn_rule() {
9661 let atn = token_then_eof_atn();
9662 let mut parser = mini_parser(vec![
9663 CommonToken::new(1).with_text("x"),
9664 CommonToken::eof("parser-test", 1, 1, 1),
9665 ]);
9666
9667 let tree = parser
9668 .parse_atn_rule(&atn, 0)
9669 .expect("artificial parser rule should parse");
9670 assert_eq!(tree.text(), "x<EOF>");
9671 assert_eq!(parser.number_of_syntax_errors(), 0);
9672 assert_eq!(
9673 tree.first_rule_stop(0)
9674 .expect("rule should stop at EOF")
9675 .token_type(),
9676 TOKEN_EOF
9677 );
9678
9679 let mut parser = mini_parser(vec![
9680 CommonToken::new(1).with_text("x"),
9681 CommonToken::eof("parser-test", 1, 1, 1),
9682 ]);
9683 let (tree, actions) = parser
9684 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
9685 .expect("runtime-option parser rule should parse");
9686 assert!(actions.is_empty());
9687 assert_eq!(
9688 tree.first_rule_stop(0)
9689 .expect("rule should stop at EOF")
9690 .token_type(),
9691 TOKEN_EOF
9692 );
9693 }
9694
9695 #[test]
9696 fn parser_exposes_buffered_token_stream_after_parse() {
9697 let atn = token_then_eof_atn();
9698 let mut parser = mini_parser(vec![
9699 CommonToken::new(1).with_text("x"),
9700 CommonToken::eof("parser-test", 1, 1, 1),
9701 ]);
9702
9703 let tree = parser
9704 .parse_atn_rule(&atn, 0)
9705 .expect("artificial parser rule should parse");
9706 assert_eq!(tree.text(), "x<EOF>");
9707
9708 let stream = parser.token_stream();
9709 let source_index_after_parse = stream.token_source().index;
9710 let buffered = stream.tokens();
9711 assert_eq!(buffered.len(), 2);
9712 assert_eq!(buffered[0].text(), Some("x"));
9713 assert_eq!(buffered[0].token_index(), 0);
9714 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
9715 assert_eq!(stream.token_source().index, source_index_after_parse);
9716
9717 let stream = parser.into_token_stream();
9718 assert_eq!(stream.token_source().index, source_index_after_parse);
9719 assert_eq!(stream.tokens()[0].text(), Some("x"));
9720 assert_eq!(stream.tokens()[1].token_type(), TOKEN_EOF);
9721 }
9722
9723 #[test]
9724 fn parser_syntax_error_count_tracks_interpreted_recovery() {
9725 let atn = token_then_eof_atn();
9726 let mut parser = mini_parser(vec![
9727 CommonToken::new(1).with_text("x"),
9728 CommonToken::new(2).with_text("y"),
9729 CommonToken::eof("parser-test", 2, 1, 2),
9730 ]);
9731
9732 let tree = parser
9733 .parse_atn_rule(&atn, 0)
9734 .expect("invalid token should recover into an error node");
9735
9736 assert_eq!(parser.number_of_syntax_errors(), 1);
9737 assert_eq!(
9738 tree.first_error_token()
9739 .expect("recovery should embed an error token")
9740 .text(),
9741 Some("y")
9742 );
9743 }
9744
9745 #[test]
9746 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
9747 let atn = token_then_eof_atn();
9748 let mut parser = mini_parser(vec![
9749 CommonToken::new(2).with_text("y"),
9750 CommonToken::eof("parser-test", 1, 1, 1),
9751 ]);
9752
9753 let error = parser
9754 .parse_atn_rule(&atn, 0)
9755 .expect_err("start-rule mismatch should remain a parser error");
9756
9757 assert_eq!(parser.number_of_syntax_errors(), 1);
9758 assert!(matches!(error, AntlrError::ParserError { .. }));
9759 }
9760
9761 #[test]
9762 fn adaptive_direct_rule_uses_simulator_decision() {
9763 let atn = two_alt_decision_atn();
9764 let mut simulator = ParserAtnSimulator::new(&atn);
9765 let mut parser = mini_parser(vec![
9766 CommonToken::new(2).with_text("y"),
9767 CommonToken::eof("parser-test", 1, 1, 1),
9768 ]);
9769
9770 let tree = parser
9771 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
9772 .expect("direct adaptive rule should parse");
9773
9774 assert_eq!(tree.text(), "y");
9775 assert_eq!(parser.input.index(), 1);
9776 }
9777
9778 #[test]
9779 fn adaptive_direct_rule_restores_input_on_fallback() {
9780 let atn = predicate_after_token_atn();
9781 let mut simulator = ParserAtnSimulator::new(&atn);
9782 let mut parser = mini_parser(vec![
9783 CommonToken::new(1).with_text("x"),
9784 CommonToken::new(2).with_text("y"),
9785 CommonToken::eof("parser-test", 2, 1, 2),
9786 ]);
9787
9788 let tree = parser
9789 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
9790 .expect("fallback recognizer should parse");
9791
9792 assert_eq!(tree.text(), "xy");
9793 assert_eq!(parser.input.index(), 2);
9794 }
9795
9796 #[test]
9797 fn parser_rule_start_skips_leading_hidden_tokens() {
9798 let atn = token_then_eof_atn();
9799 let mut parser = mini_parser(vec![
9800 CommonToken::new(99)
9801 .with_text(" ")
9802 .with_channel(HIDDEN_CHANNEL),
9803 CommonToken::new(1).with_text("x"),
9804 CommonToken::eof("parser-test", 2, 1, 2),
9805 ]);
9806
9807 let tree = parser
9808 .parse_atn_rule(&atn, 0)
9809 .expect("artificial parser rule should parse");
9810 let Some(ParseTree::Rule(rule)) = tree.first_rule(0) else {
9811 panic!("rule node should be present");
9812 };
9813 assert_eq!(
9814 rule.context()
9815 .start()
9816 .expect("rule should have a start token")
9817 .token_type(),
9818 1
9819 );
9820 }
9821
9822 #[test]
9823 fn parser_action_after_eof_stops_at_eof_token() {
9824 let atn = eof_then_action_atn();
9825 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
9826
9827 let (_, actions) = parser
9828 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
9829 .expect("EOF action rule should parse");
9830
9831 assert_eq!(actions.len(), 1);
9832 assert_eq!(actions[0].stop_index(), Some(0));
9833 assert_eq!(
9834 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
9835 ""
9836 );
9837 }
9838
9839 #[test]
9840 fn after_action_stop_uses_rule_context_stop_not_cursor() {
9841 let mut id = CommonToken::new(1).with_text("x");
9846 id.set_token_index(0);
9847 let mut eof = CommonToken::eof("parser-test", 1, 1, 1);
9848 eof.set_token_index(1);
9849 let mut parser = mini_parser(vec![id.clone(), eof]);
9850 parser.consume();
9852 assert_eq!(parser.la(1), TOKEN_EOF);
9853
9854 let mut ctx = ParserRuleContext::new(0, 0);
9857 ctx.set_stop(id);
9858 let tree = ParseTree::Rule(RuleNode::new(ctx));
9859
9860 let current_index = parser.input.index();
9861 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
9863 assert_eq!(
9865 parser.after_action_stop_index_for_tree(&tree, current_index),
9866 Some(0)
9867 );
9868 }
9869
9870 #[test]
9871 fn after_action_start_uses_rule_context_start_not_cursor() {
9872 let parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9877 let mut id = CommonToken::new(1).with_text("x");
9878 id.set_token_index(2);
9880
9881 let mut ctx = ParserRuleContext::new(0, 0);
9882 ctx.set_start(id);
9883 let tree = ParseTree::Rule(RuleNode::new(ctx));
9884
9885 assert_eq!(parser.after_action_start_index_for_tree(&tree, 0), 2);
9888
9889 let empty = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, 0)));
9891 assert_eq!(parser.after_action_start_index_for_tree(&empty, 7), 7);
9892 }
9893
9894 #[test]
9895 fn fast_outcome_selection_respects_sll_tie_order() {
9896 let first = FastRecognizeOutcome {
9897 index: 1,
9898 consumed_eof: false,
9899 diagnostics: FastDiagnostics::from_vec(vec![ParserDiagnostic {
9900 line: 1,
9901 column: 0,
9902 message: "mismatched input 'x'".to_owned(),
9903 }]),
9904 nodes: NodeList::new(),
9905 };
9906 let second = FastRecognizeOutcome {
9907 index: first.index,
9908 consumed_eof: first.consumed_eof,
9909 diagnostics: FastDiagnostics::new(),
9910 nodes: NodeList::new(),
9911 };
9912
9913 let selected = select_best_fast_outcome(
9914 [first.clone(), second.clone()].into_iter(),
9915 PredictionMode::Sll,
9916 None,
9917 |_| panic!("caller-follow token probe should not run"),
9918 )
9919 .expect("one outcome should be selected");
9920 assert_eq!(selected.diagnostics.len(), 1);
9921 let eof_second = FastRecognizeOutcome {
9922 index: second.index,
9923 consumed_eof: true,
9924 diagnostics: FastDiagnostics::new(),
9925 nodes: NodeList::new(),
9926 };
9927 let selected = select_best_fast_outcome(
9928 [first.clone(), eof_second].into_iter(),
9929 PredictionMode::Sll,
9930 None,
9931 |_| panic!("caller-follow token probe should not run"),
9932 )
9933 .expect("one outcome should be selected");
9934 assert!(!selected.consumed_eof);
9935 let selected = select_best_fast_outcome(
9936 [first, second].into_iter(),
9937 PredictionMode::Ll,
9938 None,
9939 |_| panic!("caller-follow token probe should not run"),
9940 )
9941 .expect("one outcome should be selected");
9942 assert!(selected.diagnostics.is_empty());
9943 }
9944
9945 #[test]
9946 fn fast_outcome_selection_prefers_generated_caller_follow() {
9947 let earlier = FastRecognizeOutcome {
9948 index: 7,
9949 consumed_eof: false,
9950 diagnostics: FastDiagnostics::new(),
9951 nodes: NodeList::new(),
9952 };
9953 let later = FastRecognizeOutcome {
9954 index: 8,
9955 consumed_eof: false,
9956 diagnostics: FastDiagnostics::new(),
9957 nodes: NodeList::new(),
9958 };
9959 let mut follow = TokenBitSet::default();
9960 follow.insert(5);
9961
9962 let selected = select_best_fast_outcome(
9963 [later.clone(), earlier.clone()].into_iter(),
9964 PredictionMode::Ll,
9965 Some(&follow),
9966 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
9967 )
9968 .expect("one outcome should be selected");
9969 assert_eq!(selected.index, 7);
9970
9971 let selected = select_best_fast_outcome(
9972 [later.clone(), earlier.clone()].into_iter(),
9973 PredictionMode::Ll,
9974 Some(&follow),
9975 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
9976 )
9977 .expect("one outcome should be selected");
9978 assert_eq!(selected.index, 8);
9979
9980 let indented_next_statement = FastRecognizeOutcome {
9981 index: 9,
9982 consumed_eof: false,
9983 diagnostics: FastDiagnostics::new(),
9984 nodes: NodeList::new(),
9985 };
9986 let selected = select_best_fast_outcome(
9987 [indented_next_statement, earlier.clone()].into_iter(),
9988 PredictionMode::Ll,
9989 Some(&follow),
9990 |index| {
9991 let is_boundary = index == 7;
9992 let is_boundary_gap = matches!(index, 7 | 8);
9993 (
9994 if index == 7 { 5 } else { TOKEN_EOF },
9995 is_boundary,
9996 is_boundary_gap,
9997 )
9998 },
9999 )
10000 .expect("one outcome should be selected");
10001 assert_eq!(selected.index, 7);
10002
10003 let continuation = FastRecognizeOutcome {
10004 index: 10,
10005 consumed_eof: false,
10006 diagnostics: FastDiagnostics::new(),
10007 nodes: NodeList::new(),
10008 };
10009 let selected = select_best_fast_outcome(
10010 [continuation, earlier.clone()].into_iter(),
10011 PredictionMode::Ll,
10012 Some(&follow),
10013 |index| {
10014 let is_boundary = matches!(index, 7 | 9);
10015 (
10016 if index == 7 { 5 } else { TOKEN_EOF },
10017 is_boundary,
10018 is_boundary,
10019 )
10020 },
10021 )
10022 .expect("one outcome should be selected");
10023 assert_eq!(selected.index, 10);
10024
10025 let selected = select_best_fast_outcome(
10026 [earlier, later].into_iter(),
10027 PredictionMode::Sll,
10028 Some(&follow),
10029 |_| panic!("caller-follow token probe should not run in SLL mode"),
10030 )
10031 .expect("one outcome should be selected");
10032 assert_eq!(selected.index, 8);
10033 }
10034
10035 #[test]
10036 fn caller_follow_boundary_text_requires_separator_shape() {
10037 assert!(is_caller_follow_boundary_text(";"));
10038 assert!(is_caller_follow_boundary_text("\n"));
10039 assert!(is_caller_follow_boundary_text("\r\n "));
10040 assert!(is_caller_follow_boundary_text(";\n"));
10041 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
10042 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
10043 assert!(!is_caller_follow_boundary_text("identifier"));
10044 assert!(is_caller_follow_boundary_gap_text(" \t "));
10045 assert!(is_caller_follow_boundary_gap_text("\n "));
10046 assert!(is_caller_follow_boundary_gap_text(";\t"));
10047 assert!(!is_caller_follow_boundary_gap_text(
10048 "\"\"\"line1\nline2\"\"\""
10049 ));
10050 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
10051 }
10052
10053 #[test]
10054 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
10055 let mut parser = mini_parser(vec![
10056 CommonToken::new(5).with_text("\n"),
10057 CommonToken::new(6)
10058 .with_text("// comment\n")
10059 .with_channel(HIDDEN_CHANNEL),
10060 CommonToken::new(1).with_text("x"),
10061 CommonToken::eof("parser-test", 1, 2, 0),
10062 ]);
10063
10064 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
10065 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
10066 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
10067 }
10068
10069 #[test]
10070 fn caller_follow_token_info_uses_stream_visible_channel() {
10071 let source = Source {
10072 tokens: vec![
10073 CommonToken::new(5).with_text("\n").with_channel(2),
10074 CommonToken::new(1).with_text("x").with_channel(2),
10075 CommonToken::new(6)
10076 .with_text("// comment\n")
10077 .with_channel(HIDDEN_CHANNEL),
10078 CommonToken::eof("parser-test", 1, 2, 0),
10079 ],
10080 index: 0,
10081 };
10082 let data = RecognizerData::new(
10083 "Mini.g4",
10084 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
10085 );
10086 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
10087
10088 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
10089 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
10090 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
10091 }
10092
10093 #[test]
10094 fn reset_per_parse_caches_clears_state_expected_token_cache() {
10095 let atn = token_then_eof_atn();
10096 let mut parser = mini_parser(Vec::new());
10097
10098 let _ = parser.cached_state_expected_token_set(&atn, 0);
10099 assert!(!parser.state_expected_token_cache.is_empty());
10100
10101 parser.reset_per_parse_caches();
10102 assert!(parser.state_expected_token_cache.is_empty());
10103 }
10104
10105 #[test]
10106 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
10107 let source = Source {
10108 tokens: vec![
10109 CommonToken::new(1).with_text("x"),
10110 CommonToken::eof("parser-test", 1, 1, 1),
10111 ],
10112 index: 0,
10113 };
10114 let data = RecognizerData::new(
10115 "Mini.g4",
10116 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
10117 );
10118 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
10119 let expected = ExpectedTokens {
10120 index: Some(0),
10121 symbols: BTreeSet::new(),
10122 no_viable: None,
10123 };
10124
10125 let (_, message) = parser.expected_error_message(0, 0, &expected);
10126
10127 assert_eq!(message, "mismatched input 'x'");
10128 }
10129
10130 #[test]
10131 fn eof_rule_stop_index_points_at_eof_token() {
10132 let source = Source {
10133 tokens: vec![
10134 CommonToken::new(1).with_text("x"),
10135 CommonToken::eof("parser-test", 1, 1, 1),
10136 ],
10137 index: 0,
10138 };
10139 let data = RecognizerData::new(
10140 "Mini.g4",
10141 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
10142 );
10143 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
10144
10145 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
10146 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
10147 }
10148
10149 #[test]
10150 fn generated_parser_action_uses_current_rule_stop_boundary() {
10151 let mut parser = mini_parser(vec![
10152 CommonToken::new(1).with_text("x"),
10153 CommonToken::eof("parser-test", 1, 1, 1),
10154 ]);
10155
10156 parser.match_token(1).expect("token should match");
10157 let action = parser.parser_action_at_current(7, 0, 0, false);
10158 assert_eq!(action.source_state(), 7);
10159 assert_eq!(action.rule_index(), 0);
10160 assert_eq!(action.start_index(), 0);
10161 assert_eq!(action.stop_index(), Some(0));
10162
10163 parser.match_eof().expect("EOF should match");
10164 let action = parser.parser_action_at_current(8, 0, 0, true);
10165 assert_eq!(action.stop_index(), Some(1));
10166 }
10167
10168 #[test]
10169 fn folds_left_recursive_boundary_into_rule_node() {
10170 let nodes = fold_left_recursive_boundaries(vec![
10171 RecognizedNode::Token { index: 0 },
10172 RecognizedNode::LeftRecursiveBoundary { rule_index: 1 },
10173 RecognizedNode::Token { index: 1 },
10174 ]);
10175
10176 assert_eq!(
10177 nodes,
10178 vec![
10179 RecognizedNode::Rule {
10180 rule_index: 1,
10181 invoking_state: -1,
10182 alt_number: 0,
10183 start_index: 0,
10184 stop_index: Some(0),
10185 return_values: BTreeMap::new(),
10186 children: vec![RecognizedNode::Token { index: 0 }],
10187 },
10188 RecognizedNode::Token { index: 1 },
10189 ]
10190 );
10191 }
10192
10193 #[test]
10194 fn outcome_ties_keep_later_non_recursive_alternative() {
10195 let first = RecognizeOutcome {
10196 index: 1,
10197 consumed_eof: false,
10198 alt_number: 0,
10199 member_values: BTreeMap::new(),
10200 return_values: BTreeMap::new(),
10201 diagnostics: Vec::new(),
10202 decisions: Vec::new(),
10203 actions: vec![ParserAction::new(1, 0, 0, None)],
10204 nodes: vec![RecognizedNode::Token { index: 0 }],
10205 };
10206 let second = RecognizeOutcome {
10207 actions: vec![ParserAction::new(2, 0, 0, None)],
10208 ..first.clone()
10209 };
10210
10211 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
10212 .expect("one outcome should be selected");
10213 assert_eq!(selected.actions[0].source_state(), 2);
10214 }
10215
10216 #[test]
10217 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
10218 let first = RecognizeOutcome {
10219 index: 1,
10220 consumed_eof: false,
10221 alt_number: 0,
10222 member_values: BTreeMap::new(),
10223 return_values: BTreeMap::new(),
10224 diagnostics: Vec::new(),
10225 decisions: Vec::new(),
10226 actions: vec![ParserAction::new(1, 0, 0, None)],
10227 nodes: vec![RecognizedNode::Token { index: 0 }],
10228 };
10229 let second = RecognizeOutcome {
10230 actions: vec![
10231 ParserAction::new(2, 0, 0, None),
10232 ParserAction::new(3, 0, 0, None),
10233 ],
10234 ..first.clone()
10235 };
10236
10237 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll)
10238 .expect("one outcome should be selected");
10239 assert_eq!(selected.actions.len(), 2);
10240 }
10241
10242 #[test]
10243 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
10244 let first = RecognizeOutcome {
10245 index: 7,
10246 consumed_eof: false,
10247 alt_number: 0,
10248 member_values: BTreeMap::new(),
10249 return_values: BTreeMap::new(),
10250 diagnostics: Vec::new(),
10251 decisions: vec![1, 0],
10252 actions: vec![
10253 ParserAction::new(23, 2, 2, Some(4)),
10254 ParserAction::new(23, 2, 0, Some(6)),
10255 ],
10256 nodes: vec![RecognizedNode::Token { index: 0 }],
10257 };
10258 let second = RecognizeOutcome {
10259 decisions: vec![0, 1],
10260 actions: vec![
10261 ParserAction::new(23, 2, 2, Some(6)),
10262 ParserAction::new(23, 2, 0, Some(6)),
10263 ],
10264 ..first.clone()
10265 };
10266
10267 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
10268 .expect("one outcome should be selected");
10269 assert_eq!(selected.actions[0].stop_index(), Some(6));
10270 }
10271
10272 #[test]
10273 fn outcome_ties_keep_first_recursive_tree_shape() {
10274 let recursive_nodes = vec![RecognizedNode::Rule {
10275 rule_index: 1,
10276 invoking_state: -1,
10277 alt_number: 0,
10278 start_index: 0,
10279 stop_index: Some(0),
10280 return_values: BTreeMap::new(),
10281 children: vec![RecognizedNode::Rule {
10282 rule_index: 1,
10283 invoking_state: -1,
10284 alt_number: 0,
10285 start_index: 0,
10286 stop_index: Some(0),
10287 return_values: BTreeMap::new(),
10288 children: vec![RecognizedNode::Token { index: 0 }],
10289 }],
10290 }];
10291 let first = RecognizeOutcome {
10292 index: 1,
10293 consumed_eof: false,
10294 alt_number: 0,
10295 member_values: BTreeMap::new(),
10296 return_values: BTreeMap::new(),
10297 diagnostics: Vec::new(),
10298 decisions: Vec::new(),
10299 actions: vec![ParserAction::new(1, 0, 0, None)],
10300 nodes: recursive_nodes.clone(),
10301 };
10302 let second = RecognizeOutcome {
10303 index: 1,
10304 consumed_eof: false,
10305 alt_number: 0,
10306 member_values: BTreeMap::new(),
10307 return_values: BTreeMap::new(),
10308 diagnostics: Vec::new(),
10309 decisions: Vec::new(),
10310 actions: vec![ParserAction::new(2, 0, 0, None)],
10311 nodes: recursive_nodes,
10312 };
10313
10314 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
10315 .expect("one outcome should be selected");
10316 assert_eq!(selected.actions[0].source_state(), 1);
10317 }
10318
10319 #[test]
10320 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
10321 let first_alt = RecognizeOutcome {
10322 index: 2,
10323 consumed_eof: true,
10324 alt_number: 0,
10325 member_values: BTreeMap::new(),
10326 return_values: BTreeMap::new(),
10327 diagnostics: vec![ParserDiagnostic {
10328 line: 1,
10329 column: 3,
10330 message: "missing 'Y' at '<EOF>'".to_owned(),
10331 }],
10332 decisions: vec![0],
10333 actions: vec![ParserAction::new(1, 0, 0, None)],
10334 nodes: vec![RecognizedNode::Token { index: 0 }],
10335 };
10336 let second_alt = RecognizeOutcome {
10337 diagnostics: Vec::new(),
10338 decisions: vec![1],
10339 actions: vec![ParserAction::new(2, 0, 0, None)],
10340 ..first_alt.clone()
10341 };
10342
10343 let selected =
10344 select_best_outcome([second_alt, first_alt].into_iter(), PredictionMode::Sll)
10345 .expect("one outcome should be selected");
10346 assert_eq!(selected.diagnostics.len(), 1);
10347 assert_eq!(selected.decisions, [0]);
10348 }
10349}