1use crate::atn::AtnStateKind;
2use crate::atn::parser_atn::{
3 ParserAtn as Atn, ParserAtnState as AtnState, ParserTransition, ParserTransitionKind,
4};
5#[cfg(test)]
6use crate::atn::parser_atn::{ParserAtnBuilder, ParserTransitionSpec};
7use crate::dfa::{
8 DfaStateBuilder, DfaStateId, NO_DFA_STATE, ParserDfa, ParserDfaStateView, ParserDfaStats,
9};
10use crate::int_stream::IntStream;
11use crate::prediction::{
12 AtnConfig, AtnConfigSet, ContextArena, ContextId, EMPTY_CONTEXT, EMPTY_RETURN_STATE,
13 PredictionContextStats, PredictionFxHasher, PredictionWorkspace, SemanticContext,
14 all_subsets_conflict, all_subsets_equal, conflicting_alt_subsets,
15 has_sll_conflict_terminating_prediction, single_viable_alt,
16};
17use crate::token::TOKEN_EOF;
18use std::cell::RefCell;
19use std::collections::{HashMap, HashSet};
20use std::hash::BuildHasherDefault;
21
22type FxHashSet<T> = HashSet<T, BuildHasherDefault<PredictionFxHasher>>;
23
24#[derive(Debug)]
25pub struct ParserAtnSimulator<'a> {
26 atn: &'a Atn,
27 store: PredictionStore,
28 workspace: PredictionWorkspace,
29 outer_context_cache: Option<CachedOuterContext>,
30 outer_context_cache_hits: usize,
31 outer_context_cache_misses: usize,
32 deferred_accept_states: FxHashSet<(usize, DfaStateId)>,
35 shared_cache_key: Option<usize>,
36 shared_cache_generation: u64,
37 exact_ambig_detection: bool,
41 full_context_memo: HashMap<
52 FullContextMemoKey,
53 Vec<FullContextMemoEntry>,
54 BuildHasherDefault<PredictionFxHasher>,
55 >,
56 full_context_memo_len: usize,
57 full_context_memo_gate: Option<bool>,
61}
62
63#[derive(Clone, Copy, Debug)]
64struct CachedOuterContext {
65 rule_context_version: usize,
66 context: ContextId,
67}
68
69#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
80struct FullContextMemoKey {
81 decision: usize,
82 precedence: i32,
83 outer_context: ContextId,
84 first_symbol: i32,
85}
86
87#[derive(Clone, Debug)]
98struct FullContextMemoEntry {
99 window_tail: Vec<i32>,
100 prediction: FullContextPrediction,
101}
102
103const FULL_CONTEXT_MEMO_MAX_WINDOW: usize = 16;
107const FULL_CONTEXT_MEMO_MAX_ENTRIES: usize = 4096;
111
112fn atn_has_predicate_transition(atn: &Atn) -> bool {
119 thread_local! {
120 static GATES: RefCell<HashMap<usize, bool, BuildHasherDefault<PredictionFxHasher>>> =
121 RefCell::new(HashMap::default());
122 }
123 let ptr: *const Atn = atn;
124 let key = ptr as usize;
125 GATES.with(|gates| {
126 *gates.borrow_mut().entry(key).or_insert_with(|| {
127 (0..atn.state_count()).any(|state_number| {
128 atn.state(state_number).is_some_and(|state| {
129 state
130 .transitions()
131 .into_iter()
132 .any(|transition| transition.kind() == ParserTransitionKind::Predicate)
133 })
134 })
135 })
136 })
137}
138
139#[derive(Debug, Default)]
140struct PredictionStore {
141 contexts: ContextArena,
142 decision_to_dfa: Vec<ParserDfa>,
143}
144
145impl PredictionStore {
146 fn new(atn: &Atn) -> Self {
147 Self {
148 contexts: ContextArena::new(),
149 decision_to_dfa: initial_decision_dfas(atn),
150 }
151 }
152}
153
154#[derive(Debug, Default)]
155struct SharedPredictionStore {
156 generation: u64,
157 store: Option<PredictionStore>,
158}
159
160thread_local! {
161 static SHARED_PREDICTION_STORES: RefCell<HashMap<usize, SharedPredictionStore>> =
162 RefCell::new(HashMap::new());
163}
164
165fn clear_shared_prediction_store(key: usize) -> u64 {
166 SHARED_PREDICTION_STORES.with(|cache| {
167 let mut cache = cache.borrow_mut();
168 let shared = cache.entry(key).or_default();
169 shared.generation = shared.generation.wrapping_add(1);
170 shared.store = None;
171 shared.generation
172 })
173}
174
175#[derive(Clone, Debug, Eq, PartialEq)]
176pub struct ParserAtnPrediction {
177 pub alt: usize,
178 pub requires_full_context: bool,
179 pub has_semantic_context: bool,
180 pub diagnostic: Option<ParserAtnPredictionDiagnostic>,
181}
182
183#[derive(Clone, Debug, Eq, PartialEq)]
184pub struct ParserAtnPredictionDiagnostic {
185 pub kind: ParserAtnPredictionDiagnosticKind,
186 pub start_index: usize,
187 pub sll_stop_index: usize,
188 pub ll_stop_index: usize,
189 pub conflicting_alts: Vec<usize>,
190 pub exact: bool,
194}
195
196#[derive(Clone, Copy, Debug, Eq, PartialEq)]
197pub enum ParserAtnPredictionDiagnosticKind {
198 Ambiguity,
199 ContextSensitivity,
200}
201
202#[derive(Clone, Copy)]
203struct PredictionCheck {
204 decision: usize,
205 decision_state: usize,
206 state_number: DfaStateId,
207 start_index: usize,
208 precedence: i32,
209 outer_context: ContextId,
210 force_full_context_retry: bool,
211 sll_probe_only: bool,
212}
213
214#[derive(Clone, Copy)]
215struct AdaptivePredictRequest {
216 decision: usize,
217 precedence: usize,
218 outer_context: ContextId,
219 force_full_context_retry: bool,
220 sll_probe_only: bool,
228}
229
230#[derive(Clone, Copy)]
231struct DfaEdge {
232 decision: usize,
233 source_state: DfaStateId,
234}
235
236#[derive(Clone, Debug)]
237struct PreviousGoodAlt {
238 alt: usize,
239 configs: Vec<AtnConfig>,
240}
241
242#[derive(Clone, Debug, Eq, PartialEq)]
243struct DfaPredictionInfo {
244 prediction: ParserAtnPrediction,
245 conflicting_alts: Vec<usize>,
246}
247
248#[derive(Clone, Debug, Eq, PartialEq)]
249struct FullContextPrediction {
250 prediction: ParserAtnPrediction,
251 stop_index: usize,
252 resolution: FullContextResolution,
253}
254
255#[derive(Clone, Debug, Eq, PartialEq)]
260enum FullContextResolution {
261 Unique,
262 Ambiguous { exact: bool, alts: Vec<usize> },
263}
264
265fn full_context_prediction(
266 alt: usize,
267 configs: &AtnConfigSet,
268 stop_index: usize,
269 resolution: FullContextResolution,
270) -> FullContextPrediction {
271 FullContextPrediction {
272 prediction: ParserAtnPrediction {
273 alt,
274 requires_full_context: true,
275 has_semantic_context: configs_have_semantic_context_for_alt(configs, alt),
276 diagnostic: None,
277 },
278 stop_index,
279 resolution,
280 }
281}
282
283#[derive(Clone, Debug, Eq, Hash, PartialEq)]
284struct ClosureConfigKey {
285 state: usize,
286 alt: usize,
287 context: ContextId,
288 semantic_context: SemanticContext,
289 precedence_filter_suppressed: bool,
290}
291
292impl From<&AtnConfig> for ClosureConfigKey {
293 fn from(config: &AtnConfig) -> Self {
294 Self {
295 state: config.state,
296 alt: config.alt,
297 context: config.context,
298 semantic_context: config.semantic_context.clone(),
299 precedence_filter_suppressed: config.precedence_filter_suppressed,
300 }
301 }
302}
303
304#[derive(Default)]
311struct ClosureScratch {
312 stack: Vec<(AtnConfig, bool)>,
319 visited: FxHashSet<ClosureConfigKey>,
320}
321
322#[derive(Clone, Copy)]
325struct ClosureParams {
326 precedence: i32,
327 collect_predicates: bool,
328 treat_eof_as_epsilon: bool,
329}
330
331#[derive(Debug)]
332struct LookaheadIntStream {
333 symbols: Vec<i32>,
334 index: usize,
335}
336
337impl LookaheadIntStream {
338 const fn new(symbols: Vec<i32>) -> Self {
339 Self { symbols, index: 0 }
340 }
341}
342
343impl IntStream for LookaheadIntStream {
344 fn consume(&mut self) {
345 if self.la(1) != TOKEN_EOF {
346 self.index += 1;
347 }
348 }
349
350 fn la(&mut self, offset: isize) -> i32 {
351 if offset <= 0 {
352 return 0;
353 }
354 let offset = offset.cast_unsigned() - 1;
355 self.symbols
356 .get(self.index + offset)
357 .copied()
358 .unwrap_or(TOKEN_EOF)
359 }
360
361 fn index(&self) -> usize {
362 self.index
363 }
364
365 fn seek(&mut self, index: usize) {
366 self.index = index.min(self.symbols.len());
367 }
368
369 fn size(&self) -> usize {
370 self.symbols.len()
371 }
372}
373
374fn initial_decision_dfas(atn: &Atn) -> Vec<ParserDfa> {
375 atn.decision_to_state()
376 .iter()
377 .enumerate()
378 .map(|(decision, state)| {
379 let mut dfa = ParserDfa::with_max_token_type(state, decision, atn.max_token_type());
380 if atn
381 .state(state)
382 .is_some_and(AtnState::precedence_rule_decision)
383 {
384 dfa.set_precedence_dfa(true);
385 }
386 dfa
387 })
388 .collect()
389}
390
391fn union_decision_dfas(shared: &mut Vec<ParserDfa>, local: Vec<ParserDfa>) {
401 if shared.len() != local.len() {
402 *shared = local;
403 return;
404 }
405 for (shared_dfa, local_dfa) in shared.iter_mut().zip(local) {
406 union_decision_dfa(shared_dfa, local_dfa);
407 }
408}
409
410fn union_prediction_stores(
411 shared: &mut PredictionStore,
412 mut local: PredictionStore,
413 workspace: &mut PredictionWorkspace,
414) {
415 let remap = shared.contexts.import_all(&local.contexts, workspace);
416 for dfa in &mut local.decision_to_dfa {
417 dfa.remap_contexts(&remap, &shared.contexts);
418 }
419 union_decision_dfas(&mut shared.decision_to_dfa, local.decision_to_dfa);
420}
421
422fn union_decision_dfa(shared: &mut ParserDfa, local: ParserDfa) {
423 if shared.is_precedence_dfa() != local.is_precedence_dfa() {
424 if local.state_count() > shared.state_count() {
427 *shared = local;
428 }
429 return;
430 }
431 let mut renumber = Vec::with_capacity(local.state_count());
436 for state in local.states() {
437 let configs = local.configs(state.id());
438 let number = shared.state_id_for_configs(configs).unwrap_or_else(|| {
439 let missing = local.clone_state_without_edges(state.id());
440 shared.insert_state(missing)
441 });
442 renumber.push(number);
443 }
444 for state in local.states() {
449 let mapped = renumber[state.id().index()];
450 for transition in state.transitions() {
451 let Some(&mapped_target) = renumber.get(transition.target.index()) else {
452 continue;
453 };
454 if shared.edge(mapped, transition.symbol).is_none() {
455 shared.add_edge(mapped, transition.symbol, mapped_target);
456 }
457 }
458 }
459 if shared.start_state().is_none()
460 && let Some(start) = local.start_state()
461 && let Some(&mapped) = renumber.get(start.index())
462 {
463 shared.set_start_state(mapped);
464 }
465 for (precedence, start) in local.precedence_start_states().iter().copied().enumerate() {
466 if start == NO_DFA_STATE {
467 continue;
468 }
469 if shared.precedence_start_state(precedence).is_none()
470 && let Some(&mapped) = renumber.get(start.index())
471 {
472 shared.set_precedence_start_state(precedence, mapped);
473 }
474 }
475}
476
477impl Drop for ParserAtnSimulator<'_> {
478 fn drop(&mut self) {
479 let Some(key) = self.shared_cache_key else {
480 return;
481 };
482 #[cfg(feature = "perf-counters")]
483 let publication_started = std::time::Instant::now();
484 #[cfg(feature = "perf-counters")]
485 let published_states = self
486 .store
487 .decision_to_dfa
488 .iter()
489 .map(ParserDfa::state_count)
490 .sum();
491 let store = std::mem::take(&mut self.store);
497 let published = SHARED_PREDICTION_STORES.with(|cache| {
498 let mut cache = cache.borrow_mut();
499 let shared = cache.entry(key).or_default();
500 if shared.generation != self.shared_cache_generation {
501 return false;
502 }
503 if let Some(shared_store) = shared.store.as_mut() {
504 union_prediction_stores(shared_store, store, &mut self.workspace);
505 } else {
506 shared.store = Some(store);
507 }
508 true
509 });
510 #[cfg(feature = "perf-counters")]
511 if published {
512 crate::perf::record_dfa_cache_publication(
513 publication_started.elapsed().as_nanos(),
514 published_states,
515 );
516 }
517 #[cfg(not(feature = "perf-counters"))]
518 let _ = published;
519 }
520}
521
522impl<'a> ParserAtnSimulator<'a> {
523 pub fn new(atn: &'a Atn) -> Self {
524 Self {
525 atn,
526 store: PredictionStore::new(atn),
527 workspace: PredictionWorkspace::default(),
528 outer_context_cache: None,
529 outer_context_cache_hits: 0,
530 outer_context_cache_misses: 0,
531 deferred_accept_states: FxHashSet::default(),
532 shared_cache_key: None,
533 shared_cache_generation: 0,
534 exact_ambig_detection: false,
535 full_context_memo: HashMap::default(),
536 full_context_memo_len: 0,
537 full_context_memo_gate: None,
538 }
539 }
540
541 pub fn reset(&mut self) {
543 self.outer_context_cache = None;
544 self.deferred_accept_states.clear();
545 self.workspace.reset();
546 }
547
548 pub fn clear_dfa(&mut self) {
553 self.store = PredictionStore::new(self.atn);
554 self.full_context_memo.clear();
557 self.full_context_memo_len = 0;
558 self.reset();
559 if let Some(key) = self.shared_cache_key {
560 self.shared_cache_generation = clear_shared_prediction_store(key);
561 }
562 }
563
564 pub fn clear_shared_dfa(atn: &'static Atn) {
566 let ptr: *const Atn = atn;
567 clear_shared_prediction_store(ptr as usize);
568 }
569
570 pub const fn set_exact_ambig_detection(&mut self, exact: bool) {
573 self.exact_ambig_detection = exact;
574 }
575
576 pub fn dump_dfa_java_style(&self, vocabulary: &crate::vocabulary::Vocabulary) -> String {
594 use std::fmt::Write as _;
595 let mut out = String::new();
596 let mut seen_one = false;
597 for dfa in &self.store.decision_to_dfa {
598 if dfa.is_empty() {
599 continue;
600 }
601 if seen_one {
602 out.push('\n');
603 }
604 seen_one = true;
605 let _ = writeln!(out, "Decision {}:", dfa.decision());
606 for state in dfa.states() {
607 let source = dfa_state_display(
608 state,
609 self.deferred_accept_states
610 .contains(&(dfa.decision(), state.id())),
611 );
612 for transition in state.transitions() {
613 let Some(target_state) = dfa.state(transition.target) else {
614 continue;
615 };
616 let label = vocabulary.display_name(transition.symbol);
617 let target = dfa_state_display(
618 target_state,
619 self.deferred_accept_states
620 .contains(&(dfa.decision(), target_state.id())),
621 );
622 let _ = writeln!(out, "{source}-{label}->{target}");
623 }
624 }
625 }
626 out
627 }
628
629 pub fn new_shared(atn: &'static Atn) -> Self {
630 let ptr: *const Atn = atn;
631 let key = ptr as usize;
632 #[cfg(feature = "perf-counters")]
633 let import_started = std::time::Instant::now();
634 let (store, generation) = SHARED_PREDICTION_STORES.with(|cache| {
635 let mut cache = cache.borrow_mut();
636 let shared = cache.entry(key).or_default();
637 (
638 shared
639 .store
640 .take()
641 .unwrap_or_else(|| PredictionStore::new(atn)),
642 shared.generation,
643 )
644 });
645 #[cfg(feature = "perf-counters")]
646 crate::perf::record_dfa_cache_import(
647 import_started.elapsed().as_nanos(),
648 store
649 .decision_to_dfa
650 .iter()
651 .map(ParserDfa::state_count)
652 .sum(),
653 );
654 Self {
655 atn,
656 store,
657 workspace: PredictionWorkspace::default(),
658 outer_context_cache: None,
659 outer_context_cache_hits: 0,
660 outer_context_cache_misses: 0,
661 deferred_accept_states: FxHashSet::default(),
662 shared_cache_key: Some(key),
663 shared_cache_generation: generation,
664 exact_ambig_detection: false,
665 full_context_memo: HashMap::default(),
666 full_context_memo_len: 0,
667 full_context_memo_gate: None,
668 }
669 }
670
671 pub fn decision_dfas(&self) -> &[ParserDfa] {
672 &self.store.decision_to_dfa
673 }
674
675 pub fn parser_dfa_stats(&self) -> ParserDfaStats {
677 let mut stats = ParserDfaStats::default();
678 for dfa in &self.store.decision_to_dfa {
679 stats.add_assign(dfa.stats());
680 }
681 stats
682 }
683
684 pub fn prediction_context_stats(&self) -> PredictionContextStats {
687 let mut stats = self.store.contexts.stats();
688 stats.retained_bytes += self.workspace.retained_bytes();
689 stats.workspace_merge_cache_entries = self.workspace.merge_cache_len();
690 stats.workspace_merge_cache_capacity = self.workspace.merge_cache_capacity();
691 stats.workspace_entry_capacity = self.workspace.entry_capacity();
692 stats.outer_context_cache_hits = self.outer_context_cache_hits;
693 stats.outer_context_cache_misses = self.outer_context_cache_misses;
694 stats
695 }
696
697 pub fn intern_prediction_context(
701 &mut self,
702 rule_context_version: usize,
703 return_states: impl IntoIterator<Item = usize>,
704 ) -> ContextId {
705 if let Some(cached) = self.outer_context_cache
706 && cached.rule_context_version == rule_context_version
707 {
708 self.outer_context_cache_hits = self.outer_context_cache_hits.saturating_add(1);
709 return cached.context;
710 }
711 self.outer_context_cache_misses = self.outer_context_cache_misses.saturating_add(1);
712 let mut context = EMPTY_CONTEXT;
713 for return_state in return_states {
714 context = self.store.contexts.singleton(context, return_state);
715 }
716 self.outer_context_cache = Some(CachedOuterContext {
717 rule_context_version,
718 context,
719 });
720 context
721 }
722
723 pub fn adaptive_predict(
724 &mut self,
725 decision: usize,
726 lookahead: impl IntoIterator<Item = i32>,
727 ) -> Result<usize, ParserAtnSimulatorError> {
728 self.adaptive_predict_with_precedence(decision, 0, lookahead)
729 }
730
731 pub fn adaptive_predict_stream<T: IntStream>(
732 &mut self,
733 decision: usize,
734 input: &mut T,
735 ) -> Result<usize, ParserAtnSimulatorError> {
736 self.adaptive_predict_stream_with_precedence(decision, 0, input)
737 }
738
739 pub fn adaptive_predict_stream_with_precedence<T: IntStream>(
740 &mut self,
741 decision: usize,
742 precedence: usize,
743 input: &mut T,
744 ) -> Result<usize, ParserAtnSimulatorError> {
745 self.adaptive_predict_stream_info_with_precedence(decision, precedence, input)
746 .map(|prediction| prediction.alt)
747 }
748
749 pub fn adaptive_predict_stream_info_with_precedence<T: IntStream>(
750 &mut self,
751 decision: usize,
752 precedence: usize,
753 input: &mut T,
754 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
755 let marker = input.mark();
756 let index = input.index();
757 let mut workspace = std::mem::take(&mut self.workspace);
758 workspace.reset();
759 let result = self.adaptive_predict_stream_inner(
760 AdaptivePredictRequest {
761 decision,
762 precedence,
763 outer_context: EMPTY_CONTEXT,
764 force_full_context_retry: false,
765 sll_probe_only: false,
766 },
767 input,
768 &mut workspace,
769 );
770 self.workspace = workspace;
771 input.seek(index);
772 input.release(marker);
773 result
774 }
775
776 pub fn adaptive_predict_stream_info_sll_probe<T: IntStream>(
786 &mut self,
787 decision: usize,
788 precedence: usize,
789 input: &mut T,
790 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
791 let marker = input.mark();
792 let index = input.index();
793 let mut workspace = std::mem::take(&mut self.workspace);
794 workspace.reset();
795 let result = self.adaptive_predict_stream_inner(
796 AdaptivePredictRequest {
797 decision,
798 precedence,
799 outer_context: EMPTY_CONTEXT,
800 force_full_context_retry: false,
801 sll_probe_only: true,
802 },
803 input,
804 &mut workspace,
805 );
806 self.workspace = workspace;
807 input.seek(index);
808 input.release(marker);
809 result
810 }
811
812 pub fn adaptive_predict_stream_info_with_context<T: IntStream>(
813 &mut self,
814 decision: usize,
815 precedence: usize,
816 input: &mut T,
817 outer_context: ContextId,
818 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
819 self.store.contexts.assert_valid(outer_context);
820 let marker = input.mark();
821 let index = input.index();
822 let mut workspace = std::mem::take(&mut self.workspace);
823 workspace.reset();
824 let result = self.adaptive_predict_stream_inner(
825 AdaptivePredictRequest {
826 decision,
827 precedence,
828 outer_context,
829 force_full_context_retry: true,
830 sll_probe_only: false,
831 },
832 input,
833 &mut workspace,
834 );
835 self.workspace = workspace;
836 input.seek(index);
837 input.release(marker);
838 result
839 }
840
841 pub fn adaptive_predict_with_precedence(
842 &mut self,
843 decision: usize,
844 precedence: usize,
845 lookahead: impl IntoIterator<Item = i32>,
846 ) -> Result<usize, ParserAtnSimulatorError> {
847 self.adaptive_predict_info_with_precedence(decision, precedence, lookahead)
848 .map(|prediction| prediction.alt)
849 }
850
851 pub fn adaptive_predict_info_with_precedence(
852 &mut self,
853 decision: usize,
854 precedence: usize,
855 lookahead: impl IntoIterator<Item = i32>,
856 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
857 let mut input = LookaheadIntStream::new(lookahead.into_iter().collect());
858 self.adaptive_predict_stream_info_with_precedence(decision, precedence, &mut input)
859 }
860
861 fn adaptive_predict_stream_inner<T: IntStream>(
862 &mut self,
863 request: AdaptivePredictRequest,
864 input: &mut T,
865 merge_cache: &mut PredictionWorkspace,
866 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
867 let AdaptivePredictRequest {
868 decision,
869 precedence,
870 outer_context,
871 force_full_context_retry,
872 sll_probe_only,
873 } = request;
874 self.deferred_accept_states
875 .retain(|(stored_decision, _)| *stored_decision != decision);
876 #[cfg(feature = "perf-counters")]
877 crate::perf::record_adaptive_call(decision, force_full_context_retry);
878 let Some(decision_state) = self.atn.decision_to_state().get(decision) else {
879 return Err(ParserAtnSimulatorError::UnknownDecision(decision));
880 };
881 let start_index = input.index();
882 let precedence = i32::try_from(precedence).unwrap_or(i32::MAX);
888 let mut state_number =
889 self.ensure_start_state(decision, decision_state, precedence, merge_cache)?;
890 let track_previous_good_alt = !force_full_context_retry && !sll_probe_only;
893 let mut previous_good_alt = None;
894 if let Some(prediction) = self.prediction_or_full_context(
895 input,
896 PredictionCheck {
897 decision,
898 decision_state,
899 state_number,
900 start_index,
901 precedence,
902 outer_context,
903 force_full_context_retry,
904 sll_probe_only,
905 },
906 merge_cache,
907 )? {
908 return Ok(prediction);
909 }
910 loop {
911 if track_previous_good_alt {
912 let finished = self
913 .store
914 .decision_to_dfa
915 .get(decision)
916 .map(|dfa| dfa.configs(state_number))
917 .and_then(|configs| self.previous_good_alt(configs));
918 if finished.is_some() {
919 previous_good_alt = finished;
920 }
921 }
922 let symbol = input.la(1);
923 let target = self
924 .store
925 .decision_to_dfa
926 .get(decision)
927 .and_then(|dfa| dfa.edge(state_number, symbol));
928 #[cfg(feature = "perf-counters")]
929 crate::perf::record_dfa_edge_lookup(target.is_some());
930 if let Some(target) = target {
931 state_number = target;
932 } else {
933 let configs = self
934 .store
935 .decision_to_dfa
936 .get(decision)
937 .map(|dfa| dfa.configs(state_number).clone())
938 .ok_or(ParserAtnSimulatorError::MissingDfaState(state_number))?;
939 let edge = DfaEdge {
940 decision,
941 source_state: state_number,
942 };
943 let target = match self.compute_target_state(
944 edge,
945 &configs,
946 symbol,
947 precedence,
948 merge_cache,
949 ) {
950 Ok(target) => target,
951 Err(ParserAtnSimulatorError::NoViableAlt { symbol, .. }) => {
952 if let Some(fallback) = previous_good_alt.as_ref() {
953 self.add_previous_good_alt_target(edge, symbol, fallback, merge_cache)
954 } else {
955 return Err(ParserAtnSimulatorError::NoViableAlt {
956 symbol,
957 index: input.index(),
958 });
959 }
960 }
961 Err(error) => return Err(error),
962 };
963 state_number = target;
964 }
965 if let Some(prediction) = self.prediction_or_full_context(
966 input,
967 PredictionCheck {
968 decision,
969 decision_state,
970 state_number,
971 start_index,
972 precedence,
973 outer_context,
974 force_full_context_retry,
975 sll_probe_only,
976 },
977 merge_cache,
978 )? {
979 let defer_unique = track_previous_good_alt
980 && previous_good_alt.is_some()
981 && !prediction.requires_full_context
982 && !self.prediction_reached_decision_entry_rule_stop(
983 DfaEdge {
984 decision,
985 source_state: state_number,
986 },
987 prediction.alt,
988 precedence,
989 symbol,
990 merge_cache,
991 );
992 if !defer_unique {
993 return Ok(prediction);
994 }
995 self.deferred_accept_states.insert((decision, state_number));
996 }
997 if symbol == TOKEN_EOF {
998 if let Some(configs) = self
1008 .store
1009 .decision_to_dfa
1010 .get(decision)
1011 .map(|dfa| dfa.configs(state_number).clone())
1012 && let Some(alt) = self.alt_that_finished_decision_entry_rule(&configs)
1013 {
1014 return Ok(ParserAtnPrediction {
1015 alt,
1016 requires_full_context: false,
1017 has_semantic_context: configs_have_semantic_context_for_alt(&configs, alt),
1018 diagnostic: None,
1019 });
1020 }
1021 return Err(ParserAtnSimulatorError::PredictionRequiresMoreLookahead);
1022 }
1023 input.consume();
1024 }
1025 }
1026
1027 fn prediction_or_full_context<T: IntStream>(
1028 &mut self,
1029 input: &mut T,
1030 check: PredictionCheck,
1031 merge_cache: &mut PredictionWorkspace,
1032 ) -> Result<Option<ParserAtnPrediction>, ParserAtnSimulatorError> {
1033 let PredictionCheck {
1034 decision,
1035 decision_state,
1036 state_number,
1037 start_index,
1038 precedence,
1039 outer_context,
1040 force_full_context_retry,
1041 sll_probe_only,
1042 } = check;
1043 if self.store.contexts.is_empty(outer_context)
1044 && let Some(prediction) =
1045 self.non_greedy_exit_prediction(decision, decision_state, state_number)
1046 {
1047 return Ok(Some(prediction));
1048 }
1049 let Some(info) = self.dfa_prediction_info(decision, state_number) else {
1050 return Ok(None);
1051 };
1052 let prediction = info.prediction;
1053 if sll_probe_only && prediction.requires_full_context {
1060 return Ok(Some(prediction));
1061 }
1062 if prediction.requires_full_context
1063 && (force_full_context_retry || !prediction.has_semantic_context)
1064 {
1065 #[cfg(feature = "perf-counters")]
1066 crate::perf::record_full_context_retry(decision);
1067 let sll_stop_index = input.index();
1068 input.seek(start_index);
1069 let memo_allowed = self.full_context_memo_allowed();
1070 let memo_key = FullContextMemoKey {
1071 decision,
1072 precedence,
1073 outer_context,
1074 first_symbol: 0,
1075 };
1076 if memo_allowed
1079 && let Some(full_context) = self.probe_full_context_memo(memo_key, input)
1080 {
1081 #[cfg(feature = "perf-counters")]
1082 crate::perf::record_full_context_memo_hit(decision);
1083 return Ok(Some(Self::full_context_retry_prediction(
1084 full_context,
1085 info.conflicting_alts,
1086 start_index,
1087 sll_stop_index,
1088 )));
1089 }
1090 let full_context = self.adaptive_predict_full_context(
1091 decision_state,
1092 input,
1093 precedence,
1094 outer_context,
1095 merge_cache,
1096 )?;
1097 if memo_allowed {
1098 self.record_full_context_memo(memo_key, start_index, input, &full_context);
1099 }
1100 return Ok(Some(Self::full_context_retry_prediction(
1101 full_context,
1102 info.conflicting_alts,
1103 start_index,
1104 sll_stop_index,
1105 )));
1106 }
1107 Ok(Some(prediction))
1108 }
1109
1110 fn full_context_retry_prediction(
1114 full_context: FullContextPrediction,
1115 sll_conflicting_alts: Vec<usize>,
1116 start_index: usize,
1117 sll_stop_index: usize,
1118 ) -> ParserAtnPrediction {
1119 let (kind, exact, conflicting_alts) = match full_context.resolution {
1120 FullContextResolution::Ambiguous { exact, ref alts } => (
1121 ParserAtnPredictionDiagnosticKind::Ambiguity,
1122 exact,
1123 alts.clone(),
1124 ),
1125 FullContextResolution::Unique => (
1129 ParserAtnPredictionDiagnosticKind::ContextSensitivity,
1130 false,
1131 sll_conflicting_alts,
1132 ),
1133 };
1134 let mut prediction = full_context.prediction;
1135 if conflicting_alts.len() > 1 {
1136 prediction.diagnostic = Some(ParserAtnPredictionDiagnostic {
1137 kind,
1138 start_index,
1139 sll_stop_index,
1140 ll_stop_index: full_context.stop_index,
1141 conflicting_alts,
1142 exact,
1143 });
1144 }
1145 prediction
1146 }
1147
1148 fn full_context_memo_allowed(&mut self) -> bool {
1165 if self.exact_ambig_detection {
1166 return false;
1167 }
1168 let atn = self.atn;
1169 *self
1170 .full_context_memo_gate
1171 .get_or_insert_with(|| !atn_has_predicate_transition(atn))
1172 }
1173
1174 fn probe_full_context_memo<T: IntStream>(
1185 &self,
1186 mut key: FullContextMemoKey,
1187 input: &mut T,
1188 ) -> Option<FullContextPrediction> {
1189 if self.full_context_memo.is_empty() {
1190 return None;
1191 }
1192 let start_index = input.index();
1193 key.first_symbol = input.la(1);
1194 let entries = self.full_context_memo.get(&key)?;
1195 'candidates: for entry in entries {
1205 for &expected in &entry.window_tail {
1206 input.consume();
1207 if input.la(1) != expected {
1208 input.seek(start_index);
1209 continue 'candidates;
1210 }
1211 }
1212 let mut replay = entry.prediction.clone();
1213 replay.stop_index = input.index();
1214 return Some(replay);
1215 }
1216 None
1217 }
1218
1219 fn record_full_context_memo<T: IntStream>(
1226 &mut self,
1227 mut key: FullContextMemoKey,
1228 start_index: usize,
1229 input: &mut T,
1230 full_context: &FullContextPrediction,
1231 ) {
1232 if self.full_context_memo_len >= FULL_CONTEXT_MEMO_MAX_ENTRIES {
1233 #[cfg(feature = "perf-counters")]
1234 crate::perf::record_full_context_memo_declined(key.decision);
1235 return;
1236 }
1237 let current = input.index();
1238 input.seek(start_index);
1239 key.first_symbol = input.la(1);
1240 let mut window_tail = Vec::new();
1241 while input.index() < full_context.stop_index
1242 && window_tail.len() < FULL_CONTEXT_MEMO_MAX_WINDOW
1243 {
1244 input.consume();
1245 window_tail.push(input.la(1));
1246 }
1247 let complete = input.index() >= full_context.stop_index;
1248 input.seek(current);
1249 if !complete {
1250 #[cfg(feature = "perf-counters")]
1251 crate::perf::record_full_context_memo_declined(key.decision);
1252 return;
1253 }
1254 self.full_context_memo
1255 .entry(key)
1256 .or_default()
1257 .push(FullContextMemoEntry {
1258 window_tail,
1259 prediction: full_context.clone(),
1260 });
1261 self.full_context_memo_len += 1;
1262 }
1263
1264 fn non_greedy_exit_prediction(
1265 &self,
1266 decision: usize,
1267 decision_state: usize,
1268 state_number: DfaStateId,
1269 ) -> Option<ParserAtnPrediction> {
1270 if !self
1271 .atn
1272 .state(decision_state)
1273 .is_some_and(AtnState::non_greedy)
1274 {
1275 return None;
1276 }
1277 let configs = &self
1278 .store
1279 .decision_to_dfa
1280 .get(decision)?
1281 .configs(state_number);
1282 let alt = configs
1283 .configs()
1284 .iter()
1285 .filter(|config| {
1286 self.atn
1287 .state(config.state)
1288 .is_some_and(AtnState::is_rule_stop)
1289 && self.store.contexts.has_empty_path(config.context)
1290 })
1291 .map(|config| config.alt)
1292 .min()?;
1293 Some(ParserAtnPrediction {
1294 alt,
1295 requires_full_context: false,
1296 has_semantic_context: configs_have_semantic_context_for_alt(configs, alt),
1297 diagnostic: None,
1298 })
1299 }
1300
1301 fn ensure_start_state(
1302 &mut self,
1303 decision: usize,
1304 decision_state: usize,
1305 precedence: i32,
1306 merge_cache: &mut PredictionWorkspace,
1307 ) -> Result<DfaStateId, ParserAtnSimulatorError> {
1308 if self.store.decision_to_dfa[decision].is_precedence_dfa() {
1309 let precedence_key = usize::try_from(precedence.max(0)).unwrap_or_default();
1310 if let Some(start) =
1311 self.store.decision_to_dfa[decision].precedence_start_state(precedence_key)
1312 {
1313 return Ok(start);
1314 }
1315 } else if let Some(start) = self.store.decision_to_dfa[decision].start_state() {
1316 return Ok(start);
1317 }
1318 let decision_state = self
1319 .atn
1320 .state(decision_state)
1321 .ok_or(ParserAtnSimulatorError::MissingAtnState(decision_state))?;
1322 let configs = self.compute_start_state(decision_state, precedence, merge_cache);
1323 let state_number = self.add_dfa_state(decision, DfaStateBuilder::new(configs));
1324 if self.store.decision_to_dfa[decision].is_precedence_dfa() {
1325 let precedence_key = usize::try_from(precedence.max(0)).unwrap_or_default();
1326 self.store.decision_to_dfa[decision]
1327 .set_precedence_start_state(precedence_key, state_number);
1328 } else {
1329 self.store.decision_to_dfa[decision].set_start_state(state_number);
1330 }
1331 Ok(state_number)
1332 }
1333
1334 fn add_dfa_state(&mut self, decision: usize, state: DfaStateBuilder) -> DfaStateId {
1335 self.store.decision_to_dfa[decision].add_state(state)
1336 }
1337
1338 fn compute_start_state(
1339 &mut self,
1340 decision_state: AtnState<'_>,
1341 precedence: i32,
1342 merge_cache: &mut PredictionWorkspace,
1343 ) -> AtnConfigSet {
1344 self.compute_start_state_with_context(
1345 decision_state,
1346 false,
1347 EMPTY_CONTEXT,
1348 precedence,
1349 merge_cache,
1350 )
1351 }
1352
1353 fn compute_start_state_with_context(
1354 &mut self,
1355 decision_state: AtnState<'_>,
1356 full_context: bool,
1357 initial_context: ContextId,
1358 precedence: i32,
1359 merge_cache: &mut PredictionWorkspace,
1360 ) -> AtnConfigSet {
1361 let mut configs = AtnConfigSet::new_full_context(full_context);
1362 let mut scratch = ClosureScratch::default();
1363 let params = ClosureParams {
1364 precedence,
1365 collect_predicates: true,
1366 treat_eof_as_epsilon: false,
1367 };
1368 for (index, transition) in decision_state.transitions().iter().enumerate() {
1369 let alt = index + 1;
1370 let config = AtnConfig::new(
1371 transition.target(),
1372 alt,
1373 initial_context,
1374 &self.store.contexts,
1375 );
1376 self.closure(config, &mut configs, merge_cache, &mut scratch, params);
1377 }
1378 configs
1379 }
1380
1381 fn adaptive_predict_full_context<T: IntStream>(
1382 &mut self,
1383 decision_state: usize,
1384 input: &mut T,
1385 precedence: i32,
1386 outer_context: ContextId,
1387 merge_cache: &mut PredictionWorkspace,
1388 ) -> Result<FullContextPrediction, ParserAtnSimulatorError> {
1389 let decision_state = self
1390 .atn
1391 .state(decision_state)
1392 .ok_or(ParserAtnSimulatorError::MissingAtnState(decision_state))?;
1393 let mut configs = self.compute_start_state_with_context(
1394 decision_state,
1395 true,
1396 outer_context,
1397 precedence,
1398 merge_cache,
1399 );
1400 loop {
1408 if let Some(alt) = configs.unique_alt() {
1409 return Ok(full_context_prediction(
1410 alt,
1411 &configs,
1412 input.index(),
1413 FullContextResolution::Unique,
1414 ));
1415 }
1416 let symbol = input.la(1);
1417 let reach = self.compute_reach_set(&configs, symbol, true, precedence, merge_cache);
1418 if reach.is_empty() {
1419 return Err(ParserAtnSimulatorError::NoViableAlt {
1420 symbol,
1421 index: input.index(),
1422 });
1423 }
1424 configs = reach;
1425 if let Some(alt) = configs.unique_alt() {
1426 return Ok(full_context_prediction(
1427 alt,
1428 &configs,
1429 input.index(),
1430 FullContextResolution::Unique,
1431 ));
1432 }
1433 if !configs.has_semantic_context() {
1434 let subsets = conflicting_alt_subsets(configs.configs());
1435 if self.exact_ambig_detection {
1436 let alts: Vec<usize> = configs.alts().into_iter().collect();
1437 if all_subsets_conflict(&subsets)
1441 && all_subsets_equal(&subsets)
1442 && let Some(&alt) = alts.first()
1443 {
1444 return Ok(full_context_prediction(
1445 alt,
1446 &configs,
1447 input.index(),
1448 FullContextResolution::Ambiguous { exact: true, alts },
1449 ));
1450 }
1451 } else if let Some(alt) = single_viable_alt(&subsets) {
1452 let alts: Vec<usize> = configs.alts().into_iter().collect();
1453 return Ok(full_context_prediction(
1454 alt,
1455 &configs,
1456 input.index(),
1457 FullContextResolution::Ambiguous { exact: false, alts },
1458 ));
1459 }
1460 }
1461 if symbol == TOKEN_EOF || self.configs_all_reached_rule_stop(&configs) {
1462 let alts: Vec<usize> = configs.alts().into_iter().collect();
1467 let alt = *alts
1468 .first()
1469 .ok_or(ParserAtnSimulatorError::PredictionRequiresMoreLookahead)?;
1470 let resolution = if alts.len() > 1 {
1471 FullContextResolution::Ambiguous {
1472 exact: self.exact_ambig_detection,
1473 alts,
1474 }
1475 } else {
1476 FullContextResolution::Unique
1477 };
1478 return Ok(full_context_prediction(
1479 alt,
1480 &configs,
1481 input.index(),
1482 resolution,
1483 ));
1484 }
1485 input.consume();
1486 }
1487 }
1488
1489 fn compute_target_state(
1490 &mut self,
1491 edge: DfaEdge,
1492 configs: &AtnConfigSet,
1493 symbol: i32,
1494 precedence: i32,
1495 merge_cache: &mut PredictionWorkspace,
1496 ) -> Result<DfaStateId, ParserAtnSimulatorError> {
1497 let mut reach = self.compute_reach_set(configs, symbol, false, precedence, merge_cache);
1498 if reach.is_empty() {
1499 if let Some(prediction) = self.alt_that_finished_decision_entry_rule(configs) {
1500 let mut dfa_state = DfaStateBuilder::new(configs.clone());
1501 dfa_state.mark_accept(prediction);
1502 dfa_state.set_has_semantic_context_for_alt(
1505 configs.has_semantic_context()
1506 && configs_have_semantic_context_for_alt(configs, prediction),
1507 );
1508 let target_state = self.add_dfa_state(edge.decision, dfa_state);
1509 self.store.decision_to_dfa[edge.decision].add_edge(
1510 edge.source_state,
1511 symbol,
1512 target_state,
1513 );
1514 return Ok(target_state);
1515 }
1516 return Err(ParserAtnSimulatorError::NoViableAlt { symbol, index: 0 });
1517 }
1518 let prediction = reach.unique_alt();
1519 let conflict_prediction = prediction.or_else(|| {
1520 if !has_sll_conflict_terminating_prediction(&reach, |state| {
1521 self.atn.state(state).is_some_and(AtnState::is_rule_stop)
1522 }) {
1523 return None;
1524 }
1525 reach
1526 .conflicting_alts()
1527 .into_iter()
1528 .next()
1529 .or_else(|| reach.alts().into_iter().next())
1530 });
1531 let requires_full_context = prediction.is_none() && conflict_prediction.is_some();
1532 #[cfg(feature = "perf-counters")]
1533 if requires_full_context {
1534 crate::perf::record_sll_conflict(edge.decision);
1535 }
1536 let conflicting_alts = if requires_full_context {
1537 let alts = reach.conflicting_alts();
1538 if alts.is_empty() { reach.alts() } else { alts }
1539 .into_iter()
1540 .collect()
1541 } else {
1542 Vec::new()
1543 };
1544 let mut dfa_state = DfaStateBuilder::new(reach);
1545 if let Some(prediction) = conflict_prediction {
1546 dfa_state.mark_accept(prediction);
1547 dfa_state.set_requires_full_context(requires_full_context);
1548 dfa_state.set_conflicting_alts(conflicting_alts);
1549 dfa_state.set_has_semantic_context_for_alt(
1552 dfa_state.configs.has_semantic_context()
1553 && configs_have_semantic_context_for_alt(&dfa_state.configs, prediction),
1554 );
1555 }
1556 let target_state = self.add_dfa_state(edge.decision, dfa_state);
1557 self.store.decision_to_dfa[edge.decision].add_edge(edge.source_state, symbol, target_state);
1558 Ok(target_state)
1559 }
1560
1561 fn compute_reach_set(
1562 &mut self,
1563 configs: &AtnConfigSet,
1564 symbol: i32,
1565 full_context: bool,
1566 precedence: i32,
1567 merge_cache: &mut PredictionWorkspace,
1568 ) -> AtnConfigSet {
1569 let mut intermediate = AtnConfigSet::new_full_context(full_context);
1570 let mut skipped_stop_states = Vec::new();
1571 let max_token_type = self.atn.max_token_type();
1572 for config in configs.configs() {
1573 let Some(state) = self.atn.state(config.state) else {
1574 continue;
1575 };
1576 if state.is_rule_stop() {
1577 if full_context || symbol == TOKEN_EOF {
1578 skipped_stop_states.push(config.clone());
1579 }
1580 continue;
1581 }
1582 for transition in &state.transitions() {
1583 if transition.matches(symbol, 1, max_token_type) {
1584 let target =
1585 config.moved_to(transition.target(), config.context, &self.store.contexts);
1586 intermediate.add(target, &mut self.store.contexts, merge_cache);
1587 }
1588 }
1589 }
1590 let mut reach = if skipped_stop_states.is_empty() && symbol != TOKEN_EOF {
1591 if intermediate.len() == 1 || intermediate.unique_alt().is_some() {
1592 intermediate
1593 } else {
1594 self.close_intermediate_reach_set(
1595 intermediate,
1596 full_context,
1597 precedence,
1598 symbol,
1599 merge_cache,
1600 )
1601 }
1602 } else {
1603 self.close_intermediate_reach_set(
1604 intermediate,
1605 full_context,
1606 precedence,
1607 symbol,
1608 merge_cache,
1609 )
1610 };
1611 if symbol == TOKEN_EOF {
1612 reach = self.rule_stop_configs(reach, merge_cache);
1613 }
1614 if !full_context || !self.configs_contain_rule_stop(&reach) {
1615 for config in skipped_stop_states {
1616 reach.add(config, &mut self.store.contexts, merge_cache);
1617 }
1618 }
1619 #[cfg(feature = "perf-counters")]
1620 crate::perf::record_reach_set(full_context, configs.len(), reach.len());
1621 reach
1622 }
1623
1624 fn close_intermediate_reach_set(
1625 &mut self,
1626 intermediate: AtnConfigSet,
1627 full_context: bool,
1628 precedence: i32,
1629 symbol: i32,
1630 merge_cache: &mut PredictionWorkspace,
1631 ) -> AtnConfigSet {
1632 let mut reach = AtnConfigSet::new_full_context(full_context);
1633 let mut scratch = ClosureScratch::default();
1634 let params = ClosureParams {
1635 precedence,
1636 collect_predicates: false,
1637 treat_eof_as_epsilon: symbol == TOKEN_EOF,
1638 };
1639 for config in intermediate.into_configs() {
1642 self.closure(config, &mut reach, merge_cache, &mut scratch, params);
1643 }
1644 reach
1645 }
1646
1647 fn alt_that_finished_decision_entry_rule(&self, configs: &AtnConfigSet) -> Option<usize> {
1648 configs
1649 .configs()
1650 .iter()
1651 .filter(|config| self.config_finished_decision_entry_rule(config))
1652 .map(|config| config.alt)
1653 .min()
1654 }
1655
1656 fn previous_good_alt(&self, configs: &AtnConfigSet) -> Option<PreviousGoodAlt> {
1657 let alt = self.alt_that_finished_decision_entry_rule(configs)?;
1658 let configs = configs
1659 .configs()
1660 .iter()
1661 .filter(|config| config.alt == alt && self.config_finished_decision_entry_rule(config))
1662 .cloned()
1663 .collect();
1664 Some(PreviousGoodAlt { alt, configs })
1665 }
1666
1667 fn config_finished_decision_entry_rule(&self, config: &AtnConfig) -> bool {
1668 config.reaches_into_outer_context > 0
1669 || self
1670 .atn
1671 .state(config.state)
1672 .is_some_and(AtnState::is_rule_stop)
1673 && self.store.contexts.has_empty_path(config.context)
1674 }
1675
1676 fn add_previous_good_alt_target(
1677 &mut self,
1678 edge: DfaEdge,
1679 symbol: i32,
1680 fallback: &PreviousGoodAlt,
1681 merge_cache: &mut PredictionWorkspace,
1682 ) -> DfaStateId {
1683 let mut configs = AtnConfigSet::new();
1684 for config in &fallback.configs {
1685 configs.add(config.clone(), &mut self.store.contexts, merge_cache);
1686 }
1687 let has_semantic_context = configs_have_semantic_context_for_alt(&configs, fallback.alt);
1688 let mut state = DfaStateBuilder::new(configs);
1689 state.mark_accept(fallback.alt);
1690 state.set_has_semantic_context_for_alt(has_semantic_context);
1691 let target = self.add_dfa_state(edge.decision, state);
1692 self.store.decision_to_dfa[edge.decision].add_edge(edge.source_state, symbol, target);
1693 target
1694 }
1695
1696 fn prediction_reached_decision_entry_rule_stop(
1697 &mut self,
1698 edge: DfaEdge,
1699 alt: usize,
1700 precedence: i32,
1701 symbol: i32,
1702 merge_cache: &mut PredictionWorkspace,
1703 ) -> bool {
1704 let configs = self.store.decision_to_dfa[edge.decision]
1705 .configs(edge.source_state)
1706 .clone();
1707 if self.alt_that_finished_decision_entry_rule(&configs) == Some(alt) {
1708 return true;
1709 }
1710 let closed =
1711 self.close_intermediate_reach_set(configs, false, precedence, symbol, merge_cache);
1712 self.alt_that_finished_decision_entry_rule(&closed) == Some(alt)
1713 }
1714
1715 fn rule_stop_configs(
1716 &mut self,
1717 configs: AtnConfigSet,
1718 merge_cache: &mut PredictionWorkspace,
1719 ) -> AtnConfigSet {
1720 if configs.configs().iter().all(|config| {
1721 self.atn
1722 .state(config.state)
1723 .is_some_and(AtnState::is_rule_stop)
1724 }) {
1725 return configs;
1726 }
1727 let mut result = AtnConfigSet::new_full_context(configs.full_context());
1728 for config in configs.configs().iter().filter(|config| {
1729 self.atn
1730 .state(config.state)
1731 .is_some_and(AtnState::is_rule_stop)
1732 }) {
1733 result.add(config.clone(), &mut self.store.contexts, merge_cache);
1734 }
1735 result
1736 }
1737
1738 fn configs_all_reached_rule_stop(&self, configs: &AtnConfigSet) -> bool {
1739 configs.configs().iter().all(|config| {
1740 self.atn
1741 .state(config.state)
1742 .is_some_and(AtnState::is_rule_stop)
1743 })
1744 }
1745
1746 fn configs_contain_rule_stop(&self, configs: &AtnConfigSet) -> bool {
1747 configs.configs().iter().any(|config| {
1748 self.atn
1749 .state(config.state)
1750 .is_some_and(AtnState::is_rule_stop)
1751 })
1752 }
1753
1754 fn closure(
1755 &mut self,
1756 config: AtnConfig,
1757 configs: &mut AtnConfigSet,
1758 merge_cache: &mut PredictionWorkspace,
1759 scratch: &mut ClosureScratch,
1760 params: ClosureParams,
1761 ) {
1762 let ClosureParams {
1763 precedence,
1764 collect_predicates,
1765 treat_eof_as_epsilon,
1766 } = params;
1767 let max_token_type = self.atn.max_token_type();
1768 scratch.stack.clear();
1769 scratch.visited.clear();
1770 scratch.stack.push((config, collect_predicates));
1771 while let Some((config, collect_predicates)) = scratch.stack.pop() {
1772 if !scratch.visited.insert(ClosureConfigKey::from(&config)) {
1773 continue;
1774 }
1775 let Some(state) = self.atn.state(config.state) else {
1776 continue;
1777 };
1778 let at_rule_stop = state.is_rule_stop();
1779 if at_rule_stop
1780 && self.closure_at_rule_stop(
1781 config.clone(),
1782 collect_predicates,
1783 configs,
1784 merge_cache,
1785 &mut scratch.stack,
1786 )
1787 {
1788 continue;
1789 }
1790 let epsilon_only = state.epsilon_only();
1791 if !epsilon_only {
1792 configs.add(config.clone(), &mut self.store.contexts, merge_cache);
1793 }
1794 for (index, transition) in state.transitions().iter().enumerate() {
1795 if index == 0
1796 && can_drop_left_recursive_loop_entry_edge(
1797 self.atn,
1798 state,
1799 &self.store.contexts,
1800 config.context,
1801 )
1802 {
1803 continue;
1804 }
1805 let transition_kind = transition.kind();
1806 if matches!(
1807 transition_kind,
1808 ParserTransitionKind::Epsilon
1809 | ParserTransitionKind::Rule
1810 | ParserTransitionKind::Predicate
1811 | ParserTransitionKind::Action
1812 | ParserTransitionKind::Precedence
1813 ) {
1814 if let Some(mut target) = self.epsilon_target_config(
1815 &config,
1816 transition,
1817 transition_kind,
1818 precedence,
1819 collect_predicates,
1820 configs.full_context(),
1821 ) {
1822 if at_rule_stop {
1823 target.reaches_into_outer_context =
1824 target.reaches_into_outer_context.saturating_add(1);
1825 }
1826 let target_collect_predicates =
1830 collect_predicates && transition_kind != ParserTransitionKind::Action;
1831 scratch.stack.push((target, target_collect_predicates));
1832 }
1833 } else if treat_eof_as_epsilon
1834 && transition.matches_kind(transition_kind, TOKEN_EOF, 1, max_token_type)
1835 {
1836 scratch.stack.push((
1837 config.moved_to(transition.target(), config.context, &self.store.contexts),
1838 collect_predicates,
1839 ));
1840 }
1841 }
1842 }
1843 #[cfg(feature = "perf-counters")]
1844 crate::perf::record_closure(scratch.visited.len());
1845 }
1846
1847 fn closure_at_rule_stop(
1848 &mut self,
1849 config: AtnConfig,
1850 collect_predicates: bool,
1851 configs: &mut AtnConfigSet,
1852 merge_cache: &mut PredictionWorkspace,
1853 stack: &mut Vec<(AtnConfig, bool)>,
1854 ) -> bool {
1855 if self.store.contexts.is_empty(config.context) {
1856 if configs.full_context() {
1857 configs.add(config, &mut self.store.contexts, merge_cache);
1858 return true;
1859 }
1860 return false;
1861 }
1862 let mut handled_all_paths = true;
1863 for index in 0..self.store.contexts.len(config.context) {
1864 let Some(return_state) = self.store.contexts.return_state(config.context, index) else {
1865 continue;
1866 };
1867 if return_state == EMPTY_RETURN_STATE {
1868 if configs.full_context() {
1869 let mut empty_context_config = config.clone();
1870 empty_context_config.set_context(EMPTY_CONTEXT, &self.store.contexts);
1871 configs.add(empty_context_config, &mut self.store.contexts, merge_cache);
1872 } else {
1873 handled_all_paths = false;
1874 }
1875 continue;
1876 }
1877 let parent = self
1878 .store
1879 .contexts
1880 .parent(config.context, index)
1881 .unwrap_or(EMPTY_CONTEXT);
1882 let next = config.moved_to(return_state, parent, &self.store.contexts);
1883 stack.push((next, collect_predicates));
1884 }
1885 handled_all_paths
1886 }
1887
1888 #[allow(clippy::too_many_arguments)]
1889 fn epsilon_target_config(
1890 &mut self,
1891 config: &AtnConfig,
1892 transition: ParserTransition<'_>,
1893 transition_kind: ParserTransitionKind,
1894 precedence: i32,
1895 collect_predicates: bool,
1896 full_context: bool,
1897 ) -> Option<AtnConfig> {
1898 let semantic_context = match transition_kind {
1899 ParserTransitionKind::Predicate if collect_predicates => SemanticContext::and(
1900 config.semantic_context.clone(),
1901 SemanticContext::Predicate {
1902 rule_index: transition.arg0() as usize,
1903 pred_index: transition.arg1() as usize,
1904 context_dependent: transition.arg2() != 0,
1905 },
1906 ),
1907 ParserTransitionKind::Precedence
1908 if collect_predicates
1909 && i32::from_le_bytes(transition.arg0().to_le_bytes()) < precedence =>
1910 {
1911 return None;
1912 }
1913 ParserTransitionKind::Precedence if collect_predicates && !full_context => {
1914 SemanticContext::and(
1915 config.semantic_context.clone(),
1916 SemanticContext::Precedence {
1917 precedence: i32::from_le_bytes(transition.arg0().to_le_bytes()),
1918 },
1919 )
1920 }
1921 _ => config.semantic_context.clone(),
1922 };
1923 let context = if transition_kind == ParserTransitionKind::Rule {
1924 self.store
1925 .contexts
1926 .singleton(config.context, transition.arg1() as usize)
1927 } else {
1928 config.context
1929 };
1930 let mut target = config.moved_to(transition.target(), context, &self.store.contexts);
1931 target.semantic_context = semantic_context;
1932 Some(target)
1933 }
1934
1935 fn dfa_prediction_info(
1936 &self,
1937 decision: usize,
1938 state_number: DfaStateId,
1939 ) -> Option<DfaPredictionInfo> {
1940 let dfa = self.store.decision_to_dfa.get(decision)?;
1941 let state = dfa.state(state_number)?;
1942 let alt = state.prediction()?;
1943 let requires_full_context = state.requires_full_context();
1944 let conflicting_alts = if requires_full_context {
1945 let stored = dfa.conflicting_alts(state_number);
1946 if stored.is_empty() {
1947 dfa.configs(state_number).alts().into_iter().collect()
1948 } else {
1949 stored.to_vec()
1950 }
1951 } else {
1952 Vec::new()
1953 };
1954 Some(DfaPredictionInfo {
1955 prediction: ParserAtnPrediction {
1956 alt,
1957 requires_full_context,
1958 has_semantic_context: state.has_semantic_context(),
1961 diagnostic: None,
1962 },
1963 conflicting_alts,
1964 })
1965 }
1966}
1967
1968pub(crate) fn can_drop_left_recursive_loop_entry_edge(
1971 atn: &Atn,
1972 state: AtnState<'_>,
1973 contexts: &ContextArena,
1974 context: ContextId,
1975) -> bool {
1976 if state.kind() != AtnStateKind::StarLoopEntry
1977 || !state.precedence_rule_decision()
1978 || contexts.is_empty(context)
1979 || contexts.has_empty_path(context)
1980 {
1981 return false;
1982 }
1983 let Some(rule_index) = state.rule_index() else {
1984 return false;
1985 };
1986 for index in 0..contexts.len(context) {
1987 let Some(return_state_number) = contexts.return_state(context, index) else {
1988 return false;
1989 };
1990 let Some(return_state) = atn.state(return_state_number) else {
1991 return false;
1992 };
1993 if return_state.rule_index() != Some(rule_index) {
1994 return false;
1995 }
1996 }
1997 let Some(block_end_state_number) = state
1998 .transitions()
1999 .first()
2000 .and_then(|transition| atn.state(transition.target()))
2001 .and_then(AtnState::end_state)
2002 else {
2003 return false;
2004 };
2005 for index in 0..contexts.len(context) {
2006 let return_state_number = contexts
2007 .return_state(context, index)
2008 .expect("return state checked above");
2009 let return_state = atn
2010 .state(return_state_number)
2011 .expect("return state checked above");
2012 if return_state.state_number() == block_end_state_number {
2013 continue;
2014 }
2015 if return_state.transitions().len() != 1
2016 || !return_state
2017 .transitions()
2018 .first()
2019 .is_some_and(ParserTransition::is_epsilon)
2020 {
2021 return false;
2022 }
2023 let return_target = return_state
2024 .transitions()
2025 .first()
2026 .expect("single transition checked above")
2027 .target();
2028 if return_state.kind() == AtnStateKind::BlockEnd && return_target == state.state_number() {
2029 continue;
2030 }
2031 if return_target == block_end_state_number {
2032 continue;
2033 }
2034 let Some(return_target_state) = atn.state(return_target) else {
2035 return false;
2036 };
2037 if return_target_state.kind() == AtnStateKind::BlockEnd
2038 && return_target_state.transitions().len() == 1
2039 && return_target_state
2040 .transitions()
2041 .first()
2042 .is_some_and(ParserTransition::is_epsilon)
2043 && return_target_state
2044 .transitions()
2045 .first()
2046 .is_some_and(|transition| transition.target() == state.state_number())
2047 {
2048 continue;
2049 }
2050 return false;
2051 }
2052 true
2053}
2054
2055fn configs_have_semantic_context_for_alt(configs: &AtnConfigSet, alt: usize) -> bool {
2056 configs
2057 .configs()
2058 .iter()
2059 .any(|config| config.alt == alt && !config.semantic_context.is_none())
2060}
2061
2062#[derive(Clone, Debug, Eq, PartialEq)]
2063pub enum ParserAtnSimulatorError {
2064 MissingAtnState(usize),
2065 MissingDfaState(DfaStateId),
2066 NoViableAlt { symbol: i32, index: usize },
2067 PredictionRequiresMoreLookahead,
2068 UnknownDecision(usize),
2069}
2070
2071fn dfa_state_display(state: ParserDfaStateView<'_>, deferred: bool) -> String {
2073 let mut out = String::new();
2074 let is_accept = state.is_accept_state() && !deferred;
2075 if is_accept {
2076 out.push(':');
2077 }
2078 out.push('s');
2079 out.push_str(&state.id().index().to_string());
2080 if state.requires_full_context() {
2081 out.push('^');
2082 }
2083 if is_accept {
2084 out.push_str("=>");
2085 out.push_str(
2086 &state
2087 .prediction()
2088 .map(|prediction| prediction.to_string())
2089 .unwrap_or_default(),
2090 );
2091 }
2092 out
2093}
2094
2095#[cfg(test)]
2096#[allow(clippy::disallowed_methods)] mod tests {
2098 use super::*;
2099 use crate::atn::AtnStateKind;
2100
2101 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
2102 builder.finish().expect("valid packed parser ATN")
2103 }
2104
2105 #[test]
2106 fn union_decision_dfa_preserves_disjoint_coverage() {
2107 fn configs(
2108 atn_state: usize,
2109 arena: &mut ContextArena,
2110 workspace: &mut PredictionWorkspace,
2111 ) -> AtnConfigSet {
2112 let mut set = AtnConfigSet::new();
2113 set.add(
2114 AtnConfig::new(atn_state, 1, EMPTY_CONTEXT, arena),
2115 arena,
2116 workspace,
2117 );
2118 set
2119 }
2120 fn state(
2121 atn_state: usize,
2122 arena: &mut ContextArena,
2123 workspace: &mut PredictionWorkspace,
2124 ) -> DfaStateBuilder {
2125 DfaStateBuilder::new(configs(atn_state, arena, workspace))
2126 }
2127 let mut arena = ContextArena::new();
2128 let mut workspace = PredictionWorkspace::default();
2129
2130 let mut shared = ParserDfa::with_max_token_type(0, 0, 8);
2134 let shared_root = shared.add_state(state(10, &mut arena, &mut workspace));
2135 let shared_a = shared.add_state(state(11, &mut arena, &mut workspace));
2136 shared.add_edge(shared_root, 1, shared_a);
2137 shared.set_start_state(shared_root);
2138
2139 let mut local = ParserDfa::with_max_token_type(0, 0, 8);
2140 let local_b = local.add_state(state(12, &mut arena, &mut workspace));
2141 let local_root = local.add_state(state(10, &mut arena, &mut workspace));
2142 local.add_edge(local_root, 2, local_b);
2143 local.set_precedence_start_state(3, local_root);
2144
2145 union_decision_dfa(&mut shared, local);
2146
2147 assert_eq!(shared.edge(shared_root, 1), Some(shared_a));
2150 let merged_b = shared
2151 .state_id_for_configs(&configs(12, &mut arena, &mut workspace))
2152 .expect("local-only state adopted");
2153 assert_eq!(shared.edge(shared_root, 2), Some(merged_b));
2154 assert_eq!(shared.states().len(), 3);
2155 assert_eq!(shared.start_state(), Some(shared_root));
2157 assert_eq!(shared.precedence_start_state(3), Some(shared_root));
2158 }
2159
2160 #[test]
2161 fn union_prediction_stores_remaps_context_ids_before_dfa_union() {
2162 let atn = two_token_decision_atn();
2163 let mut shared = PredictionStore::new(&atn);
2164 let mut local = PredictionStore::new(&atn);
2165 let mut workspace = PredictionWorkspace::default();
2166
2167 let distracting = shared.contexts.singleton(EMPTY_CONTEXT, 99);
2168 let local_context = local.contexts.singleton(EMPTY_CONTEXT, 7);
2169 assert_eq!(distracting, local_context, "both stores allocate ID 1");
2170
2171 let mut configs = AtnConfigSet::new();
2172 configs.add(
2173 AtnConfig::new(42, 1, local_context, &local.contexts),
2174 &mut local.contexts,
2175 &mut workspace,
2176 );
2177 local.decision_to_dfa[0].add_state(DfaStateBuilder::new(configs));
2178
2179 union_prediction_stores(&mut shared, local, &mut workspace);
2180
2181 let imported = shared.decision_to_dfa[0]
2182 .states()
2183 .flat_map(|state| shared.decision_to_dfa[0].configs(state.id()).configs())
2184 .find(|config| config.state == 42)
2185 .expect("local DFA config imported");
2186 assert_ne!(imported.context, local_context);
2187 assert_eq!(shared.contexts.return_state(imported.context, 0), Some(7));
2188 imported.assert_store(&shared.contexts);
2189 }
2190
2191 #[test]
2192 fn outer_context_cache_invalidates_with_rule_context_version() {
2193 let atn = two_token_decision_atn();
2194 let mut simulator = ParserAtnSimulator::new(&atn);
2195
2196 let first = simulator.intern_prediction_context(1, [7]);
2197 let cached = simulator.intern_prediction_context(1, [99]);
2198 let refreshed = simulator.intern_prediction_context(2, [99]);
2199
2200 assert_eq!(cached, first);
2201 assert_ne!(refreshed, first);
2202 assert_eq!(
2203 simulator.store.contexts.return_state(refreshed, 0),
2204 Some(99)
2205 );
2206 let stats = simulator.prediction_context_stats();
2207 assert_eq!(stats.outer_context_cache_hits, 1);
2208 assert_eq!(stats.outer_context_cache_misses, 2);
2209 }
2210
2211 #[test]
2212 fn outer_context_cache_is_simulator_local() {
2213 let atn = two_token_decision_atn();
2214 let mut first = ParserAtnSimulator::new(&atn);
2215 let mut second = ParserAtnSimulator::new(&atn);
2216
2217 let first_context = first.intern_prediction_context(1, [7]);
2218 let second_context = second.intern_prediction_context(1, [99]);
2219
2220 assert_eq!(first.store.contexts.return_state(first_context, 0), Some(7));
2221 assert_eq!(
2222 second.store.contexts.return_state(second_context, 0),
2223 Some(99)
2224 );
2225 }
2226
2227 #[test]
2228 fn adaptive_predict_reuses_dense_dfa_edges() {
2229 let atn = two_token_decision_atn();
2230 let mut simulator = ParserAtnSimulator::new(&atn);
2231
2232 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
2233 assert_eq!(simulator.adaptive_predict(0, [1, 3]), Ok(2));
2234
2235 let dfa = &simulator.decision_dfas()[0];
2236 let start = dfa.start_state().expect("start state");
2237 let after_first = dfa.state(start).and_then(|state| state.edge(1));
2238 assert!(after_first.is_some());
2239 }
2240
2241 #[test]
2242 fn shared_simulator_reuses_learned_dfa_states() {
2243 let atn = Box::leak(Box::new(two_token_decision_atn()));
2244 let learned_states = {
2245 let mut simulator = ParserAtnSimulator::new_shared(atn);
2246 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
2247 simulator.decision_dfas()[0].states().len()
2248 };
2249
2250 let simulator = ParserAtnSimulator::new_shared(atn);
2251 assert_eq!(simulator.decision_dfas()[0].states().len(), learned_states);
2252 }
2253
2254 #[test]
2255 fn clear_shared_dfa_drops_learned_states() {
2256 let atn = Box::leak(Box::new(two_token_decision_atn()));
2257 {
2258 let mut simulator = ParserAtnSimulator::new_shared(atn);
2259 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
2260 assert!(!simulator.decision_dfas()[0].is_empty());
2261 }
2262
2263 ParserAtnSimulator::clear_shared_dfa(atn);
2264
2265 let simulator = ParserAtnSimulator::new_shared(atn);
2266 assert!(simulator.decision_dfas()[0].is_empty());
2267 }
2268
2269 #[test]
2270 fn clear_dfa_rejects_stale_overlapping_simulator_publication() {
2271 let atn = Box::leak(Box::new(two_token_decision_atn()));
2272 let mut current = ParserAtnSimulator::new_shared(atn);
2273 let mut stale = ParserAtnSimulator::new_shared(atn);
2274 assert_eq!(stale.adaptive_predict(0, [1, 2]), Ok(1));
2275 assert!(!stale.decision_dfas()[0].is_empty());
2276
2277 current.clear_dfa();
2278 drop(stale);
2279 drop(current);
2280
2281 let simulator = ParserAtnSimulator::new_shared(atn);
2282 assert!(simulator.decision_dfas()[0].is_empty());
2283 }
2284
2285 #[test]
2286 fn adaptive_predict_reports_no_viable_alt() {
2287 let atn = two_token_decision_atn();
2288 let mut simulator = ParserAtnSimulator::new(&atn);
2289
2290 assert_eq!(
2291 simulator.adaptive_predict(0, [4]),
2292 Err(ParserAtnSimulatorError::NoViableAlt {
2293 symbol: 4,
2294 index: 0
2295 })
2296 );
2297 }
2298
2299 #[test]
2300 fn adaptive_predict_marks_sll_conflict_for_full_context() {
2301 let atn = ambiguous_single_token_decision_atn();
2302 let mut simulator = ParserAtnSimulator::new(&atn);
2303
2304 assert_eq!(simulator.adaptive_predict(0, [1]), Ok(1));
2305 let prediction = simulator
2306 .adaptive_predict_info_with_precedence(0, 0, [1])
2307 .expect("prediction");
2308 insta::assert_debug_snapshot!(
2309 "adaptive_predict_marks_sll_conflict_for_full_context",
2310 prediction
2311 );
2312
2313 let dfa = &simulator.decision_dfas()[0];
2314 let start = dfa.start_state().expect("start state");
2315 let target = dfa
2316 .state(start)
2317 .and_then(|state| state.edge(1))
2318 .expect("edge for token 1");
2319 let state = dfa.state(target).expect("target state");
2320 assert!(state.is_accept_state());
2321 assert!(state.requires_full_context());
2322 assert_eq!(state.prediction(), Some(1));
2323 }
2324
2325 #[test]
2326 fn adaptive_predict_keeps_rule_stop_configs_at_eof() {
2327 let atn = optional_token_decision_atn();
2328 let mut simulator = ParserAtnSimulator::new(&atn);
2329
2330 assert_eq!(simulator.adaptive_predict(0, [TOKEN_EOF]), Ok(2));
2331 }
2332
2333 #[test]
2334 fn adaptive_predict_treats_repeated_eof_as_epsilon_after_first_eof() {
2335 let atn = multiple_eof_decision_atn();
2336 let mut simulator = ParserAtnSimulator::new(&atn);
2337
2338 assert_eq!(simulator.adaptive_predict(0, [1, TOKEN_EOF]), Ok(1));
2339 }
2340
2341 #[test]
2342 fn adaptive_predict_uses_finished_entry_rule_alt_on_error_edge() {
2343 let atn = prefix_alt_decision_atn();
2344 let mut simulator = ParserAtnSimulator::new(&atn);
2345
2346 assert_eq!(simulator.adaptive_predict(0, [1, 3]), Ok(1));
2347 }
2348
2349 #[test]
2350 fn adaptive_predict_keeps_prefix_alt_until_longer_alt_finishes() {
2351 let atn = three_token_prefix_alt_decision_atn();
2352 let mut simulator = ParserAtnSimulator::new(&atn);
2353
2354 assert_eq!(simulator.adaptive_predict(0, [1, 2, TOKEN_EOF]), Ok(1));
2355 assert_eq!(simulator.adaptive_predict(0, [1, 2, 1, TOKEN_EOF]), Ok(2));
2356 }
2357
2358 #[test]
2359 fn sll_probe_keeps_unique_alt_early_termination() {
2360 let atn = three_token_prefix_alt_decision_atn();
2361 let mut simulator = ParserAtnSimulator::new(&atn);
2362 let mut input = VecIntStream::new(vec![1, 2, TOKEN_EOF]);
2363
2364 let prediction = simulator
2365 .adaptive_predict_stream_info_sll_probe(0, 0, &mut input)
2366 .expect("SLL prediction should succeed");
2367
2368 assert_eq!(prediction.alt, 2);
2369 }
2370
2371 #[test]
2372 fn adaptive_predict_uses_precedence_dfa_start_states() {
2373 let atn = two_token_decision_atn_with_precedence(true);
2374 let mut simulator = ParserAtnSimulator::new(&atn);
2375
2376 assert_eq!(
2377 simulator.adaptive_predict_with_precedence(0, 3, [1, 2]),
2378 Ok(1)
2379 );
2380 assert_eq!(
2381 simulator.adaptive_predict_with_precedence(0, 7, [1, 3]),
2382 Ok(2)
2383 );
2384
2385 let dfa = &simulator.decision_dfas()[0];
2386 assert!(dfa.is_precedence_dfa());
2387 assert!(dfa.precedence_start_state(3).is_some());
2388 assert!(dfa.precedence_start_state(7).is_some());
2389 }
2390
2391 #[test]
2392 fn adaptive_predict_stream_restores_input_position() {
2393 let atn = two_token_decision_atn();
2394 let mut simulator = ParserAtnSimulator::new(&atn);
2395 let mut input = VecIntStream::new(vec![1, 3, TOKEN_EOF]);
2396
2397 assert_eq!(simulator.adaptive_predict_stream(0, &mut input), Ok(2));
2398 assert_eq!(input.index(), 0);
2399 assert_eq!(input.la(1), 1);
2400 }
2401
2402 #[test]
2403 fn adaptive_predict_stream_retries_full_context_conflict() {
2404 let atn = ambiguous_single_token_decision_atn();
2405 let mut simulator = ParserAtnSimulator::new(&atn);
2406 let mut input = VecIntStream::new(vec![1, TOKEN_EOF]);
2407
2408 let prediction = simulator
2409 .adaptive_predict_stream_info_with_precedence(0, 0, &mut input)
2410 .expect("prediction");
2411
2412 insta::assert_debug_snapshot!(
2413 "adaptive_predict_stream_retries_full_context_conflict",
2414 prediction
2415 );
2416 assert_eq!(input.index(), 0);
2417 }
2418
2419 #[test]
2420 fn full_context_memo_replays_identical_retries() {
2421 let atn = ambiguous_single_token_decision_atn();
2422 let mut simulator = ParserAtnSimulator::new(&atn);
2423
2424 let mut input = VecIntStream::new(vec![1, TOKEN_EOF]);
2427 let fresh = simulator
2428 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
2429 .expect("fresh prediction");
2430 assert_eq!(simulator.full_context_memo_len, 1);
2431 assert_eq!(input.index(), 0, "cursor restored after prediction");
2432
2433 let replayed = simulator
2437 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
2438 .expect("memoized prediction");
2439 assert_eq!(replayed, fresh);
2440 assert_eq!(simulator.full_context_memo_len, 1, "no duplicate entry");
2441 assert_eq!(input.index(), 0);
2442
2443 let mut other_input = VecIntStream::new(vec![2, TOKEN_EOF]);
2446 let other = simulator.adaptive_predict_stream_info_with_context(
2447 0,
2448 0,
2449 &mut other_input,
2450 EMPTY_CONTEXT,
2451 );
2452 assert!(other.is_err(), "different window must not replay");
2455
2456 let context = simulator.store.contexts.singleton(EMPTY_CONTEXT, 6);
2458 let mut input = VecIntStream::new(vec![1, TOKEN_EOF]);
2459 let _ = simulator
2460 .adaptive_predict_stream_info_with_context(0, 0, &mut input, context)
2461 .expect("prediction under a different context");
2462 assert_eq!(
2463 simulator.full_context_memo_len, 2,
2464 "distinct context records its own entry"
2465 );
2466 }
2467
2468 #[test]
2469 fn full_context_memo_walks_multi_token_windows() {
2470 let atn = ambiguous_three_token_decision_atn();
2471 let mut simulator = ParserAtnSimulator::new(&atn);
2472
2473 let mut input = VecIntStream::new(vec![1, 2, 3, TOKEN_EOF]);
2476 let fresh = simulator
2477 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
2478 .expect("fresh prediction");
2479 assert_eq!(simulator.full_context_memo_len, 1);
2480 let recorded_window_len = simulator
2481 .full_context_memo
2482 .values()
2483 .next()
2484 .and_then(|entries| entries.first())
2485 .map(|entry| entry.window_tail.len())
2486 .expect("one recorded entry");
2487 assert!(
2488 recorded_window_len >= 1,
2489 "the LL loop consumed tokens, so the window tail must be non-empty"
2490 );
2491
2492 let replayed = simulator
2495 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
2496 .expect("memoized prediction");
2497 assert_eq!(replayed, fresh);
2498 assert_eq!(input.index(), 0, "cursor restored by the caller wrapper");
2499
2500 let mut diverging = VecIntStream::new(vec![1, 9, 9, TOKEN_EOF]);
2506 let result = simulator.adaptive_predict_stream_info_with_context(
2507 0,
2508 0,
2509 &mut diverging,
2510 EMPTY_CONTEXT,
2511 );
2512 assert!(result.is_err(), "mid-window divergence must not replay");
2513 assert_eq!(simulator.full_context_memo_len, 1);
2514 }
2515
2516 #[test]
2517 fn full_context_memo_stays_off_for_predicated_atns_and_exact_mode() {
2518 let atn = ambiguous_single_token_decision_atn();
2521 let mut simulator = ParserAtnSimulator::new(&atn);
2522 simulator.set_exact_ambig_detection(true);
2523 let mut input = VecIntStream::new(vec![1, TOKEN_EOF]);
2524 let _ = simulator
2525 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
2526 .expect("prediction");
2527 assert_eq!(simulator.full_context_memo_len, 0);
2528
2529 let mut atn = ParserAtnBuilder::new(1);
2532 add_state(&mut atn, 0, AtnStateKind::Basic);
2533 add_state(&mut atn, 1, AtnStateKind::Basic);
2534 atn.add_transition(
2535 0,
2536 ParserTransitionSpec::Predicate {
2537 target: 1,
2538 rule_index: 0,
2539 pred_index: 0,
2540 context_dependent: false,
2541 },
2542 )
2543 .expect("transition");
2544 atn.set_rule_to_start_state(vec![0])
2545 .expect("rule start states");
2546 atn.set_rule_to_stop_state(vec![1])
2547 .expect("rule stop states");
2548 let atn = finish_atn(atn);
2549 let mut simulator = ParserAtnSimulator::new(&atn);
2550 assert!(!simulator.full_context_memo_allowed());
2551 }
2552
2553 #[test]
2554 fn full_context_memo_allows_action_and_precedence_transitions() {
2555 let mut atn = ParserAtnBuilder::new(1);
2561 add_state(&mut atn, 0, AtnStateKind::Basic);
2562 add_state(&mut atn, 1, AtnStateKind::Basic);
2563 add_state(&mut atn, 2, AtnStateKind::Basic);
2564 atn.add_transition(
2565 0,
2566 ParserTransitionSpec::Action {
2567 target: 1,
2568 rule_index: 0,
2569 action_index: Some(0),
2570 context_dependent: false,
2571 },
2572 )
2573 .expect("transition");
2574 atn.add_transition(
2575 1,
2576 ParserTransitionSpec::Precedence {
2577 target: 2,
2578 precedence: 1,
2579 },
2580 )
2581 .expect("transition");
2582 atn.set_rule_to_start_state(vec![0])
2583 .expect("rule start states");
2584 atn.set_rule_to_stop_state(vec![2])
2585 .expect("rule stop states");
2586 let atn = finish_atn(atn);
2587 let mut simulator = ParserAtnSimulator::new(&atn);
2588 assert!(simulator.full_context_memo_allowed());
2589 }
2590
2591 #[test]
2592 fn context_prediction_reports_context_sensitivity_for_dfa_conflict() {
2593 let atn = two_token_decision_atn();
2594 let mut simulator = ParserAtnSimulator::new(&atn);
2595 let mut workspace = PredictionWorkspace::default();
2596 let mut start_configs = AtnConfigSet::new();
2597 start_configs.add(
2598 AtnConfig::new(2, 1, EMPTY_CONTEXT, &simulator.store.contexts),
2599 &mut simulator.store.contexts,
2600 &mut workspace,
2601 );
2602 let start =
2603 simulator.store.decision_to_dfa[0].add_state(DfaStateBuilder::new(start_configs));
2604 simulator.store.decision_to_dfa[0].set_start_state(start);
2605
2606 let mut accept_configs = AtnConfigSet::new();
2607 accept_configs.add(
2608 AtnConfig::new(3, 1, EMPTY_CONTEXT, &simulator.store.contexts).with_semantic_context(
2609 SemanticContext::Predicate {
2610 rule_index: 0,
2611 pred_index: 0,
2612 context_dependent: false,
2613 },
2614 ),
2615 &mut simulator.store.contexts,
2616 &mut workspace,
2617 );
2618 let mut accept_state = DfaStateBuilder::new(accept_configs);
2619 accept_state.mark_accept(1);
2620 accept_state.set_requires_full_context(true);
2621 accept_state.set_conflicting_alts(vec![1, 2]);
2622 let accept = simulator.store.decision_to_dfa[0].add_state(accept_state);
2623 simulator.store.decision_to_dfa[0].add_edge(start, 1, accept);
2624
2625 let mut input = VecIntStream::new(vec![1, 3, TOKEN_EOF]);
2626 let prediction = simulator
2627 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
2628 .expect("prediction");
2629
2630 insta::assert_debug_snapshot!(
2631 "context_prediction_reports_context_sensitivity_for_dfa_conflict",
2632 prediction
2633 );
2634 assert_eq!(input.index(), 0);
2635 }
2636
2637 #[test]
2638 fn full_context_reach_prefers_longer_match_over_skipped_stop_state() {
2639 let atn = prefix_alt_decision_atn();
2640 let mut simulator = ParserAtnSimulator::new(&atn);
2641 let mut configs = AtnConfigSet::new_full_context(true);
2642 let mut merge_cache = PredictionWorkspace::default();
2643 configs.add(
2644 AtnConfig::new(2, 1, EMPTY_CONTEXT, &simulator.store.contexts),
2645 &mut simulator.store.contexts,
2646 &mut merge_cache,
2647 );
2648 configs.add(
2649 AtnConfig::new(1, 2, EMPTY_CONTEXT, &simulator.store.contexts),
2650 &mut simulator.store.contexts,
2651 &mut merge_cache,
2652 );
2653
2654 let reach = simulator.compute_reach_set(&configs, 2, true, 0, &mut merge_cache);
2655
2656 assert_eq!(reach.alts(), std::iter::once(2).collect());
2657 assert!(simulator.configs_all_reached_rule_stop(&reach));
2658 }
2659
2660 #[test]
2661 fn sll_closure_follows_empty_context_rule_stop_exits() {
2662 let mut atn = ParserAtnBuilder::new(1);
2663 add_state(&mut atn, 0, AtnStateKind::RuleStop);
2664 add_state(&mut atn, 1, AtnStateKind::Basic);
2665 add_state(&mut atn, 2, AtnStateKind::Basic);
2666 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2667 .expect("transition");
2668 atn.add_transition(
2669 1,
2670 ParserTransitionSpec::Atom {
2671 target: 2,
2672 label: 1,
2673 },
2674 )
2675 .expect("transition");
2676 atn.set_rule_to_start_state(vec![0])
2677 .expect("rule start states");
2678 atn.set_rule_to_stop_state(vec![0])
2679 .expect("rule stop states");
2680 let atn = finish_atn(atn);
2681
2682 let mut simulator = ParserAtnSimulator::new(&atn);
2683 let mut configs = AtnConfigSet::new_full_context(false);
2684 let mut merge_cache = PredictionWorkspace::default();
2685 let mut scratch = ClosureScratch::default();
2686 let config = AtnConfig::new(0, 2, EMPTY_CONTEXT, &simulator.store.contexts);
2687 simulator.closure(
2688 config,
2689 &mut configs,
2690 &mut merge_cache,
2691 &mut scratch,
2692 ClosureParams {
2693 precedence: 0,
2694 collect_predicates: true,
2695 treat_eof_as_epsilon: false,
2696 },
2697 );
2698
2699 assert_eq!(configs.len(), 1);
2700 let config = &configs.configs()[0];
2701 assert_eq!(config.state, 1);
2702 assert_eq!(config.alt, 2);
2703 assert_eq!(config.reaches_into_outer_context, 1);
2704 }
2705
2706 #[test]
2707 fn precedence_contexts_are_collected_only_for_start_closure() {
2708 let mut atn = ParserAtnBuilder::new(1);
2709 add_state(&mut atn, 0, AtnStateKind::Basic);
2710 add_state(&mut atn, 1, AtnStateKind::Basic);
2711 atn.set_rule_to_start_state(vec![0])
2712 .expect("rule start states");
2713 atn.set_rule_to_stop_state(vec![1])
2714 .expect("rule stop states");
2715 atn.add_transition(
2716 0,
2717 ParserTransitionSpec::Precedence {
2718 target: 1,
2719 precedence: 2,
2720 },
2721 )
2722 .expect("precedence transition");
2723 let atn = finish_atn(atn);
2724 let transition = atn
2725 .state(0)
2726 .expect("source state")
2727 .transitions()
2728 .first()
2729 .expect("precedence transition");
2730 let mut simulator = ParserAtnSimulator::new(&atn);
2731 let config = AtnConfig::new(0, 1, EMPTY_CONTEXT, &simulator.store.contexts);
2732
2733 let sll_start = simulator
2734 .epsilon_target_config(&config, transition, transition.kind(), 1, true, false)
2735 .expect("sll start transition");
2736 assert!(matches!(
2737 sll_start.semantic_context,
2738 SemanticContext::Precedence { precedence: 2 }
2739 ));
2740
2741 let full_context_start = simulator
2742 .epsilon_target_config(&config, transition, transition.kind(), 1, true, true)
2743 .expect("full-context start transition");
2744 assert!(full_context_start.semantic_context.is_none());
2745
2746 let reach = simulator
2747 .epsilon_target_config(&config, transition, transition.kind(), 3, false, false)
2748 .expect("reach transition");
2749 assert!(reach.semantic_context.is_none());
2750
2751 assert!(
2752 simulator
2753 .epsilon_target_config(&config, transition, transition.kind(), 3, true, false)
2754 .is_none()
2755 );
2756 }
2757
2758 #[test]
2759 fn closure_stops_collecting_predicates_after_action_edge() {
2760 let mut atn = ParserAtnBuilder::new(1);
2767 add_state(&mut atn, 0, AtnStateKind::Basic);
2768 add_state(&mut atn, 1, AtnStateKind::Basic);
2769 add_state(&mut atn, 2, AtnStateKind::Basic);
2770 add_state(&mut atn, 3, AtnStateKind::Basic);
2771 atn.add_transition(
2772 0,
2773 ParserTransitionSpec::Action {
2774 target: 1,
2775 rule_index: 0,
2776 action_index: Some(0),
2777 context_dependent: false,
2778 },
2779 )
2780 .expect("transition");
2781 atn.add_transition(
2782 1,
2783 ParserTransitionSpec::Predicate {
2784 target: 2,
2785 rule_index: 0,
2786 pred_index: 0,
2787 context_dependent: false,
2788 },
2789 )
2790 .expect("transition");
2791 atn.add_transition(
2792 2,
2793 ParserTransitionSpec::Atom {
2794 target: 3,
2795 label: 1,
2796 },
2797 )
2798 .expect("transition");
2799 atn.set_rule_to_start_state(vec![0])
2800 .expect("rule start states");
2801 atn.set_rule_to_stop_state(vec![3])
2802 .expect("rule stop states");
2803 let atn = finish_atn(atn);
2804
2805 let mut simulator = ParserAtnSimulator::new(&atn);
2806 let mut configs = AtnConfigSet::new();
2807 let mut merge_cache = PredictionWorkspace::default();
2808 let mut scratch = ClosureScratch::default();
2809 let config = AtnConfig::new(0, 1, EMPTY_CONTEXT, &simulator.store.contexts);
2810 simulator.closure(
2811 config,
2812 &mut configs,
2813 &mut merge_cache,
2814 &mut scratch,
2815 ClosureParams {
2816 precedence: 0,
2817 collect_predicates: true,
2818 treat_eof_as_epsilon: false,
2819 },
2820 );
2821
2822 let at_two = configs
2825 .configs()
2826 .iter()
2827 .find(|config| config.state == 2)
2828 .expect("config at state 2");
2829 assert!(
2830 at_two.semantic_context.is_none(),
2831 "predicate after an action edge must not be collected during prediction"
2832 );
2833
2834 let direct_config = AtnConfig::new(1, 1, EMPTY_CONTEXT, &simulator.store.contexts);
2838 let direct_transition = atn
2839 .state(1)
2840 .expect("predicate source")
2841 .transitions()
2842 .first()
2843 .expect("predicate transition");
2844 let direct = simulator
2845 .epsilon_target_config(
2846 &direct_config,
2847 direct_transition,
2848 direct_transition.kind(),
2849 0,
2850 true,
2851 false,
2852 )
2853 .expect("predicate transition");
2854 assert!(matches!(
2855 direct.semantic_context,
2856 SemanticContext::Predicate { pred_index: 0, .. }
2857 ));
2858 }
2859
2860 #[test]
2861 fn reach_set_skips_closure_for_unique_intermediate_alt() {
2862 let mut atn = ParserAtnBuilder::new(1);
2863 add_state(&mut atn, 0, AtnStateKind::Basic);
2864 add_state(&mut atn, 1, AtnStateKind::Basic);
2865 add_state(&mut atn, 2, AtnStateKind::Basic);
2866 atn.add_transition(
2867 0,
2868 ParserTransitionSpec::Atom {
2869 target: 1,
2870 label: 7,
2871 },
2872 )
2873 .expect("transition");
2874 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2875 .expect("transition");
2876 atn.set_rule_to_start_state(vec![0])
2877 .expect("rule start states");
2878 atn.set_rule_to_stop_state(vec![2])
2879 .expect("rule stop states");
2880 let atn = finish_atn(atn);
2881
2882 let mut simulator = ParserAtnSimulator::new(&atn);
2883 let mut configs = AtnConfigSet::new_full_context(false);
2884 let mut merge_cache = PredictionWorkspace::default();
2885 configs.add(
2886 AtnConfig::new(0, 1, EMPTY_CONTEXT, &simulator.store.contexts),
2887 &mut simulator.store.contexts,
2888 &mut merge_cache,
2889 );
2890
2891 let reach = simulator.compute_reach_set(&configs, 7, false, 0, &mut merge_cache);
2892
2893 assert_eq!(reach.len(), 1);
2894 assert_eq!(reach.configs()[0].state, 1);
2895 }
2896
2897 #[test]
2898 fn semantic_context_flag_is_scoped_to_predicted_alt() {
2899 let mut arena = ContextArena::new();
2900 let mut workspace = PredictionWorkspace::default();
2901 let mut configs = AtnConfigSet::new();
2902 configs.add(
2903 AtnConfig::new(1, 1, EMPTY_CONTEXT, &arena),
2904 &mut arena,
2905 &mut workspace,
2906 );
2907 configs.add(
2908 AtnConfig::new(2, 2, EMPTY_CONTEXT, &arena).with_semantic_context(
2909 SemanticContext::Predicate {
2910 rule_index: 0,
2911 pred_index: 0,
2912 context_dependent: false,
2913 },
2914 ),
2915 &mut arena,
2916 &mut workspace,
2917 );
2918
2919 assert!(!configs_have_semantic_context_for_alt(&configs, 1));
2920 assert!(configs_have_semantic_context_for_alt(&configs, 2));
2921 }
2922
2923 #[test]
2924 fn adaptive_predict_prefers_non_greedy_exit_before_consuming() {
2925 let atn = non_greedy_optional_exit_first_atn();
2926 let mut simulator = ParserAtnSimulator::new(&atn);
2927
2928 assert_eq!(simulator.adaptive_predict(0, [1, TOKEN_EOF]), Ok(1));
2929 }
2930
2931 #[test]
2932 fn left_recursive_loop_entry_drop_requires_same_rule_return() {
2933 let atn = left_recursive_loop_entry_atn();
2934 let loop_entry = atn.state(1).expect("loop entry");
2935 let mut contexts = ContextArena::new();
2936 let same_rule_context = contexts.singleton(EMPTY_CONTEXT, 4);
2937 let other_rule_context = contexts.singleton(EMPTY_CONTEXT, 5);
2938
2939 assert!(can_drop_left_recursive_loop_entry_edge(
2940 &atn,
2941 loop_entry,
2942 &contexts,
2943 same_rule_context
2944 ));
2945 assert!(!can_drop_left_recursive_loop_entry_edge(
2946 &atn,
2947 loop_entry,
2948 &contexts,
2949 other_rule_context
2950 ));
2951 assert!(!can_drop_left_recursive_loop_entry_edge(
2952 &atn,
2953 loop_entry,
2954 &contexts,
2955 EMPTY_CONTEXT
2956 ));
2957 }
2958
2959 fn two_token_decision_atn() -> Atn {
2960 two_token_decision_atn_with_precedence(false)
2961 }
2962
2963 fn two_token_decision_atn_with_precedence(precedence: bool) -> Atn {
2964 let mut atn = ParserAtnBuilder::new(3);
2965 add_state(&mut atn, 0, AtnStateKind::RuleStart);
2966 add_state(&mut atn, 1, AtnStateKind::BlockStart);
2967 add_state(&mut atn, 2, AtnStateKind::Basic);
2968 add_state(&mut atn, 3, AtnStateKind::Basic);
2969 add_state(&mut atn, 4, AtnStateKind::Basic);
2970 add_state(&mut atn, 5, AtnStateKind::Basic);
2971 add_state(&mut atn, 6, AtnStateKind::BlockEnd);
2972 add_state(&mut atn, 7, AtnStateKind::RuleStop);
2973 atn.set_rule_to_start_state(vec![0])
2974 .expect("rule start states");
2975 atn.set_rule_to_stop_state(vec![7])
2976 .expect("rule stop states");
2977 atn.add_decision_state(1).expect("decision state");
2978 if precedence {
2979 atn.set_precedence_rule_decision(1)
2980 .expect("precedence decision state");
2981 }
2982 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2983 .expect("transition");
2984 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2985 .expect("transition");
2986 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
2987 .expect("transition");
2988 atn.add_transition(
2989 2,
2990 ParserTransitionSpec::Atom {
2991 target: 3,
2992 label: 1,
2993 },
2994 )
2995 .expect("transition");
2996 atn.add_transition(
2997 3,
2998 ParserTransitionSpec::Atom {
2999 target: 6,
3000 label: 2,
3001 },
3002 )
3003 .expect("transition");
3004 atn.add_transition(
3005 4,
3006 ParserTransitionSpec::Atom {
3007 target: 5,
3008 label: 1,
3009 },
3010 )
3011 .expect("transition");
3012 atn.add_transition(
3013 5,
3014 ParserTransitionSpec::Atom {
3015 target: 6,
3016 label: 3,
3017 },
3018 )
3019 .expect("transition");
3020 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
3021 .expect("transition");
3022 finish_atn(atn)
3023 }
3024
3025 fn optional_token_decision_atn() -> Atn {
3026 let mut atn = ParserAtnBuilder::new(1);
3027 add_state(&mut atn, 0, AtnStateKind::RuleStart);
3028 add_state(&mut atn, 1, AtnStateKind::BlockStart);
3029 add_state(&mut atn, 2, AtnStateKind::Basic);
3030 add_state(&mut atn, 3, AtnStateKind::BlockEnd);
3031 add_state(&mut atn, 4, AtnStateKind::RuleStop);
3032 atn.set_rule_to_start_state(vec![0])
3033 .expect("rule start states");
3034 atn.set_rule_to_stop_state(vec![4])
3035 .expect("rule stop states");
3036 atn.add_decision_state(1).expect("decision state");
3037 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
3038 .expect("transition");
3039 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
3040 .expect("transition");
3041 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
3042 .expect("transition");
3043 atn.add_transition(
3044 2,
3045 ParserTransitionSpec::Atom {
3046 target: 3,
3047 label: 1,
3048 },
3049 )
3050 .expect("transition");
3051 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
3052 .expect("transition");
3053 finish_atn(atn)
3054 }
3055
3056 fn non_greedy_optional_exit_first_atn() -> Atn {
3057 let mut atn = ParserAtnBuilder::new(1);
3058 add_state(&mut atn, 0, AtnStateKind::RuleStart);
3059 add_state(&mut atn, 1, AtnStateKind::BlockStart);
3060 add_state(&mut atn, 2, AtnStateKind::BlockEnd);
3061 add_state(&mut atn, 3, AtnStateKind::Basic);
3062 add_state(&mut atn, 4, AtnStateKind::RuleStop);
3063 atn.set_rule_to_start_state(vec![0])
3064 .expect("rule start states");
3065 atn.set_rule_to_stop_state(vec![4])
3066 .expect("rule stop states");
3067 atn.add_decision_state(1).expect("decision state");
3068 atn.set_non_greedy(1).expect("non-greedy state");
3069 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
3070 .expect("transition");
3071 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
3072 .expect("transition");
3073 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
3074 .expect("transition");
3075 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
3076 .expect("transition");
3077 atn.add_transition(
3078 3,
3079 ParserTransitionSpec::Atom {
3080 target: 4,
3081 label: 1,
3082 },
3083 )
3084 .expect("transition");
3085 finish_atn(atn)
3086 }
3087
3088 fn ambiguous_three_token_decision_atn() -> Atn {
3093 let mut atn = ParserAtnBuilder::new(3);
3094 add_state(&mut atn, 0, AtnStateKind::RuleStart);
3095 add_state(&mut atn, 1, AtnStateKind::BlockStart);
3096 add_state(&mut atn, 2, AtnStateKind::Basic);
3098 add_state(&mut atn, 3, AtnStateKind::Basic);
3099 add_state(&mut atn, 4, AtnStateKind::Basic);
3100 add_state(&mut atn, 5, AtnStateKind::Basic);
3101 add_state(&mut atn, 6, AtnStateKind::Basic);
3103 add_state(&mut atn, 7, AtnStateKind::Basic);
3104 add_state(&mut atn, 8, AtnStateKind::Basic);
3105 add_state(&mut atn, 9, AtnStateKind::Basic);
3106 add_state(&mut atn, 10, AtnStateKind::BlockEnd);
3107 add_state(&mut atn, 11, AtnStateKind::RuleStop);
3108 atn.set_rule_to_start_state(vec![0])
3109 .expect("rule start states");
3110 atn.set_rule_to_stop_state(vec![11])
3111 .expect("rule stop states");
3112 atn.add_decision_state(1).expect("decision state");
3113 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
3114 .expect("transition");
3115 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
3116 .expect("transition");
3117 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
3118 .expect("transition");
3119 for (source, target, label) in [
3120 (2, 3, 1),
3121 (3, 4, 2),
3122 (4, 5, 3),
3123 (6, 7, 1),
3124 (7, 8, 2),
3125 (8, 9, 3),
3126 ] {
3127 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
3128 .expect("transition");
3129 }
3130 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
3131 .expect("transition");
3132 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
3133 .expect("transition");
3134 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
3135 .expect("transition");
3136 finish_atn(atn)
3137 }
3138
3139 fn ambiguous_single_token_decision_atn() -> Atn {
3140 let mut atn = ParserAtnBuilder::new(1);
3141 add_state(&mut atn, 0, AtnStateKind::RuleStart);
3142 add_state(&mut atn, 1, AtnStateKind::BlockStart);
3143 add_state(&mut atn, 2, AtnStateKind::Basic);
3144 add_state(&mut atn, 3, AtnStateKind::Basic);
3145 add_state(&mut atn, 4, AtnStateKind::Basic);
3146 add_state(&mut atn, 5, AtnStateKind::Basic);
3147 add_state(&mut atn, 6, AtnStateKind::BlockEnd);
3148 add_state(&mut atn, 7, AtnStateKind::RuleStop);
3149 atn.set_rule_to_start_state(vec![0])
3150 .expect("rule start states");
3151 atn.set_rule_to_stop_state(vec![7])
3152 .expect("rule stop states");
3153 atn.add_decision_state(1).expect("decision state");
3154 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
3155 .expect("transition");
3156 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
3157 .expect("transition");
3158 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
3159 .expect("transition");
3160 atn.add_transition(
3161 2,
3162 ParserTransitionSpec::Atom {
3163 target: 3,
3164 label: 1,
3165 },
3166 )
3167 .expect("transition");
3168 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 6 })
3169 .expect("transition");
3170 atn.add_transition(
3171 4,
3172 ParserTransitionSpec::Atom {
3173 target: 5,
3174 label: 1,
3175 },
3176 )
3177 .expect("transition");
3178 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
3179 .expect("transition");
3180 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
3181 .expect("transition");
3182 finish_atn(atn)
3183 }
3184
3185 fn prefix_alt_decision_atn() -> Atn {
3186 let mut atn = ParserAtnBuilder::new(3);
3187 add_state(&mut atn, 0, AtnStateKind::BlockStart);
3188 add_state(&mut atn, 1, AtnStateKind::Basic);
3189 add_state(&mut atn, 2, AtnStateKind::RuleStop);
3190 atn.set_rule_to_start_state(vec![0])
3191 .expect("rule start states");
3192 atn.set_rule_to_stop_state(vec![2])
3193 .expect("rule stop states");
3194 atn.add_decision_state(0).expect("decision state");
3195 atn.add_transition(
3196 0,
3197 ParserTransitionSpec::Atom {
3198 target: 2,
3199 label: 1,
3200 },
3201 )
3202 .expect("transition");
3203 atn.add_transition(
3204 0,
3205 ParserTransitionSpec::Atom {
3206 target: 1,
3207 label: 1,
3208 },
3209 )
3210 .expect("transition");
3211 atn.add_transition(
3212 1,
3213 ParserTransitionSpec::Atom {
3214 target: 2,
3215 label: 2,
3216 },
3217 )
3218 .expect("transition");
3219 finish_atn(atn)
3220 }
3221
3222 fn three_token_prefix_alt_decision_atn() -> Atn {
3223 let mut atn = ParserAtnBuilder::new(2);
3224 for (state_number, kind) in [
3225 (0, AtnStateKind::BlockStart),
3226 (1, AtnStateKind::Basic),
3227 (2, AtnStateKind::Basic),
3228 (3, AtnStateKind::Basic),
3229 (4, AtnStateKind::Basic),
3230 (5, AtnStateKind::Basic),
3231 (6, AtnStateKind::RuleStop),
3232 ] {
3233 add_state(&mut atn, state_number, kind);
3234 }
3235 atn.set_rule_to_start_state(vec![0])
3236 .expect("rule start states");
3237 atn.set_rule_to_stop_state(vec![6])
3238 .expect("rule stop states");
3239 atn.add_decision_state(0).expect("decision state");
3240 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
3241 .expect("transition");
3242 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 2 })
3243 .expect("transition");
3244 atn.add_transition(
3245 1,
3246 ParserTransitionSpec::Atom {
3247 target: 6,
3248 label: 1,
3249 },
3250 )
3251 .expect("transition");
3252 atn.add_transition(
3253 2,
3254 ParserTransitionSpec::Atom {
3255 target: 3,
3256 label: 1,
3257 },
3258 )
3259 .expect("transition");
3260 atn.add_transition(
3261 3,
3262 ParserTransitionSpec::Atom {
3263 target: 4,
3264 label: 2,
3265 },
3266 )
3267 .expect("transition");
3268 atn.add_transition(
3269 4,
3270 ParserTransitionSpec::Atom {
3271 target: 5,
3272 label: 1,
3273 },
3274 )
3275 .expect("transition");
3276 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
3277 .expect("transition");
3278 finish_atn(atn)
3279 }
3280
3281 fn multiple_eof_decision_atn() -> Atn {
3282 let mut atn = ParserAtnBuilder::new(2);
3283 for state_number in 0..=10 {
3284 let kind = match state_number {
3285 0 => AtnStateKind::RuleStart,
3286 1 => AtnStateKind::BlockStart,
3287 7 => AtnStateKind::BlockEnd,
3288 10 => AtnStateKind::RuleStop,
3289 _ => AtnStateKind::Basic,
3290 };
3291 add_state(&mut atn, state_number, kind);
3292 }
3293 atn.set_rule_to_start_state(vec![0])
3294 .expect("rule start states");
3295 atn.set_rule_to_stop_state(vec![10])
3296 .expect("rule stop states");
3297 atn.add_decision_state(1).expect("decision state");
3298 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
3299 .expect("transition");
3300 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
3301 .expect("transition");
3302 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
3303 .expect("transition");
3304 atn.add_transition(
3305 2,
3306 ParserTransitionSpec::Atom {
3307 target: 3,
3308 label: 1,
3309 },
3310 )
3311 .expect("transition");
3312 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 7 })
3313 .expect("transition");
3314 atn.add_transition(
3315 4,
3316 ParserTransitionSpec::Atom {
3317 target: 5,
3318 label: 1,
3319 },
3320 )
3321 .expect("transition");
3322 atn.add_transition(
3323 5,
3324 ParserTransitionSpec::Atom {
3325 target: 6,
3326 label: 2,
3327 },
3328 )
3329 .expect("transition");
3330 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
3331 .expect("transition");
3332 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
3333 .expect("transition");
3334 atn.add_transition(
3335 8,
3336 ParserTransitionSpec::Atom {
3337 target: 9,
3338 label: TOKEN_EOF,
3339 },
3340 )
3341 .expect("transition");
3342 atn.add_transition(
3343 9,
3344 ParserTransitionSpec::Atom {
3345 target: 10,
3346 label: TOKEN_EOF,
3347 },
3348 )
3349 .expect("transition");
3350 finish_atn(atn)
3351 }
3352
3353 fn left_recursive_loop_entry_atn() -> Atn {
3354 let mut atn = ParserAtnBuilder::new(1);
3355 add_state(&mut atn, 0, AtnStateKind::RuleStart);
3356 add_state(&mut atn, 1, AtnStateKind::StarLoopEntry);
3357 add_state(&mut atn, 2, AtnStateKind::BlockStart);
3358 add_state(&mut atn, 3, AtnStateKind::BlockEnd);
3359 add_state(&mut atn, 4, AtnStateKind::Basic);
3360 assert_eq!(
3361 atn.add_state(AtnStateKind::Basic, Some(1))
3362 .expect("state")
3363 .index(),
3364 5
3365 );
3366 add_state(&mut atn, 6, AtnStateKind::LoopEnd);
3367 add_state(&mut atn, 7, AtnStateKind::RuleStop);
3368 atn.set_rule_to_start_state(vec![0, 5])
3369 .expect("rule start states");
3370 atn.set_rule_to_stop_state(vec![7, 7])
3371 .expect("rule stop states");
3372 atn.set_precedence_rule_decision(1)
3373 .expect("precedence decision state");
3374 atn.set_end_state(2, 3).expect("block end state");
3375 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
3376 .expect("transition");
3377 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
3378 .expect("transition");
3379 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 3 })
3380 .expect("transition");
3381 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 3 })
3382 .expect("transition");
3383 finish_atn(atn)
3384 }
3385
3386 fn add_state(atn: &mut ParserAtnBuilder, state_number: usize, kind: AtnStateKind) {
3387 assert_eq!(
3388 atn.add_state(kind, Some(0)).expect("state").index(),
3389 state_number
3390 );
3391 }
3392
3393 #[derive(Debug)]
3394 struct VecIntStream {
3395 symbols: Vec<i32>,
3396 index: usize,
3397 }
3398
3399 impl VecIntStream {
3400 fn new(symbols: Vec<i32>) -> Self {
3401 Self { symbols, index: 0 }
3402 }
3403 }
3404
3405 impl IntStream for VecIntStream {
3406 fn consume(&mut self) {
3407 if self.la(1) != TOKEN_EOF {
3408 self.index += 1;
3409 }
3410 }
3411
3412 fn la(&mut self, offset: isize) -> i32 {
3413 if offset <= 0 {
3414 return 0;
3415 }
3416 let offset = offset.cast_unsigned() - 1;
3417 self.symbols
3418 .get(self.index + offset)
3419 .copied()
3420 .unwrap_or(TOKEN_EOF)
3421 }
3422
3423 fn index(&self) -> usize {
3424 self.index
3425 }
3426
3427 fn seek(&mut self, index: usize) {
3428 self.index = index;
3429 }
3430
3431 fn size(&self) -> usize {
3432 self.symbols.len()
3433 }
3434 }
3435}