1use crate::atn::AtnStateKind;
4use crate::atn::parser_atn::{
5 ParserAtn as Atn, ParserAtnState as AtnState, ParserTransition, ParserTransitionKind,
6};
7#[cfg(test)]
8use crate::atn::parser_atn::{ParserAtnBuilder, ParserTransitionSpec};
9use crate::dfa::{
10 DfaStateBuilder, DfaStateId, NO_DFA_STATE, ParserDfa, ParserDfaStateView, ParserDfaStats,
11};
12use crate::int_stream::IntStream;
13use crate::prediction::{
14 AtnConfig, AtnConfigSet, ContextArena, ContextId, EMPTY_CONTEXT, EMPTY_RETURN_STATE,
15 PredictionContextStats, PredictionFxHasher, PredictionPredicateCall,
16 PredictionSemanticProvenanceArena, PredictionSemanticProvenanceId, PredictionWorkspace,
17 SemanticContext, all_subsets_conflict, all_subsets_equal, conflicting_alt_subsets,
18 has_sll_conflict_terminating_prediction, single_viable_alt,
19};
20use crate::token::TOKEN_EOF;
21use std::cell::RefCell;
22use std::collections::{HashMap, HashSet};
23use std::hash::BuildHasherDefault;
24
25type FxHashSet<T> = HashSet<T, BuildHasherDefault<PredictionFxHasher>>;
26
27#[derive(Debug)]
28pub struct ParserAtnSimulator<'a> {
29 atn: &'a Atn,
30 store: PredictionStore,
31 workspace: PredictionWorkspace,
32 outer_context_cache: Option<CachedOuterContext>,
33 outer_context_cache_hits: usize,
34 outer_context_cache_misses: usize,
35 deferred_accept_states: FxHashSet<(usize, DfaStateId)>,
38 shared_cache_key: Option<usize>,
39 shared_cache_generation: u64,
40 has_trained_decision: bool,
41 measure_adaptive_work: bool,
42 adaptive_calls: usize,
43 adaptive_closure_work: usize,
44 exact_ambig_detection: bool,
48 full_context_memo: HashMap<
59 FullContextMemoKey,
60 Vec<FullContextMemoEntry>,
61 BuildHasherDefault<PredictionFxHasher>,
62 >,
63 full_context_memo_len: usize,
64 full_context_memo_gate: Option<bool>,
68 prediction_semantic_candidates: Vec<CompactParserSemanticCandidate>,
74 track_prediction_rule_calls: bool,
79 semantic_provenance: Option<Box<PredictionSemanticProvenanceArena>>,
80}
81
82#[derive(Clone, Copy, Debug)]
83struct CachedOuterContext {
84 rule_context_version: usize,
85 context: ContextId,
86}
87
88#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
99struct FullContextMemoKey {
100 decision: usize,
101 precedence: i32,
102 outer_context: ContextId,
103 first_symbol: i32,
104}
105
106#[derive(Clone, Debug)]
117struct FullContextMemoEntry {
118 window_tail: Vec<i32>,
119 prediction: FullContextPrediction,
120}
121
122const FULL_CONTEXT_MEMO_MAX_WINDOW: usize = 16;
126const FULL_CONTEXT_MEMO_MAX_ENTRIES: usize = 4096;
130
131fn atn_has_predicate_transition(atn: &Atn) -> bool {
138 thread_local! {
139 static GATES: RefCell<HashMap<usize, bool, BuildHasherDefault<PredictionFxHasher>>> =
140 RefCell::new(HashMap::default());
141 }
142 let ptr: *const Atn = atn;
143 let key = ptr as usize;
144 GATES.with(|gates| {
145 *gates.borrow_mut().entry(key).or_insert_with(|| {
146 (0..atn.state_count()).any(|state_number| {
147 atn.state(state_number).is_some_and(|state| {
148 state
149 .transitions()
150 .into_iter()
151 .any(|transition| transition.kind() == ParserTransitionKind::Predicate)
152 })
153 })
154 })
155 })
156}
157
158#[derive(Debug, Default)]
159struct PredictionStore {
160 contexts: ContextArena,
161 decision_to_dfa: Vec<ParserDfa>,
162}
163
164impl PredictionStore {
165 fn new(atn: &Atn) -> Self {
166 Self {
167 contexts: ContextArena::new(),
168 decision_to_dfa: initial_decision_dfas(atn),
169 }
170 }
171}
172
173#[derive(Debug, Default)]
174struct SharedPredictionStore {
175 generation: u64,
176 store: Option<PredictionStore>,
177}
178
179thread_local! {
180 static SHARED_PREDICTION_STORES: RefCell<HashMap<usize, SharedPredictionStore>> =
181 RefCell::new(HashMap::new());
182}
183
184fn clear_shared_prediction_store(key: usize) -> u64 {
185 SHARED_PREDICTION_STORES.with(|cache| {
186 let mut cache = cache.borrow_mut();
187 let shared = cache.entry(key).or_default();
188 shared.generation = shared.generation.wrapping_add(1);
189 shared.store = None;
190 shared.generation
191 })
192}
193
194const ADAPTIVE_ATN_PREFERENCE_MIN_CALLS: usize = 32;
195const ADAPTIVE_ATN_PREFERENCE_MIN_CLOSURE_WORK_PER_CALL: usize = 256;
196const ADAPTIVE_ATN_PREFERENCE_DECISIVE_CLOSURE_WORK_PER_CALL: usize = 512;
197
198const fn adaptive_prediction_has_work_density(
199 calls: usize,
200 closure_work: usize,
201 minimum_closure_work_per_call: usize,
202) -> bool {
203 calls >= ADAPTIVE_ATN_PREFERENCE_MIN_CALLS
204 && closure_work >= calls.saturating_mul(minimum_closure_work_per_call)
205}
206
207#[derive(Clone, Debug, Eq, PartialEq)]
208pub struct ParserAtnPrediction {
209 pub alt: usize,
210 pub requires_full_context: bool,
211 pub has_semantic_context: bool,
212 pub diagnostic: Option<ParserAtnPredictionDiagnostic>,
213}
214
215#[derive(Clone, Debug, Eq, PartialEq)]
216pub struct ParserAtnPredictionDiagnostic {
217 pub kind: ParserAtnPredictionDiagnosticKind,
218 pub start_index: usize,
219 pub sll_stop_index: usize,
220 pub ll_stop_index: usize,
221 pub conflicting_alts: Vec<usize>,
222 pub exact: bool,
226}
227
228#[derive(Clone, Copy, Debug, Eq, PartialEq)]
229pub enum ParserAtnPredictionDiagnosticKind {
230 Ambiguity,
231 ContextSensitivity,
232}
233
234#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
235pub(crate) struct ParserSemanticCandidate {
236 pub(crate) alt: usize,
237 pub(crate) context: SemanticContext,
238 pub(crate) predicate_calls: Vec<PredictionPredicateCall>,
239}
240
241#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
242struct CompactParserSemanticCandidate {
243 alt: usize,
244 context: SemanticContext,
245 semantic_provenance: PredictionSemanticProvenanceId,
246}
247
248#[derive(Clone, Copy)]
249struct PredictionCheck {
250 decision: usize,
251 decision_state: usize,
252 state_number: DfaStateId,
253 start_index: usize,
254 precedence: i32,
255 outer_context: ContextId,
256 force_full_context_retry: bool,
257 sll_probe_only: bool,
258}
259
260#[derive(Clone, Copy)]
261struct AdaptivePredictRequest {
262 decision: usize,
263 precedence: usize,
264 outer_context: ContextId,
265 force_full_context_retry: bool,
266 sll_probe_only: bool,
274}
275
276#[derive(Clone, Copy)]
277struct DfaEdge {
278 decision: usize,
279 source_state: DfaStateId,
280}
281
282#[derive(Clone, Debug)]
283struct PreviousGoodAlt {
284 alt: usize,
285 configs: Vec<AtnConfig>,
286}
287
288#[derive(Clone, Debug, Eq, PartialEq)]
289struct DfaPredictionInfo {
290 prediction: ParserAtnPrediction,
291 conflicting_alts: Vec<usize>,
292}
293
294#[derive(Clone, Debug, Eq, PartialEq)]
295struct FullContextPrediction {
296 prediction: ParserAtnPrediction,
297 stop_index: usize,
298 resolution: FullContextResolution,
299 semantic_candidates: Vec<CompactParserSemanticCandidate>,
300}
301
302#[derive(Clone, Debug, Eq, PartialEq)]
307enum FullContextResolution {
308 Unique,
309 Ambiguous { exact: bool, alts: Vec<usize> },
310}
311
312fn full_context_prediction(
313 alt: usize,
314 configs: &AtnConfigSet,
315 stop_index: usize,
316 resolution: FullContextResolution,
317) -> FullContextPrediction {
318 FullContextPrediction {
319 prediction: ParserAtnPrediction {
320 alt,
321 requires_full_context: true,
322 has_semantic_context: configs_have_semantic_context_for_alt(configs, alt),
323 diagnostic: None,
324 },
325 stop_index,
326 resolution,
327 semantic_candidates: semantic_prediction_candidates(configs),
328 }
329}
330
331fn semantic_prediction_candidates(configs: &AtnConfigSet) -> Vec<CompactParserSemanticCandidate> {
332 if !configs.has_semantic_context() {
333 return Vec::new();
334 }
335 let mut candidates = configs
336 .configs()
337 .iter()
338 .map(|config| CompactParserSemanticCandidate {
339 alt: config.alt,
340 context: config.semantic_context.clone(),
341 semantic_provenance: config.semantic_provenance_id(),
342 })
343 .collect::<Vec<_>>();
344 candidates.sort();
345 candidates.dedup();
346 candidates
347}
348
349#[derive(Clone, Debug, Eq, Hash, PartialEq)]
350struct ClosureConfigKey {
351 state: usize,
352 alt: usize,
353 semantic_context: SemanticContext,
354 context_and_provenance: u64,
355}
356
357impl From<&AtnConfig> for ClosureConfigKey {
358 fn from(config: &AtnConfig) -> Self {
359 Self {
360 state: config.state,
361 alt: config.alt,
362 semantic_context: config.semantic_context.clone(),
363 context_and_provenance: u64::from(config.context.compact())
364 | (u64::from(config.semantic_provenance_and_flags()) << 32),
365 }
366 }
367}
368
369#[derive(Default)]
376struct ClosureScratch {
377 stack: Vec<(AtnConfig, bool)>,
384 visited: FxHashSet<ClosureConfigKey>,
385}
386
387#[derive(Clone, Copy)]
390struct ClosureParams {
391 precedence: i32,
392 collect_predicates: bool,
393 treat_eof_as_epsilon: bool,
394}
395
396#[derive(Debug)]
397struct LookaheadIntStream {
398 symbols: Vec<i32>,
399 index: usize,
400}
401
402impl LookaheadIntStream {
403 const fn new(symbols: Vec<i32>) -> Self {
404 Self { symbols, index: 0 }
405 }
406}
407
408impl IntStream for LookaheadIntStream {
409 fn consume(&mut self) {
410 if self.la(1) != TOKEN_EOF {
411 self.index += 1;
412 }
413 }
414
415 fn la(&mut self, offset: isize) -> i32 {
416 if offset <= 0 {
417 return 0;
418 }
419 let offset = offset.cast_unsigned() - 1;
420 self.symbols
421 .get(self.index + offset)
422 .copied()
423 .unwrap_or(TOKEN_EOF)
424 }
425
426 fn index(&self) -> usize {
427 self.index
428 }
429
430 fn seek(&mut self, index: usize) {
431 self.index = index.min(self.symbols.len());
432 }
433
434 fn size(&self) -> usize {
435 self.symbols.len()
436 }
437}
438
439fn initial_decision_dfas(atn: &Atn) -> Vec<ParserDfa> {
440 atn.decision_to_state()
441 .iter()
442 .enumerate()
443 .map(|(decision, state)| {
444 let mut dfa = ParserDfa::with_max_token_type(state, decision, atn.max_token_type());
445 if atn
446 .state(state)
447 .is_some_and(AtnState::precedence_rule_decision)
448 {
449 dfa.set_precedence_dfa(true);
450 }
451 dfa
452 })
453 .collect()
454}
455
456fn union_decision_dfas(shared: &mut Vec<ParserDfa>, local: Vec<ParserDfa>) {
466 if shared.len() != local.len() {
467 *shared = local;
468 return;
469 }
470 for (shared_dfa, local_dfa) in shared.iter_mut().zip(local) {
471 union_decision_dfa(shared_dfa, local_dfa);
472 }
473}
474
475fn union_prediction_stores(
476 shared: &mut PredictionStore,
477 mut local: PredictionStore,
478 workspace: &mut PredictionWorkspace,
479) {
480 let remap = shared.contexts.import_all(&local.contexts, workspace);
481 for dfa in &mut local.decision_to_dfa {
482 dfa.remap_contexts(&remap, &shared.contexts);
483 }
484 union_decision_dfas(&mut shared.decision_to_dfa, local.decision_to_dfa);
485}
486
487fn union_decision_dfa(shared: &mut ParserDfa, local: ParserDfa) {
488 if shared.is_precedence_dfa() != local.is_precedence_dfa() {
489 if local.state_count() > shared.state_count() {
492 *shared = local;
493 }
494 return;
495 }
496 let mut renumber = Vec::with_capacity(local.state_count());
501 for state in local.states() {
502 let configs = local.configs(state.id());
503 let number = shared.state_id_for_configs(configs).unwrap_or_else(|| {
504 let missing = local.clone_state_without_edges(state.id());
505 shared.insert_state(missing)
506 });
507 renumber.push(number);
508 }
509 for state in local.states() {
514 let mapped = renumber[state.id().index()];
515 for transition in state.transitions() {
516 let Some(&mapped_target) = renumber.get(transition.target.index()) else {
517 continue;
518 };
519 if shared.edge(mapped, transition.symbol).is_none() {
520 shared.add_edge(mapped, transition.symbol, mapped_target);
521 }
522 }
523 }
524 if shared.start_state().is_none()
525 && let Some(start) = local.start_state()
526 && let Some(&mapped) = renumber.get(start.index())
527 {
528 shared.set_start_state(mapped);
529 }
530 for (precedence, start) in local.precedence_start_states().iter().copied().enumerate() {
531 if start == NO_DFA_STATE {
532 continue;
533 }
534 if shared.precedence_start_state(precedence).is_none()
535 && let Some(&mapped) = renumber.get(start.index())
536 {
537 shared.set_precedence_start_state(precedence, mapped);
538 }
539 }
540}
541
542impl Drop for ParserAtnSimulator<'_> {
543 fn drop(&mut self) {
544 let Some(key) = self.shared_cache_key else {
545 return;
546 };
547 #[cfg(feature = "perf-counters")]
548 let publication_started = std::time::Instant::now();
549 #[cfg(feature = "perf-counters")]
550 let published_states = self
551 .store
552 .decision_to_dfa
553 .iter()
554 .map(ParserDfa::state_count)
555 .sum();
556 let store = std::mem::take(&mut self.store);
562 let published = SHARED_PREDICTION_STORES.with(|cache| {
563 let mut cache = cache.borrow_mut();
564 let shared = cache.entry(key).or_default();
565 if shared.generation != self.shared_cache_generation {
566 return false;
567 }
568 if let Some(shared_store) = shared.store.as_mut() {
569 union_prediction_stores(shared_store, store, &mut self.workspace);
570 } else {
571 shared.store = Some(store);
572 }
573 true
574 });
575 #[cfg(feature = "perf-counters")]
576 if published {
577 crate::perf::record_dfa_cache_publication(
578 publication_started.elapsed().as_nanos(),
579 published_states,
580 );
581 }
582 #[cfg(not(feature = "perf-counters"))]
583 let _ = published;
584 }
585}
586
587impl<'a> ParserAtnSimulator<'a> {
588 pub fn new(atn: &'a Atn) -> Self {
589 Self {
590 atn,
591 store: PredictionStore::new(atn),
592 workspace: PredictionWorkspace::default(),
593 outer_context_cache: None,
594 outer_context_cache_hits: 0,
595 outer_context_cache_misses: 0,
596 deferred_accept_states: FxHashSet::default(),
597 shared_cache_key: None,
598 shared_cache_generation: 0,
599 has_trained_decision: false,
600 measure_adaptive_work: false,
601 adaptive_calls: 0,
602 adaptive_closure_work: 0,
603 exact_ambig_detection: false,
604 full_context_memo: HashMap::default(),
605 full_context_memo_len: 0,
606 full_context_memo_gate: None,
607 prediction_semantic_candidates: Vec::new(),
608 track_prediction_rule_calls: false,
609 semantic_provenance: None,
610 }
611 }
612
613 pub fn reset(&mut self) {
615 self.measure_adaptive_work = false;
616 self.adaptive_calls = 0;
617 self.adaptive_closure_work = 0;
618 self.outer_context_cache = None;
619 self.deferred_accept_states.clear();
620 self.prediction_semantic_candidates.clear();
621 self.workspace.reset();
622 }
623
624 pub fn clear_dfa(&mut self) {
629 self.store = PredictionStore::new(self.atn);
630 if let Some(semantic_provenance) = self.semantic_provenance.as_mut() {
631 **semantic_provenance = PredictionSemanticProvenanceArena::default();
632 }
633 self.full_context_memo.clear();
636 self.full_context_memo_len = 0;
637 self.reset();
638 self.has_trained_decision = false;
639 if let Some(key) = self.shared_cache_key {
640 self.shared_cache_generation = clear_shared_prediction_store(key);
641 }
642 }
643
644 pub fn clear_shared_dfa(atn: &'static Atn) {
646 let ptr: *const Atn = atn;
647 clear_shared_prediction_store(ptr as usize);
648 }
649
650 pub const fn set_exact_ambig_detection(&mut self, exact: bool) {
653 self.exact_ambig_detection = exact;
654 }
655
656 pub fn dump_dfa_java_style(&self, vocabulary: &crate::vocabulary::Vocabulary) -> String {
674 use std::fmt::Write as _;
675 let mut out = String::new();
676 let mut seen_one = false;
677 for dfa in &self.store.decision_to_dfa {
678 if dfa.is_empty() {
679 continue;
680 }
681 if seen_one {
682 out.push('\n');
683 }
684 seen_one = true;
685 let _ = writeln!(out, "Decision {}:", dfa.decision());
686 for state in dfa.states() {
687 let source = dfa_state_display(
688 state,
689 self.deferred_accept_states
690 .contains(&(dfa.decision(), state.id())),
691 );
692 for transition in state.transitions() {
693 let Some(target_state) = dfa.state(transition.target) else {
694 continue;
695 };
696 let label = vocabulary.display_name(transition.symbol);
697 let target = dfa_state_display(
698 target_state,
699 self.deferred_accept_states
700 .contains(&(dfa.decision(), target_state.id())),
701 );
702 let _ = writeln!(out, "{source}-{label}->{target}");
703 }
704 }
705 }
706 out
707 }
708
709 pub fn new_shared(atn: &'static Atn) -> Self {
710 let ptr: *const Atn = atn;
711 let key = ptr as usize;
712 #[cfg(feature = "perf-counters")]
713 let import_started = std::time::Instant::now();
714 let (store, generation) = SHARED_PREDICTION_STORES.with(|cache| {
715 let mut cache = cache.borrow_mut();
716 let shared = cache.entry(key).or_default();
717 (
718 shared
719 .store
720 .take()
721 .unwrap_or_else(|| PredictionStore::new(atn)),
722 shared.generation,
723 )
724 });
725 let has_trained_decision = store.decision_to_dfa.iter().any(|dfa| !dfa.is_empty());
726 #[cfg(feature = "perf-counters")]
727 crate::perf::record_dfa_cache_import(
728 import_started.elapsed().as_nanos(),
729 store
730 .decision_to_dfa
731 .iter()
732 .map(ParserDfa::state_count)
733 .sum(),
734 );
735 Self {
736 atn,
737 store,
738 workspace: PredictionWorkspace::default(),
739 outer_context_cache: None,
740 outer_context_cache_hits: 0,
741 outer_context_cache_misses: 0,
742 deferred_accept_states: FxHashSet::default(),
743 shared_cache_key: Some(key),
744 shared_cache_generation: generation,
745 has_trained_decision,
746 measure_adaptive_work: false,
747 adaptive_calls: 0,
748 adaptive_closure_work: 0,
749 exact_ambig_detection: false,
750 full_context_memo: HashMap::default(),
751 full_context_memo_len: 0,
752 full_context_memo_gate: None,
753 prediction_semantic_candidates: Vec::new(),
754 track_prediction_rule_calls: false,
755 semantic_provenance: None,
756 }
757 }
758
759 pub fn decision_dfas(&self) -> &[ParserDfa] {
760 &self.store.decision_to_dfa
761 }
762
763 pub(crate) fn prediction_semantic_candidates(&self) -> Vec<ParserSemanticCandidate> {
764 self.prediction_semantic_candidates
765 .iter()
766 .map(|candidate| ParserSemanticCandidate {
767 alt: candidate.alt,
768 context: candidate.context.clone(),
769 predicate_calls: self.semantic_provenance.as_deref().map_or_else(
770 Vec::new,
771 |arena| {
772 arena
773 .predicate_calls(candidate.semantic_provenance)
774 .to_vec()
775 },
776 ),
777 })
778 .collect()
779 }
780
781 pub(crate) fn set_track_prediction_rule_calls(&mut self, track: bool) {
782 assert!(
783 self.shared_cache_key.is_none(),
784 "shared prediction simulators use a fixed untracked rule-call mode"
785 );
786 if self.track_prediction_rule_calls != track {
787 assert!(
788 !self.has_trained_decision,
789 "prediction rule-call tracking mode cannot change after DFA construction"
790 );
791 }
792 self.track_prediction_rule_calls = track;
793 if track {
794 self.semantic_provenance
795 .get_or_insert_with(|| Box::new(PredictionSemanticProvenanceArena::default()));
796 } else {
797 self.semantic_provenance = None;
798 }
799 }
800
801 #[doc(hidden)]
807 pub const fn adaptive_prediction_work(&self) -> Option<(usize, usize)> {
808 if self.has_trained_decision {
809 Some((self.adaptive_calls, self.adaptive_closure_work))
810 } else {
811 None
812 }
813 }
814
815 #[doc(hidden)]
818 pub const fn adaptive_prediction_delta_is_expensive(
819 before: (usize, usize),
820 after: (usize, usize),
821 ) -> bool {
822 adaptive_prediction_has_work_density(
823 after.0.saturating_sub(before.0),
824 after.1.saturating_sub(before.1),
825 ADAPTIVE_ATN_PREFERENCE_MIN_CLOSURE_WORK_PER_CALL,
826 )
827 }
828
829 #[doc(hidden)]
833 pub const fn adaptive_prediction_delta_is_decisive(
834 before: (usize, usize),
835 after: (usize, usize),
836 ) -> bool {
837 adaptive_prediction_has_work_density(
838 after.0.saturating_sub(before.0),
839 after.1.saturating_sub(before.1),
840 ADAPTIVE_ATN_PREFERENCE_DECISIVE_CLOSURE_WORK_PER_CALL,
841 )
842 }
843
844 pub fn parser_dfa_stats(&self) -> ParserDfaStats {
846 let mut stats = ParserDfaStats::default();
847 for dfa in &self.store.decision_to_dfa {
848 stats.add_assign(dfa.stats());
849 }
850 stats
851 }
852
853 pub fn prediction_context_stats(&self) -> PredictionContextStats {
856 let mut stats = self.store.contexts.stats();
857 stats.retained_bytes += self.workspace.retained_bytes();
858 stats.workspace_merge_cache_entries = self.workspace.merge_cache_len();
859 stats.workspace_merge_cache_capacity = self.workspace.merge_cache_capacity();
860 stats.workspace_entry_capacity = self.workspace.entry_capacity();
861 stats.outer_context_cache_hits = self.outer_context_cache_hits;
862 stats.outer_context_cache_misses = self.outer_context_cache_misses;
863 stats
864 }
865
866 pub fn intern_prediction_context(
870 &mut self,
871 rule_context_version: usize,
872 return_states: impl IntoIterator<Item = usize>,
873 ) -> ContextId {
874 if let Some(cached) = self.outer_context_cache
875 && cached.rule_context_version == rule_context_version
876 {
877 self.outer_context_cache_hits = self.outer_context_cache_hits.saturating_add(1);
878 return cached.context;
879 }
880 self.outer_context_cache_misses = self.outer_context_cache_misses.saturating_add(1);
881 let mut context = EMPTY_CONTEXT;
882 for return_state in return_states {
883 context = self.store.contexts.singleton(context, return_state);
884 }
885 self.outer_context_cache = Some(CachedOuterContext {
886 rule_context_version,
887 context,
888 });
889 context
890 }
891
892 pub fn adaptive_predict(
893 &mut self,
894 decision: usize,
895 lookahead: impl IntoIterator<Item = i32>,
896 ) -> Result<usize, ParserAtnSimulatorError> {
897 self.adaptive_predict_with_precedence(decision, 0, lookahead)
898 }
899
900 pub fn adaptive_predict_stream<T: IntStream>(
901 &mut self,
902 decision: usize,
903 input: &mut T,
904 ) -> Result<usize, ParserAtnSimulatorError> {
905 self.adaptive_predict_stream_with_precedence(decision, 0, input)
906 }
907
908 pub fn adaptive_predict_stream_with_precedence<T: IntStream>(
909 &mut self,
910 decision: usize,
911 precedence: usize,
912 input: &mut T,
913 ) -> Result<usize, ParserAtnSimulatorError> {
914 self.adaptive_predict_stream_info_with_precedence(decision, precedence, input)
915 .map(|prediction| prediction.alt)
916 }
917
918 pub fn adaptive_predict_stream_info_with_precedence<T: IntStream>(
919 &mut self,
920 decision: usize,
921 precedence: usize,
922 input: &mut T,
923 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
924 let marker = input.mark();
925 let index = input.index();
926 let mut workspace = std::mem::take(&mut self.workspace);
927 workspace.reset();
928 let result = self.adaptive_predict_stream_inner(
929 AdaptivePredictRequest {
930 decision,
931 precedence,
932 outer_context: EMPTY_CONTEXT,
933 force_full_context_retry: false,
934 sll_probe_only: false,
935 },
936 input,
937 &mut workspace,
938 );
939 self.workspace = workspace;
940 input.seek(index);
941 input.release(marker);
942 result
943 }
944
945 pub fn adaptive_predict_stream_info_sll_probe<T: IntStream>(
955 &mut self,
956 decision: usize,
957 precedence: usize,
958 input: &mut T,
959 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
960 let marker = input.mark();
961 let index = input.index();
962 let mut workspace = std::mem::take(&mut self.workspace);
963 workspace.reset();
964 let result = self.adaptive_predict_stream_inner(
965 AdaptivePredictRequest {
966 decision,
967 precedence,
968 outer_context: EMPTY_CONTEXT,
969 force_full_context_retry: false,
970 sll_probe_only: true,
971 },
972 input,
973 &mut workspace,
974 );
975 self.workspace = workspace;
976 input.seek(index);
977 input.release(marker);
978 result
979 }
980
981 pub fn adaptive_predict_stream_info_with_context<T: IntStream>(
982 &mut self,
983 decision: usize,
984 precedence: usize,
985 input: &mut T,
986 outer_context: ContextId,
987 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
988 self.store.contexts.assert_valid(outer_context);
989 let marker = input.mark();
990 let index = input.index();
991 let mut workspace = std::mem::take(&mut self.workspace);
992 workspace.reset();
993 let result = self.adaptive_predict_stream_inner(
994 AdaptivePredictRequest {
995 decision,
996 precedence,
997 outer_context,
998 force_full_context_retry: true,
999 sll_probe_only: false,
1000 },
1001 input,
1002 &mut workspace,
1003 );
1004 self.workspace = workspace;
1005 input.seek(index);
1006 input.release(marker);
1007 result
1008 }
1009
1010 pub fn adaptive_predict_with_precedence(
1011 &mut self,
1012 decision: usize,
1013 precedence: usize,
1014 lookahead: impl IntoIterator<Item = i32>,
1015 ) -> Result<usize, ParserAtnSimulatorError> {
1016 self.adaptive_predict_info_with_precedence(decision, precedence, lookahead)
1017 .map(|prediction| prediction.alt)
1018 }
1019
1020 pub fn adaptive_predict_info_with_precedence(
1021 &mut self,
1022 decision: usize,
1023 precedence: usize,
1024 lookahead: impl IntoIterator<Item = i32>,
1025 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
1026 let mut input = LookaheadIntStream::new(lookahead.into_iter().collect());
1027 self.adaptive_predict_stream_info_with_precedence(decision, precedence, &mut input)
1028 }
1029
1030 fn adaptive_predict_stream_inner<T: IntStream>(
1031 &mut self,
1032 request: AdaptivePredictRequest,
1033 input: &mut T,
1034 merge_cache: &mut PredictionWorkspace,
1035 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
1036 self.prediction_semantic_candidates.clear();
1037 let decision = request.decision;
1038 let learning_revision = self
1039 .store
1040 .decision_to_dfa
1041 .get(decision)
1042 .filter(|dfa| !dfa.is_empty())
1043 .map(ParserDfa::learning_revision);
1044 let work_start = (self.adaptive_calls, self.adaptive_closure_work);
1045 self.measure_adaptive_work = learning_revision.is_some();
1046 if self.measure_adaptive_work {
1047 self.adaptive_calls = self.adaptive_calls.saturating_add(1);
1048 }
1049 let result = self.adaptive_predict_stream_inner_impl(request, input, merge_cache);
1050 self.measure_adaptive_work = false;
1051 if let Some(learning_revision) = learning_revision
1052 && self
1053 .store
1054 .decision_to_dfa
1055 .get(decision)
1056 .map(ParserDfa::learning_revision)
1057 != Some(learning_revision)
1058 {
1059 (self.adaptive_calls, self.adaptive_closure_work) = work_start;
1060 }
1061 self.has_trained_decision |= self
1062 .store
1063 .decision_to_dfa
1064 .get(decision)
1065 .is_some_and(|dfa| !dfa.is_empty());
1066 result
1067 }
1068
1069 fn adaptive_predict_stream_inner_impl<T: IntStream>(
1070 &mut self,
1071 request: AdaptivePredictRequest,
1072 input: &mut T,
1073 merge_cache: &mut PredictionWorkspace,
1074 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
1075 let AdaptivePredictRequest {
1076 decision,
1077 precedence,
1078 outer_context,
1079 force_full_context_retry,
1080 sll_probe_only,
1081 } = request;
1082 self.deferred_accept_states
1083 .retain(|(stored_decision, _)| *stored_decision != decision);
1084 #[cfg(feature = "perf-counters")]
1085 crate::perf::record_adaptive_call(decision, force_full_context_retry);
1086 let Some(decision_state) = self.atn.decision_to_state().get(decision) else {
1087 return Err(ParserAtnSimulatorError::UnknownDecision(decision));
1088 };
1089 let start_index = input.index();
1090 let precedence = i32::try_from(precedence).unwrap_or(i32::MAX);
1096 let mut state_number =
1097 self.ensure_start_state(decision, decision_state, precedence, merge_cache)?;
1098 let track_previous_good_alt = !force_full_context_retry && !sll_probe_only;
1101 let mut previous_good_alt = None;
1102 if let Some(prediction) = self.prediction_or_full_context(
1103 input,
1104 PredictionCheck {
1105 decision,
1106 decision_state,
1107 state_number,
1108 start_index,
1109 precedence,
1110 outer_context,
1111 force_full_context_retry,
1112 sll_probe_only,
1113 },
1114 merge_cache,
1115 )? {
1116 return Ok(prediction);
1117 }
1118 loop {
1119 if track_previous_good_alt {
1120 let finished = self
1121 .store
1122 .decision_to_dfa
1123 .get(decision)
1124 .map(|dfa| dfa.configs(state_number))
1125 .and_then(|configs| self.previous_good_alt(configs));
1126 if finished.is_some() {
1127 previous_good_alt = finished;
1128 }
1129 }
1130 let symbol = input.la(1);
1131 let target = self
1132 .store
1133 .decision_to_dfa
1134 .get(decision)
1135 .and_then(|dfa| dfa.edge(state_number, symbol));
1136 #[cfg(feature = "perf-counters")]
1137 crate::perf::record_dfa_edge_lookup(target.is_some());
1138 if let Some(target) = target {
1139 state_number = target;
1140 } else {
1141 let configs = self
1142 .store
1143 .decision_to_dfa
1144 .get(decision)
1145 .map(|dfa| dfa.configs(state_number).clone())
1146 .ok_or(ParserAtnSimulatorError::MissingDfaState(state_number))?;
1147 let edge = DfaEdge {
1148 decision,
1149 source_state: state_number,
1150 };
1151 let target = match self.compute_target_state(
1152 edge,
1153 &configs,
1154 symbol,
1155 precedence,
1156 merge_cache,
1157 ) {
1158 Ok(target) => target,
1159 Err(ParserAtnSimulatorError::NoViableAlt { symbol, .. }) => {
1160 if let Some(fallback) = previous_good_alt.as_ref() {
1161 self.add_previous_good_alt_target(edge, symbol, fallback, merge_cache)
1162 } else {
1163 return Err(ParserAtnSimulatorError::NoViableAlt {
1164 symbol,
1165 index: input.index(),
1166 });
1167 }
1168 }
1169 Err(error) => return Err(error),
1170 };
1171 state_number = target;
1172 }
1173 if let Some(prediction) = self.prediction_or_full_context(
1174 input,
1175 PredictionCheck {
1176 decision,
1177 decision_state,
1178 state_number,
1179 start_index,
1180 precedence,
1181 outer_context,
1182 force_full_context_retry,
1183 sll_probe_only,
1184 },
1185 merge_cache,
1186 )? {
1187 let defer_unique = track_previous_good_alt
1188 && previous_good_alt.is_some()
1189 && !prediction.requires_full_context
1190 && !self.prediction_reached_decision_entry_rule_stop(
1191 DfaEdge {
1192 decision,
1193 source_state: state_number,
1194 },
1195 prediction.alt,
1196 precedence,
1197 symbol,
1198 merge_cache,
1199 );
1200 if !defer_unique {
1201 return Ok(prediction);
1202 }
1203 self.deferred_accept_states.insert((decision, state_number));
1204 }
1205 if symbol == TOKEN_EOF {
1206 if let Some(configs) = self
1216 .store
1217 .decision_to_dfa
1218 .get(decision)
1219 .map(|dfa| dfa.configs(state_number).clone())
1220 && let Some(alt) = self.alt_that_finished_decision_entry_rule(&configs)
1221 {
1222 self.prediction_semantic_candidates = semantic_prediction_candidates(&configs);
1223 return Ok(ParserAtnPrediction {
1224 alt,
1225 requires_full_context: false,
1226 has_semantic_context: configs_have_semantic_context_for_alt(&configs, alt),
1227 diagnostic: None,
1228 });
1229 }
1230 return Err(ParserAtnSimulatorError::PredictionRequiresMoreLookahead);
1231 }
1232 input.consume();
1233 }
1234 }
1235
1236 fn prediction_or_full_context<T: IntStream>(
1237 &mut self,
1238 input: &mut T,
1239 check: PredictionCheck,
1240 merge_cache: &mut PredictionWorkspace,
1241 ) -> Result<Option<ParserAtnPrediction>, ParserAtnSimulatorError> {
1242 let PredictionCheck {
1243 decision,
1244 decision_state,
1245 state_number,
1246 start_index,
1247 precedence,
1248 outer_context,
1249 force_full_context_retry,
1250 sll_probe_only,
1251 } = check;
1252 if self.store.contexts.is_empty(outer_context)
1253 && let Some(prediction) =
1254 self.non_greedy_exit_prediction(decision, decision_state, state_number)
1255 {
1256 self.record_prediction_semantic_candidates(decision, state_number);
1257 return Ok(Some(prediction));
1258 }
1259 let Some(info) = self.dfa_prediction_info(decision, state_number) else {
1260 return Ok(None);
1261 };
1262 let prediction = info.prediction;
1263 let semantic_candidates = self
1264 .store
1265 .decision_to_dfa
1266 .get(decision)
1267 .map(|dfa| semantic_prediction_candidates(dfa.configs(state_number)))
1268 .unwrap_or_default();
1269 self.prediction_semantic_candidates = semantic_candidates;
1270 if sll_probe_only && prediction.requires_full_context {
1277 return Ok(Some(prediction));
1278 }
1279 if prediction.requires_full_context
1280 && (force_full_context_retry || !prediction.has_semantic_context)
1281 {
1282 #[cfg(feature = "perf-counters")]
1283 crate::perf::record_full_context_retry(decision);
1284 let sll_stop_index = input.index();
1285 input.seek(start_index);
1286 let memo_allowed = self.full_context_memo_allowed();
1287 let memo_key = FullContextMemoKey {
1288 decision,
1289 precedence,
1290 outer_context,
1291 first_symbol: 0,
1292 };
1293 if memo_allowed
1296 && let Some(full_context) = self.probe_full_context_memo(memo_key, input)
1297 {
1298 #[cfg(feature = "perf-counters")]
1299 crate::perf::record_full_context_memo_hit(decision);
1300 return Ok(Some(self.full_context_retry_prediction(
1301 full_context,
1302 info.conflicting_alts,
1303 start_index,
1304 sll_stop_index,
1305 )));
1306 }
1307 let full_context = self.adaptive_predict_full_context(
1308 decision_state,
1309 input,
1310 precedence,
1311 outer_context,
1312 merge_cache,
1313 )?;
1314 if memo_allowed {
1315 self.record_full_context_memo(memo_key, start_index, input, &full_context);
1316 }
1317 return Ok(Some(self.full_context_retry_prediction(
1318 full_context,
1319 info.conflicting_alts,
1320 start_index,
1321 sll_stop_index,
1322 )));
1323 }
1324 Ok(Some(prediction))
1325 }
1326
1327 fn full_context_retry_prediction(
1331 &mut self,
1332 full_context: FullContextPrediction,
1333 sll_conflicting_alts: Vec<usize>,
1334 start_index: usize,
1335 sll_stop_index: usize,
1336 ) -> ParserAtnPrediction {
1337 let FullContextPrediction {
1338 mut prediction,
1339 stop_index,
1340 resolution,
1341 semantic_candidates,
1342 } = full_context;
1343 self.prediction_semantic_candidates = semantic_candidates;
1344 let (kind, exact, conflicting_alts) = match resolution {
1345 FullContextResolution::Ambiguous { exact, ref alts } => (
1346 ParserAtnPredictionDiagnosticKind::Ambiguity,
1347 exact,
1348 alts.clone(),
1349 ),
1350 FullContextResolution::Unique => (
1354 ParserAtnPredictionDiagnosticKind::ContextSensitivity,
1355 false,
1356 sll_conflicting_alts,
1357 ),
1358 };
1359 prediction.has_semantic_context = self
1360 .prediction_semantic_candidates
1361 .iter()
1362 .any(|candidate| candidate.alt == prediction.alt && !candidate.context.is_none());
1363 if conflicting_alts.len() > 1 {
1364 prediction.diagnostic = Some(ParserAtnPredictionDiagnostic {
1365 kind,
1366 start_index,
1367 sll_stop_index,
1368 ll_stop_index: stop_index,
1369 conflicting_alts,
1370 exact,
1371 });
1372 }
1373 prediction
1374 }
1375
1376 fn record_prediction_semantic_candidates(&mut self, decision: usize, state_number: DfaStateId) {
1377 self.prediction_semantic_candidates = self
1378 .store
1379 .decision_to_dfa
1380 .get(decision)
1381 .map(|dfa| semantic_prediction_candidates(dfa.configs(state_number)))
1382 .unwrap_or_default();
1383 }
1384
1385 fn full_context_memo_allowed(&mut self) -> bool {
1402 if self.exact_ambig_detection {
1403 return false;
1404 }
1405 let atn = self.atn;
1406 *self
1407 .full_context_memo_gate
1408 .get_or_insert_with(|| !atn_has_predicate_transition(atn))
1409 }
1410
1411 fn probe_full_context_memo<T: IntStream>(
1422 &self,
1423 mut key: FullContextMemoKey,
1424 input: &mut T,
1425 ) -> Option<FullContextPrediction> {
1426 if self.full_context_memo.is_empty() {
1427 return None;
1428 }
1429 let start_index = input.index();
1430 key.first_symbol = input.la(1);
1431 let entries = self.full_context_memo.get(&key)?;
1432 'candidates: for entry in entries {
1442 for &expected in &entry.window_tail {
1443 input.consume();
1444 if input.la(1) != expected {
1445 input.seek(start_index);
1446 continue 'candidates;
1447 }
1448 }
1449 let mut replay = entry.prediction.clone();
1450 replay.stop_index = input.index();
1451 return Some(replay);
1452 }
1453 None
1454 }
1455
1456 fn record_full_context_memo<T: IntStream>(
1463 &mut self,
1464 mut key: FullContextMemoKey,
1465 start_index: usize,
1466 input: &mut T,
1467 full_context: &FullContextPrediction,
1468 ) {
1469 if self.full_context_memo_len >= FULL_CONTEXT_MEMO_MAX_ENTRIES {
1470 #[cfg(feature = "perf-counters")]
1471 crate::perf::record_full_context_memo_declined(key.decision);
1472 return;
1473 }
1474 let current = input.index();
1475 input.seek(start_index);
1476 key.first_symbol = input.la(1);
1477 let mut window_tail = Vec::new();
1478 while input.index() < full_context.stop_index
1479 && window_tail.len() < FULL_CONTEXT_MEMO_MAX_WINDOW
1480 {
1481 input.consume();
1482 window_tail.push(input.la(1));
1483 }
1484 let complete = input.index() >= full_context.stop_index;
1485 input.seek(current);
1486 if !complete {
1487 #[cfg(feature = "perf-counters")]
1488 crate::perf::record_full_context_memo_declined(key.decision);
1489 return;
1490 }
1491 self.full_context_memo
1492 .entry(key)
1493 .or_default()
1494 .push(FullContextMemoEntry {
1495 window_tail,
1496 prediction: full_context.clone(),
1497 });
1498 self.full_context_memo_len += 1;
1499 }
1500
1501 fn non_greedy_exit_prediction(
1502 &self,
1503 decision: usize,
1504 decision_state: usize,
1505 state_number: DfaStateId,
1506 ) -> Option<ParserAtnPrediction> {
1507 if !self
1508 .atn
1509 .state(decision_state)
1510 .is_some_and(AtnState::non_greedy)
1511 {
1512 return None;
1513 }
1514 let configs = &self
1515 .store
1516 .decision_to_dfa
1517 .get(decision)?
1518 .configs(state_number);
1519 let alt = configs
1520 .configs()
1521 .iter()
1522 .filter(|config| {
1523 self.atn
1524 .state(config.state)
1525 .is_some_and(AtnState::is_rule_stop)
1526 && self.store.contexts.has_empty_path(config.context)
1527 })
1528 .map(|config| config.alt)
1529 .min()?;
1530 Some(ParserAtnPrediction {
1531 alt,
1532 requires_full_context: false,
1533 has_semantic_context: configs_have_semantic_context_for_alt(configs, alt),
1534 diagnostic: None,
1535 })
1536 }
1537
1538 fn ensure_start_state(
1539 &mut self,
1540 decision: usize,
1541 decision_state: usize,
1542 precedence: i32,
1543 merge_cache: &mut PredictionWorkspace,
1544 ) -> Result<DfaStateId, ParserAtnSimulatorError> {
1545 if self.store.decision_to_dfa[decision].is_precedence_dfa() {
1546 let precedence_key = usize::try_from(precedence.max(0)).unwrap_or_default();
1547 if let Some(start) =
1548 self.store.decision_to_dfa[decision].precedence_start_state(precedence_key)
1549 {
1550 return Ok(start);
1551 }
1552 } else if let Some(start) = self.store.decision_to_dfa[decision].start_state() {
1553 return Ok(start);
1554 }
1555 let decision_state = self
1556 .atn
1557 .state(decision_state)
1558 .ok_or(ParserAtnSimulatorError::MissingAtnState(decision_state))?;
1559 let configs = self.compute_start_state(decision_state, precedence, merge_cache);
1560 let state_number = self.add_dfa_state(decision, DfaStateBuilder::new(configs));
1561 if self.store.decision_to_dfa[decision].is_precedence_dfa() {
1562 let precedence_key = usize::try_from(precedence.max(0)).unwrap_or_default();
1563 self.store.decision_to_dfa[decision]
1564 .set_precedence_start_state(precedence_key, state_number);
1565 } else {
1566 self.store.decision_to_dfa[decision].set_start_state(state_number);
1567 }
1568 Ok(state_number)
1569 }
1570
1571 fn add_dfa_state(&mut self, decision: usize, state: DfaStateBuilder) -> DfaStateId {
1572 self.store.decision_to_dfa[decision].add_state(state)
1573 }
1574
1575 fn compute_start_state(
1576 &mut self,
1577 decision_state: AtnState<'_>,
1578 precedence: i32,
1579 merge_cache: &mut PredictionWorkspace,
1580 ) -> AtnConfigSet {
1581 self.compute_start_state_with_context(
1582 decision_state,
1583 false,
1584 EMPTY_CONTEXT,
1585 precedence,
1586 merge_cache,
1587 )
1588 }
1589
1590 fn compute_start_state_with_context(
1591 &mut self,
1592 decision_state: AtnState<'_>,
1593 full_context: bool,
1594 initial_context: ContextId,
1595 precedence: i32,
1596 merge_cache: &mut PredictionWorkspace,
1597 ) -> AtnConfigSet {
1598 let mut configs = AtnConfigSet::new_full_context(full_context);
1599 let mut scratch = ClosureScratch::default();
1600 let params = ClosureParams {
1601 precedence,
1602 collect_predicates: true,
1603 treat_eof_as_epsilon: false,
1604 };
1605 for (index, transition) in decision_state.transitions().iter().enumerate() {
1606 let alt = index + 1;
1607 let config = AtnConfig::new(
1608 transition.target(),
1609 alt,
1610 initial_context,
1611 &self.store.contexts,
1612 );
1613 self.closure(config, &mut configs, merge_cache, &mut scratch, params);
1614 }
1615 configs
1616 }
1617
1618 fn adaptive_predict_full_context<T: IntStream>(
1619 &mut self,
1620 decision_state: usize,
1621 input: &mut T,
1622 precedence: i32,
1623 outer_context: ContextId,
1624 merge_cache: &mut PredictionWorkspace,
1625 ) -> Result<FullContextPrediction, ParserAtnSimulatorError> {
1626 let decision_state = self
1627 .atn
1628 .state(decision_state)
1629 .ok_or(ParserAtnSimulatorError::MissingAtnState(decision_state))?;
1630 let mut configs = self.compute_start_state_with_context(
1631 decision_state,
1632 true,
1633 outer_context,
1634 precedence,
1635 merge_cache,
1636 );
1637 loop {
1645 if let Some(alt) = configs.unique_alt() {
1646 return Ok(full_context_prediction(
1647 alt,
1648 &configs,
1649 input.index(),
1650 FullContextResolution::Unique,
1651 ));
1652 }
1653 let symbol = input.la(1);
1654 let reach = self.compute_reach_set(&configs, symbol, true, precedence, merge_cache);
1655 if reach.is_empty() {
1656 return Err(ParserAtnSimulatorError::NoViableAlt {
1657 symbol,
1658 index: input.index(),
1659 });
1660 }
1661 configs = reach;
1662 if let Some(alt) = configs.unique_alt() {
1663 return Ok(full_context_prediction(
1664 alt,
1665 &configs,
1666 input.index(),
1667 FullContextResolution::Unique,
1668 ));
1669 }
1670 if !configs.has_semantic_context() {
1671 let subsets = conflicting_alt_subsets(configs.configs());
1672 if self.exact_ambig_detection {
1673 let alts: Vec<usize> = configs.alts().into_iter().collect();
1674 if all_subsets_conflict(&subsets)
1678 && all_subsets_equal(&subsets)
1679 && let Some(&alt) = alts.first()
1680 {
1681 return Ok(full_context_prediction(
1682 alt,
1683 &configs,
1684 input.index(),
1685 FullContextResolution::Ambiguous { exact: true, alts },
1686 ));
1687 }
1688 } else if let Some(alt) = single_viable_alt(&subsets) {
1689 let alts: Vec<usize> = configs.alts().into_iter().collect();
1690 return Ok(full_context_prediction(
1691 alt,
1692 &configs,
1693 input.index(),
1694 FullContextResolution::Ambiguous { exact: false, alts },
1695 ));
1696 }
1697 }
1698 if symbol == TOKEN_EOF || self.configs_all_reached_rule_stop(&configs) {
1699 let alts: Vec<usize> = configs.alts().into_iter().collect();
1704 let alt = *alts
1705 .first()
1706 .ok_or(ParserAtnSimulatorError::PredictionRequiresMoreLookahead)?;
1707 let resolution = if alts.len() > 1 {
1708 FullContextResolution::Ambiguous {
1709 exact: self.exact_ambig_detection,
1710 alts,
1711 }
1712 } else {
1713 FullContextResolution::Unique
1714 };
1715 return Ok(full_context_prediction(
1716 alt,
1717 &configs,
1718 input.index(),
1719 resolution,
1720 ));
1721 }
1722 input.consume();
1723 }
1724 }
1725
1726 fn compute_target_state(
1727 &mut self,
1728 edge: DfaEdge,
1729 configs: &AtnConfigSet,
1730 symbol: i32,
1731 precedence: i32,
1732 merge_cache: &mut PredictionWorkspace,
1733 ) -> Result<DfaStateId, ParserAtnSimulatorError> {
1734 let mut reach = self.compute_reach_set(configs, symbol, false, precedence, merge_cache);
1735 if reach.is_empty() {
1736 if let Some(prediction) = self.alt_that_finished_decision_entry_rule(configs) {
1737 let mut dfa_state = DfaStateBuilder::new(configs.clone());
1738 dfa_state.mark_accept(prediction);
1739 dfa_state.set_has_semantic_context_for_alt(
1742 configs.has_semantic_context()
1743 && configs_have_semantic_context_for_alt(configs, prediction),
1744 );
1745 let target_state = self.add_dfa_state(edge.decision, dfa_state);
1746 self.store.decision_to_dfa[edge.decision].add_edge(
1747 edge.source_state,
1748 symbol,
1749 target_state,
1750 );
1751 return Ok(target_state);
1752 }
1753 return Err(ParserAtnSimulatorError::NoViableAlt { symbol, index: 0 });
1754 }
1755 let prediction = reach.unique_alt();
1756 let conflict_prediction = prediction.or_else(|| {
1757 if !has_sll_conflict_terminating_prediction(&reach, |state| {
1758 self.atn.state(state).is_some_and(AtnState::is_rule_stop)
1759 }) {
1760 return None;
1761 }
1762 reach
1763 .conflicting_alts()
1764 .into_iter()
1765 .next()
1766 .or_else(|| reach.alts().into_iter().next())
1767 });
1768 let requires_full_context = prediction.is_none() && conflict_prediction.is_some();
1769 #[cfg(feature = "perf-counters")]
1770 if requires_full_context {
1771 crate::perf::record_sll_conflict(edge.decision);
1772 }
1773 let conflicting_alts = if requires_full_context {
1774 let alts = reach.conflicting_alts();
1775 if alts.is_empty() { reach.alts() } else { alts }
1776 .into_iter()
1777 .collect()
1778 } else {
1779 Vec::new()
1780 };
1781 let mut dfa_state = DfaStateBuilder::new(reach);
1782 if let Some(prediction) = conflict_prediction {
1783 dfa_state.mark_accept(prediction);
1784 dfa_state.set_requires_full_context(requires_full_context);
1785 dfa_state.set_conflicting_alts(conflicting_alts);
1786 dfa_state.set_has_semantic_context_for_alt(
1789 dfa_state.configs.has_semantic_context()
1790 && configs_have_semantic_context_for_alt(&dfa_state.configs, prediction),
1791 );
1792 }
1793 let target_state = self.add_dfa_state(edge.decision, dfa_state);
1794 self.store.decision_to_dfa[edge.decision].add_edge(edge.source_state, symbol, target_state);
1795 Ok(target_state)
1796 }
1797
1798 fn compute_reach_set(
1799 &mut self,
1800 configs: &AtnConfigSet,
1801 symbol: i32,
1802 full_context: bool,
1803 precedence: i32,
1804 merge_cache: &mut PredictionWorkspace,
1805 ) -> AtnConfigSet {
1806 let mut intermediate = AtnConfigSet::new_full_context(full_context);
1807 let mut skipped_stop_states = Vec::new();
1808 let max_token_type = self.atn.max_token_type();
1809 for config in configs.configs() {
1810 let Some(state) = self.atn.state(config.state) else {
1811 continue;
1812 };
1813 if state.is_rule_stop() {
1814 if full_context || symbol == TOKEN_EOF {
1815 skipped_stop_states.push(config.clone());
1816 }
1817 continue;
1818 }
1819 for transition in &state.transitions() {
1820 if transition.matches(symbol, 1, max_token_type) {
1821 let target =
1822 config.moved_to(transition.target(), config.context, &self.store.contexts);
1823 intermediate.add(target, &mut self.store.contexts, merge_cache);
1824 }
1825 }
1826 }
1827 let mut reach = if skipped_stop_states.is_empty() && symbol != TOKEN_EOF {
1828 if intermediate.len() == 1 || intermediate.unique_alt().is_some() {
1829 intermediate
1830 } else {
1831 self.close_intermediate_reach_set(
1832 intermediate,
1833 full_context,
1834 precedence,
1835 symbol,
1836 merge_cache,
1837 )
1838 }
1839 } else {
1840 self.close_intermediate_reach_set(
1841 intermediate,
1842 full_context,
1843 precedence,
1844 symbol,
1845 merge_cache,
1846 )
1847 };
1848 if symbol == TOKEN_EOF {
1849 reach = self.rule_stop_configs(reach, merge_cache);
1850 }
1851 if !full_context || !self.configs_contain_rule_stop(&reach) {
1852 for config in skipped_stop_states {
1853 reach.add(config, &mut self.store.contexts, merge_cache);
1854 }
1855 }
1856 #[cfg(feature = "perf-counters")]
1857 crate::perf::record_reach_set(full_context, configs.len(), reach.len());
1858 reach
1859 }
1860
1861 fn close_intermediate_reach_set(
1862 &mut self,
1863 intermediate: AtnConfigSet,
1864 full_context: bool,
1865 precedence: i32,
1866 symbol: i32,
1867 merge_cache: &mut PredictionWorkspace,
1868 ) -> AtnConfigSet {
1869 let mut reach = AtnConfigSet::new_full_context(full_context);
1870 let mut scratch = ClosureScratch::default();
1871 let params = ClosureParams {
1872 precedence,
1873 collect_predicates: false,
1874 treat_eof_as_epsilon: symbol == TOKEN_EOF,
1875 };
1876 for config in intermediate.into_configs() {
1879 self.closure(config, &mut reach, merge_cache, &mut scratch, params);
1880 }
1881 reach
1882 }
1883
1884 fn alt_that_finished_decision_entry_rule(&self, configs: &AtnConfigSet) -> Option<usize> {
1885 configs
1886 .configs()
1887 .iter()
1888 .filter(|config| self.config_finished_decision_entry_rule(config))
1889 .map(|config| config.alt)
1890 .min()
1891 }
1892
1893 fn previous_good_alt(&self, configs: &AtnConfigSet) -> Option<PreviousGoodAlt> {
1894 let alt = self.alt_that_finished_decision_entry_rule(configs)?;
1895 let configs = configs
1896 .configs()
1897 .iter()
1898 .filter(|config| config.alt == alt && self.config_finished_decision_entry_rule(config))
1899 .cloned()
1900 .collect();
1901 Some(PreviousGoodAlt { alt, configs })
1902 }
1903
1904 fn config_finished_decision_entry_rule(&self, config: &AtnConfig) -> bool {
1905 config.reaches_into_outer_context > 0
1906 || self
1907 .atn
1908 .state(config.state)
1909 .is_some_and(AtnState::is_rule_stop)
1910 && self.store.contexts.has_empty_path(config.context)
1911 }
1912
1913 fn add_previous_good_alt_target(
1914 &mut self,
1915 edge: DfaEdge,
1916 symbol: i32,
1917 fallback: &PreviousGoodAlt,
1918 merge_cache: &mut PredictionWorkspace,
1919 ) -> DfaStateId {
1920 let mut configs = AtnConfigSet::new();
1921 for config in &fallback.configs {
1922 configs.add(config.clone(), &mut self.store.contexts, merge_cache);
1923 }
1924 let has_semantic_context = configs_have_semantic_context_for_alt(&configs, fallback.alt);
1925 let mut state = DfaStateBuilder::new(configs);
1926 state.mark_accept(fallback.alt);
1927 state.set_has_semantic_context_for_alt(has_semantic_context);
1928 let target = self.add_dfa_state(edge.decision, state);
1929 self.store.decision_to_dfa[edge.decision].add_edge(edge.source_state, symbol, target);
1930 target
1931 }
1932
1933 fn prediction_reached_decision_entry_rule_stop(
1934 &mut self,
1935 edge: DfaEdge,
1936 alt: usize,
1937 precedence: i32,
1938 symbol: i32,
1939 merge_cache: &mut PredictionWorkspace,
1940 ) -> bool {
1941 let configs = self.store.decision_to_dfa[edge.decision]
1942 .configs(edge.source_state)
1943 .clone();
1944 if self.alt_that_finished_decision_entry_rule(&configs) == Some(alt) {
1945 return true;
1946 }
1947 let closed =
1948 self.close_intermediate_reach_set(configs, false, precedence, symbol, merge_cache);
1949 self.alt_that_finished_decision_entry_rule(&closed) == Some(alt)
1950 }
1951
1952 fn rule_stop_configs(
1953 &mut self,
1954 configs: AtnConfigSet,
1955 merge_cache: &mut PredictionWorkspace,
1956 ) -> AtnConfigSet {
1957 if configs.configs().iter().all(|config| {
1958 self.atn
1959 .state(config.state)
1960 .is_some_and(AtnState::is_rule_stop)
1961 }) {
1962 return configs;
1963 }
1964 let mut result = AtnConfigSet::new_full_context(configs.full_context());
1965 for config in configs.configs().iter().filter(|config| {
1966 self.atn
1967 .state(config.state)
1968 .is_some_and(AtnState::is_rule_stop)
1969 }) {
1970 result.add(config.clone(), &mut self.store.contexts, merge_cache);
1971 }
1972 result
1973 }
1974
1975 fn configs_all_reached_rule_stop(&self, configs: &AtnConfigSet) -> bool {
1976 configs.configs().iter().all(|config| {
1977 self.atn
1978 .state(config.state)
1979 .is_some_and(AtnState::is_rule_stop)
1980 })
1981 }
1982
1983 fn configs_contain_rule_stop(&self, configs: &AtnConfigSet) -> bool {
1984 configs.configs().iter().any(|config| {
1985 self.atn
1986 .state(config.state)
1987 .is_some_and(AtnState::is_rule_stop)
1988 })
1989 }
1990
1991 fn closure(
1992 &mut self,
1993 config: AtnConfig,
1994 configs: &mut AtnConfigSet,
1995 merge_cache: &mut PredictionWorkspace,
1996 scratch: &mut ClosureScratch,
1997 params: ClosureParams,
1998 ) {
1999 let ClosureParams {
2000 precedence,
2001 collect_predicates,
2002 treat_eof_as_epsilon,
2003 } = params;
2004 let max_token_type = self.atn.max_token_type();
2005 scratch.stack.clear();
2006 scratch.visited.clear();
2007 scratch.stack.push((config, collect_predicates));
2008 while let Some((config, collect_predicates)) = scratch.stack.pop() {
2009 if !scratch.visited.insert(ClosureConfigKey::from(&config)) {
2010 continue;
2011 }
2012 let Some(state) = self.atn.state(config.state) else {
2013 continue;
2014 };
2015 let at_rule_stop = state.is_rule_stop();
2016 if at_rule_stop
2017 && self.closure_at_rule_stop(
2018 config.clone(),
2019 collect_predicates,
2020 configs,
2021 merge_cache,
2022 &mut scratch.stack,
2023 )
2024 {
2025 continue;
2026 }
2027 let epsilon_only = state.epsilon_only();
2028 if !epsilon_only {
2029 configs.add(config.clone(), &mut self.store.contexts, merge_cache);
2030 }
2031 for (index, transition) in state.transitions().iter().enumerate() {
2032 if index == 0
2033 && can_drop_left_recursive_loop_entry_edge(
2034 self.atn,
2035 state,
2036 &self.store.contexts,
2037 config.context,
2038 )
2039 {
2040 continue;
2041 }
2042 let transition_kind = transition.kind();
2043 if matches!(
2044 transition_kind,
2045 ParserTransitionKind::Epsilon
2046 | ParserTransitionKind::Rule
2047 | ParserTransitionKind::Predicate
2048 | ParserTransitionKind::Action
2049 | ParserTransitionKind::Precedence
2050 ) {
2051 if let Some(mut target) = self.epsilon_target_config(
2052 &config,
2053 transition,
2054 transition_kind,
2055 precedence,
2056 collect_predicates,
2057 configs.full_context(),
2058 ) {
2059 if at_rule_stop {
2060 target.reaches_into_outer_context =
2061 target.reaches_into_outer_context.saturating_add(1);
2062 }
2063 let target_collect_predicates =
2067 collect_predicates && transition_kind != ParserTransitionKind::Action;
2068 scratch.stack.push((target, target_collect_predicates));
2069 }
2070 } else if treat_eof_as_epsilon
2071 && transition.matches_kind(transition_kind, TOKEN_EOF, 1, max_token_type)
2072 {
2073 scratch.stack.push((
2074 config.moved_to(transition.target(), config.context, &self.store.contexts),
2075 collect_predicates,
2076 ));
2077 }
2078 }
2079 }
2080 let closure_work = scratch.visited.len();
2081 if self.measure_adaptive_work {
2082 self.adaptive_closure_work = self.adaptive_closure_work.saturating_add(closure_work);
2083 }
2084 #[cfg(feature = "perf-counters")]
2085 crate::perf::record_closure(closure_work);
2086 }
2087
2088 fn closure_at_rule_stop(
2089 &mut self,
2090 config: AtnConfig,
2091 collect_predicates: bool,
2092 configs: &mut AtnConfigSet,
2093 merge_cache: &mut PredictionWorkspace,
2094 stack: &mut Vec<(AtnConfig, bool)>,
2095 ) -> bool {
2096 if self.store.contexts.is_empty(config.context) {
2097 if configs.full_context() {
2098 configs.add(config, &mut self.store.contexts, merge_cache);
2099 return true;
2100 }
2101 return false;
2102 }
2103 let mut handled_all_paths = true;
2104 for index in 0..self.store.contexts.len(config.context) {
2105 let Some(return_state) = self.store.contexts.return_state(config.context, index) else {
2106 continue;
2107 };
2108 if return_state == EMPTY_RETURN_STATE {
2109 if configs.full_context() {
2110 let mut empty_context_config = config.clone();
2111 empty_context_config.set_context(EMPTY_CONTEXT, &self.store.contexts);
2112 configs.add(empty_context_config, &mut self.store.contexts, merge_cache);
2113 } else {
2114 handled_all_paths = false;
2115 }
2116 continue;
2117 }
2118 let parent = self
2119 .store
2120 .contexts
2121 .parent(config.context, index)
2122 .unwrap_or(EMPTY_CONTEXT);
2123 let mut next = config.moved_to(return_state, parent, &self.store.contexts);
2124 if self.track_prediction_rule_calls {
2125 next.exit_prediction_rule(
2126 self.semantic_provenance
2127 .as_deref_mut()
2128 .expect("tracked prediction has a provenance arena"),
2129 );
2130 }
2131 stack.push((next, collect_predicates));
2132 }
2133 handled_all_paths
2134 }
2135
2136 #[allow(clippy::too_many_arguments)]
2137 fn epsilon_target_config(
2138 &mut self,
2139 config: &AtnConfig,
2140 transition: ParserTransition<'_>,
2141 transition_kind: ParserTransitionKind,
2142 precedence: i32,
2143 collect_predicates: bool,
2144 full_context: bool,
2145 ) -> Option<AtnConfig> {
2146 let semantic_context = match transition_kind {
2147 ParserTransitionKind::Predicate if collect_predicates => SemanticContext::and(
2148 config.semantic_context.clone(),
2149 SemanticContext::Predicate {
2150 rule_index: transition.arg0() as usize,
2151 pred_index: transition.arg1() as usize,
2152 context_dependent: transition.arg2() != 0,
2153 },
2154 ),
2155 ParserTransitionKind::Precedence
2156 if collect_predicates
2157 && i32::from_le_bytes(transition.arg0().to_le_bytes()) < precedence =>
2158 {
2159 return None;
2160 }
2161 ParserTransitionKind::Precedence if collect_predicates && !full_context => {
2162 SemanticContext::and(
2163 config.semantic_context.clone(),
2164 SemanticContext::Precedence {
2165 precedence: i32::from_le_bytes(transition.arg0().to_le_bytes()),
2166 },
2167 )
2168 }
2169 _ => config.semantic_context.clone(),
2170 };
2171 let context = if transition_kind == ParserTransitionKind::Rule {
2172 self.store
2173 .contexts
2174 .singleton(config.context, transition.arg1() as usize)
2175 } else {
2176 config.context
2177 };
2178 let mut target = config.moved_to(transition.target(), context, &self.store.contexts);
2179 target.semantic_context = semantic_context;
2180 if self.track_prediction_rule_calls {
2181 match transition_kind {
2182 ParserTransitionKind::Rule => {
2183 target.enter_prediction_rule(
2184 self.semantic_provenance
2185 .as_deref_mut()
2186 .expect("tracked prediction has a provenance arena"),
2187 config.state,
2188 transition.arg0() as usize,
2189 );
2190 }
2191 ParserTransitionKind::Predicate if collect_predicates => {
2192 target.record_prediction_predicate(
2193 self.semantic_provenance
2194 .as_deref_mut()
2195 .expect("tracked prediction has a provenance arena"),
2196 transition.arg0() as usize,
2197 transition.arg1() as usize,
2198 );
2199 }
2200 _ => {}
2201 }
2202 }
2203 Some(target)
2204 }
2205
2206 fn dfa_prediction_info(
2207 &self,
2208 decision: usize,
2209 state_number: DfaStateId,
2210 ) -> Option<DfaPredictionInfo> {
2211 let dfa = self.store.decision_to_dfa.get(decision)?;
2212 let state = dfa.state(state_number)?;
2213 let alt = state.prediction()?;
2214 let requires_full_context = state.requires_full_context();
2215 let conflicting_alts = if requires_full_context {
2216 let stored = dfa.conflicting_alts(state_number);
2217 if stored.is_empty() {
2218 dfa.configs(state_number).alts().into_iter().collect()
2219 } else {
2220 stored.to_vec()
2221 }
2222 } else {
2223 Vec::new()
2224 };
2225 Some(DfaPredictionInfo {
2226 prediction: ParserAtnPrediction {
2227 alt,
2228 requires_full_context,
2229 has_semantic_context: state.has_semantic_context(),
2232 diagnostic: None,
2233 },
2234 conflicting_alts,
2235 })
2236 }
2237}
2238
2239pub(crate) fn can_drop_left_recursive_loop_entry_edge(
2242 atn: &Atn,
2243 state: AtnState<'_>,
2244 contexts: &ContextArena,
2245 context: ContextId,
2246) -> bool {
2247 if state.kind() != AtnStateKind::StarLoopEntry
2248 || !state.precedence_rule_decision()
2249 || contexts.is_empty(context)
2250 || contexts.has_empty_path(context)
2251 {
2252 return false;
2253 }
2254 let Some(rule_index) = state.rule_index() else {
2255 return false;
2256 };
2257 for index in 0..contexts.len(context) {
2258 let Some(return_state_number) = contexts.return_state(context, index) else {
2259 return false;
2260 };
2261 let Some(return_state) = atn.state(return_state_number) else {
2262 return false;
2263 };
2264 if return_state.rule_index() != Some(rule_index) {
2265 return false;
2266 }
2267 }
2268 let Some(block_end_state_number) = state
2269 .transitions()
2270 .first()
2271 .and_then(|transition| atn.state(transition.target()))
2272 .and_then(AtnState::end_state)
2273 else {
2274 return false;
2275 };
2276 for index in 0..contexts.len(context) {
2277 let return_state_number = contexts
2278 .return_state(context, index)
2279 .expect("return state checked above");
2280 let return_state = atn
2281 .state(return_state_number)
2282 .expect("return state checked above");
2283 if return_state.state_number() == block_end_state_number {
2284 continue;
2285 }
2286 if return_state.transitions().len() != 1
2287 || !return_state
2288 .transitions()
2289 .first()
2290 .is_some_and(ParserTransition::is_epsilon)
2291 {
2292 return false;
2293 }
2294 let return_target = return_state
2295 .transitions()
2296 .first()
2297 .expect("single transition checked above")
2298 .target();
2299 if return_state.kind() == AtnStateKind::BlockEnd && return_target == state.state_number() {
2300 continue;
2301 }
2302 if return_target == block_end_state_number {
2303 continue;
2304 }
2305 let Some(return_target_state) = atn.state(return_target) else {
2306 return false;
2307 };
2308 if return_target_state.kind() == AtnStateKind::BlockEnd
2309 && return_target_state.transitions().len() == 1
2310 && return_target_state
2311 .transitions()
2312 .first()
2313 .is_some_and(ParserTransition::is_epsilon)
2314 && return_target_state
2315 .transitions()
2316 .first()
2317 .is_some_and(|transition| transition.target() == state.state_number())
2318 {
2319 continue;
2320 }
2321 return false;
2322 }
2323 true
2324}
2325
2326fn configs_have_semantic_context_for_alt(configs: &AtnConfigSet, alt: usize) -> bool {
2327 configs
2328 .configs()
2329 .iter()
2330 .any(|config| config.alt == alt && !config.semantic_context.is_none())
2331}
2332
2333#[derive(Clone, Debug, Eq, PartialEq)]
2334pub enum ParserAtnSimulatorError {
2335 MissingAtnState(usize),
2336 MissingDfaState(DfaStateId),
2337 NoViableAlt { symbol: i32, index: usize },
2338 PredictionRequiresMoreLookahead,
2339 UnknownDecision(usize),
2340}
2341
2342fn dfa_state_display(state: ParserDfaStateView<'_>, deferred: bool) -> String {
2344 let mut out = String::new();
2345 let is_accept = state.is_accept_state() && !deferred;
2346 if is_accept {
2347 out.push(':');
2348 }
2349 out.push('s');
2350 out.push_str(&state.id().index().to_string());
2351 if state.requires_full_context() {
2352 out.push('^');
2353 }
2354 if is_accept {
2355 out.push_str("=>");
2356 out.push_str(
2357 &state
2358 .prediction()
2359 .map(|prediction| prediction.to_string())
2360 .unwrap_or_default(),
2361 );
2362 }
2363 out
2364}
2365
2366#[cfg(test)]
2367#[allow(clippy::disallowed_methods)] mod tests {
2369 use super::*;
2370 use crate::atn::AtnStateKind;
2371 use std::mem::size_of;
2372
2373 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
2374 builder.finish().expect("valid packed parser ATN")
2375 }
2376
2377 #[cfg(target_pointer_width = "64")]
2378 #[test]
2379 fn parser_prediction_hot_path_layouts_stay_compact() {
2380 assert!(size_of::<ClosureConfigKey>() <= 56);
2381 assert!(size_of::<CompactParserSemanticCandidate>() <= 48);
2382 }
2383
2384 #[test]
2385 fn union_decision_dfa_preserves_disjoint_coverage() {
2386 fn configs(
2387 atn_state: usize,
2388 arena: &mut ContextArena,
2389 workspace: &mut PredictionWorkspace,
2390 ) -> AtnConfigSet {
2391 let mut set = AtnConfigSet::new();
2392 set.add(
2393 AtnConfig::new(atn_state, 1, EMPTY_CONTEXT, arena),
2394 arena,
2395 workspace,
2396 );
2397 set
2398 }
2399 fn state(
2400 atn_state: usize,
2401 arena: &mut ContextArena,
2402 workspace: &mut PredictionWorkspace,
2403 ) -> DfaStateBuilder {
2404 DfaStateBuilder::new(configs(atn_state, arena, workspace))
2405 }
2406 let mut arena = ContextArena::new();
2407 let mut workspace = PredictionWorkspace::default();
2408
2409 let mut shared = ParserDfa::with_max_token_type(0, 0, 8);
2413 let shared_root = shared.add_state(state(10, &mut arena, &mut workspace));
2414 let shared_a = shared.add_state(state(11, &mut arena, &mut workspace));
2415 shared.add_edge(shared_root, 1, shared_a);
2416 shared.set_start_state(shared_root);
2417
2418 let mut local = ParserDfa::with_max_token_type(0, 0, 8);
2419 let local_b = local.add_state(state(12, &mut arena, &mut workspace));
2420 let local_root = local.add_state(state(10, &mut arena, &mut workspace));
2421 local.add_edge(local_root, 2, local_b);
2422 local.set_precedence_start_state(3, local_root);
2423
2424 union_decision_dfa(&mut shared, local);
2425
2426 assert_eq!(shared.edge(shared_root, 1), Some(shared_a));
2429 let merged_b = shared
2430 .state_id_for_configs(&configs(12, &mut arena, &mut workspace))
2431 .expect("local-only state adopted");
2432 assert_eq!(shared.edge(shared_root, 2), Some(merged_b));
2433 assert_eq!(shared.states().len(), 3);
2434 assert_eq!(shared.start_state(), Some(shared_root));
2436 assert_eq!(shared.precedence_start_state(3), Some(shared_root));
2437 }
2438
2439 #[test]
2440 fn union_prediction_stores_remaps_context_ids_before_dfa_union() {
2441 let atn = two_token_decision_atn();
2442 let mut shared = PredictionStore::new(&atn);
2443 let mut local = PredictionStore::new(&atn);
2444 let mut workspace = PredictionWorkspace::default();
2445
2446 let distracting = shared.contexts.singleton(EMPTY_CONTEXT, 99);
2447 let local_context = local.contexts.singleton(EMPTY_CONTEXT, 7);
2448 assert_eq!(distracting, local_context, "both stores allocate ID 1");
2449
2450 let mut configs = AtnConfigSet::new();
2451 configs.add(
2452 AtnConfig::new(42, 1, local_context, &local.contexts),
2453 &mut local.contexts,
2454 &mut workspace,
2455 );
2456 local.decision_to_dfa[0].add_state(DfaStateBuilder::new(configs));
2457
2458 union_prediction_stores(&mut shared, local, &mut workspace);
2459
2460 let imported = shared.decision_to_dfa[0]
2461 .states()
2462 .flat_map(|state| shared.decision_to_dfa[0].configs(state.id()).configs())
2463 .find(|config| config.state == 42)
2464 .expect("local DFA config imported");
2465 assert_ne!(imported.context, local_context);
2466 assert_eq!(shared.contexts.return_state(imported.context, 0), Some(7));
2467 imported.assert_store(&shared.contexts);
2468 }
2469
2470 #[test]
2471 fn outer_context_cache_invalidates_with_rule_context_version() {
2472 let atn = two_token_decision_atn();
2473 let mut simulator = ParserAtnSimulator::new(&atn);
2474
2475 let first = simulator.intern_prediction_context(1, [7]);
2476 let cached = simulator.intern_prediction_context(1, [99]);
2477 let refreshed = simulator.intern_prediction_context(2, [99]);
2478
2479 assert_eq!(cached, first);
2480 assert_ne!(refreshed, first);
2481 assert_eq!(
2482 simulator.store.contexts.return_state(refreshed, 0),
2483 Some(99)
2484 );
2485 let stats = simulator.prediction_context_stats();
2486 assert_eq!(stats.outer_context_cache_hits, 1);
2487 assert_eq!(stats.outer_context_cache_misses, 2);
2488 }
2489
2490 #[test]
2491 fn outer_context_cache_is_simulator_local() {
2492 let atn = two_token_decision_atn();
2493 let mut first = ParserAtnSimulator::new(&atn);
2494 let mut second = ParserAtnSimulator::new(&atn);
2495
2496 let first_context = first.intern_prediction_context(1, [7]);
2497 let second_context = second.intern_prediction_context(1, [99]);
2498
2499 assert_eq!(first.store.contexts.return_state(first_context, 0), Some(7));
2500 assert_eq!(
2501 second.store.contexts.return_state(second_context, 0),
2502 Some(99)
2503 );
2504 }
2505
2506 #[test]
2507 fn adaptive_atn_preference_requires_expensive_prediction_delta() {
2508 assert!(!ParserAtnSimulator::adaptive_prediction_delta_is_expensive(
2509 (0, 0),
2510 (ADAPTIVE_ATN_PREFERENCE_MIN_CALLS - 1, usize::MAX),
2511 ));
2512 assert!(!ParserAtnSimulator::adaptive_prediction_delta_is_expensive(
2513 (5, 7),
2514 (
2515 5 + ADAPTIVE_ATN_PREFERENCE_MIN_CALLS,
2516 7 + ADAPTIVE_ATN_PREFERENCE_MIN_CALLS
2517 * ADAPTIVE_ATN_PREFERENCE_MIN_CLOSURE_WORK_PER_CALL
2518 - 1,
2519 ),
2520 ));
2521 assert!(ParserAtnSimulator::adaptive_prediction_delta_is_expensive(
2522 (5, 7),
2523 (
2524 5 + ADAPTIVE_ATN_PREFERENCE_MIN_CALLS,
2525 7 + ADAPTIVE_ATN_PREFERENCE_MIN_CALLS
2526 * ADAPTIVE_ATN_PREFERENCE_MIN_CLOSURE_WORK_PER_CALL,
2527 ),
2528 ));
2529 assert!(!ParserAtnSimulator::adaptive_prediction_delta_is_decisive(
2530 (5, 7),
2531 (
2532 5 + ADAPTIVE_ATN_PREFERENCE_MIN_CALLS,
2533 7 + ADAPTIVE_ATN_PREFERENCE_MIN_CALLS
2534 * ADAPTIVE_ATN_PREFERENCE_DECISIVE_CLOSURE_WORK_PER_CALL
2535 - 1,
2536 ),
2537 ));
2538 assert!(ParserAtnSimulator::adaptive_prediction_delta_is_decisive(
2539 (5, 7),
2540 (
2541 5 + ADAPTIVE_ATN_PREFERENCE_MIN_CALLS,
2542 7 + ADAPTIVE_ATN_PREFERENCE_MIN_CALLS
2543 * ADAPTIVE_ATN_PREFERENCE_DECISIVE_CLOSURE_WORK_PER_CALL,
2544 ),
2545 ));
2546 }
2547
2548 #[test]
2549 fn adaptive_atn_preference_excludes_first_population_per_decision() {
2550 let atn = two_independent_decisions_atn();
2551 let mut simulator = ParserAtnSimulator::new(&atn);
2552
2553 assert_eq!(simulator.adaptive_prediction_work(), None);
2554 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
2555 let after_first_decision = simulator
2556 .adaptive_prediction_work()
2557 .expect("one decision is trained");
2558 assert_eq!(after_first_decision, (0, 0));
2559
2560 assert_eq!(simulator.adaptive_predict(1, [1, 2]), Ok(1));
2561 assert_eq!(
2562 simulator.adaptive_prediction_work(),
2563 Some(after_first_decision),
2564 "cold work for another decision must not enter the routing counters"
2565 );
2566
2567 assert_eq!(simulator.adaptive_predict(1, [1, 2]), Ok(1));
2568 let after_warm_decision = simulator
2569 .adaptive_prediction_work()
2570 .expect("trained decision work is measurable");
2571 assert_eq!(after_warm_decision.0, after_first_decision.0 + 1);
2572 }
2573
2574 #[test]
2575 fn adaptive_atn_preference_excludes_incremental_population_per_decision() {
2576 let atn = two_token_decision_atn();
2577 let mut simulator = ParserAtnSimulator::new(&atn);
2578
2579 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
2580 let after_first_path = simulator
2581 .adaptive_prediction_work()
2582 .expect("the decision is partially trained");
2583 let transitions_after_first_path = simulator.decision_dfas()[0].stats().transitions;
2584
2585 assert_eq!(simulator.adaptive_predict(0, [1, 3]), Ok(2));
2586 assert!(
2587 simulator.decision_dfas()[0].stats().transitions > transitions_after_first_path,
2588 "the second input must extend the partially populated DFA"
2589 );
2590 assert_eq!(
2591 simulator.adaptive_prediction_work(),
2592 Some(after_first_path),
2593 "incremental DFA construction must not enter the routing counters"
2594 );
2595
2596 assert_eq!(simulator.adaptive_predict(0, [1, 3]), Ok(2));
2597 assert_eq!(
2598 simulator
2599 .adaptive_prediction_work()
2600 .expect("the repeated path is stable")
2601 .0,
2602 after_first_path.0 + 1
2603 );
2604 }
2605
2606 #[test]
2607 fn reset_retains_adaptive_training_and_clear_dfa_cools_it() {
2608 let atn = two_token_decision_atn();
2609 let mut simulator = ParserAtnSimulator::new(&atn);
2610 assert_eq!(simulator.adaptive_prediction_work(), None);
2611 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
2612 assert_eq!(simulator.adaptive_prediction_work(), Some((0, 0)));
2613
2614 simulator.reset();
2615 assert_eq!(simulator.adaptive_calls, 0);
2616 assert_eq!(simulator.adaptive_closure_work, 0);
2617 assert_eq!(simulator.adaptive_prediction_work(), Some((0, 0)));
2618
2619 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
2620 assert_eq!(
2621 simulator
2622 .adaptive_prediction_work()
2623 .expect("warmed counters")
2624 .0,
2625 1
2626 );
2627
2628 simulator.clear_dfa();
2629 assert_eq!(simulator.adaptive_calls, 0);
2630 assert_eq!(simulator.adaptive_closure_work, 0);
2631 assert_eq!(simulator.adaptive_prediction_work(), None);
2632 }
2633
2634 #[test]
2635 fn adaptive_predict_reuses_dense_dfa_edges() {
2636 let atn = two_token_decision_atn();
2637 let mut simulator = ParserAtnSimulator::new(&atn);
2638
2639 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
2640 assert_eq!(simulator.adaptive_predict(0, [1, 3]), Ok(2));
2641
2642 let dfa = &simulator.decision_dfas()[0];
2643 let start = dfa.start_state().expect("start state");
2644 let after_first = dfa.state(start).and_then(|state| state.edge(1));
2645 assert!(after_first.is_some());
2646 }
2647
2648 #[test]
2649 fn shared_simulator_reuses_learned_dfa_states() {
2650 let atn = Box::leak(Box::new(two_token_decision_atn()));
2651 let learned_states = {
2652 let mut simulator = ParserAtnSimulator::new_shared(atn);
2653 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
2654 simulator.decision_dfas()[0].states().len()
2655 };
2656
2657 let simulator = ParserAtnSimulator::new_shared(atn);
2658 assert_eq!(simulator.decision_dfas()[0].states().len(), learned_states);
2659 }
2660
2661 #[test]
2662 #[should_panic(expected = "shared prediction simulators use a fixed untracked rule-call mode")]
2663 fn shared_simulator_rejects_rule_call_tracking_mode_changes() {
2664 let atn = Box::leak(Box::new(two_token_decision_atn()));
2665 let mut simulator = ParserAtnSimulator::new_shared(atn);
2666
2667 simulator.set_track_prediction_rule_calls(true);
2668 }
2669
2670 #[test]
2671 #[should_panic(
2672 expected = "prediction rule-call tracking mode cannot change after DFA construction"
2673 )]
2674 fn simulator_rejects_rule_call_tracking_mode_changes_after_learning() {
2675 let atn = two_token_decision_atn();
2676 let mut simulator = ParserAtnSimulator::new(&atn);
2677 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
2678
2679 simulator.set_track_prediction_rule_calls(true);
2680 }
2681
2682 #[test]
2683 fn shared_simulator_preserves_and_clears_prediction_training_state() {
2684 let atn = Box::leak(Box::new(two_token_decision_atn()));
2685 {
2686 let mut simulator = ParserAtnSimulator::new_shared(atn);
2687 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
2688 }
2689
2690 {
2691 let simulator = ParserAtnSimulator::new_shared(atn);
2692 assert_eq!(simulator.adaptive_prediction_work(), Some((0, 0)));
2693 }
2694
2695 ParserAtnSimulator::clear_shared_dfa(atn);
2696 let simulator = ParserAtnSimulator::new_shared(atn);
2697 assert_eq!(simulator.adaptive_prediction_work(), None);
2698 }
2699
2700 #[test]
2701 fn overlapping_shared_simulator_treats_an_empty_store_as_cold() {
2702 let atn = Box::leak(Box::new(two_token_decision_atn()));
2703 {
2704 let mut simulator = ParserAtnSimulator::new_shared(atn);
2705 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
2706 }
2707
2708 let warmed = ParserAtnSimulator::new_shared(atn);
2709 assert_eq!(warmed.adaptive_prediction_work(), Some((0, 0)));
2710 let overlapping = ParserAtnSimulator::new_shared(atn);
2711 assert_eq!(overlapping.adaptive_prediction_work(), None);
2712 }
2713
2714 #[test]
2715 fn clear_shared_dfa_drops_learned_states() {
2716 let atn = Box::leak(Box::new(two_token_decision_atn()));
2717 {
2718 let mut simulator = ParserAtnSimulator::new_shared(atn);
2719 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
2720 assert!(!simulator.decision_dfas()[0].is_empty());
2721 }
2722
2723 ParserAtnSimulator::clear_shared_dfa(atn);
2724
2725 let simulator = ParserAtnSimulator::new_shared(atn);
2726 assert!(simulator.decision_dfas()[0].is_empty());
2727 }
2728
2729 #[test]
2730 fn clear_dfa_rejects_stale_overlapping_simulator_publication() {
2731 let atn = Box::leak(Box::new(two_token_decision_atn()));
2732 let mut current = ParserAtnSimulator::new_shared(atn);
2733 let mut stale = ParserAtnSimulator::new_shared(atn);
2734 assert_eq!(stale.adaptive_predict(0, [1, 2]), Ok(1));
2735 assert!(!stale.decision_dfas()[0].is_empty());
2736
2737 current.clear_dfa();
2738 drop(stale);
2739 drop(current);
2740
2741 let simulator = ParserAtnSimulator::new_shared(atn);
2742 assert!(simulator.decision_dfas()[0].is_empty());
2743 }
2744
2745 #[test]
2746 fn adaptive_predict_reports_no_viable_alt() {
2747 let atn = two_token_decision_atn();
2748 let mut simulator = ParserAtnSimulator::new(&atn);
2749
2750 assert_eq!(
2751 simulator.adaptive_predict(0, [4]),
2752 Err(ParserAtnSimulatorError::NoViableAlt {
2753 symbol: 4,
2754 index: 0
2755 })
2756 );
2757 }
2758
2759 #[test]
2760 fn adaptive_predict_marks_sll_conflict_for_full_context() {
2761 let atn = ambiguous_single_token_decision_atn();
2762 let mut simulator = ParserAtnSimulator::new(&atn);
2763
2764 assert_eq!(simulator.adaptive_predict(0, [1]), Ok(1));
2765 let prediction = simulator
2766 .adaptive_predict_info_with_precedence(0, 0, [1])
2767 .expect("prediction");
2768 insta::assert_debug_snapshot!(
2769 "adaptive_predict_marks_sll_conflict_for_full_context",
2770 prediction
2771 );
2772
2773 let dfa = &simulator.decision_dfas()[0];
2774 let start = dfa.start_state().expect("start state");
2775 let target = dfa
2776 .state(start)
2777 .and_then(|state| state.edge(1))
2778 .expect("edge for token 1");
2779 let state = dfa.state(target).expect("target state");
2780 assert!(state.is_accept_state());
2781 assert!(state.requires_full_context());
2782 assert_eq!(state.prediction(), Some(1));
2783 }
2784
2785 #[test]
2786 fn adaptive_predict_keeps_rule_stop_configs_at_eof() {
2787 let atn = optional_token_decision_atn();
2788 let mut simulator = ParserAtnSimulator::new(&atn);
2789
2790 assert_eq!(simulator.adaptive_predict(0, [TOKEN_EOF]), Ok(2));
2791 }
2792
2793 #[test]
2794 fn adaptive_predict_treats_repeated_eof_as_epsilon_after_first_eof() {
2795 let atn = multiple_eof_decision_atn();
2796 let mut simulator = ParserAtnSimulator::new(&atn);
2797
2798 assert_eq!(simulator.adaptive_predict(0, [1, TOKEN_EOF]), Ok(1));
2799 }
2800
2801 #[test]
2802 fn adaptive_predict_uses_finished_entry_rule_alt_on_error_edge() {
2803 let atn = prefix_alt_decision_atn();
2804 let mut simulator = ParserAtnSimulator::new(&atn);
2805
2806 assert_eq!(simulator.adaptive_predict(0, [1, 3]), Ok(1));
2807 }
2808
2809 #[test]
2810 fn adaptive_predict_keeps_prefix_alt_until_longer_alt_finishes() {
2811 let atn = three_token_prefix_alt_decision_atn();
2812 let mut simulator = ParserAtnSimulator::new(&atn);
2813
2814 assert_eq!(simulator.adaptive_predict(0, [1, 2, TOKEN_EOF]), Ok(1));
2815 assert_eq!(simulator.adaptive_predict(0, [1, 2, 1, TOKEN_EOF]), Ok(2));
2816 }
2817
2818 #[test]
2819 fn sll_probe_keeps_unique_alt_early_termination() {
2820 let atn = three_token_prefix_alt_decision_atn();
2821 let mut simulator = ParserAtnSimulator::new(&atn);
2822 let mut input = VecIntStream::new(vec![1, 2, TOKEN_EOF]);
2823
2824 let prediction = simulator
2825 .adaptive_predict_stream_info_sll_probe(0, 0, &mut input)
2826 .expect("SLL prediction should succeed");
2827
2828 assert_eq!(prediction.alt, 2);
2829 }
2830
2831 #[test]
2832 fn adaptive_predict_uses_precedence_dfa_start_states() {
2833 let atn = two_token_decision_atn_with_precedence(true);
2834 let mut simulator = ParserAtnSimulator::new(&atn);
2835
2836 assert_eq!(
2837 simulator.adaptive_predict_with_precedence(0, 3, [1, 2]),
2838 Ok(1)
2839 );
2840 assert_eq!(
2841 simulator.adaptive_predict_with_precedence(0, 7, [1, 3]),
2842 Ok(2)
2843 );
2844
2845 let dfa = &simulator.decision_dfas()[0];
2846 assert!(dfa.is_precedence_dfa());
2847 assert!(dfa.precedence_start_state(3).is_some());
2848 assert!(dfa.precedence_start_state(7).is_some());
2849 }
2850
2851 #[test]
2852 fn adaptive_predict_stream_restores_input_position() {
2853 let atn = two_token_decision_atn();
2854 let mut simulator = ParserAtnSimulator::new(&atn);
2855 let mut input = VecIntStream::new(vec![1, 3, TOKEN_EOF]);
2856
2857 assert_eq!(simulator.adaptive_predict_stream(0, &mut input), Ok(2));
2858 assert_eq!(input.index(), 0);
2859 assert_eq!(input.la(1), 1);
2860 }
2861
2862 #[test]
2863 fn adaptive_predict_stream_retries_full_context_conflict() {
2864 let atn = ambiguous_single_token_decision_atn();
2865 let mut simulator = ParserAtnSimulator::new(&atn);
2866 let mut input = VecIntStream::new(vec![1, TOKEN_EOF]);
2867
2868 let prediction = simulator
2869 .adaptive_predict_stream_info_with_precedence(0, 0, &mut input)
2870 .expect("prediction");
2871
2872 insta::assert_debug_snapshot!(
2873 "adaptive_predict_stream_retries_full_context_conflict",
2874 prediction
2875 );
2876 assert_eq!(input.index(), 0);
2877 }
2878
2879 #[test]
2880 fn full_context_memo_replays_identical_retries() {
2881 let atn = ambiguous_single_token_decision_atn();
2882 let mut simulator = ParserAtnSimulator::new(&atn);
2883
2884 let mut input = VecIntStream::new(vec![1, TOKEN_EOF]);
2887 let fresh = simulator
2888 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
2889 .expect("fresh prediction");
2890 assert_eq!(simulator.full_context_memo_len, 1);
2891 assert_eq!(input.index(), 0, "cursor restored after prediction");
2892
2893 let replayed = simulator
2897 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
2898 .expect("memoized prediction");
2899 assert_eq!(replayed, fresh);
2900 assert_eq!(simulator.full_context_memo_len, 1, "no duplicate entry");
2901 assert_eq!(input.index(), 0);
2902
2903 let mut other_input = VecIntStream::new(vec![2, TOKEN_EOF]);
2906 let other = simulator.adaptive_predict_stream_info_with_context(
2907 0,
2908 0,
2909 &mut other_input,
2910 EMPTY_CONTEXT,
2911 );
2912 assert!(other.is_err(), "different window must not replay");
2915
2916 let context = simulator.store.contexts.singleton(EMPTY_CONTEXT, 6);
2918 let mut input = VecIntStream::new(vec![1, TOKEN_EOF]);
2919 let _ = simulator
2920 .adaptive_predict_stream_info_with_context(0, 0, &mut input, context)
2921 .expect("prediction under a different context");
2922 assert_eq!(
2923 simulator.full_context_memo_len, 2,
2924 "distinct context records its own entry"
2925 );
2926 }
2927
2928 #[test]
2929 fn full_context_memo_walks_multi_token_windows() {
2930 let atn = ambiguous_three_token_decision_atn();
2931 let mut simulator = ParserAtnSimulator::new(&atn);
2932
2933 let mut input = VecIntStream::new(vec![1, 2, 3, TOKEN_EOF]);
2936 let fresh = simulator
2937 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
2938 .expect("fresh prediction");
2939 assert_eq!(simulator.full_context_memo_len, 1);
2940 let recorded_window_len = simulator
2941 .full_context_memo
2942 .values()
2943 .next()
2944 .and_then(|entries| entries.first())
2945 .map(|entry| entry.window_tail.len())
2946 .expect("one recorded entry");
2947 assert!(
2948 recorded_window_len >= 1,
2949 "the LL loop consumed tokens, so the window tail must be non-empty"
2950 );
2951
2952 let replayed = simulator
2955 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
2956 .expect("memoized prediction");
2957 assert_eq!(replayed, fresh);
2958 assert_eq!(input.index(), 0, "cursor restored by the caller wrapper");
2959
2960 let mut diverging = VecIntStream::new(vec![1, 9, 9, TOKEN_EOF]);
2966 let result = simulator.adaptive_predict_stream_info_with_context(
2967 0,
2968 0,
2969 &mut diverging,
2970 EMPTY_CONTEXT,
2971 );
2972 assert!(result.is_err(), "mid-window divergence must not replay");
2973 assert_eq!(simulator.full_context_memo_len, 1);
2974 }
2975
2976 #[test]
2977 fn full_context_memo_stays_off_for_predicated_atns_and_exact_mode() {
2978 let atn = ambiguous_single_token_decision_atn();
2981 let mut simulator = ParserAtnSimulator::new(&atn);
2982 simulator.set_exact_ambig_detection(true);
2983 let mut input = VecIntStream::new(vec![1, TOKEN_EOF]);
2984 let _ = simulator
2985 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
2986 .expect("prediction");
2987 assert_eq!(simulator.full_context_memo_len, 0);
2988
2989 let mut atn = ParserAtnBuilder::new(1);
2992 add_state(&mut atn, 0, AtnStateKind::Basic);
2993 add_state(&mut atn, 1, AtnStateKind::Basic);
2994 atn.add_transition(
2995 0,
2996 ParserTransitionSpec::Predicate {
2997 target: 1,
2998 rule_index: 0,
2999 pred_index: 0,
3000 context_dependent: false,
3001 },
3002 )
3003 .expect("transition");
3004 atn.set_rule_to_start_state(vec![0])
3005 .expect("rule start states");
3006 atn.set_rule_to_stop_state(vec![1])
3007 .expect("rule stop states");
3008 let atn = finish_atn(atn);
3009 let mut simulator = ParserAtnSimulator::new(&atn);
3010 assert!(!simulator.full_context_memo_allowed());
3011 }
3012
3013 #[test]
3014 fn full_context_memo_allows_action_and_precedence_transitions() {
3015 let mut atn = ParserAtnBuilder::new(1);
3021 add_state(&mut atn, 0, AtnStateKind::Basic);
3022 add_state(&mut atn, 1, AtnStateKind::Basic);
3023 add_state(&mut atn, 2, AtnStateKind::Basic);
3024 atn.add_transition(
3025 0,
3026 ParserTransitionSpec::Action {
3027 target: 1,
3028 rule_index: 0,
3029 action_index: Some(0),
3030 context_dependent: false,
3031 },
3032 )
3033 .expect("transition");
3034 atn.add_transition(
3035 1,
3036 ParserTransitionSpec::Precedence {
3037 target: 2,
3038 precedence: 1,
3039 },
3040 )
3041 .expect("transition");
3042 atn.set_rule_to_start_state(vec![0])
3043 .expect("rule start states");
3044 atn.set_rule_to_stop_state(vec![2])
3045 .expect("rule stop states");
3046 let atn = finish_atn(atn);
3047 let mut simulator = ParserAtnSimulator::new(&atn);
3048 assert!(simulator.full_context_memo_allowed());
3049 }
3050
3051 #[test]
3052 fn context_prediction_reports_context_sensitivity_for_dfa_conflict() {
3053 let atn = two_token_decision_atn();
3054 let mut simulator = ParserAtnSimulator::new(&atn);
3055 let mut workspace = PredictionWorkspace::default();
3056 let mut start_configs = AtnConfigSet::new();
3057 start_configs.add(
3058 AtnConfig::new(2, 1, EMPTY_CONTEXT, &simulator.store.contexts),
3059 &mut simulator.store.contexts,
3060 &mut workspace,
3061 );
3062 let start =
3063 simulator.store.decision_to_dfa[0].add_state(DfaStateBuilder::new(start_configs));
3064 simulator.store.decision_to_dfa[0].set_start_state(start);
3065
3066 let mut accept_configs = AtnConfigSet::new();
3067 accept_configs.add(
3068 AtnConfig::new(3, 1, EMPTY_CONTEXT, &simulator.store.contexts).with_semantic_context(
3069 SemanticContext::Predicate {
3070 rule_index: 0,
3071 pred_index: 0,
3072 context_dependent: false,
3073 },
3074 ),
3075 &mut simulator.store.contexts,
3076 &mut workspace,
3077 );
3078 let mut accept_state = DfaStateBuilder::new(accept_configs);
3079 accept_state.mark_accept(1);
3080 accept_state.set_requires_full_context(true);
3081 accept_state.set_conflicting_alts(vec![1, 2]);
3082 let accept = simulator.store.decision_to_dfa[0].add_state(accept_state);
3083 simulator.store.decision_to_dfa[0].add_edge(start, 1, accept);
3084
3085 let mut input = VecIntStream::new(vec![1, 3, TOKEN_EOF]);
3086 let prediction = simulator
3087 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
3088 .expect("prediction");
3089
3090 insta::assert_debug_snapshot!(
3091 "context_prediction_reports_context_sensitivity_for_dfa_conflict",
3092 prediction
3093 );
3094 assert_eq!(input.index(), 0);
3095 }
3096
3097 #[test]
3098 fn full_context_reach_prefers_longer_match_over_skipped_stop_state() {
3099 let atn = prefix_alt_decision_atn();
3100 let mut simulator = ParserAtnSimulator::new(&atn);
3101 let mut configs = AtnConfigSet::new_full_context(true);
3102 let mut merge_cache = PredictionWorkspace::default();
3103 configs.add(
3104 AtnConfig::new(2, 1, EMPTY_CONTEXT, &simulator.store.contexts),
3105 &mut simulator.store.contexts,
3106 &mut merge_cache,
3107 );
3108 configs.add(
3109 AtnConfig::new(1, 2, EMPTY_CONTEXT, &simulator.store.contexts),
3110 &mut simulator.store.contexts,
3111 &mut merge_cache,
3112 );
3113
3114 let reach = simulator.compute_reach_set(&configs, 2, true, 0, &mut merge_cache);
3115
3116 assert_eq!(reach.alts(), std::iter::once(2).collect());
3117 assert!(simulator.configs_all_reached_rule_stop(&reach));
3118 }
3119
3120 #[test]
3121 fn sll_closure_follows_empty_context_rule_stop_exits() {
3122 let mut atn = ParserAtnBuilder::new(1);
3123 add_state(&mut atn, 0, AtnStateKind::RuleStop);
3124 add_state(&mut atn, 1, AtnStateKind::Basic);
3125 add_state(&mut atn, 2, AtnStateKind::Basic);
3126 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
3127 .expect("transition");
3128 atn.add_transition(
3129 1,
3130 ParserTransitionSpec::Atom {
3131 target: 2,
3132 label: 1,
3133 },
3134 )
3135 .expect("transition");
3136 atn.set_rule_to_start_state(vec![0])
3137 .expect("rule start states");
3138 atn.set_rule_to_stop_state(vec![0])
3139 .expect("rule stop states");
3140 let atn = finish_atn(atn);
3141
3142 let mut simulator = ParserAtnSimulator::new(&atn);
3143 let mut configs = AtnConfigSet::new_full_context(false);
3144 let mut merge_cache = PredictionWorkspace::default();
3145 let mut scratch = ClosureScratch::default();
3146 let config = AtnConfig::new(0, 2, EMPTY_CONTEXT, &simulator.store.contexts);
3147 simulator.closure(
3148 config,
3149 &mut configs,
3150 &mut merge_cache,
3151 &mut scratch,
3152 ClosureParams {
3153 precedence: 0,
3154 collect_predicates: true,
3155 treat_eof_as_epsilon: false,
3156 },
3157 );
3158
3159 assert_eq!(configs.len(), 1);
3160 let config = &configs.configs()[0];
3161 assert_eq!(config.state, 1);
3162 assert_eq!(config.alt, 2);
3163 assert_eq!(config.reaches_into_outer_context, 1);
3164 }
3165
3166 #[test]
3167 fn precedence_contexts_are_collected_only_for_start_closure() {
3168 let mut atn = ParserAtnBuilder::new(1);
3169 add_state(&mut atn, 0, AtnStateKind::Basic);
3170 add_state(&mut atn, 1, AtnStateKind::Basic);
3171 atn.set_rule_to_start_state(vec![0])
3172 .expect("rule start states");
3173 atn.set_rule_to_stop_state(vec![1])
3174 .expect("rule stop states");
3175 atn.add_transition(
3176 0,
3177 ParserTransitionSpec::Precedence {
3178 target: 1,
3179 precedence: 2,
3180 },
3181 )
3182 .expect("precedence transition");
3183 let atn = finish_atn(atn);
3184 let transition = atn
3185 .state(0)
3186 .expect("source state")
3187 .transitions()
3188 .first()
3189 .expect("precedence transition");
3190 let mut simulator = ParserAtnSimulator::new(&atn);
3191 let config = AtnConfig::new(0, 1, EMPTY_CONTEXT, &simulator.store.contexts);
3192
3193 let sll_start = simulator
3194 .epsilon_target_config(&config, transition, transition.kind(), 1, true, false)
3195 .expect("sll start transition");
3196 assert!(matches!(
3197 sll_start.semantic_context,
3198 SemanticContext::Precedence { precedence: 2 }
3199 ));
3200
3201 let full_context_start = simulator
3202 .epsilon_target_config(&config, transition, transition.kind(), 1, true, true)
3203 .expect("full-context start transition");
3204 assert!(full_context_start.semantic_context.is_none());
3205
3206 let reach = simulator
3207 .epsilon_target_config(&config, transition, transition.kind(), 3, false, false)
3208 .expect("reach transition");
3209 assert!(reach.semantic_context.is_none());
3210
3211 assert!(
3212 simulator
3213 .epsilon_target_config(&config, transition, transition.kind(), 3, true, false)
3214 .is_none()
3215 );
3216 }
3217
3218 #[test]
3219 fn closure_stops_collecting_predicates_after_action_edge() {
3220 let mut atn = ParserAtnBuilder::new(1);
3227 add_state(&mut atn, 0, AtnStateKind::Basic);
3228 add_state(&mut atn, 1, AtnStateKind::Basic);
3229 add_state(&mut atn, 2, AtnStateKind::Basic);
3230 add_state(&mut atn, 3, AtnStateKind::Basic);
3231 atn.add_transition(
3232 0,
3233 ParserTransitionSpec::Action {
3234 target: 1,
3235 rule_index: 0,
3236 action_index: Some(0),
3237 context_dependent: false,
3238 },
3239 )
3240 .expect("transition");
3241 atn.add_transition(
3242 1,
3243 ParserTransitionSpec::Predicate {
3244 target: 2,
3245 rule_index: 0,
3246 pred_index: 0,
3247 context_dependent: false,
3248 },
3249 )
3250 .expect("transition");
3251 atn.add_transition(
3252 2,
3253 ParserTransitionSpec::Atom {
3254 target: 3,
3255 label: 1,
3256 },
3257 )
3258 .expect("transition");
3259 atn.set_rule_to_start_state(vec![0])
3260 .expect("rule start states");
3261 atn.set_rule_to_stop_state(vec![3])
3262 .expect("rule stop states");
3263 let atn = finish_atn(atn);
3264
3265 let mut simulator = ParserAtnSimulator::new(&atn);
3266 let mut configs = AtnConfigSet::new();
3267 let mut merge_cache = PredictionWorkspace::default();
3268 let mut scratch = ClosureScratch::default();
3269 let config = AtnConfig::new(0, 1, EMPTY_CONTEXT, &simulator.store.contexts);
3270 simulator.closure(
3271 config,
3272 &mut configs,
3273 &mut merge_cache,
3274 &mut scratch,
3275 ClosureParams {
3276 precedence: 0,
3277 collect_predicates: true,
3278 treat_eof_as_epsilon: false,
3279 },
3280 );
3281
3282 let at_two = configs
3285 .configs()
3286 .iter()
3287 .find(|config| config.state == 2)
3288 .expect("config at state 2");
3289 assert!(
3290 at_two.semantic_context.is_none(),
3291 "predicate after an action edge must not be collected during prediction"
3292 );
3293
3294 let direct_config = AtnConfig::new(1, 1, EMPTY_CONTEXT, &simulator.store.contexts);
3298 let direct_transition = atn
3299 .state(1)
3300 .expect("predicate source")
3301 .transitions()
3302 .first()
3303 .expect("predicate transition");
3304 let direct = simulator
3305 .epsilon_target_config(
3306 &direct_config,
3307 direct_transition,
3308 direct_transition.kind(),
3309 0,
3310 true,
3311 false,
3312 )
3313 .expect("predicate transition");
3314 assert!(matches!(
3315 direct.semantic_context,
3316 SemanticContext::Predicate { pred_index: 0, .. }
3317 ));
3318 }
3319
3320 #[test]
3321 fn reach_set_skips_closure_for_unique_intermediate_alt() {
3322 let mut atn = ParserAtnBuilder::new(1);
3323 add_state(&mut atn, 0, AtnStateKind::Basic);
3324 add_state(&mut atn, 1, AtnStateKind::Basic);
3325 add_state(&mut atn, 2, AtnStateKind::Basic);
3326 atn.add_transition(
3327 0,
3328 ParserTransitionSpec::Atom {
3329 target: 1,
3330 label: 7,
3331 },
3332 )
3333 .expect("transition");
3334 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
3335 .expect("transition");
3336 atn.set_rule_to_start_state(vec![0])
3337 .expect("rule start states");
3338 atn.set_rule_to_stop_state(vec![2])
3339 .expect("rule stop states");
3340 let atn = finish_atn(atn);
3341
3342 let mut simulator = ParserAtnSimulator::new(&atn);
3343 let mut configs = AtnConfigSet::new_full_context(false);
3344 let mut merge_cache = PredictionWorkspace::default();
3345 configs.add(
3346 AtnConfig::new(0, 1, EMPTY_CONTEXT, &simulator.store.contexts),
3347 &mut simulator.store.contexts,
3348 &mut merge_cache,
3349 );
3350
3351 let reach = simulator.compute_reach_set(&configs, 7, false, 0, &mut merge_cache);
3352
3353 assert_eq!(reach.len(), 1);
3354 assert_eq!(reach.configs()[0].state, 1);
3355 }
3356
3357 #[test]
3358 fn semantic_context_flag_is_scoped_to_predicted_alt() {
3359 let mut arena = ContextArena::new();
3360 let mut workspace = PredictionWorkspace::default();
3361 let mut configs = AtnConfigSet::new();
3362 configs.add(
3363 AtnConfig::new(1, 1, EMPTY_CONTEXT, &arena),
3364 &mut arena,
3365 &mut workspace,
3366 );
3367 configs.add(
3368 AtnConfig::new(2, 2, EMPTY_CONTEXT, &arena).with_semantic_context(
3369 SemanticContext::Predicate {
3370 rule_index: 0,
3371 pred_index: 0,
3372 context_dependent: false,
3373 },
3374 ),
3375 &mut arena,
3376 &mut workspace,
3377 );
3378
3379 assert!(!configs_have_semantic_context_for_alt(&configs, 1));
3380 assert!(configs_have_semantic_context_for_alt(&configs, 2));
3381 }
3382
3383 #[test]
3384 fn adaptive_predict_prefers_non_greedy_exit_before_consuming() {
3385 let atn = non_greedy_optional_exit_first_atn();
3386 let mut simulator = ParserAtnSimulator::new(&atn);
3387
3388 assert_eq!(simulator.adaptive_predict(0, [1, TOKEN_EOF]), Ok(1));
3389 }
3390
3391 #[test]
3392 fn left_recursive_loop_entry_drop_requires_same_rule_return() {
3393 let atn = left_recursive_loop_entry_atn();
3394 let loop_entry = atn.state(1).expect("loop entry");
3395 let mut contexts = ContextArena::new();
3396 let same_rule_context = contexts.singleton(EMPTY_CONTEXT, 4);
3397 let other_rule_context = contexts.singleton(EMPTY_CONTEXT, 5);
3398
3399 assert!(can_drop_left_recursive_loop_entry_edge(
3400 &atn,
3401 loop_entry,
3402 &contexts,
3403 same_rule_context
3404 ));
3405 assert!(!can_drop_left_recursive_loop_entry_edge(
3406 &atn,
3407 loop_entry,
3408 &contexts,
3409 other_rule_context
3410 ));
3411 assert!(!can_drop_left_recursive_loop_entry_edge(
3412 &atn,
3413 loop_entry,
3414 &contexts,
3415 EMPTY_CONTEXT
3416 ));
3417 }
3418
3419 fn two_token_decision_atn() -> Atn {
3420 two_token_decision_atn_with_precedence(false)
3421 }
3422
3423 fn two_independent_decisions_atn() -> Atn {
3424 let mut atn = ParserAtnBuilder::new(3);
3425 add_two_token_decision_rule(&mut atn, 0, 0);
3426 add_two_token_decision_rule(&mut atn, 8, 1);
3427 atn.set_rule_to_start_state(vec![0, 8])
3428 .expect("rule start states");
3429 atn.set_rule_to_stop_state(vec![7, 15])
3430 .expect("rule stop states");
3431 finish_atn(atn)
3432 }
3433
3434 fn two_token_decision_atn_with_precedence(precedence: bool) -> Atn {
3435 let mut atn = ParserAtnBuilder::new(3);
3436 add_two_token_decision_rule(&mut atn, 0, 0);
3437 atn.set_rule_to_start_state(vec![0])
3438 .expect("rule start states");
3439 atn.set_rule_to_stop_state(vec![7])
3440 .expect("rule stop states");
3441 if precedence {
3442 atn.set_precedence_rule_decision(1)
3443 .expect("precedence decision state");
3444 }
3445 finish_atn(atn)
3446 }
3447
3448 fn add_two_token_decision_rule(atn: &mut ParserAtnBuilder, offset: usize, rule_index: usize) {
3449 assert_eq!(atn.state_count(), offset);
3450 for kind in [
3451 AtnStateKind::RuleStart,
3452 AtnStateKind::BlockStart,
3453 AtnStateKind::Basic,
3454 AtnStateKind::Basic,
3455 AtnStateKind::Basic,
3456 AtnStateKind::Basic,
3457 AtnStateKind::BlockEnd,
3458 AtnStateKind::RuleStop,
3459 ] {
3460 let expected = atn.state_count();
3461 assert_eq!(
3462 atn.add_state(kind, Some(rule_index))
3463 .expect("state")
3464 .index(),
3465 expected
3466 );
3467 }
3468 atn.add_decision_state(offset + 1).expect("decision state");
3469 atn.add_transition(offset, ParserTransitionSpec::Epsilon { target: offset + 1 })
3470 .expect("transition");
3471 atn.add_transition(
3472 offset + 1,
3473 ParserTransitionSpec::Epsilon { target: offset + 2 },
3474 )
3475 .expect("transition");
3476 atn.add_transition(
3477 offset + 1,
3478 ParserTransitionSpec::Epsilon { target: offset + 4 },
3479 )
3480 .expect("transition");
3481 atn.add_transition(
3482 offset + 2,
3483 ParserTransitionSpec::Atom {
3484 target: offset + 3,
3485 label: 1,
3486 },
3487 )
3488 .expect("transition");
3489 atn.add_transition(
3490 offset + 3,
3491 ParserTransitionSpec::Atom {
3492 target: offset + 6,
3493 label: 2,
3494 },
3495 )
3496 .expect("transition");
3497 atn.add_transition(
3498 offset + 4,
3499 ParserTransitionSpec::Atom {
3500 target: offset + 5,
3501 label: 1,
3502 },
3503 )
3504 .expect("transition");
3505 atn.add_transition(
3506 offset + 5,
3507 ParserTransitionSpec::Atom {
3508 target: offset + 6,
3509 label: 3,
3510 },
3511 )
3512 .expect("transition");
3513 atn.add_transition(
3514 offset + 6,
3515 ParserTransitionSpec::Epsilon { target: offset + 7 },
3516 )
3517 .expect("transition");
3518 }
3519
3520 fn optional_token_decision_atn() -> Atn {
3521 let mut atn = ParserAtnBuilder::new(1);
3522 add_state(&mut atn, 0, AtnStateKind::RuleStart);
3523 add_state(&mut atn, 1, AtnStateKind::BlockStart);
3524 add_state(&mut atn, 2, AtnStateKind::Basic);
3525 add_state(&mut atn, 3, AtnStateKind::BlockEnd);
3526 add_state(&mut atn, 4, AtnStateKind::RuleStop);
3527 atn.set_rule_to_start_state(vec![0])
3528 .expect("rule start states");
3529 atn.set_rule_to_stop_state(vec![4])
3530 .expect("rule stop states");
3531 atn.add_decision_state(1).expect("decision state");
3532 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
3533 .expect("transition");
3534 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
3535 .expect("transition");
3536 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
3537 .expect("transition");
3538 atn.add_transition(
3539 2,
3540 ParserTransitionSpec::Atom {
3541 target: 3,
3542 label: 1,
3543 },
3544 )
3545 .expect("transition");
3546 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
3547 .expect("transition");
3548 finish_atn(atn)
3549 }
3550
3551 fn non_greedy_optional_exit_first_atn() -> Atn {
3552 let mut atn = ParserAtnBuilder::new(1);
3553 add_state(&mut atn, 0, AtnStateKind::RuleStart);
3554 add_state(&mut atn, 1, AtnStateKind::BlockStart);
3555 add_state(&mut atn, 2, AtnStateKind::BlockEnd);
3556 add_state(&mut atn, 3, AtnStateKind::Basic);
3557 add_state(&mut atn, 4, AtnStateKind::RuleStop);
3558 atn.set_rule_to_start_state(vec![0])
3559 .expect("rule start states");
3560 atn.set_rule_to_stop_state(vec![4])
3561 .expect("rule stop states");
3562 atn.add_decision_state(1).expect("decision state");
3563 atn.set_non_greedy(1).expect("non-greedy state");
3564 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
3565 .expect("transition");
3566 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
3567 .expect("transition");
3568 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
3569 .expect("transition");
3570 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
3571 .expect("transition");
3572 atn.add_transition(
3573 3,
3574 ParserTransitionSpec::Atom {
3575 target: 4,
3576 label: 1,
3577 },
3578 )
3579 .expect("transition");
3580 finish_atn(atn)
3581 }
3582
3583 fn ambiguous_three_token_decision_atn() -> Atn {
3588 let mut atn = ParserAtnBuilder::new(3);
3589 add_state(&mut atn, 0, AtnStateKind::RuleStart);
3590 add_state(&mut atn, 1, AtnStateKind::BlockStart);
3591 add_state(&mut atn, 2, AtnStateKind::Basic);
3593 add_state(&mut atn, 3, AtnStateKind::Basic);
3594 add_state(&mut atn, 4, AtnStateKind::Basic);
3595 add_state(&mut atn, 5, AtnStateKind::Basic);
3596 add_state(&mut atn, 6, AtnStateKind::Basic);
3598 add_state(&mut atn, 7, AtnStateKind::Basic);
3599 add_state(&mut atn, 8, AtnStateKind::Basic);
3600 add_state(&mut atn, 9, AtnStateKind::Basic);
3601 add_state(&mut atn, 10, AtnStateKind::BlockEnd);
3602 add_state(&mut atn, 11, AtnStateKind::RuleStop);
3603 atn.set_rule_to_start_state(vec![0])
3604 .expect("rule start states");
3605 atn.set_rule_to_stop_state(vec![11])
3606 .expect("rule stop states");
3607 atn.add_decision_state(1).expect("decision state");
3608 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
3609 .expect("transition");
3610 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
3611 .expect("transition");
3612 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
3613 .expect("transition");
3614 for (source, target, label) in [
3615 (2, 3, 1),
3616 (3, 4, 2),
3617 (4, 5, 3),
3618 (6, 7, 1),
3619 (7, 8, 2),
3620 (8, 9, 3),
3621 ] {
3622 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
3623 .expect("transition");
3624 }
3625 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
3626 .expect("transition");
3627 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
3628 .expect("transition");
3629 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
3630 .expect("transition");
3631 finish_atn(atn)
3632 }
3633
3634 fn ambiguous_single_token_decision_atn() -> Atn {
3635 let mut atn = ParserAtnBuilder::new(1);
3636 add_state(&mut atn, 0, AtnStateKind::RuleStart);
3637 add_state(&mut atn, 1, AtnStateKind::BlockStart);
3638 add_state(&mut atn, 2, AtnStateKind::Basic);
3639 add_state(&mut atn, 3, AtnStateKind::Basic);
3640 add_state(&mut atn, 4, AtnStateKind::Basic);
3641 add_state(&mut atn, 5, AtnStateKind::Basic);
3642 add_state(&mut atn, 6, AtnStateKind::BlockEnd);
3643 add_state(&mut atn, 7, AtnStateKind::RuleStop);
3644 atn.set_rule_to_start_state(vec![0])
3645 .expect("rule start states");
3646 atn.set_rule_to_stop_state(vec![7])
3647 .expect("rule stop states");
3648 atn.add_decision_state(1).expect("decision state");
3649 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
3650 .expect("transition");
3651 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
3652 .expect("transition");
3653 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
3654 .expect("transition");
3655 atn.add_transition(
3656 2,
3657 ParserTransitionSpec::Atom {
3658 target: 3,
3659 label: 1,
3660 },
3661 )
3662 .expect("transition");
3663 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 6 })
3664 .expect("transition");
3665 atn.add_transition(
3666 4,
3667 ParserTransitionSpec::Atom {
3668 target: 5,
3669 label: 1,
3670 },
3671 )
3672 .expect("transition");
3673 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
3674 .expect("transition");
3675 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
3676 .expect("transition");
3677 finish_atn(atn)
3678 }
3679
3680 fn prefix_alt_decision_atn() -> Atn {
3681 let mut atn = ParserAtnBuilder::new(3);
3682 add_state(&mut atn, 0, AtnStateKind::BlockStart);
3683 add_state(&mut atn, 1, AtnStateKind::Basic);
3684 add_state(&mut atn, 2, AtnStateKind::RuleStop);
3685 atn.set_rule_to_start_state(vec![0])
3686 .expect("rule start states");
3687 atn.set_rule_to_stop_state(vec![2])
3688 .expect("rule stop states");
3689 atn.add_decision_state(0).expect("decision state");
3690 atn.add_transition(
3691 0,
3692 ParserTransitionSpec::Atom {
3693 target: 2,
3694 label: 1,
3695 },
3696 )
3697 .expect("transition");
3698 atn.add_transition(
3699 0,
3700 ParserTransitionSpec::Atom {
3701 target: 1,
3702 label: 1,
3703 },
3704 )
3705 .expect("transition");
3706 atn.add_transition(
3707 1,
3708 ParserTransitionSpec::Atom {
3709 target: 2,
3710 label: 2,
3711 },
3712 )
3713 .expect("transition");
3714 finish_atn(atn)
3715 }
3716
3717 fn three_token_prefix_alt_decision_atn() -> Atn {
3718 let mut atn = ParserAtnBuilder::new(2);
3719 for (state_number, kind) in [
3720 (0, AtnStateKind::BlockStart),
3721 (1, AtnStateKind::Basic),
3722 (2, AtnStateKind::Basic),
3723 (3, AtnStateKind::Basic),
3724 (4, AtnStateKind::Basic),
3725 (5, AtnStateKind::Basic),
3726 (6, AtnStateKind::RuleStop),
3727 ] {
3728 add_state(&mut atn, state_number, kind);
3729 }
3730 atn.set_rule_to_start_state(vec![0])
3731 .expect("rule start states");
3732 atn.set_rule_to_stop_state(vec![6])
3733 .expect("rule stop states");
3734 atn.add_decision_state(0).expect("decision state");
3735 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
3736 .expect("transition");
3737 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 2 })
3738 .expect("transition");
3739 atn.add_transition(
3740 1,
3741 ParserTransitionSpec::Atom {
3742 target: 6,
3743 label: 1,
3744 },
3745 )
3746 .expect("transition");
3747 atn.add_transition(
3748 2,
3749 ParserTransitionSpec::Atom {
3750 target: 3,
3751 label: 1,
3752 },
3753 )
3754 .expect("transition");
3755 atn.add_transition(
3756 3,
3757 ParserTransitionSpec::Atom {
3758 target: 4,
3759 label: 2,
3760 },
3761 )
3762 .expect("transition");
3763 atn.add_transition(
3764 4,
3765 ParserTransitionSpec::Atom {
3766 target: 5,
3767 label: 1,
3768 },
3769 )
3770 .expect("transition");
3771 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
3772 .expect("transition");
3773 finish_atn(atn)
3774 }
3775
3776 fn multiple_eof_decision_atn() -> Atn {
3777 let mut atn = ParserAtnBuilder::new(2);
3778 for state_number in 0..=10 {
3779 let kind = match state_number {
3780 0 => AtnStateKind::RuleStart,
3781 1 => AtnStateKind::BlockStart,
3782 7 => AtnStateKind::BlockEnd,
3783 10 => AtnStateKind::RuleStop,
3784 _ => AtnStateKind::Basic,
3785 };
3786 add_state(&mut atn, state_number, kind);
3787 }
3788 atn.set_rule_to_start_state(vec![0])
3789 .expect("rule start states");
3790 atn.set_rule_to_stop_state(vec![10])
3791 .expect("rule stop states");
3792 atn.add_decision_state(1).expect("decision state");
3793 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
3794 .expect("transition");
3795 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
3796 .expect("transition");
3797 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
3798 .expect("transition");
3799 atn.add_transition(
3800 2,
3801 ParserTransitionSpec::Atom {
3802 target: 3,
3803 label: 1,
3804 },
3805 )
3806 .expect("transition");
3807 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 7 })
3808 .expect("transition");
3809 atn.add_transition(
3810 4,
3811 ParserTransitionSpec::Atom {
3812 target: 5,
3813 label: 1,
3814 },
3815 )
3816 .expect("transition");
3817 atn.add_transition(
3818 5,
3819 ParserTransitionSpec::Atom {
3820 target: 6,
3821 label: 2,
3822 },
3823 )
3824 .expect("transition");
3825 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
3826 .expect("transition");
3827 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
3828 .expect("transition");
3829 atn.add_transition(
3830 8,
3831 ParserTransitionSpec::Atom {
3832 target: 9,
3833 label: TOKEN_EOF,
3834 },
3835 )
3836 .expect("transition");
3837 atn.add_transition(
3838 9,
3839 ParserTransitionSpec::Atom {
3840 target: 10,
3841 label: TOKEN_EOF,
3842 },
3843 )
3844 .expect("transition");
3845 finish_atn(atn)
3846 }
3847
3848 fn left_recursive_loop_entry_atn() -> Atn {
3849 let mut atn = ParserAtnBuilder::new(1);
3850 add_state(&mut atn, 0, AtnStateKind::RuleStart);
3851 add_state(&mut atn, 1, AtnStateKind::StarLoopEntry);
3852 add_state(&mut atn, 2, AtnStateKind::BlockStart);
3853 add_state(&mut atn, 3, AtnStateKind::BlockEnd);
3854 add_state(&mut atn, 4, AtnStateKind::Basic);
3855 assert_eq!(
3856 atn.add_state(AtnStateKind::Basic, Some(1))
3857 .expect("state")
3858 .index(),
3859 5
3860 );
3861 add_state(&mut atn, 6, AtnStateKind::LoopEnd);
3862 add_state(&mut atn, 7, AtnStateKind::RuleStop);
3863 atn.set_rule_to_start_state(vec![0, 5])
3864 .expect("rule start states");
3865 atn.set_rule_to_stop_state(vec![7, 7])
3866 .expect("rule stop states");
3867 atn.set_precedence_rule_decision(1)
3868 .expect("precedence decision state");
3869 atn.set_end_state(2, 3).expect("block end state");
3870 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
3871 .expect("transition");
3872 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
3873 .expect("transition");
3874 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 3 })
3875 .expect("transition");
3876 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 3 })
3877 .expect("transition");
3878 finish_atn(atn)
3879 }
3880
3881 fn add_state(atn: &mut ParserAtnBuilder, state_number: usize, kind: AtnStateKind) {
3882 assert_eq!(
3883 atn.add_state(kind, Some(0)).expect("state").index(),
3884 state_number
3885 );
3886 }
3887
3888 #[derive(Debug)]
3889 struct VecIntStream {
3890 symbols: Vec<i32>,
3891 index: usize,
3892 }
3893
3894 impl VecIntStream {
3895 fn new(symbols: Vec<i32>) -> Self {
3896 Self { symbols, index: 0 }
3897 }
3898 }
3899
3900 impl IntStream for VecIntStream {
3901 fn consume(&mut self) {
3902 if self.la(1) != TOKEN_EOF {
3903 self.index += 1;
3904 }
3905 }
3906
3907 fn la(&mut self, offset: isize) -> i32 {
3908 if offset <= 0 {
3909 return 0;
3910 }
3911 let offset = offset.cast_unsigned() - 1;
3912 self.symbols
3913 .get(self.index + offset)
3914 .copied()
3915 .unwrap_or(TOKEN_EOF)
3916 }
3917
3918 fn index(&self) -> usize {
3919 self.index
3920 }
3921
3922 fn seek(&mut self, index: usize) {
3923 self.index = index;
3924 }
3925
3926 fn size(&self) -> usize {
3927 self.symbols.len()
3928 }
3929 }
3930}