Skip to main content

antlr4_runtime/atn/
parser.rs

1use crate::atn::{Atn, AtnState, AtnStateKind, Transition};
2use crate::dfa::{Dfa, DfaState};
3use crate::int_stream::IntStream;
4use crate::prediction::{
5    AtnConfig, AtnConfigSet, EMPTY_RETURN_STATE, PredictionContext, PredictionContextCache,
6    PredictionContextMergeCache, PredictionFxHasher, SemanticContext,
7    has_sll_conflict_terminating_prediction, resolves_to_just_one_viable_alt,
8};
9use crate::token::TOKEN_EOF;
10use std::cell::RefCell;
11use std::collections::{HashMap, HashSet};
12use std::hash::BuildHasherDefault;
13use std::rc::Rc;
14
15type FxHashSet<T> = HashSet<T, BuildHasherDefault<PredictionFxHasher>>;
16
17#[derive(Debug)]
18pub struct ParserAtnSimulator<'a> {
19    atn: &'a Atn,
20    decision_to_dfa: Vec<Dfa>,
21    shared_cache_key: Option<usize>,
22    context_cache: Rc<RefCell<PredictionContextCache>>,
23}
24
25thread_local! {
26    static SHARED_DECISION_DFAS: RefCell<HashMap<usize, Vec<Dfa>>> = RefCell::new(HashMap::new());
27    static SHARED_CONTEXT_CACHES: RefCell<HashMap<usize, Rc<RefCell<PredictionContextCache>>>> =
28        RefCell::new(HashMap::new());
29}
30
31#[derive(Clone, Debug, Eq, PartialEq)]
32pub struct ParserAtnPrediction {
33    pub alt: usize,
34    pub requires_full_context: bool,
35    pub has_semantic_context: bool,
36    pub diagnostic: Option<ParserAtnPredictionDiagnostic>,
37}
38
39#[derive(Clone, Debug, Eq, PartialEq)]
40pub struct ParserAtnPredictionDiagnostic {
41    pub kind: ParserAtnPredictionDiagnosticKind,
42    pub start_index: usize,
43    pub sll_stop_index: usize,
44    pub ll_stop_index: usize,
45    pub conflicting_alts: Vec<usize>,
46}
47
48#[derive(Clone, Copy, Debug, Eq, PartialEq)]
49pub enum ParserAtnPredictionDiagnosticKind {
50    Ambiguity,
51    ContextSensitivity,
52}
53
54#[derive(Clone, Copy)]
55struct PredictionCheck<'a> {
56    decision: usize,
57    decision_state: usize,
58    state_number: usize,
59    start_index: usize,
60    precedence: i32,
61    outer_context: &'a Rc<PredictionContext>,
62    force_full_context_retry: bool,
63    sll_probe_only: bool,
64}
65
66#[derive(Clone, Copy)]
67struct AdaptivePredictRequest<'a> {
68    decision: usize,
69    precedence: usize,
70    outer_context: &'a Rc<PredictionContext>,
71    force_full_context_retry: bool,
72    /// When set, the SLL walk stops at the first full-context-requiring conflict
73    /// and returns the SLL prediction (carrying `requires_full_context = true`)
74    /// WITHOUT running the expensive full-context LL loop. The generated
75    /// two-stage prediction uses only that boolean to decide whether to re-run
76    /// with the real outer context, so the empty-context LL pass this skips is
77    /// discarded work. Mirrors Go's execATN, which returns "needs LL" from the
78    /// SLL stage rather than computing LL twice.
79    sll_probe_only: bool,
80}
81
82#[derive(Clone, Copy)]
83struct DfaEdge {
84    decision: usize,
85    source_state: usize,
86}
87
88#[derive(Clone, Debug, Eq, PartialEq)]
89struct DfaPredictionInfo {
90    prediction: ParserAtnPrediction,
91    conflicting_alts: Vec<usize>,
92}
93
94#[derive(Clone, Debug, Eq, PartialEq)]
95struct FullContextPrediction {
96    prediction: ParserAtnPrediction,
97    stop_index: usize,
98    ambiguity_alts: Option<Vec<usize>>,
99}
100
101#[derive(Clone, Debug, Eq, Hash, PartialEq)]
102struct ClosureConfigKey {
103    state: usize,
104    alt: usize,
105    context: Rc<PredictionContext>,
106    semantic_context: SemanticContext,
107    precedence_filter_suppressed: bool,
108}
109
110impl From<&AtnConfig> for ClosureConfigKey {
111    fn from(config: &AtnConfig) -> Self {
112        Self {
113            state: config.state,
114            alt: config.alt,
115            context: Rc::clone(&config.context),
116            semantic_context: config.semantic_context.clone(),
117            precedence_filter_suppressed: config.precedence_filter_suppressed,
118        }
119    }
120}
121
122/// Reusable scratch buffers for `closure`. ANTLR's reference runtimes allocate a
123/// fresh work stack and "closure busy" visited set per `closure` call (millions
124/// of allocations on large parses); reusing one buffer across the per-config
125/// calls of a single reach/start-state computation removes that churn. Each
126/// `closure` call clears the buffers first, so the visited scope stays per-call
127/// — behaviour-identical to allocating fresh sets.
128#[derive(Default)]
129struct ClosureScratch {
130    /// Work stack of `(config, collect_predicates)`. The per-config
131    /// `collect_predicates` flag mirrors ANTLR's
132    /// `continueCollecting = collectPredicates && !ActionTransition`: once an
133    /// action edge is crossed, predicates on the far side are NOT collected into
134    /// the config's semantic context, so they are deferred to parse time rather
135    /// than evaluated during prediction (the "action hides predicates" rule).
136    stack: Vec<(AtnConfig, bool)>,
137    visited: FxHashSet<ClosureConfigKey>,
138}
139
140/// Per-closure-tree invariants, grouped so `closure` stays within Clippy's
141/// argument-count budget while threading the reusable [`ClosureScratch`].
142#[derive(Clone, Copy)]
143struct ClosureParams {
144    precedence: i32,
145    collect_predicates: bool,
146    treat_eof_as_epsilon: bool,
147}
148
149#[derive(Debug)]
150struct LookaheadIntStream {
151    symbols: Vec<i32>,
152    index: usize,
153}
154
155impl LookaheadIntStream {
156    const fn new(symbols: Vec<i32>) -> Self {
157        Self { symbols, index: 0 }
158    }
159}
160
161impl IntStream for LookaheadIntStream {
162    fn consume(&mut self) {
163        if self.la(1) != TOKEN_EOF {
164            self.index += 1;
165        }
166    }
167
168    fn la(&mut self, offset: isize) -> i32 {
169        if offset <= 0 {
170            return 0;
171        }
172        let offset = offset.cast_unsigned() - 1;
173        self.symbols
174            .get(self.index + offset)
175            .copied()
176            .unwrap_or(TOKEN_EOF)
177    }
178
179    fn index(&self) -> usize {
180        self.index
181    }
182
183    fn seek(&mut self, index: usize) {
184        self.index = index.min(self.symbols.len());
185    }
186
187    fn size(&self) -> usize {
188        self.symbols.len()
189    }
190}
191
192fn initial_decision_dfas(atn: &Atn) -> Vec<Dfa> {
193    atn.decision_to_state()
194        .iter()
195        .copied()
196        .enumerate()
197        .map(|(decision, state)| {
198            let mut dfa = Dfa::with_max_token_type(state, decision, atn.max_token_type());
199            if atn
200                .state(state)
201                .is_some_and(|state| state.precedence_rule_decision)
202            {
203                dfa.set_precedence_dfa(true);
204            }
205            dfa
206        })
207        .collect()
208}
209
210/// Merges a dropping simulator's DFAs into tables that another simulator
211/// checked in first, losslessly. The two evolved independently (the
212/// later-constructed one started cold), so numeric state ids are not
213/// comparable — but DFA states ARE comparable by their ATN config set, the
214/// same identity `Dfa::add_state` dedups on. Re-keying `local`'s states into
215/// `shared`'s numbering and unioning edges/starts means overlapping
216/// simulators never lose learned coverage, however it is distributed.
217/// Walking every state is fine here: this only runs on the rare
218/// overlapping-simulators drop path.
219fn union_decision_dfas(shared: &mut Vec<Dfa>, local: Vec<Dfa>) {
220    if shared.len() != local.len() {
221        *shared = local;
222        return;
223    }
224    for (shared_dfa, local_dfa) in shared.iter_mut().zip(local) {
225        union_decision_dfa(shared_dfa, local_dfa);
226    }
227}
228
229fn union_decision_dfa(shared: &mut Dfa, local: Dfa) {
230    if shared.is_precedence_dfa() != local.is_precedence_dfa() {
231        // A mode flip resets the tables (`set_precedence_dfa`), so the two are
232        // not unionable; keep whichever learned more states.
233        if local.states().len() > shared.states().len() {
234            *shared = local;
235        }
236        return;
237    }
238    // Pass 1: map every local state number to a shared state number by
239    // config-set identity, inserting the states shared has not learned.
240    // Their edges reference local numbering, so they are cleared here and
241    // re-added in pass 2 under the shared numbering.
242    let mut renumber = Vec::with_capacity(local.states().len());
243    for state in local.states() {
244        let number = shared
245            .state_number_for_configs(&state.configs)
246            .unwrap_or_else(|| {
247                let mut missing = state.clone();
248                missing.edges = Vec::new();
249                shared.insert_state(missing)
250            });
251        renumber.push(number);
252    }
253    // Pass 2: union edges, translating targets into shared numbering. The
254    // incumbent's entries win; only gaps are filled. Accept metadata needs no
255    // reconciliation: it is a pure function of the config set, and equal
256    // config sets produced it through the same accept-time computation.
257    for (state, &mapped) in local.states().iter().zip(&renumber) {
258        for (index, target) in state.edges.iter().enumerate() {
259            let (Some(target), Ok(index)) = (*target, i32::try_from(index)) else {
260                continue;
261            };
262            // Inverse of `edge_index`: slot 0 holds EOF (symbol -1).
263            let symbol = index - 1;
264            let Some(&mapped_target) = renumber.get(target) else {
265                continue;
266            };
267            let Some(shared_state) = shared.state_mut(mapped) else {
268                continue;
269            };
270            if shared_state.edge(symbol).is_none() {
271                shared_state.add_edge(symbol, mapped_target);
272            }
273        }
274    }
275    if shared.start_state().is_none()
276        && let Some(start) = local.start_state()
277        && let Some(&mapped) = renumber.get(start)
278    {
279        shared.set_start_state(mapped);
280    }
281    for (precedence, start) in local.precedence_start_states().iter().enumerate() {
282        let Some(start) = *start else {
283            continue;
284        };
285        if shared.precedence_start_state(precedence).is_none()
286            && let Some(&mapped) = renumber.get(start)
287        {
288            shared.set_precedence_start_state(precedence, mapped);
289        }
290    }
291}
292
293impl Drop for ParserAtnSimulator<'_> {
294    fn drop(&mut self) {
295        let Some(key) = self.shared_cache_key else {
296            return;
297        };
298        // Check the DFAs back IN by move. The slot is normally vacant because
299        // `new_shared` checked them out; it is occupied only when another
300        // simulator for the same ATN was created while this one was alive
301        // (that one started cold and checked its copy in first) — then union
302        // the two by config-set identity so neither side's learning is lost.
303        let dfas = std::mem::take(&mut self.decision_to_dfa);
304        SHARED_DECISION_DFAS.with(|cache| {
305            let mut cache = cache.borrow_mut();
306            if let Some(shared) = cache.get_mut(&key) {
307                union_decision_dfas(shared, dfas);
308            } else {
309                cache.insert(key, dfas);
310            }
311        });
312    }
313}
314
315impl<'a> ParserAtnSimulator<'a> {
316    pub fn new(atn: &'a Atn) -> Self {
317        Self {
318            atn,
319            decision_to_dfa: initial_decision_dfas(atn),
320            shared_cache_key: None,
321            context_cache: Rc::new(RefCell::new(PredictionContextCache::new())),
322        }
323    }
324
325    /// Creates a simulator that starts from, and publishes back into, a
326    /// thread-local DFA cache keyed by a generated parser's static ATN.
327    ///
328    /// Generated parsers usually create a fresh parser object per parse. Without
329    /// this cache every parse relearns the same adaptive DFA; with it, later
330    /// parser instances reuse the SLL cache learned by earlier instances while
331    /// still keeping mutable simulator state local to the parser during a parse.
332    ///
333    /// The DFAs are checked OUT of the cache by move (and back in on drop):
334    /// cloning a warm DFA per parser instance costs O(learned states) — ~10%
335    /// of a small parse. A second simulator created for the same ATN while one
336    /// is alive finds the slot empty and starts cold; the drop-time check-in
337    /// then keeps whichever tables learned more.
338    pub fn new_shared(atn: &'static Atn) -> Self {
339        let ptr: *const Atn = atn;
340        let key = ptr as usize;
341        let decision_to_dfa = SHARED_DECISION_DFAS
342            .with(|cache| cache.borrow_mut().remove(&key))
343            .unwrap_or_else(|| initial_decision_dfas(atn));
344        let context_cache = SHARED_CONTEXT_CACHES.with(|cache| {
345            Rc::clone(
346                cache
347                    .borrow_mut()
348                    .entry(key)
349                    .or_insert_with(|| Rc::new(RefCell::new(PredictionContextCache::new()))),
350            )
351        });
352        Self {
353            atn,
354            decision_to_dfa,
355            shared_cache_key: Some(key),
356            context_cache,
357        }
358    }
359
360    pub fn decision_dfas(&self) -> &[Dfa] {
361        &self.decision_to_dfa
362    }
363
364    pub fn adaptive_predict(
365        &mut self,
366        decision: usize,
367        lookahead: impl IntoIterator<Item = i32>,
368    ) -> Result<usize, ParserAtnSimulatorError> {
369        self.adaptive_predict_with_precedence(decision, 0, lookahead)
370    }
371
372    pub fn adaptive_predict_stream<T: IntStream>(
373        &mut self,
374        decision: usize,
375        input: &mut T,
376    ) -> Result<usize, ParserAtnSimulatorError> {
377        self.adaptive_predict_stream_with_precedence(decision, 0, input)
378    }
379
380    pub fn adaptive_predict_stream_with_precedence<T: IntStream>(
381        &mut self,
382        decision: usize,
383        precedence: usize,
384        input: &mut T,
385    ) -> Result<usize, ParserAtnSimulatorError> {
386        self.adaptive_predict_stream_info_with_precedence(decision, precedence, input)
387            .map(|prediction| prediction.alt)
388    }
389
390    pub fn adaptive_predict_stream_info_with_precedence<T: IntStream>(
391        &mut self,
392        decision: usize,
393        precedence: usize,
394        input: &mut T,
395    ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
396        let empty = PredictionContext::empty();
397        let marker = input.mark();
398        let index = input.index();
399        let mut merge_cache = PredictionContextMergeCache::new();
400        let result = self.adaptive_predict_stream_inner(
401            AdaptivePredictRequest {
402                decision,
403                precedence,
404                outer_context: &empty,
405                force_full_context_retry: false,
406                sll_probe_only: false,
407            },
408            input,
409            &mut merge_cache,
410        );
411        input.seek(index);
412        input.release(marker);
413        result
414    }
415
416    /// SLL-probe variant of [`Self::adaptive_predict_stream_info_with_precedence`].
417    ///
418    /// Identical to the precedence entry except that, when the SLL walk reaches
419    /// a conflict state requiring full context, it returns the SLL prediction
420    /// (carrying `requires_full_context = true`) WITHOUT running the
421    /// full-context LL loop. The generated two-stage prediction calls this for
422    /// stage 1 and only consults `requires_full_context` to decide whether to
423    /// re-run with the real outer context, so the empty-context LL pass this
424    /// skips would be discarded anyway. Avoids the double LL pass per escalation.
425    pub fn adaptive_predict_stream_info_sll_probe<T: IntStream>(
426        &mut self,
427        decision: usize,
428        precedence: usize,
429        input: &mut T,
430    ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
431        let empty = PredictionContext::empty();
432        let marker = input.mark();
433        let index = input.index();
434        let mut merge_cache = PredictionContextMergeCache::new();
435        let result = self.adaptive_predict_stream_inner(
436            AdaptivePredictRequest {
437                decision,
438                precedence,
439                outer_context: &empty,
440                force_full_context_retry: false,
441                sll_probe_only: true,
442            },
443            input,
444            &mut merge_cache,
445        );
446        input.seek(index);
447        input.release(marker);
448        result
449    }
450
451    pub fn adaptive_predict_stream_info_with_context<T: IntStream>(
452        &mut self,
453        decision: usize,
454        precedence: usize,
455        input: &mut T,
456        outer_context: &Rc<PredictionContext>,
457    ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
458        let marker = input.mark();
459        let index = input.index();
460        let mut merge_cache = PredictionContextMergeCache::new();
461        let result = self.adaptive_predict_stream_inner(
462            AdaptivePredictRequest {
463                decision,
464                precedence,
465                outer_context,
466                force_full_context_retry: true,
467                sll_probe_only: false,
468            },
469            input,
470            &mut merge_cache,
471        );
472        input.seek(index);
473        input.release(marker);
474        result
475    }
476
477    pub fn adaptive_predict_with_precedence(
478        &mut self,
479        decision: usize,
480        precedence: usize,
481        lookahead: impl IntoIterator<Item = i32>,
482    ) -> Result<usize, ParserAtnSimulatorError> {
483        self.adaptive_predict_info_with_precedence(decision, precedence, lookahead)
484            .map(|prediction| prediction.alt)
485    }
486
487    pub fn adaptive_predict_info_with_precedence(
488        &mut self,
489        decision: usize,
490        precedence: usize,
491        lookahead: impl IntoIterator<Item = i32>,
492    ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
493        let mut input = LookaheadIntStream::new(lookahead.into_iter().collect());
494        self.adaptive_predict_stream_info_with_precedence(decision, precedence, &mut input)
495    }
496
497    fn adaptive_predict_stream_inner<T: IntStream>(
498        &mut self,
499        request: AdaptivePredictRequest<'_>,
500        input: &mut T,
501        merge_cache: &mut PredictionContextMergeCache,
502    ) -> Result<ParserAtnPrediction, ParserAtnSimulatorError> {
503        let AdaptivePredictRequest {
504            decision,
505            precedence,
506            outer_context,
507            force_full_context_retry,
508            sll_probe_only,
509        } = request;
510        #[cfg(feature = "perf-counters")]
511        crate::perf::record_adaptive_call(decision, force_full_context_retry);
512        let Some(&decision_state) = self.atn.decision_to_state().get(decision) else {
513            return Err(ParserAtnSimulatorError::UnknownDecision(decision));
514        };
515        let start_index = input.index();
516        // Precedence originates from the parser's precedence stack (rule nesting
517        // depth), so it is always small in practice. A value above `i32::MAX`
518        // would be clamped here; the clamp only ever affects pathological inputs
519        // and at worst over-filters precedence transitions, never miscomputing a
520        // real parse.
521        let precedence = i32::try_from(precedence).unwrap_or(i32::MAX);
522        let mut state_number =
523            self.ensure_start_state(decision, decision_state, precedence, merge_cache)?;
524        if let Some(prediction) = self.prediction_or_full_context(
525            input,
526            PredictionCheck {
527                decision,
528                decision_state,
529                state_number,
530                start_index,
531                precedence,
532                outer_context,
533                force_full_context_retry,
534                sll_probe_only,
535            },
536            merge_cache,
537        )? {
538            return Ok(prediction);
539        }
540        loop {
541            let symbol = input.la(1);
542            if let Some(target) = self
543                .decision_to_dfa
544                .get(decision)
545                .and_then(|dfa| dfa.state(state_number))
546                .and_then(|state| state.edge(symbol))
547            {
548                state_number = target;
549            } else {
550                let configs = self
551                    .decision_to_dfa
552                    .get(decision)
553                    .and_then(|dfa| dfa.state(state_number))
554                    .map(|state| state.configs.clone())
555                    .ok_or(ParserAtnSimulatorError::MissingDfaState(state_number))?;
556                let target = match self.compute_target_state(
557                    DfaEdge {
558                        decision,
559                        source_state: state_number,
560                    },
561                    &configs,
562                    symbol,
563                    precedence,
564                    merge_cache,
565                ) {
566                    Ok(target) => target,
567                    Err(ParserAtnSimulatorError::NoViableAlt { symbol, .. }) => {
568                        return Err(ParserAtnSimulatorError::NoViableAlt {
569                            symbol,
570                            index: input.index(),
571                        });
572                    }
573                    Err(error) => return Err(error),
574                };
575                state_number = target;
576            }
577            if let Some(prediction) = self.prediction_or_full_context(
578                input,
579                PredictionCheck {
580                    decision,
581                    decision_state,
582                    state_number,
583                    start_index,
584                    precedence,
585                    outer_context,
586                    force_full_context_retry,
587                    sll_probe_only,
588                },
589                merge_cache,
590            )? {
591                return Ok(prediction);
592            }
593            if symbol == TOKEN_EOF {
594                // We ran out of input while still inside the decision and the
595                // current state is not a clean accept. ANTLR's execATN takes one
596                // more step on EOF, reaches an empty reach set, and falls back to
597                // getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule: any alt
598                // whose configs already reached the decision's rule-stop (i.e. an
599                // exit alt of a `(...)*`/`(...)+`/precedence loop) is a valid
600                // prediction, not a syntax error. Mirror that fallback here so we
601                // exit the loop cleanly instead of reporting a spurious
602                // "no viable alternative at input '<EOF>'".
603                if let Some(configs) = self
604                    .decision_to_dfa
605                    .get(decision)
606                    .and_then(|dfa| dfa.state(state_number))
607                    .map(|state| state.configs.clone())
608                    && let Some(alt) = self.alt_that_finished_decision_entry_rule(&configs)
609                {
610                    return Ok(ParserAtnPrediction {
611                        alt,
612                        requires_full_context: false,
613                        has_semantic_context: configs_have_semantic_context_for_alt(&configs, alt),
614                        diagnostic: None,
615                    });
616                }
617                return Err(ParserAtnSimulatorError::PredictionRequiresMoreLookahead);
618            }
619            input.consume();
620        }
621    }
622
623    fn prediction_or_full_context<T: IntStream>(
624        &self,
625        input: &mut T,
626        check: PredictionCheck<'_>,
627        merge_cache: &mut PredictionContextMergeCache,
628    ) -> Result<Option<ParserAtnPrediction>, ParserAtnSimulatorError> {
629        let PredictionCheck {
630            decision,
631            decision_state,
632            state_number,
633            start_index,
634            precedence,
635            outer_context,
636            force_full_context_retry,
637            sll_probe_only,
638        } = check;
639        if outer_context.is_empty()
640            && let Some(prediction) =
641                self.non_greedy_exit_prediction(decision, decision_state, state_number)
642        {
643            return Ok(Some(prediction));
644        }
645        let Some(info) = self.dfa_prediction_info(decision, state_number) else {
646            return Ok(None);
647        };
648        let prediction = info.prediction;
649        // SLL-probe stage: the caller only needs to know that this conflict
650        // requires full context; it will re-run with the real outer context.
651        // Returning the SLL prediction here (with requires_full_context set)
652        // avoids running the full-context LL loop with the empty probe context,
653        // whose result the generated two-stage code discards. Mirrors Go's
654        // execATN, which signals "needs LL" instead of computing LL twice.
655        if sll_probe_only && prediction.requires_full_context {
656            return Ok(Some(prediction));
657        }
658        if prediction.requires_full_context
659            && (force_full_context_retry || !prediction.has_semantic_context)
660        {
661            #[cfg(feature = "perf-counters")]
662            crate::perf::record_full_context_retry(decision);
663            let sll_stop_index = input.index();
664            input.seek(start_index);
665            let full_context = self.adaptive_predict_full_context(
666                decision_state,
667                input,
668                precedence,
669                outer_context,
670                merge_cache,
671            )?;
672            let (kind, conflicting_alts) = if let Some(ambiguity_alts) = full_context.ambiguity_alts
673            {
674                (ParserAtnPredictionDiagnosticKind::Ambiguity, ambiguity_alts)
675            } else {
676                (
677                    ParserAtnPredictionDiagnosticKind::ContextSensitivity,
678                    info.conflicting_alts,
679                )
680            };
681            let mut prediction = full_context.prediction;
682            if conflicting_alts.len() > 1 {
683                prediction.diagnostic = Some(ParserAtnPredictionDiagnostic {
684                    kind,
685                    start_index,
686                    sll_stop_index,
687                    ll_stop_index: full_context.stop_index,
688                    conflicting_alts,
689                });
690            }
691            return Ok(Some(prediction));
692        }
693        Ok(Some(prediction))
694    }
695
696    fn non_greedy_exit_prediction(
697        &self,
698        decision: usize,
699        decision_state: usize,
700        state_number: usize,
701    ) -> Option<ParserAtnPrediction> {
702        if !self
703            .atn
704            .state(decision_state)
705            .is_some_and(|state| state.non_greedy)
706        {
707            return None;
708        }
709        let configs = &self
710            .decision_to_dfa
711            .get(decision)?
712            .state(state_number)?
713            .configs;
714        let alt = configs
715            .configs()
716            .iter()
717            .filter(|config| {
718                self.atn
719                    .state(config.state)
720                    .is_some_and(AtnState::is_rule_stop)
721                    && config.context.has_empty_path()
722            })
723            .map(|config| config.alt)
724            .min()?;
725        Some(ParserAtnPrediction {
726            alt,
727            requires_full_context: false,
728            has_semantic_context: configs_have_semantic_context_for_alt(configs, alt),
729            diagnostic: None,
730        })
731    }
732
733    fn ensure_start_state(
734        &mut self,
735        decision: usize,
736        decision_state: usize,
737        precedence: i32,
738        merge_cache: &mut PredictionContextMergeCache,
739    ) -> Result<usize, ParserAtnSimulatorError> {
740        if self.decision_to_dfa[decision].is_precedence_dfa() {
741            let precedence_key = usize::try_from(precedence.max(0)).unwrap_or_default();
742            if let Some(start) =
743                self.decision_to_dfa[decision].precedence_start_state(precedence_key)
744            {
745                return Ok(start);
746            }
747        } else if let Some(start) = self.decision_to_dfa[decision].start_state() {
748            return Ok(start);
749        }
750        let decision_state = self
751            .atn
752            .state(decision_state)
753            .ok_or(ParserAtnSimulatorError::MissingAtnState(decision_state))?;
754        let configs = self.compute_start_state(decision_state, precedence, merge_cache);
755        let state_number = self.add_dfa_state(decision, DfaState::new(configs));
756        if self.decision_to_dfa[decision].is_precedence_dfa() {
757            let precedence_key = usize::try_from(precedence.max(0)).unwrap_or_default();
758            self.decision_to_dfa[decision].set_precedence_start_state(precedence_key, state_number);
759        } else {
760            self.decision_to_dfa[decision].set_start_state(state_number);
761        }
762        Ok(state_number)
763    }
764
765    fn add_dfa_state(&mut self, decision: usize, mut state: DfaState) -> usize {
766        if state.configs.is_readonly() {
767            return self.decision_to_dfa[decision].add_state(state);
768        }
769        if let Some(existing) =
770            self.decision_to_dfa[decision].state_number_for_configs(&state.configs)
771        {
772            return existing;
773        }
774        state
775            .configs
776            .optimize_contexts(&mut self.context_cache.borrow_mut());
777        self.decision_to_dfa[decision].insert_state(state)
778    }
779
780    fn compute_start_state(
781        &self,
782        decision_state: &AtnState,
783        precedence: i32,
784        merge_cache: &mut PredictionContextMergeCache,
785    ) -> AtnConfigSet {
786        let empty = PredictionContext::empty();
787        self.compute_start_state_with_context(
788            decision_state,
789            false,
790            &empty,
791            precedence,
792            merge_cache,
793        )
794    }
795
796    fn compute_start_state_with_context(
797        &self,
798        decision_state: &AtnState,
799        full_context: bool,
800        initial_context: &Rc<PredictionContext>,
801        precedence: i32,
802        merge_cache: &mut PredictionContextMergeCache,
803    ) -> AtnConfigSet {
804        let mut configs = AtnConfigSet::new_full_context(full_context);
805        let mut scratch = ClosureScratch::default();
806        let params = ClosureParams {
807            precedence,
808            collect_predicates: true,
809            treat_eof_as_epsilon: false,
810        };
811        for (index, transition) in decision_state.transitions.iter().enumerate() {
812            let alt = index + 1;
813            let config = AtnConfig::new(transition.target(), alt, Rc::clone(initial_context));
814            self.closure(config, &mut configs, merge_cache, &mut scratch, params);
815        }
816        configs
817    }
818
819    fn adaptive_predict_full_context<T: IntStream>(
820        &self,
821        decision_state: usize,
822        input: &mut T,
823        precedence: i32,
824        outer_context: &Rc<PredictionContext>,
825        merge_cache: &mut PredictionContextMergeCache,
826    ) -> Result<FullContextPrediction, ParserAtnSimulatorError> {
827        let decision_state = self
828            .atn
829            .state(decision_state)
830            .ok_or(ParserAtnSimulatorError::MissingAtnState(decision_state))?;
831        let mut configs = self.compute_start_state_with_context(
832            decision_state,
833            true,
834            outer_context,
835            precedence,
836            merge_cache,
837        );
838        loop {
839            if let Some(alt) = configs.unique_alt() {
840                return Ok(FullContextPrediction {
841                    prediction: ParserAtnPrediction {
842                        alt,
843                        requires_full_context: true,
844                        has_semantic_context: configs_have_semantic_context_for_alt(&configs, alt),
845                        diagnostic: None,
846                    },
847                    stop_index: input.index(),
848                    ambiguity_alts: None,
849                });
850            }
851            let symbol = input.la(1);
852            let reach = self.compute_reach_set(&configs, symbol, true, precedence, merge_cache);
853            if reach.is_empty() {
854                return Err(ParserAtnSimulatorError::NoViableAlt {
855                    symbol,
856                    index: input.index(),
857                });
858            }
859            configs = reach;
860            if let Some(alt) = configs.unique_alt() {
861                return Ok(FullContextPrediction {
862                    prediction: ParserAtnPrediction {
863                        alt,
864                        requires_full_context: true,
865                        has_semantic_context: configs_have_semantic_context_for_alt(&configs, alt),
866                        diagnostic: None,
867                    },
868                    stop_index: input.index(),
869                    ambiguity_alts: None,
870                });
871            }
872            if symbol == TOKEN_EOF || self.configs_all_reached_rule_stop(&configs) {
873                let alts = configs.alts();
874                let alt = alts
875                    .iter()
876                    .next()
877                    .copied()
878                    .ok_or(ParserAtnSimulatorError::PredictionRequiresMoreLookahead)?;
879                return Ok(FullContextPrediction {
880                    prediction: ParserAtnPrediction {
881                        alt,
882                        requires_full_context: true,
883                        has_semantic_context: configs_have_semantic_context_for_alt(&configs, alt),
884                        diagnostic: None,
885                    },
886                    stop_index: input.index(),
887                    ambiguity_alts: (alts.len() > 1).then(|| alts.into_iter().collect()),
888                });
889            }
890            if !configs.has_semantic_context()
891                && let Some(alt) = resolves_to_just_one_viable_alt(configs.configs())
892            {
893                return Ok(FullContextPrediction {
894                    prediction: ParserAtnPrediction {
895                        alt,
896                        requires_full_context: true,
897                        has_semantic_context: configs_have_semantic_context_for_alt(&configs, alt),
898                        diagnostic: None,
899                    },
900                    stop_index: input.index(),
901                    ambiguity_alts: None,
902                });
903            }
904            input.consume();
905        }
906    }
907
908    fn compute_target_state(
909        &mut self,
910        edge: DfaEdge,
911        configs: &AtnConfigSet,
912        symbol: i32,
913        precedence: i32,
914        merge_cache: &mut PredictionContextMergeCache,
915    ) -> Result<usize, ParserAtnSimulatorError> {
916        let mut reach = self.compute_reach_set(configs, symbol, false, precedence, merge_cache);
917        if reach.is_empty() {
918            if let Some(prediction) = self.alt_that_finished_decision_entry_rule(configs) {
919                let mut dfa_state = DfaState::new(configs.clone());
920                dfa_state.mark_accept(prediction);
921                // The set-wide flag gates the per-alt scan: if no config in the
922                // set carries a semantic context, no alt can either.
923                dfa_state.has_semantic_context_for_alt = dfa_state.configs.has_semantic_context()
924                    && configs_have_semantic_context_for_alt(&dfa_state.configs, prediction);
925                let target_state = self.add_dfa_state(edge.decision, dfa_state);
926                if let Some(source) =
927                    self.decision_to_dfa[edge.decision].state_mut(edge.source_state)
928                {
929                    source.add_edge(symbol, target_state);
930                }
931                return Ok(target_state);
932            }
933            return Err(ParserAtnSimulatorError::NoViableAlt { symbol, index: 0 });
934        }
935        let prediction = reach.unique_alt();
936        let conflict_prediction = prediction.or_else(|| {
937            if !has_sll_conflict_terminating_prediction(&reach, |state| {
938                self.atn.state(state).is_some_and(AtnState::is_rule_stop)
939            }) {
940                return None;
941            }
942            reach
943                .conflicting_alts()
944                .into_iter()
945                .next()
946                .or_else(|| reach.alts().into_iter().next())
947        });
948        let requires_full_context = prediction.is_none() && conflict_prediction.is_some();
949        #[cfg(feature = "perf-counters")]
950        if requires_full_context {
951            crate::perf::record_sll_conflict(edge.decision);
952        }
953        let conflicting_alts = if requires_full_context {
954            let alts = reach.conflicting_alts();
955            if alts.is_empty() { reach.alts() } else { alts }
956                .into_iter()
957                .collect()
958        } else {
959            Vec::new()
960        };
961        let mut dfa_state = DfaState::new(reach);
962        if let Some(prediction) = conflict_prediction {
963            dfa_state.mark_accept(prediction);
964            dfa_state.requires_full_context = requires_full_context;
965            dfa_state.conflicting_alts = conflicting_alts;
966            // The set-wide flag gates the per-alt scan: if no config in the set
967            // carries a semantic context, no alt can either.
968            dfa_state.has_semantic_context_for_alt = dfa_state.configs.has_semantic_context()
969                && configs_have_semantic_context_for_alt(&dfa_state.configs, prediction);
970        }
971        let target_state = self.add_dfa_state(edge.decision, dfa_state);
972        if let Some(source) = self.decision_to_dfa[edge.decision].state_mut(edge.source_state) {
973            source.add_edge(symbol, target_state);
974        }
975        Ok(target_state)
976    }
977
978    fn compute_reach_set(
979        &self,
980        configs: &AtnConfigSet,
981        symbol: i32,
982        full_context: bool,
983        precedence: i32,
984        merge_cache: &mut PredictionContextMergeCache,
985    ) -> AtnConfigSet {
986        let mut intermediate = AtnConfigSet::new_full_context(full_context);
987        let mut skipped_stop_states = Vec::new();
988        for config in configs.configs() {
989            let Some(state) = self.atn.state(config.state) else {
990                continue;
991            };
992            if state.is_rule_stop() {
993                if full_context || symbol == TOKEN_EOF {
994                    skipped_stop_states.push(config.clone());
995                }
996                continue;
997            }
998            for transition in &state.transitions {
999                if transition.matches(symbol, 1, self.atn.max_token_type()) {
1000                    let target = AtnConfig {
1001                        state: transition.target(),
1002                        alt: config.alt,
1003                        context: Rc::clone(&config.context),
1004                        semantic_context: config.semantic_context.clone(),
1005                        reaches_into_outer_context: config.reaches_into_outer_context,
1006                        precedence_filter_suppressed: config.precedence_filter_suppressed,
1007                    };
1008                    intermediate.add_with_merge_cache(target, Some(merge_cache));
1009                }
1010            }
1011        }
1012        let mut reach = if skipped_stop_states.is_empty() && symbol != TOKEN_EOF {
1013            if intermediate.len() == 1 || intermediate.unique_alt().is_some() {
1014                intermediate
1015            } else {
1016                self.close_intermediate_reach_set(
1017                    intermediate,
1018                    full_context,
1019                    precedence,
1020                    symbol,
1021                    merge_cache,
1022                )
1023            }
1024        } else {
1025            self.close_intermediate_reach_set(
1026                intermediate,
1027                full_context,
1028                precedence,
1029                symbol,
1030                merge_cache,
1031            )
1032        };
1033        if symbol == TOKEN_EOF {
1034            reach = self.rule_stop_configs(reach, merge_cache);
1035        }
1036        if !full_context || !self.configs_contain_rule_stop(&reach) {
1037            for config in skipped_stop_states {
1038                reach.add_with_merge_cache(config, Some(merge_cache));
1039            }
1040        }
1041        #[cfg(feature = "perf-counters")]
1042        crate::perf::record_reach_set(full_context, configs.len(), reach.len());
1043        reach
1044    }
1045
1046    fn close_intermediate_reach_set(
1047        &self,
1048        intermediate: AtnConfigSet,
1049        full_context: bool,
1050        precedence: i32,
1051        symbol: i32,
1052        merge_cache: &mut PredictionContextMergeCache,
1053    ) -> AtnConfigSet {
1054        let mut reach = AtnConfigSet::new_full_context(full_context);
1055        let mut scratch = ClosureScratch::default();
1056        let params = ClosureParams {
1057            precedence,
1058            collect_predicates: false,
1059            treat_eof_as_epsilon: symbol == TOKEN_EOF,
1060        };
1061        // `closure` takes `AtnConfig` by value, so drain the intermediate set by
1062        // move instead of cloning each config.
1063        for config in intermediate.into_configs() {
1064            self.closure(config, &mut reach, merge_cache, &mut scratch, params);
1065        }
1066        reach
1067    }
1068
1069    fn alt_that_finished_decision_entry_rule(&self, configs: &AtnConfigSet) -> Option<usize> {
1070        configs
1071            .configs()
1072            .iter()
1073            .filter(|config| {
1074                config.reaches_into_outer_context > 0
1075                    || self
1076                        .atn
1077                        .state(config.state)
1078                        .is_some_and(AtnState::is_rule_stop)
1079                        && config.context.has_empty_path()
1080            })
1081            .map(|config| config.alt)
1082            .min()
1083    }
1084
1085    fn rule_stop_configs(
1086        &self,
1087        configs: AtnConfigSet,
1088        merge_cache: &mut PredictionContextMergeCache,
1089    ) -> AtnConfigSet {
1090        if configs.configs().iter().all(|config| {
1091            self.atn
1092                .state(config.state)
1093                .is_some_and(AtnState::is_rule_stop)
1094        }) {
1095            return configs;
1096        }
1097        let mut result = AtnConfigSet::new_full_context(configs.full_context());
1098        for config in configs.configs().iter().filter(|config| {
1099            self.atn
1100                .state(config.state)
1101                .is_some_and(AtnState::is_rule_stop)
1102        }) {
1103            result.add_with_merge_cache(config.clone(), Some(merge_cache));
1104        }
1105        result
1106    }
1107
1108    fn configs_all_reached_rule_stop(&self, configs: &AtnConfigSet) -> bool {
1109        configs.configs().iter().all(|config| {
1110            self.atn
1111                .state(config.state)
1112                .is_some_and(AtnState::is_rule_stop)
1113        })
1114    }
1115
1116    fn configs_contain_rule_stop(&self, configs: &AtnConfigSet) -> bool {
1117        configs.configs().iter().any(|config| {
1118            self.atn
1119                .state(config.state)
1120                .is_some_and(AtnState::is_rule_stop)
1121        })
1122    }
1123
1124    fn closure(
1125        &self,
1126        config: AtnConfig,
1127        configs: &mut AtnConfigSet,
1128        merge_cache: &mut PredictionContextMergeCache,
1129        scratch: &mut ClosureScratch,
1130        params: ClosureParams,
1131    ) {
1132        let ClosureParams {
1133            precedence,
1134            collect_predicates,
1135            treat_eof_as_epsilon,
1136        } = params;
1137        scratch.stack.clear();
1138        scratch.visited.clear();
1139        scratch.stack.push((config, collect_predicates));
1140        while let Some((config, collect_predicates)) = scratch.stack.pop() {
1141            if !scratch.visited.insert(ClosureConfigKey::from(&config)) {
1142                continue;
1143            }
1144            let Some(state) = self.atn.state(config.state) else {
1145                continue;
1146            };
1147            let at_rule_stop = state.is_rule_stop();
1148            if at_rule_stop
1149                && self.closure_at_rule_stop(
1150                    config.clone(),
1151                    collect_predicates,
1152                    configs,
1153                    merge_cache,
1154                    &mut scratch.stack,
1155                )
1156            {
1157                continue;
1158            }
1159            let epsilon_only = !state.transitions.is_empty()
1160                && state.transitions.iter().all(Transition::is_epsilon);
1161            if !epsilon_only {
1162                configs.add_with_merge_cache(config.clone(), Some(merge_cache));
1163            }
1164            for (index, transition) in state.transitions.iter().enumerate() {
1165                if index == 0
1166                    && can_drop_left_recursive_loop_entry_edge(self.atn, state, &config.context)
1167                {
1168                    continue;
1169                }
1170                if transition.is_epsilon() {
1171                    if let Some(mut target) = self.epsilon_target_config(
1172                        &config,
1173                        transition,
1174                        precedence,
1175                        collect_predicates,
1176                        configs.full_context(),
1177                    ) {
1178                        if at_rule_stop {
1179                            target.reaches_into_outer_context =
1180                                target.reaches_into_outer_context.saturating_add(1);
1181                        }
1182                        // ANTLR: stop collecting predicates once an action edge is
1183                        // crossed, so a predicate after an action is deferred to
1184                        // parse time rather than evaluated during prediction.
1185                        let target_collect_predicates =
1186                            collect_predicates && !matches!(transition, Transition::Action { .. });
1187                        scratch.stack.push((target, target_collect_predicates));
1188                    }
1189                } else if treat_eof_as_epsilon
1190                    && transition.matches(TOKEN_EOF, 1, self.atn.max_token_type())
1191                {
1192                    scratch.stack.push((
1193                        AtnConfig {
1194                            state: transition.target(),
1195                            alt: config.alt,
1196                            context: Rc::clone(&config.context),
1197                            semantic_context: config.semantic_context.clone(),
1198                            reaches_into_outer_context: config.reaches_into_outer_context,
1199                            precedence_filter_suppressed: config.precedence_filter_suppressed,
1200                        },
1201                        collect_predicates,
1202                    ));
1203                }
1204            }
1205        }
1206        #[cfg(feature = "perf-counters")]
1207        crate::perf::record_closure(scratch.visited.len());
1208    }
1209
1210    fn closure_at_rule_stop(
1211        &self,
1212        config: AtnConfig,
1213        collect_predicates: bool,
1214        configs: &mut AtnConfigSet,
1215        merge_cache: &mut PredictionContextMergeCache,
1216        stack: &mut Vec<(AtnConfig, bool)>,
1217    ) -> bool {
1218        if config.context.is_empty() {
1219            if configs.full_context() {
1220                configs.add_with_merge_cache(config, Some(merge_cache));
1221                return true;
1222            }
1223            return false;
1224        }
1225        let mut handled_all_paths = true;
1226        for index in 0..config.context.len() {
1227            let Some(return_state) = config.context.return_state(index) else {
1228                continue;
1229            };
1230            if return_state == EMPTY_RETURN_STATE {
1231                if configs.full_context() {
1232                    let mut empty_context_config = config.clone();
1233                    empty_context_config.context = PredictionContext::empty();
1234                    configs.add_with_merge_cache(empty_context_config, Some(merge_cache));
1235                } else {
1236                    handled_all_paths = false;
1237                }
1238                continue;
1239            }
1240            let parent = config
1241                .context
1242                .parent(index)
1243                .unwrap_or_else(PredictionContext::empty);
1244            let next = AtnConfig {
1245                state: return_state,
1246                alt: config.alt,
1247                context: parent,
1248                semantic_context: config.semantic_context.clone(),
1249                reaches_into_outer_context: config.reaches_into_outer_context,
1250                precedence_filter_suppressed: config.precedence_filter_suppressed,
1251            };
1252            stack.push((next, collect_predicates));
1253        }
1254        handled_all_paths
1255    }
1256
1257    fn epsilon_target_config(
1258        &self,
1259        config: &AtnConfig,
1260        transition: &Transition,
1261        precedence: i32,
1262        collect_predicates: bool,
1263        full_context: bool,
1264    ) -> Option<AtnConfig> {
1265        let semantic_context = match transition {
1266            Transition::Predicate {
1267                rule_index,
1268                pred_index,
1269                context_dependent,
1270                ..
1271            } if collect_predicates => SemanticContext::and(
1272                config.semantic_context.clone(),
1273                SemanticContext::Predicate {
1274                    rule_index: *rule_index,
1275                    pred_index: *pred_index,
1276                    context_dependent: *context_dependent,
1277                },
1278            ),
1279            Transition::Precedence {
1280                precedence: transition_precedence,
1281                ..
1282            } if collect_predicates && *transition_precedence < precedence => return None,
1283            Transition::Precedence { precedence, .. } if collect_predicates && !full_context => {
1284                SemanticContext::and(
1285                    config.semantic_context.clone(),
1286                    SemanticContext::Precedence {
1287                        precedence: *precedence,
1288                    },
1289                )
1290            }
1291            _ => config.semantic_context.clone(),
1292        };
1293        let context = match transition {
1294            Transition::Rule { follow_state, .. } => {
1295                PredictionContext::singleton(Rc::clone(&config.context), *follow_state)
1296            }
1297            _ => Rc::clone(&config.context),
1298        };
1299        Some(AtnConfig {
1300            state: transition.target(),
1301            alt: config.alt,
1302            context,
1303            semantic_context,
1304            reaches_into_outer_context: config.reaches_into_outer_context,
1305            precedence_filter_suppressed: config.precedence_filter_suppressed,
1306        })
1307    }
1308
1309    fn dfa_prediction_info(
1310        &self,
1311        decision: usize,
1312        state_number: usize,
1313    ) -> Option<DfaPredictionInfo> {
1314        self.decision_to_dfa
1315            .get(decision)
1316            .and_then(|dfa| dfa.state(state_number))
1317            .and_then(|state| {
1318                state.prediction.map(|alt| {
1319                    let conflicting_alts = if state.requires_full_context {
1320                        if state.conflicting_alts.is_empty() {
1321                            state.configs.alts().into_iter().collect()
1322                        } else {
1323                            state.conflicting_alts.clone()
1324                        }
1325                    } else {
1326                        Vec::new()
1327                    };
1328                    DfaPredictionInfo {
1329                        prediction: ParserAtnPrediction {
1330                            alt,
1331                            requires_full_context: state.requires_full_context,
1332                            // Precomputed at accept time (see compute_target_state)
1333                            // so this warm-hit path avoids an O(configs) rescan.
1334                            has_semantic_context: state.has_semantic_context_for_alt,
1335                            diagnostic: None,
1336                        },
1337                        conflicting_alts,
1338                    }
1339                })
1340            })
1341    }
1342}
1343
1344/// Reports whether closure should skip the loop-entry branch for a
1345/// left-recursive rule under the current caller context.
1346pub(crate) fn can_drop_left_recursive_loop_entry_edge(
1347    atn: &Atn,
1348    state: &AtnState,
1349    context: &PredictionContext,
1350) -> bool {
1351    if state.kind != AtnStateKind::StarLoopEntry
1352        || !state.precedence_rule_decision
1353        || context.is_empty()
1354        || context.has_empty_path()
1355    {
1356        return false;
1357    }
1358    let Some(rule_index) = state.rule_index else {
1359        return false;
1360    };
1361    for index in 0..context.len() {
1362        let Some(return_state_number) = context.return_state(index) else {
1363            return false;
1364        };
1365        let Some(return_state) = atn.state(return_state_number) else {
1366            return false;
1367        };
1368        if return_state.rule_index != Some(rule_index) {
1369            return false;
1370        }
1371    }
1372    let Some(block_end_state_number) = state
1373        .transitions
1374        .first()
1375        .and_then(|transition| atn.state(transition.target()))
1376        .and_then(|decision_start| decision_start.end_state)
1377    else {
1378        return false;
1379    };
1380    for index in 0..context.len() {
1381        let return_state_number = context
1382            .return_state(index)
1383            .expect("return state checked above");
1384        let return_state = atn
1385            .state(return_state_number)
1386            .expect("return state checked above");
1387        if return_state.state_number == block_end_state_number {
1388            continue;
1389        }
1390        if return_state.transitions.len() != 1 || !return_state.transitions[0].is_epsilon() {
1391            return false;
1392        }
1393        let return_target = return_state.transitions[0].target();
1394        if return_state.kind == AtnStateKind::BlockEnd && return_target == state.state_number {
1395            continue;
1396        }
1397        if return_target == block_end_state_number {
1398            continue;
1399        }
1400        let Some(return_target_state) = atn.state(return_target) else {
1401            return false;
1402        };
1403        if return_target_state.kind == AtnStateKind::BlockEnd
1404            && return_target_state.transitions.len() == 1
1405            && return_target_state.transitions[0].is_epsilon()
1406            && return_target_state.transitions[0].target() == state.state_number
1407        {
1408            continue;
1409        }
1410        return false;
1411    }
1412    true
1413}
1414
1415fn configs_have_semantic_context_for_alt(configs: &AtnConfigSet, alt: usize) -> bool {
1416    configs
1417        .configs()
1418        .iter()
1419        .any(|config| config.alt == alt && !config.semantic_context.is_none())
1420}
1421
1422#[derive(Clone, Debug, Eq, PartialEq)]
1423pub enum ParserAtnSimulatorError {
1424    MissingAtnState(usize),
1425    MissingDfaState(usize),
1426    NoViableAlt { symbol: i32, index: usize },
1427    PredictionRequiresMoreLookahead,
1428    UnknownDecision(usize),
1429}
1430
1431#[cfg(test)]
1432mod tests {
1433    use super::*;
1434    use crate::atn::{AtnStateKind, AtnType};
1435
1436    #[test]
1437    fn union_decision_dfa_preserves_disjoint_coverage() {
1438        fn configs(atn_state: usize) -> AtnConfigSet {
1439            let mut set = AtnConfigSet::new();
1440            set.add(AtnConfig::new(atn_state, 1, PredictionContext::empty()));
1441            set
1442        }
1443        fn state(atn_state: usize) -> DfaState {
1444            DfaState::new(configs(atn_state))
1445        }
1446
1447        // Two DFAs that evolved independently from the same grammar: equal
1448        // state/edge counts, but disjoint transitions and different state
1449        // numbering for the shared successor.
1450        let mut shared = Dfa::with_max_token_type(0, 0, 8);
1451        let shared_root = shared.add_state(state(10));
1452        let shared_a = shared.add_state(state(11));
1453        shared
1454            .state_mut(shared_root)
1455            .expect("shared root")
1456            .add_edge(1, shared_a);
1457        shared.set_start_state(shared_root);
1458
1459        let mut local = Dfa::with_max_token_type(0, 0, 8);
1460        let local_b = local.add_state(state(12));
1461        let local_root = local.add_state(state(10));
1462        local
1463            .state_mut(local_root)
1464            .expect("local root")
1465            .add_edge(2, local_b);
1466        local.set_precedence_start_state(3, local_root);
1467
1468        union_decision_dfa(&mut shared, local);
1469
1470        // The root (same config set) gained local's edge without losing its
1471        // own, with the target re-keyed into shared numbering.
1472        let root = shared.state(shared_root).expect("root");
1473        assert_eq!(root.edge(1), Some(shared_a));
1474        let merged_b = shared
1475            .state_number_for_configs(&configs(12))
1476            .expect("local-only state adopted");
1477        assert_eq!(root.edge(2), Some(merged_b));
1478        assert_eq!(shared.states().len(), 3);
1479        // Start-state gaps fill from local; incumbents are kept.
1480        assert_eq!(shared.start_state(), Some(shared_root));
1481        assert_eq!(shared.precedence_start_state(3), Some(shared_root));
1482    }
1483
1484    #[test]
1485    fn adaptive_predict_reuses_dense_dfa_edges() {
1486        let atn = two_token_decision_atn();
1487        let mut simulator = ParserAtnSimulator::new(&atn);
1488
1489        assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
1490        assert_eq!(simulator.adaptive_predict(0, [1, 3]), Ok(2));
1491
1492        let dfa = &simulator.decision_dfas()[0];
1493        let start = dfa.start_state().expect("start state");
1494        let after_first = dfa.state(start).and_then(|state| state.edge(1));
1495        assert!(after_first.is_some());
1496    }
1497
1498    #[test]
1499    fn shared_simulator_reuses_learned_dfa_states() {
1500        let atn = Box::leak(Box::new(two_token_decision_atn()));
1501        let learned_states = {
1502            let mut simulator = ParserAtnSimulator::new_shared(atn);
1503            assert_eq!(simulator.adaptive_predict(0, [1, 2]), Ok(1));
1504            simulator.decision_dfas()[0].states().len()
1505        };
1506
1507        let simulator = ParserAtnSimulator::new_shared(atn);
1508        assert_eq!(simulator.decision_dfas()[0].states().len(), learned_states);
1509    }
1510
1511    #[test]
1512    fn adaptive_predict_reports_no_viable_alt() {
1513        let atn = two_token_decision_atn();
1514        let mut simulator = ParserAtnSimulator::new(&atn);
1515
1516        assert_eq!(
1517            simulator.adaptive_predict(0, [4]),
1518            Err(ParserAtnSimulatorError::NoViableAlt {
1519                symbol: 4,
1520                index: 0
1521            })
1522        );
1523    }
1524
1525    #[test]
1526    fn adaptive_predict_marks_sll_conflict_for_full_context() {
1527        let atn = ambiguous_single_token_decision_atn();
1528        let mut simulator = ParserAtnSimulator::new(&atn);
1529
1530        assert_eq!(simulator.adaptive_predict(0, [1]), Ok(1));
1531        let prediction = simulator
1532            .adaptive_predict_info_with_precedence(0, 0, [1])
1533            .expect("prediction");
1534        assert_eq!(
1535            prediction,
1536            ParserAtnPrediction {
1537                alt: 1,
1538                requires_full_context: true,
1539                has_semantic_context: false,
1540                diagnostic: Some(ParserAtnPredictionDiagnostic {
1541                    kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
1542                    start_index: 0,
1543                    sll_stop_index: 0,
1544                    ll_stop_index: 0,
1545                    conflicting_alts: vec![1, 2],
1546                }),
1547            }
1548        );
1549
1550        let dfa = &simulator.decision_dfas()[0];
1551        let start = dfa.start_state().expect("start state");
1552        let target = dfa
1553            .state(start)
1554            .and_then(|state| state.edge(1))
1555            .expect("edge for token 1");
1556        let state = dfa.state(target).expect("target state");
1557        assert!(state.is_accept_state);
1558        assert!(state.requires_full_context);
1559        assert_eq!(state.prediction, Some(1));
1560    }
1561
1562    #[test]
1563    fn adaptive_predict_keeps_rule_stop_configs_at_eof() {
1564        let atn = optional_token_decision_atn();
1565        let mut simulator = ParserAtnSimulator::new(&atn);
1566
1567        assert_eq!(simulator.adaptive_predict(0, [TOKEN_EOF]), Ok(2));
1568    }
1569
1570    #[test]
1571    fn adaptive_predict_treats_repeated_eof_as_epsilon_after_first_eof() {
1572        let atn = multiple_eof_decision_atn();
1573        let mut simulator = ParserAtnSimulator::new(&atn);
1574
1575        assert_eq!(simulator.adaptive_predict(0, [1, TOKEN_EOF]), Ok(1));
1576    }
1577
1578    #[test]
1579    fn adaptive_predict_uses_finished_entry_rule_alt_on_error_edge() {
1580        let atn = prefix_alt_decision_atn();
1581        let mut simulator = ParserAtnSimulator::new(&atn);
1582
1583        assert_eq!(simulator.adaptive_predict(0, [1, 3]), Ok(1));
1584    }
1585
1586    #[test]
1587    fn adaptive_predict_uses_precedence_dfa_start_states() {
1588        let mut atn = two_token_decision_atn();
1589        atn.state_mut(1)
1590            .expect("decision state")
1591            .precedence_rule_decision = true;
1592        let mut simulator = ParserAtnSimulator::new(&atn);
1593
1594        assert_eq!(
1595            simulator.adaptive_predict_with_precedence(0, 3, [1, 2]),
1596            Ok(1)
1597        );
1598        assert_eq!(
1599            simulator.adaptive_predict_with_precedence(0, 7, [1, 3]),
1600            Ok(2)
1601        );
1602
1603        let dfa = &simulator.decision_dfas()[0];
1604        assert!(dfa.is_precedence_dfa());
1605        assert!(dfa.precedence_start_state(3).is_some());
1606        assert!(dfa.precedence_start_state(7).is_some());
1607    }
1608
1609    #[test]
1610    fn adaptive_predict_stream_restores_input_position() {
1611        let atn = two_token_decision_atn();
1612        let mut simulator = ParserAtnSimulator::new(&atn);
1613        let mut input = VecIntStream::new(vec![1, 3, TOKEN_EOF]);
1614
1615        assert_eq!(simulator.adaptive_predict_stream(0, &mut input), Ok(2));
1616        assert_eq!(input.index(), 0);
1617        assert_eq!(input.la(1), 1);
1618    }
1619
1620    #[test]
1621    fn adaptive_predict_stream_retries_full_context_conflict() {
1622        let atn = ambiguous_single_token_decision_atn();
1623        let mut simulator = ParserAtnSimulator::new(&atn);
1624        let mut input = VecIntStream::new(vec![1, TOKEN_EOF]);
1625
1626        let prediction = simulator
1627            .adaptive_predict_stream_info_with_precedence(0, 0, &mut input)
1628            .expect("prediction");
1629
1630        assert_eq!(
1631            prediction,
1632            ParserAtnPrediction {
1633                alt: 1,
1634                requires_full_context: true,
1635                has_semantic_context: false,
1636                diagnostic: Some(ParserAtnPredictionDiagnostic {
1637                    kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
1638                    start_index: 0,
1639                    sll_stop_index: 0,
1640                    ll_stop_index: 0,
1641                    conflicting_alts: vec![1, 2],
1642                }),
1643            }
1644        );
1645        assert_eq!(input.index(), 0);
1646    }
1647
1648    #[test]
1649    fn context_prediction_reports_context_sensitivity_for_dfa_conflict() {
1650        let atn = two_token_decision_atn();
1651        let mut simulator = ParserAtnSimulator::new(&atn);
1652        let empty = PredictionContext::empty();
1653        let mut start_configs = AtnConfigSet::new();
1654        start_configs.add(AtnConfig::new(2, 1, Rc::clone(&empty)));
1655        let start = simulator.decision_to_dfa[0].add_state(DfaState::new(start_configs));
1656        simulator.decision_to_dfa[0].set_start_state(start);
1657
1658        let mut accept_configs = AtnConfigSet::new();
1659        accept_configs.add(
1660            AtnConfig::new(3, 1, Rc::clone(&empty)).with_semantic_context(
1661                SemanticContext::Predicate {
1662                    rule_index: 0,
1663                    pred_index: 0,
1664                    context_dependent: false,
1665                },
1666            ),
1667        );
1668        let mut accept_state = DfaState::new(accept_configs);
1669        accept_state.mark_accept(1);
1670        accept_state.requires_full_context = true;
1671        accept_state.conflicting_alts = vec![1, 2];
1672        let accept = simulator.decision_to_dfa[0].add_state(accept_state);
1673        simulator.decision_to_dfa[0]
1674            .state_mut(start)
1675            .expect("start state")
1676            .add_edge(1, accept);
1677
1678        let mut input = VecIntStream::new(vec![1, 3, TOKEN_EOF]);
1679        let prediction = simulator
1680            .adaptive_predict_stream_info_with_context(0, 0, &mut input, &empty)
1681            .expect("prediction");
1682
1683        assert_eq!(
1684            prediction,
1685            ParserAtnPrediction {
1686                alt: 2,
1687                requires_full_context: true,
1688                has_semantic_context: false,
1689                diagnostic: Some(ParserAtnPredictionDiagnostic {
1690                    kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
1691                    start_index: 0,
1692                    sll_stop_index: 0,
1693                    ll_stop_index: 1,
1694                    conflicting_alts: vec![1, 2],
1695                }),
1696            }
1697        );
1698        assert_eq!(input.index(), 0);
1699    }
1700
1701    #[test]
1702    fn full_context_reach_prefers_longer_match_over_skipped_stop_state() {
1703        let atn = prefix_alt_decision_atn();
1704        let simulator = ParserAtnSimulator::new(&atn);
1705        let empty = PredictionContext::empty();
1706        let mut configs = AtnConfigSet::new_full_context(true);
1707        configs.add(AtnConfig::new(2, 1, Rc::clone(&empty)));
1708        configs.add(AtnConfig::new(1, 2, empty));
1709        let mut merge_cache = PredictionContextMergeCache::new();
1710
1711        let reach = simulator.compute_reach_set(&configs, 2, true, 0, &mut merge_cache);
1712
1713        assert_eq!(reach.alts(), std::iter::once(2).collect());
1714        assert!(simulator.configs_all_reached_rule_stop(&reach));
1715    }
1716
1717    #[test]
1718    fn sll_closure_follows_empty_context_rule_stop_exits() {
1719        let mut atn = Atn::new(AtnType::Parser, 1);
1720        add_state(&mut atn, 0, AtnStateKind::RuleStop);
1721        add_state(&mut atn, 1, AtnStateKind::Basic);
1722        add_state(&mut atn, 2, AtnStateKind::Basic);
1723        atn.state_mut(0)
1724            .expect("state 0")
1725            .add_transition(Transition::Epsilon { target: 1 });
1726        atn.state_mut(1)
1727            .expect("state 1")
1728            .add_transition(Transition::Atom {
1729                target: 2,
1730                label: 1,
1731            });
1732
1733        let simulator = ParserAtnSimulator::new(&atn);
1734        let mut configs = AtnConfigSet::new_full_context(false);
1735        let mut merge_cache = PredictionContextMergeCache::new();
1736        let mut scratch = ClosureScratch::default();
1737        simulator.closure(
1738            AtnConfig::new(0, 2, PredictionContext::empty()),
1739            &mut configs,
1740            &mut merge_cache,
1741            &mut scratch,
1742            ClosureParams {
1743                precedence: 0,
1744                collect_predicates: true,
1745                treat_eof_as_epsilon: false,
1746            },
1747        );
1748
1749        assert_eq!(configs.len(), 1);
1750        let config = &configs.configs()[0];
1751        assert_eq!(config.state, 1);
1752        assert_eq!(config.alt, 2);
1753        assert_eq!(config.reaches_into_outer_context, 1);
1754    }
1755
1756    #[test]
1757    fn precedence_contexts_are_collected_only_for_start_closure() {
1758        let mut atn = Atn::new(AtnType::Parser, 1);
1759        add_state(&mut atn, 0, AtnStateKind::Basic);
1760        add_state(&mut atn, 1, AtnStateKind::Basic);
1761        let simulator = ParserAtnSimulator::new(&atn);
1762        let transition = Transition::Precedence {
1763            target: 1,
1764            precedence: 2,
1765        };
1766        let config = AtnConfig::new(0, 1, PredictionContext::empty());
1767
1768        let sll_start = simulator
1769            .epsilon_target_config(&config, &transition, 1, true, false)
1770            .expect("sll start transition");
1771        assert!(matches!(
1772            sll_start.semantic_context,
1773            SemanticContext::Precedence { precedence: 2 }
1774        ));
1775
1776        let full_context_start = simulator
1777            .epsilon_target_config(&config, &transition, 1, true, true)
1778            .expect("full-context start transition");
1779        assert!(full_context_start.semantic_context.is_none());
1780
1781        let reach = simulator
1782            .epsilon_target_config(&config, &transition, 3, false, false)
1783            .expect("reach transition");
1784        assert!(reach.semantic_context.is_none());
1785
1786        assert!(
1787            simulator
1788                .epsilon_target_config(&config, &transition, 3, true, false)
1789                .is_none()
1790        );
1791    }
1792
1793    #[test]
1794    fn closure_stops_collecting_predicates_after_action_edge() {
1795        // ANTLR's `closure_` sets
1796        // `continueCollecting = collectPredicates && !ActionTransition`, so a
1797        // predicate reached *after* an action edge is NOT folded into the
1798        // config's semantic context — it is deferred to parse time (the
1799        // "action hides predicates" rule). Build `0 -Action-> 1 -Pred-> 2` and
1800        // assert the closure config carries NO semantic context.
1801        let mut atn = Atn::new(AtnType::Parser, 1);
1802        add_state(&mut atn, 0, AtnStateKind::Basic);
1803        add_state(&mut atn, 1, AtnStateKind::Basic);
1804        add_state(&mut atn, 2, AtnStateKind::Basic);
1805        add_state(&mut atn, 3, AtnStateKind::Basic);
1806        atn.state_mut(0)
1807            .expect("state 0")
1808            .add_transition(Transition::Action {
1809                target: 1,
1810                rule_index: 0,
1811                action_index: Some(0),
1812                context_dependent: false,
1813            });
1814        atn.state_mut(1)
1815            .expect("state 1")
1816            .add_transition(Transition::Predicate {
1817                target: 2,
1818                rule_index: 0,
1819                pred_index: 0,
1820                context_dependent: false,
1821            });
1822        atn.state_mut(2)
1823            .expect("state 2")
1824            .add_transition(Transition::Atom {
1825                target: 3,
1826                label: 1,
1827            });
1828
1829        let simulator = ParserAtnSimulator::new(&atn);
1830        let mut configs = AtnConfigSet::new();
1831        let mut merge_cache = PredictionContextMergeCache::new();
1832        let mut scratch = ClosureScratch::default();
1833        simulator.closure(
1834            AtnConfig::new(0, 1, PredictionContext::empty()),
1835            &mut configs,
1836            &mut merge_cache,
1837            &mut scratch,
1838            ClosureParams {
1839                precedence: 0,
1840                collect_predicates: true,
1841                treat_eof_as_epsilon: false,
1842            },
1843        );
1844
1845        // The config that stops at state 2 (post-predicate, awaiting the atom)
1846        // must NOT carry the predicate — the action edge turned collection off.
1847        let at_two = configs
1848            .configs()
1849            .iter()
1850            .find(|config| config.state == 2)
1851            .expect("config at state 2");
1852        assert!(
1853            at_two.semantic_context.is_none(),
1854            "predicate after an action edge must not be collected during prediction"
1855        );
1856
1857        // Control: the SAME predicate reached WITHOUT an intervening action edge
1858        // IS collected (so the assertion above is about the action edge, not a
1859        // blanket failure to collect predicates).
1860        let direct = simulator
1861            .epsilon_target_config(
1862                &AtnConfig::new(1, 1, PredictionContext::empty()),
1863                &Transition::Predicate {
1864                    target: 2,
1865                    rule_index: 0,
1866                    pred_index: 0,
1867                    context_dependent: false,
1868                },
1869                0,
1870                true,
1871                false,
1872            )
1873            .expect("predicate transition");
1874        assert!(matches!(
1875            direct.semantic_context,
1876            SemanticContext::Predicate { pred_index: 0, .. }
1877        ));
1878    }
1879
1880    #[test]
1881    fn reach_set_skips_closure_for_unique_intermediate_alt() {
1882        let mut atn = Atn::new(AtnType::Parser, 1);
1883        add_state(&mut atn, 0, AtnStateKind::Basic);
1884        add_state(&mut atn, 1, AtnStateKind::Basic);
1885        add_state(&mut atn, 2, AtnStateKind::Basic);
1886        atn.state_mut(0)
1887            .expect("state 0")
1888            .add_transition(Transition::Atom {
1889                target: 1,
1890                label: 7,
1891            });
1892        atn.state_mut(1)
1893            .expect("state 1")
1894            .add_transition(Transition::Epsilon { target: 2 });
1895
1896        let simulator = ParserAtnSimulator::new(&atn);
1897        let empty = PredictionContext::empty();
1898        let mut configs = AtnConfigSet::new_full_context(false);
1899        configs.add(AtnConfig::new(0, 1, empty));
1900        let mut merge_cache = PredictionContextMergeCache::new();
1901
1902        let reach = simulator.compute_reach_set(&configs, 7, false, 0, &mut merge_cache);
1903
1904        assert_eq!(reach.len(), 1);
1905        assert_eq!(reach.configs()[0].state, 1);
1906    }
1907
1908    #[test]
1909    fn semantic_context_flag_is_scoped_to_predicted_alt() {
1910        let empty = PredictionContext::empty();
1911        let mut configs = AtnConfigSet::new();
1912        configs.add(AtnConfig::new(1, 1, Rc::clone(&empty)));
1913        configs.add(AtnConfig::new(2, 2, empty).with_semantic_context(
1914            SemanticContext::Predicate {
1915                rule_index: 0,
1916                pred_index: 0,
1917                context_dependent: false,
1918            },
1919        ));
1920
1921        assert!(!configs_have_semantic_context_for_alt(&configs, 1));
1922        assert!(configs_have_semantic_context_for_alt(&configs, 2));
1923    }
1924
1925    #[test]
1926    fn adaptive_predict_prefers_non_greedy_exit_before_consuming() {
1927        let atn = non_greedy_optional_exit_first_atn();
1928        let mut simulator = ParserAtnSimulator::new(&atn);
1929
1930        assert_eq!(simulator.adaptive_predict(0, [1, TOKEN_EOF]), Ok(1));
1931    }
1932
1933    #[test]
1934    fn left_recursive_loop_entry_drop_requires_same_rule_return() {
1935        let atn = left_recursive_loop_entry_atn();
1936        let loop_entry = atn.state(1).expect("loop entry");
1937        let same_rule_context = PredictionContext::singleton(PredictionContext::empty(), 4);
1938        let other_rule_context = PredictionContext::singleton(PredictionContext::empty(), 5);
1939
1940        assert!(can_drop_left_recursive_loop_entry_edge(
1941            &atn,
1942            loop_entry,
1943            &same_rule_context
1944        ));
1945        assert!(!can_drop_left_recursive_loop_entry_edge(
1946            &atn,
1947            loop_entry,
1948            &other_rule_context
1949        ));
1950        assert!(!can_drop_left_recursive_loop_entry_edge(
1951            &atn,
1952            loop_entry,
1953            &PredictionContext::empty()
1954        ));
1955    }
1956
1957    fn two_token_decision_atn() -> Atn {
1958        let mut atn = Atn::new(AtnType::Parser, 3);
1959        add_state(&mut atn, 0, AtnStateKind::RuleStart);
1960        add_state(&mut atn, 1, AtnStateKind::BlockStart);
1961        add_state(&mut atn, 2, AtnStateKind::Basic);
1962        add_state(&mut atn, 3, AtnStateKind::Basic);
1963        add_state(&mut atn, 4, AtnStateKind::Basic);
1964        add_state(&mut atn, 5, AtnStateKind::Basic);
1965        add_state(&mut atn, 6, AtnStateKind::BlockEnd);
1966        add_state(&mut atn, 7, AtnStateKind::RuleStop);
1967        atn.set_rule_to_start_state(vec![0]);
1968        atn.set_rule_to_stop_state(vec![7]);
1969        atn.add_decision_state(1);
1970        atn.state_mut(0)
1971            .expect("state 0")
1972            .add_transition(Transition::Epsilon { target: 1 });
1973        atn.state_mut(1)
1974            .expect("state 1")
1975            .add_transition(Transition::Epsilon { target: 2 });
1976        atn.state_mut(1)
1977            .expect("state 1")
1978            .add_transition(Transition::Epsilon { target: 4 });
1979        atn.state_mut(2)
1980            .expect("state 2")
1981            .add_transition(Transition::Atom {
1982                target: 3,
1983                label: 1,
1984            });
1985        atn.state_mut(3)
1986            .expect("state 3")
1987            .add_transition(Transition::Atom {
1988                target: 6,
1989                label: 2,
1990            });
1991        atn.state_mut(4)
1992            .expect("state 4")
1993            .add_transition(Transition::Atom {
1994                target: 5,
1995                label: 1,
1996            });
1997        atn.state_mut(5)
1998            .expect("state 5")
1999            .add_transition(Transition::Atom {
2000                target: 6,
2001                label: 3,
2002            });
2003        atn.state_mut(6)
2004            .expect("state 6")
2005            .add_transition(Transition::Epsilon { target: 7 });
2006        atn
2007    }
2008
2009    fn optional_token_decision_atn() -> Atn {
2010        let mut atn = Atn::new(AtnType::Parser, 1);
2011        add_state(&mut atn, 0, AtnStateKind::RuleStart);
2012        add_state(&mut atn, 1, AtnStateKind::BlockStart);
2013        add_state(&mut atn, 2, AtnStateKind::Basic);
2014        add_state(&mut atn, 3, AtnStateKind::BlockEnd);
2015        add_state(&mut atn, 4, AtnStateKind::RuleStop);
2016        atn.set_rule_to_start_state(vec![0]);
2017        atn.set_rule_to_stop_state(vec![4]);
2018        atn.add_decision_state(1);
2019        atn.state_mut(0)
2020            .expect("state 0")
2021            .add_transition(Transition::Epsilon { target: 1 });
2022        atn.state_mut(1)
2023            .expect("state 1")
2024            .add_transition(Transition::Epsilon { target: 2 });
2025        atn.state_mut(1)
2026            .expect("state 1")
2027            .add_transition(Transition::Epsilon { target: 3 });
2028        atn.state_mut(2)
2029            .expect("state 2")
2030            .add_transition(Transition::Atom {
2031                target: 3,
2032                label: 1,
2033            });
2034        atn.state_mut(3)
2035            .expect("state 3")
2036            .add_transition(Transition::Epsilon { target: 4 });
2037        atn
2038    }
2039
2040    fn non_greedy_optional_exit_first_atn() -> Atn {
2041        let mut atn = Atn::new(AtnType::Parser, 1);
2042        add_state(&mut atn, 0, AtnStateKind::RuleStart);
2043        add_state(&mut atn, 1, AtnStateKind::BlockStart);
2044        add_state(&mut atn, 2, AtnStateKind::BlockEnd);
2045        add_state(&mut atn, 3, AtnStateKind::Basic);
2046        add_state(&mut atn, 4, AtnStateKind::RuleStop);
2047        atn.set_rule_to_start_state(vec![0]);
2048        atn.set_rule_to_stop_state(vec![4]);
2049        atn.add_decision_state(1);
2050        atn.state_mut(1).expect("state 1").non_greedy = true;
2051        atn.state_mut(0)
2052            .expect("state 0")
2053            .add_transition(Transition::Epsilon { target: 1 });
2054        atn.state_mut(1)
2055            .expect("state 1")
2056            .add_transition(Transition::Epsilon { target: 2 });
2057        atn.state_mut(1)
2058            .expect("state 1")
2059            .add_transition(Transition::Epsilon { target: 3 });
2060        atn.state_mut(2)
2061            .expect("state 2")
2062            .add_transition(Transition::Epsilon { target: 4 });
2063        atn.state_mut(3)
2064            .expect("state 3")
2065            .add_transition(Transition::Atom {
2066                target: 4,
2067                label: 1,
2068            });
2069        atn
2070    }
2071
2072    fn ambiguous_single_token_decision_atn() -> Atn {
2073        let mut atn = Atn::new(AtnType::Parser, 1);
2074        add_state(&mut atn, 0, AtnStateKind::RuleStart);
2075        add_state(&mut atn, 1, AtnStateKind::BlockStart);
2076        add_state(&mut atn, 2, AtnStateKind::Basic);
2077        add_state(&mut atn, 3, AtnStateKind::Basic);
2078        add_state(&mut atn, 4, AtnStateKind::Basic);
2079        add_state(&mut atn, 5, AtnStateKind::Basic);
2080        add_state(&mut atn, 6, AtnStateKind::BlockEnd);
2081        add_state(&mut atn, 7, AtnStateKind::RuleStop);
2082        atn.set_rule_to_start_state(vec![0]);
2083        atn.set_rule_to_stop_state(vec![7]);
2084        atn.add_decision_state(1);
2085        atn.state_mut(0)
2086            .expect("state 0")
2087            .add_transition(Transition::Epsilon { target: 1 });
2088        atn.state_mut(1)
2089            .expect("state 1")
2090            .add_transition(Transition::Epsilon { target: 2 });
2091        atn.state_mut(1)
2092            .expect("state 1")
2093            .add_transition(Transition::Epsilon { target: 4 });
2094        atn.state_mut(2)
2095            .expect("state 2")
2096            .add_transition(Transition::Atom {
2097                target: 3,
2098                label: 1,
2099            });
2100        atn.state_mut(3)
2101            .expect("state 3")
2102            .add_transition(Transition::Epsilon { target: 6 });
2103        atn.state_mut(4)
2104            .expect("state 4")
2105            .add_transition(Transition::Atom {
2106                target: 5,
2107                label: 1,
2108            });
2109        atn.state_mut(5)
2110            .expect("state 5")
2111            .add_transition(Transition::Epsilon { target: 6 });
2112        atn.state_mut(6)
2113            .expect("state 6")
2114            .add_transition(Transition::Epsilon { target: 7 });
2115        atn
2116    }
2117
2118    fn prefix_alt_decision_atn() -> Atn {
2119        let mut atn = Atn::new(AtnType::Parser, 3);
2120        add_state(&mut atn, 0, AtnStateKind::BlockStart);
2121        add_state(&mut atn, 1, AtnStateKind::Basic);
2122        add_state(&mut atn, 2, AtnStateKind::RuleStop);
2123        atn.set_rule_to_start_state(vec![0]);
2124        atn.set_rule_to_stop_state(vec![2]);
2125        atn.add_decision_state(0);
2126        atn.state_mut(0)
2127            .expect("state 0")
2128            .add_transition(Transition::Atom {
2129                target: 2,
2130                label: 1,
2131            });
2132        atn.state_mut(0)
2133            .expect("state 0")
2134            .add_transition(Transition::Atom {
2135                target: 1,
2136                label: 1,
2137            });
2138        atn.state_mut(1)
2139            .expect("state 1")
2140            .add_transition(Transition::Atom {
2141                target: 2,
2142                label: 2,
2143            });
2144        atn
2145    }
2146
2147    fn multiple_eof_decision_atn() -> Atn {
2148        let mut atn = Atn::new(AtnType::Parser, 2);
2149        for state_number in 0..=10 {
2150            let kind = match state_number {
2151                0 => AtnStateKind::RuleStart,
2152                1 => AtnStateKind::BlockStart,
2153                7 => AtnStateKind::BlockEnd,
2154                10 => AtnStateKind::RuleStop,
2155                _ => AtnStateKind::Basic,
2156            };
2157            add_state(&mut atn, state_number, kind);
2158        }
2159        atn.set_rule_to_start_state(vec![0]);
2160        atn.set_rule_to_stop_state(vec![10]);
2161        atn.add_decision_state(1);
2162        atn.state_mut(0)
2163            .expect("state 0")
2164            .add_transition(Transition::Epsilon { target: 1 });
2165        atn.state_mut(1)
2166            .expect("state 1")
2167            .add_transition(Transition::Epsilon { target: 2 });
2168        atn.state_mut(1)
2169            .expect("state 1")
2170            .add_transition(Transition::Epsilon { target: 4 });
2171        atn.state_mut(2)
2172            .expect("state 2")
2173            .add_transition(Transition::Atom {
2174                target: 3,
2175                label: 1,
2176            });
2177        atn.state_mut(3)
2178            .expect("state 3")
2179            .add_transition(Transition::Epsilon { target: 7 });
2180        atn.state_mut(4)
2181            .expect("state 4")
2182            .add_transition(Transition::Atom {
2183                target: 5,
2184                label: 1,
2185            });
2186        atn.state_mut(5)
2187            .expect("state 5")
2188            .add_transition(Transition::Atom {
2189                target: 6,
2190                label: 2,
2191            });
2192        atn.state_mut(6)
2193            .expect("state 6")
2194            .add_transition(Transition::Epsilon { target: 7 });
2195        atn.state_mut(7)
2196            .expect("state 7")
2197            .add_transition(Transition::Epsilon { target: 8 });
2198        atn.state_mut(8)
2199            .expect("state 8")
2200            .add_transition(Transition::Atom {
2201                target: 9,
2202                label: TOKEN_EOF,
2203            });
2204        atn.state_mut(9)
2205            .expect("state 9")
2206            .add_transition(Transition::Atom {
2207                target: 10,
2208                label: TOKEN_EOF,
2209            });
2210        atn
2211    }
2212
2213    fn left_recursive_loop_entry_atn() -> Atn {
2214        let mut atn = Atn::new(AtnType::Parser, 1);
2215        add_state(&mut atn, 0, AtnStateKind::RuleStart);
2216        add_state(&mut atn, 1, AtnStateKind::StarLoopEntry);
2217        add_state(&mut atn, 2, AtnStateKind::BlockStart);
2218        add_state(&mut atn, 3, AtnStateKind::BlockEnd);
2219        add_state(&mut atn, 4, AtnStateKind::Basic);
2220        atn.add_state(AtnState::new(5, AtnStateKind::Basic).with_rule_index(1));
2221        add_state(&mut atn, 6, AtnStateKind::LoopEnd);
2222        add_state(&mut atn, 7, AtnStateKind::RuleStop);
2223        atn.state_mut(1)
2224            .expect("loop entry")
2225            .precedence_rule_decision = true;
2226        atn.state_mut(2).expect("block start").end_state = Some(3);
2227        atn.state_mut(1)
2228            .expect("loop entry")
2229            .add_transition(Transition::Epsilon { target: 2 });
2230        atn.state_mut(1)
2231            .expect("loop entry")
2232            .add_transition(Transition::Epsilon { target: 6 });
2233        atn.state_mut(4)
2234            .expect("same-rule return")
2235            .add_transition(Transition::Epsilon { target: 3 });
2236        atn.state_mut(5)
2237            .expect("other-rule return")
2238            .add_transition(Transition::Epsilon { target: 3 });
2239        atn
2240    }
2241
2242    fn add_state(atn: &mut Atn, state_number: usize, kind: AtnStateKind) {
2243        atn.add_state(AtnState::new(state_number, kind).with_rule_index(0));
2244    }
2245
2246    #[derive(Debug)]
2247    struct VecIntStream {
2248        symbols: Vec<i32>,
2249        index: usize,
2250    }
2251
2252    impl VecIntStream {
2253        fn new(symbols: Vec<i32>) -> Self {
2254            Self { symbols, index: 0 }
2255        }
2256    }
2257
2258    impl IntStream for VecIntStream {
2259        fn consume(&mut self) {
2260            if self.la(1) != TOKEN_EOF {
2261                self.index += 1;
2262            }
2263        }
2264
2265        fn la(&mut self, offset: isize) -> i32 {
2266            if offset <= 0 {
2267                return 0;
2268            }
2269            let offset = offset.cast_unsigned() - 1;
2270            self.symbols
2271                .get(self.index + offset)
2272                .copied()
2273                .unwrap_or(TOKEN_EOF)
2274        }
2275
2276        fn index(&self) -> usize {
2277            self.index
2278        }
2279
2280        fn seek(&mut self, index: usize) {
2281            self.index = index;
2282        }
2283
2284        fn size(&self) -> usize {
2285            self.symbols.len()
2286        }
2287    }
2288}