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, 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 report_diagnostic_errors(&self) -> bool {
455 false
456 }
457
458 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
461
462 fn prediction_mode(&self) -> PredictionMode {
464 PredictionMode::Ll
465 }
466
467 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
469}
470
471#[derive(Debug)]
472struct CachedPredictionContext {
473 version: usize,
474 atn_key: usize,
475 context: Rc<PredictionContext>,
476}
477
478#[derive(Debug)]
479pub struct BaseParser<S> {
480 input: CommonTokenStream<S>,
481 data: RecognizerData,
482 build_parse_trees: bool,
483 report_diagnostic_errors: bool,
484 prediction_mode: PredictionMode,
485 prediction_diagnostics: Vec<ParserDiagnostic>,
486 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
487 generated_parser_diagnostics: Vec<ParserDiagnostic>,
488 generated_sync_expected: Option<TokenBitSet>,
489 int_members: BTreeMap<usize, i64>,
490 rule_context_stack: Vec<RuleContextFrame>,
491 rule_context_version: usize,
492 prediction_context_cache: Option<CachedPredictionContext>,
493 pending_invoking_states: Vec<isize>,
494 precedence_stack: Vec<i32>,
495 invoked_predicates: Vec<(usize, usize)>,
499 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
504 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
510 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
515 rule_stop_reach_cache: Vec<Option<bool>>,
520 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
525 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
531 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
537 empty_cycle_cache: Vec<Option<bool>>,
541 single_outcome_memo_mode: SingleOutcomeMemoMode,
544 single_outcome_probe_seen: FxHashSet<FastRecognizeKey>,
545 single_outcome_probe_samples: usize,
546 single_outcome_probe_repeats: usize,
547 empty_recovery_symbols: Rc<BTreeSet<i32>>,
550 fast_first_set_prefilter: bool,
558 fast_recovery_enabled: bool,
562 fast_token_nodes_enabled: bool,
567}
568
569#[derive(Clone, Copy, Debug, Eq, PartialEq)]
570struct RuleContextFrame {
571 rule_index: usize,
572 invoking_state: isize,
573}
574
575#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
576struct RecognizeOutcome {
577 index: usize,
578 consumed_eof: bool,
579 alt_number: usize,
580 member_values: BTreeMap<usize, i64>,
581 return_values: BTreeMap<String, i64>,
582 diagnostics: Vec<ParserDiagnostic>,
583 decisions: Vec<usize>,
584 actions: Vec<ParserAction>,
585 nodes: Vec<RecognizedNode>,
586}
587
588#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
589enum RecognizedNode {
590 Token {
591 index: usize,
592 },
593 ErrorToken {
594 index: usize,
595 },
596 MissingToken {
597 token_type: i32,
598 at_index: usize,
599 text: String,
600 },
601 Rule {
602 rule_index: usize,
603 invoking_state: isize,
604 alt_number: usize,
605 start_index: usize,
606 stop_index: Option<usize>,
607 return_values: BTreeMap<String, i64>,
608 children: Vec<Self>,
609 },
610 LeftRecursiveBoundary {
611 rule_index: usize,
612 },
613}
614
615#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
616struct FastRecognizeOutcome {
617 index: usize,
618 consumed_eof: bool,
619 diagnostics: FastDiagnostics,
620 nodes: NodeList,
629}
630
631#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
632#[allow(clippy::box_collection)]
633struct FastDiagnostics(Option<Box<Vec<ParserDiagnostic>>>);
634
635impl FastDiagnostics {
636 const fn new() -> Self {
637 Self(None)
638 }
639
640 #[cfg(test)]
641 fn from_vec(diagnostics: Vec<ParserDiagnostic>) -> Self {
642 if diagnostics.is_empty() {
643 Self::new()
644 } else {
645 Self(Some(Box::new(diagnostics)))
646 }
647 }
648
649 fn is_empty(&self) -> bool {
650 self.0
651 .as_ref()
652 .is_none_or(|diagnostics| diagnostics.is_empty())
653 }
654
655 fn as_slice(&self) -> &[ParserDiagnostic] {
656 self.0.as_deref().map_or(&[], Vec::as_slice)
657 }
658
659 fn insert(&mut self, index: usize, diagnostic: ParserDiagnostic) {
660 self.0
661 .get_or_insert_with(Box::default)
662 .insert(index, diagnostic);
663 }
664
665 fn append(&mut self, other: &mut Self) {
666 if other.is_empty() {
667 return;
668 }
669 self.0
670 .get_or_insert_with(Box::default)
671 .append(other.0.get_or_insert_with(Box::default));
672 if other.is_empty() {
673 other.0 = None;
674 }
675 }
676}
677
678impl std::ops::Deref for FastDiagnostics {
679 type Target = [ParserDiagnostic];
680
681 fn deref(&self) -> &Self::Target {
682 self.as_slice()
683 }
684}
685
686#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
695enum NodeList {
696 #[default]
697 Empty,
698 One(Rc<FastRecognizedNode>),
699 Cons {
700 head: Rc<FastRecognizedNode>,
701 tail: Rc<Self>,
702 },
703}
704
705impl NodeList {
706 const fn new() -> Self {
708 Self::Empty
709 }
710
711 fn cons(self, node: Rc<FastRecognizedNode>) -> Self {
714 match self {
715 Self::Empty => Self::One(node),
716 existing @ (Self::One(_) | Self::Cons { .. }) => Self::Cons {
717 head: node,
718 tail: Rc::new(existing),
719 },
720 }
721 }
722
723 fn prepend(&mut self, node: Rc<FastRecognizedNode>) {
726 let owned = std::mem::take(self);
727 *self = owned.cons(node);
728 }
729
730 fn to_vec(&self) -> Vec<Rc<FastRecognizedNode>> {
735 let mut out = Vec::new();
736 let mut cursor = self;
737 loop {
738 match cursor {
739 Self::Empty => break,
740 Self::One(node) => {
741 out.push(Rc::clone(node));
742 break;
743 }
744 Self::Cons { head, tail } => {
745 out.push(Rc::clone(head));
746 cursor = tail.as_ref();
747 }
748 }
749 }
750 out
751 }
752
753 const fn iter(&self) -> NodeListIter<'_> {
754 NodeListIter { cursor: self }
755 }
756
757 fn len(&self) -> usize {
758 self.iter().count()
759 }
760
761 fn has_left_recursive_boundary(&self) -> bool {
762 self.iter()
763 .any(|node| fast_node_has_left_recursive_boundary(node.as_ref()))
764 }
765
766 fn has_explicit_token_node(&self) -> bool {
767 self.iter().any(|node| {
768 matches!(
769 node.as_ref(),
770 FastRecognizedNode::Token { .. }
771 | FastRecognizedNode::ErrorToken { .. }
772 | FastRecognizedNode::MissingToken { .. }
773 )
774 })
775 }
776
777 fn from_vec(nodes: Vec<Rc<FastRecognizedNode>>) -> Self {
779 let mut list = Self::new();
780 for node in nodes.into_iter().rev() {
781 list.prepend(node);
782 }
783 list
784 }
785}
786
787struct NodeListIter<'a> {
788 cursor: &'a NodeList,
789}
790
791impl<'a> Iterator for NodeListIter<'a> {
792 type Item = &'a Rc<FastRecognizedNode>;
793
794 fn next(&mut self) -> Option<Self::Item> {
795 match self.cursor {
796 NodeList::Empty => None,
797 NodeList::One(node) => {
798 self.cursor = &NodeList::Empty;
799 Some(node)
800 }
801 NodeList::Cons { head, tail } => {
802 self.cursor = tail.as_ref();
803 Some(head)
804 }
805 }
806 }
807}
808
809#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
813enum FastRecognizedNode {
814 Token {
815 index: usize,
816 },
817 ErrorToken {
818 index: usize,
819 },
820 MissingToken {
821 token_type: i32,
822 at_index: usize,
823 text: String,
824 },
825 Rule {
826 rule_index: usize,
827 invoking_state: isize,
828 start_index: usize,
829 stop_index: Option<usize>,
830 children: NodeList,
831 },
832 LeftRecursiveBoundary {
836 rule_index: usize,
837 },
838}
839
840#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
841struct ParserDiagnostic {
842 line: usize,
843 column: usize,
844 message: String,
845}
846
847#[derive(Clone, Debug, Default, Eq, PartialEq)]
848struct ExpectedTokens {
849 index: Option<usize>,
850 symbols: BTreeSet<i32>,
851 no_viable: Option<NoViableAlternative>,
852}
853
854#[derive(Clone, Copy, Debug, Eq, PartialEq)]
855struct NoViableAlternative {
856 start_index: usize,
857 error_index: usize,
858}
859
860impl ExpectedTokens {
861 fn record_transition(&mut self, index: usize, transition: &Transition, max_token_type: i32) {
864 let symbols = transition_expected_symbols(transition, max_token_type);
865 match self.index {
866 Some(current) if index < current => {}
867 Some(current) if index == current => self.symbols.extend(symbols),
868 _ => {
869 self.index = Some(index);
870 self.symbols = symbols;
871 }
872 }
873 }
874
875 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
878 match self.no_viable {
879 Some(current) if error_index < current.error_index => {}
880 _ => {
881 self.no_viable = Some(NoViableAlternative {
882 start_index,
883 error_index,
884 });
885 }
886 }
887 }
888}
889
890#[derive(Clone, Debug, Default, Eq, PartialEq)]
897struct TokenBitSet {
898 words: Vec<u64>,
899}
900
901impl TokenBitSet {
902 fn insert(&mut self, symbol: i32) {
903 let Some(slot) = token_bit_slot(symbol) else {
904 return;
905 };
906 let word = slot / u64::BITS as usize;
907 if word >= self.words.len() {
908 self.words.resize(word + 1, 0);
909 }
910 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
911 }
912
913 fn extend_range(&mut self, start: i32, stop: i32) {
914 let (start, stop) = if start <= stop {
915 (start, stop)
916 } else {
917 (stop, start)
918 };
919 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
920 self.insert(TOKEN_EOF);
921 }
922 let positive_start = start.max(1);
923 if positive_start > stop {
924 return;
925 }
926 let Some(start_slot) = token_bit_slot(positive_start) else {
927 return;
928 };
929 let Some(stop_slot) = token_bit_slot(stop) else {
930 return;
931 };
932 self.extend_slot_range(start_slot, stop_slot);
933 }
934
935 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
936 if start_slot > stop_slot {
937 return;
938 }
939 let start_word = start_slot / u64::BITS as usize;
940 let stop_word = stop_slot / u64::BITS as usize;
941 if stop_word >= self.words.len() {
942 self.words.resize(stop_word + 1, 0);
943 }
944 let start_offset = start_slot % u64::BITS as usize;
945 let stop_offset = stop_slot % u64::BITS as usize;
946 if start_word == stop_word {
947 self.words[start_word] |=
948 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
949 return;
950 }
951 self.words[start_word] |= !0_u64 << start_offset;
952 for word in &mut self.words[(start_word + 1)..stop_word] {
953 *word = !0_u64;
954 }
955 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
956 }
957
958 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
959 for symbol in symbols {
960 self.insert(symbol);
961 }
962 }
963
964 fn extend_from(&mut self, other: &Self) {
965 if other.words.len() > self.words.len() {
966 self.words.resize(other.words.len(), 0);
967 }
968 for (left, right) in self.words.iter_mut().zip(&other.words) {
969 *left |= *right;
970 }
971 }
972
973 fn contains(&self, symbol: i32) -> bool {
974 let Some(slot) = token_bit_slot(symbol) else {
975 return false;
976 };
977 let word = slot / u64::BITS as usize;
978 self.words
979 .get(word)
980 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
981 }
982
983 fn is_empty(&self) -> bool {
984 self.words.iter().all(|word| *word == 0)
985 }
986
987 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
988 for (word_index, word) in self.words.iter().copied().enumerate() {
989 let mut bits = word;
990 while bits != 0 {
991 let bit = bits.trailing_zeros() as usize;
992 if let Some(symbol) = token_bit_symbol(word_index * u64::BITS as usize + bit) {
993 target.insert(symbol);
994 }
995 bits &= bits - 1;
996 }
997 }
998 }
999
1000 fn to_btree_set(&self) -> BTreeSet<i32> {
1001 let mut out = BTreeSet::new();
1002 self.extend_btree_set(&mut out);
1003 out
1004 }
1005}
1006
1007fn token_bit_slot(symbol: i32) -> Option<usize> {
1008 if symbol == TOKEN_EOF {
1009 Some(0)
1010 } else if symbol > 0 {
1011 usize::try_from(symbol).ok()
1012 } else {
1013 None
1014 }
1015}
1016
1017fn token_bit_symbol(slot: usize) -> Option<i32> {
1018 if slot == 0 {
1019 Some(TOKEN_EOF)
1020 } else {
1021 i32::try_from(slot).ok()
1022 }
1023}
1024
1025fn transition_expected_symbols(transition: &Transition, max_token_type: i32) -> BTreeSet<i32> {
1028 let mut symbols = BTreeSet::new();
1029 match transition {
1030 Transition::Atom { label, .. } => {
1031 symbols.insert(*label);
1032 }
1033 Transition::Range { start, stop, .. } => {
1034 symbols.extend(*start..=*stop);
1035 }
1036 Transition::Set { set, .. } => {
1037 for (start, stop) in set.ranges() {
1038 symbols.extend(*start..=*stop);
1039 }
1040 }
1041 Transition::NotSet { set, .. } => {
1042 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
1043 }
1044 Transition::Wildcard { .. } => {
1045 symbols.extend(1..=max_token_type);
1046 }
1047 Transition::Epsilon { .. }
1048 | Transition::Rule { .. }
1049 | Transition::Predicate { .. }
1050 | Transition::Action { .. }
1051 | Transition::Precedence { .. } => {}
1052 }
1053 symbols
1054}
1055
1056fn transition_expected_token_set(transition: &Transition, max_token_type: i32) -> TokenBitSet {
1057 let mut symbols = TokenBitSet::default();
1058 match transition {
1059 Transition::Atom { label, .. } => {
1060 symbols.insert(*label);
1061 }
1062 Transition::Range { start, stop, .. } => {
1063 symbols.extend_range(*start, *stop);
1064 }
1065 Transition::Set { set, .. } => {
1066 for (start, stop) in set.ranges() {
1067 symbols.extend_range(*start, *stop);
1068 }
1069 }
1070 Transition::NotSet { set, .. } => {
1071 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
1072 }
1073 Transition::Wildcard { .. } => {
1074 symbols.extend_range(1, max_token_type);
1075 }
1076 Transition::Epsilon { .. }
1077 | Transition::Rule { .. }
1078 | Transition::Predicate { .. }
1079 | Transition::Action { .. }
1080 | Transition::Precedence { .. } => {}
1081 }
1082 symbols
1083}
1084
1085fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
1089 let mut symbols = BTreeSet::new();
1090 let mut stack = vec![state_number];
1091 let mut visited = BTreeSet::new();
1092 while let Some(current) = stack.pop() {
1093 if !visited.insert(current) {
1094 continue;
1095 }
1096 let Some(state) = atn.state(current) else {
1097 continue;
1098 };
1099 for transition in &state.transitions {
1100 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
1101 if transition_symbols.is_empty() {
1102 if transition.is_epsilon() {
1103 stack.push(transition.target());
1104 }
1105 } else {
1106 symbols.extend(transition_symbols);
1107 }
1108 }
1109 }
1110 symbols
1111}
1112
1113fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
1114 let mut symbols = TokenBitSet::default();
1115 let mut stack = vec![state_number];
1116 let mut visited = BTreeSet::new();
1117 while let Some(current) = stack.pop() {
1118 if !visited.insert(current) {
1119 continue;
1120 }
1121 let Some(state) = atn.state(current) else {
1122 continue;
1123 };
1124 for transition in &state.transitions {
1125 let transition_symbols =
1126 transition_expected_token_set(transition, atn.max_token_type());
1127 if transition_symbols.is_empty() {
1128 if transition.is_epsilon() {
1129 stack.push(transition.target());
1130 }
1131 } else {
1132 symbols.extend_from(&transition_symbols);
1133 }
1134 }
1135 }
1136 symbols
1137}
1138
1139fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
1140 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
1141 return false;
1142 };
1143 let Some(&stop_state) = atn.rule_to_stop_state().get(rule_index) else {
1144 return false;
1145 };
1146 epsilon_reaches_state(atn, state_number, stop_state)
1147}
1148
1149fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
1150 let mut stack = vec![start];
1151 let mut visited = BTreeSet::new();
1152 while let Some(current) = stack.pop() {
1153 if current == target {
1154 return true;
1155 }
1156 if !visited.insert(current) {
1157 continue;
1158 }
1159 let Some(state) = atn.state(current) else {
1160 continue;
1161 };
1162 stack.extend(
1163 state
1164 .transitions
1165 .iter()
1166 .filter(|transition| transition.is_epsilon())
1167 .map(Transition::target),
1168 );
1169 }
1170 false
1171}
1172
1173#[derive(Clone, Debug, Default, Eq, PartialEq)]
1180struct FirstSet {
1181 symbols: TokenBitSet,
1182 nullable: bool,
1183}
1184
1185type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
1192
1193type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
1200
1201#[derive(Default)]
1202struct SharedAtnCache {
1203 first_set: FirstSetCache,
1204 decision_lookahead: DecisionLookaheadCache,
1205}
1206
1207thread_local! {
1208 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
1209 RefCell::new(FxHashMap::default());
1210}
1211
1212#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1223struct SharedAtnCacheKey {
1224 atn: usize,
1225 states: usize,
1226 state_count: usize,
1227 max_token_type: i32,
1228}
1229
1230impl SharedAtnCacheKey {
1231 fn for_atn(atn: &Atn) -> Self {
1232 Self {
1233 atn: std::ptr::from_ref::<Atn>(atn) as usize,
1234 states: atn.states().as_ptr() as usize,
1235 state_count: atn.states().len(),
1236 max_token_type: atn.max_token_type(),
1237 }
1238 }
1239}
1240
1241fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
1242 SHARED_ATN_CACHES.with(|cell| {
1243 let key = SharedAtnCacheKey::for_atn(atn);
1244 let mut map = cell.borrow_mut();
1245 let cache = map.entry(key).or_default();
1246 f(&mut cache.first_set)
1247 })
1248}
1249
1250fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
1251 SHARED_ATN_CACHES.with(|cell| {
1252 let key = SharedAtnCacheKey::for_atn(atn);
1253 let mut map = cell.borrow_mut();
1254 let cache = map.entry(key).or_default();
1255 f(cache)
1256 })
1257}
1258
1259#[derive(Debug, Default)]
1268struct DecisionLookahead {
1269 transitions: Vec<TransitionLookSet>,
1270}
1271
1272#[derive(Clone, Debug, Default)]
1279struct TransitionLookSet {
1280 symbols: TokenBitSet,
1281 nullable: bool,
1282}
1283
1284struct FirstSetCtx<'a> {
1288 cache: &'a mut FirstSetCache,
1289 in_progress: BTreeSet<(usize, usize)>,
1290 hit_cycle: bool,
1291}
1292
1293fn rule_first_set(
1302 atn: &Atn,
1303 target: usize,
1304 rule_stop_state: usize,
1305 cache: &mut FirstSetCache,
1306) -> Rc<FirstSet> {
1307 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
1308 return Rc::clone(cached);
1309 }
1310 let mut ctx = FirstSetCtx {
1311 cache,
1312 in_progress: BTreeSet::new(),
1313 hit_cycle: false,
1314 };
1315 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
1316}
1317
1318fn rule_first_set_cached(
1319 atn: &Atn,
1320 target: usize,
1321 rule_stop_state: usize,
1322 ctx: &mut FirstSetCtx<'_>,
1323) -> Rc<FirstSet> {
1324 let key = (target, rule_stop_state);
1325 if let Some(cached) = ctx.cache.get(&key) {
1326 return Rc::clone(cached);
1327 }
1328 if !ctx.in_progress.insert(key) {
1329 return Rc::new(FirstSet::default());
1333 }
1334 let saved_hit_cycle = ctx.hit_cycle;
1335 ctx.hit_cycle = false;
1336 let mut first = FirstSet::default();
1337 let mut visited = BTreeSet::new();
1338 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
1339 ctx.in_progress.remove(&key);
1340 let entry = Rc::new(first);
1341 if !ctx.hit_cycle {
1342 ctx.cache.insert(key, Rc::clone(&entry));
1343 }
1344 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
1345 entry
1346}
1347
1348fn transition_first_set(
1352 atn: &Atn,
1353 transition: &Transition,
1354 rule_stop_state: usize,
1355 cache: &mut FirstSetCache,
1356) -> TransitionLookSet {
1357 match transition {
1358 Transition::Atom { label, .. } => {
1359 let mut symbols = TokenBitSet::default();
1360 symbols.insert(*label);
1361 TransitionLookSet {
1362 symbols,
1363 nullable: false,
1364 }
1365 }
1366 Transition::Range { start, stop, .. } => {
1367 let mut symbols = TokenBitSet::default();
1368 symbols.extend_range(*start, *stop);
1369 TransitionLookSet {
1370 symbols,
1371 nullable: false,
1372 }
1373 }
1374 Transition::Set { set, .. } => {
1375 let mut symbols = TokenBitSet::default();
1376 for (start, stop) in set.ranges() {
1377 symbols.extend_range(*start, *stop);
1378 }
1379 TransitionLookSet {
1380 symbols,
1381 nullable: false,
1382 }
1383 }
1384 Transition::NotSet { set, .. } => {
1385 let max = atn.max_token_type();
1386 let mut symbols = TokenBitSet::default();
1387 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
1388 TransitionLookSet {
1389 symbols,
1390 nullable: false,
1391 }
1392 }
1393 Transition::Wildcard { .. } => {
1394 let mut symbols = TokenBitSet::default();
1395 symbols.extend_range(1, atn.max_token_type());
1396 TransitionLookSet {
1397 symbols,
1398 nullable: false,
1399 }
1400 }
1401 Transition::Epsilon { target }
1402 | Transition::Action { target, .. }
1403 | Transition::Predicate { target, .. }
1404 | Transition::Precedence { target, .. } => {
1405 let first = rule_first_set(atn, *target, rule_stop_state, cache);
1408 TransitionLookSet {
1409 symbols: first.symbols.clone(),
1410 nullable: first.nullable,
1411 }
1412 }
1413 Transition::Rule {
1414 target,
1415 rule_index,
1416 follow_state,
1417 ..
1418 } => {
1419 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
1420 return TransitionLookSet::default();
1421 };
1422 let child = rule_first_set(atn, *target, child_stop, cache);
1423 let mut symbols = child.symbols.clone();
1424 let nullable = if child.nullable {
1425 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
1426 symbols.extend_from(&follow.symbols);
1427 follow.nullable
1428 } else {
1429 false
1430 };
1431 TransitionLookSet { symbols, nullable }
1432 }
1433 }
1434}
1435
1436fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
1457 let mut chosen: Option<usize> = None;
1458 for (index, transition) in entry.transitions.iter().enumerate() {
1459 if transition.nullable {
1460 return None;
1461 }
1462 if transition.symbols.contains(symbol) {
1463 if chosen.is_some() {
1464 return None;
1465 }
1466 chosen = Some(index);
1467 }
1468 }
1469 chosen
1470}
1471
1472fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
1481 let mut matching_non_nullable_alt = None;
1482 let mut nullable_alt = None;
1483 for (index, transition) in entry.transitions.iter().enumerate() {
1484 if transition.nullable {
1485 if nullable_alt.is_some() {
1486 return None;
1487 }
1488 nullable_alt = Some(index);
1489 }
1490 if transition.symbols.contains(symbol) {
1491 if transition.nullable {
1492 continue;
1493 }
1494 if matching_non_nullable_alt.is_some() {
1495 return None;
1496 }
1497 matching_non_nullable_alt = Some(index);
1498 }
1499 }
1500 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
1501 return None;
1502 }
1503 if non_greedy {
1504 nullable_alt.or(matching_non_nullable_alt)
1505 } else {
1506 matching_non_nullable_alt.or(nullable_alt)
1507 }
1508}
1509
1510fn should_skip_via_lookahead(
1511 transition: &Transition,
1512 transition_index: usize,
1513 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
1514 index: usize,
1515 record_expected: bool,
1516 expected: &mut ExpectedTokens,
1517) -> bool {
1518 let prune_non_consuming = matches!(
1519 transition,
1520 Transition::Epsilon { .. }
1521 | Transition::Action { .. }
1522 | Transition::Predicate { .. }
1523 | Transition::Rule { .. }
1524 | Transition::Precedence { .. }
1525 );
1526 if !prune_non_consuming {
1527 return false;
1528 }
1529 let Some((symbol, entry)) = lookahead_filter else {
1530 return false;
1531 };
1532 let Some(set) = entry.transitions.get(transition_index) else {
1533 return false;
1534 };
1535 if set.symbols.contains(*symbol) || set.nullable {
1536 return false;
1537 }
1538 if record_expected && !set.symbols.is_empty() {
1539 record_pruned_transition_expected(set, index, expected);
1540 }
1541 true
1542}
1543
1544fn should_skip_rule_via_first_set(
1545 first: &FirstSet,
1546 symbol: i32,
1547 record_expected: bool,
1548 index: usize,
1549 expected: &mut ExpectedTokens,
1550) -> bool {
1551 if first.nullable || first.symbols.contains(symbol) {
1552 return false;
1553 }
1554 if record_expected && !first.symbols.is_empty() {
1555 record_token_bit_expected(&first.symbols, index, expected);
1556 }
1557 true
1558}
1559
1560fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
1561 match expected.index {
1562 Some(current) if index < current => {}
1563 Some(current) if index == current => {
1564 symbols.extend_btree_set(&mut expected.symbols);
1565 }
1566 _ => {
1567 expected.index = Some(index);
1568 expected.symbols = symbols.to_btree_set();
1569 }
1570 }
1571}
1572
1573fn record_pruned_transition_expected(
1575 set: &TransitionLookSet,
1576 index: usize,
1577 expected: &mut ExpectedTokens,
1578) {
1579 match expected.index {
1580 Some(current) if index < current => {}
1581 Some(current) if index == current => {
1582 set.symbols.extend_btree_set(&mut expected.symbols);
1583 }
1584 _ => {
1585 expected.index = Some(index);
1586 expected.symbols = set.symbols.to_btree_set();
1587 }
1588 }
1589}
1590
1591fn rule_first_set_inner(
1592 atn: &Atn,
1593 state_number: usize,
1594 rule_stop_state: usize,
1595 ctx: &mut FirstSetCtx<'_>,
1596 visited: &mut BTreeSet<usize>,
1597 first: &mut FirstSet,
1598) {
1599 if !visited.insert(state_number) {
1600 return;
1601 }
1602 if state_number == rule_stop_state {
1603 first.nullable = true;
1604 return;
1605 }
1606 let Some(state) = atn.state(state_number) else {
1607 return;
1608 };
1609 for transition in &state.transitions {
1610 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
1611 if !transition_symbols.is_empty() {
1612 first.symbols.extend_iter(transition_symbols);
1613 continue;
1614 }
1615 match transition {
1616 Transition::Epsilon { target }
1617 | Transition::Action { target, .. }
1618 | Transition::Predicate { target, .. }
1619 | Transition::Precedence { target, .. } => {
1620 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
1621 }
1622 Transition::Rule {
1623 target,
1624 rule_index,
1625 follow_state,
1626 ..
1627 } => {
1628 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied() else {
1629 continue;
1630 };
1631 let child_key = (*target, child_stop);
1632 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
1633 ctx.hit_cycle = true;
1634 }
1635 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
1636 first.symbols.extend_from(&child.symbols);
1637 if child.nullable {
1638 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
1639 }
1640 }
1641 Transition::Atom { .. }
1642 | Transition::Range { .. }
1643 | Transition::Set { .. }
1644 | Transition::NotSet { .. }
1645 | Transition::Wildcard { .. } => {}
1646 }
1647 }
1648}
1649
1650fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
1653 let mut symbols = BTreeSet::new();
1654 state_sync_symbols_inner(
1655 atn,
1656 state_number,
1657 stop_state,
1658 &mut BTreeSet::new(),
1659 &mut symbols,
1660 );
1661 symbols
1662}
1663
1664fn state_sync_symbols_inner(
1667 atn: &Atn,
1668 state_number: usize,
1669 stop_state: usize,
1670 visited: &mut BTreeSet<usize>,
1671 symbols: &mut BTreeSet<i32>,
1672) {
1673 if !visited.insert(state_number) {
1674 return;
1675 }
1676 if state_number == stop_state {
1677 symbols.insert(TOKEN_EOF);
1678 return;
1679 }
1680 let Some(state) = atn.state(state_number) else {
1681 return;
1682 };
1683 for transition in &state.transitions {
1684 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
1685 if transition_symbols.is_empty() {
1686 match transition {
1687 Transition::Rule { target, .. }
1688 | Transition::Epsilon { target }
1689 | Transition::Action { target, .. }
1690 | Transition::Predicate { target, .. }
1691 | Transition::Precedence { target, .. } => {
1692 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
1693 }
1694 Transition::Atom { .. }
1695 | Transition::Range { .. }
1696 | Transition::Set { .. }
1697 | Transition::NotSet { .. }
1698 | Transition::Wildcard { .. } => {}
1699 }
1700 } else {
1701 symbols.extend(transition_symbols);
1702 }
1703 }
1704}
1705
1706fn state_can_reach_symbol_with_precedence(
1707 atn: &Atn,
1708 state_number: usize,
1709 symbol: i32,
1710 precedence: i32,
1711 visited: &mut BTreeSet<usize>,
1712) -> bool {
1713 if !visited.insert(state_number) {
1714 return false;
1715 }
1716 let Some(state) = atn.state(state_number) else {
1717 return false;
1718 };
1719 state.transitions.iter().any(|transition| {
1720 if transition.matches(symbol, 1, atn.max_token_type()) {
1721 return true;
1722 }
1723 if !transition.is_epsilon() {
1724 return false;
1725 }
1726 if matches!(
1727 transition,
1728 Transition::Precedence {
1729 precedence: transition_precedence,
1730 ..
1731 } if *transition_precedence < precedence
1732 ) {
1733 return false;
1734 }
1735 state_can_reach_symbol_with_precedence(
1736 atn,
1737 transition.target(),
1738 symbol,
1739 precedence,
1740 visited,
1741 )
1742 })
1743}
1744
1745fn context_can_match_symbol_before_state(
1746 atn: &Atn,
1747 context: &PredictionContext,
1748 stop_state_number: usize,
1749 symbol: i32,
1750) -> bool {
1751 (0..context.len()).any(|index| {
1752 context.return_state(index).is_some_and(|return_state| {
1753 let parent = context
1754 .parent(index)
1755 .unwrap_or_else(PredictionContext::empty);
1756 state_or_parent_can_match_symbol_before_state(
1757 atn,
1758 return_state,
1759 &parent,
1760 stop_state_number,
1761 symbol,
1762 &mut BTreeSet::new(),
1763 )
1764 })
1765 })
1766}
1767
1768fn state_or_parent_can_match_symbol_before_state(
1769 atn: &Atn,
1770 state_number: usize,
1771 parent: &Rc<PredictionContext>,
1772 stop_state_number: usize,
1773 symbol: i32,
1774 visited: &mut BTreeSet<usize>,
1775) -> bool {
1776 if state_number == EMPTY_RETURN_STATE {
1777 return false;
1778 }
1779 if state_number == stop_state_number {
1780 return context_can_match_symbol_before_state(atn, parent, stop_state_number, symbol);
1781 }
1782 if !visited.insert(state_number) {
1783 return false;
1784 }
1785 let Some(state) = atn.state(state_number) else {
1786 return false;
1787 };
1788 state.transitions.iter().any(|transition| {
1789 if transition.matches(symbol, 1, atn.max_token_type()) {
1790 return true;
1791 }
1792 transition.is_epsilon()
1793 && state_or_parent_can_match_symbol_before_state(
1794 atn,
1795 transition.target(),
1796 parent,
1797 stop_state_number,
1798 symbol,
1799 visited,
1800 )
1801 })
1802}
1803
1804fn next_recovery_context(
1808 atn: &Atn,
1809 state: &AtnState,
1810 inherited: &BTreeSet<i32>,
1811 inherited_state: Option<usize>,
1812) -> (BTreeSet<i32>, Option<usize>) {
1813 let state_symbols = state_expected_symbols(atn, state.state_number);
1814 if state.transitions.len() > 1 && !state_symbols.is_empty() {
1815 let mut symbols = state_symbols;
1816 symbols.extend(inherited.iter().copied());
1817 return (symbols, Some(state.state_number));
1818 }
1819 (inherited.clone(), inherited_state)
1820}
1821
1822fn recovery_expected_symbols(
1823 atn: &Atn,
1824 state_number: usize,
1825 inherited: &BTreeSet<i32>,
1826) -> BTreeSet<i32> {
1827 let mut symbols = state_expected_symbols(atn, state_number);
1828 symbols.extend(inherited.iter().copied());
1829 symbols
1830}
1831
1832fn fast_next_recovery_context<S>(
1836 parser: &mut BaseParser<S>,
1837 atn: &Atn,
1838 state: &AtnState,
1839 inherited: &Rc<BTreeSet<i32>>,
1840 inherited_state: Option<usize>,
1841) -> (Rc<BTreeSet<i32>>, Option<usize>)
1842where
1843 S: TokenSource,
1844{
1845 if state.transitions.len() <= 1 {
1846 return (Rc::clone(inherited), inherited_state);
1847 }
1848 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number);
1849 if state_symbols.is_empty() {
1850 return (Rc::clone(inherited), inherited_state);
1851 }
1852 if inherited.is_empty() {
1853 return (state_symbols, Some(state.state_number));
1854 }
1855 if Rc::ptr_eq(&state_symbols, inherited) {
1856 return (state_symbols, Some(state.state_number));
1857 }
1858 let mut combined = (*state_symbols).clone();
1859 combined.extend(inherited.iter().copied());
1860 (
1861 parser.intern_recovery_symbols(combined),
1862 Some(state.state_number),
1863 )
1864}
1865
1866fn fast_recovery_expected_symbols<S>(
1870 parser: &mut BaseParser<S>,
1871 atn: &Atn,
1872 state_number: usize,
1873 inherited: &Rc<BTreeSet<i32>>,
1874) -> Rc<BTreeSet<i32>>
1875where
1876 S: TokenSource,
1877{
1878 let cached = parser.cached_state_expected_symbols(atn, state_number);
1879 if inherited.is_empty() {
1880 return cached;
1881 }
1882 if cached.is_empty() {
1883 return Rc::clone(inherited);
1884 }
1885 if Rc::ptr_eq(&cached, inherited) {
1886 return cached;
1887 }
1888 let mut combined = (*cached).clone();
1889 combined.extend(inherited.iter().copied());
1890 parser.intern_recovery_symbols(combined)
1891}
1892
1893fn apply_member_actions(
1895 source_state: usize,
1896 actions: &[ParserMemberAction],
1897 values: &mut BTreeMap<usize, i64>,
1898) {
1899 for action in actions
1900 .iter()
1901 .filter(|action| action.source_state == source_state)
1902 {
1903 *values.entry(action.member).or_default() += action.delta;
1904 }
1905}
1906
1907fn member_values_after_action(
1909 source_state: usize,
1910 actions: &[ParserMemberAction],
1911 values: &BTreeMap<usize, i64>,
1912) -> BTreeMap<usize, i64> {
1913 let mut values = values.clone();
1914 apply_member_actions(source_state, actions, &mut values);
1915 values
1916}
1917
1918fn return_values_after_action(
1920 source_state: usize,
1921 rule_index: usize,
1922 actions: &[ParserReturnAction],
1923 values: &BTreeMap<String, i64>,
1924) -> BTreeMap<String, i64> {
1925 let mut values = values.clone();
1926 for action in actions
1927 .iter()
1928 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
1929 {
1930 values.insert(action.name.to_owned(), action.value);
1931 }
1932 values
1933}
1934
1935fn rule_local_int_arg(
1937 rule_args: &[ParserRuleArg],
1938 source_state: usize,
1939 rule_index: usize,
1940 local_int_arg: Option<(usize, i64)>,
1941) -> Option<(usize, i64)> {
1942 rule_args
1943 .iter()
1944 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
1945 .map(|arg| {
1946 let value = if arg.inherit_local {
1947 local_int_arg.map_or(arg.value, |(_, value)| value)
1948 } else {
1949 arg.value
1950 };
1951 (rule_index, value)
1952 })
1953}
1954
1955fn stop_outcome(
1958 index: usize,
1959 consumed_eof: bool,
1960 rule_alt_number: usize,
1961 member_values: BTreeMap<usize, i64>,
1962 return_values: BTreeMap<String, i64>,
1963) -> Vec<RecognizeOutcome> {
1964 vec![RecognizeOutcome {
1965 index,
1966 consumed_eof,
1967 alt_number: rule_alt_number,
1968 member_values,
1969 return_values,
1970 diagnostics: Vec::new(),
1971 decisions: Vec::new(),
1972 actions: Vec::new(),
1973 nodes: Vec::new(),
1974 }]
1975}
1976
1977#[derive(Clone, Debug, Eq, PartialEq)]
1978struct RecognizeRequest<'a> {
1979 state_number: usize,
1980 stop_state: usize,
1981 index: usize,
1982 rule_start_index: usize,
1983 decision_start_index: Option<usize>,
1984 init_action_rules: &'a BTreeSet<usize>,
1985 predicates: &'a [(usize, usize, ParserPredicate)],
1986 rule_args: &'a [ParserRuleArg],
1987 member_actions: &'a [ParserMemberAction],
1988 return_actions: &'a [ParserReturnAction],
1989 local_int_arg: Option<(usize, i64)>,
1990 member_values: BTreeMap<usize, i64>,
1991 return_values: BTreeMap<String, i64>,
1992 rule_alt_number: usize,
1993 track_alt_numbers: bool,
1994 consumed_eof: bool,
1995 precedence: i32,
1998 depth: usize,
1999 recovery_symbols: BTreeSet<i32>,
2000 recovery_state: Option<usize>,
2001}
2002
2003#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2004struct RecognizeKey {
2005 state_number: usize,
2006 stop_state: usize,
2007 index: usize,
2008 rule_start_index: usize,
2009 decision_start_index: Option<usize>,
2010 local_int_arg: Option<(usize, i64)>,
2011 member_values: BTreeMap<usize, i64>,
2012 return_values: BTreeMap<String, i64>,
2013 rule_alt_number: usize,
2014 track_alt_numbers: bool,
2015 consumed_eof: bool,
2016 precedence: i32,
2017 recovery_symbols: BTreeSet<i32>,
2018 recovery_state: Option<usize>,
2019}
2020
2021#[derive(Clone, Debug, Eq, PartialEq)]
2022struct EpsilonActionStep {
2023 source_state: usize,
2024 target: usize,
2025 action_rule_index: Option<usize>,
2026 left_recursive_boundary: Option<usize>,
2027 decision: Option<usize>,
2028 decision_start_index: Option<usize>,
2029 alt_number: usize,
2030 recovery_symbols: BTreeSet<i32>,
2031 recovery_state: Option<usize>,
2032}
2033
2034struct RecognizeScratch<'a> {
2035 visiting: &'a mut BTreeSet<RecognizeKey>,
2036 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2037 expected: &'a mut ExpectedTokens,
2038}
2039
2040#[derive(Clone, Debug, Eq, PartialEq)]
2041struct FastRecognizeRequest {
2042 state_number: usize,
2043 stop_state: usize,
2044 index: usize,
2045 rule_start_index: usize,
2046 decision_start_index: Option<usize>,
2047 precedence: i32,
2048 depth: usize,
2049 recovery_symbols: Rc<BTreeSet<i32>>,
2050 recovery_state: Option<usize>,
2051}
2052
2053#[derive(Clone, Debug)]
2060struct FastRecognizeKey {
2061 state_number: usize,
2062 stop_state: usize,
2063 index: usize,
2064 rule_start_index: usize,
2065 decision_start_index: Option<usize>,
2066 precedence: i32,
2067 recovery_symbols_id: usize,
2068 recovery_state: Option<usize>,
2069}
2070
2071impl PartialEq for FastRecognizeKey {
2072 fn eq(&self, other: &Self) -> bool {
2073 if self.state_number != other.state_number
2074 || self.stop_state != other.stop_state
2075 || self.index != other.index
2076 || self.rule_start_index != other.rule_start_index
2077 || self.decision_start_index != other.decision_start_index
2078 || self.precedence != other.precedence
2079 || self.recovery_state != other.recovery_state
2080 || self.recovery_symbols_id != other.recovery_symbols_id
2081 {
2082 return false;
2083 }
2084 true
2085 }
2086}
2087
2088impl Eq for FastRecognizeKey {}
2089
2090impl Hash for FastRecognizeKey {
2091 fn hash<H: Hasher>(&self, hasher: &mut H) {
2092 self.state_number.hash(hasher);
2093 self.stop_state.hash(hasher);
2094 self.index.hash(hasher);
2095 self.rule_start_index.hash(hasher);
2096 self.decision_start_index.hash(hasher);
2097 self.precedence.hash(hasher);
2098 self.recovery_state.hash(hasher);
2099 self.recovery_symbols_id.hash(hasher);
2100 }
2101}
2102
2103struct FastRecoveryRequest<'a, 'b> {
2104 atn: &'a Atn,
2105 transition: &'a Transition,
2106 expected_symbols: Rc<BTreeSet<i32>>,
2107 target: usize,
2108 request: FastRecognizeRequest,
2109 visiting: &'b mut FxHashSet<(usize, usize)>,
2110 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
2111 expected: &'b mut ExpectedTokens,
2112}
2113
2114struct FastCurrentTokenDeletionRequest<'a, 'b> {
2115 atn: &'a Atn,
2116 expected_symbols: Rc<BTreeSet<i32>>,
2117 request: FastRecognizeRequest,
2118 visiting: &'b mut FxHashSet<(usize, usize)>,
2119 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
2120 expected: &'b mut ExpectedTokens,
2121}
2122
2123#[derive(Clone, Copy)]
2124struct FastChildRuleFailureRecoveryRequest<'a> {
2125 atn: &'a Atn,
2126 rule_index: usize,
2127 start_index: usize,
2128 follow_state: usize,
2129 stop_state: usize,
2130 expected: &'a ExpectedTokens,
2131}
2132
2133struct RecoveryRequest<'a, 'b> {
2134 atn: &'a Atn,
2135 transition: &'a Transition,
2136 expected_symbols: BTreeSet<i32>,
2137 target: usize,
2138 request: RecognizeRequest<'a>,
2139 visiting: &'b mut BTreeSet<RecognizeKey>,
2140 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2141 expected: &'b mut ExpectedTokens,
2142}
2143
2144struct CurrentTokenDeletionRequest<'a, 'b> {
2145 atn: &'a Atn,
2146 expected_symbols: BTreeSet<i32>,
2147 request: RecognizeRequest<'a>,
2148 visiting: &'b mut BTreeSet<RecognizeKey>,
2149 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
2150 expected: &'b mut ExpectedTokens,
2151}
2152
2153struct ConsumingFailureFallback<'a> {
2156 atn: &'a Atn,
2157 target: usize,
2158 request: RecognizeRequest<'a>,
2159 symbol: i32,
2160 expected_symbols: BTreeSet<i32>,
2161 decision_start_index: Option<usize>,
2162 decision: Option<usize>,
2163}
2164
2165struct ChildRuleFailureRecovery<'a> {
2168 atn: &'a Atn,
2169 rule_index: usize,
2170 start_index: usize,
2171 follow_state: usize,
2172 stop_state: usize,
2173 member_values: BTreeMap<usize, i64>,
2174 expected: &'a ExpectedTokens,
2175}
2176
2177#[derive(Clone, Copy, Debug)]
2179struct PredicateEval<'a> {
2180 index: usize,
2181 rule_index: usize,
2182 pred_index: usize,
2183 predicates: &'a [(usize, usize, ParserPredicate)],
2184 context: Option<&'a ParserRuleContext>,
2185 local_int_arg: Option<(usize, i64)>,
2186 member_values: &'a BTreeMap<usize, i64>,
2187}
2188
2189struct PredicateFailureRecovery<'a> {
2191 rule_index: usize,
2192 index: usize,
2193 message: &'a str,
2194 member_values: BTreeMap<usize, i64>,
2195 return_values: BTreeMap<String, i64>,
2196 rule_alt_number: usize,
2197}
2198
2199#[derive(Debug)]
2200enum DirectAdaptiveParseControl {
2201 Fallback(DirectAdaptiveFallback),
2202}
2203
2204#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2205enum DirectAdaptiveFallback {
2206 Action,
2207 InvalidAlt,
2208 LeftRecursiveBoundary,
2209 MissingAtn,
2210 NoTransition,
2211 Predicate,
2212 Prediction,
2213 Precedence,
2214 RuleStop,
2215 SemanticContext,
2216 StepLimit,
2217 TokenMismatch,
2218 UnknownDecision,
2219}
2220
2221type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
2222
2223struct DirectAdaptiveParser<'atn, 'sim, S>
2224where
2225 S: TokenSource,
2226{
2227 parser: &'sim mut BaseParser<S>,
2228 atn: &'atn Atn,
2229 simulator: &'sim mut ParserAtnSimulator<'atn>,
2230 decision_by_state: Vec<Option<usize>>,
2231 steps: usize,
2232}
2233
2234#[derive(Clone, Debug, Eq, PartialEq)]
2244pub struct GeneratedMatch {
2245 children: Vec<ParseTree>,
2246 consumed_eof: bool,
2247}
2248
2249impl GeneratedMatch {
2250 #[must_use]
2254 pub fn children(&self) -> &[ParseTree] {
2255 &self.children
2256 }
2257
2258 #[must_use]
2261 pub fn into_children(self) -> Vec<ParseTree> {
2262 self.children
2263 }
2264
2265 #[must_use]
2267 pub const fn consumed_eof(&self) -> bool {
2268 self.consumed_eof
2269 }
2270}
2271
2272impl<S> BaseParser<S>
2273where
2274 S: TokenSource,
2275{
2276 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
2279 Self {
2280 input,
2281 data,
2282 build_parse_trees: true,
2283 report_diagnostic_errors: false,
2284 prediction_mode: PredictionMode::Ll,
2285 prediction_diagnostics: Vec::new(),
2286 reported_prediction_diagnostics: BTreeSet::new(),
2287 generated_parser_diagnostics: Vec::new(),
2288 generated_sync_expected: None,
2289 int_members: BTreeMap::new(),
2290 rule_context_stack: Vec::new(),
2291 rule_context_version: 0,
2292 prediction_context_cache: None,
2293 pending_invoking_states: Vec::new(),
2294 precedence_stack: vec![0],
2295 invoked_predicates: Vec::new(),
2296 rule_first_set_cache: Vec::new(),
2297 state_expected_cache: FxHashMap::default(),
2298 state_expected_token_cache: FxHashMap::default(),
2299 rule_stop_reach_cache: Vec::new(),
2300 recovery_symbols_intern: FxHashMap::default(),
2301 decision_lookahead_cache: FxHashMap::default(),
2302 ll1_decision_cache: FxHashMap::default(),
2303 empty_cycle_cache: Vec::new(),
2304 single_outcome_memo_mode: SingleOutcomeMemoMode::Probe,
2305 single_outcome_probe_seen: FxHashSet::default(),
2306 single_outcome_probe_samples: 0,
2307 single_outcome_probe_repeats: 0,
2308 empty_recovery_symbols: Rc::new(BTreeSet::new()),
2309 fast_first_set_prefilter: true,
2310 fast_recovery_enabled: true,
2311 fast_token_nodes_enabled: true,
2312 }
2313 }
2314
2315 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
2316 &mut self.input
2317 }
2318
2319 pub fn report_token_source_errors(&mut self) {
2322 report_token_source_errors(&self.input.drain_source_errors());
2323 }
2324
2325 pub const fn generated_diagnostics_checkpoint(&self) -> usize {
2328 self.generated_parser_diagnostics.len()
2329 }
2330
2331 pub fn restore_generated_diagnostics(&mut self, marker: usize) {
2333 self.generated_parser_diagnostics.truncate(marker);
2334 self.generated_sync_expected = None;
2335 }
2336
2337 pub fn report_generated_parser_diagnostics(&mut self) {
2339 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
2340 let token_errors = self.input.drain_source_errors();
2341 report_generated_diagnostics(&parser_diagnostics, &token_errors);
2342 }
2343
2344 pub fn record_generated_ambiguity_diagnostic(
2347 &mut self,
2348 atn: &Atn,
2349 state_number: usize,
2350 start_index: usize,
2351 stop_index: usize,
2352 alts: &[usize],
2353 ) {
2354 if !self.report_diagnostic_errors || alts.len() < 2 {
2355 return;
2356 }
2357 let Some(decision) = atn
2358 .decision_to_state()
2359 .iter()
2360 .position(|candidate| *candidate == state_number)
2361 else {
2362 return;
2363 };
2364 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
2365 return;
2366 };
2367 let rule_name = self
2368 .rule_names()
2369 .get(rule_index)
2370 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
2371 let input = display_input_text(&self.input.text(start_index, stop_index));
2372 let alts = alts
2373 .iter()
2374 .map(usize::to_string)
2375 .collect::<Vec<_>>()
2376 .join(", ");
2377 let key = (decision, start_index, format!("{alts}:{input}"));
2378 if !self.reported_prediction_diagnostics.insert(key) {
2379 return;
2380 }
2381 let start_token = self.token_at(start_index);
2382 let stop_token = self.token_at(stop_index);
2383 self.generated_parser_diagnostics.push(diagnostic_for_token(
2384 start_token.as_ref(),
2385 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
2386 ));
2387 self.generated_parser_diagnostics.push(diagnostic_for_token(
2388 stop_token.as_ref(),
2389 format!(
2390 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
2391 ),
2392 ));
2393 }
2394
2395 pub fn record_generated_prediction_diagnostic(
2398 &mut self,
2399 atn: &Atn,
2400 state_number: usize,
2401 prediction: &ParserAtnPrediction,
2402 ) {
2403 let Some(diagnostic) = &prediction.diagnostic else {
2404 return;
2405 };
2406 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
2407 return;
2408 }
2409 let Some(decision) = atn
2410 .decision_to_state()
2411 .iter()
2412 .position(|candidate| *candidate == state_number)
2413 else {
2414 return;
2415 };
2416 let Some(rule_index) = atn.state(state_number).and_then(|state| state.rule_index) else {
2417 return;
2418 };
2419 let rule_name = self
2420 .rule_names()
2421 .get(rule_index)
2422 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
2423 let attempt_input = display_input_text(
2424 &self
2425 .input
2426 .text(diagnostic.start_index, diagnostic.sll_stop_index),
2427 );
2428 let result_input = display_input_text(
2429 &self
2430 .input
2431 .text(diagnostic.start_index, diagnostic.ll_stop_index),
2432 );
2433 let alts = diagnostic
2434 .conflicting_alts
2435 .iter()
2436 .map(usize::to_string)
2437 .collect::<Vec<_>>()
2438 .join(", ");
2439 let key = (
2440 decision,
2441 diagnostic.start_index,
2442 format!(
2443 "{:?}:{alts}:{attempt_input}:{result_input}",
2444 diagnostic.kind
2445 ),
2446 );
2447 if !self.reported_prediction_diagnostics.insert(key) {
2448 return;
2449 }
2450 let attempt_token = self.token_at(diagnostic.sll_stop_index);
2451 self.generated_parser_diagnostics.push(diagnostic_for_token(
2452 attempt_token.as_ref(),
2453 format!(
2454 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
2455 ),
2456 ));
2457 let result_token = self.token_at(diagnostic.ll_stop_index);
2458 let message = match diagnostic.kind {
2459 ParserAtnPredictionDiagnosticKind::Ambiguity => {
2460 format!(
2461 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
2462 )
2463 }
2464 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
2465 format!(
2466 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
2467 )
2468 }
2469 };
2470 self.generated_parser_diagnostics
2471 .push(diagnostic_for_token(result_token.as_ref(), message));
2472 }
2473
2474 pub fn la(&mut self, offset: isize) -> i32 {
2475 self.input.la_token(offset)
2476 }
2477
2478 pub fn consume(&mut self) {
2479 IntStream::consume(&mut self.input);
2480 }
2481
2482 pub fn set_int_member(&mut self, member: usize, value: i64) {
2484 self.int_members.insert(member, value);
2485 }
2486
2487 pub fn int_member(&self, member: usize) -> Option<i64> {
2489 self.int_members.get(&member).copied()
2490 }
2491
2492 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
2495 self.int_members.clone()
2496 }
2497
2498 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
2500 self.int_members = members;
2501 }
2502
2503 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
2505 let value = self.int_members.entry(member).or_default();
2506 *value += delta;
2507 *value
2508 }
2509
2510 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
2517 let current = self
2518 .input
2519 .lt(1)
2520 .cloned()
2521 .ok_or_else(|| AntlrError::ParserError {
2522 line: 0,
2523 column: 0,
2524 message: "missing current token".to_owned(),
2525 })?;
2526 if current.token_type() == token_type {
2527 self.consume();
2528 Ok(ParseTree::Terminal(TerminalNode::new(current)))
2529 } else {
2530 Err(AntlrError::MismatchedInput {
2531 expected: self.vocabulary().display_name(token_type),
2532 found: self.vocabulary().display_name(current.token_type()),
2533 })
2534 }
2535 }
2536
2537 pub fn match_token_recovering(
2541 &mut self,
2542 token_type: i32,
2543 follow_state: usize,
2544 atn: &Atn,
2545 ) -> Result<GeneratedMatch, AntlrError> {
2546 let current = self
2547 .input
2548 .lt(1)
2549 .cloned()
2550 .ok_or_else(|| AntlrError::ParserError {
2551 line: 0,
2552 column: 0,
2553 message: "missing current token".to_owned(),
2554 })?;
2555 if current.token_type() == token_type {
2556 self.generated_sync_expected = None;
2557 let consumed_eof = current.token_type() == TOKEN_EOF;
2558 self.consume();
2559 return Ok(GeneratedMatch {
2560 children: vec![ParseTree::Terminal(TerminalNode::new(current))],
2561 consumed_eof,
2562 });
2563 }
2564 let mut expected_symbols = BTreeSet::new();
2565 expected_symbols.insert(token_type);
2566 self.recover_generated_match(current, &expected_symbols, follow_state, atn, |symbol| {
2567 symbol == token_type
2568 })
2569 }
2570
2571 pub fn match_set_recovering(
2572 &mut self,
2573 intervals: &[(i32, i32)],
2574 follow_state: usize,
2575 atn: &Atn,
2576 ) -> Result<GeneratedMatch, AntlrError> {
2577 let current = self
2578 .input
2579 .lt(1)
2580 .cloned()
2581 .ok_or_else(|| AntlrError::ParserError {
2582 line: 0,
2583 column: 0,
2584 message: "missing current token".to_owned(),
2585 })?;
2586 if interval_set_contains(intervals, current.token_type()) {
2587 self.generated_sync_expected = None;
2588 let consumed_eof = current.token_type() == TOKEN_EOF;
2589 self.consume();
2590 return Ok(GeneratedMatch {
2591 children: vec![ParseTree::Terminal(TerminalNode::new(current))],
2592 consumed_eof,
2593 });
2594 }
2595 let expected_symbols = interval_symbols(intervals);
2596 self.recover_generated_match(current, &expected_symbols, follow_state, atn, |symbol| {
2597 interval_set_contains(intervals, symbol)
2598 })
2599 }
2600
2601 pub fn match_not_set_recovering(
2602 &mut self,
2603 intervals: &[(i32, i32)],
2604 min_vocabulary: i32,
2605 max_vocabulary: i32,
2606 follow_state: usize,
2607 atn: &Atn,
2608 ) -> Result<GeneratedMatch, AntlrError> {
2609 let current = self
2610 .input
2611 .lt(1)
2612 .cloned()
2613 .ok_or_else(|| AntlrError::ParserError {
2614 line: 0,
2615 column: 0,
2616 message: "missing current token".to_owned(),
2617 })?;
2618 if (min_vocabulary..=max_vocabulary).contains(¤t.token_type())
2619 && !interval_set_contains(intervals, current.token_type())
2620 {
2621 self.generated_sync_expected = None;
2622 let consumed_eof = current.token_type() == TOKEN_EOF;
2623 self.consume();
2624 return Ok(GeneratedMatch {
2625 children: vec![ParseTree::Terminal(TerminalNode::new(current))],
2626 consumed_eof,
2627 });
2628 }
2629 let expected_symbols =
2630 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
2631 self.recover_generated_match(current, &expected_symbols, follow_state, atn, |symbol| {
2632 (min_vocabulary..=max_vocabulary).contains(&symbol)
2633 && !interval_set_contains(intervals, symbol)
2634 })
2635 }
2636
2637 fn recover_generated_match(
2638 &mut self,
2639 current: CommonToken,
2640 expected_symbols: &BTreeSet<i32>,
2641 follow_state: usize,
2642 atn: &Atn,
2643 matches: impl Fn(i32) -> bool,
2644 ) -> Result<GeneratedMatch, AntlrError> {
2645 let expected_display = self.expected_symbols_display(expected_symbols);
2646 if current.token_type() != TOKEN_EOF
2647 && let Some(next) = self.input.lt(2).cloned()
2648 && matches(next.token_type())
2649 {
2650 let message = format!(
2651 "extraneous input {} expecting {expected_display}",
2652 token_input_display(¤t)
2653 );
2654 self.generated_parser_diagnostics
2655 .push(diagnostic_for_token(Some(¤t), message));
2656 self.generated_sync_expected = None;
2657 let consumed_eof = next.token_type() == TOKEN_EOF;
2660 self.consume();
2661 self.consume();
2662 return Ok(GeneratedMatch {
2663 children: vec![
2664 ParseTree::Error(ErrorNode::new(current)),
2665 ParseTree::Terminal(TerminalNode::new(next)),
2666 ],
2667 consumed_eof,
2668 });
2669 }
2670 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
2671 let follow_explicitly_expects_eof = current.token_type() == TOKEN_EOF
2680 && self
2681 .cached_state_expected_symbols(atn, follow_state)
2682 .contains(&TOKEN_EOF);
2683 if follow_symbols.contains(¤t.token_type())
2684 && (current.token_type() != TOKEN_EOF
2685 || self.rule_context_stack.len() > 1
2686 || expected_symbols.is_empty()
2687 || follow_explicitly_expects_eof)
2688 {
2689 let message = format!(
2690 "missing {expected_display} at {}",
2691 token_input_display(¤t)
2692 );
2693 self.generated_parser_diagnostics
2694 .push(diagnostic_for_token(Some(¤t), message));
2695 self.generated_sync_expected = None;
2696 let token_type = expected_symbols.iter().next().copied().unwrap_or(TOKEN_EOF);
2697 let mut missing_symbol = BTreeSet::new();
2698 missing_symbol.insert(token_type);
2699 let missing_display = self.expected_symbols_display(&missing_symbol);
2700 let token = CommonToken::new(token_type)
2701 .with_text(format!("<missing {missing_display}>"))
2702 .with_span(usize::MAX, usize::MAX)
2703 .with_position(current.line(), current.column());
2704 return Ok(GeneratedMatch {
2709 children: vec![ParseTree::Error(ErrorNode::new(token))],
2710 consumed_eof: false,
2711 });
2712 }
2713 let mismatch_expected = self.generated_sync_expected.take().map_or_else(
2714 || expected_symbols.clone(),
2715 |symbols| symbols.to_btree_set(),
2716 );
2717 let mismatch_expected_display = self.expected_symbols_display(&mismatch_expected);
2718 Err(AntlrError::ParserError {
2719 line: current.line(),
2720 column: current.column(),
2721 message: format!(
2722 "mismatched input {} expecting {mismatch_expected_display}",
2723 token_input_display(¤t)
2724 ),
2725 })
2726 }
2727
2728 fn generated_recovery_follow_symbols(
2729 &mut self,
2730 atn: &Atn,
2731 follow_state: usize,
2732 ) -> BTreeSet<i32> {
2733 let mut follow = self
2734 .cached_state_expected_symbols(atn, follow_state)
2735 .as_ref()
2736 .clone();
2737 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
2738 follow.extend(self.context_expected_symbols(atn));
2739 }
2740 follow
2741 }
2742
2743 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
2744 self.match_token(TOKEN_EOF)
2745 }
2746
2747 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
2748 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
2749 }
2750
2751 pub fn match_not_set(
2752 &mut self,
2753 intervals: &[(i32, i32)],
2754 min_vocabulary: i32,
2755 max_vocabulary: i32,
2756 ) -> Result<ParseTree, AntlrError> {
2757 self.match_interval_condition(intervals, |symbol| {
2758 (min_vocabulary..=max_vocabulary).contains(&symbol)
2759 && !interval_set_contains(intervals, symbol)
2760 })
2761 }
2762
2763 fn match_interval_condition(
2764 &mut self,
2765 intervals: &[(i32, i32)],
2766 matches: impl FnOnce(i32) -> bool,
2767 ) -> Result<ParseTree, AntlrError> {
2768 let current = self
2769 .input
2770 .lt(1)
2771 .cloned()
2772 .ok_or_else(|| AntlrError::ParserError {
2773 line: 0,
2774 column: 0,
2775 message: "missing current token".to_owned(),
2776 })?;
2777 if matches(current.token_type()) {
2778 self.consume();
2779 Ok(ParseTree::Terminal(TerminalNode::new(current)))
2780 } else {
2781 Err(AntlrError::MismatchedInput {
2782 expected: self.interval_display(intervals),
2783 found: self.vocabulary().display_name(current.token_type()),
2784 })
2785 }
2786 }
2787
2788 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
2789 let values = intervals
2790 .iter()
2791 .map(|(start, stop)| {
2792 if start == stop {
2793 self.vocabulary().display_name(*start)
2794 } else {
2795 format!(
2796 "{}..{}",
2797 self.vocabulary().display_name(*start),
2798 self.vocabulary().display_name(*stop)
2799 )
2800 }
2801 })
2802 .collect::<Vec<_>>()
2803 .join(", ");
2804 format!("{{{values}}}")
2805 }
2806
2807 pub const fn rule_node(&self, context: ParserRuleContext) -> ParseTree {
2808 ParseTree::Rule(RuleNode::new(context))
2809 }
2810
2811 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
2814 self.set_state(state);
2815 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
2816 self.rule_context_stack.push(RuleContextFrame {
2817 rule_index,
2818 invoking_state,
2819 });
2820 self.invalidate_prediction_context_cache();
2821 let start_index = self.current_visible_index();
2822 let mut context = ParserRuleContext::new(rule_index, invoking_state);
2823 if let Some(token) = self.token_at(start_index) {
2824 context.set_start(token);
2825 }
2826 context
2827 }
2828
2829 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
2836 let marker = self.pending_invoking_states.len();
2837 self.pending_invoking_states.push(invoking_state);
2838 marker
2839 }
2840
2841 pub fn discard_invoking_state(&mut self, marker: usize) {
2843 self.pending_invoking_states.truncate(marker);
2844 }
2845
2846 pub fn exit_rule(&mut self) {
2848 self.rule_context_stack.pop();
2849 self.invalidate_prediction_context_cache();
2850 }
2851
2852 pub fn prediction_context(&mut self, atn: &Atn) -> Rc<PredictionContext> {
2855 let atn_ptr: *const Atn = atn;
2856 let atn_key = atn_ptr as usize;
2857 if let Some(cached) = &self.prediction_context_cache
2858 && cached.version == self.rule_context_version
2859 && cached.atn_key == atn_key
2860 {
2861 return Rc::clone(&cached.context);
2862 }
2863 let mut context = PredictionContext::empty();
2864 for frame in self.rule_context_stack.iter().skip(1) {
2865 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
2866 continue;
2867 };
2868 let Some(Transition::Rule { follow_state, .. }) = atn
2869 .state(state_number)
2870 .and_then(|state| state.transitions.first())
2871 else {
2872 continue;
2873 };
2874 context = PredictionContext::singleton(context, *follow_state);
2875 }
2876 self.prediction_context_cache = Some(CachedPredictionContext {
2877 version: self.rule_context_version,
2878 atn_key,
2879 context: Rc::clone(&context),
2880 });
2881 context
2882 }
2883
2884 fn invalidate_prediction_context_cache(&mut self) {
2885 self.rule_context_version = self.rule_context_version.wrapping_add(1);
2886 self.prediction_context_cache = None;
2887 }
2888
2889 pub fn add_parse_child(&self, context: &mut ParserRuleContext, child: ParseTree) {
2894 if self.build_parse_trees {
2895 context.add_child(child);
2896 } else {
2897 context.note_matched_child();
2898 }
2899 }
2900
2901 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
2903 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
2904 if let Some(token) = stop_index.and_then(|index| self.token_at(index)) {
2905 context.set_stop(token);
2906 }
2907 self.exit_rule();
2908 self.rule_node(context)
2909 }
2910
2911 pub fn recover_generated_rule(
2918 &mut self,
2919 context: &mut ParserRuleContext,
2920 atn: &Atn,
2921 error: AntlrError,
2922 ) {
2923 let diagnostic = self.generated_rule_error_diagnostic(error);
2924 self.push_generated_parser_diagnostic(diagnostic);
2925 self.generated_sync_expected = None;
2926 let recovery_symbols = self.context_expected_symbols(atn);
2927 loop {
2928 let symbol = self.la(1);
2929 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
2930 break;
2931 }
2932 let Some(token) = self.input.lt(1).cloned() else {
2933 break;
2934 };
2935 self.consume();
2936 self.add_parse_child(context, ParseTree::Error(ErrorNode::new(token)));
2937 }
2938 }
2939
2940 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
2941 if self
2942 .generated_parser_diagnostics
2943 .iter()
2944 .any(|existing| existing == &diagnostic)
2945 {
2946 return;
2947 }
2948 self.generated_parser_diagnostics.push(diagnostic);
2949 }
2950
2951 fn generated_rule_error_diagnostic(&mut self, error: AntlrError) -> ParserDiagnostic {
2952 match error {
2953 AntlrError::ParserError {
2954 line,
2955 column,
2956 message,
2957 } => ParserDiagnostic {
2958 line,
2959 column,
2960 message,
2961 },
2962 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
2963 self.input.lt(1),
2964 format!("mismatched input {found} expecting {expected}"),
2965 ),
2966 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
2967 self.input.lt(1),
2968 format!("no viable alternative at input {input}"),
2969 ),
2970 AntlrError::LexerError {
2971 line,
2972 column,
2973 message,
2974 } => ParserDiagnostic {
2975 line,
2976 column,
2977 message,
2978 },
2979 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
2980 }
2981 }
2982
2983 pub fn finish_recursion_rule(
2985 &mut self,
2986 mut context: ParserRuleContext,
2987 consumed_eof: bool,
2988 ) -> ParseTree {
2989 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
2990 if let Some(token) = stop_index.and_then(|index| self.token_at(index)) {
2991 context.set_stop(token);
2992 }
2993 self.unroll_recursion_context();
2994 self.rule_node(context)
2995 }
2996
2997 pub fn enter_recursion_rule(
2999 &mut self,
3000 state: isize,
3001 rule_index: usize,
3002 precedence: i32,
3003 ) -> ParserRuleContext {
3004 self.precedence_stack.push(precedence);
3005 self.enter_rule(state, rule_index)
3006 }
3007
3008 pub fn push_new_recursion_context(
3010 &mut self,
3011 state: isize,
3012 rule_index: usize,
3013 ) -> ParserRuleContext {
3014 self.set_state(state);
3015 ParserRuleContext::new(rule_index, state)
3016 }
3017
3018 pub fn push_new_recursion_context_with_previous(
3021 &mut self,
3022 state: isize,
3023 rule_index: usize,
3024 current: &mut ParserRuleContext,
3025 ) {
3026 self.set_state(state);
3027 if let Some(stop) = self
3028 .rule_stop_token_index(self.input.index(), false)
3029 .and_then(|index| self.token_at(index))
3030 {
3031 current.set_stop(stop);
3032 }
3033 let invoking_state = current.invoking_state();
3034 let start = current.start().cloned();
3035 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
3036 if let Some(start) = start {
3037 replacement.set_start(start);
3038 }
3039 let previous = std::mem::replace(current, replacement);
3040 if self.build_parse_trees {
3041 current.add_child(self.rule_node(previous));
3042 }
3043 }
3044
3045 pub fn unroll_recursion_context(&mut self) {
3047 if self.precedence_stack.len() > 1 {
3048 self.precedence_stack.pop();
3049 }
3050 self.exit_rule();
3051 }
3052
3053 pub fn left_recursive_loop_enter_matches(
3058 &mut self,
3059 atn: &Atn,
3060 state_number: usize,
3061 precedence: i32,
3062 ) -> bool {
3063 let symbol = self.la(1);
3064 if symbol == TOKEN_EOF {
3065 return false;
3066 }
3067 let Some(state) = atn.state(state_number) else {
3068 return false;
3069 };
3070 let context = self.prediction_context(atn);
3071 if context_can_match_symbol_before_state(atn, &context, state_number, symbol) {
3072 return false;
3073 }
3074 state.transitions.iter().any(|transition| {
3075 let target = transition.target();
3076 if atn
3077 .state(target)
3078 .is_some_and(|state| state.kind == AtnStateKind::LoopEnd)
3079 {
3080 return false;
3081 }
3082 state_can_reach_symbol_with_precedence(
3083 atn,
3084 target,
3085 symbol,
3086 precedence,
3087 &mut BTreeSet::new(),
3088 )
3089 })
3090 }
3091
3092 pub fn precpred(&self, precedence: i32) -> bool {
3094 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
3095 }
3096
3097 pub fn parser_semantic_predicate_matches(
3100 &mut self,
3101 predicates: &[(usize, usize, ParserPredicate)],
3102 rule_index: usize,
3103 pred_index: usize,
3104 ) -> bool {
3105 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
3106 }
3107
3108 pub fn parser_semantic_predicate_matches_with_local(
3111 &mut self,
3112 predicates: &[(usize, usize, ParserPredicate)],
3113 rule_index: usize,
3114 pred_index: usize,
3115 local_int_arg: i32,
3116 ) -> bool {
3117 self.parser_semantic_predicate_matches_inner(
3118 predicates,
3119 rule_index,
3120 pred_index,
3121 Some((rule_index, i64::from(local_int_arg))),
3122 )
3123 }
3124
3125 fn parser_semantic_predicate_matches_inner(
3126 &mut self,
3127 predicates: &[(usize, usize, ParserPredicate)],
3128 rule_index: usize,
3129 pred_index: usize,
3130 local_int_arg: Option<(usize, i64)>,
3131 ) -> bool {
3132 let index = self.input.index();
3133 let member_values = self.int_members.clone();
3134 self.parser_predicate_matches(PredicateEval {
3135 index,
3136 rule_index,
3137 pred_index,
3138 predicates,
3139 context: None,
3140 local_int_arg,
3141 member_values: &member_values,
3142 })
3143 }
3144
3145 pub fn parser_semantic_predicate_matches_with_context_and_local(
3148 &mut self,
3149 predicates: &[(usize, usize, ParserPredicate)],
3150 rule_index: usize,
3151 pred_index: usize,
3152 context: &ParserRuleContext,
3153 local_int_arg: i32,
3154 ) -> bool {
3155 let index = self.input.index();
3156 let member_values = self.int_members.clone();
3157 self.parser_predicate_matches(PredicateEval {
3158 index,
3159 rule_index,
3160 pred_index,
3161 predicates,
3162 context: Some(context),
3163 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
3164 member_values: &member_values,
3165 })
3166 }
3167
3168 pub fn parser_semantic_predicate_failure_message(
3171 &self,
3172 rule_index: usize,
3173 pred_index: usize,
3174 predicates: &[(usize, usize, ParserPredicate)],
3175 ) -> Option<&'static str> {
3176 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
3177 }
3178
3179 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
3181 let current = self
3182 .input
3183 .lt(1)
3184 .cloned()
3185 .ok_or_else(|| AntlrError::ParserError {
3186 line: 0,
3187 column: 0,
3188 message: "missing current token".to_owned(),
3189 })?;
3190 if current.token_type() == TOKEN_EOF {
3191 return Err(AntlrError::MismatchedInput {
3192 expected: "wildcard".to_owned(),
3193 found: self.vocabulary().display_name(TOKEN_EOF),
3194 });
3195 }
3196 self.consume();
3197 Ok(ParseTree::Terminal(TerminalNode::new(current)))
3198 }
3199
3200 #[allow(clippy::unnecessary_wraps)]
3204 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
3205 self.set_state(state);
3206 Ok(())
3207 }
3208
3209 pub fn sync_decision(
3217 &mut self,
3218 atn: &Atn,
3219 state_number: usize,
3220 current_context_empty: bool,
3221 loop_back: bool,
3222 ) -> Result<Vec<ParseTree>, AntlrError> {
3223 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
3224 self.generated_sync_expected = None;
3225 let Some(state) = atn.state(state_number) else {
3226 return Ok(Vec::new());
3227 };
3228 let Some(rule_index) = state.rule_index else {
3229 return Ok(Vec::new());
3230 };
3231 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index).copied() else {
3232 return Ok(Vec::new());
3233 };
3234 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
3235 let symbol = self.la(1);
3236 let mut has_expected_symbols = false;
3237 let mut nullable = false;
3238 let mut explicit_eof_expected = false;
3246 for transition in &entry.transitions {
3247 if transition.symbols.contains(symbol) {
3248 return Ok(Vec::new());
3249 }
3250 has_expected_symbols |= !transition.symbols.is_empty();
3251 nullable |= transition.nullable;
3252 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
3253 }
3254 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
3255 if nullable {
3256 if context_expected
3257 .as_ref()
3258 .is_some_and(|expected| expected.contains(symbol))
3259 {
3260 return Ok(Vec::new());
3261 }
3262 }
3263 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
3264 return Ok(Vec::new());
3265 }
3266 let mut expected = TokenBitSet::default();
3267 for transition in &entry.transitions {
3268 expected.extend_from(&transition.symbols);
3269 }
3270 if let Some(context_expected) = context_expected {
3271 expected.extend_from(&context_expected);
3272 }
3273 let can_delete_in_place =
3274 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
3275 let loop_sync = loop_back;
3292 if symbol != TOKEN_EOF && can_delete_in_place {
3293 let mut cursor = self.input.index();
3294 let mut skipped = Vec::new();
3295 loop {
3296 let current = self.token_type_at(cursor);
3297 if current == TOKEN_EOF {
3298 break;
3299 }
3300 skipped.push(cursor);
3301 let next = self.consume_index(cursor, current);
3302 if next == cursor {
3303 break;
3304 }
3305 let next_symbol = self.token_type_at(next);
3306 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
3314 explicit_eof_expected
3315 } else {
3316 expected.contains(next_symbol)
3317 };
3318 if next_is_expected_stop {
3319 let current_token = self.input.lt(1).cloned();
3320 let expected_symbols = expected.to_btree_set();
3321 let message = format!(
3322 "extraneous input {} expecting {}",
3323 current_token
3324 .as_ref()
3325 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
3326 self.expected_symbols_display(&expected_symbols)
3327 );
3328 self.generated_parser_diagnostics
3329 .push(diagnostic_for_token(current_token.as_ref(), message));
3330 let mut children = Vec::with_capacity(skipped.len());
3331 for index in skipped {
3332 if let Some(token) = self.token_at(index) {
3333 self.consume();
3334 children.push(ParseTree::Error(ErrorNode::new(token)));
3335 }
3336 }
3337 return Ok(children);
3338 }
3339 if !loop_sync {
3343 break;
3344 }
3345 cursor = next;
3346 }
3347 }
3348 if nullable {
3349 self.generated_sync_expected = Some(expected);
3350 return Ok(Vec::new());
3351 }
3352 let current = self.input.lt(1).cloned();
3353 let expected_symbols = expected.to_btree_set();
3354 Err(AntlrError::ParserError {
3355 line: current.as_ref().map(Token::line).unwrap_or_default(),
3356 column: current.as_ref().map(Token::column).unwrap_or_default(),
3357 message: format!(
3358 "mismatched input {} expecting {}",
3359 current
3360 .as_ref()
3361 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
3362 self.expected_symbols_display(&expected_symbols)
3363 ),
3364 })
3365 }
3366
3367 pub fn ll1_decision_prediction(
3374 &mut self,
3375 atn: &Atn,
3376 state_number: usize,
3377 ) -> Option<ParserAtnPrediction> {
3378 let state = atn.state(state_number)?;
3379 if state.precedence_rule_decision {
3380 return None;
3381 }
3382 let rule_stop = state
3383 .rule_index
3384 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index).copied())?;
3385 let symbol = self.la(1);
3386 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
3387 ll1_greedy_alt(&entry, symbol, state.non_greedy).map(|alt| ParserAtnPrediction {
3388 alt: alt + 1,
3389 requires_full_context: false,
3390 has_semantic_context: false,
3391 diagnostic: None,
3392 })
3393 }
3394
3395 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
3396 let context = self.prediction_context(atn);
3397 let mut expected = BTreeSet::new();
3398 self.collect_context_expected_symbols(atn, &context, &mut expected);
3399 expected
3400 }
3401
3402 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
3403 let context = self.prediction_context(atn);
3404 let mut expected = TokenBitSet::default();
3405 self.collect_context_expected_token_set(atn, &context, &mut expected);
3406 expected
3407 }
3408
3409 fn collect_context_expected_symbols(
3410 &mut self,
3411 atn: &Atn,
3412 context: &Rc<PredictionContext>,
3413 expected: &mut BTreeSet<i32>,
3414 ) {
3415 if context.is_empty() {
3416 expected.insert(TOKEN_EOF);
3417 return;
3418 }
3419 for index in 0..context.len() {
3420 let Some(return_state) = context.return_state(index) else {
3421 continue;
3422 };
3423 if return_state == EMPTY_RETURN_STATE {
3424 expected.insert(TOKEN_EOF);
3425 continue;
3426 }
3427 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
3428 if self.cached_state_can_reach_rule_stop(atn, return_state)
3429 && let Some(parent) = context.parent(index)
3430 {
3431 self.collect_context_expected_symbols(atn, &parent, expected);
3432 }
3433 }
3434 }
3435
3436 fn collect_context_expected_token_set(
3437 &mut self,
3438 atn: &Atn,
3439 context: &Rc<PredictionContext>,
3440 expected: &mut TokenBitSet,
3441 ) {
3442 if context.is_empty() {
3443 expected.insert(TOKEN_EOF);
3444 return;
3445 }
3446 for index in 0..context.len() {
3447 let Some(return_state) = context.return_state(index) else {
3448 continue;
3449 };
3450 if return_state == EMPTY_RETURN_STATE {
3451 expected.insert(TOKEN_EOF);
3452 continue;
3453 }
3454 let state_expected = self.cached_state_expected_token_set(atn, return_state);
3455 expected.extend_from(&state_expected);
3456 if self.cached_state_can_reach_rule_stop(atn, return_state)
3457 && let Some(parent) = context.parent(index)
3458 {
3459 self.collect_context_expected_token_set(atn, &parent, expected);
3460 }
3461 }
3462 }
3463
3464 pub fn no_viable_alternative_error(&mut self, start_index: usize) -> AntlrError {
3466 let error_index = self.input.index();
3467 self.no_viable_alternative_error_at(start_index, error_index)
3468 }
3469
3470 pub fn no_viable_alternative_error_at(
3475 &mut self,
3476 start_index: usize,
3477 error_index: usize,
3478 ) -> AntlrError {
3479 let diagnostic = self.no_viable_alternative(start_index, error_index);
3480 AntlrError::ParserError {
3481 line: diagnostic.line,
3482 column: diagnostic.column,
3483 message: diagnostic.message,
3484 }
3485 }
3486
3487 pub fn failed_predicate_error(&mut self, message: impl Into<String>) -> AntlrError {
3489 let current = self.input.lt(1).cloned();
3490 AntlrError::ParserError {
3491 line: current.as_ref().map(Token::line).unwrap_or_default(),
3492 column: current.as_ref().map(Token::column).unwrap_or_default(),
3493 message: format!("rule failed predicate: {}", message.into()),
3494 }
3495 }
3496
3497 pub fn failed_predicate_option_error(
3500 &mut self,
3501 rule_index: usize,
3502 message: impl Into<String>,
3503 ) -> AntlrError {
3504 let current = self.input.lt(1).cloned();
3505 let rule_name = self
3506 .rule_names()
3507 .get(rule_index)
3508 .map_or_else(|| rule_index.to_string(), Clone::clone);
3509 AntlrError::ParserError {
3510 line: current.as_ref().map(Token::line).unwrap_or_default(),
3511 column: current.as_ref().map(Token::column).unwrap_or_default(),
3512 message: format!("rule {rule_name} {}", message.into()),
3513 }
3514 }
3515
3516 pub fn parser_action_at_current(
3518 &mut self,
3519 source_state: usize,
3520 rule_index: usize,
3521 start_index: usize,
3522 consumed_eof: bool,
3523 ) -> ParserAction {
3524 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
3525 ParserAction::new(source_state, rule_index, start_index, stop_index)
3526 }
3527
3528 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
3533 &mut self,
3534 atn: &'atn Atn,
3535 simulator: &mut ParserAtnSimulator<'atn>,
3536 rule_index: usize,
3537 ) -> Result<ParseTree, AntlrError> {
3538 let start_index = self.current_visible_index();
3539 self.clear_prediction_diagnostics();
3540 self.reset_per_parse_caches();
3541 let mut decision_by_state = vec![None; atn.states().len()];
3542 for (decision, &state_number) in atn.decision_to_state().iter().enumerate() {
3543 if let Some(slot) = decision_by_state.get_mut(state_number) {
3544 *slot = Some(decision);
3545 }
3546 }
3547
3548 let result = DirectAdaptiveParser {
3549 parser: self,
3550 atn,
3551 simulator,
3552 decision_by_state,
3553 steps: 0,
3554 }
3555 .parse_rule(rule_index, -1, 0);
3556
3557 match result {
3558 Ok(tree) => {
3559 report_token_source_errors(&self.input.drain_source_errors());
3560 Ok(tree)
3561 }
3562 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
3563 let _ = reason;
3564 self.input.seek(start_index);
3565 self.parse_atn_rule(atn, rule_index)
3566 }
3567 }
3568 }
3569
3570 pub fn parse_atn_rule(
3580 &mut self,
3581 atn: &Atn,
3582 rule_index: usize,
3583 ) -> Result<ParseTree, AntlrError> {
3584 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
3585 }
3586
3587 pub fn parse_atn_rule_with_precedence(
3590 &mut self,
3591 atn: &Atn,
3592 rule_index: usize,
3593 precedence: i32,
3594 ) -> Result<ParseTree, AntlrError> {
3595 let start_state = atn
3596 .rule_to_start_state()
3597 .get(rule_index)
3598 .copied()
3599 .ok_or_else(|| {
3600 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
3601 })?;
3602 let stop_state = atn
3603 .rule_to_stop_state()
3604 .get(rule_index)
3605 .copied()
3606 .filter(|state| *state != usize::MAX)
3607 .ok_or_else(|| {
3608 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
3609 })?;
3610
3611 let start_index = self.current_visible_index();
3612 self.clear_prediction_diagnostics();
3613 self.reset_per_parse_caches();
3614 self.fast_recovery_enabled = false;
3615 self.fast_token_nodes_enabled = false;
3616 let first_pass =
3617 self.fast_recognize_top(atn, start_state, stop_state, start_index, precedence);
3618 self.fast_token_nodes_enabled = true;
3619 self.fast_recovery_enabled = true;
3620 let needs_tree_retry = matches!(
3621 &first_pass,
3622 Ok((outcome, _)) if self.build_parse_trees && outcome.nodes.has_left_recursive_boundary()
3623 );
3624 let needs_retry = match &first_pass {
3625 Err(_) => true,
3638 Ok((outcome, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
3639 };
3640 let (outcome, _expected) = if needs_retry {
3641 self.fast_first_set_prefilter = false;
3642 let retry =
3643 self.fast_recognize_top(atn, start_state, stop_state, start_index, precedence);
3644 self.fast_first_set_prefilter = true;
3645 let selected = if needs_tree_retry {
3646 match retry {
3647 ok @ Ok(_) => ok,
3648 Err(_) => first_pass,
3649 }
3650 } else {
3651 select_better_top_outcome(first_pass, retry)
3652 };
3653 selected.map_err(|expected| {
3654 let error = self.recognition_error(rule_index, start_index, &expected);
3655 report_token_source_errors(&self.input.drain_source_errors());
3656 error
3657 })?
3658 } else {
3659 first_pass.expect("first_pass is Ok in the no-retry branch")
3660 };
3661
3662 report_parser_diagnostics(&self.prediction_diagnostics);
3663 report_parser_diagnostics(&outcome.diagnostics);
3664 report_token_source_errors(&self.input.drain_source_errors());
3665 let mut context = ParserRuleContext::with_child_capacity(
3666 rule_index,
3667 self.state(),
3668 if self.build_parse_trees {
3669 outcome.nodes.len()
3670 } else {
3671 0
3672 },
3673 );
3674 if let Some(token) = self.token_at(start_index) {
3675 context.set_start(token);
3676 }
3677 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
3678 if let Some(token) = stop_index.and_then(|token_index| self.token_at(token_index)) {
3679 context.set_stop(token);
3680 }
3681 if self.build_parse_trees {
3682 if outcome.nodes.has_left_recursive_boundary() {
3683 let folded = fold_fast_left_recursive_boundaries(outcome.nodes.to_vec());
3684 if folded.iter().any(|node| {
3685 matches!(
3686 node.as_ref(),
3687 FastRecognizedNode::Token { .. }
3688 | FastRecognizedNode::ErrorToken { .. }
3689 | FastRecognizedNode::MissingToken { .. }
3690 )
3691 }) {
3692 for node in &folded {
3693 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
3694 }
3695 } else {
3696 self.add_fast_implicit_token_children(
3697 &mut context,
3698 start_index,
3699 stop_index,
3700 &folded,
3701 )?;
3702 }
3703 } else if outcome.nodes.has_explicit_token_node() {
3704 for node in outcome.nodes.iter() {
3705 context.add_child(self.fast_recognized_node_tree(node.as_ref())?);
3706 }
3707 } else {
3708 self.add_fast_implicit_token_children_iter(
3709 &mut context,
3710 start_index,
3711 stop_index,
3712 outcome.nodes.iter(),
3713 )?;
3714 }
3715 }
3716 self.input.seek(outcome.index);
3717
3718 Ok(self.rule_node(context))
3719 }
3720
3721 fn fast_recognize_top(
3726 &mut self,
3727 atn: &Atn,
3728 start_state: usize,
3729 stop_state: usize,
3730 start_index: usize,
3731 precedence: i32,
3732 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
3733 let memo_capacity = self.input.size().saturating_mul(8).clamp(65_536, 524_288);
3742 let mut visiting = FxHashSet::with_capacity_and_hasher(256, FxBuildHasher::default());
3743 let mut memo = FxHashMap::with_capacity_and_hasher(memo_capacity, FxBuildHasher::default());
3744 let mut expected = ExpectedTokens::default();
3745 let empty_recovery = self.empty_recovery_symbols();
3746 let outcomes = self.recognize_state_fast(
3747 atn,
3748 FastRecognizeRequest {
3749 state_number: start_state,
3750 stop_state,
3751 index: start_index,
3752 rule_start_index: start_index,
3753 decision_start_index: None,
3754 precedence,
3755 depth: 0,
3756 recovery_symbols: empty_recovery,
3757 recovery_state: None,
3758 },
3759 &mut visiting,
3760 &mut memo,
3761 &mut expected,
3762 );
3763 #[cfg(feature = "perf-counters")]
3764 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
3765 perf_counters::dump();
3766 perf_counters::reset();
3767 }
3768 match select_best_fast_outcome(outcomes.into_iter(), self.prediction_mode) {
3769 Some(outcome) => Ok((outcome, expected)),
3770 None => Err(expected),
3771 }
3772 }
3773
3774 fn fast_recognized_node_tree(
3777 &mut self,
3778 node: &FastRecognizedNode,
3779 ) -> Result<ParseTree, AntlrError> {
3780 match node {
3781 FastRecognizedNode::Token { index } => {
3782 let token =
3783 self.input
3784 .get(*index)
3785 .cloned()
3786 .ok_or_else(|| AntlrError::ParserError {
3787 line: 0,
3788 column: 0,
3789 message: format!("missing token at index {index}"),
3790 })?;
3791 Ok(ParseTree::Terminal(TerminalNode::new(token)))
3792 }
3793 FastRecognizedNode::ErrorToken { index } => {
3794 let token =
3795 self.input
3796 .get(*index)
3797 .cloned()
3798 .ok_or_else(|| AntlrError::ParserError {
3799 line: 0,
3800 column: 0,
3801 message: format!("missing error token at index {index}"),
3802 })?;
3803 Ok(ParseTree::Error(ErrorNode::new(token)))
3804 }
3805 FastRecognizedNode::MissingToken {
3806 token_type,
3807 at_index,
3808 text,
3809 } => {
3810 let current = self.token_at(*at_index);
3811 let token = CommonToken::new(*token_type)
3812 .with_text(text.as_str())
3813 .with_span(usize::MAX, usize::MAX)
3814 .with_position(
3815 current.as_ref().map(Token::line).unwrap_or_default(),
3816 current.as_ref().map(Token::column).unwrap_or_default(),
3817 );
3818 Ok(ParseTree::Error(ErrorNode::new(token)))
3819 }
3820 FastRecognizedNode::Rule {
3821 rule_index,
3822 invoking_state,
3823 start_index,
3824 stop_index,
3825 children,
3826 } => {
3827 let mut context = ParserRuleContext::with_child_capacity(
3828 *rule_index,
3829 *invoking_state,
3830 children.len(),
3831 );
3832 if let Some(token) = self.token_at(*start_index) {
3833 context.set_start(token);
3834 }
3835 if let Some(token) = stop_index.and_then(|index| self.token_at(index)) {
3836 context.set_stop(token);
3837 }
3838 if children.has_left_recursive_boundary() {
3839 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
3840 for child in &folded {
3841 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
3842 }
3843 } else {
3844 for child in children.iter() {
3845 context.add_child(self.fast_recognized_node_tree(child.as_ref())?);
3846 }
3847 }
3848 Ok(self.rule_node(context))
3849 }
3850 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
3851 Err(AntlrError::Unsupported(format!(
3852 "unfolded left-recursive boundary for rule {rule_index}"
3853 )))
3854 }
3855 }
3856 }
3857
3858 fn fast_recognized_node_tree_with_implicit_tokens(
3859 &mut self,
3860 node: &FastRecognizedNode,
3861 ) -> Result<ParseTree, AntlrError> {
3862 match node {
3863 FastRecognizedNode::Rule {
3864 rule_index,
3865 invoking_state,
3866 start_index,
3867 stop_index,
3868 children,
3869 } => {
3870 let mut context = ParserRuleContext::with_child_capacity(
3871 *rule_index,
3872 *invoking_state,
3873 children.len(),
3874 );
3875 if let Some(token) = self.token_at(*start_index) {
3876 context.set_start(token);
3877 }
3878 if let Some(token) = stop_index.and_then(|index| self.token_at(index)) {
3879 context.set_stop(token);
3880 }
3881 if children.has_left_recursive_boundary() {
3882 let folded = fold_fast_left_recursive_boundaries(children.to_vec());
3883 self.add_fast_implicit_token_children(
3884 &mut context,
3885 *start_index,
3886 *stop_index,
3887 &folded,
3888 )?;
3889 } else {
3890 self.add_fast_implicit_token_children_iter(
3891 &mut context,
3892 *start_index,
3893 *stop_index,
3894 children.iter(),
3895 )?;
3896 }
3897 Ok(self.rule_node(context))
3898 }
3899 _ => self.fast_recognized_node_tree(node),
3900 }
3901 }
3902
3903 fn add_fast_implicit_token_children(
3904 &mut self,
3905 context: &mut ParserRuleContext,
3906 start_index: usize,
3907 stop_index: Option<usize>,
3908 children: &[Rc<FastRecognizedNode>],
3909 ) -> Result<(), AntlrError> {
3910 self.add_fast_implicit_token_children_iter(
3911 context,
3912 start_index,
3913 stop_index,
3914 children.iter(),
3915 )
3916 }
3917
3918 fn add_fast_implicit_token_children_iter<'a>(
3919 &mut self,
3920 context: &mut ParserRuleContext,
3921 start_index: usize,
3922 stop_index: Option<usize>,
3923 children: impl IntoIterator<Item = &'a Rc<FastRecognizedNode>>,
3924 ) -> Result<(), AntlrError> {
3925 let mut cursor = Some(start_index);
3926 for child in children {
3927 if let Some((child_start, child_stop)) = fast_recognized_node_span(child.as_ref()) {
3928 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
3929 context.add_child(
3930 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
3931 );
3932 if let Some(child_stop) = child_stop {
3933 cursor = self.next_visible_after_token(child_stop);
3934 }
3935 } else {
3936 context.add_child(
3937 self.fast_recognized_node_tree_with_implicit_tokens(child.as_ref())?,
3938 );
3939 }
3940 }
3941 if let Some(stop) = stop_index {
3942 self.add_visible_terminals_through(context, cursor, stop)?;
3943 }
3944 Ok(())
3945 }
3946
3947 fn add_visible_terminals_before(
3948 &mut self,
3949 context: &mut ParserRuleContext,
3950 cursor: &mut Option<usize>,
3951 before: usize,
3952 ) -> Result<(), AntlrError> {
3953 let Some(stop) = before.checked_sub(1) else {
3954 return Ok(());
3955 };
3956 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
3957 *cursor = next;
3958 Ok(())
3959 }
3960
3961 fn add_visible_terminals_through(
3962 &mut self,
3963 context: &mut ParserRuleContext,
3964 mut cursor: Option<usize>,
3965 stop: usize,
3966 ) -> Result<Option<usize>, AntlrError> {
3967 while let Some(index) = cursor {
3968 if index > stop {
3969 return Ok(Some(index));
3970 }
3971 let token = self
3972 .input
3973 .get(index)
3974 .cloned()
3975 .ok_or_else(|| AntlrError::ParserError {
3976 line: 0,
3977 column: 0,
3978 message: format!("missing token at index {index}"),
3979 })?;
3980 let is_eof = token.token_type() == TOKEN_EOF;
3981 context.add_child(ParseTree::Terminal(TerminalNode::new(token)));
3982 if is_eof {
3983 return Ok(None);
3984 }
3985 cursor = self.next_visible_after_token(index);
3986 }
3987 Ok(None)
3988 }
3989
3990 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
3991 let next = self.input.next_visible_after(index);
3992 (next != index).then_some(next)
3993 }
3994
3995 pub fn parse_atn_rule_with_actions(
4002 &mut self,
4003 atn: &Atn,
4004 rule_index: usize,
4005 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4006 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
4007 }
4008
4009 pub fn parse_atn_rule_with_action_inits(
4017 &mut self,
4018 atn: &Atn,
4019 rule_index: usize,
4020 init_action_rules: &[usize],
4021 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4022 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
4023 }
4024
4025 pub fn parse_atn_rule_with_action_options(
4031 &mut self,
4032 atn: &Atn,
4033 rule_index: usize,
4034 init_action_rules: &[usize],
4035 track_alt_numbers: bool,
4036 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4037 self.parse_atn_rule_with_runtime_options(
4038 atn,
4039 rule_index,
4040 ParserRuntimeOptions {
4041 init_action_rules,
4042 track_alt_numbers,
4043 ..ParserRuntimeOptions::default()
4044 },
4045 )
4046 }
4047
4048 pub fn parse_atn_rule_with_runtime_options(
4055 &mut self,
4056 atn: &Atn,
4057 rule_index: usize,
4058 options: ParserRuntimeOptions<'_>,
4059 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4060 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
4061 }
4062
4063 pub fn parse_atn_rule_with_runtime_options_and_precedence(
4066 &mut self,
4067 atn: &Atn,
4068 rule_index: usize,
4069 precedence: i32,
4070 options: ParserRuntimeOptions<'_>,
4071 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
4072 let ParserRuntimeOptions {
4073 init_action_rules,
4074 track_alt_numbers,
4075 predicates,
4076 rule_args,
4077 member_actions,
4078 return_actions,
4079 } = options;
4080 let start_state = atn
4081 .rule_to_start_state()
4082 .get(rule_index)
4083 .copied()
4084 .ok_or_else(|| {
4085 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
4086 })?;
4087 let stop_state = atn
4088 .rule_to_stop_state()
4089 .get(rule_index)
4090 .copied()
4091 .filter(|state| *state != usize::MAX)
4092 .ok_or_else(|| {
4093 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
4094 })?;
4095
4096 let start_index = self.current_visible_index();
4097 self.clear_prediction_diagnostics();
4098 self.reset_per_parse_caches();
4099 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
4100 let invoking_state = self.pending_invoking_states.pop();
4101 let local_int_arg = invoking_state
4102 .and_then(|state| usize::try_from(state).ok())
4103 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
4104 let mut visiting = BTreeSet::new();
4105 let mut memo = BTreeMap::new();
4106 let mut expected = ExpectedTokens::default();
4107 let member_values = self.int_members.clone();
4108 let return_values = BTreeMap::new();
4109 let outcomes = self.recognize_state(
4110 atn,
4111 RecognizeRequest {
4112 state_number: start_state,
4113 stop_state,
4114 index: start_index,
4115 rule_start_index: start_index,
4116 decision_start_index: None,
4117 init_action_rules: &init_action_rules,
4118 predicates,
4119 rule_args,
4120 member_actions,
4121 return_actions,
4122 local_int_arg,
4123 member_values,
4124 return_values,
4125 rule_alt_number: 0,
4126 track_alt_numbers,
4127 consumed_eof: false,
4128 precedence,
4129 depth: 0,
4130 recovery_symbols: BTreeSet::new(),
4131 recovery_state: None,
4132 },
4133 &mut visiting,
4134 &mut memo,
4135 &mut expected,
4136 );
4137 let Some(outcome) = select_best_outcome(outcomes.into_iter(), self.prediction_mode) else {
4138 let error = self.recognition_error(rule_index, start_index, &expected);
4139 report_token_source_errors(&self.input.drain_source_errors());
4140 return Err(error);
4141 };
4142
4143 report_parser_diagnostics(&self.prediction_diagnostics);
4144 report_parser_diagnostics(&outcome.diagnostics);
4145 report_token_source_errors(&self.input.drain_source_errors());
4146 let mut actions = outcome.actions;
4147 if init_action_rules.contains(&rule_index) {
4148 actions.insert(
4149 0,
4150 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
4151 );
4152 }
4153 let mut context =
4154 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
4155 if track_alt_numbers {
4156 context.set_alt_number(outcome.alt_number);
4157 }
4158 for (name, value) in outcome.return_values {
4159 context.set_int_return(name, value);
4160 }
4161 if let Some(token) = self.token_at(start_index) {
4162 context.set_start(token);
4163 }
4164 if let Some(token) = self.rule_stop_token(outcome.index, outcome.consumed_eof) {
4165 context.set_stop(token);
4166 }
4167 if self.build_parse_trees {
4168 let nodes = fold_left_recursive_boundaries(outcome.nodes);
4169 for node in &nodes {
4170 context.add_child(self.recognized_node_tree(node, track_alt_numbers)?);
4171 }
4172 }
4173 self.input.seek(outcome.index);
4174
4175 Ok((self.rule_node(context), actions))
4176 }
4177
4178 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
4185 let mut context = ParserRuleContext::new(rule_index, self.state());
4186 while self.la(1) != TOKEN_EOF {
4187 let token_type = self.la(1);
4188 let child = self.match_token(token_type)?;
4189 if self.build_parse_trees {
4190 context.add_child(child);
4191 }
4192 }
4193 if self.build_parse_trees {
4194 context.add_child(self.match_eof()?);
4195 }
4196 Ok(self.rule_node(context))
4197 }
4198
4199 fn recognition_error(
4202 &mut self,
4203 rule_index: usize,
4204 start_index: usize,
4205 expected: &ExpectedTokens,
4206 ) -> AntlrError {
4207 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
4208 self.input.seek(index);
4209 let current = self.input.lt(1).cloned();
4210 let line = current.as_ref().map(Token::line).unwrap_or_default();
4211 let column = current.as_ref().map(Token::column).unwrap_or_default();
4212 AntlrError::ParserError {
4213 line,
4214 column,
4215 message,
4216 }
4217 }
4218
4219 fn expected_error_message(
4221 &mut self,
4222 rule_index: usize,
4223 start_index: usize,
4224 expected: &ExpectedTokens,
4225 ) -> (usize, String) {
4226 let index = expected
4227 .index
4228 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
4229 .unwrap_or_else(|| self.input.index());
4230 self.input.seek(index);
4231 let current = self.input.lt(1).cloned();
4232 let message = if expected
4233 .no_viable
4234 .as_ref()
4235 .is_some_and(|no_viable| no_viable.error_index == index)
4236 {
4237 let start = expected
4238 .no_viable
4239 .as_ref()
4240 .map_or(start_index, |no_viable| no_viable.start_index);
4241 let text = display_input_text(&self.input.text(start, index));
4242 format!("no viable alternative at input '{text}'")
4243 } else if expected.symbols.is_empty() {
4244 if expected.index.is_some() {
4245 let found = current
4246 .as_ref()
4247 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
4248 if current
4249 .as_ref()
4250 .is_some_and(|token| token.token_type() == TOKEN_EOF)
4251 {
4252 format!(
4253 "missing {} at {found}",
4254 self.expected_symbols_display(&expected.symbols)
4255 )
4256 } else {
4257 format!("mismatched input {found}")
4258 }
4259 } else {
4260 format!("no viable alternative while parsing rule {rule_index}")
4261 }
4262 } else {
4263 format!(
4264 "mismatched input {} expecting {}",
4265 current
4266 .as_ref()
4267 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
4268 self.expected_symbols_display(&expected.symbols)
4269 )
4270 };
4271 (index, message)
4272 }
4273
4274 fn child_rule_failure_recovery(
4277 &mut self,
4278 rule_index: usize,
4279 start_index: usize,
4280 sync_symbols: &BTreeSet<i32>,
4281 member_values: BTreeMap<usize, i64>,
4282 expected: &ExpectedTokens,
4283 ) -> Option<RecognizeOutcome> {
4284 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
4285 let token = self.token_at(error_index);
4286 let mut next_index = error_index;
4287 loop {
4288 let symbol = self.token_type_at(next_index);
4289 if sync_symbols.contains(&symbol) {
4290 if next_index == error_index {
4291 return None;
4292 }
4293 break;
4294 }
4295 if symbol == TOKEN_EOF {
4296 break;
4297 }
4298 let after = self.consume_index(next_index, symbol);
4299 if after == next_index {
4300 break;
4301 }
4302 next_index = after;
4303 }
4304 Some(RecognizeOutcome {
4305 index: next_index,
4306 consumed_eof: false,
4307 alt_number: 0,
4308 member_values,
4309 return_values: BTreeMap::new(),
4310 diagnostics: vec![diagnostic_for_token(token.as_ref(), message)],
4311 decisions: Vec::new(),
4312 actions: Vec::new(),
4313 nodes: vec![RecognizedNode::ErrorToken { index: error_index }],
4314 })
4315 }
4316
4317 fn child_rule_failure_recovery_outcomes(
4320 &mut self,
4321 request: ChildRuleFailureRecovery<'_>,
4322 ) -> Vec<RecognizeOutcome> {
4323 let sync_symbols =
4324 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
4325 self.child_rule_failure_recovery(
4326 request.rule_index,
4327 request.start_index,
4328 &sync_symbols,
4329 request.member_values,
4330 request.expected,
4331 )
4332 .into_iter()
4333 .collect()
4334 }
4335
4336 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
4338 expected_symbols_display(symbols, self.vocabulary())
4339 }
4340
4341 fn single_token_deletion(
4344 &mut self,
4345 transition: &Transition,
4346 index: usize,
4347 max_token_type: i32,
4348 expected_symbols: &BTreeSet<i32>,
4349 ) -> Option<(ParserDiagnostic, usize, i32)> {
4350 let current_symbol = self.token_type_at(index);
4351 if current_symbol == TOKEN_EOF {
4352 return None;
4353 }
4354 let next_index = self.consume_index(index, current_symbol);
4355 if next_index == index {
4356 return None;
4357 }
4358 let next_symbol = self.token_type_at(next_index);
4359 if !transition.matches(next_symbol, 1, max_token_type) {
4360 return None;
4361 }
4362 let transition_expected = transition_expected_symbols(transition, max_token_type);
4363 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
4364 &transition_expected
4365 } else {
4366 expected_symbols
4367 });
4368 let current = self.token_at(index);
4369 let message = format!(
4370 "extraneous input {} expecting {expected_display}",
4371 current
4372 .as_ref()
4373 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
4374 );
4375 Some((
4376 diagnostic_for_token(current.as_ref(), message),
4377 next_index,
4378 next_symbol,
4379 ))
4380 }
4381
4382 fn current_token_deletion(
4385 &mut self,
4386 index: usize,
4387 expected_symbols: &BTreeSet<i32>,
4388 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
4389 if expected_symbols.is_empty() {
4390 return None;
4391 }
4392 let current_symbol = self.token_type_at(index);
4393 if current_symbol == TOKEN_EOF {
4394 return None;
4395 }
4396 let current = self.token_at(index);
4397 let message = format!(
4398 "extraneous input {} expecting {}",
4399 current
4400 .as_ref()
4401 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
4402 self.expected_symbols_display(expected_symbols)
4403 );
4404 let diagnostic = diagnostic_for_token(current.as_ref(), message);
4405 let mut skipped = Vec::new();
4406 let mut cursor = index;
4407 loop {
4408 let symbol = self.token_type_at(cursor);
4409 if symbol == TOKEN_EOF {
4410 return None;
4411 }
4412 skipped.push(cursor);
4413 let next_index = self.consume_index(cursor, symbol);
4414 if next_index == cursor {
4415 return None;
4416 }
4417 let next_symbol = self.token_type_at(next_index);
4418 if expected_symbols.contains(&next_symbol) {
4419 return Some((diagnostic, next_index, skipped));
4420 }
4421 cursor = next_index;
4422 }
4423 }
4424
4425 fn single_token_insertion(
4429 &mut self,
4430 transition: &Transition,
4431 index: usize,
4432 max_token_type: i32,
4433 expected_symbols: &BTreeSet<i32>,
4434 follow_symbols: &BTreeSet<i32>,
4435 ) -> Option<(ParserDiagnostic, i32, String)> {
4436 let current_symbol = self.token_type_at(index);
4437 if !follow_symbols.contains(¤t_symbol) {
4438 return None;
4439 }
4440 let transition_expected = transition_expected_symbols(transition, max_token_type);
4441 let token_type = transition_expected.iter().next().copied()?;
4442 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
4443 &transition_expected
4444 } else {
4445 expected_symbols
4446 });
4447 let mut token_symbols = BTreeSet::new();
4448 token_symbols.insert(token_type);
4449 let missing_token_display = self.expected_symbols_display(&token_symbols);
4450 let current = self.token_at(index);
4451 let message = format!(
4452 "missing {expected_display} at {}",
4453 current
4454 .as_ref()
4455 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
4456 );
4457 let text = format!("<missing {missing_token_display}>");
4458 Some((
4459 diagnostic_for_token(current.as_ref(), message),
4460 token_type,
4461 text,
4462 ))
4463 }
4464
4465 fn fast_single_token_deletion_recovery(
4469 &mut self,
4470 recovery: FastRecoveryRequest<'_, '_>,
4471 ) -> Vec<FastRecognizeOutcome> {
4472 let FastRecoveryRequest {
4473 atn,
4474 transition,
4475 expected_symbols,
4476 target,
4477 request,
4478 visiting,
4479 memo,
4480 expected,
4481 } = recovery;
4482 let FastRecognizeRequest {
4483 stop_state,
4484 index,
4485 rule_start_index,
4486 decision_start_index,
4487 precedence,
4488 depth,
4489 ..
4490 } = request;
4491 let Some((diagnostic, next_index, next_symbol)) =
4492 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
4493 else {
4494 return Vec::new();
4495 };
4496 let after_next = self.consume_index(next_index, next_symbol);
4497 let empty_recovery = self.empty_recovery_symbols();
4498 self.recognize_state_fast(
4499 atn,
4500 FastRecognizeRequest {
4501 state_number: target,
4502 stop_state,
4503 index: after_next,
4504 rule_start_index,
4505 decision_start_index,
4506 precedence,
4507 depth: depth + 1,
4508 recovery_symbols: empty_recovery,
4509 recovery_state: None,
4510 },
4511 visiting,
4512 memo,
4513 expected,
4514 )
4515 .into_iter()
4516 .map(|mut outcome| {
4517 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
4518 outcome.diagnostics.insert(0, diagnostic.clone());
4519 if self.fast_token_nodes_enabled {
4520 outcome
4521 .nodes
4522 .prepend(Rc::new(FastRecognizedNode::Token { index: next_index }));
4523 outcome
4524 .nodes
4525 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index }));
4526 }
4527 outcome
4528 })
4529 .collect()
4530 }
4531
4532 fn fast_single_token_insertion_recovery(
4536 &mut self,
4537 recovery: FastRecoveryRequest<'_, '_>,
4538 ) -> Vec<FastRecognizeOutcome> {
4539 let FastRecoveryRequest {
4540 atn,
4541 transition,
4542 expected_symbols,
4543 target,
4544 request,
4545 visiting,
4546 memo,
4547 expected,
4548 } = recovery;
4549 let FastRecognizeRequest {
4550 stop_state,
4551 index,
4552 rule_start_index,
4553 decision_start_index,
4554 precedence,
4555 depth,
4556 ..
4557 } = request;
4558 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
4559 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
4560 transition,
4561 index,
4562 atn.max_token_type(),
4563 &expected_symbols,
4564 &follow_symbols,
4565 ) else {
4566 return Vec::new();
4567 };
4568 let empty_recovery = self.empty_recovery_symbols();
4569 self.recognize_state_fast(
4570 atn,
4571 FastRecognizeRequest {
4572 state_number: target,
4573 stop_state,
4574 index,
4575 rule_start_index,
4576 decision_start_index,
4577 precedence,
4578 depth: depth + 1,
4579 recovery_symbols: empty_recovery,
4580 recovery_state: None,
4581 },
4582 visiting,
4583 memo,
4584 expected,
4585 )
4586 .into_iter()
4587 .map(|mut outcome| {
4588 outcome.diagnostics.insert(0, diagnostic.clone());
4589 outcome
4590 .nodes
4591 .prepend(Rc::new(FastRecognizedNode::MissingToken {
4592 token_type,
4593 at_index: index,
4594 text: text.clone(),
4595 }));
4596 outcome
4597 })
4598 .collect()
4599 }
4600
4601 fn fast_current_token_deletion_recovery(
4604 &mut self,
4605 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
4606 ) -> Vec<FastRecognizeOutcome> {
4607 let FastCurrentTokenDeletionRequest {
4608 atn,
4609 expected_symbols,
4610 mut request,
4611 visiting,
4612 memo,
4613 expected,
4614 } = recovery;
4615 if request.index == request.rule_start_index {
4616 return Vec::new();
4617 }
4618 let Some((diagnostic, next_index, skipped)) =
4619 self.current_token_deletion(request.index, &expected_symbols)
4620 else {
4621 return Vec::new();
4622 };
4623 request.state_number = request.recovery_state.unwrap_or(request.state_number);
4624 request.index = next_index;
4625 request.depth += 1;
4626 request.recovery_state = None;
4627 self.recognize_state_fast(atn, request, visiting, memo, expected)
4628 .into_iter()
4629 .map(|mut outcome| {
4630 outcome.diagnostics.insert(0, diagnostic.clone());
4631 for index in skipped.iter().rev() {
4632 outcome
4633 .nodes
4634 .prepend(Rc::new(FastRecognizedNode::ErrorToken { index: *index }));
4635 }
4636 outcome
4637 })
4638 .collect()
4639 }
4640
4641 fn fast_child_rule_failure_recovery(
4644 &mut self,
4645 rule_index: usize,
4646 start_index: usize,
4647 sync_symbols: &BTreeSet<i32>,
4648 expected: &ExpectedTokens,
4649 ) -> Option<FastRecognizeOutcome> {
4650 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
4651 let token = self.token_at(error_index);
4652 let mut next_index = error_index;
4653 loop {
4654 let symbol = self.token_type_at(next_index);
4655 if sync_symbols.contains(&symbol) {
4656 if next_index == error_index {
4657 return None;
4658 }
4659 break;
4660 }
4661 if symbol == TOKEN_EOF {
4662 break;
4663 }
4664 let after = self.consume_index(next_index, symbol);
4665 if after == next_index {
4666 break;
4667 }
4668 next_index = after;
4669 }
4670 let mut diagnostics = FastDiagnostics::new();
4671 diagnostics.insert(0, diagnostic_for_token(token.as_ref(), message));
4672 let mut nodes = NodeList::new();
4673 if self.fast_token_nodes_enabled {
4674 nodes.prepend(Rc::new(FastRecognizedNode::ErrorToken {
4675 index: error_index,
4676 }));
4677 }
4678 Some(FastRecognizeOutcome {
4679 index: next_index,
4680 consumed_eof: false,
4681 diagnostics,
4682 nodes,
4683 })
4684 }
4685
4686 fn fast_child_rule_failure_recovery_outcomes(
4689 &mut self,
4690 request: FastChildRuleFailureRecoveryRequest<'_>,
4691 ) -> Vec<FastRecognizeOutcome> {
4692 let FastChildRuleFailureRecoveryRequest {
4693 atn,
4694 rule_index,
4695 start_index,
4696 follow_state,
4697 stop_state,
4698 expected,
4699 } = request;
4700 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
4701 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
4702 .into_iter()
4703 .collect()
4704 }
4705
4706 #[allow(clippy::too_many_lines)]
4709 fn recognize_state_fast(
4710 &mut self,
4711 atn: &Atn,
4712 request: FastRecognizeRequest,
4713 visiting: &mut FxHashSet<(usize, usize)>,
4714 memo: &mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4715 expected: &mut ExpectedTokens,
4716 ) -> Vec<FastRecognizeOutcome> {
4717 #[cfg(feature = "perf-counters")]
4718 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
4719 let FastRecognizeRequest {
4720 mut state_number,
4721 stop_state,
4722 mut index,
4723 rule_start_index,
4724 decision_start_index,
4725 precedence,
4726 mut depth,
4727 recovery_symbols,
4728 recovery_state,
4729 } = request;
4730 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
4749 let mut inline_consumed_eof = false;
4750 loop {
4751 if depth > RECOGNITION_DEPTH_LIMIT {
4752 return Vec::new();
4753 }
4754 if state_number == stop_state {
4755 let mut nodes = NodeList::new();
4756 if self.fast_token_nodes_enabled {
4757 for token_index in inline_consumed_tokens.iter().rev() {
4758 nodes.prepend(Rc::new(FastRecognizedNode::Token {
4759 index: *token_index,
4760 }));
4761 }
4762 }
4763 return vec![FastRecognizeOutcome {
4764 index,
4765 consumed_eof: inline_consumed_eof,
4766 diagnostics: FastDiagnostics::new(),
4767 nodes,
4768 }];
4769 }
4770 let Some(state) = atn.state(state_number) else {
4771 return Vec::new();
4772 };
4773 if state.transitions.len() == 1
4774 && !starts_prediction_decision(state)
4775 && !state.precedence_rule_decision
4776 {
4777 match &state.transitions[0] {
4778 Transition::Epsilon { target }
4779 | Transition::Predicate { target, .. }
4780 | Transition::Action { target, .. }
4781 if left_recursive_boundary(atn, state, *target).is_none() =>
4782 {
4783 #[cfg(feature = "perf-counters")]
4784 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
4785 state_number = *target;
4786 depth += 1;
4787 continue;
4788 }
4789 Transition::Precedence {
4790 target,
4791 precedence: transition_precedence,
4792 } if *transition_precedence >= precedence
4793 && left_recursive_boundary(atn, state, *target).is_none() =>
4794 {
4795 #[cfg(feature = "perf-counters")]
4796 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
4797 state_number = *target;
4798 depth += 1;
4799 continue;
4800 }
4801 Transition::Atom { target, .. }
4811 | Transition::Range { target, .. }
4812 | Transition::Set { target, .. }
4813 | Transition::NotSet { target, .. }
4814 | Transition::Wildcard { target, .. }
4815 if !self.fast_recovery_enabled =>
4816 {
4817 let symbol = self.token_type_at(index);
4818 let transition = &state.transitions[0];
4819 if transition.matches(symbol, 1, atn.max_token_type()) {
4820 #[cfg(feature = "perf-counters")]
4821 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
4822 if self.fast_token_nodes_enabled {
4823 inline_consumed_tokens.push(index);
4824 }
4825 inline_consumed_eof |= symbol == TOKEN_EOF;
4826 index = self.consume_index(index, symbol);
4827 state_number = *target;
4828 depth += 1;
4829 continue;
4830 }
4831 }
4834 _ => {}
4835 }
4836 }
4837 break;
4838 }
4839 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
4843 let Some(state) = atn.state(state_number) else {
4844 return Vec::new();
4845 };
4846 let transition_count = state.transitions.len();
4847 let memo_lookup_enabled = self.fast_recovery_enabled || transition_count > 1;
4848 let key = if self.fast_recovery_enabled {
4858 FastRecognizeKey {
4859 state_number,
4860 stop_state,
4861 index,
4862 rule_start_index,
4863 decision_start_index,
4864 precedence,
4865 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
4866 recovery_state,
4867 }
4868 } else {
4869 FastRecognizeKey {
4870 state_number,
4871 stop_state,
4872 index,
4873 rule_start_index: 0,
4874 decision_start_index: None,
4875 precedence,
4876 recovery_symbols_id: 0,
4877 recovery_state: None,
4878 }
4879 };
4880 if memo_lookup_enabled {
4881 if let Some(outcomes) = memo.get(&key) {
4882 #[cfg(feature = "perf-counters")]
4883 {
4884 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
4885 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
4886 }
4887 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
4891 let inline_eof = inline_consumed_eof;
4892 let inline_tokens = &inline_consumed_tokens;
4893 return outcomes
4894 .iter()
4895 .cloned()
4896 .map(|mut outcome| {
4897 if inline_eof {
4898 outcome.consumed_eof = true;
4899 }
4900 if self.fast_token_nodes_enabled {
4901 for token_index in inline_tokens.iter().rev() {
4902 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
4903 index: *token_index,
4904 }));
4905 }
4906 }
4907 outcome
4908 })
4909 .collect();
4910 }
4911 return outcomes.to_vec();
4912 }
4913 #[cfg(feature = "perf-counters")]
4914 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
4915 }
4916
4917 let needs_cycle_guard =
4925 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number);
4926 #[cfg(feature = "perf-counters")]
4927 if needs_cycle_guard {
4928 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
4929 } else {
4930 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
4931 match &state.transitions[0] {
4932 Transition::Rule { .. } => {
4933 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
4934 }
4935 Transition::Atom { .. }
4936 | Transition::Range { .. }
4937 | Transition::Set { .. }
4938 | Transition::NotSet { .. }
4939 | Transition::Wildcard { .. } => {
4940 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
4941 }
4942 _ => {
4943 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
4944 }
4945 }
4946 }
4947 let visit_id = (state_number, index);
4948 if needs_cycle_guard && !visiting.insert(visit_id) {
4949 #[cfg(feature = "perf-counters")]
4950 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
4951 return Vec::new();
4952 }
4953 let next_decision_start_index = if starts_prediction_decision(state) {
4954 Some(index)
4955 } else {
4956 decision_start_index
4957 };
4958 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
4959 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
4960 } else {
4961 (Rc::clone(&recovery_symbols), recovery_state)
4962 };
4963
4964 let transition_count = state.transitions.len();
4983 let lookahead_filter = if transition_count > 1
4984 && self.fast_first_set_prefilter
4985 && !state.precedence_rule_decision
4986 && (!self.fast_recovery_enabled || state.kind != AtnStateKind::RuleStart)
4987 {
4988 state
4989 .rule_index
4990 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index).copied())
4991 .map(|rule_stop| {
4992 let symbol = self.token_type_at(index);
4993 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
4994 (symbol, entry)
4995 })
4996 } else {
4997 None
4998 };
4999 let ll1_only_alt: Option<usize> = if transition_count > 1
5008 && let Some((symbol, entry)) = lookahead_filter.as_ref()
5009 {
5010 let key = (state.state_number, *symbol);
5011 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
5012 cached
5013 } else {
5014 let result = ll1_unique_alt(entry, *symbol);
5015 self.ll1_decision_cache.insert(key, result);
5016 result
5017 }
5018 } else {
5019 None
5020 };
5021 let lookahead_filter = lookahead_filter.as_ref();
5022 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
5028 for (transition_index, transition) in state.transitions.iter().enumerate() {
5029 if let Some(alt) = ll1_only_alt {
5030 if alt != transition_index {
5032 continue;
5033 }
5034 } else if should_skip_via_lookahead(
5035 transition,
5036 transition_index,
5037 lookahead_filter,
5038 index,
5039 self.fast_recovery_enabled,
5040 expected,
5041 ) {
5042 continue;
5043 }
5044 match transition {
5045 Transition::Epsilon { target }
5046 | Transition::Predicate { target, .. }
5047 | Transition::Action { target, .. } => {
5048 #[cfg(feature = "perf-counters")]
5049 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
5050 let boundary = left_recursive_boundary(atn, state, *target);
5051 outcomes.extend(
5052 self.recognize_state_fast(
5053 atn,
5054 FastRecognizeRequest {
5055 state_number: *target,
5056 stop_state,
5057 index,
5058 rule_start_index,
5059 decision_start_index: next_decision_start_index,
5060 precedence,
5061 depth: depth + 1,
5062 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
5063 recovery_state: epsilon_recovery_state,
5064 },
5065 visiting,
5066 memo,
5067 expected,
5068 )
5069 .into_iter()
5070 .map(|mut outcome| {
5071 if let Some(rule_index) = boundary {
5072 outcome.nodes.prepend(Rc::new(
5073 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
5074 ));
5075 }
5076 outcome
5077 }),
5078 );
5079 }
5080 Transition::Precedence {
5081 target,
5082 precedence: transition_precedence,
5083 } => {
5084 if *transition_precedence >= precedence {
5085 let boundary = left_recursive_boundary(atn, state, *target);
5086 outcomes.extend(
5087 self.recognize_state_fast(
5088 atn,
5089 FastRecognizeRequest {
5090 state_number: *target,
5091 stop_state,
5092 index,
5093 rule_start_index,
5094 decision_start_index: next_decision_start_index,
5095 precedence,
5096 depth: depth + 1,
5097 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
5098 recovery_state: epsilon_recovery_state,
5099 },
5100 visiting,
5101 memo,
5102 expected,
5103 )
5104 .into_iter()
5105 .map(|mut outcome| {
5106 if let Some(rule_index) = boundary {
5107 outcome.nodes.prepend(Rc::new(
5108 FastRecognizedNode::LeftRecursiveBoundary { rule_index },
5109 ));
5110 }
5111 outcome
5112 }),
5113 );
5114 }
5115 }
5116 Transition::Rule {
5117 target,
5118 rule_index,
5119 follow_state,
5120 precedence: rule_precedence,
5121 ..
5122 } => {
5123 #[cfg(feature = "perf-counters")]
5124 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
5125 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
5126 else {
5127 continue;
5128 };
5129 let symbol = self.token_type_at(index);
5141 if self.fast_first_set_prefilter {
5142 let first = self.cached_rule_first_set(atn, *target, child_stop);
5155 if should_skip_rule_via_first_set(
5156 &first,
5157 symbol,
5158 self.fast_recovery_enabled,
5159 index,
5160 expected,
5161 ) {
5162 continue;
5163 }
5164 }
5165 let expected_before_child =
5166 self.fast_recovery_enabled.then(|| expected.clone());
5167 let mut children = self.recognize_state_fast(
5168 atn,
5169 FastRecognizeRequest {
5170 state_number: *target,
5171 stop_state: child_stop,
5172 index,
5173 rule_start_index: index,
5174 decision_start_index: None,
5175 precedence: *rule_precedence,
5176 depth: depth + 1,
5177 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
5178 recovery_state: epsilon_recovery_state,
5179 },
5180 visiting,
5181 memo,
5182 expected,
5183 );
5184 if children.is_empty() && self.fast_recovery_enabled {
5185 children = self.fast_child_rule_failure_recovery_outcomes(
5186 FastChildRuleFailureRecoveryRequest {
5187 atn,
5188 rule_index: *rule_index,
5189 start_index: index,
5190 follow_state: *follow_state,
5191 stop_state,
5192 expected,
5193 },
5194 );
5195 }
5196 if let Some(expected_before_child) = expected_before_child {
5197 if children
5198 .iter()
5199 .any(|child| child.diagnostics.is_empty() && child.index > index)
5200 {
5201 *expected = expected_before_child;
5202 }
5203 }
5204 for child in children {
5205 let child_index = child.index;
5206 let child_consumed_eof = child.consumed_eof;
5207 let child_diagnostics = child.diagnostics;
5208 let empty_recovery = self.empty_recovery_symbols();
5209 let follow_outcomes = self.recognize_state_fast(
5210 atn,
5211 FastRecognizeRequest {
5212 state_number: *follow_state,
5213 stop_state,
5214 index: child_index,
5215 rule_start_index,
5216 decision_start_index: next_decision_start_index,
5217 precedence,
5218 depth: depth + 1,
5219 recovery_symbols: empty_recovery,
5220 recovery_state: None,
5221 },
5222 visiting,
5223 memo,
5224 expected,
5225 );
5226 if follow_outcomes.is_empty() {
5227 continue;
5228 }
5229 let child_node = Rc::new(FastRecognizedNode::Rule {
5230 rule_index: *rule_index,
5231 invoking_state: invoking_state_number(state_number),
5232 start_index: index,
5233 stop_index: self.rule_stop_token_index(child_index, child_consumed_eof),
5234 children: child.nodes,
5235 });
5236 let child_diags_empty = child_diagnostics.is_empty();
5237 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
5238 outcome.consumed_eof |= child_consumed_eof;
5239 if !child_diags_empty {
5242 let mut diagnostics = child_diagnostics.clone();
5243 diagnostics.append(&mut outcome.diagnostics);
5244 outcome.diagnostics = diagnostics;
5245 }
5246 outcome.nodes.prepend(Rc::clone(&child_node));
5247 outcome
5248 }));
5249 }
5250 }
5251 Transition::Atom { target, .. }
5252 | Transition::Range { target, .. }
5253 | Transition::Set { target, .. }
5254 | Transition::NotSet { target, .. }
5255 | Transition::Wildcard { target, .. } => {
5256 #[cfg(feature = "perf-counters")]
5257 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
5258 let symbol = self.token_type_at(index);
5259 if transition.matches(symbol, 1, atn.max_token_type()) {
5260 let next_index = self.consume_index(index, symbol);
5261 let empty_recovery = self.empty_recovery_symbols();
5262 outcomes.extend(
5263 self.recognize_state_fast(
5264 atn,
5265 FastRecognizeRequest {
5266 state_number: *target,
5267 stop_state,
5268 index: next_index,
5269 rule_start_index,
5270 decision_start_index: next_decision_start_index,
5271 precedence,
5272 depth: depth + 1,
5273 recovery_symbols: empty_recovery,
5274 recovery_state: None,
5275 },
5276 visiting,
5277 memo,
5278 expected,
5279 )
5280 .into_iter()
5281 .map(|mut outcome| {
5282 outcome.consumed_eof |= symbol == TOKEN_EOF;
5283 if self.fast_token_nodes_enabled {
5284 outcome
5285 .nodes
5286 .prepend(Rc::new(FastRecognizedNode::Token { index }));
5287 }
5288 outcome
5289 }),
5290 );
5291 } else {
5292 if !self.fast_recovery_enabled {
5293 continue;
5301 }
5302 let expected_symbols = fast_recovery_expected_symbols(
5303 self,
5304 atn,
5305 state.state_number,
5306 &recovery_symbols,
5307 );
5308 if expected_symbols.contains(&symbol) {
5309 continue;
5310 }
5311 {
5312 expected.record_transition(index, transition, atn.max_token_type());
5313 record_no_viable_if_ambiguous(
5314 expected,
5315 next_decision_start_index,
5316 index,
5317 );
5318 outcomes.extend(self.fast_single_token_deletion_recovery(
5319 FastRecoveryRequest {
5320 atn,
5321 transition,
5322 expected_symbols: Rc::clone(&expected_symbols),
5323 target: *target,
5324 request: FastRecognizeRequest {
5325 state_number,
5326 stop_state,
5327 index,
5328 rule_start_index,
5329 decision_start_index,
5330 precedence,
5331 depth,
5332 recovery_symbols: Rc::clone(&recovery_symbols),
5333 recovery_state,
5334 },
5335 visiting,
5336 memo,
5337 expected,
5338 },
5339 ));
5340 if !state_is_left_recursive_rule(atn, state) {
5341 outcomes.extend(self.fast_single_token_insertion_recovery(
5342 FastRecoveryRequest {
5343 atn,
5344 transition,
5345 expected_symbols: Rc::clone(&expected_symbols),
5346 target: *target,
5347 request: FastRecognizeRequest {
5348 state_number,
5349 stop_state,
5350 index,
5351 rule_start_index,
5352 decision_start_index,
5353 precedence,
5354 depth,
5355 recovery_symbols: Rc::clone(&recovery_symbols),
5356 recovery_state,
5357 },
5358 visiting,
5359 memo,
5360 expected,
5361 },
5362 ));
5363 }
5364 outcomes.extend(self.fast_current_token_deletion_recovery(
5365 FastCurrentTokenDeletionRequest {
5366 atn,
5367 expected_symbols,
5368 request: FastRecognizeRequest {
5369 state_number,
5370 stop_state,
5371 index,
5372 rule_start_index,
5373 decision_start_index,
5374 precedence,
5375 depth,
5376 recovery_symbols: Rc::clone(&recovery_symbols),
5377 recovery_state,
5378 },
5379 visiting,
5380 memo,
5381 expected,
5382 },
5383 ));
5384 }
5385 }
5386 }
5387 }
5388 }
5389
5390 if needs_cycle_guard {
5391 visiting.remove(&visit_id);
5392 }
5393 if matches!(
5394 self.prediction_mode,
5395 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
5396 ) && self.fast_recovery_enabled
5397 {
5398 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
5402 }
5403 if self.fast_recovery_enabled {
5404 dedupe_fast_outcomes(&mut outcomes);
5405 } else {
5406 dedupe_clean_fast_outcomes(&mut outcomes);
5407 }
5408 let should_memoize = self.fast_recovery_enabled
5418 || (transition_count > 1
5419 && (outcomes.is_empty()
5420 || outcomes.len() > 1
5421 || (outcomes.len() == 1 && self.should_memoize_single_outcome(&key))));
5422 let apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
5426 if inline_consumed_eof {
5427 outcome.consumed_eof = true;
5428 }
5429 if !inline_consumed_tokens.is_empty() {
5430 for token_index in inline_consumed_tokens.iter().rev() {
5431 outcome.nodes.prepend(Rc::new(FastRecognizedNode::Token {
5432 index: *token_index,
5433 }));
5434 }
5435 }
5436 outcome
5437 };
5438 if should_memoize {
5439 #[cfg(feature = "perf-counters")]
5440 {
5441 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
5442 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
5443 match outcomes.len() {
5444 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
5445 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
5446 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
5447 }
5448 }
5449 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
5454 memo.insert(key, Rc::clone(&stored));
5455 if inline_pending {
5456 return stored.iter().cloned().map(apply_inline_pending).collect();
5457 }
5458 return stored.to_vec();
5459 }
5460 #[cfg(feature = "perf-counters")]
5461 match outcomes.len() {
5462 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
5463 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
5464 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
5465 }
5466 if inline_pending {
5467 return outcomes.into_iter().map(apply_inline_pending).collect();
5468 }
5469 outcomes
5470 }
5471
5472 fn single_token_deletion_recovery(
5475 &mut self,
5476 recovery: RecoveryRequest<'_, '_>,
5477 ) -> Vec<RecognizeOutcome> {
5478 let RecoveryRequest {
5479 atn,
5480 transition,
5481 expected_symbols,
5482 target,
5483 request,
5484 visiting,
5485 memo,
5486 expected,
5487 } = recovery;
5488 let RecognizeRequest {
5489 stop_state,
5490 index,
5491 rule_start_index,
5492 decision_start_index,
5493 init_action_rules,
5494 predicates,
5495 rule_args,
5496 member_actions,
5497 return_actions,
5498 local_int_arg,
5499 member_values,
5500 return_values,
5501 rule_alt_number,
5502 track_alt_numbers,
5503 consumed_eof,
5504 precedence,
5505 depth,
5506 ..
5507 } = request;
5508 let Some((diagnostic, next_index, next_symbol)) =
5509 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
5510 else {
5511 return Vec::new();
5512 };
5513 let after_next = self.consume_index(next_index, next_symbol);
5514 self.recognize_state(
5515 atn,
5516 RecognizeRequest {
5517 state_number: target,
5518 stop_state,
5519 index: after_next,
5520 rule_start_index,
5521 decision_start_index,
5522 init_action_rules,
5523 predicates,
5524 rule_args,
5525 member_actions,
5526 return_actions,
5527 local_int_arg,
5528 member_values,
5529 return_values,
5530 rule_alt_number,
5531 track_alt_numbers,
5532 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
5533 precedence,
5534 depth: depth + 1,
5535 recovery_symbols: BTreeSet::new(),
5536 recovery_state: None,
5537 },
5538 visiting,
5539 memo,
5540 expected,
5541 )
5542 .into_iter()
5543 .map(|mut outcome| {
5544 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
5545 outcome.diagnostics.insert(0, diagnostic.clone());
5546 outcome
5547 .nodes
5548 .insert(0, RecognizedNode::Token { index: next_index });
5549 outcome
5550 .nodes
5551 .insert(0, RecognizedNode::ErrorToken { index });
5552 outcome
5553 })
5554 .collect()
5555 }
5556
5557 fn current_token_deletion_recovery(
5560 &mut self,
5561 recovery: CurrentTokenDeletionRequest<'_, '_>,
5562 ) -> Vec<RecognizeOutcome> {
5563 let CurrentTokenDeletionRequest {
5564 atn,
5565 expected_symbols,
5566 mut request,
5567 visiting,
5568 memo,
5569 expected,
5570 } = recovery;
5571 let error_index = request.index;
5572 if error_index == request.rule_start_index {
5573 return Vec::new();
5574 }
5575 let Some((diagnostic, next_index, skipped)) =
5576 self.current_token_deletion(error_index, &expected_symbols)
5577 else {
5578 return Vec::new();
5579 };
5580 request.state_number = request.recovery_state.unwrap_or(request.state_number);
5581 request.index = next_index;
5582 request.depth += 1;
5583 request.recovery_state = None;
5584 self.recognize_state(atn, request, visiting, memo, expected)
5585 .into_iter()
5586 .map(|mut outcome| {
5587 outcome.diagnostics.insert(0, diagnostic.clone());
5588 for index in skipped.iter().rev() {
5589 outcome
5590 .nodes
5591 .insert(0, RecognizedNode::ErrorToken { index: *index });
5592 }
5593 outcome
5594 })
5595 .collect()
5596 }
5597
5598 fn consuming_failure_fallback(
5601 &mut self,
5602 fallback: ConsumingFailureFallback<'_>,
5603 visiting: &mut BTreeSet<RecognizeKey>,
5604 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
5605 expected: &mut ExpectedTokens,
5606 ) -> Vec<RecognizeOutcome> {
5607 if fallback.expected_symbols.is_empty() {
5608 return Vec::new();
5609 }
5610 if fallback.symbol == TOKEN_EOF {
5611 return self.eof_consuming_failure_fallback(fallback, expected);
5612 }
5613 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
5614 }
5615
5616 fn non_eof_consuming_failure_fallback(
5619 &mut self,
5620 fallback: ConsumingFailureFallback<'_>,
5621 visiting: &mut BTreeSet<RecognizeKey>,
5622 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
5623 expected: &mut ExpectedTokens,
5624 ) -> Vec<RecognizeOutcome> {
5625 let ConsumingFailureFallback {
5626 atn,
5627 target,
5628 request,
5629 symbol,
5630 expected_symbols,
5631 decision_start_index,
5632 decision,
5633 } = fallback;
5634 let error_index = request.index;
5635 let diagnostic =
5636 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
5637 let next_index = self.consume_index(error_index, symbol);
5638 self.recognize_state(
5639 atn,
5640 RecognizeRequest {
5641 state_number: target,
5642 stop_state: request.stop_state,
5643 index: next_index,
5644 rule_start_index: request.rule_start_index,
5645 decision_start_index,
5646 init_action_rules: request.init_action_rules,
5647 predicates: request.predicates,
5648 rule_args: request.rule_args,
5649 member_actions: request.member_actions,
5650 return_actions: request.return_actions,
5651 local_int_arg: request.local_int_arg,
5652 member_values: request.member_values,
5653 return_values: request.return_values,
5654 rule_alt_number: request.rule_alt_number,
5655 track_alt_numbers: request.track_alt_numbers,
5656 consumed_eof: request.consumed_eof,
5657 precedence: request.precedence,
5658 depth: request.depth + 1,
5659 recovery_symbols: BTreeSet::new(),
5660 recovery_state: None,
5661 },
5662 visiting,
5663 memo,
5664 expected,
5665 )
5666 .into_iter()
5667 .map(|mut outcome| {
5668 prepend_decision(&mut outcome, decision);
5669 outcome.diagnostics.insert(0, diagnostic.clone());
5670 outcome
5671 .nodes
5672 .insert(0, RecognizedNode::ErrorToken { index: error_index });
5673 outcome
5674 })
5675 .collect()
5676 }
5677
5678 fn eof_consuming_failure_fallback(
5681 &mut self,
5682 fallback: ConsumingFailureFallback<'_>,
5683 expected: &ExpectedTokens,
5684 ) -> Vec<RecognizeOutcome> {
5685 let request = fallback.request;
5686 if request.index == request.rule_start_index {
5687 return Vec::new();
5688 }
5689 let diagnostic =
5690 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
5691 vec![RecognizeOutcome {
5692 index: request.index,
5693 consumed_eof: request.consumed_eof,
5694 alt_number: request.rule_alt_number,
5695 member_values: request.member_values,
5696 return_values: request.return_values,
5697 diagnostics: vec![diagnostic],
5698 decisions: Vec::new(),
5699 actions: Vec::new(),
5700 nodes: Vec::new(),
5701 }]
5702 }
5703
5704 fn single_token_insertion_recovery(
5707 &mut self,
5708 recovery: RecoveryRequest<'_, '_>,
5709 ) -> Vec<RecognizeOutcome> {
5710 let RecoveryRequest {
5711 atn,
5712 transition,
5713 expected_symbols,
5714 target,
5715 request,
5716 visiting,
5717 memo,
5718 expected,
5719 } = recovery;
5720 let RecognizeRequest {
5721 stop_state,
5722 index,
5723 rule_start_index,
5724 decision_start_index,
5725 init_action_rules,
5726 predicates,
5727 rule_args,
5728 member_actions,
5729 return_actions,
5730 local_int_arg,
5731 member_values,
5732 return_values,
5733 rule_alt_number,
5734 track_alt_numbers,
5735 consumed_eof,
5736 precedence,
5737 depth,
5738 ..
5739 } = request;
5740 let follow_symbols = state_expected_symbols(atn, transition.target());
5741 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
5742 transition,
5743 index,
5744 atn.max_token_type(),
5745 &expected_symbols,
5746 &follow_symbols,
5747 ) else {
5748 return Vec::new();
5749 };
5750 self.recognize_state(
5751 atn,
5752 RecognizeRequest {
5753 state_number: target,
5754 stop_state,
5755 index,
5756 rule_start_index,
5757 decision_start_index,
5758 init_action_rules,
5759 predicates,
5760 rule_args,
5761 member_actions,
5762 return_actions,
5763 local_int_arg,
5764 member_values,
5765 return_values,
5766 rule_alt_number,
5767 track_alt_numbers,
5768 consumed_eof,
5769 precedence,
5770 depth: 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 outcome.diagnostics.insert(0, diagnostic.clone());
5781 outcome.nodes.insert(
5782 0,
5783 RecognizedNode::MissingToken {
5784 token_type,
5785 at_index: index,
5786 text: text.clone(),
5787 },
5788 );
5789 outcome
5790 })
5791 .collect()
5792 }
5793
5794 #[allow(clippy::too_many_lines)]
5797 fn recognize_state(
5798 &mut self,
5799 atn: &Atn,
5800 request: RecognizeRequest<'_>,
5801 visiting: &mut BTreeSet<RecognizeKey>,
5802 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
5803 expected: &mut ExpectedTokens,
5804 ) -> Vec<RecognizeOutcome> {
5805 let request_template = request.clone();
5806 let RecognizeRequest {
5807 state_number,
5808 stop_state,
5809 index,
5810 rule_start_index,
5811 decision_start_index,
5812 init_action_rules,
5813 predicates,
5814 rule_args,
5815 member_actions,
5816 return_actions,
5817 local_int_arg,
5818 member_values,
5819 return_values,
5820 rule_alt_number,
5821 track_alt_numbers,
5822 consumed_eof,
5823 precedence,
5824 depth,
5825 recovery_symbols,
5826 recovery_state,
5827 } = request;
5828 if depth > RECOGNITION_DEPTH_LIMIT {
5829 return Vec::new();
5830 }
5831 if state_number == stop_state {
5832 return stop_outcome(
5833 index,
5834 consumed_eof,
5835 rule_alt_number,
5836 member_values,
5837 return_values,
5838 );
5839 }
5840 let key = RecognizeKey {
5841 state_number,
5842 stop_state,
5843 index,
5844 rule_start_index,
5845 decision_start_index,
5846 local_int_arg,
5847 member_values: member_values.clone(),
5848 return_values: return_values.clone(),
5849 rule_alt_number,
5850 track_alt_numbers,
5851 consumed_eof,
5852 precedence,
5853 recovery_symbols: recovery_symbols.clone(),
5854 recovery_state,
5855 };
5856 if let Some(outcomes) = memo.get(&key) {
5857 return outcomes.clone();
5858 }
5859
5860 let visit_key = key.clone();
5861 if !visiting.insert(visit_key.clone()) {
5862 return Vec::new();
5863 }
5864
5865 let Some(state) = atn.state(state_number) else {
5866 visiting.remove(&visit_key);
5867 return Vec::new();
5868 };
5869 let next_decision_start_index = if starts_prediction_decision(state) {
5870 Some(index)
5871 } else {
5872 decision_start_index
5873 };
5874 let (epsilon_recovery_symbols, epsilon_recovery_state) =
5875 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
5876 let mut outcomes = Vec::new();
5877 for (transition_index, transition) in state.transitions.iter().enumerate() {
5878 let decision = transition_decision(atn, state, transition_index, predicates);
5879 let next_alt_number =
5880 next_alt_number(state, transition_index, rule_alt_number, track_alt_numbers);
5881 match transition {
5882 Transition::Epsilon { target } | Transition::Action { target, .. } => {
5883 let action_rule_index = match transition {
5884 Transition::Action { rule_index, .. } => Some(*rule_index),
5885 _ => None,
5886 };
5887 outcomes.extend(self.recognize_epsilon_or_action_step(
5888 atn,
5889 &request_template,
5890 EpsilonActionStep {
5891 source_state: state_number,
5892 target: *target,
5893 action_rule_index,
5894 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
5895 decision,
5896 decision_start_index: next_decision_start_index,
5897 alt_number: next_alt_number,
5898 recovery_symbols: epsilon_recovery_symbols.clone(),
5899 recovery_state: epsilon_recovery_state,
5900 },
5901 RecognizeScratch {
5902 visiting,
5903 memo,
5904 expected,
5905 },
5906 ));
5907 }
5908 Transition::Predicate {
5909 target,
5910 rule_index,
5911 pred_index,
5912 ..
5913 } => {
5914 let predicate = PredicateEval {
5915 index,
5916 rule_index: *rule_index,
5917 pred_index: *pred_index,
5918 predicates,
5919 context: None,
5920 local_int_arg,
5921 member_values: &member_values,
5922 };
5923 if self.parser_predicate_matches(predicate) {
5924 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
5925 outcomes.extend(
5926 self.recognize_state(
5927 atn,
5928 RecognizeRequest {
5929 state_number: *target,
5930 stop_state,
5931 index,
5932 rule_start_index,
5933 decision_start_index: next_decision_start_index,
5934 init_action_rules,
5935 predicates,
5936 rule_args,
5937 member_actions,
5938 return_actions,
5939 local_int_arg,
5940 member_values: member_values.clone(),
5941 return_values: return_values.clone(),
5942 rule_alt_number: next_alt_number,
5943 track_alt_numbers,
5944 consumed_eof,
5945 precedence,
5946 depth: depth + 1,
5947 recovery_symbols: epsilon_recovery_symbols.clone(),
5948 recovery_state: epsilon_recovery_state,
5949 },
5950 visiting,
5951 memo,
5952 expected,
5953 )
5954 .into_iter()
5955 .map(|mut outcome| {
5956 prepend_decision(&mut outcome, decision);
5957 if let Some(rule_index) = left_recursive_boundary {
5958 outcome.nodes.insert(
5959 0,
5960 RecognizedNode::LeftRecursiveBoundary { rule_index },
5961 );
5962 }
5963 outcome
5964 }),
5965 );
5966 } else if let Some(message) =
5967 self.parser_predicate_failure_message(*rule_index, *pred_index, predicates)
5968 {
5969 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
5970 rule_index: *rule_index,
5971 index,
5972 message,
5973 member_values: member_values.clone(),
5974 return_values: return_values.clone(),
5975 rule_alt_number,
5976 }));
5977 } else {
5978 record_predicate_no_viable(expected, next_decision_start_index, index);
5979 }
5980 }
5981 Transition::Precedence {
5982 target,
5983 precedence: transition_precedence,
5984 } => {
5985 if *transition_precedence >= precedence {
5986 outcomes.extend(
5987 self.recognize_state(
5988 atn,
5989 RecognizeRequest {
5990 state_number: *target,
5991 stop_state,
5992 index,
5993 rule_start_index,
5994 decision_start_index: next_decision_start_index,
5995 init_action_rules,
5996 predicates,
5997 rule_args,
5998 member_actions,
5999 return_actions,
6000 local_int_arg,
6001 member_values: member_values.clone(),
6002 return_values: return_values.clone(),
6003 rule_alt_number: next_alt_number,
6004 track_alt_numbers,
6005 consumed_eof,
6006 precedence,
6007 depth: depth + 1,
6008 recovery_symbols: epsilon_recovery_symbols.clone(),
6009 recovery_state: epsilon_recovery_state,
6010 },
6011 visiting,
6012 memo,
6013 expected,
6014 )
6015 .into_iter()
6016 .map(|mut outcome| {
6017 prepend_decision(&mut outcome, decision);
6018 outcome
6019 }),
6020 );
6021 }
6022 }
6023 Transition::Rule {
6024 target,
6025 rule_index,
6026 follow_state,
6027 precedence: rule_precedence,
6028 ..
6029 } => {
6030 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
6031 else {
6032 continue;
6033 };
6034 let child_local_int_arg =
6035 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
6036 let expected_before_child = expected.clone();
6037 let children = self.recognize_state(
6038 atn,
6039 RecognizeRequest {
6040 state_number: *target,
6041 stop_state: child_stop,
6042 index,
6043 rule_start_index: index,
6044 decision_start_index: None,
6045 init_action_rules,
6046 predicates,
6047 rule_args,
6048 member_actions,
6049 return_actions,
6050 local_int_arg: child_local_int_arg,
6051 member_values: member_values.clone(),
6052 return_values: BTreeMap::new(),
6053 rule_alt_number: 0,
6054 track_alt_numbers,
6055 consumed_eof: false,
6056 precedence: *rule_precedence,
6057 depth: depth + 1,
6058 recovery_symbols: epsilon_recovery_symbols.clone(),
6059 recovery_state: epsilon_recovery_state,
6060 },
6061 visiting,
6062 memo,
6063 expected,
6064 );
6065 let children = if children.is_empty() {
6066 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
6067 atn,
6068 rule_index: *rule_index,
6069 start_index: index,
6070 follow_state: *follow_state,
6071 stop_state,
6072 member_values: member_values.clone(),
6073 expected,
6074 })
6075 } else {
6076 children
6077 };
6078 let preserve_child_expected =
6079 self.child_expected_reaches_clean_eof(&children, expected);
6080 restore_expected(
6081 &children,
6082 index,
6083 expected,
6084 expected_before_child,
6085 preserve_child_expected,
6086 );
6087 for child in children {
6088 let child_node = RecognizedNode::Rule {
6089 rule_index: *rule_index,
6090 invoking_state: invoking_state_number(state_number),
6091 alt_number: child.alt_number,
6092 start_index: index,
6093 stop_index: self.rule_stop_token_index(child.index, child.consumed_eof),
6094 return_values: child.return_values.clone(),
6095 children: fold_left_recursive_boundaries(child.nodes.clone()),
6096 };
6097 outcomes.extend(
6098 self.recognize_state(
6099 atn,
6100 RecognizeRequest {
6101 state_number: *follow_state,
6102 stop_state,
6103 index: child.index,
6104 rule_start_index,
6105 decision_start_index: next_decision_start_index,
6106 init_action_rules,
6107 predicates,
6108 rule_args,
6109 member_actions,
6110 return_actions,
6111 local_int_arg,
6112 member_values: child.member_values.clone(),
6113 return_values: return_values.clone(),
6114 rule_alt_number,
6115 track_alt_numbers,
6116 consumed_eof: consumed_eof || child.consumed_eof,
6117 precedence,
6118 depth: depth + 1,
6119 recovery_symbols: BTreeSet::new(),
6120 recovery_state: None,
6121 },
6122 visiting,
6123 memo,
6124 expected,
6125 )
6126 .into_iter()
6127 .map(|mut outcome| {
6128 outcome.consumed_eof |= child.consumed_eof;
6129 let mut diagnostics = child.diagnostics.clone();
6130 diagnostics.append(&mut outcome.diagnostics);
6131 outcome.diagnostics = diagnostics;
6132 let mut decisions = child.decisions.clone();
6133 decisions.append(&mut outcome.decisions);
6134 outcome.decisions = decisions;
6135 prepend_decision(&mut outcome, decision);
6136 let mut actions = child.actions.clone();
6137 if init_action_rules.contains(rule_index) {
6138 actions.insert(
6139 0,
6140 ParserAction::new_rule_init(
6141 *rule_index,
6142 index,
6143 Some(*follow_state),
6144 ),
6145 );
6146 }
6147 actions.append(&mut outcome.actions);
6148 outcome.actions = actions;
6149 outcome.nodes.insert(0, child_node.clone());
6150 outcome
6151 }),
6152 );
6153 }
6154 }
6155 Transition::Atom { target, .. }
6156 | Transition::Range { target, .. }
6157 | Transition::Set { target, .. }
6158 | Transition::NotSet { target, .. }
6159 | Transition::Wildcard { target, .. } => {
6160 let symbol = self.token_type_at(index);
6161 if transition.matches(symbol, 1, atn.max_token_type()) {
6162 let next_index = self.consume_index(index, symbol);
6163 outcomes.extend(
6164 self.recognize_state(
6165 atn,
6166 RecognizeRequest {
6167 state_number: *target,
6168 stop_state,
6169 index: next_index,
6170 rule_start_index,
6171 decision_start_index: next_decision_start_index,
6172 init_action_rules,
6173 predicates,
6174 rule_args,
6175 member_actions,
6176 return_actions,
6177 local_int_arg,
6178 member_values: member_values.clone(),
6179 return_values: return_values.clone(),
6180 rule_alt_number: next_alt_number,
6181 track_alt_numbers,
6182 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
6183 precedence,
6184 depth: depth + 1,
6185 recovery_symbols: BTreeSet::new(),
6186 recovery_state: None,
6187 },
6188 visiting,
6189 memo,
6190 expected,
6191 )
6192 .into_iter()
6193 .map(|mut outcome| {
6194 prepend_decision(&mut outcome, decision);
6195 outcome.consumed_eof |= symbol == TOKEN_EOF;
6196 outcome.nodes.insert(0, RecognizedNode::Token { index });
6197 outcome
6198 }),
6199 );
6200 } else {
6201 let expected_symbols =
6202 recovery_expected_symbols(atn, state.state_number, &recovery_symbols);
6203 if expected_symbols.contains(&symbol) {
6204 continue;
6205 }
6206 expected.record_transition(index, transition, atn.max_token_type());
6207 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
6208 let before_recovery = outcomes.len();
6209 let recovery_request = request_template.clone();
6210 outcomes.extend(
6211 self.single_token_deletion_recovery(RecoveryRequest {
6212 atn,
6213 transition,
6214 expected_symbols: expected_symbols.clone(),
6215 target: *target,
6216 request: recovery_request.clone(),
6217 visiting,
6218 memo,
6219 expected,
6220 })
6221 .into_iter()
6222 .map(|mut outcome| {
6223 prepend_decision(&mut outcome, decision);
6224 outcome
6225 }),
6226 );
6227 if !state_is_left_recursive_rule(atn, state) {
6228 outcomes.extend(
6229 self.single_token_insertion_recovery(RecoveryRequest {
6230 atn,
6231 transition,
6232 expected_symbols: expected_symbols.clone(),
6233 target: *target,
6234 request: recovery_request.clone(),
6235 visiting,
6236 memo,
6237 expected,
6238 })
6239 .into_iter()
6240 .map(|mut outcome| {
6241 prepend_decision(&mut outcome, decision);
6242 outcome
6243 }),
6244 );
6245 }
6246 outcomes.extend(self.current_token_deletion_recovery(
6247 CurrentTokenDeletionRequest {
6248 atn,
6249 expected_symbols: expected_symbols.clone(),
6250 request: recovery_request.clone(),
6251 visiting,
6252 memo,
6253 expected,
6254 },
6255 ));
6256 if outcomes.len() == before_recovery {
6257 outcomes.extend(self.consuming_failure_fallback(
6258 ConsumingFailureFallback {
6259 atn,
6260 target: *target,
6261 request: recovery_request,
6262 symbol,
6263 expected_symbols,
6264 decision_start_index: next_decision_start_index,
6265 decision,
6266 },
6267 visiting,
6268 memo,
6269 expected,
6270 ));
6271 }
6272 }
6273 }
6274 }
6275 }
6276
6277 visiting.remove(&visit_key);
6278 self.record_prediction_diagnostics(atn, state, index, &outcomes);
6279 if matches!(
6280 self.prediction_mode,
6281 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
6282 ) {
6283 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes);
6284 }
6285 dedupe_outcomes(&mut outcomes);
6286 memo.insert(key, outcomes.clone());
6287 outcomes
6288 }
6289
6290 fn recognize_epsilon_or_action_step(
6293 &mut self,
6294 atn: &Atn,
6295 request: &RecognizeRequest<'_>,
6296 step: EpsilonActionStep,
6297 scratch: RecognizeScratch<'_>,
6298 ) -> Vec<RecognizeOutcome> {
6299 let RecognizeScratch {
6300 visiting,
6301 memo,
6302 expected,
6303 } = scratch;
6304 let action = step.action_rule_index.map(|rule_index| {
6305 ParserAction::new(
6306 step.source_state,
6307 rule_index,
6308 request.rule_start_index,
6309 self.rule_stop_token_index(request.index, request.consumed_eof),
6310 )
6311 });
6312 let next_member_values = if action.is_some() {
6313 member_values_after_action(
6314 step.source_state,
6315 request.member_actions,
6316 &request.member_values,
6317 )
6318 } else {
6319 request.member_values.clone()
6320 };
6321 let next_return_values = action.map_or_else(
6322 || request.return_values.clone(),
6323 |action| {
6324 return_values_after_action(
6325 step.source_state,
6326 action.rule_index(),
6327 request.return_actions,
6328 &request.return_values,
6329 )
6330 },
6331 );
6332
6333 self.recognize_state(
6334 atn,
6335 RecognizeRequest {
6336 state_number: step.target,
6337 stop_state: request.stop_state,
6338 index: request.index,
6339 rule_start_index: request.rule_start_index,
6340 decision_start_index: step.decision_start_index,
6341 init_action_rules: request.init_action_rules,
6342 predicates: request.predicates,
6343 rule_args: request.rule_args,
6344 member_actions: request.member_actions,
6345 return_actions: request.return_actions,
6346 local_int_arg: request.local_int_arg,
6347 member_values: next_member_values,
6348 return_values: next_return_values,
6349 rule_alt_number: step.alt_number,
6350 track_alt_numbers: request.track_alt_numbers,
6351 consumed_eof: request.consumed_eof,
6352 precedence: request.precedence,
6353 depth: request.depth + 1,
6354 recovery_symbols: step.recovery_symbols,
6355 recovery_state: step.recovery_state,
6356 },
6357 visiting,
6358 memo,
6359 expected,
6360 )
6361 .into_iter()
6362 .map(|mut outcome| {
6363 prepend_decision(&mut outcome, step.decision);
6364 if let Some(rule_index) = step.left_recursive_boundary {
6365 outcome
6366 .nodes
6367 .insert(0, RecognizedNode::LeftRecursiveBoundary { rule_index });
6368 }
6369 if let Some(action) = action {
6370 outcome.actions.insert(0, action);
6371 }
6372 outcome
6373 })
6374 .collect()
6375 }
6376
6377 fn token_type_at(&mut self, index: usize) -> i32 {
6382 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
6383 self.input.fill();
6384 }
6385 self.input.token_type_at_index(index)
6386 }
6387
6388 fn cached_state_expected_symbols(
6400 &mut self,
6401 atn: &Atn,
6402 state_number: usize,
6403 ) -> Rc<BTreeSet<i32>> {
6404 if let Some(cached) = self.state_expected_cache.get(&state_number) {
6405 return Rc::clone(cached);
6406 }
6407 let symbols = state_expected_symbols(atn, state_number);
6408 let entry = self.intern_recovery_symbols(symbols);
6409 self.state_expected_cache
6410 .insert(state_number, Rc::clone(&entry));
6411 entry
6412 }
6413
6414 fn cached_state_expected_token_set(
6415 &mut self,
6416 atn: &Atn,
6417 state_number: usize,
6418 ) -> Rc<TokenBitSet> {
6419 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
6420 return Rc::clone(cached);
6421 }
6422 let symbols = Rc::new(state_expected_token_set(atn, state_number));
6423 self.state_expected_token_cache
6424 .insert(state_number, Rc::clone(&symbols));
6425 symbols
6426 }
6427
6428 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
6429 if self.rule_stop_reach_cache.len() <= state_number {
6430 self.rule_stop_reach_cache
6431 .resize_with(atn.states().len().max(state_number + 1), || None);
6432 }
6433 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
6434 return reaches;
6435 }
6436 let reaches = state_can_reach_rule_stop(atn, state_number);
6437 self.rule_stop_reach_cache[state_number] = Some(reaches);
6438 reaches
6439 }
6440
6441 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
6444 Rc::clone(&self.empty_recovery_symbols)
6445 }
6446
6447 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
6456 if set.is_empty() {
6457 return Rc::clone(&self.empty_recovery_symbols);
6458 }
6459 let candidate = Rc::new(set);
6460 match self.recovery_symbols_intern.get(&candidate) {
6461 Some(existing) => Rc::clone(existing),
6462 None => {
6463 self.recovery_symbols_intern
6464 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
6465 candidate
6466 }
6467 }
6468 }
6469
6470 fn cached_decision_lookahead(
6475 &mut self,
6476 atn: &Atn,
6477 state: &AtnState,
6478 rule_stop_state: usize,
6479 ) -> Rc<DecisionLookahead> {
6480 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number) {
6487 return Rc::clone(cached);
6488 }
6489 let entry = with_shared_atn_caches(atn, |cache| {
6490 if let Some(cached) = cache.decision_lookahead.get(&state.state_number) {
6491 return Rc::clone(cached);
6492 }
6493 let mut entry = DecisionLookahead {
6494 transitions: Vec::with_capacity(state.transitions.len()),
6495 };
6496 for transition in &state.transitions {
6497 entry.transitions.push(transition_first_set(
6498 atn,
6499 transition,
6500 rule_stop_state,
6501 &mut cache.first_set,
6502 ));
6503 }
6504 let entry = Rc::new(entry);
6505 cache
6506 .decision_lookahead
6507 .insert(state.state_number, Rc::clone(&entry));
6508 entry
6509 });
6510 self.decision_lookahead_cache
6511 .insert(state.state_number, Rc::clone(&entry));
6512 entry
6513 }
6514
6515 fn cached_rule_first_set(
6516 &mut self,
6517 atn: &Atn,
6518 target: usize,
6519 child_stop: usize,
6520 ) -> Rc<FirstSet> {
6521 if self.rule_first_set_cache.len() <= target {
6522 self.rule_first_set_cache
6523 .resize_with(atn.states().len().max(target + 1), || None);
6524 }
6525 if let Some(cached) = self
6526 .rule_first_set_cache
6527 .get(target)
6528 .and_then(Option::as_ref)
6529 {
6530 return Rc::clone(cached);
6531 }
6532 let first = with_shared_first_set_cache(atn, |cache| {
6533 rule_first_set(atn, target, child_stop, cache)
6534 });
6535 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
6536 first
6537 }
6538
6539 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
6540 if self.empty_cycle_cache.len() <= state_number {
6541 self.empty_cycle_cache
6542 .resize_with(atn.states().len().max(state_number + 1), || None);
6543 }
6544 if let Some(cached) = self.empty_cycle_cache[state_number] {
6545 return cached;
6546 }
6547 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
6548 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
6549 self.empty_cycle_cache[state_number] = Some(result);
6550 result
6551 }
6552
6553 fn empty_path_reaches_state(
6554 &mut self,
6555 atn: &Atn,
6556 state_number: usize,
6557 target_state: usize,
6558 visited: &mut FxHashSet<usize>,
6559 ) -> bool {
6560 if !visited.insert(state_number) {
6561 return false;
6562 }
6563 let Some(state) = atn.state(state_number) else {
6564 return false;
6565 };
6566 for transition in &state.transitions {
6567 match transition {
6568 Transition::Atom { .. }
6569 | Transition::Range { .. }
6570 | Transition::Set { .. }
6571 | Transition::NotSet { .. }
6572 | Transition::Wildcard { .. } => {}
6573 Transition::Rule {
6574 target,
6575 rule_index,
6576 follow_state,
6577 ..
6578 } => {
6579 if *target == target_state
6580 || self.empty_path_reaches_state(atn, *target, target_state, visited)
6581 {
6582 return true;
6583 }
6584 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index).copied()
6585 else {
6586 continue;
6587 };
6588 if self
6589 .cached_rule_first_set(atn, *target, child_stop)
6590 .nullable
6591 && (*follow_state == target_state
6592 || self.empty_path_reaches_state(
6593 atn,
6594 *follow_state,
6595 target_state,
6596 visited,
6597 ))
6598 {
6599 return true;
6600 }
6601 }
6602 Transition::Epsilon { target }
6603 | Transition::Predicate { target, .. }
6604 | Transition::Action { target, .. }
6605 | Transition::Precedence { target, .. } => {
6606 if *target == target_state
6607 || self.empty_path_reaches_state(atn, *target, target_state, visited)
6608 {
6609 return true;
6610 }
6611 }
6612 }
6613 }
6614 false
6615 }
6616
6617 fn should_memoize_single_outcome(&mut self, key: &FastRecognizeKey) -> bool {
6620 match self.single_outcome_memo_mode {
6621 SingleOutcomeMemoMode::Promote => true,
6622 SingleOutcomeMemoMode::Sparse => false,
6623 SingleOutcomeMemoMode::Probe => {
6624 self.single_outcome_probe_samples += 1;
6625 if !self.single_outcome_probe_seen.insert(key.clone()) {
6626 self.single_outcome_probe_repeats += 1;
6627 }
6628 if self.single_outcome_probe_repeats >= CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
6629 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Promote;
6630 self.single_outcome_probe_seen.clear();
6631 return true;
6632 }
6633 if self.single_outcome_probe_samples >= CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT {
6634 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Sparse;
6635 self.single_outcome_probe_seen.clear();
6636 return false;
6637 }
6638 true
6639 }
6640 }
6641 }
6642
6643 fn token_at(&mut self, index: usize) -> Option<CommonToken> {
6645 self.input.get(index).cloned()
6646 }
6647
6648 fn current_visible_index(&mut self) -> usize {
6651 let index = self.input.index();
6652 self.input.seek(index);
6653 self.input.index()
6654 }
6655
6656 fn child_expected_reaches_clean_eof(
6659 &mut self,
6660 children: &[RecognizeOutcome],
6661 expected: &ExpectedTokens,
6662 ) -> bool {
6663 let Some(index) = expected.index else {
6664 return false;
6665 };
6666 self.token_type_at(index) == TOKEN_EOF
6667 && children
6668 .iter()
6669 .any(|child| child.diagnostics.is_empty() && child.index == index)
6670 }
6671
6672 fn previous_token_index(&mut self, index: usize) -> Option<usize> {
6679 self.input.previous_visible_token_index(index)
6680 }
6681
6682 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
6687 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
6688 Some(index)
6689 } else {
6690 self.previous_token_index(index)
6691 }
6692 }
6693
6694 #[must_use]
6711 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
6712 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
6713 self.rule_stop_token_index(current_index, consumed_eof)
6714 }
6715
6716 #[must_use]
6725 pub fn after_action_stop_index_for_tree(
6726 &mut self,
6727 tree: &ParseTree,
6728 current_index: usize,
6729 ) -> Option<usize> {
6730 if let ParseTree::Rule(rule) = tree {
6731 if let Some(stop) = rule.context().stop() {
6732 let token_index = stop.token_index();
6733 if token_index >= 0 {
6734 return Some(token_index.unsigned_abs());
6735 }
6736 }
6737 }
6738 self.after_action_stop_index(current_index)
6739 }
6740
6741 #[must_use]
6751 pub fn after_action_start_index_for_tree(
6752 &self,
6753 tree: &ParseTree,
6754 fallback_index: usize,
6755 ) -> usize {
6756 if let ParseTree::Rule(rule) = tree {
6757 if let Some(start) = rule.context().start() {
6758 let token_index = start.token_index();
6759 if token_index >= 0 {
6760 return token_index.unsigned_abs();
6761 }
6762 }
6763 }
6764 fallback_index
6765 }
6766
6767 fn rule_stop_token(&mut self, index: usize, consumed_eof: bool) -> Option<CommonToken> {
6772 self.rule_stop_token_index(index, consumed_eof)
6773 .and_then(|token_index| self.token_at(token_index))
6774 }
6775
6776 fn predicate_failure_recovery(
6783 &mut self,
6784 request: PredicateFailureRecovery<'_>,
6785 ) -> RecognizeOutcome {
6786 let PredicateFailureRecovery {
6787 rule_index,
6788 index,
6789 message,
6790 member_values,
6791 return_values,
6792 rule_alt_number,
6793 } = request;
6794 let rule_name = self
6795 .rule_names()
6796 .get(rule_index)
6797 .map_or_else(|| rule_index.to_string(), Clone::clone);
6798 let diagnostic = diagnostic_for_token(
6799 self.token_at(index).as_ref(),
6800 format!("rule {rule_name} {message}"),
6801 );
6802 let mut nodes = Vec::new();
6803 let mut next_index = index;
6804 loop {
6805 let symbol = self.token_type_at(next_index);
6806 if symbol == TOKEN_EOF {
6807 break;
6808 }
6809 nodes.push(RecognizedNode::ErrorToken { index: next_index });
6810 let after = self.consume_index(next_index, symbol);
6811 if after == next_index {
6812 break;
6813 }
6814 next_index = after;
6815 }
6816 RecognizeOutcome {
6817 index: next_index,
6818 consumed_eof: false,
6819 alt_number: rule_alt_number,
6820 member_values,
6821 return_values,
6822 diagnostics: vec![diagnostic],
6823 decisions: Vec::new(),
6824 actions: Vec::new(),
6825 nodes,
6826 }
6827 }
6828
6829 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
6836 let PredicateEval {
6837 index,
6838 rule_index,
6839 pred_index,
6840 predicates,
6841 context,
6842 local_int_arg,
6843 member_values,
6844 } = eval;
6845 let Some((_, _, predicate)) = predicates
6846 .iter()
6847 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
6848 else {
6849 return true;
6850 };
6851 self.input.seek(index);
6852 match predicate {
6853 ParserPredicate::True => true,
6854 ParserPredicate::False => false,
6855 ParserPredicate::FalseWithMessage { .. } => false,
6856 ParserPredicate::Invoke { value } => {
6857 let key = (rule_index, pred_index);
6858 if !self.invoked_predicates.contains(&key) {
6859 self.invoked_predicates.push(key);
6860 use std::io::Write as _;
6861 let mut stdout = std::io::stdout().lock();
6862 let _ = writeln!(stdout, "eval={value}");
6863 }
6864 *value
6865 }
6866 ParserPredicate::LookaheadTextEquals { offset, text } => {
6867 self.input.lt(*offset).and_then(Token::text) == Some(*text)
6868 }
6869 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
6870 self.la(*offset) != *token_type
6871 }
6872 ParserPredicate::TokenPairAdjacent => {
6873 let Some(first) = self.input.lt(-2).map(Token::token_index) else {
6874 return false;
6875 };
6876 let Some(second) = self.input.lt(-1).map(Token::token_index) else {
6877 return false;
6878 };
6879 first + 1 == second
6880 }
6881 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
6882 .and_then(|context| {
6883 context.children().iter().find_map(|child| match child {
6884 ParseTree::Rule(rule) if rule.context().rule_index() == *rule_index => {
6885 Some(child.text())
6886 }
6887 ParseTree::Rule(_) | ParseTree::Terminal(_) | ParseTree::Error(_) => None,
6888 })
6889 })
6890 .is_none_or(|actual| actual != *text),
6891 ParserPredicate::LocalIntEquals { value } => {
6892 local_int_arg.is_none_or(|(_, actual)| actual == *value)
6893 }
6894 ParserPredicate::LocalIntLessOrEqual { value } => {
6895 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
6896 }
6897 ParserPredicate::MemberModuloEquals {
6898 member,
6899 modulus,
6900 value,
6901 equals,
6902 } => {
6903 if *modulus == 0 {
6904 return false;
6905 }
6906 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
6907 (actual == *value) == *equals
6908 }
6909 ParserPredicate::MemberEquals {
6910 member,
6911 value,
6912 equals,
6913 } => {
6914 let actual = member_values.get(member).copied().unwrap_or_default();
6915 (actual == *value) == *equals
6916 }
6917 }
6918 }
6919
6920 fn parser_predicate_failure_message(
6922 &self,
6923 rule_index: usize,
6924 pred_index: usize,
6925 predicates: &[(usize, usize, ParserPredicate)],
6926 ) -> Option<&'static str> {
6927 predicates
6928 .iter()
6929 .find_map(|(rule, pred, predicate)| match predicate {
6930 ParserPredicate::FalseWithMessage { message }
6931 if *rule == rule_index && *pred == pred_index =>
6932 {
6933 Some(*message)
6934 }
6935 _ => None,
6936 })
6937 }
6938
6939 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
6948 if symbol == TOKEN_EOF {
6949 return index;
6950 }
6951 self.input.next_visible_after(index)
6952 }
6953
6954 fn no_viable_alternative(
6957 &mut self,
6958 start_index: usize,
6959 error_index: usize,
6960 ) -> ParserDiagnostic {
6961 let text = display_input_text(&self.input.text(start_index, error_index));
6962 diagnostic_for_token(
6963 self.token_at(error_index).as_ref(),
6964 format!("no viable alternative at input '{text}'"),
6965 )
6966 }
6967
6968 fn recovery_failure_diagnostic(
6971 &mut self,
6972 index: usize,
6973 decision_start_index: Option<usize>,
6974 expected_symbols: &BTreeSet<i32>,
6975 ) -> ParserDiagnostic {
6976 if expected_symbols.len() > 1 {
6977 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
6978 return self.no_viable_alternative(decision_start, index);
6979 }
6980 }
6981 diagnostic_for_token(
6982 self.token_at(index).as_ref(),
6983 format!(
6984 "mismatched input {} expecting {}",
6985 self.token_at(index)
6986 .as_ref()
6987 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6988 self.expected_symbols_display(expected_symbols)
6989 ),
6990 )
6991 }
6992
6993 fn eof_rule_recovery_diagnostic(
6996 &mut self,
6997 index: usize,
6998 expected_symbols: &BTreeSet<i32>,
6999 expected: &ExpectedTokens,
7000 ) -> ParserDiagnostic {
7001 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
7002 &expected.symbols
7003 } else {
7004 expected_symbols
7005 };
7006 diagnostic_for_token(
7007 self.token_at(index).as_ref(),
7008 format!(
7009 "mismatched input {} expecting {}",
7010 self.token_at(index)
7011 .as_ref()
7012 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7013 self.expected_symbols_display(symbols)
7014 ),
7015 )
7016 }
7017
7018 pub fn text_interval(&mut self, start: usize, stop: Option<usize>) -> String {
7024 let Some(stop) = stop else {
7025 return String::new();
7026 };
7027 let stop = if self
7028 .token_at(stop)
7029 .is_some_and(|token| token.token_type() == TOKEN_EOF)
7030 {
7031 let Some(previous) = self.previous_token_index(stop) else {
7032 return String::new();
7033 };
7034 previous
7035 } else {
7036 stop
7037 };
7038 self.input.text(start, stop)
7039 }
7040
7041 fn clear_prediction_diagnostics(&mut self) {
7044 self.prediction_diagnostics.clear();
7045 self.reported_prediction_diagnostics.clear();
7046 }
7047
7048 fn reset_per_parse_caches(&mut self) {
7069 self.rule_first_set_cache.clear();
7070 self.decision_lookahead_cache.clear();
7071 self.ll1_decision_cache.clear();
7072 self.empty_cycle_cache.clear();
7073 self.rule_stop_reach_cache.clear();
7074 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Probe;
7075 self.single_outcome_probe_seen.clear();
7076 self.single_outcome_probe_samples = 0;
7077 self.single_outcome_probe_repeats = 0;
7078 self.recovery_symbols_intern.clear();
7079 self.state_expected_cache.clear();
7080 }
7081
7082 fn record_prediction_diagnostics(
7085 &mut self,
7086 atn: &Atn,
7087 state: &AtnState,
7088 start_index: usize,
7089 outcomes: &[RecognizeOutcome],
7090 ) {
7091 if !self.report_diagnostic_errors || state.transitions.len() < 2 {
7092 return;
7093 }
7094 let Some(decision) = atn
7095 .decision_to_state()
7096 .iter()
7097 .position(|state_number| *state_number == state.state_number)
7098 else {
7099 return;
7100 };
7101 let Some(rule_index) = state.rule_index else {
7102 return;
7103 };
7104 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
7105 for outcome in outcomes
7106 .iter()
7107 .filter(|outcome| outcome.diagnostics.is_empty())
7108 {
7109 let Some(alt) = outcome.decisions.first() else {
7110 continue;
7111 };
7112 alts_by_end
7113 .entry(outcome.index)
7114 .or_default()
7115 .insert(alt + 1);
7116 }
7117 let Some((&end_index, ambig_alts)) = alts_by_end
7118 .iter()
7119 .filter(|(_, alts)| alts.len() > 1)
7120 .max_by_key(|(end, _)| *end)
7121 else {
7122 return;
7123 };
7124 let rule_name = self
7125 .rule_names()
7126 .get(rule_index)
7127 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
7128 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
7129 let input = display_input_text(&self.input.text(start_index, stop_index));
7130 let alts = ambig_alts
7131 .iter()
7132 .map(usize::to_string)
7133 .collect::<Vec<_>>()
7134 .join(", ");
7135 let key = (decision, start_index, format!("{alts}:{input}"));
7136 if !self.reported_prediction_diagnostics.insert(key) {
7137 return;
7138 }
7139 let start_token = self.token_at(start_index);
7140 let stop_token = self.token_at(stop_index);
7141 self.prediction_diagnostics.push(diagnostic_for_token(
7142 start_token.as_ref(),
7143 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
7144 ));
7145 self.prediction_diagnostics.push(diagnostic_for_token(
7146 stop_token.as_ref(),
7147 format!(
7148 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
7149 ),
7150 ));
7151 }
7152
7153 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
7155 expected_symbols_display(
7156 &state_expected_symbols(atn, state_number),
7157 self.vocabulary(),
7158 )
7159 }
7160
7161 pub fn token_display_at(&mut self, index: usize) -> Option<String> {
7163 self.token_at(index).map(|token| format!("{token}"))
7164 }
7165
7166 fn recognized_node_tree(
7168 &mut self,
7169 node: &RecognizedNode,
7170 track_alt_numbers: bool,
7171 ) -> Result<ParseTree, AntlrError> {
7172 match node {
7173 RecognizedNode::Token { index } => {
7174 let token =
7175 self.input
7176 .get(*index)
7177 .cloned()
7178 .ok_or_else(|| AntlrError::ParserError {
7179 line: 0,
7180 column: 0,
7181 message: format!("missing token at index {index}"),
7182 })?;
7183 Ok(ParseTree::Terminal(TerminalNode::new(token)))
7184 }
7185 RecognizedNode::ErrorToken { index } => {
7186 let token =
7187 self.input
7188 .get(*index)
7189 .cloned()
7190 .ok_or_else(|| AntlrError::ParserError {
7191 line: 0,
7192 column: 0,
7193 message: format!("missing error token at index {index}"),
7194 })?;
7195 Ok(ParseTree::Error(ErrorNode::new(token)))
7196 }
7197 RecognizedNode::MissingToken {
7198 token_type,
7199 at_index,
7200 text,
7201 } => {
7202 let current = self.token_at(*at_index);
7203 let token = CommonToken::new(*token_type)
7204 .with_text(text.as_str())
7205 .with_span(usize::MAX, usize::MAX)
7206 .with_position(
7207 current.as_ref().map(Token::line).unwrap_or_default(),
7208 current.as_ref().map(Token::column).unwrap_or_default(),
7209 );
7210 Ok(ParseTree::Error(ErrorNode::new(token)))
7211 }
7212 RecognizedNode::Rule {
7213 rule_index,
7214 invoking_state,
7215 alt_number,
7216 start_index,
7217 stop_index,
7218 return_values,
7219 children,
7220 } => {
7221 let mut context = ParserRuleContext::new(*rule_index, *invoking_state);
7222 if track_alt_numbers {
7223 context.set_alt_number(*alt_number);
7224 }
7225 for (name, value) in return_values {
7226 context.set_int_return(name.clone(), *value);
7227 }
7228 if let Some(token) = self.token_at(*start_index) {
7229 context.set_start(token);
7230 }
7231 if let Some(token) = stop_index.and_then(|index| self.token_at(index)) {
7232 context.set_stop(token);
7233 }
7234 for child in children {
7235 context.add_child(self.recognized_node_tree(child, track_alt_numbers)?);
7236 }
7237 Ok(self.rule_node(context))
7238 }
7239 RecognizedNode::LeftRecursiveBoundary { rule_index } => Err(AntlrError::Unsupported(
7240 format!("unfolded left-recursive boundary for rule {rule_index}"),
7241 )),
7242 }
7243 }
7244}
7245
7246impl<S> DirectAdaptiveParser<'_, '_, S>
7247where
7248 S: TokenSource,
7249{
7250 fn parse_rule(
7251 &mut self,
7252 rule_index: usize,
7253 invoking_state: isize,
7254 precedence: i32,
7255 ) -> DirectAdaptiveParseResult<ParseTree> {
7256 let start_state = *self.atn.rule_to_start_state().get(rule_index).ok_or(
7257 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
7258 )?;
7259 let stop_state = *self
7260 .atn
7261 .rule_to_stop_state()
7262 .get(rule_index)
7263 .filter(|state| **state != usize::MAX)
7264 .ok_or(DirectAdaptiveParseControl::Fallback(
7265 DirectAdaptiveFallback::MissingAtn,
7266 ))?;
7267 let start_index = self.parser.current_visible_index();
7268 let mut children = Vec::new();
7269 let mut state_number = start_state;
7270 let mut consumed_eof = false;
7271 while state_number != stop_state {
7272 self.step()?;
7273 let (transition, boundary) = self.next_transition(state_number, precedence)?;
7274 if boundary.is_some() {
7275 return Err(DirectAdaptiveParseControl::Fallback(
7276 DirectAdaptiveFallback::LeftRecursiveBoundary,
7277 ));
7278 }
7279 match transition {
7280 Transition::Epsilon { target } => {
7281 state_number = target;
7282 }
7283 Transition::Precedence {
7284 target,
7285 precedence: transition_precedence,
7286 } => {
7287 if transition_precedence < precedence {
7288 return Err(DirectAdaptiveParseControl::Fallback(
7289 DirectAdaptiveFallback::Precedence,
7290 ));
7291 }
7292 state_number = target;
7293 }
7294 Transition::Rule {
7295 rule_index,
7296 follow_state,
7297 precedence: rule_precedence,
7298 ..
7299 } => {
7300 let child = self.parse_rule(
7301 rule_index,
7302 invoking_state_number(state_number),
7303 rule_precedence,
7304 )?;
7305 if self.parser.build_parse_trees {
7306 children.push(child);
7307 }
7308 state_number = follow_state;
7309 }
7310 Transition::Atom { .. }
7311 | Transition::Range { .. }
7312 | Transition::Set { .. }
7313 | Transition::NotSet { .. }
7314 | Transition::Wildcard { .. } => {
7315 let (matched_eof, child) = self.consume_transition(&transition)?;
7316 consumed_eof |= matched_eof;
7317 if let Some(child) = child {
7318 children.push(child);
7319 }
7320 state_number = transition.target();
7321 }
7322 Transition::Predicate { .. } => {
7323 return Err(DirectAdaptiveParseControl::Fallback(
7324 DirectAdaptiveFallback::Predicate,
7325 ));
7326 }
7327 Transition::Action { .. } => {
7328 return Err(DirectAdaptiveParseControl::Fallback(
7329 DirectAdaptiveFallback::Action,
7330 ));
7331 }
7332 }
7333 }
7334
7335 let mut context = ParserRuleContext::with_child_capacity(
7336 rule_index,
7337 invoking_state,
7338 if self.parser.build_parse_trees {
7339 children.len()
7340 } else {
7341 0
7342 },
7343 );
7344 if let Some(token) = self.parser.token_at(start_index) {
7345 context.set_start(token);
7346 }
7347 let stop_index = self
7348 .parser
7349 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
7350 if let Some(token) = stop_index.and_then(|index| self.parser.token_at(index)) {
7351 context.set_stop(token);
7352 }
7353 if self.parser.build_parse_trees {
7354 for child in children {
7355 context.add_child(child);
7356 }
7357 }
7358 Ok(self.parser.rule_node(context))
7359 }
7360
7361 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
7362 self.steps += 1;
7363 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
7364 return Err(DirectAdaptiveParseControl::Fallback(
7365 DirectAdaptiveFallback::StepLimit,
7366 ));
7367 }
7368 Ok(())
7369 }
7370
7371 fn next_transition(
7372 &mut self,
7373 state_number: usize,
7374 precedence: i32,
7375 ) -> DirectAdaptiveParseResult<(Transition, Option<usize>)> {
7376 let state = self
7377 .atn
7378 .state(state_number)
7379 .ok_or(DirectAdaptiveParseControl::Fallback(
7380 DirectAdaptiveFallback::MissingAtn,
7381 ))?;
7382 if state.is_rule_stop() {
7383 return Err(DirectAdaptiveParseControl::Fallback(
7384 DirectAdaptiveFallback::RuleStop,
7385 ));
7386 }
7387 let transition_index =
7388 self.transition_index(state_number, state.transitions.len(), precedence)?;
7389 let transition = state.transitions.get(transition_index).cloned().ok_or(
7390 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
7391 )?;
7392 let boundary = match &transition {
7393 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
7394 left_recursive_boundary(self.atn, state, *target)
7395 }
7396 _ => None,
7397 };
7398 Ok((transition, boundary))
7399 }
7400
7401 fn transition_index(
7402 &mut self,
7403 state_number: usize,
7404 transition_count: usize,
7405 precedence: i32,
7406 ) -> DirectAdaptiveParseResult<usize> {
7407 match transition_count {
7408 0 => Err(DirectAdaptiveParseControl::Fallback(
7409 DirectAdaptiveFallback::NoTransition,
7410 )),
7411 1 => Ok(0),
7412 _ => {
7413 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
7414 return Ok(alt);
7415 }
7416 let decision = self
7417 .decision_by_state
7418 .get(state_number)
7419 .and_then(|decision| *decision)
7420 .ok_or(DirectAdaptiveParseControl::Fallback(
7421 DirectAdaptiveFallback::UnknownDecision,
7422 ))?;
7423 let prediction = self
7424 .simulator
7425 .adaptive_predict_stream_info_with_precedence(
7426 decision,
7427 direct_precedence(precedence),
7428 &mut self.parser.input,
7429 )
7430 .map_err(|_| {
7431 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
7432 })?;
7433 if prediction.has_semantic_context {
7434 return Err(DirectAdaptiveParseControl::Fallback(
7435 DirectAdaptiveFallback::SemanticContext,
7436 ));
7437 }
7438 prediction
7439 .alt
7440 .checked_sub(1)
7441 .filter(|index| *index < transition_count)
7442 .ok_or(DirectAdaptiveParseControl::Fallback(
7443 DirectAdaptiveFallback::InvalidAlt,
7444 ))
7445 }
7446 }
7447 }
7448
7449 fn ll1_transition_index(
7450 &mut self,
7451 state_number: usize,
7452 transition_count: usize,
7453 ) -> DirectAdaptiveParseResult<Option<usize>> {
7454 let state = self
7455 .atn
7456 .state(state_number)
7457 .ok_or(DirectAdaptiveParseControl::Fallback(
7458 DirectAdaptiveFallback::MissingAtn,
7459 ))?;
7460 if state.precedence_rule_decision {
7461 return Ok(None);
7462 }
7463 let Some(rule_stop) = state
7464 .rule_index
7465 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index).copied())
7466 else {
7467 return Ok(None);
7468 };
7469 let symbol = self.parser.input.la_token(1);
7470 let entry = self
7471 .parser
7472 .cached_decision_lookahead(self.atn, state, rule_stop);
7473 Ok(ll1_greedy_alt(&entry, symbol, state.non_greedy).filter(|alt| *alt < transition_count))
7474 }
7475
7476 fn consume_transition(
7477 &mut self,
7478 transition: &Transition,
7479 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
7480 let symbol = self.parser.input.la_token(1);
7481 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
7482 return Err(DirectAdaptiveParseControl::Fallback(
7483 DirectAdaptiveFallback::TokenMismatch,
7484 ));
7485 }
7486 let token =
7487 self.parser
7488 .input
7489 .lt(1)
7490 .cloned()
7491 .ok_or(DirectAdaptiveParseControl::Fallback(
7492 DirectAdaptiveFallback::TokenMismatch,
7493 ))?;
7494 let matched_eof = symbol == TOKEN_EOF;
7495 if !matched_eof {
7496 self.parser.consume();
7497 }
7498 let child = self
7499 .parser
7500 .build_parse_trees
7501 .then(|| ParseTree::Terminal(TerminalNode::new(token)));
7502 Ok((matched_eof, child))
7503 }
7504}
7505
7506fn left_recursive_boundary(atn: &Atn, state: &AtnState, target: usize) -> Option<usize> {
7509 if !state.precedence_rule_decision {
7510 return None;
7511 }
7512 let target_state = atn.state(target)?;
7513 if target_state.kind == AtnStateKind::LoopEnd {
7514 return None;
7515 }
7516 state.rule_index
7517}
7518
7519const fn next_alt_number(
7526 state: &AtnState,
7527 transition_index: usize,
7528 current_alt_number: usize,
7529 track_alt_numbers: bool,
7530) -> usize {
7531 if !track_alt_numbers || current_alt_number != 0 || state.transitions.len() <= 1 {
7532 return current_alt_number;
7533 }
7534 if matches!(
7535 state.kind,
7536 AtnStateKind::Basic
7537 | AtnStateKind::BlockStart
7538 | AtnStateKind::PlusBlockStart
7539 | AtnStateKind::StarBlockStart
7540 | AtnStateKind::StarLoopEntry
7541 ) && !state.precedence_rule_decision
7542 {
7543 return transition_index + 1;
7544 }
7545 current_alt_number
7546}
7547
7548fn fold_left_recursive_boundaries(nodes: Vec<RecognizedNode>) -> Vec<RecognizedNode> {
7551 let mut folded = Vec::new();
7552 for node in nodes {
7553 match node {
7554 RecognizedNode::LeftRecursiveBoundary { rule_index } => {
7555 if !folded.is_empty() {
7556 let children = std::mem::take(&mut folded);
7557 let start_index = recognized_nodes_start_index(&children).unwrap_or_default();
7558 let stop_index = recognized_nodes_stop_index(&children);
7559 folded.push(RecognizedNode::Rule {
7560 rule_index,
7561 invoking_state: -1,
7562 alt_number: 0,
7563 start_index,
7564 stop_index,
7565 return_values: BTreeMap::new(),
7566 children,
7567 });
7568 }
7569 }
7570 node => folded.push(node),
7571 }
7572 }
7573 folded
7574}
7575
7576fn fold_fast_left_recursive_boundaries(
7578 nodes: Vec<Rc<FastRecognizedNode>>,
7579) -> Vec<Rc<FastRecognizedNode>> {
7580 if !nodes.iter().any(|node| {
7585 matches!(
7586 node.as_ref(),
7587 FastRecognizedNode::LeftRecursiveBoundary { .. }
7588 )
7589 }) {
7590 return nodes;
7591 }
7592 let mut folded: Vec<Rc<FastRecognizedNode>> = Vec::with_capacity(nodes.len());
7593 for node in nodes {
7594 match node.as_ref() {
7595 FastRecognizedNode::LeftRecursiveBoundary { rule_index } => {
7596 if !folded.is_empty() {
7597 let children = std::mem::take(&mut folded);
7598 let start_index =
7599 fast_recognized_nodes_start_index(&children).unwrap_or_default();
7600 let stop_index = fast_recognized_nodes_stop_index(&children);
7601 folded.push(Rc::new(FastRecognizedNode::Rule {
7602 rule_index: *rule_index,
7603 invoking_state: -1,
7604 start_index,
7605 stop_index,
7606 children: NodeList::from_vec(children),
7607 }));
7608 }
7609 }
7610 _ => folded.push(node),
7611 }
7612 }
7613 folded
7614}
7615
7616fn fast_node_has_left_recursive_boundary(node: &FastRecognizedNode) -> bool {
7617 match node {
7618 FastRecognizedNode::LeftRecursiveBoundary { .. } => true,
7619 FastRecognizedNode::Rule { children, .. } => children.has_left_recursive_boundary(),
7620 FastRecognizedNode::Token { .. }
7621 | FastRecognizedNode::ErrorToken { .. }
7622 | FastRecognizedNode::MissingToken { .. } => false,
7623 }
7624}
7625
7626fn fast_recognized_nodes_start_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
7627 nodes
7628 .iter()
7629 .find_map(|node| fast_recognized_node_start_index(node.as_ref()))
7630}
7631
7632const fn fast_recognized_node_start_index(node: &FastRecognizedNode) -> Option<usize> {
7633 match node {
7634 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
7635 Some(*index)
7636 }
7637 FastRecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
7638 FastRecognizedNode::Rule { start_index, .. } => Some(*start_index),
7639 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
7640 }
7641}
7642
7643const fn fast_recognized_node_span(node: &FastRecognizedNode) -> Option<(usize, Option<usize>)> {
7644 match node {
7645 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
7646 Some((*index, Some(*index)))
7647 }
7648 FastRecognizedNode::MissingToken { at_index, .. } => Some((*at_index, None)),
7649 FastRecognizedNode::Rule {
7650 start_index,
7651 stop_index,
7652 ..
7653 } => Some((*start_index, *stop_index)),
7654 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
7655 }
7656}
7657
7658fn fast_recognized_nodes_stop_index(nodes: &[Rc<FastRecognizedNode>]) -> Option<usize> {
7659 nodes
7660 .iter()
7661 .rev()
7662 .find_map(|node| fast_recognized_node_stop_index(node.as_ref()))
7663}
7664
7665const fn fast_recognized_node_stop_index(node: &FastRecognizedNode) -> Option<usize> {
7666 match node {
7667 FastRecognizedNode::Token { index } | FastRecognizedNode::ErrorToken { index } => {
7668 Some(*index)
7669 }
7670 FastRecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
7671 FastRecognizedNode::Rule { stop_index, .. } => *stop_index,
7672 FastRecognizedNode::LeftRecursiveBoundary { .. } => None,
7673 }
7674}
7675
7676fn recognized_nodes_start_index(nodes: &[RecognizedNode]) -> Option<usize> {
7677 nodes.iter().find_map(recognized_node_start_index)
7678}
7679
7680const fn recognized_node_start_index(node: &RecognizedNode) -> Option<usize> {
7681 match node {
7682 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
7683 RecognizedNode::MissingToken { at_index, .. } => Some(*at_index),
7684 RecognizedNode::Rule { start_index, .. } => Some(*start_index),
7685 RecognizedNode::LeftRecursiveBoundary { .. } => None,
7686 }
7687}
7688
7689fn recognized_nodes_stop_index(nodes: &[RecognizedNode]) -> Option<usize> {
7690 nodes.iter().rev().find_map(recognized_node_stop_index)
7691}
7692
7693fn invoking_state_number(state_number: usize) -> isize {
7696 isize::try_from(state_number).unwrap_or(isize::MAX)
7697}
7698
7699fn direct_precedence(precedence: i32) -> usize {
7700 usize::try_from(precedence.max(0)).unwrap_or_default()
7701}
7702
7703const fn recognized_node_stop_index(node: &RecognizedNode) -> Option<usize> {
7704 match node {
7705 RecognizedNode::Token { index } | RecognizedNode::ErrorToken { index } => Some(*index),
7706 RecognizedNode::MissingToken { at_index, .. } => at_index.checked_sub(1),
7707 RecognizedNode::Rule { stop_index, .. } => *stop_index,
7708 RecognizedNode::LeftRecursiveBoundary { .. } => None,
7709 }
7710}
7711
7712fn token_input_display(token: &impl Token) -> String {
7713 format!("'{}'", token.text().unwrap_or("<EOF>"))
7714}
7715
7716fn display_input_text(text: &str) -> String {
7717 let mut out = String::new();
7718 for ch in text.chars() {
7719 match ch {
7720 '\n' => out.push_str("\\n"),
7721 '\r' => out.push_str("\\r"),
7722 '\t' => out.push_str("\\t"),
7723 other => out.push(other),
7724 }
7725 }
7726 out
7727}
7728
7729fn diagnostic_for_token(token: Option<&impl Token>, message: String) -> ParserDiagnostic {
7730 ParserDiagnostic {
7731 line: token.map(Token::line).unwrap_or_default(),
7732 column: token.map(Token::column).unwrap_or_default(),
7733 message,
7734 }
7735}
7736
7737#[allow(clippy::print_stderr)]
7739fn report_parser_diagnostics(diagnostics: &[ParserDiagnostic]) {
7740 for diagnostic in diagnostics {
7741 eprintln!(
7742 "line {}:{} {}",
7743 diagnostic.line, diagnostic.column, diagnostic.message
7744 );
7745 }
7746}
7747
7748#[allow(clippy::print_stderr)]
7751fn report_generated_diagnostics(
7752 parser_diagnostics: &[ParserDiagnostic],
7753 token_errors: &[TokenSourceError],
7754) {
7755 #[derive(Clone, Copy)]
7756 enum DiagnosticSource {
7757 Token(usize),
7758 Parser(usize),
7759 }
7760
7761 let mut ordered = Vec::with_capacity(parser_diagnostics.len() + token_errors.len());
7762 ordered.extend(token_errors.iter().enumerate().map(|(index, error)| {
7763 (
7764 error.line,
7765 error.column,
7766 0_usize,
7767 index,
7768 DiagnosticSource::Token(index),
7769 )
7770 }));
7771 ordered.extend(
7772 parser_diagnostics
7773 .iter()
7774 .enumerate()
7775 .map(|(index, diagnostic)| {
7776 (
7777 diagnostic.line,
7778 diagnostic.column,
7779 1_usize,
7780 index,
7781 DiagnosticSource::Parser(index),
7782 )
7783 }),
7784 );
7785 ordered.sort_by_key(|(line, column, source_order, index, _)| {
7786 (*line, *column, *source_order, *index)
7787 });
7788
7789 for (_, _, _, _, source) in ordered {
7790 match source {
7791 DiagnosticSource::Token(index) => {
7792 let error = &token_errors[index];
7793 eprintln!("line {}:{} {}", error.line, error.column, error.message);
7794 }
7795 DiagnosticSource::Parser(index) => {
7796 let diagnostic = &parser_diagnostics[index];
7797 eprintln!(
7798 "line {}:{} {}",
7799 diagnostic.line, diagnostic.column, diagnostic.message
7800 );
7801 }
7802 }
7803 }
7804}
7805
7806#[allow(clippy::print_stderr)]
7809fn report_token_source_errors(errors: &[TokenSourceError]) {
7810 for error in errors {
7811 eprintln!("line {}:{} {}", error.line, error.column, error.message);
7812 }
7813}
7814
7815fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
7816 let items = symbols
7817 .iter()
7818 .map(|symbol| expected_symbol_display(*symbol, vocabulary))
7819 .collect::<Vec<_>>();
7820 if let [single] = items.as_slice() {
7821 return single.clone();
7822 }
7823 format!("{{{}}}", items.join(", "))
7824}
7825
7826fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
7827 if symbol == TOKEN_EOF {
7828 return "<EOF>".to_owned();
7829 }
7830 vocabulary.display_name(symbol)
7831}
7832
7833fn state_is_left_recursive_rule(atn: &Atn, state: &AtnState) -> bool {
7837 let Some(rule_index) = state.rule_index else {
7838 return false;
7839 };
7840 atn.rule_to_start_state()
7841 .get(rule_index)
7842 .and_then(|state_number| atn.state(*state_number))
7843 .is_some_and(|rule_start| rule_start.left_recursive_rule)
7844}
7845
7846fn select_better_top_outcome(
7856 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
7857 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
7858) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
7859 match (first, second) {
7860 (Ok(first), Ok(second)) => {
7861 if first.0.diagnostics.is_empty() {
7862 Ok(first)
7863 } else {
7864 Ok(second)
7865 }
7866 }
7867 (Ok(first), Err(_)) => Ok(first),
7868 (Err(_), Ok(second)) => Ok(second),
7869 (Err(_), Err(second_expected)) => Err(second_expected),
7870 }
7871}
7872
7873fn select_best_fast_outcome(
7876 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
7877 prediction_mode: PredictionMode,
7878) -> Option<FastRecognizeOutcome> {
7879 outcomes.reduce(|best, outcome| {
7880 let outcome_position = (outcome.index, outcome.consumed_eof);
7881 let best_position = (best.index, best.consumed_eof);
7882 let better = match prediction_mode {
7883 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
7884 outcome_position,
7885 &outcome.diagnostics,
7886 best_position,
7887 &best.diagnostics,
7888 ),
7889 PredictionMode::Sll => outcome.index > best.index,
7890 };
7891 if better {
7892 return outcome;
7893 }
7894 best
7895 })
7896}
7897
7898fn select_best_outcome(
7899 outcomes: impl Iterator<Item = RecognizeOutcome>,
7900 prediction_mode: PredictionMode,
7901) -> Option<RecognizeOutcome> {
7902 let outcomes = outcomes.collect::<Vec<_>>();
7903 let prefer_first_tie = outcomes
7904 .iter()
7905 .any(|outcome| nodes_need_stable_tie(&outcome.nodes));
7906 outcomes.into_iter().reduce(|best, outcome| {
7907 let outcome_position = (outcome.index, outcome.consumed_eof);
7908 let best_position = (best.index, best.consumed_eof);
7909 let better = match prediction_mode {
7910 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
7911 outcome_is_better(
7912 outcome_position,
7913 &outcome.diagnostics,
7914 best_position,
7915 &best.diagnostics,
7916 ) || (!prefer_first_tie
7917 && outcome_position == best_position
7918 && outcome.diagnostics.len() == best.diagnostics.len()
7919 && diagnostic_recovery_rank(&outcome.diagnostics)
7920 == diagnostic_recovery_rank(&best.diagnostics)
7921 && (outcome.decisions < best.decisions
7922 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
7923 }
7924 PredictionMode::Sll => {
7925 outcome_position > best_position
7926 || (outcome_position == best_position
7927 && !prefer_first_tie
7928 && (outcome.decisions < best.decisions
7929 || (outcome.decisions == best.decisions
7930 && outcome_is_better(
7931 outcome_position,
7932 &outcome.diagnostics,
7933 best_position,
7934 &best.diagnostics,
7935 ))))
7936 }
7937 };
7938 if better {
7939 return outcome;
7940 }
7941 best
7942 })
7943}
7944
7945fn transition_decision(
7952 atn: &Atn,
7953 state: &AtnState,
7954 transition_index: usize,
7955 predicates: &[(usize, usize, ParserPredicate)],
7956) -> Option<usize> {
7957 if state.transitions.len() <= 1
7958 || state.precedence_rule_decision
7959 || decision_reaches_unsupported_predicate(atn, state, predicates)
7960 {
7961 return None;
7962 }
7963 Some(transition_index)
7964}
7965
7966const fn starts_prediction_decision(state: &AtnState) -> bool {
7972 state.transitions.len() > 1
7973 && !matches!(
7974 state.kind,
7975 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
7976 )
7977}
7978
7979fn record_no_viable_if_ambiguous(
7982 expected: &mut ExpectedTokens,
7983 decision_start_index: Option<usize>,
7984 index: usize,
7985) {
7986 if expected.index == Some(index) && expected.symbols.len() > 1 {
7987 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
7988 expected.record_no_viable(decision_start, index);
7989 }
7990 }
7991}
7992
7993const fn record_predicate_no_viable(
7996 expected: &mut ExpectedTokens,
7997 decision_start_index: Option<usize>,
7998 index: usize,
7999) {
8000 if let Some(decision_start) = decision_start_index {
8001 expected.record_no_viable(decision_start, index);
8002 }
8003}
8004
8005const fn no_viable_decision_start(
8007 decision_start_index: Option<usize>,
8008 index: usize,
8009) -> Option<usize> {
8010 match decision_start_index {
8011 Some(start) if index > start => Some(start),
8012 _ => None,
8013 }
8014}
8015
8016fn restore_expected(
8020 children: &[RecognizeOutcome],
8021 child_start_index: usize,
8022 expected: &mut ExpectedTokens,
8023 snapshot: ExpectedTokens,
8024 preserve_child_expected: bool,
8025) {
8026 if preserve_child_expected {
8027 return;
8028 }
8029 if children
8030 .iter()
8031 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
8032 {
8033 *expected = snapshot;
8034 }
8035}
8036
8037fn decision_reaches_unsupported_predicate(
8040 atn: &Atn,
8041 state: &AtnState,
8042 predicates: &[(usize, usize, ParserPredicate)],
8043) -> bool {
8044 state.transitions.iter().any(|transition| {
8045 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
8046 })
8047}
8048
8049fn transition_reaches_unsupported_predicate(
8051 atn: &Atn,
8052 transition: &Transition,
8053 predicates: &[(usize, usize, ParserPredicate)],
8054 visited: &mut BTreeSet<usize>,
8055) -> bool {
8056 match transition {
8057 Transition::Predicate {
8058 rule_index,
8059 pred_index,
8060 ..
8061 } => !predicates
8062 .iter()
8063 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
8064 Transition::Epsilon { target }
8065 | Transition::Action { target, .. }
8066 | Transition::Rule { target, .. } => {
8067 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
8068 }
8069 Transition::Precedence { .. }
8070 | Transition::Atom { .. }
8071 | Transition::Range { .. }
8072 | Transition::Set { .. }
8073 | Transition::NotSet { .. }
8074 | Transition::Wildcard { .. } => false,
8075 }
8076}
8077
8078fn state_reaches_unsupported_predicate(
8080 atn: &Atn,
8081 state_number: usize,
8082 predicates: &[(usize, usize, ParserPredicate)],
8083 visited: &mut BTreeSet<usize>,
8084) -> bool {
8085 if !visited.insert(state_number) {
8086 return false;
8087 }
8088 let Some(state) = atn.state(state_number) else {
8089 return false;
8090 };
8091 state.transitions.iter().any(|transition| {
8092 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
8093 })
8094}
8095
8096fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
8098 if let Some(decision) = decision {
8099 outcome.decisions.insert(0, decision);
8100 }
8101}
8102
8103fn outcome_is_better(
8104 outcome_position: (usize, bool),
8105 outcome_diagnostics: &[ParserDiagnostic],
8106 best_position: (usize, bool),
8107 best_diagnostics: &[ParserDiagnostic],
8108) -> bool {
8109 outcome_position > best_position
8110 || (outcome_position == best_position
8111 && (outcome_diagnostics.len() < best_diagnostics.len()
8112 || (outcome_diagnostics.len() == best_diagnostics.len()
8113 && diagnostic_recovery_rank(outcome_diagnostics)
8114 < diagnostic_recovery_rank(best_diagnostics))))
8115}
8116
8117fn diagnostic_recovery_rank(diagnostics: &[ParserDiagnostic]) -> usize {
8120 diagnostics
8121 .iter()
8122 .filter(|diagnostic| {
8123 diagnostic.message.starts_with("mismatched input ")
8124 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
8125 })
8126 .count()
8127}
8128
8129fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
8130 if outcomes
8131 .iter()
8132 .any(|outcome| outcome.diagnostics.is_empty())
8133 {
8134 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
8135 }
8136}
8137
8138fn discard_recovered_outcomes_if_clean_path_exists(outcomes: &mut Vec<RecognizeOutcome>) {
8139 if outcomes.iter().any(outcome_has_rule_failure_diagnostic) {
8140 return;
8141 }
8142 if outcomes
8143 .iter()
8144 .any(|outcome| outcome.diagnostics.is_empty())
8145 {
8146 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
8147 }
8148}
8149
8150fn outcome_has_rule_failure_diagnostic(outcome: &RecognizeOutcome) -> bool {
8153 outcome
8154 .diagnostics
8155 .iter()
8156 .any(|diagnostic| diagnostic.message.starts_with("rule "))
8157}
8158
8159fn nodes_need_stable_tie(nodes: &[RecognizedNode]) -> bool {
8162 nodes.iter().any(node_needs_stable_tie)
8163}
8164
8165fn node_needs_stable_tie(node: &RecognizedNode) -> bool {
8166 match node {
8167 RecognizedNode::Token { .. }
8168 | RecognizedNode::ErrorToken { .. }
8169 | RecognizedNode::MissingToken { .. } => false,
8170 RecognizedNode::LeftRecursiveBoundary { .. } => true,
8171 RecognizedNode::Rule {
8172 rule_index,
8173 children,
8174 ..
8175 } => children.iter().any(|child| {
8176 matches!(
8177 child,
8178 RecognizedNode::Rule {
8179 rule_index: child_rule,
8180 ..
8181 } if child_rule == rule_index
8182 ) || node_needs_stable_tie(child)
8183 }),
8184 }
8185}
8186
8187fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
8201 if outcomes.len() < 2 {
8202 return;
8203 }
8204 let mut keep = Vec::with_capacity(outcomes.len());
8205 let mut seen: BTreeMap<(usize, bool), Vec<usize>> = BTreeMap::new();
8206 'outcomes: for (index, outcome) in outcomes.iter().enumerate() {
8207 let bucket = seen
8208 .entry((outcome.index, outcome.consumed_eof))
8209 .or_default();
8210 for &previous in bucket.iter() {
8211 if outcomes[previous].diagnostics == outcome.diagnostics {
8212 continue 'outcomes;
8213 }
8214 }
8215 bucket.push(index);
8216 keep.push(index);
8217 }
8218 if keep.len() == outcomes.len() {
8219 return;
8220 }
8221 let mut iter = keep.into_iter();
8222 let mut next_keep = iter.next();
8223 let mut current = 0_usize;
8224 outcomes.retain(|_| {
8225 let result = next_keep == Some(current);
8226 if result {
8227 next_keep = iter.next();
8228 }
8229 current += 1;
8230 result
8231 });
8232}
8233
8234fn dedupe_clean_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>) {
8235 if outcomes.len() < 2 {
8236 return;
8237 }
8238 let mut inline_keys: [(usize, bool); 8] = [(0, false); 8];
8248 let mut inline_len = 0_usize;
8249 let mut overflow: Vec<(usize, bool)> = Vec::new();
8250 outcomes.retain(|outcome| {
8251 let key = (outcome.index, outcome.consumed_eof);
8252 for &existing in &inline_keys[..inline_len] {
8253 if existing == key {
8254 return false;
8255 }
8256 }
8257 if !overflow.is_empty() {
8258 for &existing in &overflow {
8259 if existing == key {
8260 return false;
8261 }
8262 }
8263 }
8264 if inline_len < inline_keys.len() {
8265 inline_keys[inline_len] = key;
8266 inline_len += 1;
8267 } else {
8268 overflow.push(key);
8269 }
8270 true
8271 });
8272}
8273
8274fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>) {
8276 outcomes.sort_unstable();
8277 outcomes.dedup();
8278}
8279
8280impl<S> Recognizer for BaseParser<S>
8281where
8282 S: TokenSource,
8283{
8284 fn data(&self) -> &RecognizerData {
8285 &self.data
8286 }
8287
8288 fn data_mut(&mut self) -> &mut RecognizerData {
8289 &mut self.data
8290 }
8291}
8292
8293impl<S> Parser for BaseParser<S>
8294where
8295 S: TokenSource,
8296{
8297 fn build_parse_trees(&self) -> bool {
8298 self.build_parse_trees
8299 }
8300
8301 fn set_build_parse_trees(&mut self, build: bool) {
8302 self.build_parse_trees = build;
8303 }
8304
8305 fn report_diagnostic_errors(&self) -> bool {
8306 self.report_diagnostic_errors
8307 }
8308
8309 fn set_report_diagnostic_errors(&mut self, report: bool) {
8310 self.report_diagnostic_errors = report;
8311 }
8312
8313 fn prediction_mode(&self) -> PredictionMode {
8314 self.prediction_mode
8315 }
8316
8317 fn set_prediction_mode(&mut self, mode: PredictionMode) {
8318 self.prediction_mode = mode;
8319 }
8320}
8321
8322#[cfg(test)]
8323mod tests {
8324 use super::*;
8325 use crate::atn::AtnType;
8326 use crate::atn::IntervalSet;
8327 use crate::atn::parser::{
8328 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
8329 };
8330 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
8331 use crate::token::{CommonToken, HIDDEN_CHANNEL, Token};
8332 use crate::token_stream::CommonTokenStream;
8333 use crate::vocabulary::Vocabulary;
8334
8335 #[test]
8336 fn fx_hasher_write_matches_typed_methods_for_full_words() {
8337 let value: u64 = 0x0102_0304_0506_0708;
8344 let mut typed = FxHasher::default();
8345 typed.write_u64(value);
8346 let mut bytewise = FxHasher::default();
8347 bytewise.write(&value.to_le_bytes());
8348 assert_eq!(typed.finish(), bytewise.finish());
8349 }
8350
8351 #[derive(Debug)]
8352 struct Source {
8353 tokens: Vec<CommonToken>,
8354 index: usize,
8355 }
8356
8357 impl TokenSource for Source {
8358 fn next_token(&mut self) -> CommonToken {
8359 let token = self
8360 .tokens
8361 .get(self.index)
8362 .cloned()
8363 .unwrap_or_else(|| CommonToken::eof("parser-test", self.index, 1, self.index));
8364 self.index += 1;
8365 token
8366 }
8367
8368 fn line(&self) -> usize {
8369 1
8370 }
8371
8372 fn column(&self) -> usize {
8373 self.index
8374 }
8375
8376 fn source_name(&self) -> &'static str {
8377 "parser-test"
8378 }
8379 }
8380
8381 fn mini_parser(tokens: Vec<CommonToken>) -> BaseParser<Source> {
8382 let data = RecognizerData::new(
8383 "Mini.g4",
8384 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
8385 );
8386 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
8387 }
8388
8389 fn token_then_eof_atn() -> Atn {
8390 AtnDeserializer::new(&SerializedAtn::from_i32(&[
8391 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, ]))
8407 .deserialize()
8408 .expect("artificial parser ATN should deserialize")
8409 }
8410
8411 fn eof_then_action_atn() -> Atn {
8412 AtnDeserializer::new(&SerializedAtn::from_i32(&[
8413 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, ]))
8429 .deserialize()
8430 .expect("artificial parser ATN should deserialize")
8431 }
8432
8433 fn two_alt_decision_atn() -> Atn {
8434 let mut atn = Atn::new(AtnType::Parser, 2);
8435 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8436 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
8437 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8438 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
8439 atn.add_state(AtnState::new(4, AtnStateKind::BlockEnd).with_rule_index(0));
8440 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
8441 atn.set_rule_to_start_state(vec![0]);
8442 atn.set_rule_to_stop_state(vec![5]);
8443 atn.add_decision_state(1);
8444 atn.state_mut(0)
8445 .expect("state 0")
8446 .add_transition(Transition::Epsilon { target: 1 });
8447 atn.state_mut(1)
8448 .expect("state 1")
8449 .add_transition(Transition::Atom {
8450 target: 2,
8451 label: 1,
8452 });
8453 atn.state_mut(1)
8454 .expect("state 1")
8455 .add_transition(Transition::Atom {
8456 target: 3,
8457 label: 2,
8458 });
8459 atn.state_mut(2)
8460 .expect("state 2")
8461 .add_transition(Transition::Epsilon { target: 4 });
8462 atn.state_mut(3)
8463 .expect("state 3")
8464 .add_transition(Transition::Epsilon { target: 4 });
8465 atn.state_mut(4)
8466 .expect("state 4")
8467 .add_transition(Transition::Epsilon { target: 5 });
8468 atn
8469 }
8470
8471 fn optional_then_b_eof_atn() -> Atn {
8474 let mut atn = Atn::new(AtnType::Parser, 3);
8475 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8476 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
8477 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8478 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
8479 atn.add_state(AtnState::new(4, AtnStateKind::Basic).with_rule_index(0));
8480 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(0));
8481 atn.set_rule_to_start_state(vec![0]);
8482 atn.set_rule_to_stop_state(vec![5]);
8483 atn.add_decision_state(1);
8484 atn.state_mut(0)
8485 .expect("state 0")
8486 .add_transition(Transition::Epsilon { target: 1 });
8487 atn.state_mut(1)
8489 .expect("state 1")
8490 .add_transition(Transition::Atom {
8491 target: 3,
8492 label: 1,
8493 });
8494 atn.state_mut(1)
8495 .expect("state 1")
8496 .add_transition(Transition::Epsilon { target: 3 });
8497 atn.state_mut(3)
8499 .expect("state 3")
8500 .add_transition(Transition::Atom {
8501 target: 4,
8502 label: 2,
8503 });
8504 atn.state_mut(4)
8505 .expect("state 4")
8506 .add_transition(Transition::Atom {
8507 target: 5,
8508 label: TOKEN_EOF,
8509 });
8510 atn
8511 }
8512
8513 #[test]
8514 fn sync_decision_deletes_only_a_single_token() {
8515 let atn = optional_then_b_eof_atn();
8523
8524 let mut single = mini_parser(vec![
8525 CommonToken::new(3).with_text("c"),
8526 CommonToken::new(2).with_text("b"),
8527 CommonToken::eof("parser-test", 1, 2, 2),
8528 ]);
8529 single.rule_context_stack = vec![RuleContextFrame {
8530 rule_index: 0,
8531 invoking_state: 0,
8532 }];
8533 let children = single
8534 .sync_decision(&atn, 1, true, false)
8535 .expect("single extraneous token recovers");
8536 assert_eq!(children.len(), 1);
8537 assert!(matches!(children[0], ParseTree::Error(_)));
8538 assert_eq!(single.la(1), 2);
8540
8541 let mut double = mini_parser(vec![
8542 CommonToken::new(3).with_text("c"),
8543 CommonToken::new(3).with_text("c"),
8544 CommonToken::new(2).with_text("b"),
8545 CommonToken::eof("parser-test", 1, 3, 3),
8546 ]);
8547 double.rule_context_stack = vec![RuleContextFrame {
8548 rule_index: 0,
8549 invoking_state: 0,
8550 }];
8551 let result = double.sync_decision(&atn, 1, true, false);
8552 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
8557 match error {
8558 AntlrError::ParserError { message, .. } => {
8559 assert!(message.starts_with("mismatched input"), "got: {message}");
8560 }
8561 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
8562 }
8563 assert_eq!(double.la(1), 3);
8564 }
8565
8566 fn star_loop_then_eof_atn() -> Atn {
8570 AtnDeserializer::new(&SerializedAtn::from_i32(&[
8571 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,
8572 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,
8573 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,
8574 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
8575 ]))
8576 .deserialize()
8577 .expect("star-loop-then-EOF ATN should deserialize")
8578 }
8579
8580 #[test]
8581 fn sync_decision_deletes_token_before_eof_at_loop_back() {
8582 let atn = star_loop_then_eof_atn();
8588 let mut parser = mini_parser(vec![
8589 CommonToken::new(2).with_text("c"),
8590 CommonToken::eof("parser-test", 1, 1, 1),
8591 ]);
8592 parser.rule_context_stack = vec![RuleContextFrame {
8593 rule_index: 0,
8594 invoking_state: 0,
8595 }];
8596 let children = parser
8597 .sync_decision(&atn, 5, true, false)
8598 .expect("single token before EOF recovers");
8599 assert_eq!(children.len(), 1);
8600 assert!(matches!(children[0], ParseTree::Error(_)));
8601 assert_eq!(parser.la(1), TOKEN_EOF, "EOF is left for the rule's EOF match");
8602 }
8603
8604 #[test]
8605 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
8606 let atn = star_loop_then_eof_atn();
8611 let mut parser = mini_parser(vec![
8612 CommonToken::new(2).with_text("c"),
8613 CommonToken::new(2).with_text("c"),
8614 CommonToken::eof("parser-test", 1, 2, 2),
8615 ]);
8616 parser.rule_context_stack = vec![RuleContextFrame {
8617 rule_index: 0,
8618 invoking_state: 0,
8619 }];
8620 let error = parser
8621 .sync_decision(&atn, 5, true, false)
8622 .expect_err("two tokens at the loop entry must not be deleted");
8623 match error {
8624 AntlrError::ParserError { message, .. } => {
8625 assert!(message.starts_with("mismatched input"), "got: {message}");
8626 }
8627 other => panic!("expected mismatched-input ParserError, got {other:?}"),
8628 }
8629 assert_eq!(parser.la(1), 2, "nothing consumed; cursor still on first `c`");
8630 }
8631
8632 #[test]
8633 fn sync_decision_consumes_until_eof_at_loop_back() {
8634 let atn = star_loop_then_eof_atn();
8640 let mut parser = mini_parser(vec![
8641 CommonToken::new(2).with_text("c"),
8642 CommonToken::new(2).with_text("c"),
8643 CommonToken::eof("parser-test", 1, 2, 2),
8644 ]);
8645 parser.rule_context_stack = vec![RuleContextFrame {
8646 rule_index: 0,
8647 invoking_state: 0,
8648 }];
8649 let children = parser
8650 .sync_decision(&atn, 5, false, true)
8651 .expect("loop-back multi-token deletion recovers onto EOF");
8652 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
8653 assert!(children.iter().all(|c| matches!(c, ParseTree::Error(_))));
8654 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
8655 }
8656
8657 fn predicate_after_token_atn() -> Atn {
8658 let mut atn = Atn::new(AtnType::Parser, 2);
8659 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8660 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
8661 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8662 atn.add_state(AtnState::new(3, AtnStateKind::Basic).with_rule_index(0));
8663 atn.add_state(AtnState::new(4, AtnStateKind::RuleStop).with_rule_index(0));
8664 atn.set_rule_to_start_state(vec![0]);
8665 atn.set_rule_to_stop_state(vec![4]);
8666 atn.state_mut(0)
8667 .expect("state 0")
8668 .add_transition(Transition::Atom {
8669 target: 1,
8670 label: 1,
8671 });
8672 atn.state_mut(1)
8673 .expect("state 1")
8674 .add_transition(Transition::Predicate {
8675 target: 2,
8676 rule_index: 0,
8677 pred_index: 0,
8678 context_dependent: false,
8679 });
8680 atn.state_mut(2)
8681 .expect("state 2")
8682 .add_transition(Transition::Atom {
8683 target: 3,
8684 label: 2,
8685 });
8686 atn.state_mut(3)
8687 .expect("state 3")
8688 .add_transition(Transition::Epsilon { target: 4 });
8689 atn
8690 }
8691
8692 fn nested_nullable_context_atn() -> Atn {
8693 let mut atn = Atn::new(AtnType::Parser, 1);
8694 for state_number in 0..=20 {
8695 let kind = match state_number {
8696 0 | 10 | 16 => AtnStateKind::RuleStart,
8697 9 | 15 | 20 => AtnStateKind::RuleStop,
8698 _ => AtnStateKind::Basic,
8699 };
8700 let rule_index = match state_number {
8701 0..=9 => 0,
8702 10..=15 => 1,
8703 _ => 2,
8704 };
8705 atn.add_state(AtnState::new(state_number, kind).with_rule_index(rule_index));
8706 }
8707 atn.set_rule_to_start_state(vec![0, 10, 16]);
8708 atn.set_rule_to_stop_state(vec![9, 15, 20]);
8709 atn.state_mut(1)
8710 .expect("state 1")
8711 .add_transition(Transition::Rule {
8712 target: 10,
8713 rule_index: 1,
8714 follow_state: 8,
8715 precedence: 0,
8716 });
8717 atn.state_mut(8)
8718 .expect("state 8")
8719 .add_transition(Transition::Atom {
8720 target: 9,
8721 label: 1,
8722 });
8723 atn.state_mut(8)
8724 .expect("state 8")
8725 .add_transition(Transition::Epsilon { target: 9 });
8726 atn.state_mut(2)
8727 .expect("state 2")
8728 .add_transition(Transition::Rule {
8729 target: 16,
8730 rule_index: 2,
8731 follow_state: 14,
8732 precedence: 0,
8733 });
8734 atn.state_mut(14)
8735 .expect("state 14")
8736 .add_transition(Transition::Epsilon { target: 15 });
8737 atn
8738 }
8739
8740 fn generated_match_recovery_atn() -> Atn {
8741 let mut atn = Atn::new(AtnType::Parser, 2);
8742 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8743 atn.add_state(AtnState::new(1, AtnStateKind::Basic).with_rule_index(0));
8744 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8745 atn.add_state(AtnState::new(3, AtnStateKind::RuleStop).with_rule_index(0));
8746 atn.add_state(AtnState::new(4, AtnStateKind::RuleStart).with_rule_index(1));
8747 atn.add_state(AtnState::new(5, AtnStateKind::RuleStop).with_rule_index(1));
8748 atn.set_rule_to_start_state(vec![0, 4]);
8749 atn.set_rule_to_stop_state(vec![3, 5]);
8750 atn.state_mut(1)
8751 .expect("state 1")
8752 .add_transition(Transition::Rule {
8753 target: 4,
8754 rule_index: 1,
8755 follow_state: 2,
8756 precedence: 0,
8757 });
8758 atn.state_mut(2)
8759 .expect("state 2")
8760 .add_transition(Transition::Atom {
8761 target: 3,
8762 label: TOKEN_EOF,
8763 });
8764 atn
8765 }
8766
8767 fn complement_set_atn() -> Atn {
8768 let mut atn = Atn::new(AtnType::Parser, 1);
8769 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8770 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
8771 atn.set_rule_to_start_state(vec![0]);
8772 atn.set_rule_to_stop_state(vec![1]);
8773 let mut excluded = IntervalSet::new();
8774 excluded.add(1);
8775 atn.state_mut(0)
8776 .expect("state 0")
8777 .add_transition(Transition::NotSet {
8778 target: 1,
8779 set: excluded,
8780 });
8781 atn
8782 }
8783
8784 fn wildcard_then_eof_atn() -> Atn {
8787 let mut atn = Atn::new(AtnType::Parser, 1);
8788 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
8789 atn.add_state(AtnState::new(1, AtnStateKind::RuleStop).with_rule_index(0));
8790 atn.add_state(AtnState::new(2, AtnStateKind::Basic).with_rule_index(0));
8791 atn.set_rule_to_start_state(vec![0]);
8792 atn.set_rule_to_stop_state(vec![1]);
8793 atn.state_mut(0)
8794 .expect("state 0")
8795 .add_transition(Transition::Wildcard { target: 2 });
8796 atn.state_mut(2)
8797 .expect("state 2")
8798 .add_transition(Transition::Atom {
8799 target: 1,
8800 label: TOKEN_EOF,
8801 });
8802 atn
8803 }
8804
8805 #[test]
8806 fn parser_matches_token_and_reports_mismatch() {
8807 let source = Source {
8808 tokens: vec![
8809 CommonToken::new(1).with_text("x"),
8810 CommonToken::eof("parser-test", 1, 1, 1),
8811 ],
8812 index: 0,
8813 };
8814 let data = RecognizerData::new(
8815 "Mini.g4",
8816 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
8817 );
8818 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
8819 assert_eq!(
8820 parser.match_token(1).expect("token 1 should match").text(),
8821 "x"
8822 );
8823 assert!(parser.match_token(1).is_err());
8824 }
8825
8826 #[test]
8827 fn parser_matches_token_sets() {
8828 let mut parser = mini_parser(vec![
8829 CommonToken::new(1).with_text("x"),
8830 CommonToken::eof("parser-test", 1, 1, 1),
8831 ]);
8832
8833 assert_eq!(
8834 parser
8835 .match_set(&[(1, 1), (3, 4)])
8836 .expect("token set should match")
8837 .text(),
8838 "x"
8839 );
8840 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
8841 }
8842
8843 #[test]
8844 fn generated_rule_api_tracks_state_and_precedence() {
8845 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
8846
8847 let context = parser.enter_rule(7, 2);
8848 assert_eq!(context.rule_index(), 2);
8849 assert_eq!(parser.state(), 7);
8850 assert_eq!(
8851 parser.rule_context_stack,
8852 vec![RuleContextFrame {
8853 rule_index: 2,
8854 invoking_state: 7
8855 }]
8856 );
8857
8858 let recursive = parser.enter_recursion_rule(11, 3, 4);
8859 assert_eq!(recursive.rule_index(), 3);
8860 assert!(parser.precpred(4));
8861 assert!(parser.precpred(5));
8862 assert!(!parser.precpred(3));
8863
8864 let next = parser.push_new_recursion_context(13, 3);
8865 assert_eq!(next.invoking_state(), 13);
8866 parser.unroll_recursion_context();
8867 assert_eq!(parser.precedence_stack, vec![0]);
8868 assert_eq!(
8869 parser.rule_context_stack,
8870 vec![RuleContextFrame {
8871 rule_index: 2,
8872 invoking_state: 7
8873 }]
8874 );
8875
8876 parser.exit_rule();
8877 assert!(parser.rule_context_stack.is_empty());
8878 }
8879
8880 #[test]
8881 fn parser_predicates_support_token_adjacency() {
8882 let mut parser = mini_parser(vec![
8883 CommonToken::new(1).with_text("=").with_span(0, 0),
8884 CommonToken::new(1).with_text(">").with_span(1, 1),
8885 CommonToken::eof("parser-test", 2, 1, 2),
8886 ]);
8887 parser.consume();
8888 parser.consume();
8889
8890 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
8891
8892 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
8893
8894 let mut parser = mini_parser(vec![
8895 CommonToken::new(1).with_text("=").with_span(0, 0),
8896 CommonToken::new(1)
8897 .with_text(" ")
8898 .with_channel(HIDDEN_CHANNEL)
8899 .with_span(1, 1),
8900 CommonToken::new(1).with_text(">").with_span(2, 2),
8901 CommonToken::eof("parser-test", 3, 1, 3),
8902 ]);
8903 parser.consume();
8904 parser.consume();
8905
8906 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
8907 }
8908
8909 #[test]
8910 fn parser_predicates_support_context_child_text_checks() {
8911 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
8912 let mut context = ParserRuleContext::new(1, 0);
8913 let mut child_context = ParserRuleContext::new(2, 0);
8914 child_context.add_child(ParseTree::Terminal(TerminalNode::new(
8915 CommonToken::new(1).with_text("var"),
8916 )));
8917 context.add_child(ParseTree::Rule(RuleNode::new(child_context)));
8918 let predicates = [(
8919 1,
8920 0,
8921 ParserPredicate::ContextChildRuleTextNotEquals {
8922 rule_index: 2,
8923 text: "var",
8924 },
8925 )];
8926
8927 assert!(
8928 !parser.parser_semantic_predicate_matches_with_context_and_local(
8929 &predicates,
8930 1,
8931 0,
8932 &context,
8933 0,
8934 )
8935 );
8936 }
8937
8938 #[test]
8939 fn context_expected_symbols_walks_nullable_parent_contexts() {
8940 let atn = nested_nullable_context_atn();
8941 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
8942 parser.rule_context_stack = vec![
8943 RuleContextFrame {
8944 rule_index: 0,
8945 invoking_state: 0,
8946 },
8947 RuleContextFrame {
8948 rule_index: 1,
8949 invoking_state: 1,
8950 },
8951 RuleContextFrame {
8952 rule_index: 2,
8953 invoking_state: 2,
8954 },
8955 ];
8956
8957 let expected = parser.context_expected_symbols(&atn);
8958
8959 assert!(expected.contains(&1));
8960 assert!(expected.contains(&TOKEN_EOF));
8961 }
8962
8963 #[test]
8964 fn prediction_context_reuses_cached_stack_until_rule_stack_changes() {
8965 let atn = nested_nullable_context_atn();
8966 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
8967 parser.rule_context_stack = vec![
8968 RuleContextFrame {
8969 rule_index: 0,
8970 invoking_state: 0,
8971 },
8972 RuleContextFrame {
8973 rule_index: 1,
8974 invoking_state: 1,
8975 },
8976 RuleContextFrame {
8977 rule_index: 2,
8978 invoking_state: 2,
8979 },
8980 ];
8981
8982 let first = parser.prediction_context(&atn);
8983 let second = parser.prediction_context(&atn);
8984 assert!(Rc::ptr_eq(&first, &second));
8985
8986 parser.exit_rule();
8987 let after_pop = parser.prediction_context(&atn);
8988 assert!(!Rc::ptr_eq(&first, &after_pop));
8989 }
8990
8991 #[test]
8992 fn generated_match_token_recovers_missing_token_from_context_follow() {
8993 let atn = generated_match_recovery_atn();
8994 let data = RecognizerData::new(
8995 "Mini.g4",
8996 Vocabulary::new(
8997 [None, Some("'X'"), Some("'Y'")],
8998 [None, Some("X"), Some("Y")],
8999 [None::<&str>, None, None],
9000 ),
9001 );
9002 let mut parser = BaseParser::new(
9003 CommonTokenStream::new(Source {
9004 tokens: vec![CommonToken::eof("parser-test", 3, 1, 3)],
9005 index: 0,
9006 }),
9007 data,
9008 );
9009 parser.rule_context_stack = vec![
9010 RuleContextFrame {
9011 rule_index: 0,
9012 invoking_state: 0,
9013 },
9014 RuleContextFrame {
9015 rule_index: 1,
9016 invoking_state: 1,
9017 },
9018 ];
9019
9020 let node = parser
9021 .match_token_recovering(2, 5, &atn)
9022 .expect("generated match should insert missing token");
9023
9024 assert_eq!(node.children().len(), 1);
9025 assert_eq!(node.children()[0].text(), "<missing 'Y'>");
9026 assert!(!node.consumed_eof());
9029 assert_eq!(parser.la(1), TOKEN_EOF);
9030 assert_eq!(
9031 parser.generated_parser_diagnostics,
9032 [ParserDiagnostic {
9033 line: 1,
9034 column: 3,
9035 message: "missing 'Y' at '<EOF>'".to_owned(),
9036 }]
9037 );
9038 }
9039
9040 #[test]
9041 fn generated_prediction_diagnostics_use_adaptive_context() {
9042 let atn = two_alt_decision_atn();
9043 let data = RecognizerData::new(
9044 "Mini.g4",
9045 Vocabulary::new(
9046 [None, Some("'x'"), Some("'y'")],
9047 [None, Some("X"), Some("Y")],
9048 [None::<&str>, None, None],
9049 ),
9050 )
9051 .with_rule_names(["s"]);
9052 let mut parser = BaseParser::new(
9053 CommonTokenStream::new(Source {
9054 tokens: vec![
9055 CommonToken::new(1)
9056 .with_text("x")
9057 .with_position(1, 0)
9058 .with_span(0, 0),
9059 CommonToken::new(2)
9060 .with_text("y")
9061 .with_position(1, 2)
9062 .with_span(1, 1),
9063 CommonToken::eof("parser-test", 2, 1, 3),
9064 ],
9065 index: 0,
9066 }),
9067 data,
9068 );
9069 parser.set_report_diagnostic_errors(true);
9070
9071 parser.record_generated_prediction_diagnostic(
9072 &atn,
9073 1,
9074 &ParserAtnPrediction {
9075 alt: 1,
9076 requires_full_context: true,
9077 has_semantic_context: false,
9078 diagnostic: Some(ParserAtnPredictionDiagnostic {
9079 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
9080 start_index: 0,
9081 sll_stop_index: 1,
9082 ll_stop_index: 0,
9083 conflicting_alts: vec![1, 2],
9084 }),
9085 },
9086 );
9087 parser.record_generated_prediction_diagnostic(
9088 &atn,
9089 1,
9090 &ParserAtnPrediction {
9091 alt: 1,
9092 requires_full_context: true,
9093 has_semantic_context: false,
9094 diagnostic: Some(ParserAtnPredictionDiagnostic {
9095 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
9096 start_index: 0,
9097 sll_stop_index: 1,
9098 ll_stop_index: 1,
9099 conflicting_alts: vec![1, 2],
9100 }),
9101 },
9102 );
9103
9104 assert_eq!(
9105 parser.generated_parser_diagnostics,
9106 [
9107 ParserDiagnostic {
9108 line: 1,
9109 column: 2,
9110 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
9111 },
9112 ParserDiagnostic {
9113 line: 1,
9114 column: 0,
9115 message: "reportContextSensitivity d=0 (s), input='x'".to_owned(),
9116 },
9117 ParserDiagnostic {
9118 line: 1,
9119 column: 2,
9120 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
9121 },
9122 ParserDiagnostic {
9123 line: 1,
9124 column: 2,
9125 message: "reportAmbiguity d=0 (s): ambigAlts={1, 2}, input='xy'".to_owned(),
9126 },
9127 ]
9128 );
9129 }
9130
9131 #[test]
9132 fn generated_match_not_set_recovers_empty_complement_at_eof() {
9133 let atn = complement_set_atn();
9134 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9135 parser.rule_context_stack = vec![RuleContextFrame {
9136 rule_index: 0,
9137 invoking_state: 0,
9138 }];
9139
9140 let node = parser
9141 .match_not_set_recovering(&[(1, 1)], 1, 1, 1, &atn)
9142 .expect("empty complement should recover at EOF");
9143
9144 assert_eq!(node.children().len(), 1);
9145 assert!(!node.consumed_eof());
9148 assert_eq!(parser.la(1), TOKEN_EOF);
9149 assert_eq!(
9150 parser.generated_parser_diagnostics,
9151 [ParserDiagnostic {
9152 line: 1,
9153 column: 1,
9154 message: "missing {} at '<EOF>'".to_owned(),
9155 }]
9156 );
9157 }
9158
9159 #[test]
9160 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
9161 let atn = wildcard_then_eof_atn();
9167 let data = RecognizerData::new(
9168 "Mini.g4",
9169 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
9170 );
9171 let mut parser = BaseParser::new(
9172 CommonTokenStream::new(Source {
9173 tokens: vec![CommonToken::eof("parser-test", 1, 1, 1)],
9174 index: 0,
9175 }),
9176 data,
9177 );
9178 parser.rule_context_stack = vec![RuleContextFrame {
9179 rule_index: 0,
9180 invoking_state: 0,
9181 }];
9182
9183 let node = parser
9184 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
9185 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
9186
9187 assert_eq!(node.children().len(), 1);
9189 assert!(!node.consumed_eof());
9190 assert!(node.children()[0].text().starts_with("<missing"));
9191 assert_eq!(parser.la(1), TOKEN_EOF);
9192 assert_eq!(
9193 parser.generated_parser_diagnostics,
9194 [ParserDiagnostic {
9195 line: 1,
9196 column: 1,
9197 message: "missing 'x' at '<EOF>'".to_owned(),
9198 }]
9199 );
9200 }
9201
9202 #[test]
9203 fn generated_rule_recovery_consumes_to_parent_follow() {
9204 let atn = generated_match_recovery_atn();
9205 let data = RecognizerData::new(
9206 "Mini.g4",
9207 Vocabulary::new(
9208 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
9209 [None, Some("X"), Some("Y"), Some("Z")],
9210 [None::<&str>, None, None, None],
9211 ),
9212 );
9213 let mut parser = BaseParser::new(
9214 CommonTokenStream::new(Source {
9215 tokens: vec![
9216 CommonToken::new(3).with_text("z"),
9217 CommonToken::eof("parser-test", 1, 1, 1),
9218 ],
9219 index: 0,
9220 }),
9221 data,
9222 );
9223 let _parent = parser.enter_rule(0, 0);
9224 let marker = parser.push_invoking_state(1);
9225 let mut child = parser.enter_rule(4, 1);
9226 parser.discard_invoking_state(marker);
9227
9228 parser.recover_generated_rule(
9229 &mut child,
9230 &atn,
9231 AntlrError::ParserError {
9232 line: 1,
9233 column: 0,
9234 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
9235 },
9236 );
9237 let tree = parser.finish_rule(child, false);
9238
9239 assert_eq!(parser.la(1), TOKEN_EOF);
9240 assert_eq!(
9241 tree.to_string_tree(&["s".to_owned(), "a".to_owned()]),
9242 "(a z)"
9243 );
9244 assert_eq!(
9245 parser.generated_parser_diagnostics,
9246 [ParserDiagnostic {
9247 line: 1,
9248 column: 0,
9249 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
9250 }]
9251 );
9252 parser.exit_rule();
9253 }
9254
9255 #[test]
9256 fn greedy_ll1_alt_handles_nullable_loop_exit() {
9257 let mut body_symbols = TokenBitSet::default();
9258 body_symbols.insert(1);
9259 let entry = DecisionLookahead {
9260 transitions: vec![
9261 TransitionLookSet {
9262 symbols: body_symbols,
9263 nullable: false,
9264 },
9265 TransitionLookSet {
9266 symbols: TokenBitSet::default(),
9267 nullable: true,
9268 },
9269 ],
9270 };
9271
9272 assert_eq!(ll1_unique_alt(&entry, 2), None);
9273 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
9274 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
9275 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
9276 }
9277
9278 #[test]
9279 fn single_outcome_memo_probe_selects_sparse_or_promote_mode() {
9280 let key = |state_number| FastRecognizeKey {
9281 state_number,
9282 stop_state: 10,
9283 index: state_number,
9284 rule_start_index: 0,
9285 decision_start_index: None,
9286 precedence: 0,
9287 recovery_symbols_id: 0,
9288 recovery_state: None,
9289 };
9290
9291 let mut sparse = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9292 for state_number in 0..(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT - 1) {
9293 assert!(sparse.should_memoize_single_outcome(&key(state_number)));
9294 }
9295 assert!(!sparse.should_memoize_single_outcome(&key(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT)));
9296 assert_eq!(
9297 sparse.single_outcome_memo_mode,
9298 SingleOutcomeMemoMode::Sparse
9299 );
9300
9301 let mut promote = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9302 let repeated = key(1);
9303 for _ in 0..=CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
9304 assert!(promote.should_memoize_single_outcome(&repeated));
9305 }
9306 assert_eq!(
9307 promote.single_outcome_memo_mode,
9308 SingleOutcomeMemoMode::Promote
9309 );
9310 }
9311
9312 #[test]
9313 fn clean_empty_multi_alt_outcomes_are_memoized() {
9314 let mut atn = Atn::new(AtnType::Parser, 2);
9315 atn.add_state(AtnState::new(0, AtnStateKind::RuleStart).with_rule_index(0));
9316 atn.add_state(AtnState::new(1, AtnStateKind::BlockStart).with_rule_index(0));
9317 atn.add_state(AtnState::new(2, AtnStateKind::RuleStop).with_rule_index(0));
9318 atn.set_rule_to_start_state(vec![0]);
9319 atn.set_rule_to_stop_state(vec![2]);
9320 atn.state_mut(0)
9321 .expect("state 0")
9322 .add_transition(Transition::Epsilon { target: 1 });
9323 atn.state_mut(1)
9324 .expect("state 1")
9325 .add_transition(Transition::Atom {
9326 target: 2,
9327 label: 1,
9328 });
9329 atn.state_mut(1)
9330 .expect("state 1")
9331 .add_transition(Transition::Atom {
9332 target: 2,
9333 label: 2,
9334 });
9335
9336 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
9337 parser.fast_recovery_enabled = false;
9338 let mut visiting = FxHashSet::default();
9339 let mut memo = FxHashMap::default();
9340 let mut expected = ExpectedTokens::default();
9341 let outcomes = parser.recognize_state_fast(
9342 &atn,
9343 FastRecognizeRequest {
9344 state_number: 1,
9345 stop_state: 2,
9346 index: 0,
9347 rule_start_index: 0,
9348 decision_start_index: None,
9349 precedence: 0,
9350 depth: 0,
9351 recovery_symbols: parser.empty_recovery_symbols(),
9352 recovery_state: None,
9353 },
9354 &mut visiting,
9355 &mut memo,
9356 &mut expected,
9357 );
9358
9359 assert!(outcomes.is_empty());
9360 assert_eq!(memo.len(), 1);
9361 assert!(memo.values().next().expect("memo entry").is_empty());
9362 }
9363
9364 #[test]
9365 fn wildcard_matches_non_eof_only() {
9366 let mut parser = mini_parser(vec![
9367 CommonToken::new(1).with_text("x"),
9368 CommonToken::eof("parser-test", 1, 1, 1),
9369 ]);
9370 assert_eq!(parser.match_wildcard().expect("wildcard").text(), "x");
9371 assert!(parser.match_wildcard().is_err());
9372 }
9373
9374 #[test]
9375 fn add_parse_child_records_match_even_without_tree_building() {
9376 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9381 let token = CommonToken::new(1).with_text("x");
9382
9383 parser.set_build_parse_trees(false);
9384 let mut ctx = ParserRuleContext::new(0, 0);
9385 assert!(!ctx.has_matched_child());
9386 parser.add_parse_child(&mut ctx, ParseTree::Terminal(TerminalNode::new(token.clone())));
9387 assert!(ctx.children().is_empty());
9389 assert!(ctx.has_matched_child());
9391
9392 parser.set_build_parse_trees(true);
9394 let mut ctx = ParserRuleContext::new(0, 0);
9395 parser.add_parse_child(&mut ctx, ParseTree::Terminal(TerminalNode::new(token)));
9396 assert_eq!(ctx.children().len(), 1);
9397 assert!(ctx.has_matched_child());
9398 }
9399
9400 #[test]
9401 fn parser_interprets_simple_atn_rule() {
9402 let atn = token_then_eof_atn();
9403 let mut parser = mini_parser(vec![
9404 CommonToken::new(1).with_text("x"),
9405 CommonToken::eof("parser-test", 1, 1, 1),
9406 ]);
9407
9408 let tree = parser
9409 .parse_atn_rule(&atn, 0)
9410 .expect("artificial parser rule should parse");
9411 assert_eq!(tree.text(), "x<EOF>");
9412 assert_eq!(
9413 tree.first_rule_stop(0)
9414 .expect("rule should stop at EOF")
9415 .token_type(),
9416 TOKEN_EOF
9417 );
9418
9419 let mut parser = mini_parser(vec![
9420 CommonToken::new(1).with_text("x"),
9421 CommonToken::eof("parser-test", 1, 1, 1),
9422 ]);
9423 let (tree, actions) = parser
9424 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
9425 .expect("runtime-option parser rule should parse");
9426 assert!(actions.is_empty());
9427 assert_eq!(
9428 tree.first_rule_stop(0)
9429 .expect("rule should stop at EOF")
9430 .token_type(),
9431 TOKEN_EOF
9432 );
9433 }
9434
9435 #[test]
9436 fn adaptive_direct_rule_uses_simulator_decision() {
9437 let atn = two_alt_decision_atn();
9438 let mut simulator = ParserAtnSimulator::new(&atn);
9439 let mut parser = mini_parser(vec![
9440 CommonToken::new(2).with_text("y"),
9441 CommonToken::eof("parser-test", 1, 1, 1),
9442 ]);
9443
9444 let tree = parser
9445 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
9446 .expect("direct adaptive rule should parse");
9447
9448 assert_eq!(tree.text(), "y");
9449 assert_eq!(parser.input.index(), 1);
9450 }
9451
9452 #[test]
9453 fn adaptive_direct_rule_restores_input_on_fallback() {
9454 let atn = predicate_after_token_atn();
9455 let mut simulator = ParserAtnSimulator::new(&atn);
9456 let mut parser = mini_parser(vec![
9457 CommonToken::new(1).with_text("x"),
9458 CommonToken::new(2).with_text("y"),
9459 CommonToken::eof("parser-test", 2, 1, 2),
9460 ]);
9461
9462 let tree = parser
9463 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
9464 .expect("fallback recognizer should parse");
9465
9466 assert_eq!(tree.text(), "xy");
9467 assert_eq!(parser.input.index(), 2);
9468 }
9469
9470 #[test]
9471 fn parser_rule_start_skips_leading_hidden_tokens() {
9472 let atn = token_then_eof_atn();
9473 let mut parser = mini_parser(vec![
9474 CommonToken::new(99)
9475 .with_text(" ")
9476 .with_channel(HIDDEN_CHANNEL),
9477 CommonToken::new(1).with_text("x"),
9478 CommonToken::eof("parser-test", 2, 1, 2),
9479 ]);
9480
9481 let tree = parser
9482 .parse_atn_rule(&atn, 0)
9483 .expect("artificial parser rule should parse");
9484 let Some(ParseTree::Rule(rule)) = tree.first_rule(0) else {
9485 panic!("rule node should be present");
9486 };
9487 assert_eq!(
9488 rule.context()
9489 .start()
9490 .expect("rule should have a start token")
9491 .token_type(),
9492 1
9493 );
9494 }
9495
9496 #[test]
9497 fn parser_action_after_eof_stops_at_eof_token() {
9498 let atn = eof_then_action_atn();
9499 let mut parser = mini_parser(vec![CommonToken::eof("parser-test", 0, 1, 0)]);
9500
9501 let (_, actions) = parser
9502 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
9503 .expect("EOF action rule should parse");
9504
9505 assert_eq!(actions.len(), 1);
9506 assert_eq!(actions[0].stop_index(), Some(0));
9507 assert_eq!(
9508 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
9509 ""
9510 );
9511 }
9512
9513 #[test]
9514 fn after_action_stop_uses_rule_context_stop_not_cursor() {
9515 let mut id = CommonToken::new(1).with_text("x");
9520 id.set_token_index(0);
9521 let mut eof = CommonToken::eof("parser-test", 1, 1, 1);
9522 eof.set_token_index(1);
9523 let mut parser = mini_parser(vec![id.clone(), eof]);
9524 parser.consume();
9526 assert_eq!(parser.la(1), TOKEN_EOF);
9527
9528 let mut ctx = ParserRuleContext::new(0, 0);
9531 ctx.set_stop(id);
9532 let tree = ParseTree::Rule(RuleNode::new(ctx));
9533
9534 let current_index = parser.input.index();
9535 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
9537 assert_eq!(
9539 parser.after_action_stop_index_for_tree(&tree, current_index),
9540 Some(0)
9541 );
9542 }
9543
9544 #[test]
9545 fn after_action_start_uses_rule_context_start_not_cursor() {
9546 let parser = mini_parser(vec![CommonToken::eof("parser-test", 1, 1, 1)]);
9551 let mut id = CommonToken::new(1).with_text("x");
9552 id.set_token_index(2);
9554
9555 let mut ctx = ParserRuleContext::new(0, 0);
9556 ctx.set_start(id);
9557 let tree = ParseTree::Rule(RuleNode::new(ctx));
9558
9559 assert_eq!(parser.after_action_start_index_for_tree(&tree, 0), 2);
9562
9563 let empty = ParseTree::Rule(RuleNode::new(ParserRuleContext::new(0, 0)));
9565 assert_eq!(parser.after_action_start_index_for_tree(&empty, 7), 7);
9566 }
9567
9568 #[test]
9569 fn fast_outcome_selection_respects_sll_tie_order() {
9570 let first = FastRecognizeOutcome {
9571 index: 1,
9572 consumed_eof: false,
9573 diagnostics: FastDiagnostics::from_vec(vec![ParserDiagnostic {
9574 line: 1,
9575 column: 0,
9576 message: "mismatched input 'x'".to_owned(),
9577 }]),
9578 nodes: NodeList::new(),
9579 };
9580 let second = FastRecognizeOutcome {
9581 index: first.index,
9582 consumed_eof: first.consumed_eof,
9583 diagnostics: FastDiagnostics::new(),
9584 nodes: NodeList::new(),
9585 };
9586
9587 let selected = select_best_fast_outcome(
9588 [first.clone(), second.clone()].into_iter(),
9589 PredictionMode::Sll,
9590 )
9591 .expect("one outcome should be selected");
9592 assert_eq!(selected.diagnostics.len(), 1);
9593 let eof_second = FastRecognizeOutcome {
9594 index: second.index,
9595 consumed_eof: true,
9596 diagnostics: FastDiagnostics::new(),
9597 nodes: NodeList::new(),
9598 };
9599 let selected =
9600 select_best_fast_outcome([first.clone(), eof_second].into_iter(), PredictionMode::Sll)
9601 .expect("one outcome should be selected");
9602 assert!(!selected.consumed_eof);
9603 let selected = select_best_fast_outcome([first, second].into_iter(), PredictionMode::Ll)
9604 .expect("one outcome should be selected");
9605 assert!(selected.diagnostics.is_empty());
9606 }
9607
9608 #[test]
9609 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
9610 let source = Source {
9611 tokens: vec![
9612 CommonToken::new(1).with_text("x"),
9613 CommonToken::eof("parser-test", 1, 1, 1),
9614 ],
9615 index: 0,
9616 };
9617 let data = RecognizerData::new(
9618 "Mini.g4",
9619 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
9620 );
9621 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
9622 let expected = ExpectedTokens {
9623 index: Some(0),
9624 symbols: BTreeSet::new(),
9625 no_viable: None,
9626 };
9627
9628 let (_, message) = parser.expected_error_message(0, 0, &expected);
9629
9630 assert_eq!(message, "mismatched input 'x'");
9631 }
9632
9633 #[test]
9634 fn eof_rule_stop_index_points_at_eof_token() {
9635 let source = Source {
9636 tokens: vec![
9637 CommonToken::new(1).with_text("x"),
9638 CommonToken::eof("parser-test", 1, 1, 1),
9639 ],
9640 index: 0,
9641 };
9642 let data = RecognizerData::new(
9643 "Mini.g4",
9644 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
9645 );
9646 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
9647
9648 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
9649 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
9650 }
9651
9652 #[test]
9653 fn generated_parser_action_uses_current_rule_stop_boundary() {
9654 let mut parser = mini_parser(vec![
9655 CommonToken::new(1).with_text("x"),
9656 CommonToken::eof("parser-test", 1, 1, 1),
9657 ]);
9658
9659 parser.match_token(1).expect("token should match");
9660 let action = parser.parser_action_at_current(7, 0, 0, false);
9661 assert_eq!(action.source_state(), 7);
9662 assert_eq!(action.rule_index(), 0);
9663 assert_eq!(action.start_index(), 0);
9664 assert_eq!(action.stop_index(), Some(0));
9665
9666 parser.match_eof().expect("EOF should match");
9667 let action = parser.parser_action_at_current(8, 0, 0, true);
9668 assert_eq!(action.stop_index(), Some(1));
9669 }
9670
9671 #[test]
9672 fn folds_left_recursive_boundary_into_rule_node() {
9673 let nodes = fold_left_recursive_boundaries(vec![
9674 RecognizedNode::Token { index: 0 },
9675 RecognizedNode::LeftRecursiveBoundary { rule_index: 1 },
9676 RecognizedNode::Token { index: 1 },
9677 ]);
9678
9679 assert_eq!(
9680 nodes,
9681 vec![
9682 RecognizedNode::Rule {
9683 rule_index: 1,
9684 invoking_state: -1,
9685 alt_number: 0,
9686 start_index: 0,
9687 stop_index: Some(0),
9688 return_values: BTreeMap::new(),
9689 children: vec![RecognizedNode::Token { index: 0 }],
9690 },
9691 RecognizedNode::Token { index: 1 },
9692 ]
9693 );
9694 }
9695
9696 #[test]
9697 fn outcome_ties_keep_later_non_recursive_alternative() {
9698 let first = RecognizeOutcome {
9699 index: 1,
9700 consumed_eof: false,
9701 alt_number: 0,
9702 member_values: BTreeMap::new(),
9703 return_values: BTreeMap::new(),
9704 diagnostics: Vec::new(),
9705 decisions: Vec::new(),
9706 actions: vec![ParserAction::new(1, 0, 0, None)],
9707 nodes: vec![RecognizedNode::Token { index: 0 }],
9708 };
9709 let second = RecognizeOutcome {
9710 actions: vec![ParserAction::new(2, 0, 0, None)],
9711 ..first.clone()
9712 };
9713
9714 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
9715 .expect("one outcome should be selected");
9716 assert_eq!(selected.actions[0].source_state(), 2);
9717 }
9718
9719 #[test]
9720 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
9721 let first = RecognizeOutcome {
9722 index: 1,
9723 consumed_eof: false,
9724 alt_number: 0,
9725 member_values: BTreeMap::new(),
9726 return_values: BTreeMap::new(),
9727 diagnostics: Vec::new(),
9728 decisions: Vec::new(),
9729 actions: vec![ParserAction::new(1, 0, 0, None)],
9730 nodes: vec![RecognizedNode::Token { index: 0 }],
9731 };
9732 let second = RecognizeOutcome {
9733 actions: vec![
9734 ParserAction::new(2, 0, 0, None),
9735 ParserAction::new(3, 0, 0, None),
9736 ],
9737 ..first.clone()
9738 };
9739
9740 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll)
9741 .expect("one outcome should be selected");
9742 assert_eq!(selected.actions.len(), 2);
9743 }
9744
9745 #[test]
9746 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
9747 let first = RecognizeOutcome {
9748 index: 7,
9749 consumed_eof: false,
9750 alt_number: 0,
9751 member_values: BTreeMap::new(),
9752 return_values: BTreeMap::new(),
9753 diagnostics: Vec::new(),
9754 decisions: vec![1, 0],
9755 actions: vec![
9756 ParserAction::new(23, 2, 2, Some(4)),
9757 ParserAction::new(23, 2, 0, Some(6)),
9758 ],
9759 nodes: vec![RecognizedNode::Token { index: 0 }],
9760 };
9761 let second = RecognizeOutcome {
9762 decisions: vec![0, 1],
9763 actions: vec![
9764 ParserAction::new(23, 2, 2, Some(6)),
9765 ParserAction::new(23, 2, 0, Some(6)),
9766 ],
9767 ..first.clone()
9768 };
9769
9770 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
9771 .expect("one outcome should be selected");
9772 assert_eq!(selected.actions[0].stop_index(), Some(6));
9773 }
9774
9775 #[test]
9776 fn outcome_ties_keep_first_recursive_tree_shape() {
9777 let recursive_nodes = vec![RecognizedNode::Rule {
9778 rule_index: 1,
9779 invoking_state: -1,
9780 alt_number: 0,
9781 start_index: 0,
9782 stop_index: Some(0),
9783 return_values: BTreeMap::new(),
9784 children: vec![RecognizedNode::Rule {
9785 rule_index: 1,
9786 invoking_state: -1,
9787 alt_number: 0,
9788 start_index: 0,
9789 stop_index: Some(0),
9790 return_values: BTreeMap::new(),
9791 children: vec![RecognizedNode::Token { index: 0 }],
9792 }],
9793 }];
9794 let first = RecognizeOutcome {
9795 index: 1,
9796 consumed_eof: false,
9797 alt_number: 0,
9798 member_values: BTreeMap::new(),
9799 return_values: BTreeMap::new(),
9800 diagnostics: Vec::new(),
9801 decisions: Vec::new(),
9802 actions: vec![ParserAction::new(1, 0, 0, None)],
9803 nodes: recursive_nodes.clone(),
9804 };
9805 let second = RecognizeOutcome {
9806 index: 1,
9807 consumed_eof: false,
9808 alt_number: 0,
9809 member_values: BTreeMap::new(),
9810 return_values: BTreeMap::new(),
9811 diagnostics: Vec::new(),
9812 decisions: Vec::new(),
9813 actions: vec![ParserAction::new(2, 0, 0, None)],
9814 nodes: recursive_nodes,
9815 };
9816
9817 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll)
9818 .expect("one outcome should be selected");
9819 assert_eq!(selected.actions[0].source_state(), 1);
9820 }
9821
9822 #[test]
9823 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
9824 let first_alt = RecognizeOutcome {
9825 index: 2,
9826 consumed_eof: true,
9827 alt_number: 0,
9828 member_values: BTreeMap::new(),
9829 return_values: BTreeMap::new(),
9830 diagnostics: vec![ParserDiagnostic {
9831 line: 1,
9832 column: 3,
9833 message: "missing 'Y' at '<EOF>'".to_owned(),
9834 }],
9835 decisions: vec![0],
9836 actions: vec![ParserAction::new(1, 0, 0, None)],
9837 nodes: vec![RecognizedNode::Token { index: 0 }],
9838 };
9839 let second_alt = RecognizeOutcome {
9840 diagnostics: Vec::new(),
9841 decisions: vec![1],
9842 actions: vec![ParserAction::new(2, 0, 0, None)],
9843 ..first_alt.clone()
9844 };
9845
9846 let selected =
9847 select_best_outcome([second_alt, first_alt].into_iter(), PredictionMode::Sll)
9848 .expect("one outcome should be selected");
9849 assert_eq!(selected.diagnostics.len(), 1);
9850 assert_eq!(selected.decisions, [0]);
9851 }
9852}