1use crate::atn::AtnStateKind;
2use crate::atn::parser_atn::{
3 ParserAtn as Atn, ParserAtnState as AtnState, ParserTransition, ParserTransitionKind,
4};
5#[cfg(test)]
6use crate::atn::parser_atn::{ParserAtnBuilder, ParserTransitionSpec};
7use crate::dfa::{
8 DfaStateBuilder, DfaStateId, NO_DFA_STATE, ParserDfa, ParserDfaStateView, ParserDfaStats,
9};
10use crate::int_stream::IntStream;
11use crate::prediction::{
12 AtnConfig, AtnConfigSet, ContextArena, ContextId, EMPTY_CONTEXT, EMPTY_RETURN_STATE,
13 PredictionContextStats, PredictionFxHasher, PredictionWorkspace, SemanticContext,
14 all_subsets_conflict, all_subsets_equal, conflicting_alt_subsets,
15 has_sll_conflict_terminating_prediction, single_viable_alt,
16};
17use crate::token::TOKEN_EOF;
18use std::cell::RefCell;
19use std::collections::{HashMap, HashSet};
20use std::hash::BuildHasherDefault;
21
22type FxHashSet<T> = HashSet<T, BuildHasherDefault<PredictionFxHasher>>;
23
24#[derive(Debug)]
25pub struct ParserAtnSimulator<'a> {
26 atn: &'a Atn,
27 store: PredictionStore,
28 workspace: PredictionWorkspace,
29 outer_context_cache: Option<CachedOuterContext>,
30 outer_context_cache_hits: usize,
31 outer_context_cache_misses: usize,
32 shared_cache_key: Option<usize>,
33 shared_cache_generation: u64,
34 exact_ambig_detection: bool,
38}
39
40#[derive(Clone, Copy, Debug)]
41struct CachedOuterContext {
42 rule_context_version: usize,
43 context: ContextId,
44}
45
46#[derive(Debug, Default)]
47struct PredictionStore {
48 contexts: ContextArena,
49 decision_to_dfa: Vec<ParserDfa>,
50}
51
52impl PredictionStore {
53 fn new(atn: &Atn) -> Self {
54 Self {
55 contexts: ContextArena::new(),
56 decision_to_dfa: initial_decision_dfas(atn),
57 }
58 }
59}
60
61#[derive(Debug, Default)]
62struct SharedPredictionStore {
63 generation: u64,
64 store: Option<PredictionStore>,
65}
66
67thread_local! {
68 static SHARED_PREDICTION_STORES: RefCell<HashMap<usize, SharedPredictionStore>> =
69 RefCell::new(HashMap::new());
70}
71
72fn clear_shared_prediction_store(key: usize) -> u64 {
73 SHARED_PREDICTION_STORES.with(|cache| {
74 let mut cache = cache.borrow_mut();
75 let shared = cache.entry(key).or_default();
76 shared.generation = shared.generation.wrapping_add(1);
77 shared.store = None;
78 shared.generation
79 })
80}
81
82#[derive(Clone, Debug, Eq, PartialEq)]
83pub struct ParserAtnPrediction {
84 pub alt: usize,
85 pub requires_full_context: bool,
86 pub has_semantic_context: bool,
87 pub diagnostic: Option<ParserAtnPredictionDiagnostic>,
88}
89
90#[derive(Clone, Debug, Eq, PartialEq)]
91pub struct ParserAtnPredictionDiagnostic {
92 pub kind: ParserAtnPredictionDiagnosticKind,
93 pub start_index: usize,
94 pub sll_stop_index: usize,
95 pub ll_stop_index: usize,
96 pub conflicting_alts: Vec<usize>,
97 pub exact: bool,
101}
102
103#[derive(Clone, Copy, Debug, Eq, PartialEq)]
104pub enum ParserAtnPredictionDiagnosticKind {
105 Ambiguity,
106 ContextSensitivity,
107}
108
109#[derive(Clone, Copy)]
110struct PredictionCheck {
111 decision: usize,
112 decision_state: usize,
113 state_number: DfaStateId,
114 start_index: usize,
115 precedence: i32,
116 outer_context: ContextId,
117 force_full_context_retry: bool,
118 sll_probe_only: bool,
119}
120
121#[derive(Clone, Copy)]
122struct AdaptivePredictRequest {
123 decision: usize,
124 precedence: usize,
125 outer_context: ContextId,
126 force_full_context_retry: bool,
127 sll_probe_only: bool,
135}
136
137#[derive(Clone, Copy)]
138struct DfaEdge {
139 decision: usize,
140 source_state: DfaStateId,
141}
142
143#[derive(Clone, Debug, Eq, PartialEq)]
144struct DfaPredictionInfo {
145 prediction: ParserAtnPrediction,
146 conflicting_alts: Vec<usize>,
147}
148
149#[derive(Clone, Debug, Eq, PartialEq)]
150struct FullContextPrediction {
151 prediction: ParserAtnPrediction,
152 stop_index: usize,
153 resolution: FullContextResolution,
154}
155
156#[derive(Clone, Debug, Eq, PartialEq)]
161enum FullContextResolution {
162 Unique,
163 Ambiguous { exact: bool, alts: Vec<usize> },
164}
165
166fn full_context_prediction(
167 alt: usize,
168 configs: &AtnConfigSet,
169 stop_index: usize,
170 resolution: FullContextResolution,
171) -> FullContextPrediction {
172 FullContextPrediction {
173 prediction: ParserAtnPrediction {
174 alt,
175 requires_full_context: true,
176 has_semantic_context: configs_have_semantic_context_for_alt(configs, alt),
177 diagnostic: None,
178 },
179 stop_index,
180 resolution,
181 }
182}
183
184#[derive(Clone, Debug, Eq, Hash, PartialEq)]
185struct ClosureConfigKey {
186 state: usize,
187 alt: usize,
188 context: ContextId,
189 semantic_context: SemanticContext,
190 precedence_filter_suppressed: bool,
191}
192
193impl From<&AtnConfig> for ClosureConfigKey {
194 fn from(config: &AtnConfig) -> Self {
195 Self {
196 state: config.state,
197 alt: config.alt,
198 context: config.context,
199 semantic_context: config.semantic_context.clone(),
200 precedence_filter_suppressed: config.precedence_filter_suppressed,
201 }
202 }
203}
204
205#[derive(Default)]
212struct ClosureScratch {
213 stack: Vec<(AtnConfig, bool)>,
220 visited: FxHashSet<ClosureConfigKey>,
221}
222
223#[derive(Clone, Copy)]
226struct ClosureParams {
227 precedence: i32,
228 collect_predicates: bool,
229 treat_eof_as_epsilon: bool,
230}
231
232#[derive(Debug)]
233struct LookaheadIntStream {
234 symbols: Vec<i32>,
235 index: usize,
236}
237
238impl LookaheadIntStream {
239 const fn new(symbols: Vec<i32>) -> Self {
240 Self { symbols, index: 0 }
241 }
242}
243
244impl IntStream for LookaheadIntStream {
245 fn consume(&mut self) {
246 if self.la(1) != TOKEN_EOF {
247 self.index += 1;
248 }
249 }
250
251 fn la(&mut self, offset: isize) -> i32 {
252 if offset <= 0 {
253 return 0;
254 }
255 let offset = offset.cast_unsigned() - 1;
256 self.symbols
257 .get(self.index + offset)
258 .copied()
259 .unwrap_or(TOKEN_EOF)
260 }
261
262 fn index(&self) -> usize {
263 self.index
264 }
265
266 fn seek(&mut self, index: usize) {
267 self.index = index.min(self.symbols.len());
268 }
269
270 fn size(&self) -> usize {
271 self.symbols.len()
272 }
273}
274
275fn initial_decision_dfas(atn: &Atn) -> Vec<ParserDfa> {
276 atn.decision_to_state()
277 .iter()
278 .enumerate()
279 .map(|(decision, state)| {
280 let mut dfa = ParserDfa::with_max_token_type(state, decision, atn.max_token_type());
281 if atn
282 .state(state)
283 .is_some_and(AtnState::precedence_rule_decision)
284 {
285 dfa.set_precedence_dfa(true);
286 }
287 dfa
288 })
289 .collect()
290}
291
292fn union_decision_dfas(shared: &mut Vec<ParserDfa>, local: Vec<ParserDfa>) {
302 if shared.len() != local.len() {
303 *shared = local;
304 return;
305 }
306 for (shared_dfa, local_dfa) in shared.iter_mut().zip(local) {
307 union_decision_dfa(shared_dfa, local_dfa);
308 }
309}
310
311fn union_prediction_stores(
312 shared: &mut PredictionStore,
313 mut local: PredictionStore,
314 workspace: &mut PredictionWorkspace,
315) {
316 let remap = shared.contexts.import_all(&local.contexts, workspace);
317 for dfa in &mut local.decision_to_dfa {
318 dfa.remap_contexts(&remap, &shared.contexts);
319 }
320 union_decision_dfas(&mut shared.decision_to_dfa, local.decision_to_dfa);
321}
322
323fn union_decision_dfa(shared: &mut ParserDfa, local: ParserDfa) {
324 if shared.is_precedence_dfa() != local.is_precedence_dfa() {
325 if local.state_count() > shared.state_count() {
328 *shared = local;
329 }
330 return;
331 }
332 let mut renumber = Vec::with_capacity(local.state_count());
337 for state in local.states() {
338 let configs = local.configs(state.id());
339 let number = shared.state_id_for_configs(configs).unwrap_or_else(|| {
340 let missing = local.clone_state_without_edges(state.id());
341 shared.insert_state(missing)
342 });
343 renumber.push(number);
344 }
345 for state in local.states() {
350 let mapped = renumber[state.id().index()];
351 for transition in state.transitions() {
352 let Some(&mapped_target) = renumber.get(transition.target.index()) else {
353 continue;
354 };
355 if shared.edge(mapped, transition.symbol).is_none() {
356 shared.add_edge(mapped, transition.symbol, mapped_target);
357 }
358 }
359 }
360 if shared.start_state().is_none()
361 && let Some(start) = local.start_state()
362 && let Some(&mapped) = renumber.get(start.index())
363 {
364 shared.set_start_state(mapped);
365 }
366 for (precedence, start) in local.precedence_start_states().iter().copied().enumerate() {
367 if start == NO_DFA_STATE {
368 continue;
369 }
370 if shared.precedence_start_state(precedence).is_none()
371 && let Some(&mapped) = renumber.get(start.index())
372 {
373 shared.set_precedence_start_state(precedence, mapped);
374 }
375 }
376}
377
378impl Drop for ParserAtnSimulator<'_> {
379 fn drop(&mut self) {
380 let Some(key) = self.shared_cache_key else {
381 return;
382 };
383 #[cfg(feature = "perf-counters")]
384 let publication_started = std::time::Instant::now();
385 #[cfg(feature = "perf-counters")]
386 let published_states = self
387 .store
388 .decision_to_dfa
389 .iter()
390 .map(ParserDfa::state_count)
391 .sum();
392 let store = std::mem::take(&mut self.store);
398 let published = SHARED_PREDICTION_STORES.with(|cache| {
399 let mut cache = cache.borrow_mut();
400 let shared = cache.entry(key).or_default();
401 if shared.generation != self.shared_cache_generation {
402 return false;
403 }
404 if let Some(shared_store) = shared.store.as_mut() {
405 union_prediction_stores(shared_store, store, &mut self.workspace);
406 } else {
407 shared.store = Some(store);
408 }
409 true
410 });
411 #[cfg(feature = "perf-counters")]
412 if published {
413 crate::perf::record_dfa_cache_publication(
414 publication_started.elapsed().as_nanos(),
415 published_states,
416 );
417 }
418 #[cfg(not(feature = "perf-counters"))]
419 let _ = published;
420 }
421}
422
423impl<'a> ParserAtnSimulator<'a> {
424 pub fn new(atn: &'a Atn) -> Self {
425 Self {
426 atn,
427 store: PredictionStore::new(atn),
428 workspace: PredictionWorkspace::default(),
429 outer_context_cache: None,
430 outer_context_cache_hits: 0,
431 outer_context_cache_misses: 0,
432 shared_cache_key: None,
433 shared_cache_generation: 0,
434 exact_ambig_detection: false,
435 }
436 }
437
438 pub fn reset(&mut self) {
440 self.outer_context_cache = None;
441 self.workspace.reset();
442 }
443
444 pub fn clear_dfa(&mut self) {
449 self.store = PredictionStore::new(self.atn);
450 self.reset();
451 if let Some(key) = self.shared_cache_key {
452 self.shared_cache_generation = clear_shared_prediction_store(key);
453 }
454 }
455
456 pub fn clear_shared_dfa(atn: &'static Atn) {
458 let ptr: *const Atn = atn;
459 clear_shared_prediction_store(ptr as usize);
460 }
461
462 pub const fn set_exact_ambig_detection(&mut self, exact: bool) {
465 self.exact_ambig_detection = exact;
466 }
467
468 pub fn dump_dfa_java_style(&self, vocabulary: &crate::vocabulary::Vocabulary) -> String {
486 use std::fmt::Write as _;
487 let mut out = String::new();
488 let mut seen_one = false;
489 for dfa in &self.store.decision_to_dfa {
490 if dfa.is_empty() {
491 continue;
492 }
493 if seen_one {
494 out.push('\n');
495 }
496 seen_one = true;
497 let _ = writeln!(out, "Decision {}:", dfa.decision());
498 for state in dfa.states() {
499 let source = dfa_state_display(state);
500 for transition in state.transitions() {
501 let Some(target_state) = dfa.state(transition.target) else {
502 continue;
503 };
504 let label = vocabulary.display_name(transition.symbol);
505 let _ = writeln!(out, "{source}-{label}->{}", dfa_state_display(target_state));
506 }
507 }
508 }
509 out
510 }
511
512 pub fn new_shared(atn: &'static Atn) -> Self {
513 let ptr: *const Atn = atn;
514 let key = ptr as usize;
515 #[cfg(feature = "perf-counters")]
516 let import_started = std::time::Instant::now();
517 let (store, generation) = SHARED_PREDICTION_STORES.with(|cache| {
518 let mut cache = cache.borrow_mut();
519 let shared = cache.entry(key).or_default();
520 (
521 shared
522 .store
523 .take()
524 .unwrap_or_else(|| PredictionStore::new(atn)),
525 shared.generation,
526 )
527 });
528 #[cfg(feature = "perf-counters")]
529 crate::perf::record_dfa_cache_import(
530 import_started.elapsed().as_nanos(),
531 store
532 .decision_to_dfa
533 .iter()
534 .map(ParserDfa::state_count)
535 .sum(),
536 );
537 Self {
538 atn,
539 store,
540 workspace: PredictionWorkspace::default(),
541 outer_context_cache: None,
542 outer_context_cache_hits: 0,
543 outer_context_cache_misses: 0,
544 shared_cache_key: Some(key),
545 shared_cache_generation: generation,
546 exact_ambig_detection: false,
547 }
548 }
549
550 pub fn decision_dfas(&self) -> &[ParserDfa] {
551 &self.store.decision_to_dfa
552 }
553
554 pub fn parser_dfa_stats(&self) -> ParserDfaStats {
556 let mut stats = ParserDfaStats::default();
557 for dfa in &self.store.decision_to_dfa {
558 stats.add_assign(dfa.stats());
559 }
560 stats
561 }
562
563 pub fn prediction_context_stats(&self) -> PredictionContextStats {
566 let mut stats = self.store.contexts.stats();
567 stats.retained_bytes += self.workspace.retained_bytes();
568 stats.workspace_merge_cache_entries = self.workspace.merge_cache_len();
569 stats.workspace_merge_cache_capacity = self.workspace.merge_cache_capacity();
570 stats.workspace_entry_capacity = self.workspace.entry_capacity();
571 stats.outer_context_cache_hits = self.outer_context_cache_hits;
572 stats.outer_context_cache_misses = self.outer_context_cache_misses;
573 stats
574 }
575
576 pub fn intern_prediction_context(
580 &mut self,
581 rule_context_version: usize,
582 return_states: impl IntoIterator<Item = usize>,
583 ) -> ContextId {
584 if let Some(cached) = self.outer_context_cache
585 && cached.rule_context_version == rule_context_version
586 {
587 self.outer_context_cache_hits = self.outer_context_cache_hits.saturating_add(1);
588 return cached.context;
589 }
590 self.outer_context_cache_misses = self.outer_context_cache_misses.saturating_add(1);
591 let mut context = EMPTY_CONTEXT;
592 for return_state in return_states {
593 context = self.store.contexts.singleton(context, return_state);
594 }
595 self.outer_context_cache = Some(CachedOuterContext {
596 rule_context_version,
597 context,
598 });
599 context
600 }
601
602 pub fn adaptive_predict(
603 &mut self,
604 decision: usize,
605 lookahead: impl IntoIterator<Item = i32>,
606 ) -> Result<usize, ParserAtnSimulatorError> {
607 self.adaptive_predict_with_precedence(decision, 0, lookahead)
608 }
609
610 pub fn adaptive_predict_stream<T: IntStream>(
611 &mut self,
612 decision: usize,
613 input: &mut T,
614 ) -> Result<usize, ParserAtnSimulatorError> {
615 self.adaptive_predict_stream_with_precedence(decision, 0, input)
616 }
617
618 pub fn adaptive_predict_stream_with_precedence<T: IntStream>(
619 &mut self,
620 decision: usize,
621 precedence: usize,
622 input: &mut T,
623 ) -> Result<usize, ParserAtnSimulatorError> {
624 self.adaptive_predict_stream_info_with_precedence(decision, precedence, input)
625 .map(|prediction| prediction.alt)
626 }
627
628 pub fn adaptive_predict_stream_info_with_precedence<T: IntStream>(
629 &mut self,
630 decision: usize,
631 precedence: usize,
632 input: &mut T,
633 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
634 let marker = input.mark();
635 let index = input.index();
636 let mut workspace = std::mem::take(&mut self.workspace);
637 workspace.reset();
638 let result = self.adaptive_predict_stream_inner(
639 AdaptivePredictRequest {
640 decision,
641 precedence,
642 outer_context: EMPTY_CONTEXT,
643 force_full_context_retry: false,
644 sll_probe_only: false,
645 },
646 input,
647 &mut workspace,
648 );
649 self.workspace = workspace;
650 input.seek(index);
651 input.release(marker);
652 result
653 }
654
655 pub fn adaptive_predict_stream_info_sll_probe<T: IntStream>(
665 &mut self,
666 decision: usize,
667 precedence: usize,
668 input: &mut T,
669 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
670 let marker = input.mark();
671 let index = input.index();
672 let mut workspace = std::mem::take(&mut self.workspace);
673 workspace.reset();
674 let result = self.adaptive_predict_stream_inner(
675 AdaptivePredictRequest {
676 decision,
677 precedence,
678 outer_context: EMPTY_CONTEXT,
679 force_full_context_retry: false,
680 sll_probe_only: true,
681 },
682 input,
683 &mut workspace,
684 );
685 self.workspace = workspace;
686 input.seek(index);
687 input.release(marker);
688 result
689 }
690
691 pub fn adaptive_predict_stream_info_with_context<T: IntStream>(
692 &mut self,
693 decision: usize,
694 precedence: usize,
695 input: &mut T,
696 outer_context: ContextId,
697 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
698 self.store.contexts.assert_valid(outer_context);
699 let marker = input.mark();
700 let index = input.index();
701 let mut workspace = std::mem::take(&mut self.workspace);
702 workspace.reset();
703 let result = self.adaptive_predict_stream_inner(
704 AdaptivePredictRequest {
705 decision,
706 precedence,
707 outer_context,
708 force_full_context_retry: true,
709 sll_probe_only: false,
710 },
711 input,
712 &mut workspace,
713 );
714 self.workspace = workspace;
715 input.seek(index);
716 input.release(marker);
717 result
718 }
719
720 pub fn adaptive_predict_with_precedence(
721 &mut self,
722 decision: usize,
723 precedence: usize,
724 lookahead: impl IntoIterator<Item = i32>,
725 ) -> Result<usize, ParserAtnSimulatorError> {
726 self.adaptive_predict_info_with_precedence(decision, precedence, lookahead)
727 .map(|prediction| prediction.alt)
728 }
729
730 pub fn adaptive_predict_info_with_precedence(
731 &mut self,
732 decision: usize,
733 precedence: usize,
734 lookahead: impl IntoIterator<Item = i32>,
735 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
736 let mut input = LookaheadIntStream::new(lookahead.into_iter().collect());
737 self.adaptive_predict_stream_info_with_precedence(decision, precedence, &mut input)
738 }
739
740 fn adaptive_predict_stream_inner<T: IntStream>(
741 &mut self,
742 request: AdaptivePredictRequest,
743 input: &mut T,
744 merge_cache: &mut PredictionWorkspace,
745 ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
746 let AdaptivePredictRequest {
747 decision,
748 precedence,
749 outer_context,
750 force_full_context_retry,
751 sll_probe_only,
752 } = request;
753 #[cfg(feature = "perf-counters")]
754 crate::perf::record_adaptive_call(decision, force_full_context_retry);
755 let Some(decision_state) = self.atn.decision_to_state().get(decision) else {
756 return Err(ParserAtnSimulatorError::UnknownDecision(decision));
757 };
758 let start_index = input.index();
759 let precedence = i32::try_from(precedence).unwrap_or(i32::MAX);
765 let mut state_number =
766 self.ensure_start_state(decision, decision_state, precedence, merge_cache)?;
767 if let Some(prediction) = self.prediction_or_full_context(
768 input,
769 PredictionCheck {
770 decision,
771 decision_state,
772 state_number,
773 start_index,
774 precedence,
775 outer_context,
776 force_full_context_retry,
777 sll_probe_only,
778 },
779 merge_cache,
780 )? {
781 return Ok(prediction);
782 }
783 loop {
784 let symbol = input.la(1);
785 let target = self
786 .store
787 .decision_to_dfa
788 .get(decision)
789 .and_then(|dfa| dfa.edge(state_number, symbol));
790 #[cfg(feature = "perf-counters")]
791 crate::perf::record_dfa_edge_lookup(target.is_some());
792 if let Some(target) = target {
793 state_number = target;
794 } else {
795 let configs = self
796 .store
797 .decision_to_dfa
798 .get(decision)
799 .map(|dfa| dfa.configs(state_number).clone())
800 .ok_or(ParserAtnSimulatorError::MissingDfaState(state_number))?;
801 let target = match self.compute_target_state(
802 DfaEdge {
803 decision,
804 source_state: state_number,
805 },
806 &configs,
807 symbol,
808 precedence,
809 merge_cache,
810 ) {
811 Ok(target) => target,
812 Err(ParserAtnSimulatorError::NoViableAlt { symbol, .. }) => {
813 return Err(ParserAtnSimulatorError::NoViableAlt {
814 symbol,
815 index: input.index(),
816 });
817 }
818 Err(error) => return Err(error),
819 };
820 state_number = target;
821 }
822 if let Some(prediction) = self.prediction_or_full_context(
823 input,
824 PredictionCheck {
825 decision,
826 decision_state,
827 state_number,
828 start_index,
829 precedence,
830 outer_context,
831 force_full_context_retry,
832 sll_probe_only,
833 },
834 merge_cache,
835 )? {
836 return Ok(prediction);
837 }
838 if symbol == TOKEN_EOF {
839 if let Some(configs) = self
849 .store
850 .decision_to_dfa
851 .get(decision)
852 .map(|dfa| dfa.configs(state_number).clone())
853 && let Some(alt) = self.alt_that_finished_decision_entry_rule(&configs)
854 {
855 return Ok(ParserAtnPrediction {
856 alt,
857 requires_full_context: false,
858 has_semantic_context: configs_have_semantic_context_for_alt(&configs, alt),
859 diagnostic: None,
860 });
861 }
862 return Err(ParserAtnSimulatorError::PredictionRequiresMoreLookahead);
863 }
864 input.consume();
865 }
866 }
867
868 fn prediction_or_full_context<T: IntStream>(
869 &mut self,
870 input: &mut T,
871 check: PredictionCheck,
872 merge_cache: &mut PredictionWorkspace,
873 ) -> Result<Option<ParserAtnPrediction>, ParserAtnSimulatorError> {
874 let PredictionCheck {
875 decision,
876 decision_state,
877 state_number,
878 start_index,
879 precedence,
880 outer_context,
881 force_full_context_retry,
882 sll_probe_only,
883 } = check;
884 if self.store.contexts.is_empty(outer_context)
885 && let Some(prediction) =
886 self.non_greedy_exit_prediction(decision, decision_state, state_number)
887 {
888 return Ok(Some(prediction));
889 }
890 let Some(info) = self.dfa_prediction_info(decision, state_number) else {
891 return Ok(None);
892 };
893 let prediction = info.prediction;
894 if sll_probe_only && prediction.requires_full_context {
901 return Ok(Some(prediction));
902 }
903 if prediction.requires_full_context
904 && (force_full_context_retry || !prediction.has_semantic_context)
905 {
906 #[cfg(feature = "perf-counters")]
907 crate::perf::record_full_context_retry(decision);
908 let sll_stop_index = input.index();
909 input.seek(start_index);
910 let full_context = self.adaptive_predict_full_context(
911 decision_state,
912 input,
913 precedence,
914 outer_context,
915 merge_cache,
916 )?;
917 let (kind, exact, conflicting_alts) = match full_context.resolution {
918 FullContextResolution::Ambiguous { exact, ref alts } => (
919 ParserAtnPredictionDiagnosticKind::Ambiguity,
920 exact,
921 alts.clone(),
922 ),
923 FullContextResolution::Unique => (
927 ParserAtnPredictionDiagnosticKind::ContextSensitivity,
928 false,
929 info.conflicting_alts,
930 ),
931 };
932 let mut prediction = full_context.prediction;
933 if conflicting_alts.len() > 1 {
934 prediction.diagnostic = Some(ParserAtnPredictionDiagnostic {
935 kind,
936 start_index,
937 sll_stop_index,
938 ll_stop_index: full_context.stop_index,
939 conflicting_alts,
940 exact,
941 });
942 }
943 return Ok(Some(prediction));
944 }
945 Ok(Some(prediction))
946 }
947
948 fn non_greedy_exit_prediction(
949 &self,
950 decision: usize,
951 decision_state: usize,
952 state_number: DfaStateId,
953 ) -> Option<ParserAtnPrediction> {
954 if !self
955 .atn
956 .state(decision_state)
957 .is_some_and(AtnState::non_greedy)
958 {
959 return None;
960 }
961 let configs = &self
962 .store
963 .decision_to_dfa
964 .get(decision)?
965 .configs(state_number);
966 let alt = configs
967 .configs()
968 .iter()
969 .filter(|config| {
970 self.atn
971 .state(config.state)
972 .is_some_and(AtnState::is_rule_stop)
973 && self.store.contexts.has_empty_path(config.context)
974 })
975 .map(|config| config.alt)
976 .min()?;
977 Some(ParserAtnPrediction {
978 alt,
979 requires_full_context: false,
980 has_semantic_context: configs_have_semantic_context_for_alt(configs, alt),
981 diagnostic: None,
982 })
983 }
984
985 fn ensure_start_state(
986 &mut self,
987 decision: usize,
988 decision_state: usize,
989 precedence: i32,
990 merge_cache: &mut PredictionWorkspace,
991 ) -> Result<DfaStateId, ParserAtnSimulatorError> {
992 if self.store.decision_to_dfa[decision].is_precedence_dfa() {
993 let precedence_key = usize::try_from(precedence.max(0)).unwrap_or_default();
994 if let Some(start) =
995 self.store.decision_to_dfa[decision].precedence_start_state(precedence_key)
996 {
997 return Ok(start);
998 }
999 } else if let Some(start) = self.store.decision_to_dfa[decision].start_state() {
1000 return Ok(start);
1001 }
1002 let decision_state = self
1003 .atn
1004 .state(decision_state)
1005 .ok_or(ParserAtnSimulatorError::MissingAtnState(decision_state))?;
1006 let configs = self.compute_start_state(decision_state, precedence, merge_cache);
1007 let state_number = self.add_dfa_state(decision, DfaStateBuilder::new(configs));
1008 if self.store.decision_to_dfa[decision].is_precedence_dfa() {
1009 let precedence_key = usize::try_from(precedence.max(0)).unwrap_or_default();
1010 self.store.decision_to_dfa[decision]
1011 .set_precedence_start_state(precedence_key, state_number);
1012 } else {
1013 self.store.decision_to_dfa[decision].set_start_state(state_number);
1014 }
1015 Ok(state_number)
1016 }
1017
1018 fn add_dfa_state(&mut self, decision: usize, state: DfaStateBuilder) -> DfaStateId {
1019 self.store.decision_to_dfa[decision].add_state(state)
1020 }
1021
1022 fn compute_start_state(
1023 &mut self,
1024 decision_state: AtnState<'_>,
1025 precedence: i32,
1026 merge_cache: &mut PredictionWorkspace,
1027 ) -> AtnConfigSet {
1028 self.compute_start_state_with_context(
1029 decision_state,
1030 false,
1031 EMPTY_CONTEXT,
1032 precedence,
1033 merge_cache,
1034 )
1035 }
1036
1037 fn compute_start_state_with_context(
1038 &mut self,
1039 decision_state: AtnState<'_>,
1040 full_context: bool,
1041 initial_context: ContextId,
1042 precedence: i32,
1043 merge_cache: &mut PredictionWorkspace,
1044 ) -> AtnConfigSet {
1045 let mut configs = AtnConfigSet::new_full_context(full_context);
1046 let mut scratch = ClosureScratch::default();
1047 let params = ClosureParams {
1048 precedence,
1049 collect_predicates: true,
1050 treat_eof_as_epsilon: false,
1051 };
1052 for (index, transition) in decision_state.transitions().iter().enumerate() {
1053 let alt = index + 1;
1054 let config = AtnConfig::new(
1055 transition.target(),
1056 alt,
1057 initial_context,
1058 &self.store.contexts,
1059 );
1060 self.closure(config, &mut configs, merge_cache, &mut scratch, params);
1061 }
1062 configs
1063 }
1064
1065 fn adaptive_predict_full_context<T: IntStream>(
1066 &mut self,
1067 decision_state: usize,
1068 input: &mut T,
1069 precedence: i32,
1070 outer_context: ContextId,
1071 merge_cache: &mut PredictionWorkspace,
1072 ) -> Result<FullContextPrediction, ParserAtnSimulatorError> {
1073 let decision_state = self
1074 .atn
1075 .state(decision_state)
1076 .ok_or(ParserAtnSimulatorError::MissingAtnState(decision_state))?;
1077 let mut configs = self.compute_start_state_with_context(
1078 decision_state,
1079 true,
1080 outer_context,
1081 precedence,
1082 merge_cache,
1083 );
1084 loop {
1092 if let Some(alt) = configs.unique_alt() {
1093 return Ok(full_context_prediction(
1094 alt,
1095 &configs,
1096 input.index(),
1097 FullContextResolution::Unique,
1098 ));
1099 }
1100 let symbol = input.la(1);
1101 let reach = self.compute_reach_set(&configs, symbol, true, precedence, merge_cache);
1102 if reach.is_empty() {
1103 return Err(ParserAtnSimulatorError::NoViableAlt {
1104 symbol,
1105 index: input.index(),
1106 });
1107 }
1108 configs = reach;
1109 if let Some(alt) = configs.unique_alt() {
1110 return Ok(full_context_prediction(
1111 alt,
1112 &configs,
1113 input.index(),
1114 FullContextResolution::Unique,
1115 ));
1116 }
1117 if !configs.has_semantic_context() {
1118 let subsets = conflicting_alt_subsets(configs.configs());
1119 if self.exact_ambig_detection {
1120 let alts: Vec<usize> = configs.alts().into_iter().collect();
1121 if all_subsets_conflict(&subsets)
1125 && all_subsets_equal(&subsets)
1126 && let Some(&alt) = alts.first()
1127 {
1128 return Ok(full_context_prediction(
1129 alt,
1130 &configs,
1131 input.index(),
1132 FullContextResolution::Ambiguous { exact: true, alts },
1133 ));
1134 }
1135 } else if let Some(alt) = single_viable_alt(&subsets) {
1136 let alts: Vec<usize> = configs.alts().into_iter().collect();
1137 return Ok(full_context_prediction(
1138 alt,
1139 &configs,
1140 input.index(),
1141 FullContextResolution::Ambiguous { exact: false, alts },
1142 ));
1143 }
1144 }
1145 if symbol == TOKEN_EOF || self.configs_all_reached_rule_stop(&configs) {
1146 let alts: Vec<usize> = configs.alts().into_iter().collect();
1151 let alt = *alts
1152 .first()
1153 .ok_or(ParserAtnSimulatorError::PredictionRequiresMoreLookahead)?;
1154 let resolution = if alts.len() > 1 {
1155 FullContextResolution::Ambiguous {
1156 exact: self.exact_ambig_detection,
1157 alts,
1158 }
1159 } else {
1160 FullContextResolution::Unique
1161 };
1162 return Ok(full_context_prediction(
1163 alt,
1164 &configs,
1165 input.index(),
1166 resolution,
1167 ));
1168 }
1169 input.consume();
1170 }
1171 }
1172
1173 fn compute_target_state(
1174 &mut self,
1175 edge: DfaEdge,
1176 configs: &AtnConfigSet,
1177 symbol: i32,
1178 precedence: i32,
1179 merge_cache: &mut PredictionWorkspace,
1180 ) -> Result<DfaStateId, ParserAtnSimulatorError> {
1181 let mut reach = self.compute_reach_set(configs, symbol, false, precedence, merge_cache);
1182 if reach.is_empty() {
1183 if let Some(prediction) = self.alt_that_finished_decision_entry_rule(configs) {
1184 let mut dfa_state = DfaStateBuilder::new(configs.clone());
1185 dfa_state.mark_accept(prediction);
1186 dfa_state.set_has_semantic_context_for_alt(
1189 configs.has_semantic_context()
1190 && configs_have_semantic_context_for_alt(configs, prediction),
1191 );
1192 let target_state = self.add_dfa_state(edge.decision, dfa_state);
1193 self.store.decision_to_dfa[edge.decision].add_edge(
1194 edge.source_state,
1195 symbol,
1196 target_state,
1197 );
1198 return Ok(target_state);
1199 }
1200 return Err(ParserAtnSimulatorError::NoViableAlt { symbol, index: 0 });
1201 }
1202 let prediction = reach.unique_alt();
1203 let conflict_prediction = prediction.or_else(|| {
1204 if !has_sll_conflict_terminating_prediction(&reach, |state| {
1205 self.atn.state(state).is_some_and(AtnState::is_rule_stop)
1206 }) {
1207 return None;
1208 }
1209 reach
1210 .conflicting_alts()
1211 .into_iter()
1212 .next()
1213 .or_else(|| reach.alts().into_iter().next())
1214 });
1215 let requires_full_context = prediction.is_none() && conflict_prediction.is_some();
1216 #[cfg(feature = "perf-counters")]
1217 if requires_full_context {
1218 crate::perf::record_sll_conflict(edge.decision);
1219 }
1220 let conflicting_alts = if requires_full_context {
1221 let alts = reach.conflicting_alts();
1222 if alts.is_empty() { reach.alts() } else { alts }
1223 .into_iter()
1224 .collect()
1225 } else {
1226 Vec::new()
1227 };
1228 let mut dfa_state = DfaStateBuilder::new(reach);
1229 if let Some(prediction) = conflict_prediction {
1230 dfa_state.mark_accept(prediction);
1231 dfa_state.set_requires_full_context(requires_full_context);
1232 dfa_state.set_conflicting_alts(conflicting_alts);
1233 dfa_state.set_has_semantic_context_for_alt(
1236 dfa_state.configs.has_semantic_context()
1237 && configs_have_semantic_context_for_alt(&dfa_state.configs, prediction),
1238 );
1239 }
1240 let target_state = self.add_dfa_state(edge.decision, dfa_state);
1241 self.store.decision_to_dfa[edge.decision].add_edge(edge.source_state, symbol, target_state);
1242 Ok(target_state)
1243 }
1244
1245 fn compute_reach_set(
1246 &mut self,
1247 configs: &AtnConfigSet,
1248 symbol: i32,
1249 full_context: bool,
1250 precedence: i32,
1251 merge_cache: &mut PredictionWorkspace,
1252 ) -> AtnConfigSet {
1253 let mut intermediate = AtnConfigSet::new_full_context(full_context);
1254 let mut skipped_stop_states = Vec::new();
1255 let max_token_type = self.atn.max_token_type();
1256 for config in configs.configs() {
1257 let Some(state) = self.atn.state(config.state) else {
1258 continue;
1259 };
1260 if state.is_rule_stop() {
1261 if full_context || symbol == TOKEN_EOF {
1262 skipped_stop_states.push(config.clone());
1263 }
1264 continue;
1265 }
1266 for transition in &state.transitions() {
1267 if transition.matches(symbol, 1, max_token_type) {
1268 let target =
1269 config.moved_to(transition.target(), config.context, &self.store.contexts);
1270 intermediate.add(target, &mut self.store.contexts, merge_cache);
1271 }
1272 }
1273 }
1274 let mut reach = if skipped_stop_states.is_empty() && symbol != TOKEN_EOF {
1275 if intermediate.len() == 1 || intermediate.unique_alt().is_some() {
1276 intermediate
1277 } else {
1278 self.close_intermediate_reach_set(
1279 intermediate,
1280 full_context,
1281 precedence,
1282 symbol,
1283 merge_cache,
1284 )
1285 }
1286 } else {
1287 self.close_intermediate_reach_set(
1288 intermediate,
1289 full_context,
1290 precedence,
1291 symbol,
1292 merge_cache,
1293 )
1294 };
1295 if symbol == TOKEN_EOF {
1296 reach = self.rule_stop_configs(reach, merge_cache);
1297 }
1298 if !full_context || !self.configs_contain_rule_stop(&reach) {
1299 for config in skipped_stop_states {
1300 reach.add(config, &mut self.store.contexts, merge_cache);
1301 }
1302 }
1303 #[cfg(feature = "perf-counters")]
1304 crate::perf::record_reach_set(full_context, configs.len(), reach.len());
1305 reach
1306 }
1307
1308 fn close_intermediate_reach_set(
1309 &mut self,
1310 intermediate: AtnConfigSet,
1311 full_context: bool,
1312 precedence: i32,
1313 symbol: i32,
1314 merge_cache: &mut PredictionWorkspace,
1315 ) -> AtnConfigSet {
1316 let mut reach = AtnConfigSet::new_full_context(full_context);
1317 let mut scratch = ClosureScratch::default();
1318 let params = ClosureParams {
1319 precedence,
1320 collect_predicates: false,
1321 treat_eof_as_epsilon: symbol == TOKEN_EOF,
1322 };
1323 for config in intermediate.into_configs() {
1326 self.closure(config, &mut reach, merge_cache, &mut scratch, params);
1327 }
1328 reach
1329 }
1330
1331 fn alt_that_finished_decision_entry_rule(&self, configs: &AtnConfigSet) -> Option<usize> {
1332 configs
1333 .configs()
1334 .iter()
1335 .filter(|config| {
1336 config.reaches_into_outer_context > 0
1337 || self
1338 .atn
1339 .state(config.state)
1340 .is_some_and(AtnState::is_rule_stop)
1341 && self.store.contexts.has_empty_path(config.context)
1342 })
1343 .map(|config| config.alt)
1344 .min()
1345 }
1346
1347 fn rule_stop_configs(
1348 &mut self,
1349 configs: AtnConfigSet,
1350 merge_cache: &mut PredictionWorkspace,
1351 ) -> AtnConfigSet {
1352 if configs.configs().iter().all(|config| {
1353 self.atn
1354 .state(config.state)
1355 .is_some_and(AtnState::is_rule_stop)
1356 }) {
1357 return configs;
1358 }
1359 let mut result = AtnConfigSet::new_full_context(configs.full_context());
1360 for config in configs.configs().iter().filter(|config| {
1361 self.atn
1362 .state(config.state)
1363 .is_some_and(AtnState::is_rule_stop)
1364 }) {
1365 result.add(config.clone(), &mut self.store.contexts, merge_cache);
1366 }
1367 result
1368 }
1369
1370 fn configs_all_reached_rule_stop(&self, configs: &AtnConfigSet) -> bool {
1371 configs.configs().iter().all(|config| {
1372 self.atn
1373 .state(config.state)
1374 .is_some_and(AtnState::is_rule_stop)
1375 })
1376 }
1377
1378 fn configs_contain_rule_stop(&self, configs: &AtnConfigSet) -> bool {
1379 configs.configs().iter().any(|config| {
1380 self.atn
1381 .state(config.state)
1382 .is_some_and(AtnState::is_rule_stop)
1383 })
1384 }
1385
1386 fn closure(
1387 &mut self,
1388 config: AtnConfig,
1389 configs: &mut AtnConfigSet,
1390 merge_cache: &mut PredictionWorkspace,
1391 scratch: &mut ClosureScratch,
1392 params: ClosureParams,
1393 ) {
1394 let ClosureParams {
1395 precedence,
1396 collect_predicates,
1397 treat_eof_as_epsilon,
1398 } = params;
1399 let max_token_type = self.atn.max_token_type();
1400 scratch.stack.clear();
1401 scratch.visited.clear();
1402 scratch.stack.push((config, collect_predicates));
1403 while let Some((config, collect_predicates)) = scratch.stack.pop() {
1404 if !scratch.visited.insert(ClosureConfigKey::from(&config)) {
1405 continue;
1406 }
1407 let Some(state) = self.atn.state(config.state) else {
1408 continue;
1409 };
1410 let at_rule_stop = state.is_rule_stop();
1411 if at_rule_stop
1412 && self.closure_at_rule_stop(
1413 config.clone(),
1414 collect_predicates,
1415 configs,
1416 merge_cache,
1417 &mut scratch.stack,
1418 )
1419 {
1420 continue;
1421 }
1422 let epsilon_only = state.epsilon_only();
1423 if !epsilon_only {
1424 configs.add(config.clone(), &mut self.store.contexts, merge_cache);
1425 }
1426 for (index, transition) in state.transitions().iter().enumerate() {
1427 if index == 0
1428 && can_drop_left_recursive_loop_entry_edge(
1429 self.atn,
1430 state,
1431 &self.store.contexts,
1432 config.context,
1433 )
1434 {
1435 continue;
1436 }
1437 let transition_kind = transition.kind();
1438 if matches!(
1439 transition_kind,
1440 ParserTransitionKind::Epsilon
1441 | ParserTransitionKind::Rule
1442 | ParserTransitionKind::Predicate
1443 | ParserTransitionKind::Action
1444 | ParserTransitionKind::Precedence
1445 ) {
1446 if let Some(mut target) = self.epsilon_target_config(
1447 &config,
1448 transition,
1449 transition_kind,
1450 precedence,
1451 collect_predicates,
1452 configs.full_context(),
1453 ) {
1454 if at_rule_stop {
1455 target.reaches_into_outer_context =
1456 target.reaches_into_outer_context.saturating_add(1);
1457 }
1458 let target_collect_predicates =
1462 collect_predicates && transition_kind != ParserTransitionKind::Action;
1463 scratch.stack.push((target, target_collect_predicates));
1464 }
1465 } else if treat_eof_as_epsilon
1466 && transition.matches_kind(transition_kind, TOKEN_EOF, 1, max_token_type)
1467 {
1468 scratch.stack.push((
1469 config.moved_to(transition.target(), config.context, &self.store.contexts),
1470 collect_predicates,
1471 ));
1472 }
1473 }
1474 }
1475 #[cfg(feature = "perf-counters")]
1476 crate::perf::record_closure(scratch.visited.len());
1477 }
1478
1479 fn closure_at_rule_stop(
1480 &mut self,
1481 config: AtnConfig,
1482 collect_predicates: bool,
1483 configs: &mut AtnConfigSet,
1484 merge_cache: &mut PredictionWorkspace,
1485 stack: &mut Vec<(AtnConfig, bool)>,
1486 ) -> bool {
1487 if self.store.contexts.is_empty(config.context) {
1488 if configs.full_context() {
1489 configs.add(config, &mut self.store.contexts, merge_cache);
1490 return true;
1491 }
1492 return false;
1493 }
1494 let mut handled_all_paths = true;
1495 for index in 0..self.store.contexts.len(config.context) {
1496 let Some(return_state) = self.store.contexts.return_state(config.context, index) else {
1497 continue;
1498 };
1499 if return_state == EMPTY_RETURN_STATE {
1500 if configs.full_context() {
1501 let mut empty_context_config = config.clone();
1502 empty_context_config.set_context(EMPTY_CONTEXT, &self.store.contexts);
1503 configs.add(empty_context_config, &mut self.store.contexts, merge_cache);
1504 } else {
1505 handled_all_paths = false;
1506 }
1507 continue;
1508 }
1509 let parent = self
1510 .store
1511 .contexts
1512 .parent(config.context, index)
1513 .unwrap_or(EMPTY_CONTEXT);
1514 let next = config.moved_to(return_state, parent, &self.store.contexts);
1515 stack.push((next, collect_predicates));
1516 }
1517 handled_all_paths
1518 }
1519
1520 #[allow(clippy::too_many_arguments)]
1521 fn epsilon_target_config(
1522 &mut self,
1523 config: &AtnConfig,
1524 transition: ParserTransition<'_>,
1525 transition_kind: ParserTransitionKind,
1526 precedence: i32,
1527 collect_predicates: bool,
1528 full_context: bool,
1529 ) -> Option<AtnConfig> {
1530 let semantic_context = match transition_kind {
1531 ParserTransitionKind::Predicate if collect_predicates => SemanticContext::and(
1532 config.semantic_context.clone(),
1533 SemanticContext::Predicate {
1534 rule_index: transition.arg0() as usize,
1535 pred_index: transition.arg1() as usize,
1536 context_dependent: transition.arg2() != 0,
1537 },
1538 ),
1539 ParserTransitionKind::Precedence
1540 if collect_predicates
1541 && i32::from_le_bytes(transition.arg0().to_le_bytes()) < precedence =>
1542 {
1543 return None;
1544 }
1545 ParserTransitionKind::Precedence if collect_predicates && !full_context => {
1546 SemanticContext::and(
1547 config.semantic_context.clone(),
1548 SemanticContext::Precedence {
1549 precedence: i32::from_le_bytes(transition.arg0().to_le_bytes()),
1550 },
1551 )
1552 }
1553 _ => config.semantic_context.clone(),
1554 };
1555 let context = if transition_kind == ParserTransitionKind::Rule {
1556 self.store
1557 .contexts
1558 .singleton(config.context, transition.arg1() as usize)
1559 } else {
1560 config.context
1561 };
1562 let mut target = config.moved_to(transition.target(), context, &self.store.contexts);
1563 target.semantic_context = semantic_context;
1564 Some(target)
1565 }
1566
1567 fn dfa_prediction_info(
1568 &self,
1569 decision: usize,
1570 state_number: DfaStateId,
1571 ) -> Option<DfaPredictionInfo> {
1572 let dfa = self.store.decision_to_dfa.get(decision)?;
1573 let state = dfa.state(state_number)?;
1574 let alt = state.prediction()?;
1575 let requires_full_context = state.requires_full_context();
1576 let conflicting_alts = if requires_full_context {
1577 let stored = dfa.conflicting_alts(state_number);
1578 if stored.is_empty() {
1579 dfa.configs(state_number).alts().into_iter().collect()
1580 } else {
1581 stored.to_vec()
1582 }
1583 } else {
1584 Vec::new()
1585 };
1586 Some(DfaPredictionInfo {
1587 prediction: ParserAtnPrediction {
1588 alt,
1589 requires_full_context,
1590 has_semantic_context: state.has_semantic_context(),
1593 diagnostic: None,
1594 },
1595 conflicting_alts,
1596 })
1597 }
1598}
1599
1600pub(crate) fn can_drop_left_recursive_loop_entry_edge(
1603 atn: &Atn,
1604 state: AtnState<'_>,
1605 contexts: &ContextArena,
1606 context: ContextId,
1607) -> bool {
1608 if state.kind() != AtnStateKind::StarLoopEntry
1609 || !state.precedence_rule_decision()
1610 || contexts.is_empty(context)
1611 || contexts.has_empty_path(context)
1612 {
1613 return false;
1614 }
1615 let Some(rule_index) = state.rule_index() else {
1616 return false;
1617 };
1618 for index in 0..contexts.len(context) {
1619 let Some(return_state_number) = contexts.return_state(context, index) else {
1620 return false;
1621 };
1622 let Some(return_state) = atn.state(return_state_number) else {
1623 return false;
1624 };
1625 if return_state.rule_index() != Some(rule_index) {
1626 return false;
1627 }
1628 }
1629 let Some(block_end_state_number) = state
1630 .transitions()
1631 .first()
1632 .and_then(|transition| atn.state(transition.target()))
1633 .and_then(AtnState::end_state)
1634 else {
1635 return false;
1636 };
1637 for index in 0..contexts.len(context) {
1638 let return_state_number = contexts
1639 .return_state(context, index)
1640 .expect("return state checked above");
1641 let return_state = atn
1642 .state(return_state_number)
1643 .expect("return state checked above");
1644 if return_state.state_number() == block_end_state_number {
1645 continue;
1646 }
1647 if return_state.transitions().len() != 1
1648 || !return_state
1649 .transitions()
1650 .first()
1651 .is_some_and(ParserTransition::is_epsilon)
1652 {
1653 return false;
1654 }
1655 let return_target = return_state
1656 .transitions()
1657 .first()
1658 .expect("single transition checked above")
1659 .target();
1660 if return_state.kind() == AtnStateKind::BlockEnd && return_target == state.state_number() {
1661 continue;
1662 }
1663 if return_target == block_end_state_number {
1664 continue;
1665 }
1666 let Some(return_target_state) = atn.state(return_target) else {
1667 return false;
1668 };
1669 if return_target_state.kind() == AtnStateKind::BlockEnd
1670 && return_target_state.transitions().len() == 1
1671 && return_target_state
1672 .transitions()
1673 .first()
1674 .is_some_and(ParserTransition::is_epsilon)
1675 && return_target_state
1676 .transitions()
1677 .first()
1678 .is_some_and(|transition| transition.target() == state.state_number())
1679 {
1680 continue;
1681 }
1682 return false;
1683 }
1684 true
1685}
1686
1687fn configs_have_semantic_context_for_alt(configs: &AtnConfigSet, alt: usize) -> bool {
1688 configs
1689 .configs()
1690 .iter()
1691 .any(|config| config.alt == alt && !config.semantic_context.is_none())
1692}
1693
1694#[derive(Clone, Debug, Eq, PartialEq)]
1695pub enum ParserAtnSimulatorError {
1696 MissingAtnState(usize),
1697 MissingDfaState(DfaStateId),
1698 NoViableAlt { symbol: i32, index: usize },
1699 PredictionRequiresMoreLookahead,
1700 UnknownDecision(usize),
1701}
1702
1703fn dfa_state_display(state: ParserDfaStateView<'_>) -> String {
1705 let mut out = String::new();
1706 if state.is_accept_state() {
1707 out.push(':');
1708 }
1709 out.push('s');
1710 out.push_str(&state.id().index().to_string());
1711 if state.requires_full_context() {
1712 out.push('^');
1713 }
1714 if state.is_accept_state() {
1715 out.push_str("=>");
1716 out.push_str(
1717 &state
1718 .prediction()
1719 .map(|prediction| prediction.to_string())
1720 .unwrap_or_default(),
1721 );
1722 }
1723 out
1724}
1725
1726#[cfg(test)]
1727mod tests {
1728 use super::*;
1729 use crate::atn::AtnStateKind;
1730
1731 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
1732 builder.finish().expect("valid packed parser ATN")
1733 }
1734
1735 #[test]
1736 fn union_decision_dfa_preserves_disjoint_coverage() {
1737 fn configs(
1738 atn_state: usize,
1739 arena: &mut ContextArena,
1740 workspace: &mut PredictionWorkspace,
1741 ) -> AtnConfigSet {
1742 let mut set = AtnConfigSet::new();
1743 set.add(
1744 AtnConfig::new(atn_state, 1, EMPTY_CONTEXT, arena),
1745 arena,
1746 workspace,
1747 );
1748 set
1749 }
1750 fn state(
1751 atn_state: usize,
1752 arena: &mut ContextArena,
1753 workspace: &mut PredictionWorkspace,
1754 ) -> DfaStateBuilder {
1755 DfaStateBuilder::new(configs(atn_state, arena, workspace))
1756 }
1757 let mut arena = ContextArena::new();
1758 let mut workspace = PredictionWorkspace::default();
1759
1760 let mut shared = ParserDfa::with_max_token_type(0, 0, 8);
1764 let shared_root = shared.add_state(state(10, &mut arena, &mut workspace));
1765 let shared_a = shared.add_state(state(11, &mut arena, &mut workspace));
1766 shared.add_edge(shared_root, 1, shared_a);
1767 shared.set_start_state(shared_root);
1768
1769 let mut local = ParserDfa::with_max_token_type(0, 0, 8);
1770 let local_b = local.add_state(state(12, &mut arena, &mut workspace));
1771 let local_root = local.add_state(state(10, &mut arena, &mut workspace));
1772 local.add_edge(local_root, 2, local_b);
1773 local.set_precedence_start_state(3, local_root);
1774
1775 union_decision_dfa(&mut shared, local);
1776
1777 assert_eq!(shared.edge(shared_root, 1), Some(shared_a));
1780 let merged_b = shared
1781 .state_id_for_configs(&configs(12, &mut arena, &mut workspace))
1782 .expect("local-only state adopted");
1783 assert_eq!(shared.edge(shared_root, 2), Some(merged_b));
1784 assert_eq!(shared.states().len(), 3);
1785 assert_eq!(shared.start_state(), Some(shared_root));
1787 assert_eq!(shared.precedence_start_state(3), Some(shared_root));
1788 }
1789
1790 #[test]
1791 fn union_prediction_stores_remaps_context_ids_before_dfa_union() {
1792 let atn = two_token_decision_atn();
1793 let mut shared = PredictionStore::new(&atn);
1794 let mut local = PredictionStore::new(&atn);
1795 let mut workspace = PredictionWorkspace::default();
1796
1797 let distracting = shared.contexts.singleton(EMPTY_CONTEXT, 99);
1798 let local_context = local.contexts.singleton(EMPTY_CONTEXT, 7);
1799 assert_eq!(distracting, local_context, "both stores allocate ID 1");
1800
1801 let mut configs = AtnConfigSet::new();
1802 configs.add(
1803 AtnConfig::new(42, 1, local_context, &local.contexts),
1804 &mut local.contexts,
1805 &mut workspace,
1806 );
1807 local.decision_to_dfa[0].add_state(DfaStateBuilder::new(configs));
1808
1809 union_prediction_stores(&mut shared, local, &mut workspace);
1810
1811 let imported = shared.decision_to_dfa[0]
1812 .states()
1813 .flat_map(|state| shared.decision_to_dfa[0].configs(state.id()).configs())
1814 .find(|config| config.state == 42)
1815 .expect("local DFA config imported");
1816 assert_ne!(imported.context, local_context);
1817 assert_eq!(shared.contexts.return_state(imported.context, 0), Some(7));
1818 imported.assert_store(&shared.contexts);
1819 }
1820
1821 #[test]
1822 fn outer_context_cache_invalidates_with_rule_context_version() {
1823 let atn = two_token_decision_atn();
1824 let mut simulator = ParserAtnSimulator::new(&atn);
1825
1826 let first = simulator.intern_prediction_context(1, [7]);
1827 let cached = simulator.intern_prediction_context(1, [99]);
1828 let refreshed = simulator.intern_prediction_context(2, [99]);
1829
1830 assert_eq!(cached, first);
1831 assert_ne!(refreshed, first);
1832 assert_eq!(
1833 simulator.store.contexts.return_state(refreshed, 0),
1834 Some(99)
1835 );
1836 let stats = simulator.prediction_context_stats();
1837 assert_eq!(stats.outer_context_cache_hits, 1);
1838 assert_eq!(stats.outer_context_cache_misses, 2);
1839 }
1840
1841 #[test]
1842 fn outer_context_cache_is_simulator_local() {
1843 let atn = two_token_decision_atn();
1844 let mut first = ParserAtnSimulator::new(&atn);
1845 let mut second = ParserAtnSimulator::new(&atn);
1846
1847 let first_context = first.intern_prediction_context(1, [7]);
1848 let second_context = second.intern_prediction_context(1, [99]);
1849
1850 assert_eq!(first.store.contexts.return_state(first_context, 0), Some(7));
1851 assert_eq!(
1852 second.store.contexts.return_state(second_context, 0),
1853 Some(99)
1854 );
1855 }
1856
1857 #[test]
1858 fn adaptive_predict_reuses_dense_dfa_edges() {
1859 let atn = two_token_decision_atn();
1860 let mut simulator = ParserAtnSimulator::new(&atn);
1861
1862 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
1863 assert_eq!(simulator.adaptive_predict(0, [1, 3]), Ok(2));
1864
1865 let dfa = &simulator.decision_dfas()[0];
1866 let start = dfa.start_state().expect("start state");
1867 let after_first = dfa.state(start).and_then(|state| state.edge(1));
1868 assert!(after_first.is_some());
1869 }
1870
1871 #[test]
1872 fn shared_simulator_reuses_learned_dfa_states() {
1873 let atn = Box::leak(Box::new(two_token_decision_atn()));
1874 let learned_states = {
1875 let mut simulator = ParserAtnSimulator::new_shared(atn);
1876 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
1877 simulator.decision_dfas()[0].states().len()
1878 };
1879
1880 let simulator = ParserAtnSimulator::new_shared(atn);
1881 assert_eq!(simulator.decision_dfas()[0].states().len(), learned_states);
1882 }
1883
1884 #[test]
1885 fn clear_shared_dfa_drops_learned_states() {
1886 let atn = Box::leak(Box::new(two_token_decision_atn()));
1887 {
1888 let mut simulator = ParserAtnSimulator::new_shared(atn);
1889 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
1890 assert!(!simulator.decision_dfas()[0].is_empty());
1891 }
1892
1893 ParserAtnSimulator::clear_shared_dfa(atn);
1894
1895 let simulator = ParserAtnSimulator::new_shared(atn);
1896 assert!(simulator.decision_dfas()[0].is_empty());
1897 }
1898
1899 #[test]
1900 fn clear_dfa_rejects_stale_overlapping_simulator_publication() {
1901 let atn = Box::leak(Box::new(two_token_decision_atn()));
1902 let mut current = ParserAtnSimulator::new_shared(atn);
1903 let mut stale = ParserAtnSimulator::new_shared(atn);
1904 assert_eq!(stale.adaptive_predict(0, [1, 2]), Ok(1));
1905 assert!(!stale.decision_dfas()[0].is_empty());
1906
1907 current.clear_dfa();
1908 drop(stale);
1909 drop(current);
1910
1911 let simulator = ParserAtnSimulator::new_shared(atn);
1912 assert!(simulator.decision_dfas()[0].is_empty());
1913 }
1914
1915 #[test]
1916 fn adaptive_predict_reports_no_viable_alt() {
1917 let atn = two_token_decision_atn();
1918 let mut simulator = ParserAtnSimulator::new(&atn);
1919
1920 assert_eq!(
1921 simulator.adaptive_predict(0, [4]),
1922 Err(ParserAtnSimulatorError::NoViableAlt {
1923 symbol: 4,
1924 index: 0
1925 })
1926 );
1927 }
1928
1929 #[test]
1930 fn adaptive_predict_marks_sll_conflict_for_full_context() {
1931 let atn = ambiguous_single_token_decision_atn();
1932 let mut simulator = ParserAtnSimulator::new(&atn);
1933
1934 assert_eq!(simulator.adaptive_predict(0, [1]), Ok(1));
1935 let prediction = simulator
1936 .adaptive_predict_info_with_precedence(0, 0, [1])
1937 .expect("prediction");
1938 assert_eq!(
1939 prediction,
1940 ParserAtnPrediction {
1941 alt: 1,
1942 requires_full_context: true,
1943 has_semantic_context: false,
1944 diagnostic: Some(ParserAtnPredictionDiagnostic {
1945 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
1946 start_index: 0,
1947 sll_stop_index: 0,
1948 ll_stop_index: 0,
1949 conflicting_alts: vec![1, 2],
1950 exact: false,
1951 }),
1952 }
1953 );
1954
1955 let dfa = &simulator.decision_dfas()[0];
1956 let start = dfa.start_state().expect("start state");
1957 let target = dfa
1958 .state(start)
1959 .and_then(|state| state.edge(1))
1960 .expect("edge for token 1");
1961 let state = dfa.state(target).expect("target state");
1962 assert!(state.is_accept_state());
1963 assert!(state.requires_full_context());
1964 assert_eq!(state.prediction(), Some(1));
1965 }
1966
1967 #[test]
1968 fn adaptive_predict_keeps_rule_stop_configs_at_eof() {
1969 let atn = optional_token_decision_atn();
1970 let mut simulator = ParserAtnSimulator::new(&atn);
1971
1972 assert_eq!(simulator.adaptive_predict(0, [TOKEN_EOF]), Ok(2));
1973 }
1974
1975 #[test]
1976 fn adaptive_predict_treats_repeated_eof_as_epsilon_after_first_eof() {
1977 let atn = multiple_eof_decision_atn();
1978 let mut simulator = ParserAtnSimulator::new(&atn);
1979
1980 assert_eq!(simulator.adaptive_predict(0, [1, TOKEN_EOF]), Ok(1));
1981 }
1982
1983 #[test]
1984 fn adaptive_predict_uses_finished_entry_rule_alt_on_error_edge() {
1985 let atn = prefix_alt_decision_atn();
1986 let mut simulator = ParserAtnSimulator::new(&atn);
1987
1988 assert_eq!(simulator.adaptive_predict(0, [1, 3]), Ok(1));
1989 }
1990
1991 #[test]
1992 fn adaptive_predict_uses_precedence_dfa_start_states() {
1993 let atn = two_token_decision_atn_with_precedence(true);
1994 let mut simulator = ParserAtnSimulator::new(&atn);
1995
1996 assert_eq!(
1997 simulator.adaptive_predict_with_precedence(0, 3, [1, 2]),
1998 Ok(1)
1999 );
2000 assert_eq!(
2001 simulator.adaptive_predict_with_precedence(0, 7, [1, 3]),
2002 Ok(2)
2003 );
2004
2005 let dfa = &simulator.decision_dfas()[0];
2006 assert!(dfa.is_precedence_dfa());
2007 assert!(dfa.precedence_start_state(3).is_some());
2008 assert!(dfa.precedence_start_state(7).is_some());
2009 }
2010
2011 #[test]
2012 fn adaptive_predict_stream_restores_input_position() {
2013 let atn = two_token_decision_atn();
2014 let mut simulator = ParserAtnSimulator::new(&atn);
2015 let mut input = VecIntStream::new(vec![1, 3, TOKEN_EOF]);
2016
2017 assert_eq!(simulator.adaptive_predict_stream(0, &mut input), Ok(2));
2018 assert_eq!(input.index(), 0);
2019 assert_eq!(input.la(1), 1);
2020 }
2021
2022 #[test]
2023 fn adaptive_predict_stream_retries_full_context_conflict() {
2024 let atn = ambiguous_single_token_decision_atn();
2025 let mut simulator = ParserAtnSimulator::new(&atn);
2026 let mut input = VecIntStream::new(vec![1, TOKEN_EOF]);
2027
2028 let prediction = simulator
2029 .adaptive_predict_stream_info_with_precedence(0, 0, &mut input)
2030 .expect("prediction");
2031
2032 assert_eq!(
2033 prediction,
2034 ParserAtnPrediction {
2035 alt: 1,
2036 requires_full_context: true,
2037 has_semantic_context: false,
2038 diagnostic: Some(ParserAtnPredictionDiagnostic {
2039 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
2040 start_index: 0,
2041 sll_stop_index: 0,
2042 ll_stop_index: 0,
2043 conflicting_alts: vec![1, 2],
2044 exact: false,
2045 }),
2046 }
2047 );
2048 assert_eq!(input.index(), 0);
2049 }
2050
2051 #[test]
2052 fn context_prediction_reports_context_sensitivity_for_dfa_conflict() {
2053 let atn = two_token_decision_atn();
2054 let mut simulator = ParserAtnSimulator::new(&atn);
2055 let mut workspace = PredictionWorkspace::default();
2056 let mut start_configs = AtnConfigSet::new();
2057 start_configs.add(
2058 AtnConfig::new(2, 1, EMPTY_CONTEXT, &simulator.store.contexts),
2059 &mut simulator.store.contexts,
2060 &mut workspace,
2061 );
2062 let start =
2063 simulator.store.decision_to_dfa[0].add_state(DfaStateBuilder::new(start_configs));
2064 simulator.store.decision_to_dfa[0].set_start_state(start);
2065
2066 let mut accept_configs = AtnConfigSet::new();
2067 accept_configs.add(
2068 AtnConfig::new(3, 1, EMPTY_CONTEXT, &simulator.store.contexts).with_semantic_context(
2069 SemanticContext::Predicate {
2070 rule_index: 0,
2071 pred_index: 0,
2072 context_dependent: false,
2073 },
2074 ),
2075 &mut simulator.store.contexts,
2076 &mut workspace,
2077 );
2078 let mut accept_state = DfaStateBuilder::new(accept_configs);
2079 accept_state.mark_accept(1);
2080 accept_state.set_requires_full_context(true);
2081 accept_state.set_conflicting_alts(vec![1, 2]);
2082 let accept = simulator.store.decision_to_dfa[0].add_state(accept_state);
2083 simulator.store.decision_to_dfa[0].add_edge(start, 1, accept);
2084
2085 let mut input = VecIntStream::new(vec![1, 3, TOKEN_EOF]);
2086 let prediction = simulator
2087 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
2088 .expect("prediction");
2089
2090 assert_eq!(
2091 prediction,
2092 ParserAtnPrediction {
2093 alt: 2,
2094 requires_full_context: true,
2095 has_semantic_context: false,
2096 diagnostic: Some(ParserAtnPredictionDiagnostic {
2097 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
2098 start_index: 0,
2099 sll_stop_index: 0,
2100 ll_stop_index: 1,
2101 conflicting_alts: vec![1, 2],
2102 exact: false,
2103 }),
2104 }
2105 );
2106 assert_eq!(input.index(), 0);
2107 }
2108
2109 #[test]
2110 fn full_context_reach_prefers_longer_match_over_skipped_stop_state() {
2111 let atn = prefix_alt_decision_atn();
2112 let mut simulator = ParserAtnSimulator::new(&atn);
2113 let mut configs = AtnConfigSet::new_full_context(true);
2114 let mut merge_cache = PredictionWorkspace::default();
2115 configs.add(
2116 AtnConfig::new(2, 1, EMPTY_CONTEXT, &simulator.store.contexts),
2117 &mut simulator.store.contexts,
2118 &mut merge_cache,
2119 );
2120 configs.add(
2121 AtnConfig::new(1, 2, EMPTY_CONTEXT, &simulator.store.contexts),
2122 &mut simulator.store.contexts,
2123 &mut merge_cache,
2124 );
2125
2126 let reach = simulator.compute_reach_set(&configs, 2, true, 0, &mut merge_cache);
2127
2128 assert_eq!(reach.alts(), std::iter::once(2).collect());
2129 assert!(simulator.configs_all_reached_rule_stop(&reach));
2130 }
2131
2132 #[test]
2133 fn sll_closure_follows_empty_context_rule_stop_exits() {
2134 let mut atn = ParserAtnBuilder::new(1);
2135 add_state(&mut atn, 0, AtnStateKind::RuleStop);
2136 add_state(&mut atn, 1, AtnStateKind::Basic);
2137 add_state(&mut atn, 2, AtnStateKind::Basic);
2138 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2139 .expect("transition");
2140 atn.add_transition(
2141 1,
2142 ParserTransitionSpec::Atom {
2143 target: 2,
2144 label: 1,
2145 },
2146 )
2147 .expect("transition");
2148 atn.set_rule_to_start_state(vec![0])
2149 .expect("rule start states");
2150 atn.set_rule_to_stop_state(vec![0])
2151 .expect("rule stop states");
2152 let atn = finish_atn(atn);
2153
2154 let mut simulator = ParserAtnSimulator::new(&atn);
2155 let mut configs = AtnConfigSet::new_full_context(false);
2156 let mut merge_cache = PredictionWorkspace::default();
2157 let mut scratch = ClosureScratch::default();
2158 let config = AtnConfig::new(0, 2, EMPTY_CONTEXT, &simulator.store.contexts);
2159 simulator.closure(
2160 config,
2161 &mut configs,
2162 &mut merge_cache,
2163 &mut scratch,
2164 ClosureParams {
2165 precedence: 0,
2166 collect_predicates: true,
2167 treat_eof_as_epsilon: false,
2168 },
2169 );
2170
2171 assert_eq!(configs.len(), 1);
2172 let config = &configs.configs()[0];
2173 assert_eq!(config.state, 1);
2174 assert_eq!(config.alt, 2);
2175 assert_eq!(config.reaches_into_outer_context, 1);
2176 }
2177
2178 #[test]
2179 fn precedence_contexts_are_collected_only_for_start_closure() {
2180 let mut atn = ParserAtnBuilder::new(1);
2181 add_state(&mut atn, 0, AtnStateKind::Basic);
2182 add_state(&mut atn, 1, AtnStateKind::Basic);
2183 atn.set_rule_to_start_state(vec![0])
2184 .expect("rule start states");
2185 atn.set_rule_to_stop_state(vec![1])
2186 .expect("rule stop states");
2187 atn.add_transition(
2188 0,
2189 ParserTransitionSpec::Precedence {
2190 target: 1,
2191 precedence: 2,
2192 },
2193 )
2194 .expect("precedence transition");
2195 let atn = finish_atn(atn);
2196 let transition = atn
2197 .state(0)
2198 .expect("source state")
2199 .transitions()
2200 .first()
2201 .expect("precedence transition");
2202 let mut simulator = ParserAtnSimulator::new(&atn);
2203 let config = AtnConfig::new(0, 1, EMPTY_CONTEXT, &simulator.store.contexts);
2204
2205 let sll_start = simulator
2206 .epsilon_target_config(&config, transition, transition.kind(), 1, true, false)
2207 .expect("sll start transition");
2208 assert!(matches!(
2209 sll_start.semantic_context,
2210 SemanticContext::Precedence { precedence: 2 }
2211 ));
2212
2213 let full_context_start = simulator
2214 .epsilon_target_config(&config, transition, transition.kind(), 1, true, true)
2215 .expect("full-context start transition");
2216 assert!(full_context_start.semantic_context.is_none());
2217
2218 let reach = simulator
2219 .epsilon_target_config(&config, transition, transition.kind(), 3, false, false)
2220 .expect("reach transition");
2221 assert!(reach.semantic_context.is_none());
2222
2223 assert!(
2224 simulator
2225 .epsilon_target_config(&config, transition, transition.kind(), 3, true, false)
2226 .is_none()
2227 );
2228 }
2229
2230 #[test]
2231 fn closure_stops_collecting_predicates_after_action_edge() {
2232 let mut atn = ParserAtnBuilder::new(1);
2239 add_state(&mut atn, 0, AtnStateKind::Basic);
2240 add_state(&mut atn, 1, AtnStateKind::Basic);
2241 add_state(&mut atn, 2, AtnStateKind::Basic);
2242 add_state(&mut atn, 3, AtnStateKind::Basic);
2243 atn.add_transition(
2244 0,
2245 ParserTransitionSpec::Action {
2246 target: 1,
2247 rule_index: 0,
2248 action_index: Some(0),
2249 context_dependent: false,
2250 },
2251 )
2252 .expect("transition");
2253 atn.add_transition(
2254 1,
2255 ParserTransitionSpec::Predicate {
2256 target: 2,
2257 rule_index: 0,
2258 pred_index: 0,
2259 context_dependent: false,
2260 },
2261 )
2262 .expect("transition");
2263 atn.add_transition(
2264 2,
2265 ParserTransitionSpec::Atom {
2266 target: 3,
2267 label: 1,
2268 },
2269 )
2270 .expect("transition");
2271 atn.set_rule_to_start_state(vec![0])
2272 .expect("rule start states");
2273 atn.set_rule_to_stop_state(vec![3])
2274 .expect("rule stop states");
2275 let atn = finish_atn(atn);
2276
2277 let mut simulator = ParserAtnSimulator::new(&atn);
2278 let mut configs = AtnConfigSet::new();
2279 let mut merge_cache = PredictionWorkspace::default();
2280 let mut scratch = ClosureScratch::default();
2281 let config = AtnConfig::new(0, 1, EMPTY_CONTEXT, &simulator.store.contexts);
2282 simulator.closure(
2283 config,
2284 &mut configs,
2285 &mut merge_cache,
2286 &mut scratch,
2287 ClosureParams {
2288 precedence: 0,
2289 collect_predicates: true,
2290 treat_eof_as_epsilon: false,
2291 },
2292 );
2293
2294 let at_two = configs
2297 .configs()
2298 .iter()
2299 .find(|config| config.state == 2)
2300 .expect("config at state 2");
2301 assert!(
2302 at_two.semantic_context.is_none(),
2303 "predicate after an action edge must not be collected during prediction"
2304 );
2305
2306 let direct_config = AtnConfig::new(1, 1, EMPTY_CONTEXT, &simulator.store.contexts);
2310 let direct_transition = atn
2311 .state(1)
2312 .expect("predicate source")
2313 .transitions()
2314 .first()
2315 .expect("predicate transition");
2316 let direct = simulator
2317 .epsilon_target_config(
2318 &direct_config,
2319 direct_transition,
2320 direct_transition.kind(),
2321 0,
2322 true,
2323 false,
2324 )
2325 .expect("predicate transition");
2326 assert!(matches!(
2327 direct.semantic_context,
2328 SemanticContext::Predicate { pred_index: 0, .. }
2329 ));
2330 }
2331
2332 #[test]
2333 fn reach_set_skips_closure_for_unique_intermediate_alt() {
2334 let mut atn = ParserAtnBuilder::new(1);
2335 add_state(&mut atn, 0, AtnStateKind::Basic);
2336 add_state(&mut atn, 1, AtnStateKind::Basic);
2337 add_state(&mut atn, 2, AtnStateKind::Basic);
2338 atn.add_transition(
2339 0,
2340 ParserTransitionSpec::Atom {
2341 target: 1,
2342 label: 7,
2343 },
2344 )
2345 .expect("transition");
2346 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2347 .expect("transition");
2348 atn.set_rule_to_start_state(vec![0])
2349 .expect("rule start states");
2350 atn.set_rule_to_stop_state(vec![2])
2351 .expect("rule stop states");
2352 let atn = finish_atn(atn);
2353
2354 let mut simulator = ParserAtnSimulator::new(&atn);
2355 let mut configs = AtnConfigSet::new_full_context(false);
2356 let mut merge_cache = PredictionWorkspace::default();
2357 configs.add(
2358 AtnConfig::new(0, 1, EMPTY_CONTEXT, &simulator.store.contexts),
2359 &mut simulator.store.contexts,
2360 &mut merge_cache,
2361 );
2362
2363 let reach = simulator.compute_reach_set(&configs, 7, false, 0, &mut merge_cache);
2364
2365 assert_eq!(reach.len(), 1);
2366 assert_eq!(reach.configs()[0].state, 1);
2367 }
2368
2369 #[test]
2370 fn semantic_context_flag_is_scoped_to_predicted_alt() {
2371 let mut arena = ContextArena::new();
2372 let mut workspace = PredictionWorkspace::default();
2373 let mut configs = AtnConfigSet::new();
2374 configs.add(
2375 AtnConfig::new(1, 1, EMPTY_CONTEXT, &arena),
2376 &mut arena,
2377 &mut workspace,
2378 );
2379 configs.add(
2380 AtnConfig::new(2, 2, EMPTY_CONTEXT, &arena).with_semantic_context(
2381 SemanticContext::Predicate {
2382 rule_index: 0,
2383 pred_index: 0,
2384 context_dependent: false,
2385 },
2386 ),
2387 &mut arena,
2388 &mut workspace,
2389 );
2390
2391 assert!(!configs_have_semantic_context_for_alt(&configs, 1));
2392 assert!(configs_have_semantic_context_for_alt(&configs, 2));
2393 }
2394
2395 #[test]
2396 fn adaptive_predict_prefers_non_greedy_exit_before_consuming() {
2397 let atn = non_greedy_optional_exit_first_atn();
2398 let mut simulator = ParserAtnSimulator::new(&atn);
2399
2400 assert_eq!(simulator.adaptive_predict(0, [1, TOKEN_EOF]), Ok(1));
2401 }
2402
2403 #[test]
2404 fn left_recursive_loop_entry_drop_requires_same_rule_return() {
2405 let atn = left_recursive_loop_entry_atn();
2406 let loop_entry = atn.state(1).expect("loop entry");
2407 let mut contexts = ContextArena::new();
2408 let same_rule_context = contexts.singleton(EMPTY_CONTEXT, 4);
2409 let other_rule_context = contexts.singleton(EMPTY_CONTEXT, 5);
2410
2411 assert!(can_drop_left_recursive_loop_entry_edge(
2412 &atn,
2413 loop_entry,
2414 &contexts,
2415 same_rule_context
2416 ));
2417 assert!(!can_drop_left_recursive_loop_entry_edge(
2418 &atn,
2419 loop_entry,
2420 &contexts,
2421 other_rule_context
2422 ));
2423 assert!(!can_drop_left_recursive_loop_entry_edge(
2424 &atn,
2425 loop_entry,
2426 &contexts,
2427 EMPTY_CONTEXT
2428 ));
2429 }
2430
2431 fn two_token_decision_atn() -> Atn {
2432 two_token_decision_atn_with_precedence(false)
2433 }
2434
2435 fn two_token_decision_atn_with_precedence(precedence: bool) -> Atn {
2436 let mut atn = ParserAtnBuilder::new(3);
2437 add_state(&mut atn, 0, AtnStateKind::RuleStart);
2438 add_state(&mut atn, 1, AtnStateKind::BlockStart);
2439 add_state(&mut atn, 2, AtnStateKind::Basic);
2440 add_state(&mut atn, 3, AtnStateKind::Basic);
2441 add_state(&mut atn, 4, AtnStateKind::Basic);
2442 add_state(&mut atn, 5, AtnStateKind::Basic);
2443 add_state(&mut atn, 6, AtnStateKind::BlockEnd);
2444 add_state(&mut atn, 7, AtnStateKind::RuleStop);
2445 atn.set_rule_to_start_state(vec![0])
2446 .expect("rule start states");
2447 atn.set_rule_to_stop_state(vec![7])
2448 .expect("rule stop states");
2449 atn.add_decision_state(1).expect("decision state");
2450 if precedence {
2451 atn.set_precedence_rule_decision(1)
2452 .expect("precedence decision state");
2453 }
2454 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2455 .expect("transition");
2456 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2457 .expect("transition");
2458 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
2459 .expect("transition");
2460 atn.add_transition(
2461 2,
2462 ParserTransitionSpec::Atom {
2463 target: 3,
2464 label: 1,
2465 },
2466 )
2467 .expect("transition");
2468 atn.add_transition(
2469 3,
2470 ParserTransitionSpec::Atom {
2471 target: 6,
2472 label: 2,
2473 },
2474 )
2475 .expect("transition");
2476 atn.add_transition(
2477 4,
2478 ParserTransitionSpec::Atom {
2479 target: 5,
2480 label: 1,
2481 },
2482 )
2483 .expect("transition");
2484 atn.add_transition(
2485 5,
2486 ParserTransitionSpec::Atom {
2487 target: 6,
2488 label: 3,
2489 },
2490 )
2491 .expect("transition");
2492 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
2493 .expect("transition");
2494 finish_atn(atn)
2495 }
2496
2497 fn optional_token_decision_atn() -> Atn {
2498 let mut atn = ParserAtnBuilder::new(1);
2499 add_state(&mut atn, 0, AtnStateKind::RuleStart);
2500 add_state(&mut atn, 1, AtnStateKind::BlockStart);
2501 add_state(&mut atn, 2, AtnStateKind::Basic);
2502 add_state(&mut atn, 3, AtnStateKind::BlockEnd);
2503 add_state(&mut atn, 4, AtnStateKind::RuleStop);
2504 atn.set_rule_to_start_state(vec![0])
2505 .expect("rule start states");
2506 atn.set_rule_to_stop_state(vec![4])
2507 .expect("rule stop states");
2508 atn.add_decision_state(1).expect("decision state");
2509 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2510 .expect("transition");
2511 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2512 .expect("transition");
2513 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
2514 .expect("transition");
2515 atn.add_transition(
2516 2,
2517 ParserTransitionSpec::Atom {
2518 target: 3,
2519 label: 1,
2520 },
2521 )
2522 .expect("transition");
2523 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
2524 .expect("transition");
2525 finish_atn(atn)
2526 }
2527
2528 fn non_greedy_optional_exit_first_atn() -> Atn {
2529 let mut atn = ParserAtnBuilder::new(1);
2530 add_state(&mut atn, 0, AtnStateKind::RuleStart);
2531 add_state(&mut atn, 1, AtnStateKind::BlockStart);
2532 add_state(&mut atn, 2, AtnStateKind::BlockEnd);
2533 add_state(&mut atn, 3, AtnStateKind::Basic);
2534 add_state(&mut atn, 4, AtnStateKind::RuleStop);
2535 atn.set_rule_to_start_state(vec![0])
2536 .expect("rule start states");
2537 atn.set_rule_to_stop_state(vec![4])
2538 .expect("rule stop states");
2539 atn.add_decision_state(1).expect("decision state");
2540 atn.set_non_greedy(1).expect("non-greedy state");
2541 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2542 .expect("transition");
2543 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2544 .expect("transition");
2545 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
2546 .expect("transition");
2547 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
2548 .expect("transition");
2549 atn.add_transition(
2550 3,
2551 ParserTransitionSpec::Atom {
2552 target: 4,
2553 label: 1,
2554 },
2555 )
2556 .expect("transition");
2557 finish_atn(atn)
2558 }
2559
2560 fn ambiguous_single_token_decision_atn() -> Atn {
2561 let mut atn = ParserAtnBuilder::new(1);
2562 add_state(&mut atn, 0, AtnStateKind::RuleStart);
2563 add_state(&mut atn, 1, AtnStateKind::BlockStart);
2564 add_state(&mut atn, 2, AtnStateKind::Basic);
2565 add_state(&mut atn, 3, AtnStateKind::Basic);
2566 add_state(&mut atn, 4, AtnStateKind::Basic);
2567 add_state(&mut atn, 5, AtnStateKind::Basic);
2568 add_state(&mut atn, 6, AtnStateKind::BlockEnd);
2569 add_state(&mut atn, 7, AtnStateKind::RuleStop);
2570 atn.set_rule_to_start_state(vec![0])
2571 .expect("rule start states");
2572 atn.set_rule_to_stop_state(vec![7])
2573 .expect("rule stop states");
2574 atn.add_decision_state(1).expect("decision state");
2575 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2576 .expect("transition");
2577 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2578 .expect("transition");
2579 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
2580 .expect("transition");
2581 atn.add_transition(
2582 2,
2583 ParserTransitionSpec::Atom {
2584 target: 3,
2585 label: 1,
2586 },
2587 )
2588 .expect("transition");
2589 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 6 })
2590 .expect("transition");
2591 atn.add_transition(
2592 4,
2593 ParserTransitionSpec::Atom {
2594 target: 5,
2595 label: 1,
2596 },
2597 )
2598 .expect("transition");
2599 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
2600 .expect("transition");
2601 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
2602 .expect("transition");
2603 finish_atn(atn)
2604 }
2605
2606 fn prefix_alt_decision_atn() -> Atn {
2607 let mut atn = ParserAtnBuilder::new(3);
2608 add_state(&mut atn, 0, AtnStateKind::BlockStart);
2609 add_state(&mut atn, 1, AtnStateKind::Basic);
2610 add_state(&mut atn, 2, AtnStateKind::RuleStop);
2611 atn.set_rule_to_start_state(vec![0])
2612 .expect("rule start states");
2613 atn.set_rule_to_stop_state(vec![2])
2614 .expect("rule stop states");
2615 atn.add_decision_state(0).expect("decision state");
2616 atn.add_transition(
2617 0,
2618 ParserTransitionSpec::Atom {
2619 target: 2,
2620 label: 1,
2621 },
2622 )
2623 .expect("transition");
2624 atn.add_transition(
2625 0,
2626 ParserTransitionSpec::Atom {
2627 target: 1,
2628 label: 1,
2629 },
2630 )
2631 .expect("transition");
2632 atn.add_transition(
2633 1,
2634 ParserTransitionSpec::Atom {
2635 target: 2,
2636 label: 2,
2637 },
2638 )
2639 .expect("transition");
2640 finish_atn(atn)
2641 }
2642
2643 fn multiple_eof_decision_atn() -> Atn {
2644 let mut atn = ParserAtnBuilder::new(2);
2645 for state_number in 0..=10 {
2646 let kind = match state_number {
2647 0 => AtnStateKind::RuleStart,
2648 1 => AtnStateKind::BlockStart,
2649 7 => AtnStateKind::BlockEnd,
2650 10 => AtnStateKind::RuleStop,
2651 _ => AtnStateKind::Basic,
2652 };
2653 add_state(&mut atn, state_number, kind);
2654 }
2655 atn.set_rule_to_start_state(vec![0])
2656 .expect("rule start states");
2657 atn.set_rule_to_stop_state(vec![10])
2658 .expect("rule stop states");
2659 atn.add_decision_state(1).expect("decision state");
2660 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2661 .expect("transition");
2662 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2663 .expect("transition");
2664 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
2665 .expect("transition");
2666 atn.add_transition(
2667 2,
2668 ParserTransitionSpec::Atom {
2669 target: 3,
2670 label: 1,
2671 },
2672 )
2673 .expect("transition");
2674 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 7 })
2675 .expect("transition");
2676 atn.add_transition(
2677 4,
2678 ParserTransitionSpec::Atom {
2679 target: 5,
2680 label: 1,
2681 },
2682 )
2683 .expect("transition");
2684 atn.add_transition(
2685 5,
2686 ParserTransitionSpec::Atom {
2687 target: 6,
2688 label: 2,
2689 },
2690 )
2691 .expect("transition");
2692 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
2693 .expect("transition");
2694 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
2695 .expect("transition");
2696 atn.add_transition(
2697 8,
2698 ParserTransitionSpec::Atom {
2699 target: 9,
2700 label: TOKEN_EOF,
2701 },
2702 )
2703 .expect("transition");
2704 atn.add_transition(
2705 9,
2706 ParserTransitionSpec::Atom {
2707 target: 10,
2708 label: TOKEN_EOF,
2709 },
2710 )
2711 .expect("transition");
2712 finish_atn(atn)
2713 }
2714
2715 fn left_recursive_loop_entry_atn() -> Atn {
2716 let mut atn = ParserAtnBuilder::new(1);
2717 add_state(&mut atn, 0, AtnStateKind::RuleStart);
2718 add_state(&mut atn, 1, AtnStateKind::StarLoopEntry);
2719 add_state(&mut atn, 2, AtnStateKind::BlockStart);
2720 add_state(&mut atn, 3, AtnStateKind::BlockEnd);
2721 add_state(&mut atn, 4, AtnStateKind::Basic);
2722 assert_eq!(
2723 atn.add_state(AtnStateKind::Basic, Some(1))
2724 .expect("state")
2725 .index(),
2726 5
2727 );
2728 add_state(&mut atn, 6, AtnStateKind::LoopEnd);
2729 add_state(&mut atn, 7, AtnStateKind::RuleStop);
2730 atn.set_rule_to_start_state(vec![0, 5])
2731 .expect("rule start states");
2732 atn.set_rule_to_stop_state(vec![7, 7])
2733 .expect("rule stop states");
2734 atn.set_precedence_rule_decision(1)
2735 .expect("precedence decision state");
2736 atn.set_end_state(2, 3).expect("block end state");
2737 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2738 .expect("transition");
2739 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
2740 .expect("transition");
2741 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 3 })
2742 .expect("transition");
2743 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 3 })
2744 .expect("transition");
2745 finish_atn(atn)
2746 }
2747
2748 fn add_state(atn: &mut ParserAtnBuilder, state_number: usize, kind: AtnStateKind) {
2749 assert_eq!(
2750 atn.add_state(kind, Some(0)).expect("state").index(),
2751 state_number
2752 );
2753 }
2754
2755 #[derive(Debug)]
2756 struct VecIntStream {
2757 symbols: Vec<i32>,
2758 index: usize,
2759 }
2760
2761 impl VecIntStream {
2762 fn new(symbols: Vec<i32>) -> Self {
2763 Self { symbols, index: 0 }
2764 }
2765 }
2766
2767 impl IntStream for VecIntStream {
2768 fn consume(&mut self) {
2769 if self.la(1) != TOKEN_EOF {
2770 self.index += 1;
2771 }
2772 }
2773
2774 fn la(&mut self, offset: isize) -> i32 {
2775 if offset <= 0 {
2776 return 0;
2777 }
2778 let offset = offset.cast_unsigned() - 1;
2779 self.symbols
2780 .get(self.index + offset)
2781 .copied()
2782 .unwrap_or(TOKEN_EOF)
2783 }
2784
2785 fn index(&self) -> usize {
2786 self.index
2787 }
2788
2789 fn seek(&mut self, index: usize) {
2790 self.index = index;
2791 }
2792
2793 fn size(&self) -> usize {
2794 self.symbols.len()
2795 }
2796 }
2797}