1use std::cell::RefCell;
7use std::cmp::Ordering;
8#[allow(clippy::disallowed_types)]
9use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
10use std::hash::{BuildHasherDefault, Hash, Hasher};
11use std::rc::Rc;
12
13#[derive(Clone, Copy, Default)]
20struct FxHasher {
21 hash: u64,
22}
23
24const FX_ROT: u32 = 5;
25const FX_SEED: u64 = 0x51_7c_c1_b7_27_22_0a_95;
26
27impl Hasher for FxHasher {
28 #[inline]
36 fn write(&mut self, mut bytes: &[u8]) {
37 while bytes.len() >= 8 {
38 let (head, rest) = bytes.split_at(8);
39 let word = u64::from_le_bytes(head.try_into().expect("8-byte chunk"));
40 self.hash = (self.hash.rotate_left(FX_ROT) ^ word).wrapping_mul(FX_SEED);
41 bytes = rest;
42 }
43 for byte in bytes {
44 self.hash = (self.hash.rotate_left(FX_ROT) ^ u64::from(*byte)).wrapping_mul(FX_SEED);
45 }
46 }
47 #[inline]
48 fn write_u64(&mut self, value: u64) {
49 self.hash = (self.hash.rotate_left(FX_ROT) ^ value).wrapping_mul(FX_SEED);
50 }
51 #[inline]
52 fn write_usize(&mut self, value: usize) {
53 self.write_u64(value as u64);
54 }
55 #[inline]
56 fn write_u32(&mut self, value: u32) {
57 self.write_u64(u64::from(value));
58 }
59 #[inline]
60 fn write_i32(&mut self, value: i32) {
61 self.write_u64(u64::from(i32::cast_unsigned(value)));
62 }
63 #[inline]
64 fn finish(&self) -> u64 {
65 self.hash
66 }
67}
68
69type FxBuildHasher = BuildHasherDefault<FxHasher>;
70#[allow(clippy::disallowed_types)]
71type FxHashMap<K, V> = HashMap<K, V, FxBuildHasher>;
72#[allow(clippy::disallowed_types)]
73type FxHashSet<K> = HashSet<K, FxBuildHasher>;
74
75use crate::atn::AtnStateKind;
76use crate::atn::parser::{
77 ParserAtnPrediction, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
78};
79use crate::atn::parser_atn::{
80 ParserAtn as Atn, ParserAtnState as AtnState, ParserIntervalSet, ParserTransition,
81 ParserTransitionData as Transition, ParserTransitionKind,
82};
83#[cfg(test)]
84use crate::atn::parser_atn::{ParserAtnBuilder, ParserTransitionSpec};
85use crate::char_stream::CharStream;
86use crate::errors::AntlrError;
87use crate::int_stream::IntStream;
88use crate::lexer::{LexerCustomAction, LexerLifecycleCtx, LexerSemCtx};
89use crate::recognizer::{Recognizer, RecognizerData};
90use crate::semir::{self, AStmt, ArithOp, CmpOp, ExprId, HookId, PExpr, SemIr, StmtId};
91use crate::token::{
92 TOKEN_EOF, Token, TokenId, TokenSource, TokenSourceError, TokenSpec, TokenStore, TokenView,
93};
94use crate::token_stream::CommonTokenStream;
95use crate::tree::{
96 Node, NodeId, ParseTreeCheckpoint, ParseTreeStorage, ParsedFile, ParserRuleContext,
97};
98use crate::vocabulary::Vocabulary;
99
100type ParseTree = NodeId;
101
102const RECOGNITION_DEPTH_LIMIT: usize = 32_768;
106const ADAPTIVE_DIRECT_STEP_LIMIT: usize = RECOGNITION_DEPTH_LIMIT;
110const CLEAN_MEMO_PROBE_LIMIT: usize = 4096;
114const CLEAN_MEMO_REPEAT_LIMIT: usize = 8;
115const CLEAN_MEMO_REPROBE_INTERVAL: usize = 262_144;
118const FAST_RECOGNIZE_VISITING_CAPACITY: usize = 256;
119const FAST_RECOGNIZE_MIN_MEMO_CAPACITY: usize = 256;
120const FAST_RECOGNIZE_MAX_MEMO_CAPACITY: usize = 524_288;
121const FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY: usize = 65_536;
122
123#[derive(Clone, Copy, Debug, Eq, PartialEq)]
124enum CleanMemoMode {
125 Probe,
126 Promote,
127 Sparse,
128}
129
130fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
131 intervals
132 .iter()
133 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
134}
135
136fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
137 let mut symbols = BTreeSet::new();
138 for (start, stop) in intervals {
139 symbols.extend(*start..=*stop);
140 }
141 symbols
142}
143
144fn interval_complement_symbols(
145 intervals: &[(i32, i32)],
146 min_vocabulary: i32,
147 max_vocabulary: i32,
148) -> BTreeSet<i32> {
149 (min_vocabulary..=max_vocabulary)
150 .filter(|symbol| !interval_set_contains(intervals, *symbol))
151 .collect()
152}
153
154#[cfg(feature = "perf-counters")]
155mod perf_counters {
156 use std::cell::Cell;
157 thread_local! {
158 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
159 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
160 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
161 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
162 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
163 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
164 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
165 pub(super) static OUTCOME_DEDUPE_INPUTS: Cell<u64> = const { Cell::new(0) };
166 pub(super) static OUTCOME_DEDUPE_REMOVED: Cell<u64> = const { Cell::new(0) };
167 pub(super) static OUTCOME_DEDUPE_INLINE: Cell<u64> = const { Cell::new(0) };
168 pub(super) static OUTCOME_DEDUPE_DENSE: Cell<u64> = const { Cell::new(0) };
169 pub(super) static OUTCOME_DEDUPE_SPARSE: Cell<u64> = const { Cell::new(0) };
170 pub(super) static OUTCOME_DEDUPE_DENSE_WORDS: Cell<u64> = const { Cell::new(0) };
171 }
172 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
173 c.with(|v| v.set(v.get() + n));
174 }
175 thread_local! {
176 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
177 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
178 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
179 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
180 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
181 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
182 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
183 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
184 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
185 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
186 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
187 }
188 pub(super) fn snapshot() -> [(&'static str, u64); 24] {
189 [
190 ("rfs_calls", RFS_CALLS.with(Cell::get)),
191 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
192 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
193 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
194 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
195 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
196 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
197 (
198 "outcome_dedupe_inputs",
199 OUTCOME_DEDUPE_INPUTS.with(Cell::get),
200 ),
201 (
202 "outcome_dedupe_removed",
203 OUTCOME_DEDUPE_REMOVED.with(Cell::get),
204 ),
205 (
206 "outcome_dedupe_inline",
207 OUTCOME_DEDUPE_INLINE.with(Cell::get),
208 ),
209 ("outcome_dedupe_dense", OUTCOME_DEDUPE_DENSE.with(Cell::get)),
210 (
211 "outcome_dedupe_sparse",
212 OUTCOME_DEDUPE_SPARSE.with(Cell::get),
213 ),
214 (
215 "outcome_dedupe_dense_words",
216 OUTCOME_DEDUPE_DENSE_WORDS.with(Cell::get),
217 ),
218 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
219 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
220 (
221 "atom_range_transitions",
222 ATOM_RANGE_TRANSITIONS.with(Cell::get),
223 ),
224 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
225 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
226 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
227 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
228 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
229 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
230 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
231 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
232 ]
233 }
234 pub fn reset() {
235 RFS_CALLS.with(|c| c.set(0));
236 RFS_MEMO_HITS.with(|c| c.set(0));
237 RFS_MEMO_MISSES.with(|c| c.set(0));
238 RFS_VISITING_CYCLE.with(|c| c.set(0));
239 MEMO_INSERTED.with(|c| c.set(0));
240 OUTCOMES_PUSHED.with(|c| c.set(0));
241 OUTCOMES_CLONED.with(|c| c.set(0));
242 OUTCOME_DEDUPE_INPUTS.with(|c| c.set(0));
243 OUTCOME_DEDUPE_REMOVED.with(|c| c.set(0));
244 OUTCOME_DEDUPE_INLINE.with(|c| c.set(0));
245 OUTCOME_DEDUPE_DENSE.with(|c| c.set(0));
246 OUTCOME_DEDUPE_SPARSE.with(|c| c.set(0));
247 OUTCOME_DEDUPE_DENSE_WORDS.with(|c| c.set(0));
248 EPSILON_TRANSITIONS.with(|c| c.set(0));
249 RULE_TRANSITIONS.with(|c| c.set(0));
250 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
251 SINGLE_TRANS_BODY.with(|c| c.set(0));
252 MULTI_TRANS_BODY.with(|c| c.set(0));
253 SINGLE_TRANS_RULE.with(|c| c.set(0));
254 SINGLE_TRANS_ATOM.with(|c| c.set(0));
255 SINGLE_TRANS_OTHER.with(|c| c.set(0));
256 OUTCOMES_RETURN_0.with(|c| c.set(0));
257 OUTCOMES_RETURN_1.with(|c| c.set(0));
258 OUTCOMES_RETURN_N.with(|c| c.set(0));
259 }
260 pub fn dump() {
261 for (name, value) in snapshot() {
262 #[allow(clippy::print_stderr)]
263 {
264 eprintln!("perf {name}={value}");
265 }
266 }
267 }
268}
269
270#[cfg(feature = "perf-counters")]
271pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
272const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
277#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
286pub struct ParserAction {
287 source_state: usize,
288 rule_index: usize,
289 start_index: usize,
290 stop_index: Option<usize>,
291 rule_init: bool,
292 expected_state: Option<usize>,
293}
294
295impl ParserAction {
296 pub const fn new(
298 source_state: usize,
299 rule_index: usize,
300 start_index: usize,
301 stop_index: Option<usize>,
302 ) -> Self {
303 Self {
304 source_state,
305 rule_index,
306 start_index,
307 stop_index,
308 rule_init: false,
309 expected_state: None,
310 }
311 }
312
313 pub const fn new_rule_init(
315 rule_index: usize,
316 start_index: usize,
317 expected_state: Option<usize>,
318 ) -> Self {
319 Self {
320 source_state: usize::MAX,
321 rule_index,
322 start_index,
323 stop_index: None,
324 rule_init: true,
325 expected_state,
326 }
327 }
328
329 pub const fn source_state(&self) -> usize {
331 self.source_state
332 }
333
334 pub const fn rule_index(&self) -> usize {
336 self.rule_index
337 }
338
339 pub const fn start_index(&self) -> usize {
341 self.start_index
342 }
343
344 pub const fn stop_index(&self) -> Option<usize> {
346 self.stop_index
347 }
348
349 pub const fn is_rule_init(&self) -> bool {
351 self.rule_init
352 }
353
354 pub const fn expected_state(&self) -> Option<usize> {
356 self.expected_state
357 }
358}
359
360pub struct ParserSemCtx<'a, S>
368where
369 S: TokenSource,
370{
371 input: &'a mut CommonTokenStream<S>,
372 tree_storage: &'a ParseTreeStorage,
373 rule_index: usize,
374 coordinate_index: usize,
375 rule_name: Option<String>,
376 context: Option<&'a ParserRuleContext>,
377 tree: Option<ParseTree>,
378 local_int_arg: Option<(usize, i64)>,
379 member_values: &'a BTreeMap<usize, i64>,
380 action: Option<ParserAction>,
381}
382
383impl<S> std::fmt::Debug for ParserSemCtx<'_, S>
384where
385 S: TokenSource,
386{
387 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
388 f.debug_struct("ParserSemCtx")
389 .field("rule_index", &self.rule_index)
390 .field("coordinate_index", &self.coordinate_index)
391 .field("rule_name", &self.rule_name)
392 .field("context", &self.context)
393 .field("tree", &self.tree)
394 .field("local_int_arg", &self.local_int_arg)
395 .field("member_values", &self.member_values)
396 .field("action", &self.action)
397 .finish_non_exhaustive()
398 }
399}
400
401impl<'a, S> ParserSemCtx<'a, S>
402where
403 S: TokenSource,
404{
405 #[must_use]
407 pub const fn rule_index(&self) -> usize {
408 self.rule_index
409 }
410
411 #[must_use]
413 pub fn rule_name(&self) -> Option<&str> {
414 self.rule_name.as_deref()
415 }
416
417 #[must_use]
421 pub const fn coordinate_index(&self) -> usize {
422 self.coordinate_index
423 }
424
425 #[must_use]
427 pub fn input_index(&self) -> usize {
428 self.input.index()
429 }
430
431 pub fn la(&mut self, offset: isize) -> i32 {
433 self.input.la(offset)
434 }
435
436 pub fn lt(&self, offset: isize) -> Option<TokenView<'_>> {
438 self.input.lt(offset)
439 }
440
441 pub fn token_text(&self, offset: isize) -> Option<TokenView<'_>> {
443 self.lt(offset)
444 }
445
446 pub fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
453 self.input.get(index)
454 }
455
456 #[must_use]
459 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
460 self.context
461 }
462
463 #[must_use]
465 pub const fn parse_tree_storage(&self) -> &'a ParseTreeStorage {
466 self.tree_storage
467 }
468
469 #[must_use]
471 pub const fn token_store(&self) -> &TokenStore {
472 self.input.token_store()
473 }
474
475 #[must_use]
477 pub const fn tree_id(&self) -> Option<NodeId> {
478 self.tree
479 }
480
481 #[must_use]
484 pub fn tree(&self) -> Option<Node<'_>> {
485 self.tree
486 .and_then(|id| self.tree_storage.node(self.input.token_store(), id))
487 }
488
489 #[must_use]
491 pub fn local_int_arg(&self) -> Option<i64> {
492 self.local_int_arg.map(|(_, value)| value)
493 }
494
495 #[must_use]
497 pub fn member_int(&self, member: usize) -> Option<i64> {
498 self.member_values.get(&member).copied()
499 }
500
501 #[must_use]
504 pub const fn action(&self) -> Option<ParserAction> {
505 self.action
506 }
507
508 pub fn action_text(&self) -> String {
516 let Some(action) = self.action else {
517 return String::new();
518 };
519 let Some(stop) = action.stop_index() else {
520 return String::new();
521 };
522 let stop = if self
523 .input
524 .get(stop)
525 .is_some_and(|token| token.token_type() == TOKEN_EOF)
526 {
527 let Some(previous) = self.input.previous_visible_token_index(stop) else {
528 return String::new();
529 };
530 previous
531 } else {
532 stop
533 };
534 self.input.text(action.start_index(), stop)
535 }
536}
537
538pub trait SemanticHooks {
545 const ENABLES_LEXER_LIFECYCLE: bool = true;
552
553 fn observes_parser_predicates(&self) -> bool {
558 true
559 }
560
561 fn sempred<S>(
562 &mut self,
563 ctx: &mut ParserSemCtx<'_, S>,
564 rule_index: usize,
565 pred_index: usize,
566 ) -> Option<bool>
567 where
568 S: TokenSource,
569 {
570 let _ = (ctx, rule_index, pred_index);
571 None
572 }
573
574 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
575 where
576 S: TokenSource,
577 {
578 let _ = (ctx, action);
579 false
580 }
581
582 fn lexer_sempred<I>(
583 &mut self,
584 ctx: &mut LexerSemCtx<'_, I>,
585 rule_index: usize,
586 pred_index: usize,
587 ) -> Option<bool>
588 where
589 I: CharStream,
590 {
591 let _ = (ctx, rule_index, pred_index);
592 None
593 }
594
595 fn lexer_action<I>(&mut self, ctx: &mut LexerSemCtx<'_, I>, action: LexerCustomAction) -> bool
605 where
606 I: CharStream,
607 {
608 let _ = (ctx, action);
609 false
610 }
611
612 fn lexer_reset<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
616 where
617 I: CharStream,
618 {
619 let _ = ctx;
620 }
621
622 fn lexer_before_token<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
628 where
629 I: CharStream,
630 {
631 let _ = ctx;
632 }
633
634 fn lexer_after_accept<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
643 where
644 I: CharStream,
645 {
646 let _ = ctx;
647 }
648
649 fn lexer_token_emitted(&mut self, token: TokenView<'_>) {
656 let _ = token;
657 }
658}
659
660#[derive(Clone, Copy, Debug, Default)]
663pub struct NoSemanticHooks;
664
665impl SemanticHooks for NoSemanticHooks {
666 const ENABLES_LEXER_LIFECYCLE: bool = false;
667
668 fn observes_parser_predicates(&self) -> bool {
669 false
670 }
671}
672
673#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
680pub enum ParserPredicate {
681 True,
682 False,
683 FalseWithMessage {
685 message: &'static str,
686 },
687 Invoke {
690 value: bool,
691 },
692 LookaheadTextEquals {
693 offset: isize,
694 text: &'static str,
695 },
696 LookaheadNotEquals {
697 offset: isize,
698 token_type: i32,
699 },
700 TokenPairAdjacent,
703 ContextChildRuleTextNotEquals {
708 rule_index: usize,
709 text: &'static str,
710 },
711 LocalIntEquals {
714 value: i64,
715 },
716 LocalIntLessOrEqual {
719 value: i64,
720 },
721 MemberModuloEquals {
723 member: usize,
724 modulus: i64,
725 value: i64,
726 equals: bool,
727 },
728 MemberEquals {
730 member: usize,
731 value: i64,
732 equals: bool,
733 },
734}
735
736impl ParserPredicate {
737 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
743 match self {
744 Self::True => ir.expr(PExpr::Bool(true)),
745 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
746 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
747 Self::LookaheadTextEquals { offset, text } => {
748 let token = ir.expr(PExpr::TokenText(offset));
749 let text = ir.intern(text);
750 let text = ir.expr(PExpr::Str(text));
751 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
752 }
753 Self::LookaheadNotEquals { offset, token_type } => {
754 let actual = ir.expr(PExpr::La(offset));
755 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
756 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
757 }
758 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
759 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
760 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
761 let expected = ir.intern(text);
762 let expected = ir.expr(PExpr::Str(expected));
763 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
764 }
765 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
766 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
767 Self::MemberModuloEquals {
768 member,
769 modulus,
770 value,
771 equals,
772 } => {
773 if modulus == 0 {
774 return ir.expr(PExpr::Bool(false));
775 }
776 let member = ir.expr(PExpr::Member(member));
777 let modulus = ir.expr(PExpr::Int(modulus));
778 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
779 let expected = ir.expr(PExpr::Int(value));
780 ir.expr(PExpr::Cmp(
781 if equals { CmpOp::Eq } else { CmpOp::Ne },
782 actual,
783 expected,
784 ))
785 }
786 Self::MemberEquals {
787 member,
788 value,
789 equals,
790 } => {
791 let actual = ir.expr(PExpr::Member(member));
792 let expected = ir.expr(PExpr::Int(value));
793 ir.expr(PExpr::Cmp(
794 if equals { CmpOp::Eq } else { CmpOp::Ne },
795 actual,
796 expected,
797 ))
798 }
799 }
800 }
801
802 #[must_use]
803 pub const fn failure_message(self) -> Option<&'static str> {
804 match self {
805 Self::FalseWithMessage { message } => Some(message),
806 Self::True
807 | Self::False
808 | Self::Invoke { .. }
809 | Self::LookaheadTextEquals { .. }
810 | Self::LookaheadNotEquals { .. }
811 | Self::TokenPairAdjacent
812 | Self::ContextChildRuleTextNotEquals { .. }
813 | Self::LocalIntEquals { .. }
814 | Self::LocalIntLessOrEqual { .. }
815 | Self::MemberModuloEquals { .. }
816 | Self::MemberEquals { .. } => None,
817 }
818 }
819}
820
821fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
822 let local = ir.expr(PExpr::LocalArg);
823 let absent = ir.expr(PExpr::IsNull(local));
824 let expected = ir.expr(PExpr::Int(value));
825 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
826 ir.expr(PExpr::Or([absent, comparison].into()))
827}
828
829#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
842pub enum UnknownSemanticPolicy {
843 #[default]
845 AssumeTrue,
846 AssumeFalse,
848 Error,
851}
852
853fn apply_unknown_predicate_policy(
862 policy: UnknownSemanticPolicy,
863 rule_index: usize,
864 pred_index: usize,
865 hits: &mut Vec<(usize, usize)>,
866) -> bool {
867 match policy {
868 UnknownSemanticPolicy::AssumeTrue => true,
869 UnknownSemanticPolicy::AssumeFalse => false,
870 UnknownSemanticPolicy::Error => {
871 let coordinate = (rule_index, pred_index);
872 if !hits.contains(&coordinate) {
873 hits.push(coordinate);
874 }
875 false
876 }
877 }
878}
879
880#[derive(Clone, Debug, Eq, PartialEq)]
884pub struct ExpectedTokenSet {
885 symbols: BTreeSet<i32>,
886}
887
888impl ExpectedTokenSet {
889 #[must_use]
891 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
892 expected_symbols_display(&self.symbols, vocabulary)
893 }
894}
895
896#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
901pub struct BailErrorStrategy;
902
903impl BailErrorStrategy {
904 #[must_use]
905 pub const fn new() -> Self {
906 Self
907 }
908}
909
910#[derive(Clone, Copy, Debug, Eq, PartialEq)]
912pub enum PredictionMode {
913 Ll,
916 Sll,
919 LlExactAmbigDetection,
921}
922
923#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
929pub struct ParserRuleArg {
930 pub source_state: usize,
932 pub rule_index: usize,
934 pub value: i64,
936 pub inherit_local: bool,
938}
939
940#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
942pub struct ParserMemberAction {
943 pub source_state: usize,
945 pub member: usize,
947 pub delta: i64,
949}
950
951#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
958pub struct ParserReturnAction {
959 pub source_state: usize,
961 pub rule_index: usize,
963 pub name: &'static str,
965 pub value: i64,
967}
968
969impl ParserMemberAction {
970 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
972 let delta = ir.expr(PExpr::Int(self.delta));
973 ParserSemanticAction {
974 source_state: self.source_state,
975 rule_index: usize::MAX,
976 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
977 speculative: true,
978 }
979 }
980}
981
982impl ParserReturnAction {
983 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
985 let name = ir.intern(self.name);
986 let value = ir.expr(PExpr::Int(self.value));
987 ParserSemanticAction {
988 source_state: self.source_state,
989 rule_index: self.rule_index,
990 stmt: ir.stmt(AStmt::SetReturn(name, value)),
991 speculative: false,
992 }
993 }
994}
995
996#[derive(Clone, Copy, Debug, Eq, PartialEq)]
998pub struct ParserSemanticPredicate {
999 pub rule_index: usize,
1001 pub pred_index: usize,
1003 pub expr: ExprId,
1005 pub failure_message: Option<&'static str>,
1007}
1008
1009#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1011pub struct ParserSemanticAction {
1012 pub source_state: usize,
1014 pub rule_index: usize,
1016 pub stmt: StmtId,
1018 pub speculative: bool,
1020}
1021
1022#[derive(Clone, Debug, Default, Eq, PartialEq)]
1029pub struct ParserSemantics {
1030 pub ir: SemIr,
1031 pub predicates: Vec<ParserSemanticPredicate>,
1032 pub actions: Vec<ParserSemanticAction>,
1033}
1034
1035#[derive(Clone, Copy, Debug, Default)]
1037pub struct ParserRuntimeOptions<'a> {
1038 pub init_action_rules: &'a [usize],
1040 pub track_alt_numbers: bool,
1042 pub predicates: &'a [(usize, usize, ParserPredicate)],
1044 pub semantics: Option<&'a ParserSemantics>,
1046 pub rule_args: &'a [ParserRuleArg],
1048 pub member_actions: &'a [ParserMemberAction],
1050 pub return_actions: &'a [ParserReturnAction],
1052 pub unknown_predicate_policy: UnknownSemanticPolicy,
1055}
1056
1057pub trait Parser: Recognizer {
1058 fn build_parse_trees(&self) -> bool;
1061
1062 fn set_build_parse_trees(&mut self, build: bool);
1064
1065 fn number_of_syntax_errors(&self) -> usize {
1068 0
1069 }
1070
1071 fn report_diagnostic_errors(&self) -> bool {
1074 false
1075 }
1076
1077 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
1080
1081 fn prediction_mode(&self) -> PredictionMode {
1083 PredictionMode::Ll
1084 }
1085
1086 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
1088}
1089
1090#[derive(Debug)]
1091struct LeftRecursiveCallerOverlap {
1092 atn_key: SharedAtnCacheKey,
1093 state_number: usize,
1094 symbol: i32,
1095 context_version: usize,
1096 overlaps: bool,
1097}
1098
1099const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
1100
1101#[derive(Debug)]
1102pub struct BaseParser<S, H = NoSemanticHooks> {
1103 input: CommonTokenStream<S>,
1104 tree: ParseTreeStorage,
1105 data: RecognizerData,
1106 semantic_hooks: H,
1107 build_parse_trees: bool,
1108 syntax_errors: usize,
1109 report_diagnostic_errors: bool,
1110 prediction_mode: PredictionMode,
1111 prediction_diagnostics: Vec<ParserDiagnostic>,
1112 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1113 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1114 generated_sync_expected: Option<TokenBitSet>,
1115 int_members: BTreeMap<usize, i64>,
1116 rule_context_stack: Vec<RuleContextFrame>,
1117 rule_context_version: usize,
1118 left_recursive_caller_overlap_cache:
1119 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1120 pending_invoking_states: Vec<isize>,
1121 precedence_stack: Vec<i32>,
1122 invoked_predicates: Vec<(usize, usize)>,
1126 bail_on_error: bool,
1130 unknown_predicate_policy: UnknownSemanticPolicy,
1133 unknown_predicate_hits: Vec<(usize, usize)>,
1136 unhandled_action_hits: Vec<(usize, usize)>,
1141 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1146 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1152 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1157 rule_stop_reach_cache: Vec<Option<bool>>,
1162 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1167 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1173 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1179 fast_predicate_cache: FxHashMap<(usize, usize, usize), bool>,
1183 empty_cycle_cache: Vec<Option<bool>>,
1189 empty_cycle_cache_atn: Option<SharedAtnCacheKey>,
1190 clean_memo_mode: CleanMemoMode,
1193 clean_memo_probe_seen: FxHashSet<FastRecognizeKey>,
1194 clean_memo_probe_samples: usize,
1195 clean_memo_probe_repeats: usize,
1196 clean_memo_sparse_samples: usize,
1197 fast_recognize_scratch: FastRecognizeTopScratch,
1199 fast_outcome_dedup: FastOutcomeDedupScratch,
1201 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1204 fast_first_set_prefilter: bool,
1212 fast_recovery_enabled: bool,
1216 fast_token_nodes_enabled: bool,
1221 recognition_arena: RecognitionArena,
1225 last_recognition_arena_root: NodeSeqId,
1226 last_recognition_arena_diagnostics: DiagnosticSeqId,
1227}
1228
1229#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1231pub struct GeneratedDiagnosticsCheckpoint {
1232 diagnostics_len: usize,
1233 syntax_errors: usize,
1234 tree: ParseTreeCheckpoint,
1235}
1236
1237#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1240pub struct RecognitionArenaStats {
1241 pub total_nodes: usize,
1242 pub live_nodes: usize,
1243 pub dead_nodes: usize,
1244 pub node_capacity: usize,
1245 pub total_links: usize,
1246 pub live_links: usize,
1247 pub dead_links: usize,
1248 pub link_capacity: usize,
1249 pub total_extras: usize,
1250 pub live_extras: usize,
1251 pub dead_extras: usize,
1252 pub extra_capacity: usize,
1253}
1254
1255#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1256struct RuleContextFrame {
1257 rule_index: usize,
1258 invoking_state: isize,
1259}
1260
1261#[derive(Clone, Debug, Eq, PartialEq)]
1262struct RecognizeOutcome {
1263 index: usize,
1264 consumed_eof: bool,
1265 alt_number: usize,
1266 member_values: BTreeMap<usize, i64>,
1267 return_values: BTreeMap<String, i64>,
1268 diagnostics: DiagnosticSeqId,
1269 decisions: Vec<usize>,
1270 actions: Vec<ParserAction>,
1271 nodes: NodeSeqId,
1272}
1273
1274#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1275struct FastRecognizeOutcome {
1276 index: usize,
1277 consumed_eof: bool,
1278 diagnostics: DiagnosticSeqId,
1279 deferred_nodes: FastDeferredNodeId,
1280 nodes: NodeSeqId,
1284}
1285
1286#[derive(Debug, Default)]
1287struct FastRecognizeTopScratch {
1288 visiting: FxHashSet<FastRecognizeKey>,
1289 memo: FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
1290}
1291
1292impl FastRecognizeTopScratch {
1293 fn prepare(&mut self, memo_capacity: usize) {
1294 self.visiting.clear();
1295 self.visiting.reserve(FAST_RECOGNIZE_VISITING_CAPACITY);
1296 self.memo.clear();
1297 self.memo.reserve(memo_capacity);
1298 }
1299
1300 fn release_oversized_memo(&mut self) {
1301 self.memo.clear();
1302 if self.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY {
1303 self.memo = FxHashMap::default();
1304 }
1305 }
1306}
1307
1308fn fast_recognize_memo_capacity(buffered_tokens: usize) -> usize {
1309 buffered_tokens.saturating_mul(8).clamp(
1310 FAST_RECOGNIZE_MIN_MEMO_CAPACITY,
1311 FAST_RECOGNIZE_MAX_MEMO_CAPACITY,
1312 )
1313}
1314
1315#[derive(Debug, Default)]
1316struct FastOutcomeDedupScratch {
1317 dense_words: Vec<u64>,
1318 touched_dense_words: Vec<u32>,
1319 sparse_keys: FxHashSet<(usize, bool)>,
1320}
1321
1322#[repr(transparent)]
1327#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1328struct FastDeferredNodeId(u32);
1329
1330impl FastDeferredNodeId {
1331 const EMPTY: Self = Self(u32::MAX);
1332
1333 const fn is_empty(self) -> bool {
1334 self.0 == Self::EMPTY.0
1335 }
1336}
1337
1338impl Default for FastDeferredNodeId {
1339 fn default() -> Self {
1340 Self::EMPTY
1341 }
1342}
1343
1344#[repr(transparent)]
1345#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1346struct FastDeferredRuleId(u32);
1347
1348#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1350enum FastDeferredNode {
1351 Fragment(NodeSeqId),
1352 Rule(FastDeferredRuleId),
1353 Concat {
1354 prefix: FastDeferredNodeId,
1355 suffix: FastDeferredNodeId,
1356 },
1357}
1358
1359#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1360struct FastDeferredRule {
1361 rule_index: u32,
1362 invoking_state: i32,
1363 start_index: u32,
1364 stop_index: Option<u32>,
1365 deferred_children: FastDeferredNodeId,
1366 children: NodeSeqId,
1367}
1368
1369#[repr(transparent)]
1370#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1371struct RecognizedNodeId(u32);
1372
1373#[repr(transparent)]
1374#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1375struct NodeSeqId(u32);
1376
1377impl NodeSeqId {
1378 const EMPTY: Self = Self(u32::MAX);
1379
1380 const fn is_empty(self) -> bool {
1381 self.0 == Self::EMPTY.0
1382 }
1383}
1384
1385impl Default for NodeSeqId {
1386 fn default() -> Self {
1387 Self::EMPTY
1388 }
1389}
1390
1391#[repr(transparent)]
1392#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1393struct DiagnosticSeqId(u32);
1394
1395impl DiagnosticSeqId {
1396 const EMPTY: Self = Self(u32::MAX);
1397
1398 const fn is_empty(self) -> bool {
1399 self.0 == Self::EMPTY.0
1400 }
1401}
1402
1403impl Default for DiagnosticSeqId {
1404 fn default() -> Self {
1405 Self::EMPTY
1406 }
1407}
1408
1409#[repr(transparent)]
1410#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1411struct RecognitionExtraId(u32);
1412
1413#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1414struct SeqLink {
1415 head: RecognizedNodeId,
1416 tail: NodeSeqId,
1417}
1418
1419#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1420struct DiagnosticLink {
1421 head: RecognitionExtraId,
1422 tail: DiagnosticSeqId,
1423}
1424
1425struct ArenaRuleSpec {
1426 rule_index: usize,
1427 invoking_state: isize,
1428 alt_number: usize,
1429 start_index: usize,
1430 stop_index: Option<usize>,
1431 return_values: BTreeMap<String, i64>,
1432 children: NodeSeqId,
1433}
1434
1435#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1438enum ArenaRecognizedNode {
1439 Token {
1440 token: TokenId,
1441 },
1442 ErrorToken {
1443 token: TokenId,
1444 },
1445 MissingToken {
1446 extra: RecognitionExtraId,
1447 },
1448 Rule {
1449 rule_index: u32,
1450 invoking_state: i32,
1451 alt_number: u32,
1452 start_index: u32,
1453 stop_index: Option<u32>,
1454 return_values: Option<RecognitionExtraId>,
1455 children: NodeSeqId,
1456 },
1457 LeftRecursiveBoundary {
1461 rule_index: u32,
1462 },
1463}
1464
1465#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1466enum RecognitionExtra {
1467 MissingToken {
1468 token_type: i32,
1469 at_index: u32,
1470 text: String,
1471 },
1472 ReturnValues(BTreeMap<String, i64>),
1473 Diagnostic(ParserDiagnostic),
1474}
1475
1476#[derive(Debug, Default)]
1477struct RecognitionArena {
1478 nodes: Vec<ArenaRecognizedNode>,
1479 seq_links: Vec<SeqLink>,
1480 diagnostic_links: Vec<DiagnosticLink>,
1481 extras: Vec<RecognitionExtra>,
1482 deferred_nodes: Vec<FastDeferredNode>,
1483 deferred_rules: Vec<FastDeferredRule>,
1484}
1485
1486const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1489const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1490const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1491const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1492const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1493const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1494
1495impl RecognitionArena {
1496 fn reset(&mut self) {
1497 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1498 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1499 reset_arena_vec(
1500 &mut self.diagnostic_links,
1501 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1502 );
1503 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1504 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1505 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1506 }
1507
1508 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1509 let id = RecognizedNodeId(
1510 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1511 );
1512 self.nodes.push(node);
1513 id
1514 }
1515
1516 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1517 let id = RecognitionExtraId(
1518 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1519 );
1520 self.extras.push(extra);
1521 id
1522 }
1523
1524 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1525 let id = NodeSeqId(
1526 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1527 );
1528 self.seq_links.push(SeqLink { head, tail });
1529 id
1530 }
1531
1532 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1533 let id = FastDeferredNodeId(
1534 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
1535 );
1536 self.deferred_nodes.push(node);
1537 id
1538 }
1539
1540 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
1541 let id = FastDeferredRuleId(
1542 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
1543 );
1544 self.deferred_rules.push(rule);
1545 id
1546 }
1547
1548 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
1549 if nodes.is_empty() {
1550 FastDeferredNodeId::EMPTY
1551 } else {
1552 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
1553 }
1554 }
1555
1556 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
1557 let rule = self.push_deferred_rule(rule);
1558 self.push_deferred_node(FastDeferredNode::Rule(rule))
1559 }
1560
1561 fn concat_deferred_nodes(
1562 &mut self,
1563 prefix: FastDeferredNodeId,
1564 suffix: FastDeferredNodeId,
1565 ) -> FastDeferredNodeId {
1566 if prefix.is_empty() {
1567 return suffix;
1568 }
1569 if suffix.is_empty() {
1570 return prefix;
1571 }
1572 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
1573 }
1574
1575 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
1576 self.deferred_nodes[id.0 as usize]
1577 }
1578
1579 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
1580 self.deferred_rules[id.0 as usize]
1581 }
1582
1583 fn prepend_diagnostic(
1584 &mut self,
1585 tail: DiagnosticSeqId,
1586 diagnostic: ParserDiagnostic,
1587 ) -> DiagnosticSeqId {
1588 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
1589 self.prepend_diagnostic_id(tail, head)
1590 }
1591
1592 fn prepend_diagnostic_id(
1593 &mut self,
1594 tail: DiagnosticSeqId,
1595 head: RecognitionExtraId,
1596 ) -> DiagnosticSeqId {
1597 let id = DiagnosticSeqId(
1598 u32::try_from(self.diagnostic_links.len())
1599 .expect("diagnostic sequence arena fits in u32"),
1600 );
1601 self.diagnostic_links.push(DiagnosticLink { head, tail });
1602 id
1603 }
1604
1605 fn concat_diagnostics(
1606 &mut self,
1607 prefix: DiagnosticSeqId,
1608 mut suffix: DiagnosticSeqId,
1609 ) -> DiagnosticSeqId {
1610 if prefix.is_empty() {
1611 return suffix;
1612 }
1613 if suffix.is_empty() {
1614 return prefix;
1615 }
1616 let mut reversed = DiagnosticSeqId::EMPTY;
1617 let mut cursor = prefix;
1618 while let Some(link) = self.diagnostic_link(cursor) {
1619 reversed = self.prepend_diagnostic_id(reversed, link.head);
1620 cursor = link.tail;
1621 }
1622 while let Some(link) = self.diagnostic_link(reversed) {
1623 suffix = self.prepend_diagnostic_id(suffix, link.head);
1624 reversed = link.tail;
1625 }
1626 suffix
1627 }
1628
1629 #[cfg(test)]
1630 fn diagnostic_sequence(
1631 &mut self,
1632 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
1633 ) -> DiagnosticSeqId {
1634 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
1635 let mut sequence = DiagnosticSeqId::EMPTY;
1636 for diagnostic in diagnostics.into_iter().rev() {
1637 sequence = self.prepend_diagnostic(sequence, diagnostic);
1638 }
1639 sequence
1640 }
1641
1642 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
1643 self.nodes[id.0 as usize]
1644 }
1645
1646 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
1647 &self.extras[id.0 as usize]
1648 }
1649
1650 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
1651 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
1652 }
1653
1654 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
1655 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
1656 }
1657
1658 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
1659 NodeSeqIter {
1660 arena: self,
1661 cursor: sequence,
1662 }
1663 }
1664
1665 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
1666 DiagnosticSeqIter {
1667 arena: self,
1668 cursor: sequence,
1669 }
1670 }
1671
1672 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
1673 self.diagnostics(sequence).count()
1674 }
1675
1676 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
1677 self.diagnostics(sequence)
1678 .filter(|diagnostic| {
1679 diagnostic.message.starts_with("mismatched input ")
1680 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
1681 })
1682 .count()
1683 }
1684
1685 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
1686 self.diagnostics(left).cmp(self.diagnostics(right))
1687 }
1688
1689 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
1690 self.iter(sequence).count()
1691 }
1692
1693 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
1694 self.iter(sequence).any(|node| match self.node(node) {
1695 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1696 ArenaRecognizedNode::Rule { children, .. } => {
1697 self.sequence_has_left_recursive_boundary(children)
1698 }
1699 ArenaRecognizedNode::Token { .. }
1700 | ArenaRecognizedNode::ErrorToken { .. }
1701 | ArenaRecognizedNode::MissingToken { .. } => false,
1702 })
1703 }
1704
1705 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
1706 self.iter(sequence).any(|node| {
1707 matches!(
1708 self.node(node),
1709 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
1710 )
1711 })
1712 }
1713
1714 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
1715 self.iter(sequence).any(|node| {
1716 matches!(
1717 self.node(node),
1718 ArenaRecognizedNode::Token { .. }
1719 | ArenaRecognizedNode::ErrorToken { .. }
1720 | ArenaRecognizedNode::MissingToken { .. }
1721 )
1722 })
1723 }
1724
1725 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
1726 match self.node(node) {
1727 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1728 Some(token.index())
1729 }
1730 ArenaRecognizedNode::MissingToken { extra } => {
1731 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1732 unreachable!("missing-token node must reference missing-token extra");
1733 };
1734 Some(*at_index as usize)
1735 }
1736 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
1737 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1738 }
1739 }
1740
1741 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
1742 match self.node(node) {
1743 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1744 Some(token.index())
1745 }
1746 ArenaRecognizedNode::MissingToken { extra } => {
1747 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1748 unreachable!("missing-token node must reference missing-token extra");
1749 };
1750 (*at_index as usize).checked_sub(1)
1751 }
1752 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
1753 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1754 }
1755 }
1756
1757 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
1758 let start = self.node_start_index(node)?;
1759 let stop = self.node_stop_index(node);
1760 Some((start, stop))
1761 }
1762
1763 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
1764 self.iter(sequence)
1765 .find_map(|node| self.node_start_index(node))
1766 }
1767
1768 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
1769 let mut stop = None;
1770 for node in self.iter(sequence) {
1771 if let Some(index) = self.node_stop_index(node) {
1772 stop = Some(index);
1773 }
1774 }
1775 stop
1776 }
1777
1778 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
1779 self.iter(sequence)
1780 .any(|node| self.node_needs_stable_tie(node))
1781 }
1782
1783 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
1784 match self.node(node) {
1785 ArenaRecognizedNode::Token { .. }
1786 | ArenaRecognizedNode::ErrorToken { .. }
1787 | ArenaRecognizedNode::MissingToken { .. } => false,
1788 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1789 ArenaRecognizedNode::Rule {
1790 rule_index,
1791 children,
1792 ..
1793 } => self.iter(children).any(|child| {
1794 matches!(
1795 self.node(child),
1796 ArenaRecognizedNode::Rule {
1797 rule_index: child_rule,
1798 ..
1799 } if child_rule == rule_index
1800 ) || self.node_needs_stable_tie(child)
1801 }),
1802 }
1803 }
1804
1805 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
1806 loop {
1807 match (self.link(left), self.link(right)) {
1808 (Some(left_link), Some(right_link)) => {
1809 let order = self.compare_nodes(left_link.head, right_link.head);
1810 if order != Ordering::Equal {
1811 return order;
1812 }
1813 left = left_link.tail;
1814 right = right_link.tail;
1815 }
1816 (None, None) => return Ordering::Equal,
1817 (None, Some(_)) => return Ordering::Less,
1818 (Some(_), None) => return Ordering::Greater,
1819 }
1820 }
1821 }
1822
1823 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
1824 let left = self.node(left);
1825 let right = self.node(right);
1826 match (left, right) {
1827 (
1828 ArenaRecognizedNode::Token { token: left },
1829 ArenaRecognizedNode::Token { token: right },
1830 )
1831 | (
1832 ArenaRecognizedNode::ErrorToken { token: left },
1833 ArenaRecognizedNode::ErrorToken { token: right },
1834 ) => left.cmp(&right),
1835 (
1836 ArenaRecognizedNode::MissingToken { extra: left },
1837 ArenaRecognizedNode::MissingToken { extra: right },
1838 ) => self.extra(left).cmp(self.extra(right)),
1839 (
1840 ArenaRecognizedNode::Rule {
1841 rule_index: left_rule,
1842 invoking_state: left_invoking,
1843 alt_number: left_alt,
1844 start_index: left_start,
1845 stop_index: left_stop,
1846 return_values: left_returns,
1847 children: left_children,
1848 },
1849 ArenaRecognizedNode::Rule {
1850 rule_index: right_rule,
1851 invoking_state: right_invoking,
1852 alt_number: right_alt,
1853 start_index: right_start,
1854 stop_index: right_stop,
1855 return_values: right_returns,
1856 children: right_children,
1857 },
1858 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
1859 .cmp(&(
1860 right_rule,
1861 right_invoking,
1862 right_alt,
1863 right_start,
1864 right_stop,
1865 ))
1866 .then_with(|| {
1867 left_returns
1868 .map(|id| self.extra(id))
1869 .cmp(&right_returns.map(|id| self.extra(id)))
1870 })
1871 .then_with(|| self.compare_sequences(left_children, right_children)),
1872 (
1873 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: left },
1874 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: right },
1875 ) => left.cmp(&right),
1876 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
1877 }
1878 }
1879
1880 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1881 let mut reversed = NodeSeqId::EMPTY;
1882 while let Some(link) = self.link(sequence) {
1883 reversed = self.prepend(reversed, link.head);
1884 sequence = link.tail;
1885 }
1886 reversed
1887 }
1888
1889 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1890 if !self.sequence_has_direct_boundary(sequence) {
1891 return sequence;
1892 }
1893 let mut reversed = NodeSeqId::EMPTY;
1894 while let Some(link) = self.link(sequence) {
1895 match self.node(link.head) {
1896 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index } => {
1897 if !reversed.is_empty() {
1898 let children = self.reverse_sequence(reversed);
1899 let start_index = self.sequence_start_index(children).unwrap_or_default();
1900 let stop_index = self.sequence_stop_index(children);
1901 let rule = self.push_node(ArenaRecognizedNode::Rule {
1902 rule_index,
1903 invoking_state: -1,
1904 alt_number: 0,
1905 start_index: u32::try_from(start_index)
1906 .expect("left-recursive start index fits in u32"),
1907 stop_index: stop_index.map(|index| {
1908 u32::try_from(index).expect("left-recursive stop index fits in u32")
1909 }),
1910 return_values: None,
1911 children,
1912 });
1913 reversed = self.prepend(NodeSeqId::EMPTY, rule);
1914 }
1915 }
1916 _ => {
1917 reversed = self.prepend(reversed, link.head);
1918 }
1919 }
1920 sequence = link.tail;
1921 }
1922 self.reverse_sequence(reversed)
1923 }
1924
1925 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
1926 let mut live_nodes = vec![false; self.nodes.len()];
1927 let mut live_links = vec![false; self.seq_links.len()];
1928 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
1929 let mut live_extras = vec![false; self.extras.len()];
1930 let mut pending = vec![root];
1931 while let Some(mut sequence) = pending.pop() {
1932 while let Some(link) = self.link(sequence) {
1933 let link_index = sequence.0 as usize;
1934 if live_links[link_index] {
1935 break;
1936 }
1937 live_links[link_index] = true;
1938 let node_index = link.head.0 as usize;
1939 if !live_nodes[node_index] {
1940 live_nodes[node_index] = true;
1941 match self.node(link.head) {
1942 ArenaRecognizedNode::MissingToken { extra } => {
1943 live_extras[extra.0 as usize] = true;
1944 }
1945 ArenaRecognizedNode::Rule {
1946 return_values,
1947 children,
1948 ..
1949 } => {
1950 if let Some(extra) = return_values {
1951 live_extras[extra.0 as usize] = true;
1952 }
1953 pending.push(children);
1954 }
1955 ArenaRecognizedNode::Token { .. }
1956 | ArenaRecognizedNode::ErrorToken { .. }
1957 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
1958 }
1959 }
1960 sequence = link.tail;
1961 }
1962 }
1963 let mut diagnostics = diagnostics;
1964 while let Some(link) = self.diagnostic_link(diagnostics) {
1965 let link_index = diagnostics.0 as usize;
1966 if live_diagnostic_links[link_index] {
1967 break;
1968 }
1969 live_diagnostic_links[link_index] = true;
1970 live_extras[link.head.0 as usize] = true;
1971 diagnostics = link.tail;
1972 }
1973 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
1974 let live_link_count = live_links.into_iter().filter(|live| *live).count()
1975 + live_diagnostic_links
1976 .into_iter()
1977 .filter(|live| *live)
1978 .count();
1979 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
1980 let total_links = self.seq_links.len() + self.diagnostic_links.len();
1981 RecognitionArenaStats {
1982 total_nodes: self.nodes.len(),
1983 live_nodes: live_node_count,
1984 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
1985 node_capacity: self.nodes.capacity(),
1986 total_links,
1987 live_links: live_link_count,
1988 dead_links: total_links.saturating_sub(live_link_count),
1989 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
1990 total_extras: self.extras.len(),
1991 live_extras: live_extra_count,
1992 dead_extras: self.extras.len().saturating_sub(live_extra_count),
1993 extra_capacity: self.extras.capacity(),
1994 }
1995 }
1996}
1997
1998fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
1999 if storage.capacity() > max_retained_capacity {
2000 *storage = Vec::new();
2001 } else {
2002 storage.clear();
2003 }
2004}
2005
2006const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
2007 match node {
2008 ArenaRecognizedNode::Token { .. } => 0,
2009 ArenaRecognizedNode::ErrorToken { .. } => 1,
2010 ArenaRecognizedNode::MissingToken { .. } => 2,
2011 ArenaRecognizedNode::Rule { .. } => 3,
2012 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
2013 }
2014}
2015
2016struct NodeSeqIter<'a> {
2017 arena: &'a RecognitionArena,
2018 cursor: NodeSeqId,
2019}
2020
2021impl Iterator for NodeSeqIter<'_> {
2022 type Item = RecognizedNodeId;
2023
2024 fn next(&mut self) -> Option<Self::Item> {
2025 let link = self.arena.link(self.cursor)?;
2026 self.cursor = link.tail;
2027 Some(link.head)
2028 }
2029}
2030
2031struct DiagnosticSeqIter<'a> {
2032 arena: &'a RecognitionArena,
2033 cursor: DiagnosticSeqId,
2034}
2035
2036impl<'a> Iterator for DiagnosticSeqIter<'a> {
2037 type Item = &'a ParserDiagnostic;
2038
2039 fn next(&mut self) -> Option<Self::Item> {
2040 let link = self.arena.diagnostic_link(self.cursor)?;
2041 self.cursor = link.tail;
2042 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2043 unreachable!("diagnostic link must reference diagnostic extra");
2044 };
2045 Some(diagnostic)
2046 }
2047}
2048
2049#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2050struct ParserDiagnostic {
2051 line: usize,
2052 column: usize,
2053 message: String,
2054}
2055
2056#[derive(Clone, Debug, Default, Eq, PartialEq)]
2057struct ExpectedTokens {
2058 index: Option<usize>,
2059 symbols: BTreeSet<i32>,
2060 no_viable: Option<NoViableAlternative>,
2061}
2062
2063#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2064struct NoViableAlternative {
2065 start_index: usize,
2066 error_index: usize,
2067}
2068
2069impl ExpectedTokens {
2070 fn record_transition(
2073 &mut self,
2074 index: usize,
2075 transition: ParserTransition<'_>,
2076 max_token_type: i32,
2077 ) {
2078 let symbols = transition_expected_symbols(transition, max_token_type);
2079 match self.index {
2080 Some(current) if index < current => {}
2081 Some(current) if index == current => self.symbols.extend(symbols),
2082 _ => {
2083 self.index = Some(index);
2084 self.symbols = symbols;
2085 }
2086 }
2087 }
2088
2089 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2092 match self.no_viable {
2093 Some(current) if error_index < current.error_index => {}
2094 _ => {
2095 self.no_viable = Some(NoViableAlternative {
2096 start_index,
2097 error_index,
2098 });
2099 }
2100 }
2101 }
2102}
2103
2104#[derive(Clone, Debug, Default, Eq, PartialEq)]
2111struct TokenBitSet {
2112 words: Vec<u64>,
2113}
2114
2115impl TokenBitSet {
2116 fn insert(&mut self, symbol: i32) {
2117 let Some(slot) = token_bit_slot(symbol) else {
2118 return;
2119 };
2120 let word = slot / u64::BITS as usize;
2121 if word >= self.words.len() {
2122 self.words.resize(word + 1, 0);
2123 }
2124 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2125 }
2126
2127 fn extend_range(&mut self, start: i32, stop: i32) {
2128 let (start, stop) = if start <= stop {
2129 (start, stop)
2130 } else {
2131 (stop, start)
2132 };
2133 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2134 self.insert(TOKEN_EOF);
2135 }
2136 let positive_start = start.max(1);
2137 if positive_start > stop {
2138 return;
2139 }
2140 let Some(start_slot) = token_bit_slot(positive_start) else {
2141 return;
2142 };
2143 let Some(stop_slot) = token_bit_slot(stop) else {
2144 return;
2145 };
2146 self.extend_slot_range(start_slot, stop_slot);
2147 }
2148
2149 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2150 if start_slot > stop_slot {
2151 return;
2152 }
2153 let start_word = start_slot / u64::BITS as usize;
2154 let stop_word = stop_slot / u64::BITS as usize;
2155 if stop_word >= self.words.len() {
2156 self.words.resize(stop_word + 1, 0);
2157 }
2158 let start_offset = start_slot % u64::BITS as usize;
2159 let stop_offset = stop_slot % u64::BITS as usize;
2160 if start_word == stop_word {
2161 self.words[start_word] |=
2162 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2163 return;
2164 }
2165 self.words[start_word] |= !0_u64 << start_offset;
2166 for word in &mut self.words[(start_word + 1)..stop_word] {
2167 *word = !0_u64;
2168 }
2169 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2170 }
2171
2172 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2173 for symbol in symbols {
2174 self.insert(symbol);
2175 }
2176 }
2177
2178 fn extend_from(&mut self, other: &Self) {
2179 if other.words.len() > self.words.len() {
2180 self.words.resize(other.words.len(), 0);
2181 }
2182 for (left, right) in self.words.iter_mut().zip(&other.words) {
2183 *left |= *right;
2184 }
2185 }
2186
2187 fn contains(&self, symbol: i32) -> bool {
2188 let Some(slot) = token_bit_slot(symbol) else {
2189 return false;
2190 };
2191 let word = slot / u64::BITS as usize;
2192 self.words
2193 .get(word)
2194 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2195 }
2196
2197 fn is_empty(&self) -> bool {
2198 self.words.iter().all(|word| *word == 0)
2199 }
2200
2201 fn symbols(&self) -> impl Iterator<Item = i32> + '_ {
2202 self.words
2203 .iter()
2204 .copied()
2205 .enumerate()
2206 .flat_map(|(word_index, mut bits)| {
2207 std::iter::from_fn(move || {
2208 while bits != 0 {
2209 let bit = bits.trailing_zeros() as usize;
2210 bits &= bits - 1;
2211 if let Some(symbol) =
2212 token_bit_symbol(word_index * u64::BITS as usize + bit)
2213 {
2214 return Some(symbol);
2215 }
2216 }
2217 None
2218 })
2219 })
2220 }
2221
2222 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2223 target.extend(self.symbols());
2224 }
2225
2226 fn to_btree_set(&self) -> BTreeSet<i32> {
2227 let mut out = BTreeSet::new();
2228 self.extend_btree_set(&mut out);
2229 out
2230 }
2231}
2232
2233fn token_bit_slot(symbol: i32) -> Option<usize> {
2234 if symbol == TOKEN_EOF {
2235 Some(0)
2236 } else if symbol > 0 {
2237 usize::try_from(symbol).ok()
2238 } else {
2239 None
2240 }
2241}
2242
2243fn token_bit_symbol(slot: usize) -> Option<i32> {
2244 if slot == 0 {
2245 Some(TOKEN_EOF)
2246 } else {
2247 i32::try_from(slot).ok()
2248 }
2249}
2250
2251fn transition_expected_symbols(
2254 transition: ParserTransition<'_>,
2255 max_token_type: i32,
2256) -> BTreeSet<i32> {
2257 let mut symbols = BTreeSet::new();
2258 match &transition.data() {
2259 Transition::Atom { label, .. } => {
2260 symbols.insert(*label);
2261 }
2262 Transition::Range { start, stop, .. } => {
2263 symbols.extend(*start..=*stop);
2264 }
2265 Transition::Set { set, .. } => {
2266 for (start, stop) in set.ranges() {
2267 symbols.extend(start..=stop);
2268 }
2269 }
2270 Transition::NotSet { set, .. } => {
2271 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2272 }
2273 Transition::Wildcard { .. } => {
2274 symbols.extend(1..=max_token_type);
2275 }
2276 Transition::Epsilon { .. }
2277 | Transition::Rule { .. }
2278 | Transition::Predicate { .. }
2279 | Transition::Action { .. }
2280 | Transition::Precedence { .. } => {}
2281 }
2282 symbols
2283}
2284
2285fn transition_expected_token_set(
2286 transition: ParserTransition<'_>,
2287 max_token_type: i32,
2288) -> TokenBitSet {
2289 let mut symbols = TokenBitSet::default();
2290 match &transition.data() {
2291 Transition::Atom { label, .. } => {
2292 symbols.insert(*label);
2293 }
2294 Transition::Range { start, stop, .. } => {
2295 symbols.extend_range(*start, *stop);
2296 }
2297 Transition::Set { set, .. } => {
2298 for (start, stop) in set.ranges() {
2299 symbols.extend_range(start, stop);
2300 }
2301 }
2302 Transition::NotSet { set, .. } => {
2303 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2304 }
2305 Transition::Wildcard { .. } => {
2306 symbols.extend_range(1, max_token_type);
2307 }
2308 Transition::Epsilon { .. }
2309 | Transition::Rule { .. }
2310 | Transition::Predicate { .. }
2311 | Transition::Action { .. }
2312 | Transition::Precedence { .. } => {}
2313 }
2314 symbols
2315}
2316
2317fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2321 let mut symbols = BTreeSet::new();
2322 let mut stack = vec![state_number];
2323 let mut visited = BTreeSet::new();
2324 while let Some(current) = stack.pop() {
2325 if !visited.insert(current) {
2326 continue;
2327 }
2328 let Some(state) = atn.state(current) else {
2329 continue;
2330 };
2331 for transition in &state.transitions() {
2332 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2333 if transition_symbols.is_empty() {
2334 if transition.is_epsilon() {
2335 stack.push(transition.target());
2336 }
2337 } else {
2338 symbols.extend(transition_symbols);
2339 }
2340 }
2341 }
2342 symbols
2343}
2344
2345fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2346 let mut symbols = TokenBitSet::default();
2347 let mut stack = vec![state_number];
2348 let mut visited = BTreeSet::new();
2349 while let Some(current) = stack.pop() {
2350 if !visited.insert(current) {
2351 continue;
2352 }
2353 let Some(state) = atn.state(current) else {
2354 continue;
2355 };
2356 for transition in &state.transitions() {
2357 let transition_symbols =
2358 transition_expected_token_set(transition, atn.max_token_type());
2359 if transition_symbols.is_empty() {
2360 if transition.is_epsilon() {
2361 stack.push(transition.target());
2362 }
2363 } else {
2364 symbols.extend_from(&transition_symbols);
2365 }
2366 }
2367 }
2368 symbols
2369}
2370
2371fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2372 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2373 return false;
2374 };
2375 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2376 return false;
2377 };
2378 epsilon_reaches_state(atn, state_number, stop_state)
2379}
2380
2381fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2382 let mut stack = vec![start];
2383 let mut visited = BTreeSet::new();
2384 while let Some(current) = stack.pop() {
2385 if current == target {
2386 return true;
2387 }
2388 if !visited.insert(current) {
2389 continue;
2390 }
2391 let Some(state) = atn.state(current) else {
2392 continue;
2393 };
2394 stack.extend(
2395 state
2396 .transitions()
2397 .iter()
2398 .filter(|transition| transition.is_epsilon())
2399 .map(ParserTransition::target),
2400 );
2401 }
2402 false
2403}
2404
2405#[derive(Clone, Debug, Default, Eq, PartialEq)]
2412struct FirstSet {
2413 symbols: TokenBitSet,
2414 nullable: bool,
2415}
2416
2417type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2424
2425type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2432
2433#[derive(Debug, Default)]
2434struct LeftRecursiveOperatorLookahead {
2435 single_token: TokenBitSet,
2439 multi_token_prefix: TokenBitSet,
2444 predicate_dependent: TokenBitSet,
2445}
2446
2447#[derive(Default)]
2448struct SharedAtnCache {
2449 first_set: FirstSetCache,
2450 decision_lookahead: DecisionLookaheadCache,
2451 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2452 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2453 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2454 rule_stop_reach: FxHashMap<usize, bool>,
2455 observable_action_transitions: Option<bool>,
2456 predicate_transitions: Option<bool>,
2457}
2458
2459thread_local! {
2460 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2461 RefCell::new(FxHashMap::default());
2462}
2463
2464#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2475struct SharedAtnCacheKey {
2476 atn: usize,
2477 states: usize,
2478 state_count: usize,
2479 max_token_type: i32,
2480}
2481
2482impl SharedAtnCacheKey {
2483 fn for_atn(atn: &Atn) -> Self {
2484 let (states, state_count) = atn.storage_identity();
2485 Self {
2486 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2487 states,
2488 state_count,
2489 max_token_type: atn.max_token_type(),
2490 }
2491 }
2492}
2493
2494fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2495 SHARED_ATN_CACHES.with(|cell| {
2496 let key = SharedAtnCacheKey::for_atn(atn);
2497 let mut map = cell.borrow_mut();
2498 let cache = map.entry(key).or_default();
2499 f(&mut cache.first_set)
2500 })
2501}
2502
2503fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
2504 SHARED_ATN_CACHES.with(|cell| {
2505 let key = SharedAtnCacheKey::for_atn(atn);
2506 let mut map = cell.borrow_mut();
2507 let cache = map.entry(key).or_default();
2508 f(cache)
2509 })
2510}
2511
2512#[derive(Debug, Default)]
2521struct DecisionLookahead {
2522 transitions: Vec<TransitionLookSet>,
2523}
2524
2525#[derive(Clone, Debug, Default)]
2532struct TransitionLookSet {
2533 symbols: TokenBitSet,
2534 nullable: bool,
2535}
2536
2537struct FirstSetCtx<'a> {
2541 cache: &'a mut FirstSetCache,
2542 in_progress: BTreeSet<(usize, usize)>,
2543 hit_cycle: bool,
2544}
2545
2546fn rule_first_set(
2555 atn: &Atn,
2556 target: usize,
2557 rule_stop_state: usize,
2558 cache: &mut FirstSetCache,
2559) -> Rc<FirstSet> {
2560 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
2561 return Rc::clone(cached);
2562 }
2563 let mut ctx = FirstSetCtx {
2564 cache,
2565 in_progress: BTreeSet::new(),
2566 hit_cycle: false,
2567 };
2568 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
2569}
2570
2571fn rule_first_set_cached(
2572 atn: &Atn,
2573 target: usize,
2574 rule_stop_state: usize,
2575 ctx: &mut FirstSetCtx<'_>,
2576) -> Rc<FirstSet> {
2577 let key = (target, rule_stop_state);
2578 if let Some(cached) = ctx.cache.get(&key) {
2579 return Rc::clone(cached);
2580 }
2581 if !ctx.in_progress.insert(key) {
2582 return Rc::new(FirstSet::default());
2586 }
2587 let saved_hit_cycle = ctx.hit_cycle;
2588 ctx.hit_cycle = false;
2589 let mut first = FirstSet::default();
2590 let mut visited = BTreeSet::new();
2591 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
2592 ctx.in_progress.remove(&key);
2593 let entry = Rc::new(first);
2594 if !ctx.hit_cycle {
2595 ctx.cache.insert(key, Rc::clone(&entry));
2596 }
2597 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
2598 entry
2599}
2600
2601fn transition_first_set(
2605 atn: &Atn,
2606 transition: ParserTransition<'_>,
2607 rule_stop_state: usize,
2608 cache: &mut FirstSetCache,
2609) -> TransitionLookSet {
2610 match &transition.data() {
2611 Transition::Atom { label, .. } => {
2612 let mut symbols = TokenBitSet::default();
2613 symbols.insert(*label);
2614 TransitionLookSet {
2615 symbols,
2616 nullable: false,
2617 }
2618 }
2619 Transition::Range { start, stop, .. } => {
2620 let mut symbols = TokenBitSet::default();
2621 symbols.extend_range(*start, *stop);
2622 TransitionLookSet {
2623 symbols,
2624 nullable: false,
2625 }
2626 }
2627 Transition::Set { set, .. } => {
2628 let mut symbols = TokenBitSet::default();
2629 for (start, stop) in set.ranges() {
2630 symbols.extend_range(start, stop);
2631 }
2632 TransitionLookSet {
2633 symbols,
2634 nullable: false,
2635 }
2636 }
2637 Transition::NotSet { set, .. } => {
2638 let max = atn.max_token_type();
2639 let mut symbols = TokenBitSet::default();
2640 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
2641 TransitionLookSet {
2642 symbols,
2643 nullable: false,
2644 }
2645 }
2646 Transition::Wildcard { .. } => {
2647 let mut symbols = TokenBitSet::default();
2648 symbols.extend_range(1, atn.max_token_type());
2649 TransitionLookSet {
2650 symbols,
2651 nullable: false,
2652 }
2653 }
2654 Transition::Epsilon { target }
2655 | Transition::Action { target, .. }
2656 | Transition::Predicate { target, .. }
2657 | Transition::Precedence { target, .. } => {
2658 let first = rule_first_set(atn, *target, rule_stop_state, cache);
2661 TransitionLookSet {
2662 symbols: first.symbols.clone(),
2663 nullable: first.nullable,
2664 }
2665 }
2666 Transition::Rule {
2667 target,
2668 rule_index,
2669 follow_state,
2670 ..
2671 } => {
2672 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2673 return TransitionLookSet::default();
2674 };
2675 let child = rule_first_set(atn, *target, child_stop, cache);
2676 let mut symbols = child.symbols.clone();
2677 let nullable = if child.nullable {
2678 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
2679 symbols.extend_from(&follow.symbols);
2680 follow.nullable
2681 } else {
2682 false
2683 };
2684 TransitionLookSet { symbols, nullable }
2685 }
2686 }
2687}
2688
2689fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
2710 let mut chosen: Option<usize> = None;
2711 for (index, transition) in entry.transitions.iter().enumerate() {
2712 if transition.nullable {
2713 return None;
2714 }
2715 if transition.symbols.contains(symbol) {
2716 if chosen.is_some() {
2717 return None;
2718 }
2719 chosen = Some(index);
2720 }
2721 }
2722 chosen
2723}
2724
2725fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
2734 let mut matching_non_nullable_alt = None;
2735 let mut nullable_alt = None;
2736 for (index, transition) in entry.transitions.iter().enumerate() {
2737 if transition.nullable {
2738 if nullable_alt.is_some() {
2739 return None;
2740 }
2741 nullable_alt = Some(index);
2742 }
2743 if transition.symbols.contains(symbol) {
2744 if transition.nullable {
2745 continue;
2746 }
2747 if matching_non_nullable_alt.is_some() {
2748 return None;
2749 }
2750 matching_non_nullable_alt = Some(index);
2751 }
2752 }
2753 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
2754 return None;
2755 }
2756 if non_greedy {
2757 nullable_alt.or(matching_non_nullable_alt)
2758 } else {
2759 matching_non_nullable_alt.or(nullable_alt)
2760 }
2761}
2762
2763fn should_skip_via_lookahead(
2764 transition_kind: ParserTransitionKind,
2765 transition_index: usize,
2766 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
2767 index: usize,
2768 record_expected: bool,
2769 expected: &mut ExpectedTokens,
2770) -> bool {
2771 let prune_non_consuming = matches!(
2772 transition_kind,
2773 ParserTransitionKind::Epsilon
2774 | ParserTransitionKind::Action
2775 | ParserTransitionKind::Predicate
2776 | ParserTransitionKind::Rule
2777 | ParserTransitionKind::Precedence
2778 );
2779 if !prune_non_consuming {
2780 return false;
2781 }
2782 let Some((symbol, entry)) = lookahead_filter else {
2783 return false;
2784 };
2785 let Some(set) = entry.transitions.get(transition_index) else {
2786 return false;
2787 };
2788 if set.symbols.contains(*symbol) || set.nullable {
2789 return false;
2790 }
2791 if record_expected && !set.symbols.is_empty() {
2792 record_pruned_transition_expected(set, index, expected);
2793 }
2794 true
2795}
2796
2797fn should_skip_rule_via_first_set(
2798 first: &FirstSet,
2799 symbol: i32,
2800 record_expected: bool,
2801 index: usize,
2802 expected: &mut ExpectedTokens,
2803) -> bool {
2804 if first.nullable || first.symbols.contains(symbol) {
2805 return false;
2806 }
2807 if record_expected && !first.symbols.is_empty() {
2808 record_token_bit_expected(&first.symbols, index, expected);
2809 }
2810 true
2811}
2812
2813fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
2814 match expected.index {
2815 Some(current) if index < current => {}
2816 Some(current) if index == current => {
2817 symbols.extend_btree_set(&mut expected.symbols);
2818 }
2819 _ => {
2820 expected.index = Some(index);
2821 expected.symbols = symbols.to_btree_set();
2822 }
2823 }
2824}
2825
2826fn record_pruned_transition_expected(
2828 set: &TransitionLookSet,
2829 index: usize,
2830 expected: &mut ExpectedTokens,
2831) {
2832 match expected.index {
2833 Some(current) if index < current => {}
2834 Some(current) if index == current => {
2835 set.symbols.extend_btree_set(&mut expected.symbols);
2836 }
2837 _ => {
2838 expected.index = Some(index);
2839 expected.symbols = set.symbols.to_btree_set();
2840 }
2841 }
2842}
2843
2844fn rule_first_set_inner(
2845 atn: &Atn,
2846 state_number: usize,
2847 rule_stop_state: usize,
2848 ctx: &mut FirstSetCtx<'_>,
2849 visited: &mut BTreeSet<usize>,
2850 first: &mut FirstSet,
2851) {
2852 if !visited.insert(state_number) {
2853 return;
2854 }
2855 if state_number == rule_stop_state {
2856 first.nullable = true;
2857 return;
2858 }
2859 let Some(state) = atn.state(state_number) else {
2860 return;
2861 };
2862 for transition in &state.transitions() {
2863 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2864 if !transition_symbols.is_empty() {
2865 first.symbols.extend_iter(transition_symbols);
2866 continue;
2867 }
2868 match &transition.data() {
2869 Transition::Epsilon { target }
2870 | Transition::Action { target, .. }
2871 | Transition::Predicate { target, .. }
2872 | Transition::Precedence { target, .. } => {
2873 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
2874 }
2875 Transition::Rule {
2876 target,
2877 rule_index,
2878 follow_state,
2879 ..
2880 } => {
2881 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2882 continue;
2883 };
2884 let child_key = (*target, child_stop);
2885 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
2886 ctx.hit_cycle = true;
2887 }
2888 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
2889 first.symbols.extend_from(&child.symbols);
2890 if child.nullable {
2891 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
2892 }
2893 }
2894 Transition::Atom { .. }
2895 | Transition::Range { .. }
2896 | Transition::Set { .. }
2897 | Transition::NotSet { .. }
2898 | Transition::Wildcard { .. } => {}
2899 }
2900 }
2901}
2902
2903fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
2906 let mut symbols = BTreeSet::new();
2907 state_sync_symbols_inner(
2908 atn,
2909 state_number,
2910 stop_state,
2911 &mut BTreeSet::new(),
2912 &mut symbols,
2913 );
2914 symbols
2915}
2916
2917fn state_sync_symbols_inner(
2920 atn: &Atn,
2921 state_number: usize,
2922 stop_state: usize,
2923 visited: &mut BTreeSet<usize>,
2924 symbols: &mut BTreeSet<i32>,
2925) {
2926 if !visited.insert(state_number) {
2927 return;
2928 }
2929 if state_number == stop_state {
2930 symbols.insert(TOKEN_EOF);
2931 return;
2932 }
2933 let Some(state) = atn.state(state_number) else {
2934 return;
2935 };
2936 for transition in &state.transitions() {
2937 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2938 if transition_symbols.is_empty() {
2939 match &transition.data() {
2940 Transition::Rule { target, .. }
2941 | Transition::Epsilon { target }
2942 | Transition::Action { target, .. }
2943 | Transition::Predicate { target, .. }
2944 | Transition::Precedence { target, .. } => {
2945 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
2946 }
2947 Transition::Atom { .. }
2948 | Transition::Range { .. }
2949 | Transition::Set { .. }
2950 | Transition::NotSet { .. }
2951 | Transition::Wildcard { .. } => {}
2952 }
2953 } else {
2954 symbols.extend(transition_symbols);
2955 }
2956 }
2957}
2958
2959#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
2960struct OperatorSymbolReachability {
2961 single_token: bool,
2963 multi_token: bool,
2965 predicate_dependent: bool,
2967}
2968
2969impl OperatorSymbolReachability {
2970 const ADAPTIVE_FALLBACK: Self = Self {
2971 single_token: false,
2972 multi_token: false,
2973 predicate_dependent: true,
2974 };
2975
2976 const fn single_token(predicate_dependent: bool) -> Self {
2977 if predicate_dependent {
2978 Self {
2979 single_token: false,
2980 multi_token: false,
2981 predicate_dependent: true,
2982 }
2983 } else {
2984 Self {
2985 single_token: true,
2986 multi_token: false,
2987 predicate_dependent: false,
2988 }
2989 }
2990 }
2991
2992 const fn multi_token(predicate_dependent: bool) -> Self {
2993 if predicate_dependent {
2994 Self {
2995 single_token: false,
2996 multi_token: false,
2997 predicate_dependent: true,
2998 }
2999 } else {
3000 Self {
3001 single_token: false,
3002 multi_token: true,
3003 predicate_dependent: false,
3004 }
3005 }
3006 }
3007
3008 const fn union(self, other: Self) -> Self {
3009 Self {
3010 single_token: self.single_token || other.single_token,
3011 multi_token: self.multi_token || other.multi_token,
3012 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
3013 }
3014 }
3015}
3016
3017#[derive(Clone, Copy)]
3018struct OperatorReachabilityRequest {
3019 symbol: i32,
3020 precedence: i32,
3021 predicate_dependent: bool,
3022 operator_rule_index: usize,
3023}
3024
3025#[derive(Clone, Copy, Debug)]
3026struct OperatorRuleContinuation {
3027 stop_state: usize,
3028 follow_state: usize,
3029 return_precedence: i32,
3030}
3031
3032struct NullablePrecedenceCtx {
3033 cache: FxHashMap<(usize, usize, i32, bool), bool>,
3034 in_progress: BTreeSet<(usize, usize, i32, bool)>,
3035 hit_cycle: bool,
3036}
3037
3038fn state_is_nullable_with_precedence(
3039 atn: &Atn,
3040 state_number: usize,
3041 stop_state_number: usize,
3042 precedence: i32,
3043 allow_predicates: bool,
3044 ctx: &mut NullablePrecedenceCtx,
3045) -> bool {
3046 let saved_hit_cycle = ctx.hit_cycle;
3047 ctx.hit_cycle = false;
3048 let nullable = state_is_nullable_with_precedence_cached(
3049 atn,
3050 state_number,
3051 stop_state_number,
3052 precedence,
3053 allow_predicates,
3054 ctx,
3055 );
3056 ctx.hit_cycle = saved_hit_cycle;
3057 nullable
3058}
3059
3060fn state_is_nullable_with_precedence_cached(
3061 atn: &Atn,
3062 state_number: usize,
3063 stop_state_number: usize,
3064 precedence: i32,
3065 allow_predicates: bool,
3066 ctx: &mut NullablePrecedenceCtx,
3067) -> bool {
3068 if state_number == stop_state_number {
3069 return true;
3070 }
3071 let key = (
3072 state_number,
3073 stop_state_number,
3074 precedence,
3075 allow_predicates,
3076 );
3077 if let Some(cached) = ctx.cache.get(&key) {
3078 return *cached;
3079 }
3080 if !ctx.in_progress.insert(key) {
3081 ctx.hit_cycle = true;
3082 return false;
3083 }
3084 let saved_hit_cycle = ctx.hit_cycle;
3085 ctx.hit_cycle = false;
3086 let nullable = atn.state(state_number).is_some_and(|state| {
3087 state
3088 .transitions()
3089 .iter()
3090 .any(|transition| match &transition.data() {
3091 Transition::Rule {
3092 target,
3093 rule_index,
3094 follow_state,
3095 precedence: rule_precedence,
3096 } => {
3097 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3098 return false;
3099 };
3100 state_is_nullable_with_precedence_cached(
3101 atn,
3102 *target,
3103 child_stop,
3104 *rule_precedence,
3105 allow_predicates,
3106 ctx,
3107 ) && state_is_nullable_with_precedence_cached(
3108 atn,
3109 *follow_state,
3110 stop_state_number,
3111 precedence,
3112 allow_predicates,
3113 ctx,
3114 )
3115 }
3116 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3117 state_is_nullable_with_precedence_cached(
3118 atn,
3119 *target,
3120 stop_state_number,
3121 precedence,
3122 allow_predicates,
3123 ctx,
3124 )
3125 }
3126 Transition::Predicate { target, .. } if allow_predicates => {
3127 state_is_nullable_with_precedence_cached(
3128 atn,
3129 *target,
3130 stop_state_number,
3131 precedence,
3132 allow_predicates,
3133 ctx,
3134 )
3135 }
3136 Transition::Precedence {
3137 target,
3138 precedence: transition_precedence,
3139 } if *transition_precedence >= precedence => {
3140 state_is_nullable_with_precedence_cached(
3141 atn,
3142 *target,
3143 stop_state_number,
3144 precedence,
3145 allow_predicates,
3146 ctx,
3147 )
3148 }
3149 Transition::Atom { .. }
3150 | Transition::Range { .. }
3151 | Transition::Set { .. }
3152 | Transition::NotSet { .. }
3153 | Transition::Wildcard { .. }
3154 | Transition::Predicate { .. }
3155 | Transition::Precedence { .. } => false,
3156 })
3157 });
3158 ctx.in_progress.remove(&key);
3159 if !ctx.hit_cycle {
3160 ctx.cache.insert(key, nullable);
3161 }
3162 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3163 nullable
3164}
3165
3166fn state_operator_token_prefix_reachability(
3168 atn: &Atn,
3169 state_number: usize,
3170 request: OperatorReachabilityRequest,
3171 continuations: &[OperatorRuleContinuation],
3172 visited: &mut BTreeSet<(usize, i32, bool)>,
3173) -> OperatorSymbolReachability {
3174 let key = (
3175 state_number,
3176 request.precedence,
3177 request.predicate_dependent,
3178 );
3179 if !visited.insert(key) {
3180 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3184 }
3185 if let Some((continuation, remaining)) = continuations.split_last()
3186 && state_number == continuation.stop_state
3187 {
3188 let result = state_operator_token_prefix_reachability(
3189 atn,
3190 continuation.follow_state,
3191 OperatorReachabilityRequest {
3192 precedence: continuation.return_precedence,
3193 ..request
3194 },
3195 remaining,
3196 visited,
3197 );
3198 visited.remove(&key);
3199 return result;
3200 }
3201 let Some(state) = atn.state(state_number) else {
3202 visited.remove(&key);
3203 return OperatorSymbolReachability::default();
3204 };
3205 let completes_operator = match state.kind() {
3206 AtnStateKind::RuleStop => continuations.is_empty(),
3207 AtnStateKind::StarLoopBack
3208 | AtnStateKind::StarLoopEntry
3209 | AtnStateKind::PlusLoopBack
3210 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3211 _ => false,
3212 };
3213 if completes_operator {
3214 visited.remove(&key);
3215 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3216 }
3217 let mut reachability = OperatorSymbolReachability::default();
3218 for transition in &state.transitions() {
3219 let transition_reachability = match &transition.data() {
3220 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3221 OperatorSymbolReachability::single_token(request.predicate_dependent)
3222 }
3223 Transition::Rule {
3224 target,
3225 rule_index,
3226 follow_state,
3227 precedence: rule_precedence,
3228 } => {
3229 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3230 continue;
3231 };
3232 let mut nested = continuations.to_vec();
3233 nested.push(OperatorRuleContinuation {
3234 stop_state: child_stop,
3235 follow_state: *follow_state,
3236 return_precedence: request.precedence,
3237 });
3238 state_operator_token_prefix_reachability(
3239 atn,
3240 *target,
3241 OperatorReachabilityRequest {
3242 precedence: *rule_precedence,
3243 ..request
3244 },
3245 &nested,
3246 visited,
3247 )
3248 }
3249 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3250 state_operator_token_prefix_reachability(
3251 atn,
3252 *target,
3253 request,
3254 continuations,
3255 visited,
3256 )
3257 }
3258 Transition::Precedence {
3259 target,
3260 precedence: transition_precedence,
3261 } => {
3262 if *transition_precedence < request.precedence {
3263 OperatorSymbolReachability::default()
3264 } else {
3265 state_operator_token_prefix_reachability(
3266 atn,
3267 *target,
3268 request,
3269 continuations,
3270 visited,
3271 )
3272 }
3273 }
3274 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3275 atn,
3276 *target,
3277 OperatorReachabilityRequest {
3278 predicate_dependent: true,
3279 ..request
3280 },
3281 continuations,
3282 visited,
3283 ),
3284 Transition::Atom { .. }
3285 | Transition::Range { .. }
3286 | Transition::Set { .. }
3287 | Transition::NotSet { .. }
3288 | Transition::Wildcard { .. } => {
3289 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3290 }
3291 };
3292 reachability = reachability.union(transition_reachability);
3293 }
3294 visited.remove(&key);
3295 reachability
3296}
3297
3298fn state_can_reach_symbol_with_precedence(
3299 atn: &Atn,
3300 state_number: usize,
3301 request: OperatorReachabilityRequest,
3302 nullable_ctx: &mut NullablePrecedenceCtx,
3303 continuations: &mut Vec<OperatorRuleContinuation>,
3304 visited: &mut BTreeSet<(usize, i32, bool)>,
3305) -> OperatorSymbolReachability {
3306 let key = (
3307 state_number,
3308 request.precedence,
3309 request.predicate_dependent,
3310 );
3311 if !visited.insert(key) {
3312 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3313 }
3314 let Some(state) = atn.state(state_number) else {
3315 visited.remove(&key);
3316 return OperatorSymbolReachability::default();
3317 };
3318 let mut reachability = OperatorSymbolReachability::default();
3319 for transition in &state.transitions() {
3320 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3321 reachability = reachability.union(state_operator_token_prefix_reachability(
3322 atn,
3323 transition.target(),
3324 request,
3325 continuations,
3326 &mut BTreeSet::new(),
3327 ));
3328 continue;
3329 }
3330 let transition_reachability = match &transition.data() {
3331 Transition::Rule {
3332 target,
3333 rule_index,
3334 follow_state,
3335 precedence: rule_precedence,
3336 } => {
3337 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3338 continue;
3339 };
3340 continuations.push(OperatorRuleContinuation {
3341 stop_state: child_stop,
3342 follow_state: *follow_state,
3343 return_precedence: request.precedence,
3344 });
3345 let mut result = state_can_reach_symbol_with_precedence(
3346 atn,
3347 *target,
3348 OperatorReachabilityRequest {
3349 precedence: *rule_precedence,
3350 ..request
3351 },
3352 nullable_ctx,
3353 continuations,
3354 visited,
3355 );
3356 continuations.pop();
3357 if state_is_nullable_with_precedence(
3358 atn,
3359 *target,
3360 child_stop,
3361 *rule_precedence,
3362 true,
3363 nullable_ctx,
3364 ) {
3365 let child_predicate_dependent = request.predicate_dependent
3366 || !state_is_nullable_with_precedence(
3367 atn,
3368 *target,
3369 child_stop,
3370 *rule_precedence,
3371 false,
3372 nullable_ctx,
3373 );
3374 result = result.union(state_can_reach_symbol_with_precedence(
3375 atn,
3376 *follow_state,
3377 OperatorReachabilityRequest {
3378 predicate_dependent: child_predicate_dependent,
3379 ..request
3380 },
3381 nullable_ctx,
3382 continuations,
3383 visited,
3384 ));
3385 }
3386 result
3387 }
3388 Transition::Epsilon { target }
3389 | Transition::Action { target, .. }
3390 | Transition::Precedence { target, .. } => {
3391 if matches!(
3392 &transition.data(),
3393 Transition::Precedence {
3394 precedence: transition_precedence,
3395 ..
3396 } if *transition_precedence < request.precedence
3397 ) {
3398 continue;
3399 }
3400 state_can_reach_symbol_with_precedence(
3401 atn,
3402 *target,
3403 request,
3404 nullable_ctx,
3405 continuations,
3406 visited,
3407 )
3408 }
3409 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3410 atn,
3411 *target,
3412 OperatorReachabilityRequest {
3413 predicate_dependent: true,
3414 ..request
3415 },
3416 nullable_ctx,
3417 continuations,
3418 visited,
3419 ),
3420 Transition::Atom { .. }
3421 | Transition::Range { .. }
3422 | Transition::Set { .. }
3423 | Transition::NotSet { .. }
3424 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3425 };
3426 reachability = reachability.union(transition_reachability);
3427 }
3428 visited.remove(&key);
3429 reachability
3430}
3431
3432fn left_recursive_operator_lookahead(
3433 atn: &Atn,
3434 state_number: usize,
3435 precedence: i32,
3436) -> LeftRecursiveOperatorLookahead {
3437 let Some(state) = atn.state(state_number) else {
3438 return LeftRecursiveOperatorLookahead::default();
3439 };
3440 let Some(operator_rule_index) = state.rule_index() else {
3441 return LeftRecursiveOperatorLookahead::default();
3442 };
3443 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3444 let mut nullable_ctx = NullablePrecedenceCtx {
3445 cache: FxHashMap::default(),
3446 in_progress: BTreeSet::new(),
3447 hit_cycle: false,
3448 };
3449 for transition in &state.transitions() {
3450 let target = transition.target();
3451 if atn
3452 .state(target)
3453 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3454 {
3455 continue;
3456 }
3457 for symbol in 1..=atn.max_token_type() {
3458 let reachability = state_can_reach_symbol_with_precedence(
3459 atn,
3460 target,
3461 OperatorReachabilityRequest {
3462 symbol,
3463 precedence,
3464 predicate_dependent: false,
3465 operator_rule_index,
3466 },
3467 &mut nullable_ctx,
3468 &mut Vec::new(),
3469 &mut BTreeSet::new(),
3470 );
3471 if reachability.single_token {
3472 lookahead.single_token.insert(symbol);
3473 }
3474 if reachability.multi_token {
3475 lookahead.multi_token_prefix.insert(symbol);
3476 }
3477 if reachability.predicate_dependent {
3478 lookahead.predicate_dependent.insert(symbol);
3479 }
3480 }
3481 }
3482 lookahead
3483}
3484
3485#[derive(Debug, Default)]
3486struct StateBeforeStopLookahead {
3487 symbols: TokenBitSet,
3488 reaches_context_boundary: bool,
3489}
3490
3491fn state_before_stop_lookahead(
3492 atn: &Atn,
3493 state_number: usize,
3494 stop_state_number: usize,
3495) -> Rc<StateBeforeStopLookahead> {
3496 with_shared_atn_caches(atn, |cache| {
3497 let key = (state_number, stop_state_number);
3498 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
3499 return Rc::clone(cached);
3500 }
3501 let mut lookahead = StateBeforeStopLookahead::default();
3502 state_before_stop_lookahead_inner(
3503 atn,
3504 state_number,
3505 stop_state_number,
3506 &mut BTreeSet::new(),
3507 &mut cache.first_set,
3508 &mut lookahead,
3509 );
3510 let lookahead = Rc::new(lookahead);
3511 cache
3512 .state_before_stop_lookahead
3513 .insert(key, Rc::clone(&lookahead));
3514 lookahead
3515 })
3516}
3517
3518fn state_before_stop_lookahead_inner(
3519 atn: &Atn,
3520 state_number: usize,
3521 stop_state_number: usize,
3522 visited: &mut BTreeSet<usize>,
3523 first_set_cache: &mut FirstSetCache,
3524 lookahead: &mut StateBeforeStopLookahead,
3525) {
3526 if state_number == stop_state_number {
3527 lookahead.reaches_context_boundary = true;
3528 return;
3529 }
3530 if !visited.insert(state_number) {
3531 return;
3532 }
3533 let Some(state) = atn.state(state_number) else {
3534 return;
3535 };
3536 if state.kind() == AtnStateKind::RuleStop {
3537 lookahead.reaches_context_boundary = true;
3538 return;
3539 }
3540 for transition in &state.transitions() {
3541 match &transition.data() {
3542 Transition::Epsilon { target }
3543 | Transition::Action { target, .. }
3544 | Transition::Predicate { target, .. }
3545 | Transition::Precedence { target, .. } => {
3546 state_before_stop_lookahead_inner(
3547 atn,
3548 *target,
3549 stop_state_number,
3550 visited,
3551 first_set_cache,
3552 lookahead,
3553 );
3554 }
3555 Transition::Rule {
3556 target,
3557 rule_index,
3558 follow_state,
3559 ..
3560 } => {
3561 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3562 continue;
3563 };
3564 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
3565 lookahead.symbols.extend_from(&child.symbols);
3566 if child.nullable {
3567 state_before_stop_lookahead_inner(
3568 atn,
3569 *follow_state,
3570 stop_state_number,
3571 visited,
3572 first_set_cache,
3573 lookahead,
3574 );
3575 }
3576 }
3577 Transition::Atom { .. }
3578 | Transition::Range { .. }
3579 | Transition::Set { .. }
3580 | Transition::NotSet { .. }
3581 | Transition::Wildcard { .. } => {
3582 lookahead.symbols.extend_iter(transition_expected_symbols(
3583 transition,
3584 atn.max_token_type(),
3585 ));
3586 }
3587 }
3588 }
3589}
3590
3591fn caller_context_can_match_symbol_before_state(
3592 atn: &Atn,
3593 return_states: impl DoubleEndedIterator<Item = usize>,
3594 stop_state_number: usize,
3595 symbol: i32,
3596) -> bool {
3597 for return_state in return_states.rev() {
3598 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
3599 if lookahead.symbols.contains(symbol) {
3600 return true;
3601 }
3602 if !lookahead.reaches_context_boundary {
3603 return false;
3604 }
3605 }
3606 false
3607}
3608
3609fn next_recovery_context(
3613 atn: &Atn,
3614 state: AtnState<'_>,
3615 inherited: &BTreeSet<i32>,
3616 inherited_state: Option<usize>,
3617) -> (BTreeSet<i32>, Option<usize>) {
3618 let state_symbols = state_expected_symbols(atn, state.state_number());
3619 if state.transitions().len() > 1 && !state_symbols.is_empty() {
3620 let mut symbols = state_symbols;
3621 symbols.extend(inherited.iter().copied());
3622 return (symbols, Some(state.state_number()));
3623 }
3624 (inherited.clone(), inherited_state)
3625}
3626
3627fn recovery_expected_symbols(
3628 atn: &Atn,
3629 state_number: usize,
3630 inherited: &BTreeSet<i32>,
3631) -> BTreeSet<i32> {
3632 let mut symbols = state_expected_symbols(atn, state_number);
3633 symbols.extend(inherited.iter().copied());
3634 symbols
3635}
3636
3637fn fast_next_recovery_context<S, H>(
3641 parser: &mut BaseParser<S, H>,
3642 atn: &Atn,
3643 state: AtnState<'_>,
3644 inherited: &Rc<BTreeSet<i32>>,
3645 inherited_state: Option<usize>,
3646) -> (Rc<BTreeSet<i32>>, Option<usize>)
3647where
3648 S: TokenSource,
3649 H: SemanticHooks,
3650{
3651 if state.transitions().len() <= 1 {
3652 return (Rc::clone(inherited), inherited_state);
3653 }
3654 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
3655 if state_symbols.is_empty() {
3656 return (Rc::clone(inherited), inherited_state);
3657 }
3658 if inherited.is_empty() {
3659 return (state_symbols, Some(state.state_number()));
3660 }
3661 if Rc::ptr_eq(&state_symbols, inherited) {
3662 return (state_symbols, Some(state.state_number()));
3663 }
3664 let mut combined = (*state_symbols).clone();
3665 combined.extend(inherited.iter().copied());
3666 (
3667 parser.intern_recovery_symbols(combined),
3668 Some(state.state_number()),
3669 )
3670}
3671
3672fn fast_recovery_expected_symbols<S, H>(
3676 parser: &mut BaseParser<S, H>,
3677 atn: &Atn,
3678 state_number: usize,
3679 inherited: &Rc<BTreeSet<i32>>,
3680) -> Rc<BTreeSet<i32>>
3681where
3682 S: TokenSource,
3683 H: SemanticHooks,
3684{
3685 let cached = parser.cached_state_expected_symbols(atn, state_number);
3686 if inherited.is_empty() {
3687 return cached;
3688 }
3689 if cached.is_empty() {
3690 return Rc::clone(inherited);
3691 }
3692 if Rc::ptr_eq(&cached, inherited) {
3693 return cached;
3694 }
3695 let mut combined = (*cached).clone();
3696 combined.extend(inherited.iter().copied());
3697 parser.intern_recovery_symbols(combined)
3698}
3699
3700struct ParserTableSemCtx<'a> {
3701 member_values: &'a mut BTreeMap<usize, i64>,
3702 return_values: &'a mut BTreeMap<String, i64>,
3703}
3704
3705impl semir::PredContext for ParserTableSemCtx<'_> {
3706 type TokenText<'a>
3707 = &'a str
3708 where
3709 Self: 'a;
3710
3711 fn la(&mut self, _offset: isize) -> i64 {
3712 i64::from(TOKEN_EOF)
3713 }
3714
3715 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
3716 None
3717 }
3718
3719 fn token_index_adjacent(&mut self) -> bool {
3720 false
3721 }
3722
3723 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
3724 None
3725 }
3726
3727 fn member(&self, member: usize) -> Option<i64> {
3728 Some(self.member_values.get(&member).copied().unwrap_or_default())
3729 }
3730
3731 fn local_arg(&self) -> Option<i64> {
3732 None
3733 }
3734
3735 fn column(&self) -> Option<i64> {
3736 None
3737 }
3738
3739 fn token_start_column(&self) -> Option<i64> {
3740 None
3741 }
3742
3743 fn token_text_so_far(&self) -> Option<String> {
3744 None
3745 }
3746
3747 fn hook(&mut self, _hook: HookId) -> bool {
3748 false
3749 }
3750}
3751
3752impl semir::ActContext for ParserTableSemCtx<'_> {
3753 fn set_member(&mut self, member: usize, value: i64) {
3754 self.member_values.insert(member, value);
3755 }
3756
3757 fn set_return(&mut self, name: &str, value: i64) {
3758 self.return_values.insert(name.to_owned(), value);
3759 }
3760
3761 fn action_hook(&mut self, _hook: HookId) {}
3762}
3763
3764fn apply_member_actions(
3766 source_state: usize,
3767 actions: &[ParserMemberAction],
3768 semantics: Option<&ParserSemantics>,
3769 values: &mut BTreeMap<usize, i64>,
3770) {
3771 for action in actions
3772 .iter()
3773 .filter(|action| action.source_state == source_state)
3774 {
3775 *values.entry(action.member).or_default() += action.delta;
3776 }
3777 let Some(semantics) = semantics else {
3778 return;
3779 };
3780 let mut return_values = BTreeMap::new();
3781 let mut ctx = ParserTableSemCtx {
3782 member_values: values,
3783 return_values: &mut return_values,
3784 };
3785 for action in semantics
3786 .actions
3787 .iter()
3788 .filter(|action| action.source_state == source_state && action.speculative)
3789 {
3790 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3791 }
3792}
3793
3794fn member_values_after_action(
3796 source_state: usize,
3797 actions: &[ParserMemberAction],
3798 semantics: Option<&ParserSemantics>,
3799 values: &BTreeMap<usize, i64>,
3800) -> BTreeMap<usize, i64> {
3801 let mut values = values.clone();
3802 apply_member_actions(source_state, actions, semantics, &mut values);
3803 values
3804}
3805
3806fn return_values_after_action(
3808 source_state: usize,
3809 rule_index: usize,
3810 actions: &[ParserReturnAction],
3811 semantics: Option<&ParserSemantics>,
3812 values: &BTreeMap<String, i64>,
3813) -> BTreeMap<String, i64> {
3814 let mut values = values.clone();
3815 for action in actions
3816 .iter()
3817 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
3818 {
3819 values.insert(action.name.to_owned(), action.value);
3820 }
3821 if let Some(semantics) = semantics {
3822 let mut member_values = BTreeMap::new();
3823 let mut ctx = ParserTableSemCtx {
3824 member_values: &mut member_values,
3825 return_values: &mut values,
3826 };
3827 for action in semantics.actions.iter().filter(|action| {
3828 action.source_state == source_state
3829 && action.rule_index == rule_index
3830 && !action.speculative
3831 }) {
3832 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3833 }
3834 }
3835 values
3836}
3837
3838fn rule_local_int_arg(
3840 rule_args: &[ParserRuleArg],
3841 source_state: usize,
3842 rule_index: usize,
3843 local_int_arg: Option<(usize, i64)>,
3844) -> Option<(usize, i64)> {
3845 rule_args
3846 .iter()
3847 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
3848 .map(|arg| {
3849 let value = if arg.inherit_local {
3850 local_int_arg.map_or(arg.value, |(_, value)| value)
3851 } else {
3852 arg.value
3853 };
3854 (rule_index, value)
3855 })
3856}
3857
3858fn stop_outcome(
3861 index: usize,
3862 consumed_eof: bool,
3863 rule_alt_number: usize,
3864 member_values: BTreeMap<usize, i64>,
3865 return_values: BTreeMap<String, i64>,
3866) -> Vec<RecognizeOutcome> {
3867 vec![RecognizeOutcome {
3868 index,
3869 consumed_eof,
3870 alt_number: rule_alt_number,
3871 member_values,
3872 return_values,
3873 diagnostics: DiagnosticSeqId::EMPTY,
3874 decisions: Vec::new(),
3875 actions: Vec::new(),
3876 nodes: NodeSeqId::EMPTY,
3877 }]
3878}
3879
3880fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
3881 with_shared_atn_caches(atn, |cache| {
3882 *cache.observable_action_transitions.get_or_insert_with(|| {
3883 atn.states().any(|state| {
3884 state.transitions().iter().any(|transition| {
3885 matches!(
3886 &transition.data(),
3887 Transition::Action {
3888 action_index: Some(_),
3889 ..
3890 }
3891 )
3892 })
3893 })
3894 })
3895 })
3896}
3897
3898fn atn_has_predicate_transitions(atn: &Atn) -> bool {
3899 with_shared_atn_caches(atn, |cache| {
3900 *cache.predicate_transitions.get_or_insert_with(|| {
3901 atn.states().any(|state| {
3902 state
3903 .transitions()
3904 .iter()
3905 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
3906 })
3907 })
3908 })
3909}
3910
3911fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
3916 options.init_action_rules.is_empty()
3917 && !options.track_alt_numbers
3918 && options
3919 .predicates
3920 .iter()
3921 .all(|(_, _, predicate)| predicate.failure_message().is_none())
3922 && options.semantics.is_none_or(|semantics| {
3923 semantics.actions.is_empty()
3924 && semantics
3925 .predicates
3926 .iter()
3927 .all(|predicate| predicate.failure_message.is_none())
3928 })
3929 && options.rule_args.is_empty()
3930 && options.member_actions.is_empty()
3931 && options.return_actions.is_empty()
3932 && !atn_has_observable_action_transitions(atn)
3933}
3934
3935#[derive(Clone, Debug, Eq, PartialEq)]
3936struct RecognizeRequest<'a> {
3937 state_number: usize,
3938 stop_state: usize,
3939 index: usize,
3940 rule_start_index: usize,
3941 decision_start_index: Option<usize>,
3942 init_action_rules: &'a BTreeSet<usize>,
3943 predicates: &'a [(usize, usize, ParserPredicate)],
3944 semantics: Option<&'a ParserSemantics>,
3945 rule_args: &'a [ParserRuleArg],
3946 member_actions: &'a [ParserMemberAction],
3947 return_actions: &'a [ParserReturnAction],
3948 local_int_arg: Option<(usize, i64)>,
3949 member_values: BTreeMap<usize, i64>,
3950 return_values: BTreeMap<String, i64>,
3951 rule_alt_number: usize,
3952 track_alt_numbers: bool,
3953 consumed_eof: bool,
3954 precedence: i32,
3957 depth: usize,
3958 recovery_symbols: BTreeSet<i32>,
3959 recovery_state: Option<usize>,
3960}
3961
3962#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
3963struct RecognizeKey {
3964 state_number: usize,
3965 stop_state: usize,
3966 index: usize,
3967 rule_start_index: usize,
3968 decision_start_index: Option<usize>,
3969 local_int_arg: Option<(usize, i64)>,
3970 member_values: BTreeMap<usize, i64>,
3971 return_values: BTreeMap<String, i64>,
3972 rule_alt_number: usize,
3973 track_alt_numbers: bool,
3974 consumed_eof: bool,
3975 precedence: i32,
3976 recovery_symbols: BTreeSet<i32>,
3977 recovery_state: Option<usize>,
3978}
3979
3980#[derive(Clone, Debug, Eq, PartialEq)]
3981struct EpsilonActionStep {
3982 source_state: usize,
3983 target: usize,
3984 action_rule_index: Option<usize>,
3985 left_recursive_boundary: Option<usize>,
3986 decision: Option<usize>,
3987 decision_start_index: Option<usize>,
3988 alt_number: usize,
3989 recovery_symbols: BTreeSet<i32>,
3990 recovery_state: Option<usize>,
3991}
3992
3993struct RecognizeScratch<'a> {
3994 visiting: &'a mut BTreeSet<RecognizeKey>,
3995 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
3996 expected: &'a mut ExpectedTokens,
3997}
3998
3999#[derive(Clone, Debug, Eq, PartialEq)]
4000struct FastRecognizeRequest {
4001 state_number: usize,
4002 stop_state: usize,
4003 index: usize,
4004 rule_start_index: usize,
4005 decision_start_index: Option<usize>,
4006 precedence: i32,
4007 depth: usize,
4008 recovery_symbols: Rc<BTreeSet<i32>>,
4009 recovery_state: Option<usize>,
4010}
4011
4012#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4013struct FastRecognizeTopRequest {
4014 start_state: usize,
4015 stop_state: usize,
4016 start_index: usize,
4017 precedence: i32,
4018 caller_follow_state: Option<usize>,
4019}
4020
4021#[derive(Clone, Copy, Debug)]
4022struct FastPredicateContext<'a> {
4023 predicates: &'a [(usize, usize, ParserPredicate)],
4024 semantics: Option<&'a ParserSemantics>,
4025 member_values: &'a BTreeMap<usize, i64>,
4026}
4027
4028struct FastRecognizeScratch<'a, 'b> {
4029 predicate_context: Option<FastPredicateContext<'a>>,
4030 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4031 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4032 expected: &'b mut ExpectedTokens,
4033}
4034
4035#[derive(Clone, Copy, Debug)]
4036struct FastRepetitionShape {
4037 enter_target: usize,
4038 exit_target: usize,
4039 body_stop_state: usize,
4040 enter_transition_index: usize,
4041 exit_transition_index: usize,
4042}
4043
4044#[derive(Clone, Copy, Debug)]
4045struct FastRepetitionPath {
4046 index: usize,
4047 deferred_nodes: FastDeferredNodeId,
4048 diagnostics: DiagnosticSeqId,
4049 consumed_eof: bool,
4050}
4051
4052enum FastRepetitionWork {
4053 Enter(FastRepetitionPath),
4054 Exit(FastRepetitionPath),
4055}
4056
4057struct FastRepetitionCoordinates {
4062 base_index: usize,
4063 base_state: u8,
4064 later_states: Vec<u8>,
4065}
4066
4067impl FastRepetitionCoordinates {
4068 const ENTERED: u8 = 0;
4069 const EXITED: u8 = 2;
4070
4071 const fn new(base_index: usize) -> Self {
4072 Self {
4073 base_index,
4074 base_state: 0,
4075 later_states: Vec::new(),
4076 }
4077 }
4078
4079 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4080 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4081 }
4082
4083 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4084 self.insert(path.index, path.consumed_eof, Self::EXITED)
4085 }
4086
4087 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4088 let Some(offset) = index.checked_sub(self.base_index) else {
4089 return false;
4090 };
4091 let state = if offset == 0 {
4092 &mut self.base_state
4093 } else {
4094 if self.later_states.len() < offset {
4095 self.later_states.resize(offset, 0);
4096 }
4097 &mut self.later_states[offset - 1]
4098 };
4099 let bit = 1 << (base_bit + u8::from(consumed_eof));
4100 let is_new = *state & bit == 0;
4101 *state |= bit;
4102 is_new
4103 }
4104}
4105
4106fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4107 if state.precedence_rule_decision()
4108 || !matches!(
4109 state.kind(),
4110 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4111 )
4112 || state.transitions().len() != 2
4113 {
4114 return None;
4115 }
4116 let mut enter = None;
4117 let mut exit = None;
4118 for (index, transition) in state.transitions().iter().enumerate() {
4119 if transition.kind() != ParserTransitionKind::Epsilon {
4120 return None;
4121 }
4122 let target = transition.target();
4123 if atn
4124 .state(target)
4125 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4126 {
4127 if exit.replace((index, target)).is_some() {
4128 return None;
4129 }
4130 } else if enter.replace((index, target)).is_some() {
4131 return None;
4132 }
4133 }
4134 let (enter_transition_index, enter_target) = enter?;
4135 let (exit_transition_index, exit_target) = exit?;
4136 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4137 atn.state(exit_target)?.loop_back_state()?
4138 } else {
4139 state.state_number()
4140 };
4141 Some(FastRepetitionShape {
4142 enter_target,
4143 exit_target,
4144 body_stop_state,
4145 enter_transition_index,
4146 exit_transition_index,
4147 })
4148}
4149
4150fn push_fast_repetition_work(
4151 work: &mut Vec<FastRepetitionWork>,
4152 shape: FastRepetitionShape,
4153 path: FastRepetitionPath,
4154 lookahead: Option<&DecisionLookahead>,
4155 symbol: i32,
4156) {
4157 let transition_is_viable = |transition_index: usize| {
4160 let Some(entry) = lookahead else {
4161 return true;
4162 };
4163 let Some(transition) = entry.transitions.get(transition_index) else {
4164 return true;
4165 };
4166 transition.nullable || transition.symbols.contains(symbol)
4167 };
4168 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4169 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4170 if shape.enter_transition_index < shape.exit_transition_index {
4171 if exit_is_viable {
4172 work.push(FastRepetitionWork::Exit(path));
4173 }
4174 if enter_is_viable {
4175 work.push(FastRepetitionWork::Enter(path));
4176 }
4177 } else {
4178 if enter_is_viable {
4179 work.push(FastRepetitionWork::Enter(path));
4180 }
4181 if exit_is_viable {
4182 work.push(FastRepetitionWork::Exit(path));
4183 }
4184 }
4185}
4186
4187#[derive(Clone, Debug)]
4194struct FastRecognizeKey {
4195 state_number: usize,
4196 stop_state: usize,
4197 index: usize,
4198 rule_start_index: usize,
4199 decision_start_index: Option<usize>,
4200 precedence: i32,
4201 recovery_symbols_id: usize,
4202 recovery_state: Option<usize>,
4203}
4204
4205impl PartialEq for FastRecognizeKey {
4206 fn eq(&self, other: &Self) -> bool {
4207 if self.state_number != other.state_number
4208 || self.stop_state != other.stop_state
4209 || self.index != other.index
4210 || self.rule_start_index != other.rule_start_index
4211 || self.decision_start_index != other.decision_start_index
4212 || self.precedence != other.precedence
4213 || self.recovery_state != other.recovery_state
4214 || self.recovery_symbols_id != other.recovery_symbols_id
4215 {
4216 return false;
4217 }
4218 true
4219 }
4220}
4221
4222impl Eq for FastRecognizeKey {}
4223
4224impl Hash for FastRecognizeKey {
4225 fn hash<H: Hasher>(&self, hasher: &mut H) {
4226 self.state_number.hash(hasher);
4227 self.stop_state.hash(hasher);
4228 self.index.hash(hasher);
4229 self.rule_start_index.hash(hasher);
4230 self.decision_start_index.hash(hasher);
4231 self.precedence.hash(hasher);
4232 self.recovery_state.hash(hasher);
4233 self.recovery_symbols_id.hash(hasher);
4234 }
4235}
4236
4237struct FastRecoveryRequest<'a, 'b> {
4238 atn: &'a Atn,
4239 transition: ParserTransition<'a>,
4240 expected_symbols: Rc<BTreeSet<i32>>,
4241 target: usize,
4242 request: FastRecognizeRequest,
4243 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4244 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4245 expected: &'b mut ExpectedTokens,
4246}
4247
4248struct FastCurrentTokenDeletionRequest<'a, 'b> {
4249 atn: &'a Atn,
4250 expected_symbols: Rc<BTreeSet<i32>>,
4251 request: FastRecognizeRequest,
4252 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4253 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4254 expected: &'b mut ExpectedTokens,
4255}
4256
4257#[derive(Clone, Copy)]
4258struct FastChildRuleFailureRecoveryRequest<'a> {
4259 atn: &'a Atn,
4260 rule_index: usize,
4261 start_index: usize,
4262 follow_state: usize,
4263 stop_state: usize,
4264 expected: &'a ExpectedTokens,
4265}
4266
4267struct RecoveryRequest<'a, 'b> {
4268 atn: &'a Atn,
4269 transition: ParserTransition<'a>,
4270 expected_symbols: BTreeSet<i32>,
4271 target: usize,
4272 request: RecognizeRequest<'a>,
4273 visiting: &'b mut BTreeSet<RecognizeKey>,
4274 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4275 expected: &'b mut ExpectedTokens,
4276}
4277
4278struct CurrentTokenDeletionRequest<'a, 'b> {
4279 atn: &'a Atn,
4280 expected_symbols: BTreeSet<i32>,
4281 request: RecognizeRequest<'a>,
4282 visiting: &'b mut BTreeSet<RecognizeKey>,
4283 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4284 expected: &'b mut ExpectedTokens,
4285}
4286
4287struct ConsumingFailureFallback<'a> {
4290 atn: &'a Atn,
4291 target: usize,
4292 request: RecognizeRequest<'a>,
4293 symbol: i32,
4294 expected_symbols: BTreeSet<i32>,
4295 decision_start_index: Option<usize>,
4296 decision: Option<usize>,
4297}
4298
4299struct ChildRuleFailureRecovery<'a> {
4302 atn: &'a Atn,
4303 rule_index: usize,
4304 start_index: usize,
4305 follow_state: usize,
4306 stop_state: usize,
4307 member_values: BTreeMap<usize, i64>,
4308 expected: &'a ExpectedTokens,
4309}
4310
4311#[derive(Clone, Copy, Debug)]
4313struct PredicateEval<'a> {
4314 index: usize,
4315 rule_index: usize,
4316 pred_index: usize,
4317 predicates: &'a [(usize, usize, ParserPredicate)],
4318 semantics: Option<&'a ParserSemantics>,
4319 context: Option<&'a ParserRuleContext>,
4320 local_int_arg: Option<(usize, i64)>,
4321 member_values: &'a BTreeMap<usize, i64>,
4322}
4323
4324#[derive(Clone, Copy, Debug)]
4325struct ParserSemanticHookRequest<'a> {
4326 index: usize,
4327 rule_index: usize,
4328 pred_index: usize,
4329 context: Option<&'a ParserRuleContext>,
4330 local_int_arg: Option<(usize, i64)>,
4331 member_values: &'a BTreeMap<usize, i64>,
4332}
4333
4334struct ParserSemIrCtx<'a, S, H>
4343where
4344 S: TokenSource,
4345 H: SemanticHooks,
4346{
4347 input: &'a mut CommonTokenStream<S>,
4348 tree_storage: &'a ParseTreeStorage,
4349 semantic_hooks: &'a mut H,
4350 rule_index: usize,
4351 coordinate_index: usize,
4352 rule_name: Option<&'a str>,
4353 context: Option<&'a ParserRuleContext>,
4354 local_int_arg: Option<(usize, i64)>,
4355 member_values: &'a BTreeMap<usize, i64>,
4356 invoked_predicates: &'a mut Vec<(usize, usize)>,
4357 unknown_predicate_policy: UnknownSemanticPolicy,
4361 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4362}
4363
4364impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4365where
4366 S: TokenSource,
4367 H: SemanticHooks,
4368{
4369 type TokenText<'a>
4370 = TokenView<'a>
4371 where
4372 Self: 'a;
4373
4374 fn la(&mut self, offset: isize) -> i64 {
4375 i64::from(self.input.la(offset))
4376 }
4377
4378 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4379 self.input.lt(offset)
4380 }
4381
4382 fn token_index_adjacent(&mut self) -> bool {
4383 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4384 return false;
4385 };
4386 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4387 return false;
4388 };
4389 first + 1 == second
4390 }
4391
4392 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4393 self.context.and_then(|context| {
4394 context
4395 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4396 .next()
4397 .map(crate::tree::RuleNodeView::text)
4398 })
4399 }
4400
4401 fn member(&self, member: usize) -> Option<i64> {
4402 Some(self.member_values.get(&member).copied().unwrap_or_default())
4403 }
4404
4405 fn local_arg(&self) -> Option<i64> {
4406 self.local_int_arg.map(|(_, value)| value)
4407 }
4408
4409 fn column(&self) -> Option<i64> {
4410 None
4411 }
4412
4413 fn token_start_column(&self) -> Option<i64> {
4414 None
4415 }
4416
4417 fn token_text_so_far(&self) -> Option<String> {
4418 None
4419 }
4420
4421 fn hook(&mut self, _hook: HookId) -> bool {
4422 let mut ctx = ParserSemCtx {
4423 input: &mut *self.input,
4424 tree_storage: self.tree_storage,
4425 rule_index: self.rule_index,
4426 coordinate_index: self.coordinate_index,
4427 rule_name: self.rule_name.map(str::to_owned),
4428 context: self.context,
4429 tree: None,
4430 local_int_arg: self.local_int_arg,
4431 member_values: self.member_values,
4432 action: None,
4433 };
4434 match self
4435 .semantic_hooks
4436 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4437 {
4438 Some(result) => result,
4439 None => apply_unknown_predicate_policy(
4443 self.unknown_predicate_policy,
4444 self.rule_index,
4445 self.coordinate_index,
4446 self.unknown_predicate_hits,
4447 ),
4448 }
4449 }
4450
4451 fn trace_bool(&mut self, value: bool) -> bool {
4452 let key = (self.rule_index, self.coordinate_index);
4453 if !self.invoked_predicates.contains(&key) {
4454 self.invoked_predicates.push(key);
4455 use std::io::Write as _;
4456 let mut stdout = std::io::stdout().lock();
4457 let _ = writeln!(stdout, "eval={value}");
4458 }
4459 value
4460 }
4461}
4462
4463struct PredicateFailureRecovery<'a> {
4465 rule_index: usize,
4466 index: usize,
4467 message: &'a str,
4468 member_values: BTreeMap<usize, i64>,
4469 return_values: BTreeMap<String, i64>,
4470 rule_alt_number: usize,
4471}
4472
4473#[derive(Debug)]
4474enum DirectAdaptiveParseControl {
4475 Fallback(DirectAdaptiveFallback),
4476}
4477
4478#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4479enum DirectAdaptiveFallback {
4480 Action,
4481 InvalidAlt,
4482 LeftRecursiveBoundary,
4483 MissingAtn,
4484 NoTransition,
4485 Predicate,
4486 Prediction,
4487 Precedence,
4488 RuleStop,
4489 SemanticContext,
4490 StepLimit,
4491 TokenMismatch,
4492 UnknownDecision,
4493}
4494
4495type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
4496
4497struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
4498where
4499 S: TokenSource,
4500 H: SemanticHooks,
4501{
4502 parser: &'sim mut BaseParser<S, H>,
4503 atn: &'atn Atn,
4504 simulator: &'sim mut ParserAtnSimulator<'atn>,
4505 decision_by_state: Vec<Option<usize>>,
4506 steps: usize,
4507}
4508
4509#[derive(Clone, Debug, Eq, PartialEq)]
4519pub struct GeneratedMatch {
4520 children: GeneratedMatchChildren,
4521 consumed_eof: bool,
4522}
4523
4524#[derive(Clone, Copy)]
4525enum GeneratedExpectedSymbols<'a> {
4526 Tree(&'a BTreeSet<i32>),
4527 TokenSet(ParserIntervalSet<'a>),
4528 TokenSetComplement {
4529 set: ParserIntervalSet<'a>,
4530 min_vocabulary: i32,
4531 max_vocabulary: i32,
4532 },
4533}
4534
4535impl GeneratedExpectedSymbols<'_> {
4536 fn is_empty(self) -> bool {
4537 match self {
4538 Self::Tree(symbols) => symbols.is_empty(),
4539 Self::TokenSet(set) => set.is_empty(),
4540 Self::TokenSetComplement {
4541 set,
4542 min_vocabulary,
4543 max_vocabulary,
4544 } => (min_vocabulary..=max_vocabulary).all(|symbol| set.contains(symbol)),
4545 }
4546 }
4547
4548 fn first(self) -> Option<i32> {
4549 match self {
4550 Self::Tree(symbols) => symbols.iter().next().copied(),
4551 Self::TokenSet(set) => set.ranges().next().map(|(start, _)| start),
4552 Self::TokenSetComplement {
4553 set,
4554 min_vocabulary,
4555 max_vocabulary,
4556 } => (min_vocabulary..=max_vocabulary).find(|symbol| !set.contains(*symbol)),
4557 }
4558 }
4559
4560 fn display(self, vocabulary: &Vocabulary) -> String {
4561 match self {
4562 Self::Tree(symbols) => expected_symbols_display(symbols, vocabulary),
4563 Self::TokenSet(set) => expected_symbols_display_iter(
4564 set.ranges().flat_map(|(start, stop)| start..=stop),
4565 vocabulary,
4566 ),
4567 Self::TokenSetComplement {
4568 set,
4569 min_vocabulary,
4570 max_vocabulary,
4571 } => expected_symbols_display_iter(
4572 (min_vocabulary..=max_vocabulary).filter(|symbol| !set.contains(*symbol)),
4573 vocabulary,
4574 ),
4575 }
4576 }
4577}
4578
4579#[derive(Clone, Debug, Eq, PartialEq)]
4580enum GeneratedMatchChildren {
4581 One(ParseTree),
4582 Many(Vec<ParseTree>),
4583}
4584
4585struct GeneratedMatchChildrenIntoIter {
4586 one: Option<ParseTree>,
4587 many: Option<std::vec::IntoIter<ParseTree>>,
4588}
4589
4590impl Iterator for GeneratedMatchChildrenIntoIter {
4591 type Item = ParseTree;
4592
4593 fn next(&mut self) -> Option<Self::Item> {
4594 self.one
4595 .take()
4596 .or_else(|| self.many.as_mut().and_then(Iterator::next))
4597 }
4598}
4599
4600impl GeneratedMatch {
4601 #[must_use]
4605 pub fn children(&self) -> &[ParseTree] {
4606 match &self.children {
4607 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
4608 GeneratedMatchChildren::Many(children) => children,
4609 }
4610 }
4611
4612 #[must_use]
4615 pub fn into_children(self) -> Vec<ParseTree> {
4616 match self.children {
4617 GeneratedMatchChildren::One(child) => vec![child],
4618 GeneratedMatchChildren::Many(children) => children,
4619 }
4620 }
4621
4622 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
4624 match self.children {
4625 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
4626 one: Some(child),
4627 many: None,
4628 },
4629 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
4630 one: None,
4631 many: Some(children.into_iter()),
4632 },
4633 }
4634 }
4635
4636 #[must_use]
4638 pub const fn consumed_eof(&self) -> bool {
4639 self.consumed_eof
4640 }
4641}
4642
4643impl<S> BaseParser<S, NoSemanticHooks>
4644where
4645 S: TokenSource,
4646{
4647 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
4650 Self::with_semantic_hooks(input, data, NoSemanticHooks)
4651 }
4652}
4653
4654impl<S, H> BaseParser<S, H>
4655where
4656 S: TokenSource,
4657 H: SemanticHooks,
4658{
4659 pub fn with_semantic_hooks(
4661 input: CommonTokenStream<S>,
4662 data: RecognizerData,
4663 semantic_hooks: H,
4664 ) -> Self {
4665 Self {
4666 input,
4667 tree: ParseTreeStorage::new(),
4668 data,
4669 semantic_hooks,
4670 build_parse_trees: true,
4671 syntax_errors: 0,
4672 report_diagnostic_errors: false,
4673 prediction_mode: PredictionMode::Ll,
4674 prediction_diagnostics: Vec::new(),
4675 reported_prediction_diagnostics: BTreeSet::new(),
4676 generated_parser_diagnostics: Vec::new(),
4677 generated_sync_expected: None,
4678 int_members: BTreeMap::new(),
4679 rule_context_stack: Vec::new(),
4680 rule_context_version: 0,
4681 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
4682 pending_invoking_states: Vec::new(),
4683 precedence_stack: vec![0],
4684 invoked_predicates: Vec::new(),
4685 bail_on_error: false,
4686 unknown_predicate_policy: UnknownSemanticPolicy::default(),
4687 unknown_predicate_hits: Vec::new(),
4688 unhandled_action_hits: Vec::new(),
4689 rule_first_set_cache: Vec::new(),
4690 state_expected_cache: FxHashMap::default(),
4691 state_expected_token_cache: FxHashMap::default(),
4692 rule_stop_reach_cache: Vec::new(),
4693 recovery_symbols_intern: FxHashMap::default(),
4694 decision_lookahead_cache: FxHashMap::default(),
4695 ll1_decision_cache: FxHashMap::default(),
4696 fast_predicate_cache: FxHashMap::default(),
4697 empty_cycle_cache: Vec::new(),
4698 empty_cycle_cache_atn: None,
4699 clean_memo_mode: CleanMemoMode::Probe,
4700 clean_memo_probe_seen: FxHashSet::default(),
4701 clean_memo_probe_samples: 0,
4702 clean_memo_probe_repeats: 0,
4703 clean_memo_sparse_samples: 0,
4704 fast_recognize_scratch: FastRecognizeTopScratch::default(),
4705 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
4706 empty_recovery_symbols: Rc::new(BTreeSet::new()),
4707 fast_first_set_prefilter: true,
4708 fast_recovery_enabled: true,
4709 fast_token_nodes_enabled: true,
4710 recognition_arena: RecognitionArena::default(),
4711 last_recognition_arena_root: NodeSeqId::EMPTY,
4712 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
4713 }
4714 }
4715
4716 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
4717 &mut self.input
4718 }
4719
4720 pub fn reset(&mut self) {
4725 self.input.seek(0);
4726 self.tree.reset();
4727 self.data.set_state(-1);
4728 self.syntax_errors = 0;
4729 self.prediction_diagnostics.clear();
4730 self.reported_prediction_diagnostics.clear();
4731 self.generated_parser_diagnostics.clear();
4732 self.generated_sync_expected = None;
4733 self.rule_context_stack.clear();
4734 self.advance_rule_context_version();
4735 self.left_recursive_caller_overlap_cache = std::array::from_fn(|_| None);
4736 self.pending_invoking_states.clear();
4737 self.precedence_stack.clear();
4738 self.precedence_stack.push(0);
4739 self.invoked_predicates.clear();
4740 self.unknown_predicate_hits.clear();
4741 self.unhandled_action_hits.clear();
4742 self.reset_per_parse_caches();
4743 self.fast_first_set_prefilter = true;
4744 self.fast_recovery_enabled = true;
4745 self.fast_token_nodes_enabled = self.build_parse_trees;
4746 self.reset_recognition_arena();
4747 }
4748
4749 pub fn set_token_stream(&mut self, input: CommonTokenStream<S>) {
4751 self.input = input;
4752 self.reset();
4753 }
4754
4755 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
4766 self.unknown_predicate_policy = policy;
4767 }
4768
4769 #[must_use]
4775 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
4776 let error = self.unknown_semantic_error();
4777 self.unknown_predicate_hits.clear();
4778 self.unhandled_action_hits.clear();
4779 error
4780 }
4781
4782 pub fn reset_unknown_semantic_hits(&mut self) {
4789 self.unknown_predicate_hits.clear();
4790 self.unhandled_action_hits.clear();
4791 }
4792
4793 #[must_use]
4795 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
4796 &self.input
4797 }
4798
4799 #[must_use]
4801 pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<S> {
4802 &mut self.input
4803 }
4804
4805 #[must_use]
4807 pub const fn token_store(&self) -> &TokenStore {
4808 self.input.token_store()
4809 }
4810
4811 #[must_use]
4813 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
4814 &self.tree
4815 }
4816
4817 #[must_use]
4819 pub fn node(&self, id: NodeId) -> Node<'_> {
4820 self.tree
4821 .node(self.input.token_store(), id)
4822 .expect("parser-produced node ID should remain valid")
4823 }
4824
4825 #[must_use]
4827 pub fn into_token_stream(self) -> CommonTokenStream<S> {
4828 self.input
4829 }
4830
4831 #[must_use]
4833 pub fn into_token_store(self) -> TokenStore {
4834 self.input.into_token_store()
4835 }
4836
4837 #[must_use]
4839 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
4840 ParsedFile::new(self.input.into_token_store(), self.tree, root)
4841 }
4842
4843 pub const fn number_of_syntax_errors(&self) -> usize {
4846 self.syntax_errors
4847 }
4848
4849 #[must_use]
4855 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
4856 self.recognition_arena.stats(
4857 self.last_recognition_arena_root,
4858 self.last_recognition_arena_diagnostics,
4859 )
4860 }
4861
4862 pub const fn record_generated_syntax_error(&mut self) {
4865 self.record_syntax_errors(1);
4866 }
4867
4868 const fn record_syntax_errors(&mut self, count: usize) {
4869 self.syntax_errors = self.syntax_errors.saturating_add(count);
4870 }
4871
4872 pub fn report_token_source_errors(&mut self) {
4875 let errors = self.input.drain_source_errors();
4876 self.dispatch_token_source_errors(&errors);
4877 }
4878
4879 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
4882 GeneratedDiagnosticsCheckpoint {
4883 diagnostics_len: self.generated_parser_diagnostics.len(),
4884 syntax_errors: self.syntax_errors,
4885 tree: self.tree.checkpoint(),
4886 }
4887 }
4888
4889 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
4891 self.generated_parser_diagnostics
4892 .truncate(marker.diagnostics_len);
4893 self.syntax_errors = marker.syntax_errors;
4894 self.generated_sync_expected = None;
4895 self.tree.rollback(marker.tree);
4896 }
4897
4898 pub fn report_generated_parser_diagnostics(&mut self) {
4900 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
4901 let token_errors = self.input.drain_source_errors();
4902 self.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
4903 }
4904
4905 fn dispatch_parser_diagnostic(&self, diagnostic: &ParserDiagnostic) {
4906 self.notify_error_listeners(
4907 diagnostic.line,
4908 diagnostic.column,
4909 &diagnostic.message,
4910 None,
4911 );
4912 }
4913
4914 fn dispatch_parser_diagnostics<'a>(
4915 &self,
4916 diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>,
4917 ) {
4918 for diagnostic in diagnostics {
4919 self.dispatch_parser_diagnostic(diagnostic);
4920 }
4921 }
4922
4923 fn dispatch_token_source_error(&self, source_error: &TokenSourceError) {
4924 if self.input.token_source().report_error(source_error) {
4925 return;
4926 }
4927 self.notify_error_listeners(
4928 source_error.line,
4929 source_error.column,
4930 &source_error.message,
4931 None,
4932 );
4933 }
4934
4935 fn dispatch_token_source_errors(&self, errors: &[TokenSourceError]) {
4936 for error in errors {
4937 self.dispatch_token_source_error(error);
4938 }
4939 }
4940
4941 fn dispatch_generated_diagnostics(
4944 &self,
4945 parser_diagnostics: &[ParserDiagnostic],
4946 token_errors: &[TokenSourceError],
4947 ) {
4948 let mut token_iter = token_errors.iter().peekable();
4954 for diagnostic in parser_diagnostics {
4955 while let Some(error) = token_iter.peek() {
4956 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
4957 self.dispatch_token_source_error(error);
4958 token_iter.next();
4959 } else {
4960 break;
4961 }
4962 }
4963 self.dispatch_parser_diagnostic(diagnostic);
4964 }
4965 for error in token_iter {
4966 self.dispatch_token_source_error(error);
4967 }
4968 }
4969
4970 pub fn record_generated_ambiguity_diagnostic(
4973 &mut self,
4974 atn: &Atn,
4975 state_number: usize,
4976 start_index: usize,
4977 stop_index: usize,
4978 alts: &[usize],
4979 ) {
4980 if !self.report_diagnostic_errors || alts.len() < 2 {
4981 return;
4982 }
4983 let Some(decision) = atn
4984 .decision_to_state()
4985 .iter()
4986 .position(|candidate| candidate == state_number)
4987 else {
4988 return;
4989 };
4990 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
4991 return;
4992 };
4993 let rule_name = self
4994 .rule_names()
4995 .get(rule_index)
4996 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
4997 let input = display_input_text(&self.input.text(start_index, stop_index));
4998 let alts = alts
4999 .iter()
5000 .map(usize::to_string)
5001 .collect::<Vec<_>>()
5002 .join(", ");
5003 let key = (decision, start_index, format!("{alts}:{input}"));
5004 if !self.reported_prediction_diagnostics.insert(key) {
5005 return;
5006 }
5007 let start_diagnostic = diagnostic_for_token(
5008 self.token_at(start_index),
5009 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
5010 );
5011 let stop_diagnostic = diagnostic_for_token(
5012 self.token_at(stop_index),
5013 format!(
5014 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
5015 ),
5016 );
5017 self.generated_parser_diagnostics.push(start_diagnostic);
5018 self.generated_parser_diagnostics.push(stop_diagnostic);
5019 }
5020
5021 pub fn record_generated_prediction_diagnostic(
5024 &mut self,
5025 atn: &Atn,
5026 state_number: usize,
5027 prediction: &ParserAtnPrediction,
5028 ) {
5029 let Some(diagnostic) = &prediction.diagnostic else {
5030 return;
5031 };
5032 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5033 return;
5034 }
5035 let Some(decision) = atn
5036 .decision_to_state()
5037 .iter()
5038 .position(|candidate| candidate == state_number)
5039 else {
5040 return;
5041 };
5042 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5043 return;
5044 };
5045 let rule_name = self
5046 .rule_names()
5047 .get(rule_index)
5048 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5049 let attempt_input = display_input_text(
5050 &self
5051 .input
5052 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5053 );
5054 let result_input = display_input_text(
5055 &self
5056 .input
5057 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5058 );
5059 let alts = diagnostic
5060 .conflicting_alts
5061 .iter()
5062 .map(usize::to_string)
5063 .collect::<Vec<_>>()
5064 .join(", ");
5065 let key = (
5066 decision,
5067 diagnostic.start_index,
5068 format!(
5069 "{:?}:{alts}:{attempt_input}:{result_input}",
5070 diagnostic.kind
5071 ),
5072 );
5073 if !self.reported_prediction_diagnostics.insert(key) {
5074 return;
5075 }
5076 let attempt_diagnostic = diagnostic_for_token(
5077 self.token_at(diagnostic.sll_stop_index),
5078 format!(
5079 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5080 ),
5081 );
5082 self.generated_parser_diagnostics.push(attempt_diagnostic);
5083 let message = match diagnostic.kind {
5084 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5085 if !diagnostic.exact {
5090 return;
5091 }
5092 format!(
5093 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5094 )
5095 }
5096 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5097 format!(
5098 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5099 )
5100 }
5101 };
5102 let result_diagnostic =
5103 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5104 self.generated_parser_diagnostics.push(result_diagnostic);
5105 }
5106
5107 pub fn la(&self, offset: isize) -> i32 {
5108 self.input.la_token(offset)
5109 }
5110
5111 pub fn consume(&mut self) {
5112 IntStream::consume(&mut self.input);
5113 }
5114
5115 pub fn set_int_member(&mut self, member: usize, value: i64) {
5117 self.int_members.insert(member, value);
5118 }
5119
5120 pub fn int_member(&self, member: usize) -> Option<i64> {
5122 self.int_members.get(&member).copied()
5123 }
5124
5125 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
5128 self.int_members.clone()
5129 }
5130
5131 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
5133 self.int_members = members;
5134 }
5135
5136 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5138 let value = self.int_members.entry(member).or_default();
5139 *value += delta;
5140 *value
5141 }
5142
5143 fn token_type_for_id(&self, id: TokenId) -> i32 {
5144 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5145 }
5146
5147 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5148 if self.build_parse_trees {
5149 self.tree.terminal(id)
5150 } else {
5151 NodeId::placeholder()
5152 }
5153 }
5154
5155 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5156 if self.build_parse_trees {
5157 self.tree.error(id)
5158 } else {
5159 NodeId::placeholder()
5160 }
5161 }
5162
5163 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5164 context.set_start_id(id);
5165 }
5166
5167 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5168 context.set_stop_id(id);
5169 }
5170
5171 fn insert_synthetic_token(
5172 &mut self,
5173 token_type: i32,
5174 text: String,
5175 line: usize,
5176 column: usize,
5177 ) -> Result<TokenId, AntlrError> {
5178 self.input
5179 .insert(
5180 TokenSpec::explicit(token_type, text)
5181 .with_span(usize::MAX, usize::MAX)
5182 .with_byte_span(0, 0)
5183 .with_position(line, column),
5184 )
5185 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5186 }
5187
5188 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5195 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5196 line: 0,
5197 column: 0,
5198 message: "missing current token".to_owned(),
5199 })?;
5200 let current_type = self.token_type_for_id(current);
5201 if current_type == token_type {
5202 self.consume();
5203 Ok(self.terminal_tree(current))
5204 } else {
5205 Err(AntlrError::MismatchedInput {
5206 expected: self.vocabulary().display_name(token_type),
5207 found: self.vocabulary().display_name(current_type),
5208 })
5209 }
5210 }
5211
5212 pub fn match_token_recovering(
5216 &mut self,
5217 token_type: i32,
5218 follow_state: usize,
5219 atn: &Atn,
5220 ) -> Result<GeneratedMatch, AntlrError> {
5221 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5222 line: 0,
5223 column: 0,
5224 message: "missing current token".to_owned(),
5225 })?;
5226 let current_type = self.token_type_for_id(current);
5227 if current_type == token_type {
5228 self.generated_sync_expected = None;
5229 let consumed_eof = current_type == TOKEN_EOF;
5230 self.consume();
5231 return Ok(GeneratedMatch {
5232 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5233 consumed_eof,
5234 });
5235 }
5236 let mut expected_symbols = BTreeSet::new();
5237 expected_symbols.insert(token_type);
5238 self.recover_generated_match(
5239 current,
5240 GeneratedExpectedSymbols::Tree(&expected_symbols),
5241 follow_state,
5242 atn,
5243 |symbol| symbol == token_type,
5244 )
5245 }
5246
5247 pub fn match_set_recovering(
5248 &mut self,
5249 intervals: &[(i32, i32)],
5250 follow_state: usize,
5251 atn: &Atn,
5252 ) -> Result<GeneratedMatch, AntlrError> {
5253 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5254 line: 0,
5255 column: 0,
5256 message: "missing current token".to_owned(),
5257 })?;
5258 let current_type = self.token_type_for_id(current);
5259 if interval_set_contains(intervals, current_type) {
5260 self.generated_sync_expected = None;
5261 let consumed_eof = current_type == TOKEN_EOF;
5262 self.consume();
5263 return Ok(GeneratedMatch {
5264 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5265 consumed_eof,
5266 });
5267 }
5268 let expected_symbols = interval_symbols(intervals);
5269 self.recover_generated_match(
5270 current,
5271 GeneratedExpectedSymbols::Tree(&expected_symbols),
5272 follow_state,
5273 atn,
5274 |symbol| interval_set_contains(intervals, symbol),
5275 )
5276 }
5277
5278 pub fn match_token_set_recovering(
5279 &mut self,
5280 set: ParserIntervalSet<'_>,
5281 follow_state: usize,
5282 atn: &Atn,
5283 ) -> Result<GeneratedMatch, AntlrError> {
5284 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5285 line: 0,
5286 column: 0,
5287 message: "missing current token".to_owned(),
5288 })?;
5289 let current_type = self.token_type_for_id(current);
5290 if set.contains(current_type) {
5291 self.generated_sync_expected = None;
5292 let consumed_eof = current_type == TOKEN_EOF;
5293 self.consume();
5294 return Ok(GeneratedMatch {
5295 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5296 consumed_eof,
5297 });
5298 }
5299 self.recover_generated_match(
5300 current,
5301 GeneratedExpectedSymbols::TokenSet(set),
5302 follow_state,
5303 atn,
5304 |symbol| set.contains(symbol),
5305 )
5306 }
5307
5308 pub fn match_not_set_recovering(
5309 &mut self,
5310 intervals: &[(i32, i32)],
5311 min_vocabulary: i32,
5312 max_vocabulary: i32,
5313 follow_state: usize,
5314 atn: &Atn,
5315 ) -> Result<GeneratedMatch, AntlrError> {
5316 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5317 line: 0,
5318 column: 0,
5319 message: "missing current token".to_owned(),
5320 })?;
5321 let current_type = self.token_type_for_id(current);
5322 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5323 && !interval_set_contains(intervals, current_type)
5324 {
5325 self.generated_sync_expected = None;
5326 let consumed_eof = current_type == TOKEN_EOF;
5327 self.consume();
5328 return Ok(GeneratedMatch {
5329 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5330 consumed_eof,
5331 });
5332 }
5333 let expected_symbols =
5334 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
5335 self.recover_generated_match(
5336 current,
5337 GeneratedExpectedSymbols::Tree(&expected_symbols),
5338 follow_state,
5339 atn,
5340 |symbol| {
5341 (min_vocabulary..=max_vocabulary).contains(&symbol)
5342 && !interval_set_contains(intervals, symbol)
5343 },
5344 )
5345 }
5346
5347 pub fn match_not_token_set_recovering(
5348 &mut self,
5349 set: ParserIntervalSet<'_>,
5350 min_vocabulary: i32,
5351 max_vocabulary: i32,
5352 follow_state: usize,
5353 atn: &Atn,
5354 ) -> Result<GeneratedMatch, AntlrError> {
5355 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5356 line: 0,
5357 column: 0,
5358 message: "missing current token".to_owned(),
5359 })?;
5360 let current_type = self.token_type_for_id(current);
5361 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
5362 {
5363 self.generated_sync_expected = None;
5364 let consumed_eof = current_type == TOKEN_EOF;
5365 self.consume();
5366 return Ok(GeneratedMatch {
5367 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5368 consumed_eof,
5369 });
5370 }
5371 self.recover_generated_match(
5372 current,
5373 GeneratedExpectedSymbols::TokenSetComplement {
5374 set,
5375 min_vocabulary,
5376 max_vocabulary,
5377 },
5378 follow_state,
5379 atn,
5380 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
5381 )
5382 }
5383
5384 fn recover_generated_match(
5385 &mut self,
5386 current: TokenId,
5387 expected_symbols: GeneratedExpectedSymbols<'_>,
5388 follow_state: usize,
5389 atn: &Atn,
5390 matches: impl Fn(i32) -> bool,
5391 ) -> Result<GeneratedMatch, AntlrError> {
5392 let expected_display = expected_symbols.display(self.vocabulary());
5393 let (current_type, current_line, current_column, current_display) = {
5394 let token = self
5395 .input
5396 .token_view(current)
5397 .expect("current token ID should be valid");
5398 (
5399 token.token_type(),
5400 token.line(),
5401 token.column(),
5402 token_input_display(&token),
5403 )
5404 };
5405 if self.bail_on_error {
5406 return Err(AntlrError::ParserError {
5407 line: current_line,
5408 column: current_column,
5409 message: format!("mismatched input {current_display} expecting {expected_display}"),
5410 });
5411 }
5412 if current_type != TOKEN_EOF
5413 && let Some(next) = self.input.lt_id(2)
5414 && matches(self.token_type_for_id(next))
5415 {
5416 let message =
5417 format!("extraneous input {current_display} expecting {expected_display}");
5418 self.push_generated_parser_diagnostic(ParserDiagnostic {
5419 line: current_line,
5420 column: current_column,
5421 message,
5422 });
5423 self.record_syntax_errors(1);
5424 self.generated_sync_expected = None;
5425 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
5428 self.consume();
5429 self.consume();
5430 return Ok(GeneratedMatch {
5431 children: GeneratedMatchChildren::Many(vec![
5432 self.error_tree(current),
5433 self.terminal_tree(next),
5434 ]),
5435 consumed_eof,
5436 });
5437 }
5438 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
5439 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
5448 && self
5449 .cached_state_expected_symbols(atn, follow_state)
5450 .contains(&TOKEN_EOF);
5451 if follow_symbols.contains(¤t_type)
5452 && (current_type != TOKEN_EOF
5453 || self.rule_context_stack.len() > 1
5454 || expected_symbols.is_empty()
5455 || follow_explicitly_expects_eof)
5456 {
5457 let message = format!("missing {expected_display} at {current_display}");
5458 self.push_generated_parser_diagnostic(ParserDiagnostic {
5459 line: current_line,
5460 column: current_column,
5461 message,
5462 });
5463 self.record_syntax_errors(1);
5464 self.generated_sync_expected = None;
5465 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
5466 let missing_display = expected_symbol_display(token_type, self.vocabulary());
5467 let token = self.insert_synthetic_token(
5468 token_type,
5469 format!("<missing {missing_display}>"),
5470 current_line,
5471 current_column,
5472 )?;
5473 return Ok(GeneratedMatch {
5478 children: GeneratedMatchChildren::One(self.error_tree(token)),
5479 consumed_eof: false,
5480 });
5481 }
5482 let mismatch_expected_display = self
5483 .generated_sync_expected
5484 .take()
5485 .map_or(expected_display, |symbols| {
5486 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
5487 });
5488 Err(AntlrError::ParserError {
5489 line: current_line,
5490 column: current_column,
5491 message: format!(
5492 "mismatched input {current_display} expecting {mismatch_expected_display}"
5493 ),
5494 })
5495 }
5496
5497 fn generated_recovery_follow_symbols(
5498 &mut self,
5499 atn: &Atn,
5500 follow_state: usize,
5501 ) -> BTreeSet<i32> {
5502 let mut follow = self
5503 .cached_state_expected_symbols(atn, follow_state)
5504 .as_ref()
5505 .clone();
5506 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
5507 follow.extend(self.context_expected_symbols(atn));
5508 }
5509 follow
5510 }
5511
5512 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
5513 self.match_token(TOKEN_EOF)
5514 }
5515
5516 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
5517 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
5518 }
5519
5520 pub fn match_not_set(
5521 &mut self,
5522 intervals: &[(i32, i32)],
5523 min_vocabulary: i32,
5524 max_vocabulary: i32,
5525 ) -> Result<ParseTree, AntlrError> {
5526 self.match_interval_condition(intervals, |symbol| {
5527 (min_vocabulary..=max_vocabulary).contains(&symbol)
5528 && !interval_set_contains(intervals, symbol)
5529 })
5530 }
5531
5532 fn match_interval_condition(
5533 &mut self,
5534 intervals: &[(i32, i32)],
5535 matches: impl FnOnce(i32) -> bool,
5536 ) -> Result<ParseTree, AntlrError> {
5537 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5538 line: 0,
5539 column: 0,
5540 message: "missing current token".to_owned(),
5541 })?;
5542 let current_type = self.token_type_for_id(current);
5543 if matches(current_type) {
5544 self.consume();
5545 Ok(self.terminal_tree(current))
5546 } else {
5547 Err(AntlrError::MismatchedInput {
5548 expected: self.interval_display(intervals),
5549 found: self.vocabulary().display_name(current_type),
5550 })
5551 }
5552 }
5553
5554 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
5555 let values = intervals
5556 .iter()
5557 .map(|(start, stop)| {
5558 if start == stop {
5559 self.vocabulary().display_name(*start)
5560 } else {
5561 format!(
5562 "{}..{}",
5563 self.vocabulary().display_name(*start),
5564 self.vocabulary().display_name(*stop)
5565 )
5566 }
5567 })
5568 .collect::<Vec<_>>()
5569 .join(", ");
5570 format!("{{{values}}}")
5571 }
5572
5573 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
5574 if self.build_parse_trees {
5575 self.tree.finish_rule(context)
5576 } else {
5577 NodeId::placeholder()
5578 }
5579 }
5580
5581 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
5584 self.set_state(state);
5585 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
5586 self.rule_context_stack.push(RuleContextFrame {
5587 rule_index,
5588 invoking_state,
5589 });
5590 self.advance_rule_context_version();
5591 let start_index = self.current_visible_index();
5592 let mut context = ParserRuleContext::new(rule_index, invoking_state);
5593 if let Some(token) = self.token_id_at(start_index) {
5594 self.set_context_start(&mut context, token);
5595 }
5596 context
5597 }
5598
5599 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
5606 let marker = self.pending_invoking_states.len();
5607 self.pending_invoking_states.push(invoking_state);
5608 marker
5609 }
5610
5611 pub fn discard_invoking_state(&mut self, marker: usize) {
5613 self.pending_invoking_states.truncate(marker);
5614 }
5615
5616 pub fn exit_rule(&mut self) {
5618 self.rule_context_stack.pop();
5619 self.advance_rule_context_version();
5620 }
5621
5622 pub fn prediction_context_return_states<'a>(
5625 &'a self,
5626 atn: &'a Atn,
5627 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
5628 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
5629 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
5630 return None;
5631 };
5632 let Some(Transition::Rule { follow_state, .. }) = atn
5633 .state(state_number)
5634 .and_then(|state| state.transitions().first())
5635 .map(ParserTransition::data)
5636 else {
5637 return None;
5638 };
5639 Some(follow_state)
5640 })
5641 }
5642
5643 pub const fn rule_context_version(&self) -> usize {
5648 self.rule_context_version
5649 }
5650
5651 const fn advance_rule_context_version(&mut self) {
5652 self.rule_context_version = self.rule_context_version.wrapping_add(1);
5653 }
5654
5655 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
5660 if self.build_parse_trees {
5661 self.tree.add_child(context, child);
5662 } else {
5663 context.note_matched_child();
5664 }
5665 }
5666
5667 fn release_tree_scratch_if_idle(&mut self) {
5668 if self.rule_context_stack.is_empty() {
5669 self.tree.release_scratch();
5670 }
5671 }
5672
5673 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
5675 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5676 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5677 self.set_context_stop(&mut context, token);
5678 }
5679 let node = self.rule_node(context);
5680 self.exit_rule();
5681 self.release_tree_scratch_if_idle();
5682 node
5683 }
5684
5685 pub fn recover_generated_rule(
5692 &mut self,
5693 context: &mut ParserRuleContext,
5694 atn: &Atn,
5695 error: AntlrError,
5696 ) {
5697 let diagnostic = self.generated_rule_error_diagnostic(error);
5698 self.push_generated_parser_diagnostic(diagnostic);
5699 self.generated_sync_expected = None;
5700 let recovery_symbols = self.context_expected_symbols(atn);
5701 loop {
5702 let symbol = self.la(1);
5703 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
5704 break;
5705 }
5706 let Some(token) = self.input.lt_id(1) else {
5707 break;
5708 };
5709 self.consume();
5710 let child = self.error_tree(token);
5711 self.add_parse_child(context, child);
5712 }
5713 self.record_syntax_errors(1);
5714 }
5715
5716 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
5717 if self
5718 .generated_parser_diagnostics
5719 .iter()
5720 .any(|existing| existing == &diagnostic)
5721 {
5722 return;
5723 }
5724 self.generated_parser_diagnostics.push(diagnostic);
5725 }
5726
5727 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
5728 match error {
5729 AntlrError::ParserError {
5730 line,
5731 column,
5732 message,
5733 } => ParserDiagnostic {
5734 line,
5735 column,
5736 message,
5737 },
5738 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
5739 self.input.lt(1),
5740 format!("mismatched input {found} expecting {expected}"),
5741 ),
5742 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
5743 self.input.lt(1),
5744 format!("no viable alternative at input {input}"),
5745 ),
5746 AntlrError::LexerError {
5747 line,
5748 column,
5749 message,
5750 } => ParserDiagnostic {
5751 line,
5752 column,
5753 message,
5754 },
5755 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
5756 }
5757 }
5758
5759 pub fn finish_recursion_rule(
5761 &mut self,
5762 mut context: ParserRuleContext,
5763 consumed_eof: bool,
5764 ) -> ParseTree {
5765 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5766 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5767 self.set_context_stop(&mut context, token);
5768 }
5769 let node = self.rule_node(context);
5770 self.unroll_recursion_context();
5771 self.release_tree_scratch_if_idle();
5772 node
5773 }
5774
5775 pub fn enter_recursion_rule(
5777 &mut self,
5778 state: isize,
5779 rule_index: usize,
5780 precedence: i32,
5781 ) -> ParserRuleContext {
5782 self.precedence_stack.push(precedence);
5783 self.enter_rule(state, rule_index)
5784 }
5785
5786 pub fn push_new_recursion_context(
5788 &mut self,
5789 state: isize,
5790 rule_index: usize,
5791 ) -> ParserRuleContext {
5792 self.set_state(state);
5793 ParserRuleContext::new(rule_index, state)
5794 }
5795
5796 pub fn push_new_recursion_context_with_previous(
5799 &mut self,
5800 state: isize,
5801 rule_index: usize,
5802 current: &mut ParserRuleContext,
5803 ) {
5804 self.set_state(state);
5805 if let Some(stop) = self
5806 .rule_stop_token_index(self.input.index(), false)
5807 .and_then(|index| self.token_id_at(index))
5808 {
5809 self.set_context_stop(current, stop);
5810 }
5811 let invoking_state = current.invoking_state();
5812 let start = current.start_id();
5813 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
5814 if start.is_some() {
5815 replacement.set_start_from_context(current);
5816 }
5817 let previous = std::mem::replace(current, replacement);
5818 if self.build_parse_trees {
5819 let previous = self.rule_node(previous);
5820 self.tree.add_child(current, previous);
5821 }
5822 }
5823
5824 pub fn unroll_recursion_context(&mut self) {
5826 if self.precedence_stack.len() > 1 {
5827 self.precedence_stack.pop();
5828 }
5829 self.exit_rule();
5830 }
5831
5832 pub fn left_recursive_loop_enter_prediction(
5846 &mut self,
5847 atn: &Atn,
5848 state_number: usize,
5849 precedence: i32,
5850 ) -> Option<bool> {
5851 let symbol = self.la(1);
5852 if symbol == TOKEN_EOF {
5853 return Some(false);
5854 }
5855 let operator_lookahead =
5856 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
5857 let can_single = operator_lookahead.single_token.contains(symbol);
5858 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
5859 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
5860 if !can_single && !can_multi && !can_predicate {
5861 return Some(false);
5862 }
5863 if can_predicate && !can_single {
5864 return None;
5865 }
5866 if !can_single && can_multi && precedence > 0 {
5870 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
5871 if baseline.single_token.contains(symbol) {
5872 return None;
5873 }
5874 }
5875 let atn_key = SharedAtnCacheKey::for_atn(atn);
5876 let cached_overlap = self
5877 .left_recursive_caller_overlap_cache
5878 .iter()
5879 .flatten()
5880 .find(|entry| {
5881 entry.atn_key == atn_key
5882 && entry.state_number == state_number
5883 && entry.symbol == symbol
5884 && entry.context_version == self.rule_context_version
5885 })
5886 .map(|entry| entry.overlaps);
5887 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
5888 let overlaps = caller_context_can_match_symbol_before_state(
5889 atn,
5890 self.prediction_context_return_states(atn),
5891 state_number,
5892 symbol,
5893 );
5894 if let Some(slot) = self
5895 .left_recursive_caller_overlap_cache
5896 .iter_mut()
5897 .find(|slot| slot.is_none())
5898 {
5899 *slot = Some(LeftRecursiveCallerOverlap {
5900 atn_key,
5901 state_number,
5902 symbol,
5903 context_version: self.rule_context_version,
5904 overlaps,
5905 });
5906 }
5907 overlaps
5908 });
5909 if caller_overlaps {
5910 return None;
5911 }
5912 Some(true)
5913 }
5914
5915 fn cached_left_recursive_operator_lookahead(
5916 atn: &Atn,
5917 state_number: usize,
5918 precedence: i32,
5919 ) -> Rc<LeftRecursiveOperatorLookahead> {
5920 with_shared_atn_caches(atn, |cache| {
5921 let key = (state_number, precedence);
5922 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
5923 return Rc::clone(cached);
5924 }
5925 let lookahead = Rc::new(left_recursive_operator_lookahead(
5926 atn,
5927 state_number,
5928 precedence,
5929 ));
5930 cache
5931 .left_recursive_operator_lookahead
5932 .insert(key, Rc::clone(&lookahead));
5933 lookahead
5934 })
5935 }
5936
5937 pub fn left_recursive_loop_enter_matches(
5940 &mut self,
5941 atn: &Atn,
5942 state_number: usize,
5943 precedence: i32,
5944 ) -> bool {
5945 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
5946 }
5947
5948 pub fn precpred(&self, precedence: i32) -> bool {
5950 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
5951 }
5952
5953 pub fn parser_semantic_predicate_matches(
5956 &mut self,
5957 predicates: &[(usize, usize, ParserPredicate)],
5958 rule_index: usize,
5959 pred_index: usize,
5960 ) -> bool {
5961 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
5962 }
5963
5964 pub fn parser_semantic_predicate_matches_with_local(
5967 &mut self,
5968 predicates: &[(usize, usize, ParserPredicate)],
5969 rule_index: usize,
5970 pred_index: usize,
5971 local_int_arg: i32,
5972 ) -> bool {
5973 self.parser_semantic_predicate_matches_inner(
5974 predicates,
5975 rule_index,
5976 pred_index,
5977 Some((rule_index, i64::from(local_int_arg))),
5978 )
5979 }
5980
5981 fn parser_semantic_predicate_matches_inner(
5982 &mut self,
5983 predicates: &[(usize, usize, ParserPredicate)],
5984 rule_index: usize,
5985 pred_index: usize,
5986 local_int_arg: Option<(usize, i64)>,
5987 ) -> bool {
5988 let index = self.input.index();
5989 let member_values = self.int_members.clone();
5990 self.parser_predicate_matches(PredicateEval {
5991 index,
5992 rule_index,
5993 pred_index,
5994 predicates,
5995 semantics: None,
5996 context: None,
5997 local_int_arg,
5998 member_values: &member_values,
5999 })
6000 }
6001
6002 pub fn parser_semantic_predicate_matches_with_context_and_local(
6005 &mut self,
6006 predicates: &[(usize, usize, ParserPredicate)],
6007 rule_index: usize,
6008 pred_index: usize,
6009 context: &ParserRuleContext,
6010 local_int_arg: i32,
6011 ) -> bool {
6012 let index = self.input.index();
6013 let member_values = self.int_members.clone();
6014 self.parser_predicate_matches(PredicateEval {
6015 index,
6016 rule_index,
6017 pred_index,
6018 predicates,
6019 semantics: None,
6020 context: Some(context),
6021 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6022 member_values: &member_values,
6023 })
6024 }
6025
6026 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
6029 &mut self,
6030 semantics: &ParserSemantics,
6031 rule_index: usize,
6032 pred_index: usize,
6033 context: &ParserRuleContext,
6034 local_int_arg: i32,
6035 ) -> bool {
6036 let index = self.input.index();
6037 let member_values = self.int_members.clone();
6038 self.parser_predicate_matches(PredicateEval {
6039 index,
6040 rule_index,
6041 pred_index,
6042 predicates: &[],
6043 semantics: Some(semantics),
6044 context: Some(context),
6045 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6046 member_values: &member_values,
6047 })
6048 }
6049
6050 pub fn parser_semantic_predicate_failure_message(
6053 &self,
6054 rule_index: usize,
6055 pred_index: usize,
6056 predicates: &[(usize, usize, ParserPredicate)],
6057 ) -> Option<&'static str> {
6058 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
6059 }
6060
6061 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
6063 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6064 line: 0,
6065 column: 0,
6066 message: "missing current token".to_owned(),
6067 })?;
6068 if self.token_type_for_id(current) == TOKEN_EOF {
6069 return Err(AntlrError::MismatchedInput {
6070 expected: "wildcard".to_owned(),
6071 found: self.vocabulary().display_name(TOKEN_EOF),
6072 });
6073 }
6074 self.consume();
6075 Ok(self.terminal_tree(current))
6076 }
6077
6078 #[allow(clippy::unnecessary_wraps)]
6082 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
6083 self.set_state(state);
6084 Ok(())
6085 }
6086
6087 pub fn sync_decision(
6095 &mut self,
6096 atn: &Atn,
6097 state_number: usize,
6098 current_context_empty: bool,
6099 loop_back: bool,
6100 ) -> Result<Vec<ParseTree>, AntlrError> {
6101 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
6102 self.generated_sync_expected = None;
6103 let Some(state) = atn.state(state_number) else {
6104 return Ok(Vec::new());
6105 };
6106 let Some(rule_index) = state.rule_index() else {
6107 return Ok(Vec::new());
6108 };
6109 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
6110 return Ok(Vec::new());
6111 };
6112 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6113 let symbol = self.la(1);
6114 let mut has_expected_symbols = false;
6115 let mut nullable = false;
6116 let mut explicit_eof_expected = false;
6124 for transition in &entry.transitions {
6125 if transition.symbols.contains(symbol) {
6126 return Ok(Vec::new());
6127 }
6128 has_expected_symbols |= !transition.symbols.is_empty();
6129 nullable |= transition.nullable;
6130 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
6131 }
6132 if nullable && self.context_expected_contains(atn, symbol) {
6137 return Ok(Vec::new());
6138 }
6139 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
6140 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
6141 return Ok(Vec::new());
6142 }
6143 let mut expected = TokenBitSet::default();
6144 for transition in &entry.transitions {
6145 expected.extend_from(&transition.symbols);
6146 }
6147 if let Some(context_expected) = context_expected {
6148 expected.extend_from(&context_expected);
6149 }
6150 let can_delete_in_place =
6151 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
6152 let loop_sync = loop_back;
6169 if symbol != TOKEN_EOF && can_delete_in_place {
6170 let mut cursor = self.input.index();
6171 let mut skipped = Vec::new();
6172 loop {
6173 let current = self.token_type_at(cursor);
6174 if current == TOKEN_EOF {
6175 break;
6176 }
6177 skipped.push(cursor);
6178 let next = self.consume_index(cursor, current);
6179 if next == cursor {
6180 break;
6181 }
6182 let next_symbol = self.token_type_at(next);
6183 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
6191 explicit_eof_expected
6192 } else {
6193 expected.contains(next_symbol)
6194 };
6195 if next_is_expected_stop {
6196 let current_token = self.input.lt(1);
6197 let expected_symbols = expected.to_btree_set();
6198 let message = format!(
6199 "extraneous input {} expecting {}",
6200 current_token
6201 .as_ref()
6202 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6203 self.expected_symbols_display(&expected_symbols)
6204 );
6205 self.push_generated_parser_diagnostic(diagnostic_for_token(
6206 current_token,
6207 message,
6208 ));
6209 self.record_syntax_errors(1);
6210 let mut children = Vec::with_capacity(skipped.len());
6211 for index in skipped {
6212 if let Some(token) = self.token_id_at(index) {
6213 self.consume();
6214 children.push(self.error_tree(token));
6215 }
6216 }
6217 return Ok(children);
6218 }
6219 if !loop_sync {
6223 break;
6224 }
6225 cursor = next;
6226 }
6227 }
6228 if nullable {
6229 self.generated_sync_expected = Some(expected);
6230 return Ok(Vec::new());
6231 }
6232 let current = self.input.lt(1);
6233 let expected_symbols = expected.to_btree_set();
6234 Err(AntlrError::ParserError {
6235 line: current.as_ref().map(Token::line).unwrap_or_default(),
6236 column: current.as_ref().map(Token::column).unwrap_or_default(),
6237 message: format!(
6238 "mismatched input {} expecting {}",
6239 current
6240 .as_ref()
6241 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6242 self.expected_symbols_display(&expected_symbols)
6243 ),
6244 })
6245 }
6246
6247 pub fn ll1_decision_prediction(
6254 &mut self,
6255 atn: &Atn,
6256 state_number: usize,
6257 ) -> Option<ParserAtnPrediction> {
6258 let state = atn.state(state_number)?;
6259 if state.precedence_rule_decision() {
6260 return None;
6261 }
6262 let rule_stop = state
6263 .rule_index()
6264 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
6265 let symbol = self.la(1);
6266 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6267 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
6268 alt: alt + 1,
6269 requires_full_context: false,
6270 has_semantic_context: false,
6271 diagnostic: None,
6272 })
6273 }
6274
6275 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
6276 let mut expected = BTreeSet::new();
6277 for index in (1..self.rule_context_stack.len()).rev() {
6278 let invoking_state = self.rule_context_stack[index].invoking_state;
6279 let Ok(state_number) = usize::try_from(invoking_state) else {
6280 continue;
6281 };
6282 let Some(Transition::Rule { follow_state, .. }) = atn
6283 .state(state_number)
6284 .and_then(|state| state.transitions().first())
6285 .map(ParserTransition::data)
6286 else {
6287 continue;
6288 };
6289 let return_state = follow_state;
6290 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
6291 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
6292 return expected;
6293 }
6294 }
6295 expected.insert(TOKEN_EOF);
6296 expected
6297 }
6298
6299 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
6300 let mut expected = TokenBitSet::default();
6301 for index in (1..self.rule_context_stack.len()).rev() {
6302 let invoking_state = self.rule_context_stack[index].invoking_state;
6303 let Ok(state_number) = usize::try_from(invoking_state) else {
6304 continue;
6305 };
6306 let Some(Transition::Rule { follow_state, .. }) = atn
6307 .state(state_number)
6308 .and_then(|state| state.transitions().first())
6309 .map(ParserTransition::data)
6310 else {
6311 continue;
6312 };
6313 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
6314 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6315 return expected;
6316 }
6317 }
6318 expected.insert(TOKEN_EOF);
6319 expected
6320 }
6321
6322 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
6333 for index in (1..self.rule_context_stack.len()).rev() {
6334 let invoking_state = self.rule_context_stack[index].invoking_state;
6335 let Ok(state_number) = usize::try_from(invoking_state) else {
6336 continue;
6337 };
6338 let Some(Transition::Rule { follow_state, .. }) = atn
6339 .state(state_number)
6340 .and_then(|state| state.transitions().first())
6341 .map(ParserTransition::data)
6342 else {
6343 continue;
6344 };
6345 if self
6346 .cached_state_expected_token_set(atn, follow_state)
6347 .contains(symbol)
6348 {
6349 return true;
6350 }
6351 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6352 return false;
6353 }
6354 }
6355 symbol == TOKEN_EOF
6356 }
6357
6358 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
6360 let error_index = self.input.index();
6361 self.no_viable_alternative_error_at(start_index, error_index)
6362 }
6363
6364 pub fn no_viable_alternative_error_at(
6369 &self,
6370 start_index: usize,
6371 error_index: usize,
6372 ) -> AntlrError {
6373 let diagnostic = self.no_viable_alternative(start_index, error_index);
6374 AntlrError::ParserError {
6375 line: diagnostic.line,
6376 column: diagnostic.column,
6377 message: diagnostic.message,
6378 }
6379 }
6380
6381 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
6383 let current = self.input.lt(1);
6384 AntlrError::ParserError {
6385 line: current.as_ref().map(Token::line).unwrap_or_default(),
6386 column: current.as_ref().map(Token::column).unwrap_or_default(),
6387 message: format!("rule failed predicate: {}", message.into()),
6388 }
6389 }
6390
6391 pub fn failed_predicate_option_error(
6394 &self,
6395 rule_index: usize,
6396 message: impl Into<String>,
6397 ) -> AntlrError {
6398 let current = self.input.lt(1);
6399 let rule_name = self
6400 .rule_names()
6401 .get(rule_index)
6402 .map_or_else(|| rule_index.to_string(), Clone::clone);
6403 AntlrError::ParserError {
6404 line: current.as_ref().map(Token::line).unwrap_or_default(),
6405 column: current.as_ref().map(Token::column).unwrap_or_default(),
6406 message: format!("rule {rule_name} {}", message.into()),
6407 }
6408 }
6409
6410 pub fn parser_action_at_current(
6412 &mut self,
6413 source_state: usize,
6414 rule_index: usize,
6415 start_index: usize,
6416 consumed_eof: bool,
6417 ) -> ParserAction {
6418 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6419 ParserAction::new(source_state, rule_index, start_index, stop_index)
6420 }
6421
6422 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
6427 let rule_index = action.rule_index();
6428 let rule_name = self.rule_names().get(rule_index).cloned();
6429 let context = None;
6430 let input = &mut self.input;
6431 let semantic_hooks = &mut self.semantic_hooks;
6432 let member_values = &self.int_members;
6433 let mut ctx = ParserSemCtx {
6434 input,
6435 tree_storage: &self.tree,
6436 rule_index,
6437 coordinate_index: usize::MAX,
6438 rule_name,
6439 context,
6440 tree: Some(tree),
6441 local_int_arg: None,
6442 member_values,
6443 action: Some(action),
6444 };
6445 let handled = semantic_hooks.action(&mut ctx, action);
6446 if !handled && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error) {
6452 let coordinate = (rule_index, action.source_state());
6453 if !self.unhandled_action_hits.contains(&coordinate) {
6454 self.unhandled_action_hits.push(coordinate);
6455 }
6456 }
6457 handled
6458 }
6459
6460 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
6465 &mut self,
6466 atn: &'atn Atn,
6467 simulator: &mut ParserAtnSimulator<'atn>,
6468 rule_index: usize,
6469 ) -> Result<ParseTree, AntlrError> {
6470 let start_index = self.current_visible_index();
6471 self.clear_prediction_diagnostics();
6472 self.reset_per_parse_caches();
6473 self.reset_recognition_arena();
6474 let tree_checkpoint = self.tree.checkpoint();
6475 let mut decision_by_state = vec![None; atn.states().len()];
6476 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
6477 if let Some(slot) = decision_by_state.get_mut(state_number) {
6478 *slot = Some(decision);
6479 }
6480 }
6481
6482 let result = DirectAdaptiveParser {
6483 parser: self,
6484 atn,
6485 simulator,
6486 decision_by_state,
6487 steps: 0,
6488 }
6489 .parse_rule(rule_index, -1, 0);
6490
6491 match result {
6492 Ok(tree) => {
6493 self.report_token_source_errors();
6494 self.release_tree_scratch_if_idle();
6495 Ok(tree)
6496 }
6497 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
6498 let _ = reason;
6499 self.tree.rollback(tree_checkpoint);
6500 self.input.seek(start_index);
6501 self.parse_atn_rule(atn, rule_index)
6502 }
6503 }
6504 }
6505
6506 pub fn parse_atn_rule(
6516 &mut self,
6517 atn: &Atn,
6518 rule_index: usize,
6519 ) -> Result<ParseTree, AntlrError> {
6520 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
6521 }
6522
6523 pub fn parse_atn_rule_with_precedence(
6526 &mut self,
6527 atn: &Atn,
6528 rule_index: usize,
6529 precedence: i32,
6530 ) -> Result<ParseTree, AntlrError> {
6531 self.parse_atn_rule_with_precedence_inner(atn, rule_index, precedence, None)
6532 }
6533
6534 fn parse_atn_rule_with_precedence_inner(
6535 &mut self,
6536 atn: &Atn,
6537 rule_index: usize,
6538 precedence: i32,
6539 predicate_context: Option<FastPredicateContext<'_>>,
6540 ) -> Result<ParseTree, AntlrError> {
6541 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
6542 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
6543 })?;
6544 let stop_state = atn
6545 .rule_to_stop_state()
6546 .get(rule_index)
6547 .filter(|state| *state != usize::MAX)
6548 .ok_or_else(|| {
6549 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
6550 })?;
6551
6552 let start_index = self.current_visible_index();
6553 self.clear_prediction_diagnostics();
6554 self.reset_per_parse_caches();
6555 self.reset_recognition_arena();
6556 let caller_follow_state = self.pending_invoking_follow_state(atn);
6557 self.fast_recovery_enabled = false;
6558 self.fast_token_nodes_enabled = false;
6559 let top_request = FastRecognizeTopRequest {
6560 start_state,
6561 stop_state,
6562 start_index,
6563 precedence,
6564 caller_follow_state,
6565 };
6566 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
6567 self.fast_token_nodes_enabled = self.build_parse_trees;
6568 let needs_tree_retry = matches!(
6569 &first_pass,
6570 Ok((outcome, _))
6571 if self.build_parse_trees
6572 && self
6573 .recognition_arena
6574 .sequence_has_left_recursive_boundary(outcome.nodes)
6575 );
6576 let needs_retry = match &first_pass {
6577 Err(_) => true,
6590 Ok((outcome, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
6591 };
6592 let (outcome, _expected) = if needs_retry {
6593 self.fast_first_set_prefilter = false;
6594 self.fast_recovery_enabled = false;
6595 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6596 let clean_selected = if needs_tree_retry {
6597 match clean_retry {
6598 ok @ Ok(_) => ok,
6599 Err(_) => first_pass,
6600 }
6601 } else {
6602 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
6603 };
6604 let selected = if clean_selected.is_err()
6605 || matches!(&clean_selected, Ok((outcome, _)) if !outcome.diagnostics.is_empty())
6606 {
6607 self.fast_recovery_enabled = true;
6608 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6609 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
6610 } else {
6611 clean_selected
6612 };
6613 self.fast_first_set_prefilter = true;
6614 self.fast_recovery_enabled = true;
6615 selected.map_err(|expected| {
6616 if predicate_context.is_some()
6617 && let Some(error) = self.unknown_semantic_error()
6618 {
6619 self.report_token_source_errors();
6620 return error;
6621 }
6622 let error = self.recognition_error(rule_index, start_index, &expected);
6623 self.record_syntax_errors(1);
6624 self.report_token_source_errors();
6625 error
6626 })?
6627 } else {
6628 first_pass.expect("first_pass is Ok in the no-retry branch")
6629 };
6630 if predicate_context.is_some()
6631 && let Some(error) = self.unknown_semantic_error()
6632 {
6633 self.report_token_source_errors();
6634 return Err(error);
6635 }
6636 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
6637 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
6638 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
6639 self.report_token_source_errors();
6640 let mut context = ParserRuleContext::with_child_capacity(
6641 rule_index,
6642 self.state(),
6643 if self.build_parse_trees {
6644 self.recognition_arena.sequence_len(outcome.nodes)
6645 } else {
6646 0
6647 },
6648 );
6649 if let Some(token) = self.token_id_at(start_index) {
6650 self.set_context_start(&mut context, token);
6651 }
6652 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
6653 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
6654 self.set_context_stop(&mut context, token);
6655 }
6656 let live_root = if self.build_parse_trees {
6657 self.recognition_arena
6658 .fold_left_recursive_boundaries(outcome.nodes)
6659 } else {
6660 outcome.nodes
6661 };
6662 if self.build_parse_trees {
6663 if self
6664 .recognition_arena
6665 .sequence_has_explicit_token(live_root)
6666 {
6667 let mut cursor = live_root;
6668 while let Some(link) = self.recognition_arena.link(cursor) {
6669 let child = self.arena_recognized_node_tree(link.head, false)?;
6670 self.tree.add_child(&mut context, child);
6671 cursor = link.tail;
6672 }
6673 } else {
6674 self.add_arena_implicit_token_children(
6675 &mut context,
6676 start_index,
6677 stop_index,
6678 live_root,
6679 )?;
6680 }
6681 }
6682 self.finish_recognition_arena(live_root, outcome.diagnostics);
6683 self.input.seek(outcome.index);
6684
6685 let tree = self.rule_node(context);
6686 self.release_tree_scratch_if_idle();
6687 Ok(tree)
6688 }
6689
6690 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
6691 let invoking_state = self.pending_invoking_states.last().copied()?;
6692 let state_number = usize::try_from(invoking_state).ok()?;
6693 match atn.state(state_number)?.transitions().first()?.data() {
6694 Transition::Rule { follow_state, .. } => Some(follow_state),
6695 _ => None,
6696 }
6697 }
6698
6699 #[cfg(test)]
6700 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
6701 caller_follow_token_info_for_stream(&mut self.input, index)
6702 }
6703
6704 fn fast_recognize_top(
6709 &mut self,
6710 atn: &Atn,
6711 request: FastRecognizeTopRequest,
6712 predicate_context: Option<FastPredicateContext<'_>>,
6713 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
6714 let FastRecognizeTopRequest {
6715 start_state,
6716 stop_state,
6717 start_index,
6718 precedence,
6719 caller_follow_state,
6720 } = request;
6721 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
6730 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
6731 recognize_scratch.prepare(memo_capacity);
6732 let mut expected = ExpectedTokens::default();
6733 let empty_recovery = self.empty_recovery_symbols();
6734 let outcomes = self.recognize_state_fast(
6735 atn,
6736 FastRecognizeRequest {
6737 state_number: start_state,
6738 stop_state,
6739 index: start_index,
6740 rule_start_index: start_index,
6741 decision_start_index: None,
6742 precedence,
6743 depth: 0,
6744 recovery_symbols: empty_recovery,
6745 recovery_state: None,
6746 },
6747 FastRecognizeScratch {
6748 predicate_context,
6749 visiting: &mut recognize_scratch.visiting,
6750 memo: &mut recognize_scratch.memo,
6751 expected: &mut expected,
6752 },
6753 );
6754 recognize_scratch.release_oversized_memo();
6755 self.fast_recognize_scratch = recognize_scratch;
6756 #[cfg(feature = "perf-counters")]
6757 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
6758 perf_counters::dump();
6759 perf_counters::reset();
6760 }
6761 let caller_follow =
6762 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
6763 let selected = {
6764 let arena = &self.recognition_arena;
6765 let input = &mut self.input;
6766 select_best_fast_outcome(
6767 outcomes.into_iter(),
6768 self.prediction_mode,
6769 caller_follow.as_deref(),
6770 |index| caller_follow_token_info_for_stream(input, index),
6771 arena,
6772 )
6773 };
6774 match selected {
6775 Some(mut outcome) => {
6776 if self.build_parse_trees {
6777 self.materialize_fast_outcome_nodes(&mut outcome);
6778 }
6779 Ok((outcome, expected))
6780 }
6781 None => Err(expected),
6782 }
6783 }
6784
6785 fn arena_recognized_node_tree(
6787 &mut self,
6788 node_id: RecognizedNodeId,
6789 track_alt_numbers: bool,
6790 ) -> Result<ParseTree, AntlrError> {
6791 let node = self.recognition_arena.node(node_id);
6792 match node {
6793 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
6794 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
6795 ArenaRecognizedNode::MissingToken { extra } => {
6796 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
6797 RecognitionExtra::MissingToken {
6798 token_type,
6799 at_index,
6800 text,
6801 } => (*token_type, *at_index as usize, text.clone()),
6802 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
6803 unreachable!("missing-token node must reference missing-token extra")
6804 }
6805 };
6806 let (line, column) = self
6807 .token_at(at_index)
6808 .map_or((0, 0), |token| (token.line(), token.column()));
6809 let token = self.insert_synthetic_token(token_type, text, line, column)?;
6810 Ok(self.error_tree(token))
6811 }
6812 ArenaRecognizedNode::Rule {
6813 rule_index,
6814 invoking_state,
6815 alt_number,
6816 start_index,
6817 stop_index,
6818 return_values,
6819 children,
6820 } => {
6821 let mut context = ParserRuleContext::with_child_capacity(
6822 rule_index as usize,
6823 invoking_state as isize,
6824 self.recognition_arena.sequence_len(children),
6825 );
6826 if track_alt_numbers {
6827 context.set_alt_number(alt_number as usize);
6828 }
6829 if let Some(extra) = return_values {
6830 let RecognitionExtra::ReturnValues(values) =
6831 self.recognition_arena.extra(extra)
6832 else {
6833 unreachable!("rule node must reference return-values extra");
6834 };
6835 for (name, value) in values {
6836 context.set_int_return(name.clone(), *value);
6837 }
6838 }
6839 if let Some(token) = self.token_id_at(start_index as usize) {
6840 self.set_context_start(&mut context, token);
6841 }
6842 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
6843 self.set_context_stop(&mut context, token);
6844 }
6845 let mut cursor = self
6846 .recognition_arena
6847 .fold_left_recursive_boundaries(children);
6848 while let Some(link) = self.recognition_arena.link(cursor) {
6849 let child = self.arena_recognized_node_tree(link.head, track_alt_numbers)?;
6850 self.tree.add_child(&mut context, child);
6851 cursor = link.tail;
6852 }
6853 Ok(self.rule_node(context))
6854 }
6855 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index } => {
6856 Err(AntlrError::Unsupported(format!(
6857 "unfolded left-recursive boundary for rule {rule_index}"
6858 )))
6859 }
6860 }
6861 }
6862
6863 fn arena_recognized_node_tree_with_implicit_tokens(
6864 &mut self,
6865 node_id: RecognizedNodeId,
6866 ) -> Result<ParseTree, AntlrError> {
6867 let node = self.recognition_arena.node(node_id);
6868 match node {
6869 ArenaRecognizedNode::Rule {
6870 rule_index,
6871 invoking_state,
6872 start_index,
6873 stop_index,
6874 children,
6875 ..
6876 } => {
6877 let mut context = ParserRuleContext::with_child_capacity(
6878 rule_index as usize,
6879 invoking_state as isize,
6880 self.recognition_arena.sequence_len(children),
6881 );
6882 if let Some(token) = self.token_id_at(start_index as usize) {
6883 self.set_context_start(&mut context, token);
6884 }
6885 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
6886 self.set_context_stop(&mut context, token);
6887 }
6888 let children = self
6889 .recognition_arena
6890 .fold_left_recursive_boundaries(children);
6891 self.add_arena_implicit_token_children(
6892 &mut context,
6893 start_index as usize,
6894 stop_index.map(|index| index as usize),
6895 children,
6896 )?;
6897 Ok(self.rule_node(context))
6898 }
6899 _ => self.arena_recognized_node_tree(node_id, false),
6900 }
6901 }
6902
6903 fn add_arena_implicit_token_children(
6904 &mut self,
6905 context: &mut ParserRuleContext,
6906 start_index: usize,
6907 stop_index: Option<usize>,
6908 mut children: NodeSeqId,
6909 ) -> Result<(), AntlrError> {
6910 let mut cursor = Some(start_index);
6911 while let Some(link) = self.recognition_arena.link(children) {
6912 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
6913 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
6914 let child = self.arena_recognized_node_tree_with_implicit_tokens(link.head)?;
6915 self.tree.add_child(context, child);
6916 if let Some(child_stop) = child_stop {
6917 cursor = self.next_visible_after_token(child_stop);
6918 }
6919 } else {
6920 let child = self.arena_recognized_node_tree_with_implicit_tokens(link.head)?;
6921 self.tree.add_child(context, child);
6922 }
6923 children = link.tail;
6924 }
6925 if let Some(stop) = stop_index {
6926 self.add_visible_terminals_through(context, cursor, stop)?;
6927 }
6928 Ok(())
6929 }
6930
6931 fn add_visible_terminals_before(
6932 &mut self,
6933 context: &mut ParserRuleContext,
6934 cursor: &mut Option<usize>,
6935 before: usize,
6936 ) -> Result<(), AntlrError> {
6937 let Some(stop) = before.checked_sub(1) else {
6938 return Ok(());
6939 };
6940 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
6941 *cursor = next;
6942 Ok(())
6943 }
6944
6945 fn add_visible_terminals_through(
6946 &mut self,
6947 context: &mut ParserRuleContext,
6948 mut cursor: Option<usize>,
6949 stop: usize,
6950 ) -> Result<Option<usize>, AntlrError> {
6951 while let Some(index) = cursor {
6952 if index > stop {
6953 return Ok(Some(index));
6954 }
6955 let token = self
6956 .input
6957 .get_id(index)
6958 .ok_or_else(|| AntlrError::ParserError {
6959 line: 0,
6960 column: 0,
6961 message: format!("missing token at index {index}"),
6962 })?;
6963 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
6964 let child = self.terminal_tree(token);
6965 self.tree.add_child(context, child);
6966 if is_eof {
6967 return Ok(None);
6968 }
6969 cursor = self.next_visible_after_token(index);
6970 }
6971 Ok(None)
6972 }
6973
6974 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
6975 let next = self.input.next_visible_after(index);
6976 (next != index).then_some(next)
6977 }
6978
6979 pub fn parse_atn_rule_with_actions(
6986 &mut self,
6987 atn: &Atn,
6988 rule_index: usize,
6989 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
6990 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
6991 }
6992
6993 pub fn parse_atn_rule_with_action_inits(
7001 &mut self,
7002 atn: &Atn,
7003 rule_index: usize,
7004 init_action_rules: &[usize],
7005 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7006 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
7007 }
7008
7009 pub fn parse_atn_rule_with_action_options(
7015 &mut self,
7016 atn: &Atn,
7017 rule_index: usize,
7018 init_action_rules: &[usize],
7019 track_alt_numbers: bool,
7020 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7021 self.parse_atn_rule_with_runtime_options(
7022 atn,
7023 rule_index,
7024 ParserRuntimeOptions {
7025 init_action_rules,
7026 track_alt_numbers,
7027 ..ParserRuntimeOptions::default()
7028 },
7029 )
7030 }
7031
7032 pub fn parse_atn_rule_with_runtime_options(
7039 &mut self,
7040 atn: &Atn,
7041 rule_index: usize,
7042 options: ParserRuntimeOptions<'_>,
7043 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7044 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
7045 }
7046
7047 pub fn parse_atn_rule_with_runtime_options_and_precedence(
7050 &mut self,
7051 atn: &Atn,
7052 rule_index: usize,
7053 precedence: i32,
7054 options: ParserRuntimeOptions<'_>,
7055 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7056 let ParserRuntimeOptions {
7057 init_action_rules,
7058 track_alt_numbers,
7059 predicates,
7060 semantics,
7061 rule_args,
7062 member_actions,
7063 return_actions,
7064 unknown_predicate_policy,
7065 } = options;
7066 if init_action_rules.is_empty()
7067 && !track_alt_numbers
7068 && predicates.is_empty()
7069 && semantics.is_none()
7070 && rule_args.is_empty()
7071 && member_actions.is_empty()
7072 && return_actions.is_empty()
7073 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
7074 && !atn_has_observable_action_transitions(atn)
7075 && (!self.semantic_hooks.observes_parser_predicates()
7076 || !atn_has_predicate_transitions(atn))
7077 {
7078 return self
7079 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
7080 .map(|tree| (tree, Vec::new()));
7081 }
7082 if can_use_fast_predicate_recognizer(atn, &options) {
7083 self.unknown_predicate_policy = unknown_predicate_policy;
7084 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7085 let member_values = self.int_members.clone();
7086 let result = self
7087 .parse_atn_rule_with_precedence_inner(
7088 atn,
7089 rule_index,
7090 precedence,
7091 Some(FastPredicateContext {
7092 predicates,
7093 semantics,
7094 member_values: &member_values,
7095 }),
7096 )
7097 .map(|tree| (tree, Vec::new()));
7098 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
7099 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7100 }
7101 return result;
7102 }
7103 self.unknown_predicate_policy = unknown_predicate_policy;
7104 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7111 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7112 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7113 })?;
7114 let stop_state = atn
7115 .rule_to_stop_state()
7116 .get(rule_index)
7117 .filter(|state| *state != usize::MAX)
7118 .ok_or_else(|| {
7119 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7120 })?;
7121
7122 let start_index = self.current_visible_index();
7123 self.clear_prediction_diagnostics();
7124 self.reset_per_parse_caches();
7125 self.reset_recognition_arena();
7126 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
7127 let invoking_state = self.pending_invoking_states.pop();
7128 let local_int_arg = invoking_state
7129 .and_then(|state| usize::try_from(state).ok())
7130 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
7131 let mut visiting = BTreeSet::new();
7132 let mut memo = BTreeMap::new();
7133 let mut expected = ExpectedTokens::default();
7134 let member_values = self.int_members.clone();
7135 let return_values = BTreeMap::new();
7136 let outcomes = self.recognize_state(
7137 atn,
7138 RecognizeRequest {
7139 state_number: start_state,
7140 stop_state,
7141 index: start_index,
7142 rule_start_index: start_index,
7143 decision_start_index: None,
7144 init_action_rules: &init_action_rules,
7145 predicates,
7146 semantics,
7147 rule_args,
7148 member_actions,
7149 return_actions,
7150 local_int_arg,
7151 member_values,
7152 return_values,
7153 rule_alt_number: 0,
7154 track_alt_numbers,
7155 consumed_eof: false,
7156 precedence,
7157 depth: 0,
7158 recovery_symbols: BTreeSet::new(),
7159 recovery_state: None,
7160 },
7161 &mut visiting,
7162 &mut memo,
7163 &mut expected,
7164 );
7165 if let Some(error) = self.unknown_semantic_error() {
7166 self.report_token_source_errors();
7167 return Err(error);
7174 }
7175 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7178 let Some(outcome) = select_best_outcome(
7179 outcomes.into_iter(),
7180 self.prediction_mode,
7181 &self.recognition_arena,
7182 ) else {
7183 let error = self.recognition_error(rule_index, start_index, &expected);
7184 self.record_syntax_errors(1);
7185 self.report_token_source_errors();
7186 return Err(error);
7187 };
7188
7189 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7190 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7191 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7192 self.report_token_source_errors();
7193 let mut actions = outcome.actions;
7194 if init_action_rules.contains(&rule_index) {
7195 actions.insert(
7196 0,
7197 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
7198 );
7199 }
7200 let mut context =
7201 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
7202 if track_alt_numbers {
7203 context.set_alt_number(outcome.alt_number);
7204 }
7205 for (name, value) in outcome.return_values {
7206 context.set_int_return(name, value);
7207 }
7208 if let Some(token) = self.token_id_at(start_index) {
7209 self.set_context_start(&mut context, token);
7210 }
7211 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
7212 self.set_context_stop(&mut context, token);
7213 }
7214 let live_root = if self.build_parse_trees {
7215 self.recognition_arena
7216 .fold_left_recursive_boundaries(outcome.nodes)
7217 } else {
7218 outcome.nodes
7219 };
7220 if self.build_parse_trees {
7221 let mut nodes = live_root;
7222 while let Some(link) = self.recognition_arena.link(nodes) {
7223 let child = self.arena_recognized_node_tree(link.head, track_alt_numbers)?;
7224 self.tree.add_child(&mut context, child);
7225 nodes = link.tail;
7226 }
7227 }
7228 self.finish_recognition_arena(live_root, outcome.diagnostics);
7229 self.input.seek(outcome.index);
7230
7231 let tree = self.rule_node(context);
7232 self.release_tree_scratch_if_idle();
7233 Ok((tree, actions))
7234 }
7235
7236 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
7243 let mut context = ParserRuleContext::new(rule_index, self.state());
7244 while self.la(1) != TOKEN_EOF {
7245 let token_type = self.la(1);
7246 let child = self.match_token(token_type)?;
7247 if self.build_parse_trees {
7248 self.tree.add_child(&mut context, child);
7249 }
7250 }
7251 if self.build_parse_trees {
7252 let child = self.match_eof()?;
7253 self.tree.add_child(&mut context, child);
7254 }
7255 let tree = self.rule_node(context);
7256 self.release_tree_scratch_if_idle();
7257 Ok(tree)
7258 }
7259
7260 fn recognition_error(
7263 &mut self,
7264 rule_index: usize,
7265 start_index: usize,
7266 expected: &ExpectedTokens,
7267 ) -> AntlrError {
7268 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
7269 self.input.seek(index);
7270 let current = self.input.lt(1);
7271 let line = current.as_ref().map(Token::line).unwrap_or_default();
7272 let column = current.as_ref().map(Token::column).unwrap_or_default();
7273 AntlrError::ParserError {
7274 line,
7275 column,
7276 message,
7277 }
7278 }
7279
7280 fn expected_error_message(
7282 &mut self,
7283 rule_index: usize,
7284 start_index: usize,
7285 expected: &ExpectedTokens,
7286 ) -> (usize, String) {
7287 let index = expected
7288 .index
7289 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
7290 .unwrap_or_else(|| self.input.index());
7291 self.input.seek(index);
7292 let current = self.input.lt(1);
7293 let message = if expected
7294 .no_viable
7295 .as_ref()
7296 .is_some_and(|no_viable| no_viable.error_index == index)
7297 {
7298 let start = expected
7299 .no_viable
7300 .as_ref()
7301 .map_or(start_index, |no_viable| no_viable.start_index);
7302 let text = display_input_text(&self.input.text(start, index));
7303 format!("no viable alternative at input '{text}'")
7304 } else if expected.symbols.is_empty() {
7305 if expected.index.is_some() {
7306 let found = current
7307 .as_ref()
7308 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
7309 if current
7310 .as_ref()
7311 .is_some_and(|token| token.token_type() == TOKEN_EOF)
7312 {
7313 format!(
7314 "missing {} at {found}",
7315 self.expected_symbols_display(&expected.symbols)
7316 )
7317 } else {
7318 format!("mismatched input {found}")
7319 }
7320 } else {
7321 format!("no viable alternative while parsing rule {rule_index}")
7322 }
7323 } else {
7324 format!(
7325 "mismatched input {} expecting {}",
7326 current
7327 .as_ref()
7328 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7329 self.expected_symbols_display(&expected.symbols)
7330 )
7331 };
7332 (index, message)
7333 }
7334
7335 fn child_rule_failure_recovery(
7338 &mut self,
7339 rule_index: usize,
7340 start_index: usize,
7341 sync_symbols: &BTreeSet<i32>,
7342 member_values: BTreeMap<usize, i64>,
7343 expected: &ExpectedTokens,
7344 ) -> Option<RecognizeOutcome> {
7345 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7346 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7347 let mut next_index = error_index;
7348 loop {
7349 let symbol = self.token_type_at(next_index);
7350 if sync_symbols.contains(&symbol) {
7351 if next_index == error_index {
7352 return None;
7353 }
7354 break;
7355 }
7356 if symbol == TOKEN_EOF {
7357 break;
7358 }
7359 let after = self.consume_index(next_index, symbol);
7360 if after == next_index {
7361 break;
7362 }
7363 next_index = after;
7364 }
7365 let mut nodes = NodeSeqId::EMPTY;
7366 let error = self.arena_token_node(error_index, true);
7367 self.arena_prepend(&mut nodes, error);
7368 let diagnostics = self
7369 .recognition_arena
7370 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7371 Some(RecognizeOutcome {
7372 index: next_index,
7373 consumed_eof: false,
7374 alt_number: 0,
7375 member_values,
7376 return_values: BTreeMap::new(),
7377 diagnostics,
7378 decisions: Vec::new(),
7379 actions: Vec::new(),
7380 nodes,
7381 })
7382 }
7383
7384 fn child_rule_failure_recovery_outcomes(
7387 &mut self,
7388 request: ChildRuleFailureRecovery<'_>,
7389 ) -> Vec<RecognizeOutcome> {
7390 let sync_symbols =
7391 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
7392 self.child_rule_failure_recovery(
7393 request.rule_index,
7394 request.start_index,
7395 &sync_symbols,
7396 request.member_values,
7397 request.expected,
7398 )
7399 .into_iter()
7400 .collect()
7401 }
7402
7403 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
7405 expected_symbols_display(symbols, self.vocabulary())
7406 }
7407
7408 fn single_token_deletion(
7411 &mut self,
7412 transition: ParserTransition<'_>,
7413 index: usize,
7414 max_token_type: i32,
7415 expected_symbols: &BTreeSet<i32>,
7416 ) -> Option<(ParserDiagnostic, usize, i32)> {
7417 let current_symbol = self.token_type_at(index);
7418 if current_symbol == TOKEN_EOF {
7419 return None;
7420 }
7421 let next_index = self.consume_index(index, current_symbol);
7422 if next_index == index {
7423 return None;
7424 }
7425 let next_symbol = self.token_type_at(next_index);
7426 if !transition.matches(next_symbol, 1, max_token_type) {
7427 return None;
7428 }
7429 let transition_expected = transition_expected_symbols(transition, max_token_type);
7430 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7431 &transition_expected
7432 } else {
7433 expected_symbols
7434 });
7435 let current = self.token_at(index);
7436 let message = format!(
7437 "extraneous input {} expecting {expected_display}",
7438 current
7439 .as_ref()
7440 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7441 );
7442 Some((
7443 diagnostic_for_token(current, message),
7444 next_index,
7445 next_symbol,
7446 ))
7447 }
7448
7449 fn current_token_deletion(
7452 &mut self,
7453 index: usize,
7454 expected_symbols: &BTreeSet<i32>,
7455 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
7456 if expected_symbols.is_empty() {
7457 return None;
7458 }
7459 let current_symbol = self.token_type_at(index);
7460 if current_symbol == TOKEN_EOF {
7461 return None;
7462 }
7463 let current = self.token_at(index);
7464 let message = format!(
7465 "extraneous input {} expecting {}",
7466 current
7467 .as_ref()
7468 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7469 self.expected_symbols_display(expected_symbols)
7470 );
7471 let diagnostic = diagnostic_for_token(current, message);
7472 let mut skipped = Vec::new();
7473 let mut cursor = index;
7474 loop {
7475 let symbol = self.token_type_at(cursor);
7476 if symbol == TOKEN_EOF {
7477 return None;
7478 }
7479 skipped.push(cursor);
7480 let next_index = self.consume_index(cursor, symbol);
7481 if next_index == cursor {
7482 return None;
7483 }
7484 let next_symbol = self.token_type_at(next_index);
7485 if expected_symbols.contains(&next_symbol) {
7486 return Some((diagnostic, next_index, skipped));
7487 }
7488 cursor = next_index;
7489 }
7490 }
7491
7492 fn single_token_insertion(
7496 &mut self,
7497 transition: ParserTransition<'_>,
7498 index: usize,
7499 max_token_type: i32,
7500 expected_symbols: &BTreeSet<i32>,
7501 follow_symbols: &BTreeSet<i32>,
7502 ) -> Option<(ParserDiagnostic, i32, String)> {
7503 let current_symbol = self.token_type_at(index);
7504 if !follow_symbols.contains(¤t_symbol) {
7505 return None;
7506 }
7507 let transition_expected = transition_expected_symbols(transition, max_token_type);
7508 let token_type = transition_expected.iter().next().copied()?;
7509 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7510 &transition_expected
7511 } else {
7512 expected_symbols
7513 });
7514 let mut token_symbols = BTreeSet::new();
7515 token_symbols.insert(token_type);
7516 let missing_token_display = self.expected_symbols_display(&token_symbols);
7517 let current = self.token_at(index);
7518 let message = format!(
7519 "missing {expected_display} at {}",
7520 current
7521 .as_ref()
7522 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7523 );
7524 let text = format!("<missing {missing_token_display}>");
7525 Some((
7526 diagnostic_for_token(current.as_ref(), message),
7527 token_type,
7528 text,
7529 ))
7530 }
7531
7532 fn fast_single_token_deletion_recovery(
7536 &mut self,
7537 recovery: FastRecoveryRequest<'_, '_>,
7538 predicate_context: Option<FastPredicateContext<'_>>,
7539 ) -> Vec<FastRecognizeOutcome> {
7540 let FastRecoveryRequest {
7541 atn,
7542 transition,
7543 expected_symbols,
7544 target,
7545 request,
7546 visiting,
7547 memo,
7548 expected,
7549 } = recovery;
7550 let FastRecognizeRequest {
7551 stop_state,
7552 index,
7553 rule_start_index,
7554 decision_start_index,
7555 precedence,
7556 depth,
7557 ..
7558 } = request;
7559 let Some((diagnostic, next_index, next_symbol)) =
7560 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
7561 else {
7562 return Vec::new();
7563 };
7564 let after_next = self.consume_index(next_index, next_symbol);
7565 let empty_recovery = self.empty_recovery_symbols();
7566 self.recognize_state_fast(
7567 atn,
7568 FastRecognizeRequest {
7569 state_number: target,
7570 stop_state,
7571 index: after_next,
7572 rule_start_index,
7573 decision_start_index,
7574 precedence,
7575 depth: depth + 1,
7576 recovery_symbols: empty_recovery,
7577 recovery_state: None,
7578 },
7579 FastRecognizeScratch {
7580 predicate_context,
7581 visiting,
7582 memo,
7583 expected,
7584 },
7585 )
7586 .into_iter()
7587 .map(|mut outcome| {
7588 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
7589 outcome.diagnostics = self
7590 .recognition_arena
7591 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7592 if self.fast_token_nodes_enabled {
7593 let token = self.arena_token_node(next_index, false);
7594 self.defer_fast_outcome_node(&mut outcome, token);
7595 let error = self.arena_token_node(index, true);
7596 self.defer_fast_outcome_node(&mut outcome, error);
7597 }
7598 outcome
7599 })
7600 .collect()
7601 }
7602
7603 fn fast_single_token_insertion_recovery(
7607 &mut self,
7608 recovery: FastRecoveryRequest<'_, '_>,
7609 predicate_context: Option<FastPredicateContext<'_>>,
7610 ) -> Vec<FastRecognizeOutcome> {
7611 let FastRecoveryRequest {
7612 atn,
7613 transition,
7614 expected_symbols,
7615 target,
7616 request,
7617 visiting,
7618 memo,
7619 expected,
7620 } = recovery;
7621 let FastRecognizeRequest {
7622 stop_state,
7623 index,
7624 rule_start_index,
7625 decision_start_index,
7626 precedence,
7627 depth,
7628 ..
7629 } = request;
7630 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
7631 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
7632 transition,
7633 index,
7634 atn.max_token_type(),
7635 &expected_symbols,
7636 &follow_symbols,
7637 ) else {
7638 return Vec::new();
7639 };
7640 let empty_recovery = self.empty_recovery_symbols();
7641 self.recognize_state_fast(
7642 atn,
7643 FastRecognizeRequest {
7644 state_number: target,
7645 stop_state,
7646 index,
7647 rule_start_index,
7648 decision_start_index,
7649 precedence,
7650 depth: depth + 1,
7651 recovery_symbols: empty_recovery,
7652 recovery_state: None,
7653 },
7654 FastRecognizeScratch {
7655 predicate_context,
7656 visiting,
7657 memo,
7658 expected,
7659 },
7660 )
7661 .into_iter()
7662 .map(|mut outcome| {
7663 outcome.diagnostics = self
7664 .recognition_arena
7665 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7666 let missing = self.arena_missing_token_node(token_type, index, text.clone());
7667 self.defer_fast_outcome_node(&mut outcome, missing);
7668 outcome
7669 })
7670 .collect()
7671 }
7672
7673 fn fast_current_token_deletion_recovery(
7676 &mut self,
7677 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
7678 predicate_context: Option<FastPredicateContext<'_>>,
7679 ) -> Vec<FastRecognizeOutcome> {
7680 let FastCurrentTokenDeletionRequest {
7681 atn,
7682 expected_symbols,
7683 mut request,
7684 visiting,
7685 memo,
7686 expected,
7687 } = recovery;
7688 if request.index == request.rule_start_index {
7689 return Vec::new();
7690 }
7691 let Some((diagnostic, next_index, skipped)) =
7692 self.current_token_deletion(request.index, &expected_symbols)
7693 else {
7694 return Vec::new();
7695 };
7696 request.state_number = request.recovery_state.unwrap_or(request.state_number);
7697 request.index = next_index;
7698 request.depth += 1;
7699 request.recovery_state = None;
7700 self.recognize_state_fast(
7701 atn,
7702 request,
7703 FastRecognizeScratch {
7704 predicate_context,
7705 visiting,
7706 memo,
7707 expected,
7708 },
7709 )
7710 .into_iter()
7711 .map(|mut outcome| {
7712 outcome.diagnostics = self
7713 .recognition_arena
7714 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7715 for index in skipped.iter().rev() {
7716 let error = self.arena_token_node(*index, true);
7717 self.defer_fast_outcome_node(&mut outcome, error);
7718 }
7719 outcome
7720 })
7721 .collect()
7722 }
7723
7724 fn fast_child_rule_failure_recovery(
7727 &mut self,
7728 rule_index: usize,
7729 start_index: usize,
7730 sync_symbols: &BTreeSet<i32>,
7731 expected: &ExpectedTokens,
7732 ) -> Option<FastRecognizeOutcome> {
7733 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7734 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7735 let mut next_index = error_index;
7736 loop {
7737 let symbol = self.token_type_at(next_index);
7738 if sync_symbols.contains(&symbol) {
7739 if next_index == error_index {
7740 return None;
7741 }
7742 break;
7743 }
7744 if symbol == TOKEN_EOF {
7745 break;
7746 }
7747 let after = self.consume_index(next_index, symbol);
7748 if after == next_index {
7749 break;
7750 }
7751 next_index = after;
7752 }
7753 let diagnostics = self
7754 .recognition_arena
7755 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7756 let mut nodes = NodeSeqId::EMPTY;
7757 if self.fast_token_nodes_enabled {
7758 let error = self.arena_token_node(error_index, true);
7759 self.arena_prepend(&mut nodes, error);
7760 }
7761 Some(FastRecognizeOutcome {
7762 index: next_index,
7763 consumed_eof: false,
7764 diagnostics,
7765 deferred_nodes: FastDeferredNodeId::EMPTY,
7766 nodes,
7767 })
7768 }
7769
7770 fn fast_child_rule_failure_recovery_outcomes(
7773 &mut self,
7774 request: FastChildRuleFailureRecoveryRequest<'_>,
7775 ) -> Vec<FastRecognizeOutcome> {
7776 let FastChildRuleFailureRecoveryRequest {
7777 atn,
7778 rule_index,
7779 start_index,
7780 follow_state,
7781 stop_state,
7782 expected,
7783 } = request;
7784 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
7785 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
7786 .into_iter()
7787 .collect()
7788 }
7789
7790 fn defer_fast_outcome_node(
7791 &mut self,
7792 outcome: &mut FastRecognizeOutcome,
7793 node: RecognizedNodeId,
7794 ) {
7795 if outcome.deferred_nodes.is_empty() {
7796 self.arena_prepend(&mut outcome.nodes, node);
7797 return;
7798 }
7799 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
7800 let fragment = self.recognition_arena.deferred_fragment(fragment);
7801 outcome.deferred_nodes = self
7802 .recognition_arena
7803 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
7804 }
7805
7806 fn materialize_fast_deferred_nodes(
7807 &mut self,
7808 root: FastDeferredNodeId,
7809 initial_suffix: NodeSeqId,
7810 ) -> NodeSeqId {
7811 if root.is_empty() {
7812 return initial_suffix;
7813 }
7814
7815 enum Frame {
7816 Visit(FastDeferredNodeId),
7817 ContinuePrefix(FastDeferredNodeId),
7818 FinishRule {
7819 rule: FastDeferredRule,
7820 parent_suffix: NodeSeqId,
7821 },
7822 }
7823
7824 let mut result = initial_suffix;
7825 let mut pending = Vec::with_capacity(16);
7826 pending.push(Frame::Visit(root));
7827 let mut fragment_nodes = Vec::new();
7828 while let Some(frame) = pending.pop() {
7829 match frame {
7830 Frame::Visit(deferred) => {
7831 if deferred.is_empty() {
7832 continue;
7833 }
7834
7835 match self.recognition_arena.deferred_node(deferred) {
7836 FastDeferredNode::Fragment(sequence) => {
7837 fragment_nodes.clear();
7838 fragment_nodes.extend(self.recognition_arena.iter(sequence));
7839 while let Some(node) = fragment_nodes.pop() {
7840 self.arena_prepend(&mut result, node);
7841 }
7842 }
7843 FastDeferredNode::Rule(rule) => {
7844 let rule = self.recognition_arena.deferred_rule(rule);
7845 let parent_suffix = result;
7846 result = rule.children;
7847 pending.push(Frame::FinishRule {
7848 rule,
7849 parent_suffix,
7850 });
7851 pending.push(Frame::Visit(rule.deferred_children));
7852 }
7853 FastDeferredNode::Concat {
7854 prefix,
7855 suffix: deferred_suffix,
7856 } => {
7857 pending.push(Frame::ContinuePrefix(prefix));
7858 pending.push(Frame::Visit(deferred_suffix));
7859 }
7860 }
7861 }
7862 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
7863 Frame::FinishRule {
7864 rule,
7865 parent_suffix,
7866 } => {
7867 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
7868 rule_index: rule.rule_index,
7869 invoking_state: rule.invoking_state,
7870 alt_number: 0,
7871 start_index: rule.start_index,
7872 stop_index: rule.stop_index,
7873 return_values: None,
7874 children: result,
7875 });
7876 result = parent_suffix;
7877 self.arena_prepend(&mut result, node);
7878 }
7879 }
7880 }
7881 result
7882 }
7883
7884 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) {
7885 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
7886 outcome.nodes = self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
7887 }
7888
7889 fn recognize_repetition_fast(
7892 &mut self,
7893 atn: &Atn,
7894 request: &FastRecognizeRequest,
7895 shape: FastRepetitionShape,
7896 scratch: FastRecognizeScratch<'_, '_>,
7897 ) -> Vec<FastRecognizeOutcome> {
7898 let FastRecognizeScratch {
7899 predicate_context,
7900 visiting,
7901 memo,
7902 expected,
7903 } = scratch;
7904 let lookahead = if self.fast_first_set_prefilter {
7905 atn.state(request.state_number).and_then(|state| {
7906 state
7907 .rule_index()
7908 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
7909 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
7910 })
7911 } else {
7912 None
7913 };
7914 let mut work = Vec::with_capacity(2);
7915 push_fast_repetition_work(
7916 &mut work,
7917 shape,
7918 FastRepetitionPath {
7919 index: request.index,
7920 deferred_nodes: FastDeferredNodeId::EMPTY,
7921 diagnostics: DiagnosticSeqId::EMPTY,
7922 consumed_eof: false,
7923 },
7924 lookahead.as_deref(),
7925 self.token_type_at(request.index),
7926 );
7927 let mut coordinates = FastRepetitionCoordinates::new(request.index);
7928 let mut outcomes = Vec::new();
7929 while let Some(item) = work.pop() {
7930 match item {
7931 FastRepetitionWork::Enter(path) => {
7932 if !coordinates.insert_entered(path) {
7933 continue;
7934 }
7935 let body_outcomes = self.recognize_state_fast(
7936 atn,
7937 FastRecognizeRequest {
7938 state_number: shape.enter_target,
7939 stop_state: shape.body_stop_state,
7940 index: path.index,
7941 rule_start_index: request.rule_start_index,
7942 decision_start_index: request.decision_start_index,
7943 precedence: request.precedence,
7944 depth: request.depth.saturating_add(1),
7945 recovery_symbols: Rc::clone(&request.recovery_symbols),
7946 recovery_state: request.recovery_state,
7947 },
7948 FastRecognizeScratch {
7949 predicate_context,
7950 visiting: &mut *visiting,
7951 memo: &mut *memo,
7952 expected: &mut *expected,
7953 },
7954 );
7955 for body in body_outcomes.into_iter().rev() {
7956 if body.index <= path.index {
7960 continue;
7961 }
7962 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
7963 let body_nodes = self
7964 .recognition_arena
7965 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
7966 let deferred_nodes = self
7967 .recognition_arena
7968 .concat_deferred_nodes(path.deferred_nodes, body_nodes);
7969 let next_path = FastRepetitionPath {
7970 index: body.index,
7971 deferred_nodes,
7972 diagnostics: self
7973 .recognition_arena
7974 .concat_diagnostics(path.diagnostics, body.diagnostics),
7975 consumed_eof: path.consumed_eof || body.consumed_eof,
7976 };
7977 let symbol = self.token_type_at(next_path.index);
7978 push_fast_repetition_work(
7979 &mut work,
7980 shape,
7981 next_path,
7982 lookahead.as_deref(),
7983 symbol,
7984 );
7985 }
7986 }
7987 FastRepetitionWork::Exit(path) => {
7988 if !coordinates.insert_exited(path) {
7989 continue;
7990 }
7991 let suffixes = self.recognize_state_fast(
7992 atn,
7993 FastRecognizeRequest {
7994 state_number: shape.exit_target,
7995 stop_state: request.stop_state,
7996 index: path.index,
7997 rule_start_index: request.rule_start_index,
7998 decision_start_index: request.decision_start_index,
7999 precedence: request.precedence,
8000 depth: request.depth.saturating_add(1),
8001 recovery_symbols: Rc::clone(&request.recovery_symbols),
8002 recovery_state: request.recovery_state,
8003 },
8004 FastRecognizeScratch {
8005 predicate_context,
8006 visiting: &mut *visiting,
8007 memo: &mut *memo,
8008 expected: &mut *expected,
8009 },
8010 );
8011 for mut outcome in suffixes {
8012 outcome.deferred_nodes = self
8013 .recognition_arena
8014 .concat_deferred_nodes(path.deferred_nodes, outcome.deferred_nodes);
8015 outcome.diagnostics = self
8016 .recognition_arena
8017 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
8018 outcome.consumed_eof |= path.consumed_eof;
8019 outcomes.push(outcome);
8020 }
8021 }
8022 }
8023 }
8024 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8025 outcomes
8026 }
8027
8028 #[allow(clippy::too_many_lines)]
8031 fn recognize_state_fast(
8032 &mut self,
8033 atn: &Atn,
8034 request: FastRecognizeRequest,
8035 scratch: FastRecognizeScratch<'_, '_>,
8036 ) -> Vec<FastRecognizeOutcome> {
8037 #[cfg(feature = "perf-counters")]
8038 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
8039 let FastRecognizeScratch {
8040 predicate_context,
8041 visiting,
8042 memo,
8043 expected,
8044 } = scratch;
8045 let FastRecognizeRequest {
8046 mut state_number,
8047 stop_state,
8048 mut index,
8049 rule_start_index,
8050 decision_start_index,
8051 precedence,
8052 mut depth,
8053 recovery_symbols,
8054 recovery_state,
8055 } = request;
8056 let max_token_type = atn.max_token_type();
8057 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
8076 let mut inline_consumed_eof = false;
8077 loop {
8078 if depth > RECOGNITION_DEPTH_LIMIT {
8079 return Vec::new();
8080 }
8081 if state_number == stop_state {
8082 let mut nodes = NodeSeqId::EMPTY;
8083 if self.fast_token_nodes_enabled {
8084 for token_index in inline_consumed_tokens.iter().rev() {
8085 let token = self.arena_token_node(*token_index, false);
8086 self.arena_prepend(&mut nodes, token);
8087 }
8088 }
8089 return vec![FastRecognizeOutcome {
8090 index,
8091 consumed_eof: inline_consumed_eof,
8092 diagnostics: DiagnosticSeqId::EMPTY,
8093 deferred_nodes: FastDeferredNodeId::EMPTY,
8094 nodes,
8095 }];
8096 }
8097 let Some(state) = atn.state(state_number) else {
8098 return Vec::new();
8099 };
8100 let transitions = state.transitions();
8101 if transitions.len() == 1 && !state.precedence_rule_decision() {
8102 let transition = transitions
8103 .first()
8104 .expect("single transition checked above");
8105 let transition_kind = transition.kind();
8106 let target = transition.target();
8107 match transition_kind {
8108 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
8109 if left_recursive_boundary(atn, state, target).is_none() =>
8110 {
8111 #[cfg(feature = "perf-counters")]
8112 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8113 state_number = target;
8114 depth += 1;
8115 continue;
8116 }
8117 ParserTransitionKind::Predicate
8118 if left_recursive_boundary(atn, state, target).is_none() =>
8119 {
8120 #[cfg(feature = "perf-counters")]
8121 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8122 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
8123 {
8124 record_predicate_no_viable(expected, decision_start_index, index);
8125 return Vec::new();
8126 }
8127 state_number = target;
8128 depth += 1;
8129 continue;
8130 }
8131 ParserTransitionKind::Precedence
8132 if packed_i32(transition.arg0()) >= precedence
8133 && left_recursive_boundary(atn, state, target).is_none() =>
8134 {
8135 #[cfg(feature = "perf-counters")]
8136 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8137 state_number = target;
8138 depth += 1;
8139 continue;
8140 }
8141 ParserTransitionKind::Atom
8151 | ParserTransitionKind::Range
8152 | ParserTransitionKind::Set
8153 | ParserTransitionKind::NotSet
8154 | ParserTransitionKind::Wildcard
8155 if !self.fast_recovery_enabled =>
8156 {
8157 let symbol = self.token_type_at(index);
8158 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
8159 #[cfg(feature = "perf-counters")]
8160 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
8161 if self.fast_token_nodes_enabled {
8162 inline_consumed_tokens.push(index);
8163 }
8164 inline_consumed_eof |= symbol == TOKEN_EOF;
8165 index = self.consume_index(index, symbol);
8166 state_number = target;
8167 depth += 1;
8168 continue;
8169 }
8170 }
8173 _ => {}
8174 }
8175 }
8176 break;
8177 }
8178 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
8182 let Some(state) = atn.state(state_number) else {
8183 return Vec::new();
8184 };
8185 let transitions = state.transitions();
8186 let transition_count = transitions.len();
8187 if !self.fast_recovery_enabled
8188 && let Some(shape) = fast_repetition_shape(atn, state)
8189 {
8190 let mut outcomes = self.recognize_repetition_fast(
8191 atn,
8192 &FastRecognizeRequest {
8193 state_number,
8194 stop_state,
8195 index,
8196 rule_start_index,
8197 decision_start_index,
8198 precedence,
8199 depth,
8200 recovery_symbols: Rc::clone(&recovery_symbols),
8201 recovery_state,
8202 },
8203 shape,
8204 FastRecognizeScratch {
8205 predicate_context,
8206 visiting: &mut *visiting,
8207 memo: &mut *memo,
8208 expected: &mut *expected,
8209 },
8210 );
8211 if inline_pending {
8212 for outcome in &mut outcomes {
8213 outcome.consumed_eof |= inline_consumed_eof;
8214 if self.fast_token_nodes_enabled {
8215 for token_index in inline_consumed_tokens.iter().rev() {
8216 let token = self.arena_token_node(*token_index, false);
8217 self.defer_fast_outcome_node(outcome, token);
8218 }
8219 }
8220 }
8221 }
8222 return outcomes;
8223 }
8224 let key = if self.fast_recovery_enabled {
8234 FastRecognizeKey {
8235 state_number,
8236 stop_state,
8237 index,
8238 rule_start_index,
8239 decision_start_index,
8240 precedence,
8241 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
8242 recovery_state,
8243 }
8244 } else {
8245 FastRecognizeKey {
8246 state_number,
8247 stop_state,
8248 index,
8249 rule_start_index: 0,
8250 decision_start_index: None,
8251 precedence,
8252 recovery_symbols_id: 0,
8253 recovery_state: None,
8254 }
8255 };
8256 let memo_lookup_enabled = self.fast_recovery_enabled
8261 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
8262 if memo_lookup_enabled {
8263 if let Some(outcomes) = memo.get(&key) {
8264 #[cfg(feature = "perf-counters")]
8265 {
8266 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
8267 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
8268 }
8269 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
8273 let inline_eof = inline_consumed_eof;
8274 let inline_tokens = &inline_consumed_tokens;
8275 return outcomes
8276 .iter()
8277 .copied()
8278 .map(|mut outcome| {
8279 if inline_eof {
8280 outcome.consumed_eof = true;
8281 }
8282 if self.fast_token_nodes_enabled {
8283 for token_index in inline_tokens.iter().rev() {
8284 let token = self.arena_token_node(*token_index, false);
8285 self.defer_fast_outcome_node(&mut outcome, token);
8286 }
8287 }
8288 outcome
8289 })
8290 .collect();
8291 }
8292 return outcomes.to_vec();
8293 }
8294 #[cfg(feature = "perf-counters")]
8295 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
8296 }
8297
8298 let needs_cycle_guard = if self.fast_recovery_enabled {
8303 transitions.iter().any(ParserTransition::is_epsilon)
8304 } else {
8305 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
8306 };
8307 #[cfg(feature = "perf-counters")]
8308 if needs_cycle_guard {
8309 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
8310 } else {
8311 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
8312 match state
8313 .transitions()
8314 .first()
8315 .expect("single-transition path requires one transition")
8316 .data()
8317 {
8318 Transition::Rule { .. } => {
8319 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
8320 }
8321 Transition::Atom { .. }
8322 | Transition::Range { .. }
8323 | Transition::Set { .. }
8324 | Transition::NotSet { .. }
8325 | Transition::Wildcard { .. } => {
8326 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
8327 }
8328 _ => {
8329 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
8330 }
8331 }
8332 }
8333 let has_inserted_cycle_guard = if needs_cycle_guard {
8334 if !visiting.insert(key.clone()) {
8335 #[cfg(feature = "perf-counters")]
8336 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
8337 return Vec::new();
8338 }
8339 true
8340 } else {
8341 false
8342 };
8343 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
8344 Some(index)
8345 } else {
8346 decision_start_index
8347 };
8348 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
8349 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
8350 } else {
8351 (Rc::clone(&recovery_symbols), recovery_state)
8352 };
8353
8354 let lookahead_filter = if transition_count > 1
8373 && self.fast_first_set_prefilter
8374 && !state.precedence_rule_decision()
8375 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
8376 {
8377 state
8378 .rule_index()
8379 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8380 .map(|rule_stop| {
8381 let symbol = self.token_type_at(index);
8382 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
8383 (symbol, entry)
8384 })
8385 } else {
8386 None
8387 };
8388 let ll1_only_alt: Option<usize> = if transition_count > 1
8397 && let Some((symbol, entry)) = lookahead_filter.as_ref()
8398 {
8399 let key = (state.state_number(), *symbol);
8400 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
8401 cached
8402 } else {
8403 let result = ll1_unique_alt(entry, *symbol);
8404 self.ll1_decision_cache.insert(key, result);
8405 result
8406 }
8407 } else {
8408 None
8409 };
8410 let lookahead_filter = lookahead_filter.as_ref();
8411 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
8417 for (transition_index, transition) in transitions.iter().enumerate() {
8418 if let Some(alt) = ll1_only_alt {
8419 if alt != transition_index {
8421 continue;
8422 }
8423 }
8424 let transition_kind = transition.kind();
8425 if ll1_only_alt.is_none()
8426 && should_skip_via_lookahead(
8427 transition_kind,
8428 transition_index,
8429 lookahead_filter,
8430 index,
8431 self.fast_recovery_enabled,
8432 expected,
8433 )
8434 {
8435 continue;
8436 }
8437 let target = transition.target();
8438 match transition_kind {
8439 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
8440 #[cfg(feature = "perf-counters")]
8441 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8442 let boundary = left_recursive_boundary(atn, state, target);
8443 outcomes.extend(
8444 self.recognize_state_fast(
8445 atn,
8446 FastRecognizeRequest {
8447 state_number: target,
8448 stop_state,
8449 index,
8450 rule_start_index,
8451 decision_start_index: next_decision_start_index,
8452 precedence,
8453 depth: depth + 1,
8454 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8455 recovery_state: epsilon_recovery_state,
8456 },
8457 FastRecognizeScratch {
8458 predicate_context,
8459 visiting,
8460 memo,
8461 expected,
8462 },
8463 )
8464 .into_iter()
8465 .map(|mut outcome| {
8466 if let Some(rule_index) = boundary {
8467 let boundary = self.arena_boundary_node(rule_index);
8468 self.defer_fast_outcome_node(&mut outcome, boundary);
8469 }
8470 outcome
8471 }),
8472 );
8473 }
8474 ParserTransitionKind::Predicate => {
8475 #[cfg(feature = "perf-counters")]
8476 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8477 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
8478 let boundary = left_recursive_boundary(atn, state, target);
8479 outcomes.extend(
8480 self.recognize_state_fast(
8481 atn,
8482 FastRecognizeRequest {
8483 state_number: target,
8484 stop_state,
8485 index,
8486 rule_start_index,
8487 decision_start_index: next_decision_start_index,
8488 precedence,
8489 depth: depth + 1,
8490 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8491 recovery_state: epsilon_recovery_state,
8492 },
8493 FastRecognizeScratch {
8494 predicate_context,
8495 visiting,
8496 memo,
8497 expected,
8498 },
8499 )
8500 .into_iter()
8501 .map(|mut outcome| {
8502 if let Some(rule_index) = boundary {
8503 let boundary = self.arena_boundary_node(rule_index);
8504 self.defer_fast_outcome_node(&mut outcome, boundary);
8505 }
8506 outcome
8507 }),
8508 );
8509 } else {
8510 record_predicate_no_viable(expected, next_decision_start_index, index);
8511 }
8512 }
8513 ParserTransitionKind::Precedence => {
8514 let transition_precedence = packed_i32(transition.arg0());
8515 if transition_precedence >= precedence {
8516 let boundary = left_recursive_boundary(atn, state, target);
8517 outcomes.extend(
8518 self.recognize_state_fast(
8519 atn,
8520 FastRecognizeRequest {
8521 state_number: target,
8522 stop_state,
8523 index,
8524 rule_start_index,
8525 decision_start_index: next_decision_start_index,
8526 precedence,
8527 depth: depth + 1,
8528 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8529 recovery_state: epsilon_recovery_state,
8530 },
8531 FastRecognizeScratch {
8532 predicate_context,
8533 visiting,
8534 memo,
8535 expected,
8536 },
8537 )
8538 .into_iter()
8539 .map(|mut outcome| {
8540 if let Some(rule_index) = boundary {
8541 let boundary = self.arena_boundary_node(rule_index);
8542 self.defer_fast_outcome_node(&mut outcome, boundary);
8543 }
8544 outcome
8545 }),
8546 );
8547 }
8548 }
8549 ParserTransitionKind::Rule => {
8550 let rule_index = transition.arg0() as usize;
8551 let follow_state = transition.arg1() as usize;
8552 let rule_precedence = packed_i32(transition.arg2());
8553 #[cfg(feature = "perf-counters")]
8554 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
8555 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
8556 continue;
8557 };
8558 let symbol = self.token_type_at(index);
8570 if self.fast_first_set_prefilter {
8571 let first = self.cached_rule_first_set(atn, target, child_stop);
8584 if should_skip_rule_via_first_set(
8585 &first,
8586 symbol,
8587 self.fast_recovery_enabled,
8588 index,
8589 expected,
8590 ) {
8591 continue;
8592 }
8593 }
8594 let expected_before_child =
8595 self.fast_recovery_enabled.then(|| expected.clone());
8596 let mut children = self.recognize_state_fast(
8597 atn,
8598 FastRecognizeRequest {
8599 state_number: target,
8600 stop_state: child_stop,
8601 index,
8602 rule_start_index: index,
8603 decision_start_index: None,
8604 precedence: rule_precedence,
8605 depth: depth + 1,
8606 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8607 recovery_state: epsilon_recovery_state,
8608 },
8609 FastRecognizeScratch {
8610 predicate_context,
8611 visiting,
8612 memo,
8613 expected,
8614 },
8615 );
8616 if children.is_empty() && self.fast_recovery_enabled {
8617 children = self.fast_child_rule_failure_recovery_outcomes(
8618 FastChildRuleFailureRecoveryRequest {
8619 atn,
8620 rule_index,
8621 start_index: index,
8622 follow_state,
8623 stop_state,
8624 expected,
8625 },
8626 );
8627 }
8628 if let Some(expected_before_child) = expected_before_child {
8629 if children
8630 .iter()
8631 .any(|child| child.diagnostics.is_empty() && child.index > index)
8632 {
8633 *expected = expected_before_child;
8634 }
8635 }
8636 for child in children {
8637 let child_index = child.index;
8638 let child_consumed_eof = child.consumed_eof;
8639 let child_diagnostics = child.diagnostics;
8640 let empty_recovery = self.empty_recovery_symbols();
8641 let follow_outcomes = self.recognize_state_fast(
8642 atn,
8643 FastRecognizeRequest {
8644 state_number: follow_state,
8645 stop_state,
8646 index: child_index,
8647 rule_start_index,
8648 decision_start_index: next_decision_start_index,
8649 precedence,
8650 depth: depth + 1,
8651 recovery_symbols: empty_recovery,
8652 recovery_state: None,
8653 },
8654 FastRecognizeScratch {
8655 predicate_context,
8656 visiting,
8657 memo,
8658 expected,
8659 },
8660 );
8661 if follow_outcomes.is_empty() {
8662 continue;
8663 }
8664 let child_stop_index =
8665 self.rule_stop_token_index(child_index, child_consumed_eof);
8666 let child_node = self.build_parse_trees.then(|| {
8667 self.recognition_arena.deferred_rule_node(FastDeferredRule {
8668 rule_index: u32::try_from(rule_index)
8669 .expect("rule index fits in u32"),
8670 invoking_state: i32::try_from(invoking_state_number(state_number))
8671 .expect("invoking state fits in i32"),
8672 start_index: u32::try_from(index)
8673 .expect("rule start index fits in u32"),
8674 stop_index: child_stop_index.map(|stop_index| {
8675 u32::try_from(stop_index).expect("rule stop index fits in u32")
8676 }),
8677 deferred_children: child.deferred_nodes,
8678 children: child.nodes,
8679 })
8680 });
8681 let child_diags_empty = child_diagnostics.is_empty();
8682 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
8683 outcome.consumed_eof |= child_consumed_eof;
8684 if !child_diags_empty {
8687 outcome.diagnostics = self
8688 .recognition_arena
8689 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
8690 }
8691 if let Some(child_node) = child_node {
8692 outcome.deferred_nodes = self
8693 .recognition_arena
8694 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
8695 }
8696 outcome
8697 }));
8698 }
8699 }
8700 ParserTransitionKind::Atom
8701 | ParserTransitionKind::Range
8702 | ParserTransitionKind::Set
8703 | ParserTransitionKind::NotSet
8704 | ParserTransitionKind::Wildcard => {
8705 #[cfg(feature = "perf-counters")]
8706 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
8707 let symbol = self.token_type_at(index);
8708 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
8709 let next_index = self.consume_index(index, symbol);
8710 let empty_recovery = self.empty_recovery_symbols();
8711 outcomes.extend(
8712 self.recognize_state_fast(
8713 atn,
8714 FastRecognizeRequest {
8715 state_number: target,
8716 stop_state,
8717 index: next_index,
8718 rule_start_index,
8719 decision_start_index: next_decision_start_index,
8720 precedence,
8721 depth: depth + 1,
8722 recovery_symbols: empty_recovery,
8723 recovery_state: None,
8724 },
8725 FastRecognizeScratch {
8726 predicate_context,
8727 visiting,
8728 memo,
8729 expected,
8730 },
8731 )
8732 .into_iter()
8733 .map(|mut outcome| {
8734 outcome.consumed_eof |= symbol == TOKEN_EOF;
8735 if self.fast_token_nodes_enabled {
8736 let token = self.arena_token_node(index, false);
8737 self.defer_fast_outcome_node(&mut outcome, token);
8738 }
8739 outcome
8740 }),
8741 );
8742 } else {
8743 if !self.fast_recovery_enabled {
8744 continue;
8752 }
8753 let expected_symbols = fast_recovery_expected_symbols(
8754 self,
8755 atn,
8756 state.state_number(),
8757 &recovery_symbols,
8758 );
8759 if expected_symbols.contains(&symbol) {
8760 continue;
8761 }
8762 {
8763 expected.record_transition(index, transition, max_token_type);
8764 record_no_viable_if_ambiguous(
8765 expected,
8766 next_decision_start_index,
8767 index,
8768 );
8769 outcomes.extend(self.fast_single_token_deletion_recovery(
8770 FastRecoveryRequest {
8771 atn,
8772 transition,
8773 expected_symbols: Rc::clone(&expected_symbols),
8774 target,
8775 request: FastRecognizeRequest {
8776 state_number,
8777 stop_state,
8778 index,
8779 rule_start_index,
8780 decision_start_index,
8781 precedence,
8782 depth,
8783 recovery_symbols: Rc::clone(&recovery_symbols),
8784 recovery_state,
8785 },
8786 visiting,
8787 memo,
8788 expected,
8789 },
8790 predicate_context,
8791 ));
8792 if !state_is_left_recursive_rule(atn, state) {
8793 outcomes.extend(self.fast_single_token_insertion_recovery(
8794 FastRecoveryRequest {
8795 atn,
8796 transition,
8797 expected_symbols: Rc::clone(&expected_symbols),
8798 target,
8799 request: FastRecognizeRequest {
8800 state_number,
8801 stop_state,
8802 index,
8803 rule_start_index,
8804 decision_start_index,
8805 precedence,
8806 depth,
8807 recovery_symbols: Rc::clone(&recovery_symbols),
8808 recovery_state,
8809 },
8810 visiting,
8811 memo,
8812 expected,
8813 },
8814 predicate_context,
8815 ));
8816 }
8817 outcomes.extend(self.fast_current_token_deletion_recovery(
8818 FastCurrentTokenDeletionRequest {
8819 atn,
8820 expected_symbols,
8821 request: FastRecognizeRequest {
8822 state_number,
8823 stop_state,
8824 index,
8825 rule_start_index,
8826 decision_start_index,
8827 precedence,
8828 depth,
8829 recovery_symbols: Rc::clone(&recovery_symbols),
8830 recovery_state,
8831 },
8832 visiting,
8833 memo,
8834 expected,
8835 },
8836 predicate_context,
8837 ));
8838 }
8839 }
8840 }
8841 }
8842 }
8843
8844 if has_inserted_cycle_guard {
8845 visiting.remove(&key);
8846 }
8847 if matches!(
8848 self.prediction_mode,
8849 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
8850 ) && self.fast_recovery_enabled
8851 {
8852 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
8856 }
8857 if self.fast_recovery_enabled {
8858 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
8859 } else {
8860 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8861 }
8862 let should_memoize = self.fast_recovery_enabled
8872 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
8873 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
8877 if inline_consumed_eof {
8878 outcome.consumed_eof = true;
8879 }
8880 if !inline_consumed_tokens.is_empty() {
8881 for token_index in inline_consumed_tokens.iter().rev() {
8882 let token = self.arena_token_node(*token_index, false);
8883 self.defer_fast_outcome_node(&mut outcome, token);
8884 }
8885 }
8886 outcome
8887 };
8888 if should_memoize {
8889 #[cfg(feature = "perf-counters")]
8890 {
8891 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
8892 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
8893 match outcomes.len() {
8894 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
8895 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
8896 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
8897 }
8898 }
8899 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
8904 memo.insert(key, Rc::clone(&stored));
8905 if inline_pending {
8906 return stored
8907 .iter()
8908 .copied()
8909 .map(&mut apply_inline_pending)
8910 .collect();
8911 }
8912 return stored.to_vec();
8913 }
8914 #[cfg(feature = "perf-counters")]
8915 match outcomes.len() {
8916 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
8917 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
8918 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
8919 }
8920 if inline_pending {
8921 return outcomes.into_iter().map(apply_inline_pending).collect();
8922 }
8923 outcomes
8924 }
8925
8926 fn single_token_deletion_recovery(
8929 &mut self,
8930 recovery: RecoveryRequest<'_, '_>,
8931 ) -> Vec<RecognizeOutcome> {
8932 let RecoveryRequest {
8933 atn,
8934 transition,
8935 expected_symbols,
8936 target,
8937 request,
8938 visiting,
8939 memo,
8940 expected,
8941 } = recovery;
8942 let RecognizeRequest {
8943 stop_state,
8944 index,
8945 rule_start_index,
8946 decision_start_index,
8947 init_action_rules,
8948 predicates,
8949 semantics,
8950 rule_args,
8951 member_actions,
8952 return_actions,
8953 local_int_arg,
8954 member_values,
8955 return_values,
8956 rule_alt_number,
8957 track_alt_numbers,
8958 consumed_eof,
8959 precedence,
8960 depth,
8961 ..
8962 } = request;
8963 let Some((diagnostic, next_index, next_symbol)) =
8964 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
8965 else {
8966 return Vec::new();
8967 };
8968 let after_next = self.consume_index(next_index, next_symbol);
8969 self.recognize_state(
8970 atn,
8971 RecognizeRequest {
8972 state_number: target,
8973 stop_state,
8974 index: after_next,
8975 rule_start_index,
8976 decision_start_index,
8977 init_action_rules,
8978 predicates,
8979 semantics,
8980 rule_args,
8981 member_actions,
8982 return_actions,
8983 local_int_arg,
8984 member_values,
8985 return_values,
8986 rule_alt_number,
8987 track_alt_numbers,
8988 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
8989 precedence,
8990 depth: depth + 1,
8991 recovery_symbols: BTreeSet::new(),
8992 recovery_state: None,
8993 },
8994 visiting,
8995 memo,
8996 expected,
8997 )
8998 .into_iter()
8999 .map(|mut outcome| {
9000 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
9001 outcome.diagnostics = self
9002 .recognition_arena
9003 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9004 let token = self.arena_token_node(next_index, false);
9005 self.arena_prepend(&mut outcome.nodes, token);
9006 let error = self.arena_token_node(index, true);
9007 self.arena_prepend(&mut outcome.nodes, error);
9008 outcome
9009 })
9010 .collect()
9011 }
9012
9013 fn current_token_deletion_recovery(
9016 &mut self,
9017 recovery: CurrentTokenDeletionRequest<'_, '_>,
9018 ) -> Vec<RecognizeOutcome> {
9019 let CurrentTokenDeletionRequest {
9020 atn,
9021 expected_symbols,
9022 mut request,
9023 visiting,
9024 memo,
9025 expected,
9026 } = recovery;
9027 let error_index = request.index;
9028 if error_index == request.rule_start_index {
9029 return Vec::new();
9030 }
9031 let Some((diagnostic, next_index, skipped)) =
9032 self.current_token_deletion(error_index, &expected_symbols)
9033 else {
9034 return Vec::new();
9035 };
9036 request.state_number = request.recovery_state.unwrap_or(request.state_number);
9037 request.index = next_index;
9038 request.depth += 1;
9039 request.recovery_state = None;
9040 self.recognize_state(atn, request, visiting, memo, expected)
9041 .into_iter()
9042 .map(|mut outcome| {
9043 outcome.diagnostics = self
9044 .recognition_arena
9045 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9046 for index in skipped.iter().rev() {
9047 let error = self.arena_token_node(*index, true);
9048 self.arena_prepend(&mut outcome.nodes, error);
9049 }
9050 outcome
9051 })
9052 .collect()
9053 }
9054
9055 fn consuming_failure_fallback(
9058 &mut self,
9059 fallback: ConsumingFailureFallback<'_>,
9060 visiting: &mut BTreeSet<RecognizeKey>,
9061 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9062 expected: &mut ExpectedTokens,
9063 ) -> Vec<RecognizeOutcome> {
9064 if fallback.expected_symbols.is_empty() {
9065 return Vec::new();
9066 }
9067 if fallback.symbol == TOKEN_EOF {
9068 return self.eof_consuming_failure_fallback(fallback, expected);
9069 }
9070 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
9071 }
9072
9073 fn non_eof_consuming_failure_fallback(
9076 &mut self,
9077 fallback: ConsumingFailureFallback<'_>,
9078 visiting: &mut BTreeSet<RecognizeKey>,
9079 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9080 expected: &mut ExpectedTokens,
9081 ) -> Vec<RecognizeOutcome> {
9082 let ConsumingFailureFallback {
9083 atn,
9084 target,
9085 request,
9086 symbol,
9087 expected_symbols,
9088 decision_start_index,
9089 decision,
9090 } = fallback;
9091 let error_index = request.index;
9092 let diagnostic =
9093 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
9094 let next_index = self.consume_index(error_index, symbol);
9095 self.recognize_state(
9096 atn,
9097 RecognizeRequest {
9098 state_number: target,
9099 stop_state: request.stop_state,
9100 index: next_index,
9101 rule_start_index: request.rule_start_index,
9102 decision_start_index,
9103 init_action_rules: request.init_action_rules,
9104 predicates: request.predicates,
9105 semantics: request.semantics,
9106 rule_args: request.rule_args,
9107 member_actions: request.member_actions,
9108 return_actions: request.return_actions,
9109 local_int_arg: request.local_int_arg,
9110 member_values: request.member_values,
9111 return_values: request.return_values,
9112 rule_alt_number: request.rule_alt_number,
9113 track_alt_numbers: request.track_alt_numbers,
9114 consumed_eof: request.consumed_eof,
9115 precedence: request.precedence,
9116 depth: request.depth + 1,
9117 recovery_symbols: BTreeSet::new(),
9118 recovery_state: None,
9119 },
9120 visiting,
9121 memo,
9122 expected,
9123 )
9124 .into_iter()
9125 .map(|mut outcome| {
9126 prepend_decision(&mut outcome, decision);
9127 outcome.diagnostics = self
9128 .recognition_arena
9129 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9130 let error = self.arena_token_node(error_index, true);
9131 self.arena_prepend(&mut outcome.nodes, error);
9132 outcome
9133 })
9134 .collect()
9135 }
9136
9137 fn eof_consuming_failure_fallback(
9140 &mut self,
9141 fallback: ConsumingFailureFallback<'_>,
9142 expected: &ExpectedTokens,
9143 ) -> Vec<RecognizeOutcome> {
9144 let request = fallback.request;
9145 if request.index == request.rule_start_index {
9146 return Vec::new();
9147 }
9148 let diagnostic =
9149 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
9150 let diagnostics = self
9151 .recognition_arena
9152 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
9153 vec![RecognizeOutcome {
9154 index: request.index,
9155 consumed_eof: request.consumed_eof,
9156 alt_number: request.rule_alt_number,
9157 member_values: request.member_values,
9158 return_values: request.return_values,
9159 diagnostics,
9160 decisions: Vec::new(),
9161 actions: Vec::new(),
9162 nodes: NodeSeqId::EMPTY,
9163 }]
9164 }
9165
9166 fn single_token_insertion_recovery(
9169 &mut self,
9170 recovery: RecoveryRequest<'_, '_>,
9171 ) -> Vec<RecognizeOutcome> {
9172 let RecoveryRequest {
9173 atn,
9174 transition,
9175 expected_symbols,
9176 target,
9177 request,
9178 visiting,
9179 memo,
9180 expected,
9181 } = recovery;
9182 let RecognizeRequest {
9183 stop_state,
9184 index,
9185 rule_start_index,
9186 decision_start_index,
9187 init_action_rules,
9188 predicates,
9189 semantics,
9190 rule_args,
9191 member_actions,
9192 return_actions,
9193 local_int_arg,
9194 member_values,
9195 return_values,
9196 rule_alt_number,
9197 track_alt_numbers,
9198 consumed_eof,
9199 precedence,
9200 depth,
9201 ..
9202 } = request;
9203 let follow_symbols = state_expected_symbols(atn, transition.target());
9204 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
9205 transition,
9206 index,
9207 atn.max_token_type(),
9208 &expected_symbols,
9209 &follow_symbols,
9210 ) else {
9211 return Vec::new();
9212 };
9213 self.recognize_state(
9214 atn,
9215 RecognizeRequest {
9216 state_number: target,
9217 stop_state,
9218 index,
9219 rule_start_index,
9220 decision_start_index,
9221 init_action_rules,
9222 predicates,
9223 semantics,
9224 rule_args,
9225 member_actions,
9226 return_actions,
9227 local_int_arg,
9228 member_values,
9229 return_values,
9230 rule_alt_number,
9231 track_alt_numbers,
9232 consumed_eof,
9233 precedence,
9234 depth: depth + 1,
9235 recovery_symbols: BTreeSet::new(),
9236 recovery_state: None,
9237 },
9238 visiting,
9239 memo,
9240 expected,
9241 )
9242 .into_iter()
9243 .map(|mut outcome| {
9244 outcome.diagnostics = self
9245 .recognition_arena
9246 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9247 let missing = self.arena_missing_token_node(token_type, index, text.clone());
9248 self.arena_prepend(&mut outcome.nodes, missing);
9249 outcome
9250 })
9251 .collect()
9252 }
9253
9254 #[allow(clippy::too_many_lines)]
9257 fn recognize_state(
9258 &mut self,
9259 atn: &Atn,
9260 request: RecognizeRequest<'_>,
9261 visiting: &mut BTreeSet<RecognizeKey>,
9262 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9263 expected: &mut ExpectedTokens,
9264 ) -> Vec<RecognizeOutcome> {
9265 let request_template = request.clone();
9266 let RecognizeRequest {
9267 state_number,
9268 stop_state,
9269 index,
9270 rule_start_index,
9271 decision_start_index,
9272 init_action_rules,
9273 predicates,
9274 semantics,
9275 rule_args,
9276 member_actions,
9277 return_actions,
9278 local_int_arg,
9279 member_values,
9280 return_values,
9281 rule_alt_number,
9282 track_alt_numbers,
9283 consumed_eof,
9284 precedence,
9285 depth,
9286 recovery_symbols,
9287 recovery_state,
9288 } = request;
9289 if depth > RECOGNITION_DEPTH_LIMIT {
9290 return Vec::new();
9291 }
9292 if state_number == stop_state {
9293 return stop_outcome(
9294 index,
9295 consumed_eof,
9296 rule_alt_number,
9297 member_values,
9298 return_values,
9299 );
9300 }
9301 let key = RecognizeKey {
9302 state_number,
9303 stop_state,
9304 index,
9305 rule_start_index,
9306 decision_start_index,
9307 local_int_arg,
9308 member_values: member_values.clone(),
9309 return_values: return_values.clone(),
9310 rule_alt_number,
9311 track_alt_numbers,
9312 consumed_eof,
9313 precedence,
9314 recovery_symbols: recovery_symbols.clone(),
9315 recovery_state,
9316 };
9317 if let Some(outcomes) = memo.get(&key) {
9318 return outcomes.clone();
9319 }
9320
9321 let visit_key = key.clone();
9322 if !visiting.insert(visit_key.clone()) {
9323 return Vec::new();
9324 }
9325
9326 let Some(state) = atn.state(state_number) else {
9327 visiting.remove(&visit_key);
9328 return Vec::new();
9329 };
9330 let transitions = state.transitions();
9331 let transition_count = transitions.len();
9332 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9333 Some(index)
9334 } else {
9335 decision_start_index
9336 };
9337 let (epsilon_recovery_symbols, epsilon_recovery_state) =
9338 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
9339 let mut outcomes = Vec::new();
9340 for (transition_index, transition) in transitions.iter().enumerate() {
9341 let decision =
9342 transition_decision(atn, state, transition_count, transition_index, predicates);
9343 let next_alt_number = next_alt_number(
9344 state,
9345 transition_count,
9346 transition_index,
9347 rule_alt_number,
9348 track_alt_numbers,
9349 );
9350 let transition_data = transition.data();
9351 match &transition_data {
9352 Transition::Epsilon { target } | Transition::Action { target, .. } => {
9353 let action_rule_index = match &transition_data {
9354 Transition::Action { rule_index, .. } => Some(*rule_index),
9355 _ => None,
9356 };
9357 outcomes.extend(self.recognize_epsilon_or_action_step(
9358 atn,
9359 &request_template,
9360 EpsilonActionStep {
9361 source_state: state_number,
9362 target: *target,
9363 action_rule_index,
9364 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
9365 decision,
9366 decision_start_index: next_decision_start_index,
9367 alt_number: next_alt_number,
9368 recovery_symbols: epsilon_recovery_symbols.clone(),
9369 recovery_state: epsilon_recovery_state,
9370 },
9371 RecognizeScratch {
9372 visiting,
9373 memo,
9374 expected,
9375 },
9376 ));
9377 }
9378 Transition::Predicate {
9379 target,
9380 rule_index,
9381 pred_index,
9382 ..
9383 } => {
9384 let predicate = PredicateEval {
9385 index,
9386 rule_index: *rule_index,
9387 pred_index: *pred_index,
9388 predicates,
9389 semantics,
9390 context: None,
9391 local_int_arg,
9392 member_values: &member_values,
9393 };
9394 if self.parser_predicate_matches(predicate) {
9395 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
9396 outcomes.extend(
9397 self.recognize_state(
9398 atn,
9399 RecognizeRequest {
9400 state_number: *target,
9401 stop_state,
9402 index,
9403 rule_start_index,
9404 decision_start_index: next_decision_start_index,
9405 init_action_rules,
9406 predicates,
9407 semantics,
9408 rule_args,
9409 member_actions,
9410 return_actions,
9411 local_int_arg,
9412 member_values: member_values.clone(),
9413 return_values: return_values.clone(),
9414 rule_alt_number: next_alt_number,
9415 track_alt_numbers,
9416 consumed_eof,
9417 precedence,
9418 depth: depth + 1,
9419 recovery_symbols: epsilon_recovery_symbols.clone(),
9420 recovery_state: epsilon_recovery_state,
9421 },
9422 visiting,
9423 memo,
9424 expected,
9425 )
9426 .into_iter()
9427 .map(|mut outcome| {
9428 prepend_decision(&mut outcome, decision);
9429 if let Some(rule_index) = left_recursive_boundary {
9430 let boundary = self.arena_boundary_node(rule_index);
9431 self.arena_prepend(&mut outcome.nodes, boundary);
9432 }
9433 outcome
9434 }),
9435 );
9436 } else if let Some(message) = semantics
9437 .and_then(|semantics| {
9438 self.parser_semantic_ir_predicate_failure_message(
9439 *rule_index,
9440 *pred_index,
9441 semantics,
9442 )
9443 })
9444 .or_else(|| {
9445 self.parser_predicate_failure_message(
9446 *rule_index,
9447 *pred_index,
9448 predicates,
9449 )
9450 })
9451 {
9452 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
9453 rule_index: *rule_index,
9454 index,
9455 message,
9456 member_values: member_values.clone(),
9457 return_values: return_values.clone(),
9458 rule_alt_number,
9459 }));
9460 } else {
9461 record_predicate_no_viable(expected, next_decision_start_index, index);
9462 }
9463 }
9464 Transition::Precedence {
9465 target,
9466 precedence: transition_precedence,
9467 } => {
9468 if *transition_precedence >= precedence {
9469 outcomes.extend(
9470 self.recognize_state(
9471 atn,
9472 RecognizeRequest {
9473 state_number: *target,
9474 stop_state,
9475 index,
9476 rule_start_index,
9477 decision_start_index: next_decision_start_index,
9478 init_action_rules,
9479 predicates,
9480 semantics,
9481 rule_args,
9482 member_actions,
9483 return_actions,
9484 local_int_arg,
9485 member_values: member_values.clone(),
9486 return_values: return_values.clone(),
9487 rule_alt_number: next_alt_number,
9488 track_alt_numbers,
9489 consumed_eof,
9490 precedence,
9491 depth: depth + 1,
9492 recovery_symbols: epsilon_recovery_symbols.clone(),
9493 recovery_state: epsilon_recovery_state,
9494 },
9495 visiting,
9496 memo,
9497 expected,
9498 )
9499 .into_iter()
9500 .map(|mut outcome| {
9501 prepend_decision(&mut outcome, decision);
9502 outcome
9503 }),
9504 );
9505 }
9506 }
9507 Transition::Rule {
9508 target,
9509 rule_index,
9510 follow_state,
9511 precedence: rule_precedence,
9512 ..
9513 } => {
9514 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
9515 continue;
9516 };
9517 let child_local_int_arg =
9518 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
9519 let expected_before_child = expected.clone();
9520 let children = self.recognize_state(
9521 atn,
9522 RecognizeRequest {
9523 state_number: *target,
9524 stop_state: child_stop,
9525 index,
9526 rule_start_index: index,
9527 decision_start_index: None,
9528 init_action_rules,
9529 predicates,
9530 semantics,
9531 rule_args,
9532 member_actions,
9533 return_actions,
9534 local_int_arg: child_local_int_arg,
9535 member_values: member_values.clone(),
9536 return_values: BTreeMap::new(),
9537 rule_alt_number: 0,
9538 track_alt_numbers,
9539 consumed_eof: false,
9540 precedence: *rule_precedence,
9541 depth: depth + 1,
9542 recovery_symbols: epsilon_recovery_symbols.clone(),
9543 recovery_state: epsilon_recovery_state,
9544 },
9545 visiting,
9546 memo,
9547 expected,
9548 );
9549 let children = if children.is_empty() {
9550 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
9551 atn,
9552 rule_index: *rule_index,
9553 start_index: index,
9554 follow_state: *follow_state,
9555 stop_state,
9556 member_values: member_values.clone(),
9557 expected,
9558 })
9559 } else {
9560 children
9561 };
9562 let preserve_child_expected =
9563 self.child_expected_reaches_clean_eof(&children, expected);
9564 restore_expected(
9565 &children,
9566 index,
9567 expected,
9568 expected_before_child,
9569 preserve_child_expected,
9570 );
9571 for child in children {
9572 let child_stop_index =
9573 self.rule_stop_token_index(child.index, child.consumed_eof);
9574 let child_nodes = self
9575 .recognition_arena
9576 .fold_left_recursive_boundaries(child.nodes);
9577 let child_node = self.arena_rule_node(ArenaRuleSpec {
9578 rule_index: *rule_index,
9579 invoking_state: invoking_state_number(state_number),
9580 alt_number: child.alt_number,
9581 start_index: index,
9582 stop_index: child_stop_index,
9583 return_values: child.return_values.clone(),
9584 children: child_nodes,
9585 });
9586 outcomes.extend(
9587 self.recognize_state(
9588 atn,
9589 RecognizeRequest {
9590 state_number: *follow_state,
9591 stop_state,
9592 index: child.index,
9593 rule_start_index,
9594 decision_start_index: next_decision_start_index,
9595 init_action_rules,
9596 predicates,
9597 semantics,
9598 rule_args,
9599 member_actions,
9600 return_actions,
9601 local_int_arg,
9602 member_values: child.member_values.clone(),
9603 return_values: return_values.clone(),
9604 rule_alt_number,
9605 track_alt_numbers,
9606 consumed_eof: consumed_eof || child.consumed_eof,
9607 precedence,
9608 depth: depth + 1,
9609 recovery_symbols: BTreeSet::new(),
9610 recovery_state: None,
9611 },
9612 visiting,
9613 memo,
9614 expected,
9615 )
9616 .into_iter()
9617 .map(|mut outcome| {
9618 outcome.consumed_eof |= child.consumed_eof;
9619 outcome.diagnostics = self
9620 .recognition_arena
9621 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
9622 let mut decisions = child.decisions.clone();
9623 decisions.append(&mut outcome.decisions);
9624 outcome.decisions = decisions;
9625 prepend_decision(&mut outcome, decision);
9626 let mut actions = child.actions.clone();
9627 if init_action_rules.contains(rule_index) {
9628 actions.insert(
9629 0,
9630 ParserAction::new_rule_init(
9631 *rule_index,
9632 index,
9633 Some(*follow_state),
9634 ),
9635 );
9636 }
9637 actions.append(&mut outcome.actions);
9638 outcome.actions = actions;
9639 self.arena_prepend(&mut outcome.nodes, child_node);
9640 outcome
9641 }),
9642 );
9643 }
9644 }
9645 Transition::Atom { target, .. }
9646 | Transition::Range { target, .. }
9647 | Transition::Set { target, .. }
9648 | Transition::NotSet { target, .. }
9649 | Transition::Wildcard { target, .. } => {
9650 let symbol = self.token_type_at(index);
9651 if transition_data.matches(symbol, 1, atn.max_token_type()) {
9652 let next_index = self.consume_index(index, symbol);
9653 outcomes.extend(
9654 self.recognize_state(
9655 atn,
9656 RecognizeRequest {
9657 state_number: *target,
9658 stop_state,
9659 index: next_index,
9660 rule_start_index,
9661 decision_start_index: next_decision_start_index,
9662 init_action_rules,
9663 predicates,
9664 semantics,
9665 rule_args,
9666 member_actions,
9667 return_actions,
9668 local_int_arg,
9669 member_values: member_values.clone(),
9670 return_values: return_values.clone(),
9671 rule_alt_number: next_alt_number,
9672 track_alt_numbers,
9673 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
9674 precedence,
9675 depth: depth + 1,
9676 recovery_symbols: BTreeSet::new(),
9677 recovery_state: None,
9678 },
9679 visiting,
9680 memo,
9681 expected,
9682 )
9683 .into_iter()
9684 .map(|mut outcome| {
9685 prepend_decision(&mut outcome, decision);
9686 outcome.consumed_eof |= symbol == TOKEN_EOF;
9687 let token = self.arena_token_node(index, false);
9688 self.arena_prepend(&mut outcome.nodes, token);
9689 outcome
9690 }),
9691 );
9692 } else {
9693 let expected_symbols =
9694 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
9695 if expected_symbols.contains(&symbol) {
9696 continue;
9697 }
9698 expected.record_transition(index, transition, atn.max_token_type());
9699 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
9700 let before_recovery = outcomes.len();
9701 let recovery_request = request_template.clone();
9702 outcomes.extend(
9703 self.single_token_deletion_recovery(RecoveryRequest {
9704 atn,
9705 transition,
9706 expected_symbols: expected_symbols.clone(),
9707 target: *target,
9708 request: recovery_request.clone(),
9709 visiting,
9710 memo,
9711 expected,
9712 })
9713 .into_iter()
9714 .map(|mut outcome| {
9715 prepend_decision(&mut outcome, decision);
9716 outcome
9717 }),
9718 );
9719 if !state_is_left_recursive_rule(atn, state) {
9720 outcomes.extend(
9721 self.single_token_insertion_recovery(RecoveryRequest {
9722 atn,
9723 transition,
9724 expected_symbols: expected_symbols.clone(),
9725 target: *target,
9726 request: recovery_request.clone(),
9727 visiting,
9728 memo,
9729 expected,
9730 })
9731 .into_iter()
9732 .map(|mut outcome| {
9733 prepend_decision(&mut outcome, decision);
9734 outcome
9735 }),
9736 );
9737 }
9738 outcomes.extend(self.current_token_deletion_recovery(
9739 CurrentTokenDeletionRequest {
9740 atn,
9741 expected_symbols: expected_symbols.clone(),
9742 request: recovery_request.clone(),
9743 visiting,
9744 memo,
9745 expected,
9746 },
9747 ));
9748 if outcomes.len() == before_recovery {
9749 outcomes.extend(self.consuming_failure_fallback(
9750 ConsumingFailureFallback {
9751 atn,
9752 target: *target,
9753 request: recovery_request,
9754 symbol,
9755 expected_symbols,
9756 decision_start_index: next_decision_start_index,
9757 decision,
9758 },
9759 visiting,
9760 memo,
9761 expected,
9762 ));
9763 }
9764 }
9765 }
9766 }
9767 }
9768
9769 visiting.remove(&visit_key);
9770 self.record_prediction_diagnostics(atn, state, index, &outcomes);
9771 if matches!(
9772 self.prediction_mode,
9773 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9774 ) {
9775 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
9776 }
9777 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
9778 memo.insert(key, outcomes.clone());
9779 outcomes
9780 }
9781
9782 fn recognize_epsilon_or_action_step(
9785 &mut self,
9786 atn: &Atn,
9787 request: &RecognizeRequest<'_>,
9788 step: EpsilonActionStep,
9789 scratch: RecognizeScratch<'_>,
9790 ) -> Vec<RecognizeOutcome> {
9791 let RecognizeScratch {
9792 visiting,
9793 memo,
9794 expected,
9795 } = scratch;
9796 let action = step.action_rule_index.map(|rule_index| {
9797 ParserAction::new(
9798 step.source_state,
9799 rule_index,
9800 request.rule_start_index,
9801 self.rule_stop_token_index(request.index, request.consumed_eof),
9802 )
9803 });
9804 let next_member_values = if action.is_some() {
9805 member_values_after_action(
9806 step.source_state,
9807 request.member_actions,
9808 request.semantics,
9809 &request.member_values,
9810 )
9811 } else {
9812 request.member_values.clone()
9813 };
9814 let next_return_values = action.map_or_else(
9815 || request.return_values.clone(),
9816 |action| {
9817 return_values_after_action(
9818 step.source_state,
9819 action.rule_index(),
9820 request.return_actions,
9821 request.semantics,
9822 &request.return_values,
9823 )
9824 },
9825 );
9826
9827 self.recognize_state(
9828 atn,
9829 RecognizeRequest {
9830 state_number: step.target,
9831 stop_state: request.stop_state,
9832 index: request.index,
9833 rule_start_index: request.rule_start_index,
9834 decision_start_index: step.decision_start_index,
9835 init_action_rules: request.init_action_rules,
9836 predicates: request.predicates,
9837 semantics: request.semantics,
9838 rule_args: request.rule_args,
9839 member_actions: request.member_actions,
9840 return_actions: request.return_actions,
9841 local_int_arg: request.local_int_arg,
9842 member_values: next_member_values,
9843 return_values: next_return_values,
9844 rule_alt_number: step.alt_number,
9845 track_alt_numbers: request.track_alt_numbers,
9846 consumed_eof: request.consumed_eof,
9847 precedence: request.precedence,
9848 depth: request.depth + 1,
9849 recovery_symbols: step.recovery_symbols,
9850 recovery_state: step.recovery_state,
9851 },
9852 visiting,
9853 memo,
9854 expected,
9855 )
9856 .into_iter()
9857 .map(|mut outcome| {
9858 prepend_decision(&mut outcome, step.decision);
9859 if let Some(rule_index) = step.left_recursive_boundary {
9860 let boundary = self.arena_boundary_node(rule_index);
9861 self.arena_prepend(&mut outcome.nodes, boundary);
9862 }
9863 if let Some(action) = action {
9864 outcome.actions.insert(0, action);
9865 }
9866 outcome
9867 })
9868 .collect()
9869 }
9870
9871 fn token_type_at(&mut self, index: usize) -> i32 {
9876 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
9877 self.input.fill();
9878 }
9879 self.input.token_type_at_index(index)
9880 }
9881
9882 fn cached_state_expected_symbols(
9894 &mut self,
9895 atn: &Atn,
9896 state_number: usize,
9897 ) -> Rc<BTreeSet<i32>> {
9898 if let Some(cached) = self.state_expected_cache.get(&state_number) {
9899 return Rc::clone(cached);
9900 }
9901 let symbols = state_expected_symbols(atn, state_number);
9902 let entry = self.intern_recovery_symbols(symbols);
9903 self.state_expected_cache
9904 .insert(state_number, Rc::clone(&entry));
9905 entry
9906 }
9907
9908 fn cached_state_expected_token_set(
9909 &mut self,
9910 atn: &Atn,
9911 state_number: usize,
9912 ) -> Rc<TokenBitSet> {
9913 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
9914 return Rc::clone(cached);
9915 }
9916 let symbols = with_shared_atn_caches(atn, |cache| {
9920 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
9921 return Rc::clone(cached);
9922 }
9923 let symbols = Rc::new(state_expected_token_set(atn, state_number));
9924 cache
9925 .state_expected_tokens
9926 .insert(state_number, Rc::clone(&symbols));
9927 symbols
9928 });
9929 self.state_expected_token_cache
9930 .insert(state_number, Rc::clone(&symbols));
9931 symbols
9932 }
9933
9934 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
9935 if self.rule_stop_reach_cache.len() <= state_number {
9936 self.rule_stop_reach_cache
9937 .resize_with(atn.states().len().max(state_number + 1), || None);
9938 }
9939 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
9940 return reaches;
9941 }
9942 let reaches = with_shared_atn_caches(atn, |cache| {
9943 *cache
9944 .rule_stop_reach
9945 .entry(state_number)
9946 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
9947 });
9948 self.rule_stop_reach_cache[state_number] = Some(reaches);
9949 reaches
9950 }
9951
9952 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
9955 Rc::clone(&self.empty_recovery_symbols)
9956 }
9957
9958 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
9967 if set.is_empty() {
9968 return Rc::clone(&self.empty_recovery_symbols);
9969 }
9970 let candidate = Rc::new(set);
9971 match self.recovery_symbols_intern.get(&candidate) {
9972 Some(existing) => Rc::clone(existing),
9973 None => {
9974 self.recovery_symbols_intern
9975 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
9976 candidate
9977 }
9978 }
9979 }
9980
9981 fn cached_decision_lookahead(
9986 &mut self,
9987 atn: &Atn,
9988 state: AtnState<'_>,
9989 rule_stop_state: usize,
9990 ) -> Rc<DecisionLookahead> {
9991 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
9998 return Rc::clone(cached);
9999 }
10000 let entry = with_shared_atn_caches(atn, |cache| {
10001 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
10002 return Rc::clone(cached);
10003 }
10004 let mut entry = DecisionLookahead {
10005 transitions: Vec::with_capacity(state.transitions().len()),
10006 };
10007 for transition in &state.transitions() {
10008 entry.transitions.push(transition_first_set(
10009 atn,
10010 transition,
10011 rule_stop_state,
10012 &mut cache.first_set,
10013 ));
10014 }
10015 let entry = Rc::new(entry);
10016 cache
10017 .decision_lookahead
10018 .insert(state.state_number(), Rc::clone(&entry));
10019 entry
10020 });
10021 self.decision_lookahead_cache
10022 .insert(state.state_number(), Rc::clone(&entry));
10023 entry
10024 }
10025
10026 fn cached_rule_first_set(
10027 &mut self,
10028 atn: &Atn,
10029 target: usize,
10030 child_stop: usize,
10031 ) -> Rc<FirstSet> {
10032 if self.rule_first_set_cache.len() <= target {
10033 self.rule_first_set_cache
10034 .resize_with(atn.states().len().max(target + 1), || None);
10035 }
10036 if let Some(cached) = self
10037 .rule_first_set_cache
10038 .get(target)
10039 .and_then(Option::as_ref)
10040 {
10041 return Rc::clone(cached);
10042 }
10043 let first = with_shared_first_set_cache(atn, |cache| {
10044 rule_first_set(atn, target, child_stop, cache)
10045 });
10046 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
10047 first
10048 }
10049
10050 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
10051 let atn_key = SharedAtnCacheKey::for_atn(atn);
10052 if self.empty_cycle_cache_atn != Some(atn_key) {
10053 self.empty_cycle_cache.clear();
10054 self.empty_cycle_cache_atn = Some(atn_key);
10055 }
10056 if self.empty_cycle_cache.len() <= state_number {
10057 self.empty_cycle_cache
10058 .resize_with(atn.state_count().max(state_number + 1), || None);
10059 }
10060 if let Some(cached) = self.empty_cycle_cache[state_number] {
10061 return cached;
10062 }
10063 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
10064 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
10065 self.empty_cycle_cache[state_number] = Some(result);
10066 result
10067 }
10068
10069 fn empty_path_reaches_state(
10070 &mut self,
10071 atn: &Atn,
10072 state_number: usize,
10073 target_state: usize,
10074 visited: &mut FxHashSet<usize>,
10075 ) -> bool {
10076 if !visited.insert(state_number) {
10077 return false;
10078 }
10079 let Some(state) = atn.state(state_number) else {
10080 return false;
10081 };
10082 for transition in &state.transitions() {
10083 let kind = transition.kind();
10084 let target = transition.target();
10085 match kind {
10086 ParserTransitionKind::Atom
10087 | ParserTransitionKind::Range
10088 | ParserTransitionKind::Set
10089 | ParserTransitionKind::NotSet
10090 | ParserTransitionKind::Wildcard => {}
10091 ParserTransitionKind::Rule => {
10092 let rule_index = transition.arg0() as usize;
10093 let follow_state = transition.arg1() as usize;
10094 if target == target_state
10095 || self.empty_path_reaches_state(atn, target, target_state, visited)
10096 {
10097 return true;
10098 }
10099 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
10100 continue;
10101 };
10102 if self.cached_rule_first_set(atn, target, child_stop).nullable
10103 && (follow_state == target_state
10104 || self.empty_path_reaches_state(
10105 atn,
10106 follow_state,
10107 target_state,
10108 visited,
10109 ))
10110 {
10111 return true;
10112 }
10113 }
10114 ParserTransitionKind::Epsilon
10115 | ParserTransitionKind::Predicate
10116 | ParserTransitionKind::Action
10117 | ParserTransitionKind::Precedence => {
10118 if target == target_state
10119 || self.empty_path_reaches_state(atn, target, target_state, visited)
10120 {
10121 return true;
10122 }
10123 }
10124 }
10125 }
10126 false
10127 }
10128
10129 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
10132 match self.clean_memo_mode {
10133 CleanMemoMode::Promote => true,
10134 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
10135 CleanMemoMode::Sparse => {
10136 self.clean_memo_sparse_samples += 1;
10137 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
10138 return false;
10139 }
10140 self.clean_memo_sparse_samples = 0;
10141 self.clean_memo_mode = CleanMemoMode::Probe;
10142 self.clean_memo_probe_samples = 0;
10143 self.clean_memo_probe_repeats = 0;
10144 self.clean_memo_probe_seen.clear();
10145 self.observe_clean_memo_probe(key)
10146 }
10147 }
10148 }
10149
10150 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
10151 self.clean_memo_probe_samples += 1;
10152 if !self.clean_memo_probe_seen.insert(key.clone()) {
10153 self.clean_memo_probe_repeats += 1;
10154 }
10155 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
10156 self.clean_memo_mode = CleanMemoMode::Promote;
10157 self.clean_memo_probe_seen.clear();
10158 return true;
10159 }
10160 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
10161 self.clean_memo_mode = CleanMemoMode::Sparse;
10162 self.clean_memo_sparse_samples = 0;
10163 self.clean_memo_probe_seen.clear();
10164 return false;
10165 }
10166 true
10167 }
10168
10169 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
10171 self.input.get(index)
10172 }
10173
10174 fn token_id_at(&self, index: usize) -> Option<TokenId> {
10176 self.input.get_id(index)
10177 }
10178
10179 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
10180 let token = self
10181 .token_id_at(index)
10182 .expect("recognized token index must exist in the token store");
10183 let node = if error {
10184 ArenaRecognizedNode::ErrorToken { token }
10185 } else {
10186 ArenaRecognizedNode::Token { token }
10187 };
10188 self.recognition_arena.push_node(node)
10189 }
10190
10191 fn arena_missing_token_node(
10192 &mut self,
10193 token_type: i32,
10194 at_index: usize,
10195 text: String,
10196 ) -> RecognizedNodeId {
10197 let extra = self
10198 .recognition_arena
10199 .push_extra(RecognitionExtra::MissingToken {
10200 token_type,
10201 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
10202 text,
10203 });
10204 self.recognition_arena
10205 .push_node(ArenaRecognizedNode::MissingToken { extra })
10206 }
10207
10208 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
10209 let ArenaRuleSpec {
10210 rule_index,
10211 invoking_state,
10212 alt_number,
10213 start_index,
10214 stop_index,
10215 return_values,
10216 children,
10217 } = spec;
10218 let return_values = (!return_values.is_empty()).then(|| {
10219 self.recognition_arena
10220 .push_extra(RecognitionExtra::ReturnValues(return_values))
10221 });
10222 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
10223 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10224 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
10225 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
10226 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
10227 stop_index: stop_index
10228 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
10229 return_values,
10230 children,
10231 })
10232 }
10233
10234 fn arena_boundary_node(&mut self, rule_index: usize) -> RecognizedNodeId {
10235 self.recognition_arena
10236 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
10237 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10238 })
10239 }
10240
10241 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
10242 *sequence = self.recognition_arena.prepend(*sequence, node);
10243 }
10244
10245 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
10246 self.last_recognition_arena_root = root;
10247 self.last_recognition_arena_diagnostics = diagnostics;
10248 #[cfg(feature = "perf-counters")]
10249 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
10250 let stats = self.recognition_arena_stats();
10251 #[allow(clippy::print_stderr)]
10252 {
10253 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
10254 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
10255 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
10256 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
10257 eprintln!("perf recognition_links_total={}", stats.total_links);
10258 eprintln!("perf recognition_links_live={}", stats.live_links);
10259 eprintln!("perf recognition_links_dead={}", stats.dead_links);
10260 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
10261 eprintln!("perf recognition_extras_total={}", stats.total_extras);
10262 eprintln!("perf recognition_extras_live={}", stats.live_extras);
10263 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
10264 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
10265 }
10266 }
10267 }
10268
10269 fn reset_recognition_arena(&mut self) {
10270 self.recognition_arena.reset();
10271 self.last_recognition_arena_root = NodeSeqId::EMPTY;
10272 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
10273 }
10274
10275 fn current_visible_index(&mut self) -> usize {
10278 let index = self.input.index();
10279 self.input.seek(index);
10280 self.input.index()
10281 }
10282
10283 fn child_expected_reaches_clean_eof(
10286 &mut self,
10287 children: &[RecognizeOutcome],
10288 expected: &ExpectedTokens,
10289 ) -> bool {
10290 let Some(index) = expected.index else {
10291 return false;
10292 };
10293 self.token_type_at(index) == TOKEN_EOF
10294 && children
10295 .iter()
10296 .any(|child| child.diagnostics.is_empty() && child.index == index)
10297 }
10298
10299 fn previous_token_index(&self, index: usize) -> Option<usize> {
10306 self.input.previous_visible_token_index(index)
10307 }
10308
10309 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
10314 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
10315 Some(index)
10316 } else {
10317 self.previous_token_index(index)
10318 }
10319 }
10320
10321 #[must_use]
10338 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
10339 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
10340 self.rule_stop_token_index(current_index, consumed_eof)
10341 }
10342
10343 #[must_use]
10352 pub fn after_action_stop_index_for_tree(
10353 &mut self,
10354 tree: ParseTree,
10355 current_index: usize,
10356 ) -> Option<usize> {
10357 if let Some(stop) = self
10358 .node(tree)
10359 .as_rule()
10360 .and_then(crate::tree::RuleNodeView::stop_id)
10361 {
10362 return Some(stop.index());
10363 }
10364 self.after_action_stop_index(current_index)
10365 }
10366
10367 #[must_use]
10377 pub fn after_action_start_index_for_tree(
10378 &self,
10379 tree: ParseTree,
10380 fallback_index: usize,
10381 ) -> usize {
10382 if let Some(start) = self
10383 .node(tree)
10384 .as_rule()
10385 .and_then(crate::tree::RuleNodeView::start_id)
10386 {
10387 return start.index();
10388 }
10389 fallback_index
10390 }
10391
10392 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
10397 self.rule_stop_token_index(index, consumed_eof)
10398 .and_then(|token_index| self.token_id_at(token_index))
10399 }
10400
10401 fn predicate_failure_recovery(
10408 &mut self,
10409 request: PredicateFailureRecovery<'_>,
10410 ) -> RecognizeOutcome {
10411 let PredicateFailureRecovery {
10412 rule_index,
10413 index,
10414 message,
10415 member_values,
10416 return_values,
10417 rule_alt_number,
10418 } = request;
10419 let rule_name = self
10420 .rule_names()
10421 .get(rule_index)
10422 .map_or_else(|| rule_index.to_string(), Clone::clone);
10423 let diagnostic = diagnostic_for_token(
10424 self.token_at(index).as_ref(),
10425 format!("rule {rule_name} {message}"),
10426 );
10427 let mut reversed_nodes = NodeSeqId::EMPTY;
10428 let mut next_index = index;
10429 loop {
10430 let symbol = self.token_type_at(next_index);
10431 if symbol == TOKEN_EOF {
10432 break;
10433 }
10434 let error = self.arena_token_node(next_index, true);
10435 self.arena_prepend(&mut reversed_nodes, error);
10436 let after = self.consume_index(next_index, symbol);
10437 if after == next_index {
10438 break;
10439 }
10440 next_index = after;
10441 }
10442 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
10443 let diagnostics = self
10444 .recognition_arena
10445 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10446 RecognizeOutcome {
10447 index: next_index,
10448 consumed_eof: false,
10449 alt_number: rule_alt_number,
10450 member_values,
10451 return_values,
10452 diagnostics,
10453 decisions: Vec::new(),
10454 actions: Vec::new(),
10455 nodes,
10456 }
10457 }
10458
10459 fn parser_semantic_hook_result(
10462 &mut self,
10463 request: ParserSemanticHookRequest<'_>,
10464 ) -> Option<bool> {
10465 let ParserSemanticHookRequest {
10466 index,
10467 rule_index,
10468 pred_index,
10469 context,
10470 local_int_arg,
10471 member_values,
10472 } = request;
10473 let rule_name = self.rule_names().get(rule_index).cloned();
10474 self.input.seek(index);
10475 let input = &mut self.input;
10476 let semantic_hooks = &mut self.semantic_hooks;
10477 let mut ctx = ParserSemCtx {
10478 input,
10479 tree_storage: &self.tree,
10480 rule_index,
10481 coordinate_index: pred_index,
10482 rule_name,
10483 context,
10484 tree: None,
10485 local_int_arg,
10486 member_values,
10487 action: None,
10488 };
10489 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
10490 }
10491
10492 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
10497 if prior.is_empty() {
10498 return;
10499 }
10500 let mut merged = prior;
10501 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
10502 if !merged.contains(&coordinate) {
10503 merged.push(coordinate);
10504 }
10505 }
10506 self.unknown_predicate_hits = merged;
10507 }
10508
10509 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
10518 apply_unknown_predicate_policy(
10519 self.unknown_predicate_policy,
10520 rule_index,
10521 pred_index,
10522 &mut self.unknown_predicate_hits,
10523 )
10524 }
10525
10526 fn unknown_semantic_error(&self) -> Option<AntlrError> {
10529 use std::fmt::Write as _;
10530 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
10531 return None;
10532 }
10533 let mut message = String::new();
10534 for (rule_index, pred_index) in &self.unknown_predicate_hits {
10535 if !message.is_empty() {
10536 message.push_str("; ");
10537 }
10538 let _ = match self.rule_names().get(*rule_index) {
10539 Some(rule_name) => write!(
10540 message,
10541 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
10542 ),
10543 None => write!(
10544 message,
10545 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
10546 ),
10547 };
10548 }
10549 for (rule_index, source_state) in &self.unhandled_action_hits {
10550 if !message.is_empty() {
10551 message.push_str("; ");
10552 }
10553 let _ = match self.rule_names().get(*rule_index) {
10554 Some(rule_name) => write!(
10555 message,
10556 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
10557 ),
10558 None => write!(
10559 message,
10560 "unhandled semantic action: rule_index={rule_index} state={source_state}"
10561 ),
10562 };
10563 }
10564 Some(AntlrError::Unsupported(message))
10565 }
10566
10567 fn parser_semir_predicate_matches(
10575 &mut self,
10576 semantics: &ParserSemantics,
10577 predicate: &ParserSemanticPredicate,
10578 request: ParserSemanticHookRequest<'_>,
10579 ) -> bool {
10580 self.input.seek(request.index);
10581 let rule_name = self
10582 .data
10583 .rule_names()
10584 .get(request.rule_index)
10585 .map(String::as_str);
10586 let unknown_predicate_policy = self.unknown_predicate_policy;
10587 let mut ctx = ParserSemIrCtx {
10588 input: &mut self.input,
10589 tree_storage: &self.tree,
10590 semantic_hooks: &mut self.semantic_hooks,
10591 rule_index: request.rule_index,
10592 coordinate_index: request.pred_index,
10593 rule_name,
10594 context: request.context,
10595 local_int_arg: request.local_int_arg,
10596 member_values: request.member_values,
10597 invoked_predicates: &mut self.invoked_predicates,
10598 unknown_predicate_policy,
10599 unknown_predicate_hits: &mut self.unknown_predicate_hits,
10600 };
10601 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
10602 }
10603
10604 fn fast_parser_predicate_matches(
10605 &mut self,
10606 context: Option<FastPredicateContext<'_>>,
10607 transition: ParserTransition<'_>,
10608 index: usize,
10609 ) -> bool {
10610 let Some(context) = context else {
10611 return true;
10612 };
10613 let rule_index = transition.arg0() as usize;
10614 let pred_index = transition.arg1() as usize;
10615 let key = (index, rule_index, pred_index);
10616 if let Some(result) = self.fast_predicate_cache.get(&key) {
10617 return *result;
10618 }
10619 let result = self.parser_predicate_matches(PredicateEval {
10620 index,
10621 rule_index,
10622 pred_index,
10623 predicates: context.predicates,
10624 semantics: context.semantics,
10625 context: None,
10626 local_int_arg: None,
10627 member_values: context.member_values,
10628 });
10629 self.fast_predicate_cache.insert(key, result);
10630 result
10631 }
10632
10633 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
10634 let PredicateEval {
10635 index,
10636 rule_index,
10637 pred_index,
10638 predicates,
10639 semantics,
10640 context,
10641 local_int_arg,
10642 member_values,
10643 } = eval;
10644 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
10645 semantics
10646 .predicates
10647 .iter()
10648 .find(|predicate| {
10649 predicate.rule_index == rule_index && predicate.pred_index == pred_index
10650 })
10651 .map(|predicate| (semantics, predicate))
10652 }) {
10653 return self.parser_semir_predicate_matches(
10654 semantics,
10655 predicate,
10656 ParserSemanticHookRequest {
10657 index,
10658 rule_index,
10659 pred_index,
10660 context,
10661 local_int_arg,
10662 member_values,
10663 },
10664 );
10665 }
10666 let Some((_, _, predicate)) = predicates
10667 .iter()
10668 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
10669 else {
10670 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
10671 index,
10672 rule_index,
10673 pred_index,
10674 context,
10675 local_int_arg,
10676 member_values,
10677 }) {
10678 return result;
10679 }
10680 return self.unknown_predicate_result(rule_index, pred_index);
10681 };
10682 self.input.seek(index);
10683 match predicate {
10684 ParserPredicate::True => true,
10685 ParserPredicate::False => false,
10686 ParserPredicate::FalseWithMessage { .. } => false,
10687 ParserPredicate::Invoke { value } => {
10688 let key = (rule_index, pred_index);
10689 if !self.invoked_predicates.contains(&key) {
10690 self.invoked_predicates.push(key);
10691 use std::io::Write as _;
10692 let mut stdout = std::io::stdout().lock();
10693 let _ = writeln!(stdout, "eval={value}");
10694 }
10695 *value
10696 }
10697 ParserPredicate::LookaheadTextEquals { offset, text } => self
10698 .input
10699 .lt(*offset)
10700 .is_some_and(|token| Token::text(&token) == Some(*text)),
10701 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
10702 self.la(*offset) != *token_type
10703 }
10704 ParserPredicate::TokenPairAdjacent => {
10705 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
10706 return false;
10707 };
10708 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
10709 return false;
10710 };
10711 first + 1 == second
10712 }
10713 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
10714 .and_then(|context| {
10715 context
10716 .child_rules(&self.tree, self.input.token_store(), *rule_index)
10717 .next()
10718 .map(crate::tree::RuleNodeView::text)
10719 })
10720 .is_none_or(|actual| actual != *text),
10721 ParserPredicate::LocalIntEquals { value } => {
10722 local_int_arg.is_none_or(|(_, actual)| actual == *value)
10723 }
10724 ParserPredicate::LocalIntLessOrEqual { value } => {
10725 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
10726 }
10727 ParserPredicate::MemberModuloEquals {
10728 member,
10729 modulus,
10730 value,
10731 equals,
10732 } => {
10733 if *modulus == 0 {
10734 return false;
10735 }
10736 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
10737 (actual == *value) == *equals
10738 }
10739 ParserPredicate::MemberEquals {
10740 member,
10741 value,
10742 equals,
10743 } => {
10744 let actual = member_values.get(member).copied().unwrap_or_default();
10745 (actual == *value) == *equals
10746 }
10747 }
10748 }
10749
10750 fn parser_predicate_failure_message(
10752 &self,
10753 rule_index: usize,
10754 pred_index: usize,
10755 predicates: &[(usize, usize, ParserPredicate)],
10756 ) -> Option<&'static str> {
10757 predicates
10758 .iter()
10759 .find_map(|(rule, pred, predicate)| match predicate {
10760 ParserPredicate::FalseWithMessage { message }
10761 if *rule == rule_index && *pred == pred_index =>
10762 {
10763 Some(*message)
10764 }
10765 _ => None,
10766 })
10767 }
10768
10769 pub fn parser_semantic_ir_predicate_failure_message(
10772 &self,
10773 rule_index: usize,
10774 pred_index: usize,
10775 semantics: &ParserSemantics,
10776 ) -> Option<&'static str> {
10777 semantics
10778 .predicates
10779 .iter()
10780 .find(|predicate| {
10781 predicate.rule_index == rule_index && predicate.pred_index == pred_index
10782 })
10783 .and_then(|predicate| predicate.failure_message)
10784 }
10785
10786 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
10795 if symbol == TOKEN_EOF {
10796 return index;
10797 }
10798 self.input.next_visible_after(index)
10799 }
10800
10801 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
10804 let text = display_input_text(&self.input.text(start_index, error_index));
10805 diagnostic_for_token(
10806 self.token_at(error_index).as_ref(),
10807 format!("no viable alternative at input '{text}'"),
10808 )
10809 }
10810
10811 fn recovery_failure_diagnostic(
10814 &self,
10815 index: usize,
10816 decision_start_index: Option<usize>,
10817 expected_symbols: &BTreeSet<i32>,
10818 ) -> ParserDiagnostic {
10819 if expected_symbols.len() > 1 {
10820 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
10821 return self.no_viable_alternative(decision_start, index);
10822 }
10823 }
10824 diagnostic_for_token(
10825 self.token_at(index).as_ref(),
10826 format!(
10827 "mismatched input {} expecting {}",
10828 self.token_at(index)
10829 .as_ref()
10830 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
10831 self.expected_symbols_display(expected_symbols)
10832 ),
10833 )
10834 }
10835
10836 fn eof_rule_recovery_diagnostic(
10839 &self,
10840 index: usize,
10841 expected_symbols: &BTreeSet<i32>,
10842 expected: &ExpectedTokens,
10843 ) -> ParserDiagnostic {
10844 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
10845 &expected.symbols
10846 } else {
10847 expected_symbols
10848 };
10849 diagnostic_for_token(
10850 self.token_at(index).as_ref(),
10851 format!(
10852 "mismatched input {} expecting {}",
10853 self.token_at(index)
10854 .as_ref()
10855 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
10856 self.expected_symbols_display(symbols)
10857 ),
10858 )
10859 }
10860
10861 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
10867 let Some(stop) = stop else {
10868 return String::new();
10869 };
10870 let stop = if self
10871 .token_at(stop)
10872 .is_some_and(|token| token.token_type() == TOKEN_EOF)
10873 {
10874 let Some(previous) = self.previous_token_index(stop) else {
10875 return String::new();
10876 };
10877 previous
10878 } else {
10879 stop
10880 };
10881 self.input.text(start, stop)
10882 }
10883
10884 fn clear_prediction_diagnostics(&mut self) {
10887 self.prediction_diagnostics.clear();
10888 self.reported_prediction_diagnostics.clear();
10889 }
10890
10891 fn reset_per_parse_caches(&mut self) {
10915 self.rule_first_set_cache.clear();
10916 self.decision_lookahead_cache.clear();
10917 self.ll1_decision_cache.clear();
10918 self.fast_predicate_cache.clear();
10919 self.rule_stop_reach_cache.clear();
10920 self.clean_memo_mode = CleanMemoMode::Probe;
10921 self.clean_memo_probe_seen.clear();
10922 self.clean_memo_probe_samples = 0;
10923 self.clean_memo_probe_repeats = 0;
10924 self.clean_memo_sparse_samples = 0;
10925 self.recovery_symbols_intern.clear();
10926 self.state_expected_cache.clear();
10927 self.state_expected_token_cache.clear();
10928 }
10929
10930 fn record_prediction_diagnostics(
10933 &mut self,
10934 atn: &Atn,
10935 state: AtnState<'_>,
10936 start_index: usize,
10937 outcomes: &[RecognizeOutcome],
10938 ) {
10939 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
10940 return;
10941 }
10942 let Some(decision) = atn
10943 .decision_to_state()
10944 .iter()
10945 .position(|state_number| state_number == state.state_number())
10946 else {
10947 return;
10948 };
10949 let Some(rule_index) = state.rule_index() else {
10950 return;
10951 };
10952 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
10953 for outcome in outcomes
10954 .iter()
10955 .filter(|outcome| outcome.diagnostics.is_empty())
10956 {
10957 let Some(alt) = outcome.decisions.first() else {
10958 continue;
10959 };
10960 alts_by_end
10961 .entry(outcome.index)
10962 .or_default()
10963 .insert(alt + 1);
10964 }
10965 let Some((&end_index, ambig_alts)) = alts_by_end
10966 .iter()
10967 .filter(|(_, alts)| alts.len() > 1)
10968 .max_by_key(|(end, _)| *end)
10969 else {
10970 return;
10971 };
10972 let rule_name = self
10973 .rule_names()
10974 .get(rule_index)
10975 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
10976 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
10977 let input = display_input_text(&self.input.text(start_index, stop_index));
10978 let alts = ambig_alts
10979 .iter()
10980 .map(usize::to_string)
10981 .collect::<Vec<_>>()
10982 .join(", ");
10983 let key = (decision, start_index, format!("{alts}:{input}"));
10984 if !self.reported_prediction_diagnostics.insert(key) {
10985 return;
10986 }
10987 let start_diagnostic = diagnostic_for_token(
10988 self.token_at(start_index),
10989 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
10990 );
10991 let stop_diagnostic = diagnostic_for_token(
10992 self.token_at(stop_index),
10993 format!(
10994 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
10995 ),
10996 );
10997 self.prediction_diagnostics.push(start_diagnostic);
10998 self.prediction_diagnostics.push(stop_diagnostic);
10999 }
11000
11001 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
11003 expected_symbols_display(
11004 &state_expected_symbols(atn, state_number),
11005 self.vocabulary(),
11006 )
11007 }
11008
11009 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
11014 let state = usize::try_from(self.data().state()).unwrap_or(0);
11015 ExpectedTokenSet {
11016 symbols: state_expected_symbols(atn, state),
11017 }
11018 }
11019
11020 pub const fn set_bail_on_error(&mut self, bail: bool) {
11023 self.bail_on_error = bail;
11024 }
11025
11026 #[must_use]
11028 pub const fn bail_on_error(&self) -> bool {
11029 self.bail_on_error
11030 }
11031
11032 pub fn rule_invocation_stack(&self) -> Vec<String> {
11035 self.rule_context_stack
11036 .iter()
11037 .rev()
11038 .map(|frame| {
11039 self.data()
11040 .rule_names()
11041 .get(frame.rule_index)
11042 .cloned()
11043 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
11044 })
11045 .collect()
11046 }
11047
11048 pub fn active_invocation_states(&self) -> Vec<isize> {
11052 self.rule_context_stack
11053 .iter()
11054 .skip(1)
11055 .rev()
11056 .map(|frame| frame.invoking_state)
11057 .collect()
11058 }
11059
11060 pub fn token_display_at(&self, index: usize) -> Option<String> {
11062 self.token_at(index).map(|token| format!("{token}"))
11063 }
11064}
11065
11066impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
11067where
11068 S: TokenSource,
11069 H: SemanticHooks,
11070{
11071 fn parse_rule(
11072 &mut self,
11073 rule_index: usize,
11074 invoking_state: isize,
11075 precedence: i32,
11076 ) -> DirectAdaptiveParseResult<ParseTree> {
11077 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
11078 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
11079 )?;
11080 let stop_state = self
11081 .atn
11082 .rule_to_stop_state()
11083 .get(rule_index)
11084 .filter(|state| *state != usize::MAX)
11085 .ok_or(DirectAdaptiveParseControl::Fallback(
11086 DirectAdaptiveFallback::MissingAtn,
11087 ))?;
11088 let start_index = self.parser.current_visible_index();
11089 let mut context = ParserRuleContext::new(rule_index, invoking_state);
11090 if let Some(token) = self.parser.token_id_at(start_index) {
11091 self.parser.set_context_start(&mut context, token);
11092 }
11093 let mut state_number = start_state;
11094 let mut consumed_eof = false;
11095 while state_number != stop_state {
11096 self.step()?;
11097 let (transition, boundary) = self.next_transition(state_number, precedence)?;
11098 if boundary.is_some() {
11099 return Err(DirectAdaptiveParseControl::Fallback(
11100 DirectAdaptiveFallback::LeftRecursiveBoundary,
11101 ));
11102 }
11103 match transition.data() {
11104 Transition::Epsilon { target } => {
11105 state_number = target;
11106 }
11107 Transition::Precedence {
11108 target,
11109 precedence: transition_precedence,
11110 } => {
11111 if transition_precedence < precedence {
11112 return Err(DirectAdaptiveParseControl::Fallback(
11113 DirectAdaptiveFallback::Precedence,
11114 ));
11115 }
11116 state_number = target;
11117 }
11118 Transition::Rule {
11119 rule_index,
11120 follow_state,
11121 precedence: rule_precedence,
11122 ..
11123 } => {
11124 let child = self.parse_rule(
11125 rule_index,
11126 invoking_state_number(state_number),
11127 rule_precedence,
11128 )?;
11129 if self.parser.build_parse_trees {
11130 self.parser.tree.add_child(&mut context, child);
11131 }
11132 state_number = follow_state;
11133 }
11134 Transition::Atom { .. }
11135 | Transition::Range { .. }
11136 | Transition::Set { .. }
11137 | Transition::NotSet { .. }
11138 | Transition::Wildcard { .. } => {
11139 let (matched_eof, child) = self.consume_transition(transition)?;
11140 consumed_eof |= matched_eof;
11141 if let Some(child) = child {
11142 self.parser.tree.add_child(&mut context, child);
11143 }
11144 state_number = transition.target();
11145 }
11146 Transition::Predicate { .. } => {
11147 return Err(DirectAdaptiveParseControl::Fallback(
11148 DirectAdaptiveFallback::Predicate,
11149 ));
11150 }
11151 Transition::Action { .. } => {
11152 return Err(DirectAdaptiveParseControl::Fallback(
11153 DirectAdaptiveFallback::Action,
11154 ));
11155 }
11156 }
11157 }
11158
11159 let stop_index = self
11160 .parser
11161 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
11162 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
11163 self.parser.set_context_stop(&mut context, token);
11164 }
11165 Ok(self.parser.rule_node(context))
11166 }
11167
11168 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
11169 self.steps += 1;
11170 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
11171 return Err(DirectAdaptiveParseControl::Fallback(
11172 DirectAdaptiveFallback::StepLimit,
11173 ));
11174 }
11175 Ok(())
11176 }
11177
11178 fn next_transition(
11179 &mut self,
11180 state_number: usize,
11181 precedence: i32,
11182 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
11183 let state = self
11184 .atn
11185 .state(state_number)
11186 .ok_or(DirectAdaptiveParseControl::Fallback(
11187 DirectAdaptiveFallback::MissingAtn,
11188 ))?;
11189 if state.is_rule_stop() {
11190 return Err(DirectAdaptiveParseControl::Fallback(
11191 DirectAdaptiveFallback::RuleStop,
11192 ));
11193 }
11194 let transition_index =
11195 self.transition_index(state_number, state.transitions().len(), precedence)?;
11196 let transition = state.transitions().get(transition_index).ok_or(
11197 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
11198 )?;
11199 let boundary = match &transition.data() {
11200 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
11201 left_recursive_boundary(self.atn, state, *target)
11202 }
11203 _ => None,
11204 };
11205 Ok((transition, boundary))
11206 }
11207
11208 fn transition_index(
11209 &mut self,
11210 state_number: usize,
11211 transition_count: usize,
11212 precedence: i32,
11213 ) -> DirectAdaptiveParseResult<usize> {
11214 match transition_count {
11215 0 => Err(DirectAdaptiveParseControl::Fallback(
11216 DirectAdaptiveFallback::NoTransition,
11217 )),
11218 1 => Ok(0),
11219 _ => {
11220 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
11221 return Ok(alt);
11222 }
11223 let decision = self
11224 .decision_by_state
11225 .get(state_number)
11226 .and_then(|decision| *decision)
11227 .ok_or(DirectAdaptiveParseControl::Fallback(
11228 DirectAdaptiveFallback::UnknownDecision,
11229 ))?;
11230 let prediction = self
11231 .simulator
11232 .adaptive_predict_stream_info_with_precedence(
11233 decision,
11234 direct_precedence(precedence),
11235 &mut self.parser.input,
11236 )
11237 .map_err(|_| {
11238 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
11239 })?;
11240 if prediction.has_semantic_context {
11241 return Err(DirectAdaptiveParseControl::Fallback(
11242 DirectAdaptiveFallback::SemanticContext,
11243 ));
11244 }
11245 prediction
11246 .alt
11247 .checked_sub(1)
11248 .filter(|index| *index < transition_count)
11249 .ok_or(DirectAdaptiveParseControl::Fallback(
11250 DirectAdaptiveFallback::InvalidAlt,
11251 ))
11252 }
11253 }
11254 }
11255
11256 fn ll1_transition_index(
11257 &mut self,
11258 state_number: usize,
11259 transition_count: usize,
11260 ) -> DirectAdaptiveParseResult<Option<usize>> {
11261 let state = self
11262 .atn
11263 .state(state_number)
11264 .ok_or(DirectAdaptiveParseControl::Fallback(
11265 DirectAdaptiveFallback::MissingAtn,
11266 ))?;
11267 if state.precedence_rule_decision() {
11268 return Ok(None);
11269 }
11270 let Some(rule_stop) = state
11271 .rule_index()
11272 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
11273 else {
11274 return Ok(None);
11275 };
11276 let symbol = self.parser.input.la_token(1);
11277 let entry = self
11278 .parser
11279 .cached_decision_lookahead(self.atn, state, rule_stop);
11280 Ok(
11281 ll1_greedy_alt(&entry, symbol, state.non_greedy())
11282 .filter(|alt| *alt < transition_count),
11283 )
11284 }
11285
11286 fn consume_transition(
11287 &mut self,
11288 transition: ParserTransition<'_>,
11289 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
11290 let symbol = self.parser.input.la_token(1);
11291 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
11292 return Err(DirectAdaptiveParseControl::Fallback(
11293 DirectAdaptiveFallback::TokenMismatch,
11294 ));
11295 }
11296 let token = self
11297 .parser
11298 .input
11299 .lt_id(1)
11300 .ok_or(DirectAdaptiveParseControl::Fallback(
11301 DirectAdaptiveFallback::TokenMismatch,
11302 ))?;
11303 let matched_eof = symbol == TOKEN_EOF;
11304 if !matched_eof {
11305 self.parser.consume();
11306 }
11307 let child = self
11308 .parser
11309 .build_parse_trees
11310 .then(|| self.parser.terminal_tree(token));
11311 Ok((matched_eof, child))
11312 }
11313}
11314
11315fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
11318 if !state.precedence_rule_decision() {
11319 return None;
11320 }
11321 let target_state = atn.state(target)?;
11322 if target_state.kind() == AtnStateKind::LoopEnd {
11323 return None;
11324 }
11325 state.rule_index()
11326}
11327
11328fn next_alt_number(
11335 state: AtnState<'_>,
11336 transition_count: usize,
11337 transition_index: usize,
11338 current_alt_number: usize,
11339 track_alt_numbers: bool,
11340) -> usize {
11341 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
11342 return current_alt_number;
11343 }
11344 if matches!(
11345 state.kind(),
11346 AtnStateKind::Basic
11347 | AtnStateKind::BlockStart
11348 | AtnStateKind::PlusBlockStart
11349 | AtnStateKind::StarBlockStart
11350 | AtnStateKind::StarLoopEntry
11351 ) && !state.precedence_rule_decision()
11352 {
11353 return transition_index + 1;
11354 }
11355 current_alt_number
11356}
11357
11358fn invoking_state_number(state_number: usize) -> isize {
11361 isize::try_from(state_number).unwrap_or(isize::MAX)
11362}
11363
11364const fn packed_i32(value: u32) -> i32 {
11365 i32::from_le_bytes(value.to_le_bytes())
11366}
11367
11368fn direct_precedence(precedence: i32) -> usize {
11369 usize::try_from(precedence.max(0)).unwrap_or_default()
11370}
11371
11372fn token_input_display(token: &impl Token) -> String {
11373 format!("'{}'", token.text().unwrap_or("<EOF>"))
11374}
11375
11376fn display_input_text(text: &str) -> String {
11377 let mut out = String::new();
11378 for ch in text.chars() {
11379 match ch {
11380 '\n' => out.push_str("\\n"),
11381 '\r' => out.push_str("\\r"),
11382 '\t' => out.push_str("\\t"),
11383 other => out.push(other),
11384 }
11385 }
11386 out
11387}
11388
11389fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
11390 let (line, column) = token.map_or((0, 0), |token| (token.line(), token.column()));
11391 ParserDiagnostic {
11392 line,
11393 column,
11394 message,
11395 }
11396}
11397
11398fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
11399 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
11400}
11401
11402fn expected_symbols_display_iter(
11403 symbols: impl IntoIterator<Item = i32>,
11404 vocabulary: &Vocabulary,
11405) -> String {
11406 let items = symbols
11407 .into_iter()
11408 .map(|symbol| expected_symbol_display(symbol, vocabulary))
11409 .collect::<Vec<_>>();
11410 if let [single] = items.as_slice() {
11411 return single.clone();
11412 }
11413 format!("{{{}}}", items.join(", "))
11414}
11415
11416fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
11417 if symbol == TOKEN_EOF {
11418 return "<EOF>".to_owned();
11419 }
11420 vocabulary.display_name(symbol)
11421}
11422
11423fn caller_follow_token_info_for_stream<S: TokenSource>(
11424 input: &mut CommonTokenStream<S>,
11425 index: usize,
11426) -> (i32, bool, bool) {
11427 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
11430 input.fill();
11431 }
11432 let token_type = input.token_type_at_index(index);
11433 let visible_channel = input.channel();
11434 let token = input.get(index);
11435 let is_boundary = token
11436 .as_ref()
11437 .and_then(Token::text)
11438 .is_some_and(is_caller_follow_boundary_text);
11439 let is_boundary_gap = token.as_ref().is_some_and(|token| {
11440 token.channel() != visible_channel || is_caller_follow_boundary_gap_text(token.text())
11441 });
11442 (token_type, is_boundary, is_boundary_gap)
11443}
11444
11445fn is_caller_follow_boundary_text(text: &str) -> bool {
11446 text.chars().any(|ch| ch == ';' || ch == '\n')
11447 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11448}
11449
11450fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
11451 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11452}
11453
11454fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
11458 let Some(rule_index) = state.rule_index() else {
11459 return false;
11460 };
11461 atn.rule_to_start_state()
11462 .get(rule_index)
11463 .and_then(|state_number| atn.state(state_number))
11464 .is_some_and(AtnState::left_recursive_rule)
11465}
11466
11467fn select_better_top_outcome(
11474 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
11475 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
11476 arena: &RecognitionArena,
11477) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
11478 match (first, second) {
11479 (Ok(first), Ok(second)) => {
11480 if arena.diagnostics(first.0.diagnostics).next().is_none() {
11481 Ok(first)
11482 } else {
11483 Ok(second)
11484 }
11485 }
11486 (Ok(first), Err(_)) => Ok(first),
11487 (Err(_), Ok(second)) => Ok(second),
11488 (Err(_), Err(second_expected)) => Err(second_expected),
11489 }
11490}
11491
11492fn select_best_fast_outcome(
11498 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
11499 prediction_mode: PredictionMode,
11500 caller_follow: Option<&TokenBitSet>,
11501 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
11502 arena: &RecognitionArena,
11503) -> Option<FastRecognizeOutcome> {
11504 let mut best = None;
11505 let mut best_caller_follow = None;
11506 for outcome in outcomes {
11507 if matches!(
11508 prediction_mode,
11509 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
11510 ) && outcome.diagnostics.is_empty()
11511 && let Some(follow) = caller_follow
11512 {
11513 let (token_type, is_boundary, _) = token_info_at(outcome.index);
11514 if is_boundary && follow.contains(token_type) {
11515 let replace =
11516 best_caller_follow
11517 .as_ref()
11518 .is_none_or(|existing: &FastRecognizeOutcome| {
11519 (outcome.index, outcome.consumed_eof)
11520 < (existing.index, existing.consumed_eof)
11521 });
11522 if replace {
11523 best_caller_follow = Some(outcome);
11524 }
11525 }
11526 }
11527 let Some(existing) = best else {
11528 best = Some(outcome);
11529 continue;
11530 };
11531 let outcome_position = (outcome.index, outcome.consumed_eof);
11532 let best_position = (existing.index, existing.consumed_eof);
11533 let better = match prediction_mode {
11534 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
11535 outcome_position,
11536 outcome.diagnostics,
11537 best_position,
11538 existing.diagnostics,
11539 arena,
11540 ),
11541 PredictionMode::Sll => outcome.index > existing.index,
11542 };
11543 best = Some(if better { outcome } else { existing });
11544 }
11545 let should_use_caller_follow =
11546 best_caller_follow
11547 .as_ref()
11548 .zip(best.as_ref())
11549 .is_some_and(|(candidate, selected)| {
11550 if !selected.diagnostics.is_empty() {
11551 return true;
11552 }
11553 candidate.index < selected.index
11554 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
11555 });
11556 if should_use_caller_follow {
11557 best_caller_follow
11558 } else {
11559 best
11560 }
11561}
11562
11563fn select_best_outcome(
11564 outcomes: impl Iterator<Item = RecognizeOutcome>,
11565 prediction_mode: PredictionMode,
11566 arena: &RecognitionArena,
11567) -> Option<RecognizeOutcome> {
11568 let outcomes = outcomes.collect::<Vec<_>>();
11569 let prefer_first_tie = outcomes
11570 .iter()
11571 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
11572 outcomes.into_iter().reduce(|best, outcome| {
11573 let outcome_position = (outcome.index, outcome.consumed_eof);
11574 let best_position = (best.index, best.consumed_eof);
11575 let better = match prediction_mode {
11576 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
11577 outcome_is_better(
11578 outcome_position,
11579 outcome.diagnostics,
11580 best_position,
11581 best.diagnostics,
11582 arena,
11583 ) || (!prefer_first_tie
11584 && outcome_position == best_position
11585 && arena.diagnostics_len(outcome.diagnostics)
11586 == arena.diagnostics_len(best.diagnostics)
11587 && arena.diagnostics_recovery_rank(outcome.diagnostics)
11588 == arena.diagnostics_recovery_rank(best.diagnostics)
11589 && (outcome.decisions < best.decisions
11590 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
11591 }
11592 PredictionMode::Sll => {
11593 outcome_position > best_position
11594 || (outcome_position == best_position
11595 && !prefer_first_tie
11596 && (outcome.decisions < best.decisions
11597 || (outcome.decisions == best.decisions
11598 && outcome_is_better(
11599 outcome_position,
11600 outcome.diagnostics,
11601 best_position,
11602 best.diagnostics,
11603 arena,
11604 ))))
11605 }
11606 };
11607 if better {
11608 return outcome;
11609 }
11610 best
11611 })
11612}
11613
11614fn transition_decision(
11621 atn: &Atn,
11622 state: AtnState<'_>,
11623 transition_count: usize,
11624 transition_index: usize,
11625 predicates: &[(usize, usize, ParserPredicate)],
11626) -> Option<usize> {
11627 if transition_count <= 1
11628 || state.precedence_rule_decision()
11629 || decision_reaches_unsupported_predicate(atn, state, predicates)
11630 {
11631 return None;
11632 }
11633 Some(transition_index)
11634}
11635
11636fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
11642 transition_count > 1
11643 && !matches!(
11644 state.kind(),
11645 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
11646 )
11647}
11648
11649fn record_no_viable_if_ambiguous(
11652 expected: &mut ExpectedTokens,
11653 decision_start_index: Option<usize>,
11654 index: usize,
11655) {
11656 if expected.index == Some(index) && expected.symbols.len() > 1 {
11657 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
11658 expected.record_no_viable(decision_start, index);
11659 }
11660 }
11661}
11662
11663const fn record_predicate_no_viable(
11666 expected: &mut ExpectedTokens,
11667 decision_start_index: Option<usize>,
11668 index: usize,
11669) {
11670 if let Some(decision_start) = decision_start_index {
11671 expected.record_no_viable(decision_start, index);
11672 }
11673}
11674
11675const fn no_viable_decision_start(
11677 decision_start_index: Option<usize>,
11678 index: usize,
11679) -> Option<usize> {
11680 match decision_start_index {
11681 Some(start) if index > start => Some(start),
11682 _ => None,
11683 }
11684}
11685
11686fn restore_expected(
11690 children: &[RecognizeOutcome],
11691 child_start_index: usize,
11692 expected: &mut ExpectedTokens,
11693 snapshot: ExpectedTokens,
11694 preserve_child_expected: bool,
11695) {
11696 if preserve_child_expected {
11697 return;
11698 }
11699 if children
11700 .iter()
11701 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
11702 {
11703 *expected = snapshot;
11704 }
11705}
11706
11707fn decision_reaches_unsupported_predicate(
11710 atn: &Atn,
11711 state: AtnState<'_>,
11712 predicates: &[(usize, usize, ParserPredicate)],
11713) -> bool {
11714 state.transitions().iter().any(|transition| {
11715 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
11716 })
11717}
11718
11719fn transition_reaches_unsupported_predicate(
11721 atn: &Atn,
11722 transition: ParserTransition<'_>,
11723 predicates: &[(usize, usize, ParserPredicate)],
11724 visited: &mut BTreeSet<usize>,
11725) -> bool {
11726 match &transition.data() {
11727 Transition::Predicate {
11728 rule_index,
11729 pred_index,
11730 ..
11731 } => !predicates
11732 .iter()
11733 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
11734 Transition::Epsilon { target }
11735 | Transition::Action { target, .. }
11736 | Transition::Rule { target, .. } => {
11737 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
11738 }
11739 Transition::Precedence { .. }
11740 | Transition::Atom { .. }
11741 | Transition::Range { .. }
11742 | Transition::Set { .. }
11743 | Transition::NotSet { .. }
11744 | Transition::Wildcard { .. } => false,
11745 }
11746}
11747
11748fn state_reaches_unsupported_predicate(
11750 atn: &Atn,
11751 state_number: usize,
11752 predicates: &[(usize, usize, ParserPredicate)],
11753 visited: &mut BTreeSet<usize>,
11754) -> bool {
11755 if !visited.insert(state_number) {
11756 return false;
11757 }
11758 let Some(state) = atn.state(state_number) else {
11759 return false;
11760 };
11761 state.transitions().iter().any(|transition| {
11762 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
11763 })
11764}
11765
11766fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
11768 if let Some(decision) = decision {
11769 outcome.decisions.insert(0, decision);
11770 }
11771}
11772
11773fn outcome_is_better(
11774 outcome_position: (usize, bool),
11775 outcome_diagnostics: DiagnosticSeqId,
11776 best_position: (usize, bool),
11777 best_diagnostics: DiagnosticSeqId,
11778 arena: &RecognitionArena,
11779) -> bool {
11780 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
11781 let best_len = arena.diagnostics_len(best_diagnostics);
11782 outcome_position > best_position
11783 || (outcome_position == best_position
11784 && (outcome_len < best_len
11785 || (outcome_len == best_len
11786 && arena.diagnostics_recovery_rank(outcome_diagnostics)
11787 < arena.diagnostics_recovery_rank(best_diagnostics))))
11788}
11789
11790fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
11791 if outcomes
11792 .iter()
11793 .any(|outcome| outcome.diagnostics.is_empty())
11794 {
11795 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
11796 }
11797}
11798
11799fn discard_recovered_outcomes_if_clean_path_exists(
11800 outcomes: &mut Vec<RecognizeOutcome>,
11801 arena: &RecognitionArena,
11802) {
11803 if outcomes
11804 .iter()
11805 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
11806 {
11807 return;
11808 }
11809 if outcomes
11810 .iter()
11811 .any(|outcome| outcome.diagnostics.is_empty())
11812 {
11813 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
11814 }
11815}
11816
11817fn outcome_has_rule_failure_diagnostic(
11820 outcome: &RecognizeOutcome,
11821 arena: &RecognitionArena,
11822) -> bool {
11823 arena
11824 .diagnostics(outcome.diagnostics)
11825 .any(|diagnostic| diagnostic.message.starts_with("rule "))
11826}
11827
11828fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
11842 if outcomes.len() < 2 {
11843 return;
11844 }
11845 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
11846 outcomes.retain(|outcome| {
11847 seen.insert((
11848 outcome.index,
11849 outcome.consumed_eof,
11850 arena.diagnostics_len(outcome.diagnostics),
11851 arena.diagnostics_recovery_rank(outcome.diagnostics),
11852 ))
11853 });
11854}
11855
11856const FAST_OUTCOME_INLINE_KEYS: usize = 8;
11857const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
11858const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
11859const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
11860
11861#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11862enum FastOutcomeDedupStrategy {
11863 Inline,
11864 Dense,
11865 Sparse,
11866}
11867
11868impl FastOutcomeDedupScratch {
11869 fn prepare_dense(&mut self, word_count: usize) {
11870 while let Some(word_index) = self.touched_dense_words.pop() {
11871 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
11872 }
11873 if self.dense_words.len() < word_count {
11874 self.dense_words.resize(word_count, 0);
11875 }
11876 }
11877}
11878
11879fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
11880 let first_index = outcomes.first()?.index;
11881 let (min_index, max_index) = outcomes[1..].iter().fold(
11882 (first_index, first_index),
11883 |(min_index, max_index), outcome| {
11884 (min_index.min(outcome.index), max_index.max(outcome.index))
11885 },
11886 );
11887 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
11888 let bit_count = index_span.checked_mul(2)?;
11889 let word_count =
11890 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
11891 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
11892 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
11893 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
11894 .then_some((min_index, word_count))
11895}
11896
11897#[cfg(feature = "perf-counters")]
11898fn record_clean_fast_outcome_dedup(
11899 strategy: FastOutcomeDedupStrategy,
11900 input_len: usize,
11901 output_len: usize,
11902 dense_words: usize,
11903) {
11904 let counter = match strategy {
11905 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
11906 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
11907 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
11908 };
11909 perf_counters::inc(
11910 &perf_counters::OUTCOME_DEDUPE_INPUTS,
11911 u64::try_from(input_len).unwrap_or(u64::MAX),
11912 );
11913 perf_counters::inc(
11914 &perf_counters::OUTCOME_DEDUPE_REMOVED,
11915 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
11916 );
11917 perf_counters::inc(counter, 1);
11918 perf_counters::inc(
11919 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
11920 u64::try_from(dense_words).unwrap_or(u64::MAX),
11921 );
11922}
11923
11924fn dedupe_clean_fast_outcomes(
11928 outcomes: &mut Vec<FastRecognizeOutcome>,
11929 scratch: &mut FastOutcomeDedupScratch,
11930) -> FastOutcomeDedupStrategy {
11931 #[cfg(feature = "perf-counters")]
11932 let input_len = outcomes.len();
11933 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
11934 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
11935 let mut inline_len = 0_usize;
11936 outcomes.retain(|outcome| {
11937 let key = (outcome.index, outcome.consumed_eof);
11938 if inline_keys[..inline_len].contains(&key) {
11939 return false;
11940 }
11941 inline_keys[inline_len] = key;
11942 inline_len += 1;
11943 true
11944 });
11945 #[cfg(feature = "perf-counters")]
11946 record_clean_fast_outcome_dedup(
11947 FastOutcomeDedupStrategy::Inline,
11948 input_len,
11949 outcomes.len(),
11950 0,
11951 );
11952 return FastOutcomeDedupStrategy::Inline;
11953 }
11954
11955 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
11956 scratch.prepare_dense(word_count);
11957 outcomes.retain(|outcome| {
11958 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
11959 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
11960 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
11961 let word = &mut scratch.dense_words[word_index];
11962 if *word & bit != 0 {
11963 return false;
11964 }
11965 if *word == 0 {
11966 scratch
11967 .touched_dense_words
11968 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
11969 }
11970 *word |= bit;
11971 true
11972 });
11973 #[cfg(feature = "perf-counters")]
11974 record_clean_fast_outcome_dedup(
11975 FastOutcomeDedupStrategy::Dense,
11976 input_len,
11977 outcomes.len(),
11978 word_count,
11979 );
11980 return FastOutcomeDedupStrategy::Dense;
11981 }
11982
11983 scratch.sparse_keys.clear();
11984 scratch.sparse_keys.reserve(outcomes.len());
11985 outcomes.retain(|outcome| {
11986 scratch
11987 .sparse_keys
11988 .insert((outcome.index, outcome.consumed_eof))
11989 });
11990 #[cfg(feature = "perf-counters")]
11991 record_clean_fast_outcome_dedup(
11992 FastOutcomeDedupStrategy::Sparse,
11993 input_len,
11994 outcomes.len(),
11995 0,
11996 );
11997 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
11998 scratch.sparse_keys = FxHashSet::default();
11999 }
12000 FastOutcomeDedupStrategy::Sparse
12001}
12002
12003fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
12006 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
12007 outcomes
12008 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
12009}
12010
12011fn compare_recognize_outcomes(
12012 left: &RecognizeOutcome,
12013 right: &RecognizeOutcome,
12014 arena: &RecognitionArena,
12015) -> Ordering {
12016 left.index
12017 .cmp(&right.index)
12018 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
12019 .then_with(|| left.alt_number.cmp(&right.alt_number))
12020 .then_with(|| left.member_values.cmp(&right.member_values))
12021 .then_with(|| left.return_values.cmp(&right.return_values))
12022 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
12023 .then_with(|| left.decisions.cmp(&right.decisions))
12024 .then_with(|| left.actions.cmp(&right.actions))
12025 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
12026}
12027
12028impl<S, H> Recognizer for BaseParser<S, H>
12029where
12030 S: TokenSource,
12031 H: SemanticHooks,
12032{
12033 fn data(&self) -> &RecognizerData {
12034 &self.data
12035 }
12036
12037 fn data_mut(&mut self) -> &mut RecognizerData {
12038 &mut self.data
12039 }
12040}
12041
12042impl<S, H> Parser for BaseParser<S, H>
12043where
12044 S: TokenSource,
12045 H: SemanticHooks,
12046{
12047 fn build_parse_trees(&self) -> bool {
12048 self.build_parse_trees
12049 }
12050
12051 fn set_build_parse_trees(&mut self, build: bool) {
12052 self.build_parse_trees = build;
12053 }
12054
12055 fn number_of_syntax_errors(&self) -> usize {
12056 Self::number_of_syntax_errors(self)
12057 }
12058
12059 fn report_diagnostic_errors(&self) -> bool {
12060 self.report_diagnostic_errors
12061 }
12062
12063 fn set_report_diagnostic_errors(&mut self, report: bool) {
12064 self.report_diagnostic_errors = report;
12065 }
12066
12067 fn prediction_mode(&self) -> PredictionMode {
12068 self.prediction_mode
12069 }
12070
12071 fn set_prediction_mode(&mut self, mode: PredictionMode) {
12072 self.prediction_mode = mode;
12073 }
12074}
12075
12076#[cfg(test)]
12077mod tests {
12078 use super::*;
12079 use crate::atn::parser::{
12080 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
12081 };
12082 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
12083 use crate::token::{HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError};
12084 use crate::token_stream::CommonTokenStream;
12085 use crate::tree::{NodeKind, ParseTreeStats};
12086 use crate::vocabulary::Vocabulary;
12087 use std::cell::RefCell;
12088 use std::mem::size_of;
12089 use std::rc::Rc;
12090 use std::sync::{Arc, Mutex};
12091
12092 #[test]
12093 fn fx_hasher_write_matches_typed_methods_for_full_words() {
12094 let value: u64 = 0x0102_0304_0506_0708;
12101 let mut typed = FxHasher::default();
12102 typed.write_u64(value);
12103 let mut bytewise = FxHasher::default();
12104 bytewise.write(&value.to_le_bytes());
12105 assert_eq!(typed.finish(), bytewise.finish());
12106 }
12107
12108 #[derive(Clone, Debug)]
12109 struct TestToken {
12110 spec: TokenSpec,
12111 id: TokenId,
12112 source_name: String,
12113 }
12114
12115 impl TestToken {
12116 fn new(token_type: i32) -> Self {
12117 Self {
12118 spec: TokenSpec::explicit(token_type, ""),
12119 id: TokenId::try_from(0).expect("zero token ID"),
12120 source_name: String::new(),
12121 }
12122 }
12123
12124 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
12125 Self {
12126 spec: TokenSpec::eof(index, index, line, column),
12127 id: TokenId::try_from(0).expect("zero token ID"),
12128 source_name: source_name.to_owned(),
12129 }
12130 }
12131
12132 fn with_text(mut self, text: impl Into<String>) -> Self {
12133 self.spec.text = Some(text.into());
12134 self
12135 }
12136
12137 const fn with_channel(mut self, channel: i32) -> Self {
12138 self.spec.channel = channel;
12139 self
12140 }
12141
12142 const fn with_span(mut self, start: usize, stop: usize) -> Self {
12143 self.spec.start = start;
12144 self.spec.stop = stop;
12145 self.spec.start_byte = start;
12146 self.spec.stop_byte = match stop.checked_add(1) {
12147 Some(end) if end >= start => end,
12148 Some(_) | None => start,
12149 };
12150 self
12151 }
12152
12153 const fn with_position(mut self, line: usize, column: usize) -> Self {
12154 self.spec.line = line;
12155 self.spec.column = column;
12156 self
12157 }
12158
12159 fn set_token_index(&mut self, index: isize) {
12160 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
12161 }
12162 }
12163
12164 impl Token for TestToken {
12165 fn token_id(&self) -> TokenId {
12166 self.id
12167 }
12168
12169 fn token_type(&self) -> i32 {
12170 self.spec.token_type
12171 }
12172
12173 fn channel(&self) -> i32 {
12174 self.spec.channel
12175 }
12176
12177 fn start(&self) -> usize {
12178 self.spec.start
12179 }
12180
12181 fn stop(&self) -> usize {
12182 self.spec.stop
12183 }
12184
12185 fn line(&self) -> usize {
12186 self.spec.line
12187 }
12188
12189 fn column(&self) -> usize {
12190 self.spec.column
12191 }
12192
12193 fn text(&self) -> Option<&str> {
12194 self.spec.text.as_deref()
12195 }
12196
12197 fn source_name(&self) -> &str {
12198 &self.source_name
12199 }
12200
12201 fn start_byte(&self) -> usize {
12202 self.spec.start_byte
12203 }
12204
12205 fn stop_byte(&self) -> usize {
12206 self.spec.stop_byte
12207 }
12208 }
12209
12210 #[derive(Debug)]
12211 struct Source {
12212 tokens: Vec<TestToken>,
12213 index: usize,
12214 }
12215
12216 impl TokenSource for Source {
12217 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
12218 let token = self
12219 .tokens
12220 .get(self.index)
12221 .cloned()
12222 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
12223 self.index += 1;
12224 sink.push(token.spec)
12225 }
12226
12227 fn line(&self) -> usize {
12228 1
12229 }
12230
12231 fn column(&self) -> usize {
12232 self.index
12233 }
12234
12235 fn source_name(&self) -> &'static str {
12236 "parser-test"
12237 }
12238 }
12239
12240 #[derive(Clone, Debug, Eq, PartialEq)]
12241 struct RecordedDiagnostic {
12242 grammar_file_name: String,
12243 line: usize,
12244 column: usize,
12245 message: String,
12246 error: Option<AntlrError>,
12247 }
12248
12249 #[derive(Clone, Debug)]
12250 struct RecordingErrorListener {
12251 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
12252 }
12253
12254 impl<R> crate::ErrorListener<R> for RecordingErrorListener
12255 where
12256 R: Recognizer + ?Sized,
12257 {
12258 fn syntax_error(
12259 &mut self,
12260 recognizer: &R,
12261 line: usize,
12262 column: usize,
12263 message: &str,
12264 error: Option<&AntlrError>,
12265 ) {
12266 self.diagnostics
12267 .lock()
12268 .expect("recorded diagnostics lock")
12269 .push(RecordedDiagnostic {
12270 grammar_file_name: recognizer.grammar_file_name().to_owned(),
12271 line,
12272 column,
12273 message: message.to_owned(),
12274 error: error.cloned(),
12275 });
12276 }
12277 }
12278
12279 #[derive(Debug)]
12280 struct ReportingSource {
12281 source: Source,
12282 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
12283 }
12284
12285 impl TokenSource for ReportingSource {
12286 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
12287 self.source.next_token(sink)
12288 }
12289
12290 fn line(&self) -> usize {
12291 self.source.line()
12292 }
12293
12294 fn column(&self) -> usize {
12295 self.source.column()
12296 }
12297
12298 fn source_name(&self) -> &str {
12299 self.source.source_name()
12300 }
12301
12302 fn report_error(&self, error: &TokenSourceError) -> bool {
12303 self.diagnostics.borrow_mut().push(error.clone());
12304 true
12305 }
12306 }
12307
12308 fn mini_parser_data() -> RecognizerData {
12309 RecognizerData::new(
12310 "Mini.g4",
12311 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
12312 )
12313 .with_rule_names(["s"])
12314 }
12315
12316 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
12317 let data = mini_parser_data();
12318 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
12319 }
12320
12321 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
12322 where
12323 H: SemanticHooks,
12324 {
12325 BaseParser::with_semantic_hooks(
12326 CommonTokenStream::new(Source { tokens, index: 0 }),
12327 mini_parser_data(),
12328 hooks,
12329 )
12330 }
12331
12332 #[test]
12333 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
12334 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
12335 parser.remove_error_listeners();
12336 let diagnostics = Arc::new(Mutex::new(Vec::new()));
12337 parser.add_error_listener(RecordingErrorListener {
12338 diagnostics: Arc::clone(&diagnostics),
12339 });
12340 let parser_diagnostics = [ParserDiagnostic {
12341 line: 1,
12342 column: 2,
12343 message: "missing 'x' at 'y'".to_owned(),
12344 }];
12345 let token_errors = [
12346 TokenSourceError::new(1, 1, "token recognition error at: '@'"),
12347 TokenSourceError::new(1, 3, "token recognition error at: '#'"),
12348 ];
12349
12350 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
12351
12352 assert_eq!(
12353 *diagnostics.lock().expect("recorded diagnostics lock"),
12354 [
12355 RecordedDiagnostic {
12356 grammar_file_name: "Mini.g4".to_owned(),
12357 line: 1,
12358 column: 1,
12359 message: "token recognition error at: '@'".to_owned(),
12360 error: None,
12361 },
12362 RecordedDiagnostic {
12363 grammar_file_name: "Mini.g4".to_owned(),
12364 line: 1,
12365 column: 2,
12366 message: "missing 'x' at 'y'".to_owned(),
12367 error: None,
12368 },
12369 RecordedDiagnostic {
12370 grammar_file_name: "Mini.g4".to_owned(),
12371 line: 1,
12372 column: 3,
12373 message: "token recognition error at: '#'".to_owned(),
12374 error: None,
12375 },
12376 ]
12377 );
12378
12379 parser.remove_error_listeners();
12380 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
12381 assert_eq!(
12382 diagnostics.lock().expect("recorded diagnostics lock").len(),
12383 3
12384 );
12385 }
12386
12387 #[test]
12388 fn parser_leaves_token_errors_to_source_owned_listeners() {
12389 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
12390 let source = ReportingSource {
12391 source: Source {
12392 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
12393 index: 0,
12394 },
12395 diagnostics: Rc::clone(&source_diagnostics),
12396 };
12397 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
12398 parser.remove_error_listeners();
12399 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
12400 parser.add_error_listener(RecordingErrorListener {
12401 diagnostics: Arc::clone(&parser_diagnostics),
12402 });
12403 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
12404
12405 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
12406
12407 assert_eq!(*source_diagnostics.borrow(), [source_error]);
12408 assert!(
12409 parser_diagnostics
12410 .lock()
12411 .expect("recorded diagnostics lock")
12412 .is_empty()
12413 );
12414 }
12415
12416 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
12417 builder.finish().expect("valid packed parser ATN")
12418 }
12419
12420 fn ordinary_star_loop_atn() -> Atn {
12421 let mut atn = ParserAtnBuilder::new(2);
12422 for (state_number, kind, rule_index) in [
12423 (0, AtnStateKind::RuleStart, 0),
12424 (1, AtnStateKind::StarLoopEntry, 0),
12425 (2, AtnStateKind::Basic, 0),
12426 (3, AtnStateKind::StarLoopBack, 0),
12427 (4, AtnStateKind::LoopEnd, 0),
12428 (5, AtnStateKind::Basic, 0),
12429 (6, AtnStateKind::RuleStop, 0),
12430 (7, AtnStateKind::RuleStart, 1),
12431 (8, AtnStateKind::Basic, 1),
12432 (9, AtnStateKind::RuleStop, 1),
12433 ] {
12434 assert_eq!(
12435 atn.add_state(kind, Some(rule_index))
12436 .expect("state")
12437 .index(),
12438 state_number
12439 );
12440 }
12441 atn.set_rule_to_start_state(vec![0, 7])
12442 .expect("rule start states");
12443 atn.set_rule_to_stop_state(vec![6, 9])
12444 .expect("rule stop states");
12445 atn.add_decision_state(1).expect("decision state");
12446 atn.set_loop_back_state(4, 3).expect("loop back state");
12447 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12448 .expect("transition");
12449 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12450 .expect("transition");
12451 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
12452 .expect("transition");
12453 atn.add_transition(
12454 2,
12455 ParserTransitionSpec::Rule {
12456 target: 7,
12457 rule_index: 1,
12458 follow_state: 3,
12459 precedence: 0,
12460 },
12461 )
12462 .expect("transition");
12463 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
12464 .expect("transition");
12465 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12466 .expect("transition");
12467 atn.add_transition(
12468 5,
12469 ParserTransitionSpec::Atom {
12470 target: 6,
12471 label: TOKEN_EOF,
12472 },
12473 )
12474 .expect("transition");
12475 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
12476 .expect("transition");
12477 atn.add_transition(
12478 8,
12479 ParserTransitionSpec::Atom {
12480 target: 9,
12481 label: 1,
12482 },
12483 )
12484 .expect("transition");
12485 finish_atn(atn)
12486 }
12487
12488 fn ambiguous_ordinary_star_loop_atn() -> Atn {
12490 let mut atn = ParserAtnBuilder::new(1);
12491 for (state_number, kind) in [
12492 (0, AtnStateKind::RuleStart),
12493 (1, AtnStateKind::StarLoopEntry),
12494 (2, AtnStateKind::StarBlockStart),
12495 (3, AtnStateKind::Basic),
12496 (4, AtnStateKind::BlockEnd),
12497 (5, AtnStateKind::StarLoopBack),
12498 (6, AtnStateKind::LoopEnd),
12499 (7, AtnStateKind::Basic),
12500 (8, AtnStateKind::RuleStop),
12501 ] {
12502 assert_eq!(
12503 atn.add_state(kind, Some(0)).expect("state").index(),
12504 state_number
12505 );
12506 }
12507 atn.set_rule_to_start_state(vec![0])
12508 .expect("rule start states");
12509 atn.set_rule_to_stop_state(vec![8])
12510 .expect("rule stop states");
12511 atn.set_end_state(2, 4).expect("block end state");
12512 atn.set_loop_back_state(6, 5).expect("loop back state");
12513 atn.add_decision_state(1).expect("decision state");
12514 atn.add_decision_state(2).expect("decision state");
12515 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12516 .expect("transition");
12517 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12518 .expect("transition");
12519 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
12520 .expect("transition");
12521 atn.add_transition(
12522 2,
12523 ParserTransitionSpec::Atom {
12524 target: 4,
12525 label: 1,
12526 },
12527 )
12528 .expect("transition");
12529 atn.add_transition(
12530 2,
12531 ParserTransitionSpec::Atom {
12532 target: 3,
12533 label: 1,
12534 },
12535 )
12536 .expect("transition");
12537 atn.add_transition(
12538 3,
12539 ParserTransitionSpec::Atom {
12540 target: 4,
12541 label: 1,
12542 },
12543 )
12544 .expect("transition");
12545 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12546 .expect("transition");
12547 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
12548 .expect("transition");
12549 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12550 .expect("transition");
12551 atn.add_transition(
12552 7,
12553 ParserTransitionSpec::Atom {
12554 target: 8,
12555 label: TOKEN_EOF,
12556 },
12557 )
12558 .expect("transition");
12559 finish_atn(atn)
12560 }
12561
12562 fn ordinary_plus_loop_atn() -> Atn {
12563 let mut atn = ParserAtnBuilder::new(2);
12564 for (state_number, kind, rule_index) in [
12565 (0, AtnStateKind::RuleStart, 0),
12566 (1, AtnStateKind::Basic, 0),
12567 (2, AtnStateKind::PlusLoopBack, 0),
12568 (3, AtnStateKind::LoopEnd, 0),
12569 (4, AtnStateKind::Basic, 0),
12570 (5, AtnStateKind::RuleStop, 0),
12571 (6, AtnStateKind::RuleStart, 1),
12572 (7, AtnStateKind::Basic, 1),
12573 (8, AtnStateKind::RuleStop, 1),
12574 ] {
12575 assert_eq!(
12576 atn.add_state(kind, Some(rule_index))
12577 .expect("state")
12578 .index(),
12579 state_number
12580 );
12581 }
12582 atn.set_rule_to_start_state(vec![0, 6])
12583 .expect("rule start states");
12584 atn.set_rule_to_stop_state(vec![5, 8])
12585 .expect("rule stop states");
12586 atn.add_decision_state(2).expect("decision state");
12587 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12588 .expect("transition");
12589 atn.add_transition(
12590 1,
12591 ParserTransitionSpec::Rule {
12592 target: 6,
12593 rule_index: 1,
12594 follow_state: 2,
12595 precedence: 0,
12596 },
12597 )
12598 .expect("transition");
12599 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
12600 .expect("transition");
12601 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12602 .expect("transition");
12603 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
12604 .expect("transition");
12605 atn.add_transition(
12606 4,
12607 ParserTransitionSpec::Atom {
12608 target: 5,
12609 label: TOKEN_EOF,
12610 },
12611 )
12612 .expect("transition");
12613 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12614 .expect("transition");
12615 atn.add_transition(
12616 7,
12617 ParserTransitionSpec::Atom {
12618 target: 8,
12619 label: 1,
12620 },
12621 )
12622 .expect("transition");
12623 finish_atn(atn)
12624 }
12625
12626 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
12627 let mut tokens = (0..count)
12628 .map(|_| TestToken::new(1).with_text("x"))
12629 .collect::<Vec<_>>();
12630 tokens.push(TestToken::eof("parser-test", count, 1, count));
12631 tokens
12632 }
12633
12634 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
12635 let mut atn = ParserAtnBuilder::new(2);
12636 assert_eq!(
12637 atn.add_state(AtnStateKind::RuleStart, Some(0))
12638 .expect("state")
12639 .index(),
12640 0
12641 );
12642 assert_eq!(
12643 atn.add_state(AtnStateKind::Basic, Some(0))
12644 .expect("state")
12645 .index(),
12646 1
12647 );
12648 assert_eq!(
12649 atn.add_state(AtnStateKind::Basic, Some(0))
12650 .expect("state")
12651 .index(),
12652 2
12653 );
12654 assert_eq!(
12655 atn.add_state(AtnStateKind::RuleStart, Some(1))
12656 .expect("state")
12657 .index(),
12658 3
12659 );
12660 atn.set_left_recursive_rule(3)
12661 .expect("left-recursive rule start");
12662 assert_eq!(
12663 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
12664 .expect("state")
12665 .index(),
12666 4
12667 );
12668 atn.set_precedence_rule_decision(4)
12669 .expect("precedence decision");
12670 assert_eq!(
12671 atn.add_state(AtnStateKind::Basic, Some(1))
12672 .expect("state")
12673 .index(),
12674 5
12675 );
12676 assert_eq!(
12677 atn.add_state(AtnStateKind::Basic, Some(1))
12678 .expect("state")
12679 .index(),
12680 6
12681 );
12682 assert_eq!(
12683 atn.add_state(AtnStateKind::LoopEnd, Some(1))
12684 .expect("state")
12685 .index(),
12686 7
12687 );
12688 assert_eq!(
12689 atn.add_state(AtnStateKind::RuleStop, Some(1))
12690 .expect("state")
12691 .index(),
12692 8
12693 );
12694 assert_eq!(
12695 atn.add_state(AtnStateKind::RuleStop, Some(0))
12696 .expect("state")
12697 .index(),
12698 9
12699 );
12700 atn.set_rule_to_start_state(vec![0, 3])
12701 .expect("rule start states");
12702 atn.set_rule_to_stop_state(vec![9, 8])
12703 .expect("rule stop states");
12704 atn.add_transition(
12705 1,
12706 ParserTransitionSpec::Rule {
12707 target: 3,
12708 rule_index: 1,
12709 follow_state: 2,
12710 precedence: 0,
12711 },
12712 )
12713 .expect("transition");
12714 atn.add_transition(
12715 2,
12716 ParserTransitionSpec::Atom {
12717 target: 9,
12718 label: caller_symbol,
12719 },
12720 )
12721 .expect("transition");
12722 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12723 .expect("transition");
12724 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
12725 .expect("transition");
12726 atn.add_transition(
12727 5,
12728 ParserTransitionSpec::Precedence {
12729 target: 6,
12730 precedence: 1,
12731 },
12732 )
12733 .expect("transition");
12734 atn.add_transition(
12735 6,
12736 ParserTransitionSpec::Atom {
12737 target: 4,
12738 label: 1,
12739 },
12740 )
12741 .expect("transition");
12742 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
12743 .expect("transition");
12744 finish_atn(atn)
12745 }
12746
12747 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
12748 let mut parser = mini_parser(vec![
12749 TestToken::new(symbol).with_text("lookahead"),
12750 TestToken::eof("parser-test", 1, 1, 1),
12751 ]);
12752 parser.rule_context_stack = vec![
12753 RuleContextFrame {
12754 rule_index: 0,
12755 invoking_state: -1,
12756 },
12757 RuleContextFrame {
12758 rule_index: 1,
12759 invoking_state: 1,
12760 },
12761 ];
12762 parser
12763 }
12764
12765 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
12766 let mut atn = ParserAtnBuilder::new(1);
12770 for (state, kind, rule) in [
12771 (0, AtnStateKind::RuleStart, 0),
12772 (1, AtnStateKind::StarLoopEntry, 0),
12773 (2, AtnStateKind::Basic, 0), (3, AtnStateKind::Basic, 0), (4, AtnStateKind::Basic, 0), (5, AtnStateKind::Basic, 0), (6, AtnStateKind::Basic, 0), (7, AtnStateKind::Basic, 0), (8, AtnStateKind::LoopEnd, 0),
12780 (9, AtnStateKind::RuleStop, 0),
12781 ] {
12782 assert_eq!(
12783 atn.add_state(kind, Some(rule)).expect("state").index(),
12784 state
12785 );
12786 if state == 0 {
12787 atn.set_left_recursive_rule(state)
12788 .expect("left-recursive rule start");
12789 } else if state == 1 {
12790 atn.set_precedence_rule_decision(state)
12791 .expect("precedence decision");
12792 }
12793 }
12794 atn.set_rule_to_start_state(vec![0])
12795 .expect("rule start states");
12796 atn.set_rule_to_stop_state(vec![9])
12797 .expect("rule stop states");
12798 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12799 .expect("ops");
12800 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
12801 .expect("exit");
12802 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12803 .expect("to shift");
12804 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
12805 .expect("to rel");
12806 atn.add_transition(
12807 3,
12808 ParserTransitionSpec::Precedence {
12809 target: 4,
12810 precedence: 2,
12811 },
12812 )
12813 .expect("shift prec");
12814 atn.add_transition(
12815 4,
12816 ParserTransitionSpec::Atom {
12817 target: 5,
12818 label: 1,
12819 },
12820 )
12821 .expect("shift first >");
12822 atn.add_transition(
12823 5,
12824 ParserTransitionSpec::Atom {
12825 target: 1,
12826 label: 1,
12827 },
12828 )
12829 .expect("shift second >");
12830 atn.add_transition(
12831 6,
12832 ParserTransitionSpec::Precedence {
12833 target: 7,
12834 precedence: 1,
12835 },
12836 )
12837 .expect("rel prec");
12838 atn.add_transition(
12839 7,
12840 ParserTransitionSpec::Atom {
12841 target: 1,
12842 label: 1,
12843 },
12844 )
12845 .expect("rel >");
12846 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
12847 .expect("loop end");
12848 finish_atn(atn)
12849 }
12850
12851 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
12852 let mut atn = ParserAtnBuilder::new(2);
12853 for (state, kind, rule) in [
12854 (0, AtnStateKind::RuleStart, 0),
12855 (1, AtnStateKind::StarLoopEntry, 0),
12856 (2, AtnStateKind::Basic, 0),
12857 (3, AtnStateKind::Basic, 0),
12858 (4, AtnStateKind::Basic, 0),
12859 (5, AtnStateKind::Basic, 0),
12860 (6, AtnStateKind::Basic, 0),
12861 (7, AtnStateKind::Basic, 0),
12862 (8, AtnStateKind::LoopEnd, 0),
12863 (9, AtnStateKind::RuleStop, 0),
12864 (10, AtnStateKind::RuleStart, 1),
12865 (11, AtnStateKind::Basic, 1),
12866 (12, AtnStateKind::RuleStop, 1),
12867 ] {
12868 assert_eq!(
12869 atn.add_state(kind, Some(rule)).expect("state").index(),
12870 state
12871 );
12872 if state == 0 {
12873 atn.set_left_recursive_rule(state)
12874 .expect("left-recursive rule start");
12875 } else if state == 1 {
12876 atn.set_precedence_rule_decision(state)
12877 .expect("precedence decision");
12878 }
12879 }
12880 atn.set_rule_to_start_state(vec![0, 10])
12881 .expect("rule start states");
12882 atn.set_rule_to_stop_state(vec![9, 12])
12883 .expect("rule stop states");
12884 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12885 .expect("ops");
12886 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
12887 .expect("exit");
12888 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12889 .expect("to shift");
12890 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
12891 .expect("to relational");
12892 atn.add_transition(
12893 3,
12894 ParserTransitionSpec::Precedence {
12895 target: 4,
12896 precedence: 2,
12897 },
12898 )
12899 .expect("shift precedence");
12900 atn.add_transition(
12901 4,
12902 ParserTransitionSpec::Rule {
12903 target: 10,
12904 rule_index: 1,
12905 follow_state: 5,
12906 precedence: 0,
12907 },
12908 )
12909 .expect("first shift token helper");
12910 atn.add_transition(
12911 5,
12912 ParserTransitionSpec::Atom {
12913 target: 1,
12914 label: 1,
12915 },
12916 )
12917 .expect("second shift token");
12918 atn.add_transition(
12919 6,
12920 ParserTransitionSpec::Precedence {
12921 target: 7,
12922 precedence: 1,
12923 },
12924 )
12925 .expect("relational precedence");
12926 atn.add_transition(
12927 7,
12928 ParserTransitionSpec::Atom {
12929 target: 1,
12930 label: 1,
12931 },
12932 )
12933 .expect("relational token");
12934 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
12935 .expect("loop end");
12936 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
12937 .expect("helper entry");
12938 atn.add_transition(
12939 11,
12940 ParserTransitionSpec::Atom {
12941 target: 12,
12942 label: 1,
12943 },
12944 )
12945 .expect("first shift token");
12946 finish_atn(atn)
12947 }
12948
12949 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
12950 let mut atn = ParserAtnBuilder::new(1);
12951 for (state, kind) in [
12952 (0, AtnStateKind::RuleStart),
12953 (1, AtnStateKind::StarLoopEntry),
12954 (2, AtnStateKind::Basic),
12955 (3, AtnStateKind::Basic),
12956 (4, AtnStateKind::Basic),
12957 (5, AtnStateKind::Basic),
12958 (6, AtnStateKind::Basic),
12959 (7, AtnStateKind::Basic),
12960 (8, AtnStateKind::Basic),
12961 (9, AtnStateKind::LoopEnd),
12962 (10, AtnStateKind::RuleStop),
12963 ] {
12964 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
12965 if state == 0 {
12966 atn.set_left_recursive_rule(state)
12967 .expect("left-recursive rule start");
12968 } else if state == 1 {
12969 atn.set_precedence_rule_decision(state)
12970 .expect("precedence decision");
12971 }
12972 }
12973 atn.set_rule_to_start_state(vec![0])
12974 .expect("rule start states");
12975 atn.set_rule_to_stop_state(vec![10])
12976 .expect("rule stop states");
12977 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12978 .expect("ops");
12979 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
12980 .expect("exit");
12981 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12982 .expect("to multi-token operator");
12983 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
12984 .expect("to predicate operator");
12985 atn.add_transition(
12986 3,
12987 ParserTransitionSpec::Precedence {
12988 target: 4,
12989 precedence: 2,
12990 },
12991 )
12992 .expect("multi-token precedence");
12993 atn.add_transition(
12994 4,
12995 ParserTransitionSpec::Atom {
12996 target: 5,
12997 label: 1,
12998 },
12999 )
13000 .expect("multi-token first");
13001 atn.add_transition(
13002 5,
13003 ParserTransitionSpec::Atom {
13004 target: 1,
13005 label: 1,
13006 },
13007 )
13008 .expect("multi-token second");
13009 atn.add_transition(
13010 6,
13011 ParserTransitionSpec::Precedence {
13012 target: 7,
13013 precedence: 2,
13014 },
13015 )
13016 .expect("predicate precedence");
13017 atn.add_transition(
13018 7,
13019 ParserTransitionSpec::Predicate {
13020 target: 8,
13021 rule_index: 0,
13022 pred_index: 0,
13023 context_dependent: false,
13024 },
13025 )
13026 .expect("operator predicate");
13027 atn.add_transition(
13028 8,
13029 ParserTransitionSpec::Atom {
13030 target: 1,
13031 label: 1,
13032 },
13033 )
13034 .expect("predicate single token");
13035 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13036 .expect("loop end");
13037 finish_atn(atn)
13038 }
13039
13040 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
13041 let mut atn = ParserAtnBuilder::new(2);
13042 for (state, kind, rule) in [
13043 (0, AtnStateKind::RuleStart, 0),
13044 (1, AtnStateKind::StarLoopEntry, 0),
13045 (2, AtnStateKind::Basic, 0),
13046 (3, AtnStateKind::Basic, 0),
13047 (4, AtnStateKind::Basic, 0),
13048 (5, AtnStateKind::LoopEnd, 0),
13049 (6, AtnStateKind::RuleStop, 0),
13050 (7, AtnStateKind::RuleStart, 1),
13051 (8, AtnStateKind::RuleStop, 1),
13052 (9, AtnStateKind::Basic, 1),
13053 ] {
13054 assert_eq!(
13055 atn.add_state(kind, Some(rule)).expect("state").index(),
13056 state
13057 );
13058 if state == 0 {
13059 atn.set_left_recursive_rule(state)
13060 .expect("left-recursive rule start");
13061 } else if state == 1 {
13062 atn.set_precedence_rule_decision(state)
13063 .expect("precedence decision");
13064 }
13065 }
13066 atn.set_rule_to_start_state(vec![0, 7])
13067 .expect("rule start states");
13068 atn.set_rule_to_stop_state(vec![6, 8])
13069 .expect("rule stop states");
13070 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13071 .expect("transition");
13072 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
13073 .expect("transition");
13074 atn.add_transition(
13075 2,
13076 ParserTransitionSpec::Precedence {
13077 target: 3,
13078 precedence: 3,
13079 },
13080 )
13081 .expect("transition");
13082 atn.add_transition(
13083 3,
13084 ParserTransitionSpec::Rule {
13085 target: 7,
13086 rule_index: 1,
13087 follow_state: 4,
13088 precedence: 0,
13089 },
13090 )
13091 .expect("transition");
13092 atn.add_transition(
13093 4,
13094 ParserTransitionSpec::Atom {
13095 target: 1,
13096 label: 1,
13097 },
13098 )
13099 .expect("transition");
13100 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13101 .expect("transition");
13102 atn.add_transition(
13103 7,
13104 ParserTransitionSpec::Precedence {
13105 target: 9,
13106 precedence: 1,
13107 },
13108 )
13109 .expect("transition");
13110 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
13111 .expect("transition");
13112 finish_atn(atn)
13113 }
13114
13115 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
13116 let mut atn = ParserAtnBuilder::new(2);
13117 for (state, kind) in [
13118 (0, AtnStateKind::RuleStart),
13119 (1, AtnStateKind::StarLoopEntry),
13120 (2, AtnStateKind::Basic),
13121 (3, AtnStateKind::Basic),
13122 (4, AtnStateKind::Basic),
13123 (5, AtnStateKind::LoopEnd),
13124 (6, AtnStateKind::RuleStop),
13125 ] {
13126 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13127 if state == 0 {
13128 atn.set_left_recursive_rule(state)
13129 .expect("left-recursive rule start");
13130 } else if state == 1 {
13131 atn.set_precedence_rule_decision(state)
13132 .expect("precedence decision");
13133 }
13134 }
13135 atn.set_rule_to_start_state(vec![0])
13136 .expect("rule start states");
13137 atn.set_rule_to_stop_state(vec![6])
13138 .expect("rule stop states");
13139 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13140 .expect("transition");
13141 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
13142 .expect("transition");
13143 atn.add_transition(
13144 2,
13145 ParserTransitionSpec::Precedence {
13146 target: 3,
13147 precedence: 1,
13148 },
13149 )
13150 .expect("transition");
13151 atn.add_transition(
13152 3,
13153 ParserTransitionSpec::Predicate {
13154 target: 4,
13155 rule_index: 0,
13156 pred_index: 0,
13157 context_dependent: false,
13158 },
13159 )
13160 .expect("transition");
13161 atn.add_transition(
13162 4,
13163 ParserTransitionSpec::Atom {
13164 target: 1,
13165 label: 1,
13166 },
13167 )
13168 .expect("transition");
13169 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13170 .expect("transition");
13171 finish_atn(atn)
13172 }
13173
13174 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
13175 let mut atn = ParserAtnBuilder::new(2);
13176 for (state, kind, rule) in [
13177 (0, AtnStateKind::RuleStart, 0),
13178 (1, AtnStateKind::Basic, 0),
13179 (2, AtnStateKind::Basic, 0),
13180 (3, AtnStateKind::Basic, 0),
13181 (4, AtnStateKind::RuleStop, 0),
13182 (5, AtnStateKind::RuleStart, 1),
13183 (6, AtnStateKind::StarLoopEntry, 1),
13184 (7, AtnStateKind::Basic, 1),
13185 (8, AtnStateKind::Basic, 1),
13186 (9, AtnStateKind::LoopEnd, 1),
13187 (10, AtnStateKind::RuleStop, 1),
13188 (11, AtnStateKind::RuleStart, 2),
13189 (12, AtnStateKind::RuleStop, 2),
13190 ] {
13191 assert_eq!(
13192 atn.add_state(kind, Some(rule)).expect("state").index(),
13193 state
13194 );
13195 if state == 5 {
13196 atn.set_left_recursive_rule(state)
13197 .expect("left-recursive rule start");
13198 } else if state == 6 {
13199 atn.set_precedence_rule_decision(state)
13200 .expect("precedence decision");
13201 }
13202 }
13203 atn.set_rule_to_start_state(vec![0, 5, 11])
13204 .expect("rule start states");
13205 atn.set_rule_to_stop_state(vec![4, 10, 12])
13206 .expect("rule stop states");
13207 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13208 .expect("transition");
13209 atn.add_transition(
13210 1,
13211 ParserTransitionSpec::Rule {
13212 target: 5,
13213 rule_index: 1,
13214 follow_state: 2,
13215 precedence: 0,
13216 },
13217 )
13218 .expect("transition");
13219 atn.add_transition(
13220 2,
13221 ParserTransitionSpec::Rule {
13222 target: 11,
13223 rule_index: 2,
13224 follow_state: 3,
13225 precedence: 0,
13226 },
13227 )
13228 .expect("transition");
13229 atn.add_transition(
13230 3,
13231 ParserTransitionSpec::Atom {
13232 target: 4,
13233 label: caller_symbol,
13234 },
13235 )
13236 .expect("transition");
13237 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13238 .expect("transition");
13239 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
13240 .expect("transition");
13241 atn.add_transition(
13242 7,
13243 ParserTransitionSpec::Precedence {
13244 target: 8,
13245 precedence: 1,
13246 },
13247 )
13248 .expect("transition");
13249 atn.add_transition(
13250 8,
13251 ParserTransitionSpec::Atom {
13252 target: 6,
13253 label: 1,
13254 },
13255 )
13256 .expect("transition");
13257 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13258 .expect("transition");
13259 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
13260 .expect("transition");
13261 finish_atn(atn)
13262 }
13263
13264 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
13265 let mut atn = ParserAtnBuilder::new(2);
13266 for (state, kind, rule) in [
13267 (0, AtnStateKind::RuleStart, 0),
13268 (1, AtnStateKind::Basic, 0),
13269 (2, AtnStateKind::Basic, 0),
13270 (3, AtnStateKind::RuleStop, 0),
13271 (4, AtnStateKind::RuleStart, 1),
13272 (5, AtnStateKind::Basic, 1),
13273 (6, AtnStateKind::Basic, 1),
13274 (7, AtnStateKind::RuleStop, 1),
13275 (8, AtnStateKind::RuleStart, 2),
13276 (9, AtnStateKind::StarLoopEntry, 2),
13277 (10, AtnStateKind::Basic, 2),
13278 (11, AtnStateKind::Basic, 2),
13279 (12, AtnStateKind::LoopEnd, 2),
13280 (13, AtnStateKind::RuleStop, 2),
13281 ] {
13282 assert_eq!(
13283 atn.add_state(kind, Some(rule)).expect("state").index(),
13284 state
13285 );
13286 if state == 8 {
13287 atn.set_left_recursive_rule(state)
13288 .expect("left-recursive rule start");
13289 } else if state == 9 {
13290 atn.set_precedence_rule_decision(state)
13291 .expect("precedence decision");
13292 }
13293 }
13294 atn.set_rule_to_start_state(vec![0, 4, 8])
13295 .expect("rule start states");
13296 atn.set_rule_to_stop_state(vec![3, 7, 13])
13297 .expect("rule stop states");
13298 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13299 .expect("transition");
13300 atn.add_transition(
13301 1,
13302 ParserTransitionSpec::Rule {
13303 target: 4,
13304 rule_index: 1,
13305 follow_state: 2,
13306 precedence: 0,
13307 },
13308 )
13309 .expect("transition");
13310 atn.add_transition(
13311 2,
13312 ParserTransitionSpec::Atom {
13313 target: 3,
13314 label: caller_symbol,
13315 },
13316 )
13317 .expect("transition");
13318 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13319 .expect("transition");
13320 atn.add_transition(
13321 5,
13322 ParserTransitionSpec::Rule {
13323 target: 8,
13324 rule_index: 2,
13325 follow_state: 6,
13326 precedence: 0,
13327 },
13328 )
13329 .expect("transition");
13330 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13331 .expect("transition");
13332 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13333 .expect("transition");
13334 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
13335 .expect("transition");
13336 atn.add_transition(
13337 10,
13338 ParserTransitionSpec::Precedence {
13339 target: 11,
13340 precedence: 1,
13341 },
13342 )
13343 .expect("transition");
13344 atn.add_transition(
13345 11,
13346 ParserTransitionSpec::Atom {
13347 target: 9,
13348 label: 1,
13349 },
13350 )
13351 .expect("transition");
13352 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
13353 .expect("transition");
13354 finish_atn(atn)
13355 }
13356
13357 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
13358 let mut atn = ParserAtnBuilder::new(2);
13359 for (state, kind, rule) in [
13360 (0, AtnStateKind::RuleStart, 0),
13361 (1, AtnStateKind::Basic, 0),
13362 (2, AtnStateKind::Basic, 0),
13363 (3, AtnStateKind::RuleStop, 0),
13364 (4, AtnStateKind::RuleStart, 1),
13365 (5, AtnStateKind::StarLoopEntry, 1),
13366 (6, AtnStateKind::Basic, 1),
13367 (7, AtnStateKind::Basic, 1),
13368 (8, AtnStateKind::Basic, 1),
13369 (9, AtnStateKind::Basic, 1),
13370 (10, AtnStateKind::LoopEnd, 1),
13371 (11, AtnStateKind::RuleStop, 1),
13372 ] {
13373 assert_eq!(
13374 atn.add_state(kind, Some(rule)).expect("state").index(),
13375 state
13376 );
13377 if state == 4 {
13378 atn.set_left_recursive_rule(state)
13379 .expect("left-recursive rule start");
13380 } else if state == 5 {
13381 atn.set_precedence_rule_decision(state)
13382 .expect("precedence decision");
13383 }
13384 }
13385 atn.set_rule_to_start_state(vec![0, 4])
13386 .expect("rule start states");
13387 atn.set_rule_to_stop_state(vec![3, 11])
13388 .expect("rule stop states");
13389 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13390 .expect("transition");
13391 atn.add_transition(
13392 1,
13393 ParserTransitionSpec::Rule {
13394 target: 4,
13395 rule_index: 1,
13396 follow_state: 2,
13397 precedence: 0,
13398 },
13399 )
13400 .expect("transition");
13401 atn.add_transition(
13402 2,
13403 ParserTransitionSpec::Atom {
13404 target: 3,
13405 label: caller_symbol,
13406 },
13407 )
13408 .expect("transition");
13409 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13410 .expect("transition");
13411 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
13412 .expect("transition");
13413 atn.add_transition(
13414 6,
13415 ParserTransitionSpec::Precedence {
13416 target: 7,
13417 precedence: 1,
13418 },
13419 )
13420 .expect("transition");
13421 atn.add_transition(
13422 7,
13423 ParserTransitionSpec::Atom {
13424 target: 8,
13425 label: 1,
13426 },
13427 )
13428 .expect("transition");
13429 atn.add_transition(
13430 8,
13431 ParserTransitionSpec::Rule {
13432 target: 4,
13433 rule_index: 1,
13434 follow_state: 9,
13435 precedence: 2,
13436 },
13437 )
13438 .expect("transition");
13439 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
13440 .expect("transition");
13441 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
13442 .expect("transition");
13443 finish_atn(atn)
13444 }
13445
13446 #[test]
13447 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
13448 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
13449 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
13450
13451 let mut overlapping = parser_inside_left_recursive_callee(1);
13452 assert_eq!(
13453 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
13454 None
13455 );
13456
13457 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
13458 assert_eq!(
13459 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13460 Some(true)
13461 );
13462
13463 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
13464 assert_eq!(
13465 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13466 Some(false)
13467 );
13468
13469 assert_eq!(
13470 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13471 Some(true),
13472 "overlap results must not leak across ATNs"
13473 );
13474 }
13475
13476 #[test]
13477 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
13478 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
13479 let mut parser = mini_parser(vec![
13480 TestToken::new(1).with_text("operator"),
13481 TestToken::eof("parser-test", 1, 1, 1),
13482 ]);
13483 parser.rule_context_stack = vec![RuleContextFrame {
13484 rule_index: 0,
13485 invoking_state: -1,
13486 }];
13487
13488 assert_eq!(
13489 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13490 Some(true)
13491 );
13492 assert_eq!(
13493 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13494 Some(true),
13495 "cached operator lookahead must preserve the nullable prefix return path"
13496 );
13497 assert_eq!(
13498 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13499 Some(true),
13500 "the nullable child must use its rule-call precedence, not the caller precedence"
13501 );
13502 }
13503
13504 #[test]
13505 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
13506 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
13511 let mut parser = mini_parser(vec![
13512 TestToken::new(1).with_text(">"),
13513 TestToken::new(2).with_text("id"),
13514 TestToken::eof("parser-test", 1, 1, 1),
13515 ]);
13516 parser.rule_context_stack = vec![RuleContextFrame {
13517 rule_index: 0,
13518 invoking_state: -1,
13519 }];
13520
13521 assert_eq!(
13522 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13523 Some(true),
13524 "at low precedence relational `>` is a single-token operator"
13525 );
13526 assert_eq!(
13527 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
13528 Some(true),
13529 "relational remains single-token at its own precedence"
13530 );
13531 assert_eq!(
13532 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13533 None,
13534 "at shift precedence, bare `>` must not force enter"
13535 );
13536 }
13537
13538 #[test]
13539 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
13540 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
13541 let mut parser = mini_parser(vec![
13542 TestToken::new(1).with_text(">"),
13543 TestToken::new(2).with_text("id"),
13544 TestToken::eof("parser-test", 1, 1, 1),
13545 ]);
13546 parser.rule_context_stack = vec![RuleContextFrame {
13547 rule_index: 0,
13548 invoking_state: -1,
13549 }];
13550
13551 assert_eq!(
13552 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13553 Some(true),
13554 "the direct relational alternative remains a one-token operator"
13555 );
13556 assert_eq!(
13557 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13558 None,
13559 "a token matched in the helper rule must return to the second shift token"
13560 );
13561 }
13562
13563 #[test]
13564 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
13565 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
13566 let mut parser = mini_parser(vec![
13567 TestToken::new(1).with_text(">"),
13568 TestToken::new(2).with_text("id"),
13569 TestToken::eof("parser-test", 1, 1, 1),
13570 ]);
13571 parser.rule_context_stack = vec![RuleContextFrame {
13572 rule_index: 0,
13573 invoking_state: -1,
13574 }];
13575
13576 assert_eq!(
13577 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13578 None,
13579 "a predicate-gated single-token path must not be hidden by a multi-token path"
13580 );
13581 }
13582
13583 #[test]
13584 fn left_recursive_loop_defers_predicate_guarded_operator() {
13585 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
13586 let mut parser = mini_parser_with_hooks(
13587 vec![
13588 TestToken::new(1).with_text("operator"),
13589 TestToken::eof("parser-test", 1, 1, 1),
13590 ],
13591 RejectingPredicateHooks::default(),
13592 );
13593 parser.rule_context_stack = vec![RuleContextFrame {
13594 rule_index: 0,
13595 invoking_state: -1,
13596 }];
13597
13598 assert_eq!(
13599 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13600 None,
13601 "a false predicate must be evaluated before entering the operator alternative"
13602 );
13603 assert_eq!(
13604 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13605 None,
13606 "cached predicate-dependent lookahead must keep deferring"
13607 );
13608 }
13609
13610 #[test]
13611 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
13612 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
13613 let mut parser = parser_inside_left_recursive_callee(1);
13614
13615 assert_eq!(
13616 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
13617 None
13618 );
13619 assert_eq!(
13620 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
13621 None,
13622 "the cached overlap must preserve the nullable child return path"
13623 );
13624 }
13625
13626 #[test]
13627 fn left_recursive_loop_defers_through_nullable_parent_return() {
13628 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
13629 let mut parser = mini_parser(vec![
13630 TestToken::new(1).with_text("lookahead"),
13631 TestToken::eof("parser-test", 1, 1, 1),
13632 ]);
13633 parser.rule_context_stack = vec![
13634 RuleContextFrame {
13635 rule_index: 0,
13636 invoking_state: -1,
13637 },
13638 RuleContextFrame {
13639 rule_index: 1,
13640 invoking_state: 1,
13641 },
13642 RuleContextFrame {
13643 rule_index: 2,
13644 invoking_state: 5,
13645 },
13646 ];
13647
13648 assert_eq!(
13649 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
13650 None,
13651 "a nullable caller must unwind to its parent's consuming follow path"
13652 );
13653 assert_eq!(
13654 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
13655 None,
13656 "the caller-overlap cache must not retain a false negative"
13657 );
13658 }
13659
13660 #[test]
13661 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
13662 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
13663 let mut parser = mini_parser(vec![
13664 TestToken::new(1).with_text("lookahead"),
13665 TestToken::eof("parser-test", 1, 1, 1),
13666 ]);
13667 parser.rule_context_stack = vec![
13668 RuleContextFrame {
13669 rule_index: 0,
13670 invoking_state: -1,
13671 },
13672 RuleContextFrame {
13673 rule_index: 1,
13674 invoking_state: 1,
13675 },
13676 RuleContextFrame {
13677 rule_index: 1,
13678 invoking_state: 8,
13679 },
13680 ];
13681
13682 assert_eq!(
13683 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
13684 None,
13685 "a recursive operand return must preserve its parent caller context"
13686 );
13687 assert_eq!(
13688 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
13689 None,
13690 "the caller-overlap cache must preserve the loop-boundary return"
13691 );
13692 }
13693
13694 fn token_then_eof_atn() -> Atn {
13695 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13696 4, 1, 2, 3, 2, 0, 1, 0, 7, 0, 0, 0, 1, 0, 0, 0, 2, 0, 1, 5, 1, 0, 0, 1, 2, 5, -1, 0, 0, 0, ]))
13712 .deserialize_parser()
13713 .expect("artificial parser ATN should deserialize")
13714 }
13715
13716 fn epsilon_cycle_atn() -> Atn {
13717 let mut atn = ParserAtnBuilder::new(1);
13718 for (state_number, kind) in [
13719 (0, AtnStateKind::RuleStart),
13720 (1, AtnStateKind::Basic),
13721 (2, AtnStateKind::RuleStop),
13722 ] {
13723 assert_eq!(
13724 atn.add_state(kind, Some(0)).expect("state").index(),
13725 state_number
13726 );
13727 }
13728 atn.set_rule_to_start_state(vec![0])
13729 .expect("rule start states");
13730 atn.set_rule_to_stop_state(vec![2])
13731 .expect("rule stop states");
13732 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13733 .expect("transition");
13734 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
13735 .expect("self-cycle transition");
13736 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13737 .expect("exit transition");
13738 finish_atn(atn)
13739 }
13740
13741 fn eof_then_action_atn() -> Atn {
13742 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13743 4, 1, 1, 3, 2, 0, 1, 0, 7, 0, 0, 0, 1, 0, 0, 0, 2, 0, 1, 5, -1, 0, 0, 1, 2, 6, 0, 0, 0, 0, ]))
13759 .deserialize_parser()
13760 .expect("artificial parser ATN should deserialize")
13761 }
13762
13763 fn noop_action_then_token_then_eof_atn() -> Atn {
13764 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13765 4, 1, 2, 4, 2, 0, 1, 0, 1, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 1, 6, 0, -1, 0, 1, 2, 5, 1, 0, 0, 2, 3, 5, -1, 0, 0, 0, ]))
13783 .deserialize_parser()
13784 .expect("artificial no-op action ATN should deserialize")
13785 }
13786
13787 fn two_alt_decision_atn() -> Atn {
13788 let mut atn = ParserAtnBuilder::new(2);
13789 assert_eq!(
13790 atn.add_state(AtnStateKind::RuleStart, Some(0))
13791 .expect("state")
13792 .index(),
13793 0
13794 );
13795 assert_eq!(
13796 atn.add_state(AtnStateKind::BlockStart, Some(0))
13797 .expect("state")
13798 .index(),
13799 1
13800 );
13801 assert_eq!(
13802 atn.add_state(AtnStateKind::Basic, Some(0))
13803 .expect("state")
13804 .index(),
13805 2
13806 );
13807 assert_eq!(
13808 atn.add_state(AtnStateKind::Basic, Some(0))
13809 .expect("state")
13810 .index(),
13811 3
13812 );
13813 assert_eq!(
13814 atn.add_state(AtnStateKind::BlockEnd, Some(0))
13815 .expect("state")
13816 .index(),
13817 4
13818 );
13819 assert_eq!(
13820 atn.add_state(AtnStateKind::RuleStop, Some(0))
13821 .expect("state")
13822 .index(),
13823 5
13824 );
13825 atn.set_rule_to_start_state(vec![0])
13826 .expect("rule start states");
13827 atn.set_rule_to_stop_state(vec![5])
13828 .expect("rule stop states");
13829 atn.add_decision_state(1).expect("decision state");
13830 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13831 .expect("transition");
13832 atn.add_transition(
13833 1,
13834 ParserTransitionSpec::Atom {
13835 target: 2,
13836 label: 1,
13837 },
13838 )
13839 .expect("transition");
13840 atn.add_transition(
13841 1,
13842 ParserTransitionSpec::Atom {
13843 target: 3,
13844 label: 2,
13845 },
13846 )
13847 .expect("transition");
13848 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
13849 .expect("transition");
13850 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
13851 .expect("transition");
13852 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13853 .expect("transition");
13854 finish_atn(atn)
13855 }
13856
13857 fn optional_then_b_eof_atn() -> Atn {
13860 let mut atn = ParserAtnBuilder::new(3);
13861 assert_eq!(
13862 atn.add_state(AtnStateKind::RuleStart, Some(0))
13863 .expect("state")
13864 .index(),
13865 0
13866 );
13867 assert_eq!(
13868 atn.add_state(AtnStateKind::BlockStart, Some(0))
13869 .expect("state")
13870 .index(),
13871 1
13872 );
13873 assert_eq!(
13874 atn.add_state(AtnStateKind::Basic, Some(0))
13875 .expect("state")
13876 .index(),
13877 2
13878 );
13879 assert_eq!(
13880 atn.add_state(AtnStateKind::Basic, Some(0))
13881 .expect("state")
13882 .index(),
13883 3
13884 );
13885 assert_eq!(
13886 atn.add_state(AtnStateKind::Basic, Some(0))
13887 .expect("state")
13888 .index(),
13889 4
13890 );
13891 assert_eq!(
13892 atn.add_state(AtnStateKind::RuleStop, Some(0))
13893 .expect("state")
13894 .index(),
13895 5
13896 );
13897 atn.set_rule_to_start_state(vec![0])
13898 .expect("rule start states");
13899 atn.set_rule_to_stop_state(vec![5])
13900 .expect("rule stop states");
13901 atn.add_decision_state(1).expect("decision state");
13902 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13903 .expect("transition");
13904 atn.add_transition(
13906 1,
13907 ParserTransitionSpec::Atom {
13908 target: 3,
13909 label: 1,
13910 },
13911 )
13912 .expect("transition");
13913 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
13914 .expect("transition");
13915 atn.add_transition(
13917 3,
13918 ParserTransitionSpec::Atom {
13919 target: 4,
13920 label: 2,
13921 },
13922 )
13923 .expect("transition");
13924 atn.add_transition(
13925 4,
13926 ParserTransitionSpec::Atom {
13927 target: 5,
13928 label: TOKEN_EOF,
13929 },
13930 )
13931 .expect("transition");
13932 finish_atn(atn)
13933 }
13934
13935 #[test]
13936 fn sync_decision_deletes_only_a_single_token() {
13937 let atn = optional_then_b_eof_atn();
13945
13946 let mut single = mini_parser(vec![
13947 TestToken::new(3).with_text("c"),
13948 TestToken::new(2).with_text("b"),
13949 TestToken::eof("parser-test", 1, 2, 2),
13950 ]);
13951 single.rule_context_stack = vec![RuleContextFrame {
13952 rule_index: 0,
13953 invoking_state: 0,
13954 }];
13955 let children = single
13956 .sync_decision(&atn, 1, true, false)
13957 .expect("single extraneous token recovers");
13958 assert_eq!(children.len(), 1);
13959 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
13960 assert_eq!(single.number_of_syntax_errors(), 1);
13961 assert_eq!(single.la(1), 2);
13963
13964 let mut double = mini_parser(vec![
13965 TestToken::new(3).with_text("c"),
13966 TestToken::new(3).with_text("c"),
13967 TestToken::new(2).with_text("b"),
13968 TestToken::eof("parser-test", 1, 3, 3),
13969 ]);
13970 double.rule_context_stack = vec![RuleContextFrame {
13971 rule_index: 0,
13972 invoking_state: 0,
13973 }];
13974 let result = double.sync_decision(&atn, 1, true, false);
13975 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
13980 match error {
13981 AntlrError::ParserError { message, .. } => {
13982 assert!(message.starts_with("mismatched input"), "got: {message}");
13983 }
13984 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
13985 }
13986 assert_eq!(double.la(1), 3);
13987 }
13988
13989 fn star_loop_then_eof_atn() -> Atn {
13993 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13994 4, 1, 3, 11, 2, 0, 7, 0, 1, 0, 5, 0, 4, 8, 0, 10, 0, 12, 0, 7, 9, 0, 1, 0, 1, 0, 1, 0,
13995 0, 0, 1, 0, 0, 0, 10, 0, 5, 1, 0, 0, 0, 2, 4, 5, 1, 0, 0, 3, 2, 1, 0, 0, 0, 4, 7, 1, 0,
13996 0, 0, 5, 3, 1, 0, 0, 0, 5, 6, 1, 0, 0, 0, 6, 8, 1, 0, 0, 0, 7, 5, 1, 0, 0, 0, 8, 9, 5,
13997 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
13998 ]))
13999 .deserialize_parser()
14000 .expect("star-loop-then-EOF ATN should deserialize")
14001 }
14002
14003 fn plus_loop_with_recovering_body_atn() -> Atn {
14009 let mut atn = ParserAtnBuilder::new(2);
14010 assert_eq!(
14011 atn.add_state(AtnStateKind::RuleStart, Some(0))
14012 .expect("state")
14013 .index(),
14014 0
14015 );
14016 assert_eq!(
14017 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
14018 .expect("state")
14019 .index(),
14020 1
14021 );
14022 assert_eq!(
14023 atn.add_state(AtnStateKind::Basic, Some(0))
14024 .expect("state")
14025 .index(),
14026 2
14027 );
14028 assert_eq!(
14029 atn.add_state(AtnStateKind::BlockEnd, Some(0))
14030 .expect("state")
14031 .index(),
14032 3
14033 );
14034 assert_eq!(
14035 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
14036 .expect("state")
14037 .index(),
14038 4
14039 );
14040 assert_eq!(
14041 atn.add_state(AtnStateKind::LoopEnd, Some(0))
14042 .expect("state")
14043 .index(),
14044 5
14045 );
14046 assert_eq!(
14047 atn.add_state(AtnStateKind::RuleStop, Some(0))
14048 .expect("state")
14049 .index(),
14050 6
14051 );
14052 assert_eq!(
14053 atn.add_state(AtnStateKind::RuleStart, Some(1))
14054 .expect("state")
14055 .index(),
14056 7
14057 );
14058 assert_eq!(
14059 atn.add_state(AtnStateKind::Basic, Some(1))
14060 .expect("state")
14061 .index(),
14062 8
14063 );
14064 assert_eq!(
14065 atn.add_state(AtnStateKind::RuleStop, Some(1))
14066 .expect("state")
14067 .index(),
14068 9
14069 );
14070 atn.set_rule_to_start_state(vec![0, 7])
14071 .expect("rule start states");
14072 atn.set_rule_to_stop_state(vec![6, 9])
14073 .expect("rule stop states");
14074 atn.set_end_state(1, 3).expect("block end state");
14075 atn.set_loop_back_state(5, 4).expect("loop back state");
14076 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14077 .expect("transition");
14078 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14079 .expect("transition");
14080 atn.add_transition(
14081 2,
14082 ParserTransitionSpec::Rule {
14083 target: 7,
14084 rule_index: 1,
14085 follow_state: 3,
14086 precedence: 0,
14087 },
14088 )
14089 .expect("transition");
14090 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14091 .expect("transition");
14092 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
14093 .expect("transition");
14094 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14095 .expect("transition");
14096 atn.add_transition(
14097 5,
14098 ParserTransitionSpec::Atom {
14099 target: 6,
14100 label: 2,
14101 },
14102 )
14103 .expect("transition");
14104 atn.add_transition(
14105 7,
14106 ParserTransitionSpec::Atom {
14107 target: 8,
14108 label: 1,
14109 },
14110 )
14111 .expect("transition");
14112 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14113 .expect("transition");
14114 finish_atn(atn)
14115 }
14116
14117 #[test]
14118 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
14119 let atn = plus_loop_with_recovering_body_atn();
14120 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14121
14122 let error = parser
14123 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
14124 .expect_err("EOF recovery should report a bounded mismatch");
14125
14126 let AntlrError::ParserError { message, .. } = error else {
14127 panic!("expected ParserError, got {error:?}");
14128 };
14129 assert_eq!(message, "mismatched input '<EOF>' expecting {'x', 2}");
14130 assert_eq!(parser.number_of_syntax_errors(), 1);
14131 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
14132 }
14133
14134 #[test]
14135 fn sync_decision_deletes_token_before_eof_at_loop_back() {
14136 let atn = star_loop_then_eof_atn();
14142 let mut parser = mini_parser(vec![
14143 TestToken::new(2).with_text("c"),
14144 TestToken::eof("parser-test", 1, 1, 1),
14145 ]);
14146 parser.rule_context_stack = vec![RuleContextFrame {
14147 rule_index: 0,
14148 invoking_state: 0,
14149 }];
14150 let children = parser
14151 .sync_decision(&atn, 5, true, false)
14152 .expect("single token before EOF recovers");
14153 assert_eq!(children.len(), 1);
14154 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
14155 assert_eq!(parser.number_of_syntax_errors(), 1);
14156 assert_eq!(
14157 parser.la(1),
14158 TOKEN_EOF,
14159 "EOF is left for the rule's EOF match"
14160 );
14161 }
14162
14163 #[test]
14164 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
14165 let atn = star_loop_then_eof_atn();
14170 let mut parser = mini_parser(vec![
14171 TestToken::new(2).with_text("c"),
14172 TestToken::new(2).with_text("c"),
14173 TestToken::eof("parser-test", 1, 2, 2),
14174 ]);
14175 parser.rule_context_stack = vec![RuleContextFrame {
14176 rule_index: 0,
14177 invoking_state: 0,
14178 }];
14179 let error = parser
14180 .sync_decision(&atn, 5, true, false)
14181 .expect_err("two tokens at the loop entry must not be deleted");
14182 match error {
14183 AntlrError::ParserError { message, .. } => {
14184 assert!(message.starts_with("mismatched input"), "got: {message}");
14185 }
14186 other => panic!("expected mismatched-input ParserError, got {other:?}"),
14187 }
14188 assert_eq!(
14189 parser.la(1),
14190 2,
14191 "nothing consumed; cursor still on first `c`"
14192 );
14193 }
14194
14195 #[test]
14196 fn sync_decision_consumes_until_eof_at_loop_back() {
14197 let atn = star_loop_then_eof_atn();
14203 let mut parser = mini_parser(vec![
14204 TestToken::new(2).with_text("c"),
14205 TestToken::new(2).with_text("c"),
14206 TestToken::eof("parser-test", 1, 2, 2),
14207 ]);
14208 parser.rule_context_stack = vec![RuleContextFrame {
14209 rule_index: 0,
14210 invoking_state: 0,
14211 }];
14212 let children = parser
14213 .sync_decision(&atn, 5, false, true)
14214 .expect("loop-back multi-token deletion recovers onto EOF");
14215 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
14216 assert!(
14217 children
14218 .iter()
14219 .all(|child| parser.node(*child).kind() == NodeKind::Error)
14220 );
14221 assert_eq!(parser.number_of_syntax_errors(), 1);
14222 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
14223 }
14224
14225 fn predicate_after_token_atn() -> Atn {
14226 let mut atn = ParserAtnBuilder::new(2);
14227 assert_eq!(
14228 atn.add_state(AtnStateKind::RuleStart, Some(0))
14229 .expect("state")
14230 .index(),
14231 0
14232 );
14233 assert_eq!(
14234 atn.add_state(AtnStateKind::Basic, Some(0))
14235 .expect("state")
14236 .index(),
14237 1
14238 );
14239 assert_eq!(
14240 atn.add_state(AtnStateKind::Basic, Some(0))
14241 .expect("state")
14242 .index(),
14243 2
14244 );
14245 assert_eq!(
14246 atn.add_state(AtnStateKind::Basic, Some(0))
14247 .expect("state")
14248 .index(),
14249 3
14250 );
14251 assert_eq!(
14252 atn.add_state(AtnStateKind::RuleStop, Some(0))
14253 .expect("state")
14254 .index(),
14255 4
14256 );
14257 atn.set_rule_to_start_state(vec![0])
14258 .expect("rule start states");
14259 atn.set_rule_to_stop_state(vec![4])
14260 .expect("rule stop states");
14261 atn.add_transition(
14262 0,
14263 ParserTransitionSpec::Atom {
14264 target: 1,
14265 label: 1,
14266 },
14267 )
14268 .expect("transition");
14269 atn.add_transition(
14270 1,
14271 ParserTransitionSpec::Predicate {
14272 target: 2,
14273 rule_index: 0,
14274 pred_index: 0,
14275 context_dependent: false,
14276 },
14277 )
14278 .expect("transition");
14279 atn.add_transition(
14280 2,
14281 ParserTransitionSpec::Atom {
14282 target: 3,
14283 label: 2,
14284 },
14285 )
14286 .expect("transition");
14287 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14288 .expect("transition");
14289 finish_atn(atn)
14290 }
14291
14292 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
14293 let mut atn = ParserAtnBuilder::new(1);
14294 for (state_number, kind) in [
14295 (0, AtnStateKind::RuleStart),
14296 (1, AtnStateKind::BlockStart),
14297 (2, AtnStateKind::Basic),
14298 (3, AtnStateKind::Basic),
14299 (4, AtnStateKind::Basic),
14300 (5, AtnStateKind::Basic),
14301 (6, AtnStateKind::BlockEnd),
14302 (7, AtnStateKind::RuleStop),
14303 ] {
14304 assert_eq!(
14305 atn.add_state(kind, Some(0)).expect("state").index(),
14306 state_number
14307 );
14308 }
14309 atn.set_rule_to_start_state(vec![0])
14310 .expect("rule start states");
14311 atn.set_rule_to_stop_state(vec![7])
14312 .expect("rule stop states");
14313 atn.add_decision_state(1).expect("decision state");
14314 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14315 .expect("transition");
14316 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14317 .expect("transition");
14318 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
14319 .expect("transition");
14320 atn.add_transition(
14321 2,
14322 ParserTransitionSpec::Predicate {
14323 target: 4,
14324 rule_index: 0,
14325 pred_index: pred_indexes[0],
14326 context_dependent: false,
14327 },
14328 )
14329 .expect("transition");
14330 atn.add_transition(
14331 3,
14332 ParserTransitionSpec::Predicate {
14333 target: 5,
14334 rule_index: 0,
14335 pred_index: pred_indexes[1],
14336 context_dependent: false,
14337 },
14338 )
14339 .expect("transition");
14340 atn.add_transition(
14341 4,
14342 ParserTransitionSpec::Atom {
14343 target: 6,
14344 label: 1,
14345 },
14346 )
14347 .expect("transition");
14348 atn.add_transition(
14349 5,
14350 ParserTransitionSpec::Atom {
14351 target: 6,
14352 label: 1,
14353 },
14354 )
14355 .expect("transition");
14356 atn.add_transition(
14357 6,
14358 ParserTransitionSpec::Atom {
14359 target: 7,
14360 label: TOKEN_EOF,
14361 },
14362 )
14363 .expect("transition");
14364 finish_atn(atn)
14365 }
14366
14367 fn nested_nullable_context_atn() -> Atn {
14368 let mut atn = ParserAtnBuilder::new(1);
14369 for state_number in 0..=20 {
14370 let kind = match state_number {
14371 0 | 10 | 16 => AtnStateKind::RuleStart,
14372 9 | 15 | 20 => AtnStateKind::RuleStop,
14373 _ => AtnStateKind::Basic,
14374 };
14375 let rule_index = match state_number {
14376 0..=9 => 0,
14377 10..=15 => 1,
14378 _ => 2,
14379 };
14380 assert_eq!(
14381 atn.add_state(kind, Some(rule_index))
14382 .expect("state")
14383 .index(),
14384 state_number
14385 );
14386 }
14387 atn.set_rule_to_start_state(vec![0, 10, 16])
14388 .expect("rule start states");
14389 atn.set_rule_to_stop_state(vec![9, 15, 20])
14390 .expect("rule stop states");
14391 atn.add_transition(
14392 1,
14393 ParserTransitionSpec::Rule {
14394 target: 10,
14395 rule_index: 1,
14396 follow_state: 8,
14397 precedence: 0,
14398 },
14399 )
14400 .expect("transition");
14401 atn.add_transition(
14402 8,
14403 ParserTransitionSpec::Atom {
14404 target: 9,
14405 label: 1,
14406 },
14407 )
14408 .expect("transition");
14409 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14410 .expect("transition");
14411 atn.add_transition(
14412 2,
14413 ParserTransitionSpec::Rule {
14414 target: 16,
14415 rule_index: 2,
14416 follow_state: 14,
14417 precedence: 0,
14418 },
14419 )
14420 .expect("transition");
14421 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
14422 .expect("transition");
14423 finish_atn(atn)
14424 }
14425
14426 fn generated_match_recovery_atn() -> Atn {
14427 let mut atn = ParserAtnBuilder::new(2);
14428 assert_eq!(
14429 atn.add_state(AtnStateKind::RuleStart, Some(0))
14430 .expect("state")
14431 .index(),
14432 0
14433 );
14434 assert_eq!(
14435 atn.add_state(AtnStateKind::Basic, Some(0))
14436 .expect("state")
14437 .index(),
14438 1
14439 );
14440 assert_eq!(
14441 atn.add_state(AtnStateKind::Basic, Some(0))
14442 .expect("state")
14443 .index(),
14444 2
14445 );
14446 assert_eq!(
14447 atn.add_state(AtnStateKind::RuleStop, Some(0))
14448 .expect("state")
14449 .index(),
14450 3
14451 );
14452 assert_eq!(
14453 atn.add_state(AtnStateKind::RuleStart, Some(1))
14454 .expect("state")
14455 .index(),
14456 4
14457 );
14458 assert_eq!(
14459 atn.add_state(AtnStateKind::RuleStop, Some(1))
14460 .expect("state")
14461 .index(),
14462 5
14463 );
14464 atn.set_rule_to_start_state(vec![0, 4])
14465 .expect("rule start states");
14466 atn.set_rule_to_stop_state(vec![3, 5])
14467 .expect("rule stop states");
14468 atn.add_transition(
14469 1,
14470 ParserTransitionSpec::Rule {
14471 target: 4,
14472 rule_index: 1,
14473 follow_state: 2,
14474 precedence: 0,
14475 },
14476 )
14477 .expect("transition");
14478 atn.add_transition(
14479 2,
14480 ParserTransitionSpec::Atom {
14481 target: 3,
14482 label: TOKEN_EOF,
14483 },
14484 )
14485 .expect("transition");
14486 finish_atn(atn)
14487 }
14488
14489 fn complement_set_atn() -> Atn {
14490 let mut atn = ParserAtnBuilder::new(1);
14491 assert_eq!(
14492 atn.add_state(AtnStateKind::RuleStart, Some(0))
14493 .expect("state")
14494 .index(),
14495 0
14496 );
14497 assert_eq!(
14498 atn.add_state(AtnStateKind::RuleStop, Some(0))
14499 .expect("state")
14500 .index(),
14501 1
14502 );
14503 atn.set_rule_to_start_state(vec![0])
14504 .expect("rule start states");
14505 atn.set_rule_to_stop_state(vec![1])
14506 .expect("rule stop states");
14507 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
14508 atn.add_transition(
14509 0,
14510 ParserTransitionSpec::NotSet {
14511 target: 1,
14512 set: excluded,
14513 },
14514 )
14515 .expect("transition");
14516 finish_atn(atn)
14517 }
14518
14519 fn wildcard_then_eof_atn() -> Atn {
14522 let mut atn = ParserAtnBuilder::new(1);
14523 assert_eq!(
14524 atn.add_state(AtnStateKind::RuleStart, Some(0))
14525 .expect("state")
14526 .index(),
14527 0
14528 );
14529 assert_eq!(
14530 atn.add_state(AtnStateKind::RuleStop, Some(0))
14531 .expect("state")
14532 .index(),
14533 1
14534 );
14535 assert_eq!(
14536 atn.add_state(AtnStateKind::Basic, Some(0))
14537 .expect("state")
14538 .index(),
14539 2
14540 );
14541 atn.set_rule_to_start_state(vec![0])
14542 .expect("rule start states");
14543 atn.set_rule_to_stop_state(vec![1])
14544 .expect("rule stop states");
14545 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
14546 .expect("transition");
14547 atn.add_transition(
14548 2,
14549 ParserTransitionSpec::Atom {
14550 target: 1,
14551 label: TOKEN_EOF,
14552 },
14553 )
14554 .expect("transition");
14555 finish_atn(atn)
14556 }
14557
14558 #[test]
14559 fn parser_matches_token_and_reports_mismatch() {
14560 let source = Source {
14561 tokens: vec![
14562 TestToken::new(1).with_text("x"),
14563 TestToken::eof("parser-test", 1, 1, 1),
14564 ],
14565 index: 0,
14566 };
14567 let data = RecognizerData::new(
14568 "Mini.g4",
14569 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
14570 );
14571 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
14572 let matched = parser.match_token(1).expect("token 1 should match");
14573 assert_eq!(parser.node(matched).text(), "x");
14574 assert!(parser.match_token(1).is_err());
14575 }
14576
14577 #[test]
14578 fn parser_matches_token_sets() {
14579 let mut parser = mini_parser(vec![
14580 TestToken::new(1).with_text("x"),
14581 TestToken::eof("parser-test", 1, 1, 1),
14582 ]);
14583
14584 let matched = parser
14585 .match_set(&[(1, 1), (3, 4)])
14586 .expect("token set should match");
14587 assert_eq!(parser.node(matched).text(), "x");
14588 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
14589 }
14590
14591 #[test]
14592 fn generated_rule_api_tracks_state_and_precedence() {
14593 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14594
14595 let context = parser.enter_rule(7, 2);
14596 assert_eq!(context.rule_index(), 2);
14597 assert_eq!(parser.state(), 7);
14598 assert_eq!(
14599 parser.rule_context_stack,
14600 vec![RuleContextFrame {
14601 rule_index: 2,
14602 invoking_state: 7
14603 }]
14604 );
14605
14606 let recursive = parser.enter_recursion_rule(11, 3, 4);
14607 assert_eq!(recursive.rule_index(), 3);
14608 assert!(parser.precpred(4));
14609 assert!(parser.precpred(5));
14610 assert!(!parser.precpred(3));
14611
14612 let next = parser.push_new_recursion_context(13, 3);
14613 assert_eq!(next.invoking_state(), 13);
14614 parser.unroll_recursion_context();
14615 assert_eq!(parser.precedence_stack, vec![0]);
14616 assert_eq!(
14617 parser.rule_context_stack,
14618 vec![RuleContextFrame {
14619 rule_index: 2,
14620 invoking_state: 7
14621 }]
14622 );
14623
14624 parser.exit_rule();
14625 assert!(parser.rule_context_stack.is_empty());
14626 }
14627
14628 #[test]
14629 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
14630 let mut parser = mini_parser(vec![
14631 TestToken::new(1).with_text("x"),
14632 TestToken::eof("parser-test", 1, 1, 1),
14633 ]);
14634 let matched = parser.match_token(1).expect("token should match");
14635 assert_eq!(parser.node(matched).text(), "x");
14636 parser.record_generated_syntax_error();
14637 parser.set_int_member(7, 11);
14638 parser.set_build_parse_trees(false);
14639 parser.set_report_diagnostic_errors(true);
14640 parser.set_prediction_mode(PredictionMode::Sll);
14641 parser.set_bail_on_error(true);
14642 let _context = parser.enter_recursion_rule(9, 0, 4);
14643 parser.pending_invoking_states.push(5);
14644 parser.unknown_predicate_hits.push((0, 1));
14645 parser.unhandled_action_hits.push((0, 2));
14646
14647 parser.reset();
14648
14649 assert_eq!(parser.input.index(), 0);
14650 assert_eq!(parser.la(1), 1);
14651 assert_eq!(parser.state(), -1);
14652 assert_eq!(parser.number_of_syntax_errors(), 0);
14653 assert_eq!(parser.parse_tree_storage().node_count(), 0);
14654 assert!(parser.rule_context_stack.is_empty());
14655 assert!(parser.pending_invoking_states.is_empty());
14656 assert_eq!(parser.precedence_stack, [0]);
14657 assert!(parser.unknown_predicate_hits.is_empty());
14658 assert!(parser.unhandled_action_hits.is_empty());
14659 assert_eq!(parser.int_member(7), Some(11));
14660 assert!(!parser.build_parse_trees());
14661 assert!(parser.report_diagnostic_errors());
14662 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
14663 assert!(parser.bail_on_error());
14664 }
14665
14666 #[test]
14667 fn set_token_stream_replaces_input_and_resets_parser() {
14668 let mut parser = mini_parser(vec![
14669 TestToken::new(1).with_text("old"),
14670 TestToken::eof("parser-test", 1, 1, 1),
14671 ]);
14672 parser.consume();
14673 parser.record_generated_syntax_error();
14674 let replacement = CommonTokenStream::new(Source {
14675 tokens: vec![
14676 TestToken::new(2).with_text("new"),
14677 TestToken::eof("parser-test", 1, 1, 1),
14678 ],
14679 index: 0,
14680 });
14681
14682 parser.set_token_stream(replacement);
14683
14684 assert_eq!(parser.input.index(), 0);
14685 assert_eq!(parser.la(1), 2);
14686 assert_eq!(parser.input.text_all(), "new");
14687 assert_eq!(parser.number_of_syntax_errors(), 0);
14688 }
14689
14690 #[test]
14691 fn active_invocation_states_exclude_the_root_frame() {
14692 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14693
14694 let _root = parser.enter_rule(0, 0);
14695 assert!(parser.active_invocation_states().is_empty());
14696
14697 let marker = parser.push_invoking_state(6);
14698 let _child = parser.enter_rule(2, 1);
14699 parser.discard_invoking_state(marker);
14700 assert_eq!(parser.active_invocation_states(), [6]);
14701
14702 let marker = parser.push_invoking_state(13);
14703 let _grandchild = parser.enter_rule(4, 2);
14704 parser.discard_invoking_state(marker);
14705 assert_eq!(parser.active_invocation_states(), [13, 6]);
14706
14707 parser.exit_rule();
14708 parser.exit_rule();
14709 parser.exit_rule();
14710 }
14711
14712 #[test]
14713 fn parser_predicates_support_token_adjacency() {
14714 let mut parser = mini_parser(vec![
14715 TestToken::new(1).with_text("=").with_span(0, 0),
14716 TestToken::new(1).with_text(">").with_span(1, 1),
14717 TestToken::eof("parser-test", 2, 1, 2),
14718 ]);
14719 parser.consume();
14720 parser.consume();
14721
14722 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
14723
14724 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
14725
14726 let mut parser = mini_parser(vec![
14727 TestToken::new(1).with_text("=").with_span(0, 0),
14728 TestToken::new(1)
14729 .with_text(" ")
14730 .with_channel(HIDDEN_CHANNEL)
14731 .with_span(1, 1),
14732 TestToken::new(1).with_text(">").with_span(2, 2),
14733 TestToken::eof("parser-test", 3, 1, 3),
14734 ]);
14735 parser.consume();
14736 parser.consume();
14737
14738 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
14739 }
14740
14741 #[test]
14742 fn parser_predicates_support_context_child_text_checks() {
14743 let mut parser = mini_parser(vec![
14744 TestToken::new(1).with_text("var"),
14745 TestToken::eof("parser-test", 1, 1, 1),
14746 ]);
14747 let mut context = ParserRuleContext::new(1, 0);
14748 let mut child_context = ParserRuleContext::new(2, 0);
14749 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
14750 parser.tree.add_child(&mut child_context, terminal);
14751 let child = parser.rule_node(child_context);
14752 parser.tree.add_child(&mut context, child);
14753 let predicates = [(
14754 1,
14755 0,
14756 ParserPredicate::ContextChildRuleTextNotEquals {
14757 rule_index: 2,
14758 text: "var",
14759 },
14760 )];
14761
14762 assert!(
14763 !parser.parser_semantic_predicate_matches_with_context_and_local(
14764 &predicates,
14765 1,
14766 0,
14767 &context,
14768 0,
14769 )
14770 );
14771 }
14772
14773 #[test]
14774 fn context_expected_symbols_walks_nullable_parent_contexts() {
14775 let atn = nested_nullable_context_atn();
14776 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14777 parser.rule_context_stack = vec![
14778 RuleContextFrame {
14779 rule_index: 0,
14780 invoking_state: 0,
14781 },
14782 RuleContextFrame {
14783 rule_index: 1,
14784 invoking_state: 1,
14785 },
14786 RuleContextFrame {
14787 rule_index: 2,
14788 invoking_state: 2,
14789 },
14790 ];
14791
14792 let expected = parser.context_expected_symbols(&atn);
14793
14794 assert!(expected.contains(&1));
14795 assert!(expected.contains(&TOKEN_EOF));
14796 }
14797
14798 #[test]
14799 fn prediction_context_return_states_track_rule_stack_changes() {
14800 let atn = nested_nullable_context_atn();
14801 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14802 parser.rule_context_stack = vec![
14803 RuleContextFrame {
14804 rule_index: 0,
14805 invoking_state: 0,
14806 },
14807 RuleContextFrame {
14808 rule_index: 1,
14809 invoking_state: 1,
14810 },
14811 RuleContextFrame {
14812 rule_index: 2,
14813 invoking_state: 2,
14814 },
14815 ];
14816
14817 let initial_version = parser.rule_context_version();
14818 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14819 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14820 assert_eq!(first, second);
14821 assert_eq!(parser.rule_context_version(), initial_version);
14822
14823 parser.exit_rule();
14824 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14825 assert_ne!(first, after_pop);
14826 assert_ne!(parser.rule_context_version(), initial_version);
14827 }
14828
14829 #[test]
14830 fn generated_match_token_recovers_missing_token_from_context_follow() {
14831 let atn = generated_match_recovery_atn();
14832 let data = RecognizerData::new(
14833 "Mini.g4",
14834 Vocabulary::new(
14835 [None, Some("'X'"), Some("'Y'")],
14836 [None, Some("X"), Some("Y")],
14837 [None::<&str>, None, None],
14838 ),
14839 );
14840 let mut parser = BaseParser::new(
14841 CommonTokenStream::new(Source {
14842 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
14843 index: 0,
14844 }),
14845 data,
14846 );
14847 parser.rule_context_stack = vec![
14848 RuleContextFrame {
14849 rule_index: 0,
14850 invoking_state: 0,
14851 },
14852 RuleContextFrame {
14853 rule_index: 1,
14854 invoking_state: 1,
14855 },
14856 ];
14857 assert_eq!(parser.number_of_syntax_errors(), 0);
14858
14859 let node = parser
14860 .match_token_recovering(2, 5, &atn)
14861 .expect("generated match should insert missing token");
14862
14863 assert_eq!(node.children().len(), 1);
14864 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
14865 assert_eq!(
14866 node.clone()
14867 .into_child_iter()
14868 .map(|child| parser.node(child).text())
14869 .collect::<Vec<_>>(),
14870 ["<missing 'Y'>"]
14871 );
14872 assert!(!node.consumed_eof());
14875 assert_eq!(parser.la(1), TOKEN_EOF);
14876 assert_eq!(parser.number_of_syntax_errors(), 1);
14877 assert_eq!(
14878 parser.generated_parser_diagnostics,
14879 [ParserDiagnostic {
14880 line: 1,
14881 column: 3,
14882 message: "missing 'Y' at '<EOF>'".to_owned(),
14883 }]
14884 );
14885 }
14886
14887 #[test]
14888 fn generated_match_token_counts_single_token_deletion_recovery() {
14889 let atn = generated_match_recovery_atn();
14890 let data = RecognizerData::new(
14891 "Mini.g4",
14892 Vocabulary::new(
14893 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
14894 [None, Some("X"), Some("Y"), Some("Z")],
14895 [None::<&str>, None, None, None],
14896 ),
14897 );
14898 let mut parser = BaseParser::new(
14899 CommonTokenStream::new(Source {
14900 tokens: vec![
14901 TestToken::new(3).with_text("z"),
14902 TestToken::new(2).with_text("y"),
14903 TestToken::eof("parser-test", 3, 1, 3),
14904 ],
14905 index: 0,
14906 }),
14907 data,
14908 );
14909
14910 let node = parser
14911 .match_token_recovering(2, 5, &atn)
14912 .expect("generated match should delete the extraneous token");
14913
14914 assert_eq!(node.children().len(), 2);
14915 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
14916 assert_eq!(parser.node(node.children()[0]).text(), "z");
14917 assert_eq!(parser.node(node.children()[1]).text(), "y");
14918 assert_eq!(
14919 node.into_child_iter()
14920 .map(|child| parser.node(child).text())
14921 .collect::<Vec<_>>(),
14922 ["z", "y"]
14923 );
14924 assert_eq!(parser.number_of_syntax_errors(), 1);
14925 }
14926
14927 #[test]
14928 fn generated_match_token_iterates_single_success_without_a_children_vec() {
14929 let atn = generated_match_recovery_atn();
14930 let data = RecognizerData::new(
14931 "Mini.g4",
14932 Vocabulary::new(
14933 [None, Some("'X'"), Some("'Y'")],
14934 [None, Some("X"), Some("Y")],
14935 [None::<&str>, None, None],
14936 ),
14937 );
14938 let mut parser = BaseParser::new(
14939 CommonTokenStream::new(Source {
14940 tokens: vec![
14941 TestToken::new(2).with_text("y"),
14942 TestToken::eof("parser-test", 1, 1, 1),
14943 ],
14944 index: 0,
14945 }),
14946 data,
14947 );
14948
14949 let node = parser
14950 .match_token_recovering(2, 5, &atn)
14951 .expect("generated match should consume the expected token");
14952
14953 assert_eq!(
14954 node.into_child_iter()
14955 .map(|child| parser.node(child).text())
14956 .collect::<Vec<_>>(),
14957 ["y"]
14958 );
14959 assert_eq!(parser.number_of_syntax_errors(), 0);
14960 }
14961
14962 #[test]
14963 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
14964 let atn = generated_match_recovery_atn();
14965 let data = RecognizerData::new(
14966 "Mini.g4",
14967 Vocabulary::new(
14968 [None, Some("'X'"), Some("'Y'")],
14969 [None, Some("X"), Some("Y")],
14970 [None::<&str>, None, None],
14971 ),
14972 );
14973 let mut parser = BaseParser::new(
14974 CommonTokenStream::new(Source {
14975 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
14976 index: 0,
14977 }),
14978 data,
14979 );
14980 parser.rule_context_stack = vec![
14981 RuleContextFrame {
14982 rule_index: 0,
14983 invoking_state: 0,
14984 },
14985 RuleContextFrame {
14986 rule_index: 1,
14987 invoking_state: 1,
14988 },
14989 ];
14990 let marker = parser.generated_diagnostics_checkpoint();
14991
14992 let _ = parser
14993 .match_token_recovering(2, 5, &atn)
14994 .expect("generated match should insert missing token");
14995 assert_eq!(parser.number_of_syntax_errors(), 1);
14996
14997 parser.restore_generated_diagnostics(marker);
14998
14999 assert_eq!(parser.number_of_syntax_errors(), 0);
15000 assert!(parser.generated_parser_diagnostics.is_empty());
15001 }
15002
15003 #[test]
15004 fn generated_prediction_diagnostics_use_adaptive_context() {
15005 let atn = two_alt_decision_atn();
15006 let data = RecognizerData::new(
15007 "Mini.g4",
15008 Vocabulary::new(
15009 [None, Some("'x'"), Some("'y'")],
15010 [None, Some("X"), Some("Y")],
15011 [None::<&str>, None, None],
15012 ),
15013 )
15014 .with_rule_names(["s"]);
15015 let mut parser = BaseParser::new(
15016 CommonTokenStream::new(Source {
15017 tokens: vec![
15018 TestToken::new(1)
15019 .with_text("x")
15020 .with_position(1, 0)
15021 .with_span(0, 0),
15022 TestToken::new(2)
15023 .with_text("y")
15024 .with_position(1, 2)
15025 .with_span(1, 1),
15026 TestToken::eof("parser-test", 2, 1, 3),
15027 ],
15028 index: 0,
15029 }),
15030 data,
15031 );
15032 parser.set_report_diagnostic_errors(true);
15033
15034 parser.record_generated_prediction_diagnostic(
15035 &atn,
15036 1,
15037 &ParserAtnPrediction {
15038 alt: 1,
15039 requires_full_context: true,
15040 has_semantic_context: false,
15041 diagnostic: Some(ParserAtnPredictionDiagnostic {
15042 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
15043 start_index: 0,
15044 sll_stop_index: 1,
15045 ll_stop_index: 0,
15046 conflicting_alts: vec![1, 2],
15047 exact: false,
15048 }),
15049 },
15050 );
15051 parser.record_generated_prediction_diagnostic(
15056 &atn,
15057 1,
15058 &ParserAtnPrediction {
15059 alt: 1,
15060 requires_full_context: true,
15061 has_semantic_context: false,
15062 diagnostic: Some(ParserAtnPredictionDiagnostic {
15063 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
15064 start_index: 0,
15065 sll_stop_index: 1,
15066 ll_stop_index: 1,
15067 conflicting_alts: vec![1, 2],
15068 exact: false,
15069 }),
15070 },
15071 );
15072
15073 assert_eq!(
15074 parser.generated_parser_diagnostics,
15075 [
15076 ParserDiagnostic {
15077 line: 1,
15078 column: 2,
15079 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
15080 },
15081 ParserDiagnostic {
15082 line: 1,
15083 column: 0,
15084 message: "reportContextSensitivity d=0 (s), input='x'".to_owned(),
15085 },
15086 ParserDiagnostic {
15087 line: 1,
15088 column: 2,
15089 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
15090 },
15091 ]
15092 );
15093 }
15094
15095 #[test]
15096 fn generated_match_not_set_recovers_empty_complement_at_eof() {
15097 let atn = complement_set_atn();
15098 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15099 parser.rule_context_stack = vec![RuleContextFrame {
15100 rule_index: 0,
15101 invoking_state: 0,
15102 }];
15103
15104 let node = parser
15105 .match_not_token_set_recovering(
15106 atn.token_set(0).expect("excluded token set"),
15107 1,
15108 1,
15109 1,
15110 &atn,
15111 )
15112 .expect("empty complement should recover at EOF");
15113
15114 assert_eq!(node.children().len(), 1);
15115 assert!(!node.consumed_eof());
15118 assert_eq!(parser.la(1), TOKEN_EOF);
15119 assert_eq!(
15120 parser.generated_parser_diagnostics,
15121 [ParserDiagnostic {
15122 line: 1,
15123 column: 1,
15124 message: "missing {} at '<EOF>'".to_owned(),
15125 }]
15126 );
15127 }
15128
15129 #[test]
15130 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
15131 let atn = wildcard_then_eof_atn();
15137 let data = RecognizerData::new(
15138 "Mini.g4",
15139 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
15140 );
15141 let mut parser = BaseParser::new(
15142 CommonTokenStream::new(Source {
15143 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
15144 index: 0,
15145 }),
15146 data,
15147 );
15148 parser.rule_context_stack = vec![RuleContextFrame {
15149 rule_index: 0,
15150 invoking_state: 0,
15151 }];
15152
15153 let node = parser
15154 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
15155 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
15156
15157 assert_eq!(node.children().len(), 1);
15159 assert!(!node.consumed_eof());
15160 assert!(
15161 parser
15162 .node(node.children()[0])
15163 .text()
15164 .starts_with("<missing")
15165 );
15166 assert_eq!(parser.la(1), TOKEN_EOF);
15167 assert_eq!(
15168 parser.generated_parser_diagnostics,
15169 [ParserDiagnostic {
15170 line: 1,
15171 column: 1,
15172 message: "missing 'x' at '<EOF>'".to_owned(),
15173 }]
15174 );
15175 }
15176
15177 #[test]
15178 fn generated_rule_recovery_consumes_to_parent_follow() {
15179 let atn = generated_match_recovery_atn();
15180 let data = RecognizerData::new(
15181 "Mini.g4",
15182 Vocabulary::new(
15183 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
15184 [None, Some("X"), Some("Y"), Some("Z")],
15185 [None::<&str>, None, None, None],
15186 ),
15187 );
15188 let mut parser = BaseParser::new(
15189 CommonTokenStream::new(Source {
15190 tokens: vec![
15191 TestToken::new(3).with_text("z"),
15192 TestToken::eof("parser-test", 1, 1, 1),
15193 ],
15194 index: 0,
15195 }),
15196 data,
15197 );
15198 let _parent = parser.enter_rule(0, 0);
15199 let marker = parser.push_invoking_state(1);
15200 let mut child = parser.enter_rule(4, 1);
15201 parser.discard_invoking_state(marker);
15202
15203 parser.recover_generated_rule(
15204 &mut child,
15205 &atn,
15206 AntlrError::ParserError {
15207 line: 1,
15208 column: 0,
15209 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
15210 },
15211 );
15212 let tree = parser.finish_rule(child, false);
15213
15214 assert_eq!(parser.la(1), TOKEN_EOF);
15215 assert_eq!(
15216 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
15217 "(a z)"
15218 );
15219 assert_eq!(parser.number_of_syntax_errors(), 1);
15220 assert_eq!(
15221 parser.generated_parser_diagnostics,
15222 [ParserDiagnostic {
15223 line: 1,
15224 column: 0,
15225 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
15226 }]
15227 );
15228 parser.exit_rule();
15229 }
15230
15231 #[test]
15232 fn greedy_ll1_alt_handles_nullable_loop_exit() {
15233 let mut body_symbols = TokenBitSet::default();
15234 body_symbols.insert(1);
15235 let entry = DecisionLookahead {
15236 transitions: vec![
15237 TransitionLookSet {
15238 symbols: body_symbols,
15239 nullable: false,
15240 },
15241 TransitionLookSet {
15242 symbols: TokenBitSet::default(),
15243 nullable: true,
15244 },
15245 ],
15246 };
15247
15248 assert_eq!(ll1_unique_alt(&entry, 2), None);
15249 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
15250 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
15251 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
15252 }
15253
15254 #[test]
15255 fn ordinary_repetition_builds_tree_in_input_order() {
15256 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15257 let mut parser = mini_parser(repeated_x_tokens(3));
15258 let tree = parser
15259 .parse_atn_rule(&atn, 0)
15260 .expect("ordinary repetition should parse");
15261
15262 let root = parser
15263 .node(tree)
15264 .as_rule()
15265 .expect("entry result should be a rule");
15266 let body_rules = root.child_rules(1).collect::<Vec<_>>();
15267 assert_eq!(root.text(), "xxx<EOF>");
15268 assert_eq!(body_rules.len(), 3);
15269 assert_eq!(
15270 body_rules
15271 .iter()
15272 .map(|rule| rule.start_id().expect("body start").index())
15273 .collect::<Vec<_>>(),
15274 [0, 1, 2]
15275 );
15276 assert_eq!(
15277 body_rules
15278 .iter()
15279 .map(|rule| rule.stop_id().expect("body stop").index())
15280 .collect::<Vec<_>>(),
15281 [0, 1, 2]
15282 );
15283 assert_eq!(parser.number_of_syntax_errors(), 0);
15284 }
15285 }
15286
15287 #[test]
15288 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
15289 const DEPTH: usize = 20_000;
15290
15291 std::thread::Builder::new()
15292 .name("deferred-rule-materialization".to_owned())
15293 .stack_size(256 * 1024)
15294 .spawn(|| {
15295 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
15296 let mut root = FastDeferredNodeId::EMPTY;
15297 for depth in 0..DEPTH {
15298 root = parser
15299 .recognition_arena
15300 .deferred_rule_node(FastDeferredRule {
15301 rule_index: u32::try_from(depth).expect("depth fits in u32"),
15302 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
15303 start_index: 0,
15304 stop_index: None,
15305 deferred_children: root,
15306 children: NodeSeqId::EMPTY,
15307 });
15308 }
15309
15310 let mut children = parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
15311 for expected_rule in (0..DEPTH).rev() {
15312 let mut nodes = parser.recognition_arena.iter(children);
15313 let node = nodes.next().expect("nested rule node");
15314 assert!(nodes.next().is_none(), "each rule has one child");
15315 let ArenaRecognizedNode::Rule {
15316 rule_index,
15317 children: nested,
15318 ..
15319 } = parser.recognition_arena.node(node)
15320 else {
15321 panic!("expected nested rule");
15322 };
15323 assert_eq!(rule_index as usize, expected_rule);
15324 children = nested;
15325 }
15326 assert!(children.is_empty());
15327 })
15328 .expect("small-stack thread should start")
15329 .join()
15330 .expect("deferred rules should materialize without recursion");
15331 }
15332
15333 #[test]
15334 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
15335 const REPETITIONS: usize = 64;
15336
15337 let atn = ambiguous_ordinary_star_loop_atn();
15338 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15339 let tree = parser
15340 .parse_atn_rule(&atn, 0)
15341 .expect("ambiguous ordinary repetition should parse");
15342
15343 let root = parser
15344 .node(tree)
15345 .as_rule()
15346 .expect("entry result should be a rule");
15347 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
15348 assert_eq!(parser.input.index(), REPETITIONS);
15349 assert!(
15350 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
15351 "equivalent segmentations should keep deferred storage linear"
15352 );
15353 assert_eq!(parser.number_of_syntax_errors(), 0);
15354 }
15355
15356 #[test]
15357 fn long_ordinary_repetition_does_not_consume_native_stack() {
15358 const REPETITIONS: usize = 20_000;
15359
15360 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15361 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15362 parser.set_build_parse_trees(false);
15363 parser
15364 .parse_atn_rule(&atn, 0)
15365 .expect("long ordinary repetition should parse");
15366
15367 assert_eq!(parser.input.index(), REPETITIONS);
15368 assert_eq!(parser.number_of_syntax_errors(), 0);
15369 }
15370 }
15371
15372 #[test]
15373 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
15374 const REPETITIONS: usize = 2_000;
15375 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
15376
15377 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15378 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15379 let tree = parser
15380 .parse_atn_rule(&atn, 0)
15381 .expect("long rule repetition should parse");
15382
15383 let root = parser
15384 .node(tree)
15385 .as_rule()
15386 .expect("entry result should be a rule");
15387 assert_eq!(root.text(), expected_text);
15388 assert_eq!(root.child_rules(1).count(), REPETITIONS);
15389 let first_body = root.child_rules(1).next().expect("first body rule");
15390 let last_body = root.child_rules(1).next_back().expect("last body rule");
15391 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
15392 assert_eq!(
15393 last_body.stop_id().expect("last body stop").index(),
15394 REPETITIONS - 1
15395 );
15396
15397 let stats = parser.recognition_arena_stats();
15398 assert_eq!(
15399 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
15400 (REPETITIONS, REPETITIONS, 0)
15401 );
15402 assert_eq!(
15403 (stats.total_links, stats.live_links, stats.dead_links),
15404 (REPETITIONS, REPETITIONS, 0)
15405 );
15406 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
15407 assert_eq!(
15408 parser.recognition_arena.deferred_nodes.len(),
15409 REPETITIONS * 2 - 1
15410 );
15411 assert_eq!(parser.number_of_syntax_errors(), 0);
15412 }
15413 }
15414
15415 #[test]
15416 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
15417 let key = |state_number| FastRecognizeKey {
15418 state_number,
15419 stop_state: 10,
15420 index: state_number,
15421 rule_start_index: 0,
15422 decision_start_index: None,
15423 precedence: 0,
15424 recovery_symbols_id: 0,
15425 recovery_state: None,
15426 };
15427
15428 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15429 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
15430 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
15431 }
15432 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
15433 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
15434
15435 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15436 let repeated = key(1);
15437 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
15438 assert!(promote.clean_memo_enabled_for_key(&repeated));
15439 }
15440 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
15441
15442 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
15443 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
15444 }
15445 assert!(sparse.clean_memo_enabled_for_key(&repeated));
15446 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
15447 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
15448 assert!(sparse.clean_memo_enabled_for_key(&repeated));
15449 }
15450 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
15451 }
15452
15453 #[test]
15454 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
15455 assert_eq!(
15456 fast_recognize_memo_capacity(0),
15457 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
15458 );
15459 assert_eq!(
15460 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
15461 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
15462 );
15463 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
15464 assert_eq!(
15465 fast_recognize_memo_capacity(usize::MAX),
15466 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
15467 );
15468 }
15469
15470 #[test]
15471 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
15472 let mut scratch = FastRecognizeTopScratch::default();
15473 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
15474 let retained_capacity = scratch.memo.capacity();
15475 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
15476 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15477
15478 let larger_capacity = retained_capacity + 1;
15479 scratch.prepare(larger_capacity);
15480 let grown_capacity = scratch.memo.capacity();
15481 assert!(grown_capacity >= larger_capacity);
15482 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15483
15484 scratch.memo.insert(
15485 FastRecognizeKey {
15486 state_number: 0,
15487 stop_state: 0,
15488 index: 0,
15489 rule_start_index: 0,
15490 decision_start_index: None,
15491 precedence: 0,
15492 recovery_symbols_id: 0,
15493 recovery_state: None,
15494 },
15495 Rc::from([FastRecognizeOutcome {
15496 index: 0,
15497 consumed_eof: false,
15498 diagnostics: DiagnosticSeqId::EMPTY,
15499 deferred_nodes: FastDeferredNodeId::EMPTY,
15500 nodes: NodeSeqId::EMPTY,
15501 }]),
15502 );
15503 scratch.release_oversized_memo();
15504 assert!(scratch.memo.is_empty());
15505 assert_eq!(scratch.memo.capacity(), grown_capacity);
15506
15507 scratch
15508 .memo
15509 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
15510 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15511
15512 scratch.release_oversized_memo();
15513 assert!(scratch.memo.is_empty());
15514 assert_eq!(scratch.memo.capacity(), 0);
15515 }
15516
15517 #[test]
15518 fn clean_empty_multi_alt_outcomes_are_memoized() {
15519 let mut atn = ParserAtnBuilder::new(2);
15520 assert_eq!(
15521 atn.add_state(AtnStateKind::RuleStart, Some(0))
15522 .expect("state")
15523 .index(),
15524 0
15525 );
15526 assert_eq!(
15527 atn.add_state(AtnStateKind::BlockStart, Some(0))
15528 .expect("state")
15529 .index(),
15530 1
15531 );
15532 assert_eq!(
15533 atn.add_state(AtnStateKind::RuleStop, Some(0))
15534 .expect("state")
15535 .index(),
15536 2
15537 );
15538 atn.set_rule_to_start_state(vec![0])
15539 .expect("rule start states");
15540 atn.set_rule_to_stop_state(vec![2])
15541 .expect("rule stop states");
15542 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15543 .expect("transition");
15544 atn.add_transition(
15545 1,
15546 ParserTransitionSpec::Atom {
15547 target: 2,
15548 label: 1,
15549 },
15550 )
15551 .expect("transition");
15552 atn.add_transition(
15553 1,
15554 ParserTransitionSpec::Atom {
15555 target: 2,
15556 label: 2,
15557 },
15558 )
15559 .expect("transition");
15560 let atn = finish_atn(atn);
15561
15562 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
15563 parser.fast_recovery_enabled = false;
15564 let mut visiting = FxHashSet::default();
15565 let mut memo = FxHashMap::default();
15566 let mut expected = ExpectedTokens::default();
15567 let outcomes = parser.recognize_state_fast(
15568 &atn,
15569 FastRecognizeRequest {
15570 state_number: 1,
15571 stop_state: 2,
15572 index: 0,
15573 rule_start_index: 0,
15574 decision_start_index: None,
15575 precedence: 0,
15576 depth: 0,
15577 recovery_symbols: parser.empty_recovery_symbols(),
15578 recovery_state: None,
15579 },
15580 FastRecognizeScratch {
15581 predicate_context: None,
15582 visiting: &mut visiting,
15583 memo: &mut memo,
15584 expected: &mut expected,
15585 },
15586 );
15587
15588 assert!(outcomes.is_empty());
15589 assert_eq!(memo.len(), 1);
15590 assert!(memo.values().next().expect("memo entry").is_empty());
15591
15592 parser.clean_memo_mode = CleanMemoMode::Sparse;
15593 visiting.clear();
15594 memo.clear();
15595 expected = ExpectedTokens::default();
15596 let sparse_outcomes = parser.recognize_state_fast(
15597 &atn,
15598 FastRecognizeRequest {
15599 state_number: 1,
15600 stop_state: 2,
15601 index: 0,
15602 rule_start_index: 0,
15603 decision_start_index: None,
15604 precedence: 0,
15605 depth: 0,
15606 recovery_symbols: parser.empty_recovery_symbols(),
15607 recovery_state: None,
15608 },
15609 FastRecognizeScratch {
15610 predicate_context: None,
15611 visiting: &mut visiting,
15612 memo: &mut memo,
15613 expected: &mut expected,
15614 },
15615 );
15616
15617 assert!(sparse_outcomes.is_empty());
15618 assert!(memo.is_empty());
15619 }
15620
15621 #[test]
15622 fn wildcard_matches_non_eof_only() {
15623 let mut parser = mini_parser(vec![
15624 TestToken::new(1).with_text("x"),
15625 TestToken::eof("parser-test", 1, 1, 1),
15626 ]);
15627 let matched = parser.match_wildcard().expect("wildcard");
15628 assert_eq!(parser.node(matched).text(), "x");
15629 assert!(parser.match_wildcard().is_err());
15630 }
15631
15632 #[test]
15633 fn add_parse_child_records_match_even_without_tree_building() {
15634 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15639 let token = TestToken::new(1).with_text("x");
15640
15641 parser.set_build_parse_trees(false);
15642 let mut ctx = ParserRuleContext::new(0, 0);
15643 assert!(!ctx.has_matched_child());
15644 let child = parser.terminal_tree(token.id);
15645 parser.add_parse_child(&mut ctx, child);
15646 assert_eq!(ctx.child_count(), 0);
15648 assert_eq!(parser.parse_tree_storage().node_count(), 0);
15649 assert!(ctx.has_matched_child());
15651
15652 parser.set_build_parse_trees(true);
15654 let mut ctx = ParserRuleContext::new(0, 0);
15655 let child = parser.terminal_tree(token.id);
15656 parser.add_parse_child(&mut ctx, child);
15657 assert_eq!(ctx.child_count(), 1);
15658 assert!(ctx.has_matched_child());
15659 }
15660
15661 #[test]
15662 fn disabled_tree_building_does_not_grow_flat_storage() {
15663 let mut parser = mini_parser(vec![
15664 TestToken::new(1).with_text("x"),
15665 TestToken::new(1).with_text("y"),
15666 TestToken::eof("parser-test", 2, 1, 2),
15667 ]);
15668 parser.set_build_parse_trees(false);
15669 let mut context = ParserRuleContext::new(0, -1);
15670
15671 for _ in 0..2 {
15672 let child = parser.match_token(1).expect("token should match");
15673 parser.add_parse_child(&mut context, child);
15674 }
15675 let current = parser.input.lt_id(1).expect("EOF token");
15676 let error = parser.error_tree(current);
15677 parser.add_parse_child(&mut context, error);
15678 let root = parser.rule_node(context);
15679
15680 assert_eq!(
15681 parser.parse_tree_storage().stats(),
15682 ParseTreeStats::default()
15683 );
15684 assert!(
15685 parser
15686 .parse_tree_storage()
15687 .node(parser.token_store(), root)
15688 .is_none(),
15689 "the no-tree sentinel must not resolve to stored data"
15690 );
15691 }
15692
15693 #[test]
15694 fn disabled_tree_building_skips_recognition_rule_node_storage() {
15695 let atn = ordinary_star_loop_atn();
15696 let mut parser = mini_parser(repeated_x_tokens(3));
15697 parser.set_build_parse_trees(false);
15698
15699 parser
15700 .parse_atn_rule(&atn, 0)
15701 .expect("ordinary repetition should parse without a tree");
15702
15703 assert_eq!(parser.input.index(), 3);
15704 assert!(parser.recognition_arena.nodes.is_empty());
15705 assert!(parser.recognition_arena.seq_links.is_empty());
15706 assert!(parser.recognition_arena.deferred_nodes.is_empty());
15707 assert!(parser.recognition_arena.deferred_rules.is_empty());
15708 assert!(!parser.fast_token_nodes_enabled);
15709 assert!(parser.fast_recognize_scratch.memo.is_empty());
15710 }
15711
15712 #[test]
15713 fn parser_interprets_simple_atn_rule() {
15714 let atn = token_then_eof_atn();
15715 let mut parser = mini_parser(vec![
15716 TestToken::new(1).with_text("x"),
15717 TestToken::eof("parser-test", 1, 1, 1),
15718 ]);
15719
15720 let tree = parser
15721 .parse_atn_rule(&atn, 0)
15722 .expect("artificial parser rule should parse");
15723 assert_eq!(parser.node(tree).text(), "x<EOF>");
15724 assert_eq!(parser.number_of_syntax_errors(), 0);
15725 assert_eq!(
15726 parser
15727 .node(tree)
15728 .first_rule_stop(0)
15729 .expect("rule should stop at EOF")
15730 .token_type(),
15731 TOKEN_EOF
15732 );
15733
15734 let mut parser = mini_parser(vec![
15735 TestToken::new(1).with_text("x"),
15736 TestToken::eof("parser-test", 1, 1, 1),
15737 ]);
15738 let (tree, actions) = parser
15739 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15740 .expect("runtime-option parser rule should parse");
15741 assert!(actions.is_empty());
15742 assert_eq!(
15743 parser
15744 .node(tree)
15745 .first_rule_stop(0)
15746 .expect("rule should stop at EOF")
15747 .token_type(),
15748 TOKEN_EOF
15749 );
15750 }
15751
15752 #[test]
15753 fn runtime_options_default_ignores_noop_action_transitions() {
15754 let atn = noop_action_then_token_then_eof_atn();
15755 let mut parser = mini_parser(vec![
15756 TestToken::new(1).with_text("x"),
15757 TestToken::eof("parser-test", 1, 1, 1),
15758 ]);
15759
15760 let (tree, actions) = parser
15761 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15762 .expect("no-op parser action should not force action replay");
15763
15764 assert_eq!(parser.node(tree).text(), "x<EOF>");
15765 assert!(
15766 actions.is_empty(),
15767 "action_index=None transitions are ANTLR metadata, not replay actions"
15768 );
15769 assert_eq!(parser.number_of_syntax_errors(), 0);
15770 }
15771
15772 #[test]
15773 fn parser_exposes_buffered_token_stream_after_parse() {
15774 let atn = token_then_eof_atn();
15775 let mut parser = mini_parser(vec![
15776 TestToken::new(1).with_text("x"),
15777 TestToken::eof("parser-test", 1, 1, 1),
15778 ]);
15779
15780 let tree = parser
15781 .parse_atn_rule(&atn, 0)
15782 .expect("artificial parser rule should parse");
15783 assert_eq!(parser.node(tree).text(), "x<EOF>");
15784
15785 let stream = parser.token_stream();
15786 let source_index_after_parse = stream.token_source().index;
15787 let buffered = stream.tokens().collect::<Vec<_>>();
15788 assert_eq!(buffered.len(), 2);
15789 assert_eq!(buffered[0].text(), "x");
15790 assert_eq!(buffered[0].token_id().index(), 0);
15791 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
15792 assert_eq!(stream.token_source().index, source_index_after_parse);
15793 drop(buffered);
15794
15795 let stream = parser.into_token_stream();
15796 assert_eq!(stream.token_source().index, source_index_after_parse);
15797 assert_eq!(stream.tokens().next().expect("first token").text(), "x");
15798 assert_eq!(
15799 stream.tokens().nth(1).expect("EOF token").token_type(),
15800 TOKEN_EOF
15801 );
15802 }
15803
15804 #[test]
15805 fn parser_syntax_error_count_tracks_interpreted_recovery() {
15806 let atn = token_then_eof_atn();
15807 let mut parser = mini_parser(vec![
15808 TestToken::new(1).with_text("x"),
15809 TestToken::new(2).with_text("y"),
15810 TestToken::eof("parser-test", 2, 1, 2),
15811 ]);
15812
15813 let tree = parser
15814 .parse_atn_rule(&atn, 0)
15815 .expect("invalid token should recover into an error node");
15816
15817 assert_eq!(parser.number_of_syntax_errors(), 1);
15818 assert_eq!(
15819 parser
15820 .node(tree)
15821 .first_error_token()
15822 .expect("recovery should embed an error token")
15823 .text(),
15824 "y"
15825 );
15826 }
15827
15828 #[test]
15829 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
15830 let atn = token_then_eof_atn();
15831 let mut parser = mini_parser(vec![
15832 TestToken::new(2).with_text("y"),
15833 TestToken::eof("parser-test", 1, 1, 1),
15834 ]);
15835
15836 let error = parser
15837 .parse_atn_rule(&atn, 0)
15838 .expect_err("start-rule mismatch should remain a parser error");
15839
15840 assert_eq!(parser.number_of_syntax_errors(), 1);
15841 assert!(matches!(error, AntlrError::ParserError { .. }));
15842 }
15843
15844 #[test]
15845 fn adaptive_direct_rule_uses_simulator_decision() {
15846 let atn = two_alt_decision_atn();
15847 let mut simulator = ParserAtnSimulator::new(&atn);
15848 let mut parser = mini_parser(vec![
15849 TestToken::new(2).with_text("y"),
15850 TestToken::eof("parser-test", 1, 1, 1),
15851 ]);
15852
15853 let tree = parser
15854 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
15855 .expect("direct adaptive rule should parse");
15856
15857 assert_eq!(parser.node(tree).text(), "y");
15858 assert_eq!(parser.input.index(), 1);
15859 }
15860
15861 #[test]
15862 fn adaptive_direct_rule_restores_input_on_fallback() {
15863 let atn = predicate_after_token_atn();
15864 let mut simulator = ParserAtnSimulator::new(&atn);
15865 let mut parser = mini_parser(vec![
15866 TestToken::new(1).with_text("x"),
15867 TestToken::new(2).with_text("y"),
15868 TestToken::eof("parser-test", 2, 1, 2),
15869 ]);
15870
15871 let tree = parser
15872 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
15873 .expect("fallback recognizer should parse");
15874
15875 assert_eq!(parser.node(tree).text(), "xy");
15876 assert_eq!(parser.input.index(), 2);
15877 let stats = parser.parse_tree_storage().stats();
15878 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
15879 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
15880 assert_eq!(stats.scratch_links, 0);
15881 }
15882
15883 #[test]
15884 fn unknown_predicate_policy_defaults_to_assume_true() {
15885 let atn = predicate_after_token_atn();
15886 let mut parser = mini_parser(vec![
15887 TestToken::new(1).with_text("x"),
15888 TestToken::new(2).with_text("y"),
15889 TestToken::eof("parser-test", 2, 1, 2),
15890 ]);
15891
15892 let (tree, _) = parser
15893 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15894 .expect("unknown predicate should pass under the default policy");
15895
15896 assert_eq!(parser.node(tree).text(), "xy");
15897 assert_eq!(parser.number_of_syntax_errors(), 0);
15898 }
15899
15900 #[test]
15901 fn predicate_gated_same_lookahead_uses_viable_alternative() {
15902 let atn = predicate_gated_same_lookahead_atn([0, 1]);
15903 let mut parser = mini_parser(vec![
15904 TestToken::new(1).with_text("x"),
15905 TestToken::eof("parser-test", 1, 1, 1),
15906 ]);
15907
15908 let (tree, _) = parser
15909 .parse_atn_rule_with_runtime_options(
15910 &atn,
15911 0,
15912 ParserRuntimeOptions {
15913 predicates: &[
15914 (0, 0, ParserPredicate::False),
15915 (0, 1, ParserPredicate::True),
15916 ],
15917 ..ParserRuntimeOptions::default()
15918 },
15919 )
15920 .expect("the second predicate-gated alternative should match");
15921
15922 assert_eq!(parser.node(tree).text(), "x<EOF>");
15923 assert_eq!(parser.number_of_syntax_errors(), 0);
15924 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
15925 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
15926 }
15927
15928 #[test]
15929 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
15930 let atn = token_then_eof_atn();
15934 let mut parser = mini_parser(vec![
15935 TestToken::new(1).with_text("x"),
15936 TestToken::eof("parser-test", 1, 1, 1),
15937 ]);
15938
15939 parser.unknown_predicate_hits.push((7, 3));
15941
15942 parser
15944 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15945 .expect("child rule parses");
15946
15947 let error = parser
15949 .take_unknown_semantic_error()
15950 .expect("parent's recorded coordinate must survive the nested interpreted parse");
15951 let AntlrError::Unsupported(message) = error else {
15952 panic!("expected AntlrError::Unsupported, got {error:?}");
15953 };
15954 assert!(message.contains("pred_index=3"), "message: {message}");
15955 }
15956
15957 #[test]
15958 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
15959 let atn = predicate_after_token_atn();
15960 let mut parser = mini_parser(vec![
15961 TestToken::new(1).with_text("x"),
15962 TestToken::new(2).with_text("y"),
15963 TestToken::eof("parser-test", 2, 1, 2),
15964 ]);
15965
15966 let result = parser.parse_atn_rule_with_runtime_options(
15967 &atn,
15968 0,
15969 ParserRuntimeOptions {
15970 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
15971 ..ParserRuntimeOptions::default()
15972 },
15973 );
15974
15975 assert!(
15976 result.is_err(),
15977 "the only path is predicate-guarded, so assume-false must fail the parse"
15978 );
15979 }
15980
15981 #[test]
15982 fn predicate_failure_message_keeps_semantic_recovery_path() {
15983 let atn = predicate_after_token_atn();
15984 let mut parser = mini_parser(vec![
15985 TestToken::new(1).with_text("x"),
15986 TestToken::new(2).with_text("y"),
15987 TestToken::eof("parser-test", 2, 1, 2),
15988 ]);
15989
15990 let (tree, _) = parser
15991 .parse_atn_rule_with_runtime_options(
15992 &atn,
15993 0,
15994 ParserRuntimeOptions {
15995 predicates: &[(
15996 0,
15997 0,
15998 ParserPredicate::FalseWithMessage {
15999 message: "predicate rejected input",
16000 },
16001 )],
16002 ..ParserRuntimeOptions::default()
16003 },
16004 )
16005 .expect("failure-message predicates recover through the semantic interpreter");
16006
16007 assert_eq!(parser.node(tree).text(), "xy");
16008 assert_eq!(parser.number_of_syntax_errors(), 1);
16009 assert!(
16010 parser.fast_predicate_cache.is_empty(),
16011 "failure-message predicates need the semantic interpreter's recovery outcome"
16012 );
16013 }
16014
16015 #[test]
16016 fn unknown_predicate_policy_error_names_the_coordinate() {
16017 let atn = predicate_after_token_atn();
16018 let mut parser = mini_parser(vec![
16019 TestToken::new(1).with_text("x"),
16020 TestToken::new(2).with_text("y"),
16021 TestToken::eof("parser-test", 2, 1, 2),
16022 ]);
16023
16024 let error = parser
16025 .parse_atn_rule_with_runtime_options(
16026 &atn,
16027 0,
16028 ParserRuntimeOptions {
16029 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16030 ..ParserRuntimeOptions::default()
16031 },
16032 )
16033 .expect_err("evaluating an unknown predicate under Error policy must fail");
16034
16035 let AntlrError::Unsupported(message) = error else {
16036 panic!("expected AntlrError::Unsupported, got {error:?}");
16037 };
16038 assert!(
16039 message.contains("unsupported semantic predicate"),
16040 "message should name the failure class: {message}"
16041 );
16042 assert!(
16043 message.contains("pred_index=0"),
16044 "message should carry the coordinate: {message}"
16045 );
16046 }
16047
16048 #[test]
16049 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
16050 let atn = predicate_after_token_atn();
16056 let mut parser = mini_parser(vec![
16057 TestToken::new(1).with_text("x"),
16058 TestToken::new(2).with_text("y"),
16059 TestToken::eof("parser-test", 2, 1, 2),
16060 ]);
16061
16062 parser
16063 .parse_atn_rule_with_runtime_options(
16064 &atn,
16065 0,
16066 ParserRuntimeOptions {
16067 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16068 ..ParserRuntimeOptions::default()
16069 },
16070 )
16071 .expect_err("first parse fails loud under the Error policy");
16072
16073 parser.reset_unknown_semantic_hits();
16078 assert!(
16079 parser.take_unknown_semantic_error().is_none(),
16080 "reset must drop stale unknown-predicate coordinates before a reused parse"
16081 );
16082 }
16083
16084 #[derive(Debug, Default)]
16085 struct RecordingHooks {
16086 predicates: Vec<(usize, usize, usize, Option<String>)>,
16087 actions: Vec<(usize, String, Option<String>)>,
16088 action_trees: Vec<Option<String>>,
16089 }
16090
16091 impl SemanticHooks for RecordingHooks {
16092 fn sempred<S>(
16093 &mut self,
16094 ctx: &mut ParserSemCtx<'_, S>,
16095 rule_index: usize,
16096 pred_index: usize,
16097 ) -> Option<bool>
16098 where
16099 S: TokenSource,
16100 {
16101 self.predicates.push((
16102 ctx.input_index(),
16103 rule_index,
16104 pred_index,
16105 ctx.token_text(1).map(|token| token.text().to_owned()),
16106 ));
16107 Some(true)
16108 }
16109
16110 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
16111 where
16112 S: TokenSource,
16113 {
16114 self.actions.push((
16115 action.source_state(),
16116 ctx.action_text(),
16117 ctx.rule_name().map(str::to_owned),
16118 ));
16119 self.action_trees.push(ctx.tree().map(Node::text));
16120 true
16121 }
16122 }
16123
16124 #[derive(Debug, Default)]
16125 struct RejectingPredicateHooks {
16126 predicates: Vec<(usize, usize, usize, Option<String>)>,
16127 }
16128
16129 impl SemanticHooks for RejectingPredicateHooks {
16130 fn sempred<S>(
16131 &mut self,
16132 ctx: &mut ParserSemCtx<'_, S>,
16133 rule_index: usize,
16134 pred_index: usize,
16135 ) -> Option<bool>
16136 where
16137 S: TokenSource,
16138 {
16139 self.predicates.push((
16140 ctx.input_index(),
16141 rule_index,
16142 pred_index,
16143 ctx.token_text(1).map(|token| token.text().to_owned()),
16144 ));
16145 Some(false)
16146 }
16147 }
16148
16149 #[test]
16150 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
16151 let atn = predicate_gated_same_lookahead_atn([0, 0]);
16152 let mut parser = mini_parser_with_hooks(
16153 vec![
16154 TestToken::new(1).with_text("x"),
16155 TestToken::eof("parser-test", 1, 1, 1),
16156 ],
16157 RecordingHooks::default(),
16158 );
16159
16160 let (tree, _) = parser
16161 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16162 .expect("both alternatives share one replay-safe predicate result");
16163
16164 assert_eq!(parser.node(tree).text(), "x<EOF>");
16165 assert_eq!(
16166 parser.semantic_hooks.predicates,
16167 vec![(0, 0, 0, Some("x".to_owned()))]
16168 );
16169 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
16170 }
16171
16172 #[test]
16173 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
16174 let atn = predicate_after_token_atn();
16175 let mut parser = mini_parser_with_hooks(
16176 vec![
16177 TestToken::new(1).with_text("x"),
16178 TestToken::new(2).with_text("y"),
16179 TestToken::eof("parser-test", 2, 1, 2),
16180 ],
16181 RecordingHooks::default(),
16182 );
16183
16184 let (tree, _) = parser
16185 .parse_atn_rule_with_runtime_options(
16186 &atn,
16187 0,
16188 ParserRuntimeOptions {
16189 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16190 ..ParserRuntimeOptions::default()
16191 },
16192 )
16193 .expect("hook supplies the missing predicate result");
16194
16195 assert_eq!(parser.node(tree).text(), "xy");
16196 assert_eq!(
16197 parser.semantic_hooks.predicates,
16198 vec![(1, 0, 0, Some("y".to_owned()))]
16199 );
16200 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
16201 }
16202
16203 #[test]
16204 fn runtime_options_default_preserves_semantic_hook_predicates() {
16205 let atn = predicate_after_token_atn();
16206 let mut parser = mini_parser_with_hooks(
16207 vec![
16208 TestToken::new(1).with_text("x"),
16209 TestToken::new(2).with_text("y"),
16210 TestToken::eof("parser-test", 2, 1, 2),
16211 ],
16212 RejectingPredicateHooks::default(),
16213 );
16214
16215 let result =
16216 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
16217
16218 assert!(
16219 result.is_err(),
16220 "default runtime options must not bypass semantic hooks for predicate ATNs"
16221 );
16222 assert_eq!(
16223 parser.semantic_hooks.predicates,
16224 vec![(1, 0, 0, Some("y".to_owned()))]
16225 );
16226 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
16227 }
16228
16229 #[test]
16230 fn semantic_hook_handles_committed_parser_action() {
16231 let atn = token_then_eof_atn();
16232 let mut parser = mini_parser_with_hooks(
16233 vec![
16234 TestToken::new(1).with_text("x"),
16235 TestToken::eof("parser-test", 1, 1, 1),
16236 ],
16237 RecordingHooks::default(),
16238 );
16239 let (tree, _) = parser
16240 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16241 .expect("rule parses before action hook is tested");
16242
16243 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
16244 assert_eq!(
16245 parser.semantic_hooks.actions,
16246 vec![(42, "x".to_owned(), Some("s".to_owned()))]
16247 );
16248 assert_eq!(
16249 parser.semantic_hooks.action_trees,
16250 [Some("x<EOF>".to_owned())]
16251 );
16252 }
16253
16254 #[test]
16255 fn unhandled_committed_action_fails_loud_under_error_policy() {
16256 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16260 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
16261 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
16262
16263 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
16265
16266 let error = parser
16267 .take_unknown_semantic_error()
16268 .expect("an unhandled committed action under Error policy must fail loud");
16269 let AntlrError::Unsupported(message) = error else {
16270 panic!("expected AntlrError::Unsupported, got {error:?}");
16271 };
16272 assert!(
16273 message.contains("unhandled semantic action") && message.contains("state=42"),
16274 "message should name the dropped action coordinate: {message}"
16275 );
16276
16277 let mut lenient =
16279 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16280 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
16281 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
16282 assert!(lenient.take_unknown_semantic_error().is_none());
16283 }
16284
16285 #[test]
16286 fn translated_predicate_is_unaffected_by_error_policy() {
16287 let atn = predicate_after_token_atn();
16288 let mut parser = mini_parser(vec![
16289 TestToken::new(1).with_text("x"),
16290 TestToken::new(2).with_text("y"),
16291 TestToken::eof("parser-test", 2, 1, 2),
16292 ]);
16293
16294 let (tree, _) = parser
16295 .parse_atn_rule_with_runtime_options(
16296 &atn,
16297 0,
16298 ParserRuntimeOptions {
16299 predicates: &[(0, 0, ParserPredicate::True)],
16300 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16301 ..ParserRuntimeOptions::default()
16302 },
16303 )
16304 .expect("a predicate covered by the table is not an unknown coordinate");
16305
16306 assert_eq!(parser.node(tree).text(), "xy");
16307 }
16308
16309 fn hook_predicate_semantics() -> ParserSemantics {
16314 let mut ir = SemIr::new();
16315 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
16316 ParserSemantics {
16317 ir,
16318 predicates: vec![ParserSemanticPredicate {
16319 rule_index: 0,
16320 pred_index: 0,
16321 expr,
16322 failure_message: None,
16323 }],
16324 actions: Vec::new(),
16325 }
16326 }
16327
16328 #[derive(Debug, Default)]
16329 struct DecliningHooks;
16330
16331 impl SemanticHooks for DecliningHooks {}
16332
16333 #[test]
16334 fn semir_hook_none_falls_through_to_assume_true() {
16335 let atn = predicate_after_token_atn();
16336 let semantics = hook_predicate_semantics();
16337 let mut parser = mini_parser_with_hooks(
16338 vec![
16339 TestToken::new(1).with_text("x"),
16340 TestToken::new(2).with_text("y"),
16341 TestToken::eof("parser-test", 2, 1, 2),
16342 ],
16343 DecliningHooks,
16344 );
16345
16346 let (tree, _) = parser
16347 .parse_atn_rule_with_runtime_options(
16348 &atn,
16349 0,
16350 ParserRuntimeOptions {
16351 semantics: Some(&semantics),
16352 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
16353 ..ParserRuntimeOptions::default()
16354 },
16355 )
16356 .expect("a declined SemIR hook must pass under assume-true");
16357
16358 assert_eq!(parser.node(tree).text(), "xy");
16359 }
16360
16361 #[test]
16362 fn semir_hook_none_falls_through_to_assume_false() {
16363 let atn = predicate_after_token_atn();
16364 let semantics = hook_predicate_semantics();
16365 let mut parser = mini_parser_with_hooks(
16366 vec![
16367 TestToken::new(1).with_text("x"),
16368 TestToken::new(2).with_text("y"),
16369 TestToken::eof("parser-test", 2, 1, 2),
16370 ],
16371 DecliningHooks,
16372 );
16373
16374 let result = parser.parse_atn_rule_with_runtime_options(
16375 &atn,
16376 0,
16377 ParserRuntimeOptions {
16378 semantics: Some(&semantics),
16379 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
16380 ..ParserRuntimeOptions::default()
16381 },
16382 );
16383
16384 assert!(
16385 result.is_err(),
16386 "a declined SemIR hook must fail the only guarded path under assume-false"
16387 );
16388 }
16389
16390 #[test]
16391 fn semir_hook_none_records_coordinate_under_error_policy() {
16392 let atn = predicate_after_token_atn();
16393 let semantics = hook_predicate_semantics();
16394 let mut parser = mini_parser_with_hooks(
16395 vec![
16396 TestToken::new(1).with_text("x"),
16397 TestToken::new(2).with_text("y"),
16398 TestToken::eof("parser-test", 2, 1, 2),
16399 ],
16400 DecliningHooks,
16401 );
16402
16403 let error = parser
16404 .parse_atn_rule_with_runtime_options(
16405 &atn,
16406 0,
16407 ParserRuntimeOptions {
16408 semantics: Some(&semantics),
16409 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16410 ..ParserRuntimeOptions::default()
16411 },
16412 )
16413 .expect_err("a declined SemIR hook under Error policy must fail the parse");
16414
16415 let AntlrError::Unsupported(message) = error else {
16416 panic!("expected AntlrError::Unsupported, got {error:?}");
16417 };
16418 assert!(
16419 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
16420 "message should name the unresolved coordinate: {message}"
16421 );
16422 }
16423
16424 #[test]
16425 fn generated_direct_predicate_honors_installed_policy() {
16426 let semantics = hook_predicate_semantics();
16432 let context = ParserRuleContext::new(0, -1);
16433
16434 let mut assume_true =
16435 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16436 assert!(
16437 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
16438 &semantics, 0, 0, &context, 0
16439 ),
16440 "default AssumeTrue accepts a declined hook"
16441 );
16442 assert!(assume_true.take_unknown_semantic_error().is_none());
16443
16444 let mut error_policy =
16445 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16446 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
16447 assert!(
16448 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
16449 &semantics, 0, 0, &context, 0
16450 ),
16451 "Error policy rejects a declined hook on the generated-direct path"
16452 );
16453 let error = error_policy
16454 .take_unknown_semantic_error()
16455 .expect("Error policy records the unresolved coordinate for the generated path");
16456 let AntlrError::Unsupported(message) = error else {
16457 panic!("expected AntlrError::Unsupported, got {error:?}");
16458 };
16459 assert!(message.contains("pred_index=0"), "message: {message}");
16460 }
16461
16462 #[test]
16463 fn parser_rule_start_skips_leading_hidden_tokens() {
16464 let atn = token_then_eof_atn();
16465 let mut parser = mini_parser(vec![
16466 TestToken::new(99)
16467 .with_text(" ")
16468 .with_channel(HIDDEN_CHANNEL),
16469 TestToken::new(1).with_text("x"),
16470 TestToken::eof("parser-test", 2, 1, 2),
16471 ]);
16472
16473 let tree = parser
16474 .parse_atn_rule(&atn, 0)
16475 .expect("artificial parser rule should parse");
16476 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
16477 panic!("rule node should be present");
16478 };
16479 assert_eq!(
16480 rule.start()
16481 .expect("rule should have a start token")
16482 .token_type(),
16483 1
16484 );
16485 }
16486
16487 #[test]
16488 fn parser_action_after_eof_stops_at_eof_token() {
16489 let atn = eof_then_action_atn();
16490 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
16491
16492 let (_, actions) = parser
16493 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16494 .expect("EOF action rule should parse");
16495
16496 assert_eq!(actions.len(), 1);
16497 assert_eq!(actions[0].stop_index(), Some(0));
16498 assert_eq!(
16499 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
16500 ""
16501 );
16502 }
16503
16504 #[test]
16505 fn after_action_stop_uses_rule_context_stop_not_cursor() {
16506 let mut id = TestToken::new(1).with_text("x");
16511 id.set_token_index(0);
16512 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
16513 eof.set_token_index(1);
16514 let mut parser = mini_parser(vec![id.clone(), eof]);
16515 parser.consume();
16517 assert_eq!(parser.la(1), TOKEN_EOF);
16518
16519 let mut ctx = ParserRuleContext::new(0, 0);
16522 parser.set_context_stop(
16523 &mut ctx,
16524 parser.token_id_at(0).expect("ID token should be buffered"),
16525 );
16526 let tree = parser.rule_node(ctx);
16527
16528 let current_index = parser.input.index();
16529 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
16531 assert_eq!(
16533 parser.after_action_stop_index_for_tree(tree, current_index),
16534 Some(0)
16535 );
16536 }
16537
16538 #[test]
16539 fn after_action_start_uses_rule_context_start_not_cursor() {
16540 let mut parser = mini_parser(vec![
16545 TestToken::new(9)
16546 .with_text(" ")
16547 .with_channel(HIDDEN_CHANNEL),
16548 TestToken::new(9)
16549 .with_text(" ")
16550 .with_channel(HIDDEN_CHANNEL),
16551 TestToken::new(1).with_text("x"),
16552 TestToken::eof("parser-test", 3, 1, 3),
16553 ]);
16554
16555 let mut ctx = ParserRuleContext::new(0, 0);
16556 parser.set_context_start(
16557 &mut ctx,
16558 parser.token_id_at(2).expect("ID token should be buffered"),
16559 );
16560 let tree = parser.rule_node(ctx);
16561
16562 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
16565
16566 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
16568 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
16569 }
16570
16571 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
16572 FastRecognizeOutcome {
16573 index,
16574 consumed_eof,
16575 diagnostics: DiagnosticSeqId::EMPTY,
16576 deferred_nodes: FastDeferredNodeId::EMPTY,
16577 nodes: NodeSeqId(marker),
16578 }
16579 }
16580
16581 #[test]
16582 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
16583 let mut outcomes = vec![
16584 clean_fast_outcome(4, false, 0),
16585 clean_fast_outcome(2, false, 1),
16586 clean_fast_outcome(4, false, 2),
16587 clean_fast_outcome(4, true, 3),
16588 clean_fast_outcome(2, false, 4),
16589 ];
16590 let mut scratch = FastOutcomeDedupScratch::default();
16591
16592 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16593
16594 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
16595 assert_eq!(
16596 outcomes
16597 .iter()
16598 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
16599 .collect::<Vec<_>>(),
16600 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
16601 );
16602 assert!(scratch.dense_words.is_empty());
16603 assert!(scratch.sparse_keys.is_empty());
16604 }
16605
16606 #[test]
16607 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
16608 let mut scratch = FastOutcomeDedupScratch::default();
16609 let mut outcomes = (100..109)
16610 .flat_map(|index| {
16611 [
16612 clean_fast_outcome(
16613 index,
16614 false,
16615 u32::try_from(index).expect("test index fits in u32"),
16616 ),
16617 clean_fast_outcome(index, false, u32::MAX),
16618 ]
16619 })
16620 .collect();
16621
16622 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16623
16624 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
16625 assert_eq!(outcomes.len(), 9);
16626 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
16627 let dense_capacity = scratch.dense_words.capacity();
16628
16629 let mut reused = (1_000..1_009)
16630 .map(|index| {
16631 clean_fast_outcome(
16632 index,
16633 false,
16634 u32::try_from(index).expect("test index fits in u32"),
16635 )
16636 })
16637 .collect();
16638 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
16639
16640 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
16641 assert_eq!(reused.len(), 9);
16642 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
16643 }
16644
16645 #[test]
16646 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
16647 let mut scratch = FastOutcomeDedupScratch::default();
16648 let sparse_indexes = [
16649 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
16650 ];
16651 let mut outcomes = sparse_indexes
16652 .into_iter()
16653 .chain([400_000])
16654 .enumerate()
16655 .map(|(marker, index)| {
16656 clean_fast_outcome(
16657 index,
16658 false,
16659 u32::try_from(marker).expect("test marker fits in u32"),
16660 )
16661 })
16662 .collect();
16663
16664 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16665
16666 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16667 assert_eq!(outcomes.len(), sparse_indexes.len());
16668 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
16669 let sparse_capacity = scratch.sparse_keys.capacity();
16670
16671 let mut reused = sparse_indexes
16672 .into_iter()
16673 .map(|index| {
16674 clean_fast_outcome(
16675 index,
16676 false,
16677 u32::try_from(index).expect("test index fits in u32"),
16678 )
16679 })
16680 .collect();
16681 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
16682
16683 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16684 assert_eq!(reused.len(), sparse_indexes.len());
16685 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
16686 }
16687
16688 #[test]
16689 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
16690 let mut scratch = FastOutcomeDedupScratch::default();
16691 scratch
16692 .sparse_keys
16693 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
16694 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
16695 let mut outcomes = (0..9)
16696 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
16697 .collect();
16698
16699 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16700
16701 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16702 assert!(scratch.sparse_keys.is_empty());
16703 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
16704 }
16705
16706 #[test]
16707 fn fast_outcome_selection_respects_sll_tie_order() {
16708 let mut arena = RecognitionArena::default();
16709 let first = FastRecognizeOutcome {
16710 index: 1,
16711 consumed_eof: false,
16712 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16713 line: 1,
16714 column: 0,
16715 message: "mismatched input 'x'".to_owned(),
16716 }]),
16717 deferred_nodes: FastDeferredNodeId::EMPTY,
16718 nodes: NodeSeqId::EMPTY,
16719 };
16720 let second = FastRecognizeOutcome {
16721 index: first.index,
16722 consumed_eof: first.consumed_eof,
16723 diagnostics: DiagnosticSeqId::EMPTY,
16724 deferred_nodes: FastDeferredNodeId::EMPTY,
16725 nodes: NodeSeqId::EMPTY,
16726 };
16727
16728 let selected = select_best_fast_outcome(
16729 [first, second].into_iter(),
16730 PredictionMode::Sll,
16731 None,
16732 |_| panic!("caller-follow token probe should not run"),
16733 &arena,
16734 )
16735 .expect("one outcome should be selected");
16736 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
16737 let eof_second = FastRecognizeOutcome {
16738 index: second.index,
16739 consumed_eof: true,
16740 diagnostics: DiagnosticSeqId::EMPTY,
16741 deferred_nodes: FastDeferredNodeId::EMPTY,
16742 nodes: NodeSeqId::EMPTY,
16743 };
16744 let selected = select_best_fast_outcome(
16745 [first, eof_second].into_iter(),
16746 PredictionMode::Sll,
16747 None,
16748 |_| panic!("caller-follow token probe should not run"),
16749 &arena,
16750 )
16751 .expect("one outcome should be selected");
16752 assert!(!selected.consumed_eof);
16753 let selected = select_best_fast_outcome(
16754 [first, second].into_iter(),
16755 PredictionMode::Ll,
16756 None,
16757 |_| panic!("caller-follow token probe should not run"),
16758 &arena,
16759 )
16760 .expect("one outcome should be selected");
16761 assert!(selected.diagnostics.is_empty());
16762 }
16763
16764 #[test]
16765 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
16766 let mut arena = RecognitionArena::default();
16767 let first = FastRecognizeOutcome {
16768 index: 3,
16769 consumed_eof: false,
16770 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16771 line: 1,
16772 column: 0,
16773 message: "mismatched input 'x' expecting 'a'".to_owned(),
16774 }]),
16775 deferred_nodes: FastDeferredNodeId::EMPTY,
16776 nodes: NodeSeqId::EMPTY,
16777 };
16778 let same_rank = FastRecognizeOutcome {
16779 index: first.index,
16780 consumed_eof: first.consumed_eof,
16781 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16782 line: 1,
16783 column: 0,
16784 message: "mismatched input 'x' expecting 'b'".to_owned(),
16785 }]),
16786 deferred_nodes: FastDeferredNodeId::EMPTY,
16787 nodes: NodeSeqId::EMPTY,
16788 };
16789 let better_rank = FastRecognizeOutcome {
16790 index: first.index,
16791 consumed_eof: first.consumed_eof,
16792 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16793 line: 1,
16794 column: 0,
16795 message: "missing 'a' at 'x'".to_owned(),
16796 }]),
16797 deferred_nodes: FastDeferredNodeId::EMPTY,
16798 nodes: NodeSeqId::EMPTY,
16799 };
16800 let mut outcomes = vec![first, same_rank, better_rank];
16801
16802 dedupe_fast_outcomes(&mut outcomes, &arena);
16803
16804 assert_eq!(outcomes.len(), 2);
16805 assert_eq!(
16806 arena
16807 .diagnostics(outcomes[0].diagnostics)
16808 .next()
16809 .expect("first diagnostic")
16810 .message,
16811 "mismatched input 'x' expecting 'a'"
16812 );
16813 assert_eq!(
16814 arena
16815 .diagnostics(outcomes[1].diagnostics)
16816 .next()
16817 .expect("second diagnostic")
16818 .message,
16819 "missing 'a' at 'x'"
16820 );
16821 }
16822
16823 #[test]
16824 fn fast_outcome_selection_prefers_generated_caller_follow() {
16825 let arena = RecognitionArena::default();
16826 let earlier = FastRecognizeOutcome {
16827 index: 7,
16828 consumed_eof: false,
16829 diagnostics: DiagnosticSeqId::EMPTY,
16830 deferred_nodes: FastDeferredNodeId::EMPTY,
16831 nodes: NodeSeqId::EMPTY,
16832 };
16833 let later = FastRecognizeOutcome {
16834 index: 8,
16835 consumed_eof: false,
16836 diagnostics: DiagnosticSeqId::EMPTY,
16837 deferred_nodes: FastDeferredNodeId::EMPTY,
16838 nodes: NodeSeqId::EMPTY,
16839 };
16840 let mut follow = TokenBitSet::default();
16841 follow.insert(5);
16842
16843 let selected = select_best_fast_outcome(
16844 [later, earlier].into_iter(),
16845 PredictionMode::Ll,
16846 Some(&follow),
16847 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
16848 &arena,
16849 )
16850 .expect("one outcome should be selected");
16851 assert_eq!(selected.index, 7);
16852
16853 let selected = select_best_fast_outcome(
16854 [later, earlier].into_iter(),
16855 PredictionMode::Ll,
16856 Some(&follow),
16857 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
16858 &arena,
16859 )
16860 .expect("one outcome should be selected");
16861 assert_eq!(selected.index, 8);
16862
16863 let indented_next_statement = FastRecognizeOutcome {
16864 index: 9,
16865 consumed_eof: false,
16866 diagnostics: DiagnosticSeqId::EMPTY,
16867 deferred_nodes: FastDeferredNodeId::EMPTY,
16868 nodes: NodeSeqId::EMPTY,
16869 };
16870 let selected = select_best_fast_outcome(
16871 [indented_next_statement, earlier].into_iter(),
16872 PredictionMode::Ll,
16873 Some(&follow),
16874 |index| {
16875 let is_boundary = index == 7;
16876 let is_boundary_gap = matches!(index, 7 | 8);
16877 (
16878 if index == 7 { 5 } else { TOKEN_EOF },
16879 is_boundary,
16880 is_boundary_gap,
16881 )
16882 },
16883 &arena,
16884 )
16885 .expect("one outcome should be selected");
16886 assert_eq!(selected.index, 7);
16887
16888 let continuation = FastRecognizeOutcome {
16889 index: 10,
16890 consumed_eof: false,
16891 diagnostics: DiagnosticSeqId::EMPTY,
16892 deferred_nodes: FastDeferredNodeId::EMPTY,
16893 nodes: NodeSeqId::EMPTY,
16894 };
16895 let selected = select_best_fast_outcome(
16896 [continuation, earlier].into_iter(),
16897 PredictionMode::Ll,
16898 Some(&follow),
16899 |index| {
16900 let is_boundary = matches!(index, 7 | 9);
16901 (
16902 if index == 7 { 5 } else { TOKEN_EOF },
16903 is_boundary,
16904 is_boundary,
16905 )
16906 },
16907 &arena,
16908 )
16909 .expect("one outcome should be selected");
16910 assert_eq!(selected.index, 10);
16911
16912 let selected = select_best_fast_outcome(
16913 [earlier, later].into_iter(),
16914 PredictionMode::Sll,
16915 Some(&follow),
16916 |_| panic!("caller-follow token probe should not run in SLL mode"),
16917 &arena,
16918 )
16919 .expect("one outcome should be selected");
16920 assert_eq!(selected.index, 8);
16921 }
16922
16923 #[test]
16924 fn caller_follow_boundary_text_requires_separator_shape() {
16925 assert!(is_caller_follow_boundary_text(";"));
16926 assert!(is_caller_follow_boundary_text("\n"));
16927 assert!(is_caller_follow_boundary_text("\r\n "));
16928 assert!(is_caller_follow_boundary_text(";\n"));
16929 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
16930 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
16931 assert!(!is_caller_follow_boundary_text("identifier"));
16932 assert!(is_caller_follow_boundary_gap_text(" \t "));
16933 assert!(is_caller_follow_boundary_gap_text("\n "));
16934 assert!(is_caller_follow_boundary_gap_text(";\t"));
16935 assert!(!is_caller_follow_boundary_gap_text(
16936 "\"\"\"line1\nline2\"\"\""
16937 ));
16938 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
16939 }
16940
16941 #[test]
16942 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
16943 let mut parser = mini_parser(vec![
16944 TestToken::new(5).with_text("\n"),
16945 TestToken::new(6)
16946 .with_text("// comment\n")
16947 .with_channel(HIDDEN_CHANNEL),
16948 TestToken::new(1).with_text("x"),
16949 TestToken::eof("parser-test", 1, 2, 0),
16950 ]);
16951
16952 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
16953 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
16954 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
16955 }
16956
16957 #[test]
16958 fn caller_follow_token_info_uses_stream_visible_channel() {
16959 let source = Source {
16960 tokens: vec![
16961 TestToken::new(5).with_text("\n").with_channel(2),
16962 TestToken::new(1).with_text("x").with_channel(2),
16963 TestToken::new(6)
16964 .with_text("// comment\n")
16965 .with_channel(HIDDEN_CHANNEL),
16966 TestToken::eof("parser-test", 1, 2, 0),
16967 ],
16968 index: 0,
16969 };
16970 let data = RecognizerData::new(
16971 "Mini.g4",
16972 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
16973 );
16974 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
16975
16976 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
16977 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
16978 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
16979 }
16980
16981 #[test]
16982 fn reset_per_parse_caches_clears_state_expected_token_cache() {
16983 let atn = token_then_eof_atn();
16984 let mut parser = mini_parser(Vec::new());
16985
16986 let _ = parser.cached_state_expected_token_set(&atn, 0);
16987 assert!(!parser.state_expected_token_cache.is_empty());
16988
16989 parser.reset_per_parse_caches();
16990 assert!(parser.state_expected_token_cache.is_empty());
16991 }
16992
16993 #[test]
16994 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
16995 let cyclic = epsilon_cycle_atn();
16996 let acyclic = token_then_eof_atn();
16997 let mut parser = mini_parser(Vec::new());
16998
16999 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
17000 assert_eq!(
17001 parser.empty_cycle_cache_atn,
17002 Some(SharedAtnCacheKey::for_atn(&cyclic))
17003 );
17004 assert_eq!(parser.empty_cycle_cache[1], Some(true));
17005
17006 parser.reset_per_parse_caches();
17007 assert_eq!(parser.empty_cycle_cache[1], Some(true));
17008 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
17009
17010 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
17011 assert_eq!(
17012 parser.empty_cycle_cache_atn,
17013 Some(SharedAtnCacheKey::for_atn(&acyclic))
17014 );
17015 assert_eq!(parser.empty_cycle_cache[1], Some(false));
17016 }
17017
17018 #[test]
17019 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
17020 let source = Source {
17021 tokens: vec![
17022 TestToken::new(1).with_text("x"),
17023 TestToken::eof("parser-test", 1, 1, 1),
17024 ],
17025 index: 0,
17026 };
17027 let data = RecognizerData::new(
17028 "Mini.g4",
17029 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17030 );
17031 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17032 let expected = ExpectedTokens {
17033 index: Some(0),
17034 symbols: BTreeSet::new(),
17035 no_viable: None,
17036 };
17037
17038 let (_, message) = parser.expected_error_message(0, 0, &expected);
17039
17040 assert_eq!(message, "mismatched input 'x'");
17041 }
17042
17043 #[test]
17044 fn eof_rule_stop_index_points_at_eof_token() {
17045 let source = Source {
17046 tokens: vec![
17047 TestToken::new(1).with_text("x"),
17048 TestToken::eof("parser-test", 1, 1, 1),
17049 ],
17050 index: 0,
17051 };
17052 let data = RecognizerData::new(
17053 "Mini.g4",
17054 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17055 );
17056 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17057
17058 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
17059 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
17060 }
17061
17062 #[test]
17063 fn generated_parser_action_uses_current_rule_stop_boundary() {
17064 let mut parser = mini_parser(vec![
17065 TestToken::new(1).with_text("x"),
17066 TestToken::eof("parser-test", 1, 1, 1),
17067 ]);
17068
17069 parser.match_token(1).expect("token should match");
17070 let action = parser.parser_action_at_current(7, 0, 0, false);
17071 assert_eq!(action.source_state(), 7);
17072 assert_eq!(action.rule_index(), 0);
17073 assert_eq!(action.start_index(), 0);
17074 assert_eq!(action.stop_index(), Some(0));
17075
17076 parser.match_eof().expect("EOF should match");
17077 let action = parser.parser_action_at_current(8, 0, 0, true);
17078 assert_eq!(action.stop_index(), Some(1));
17079 }
17080
17081 #[test]
17082 fn folds_left_recursive_boundary_into_rule_node() {
17083 let mut arena = RecognitionArena::default();
17084 let first = arena.push_node(ArenaRecognizedNode::Token {
17085 token: TokenId::try_from(0).expect("test token ID"),
17086 });
17087 let boundary =
17088 arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: 1 });
17089 let second = arena.push_node(ArenaRecognizedNode::Token {
17090 token: TokenId::try_from(1).expect("test token ID"),
17091 });
17092 let mut nodes = NodeSeqId::EMPTY;
17093 for node in [first, boundary, second].into_iter().rev() {
17094 nodes = arena.prepend(nodes, node);
17095 }
17096
17097 let folded = arena.fold_left_recursive_boundaries(nodes);
17098 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
17099
17100 assert_eq!(folded_nodes.len(), 2);
17101 let ArenaRecognizedNode::Rule {
17102 rule_index,
17103 invoking_state,
17104 start_index,
17105 stop_index,
17106 children,
17107 ..
17108 } = arena.node(folded_nodes[0])
17109 else {
17110 panic!("first folded node should be a rule");
17111 };
17112 assert_eq!(rule_index, 1);
17113 assert_eq!(invoking_state, -1);
17114 assert_eq!(start_index, 0);
17115 assert_eq!(stop_index, Some(0));
17116 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
17117 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
17118
17119 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
17120 assert_eq!(
17121 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17122 (4, 3, 1)
17123 );
17124 assert_eq!(
17125 (stats.total_links, stats.live_links, stats.dead_links),
17126 (9, 3, 6)
17127 );
17128 }
17129
17130 #[test]
17131 fn recognition_arena_reports_live_dead_and_retained_capacity() {
17132 let mut arena = RecognitionArena::default();
17133 let token = arena.push_node(ArenaRecognizedNode::Token {
17134 token: TokenId::try_from(0).expect("test token ID"),
17135 });
17136 let extra = arena.push_extra(RecognitionExtra::MissingToken {
17137 token_type: 2,
17138 at_index: 1,
17139 text: "<missing X>".to_owned(),
17140 });
17141 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
17142 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
17143 token: TokenId::try_from(1).expect("test token ID"),
17144 });
17145 let mut live = NodeSeqId::EMPTY;
17146 live = arena.prepend(live, missing);
17147 live = arena.prepend(live, token);
17148 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
17149 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17150 line: 1,
17151 column: 0,
17152 message: "missing X".to_owned(),
17153 }]);
17154 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17155 line: 1,
17156 column: 1,
17157 message: "discarded".to_owned(),
17158 }]);
17159 let deferred_children = arena.deferred_fragment(live);
17160 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
17161 rule_index: 0,
17162 invoking_state: -1,
17163 start_index: 0,
17164 stop_index: Some(1),
17165 deferred_children,
17166 children: NodeSeqId::EMPTY,
17167 });
17168
17169 let stats = arena.stats(live, live_diagnostics);
17170
17171 assert_eq!(
17172 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17173 (3, 2, 1)
17174 );
17175 assert_eq!(
17176 (stats.total_links, stats.live_links, stats.dead_links),
17177 (5, 3, 2)
17178 );
17179 assert_eq!(
17180 (stats.total_extras, stats.live_extras, stats.dead_extras),
17181 (3, 2, 1)
17182 );
17183 assert!(size_of::<SeqLink>() <= 8);
17184 assert!(size_of::<DiagnosticLink>() <= 8);
17185 assert!(size_of::<FastDeferredNode>() <= 12);
17186 assert!(size_of::<FastDeferredRule>() <= 28);
17187 assert!(size_of::<FastRecognizeOutcome>() <= 24);
17188 let capacities = (
17189 stats.node_capacity,
17190 stats.link_capacity,
17191 stats.extra_capacity,
17192 );
17193 let deferred_capacities = (
17194 arena.deferred_nodes.capacity(),
17195 arena.deferred_rules.capacity(),
17196 );
17197
17198 arena.reset();
17199 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
17200 assert_eq!(
17201 (reset.total_nodes, reset.total_links, reset.total_extras),
17202 (0, 0, 0)
17203 );
17204 assert_eq!(
17205 (
17206 reset.node_capacity,
17207 reset.link_capacity,
17208 reset.extra_capacity,
17209 ),
17210 capacities
17211 );
17212 assert!(arena.deferred_nodes.is_empty());
17213 assert!(arena.deferred_rules.is_empty());
17214 assert_eq!(
17215 (
17216 arena.deferred_nodes.capacity(),
17217 arena.deferred_rules.capacity(),
17218 ),
17219 deferred_capacities
17220 );
17221 }
17222
17223 #[test]
17224 fn parser_computes_recognition_arena_stats_on_demand() {
17225 let mut parser = mini_parser(Vec::new());
17226 let live = parser
17227 .recognition_arena
17228 .push_node(ArenaRecognizedNode::Token {
17229 token: TokenId::try_from(0).expect("test token ID"),
17230 });
17231 let discarded = parser
17232 .recognition_arena
17233 .push_node(ArenaRecognizedNode::ErrorToken {
17234 token: TokenId::try_from(1).expect("test token ID"),
17235 });
17236 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
17237 let _discarded_root = parser
17238 .recognition_arena
17239 .prepend(NodeSeqId::EMPTY, discarded);
17240 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
17241
17242 let stats = parser.recognition_arena_stats();
17243
17244 assert_eq!(
17245 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17246 (2, 1, 1)
17247 );
17248 assert_eq!(
17249 (stats.total_links, stats.live_links, stats.dead_links),
17250 (2, 1, 1)
17251 );
17252 }
17253
17254 #[test]
17255 fn recognition_arena_drops_capacity_above_retention_limit() {
17256 let mut storage = Vec::<u8>::with_capacity(4);
17257 storage.extend([1, 2, 3]);
17258
17259 reset_arena_vec(&mut storage, 3);
17260
17261 assert!(storage.is_empty());
17262 assert_eq!(storage.capacity(), 0);
17263 }
17264
17265 #[test]
17266 fn recognition_arena_concatenates_diagnostics_in_source_order() {
17267 let mut arena = RecognitionArena::default();
17268 let prefix = arena.diagnostic_sequence([
17269 ParserDiagnostic {
17270 line: 1,
17271 column: 0,
17272 message: "first".to_owned(),
17273 },
17274 ParserDiagnostic {
17275 line: 1,
17276 column: 1,
17277 message: "second".to_owned(),
17278 },
17279 ]);
17280 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
17281 line: 1,
17282 column: 2,
17283 message: "third".to_owned(),
17284 }]);
17285 let extras_before = arena.extras.len();
17286
17287 let combined = arena.concat_diagnostics(prefix, suffix);
17288 let messages = arena
17289 .diagnostics(combined)
17290 .map(|diagnostic| diagnostic.message.as_str())
17291 .collect::<Vec<_>>();
17292
17293 assert_eq!(messages, ["first", "second", "third"]);
17294 assert_eq!(arena.extras.len(), extras_before);
17295 }
17296
17297 #[test]
17298 fn outcome_ties_keep_later_non_recursive_alternative() {
17299 let arena = RecognitionArena::default();
17300 let first = RecognizeOutcome {
17301 index: 1,
17302 consumed_eof: false,
17303 alt_number: 0,
17304 member_values: BTreeMap::new(),
17305 return_values: BTreeMap::new(),
17306 diagnostics: DiagnosticSeqId::EMPTY,
17307 decisions: Vec::new(),
17308 actions: vec![ParserAction::new(1, 0, 0, None)],
17309 nodes: NodeSeqId::EMPTY,
17310 };
17311 let second = RecognizeOutcome {
17312 actions: vec![ParserAction::new(2, 0, 0, None)],
17313 ..first.clone()
17314 };
17315
17316 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17317 .expect("one outcome should be selected");
17318 assert_eq!(selected.actions[0].source_state(), 2);
17319 }
17320
17321 #[test]
17322 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
17323 let arena = RecognitionArena::default();
17324 let first = RecognizeOutcome {
17325 index: 1,
17326 consumed_eof: false,
17327 alt_number: 0,
17328 member_values: BTreeMap::new(),
17329 return_values: BTreeMap::new(),
17330 diagnostics: DiagnosticSeqId::EMPTY,
17331 decisions: Vec::new(),
17332 actions: vec![ParserAction::new(1, 0, 0, None)],
17333 nodes: NodeSeqId::EMPTY,
17334 };
17335 let second = RecognizeOutcome {
17336 actions: vec![
17337 ParserAction::new(2, 0, 0, None),
17338 ParserAction::new(3, 0, 0, None),
17339 ],
17340 ..first.clone()
17341 };
17342
17343 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
17344 .expect("one outcome should be selected");
17345 assert_eq!(selected.actions.len(), 2);
17346 }
17347
17348 #[test]
17349 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
17350 let arena = RecognitionArena::default();
17351 let first = RecognizeOutcome {
17352 index: 7,
17353 consumed_eof: false,
17354 alt_number: 0,
17355 member_values: BTreeMap::new(),
17356 return_values: BTreeMap::new(),
17357 diagnostics: DiagnosticSeqId::EMPTY,
17358 decisions: vec![1, 0],
17359 actions: vec![
17360 ParserAction::new(23, 2, 2, Some(4)),
17361 ParserAction::new(23, 2, 0, Some(6)),
17362 ],
17363 nodes: NodeSeqId::EMPTY,
17364 };
17365 let second = RecognizeOutcome {
17366 decisions: vec![0, 1],
17367 actions: vec![
17368 ParserAction::new(23, 2, 2, Some(6)),
17369 ParserAction::new(23, 2, 0, Some(6)),
17370 ],
17371 ..first.clone()
17372 };
17373
17374 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17375 .expect("one outcome should be selected");
17376 assert_eq!(selected.actions[0].stop_index(), Some(6));
17377 }
17378
17379 #[test]
17380 fn outcome_ties_keep_first_recursive_tree_shape() {
17381 let mut arena = RecognitionArena::default();
17382 let token = arena.push_node(ArenaRecognizedNode::Token {
17383 token: TokenId::try_from(0).expect("test token ID"),
17384 });
17385 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
17386 let inner = arena.push_node(ArenaRecognizedNode::Rule {
17387 rule_index: 1,
17388 invoking_state: -1,
17389 alt_number: 0,
17390 start_index: 0,
17391 stop_index: Some(0),
17392 return_values: None,
17393 children: token_children,
17394 });
17395 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
17396 let outer = arena.push_node(ArenaRecognizedNode::Rule {
17397 rule_index: 1,
17398 invoking_state: -1,
17399 alt_number: 0,
17400 start_index: 0,
17401 stop_index: Some(0),
17402 return_values: None,
17403 children: inner_children,
17404 });
17405 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
17406 let first = RecognizeOutcome {
17407 index: 1,
17408 consumed_eof: false,
17409 alt_number: 0,
17410 member_values: BTreeMap::new(),
17411 return_values: BTreeMap::new(),
17412 diagnostics: DiagnosticSeqId::EMPTY,
17413 decisions: Vec::new(),
17414 actions: vec![ParserAction::new(1, 0, 0, None)],
17415 nodes: recursive_nodes,
17416 };
17417 let second = RecognizeOutcome {
17418 index: 1,
17419 consumed_eof: false,
17420 alt_number: 0,
17421 member_values: BTreeMap::new(),
17422 return_values: BTreeMap::new(),
17423 diagnostics: DiagnosticSeqId::EMPTY,
17424 decisions: Vec::new(),
17425 actions: vec![ParserAction::new(2, 0, 0, None)],
17426 nodes: recursive_nodes,
17427 };
17428
17429 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17430 .expect("one outcome should be selected");
17431 assert_eq!(selected.actions[0].source_state(), 1);
17432 }
17433
17434 #[test]
17435 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
17436 let mut arena = RecognitionArena::default();
17437 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17438 line: 1,
17439 column: 3,
17440 message: "missing 'Y' at '<EOF>'".to_owned(),
17441 }]);
17442 let first_alt = RecognizeOutcome {
17443 index: 2,
17444 consumed_eof: true,
17445 alt_number: 0,
17446 member_values: BTreeMap::new(),
17447 return_values: BTreeMap::new(),
17448 diagnostics: recovered_diagnostics,
17449 decisions: vec![0],
17450 actions: vec![ParserAction::new(1, 0, 0, None)],
17451 nodes: NodeSeqId::EMPTY,
17452 };
17453 let second_alt = RecognizeOutcome {
17454 diagnostics: DiagnosticSeqId::EMPTY,
17455 decisions: vec![1],
17456 actions: vec![ParserAction::new(2, 0, 0, None)],
17457 ..first_alt.clone()
17458 };
17459
17460 let selected = select_best_outcome(
17461 [second_alt, first_alt].into_iter(),
17462 PredictionMode::Sll,
17463 &arena,
17464 )
17465 .expect("one outcome should be selected");
17466 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
17467 assert_eq!(selected.decisions, [0]);
17468 }
17469}