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)]
1727#[allow(clippy::disallowed_methods)] mod tests {
1729 use super::*;
1730 use crate::atn::AtnStateKind;
1731
1732 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
1733 builder.finish().expect("valid packed parser ATN")
1734 }
1735
1736 #[test]
1737 fn union_decision_dfa_preserves_disjoint_coverage() {
1738 fn configs(
1739 atn_state: usize,
1740 arena: &mut ContextArena,
1741 workspace: &mut PredictionWorkspace,
1742 ) -> AtnConfigSet {
1743 let mut set = AtnConfigSet::new();
1744 set.add(
1745 AtnConfig::new(atn_state, 1, EMPTY_CONTEXT, arena),
1746 arena,
1747 workspace,
1748 );
1749 set
1750 }
1751 fn state(
1752 atn_state: usize,
1753 arena: &mut ContextArena,
1754 workspace: &mut PredictionWorkspace,
1755 ) -> DfaStateBuilder {
1756 DfaStateBuilder::new(configs(atn_state, arena, workspace))
1757 }
1758 let mut arena = ContextArena::new();
1759 let mut workspace = PredictionWorkspace::default();
1760
1761 let mut shared = ParserDfa::with_max_token_type(0, 0, 8);
1765 let shared_root = shared.add_state(state(10, &mut arena, &mut workspace));
1766 let shared_a = shared.add_state(state(11, &mut arena, &mut workspace));
1767 shared.add_edge(shared_root, 1, shared_a);
1768 shared.set_start_state(shared_root);
1769
1770 let mut local = ParserDfa::with_max_token_type(0, 0, 8);
1771 let local_b = local.add_state(state(12, &mut arena, &mut workspace));
1772 let local_root = local.add_state(state(10, &mut arena, &mut workspace));
1773 local.add_edge(local_root, 2, local_b);
1774 local.set_precedence_start_state(3, local_root);
1775
1776 union_decision_dfa(&mut shared, local);
1777
1778 assert_eq!(shared.edge(shared_root, 1), Some(shared_a));
1781 let merged_b = shared
1782 .state_id_for_configs(&configs(12, &mut arena, &mut workspace))
1783 .expect("local-only state adopted");
1784 assert_eq!(shared.edge(shared_root, 2), Some(merged_b));
1785 assert_eq!(shared.states().len(), 3);
1786 assert_eq!(shared.start_state(), Some(shared_root));
1788 assert_eq!(shared.precedence_start_state(3), Some(shared_root));
1789 }
1790
1791 #[test]
1792 fn union_prediction_stores_remaps_context_ids_before_dfa_union() {
1793 let atn = two_token_decision_atn();
1794 let mut shared = PredictionStore::new(&atn);
1795 let mut local = PredictionStore::new(&atn);
1796 let mut workspace = PredictionWorkspace::default();
1797
1798 let distracting = shared.contexts.singleton(EMPTY_CONTEXT, 99);
1799 let local_context = local.contexts.singleton(EMPTY_CONTEXT, 7);
1800 assert_eq!(distracting, local_context, "both stores allocate ID 1");
1801
1802 let mut configs = AtnConfigSet::new();
1803 configs.add(
1804 AtnConfig::new(42, 1, local_context, &local.contexts),
1805 &mut local.contexts,
1806 &mut workspace,
1807 );
1808 local.decision_to_dfa[0].add_state(DfaStateBuilder::new(configs));
1809
1810 union_prediction_stores(&mut shared, local, &mut workspace);
1811
1812 let imported = shared.decision_to_dfa[0]
1813 .states()
1814 .flat_map(|state| shared.decision_to_dfa[0].configs(state.id()).configs())
1815 .find(|config| config.state == 42)
1816 .expect("local DFA config imported");
1817 assert_ne!(imported.context, local_context);
1818 assert_eq!(shared.contexts.return_state(imported.context, 0), Some(7));
1819 imported.assert_store(&shared.contexts);
1820 }
1821
1822 #[test]
1823 fn outer_context_cache_invalidates_with_rule_context_version() {
1824 let atn = two_token_decision_atn();
1825 let mut simulator = ParserAtnSimulator::new(&atn);
1826
1827 let first = simulator.intern_prediction_context(1, [7]);
1828 let cached = simulator.intern_prediction_context(1, [99]);
1829 let refreshed = simulator.intern_prediction_context(2, [99]);
1830
1831 assert_eq!(cached, first);
1832 assert_ne!(refreshed, first);
1833 assert_eq!(
1834 simulator.store.contexts.return_state(refreshed, 0),
1835 Some(99)
1836 );
1837 let stats = simulator.prediction_context_stats();
1838 assert_eq!(stats.outer_context_cache_hits, 1);
1839 assert_eq!(stats.outer_context_cache_misses, 2);
1840 }
1841
1842 #[test]
1843 fn outer_context_cache_is_simulator_local() {
1844 let atn = two_token_decision_atn();
1845 let mut first = ParserAtnSimulator::new(&atn);
1846 let mut second = ParserAtnSimulator::new(&atn);
1847
1848 let first_context = first.intern_prediction_context(1, [7]);
1849 let second_context = second.intern_prediction_context(1, [99]);
1850
1851 assert_eq!(first.store.contexts.return_state(first_context, 0), Some(7));
1852 assert_eq!(
1853 second.store.contexts.return_state(second_context, 0),
1854 Some(99)
1855 );
1856 }
1857
1858 #[test]
1859 fn adaptive_predict_reuses_dense_dfa_edges() {
1860 let atn = two_token_decision_atn();
1861 let mut simulator = ParserAtnSimulator::new(&atn);
1862
1863 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
1864 assert_eq!(simulator.adaptive_predict(0, [1, 3]), Ok(2));
1865
1866 let dfa = &simulator.decision_dfas()[0];
1867 let start = dfa.start_state().expect("start state");
1868 let after_first = dfa.state(start).and_then(|state| state.edge(1));
1869 assert!(after_first.is_some());
1870 }
1871
1872 #[test]
1873 fn shared_simulator_reuses_learned_dfa_states() {
1874 let atn = Box::leak(Box::new(two_token_decision_atn()));
1875 let learned_states = {
1876 let mut simulator = ParserAtnSimulator::new_shared(atn);
1877 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
1878 simulator.decision_dfas()[0].states().len()
1879 };
1880
1881 let simulator = ParserAtnSimulator::new_shared(atn);
1882 assert_eq!(simulator.decision_dfas()[0].states().len(), learned_states);
1883 }
1884
1885 #[test]
1886 fn clear_shared_dfa_drops_learned_states() {
1887 let atn = Box::leak(Box::new(two_token_decision_atn()));
1888 {
1889 let mut simulator = ParserAtnSimulator::new_shared(atn);
1890 assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
1891 assert!(!simulator.decision_dfas()[0].is_empty());
1892 }
1893
1894 ParserAtnSimulator::clear_shared_dfa(atn);
1895
1896 let simulator = ParserAtnSimulator::new_shared(atn);
1897 assert!(simulator.decision_dfas()[0].is_empty());
1898 }
1899
1900 #[test]
1901 fn clear_dfa_rejects_stale_overlapping_simulator_publication() {
1902 let atn = Box::leak(Box::new(two_token_decision_atn()));
1903 let mut current = ParserAtnSimulator::new_shared(atn);
1904 let mut stale = ParserAtnSimulator::new_shared(atn);
1905 assert_eq!(stale.adaptive_predict(0, [1, 2]), Ok(1));
1906 assert!(!stale.decision_dfas()[0].is_empty());
1907
1908 current.clear_dfa();
1909 drop(stale);
1910 drop(current);
1911
1912 let simulator = ParserAtnSimulator::new_shared(atn);
1913 assert!(simulator.decision_dfas()[0].is_empty());
1914 }
1915
1916 #[test]
1917 fn adaptive_predict_reports_no_viable_alt() {
1918 let atn = two_token_decision_atn();
1919 let mut simulator = ParserAtnSimulator::new(&atn);
1920
1921 assert_eq!(
1922 simulator.adaptive_predict(0, [4]),
1923 Err(ParserAtnSimulatorError::NoViableAlt {
1924 symbol: 4,
1925 index: 0
1926 })
1927 );
1928 }
1929
1930 #[test]
1931 fn adaptive_predict_marks_sll_conflict_for_full_context() {
1932 let atn = ambiguous_single_token_decision_atn();
1933 let mut simulator = ParserAtnSimulator::new(&atn);
1934
1935 assert_eq!(simulator.adaptive_predict(0, [1]), Ok(1));
1936 let prediction = simulator
1937 .adaptive_predict_info_with_precedence(0, 0, [1])
1938 .expect("prediction");
1939 insta::assert_debug_snapshot!(
1940 "adaptive_predict_marks_sll_conflict_for_full_context",
1941 prediction
1942 );
1943
1944 let dfa = &simulator.decision_dfas()[0];
1945 let start = dfa.start_state().expect("start state");
1946 let target = dfa
1947 .state(start)
1948 .and_then(|state| state.edge(1))
1949 .expect("edge for token 1");
1950 let state = dfa.state(target).expect("target state");
1951 assert!(state.is_accept_state());
1952 assert!(state.requires_full_context());
1953 assert_eq!(state.prediction(), Some(1));
1954 }
1955
1956 #[test]
1957 fn adaptive_predict_keeps_rule_stop_configs_at_eof() {
1958 let atn = optional_token_decision_atn();
1959 let mut simulator = ParserAtnSimulator::new(&atn);
1960
1961 assert_eq!(simulator.adaptive_predict(0, [TOKEN_EOF]), Ok(2));
1962 }
1963
1964 #[test]
1965 fn adaptive_predict_treats_repeated_eof_as_epsilon_after_first_eof() {
1966 let atn = multiple_eof_decision_atn();
1967 let mut simulator = ParserAtnSimulator::new(&atn);
1968
1969 assert_eq!(simulator.adaptive_predict(0, [1, TOKEN_EOF]), Ok(1));
1970 }
1971
1972 #[test]
1973 fn adaptive_predict_uses_finished_entry_rule_alt_on_error_edge() {
1974 let atn = prefix_alt_decision_atn();
1975 let mut simulator = ParserAtnSimulator::new(&atn);
1976
1977 assert_eq!(simulator.adaptive_predict(0, [1, 3]), Ok(1));
1978 }
1979
1980 #[test]
1981 fn adaptive_predict_uses_precedence_dfa_start_states() {
1982 let atn = two_token_decision_atn_with_precedence(true);
1983 let mut simulator = ParserAtnSimulator::new(&atn);
1984
1985 assert_eq!(
1986 simulator.adaptive_predict_with_precedence(0, 3, [1, 2]),
1987 Ok(1)
1988 );
1989 assert_eq!(
1990 simulator.adaptive_predict_with_precedence(0, 7, [1, 3]),
1991 Ok(2)
1992 );
1993
1994 let dfa = &simulator.decision_dfas()[0];
1995 assert!(dfa.is_precedence_dfa());
1996 assert!(dfa.precedence_start_state(3).is_some());
1997 assert!(dfa.precedence_start_state(7).is_some());
1998 }
1999
2000 #[test]
2001 fn adaptive_predict_stream_restores_input_position() {
2002 let atn = two_token_decision_atn();
2003 let mut simulator = ParserAtnSimulator::new(&atn);
2004 let mut input = VecIntStream::new(vec![1, 3, TOKEN_EOF]);
2005
2006 assert_eq!(simulator.adaptive_predict_stream(0, &mut input), Ok(2));
2007 assert_eq!(input.index(), 0);
2008 assert_eq!(input.la(1), 1);
2009 }
2010
2011 #[test]
2012 fn adaptive_predict_stream_retries_full_context_conflict() {
2013 let atn = ambiguous_single_token_decision_atn();
2014 let mut simulator = ParserAtnSimulator::new(&atn);
2015 let mut input = VecIntStream::new(vec![1, TOKEN_EOF]);
2016
2017 let prediction = simulator
2018 .adaptive_predict_stream_info_with_precedence(0, 0, &mut input)
2019 .expect("prediction");
2020
2021 insta::assert_debug_snapshot!(
2022 "adaptive_predict_stream_retries_full_context_conflict",
2023 prediction
2024 );
2025 assert_eq!(input.index(), 0);
2026 }
2027
2028 #[test]
2029 fn context_prediction_reports_context_sensitivity_for_dfa_conflict() {
2030 let atn = two_token_decision_atn();
2031 let mut simulator = ParserAtnSimulator::new(&atn);
2032 let mut workspace = PredictionWorkspace::default();
2033 let mut start_configs = AtnConfigSet::new();
2034 start_configs.add(
2035 AtnConfig::new(2, 1, EMPTY_CONTEXT, &simulator.store.contexts),
2036 &mut simulator.store.contexts,
2037 &mut workspace,
2038 );
2039 let start =
2040 simulator.store.decision_to_dfa[0].add_state(DfaStateBuilder::new(start_configs));
2041 simulator.store.decision_to_dfa[0].set_start_state(start);
2042
2043 let mut accept_configs = AtnConfigSet::new();
2044 accept_configs.add(
2045 AtnConfig::new(3, 1, EMPTY_CONTEXT, &simulator.store.contexts).with_semantic_context(
2046 SemanticContext::Predicate {
2047 rule_index: 0,
2048 pred_index: 0,
2049 context_dependent: false,
2050 },
2051 ),
2052 &mut simulator.store.contexts,
2053 &mut workspace,
2054 );
2055 let mut accept_state = DfaStateBuilder::new(accept_configs);
2056 accept_state.mark_accept(1);
2057 accept_state.set_requires_full_context(true);
2058 accept_state.set_conflicting_alts(vec![1, 2]);
2059 let accept = simulator.store.decision_to_dfa[0].add_state(accept_state);
2060 simulator.store.decision_to_dfa[0].add_edge(start, 1, accept);
2061
2062 let mut input = VecIntStream::new(vec![1, 3, TOKEN_EOF]);
2063 let prediction = simulator
2064 .adaptive_predict_stream_info_with_context(0, 0, &mut input, EMPTY_CONTEXT)
2065 .expect("prediction");
2066
2067 insta::assert_debug_snapshot!(
2068 "context_prediction_reports_context_sensitivity_for_dfa_conflict",
2069 prediction
2070 );
2071 assert_eq!(input.index(), 0);
2072 }
2073
2074 #[test]
2075 fn full_context_reach_prefers_longer_match_over_skipped_stop_state() {
2076 let atn = prefix_alt_decision_atn();
2077 let mut simulator = ParserAtnSimulator::new(&atn);
2078 let mut configs = AtnConfigSet::new_full_context(true);
2079 let mut merge_cache = PredictionWorkspace::default();
2080 configs.add(
2081 AtnConfig::new(2, 1, EMPTY_CONTEXT, &simulator.store.contexts),
2082 &mut simulator.store.contexts,
2083 &mut merge_cache,
2084 );
2085 configs.add(
2086 AtnConfig::new(1, 2, EMPTY_CONTEXT, &simulator.store.contexts),
2087 &mut simulator.store.contexts,
2088 &mut merge_cache,
2089 );
2090
2091 let reach = simulator.compute_reach_set(&configs, 2, true, 0, &mut merge_cache);
2092
2093 assert_eq!(reach.alts(), std::iter::once(2).collect());
2094 assert!(simulator.configs_all_reached_rule_stop(&reach));
2095 }
2096
2097 #[test]
2098 fn sll_closure_follows_empty_context_rule_stop_exits() {
2099 let mut atn = ParserAtnBuilder::new(1);
2100 add_state(&mut atn, 0, AtnStateKind::RuleStop);
2101 add_state(&mut atn, 1, AtnStateKind::Basic);
2102 add_state(&mut atn, 2, AtnStateKind::Basic);
2103 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2104 .expect("transition");
2105 atn.add_transition(
2106 1,
2107 ParserTransitionSpec::Atom {
2108 target: 2,
2109 label: 1,
2110 },
2111 )
2112 .expect("transition");
2113 atn.set_rule_to_start_state(vec![0])
2114 .expect("rule start states");
2115 atn.set_rule_to_stop_state(vec![0])
2116 .expect("rule stop states");
2117 let atn = finish_atn(atn);
2118
2119 let mut simulator = ParserAtnSimulator::new(&atn);
2120 let mut configs = AtnConfigSet::new_full_context(false);
2121 let mut merge_cache = PredictionWorkspace::default();
2122 let mut scratch = ClosureScratch::default();
2123 let config = AtnConfig::new(0, 2, EMPTY_CONTEXT, &simulator.store.contexts);
2124 simulator.closure(
2125 config,
2126 &mut configs,
2127 &mut merge_cache,
2128 &mut scratch,
2129 ClosureParams {
2130 precedence: 0,
2131 collect_predicates: true,
2132 treat_eof_as_epsilon: false,
2133 },
2134 );
2135
2136 assert_eq!(configs.len(), 1);
2137 let config = &configs.configs()[0];
2138 assert_eq!(config.state, 1);
2139 assert_eq!(config.alt, 2);
2140 assert_eq!(config.reaches_into_outer_context, 1);
2141 }
2142
2143 #[test]
2144 fn precedence_contexts_are_collected_only_for_start_closure() {
2145 let mut atn = ParserAtnBuilder::new(1);
2146 add_state(&mut atn, 0, AtnStateKind::Basic);
2147 add_state(&mut atn, 1, AtnStateKind::Basic);
2148 atn.set_rule_to_start_state(vec![0])
2149 .expect("rule start states");
2150 atn.set_rule_to_stop_state(vec![1])
2151 .expect("rule stop states");
2152 atn.add_transition(
2153 0,
2154 ParserTransitionSpec::Precedence {
2155 target: 1,
2156 precedence: 2,
2157 },
2158 )
2159 .expect("precedence transition");
2160 let atn = finish_atn(atn);
2161 let transition = atn
2162 .state(0)
2163 .expect("source state")
2164 .transitions()
2165 .first()
2166 .expect("precedence transition");
2167 let mut simulator = ParserAtnSimulator::new(&atn);
2168 let config = AtnConfig::new(0, 1, EMPTY_CONTEXT, &simulator.store.contexts);
2169
2170 let sll_start = simulator
2171 .epsilon_target_config(&config, transition, transition.kind(), 1, true, false)
2172 .expect("sll start transition");
2173 assert!(matches!(
2174 sll_start.semantic_context,
2175 SemanticContext::Precedence { precedence: 2 }
2176 ));
2177
2178 let full_context_start = simulator
2179 .epsilon_target_config(&config, transition, transition.kind(), 1, true, true)
2180 .expect("full-context start transition");
2181 assert!(full_context_start.semantic_context.is_none());
2182
2183 let reach = simulator
2184 .epsilon_target_config(&config, transition, transition.kind(), 3, false, false)
2185 .expect("reach transition");
2186 assert!(reach.semantic_context.is_none());
2187
2188 assert!(
2189 simulator
2190 .epsilon_target_config(&config, transition, transition.kind(), 3, true, false)
2191 .is_none()
2192 );
2193 }
2194
2195 #[test]
2196 fn closure_stops_collecting_predicates_after_action_edge() {
2197 let mut atn = ParserAtnBuilder::new(1);
2204 add_state(&mut atn, 0, AtnStateKind::Basic);
2205 add_state(&mut atn, 1, AtnStateKind::Basic);
2206 add_state(&mut atn, 2, AtnStateKind::Basic);
2207 add_state(&mut atn, 3, AtnStateKind::Basic);
2208 atn.add_transition(
2209 0,
2210 ParserTransitionSpec::Action {
2211 target: 1,
2212 rule_index: 0,
2213 action_index: Some(0),
2214 context_dependent: false,
2215 },
2216 )
2217 .expect("transition");
2218 atn.add_transition(
2219 1,
2220 ParserTransitionSpec::Predicate {
2221 target: 2,
2222 rule_index: 0,
2223 pred_index: 0,
2224 context_dependent: false,
2225 },
2226 )
2227 .expect("transition");
2228 atn.add_transition(
2229 2,
2230 ParserTransitionSpec::Atom {
2231 target: 3,
2232 label: 1,
2233 },
2234 )
2235 .expect("transition");
2236 atn.set_rule_to_start_state(vec![0])
2237 .expect("rule start states");
2238 atn.set_rule_to_stop_state(vec![3])
2239 .expect("rule stop states");
2240 let atn = finish_atn(atn);
2241
2242 let mut simulator = ParserAtnSimulator::new(&atn);
2243 let mut configs = AtnConfigSet::new();
2244 let mut merge_cache = PredictionWorkspace::default();
2245 let mut scratch = ClosureScratch::default();
2246 let config = AtnConfig::new(0, 1, EMPTY_CONTEXT, &simulator.store.contexts);
2247 simulator.closure(
2248 config,
2249 &mut configs,
2250 &mut merge_cache,
2251 &mut scratch,
2252 ClosureParams {
2253 precedence: 0,
2254 collect_predicates: true,
2255 treat_eof_as_epsilon: false,
2256 },
2257 );
2258
2259 let at_two = configs
2262 .configs()
2263 .iter()
2264 .find(|config| config.state == 2)
2265 .expect("config at state 2");
2266 assert!(
2267 at_two.semantic_context.is_none(),
2268 "predicate after an action edge must not be collected during prediction"
2269 );
2270
2271 let direct_config = AtnConfig::new(1, 1, EMPTY_CONTEXT, &simulator.store.contexts);
2275 let direct_transition = atn
2276 .state(1)
2277 .expect("predicate source")
2278 .transitions()
2279 .first()
2280 .expect("predicate transition");
2281 let direct = simulator
2282 .epsilon_target_config(
2283 &direct_config,
2284 direct_transition,
2285 direct_transition.kind(),
2286 0,
2287 true,
2288 false,
2289 )
2290 .expect("predicate transition");
2291 assert!(matches!(
2292 direct.semantic_context,
2293 SemanticContext::Predicate { pred_index: 0, .. }
2294 ));
2295 }
2296
2297 #[test]
2298 fn reach_set_skips_closure_for_unique_intermediate_alt() {
2299 let mut atn = ParserAtnBuilder::new(1);
2300 add_state(&mut atn, 0, AtnStateKind::Basic);
2301 add_state(&mut atn, 1, AtnStateKind::Basic);
2302 add_state(&mut atn, 2, AtnStateKind::Basic);
2303 atn.add_transition(
2304 0,
2305 ParserTransitionSpec::Atom {
2306 target: 1,
2307 label: 7,
2308 },
2309 )
2310 .expect("transition");
2311 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2312 .expect("transition");
2313 atn.set_rule_to_start_state(vec![0])
2314 .expect("rule start states");
2315 atn.set_rule_to_stop_state(vec![2])
2316 .expect("rule stop states");
2317 let atn = finish_atn(atn);
2318
2319 let mut simulator = ParserAtnSimulator::new(&atn);
2320 let mut configs = AtnConfigSet::new_full_context(false);
2321 let mut merge_cache = PredictionWorkspace::default();
2322 configs.add(
2323 AtnConfig::new(0, 1, EMPTY_CONTEXT, &simulator.store.contexts),
2324 &mut simulator.store.contexts,
2325 &mut merge_cache,
2326 );
2327
2328 let reach = simulator.compute_reach_set(&configs, 7, false, 0, &mut merge_cache);
2329
2330 assert_eq!(reach.len(), 1);
2331 assert_eq!(reach.configs()[0].state, 1);
2332 }
2333
2334 #[test]
2335 fn semantic_context_flag_is_scoped_to_predicted_alt() {
2336 let mut arena = ContextArena::new();
2337 let mut workspace = PredictionWorkspace::default();
2338 let mut configs = AtnConfigSet::new();
2339 configs.add(
2340 AtnConfig::new(1, 1, EMPTY_CONTEXT, &arena),
2341 &mut arena,
2342 &mut workspace,
2343 );
2344 configs.add(
2345 AtnConfig::new(2, 2, EMPTY_CONTEXT, &arena).with_semantic_context(
2346 SemanticContext::Predicate {
2347 rule_index: 0,
2348 pred_index: 0,
2349 context_dependent: false,
2350 },
2351 ),
2352 &mut arena,
2353 &mut workspace,
2354 );
2355
2356 assert!(!configs_have_semantic_context_for_alt(&configs, 1));
2357 assert!(configs_have_semantic_context_for_alt(&configs, 2));
2358 }
2359
2360 #[test]
2361 fn adaptive_predict_prefers_non_greedy_exit_before_consuming() {
2362 let atn = non_greedy_optional_exit_first_atn();
2363 let mut simulator = ParserAtnSimulator::new(&atn);
2364
2365 assert_eq!(simulator.adaptive_predict(0, [1, TOKEN_EOF]), Ok(1));
2366 }
2367
2368 #[test]
2369 fn left_recursive_loop_entry_drop_requires_same_rule_return() {
2370 let atn = left_recursive_loop_entry_atn();
2371 let loop_entry = atn.state(1).expect("loop entry");
2372 let mut contexts = ContextArena::new();
2373 let same_rule_context = contexts.singleton(EMPTY_CONTEXT, 4);
2374 let other_rule_context = contexts.singleton(EMPTY_CONTEXT, 5);
2375
2376 assert!(can_drop_left_recursive_loop_entry_edge(
2377 &atn,
2378 loop_entry,
2379 &contexts,
2380 same_rule_context
2381 ));
2382 assert!(!can_drop_left_recursive_loop_entry_edge(
2383 &atn,
2384 loop_entry,
2385 &contexts,
2386 other_rule_context
2387 ));
2388 assert!(!can_drop_left_recursive_loop_entry_edge(
2389 &atn,
2390 loop_entry,
2391 &contexts,
2392 EMPTY_CONTEXT
2393 ));
2394 }
2395
2396 fn two_token_decision_atn() -> Atn {
2397 two_token_decision_atn_with_precedence(false)
2398 }
2399
2400 fn two_token_decision_atn_with_precedence(precedence: bool) -> Atn {
2401 let mut atn = ParserAtnBuilder::new(3);
2402 add_state(&mut atn, 0, AtnStateKind::RuleStart);
2403 add_state(&mut atn, 1, AtnStateKind::BlockStart);
2404 add_state(&mut atn, 2, AtnStateKind::Basic);
2405 add_state(&mut atn, 3, AtnStateKind::Basic);
2406 add_state(&mut atn, 4, AtnStateKind::Basic);
2407 add_state(&mut atn, 5, AtnStateKind::Basic);
2408 add_state(&mut atn, 6, AtnStateKind::BlockEnd);
2409 add_state(&mut atn, 7, AtnStateKind::RuleStop);
2410 atn.set_rule_to_start_state(vec![0])
2411 .expect("rule start states");
2412 atn.set_rule_to_stop_state(vec![7])
2413 .expect("rule stop states");
2414 atn.add_decision_state(1).expect("decision state");
2415 if precedence {
2416 atn.set_precedence_rule_decision(1)
2417 .expect("precedence decision state");
2418 }
2419 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2420 .expect("transition");
2421 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2422 .expect("transition");
2423 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
2424 .expect("transition");
2425 atn.add_transition(
2426 2,
2427 ParserTransitionSpec::Atom {
2428 target: 3,
2429 label: 1,
2430 },
2431 )
2432 .expect("transition");
2433 atn.add_transition(
2434 3,
2435 ParserTransitionSpec::Atom {
2436 target: 6,
2437 label: 2,
2438 },
2439 )
2440 .expect("transition");
2441 atn.add_transition(
2442 4,
2443 ParserTransitionSpec::Atom {
2444 target: 5,
2445 label: 1,
2446 },
2447 )
2448 .expect("transition");
2449 atn.add_transition(
2450 5,
2451 ParserTransitionSpec::Atom {
2452 target: 6,
2453 label: 3,
2454 },
2455 )
2456 .expect("transition");
2457 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
2458 .expect("transition");
2459 finish_atn(atn)
2460 }
2461
2462 fn optional_token_decision_atn() -> Atn {
2463 let mut atn = ParserAtnBuilder::new(1);
2464 add_state(&mut atn, 0, AtnStateKind::RuleStart);
2465 add_state(&mut atn, 1, AtnStateKind::BlockStart);
2466 add_state(&mut atn, 2, AtnStateKind::Basic);
2467 add_state(&mut atn, 3, AtnStateKind::BlockEnd);
2468 add_state(&mut atn, 4, AtnStateKind::RuleStop);
2469 atn.set_rule_to_start_state(vec![0])
2470 .expect("rule start states");
2471 atn.set_rule_to_stop_state(vec![4])
2472 .expect("rule stop states");
2473 atn.add_decision_state(1).expect("decision state");
2474 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2475 .expect("transition");
2476 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2477 .expect("transition");
2478 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
2479 .expect("transition");
2480 atn.add_transition(
2481 2,
2482 ParserTransitionSpec::Atom {
2483 target: 3,
2484 label: 1,
2485 },
2486 )
2487 .expect("transition");
2488 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
2489 .expect("transition");
2490 finish_atn(atn)
2491 }
2492
2493 fn non_greedy_optional_exit_first_atn() -> Atn {
2494 let mut atn = ParserAtnBuilder::new(1);
2495 add_state(&mut atn, 0, AtnStateKind::RuleStart);
2496 add_state(&mut atn, 1, AtnStateKind::BlockStart);
2497 add_state(&mut atn, 2, AtnStateKind::BlockEnd);
2498 add_state(&mut atn, 3, AtnStateKind::Basic);
2499 add_state(&mut atn, 4, AtnStateKind::RuleStop);
2500 atn.set_rule_to_start_state(vec![0])
2501 .expect("rule start states");
2502 atn.set_rule_to_stop_state(vec![4])
2503 .expect("rule stop states");
2504 atn.add_decision_state(1).expect("decision state");
2505 atn.set_non_greedy(1).expect("non-greedy state");
2506 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2507 .expect("transition");
2508 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2509 .expect("transition");
2510 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
2511 .expect("transition");
2512 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
2513 .expect("transition");
2514 atn.add_transition(
2515 3,
2516 ParserTransitionSpec::Atom {
2517 target: 4,
2518 label: 1,
2519 },
2520 )
2521 .expect("transition");
2522 finish_atn(atn)
2523 }
2524
2525 fn ambiguous_single_token_decision_atn() -> Atn {
2526 let mut atn = ParserAtnBuilder::new(1);
2527 add_state(&mut atn, 0, AtnStateKind::RuleStart);
2528 add_state(&mut atn, 1, AtnStateKind::BlockStart);
2529 add_state(&mut atn, 2, AtnStateKind::Basic);
2530 add_state(&mut atn, 3, AtnStateKind::Basic);
2531 add_state(&mut atn, 4, AtnStateKind::Basic);
2532 add_state(&mut atn, 5, AtnStateKind::Basic);
2533 add_state(&mut atn, 6, AtnStateKind::BlockEnd);
2534 add_state(&mut atn, 7, AtnStateKind::RuleStop);
2535 atn.set_rule_to_start_state(vec![0])
2536 .expect("rule start states");
2537 atn.set_rule_to_stop_state(vec![7])
2538 .expect("rule stop states");
2539 atn.add_decision_state(1).expect("decision state");
2540 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2541 .expect("transition");
2542 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2543 .expect("transition");
2544 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
2545 .expect("transition");
2546 atn.add_transition(
2547 2,
2548 ParserTransitionSpec::Atom {
2549 target: 3,
2550 label: 1,
2551 },
2552 )
2553 .expect("transition");
2554 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 6 })
2555 .expect("transition");
2556 atn.add_transition(
2557 4,
2558 ParserTransitionSpec::Atom {
2559 target: 5,
2560 label: 1,
2561 },
2562 )
2563 .expect("transition");
2564 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
2565 .expect("transition");
2566 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
2567 .expect("transition");
2568 finish_atn(atn)
2569 }
2570
2571 fn prefix_alt_decision_atn() -> Atn {
2572 let mut atn = ParserAtnBuilder::new(3);
2573 add_state(&mut atn, 0, AtnStateKind::BlockStart);
2574 add_state(&mut atn, 1, AtnStateKind::Basic);
2575 add_state(&mut atn, 2, AtnStateKind::RuleStop);
2576 atn.set_rule_to_start_state(vec![0])
2577 .expect("rule start states");
2578 atn.set_rule_to_stop_state(vec![2])
2579 .expect("rule stop states");
2580 atn.add_decision_state(0).expect("decision state");
2581 atn.add_transition(
2582 0,
2583 ParserTransitionSpec::Atom {
2584 target: 2,
2585 label: 1,
2586 },
2587 )
2588 .expect("transition");
2589 atn.add_transition(
2590 0,
2591 ParserTransitionSpec::Atom {
2592 target: 1,
2593 label: 1,
2594 },
2595 )
2596 .expect("transition");
2597 atn.add_transition(
2598 1,
2599 ParserTransitionSpec::Atom {
2600 target: 2,
2601 label: 2,
2602 },
2603 )
2604 .expect("transition");
2605 finish_atn(atn)
2606 }
2607
2608 fn multiple_eof_decision_atn() -> Atn {
2609 let mut atn = ParserAtnBuilder::new(2);
2610 for state_number in 0..=10 {
2611 let kind = match state_number {
2612 0 => AtnStateKind::RuleStart,
2613 1 => AtnStateKind::BlockStart,
2614 7 => AtnStateKind::BlockEnd,
2615 10 => AtnStateKind::RuleStop,
2616 _ => AtnStateKind::Basic,
2617 };
2618 add_state(&mut atn, state_number, kind);
2619 }
2620 atn.set_rule_to_start_state(vec![0])
2621 .expect("rule start states");
2622 atn.set_rule_to_stop_state(vec![10])
2623 .expect("rule stop states");
2624 atn.add_decision_state(1).expect("decision state");
2625 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
2626 .expect("transition");
2627 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2628 .expect("transition");
2629 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
2630 .expect("transition");
2631 atn.add_transition(
2632 2,
2633 ParserTransitionSpec::Atom {
2634 target: 3,
2635 label: 1,
2636 },
2637 )
2638 .expect("transition");
2639 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 7 })
2640 .expect("transition");
2641 atn.add_transition(
2642 4,
2643 ParserTransitionSpec::Atom {
2644 target: 5,
2645 label: 1,
2646 },
2647 )
2648 .expect("transition");
2649 atn.add_transition(
2650 5,
2651 ParserTransitionSpec::Atom {
2652 target: 6,
2653 label: 2,
2654 },
2655 )
2656 .expect("transition");
2657 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
2658 .expect("transition");
2659 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
2660 .expect("transition");
2661 atn.add_transition(
2662 8,
2663 ParserTransitionSpec::Atom {
2664 target: 9,
2665 label: TOKEN_EOF,
2666 },
2667 )
2668 .expect("transition");
2669 atn.add_transition(
2670 9,
2671 ParserTransitionSpec::Atom {
2672 target: 10,
2673 label: TOKEN_EOF,
2674 },
2675 )
2676 .expect("transition");
2677 finish_atn(atn)
2678 }
2679
2680 fn left_recursive_loop_entry_atn() -> Atn {
2681 let mut atn = ParserAtnBuilder::new(1);
2682 add_state(&mut atn, 0, AtnStateKind::RuleStart);
2683 add_state(&mut atn, 1, AtnStateKind::StarLoopEntry);
2684 add_state(&mut atn, 2, AtnStateKind::BlockStart);
2685 add_state(&mut atn, 3, AtnStateKind::BlockEnd);
2686 add_state(&mut atn, 4, AtnStateKind::Basic);
2687 assert_eq!(
2688 atn.add_state(AtnStateKind::Basic, Some(1))
2689 .expect("state")
2690 .index(),
2691 5
2692 );
2693 add_state(&mut atn, 6, AtnStateKind::LoopEnd);
2694 add_state(&mut atn, 7, AtnStateKind::RuleStop);
2695 atn.set_rule_to_start_state(vec![0, 5])
2696 .expect("rule start states");
2697 atn.set_rule_to_stop_state(vec![7, 7])
2698 .expect("rule stop states");
2699 atn.set_precedence_rule_decision(1)
2700 .expect("precedence decision state");
2701 atn.set_end_state(2, 3).expect("block end state");
2702 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
2703 .expect("transition");
2704 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
2705 .expect("transition");
2706 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 3 })
2707 .expect("transition");
2708 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 3 })
2709 .expect("transition");
2710 finish_atn(atn)
2711 }
2712
2713 fn add_state(atn: &mut ParserAtnBuilder, state_number: usize, kind: AtnStateKind) {
2714 assert_eq!(
2715 atn.add_state(kind, Some(0)).expect("state").index(),
2716 state_number
2717 );
2718 }
2719
2720 #[derive(Debug)]
2721 struct VecIntStream {
2722 symbols: Vec<i32>,
2723 index: usize,
2724 }
2725
2726 impl VecIntStream {
2727 fn new(symbols: Vec<i32>) -> Self {
2728 Self { symbols, index: 0 }
2729 }
2730 }
2731
2732 impl IntStream for VecIntStream {
2733 fn consume(&mut self) {
2734 if self.la(1) != TOKEN_EOF {
2735 self.index += 1;
2736 }
2737 }
2738
2739 fn la(&mut self, offset: isize) -> i32 {
2740 if offset <= 0 {
2741 return 0;
2742 }
2743 let offset = offset.cast_unsigned() - 1;
2744 self.symbols
2745 .get(self.index + offset)
2746 .copied()
2747 .unwrap_or(TOKEN_EOF)
2748 }
2749
2750 fn index(&self) -> usize {
2751 self.index
2752 }
2753
2754 fn seek(&mut self, index: usize) {
2755 self.index = index;
2756 }
2757
2758 fn size(&self) -> usize {
2759 self.symbols.len()
2760 }
2761 }
2762}