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