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