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