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