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, 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_SINGLE_OUTCOME_MEMO_PROBE_LIMIT: usize = 4096;
114const CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT: usize = 8;
115
116#[derive(Clone, Copy, Debug, Eq, PartialEq)]
117enum SingleOutcomeMemoMode {
118 Probe,
119 Promote,
120 Sparse,
121}
122
123fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
124 intervals
125 .iter()
126 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
127}
128
129fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
130 let mut symbols = BTreeSet::new();
131 for (start, stop) in intervals {
132 symbols.extend(*start..=*stop);
133 }
134 symbols
135}
136
137fn interval_complement_symbols(
138 intervals: &[(i32, i32)],
139 min_vocabulary: i32,
140 max_vocabulary: i32,
141) -> BTreeSet<i32> {
142 (min_vocabulary..=max_vocabulary)
143 .filter(|symbol| !interval_set_contains(intervals, *symbol))
144 .collect()
145}
146
147#[cfg(feature = "perf-counters")]
148mod perf_counters {
149 use std::cell::Cell;
150 thread_local! {
151 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
152 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
153 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
154 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
155 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
156 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
157 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
158 pub(super) static OUTCOME_DEDUPE_INPUTS: Cell<u64> = const { Cell::new(0) };
159 pub(super) static OUTCOME_DEDUPE_REMOVED: Cell<u64> = const { Cell::new(0) };
160 pub(super) static OUTCOME_DEDUPE_INLINE: Cell<u64> = const { Cell::new(0) };
161 pub(super) static OUTCOME_DEDUPE_DENSE: Cell<u64> = const { Cell::new(0) };
162 pub(super) static OUTCOME_DEDUPE_SPARSE: Cell<u64> = const { Cell::new(0) };
163 pub(super) static OUTCOME_DEDUPE_DENSE_WORDS: Cell<u64> = const { Cell::new(0) };
164 }
165 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
166 c.with(|v| v.set(v.get() + n));
167 }
168 thread_local! {
169 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
170 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
171 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
172 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
173 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
174 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
175 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
176 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
177 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
178 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
179 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
180 }
181 pub(super) fn snapshot() -> [(&'static str, u64); 24] {
182 [
183 ("rfs_calls", RFS_CALLS.with(Cell::get)),
184 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
185 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
186 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
187 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
188 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
189 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
190 (
191 "outcome_dedupe_inputs",
192 OUTCOME_DEDUPE_INPUTS.with(Cell::get),
193 ),
194 (
195 "outcome_dedupe_removed",
196 OUTCOME_DEDUPE_REMOVED.with(Cell::get),
197 ),
198 (
199 "outcome_dedupe_inline",
200 OUTCOME_DEDUPE_INLINE.with(Cell::get),
201 ),
202 ("outcome_dedupe_dense", OUTCOME_DEDUPE_DENSE.with(Cell::get)),
203 (
204 "outcome_dedupe_sparse",
205 OUTCOME_DEDUPE_SPARSE.with(Cell::get),
206 ),
207 (
208 "outcome_dedupe_dense_words",
209 OUTCOME_DEDUPE_DENSE_WORDS.with(Cell::get),
210 ),
211 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
212 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
213 (
214 "atom_range_transitions",
215 ATOM_RANGE_TRANSITIONS.with(Cell::get),
216 ),
217 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
218 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
219 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
220 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
221 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
222 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
223 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
224 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
225 ]
226 }
227 pub fn reset() {
228 RFS_CALLS.with(|c| c.set(0));
229 RFS_MEMO_HITS.with(|c| c.set(0));
230 RFS_MEMO_MISSES.with(|c| c.set(0));
231 RFS_VISITING_CYCLE.with(|c| c.set(0));
232 MEMO_INSERTED.with(|c| c.set(0));
233 OUTCOMES_PUSHED.with(|c| c.set(0));
234 OUTCOMES_CLONED.with(|c| c.set(0));
235 OUTCOME_DEDUPE_INPUTS.with(|c| c.set(0));
236 OUTCOME_DEDUPE_REMOVED.with(|c| c.set(0));
237 OUTCOME_DEDUPE_INLINE.with(|c| c.set(0));
238 OUTCOME_DEDUPE_DENSE.with(|c| c.set(0));
239 OUTCOME_DEDUPE_SPARSE.with(|c| c.set(0));
240 OUTCOME_DEDUPE_DENSE_WORDS.with(|c| c.set(0));
241 EPSILON_TRANSITIONS.with(|c| c.set(0));
242 RULE_TRANSITIONS.with(|c| c.set(0));
243 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
244 SINGLE_TRANS_BODY.with(|c| c.set(0));
245 MULTI_TRANS_BODY.with(|c| c.set(0));
246 SINGLE_TRANS_RULE.with(|c| c.set(0));
247 SINGLE_TRANS_ATOM.with(|c| c.set(0));
248 SINGLE_TRANS_OTHER.with(|c| c.set(0));
249 OUTCOMES_RETURN_0.with(|c| c.set(0));
250 OUTCOMES_RETURN_1.with(|c| c.set(0));
251 OUTCOMES_RETURN_N.with(|c| c.set(0));
252 }
253 pub fn dump() {
254 for (name, value) in snapshot() {
255 #[allow(clippy::print_stderr)]
256 {
257 eprintln!("perf {name}={value}");
258 }
259 }
260 }
261}
262
263#[cfg(feature = "perf-counters")]
264pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
265const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
270#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
279pub struct ParserAction {
280 source_state: usize,
281 rule_index: usize,
282 start_index: usize,
283 stop_index: Option<usize>,
284 rule_init: bool,
285 expected_state: Option<usize>,
286}
287
288impl ParserAction {
289 pub const fn new(
291 source_state: usize,
292 rule_index: usize,
293 start_index: usize,
294 stop_index: Option<usize>,
295 ) -> Self {
296 Self {
297 source_state,
298 rule_index,
299 start_index,
300 stop_index,
301 rule_init: false,
302 expected_state: None,
303 }
304 }
305
306 pub const fn new_rule_init(
308 rule_index: usize,
309 start_index: usize,
310 expected_state: Option<usize>,
311 ) -> Self {
312 Self {
313 source_state: usize::MAX,
314 rule_index,
315 start_index,
316 stop_index: None,
317 rule_init: true,
318 expected_state,
319 }
320 }
321
322 pub const fn source_state(&self) -> usize {
324 self.source_state
325 }
326
327 pub const fn rule_index(&self) -> usize {
329 self.rule_index
330 }
331
332 pub const fn start_index(&self) -> usize {
334 self.start_index
335 }
336
337 pub const fn stop_index(&self) -> Option<usize> {
339 self.stop_index
340 }
341
342 pub const fn is_rule_init(&self) -> bool {
344 self.rule_init
345 }
346
347 pub const fn expected_state(&self) -> Option<usize> {
349 self.expected_state
350 }
351}
352
353pub struct ParserSemCtx<'a, S>
361where
362 S: TokenSource,
363{
364 input: &'a mut CommonTokenStream<S>,
365 tree_storage: &'a ParseTreeStorage,
366 rule_index: usize,
367 coordinate_index: usize,
368 rule_name: Option<String>,
369 context: Option<&'a ParserRuleContext>,
370 tree: Option<ParseTree>,
371 local_int_arg: Option<(usize, i64)>,
372 member_values: &'a BTreeMap<usize, i64>,
373 action: Option<ParserAction>,
374}
375
376impl<S> std::fmt::Debug for ParserSemCtx<'_, S>
377where
378 S: TokenSource,
379{
380 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
381 f.debug_struct("ParserSemCtx")
382 .field("rule_index", &self.rule_index)
383 .field("coordinate_index", &self.coordinate_index)
384 .field("rule_name", &self.rule_name)
385 .field("context", &self.context)
386 .field("tree", &self.tree)
387 .field("local_int_arg", &self.local_int_arg)
388 .field("member_values", &self.member_values)
389 .field("action", &self.action)
390 .finish_non_exhaustive()
391 }
392}
393
394impl<'a, S> ParserSemCtx<'a, S>
395where
396 S: TokenSource,
397{
398 #[must_use]
400 pub const fn rule_index(&self) -> usize {
401 self.rule_index
402 }
403
404 #[must_use]
406 pub fn rule_name(&self) -> Option<&str> {
407 self.rule_name.as_deref()
408 }
409
410 #[must_use]
414 pub const fn coordinate_index(&self) -> usize {
415 self.coordinate_index
416 }
417
418 #[must_use]
420 pub fn input_index(&self) -> usize {
421 self.input.index()
422 }
423
424 pub fn la(&mut self, offset: isize) -> i32 {
426 self.input.la(offset)
427 }
428
429 pub fn lt(&self, offset: isize) -> Option<TokenView<'_>> {
431 self.input.lt(offset)
432 }
433
434 pub fn token_text(&self, offset: isize) -> Option<TokenView<'_>> {
436 self.lt(offset)
437 }
438
439 pub fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
446 self.input.get(index)
447 }
448
449 #[must_use]
452 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
453 self.context
454 }
455
456 #[must_use]
458 pub const fn parse_tree_storage(&self) -> &'a ParseTreeStorage {
459 self.tree_storage
460 }
461
462 #[must_use]
464 pub const fn token_store(&self) -> &TokenStore {
465 self.input.token_store()
466 }
467
468 #[must_use]
470 pub const fn tree_id(&self) -> Option<NodeId> {
471 self.tree
472 }
473
474 #[must_use]
477 pub fn tree(&self) -> Option<Node<'_>> {
478 self.tree
479 .and_then(|id| self.tree_storage.node(self.input.token_store(), id))
480 }
481
482 #[must_use]
484 pub fn local_int_arg(&self) -> Option<i64> {
485 self.local_int_arg.map(|(_, value)| value)
486 }
487
488 #[must_use]
490 pub fn member_int(&self, member: usize) -> Option<i64> {
491 self.member_values.get(&member).copied()
492 }
493
494 #[must_use]
497 pub const fn action(&self) -> Option<ParserAction> {
498 self.action
499 }
500
501 pub fn action_text(&self) -> String {
509 let Some(action) = self.action else {
510 return String::new();
511 };
512 let Some(stop) = action.stop_index() else {
513 return String::new();
514 };
515 let stop = if self
516 .input
517 .get(stop)
518 .is_some_and(|token| token.token_type() == TOKEN_EOF)
519 {
520 let Some(previous) = self.input.previous_visible_token_index(stop) else {
521 return String::new();
522 };
523 previous
524 } else {
525 stop
526 };
527 self.input.text(action.start_index(), stop)
528 }
529}
530
531pub trait SemanticHooks {
538 const ENABLES_LEXER_LIFECYCLE: bool = true;
545
546 fn observes_parser_predicates(&self) -> bool {
551 true
552 }
553
554 fn sempred<S>(
555 &mut self,
556 ctx: &mut ParserSemCtx<'_, S>,
557 rule_index: usize,
558 pred_index: usize,
559 ) -> Option<bool>
560 where
561 S: TokenSource,
562 {
563 let _ = (ctx, rule_index, pred_index);
564 None
565 }
566
567 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
568 where
569 S: TokenSource,
570 {
571 let _ = (ctx, action);
572 false
573 }
574
575 fn lexer_sempred<I>(
576 &mut self,
577 ctx: &mut LexerSemCtx<'_, I>,
578 rule_index: usize,
579 pred_index: usize,
580 ) -> Option<bool>
581 where
582 I: CharStream,
583 {
584 let _ = (ctx, rule_index, pred_index);
585 None
586 }
587
588 fn lexer_action<I>(&mut self, ctx: &mut LexerSemCtx<'_, I>, action: LexerCustomAction) -> bool
598 where
599 I: CharStream,
600 {
601 let _ = (ctx, action);
602 false
603 }
604
605 fn lexer_reset<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
609 where
610 I: CharStream,
611 {
612 let _ = ctx;
613 }
614
615 fn lexer_before_token<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
621 where
622 I: CharStream,
623 {
624 let _ = ctx;
625 }
626
627 fn lexer_after_accept<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
636 where
637 I: CharStream,
638 {
639 let _ = ctx;
640 }
641
642 fn lexer_token_emitted(&mut self, token: TokenView<'_>) {
649 let _ = token;
650 }
651}
652
653#[derive(Clone, Copy, Debug, Default)]
656pub struct NoSemanticHooks;
657
658impl SemanticHooks for NoSemanticHooks {
659 const ENABLES_LEXER_LIFECYCLE: bool = false;
660
661 fn observes_parser_predicates(&self) -> bool {
662 false
663 }
664}
665
666#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
673pub enum ParserPredicate {
674 True,
675 False,
676 FalseWithMessage {
678 message: &'static str,
679 },
680 Invoke {
683 value: bool,
684 },
685 LookaheadTextEquals {
686 offset: isize,
687 text: &'static str,
688 },
689 LookaheadNotEquals {
690 offset: isize,
691 token_type: i32,
692 },
693 TokenPairAdjacent,
696 ContextChildRuleTextNotEquals {
701 rule_index: usize,
702 text: &'static str,
703 },
704 LocalIntEquals {
707 value: i64,
708 },
709 LocalIntLessOrEqual {
712 value: i64,
713 },
714 MemberModuloEquals {
716 member: usize,
717 modulus: i64,
718 value: i64,
719 equals: bool,
720 },
721 MemberEquals {
723 member: usize,
724 value: i64,
725 equals: bool,
726 },
727}
728
729impl ParserPredicate {
730 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
736 match self {
737 Self::True => ir.expr(PExpr::Bool(true)),
738 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
739 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
740 Self::LookaheadTextEquals { offset, text } => {
741 let token = ir.expr(PExpr::TokenText(offset));
742 let text = ir.intern(text);
743 let text = ir.expr(PExpr::Str(text));
744 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
745 }
746 Self::LookaheadNotEquals { offset, token_type } => {
747 let actual = ir.expr(PExpr::La(offset));
748 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
749 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
750 }
751 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
752 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
753 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
754 let expected = ir.intern(text);
755 let expected = ir.expr(PExpr::Str(expected));
756 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
757 }
758 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
759 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
760 Self::MemberModuloEquals {
761 member,
762 modulus,
763 value,
764 equals,
765 } => {
766 if modulus == 0 {
767 return ir.expr(PExpr::Bool(false));
768 }
769 let member = ir.expr(PExpr::Member(member));
770 let modulus = ir.expr(PExpr::Int(modulus));
771 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
772 let expected = ir.expr(PExpr::Int(value));
773 ir.expr(PExpr::Cmp(
774 if equals { CmpOp::Eq } else { CmpOp::Ne },
775 actual,
776 expected,
777 ))
778 }
779 Self::MemberEquals {
780 member,
781 value,
782 equals,
783 } => {
784 let actual = ir.expr(PExpr::Member(member));
785 let expected = ir.expr(PExpr::Int(value));
786 ir.expr(PExpr::Cmp(
787 if equals { CmpOp::Eq } else { CmpOp::Ne },
788 actual,
789 expected,
790 ))
791 }
792 }
793 }
794
795 #[must_use]
796 pub const fn failure_message(self) -> Option<&'static str> {
797 match self {
798 Self::FalseWithMessage { message } => Some(message),
799 Self::True
800 | Self::False
801 | Self::Invoke { .. }
802 | Self::LookaheadTextEquals { .. }
803 | Self::LookaheadNotEquals { .. }
804 | Self::TokenPairAdjacent
805 | Self::ContextChildRuleTextNotEquals { .. }
806 | Self::LocalIntEquals { .. }
807 | Self::LocalIntLessOrEqual { .. }
808 | Self::MemberModuloEquals { .. }
809 | Self::MemberEquals { .. } => None,
810 }
811 }
812}
813
814fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
815 let local = ir.expr(PExpr::LocalArg);
816 let absent = ir.expr(PExpr::IsNull(local));
817 let expected = ir.expr(PExpr::Int(value));
818 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
819 ir.expr(PExpr::Or([absent, comparison].into()))
820}
821
822#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
835pub enum UnknownSemanticPolicy {
836 #[default]
838 AssumeTrue,
839 AssumeFalse,
841 Error,
844}
845
846fn apply_unknown_predicate_policy(
855 policy: UnknownSemanticPolicy,
856 rule_index: usize,
857 pred_index: usize,
858 hits: &mut Vec<(usize, usize)>,
859) -> bool {
860 match policy {
861 UnknownSemanticPolicy::AssumeTrue => true,
862 UnknownSemanticPolicy::AssumeFalse => false,
863 UnknownSemanticPolicy::Error => {
864 let coordinate = (rule_index, pred_index);
865 if !hits.contains(&coordinate) {
866 hits.push(coordinate);
867 }
868 false
869 }
870 }
871}
872
873#[derive(Clone, Debug, Eq, PartialEq)]
877pub struct ExpectedTokenSet {
878 symbols: BTreeSet<i32>,
879}
880
881impl ExpectedTokenSet {
882 #[must_use]
884 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
885 expected_symbols_display(&self.symbols, vocabulary)
886 }
887}
888
889#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
894pub struct BailErrorStrategy;
895
896impl BailErrorStrategy {
897 #[must_use]
898 pub const fn new() -> Self {
899 Self
900 }
901}
902
903#[derive(Clone, Copy, Debug, Eq, PartialEq)]
905pub enum PredictionMode {
906 Ll,
909 Sll,
912 LlExactAmbigDetection,
914}
915
916#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
922pub struct ParserRuleArg {
923 pub source_state: usize,
925 pub rule_index: usize,
927 pub value: i64,
929 pub inherit_local: bool,
931}
932
933#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
935pub struct ParserMemberAction {
936 pub source_state: usize,
938 pub member: usize,
940 pub delta: i64,
942}
943
944#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
951pub struct ParserReturnAction {
952 pub source_state: usize,
954 pub rule_index: usize,
956 pub name: &'static str,
958 pub value: i64,
960}
961
962impl ParserMemberAction {
963 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
965 let delta = ir.expr(PExpr::Int(self.delta));
966 ParserSemanticAction {
967 source_state: self.source_state,
968 rule_index: usize::MAX,
969 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
970 speculative: true,
971 }
972 }
973}
974
975impl ParserReturnAction {
976 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
978 let name = ir.intern(self.name);
979 let value = ir.expr(PExpr::Int(self.value));
980 ParserSemanticAction {
981 source_state: self.source_state,
982 rule_index: self.rule_index,
983 stmt: ir.stmt(AStmt::SetReturn(name, value)),
984 speculative: false,
985 }
986 }
987}
988
989#[derive(Clone, Copy, Debug, Eq, PartialEq)]
991pub struct ParserSemanticPredicate {
992 pub rule_index: usize,
994 pub pred_index: usize,
996 pub expr: ExprId,
998 pub failure_message: Option<&'static str>,
1000}
1001
1002#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1004pub struct ParserSemanticAction {
1005 pub source_state: usize,
1007 pub rule_index: usize,
1009 pub stmt: StmtId,
1011 pub speculative: bool,
1013}
1014
1015#[derive(Clone, Debug, Default, Eq, PartialEq)]
1022pub struct ParserSemantics {
1023 pub ir: SemIr,
1024 pub predicates: Vec<ParserSemanticPredicate>,
1025 pub actions: Vec<ParserSemanticAction>,
1026}
1027
1028#[derive(Clone, Copy, Debug, Default)]
1030pub struct ParserRuntimeOptions<'a> {
1031 pub init_action_rules: &'a [usize],
1033 pub track_alt_numbers: bool,
1035 pub predicates: &'a [(usize, usize, ParserPredicate)],
1037 pub semantics: Option<&'a ParserSemantics>,
1039 pub rule_args: &'a [ParserRuleArg],
1041 pub member_actions: &'a [ParserMemberAction],
1043 pub return_actions: &'a [ParserReturnAction],
1045 pub unknown_predicate_policy: UnknownSemanticPolicy,
1048}
1049
1050pub trait Parser: Recognizer {
1051 fn build_parse_trees(&self) -> bool;
1054
1055 fn set_build_parse_trees(&mut self, build: bool);
1057
1058 fn number_of_syntax_errors(&self) -> usize {
1061 0
1062 }
1063
1064 fn report_diagnostic_errors(&self) -> bool {
1067 false
1068 }
1069
1070 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
1073
1074 fn prediction_mode(&self) -> PredictionMode {
1076 PredictionMode::Ll
1077 }
1078
1079 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
1081}
1082
1083#[derive(Debug)]
1084struct LeftRecursiveCallerOverlap {
1085 atn_key: SharedAtnCacheKey,
1086 state_number: usize,
1087 symbol: i32,
1088 context_version: usize,
1089 overlaps: bool,
1090}
1091
1092const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
1093
1094#[derive(Debug)]
1095pub struct BaseParser<S, H = NoSemanticHooks> {
1096 input: CommonTokenStream<S>,
1097 tree: ParseTreeStorage,
1098 data: RecognizerData,
1099 semantic_hooks: H,
1100 build_parse_trees: bool,
1101 syntax_errors: usize,
1102 report_diagnostic_errors: bool,
1103 prediction_mode: PredictionMode,
1104 prediction_diagnostics: Vec<ParserDiagnostic>,
1105 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1106 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1107 generated_sync_expected: Option<TokenBitSet>,
1108 int_members: BTreeMap<usize, i64>,
1109 rule_context_stack: Vec<RuleContextFrame>,
1110 rule_context_version: usize,
1111 left_recursive_caller_overlap_cache:
1112 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1113 pending_invoking_states: Vec<isize>,
1114 precedence_stack: Vec<i32>,
1115 invoked_predicates: Vec<(usize, usize)>,
1119 bail_on_error: bool,
1123 unknown_predicate_policy: UnknownSemanticPolicy,
1126 unknown_predicate_hits: Vec<(usize, usize)>,
1129 unhandled_action_hits: Vec<(usize, usize)>,
1134 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1139 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1145 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1150 rule_stop_reach_cache: Vec<Option<bool>>,
1155 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1160 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1166 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1172 fast_predicate_cache: FxHashMap<(usize, usize, usize), bool>,
1176 empty_cycle_cache: Vec<Option<bool>>,
1180 single_outcome_memo_mode: SingleOutcomeMemoMode,
1183 single_outcome_probe_seen: FxHashSet<FastRecognizeKey>,
1184 single_outcome_probe_samples: usize,
1185 single_outcome_probe_repeats: usize,
1186 fast_outcome_dedup: FastOutcomeDedupScratch,
1188 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1191 fast_first_set_prefilter: bool,
1199 fast_recovery_enabled: bool,
1203 fast_token_nodes_enabled: bool,
1208 recognition_arena: RecognitionArena,
1212 last_recognition_arena_root: NodeSeqId,
1213 last_recognition_arena_diagnostics: DiagnosticSeqId,
1214}
1215
1216#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1218pub struct GeneratedDiagnosticsCheckpoint {
1219 diagnostics_len: usize,
1220 syntax_errors: usize,
1221 tree: ParseTreeCheckpoint,
1222}
1223
1224#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1227pub struct RecognitionArenaStats {
1228 pub total_nodes: usize,
1229 pub live_nodes: usize,
1230 pub dead_nodes: usize,
1231 pub node_capacity: usize,
1232 pub total_links: usize,
1233 pub live_links: usize,
1234 pub dead_links: usize,
1235 pub link_capacity: usize,
1236 pub total_extras: usize,
1237 pub live_extras: usize,
1238 pub dead_extras: usize,
1239 pub extra_capacity: usize,
1240}
1241
1242#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1243struct RuleContextFrame {
1244 rule_index: usize,
1245 invoking_state: isize,
1246}
1247
1248#[derive(Clone, Debug, Eq, PartialEq)]
1249struct RecognizeOutcome {
1250 index: usize,
1251 consumed_eof: bool,
1252 alt_number: usize,
1253 member_values: BTreeMap<usize, i64>,
1254 return_values: BTreeMap<String, i64>,
1255 diagnostics: DiagnosticSeqId,
1256 decisions: Vec<usize>,
1257 actions: Vec<ParserAction>,
1258 nodes: NodeSeqId,
1259}
1260
1261#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1262struct FastRecognizeOutcome {
1263 index: usize,
1264 consumed_eof: bool,
1265 diagnostics: DiagnosticSeqId,
1266 deferred_nodes: FastDeferredNodeId,
1267 nodes: NodeSeqId,
1271}
1272
1273#[derive(Debug, Default)]
1274struct FastOutcomeDedupScratch {
1275 dense_words: Vec<u64>,
1276 touched_dense_words: Vec<u32>,
1277 sparse_keys: FxHashSet<(usize, bool)>,
1278}
1279
1280#[repr(transparent)]
1285#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1286struct FastDeferredNodeId(u32);
1287
1288impl FastDeferredNodeId {
1289 const EMPTY: Self = Self(u32::MAX);
1290
1291 const fn is_empty(self) -> bool {
1292 self.0 == Self::EMPTY.0
1293 }
1294}
1295
1296impl Default for FastDeferredNodeId {
1297 fn default() -> Self {
1298 Self::EMPTY
1299 }
1300}
1301
1302#[repr(transparent)]
1303#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1304struct FastDeferredRuleId(u32);
1305
1306#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1308enum FastDeferredNode {
1309 Fragment(NodeSeqId),
1310 Rule(FastDeferredRuleId),
1311 Concat {
1312 prefix: FastDeferredNodeId,
1313 suffix: FastDeferredNodeId,
1314 },
1315}
1316
1317#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1318struct FastDeferredRule {
1319 rule_index: u32,
1320 invoking_state: i32,
1321 start_index: u32,
1322 stop_index: Option<u32>,
1323 deferred_children: FastDeferredNodeId,
1324 children: NodeSeqId,
1325}
1326
1327#[repr(transparent)]
1328#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1329struct RecognizedNodeId(u32);
1330
1331#[repr(transparent)]
1332#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1333struct NodeSeqId(u32);
1334
1335impl NodeSeqId {
1336 const EMPTY: Self = Self(u32::MAX);
1337
1338 const fn is_empty(self) -> bool {
1339 self.0 == Self::EMPTY.0
1340 }
1341}
1342
1343impl Default for NodeSeqId {
1344 fn default() -> Self {
1345 Self::EMPTY
1346 }
1347}
1348
1349#[repr(transparent)]
1350#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1351struct DiagnosticSeqId(u32);
1352
1353impl DiagnosticSeqId {
1354 const EMPTY: Self = Self(u32::MAX);
1355
1356 const fn is_empty(self) -> bool {
1357 self.0 == Self::EMPTY.0
1358 }
1359}
1360
1361impl Default for DiagnosticSeqId {
1362 fn default() -> Self {
1363 Self::EMPTY
1364 }
1365}
1366
1367#[repr(transparent)]
1368#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1369struct RecognitionExtraId(u32);
1370
1371#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1372struct SeqLink {
1373 head: RecognizedNodeId,
1374 tail: NodeSeqId,
1375}
1376
1377#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1378struct DiagnosticLink {
1379 head: RecognitionExtraId,
1380 tail: DiagnosticSeqId,
1381}
1382
1383struct ArenaRuleSpec {
1384 rule_index: usize,
1385 invoking_state: isize,
1386 alt_number: usize,
1387 start_index: usize,
1388 stop_index: Option<usize>,
1389 return_values: BTreeMap<String, i64>,
1390 children: NodeSeqId,
1391}
1392
1393#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1396enum ArenaRecognizedNode {
1397 Token {
1398 token: TokenId,
1399 },
1400 ErrorToken {
1401 token: TokenId,
1402 },
1403 MissingToken {
1404 extra: RecognitionExtraId,
1405 },
1406 Rule {
1407 rule_index: u32,
1408 invoking_state: i32,
1409 alt_number: u32,
1410 start_index: u32,
1411 stop_index: Option<u32>,
1412 return_values: Option<RecognitionExtraId>,
1413 children: NodeSeqId,
1414 },
1415 LeftRecursiveBoundary {
1419 rule_index: u32,
1420 },
1421}
1422
1423#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1424enum RecognitionExtra {
1425 MissingToken {
1426 token_type: i32,
1427 at_index: u32,
1428 text: String,
1429 },
1430 ReturnValues(BTreeMap<String, i64>),
1431 Diagnostic(ParserDiagnostic),
1432}
1433
1434#[derive(Debug, Default)]
1435struct RecognitionArena {
1436 nodes: Vec<ArenaRecognizedNode>,
1437 seq_links: Vec<SeqLink>,
1438 diagnostic_links: Vec<DiagnosticLink>,
1439 extras: Vec<RecognitionExtra>,
1440 deferred_nodes: Vec<FastDeferredNode>,
1441 deferred_rules: Vec<FastDeferredRule>,
1442}
1443
1444const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1447const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1448const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1449const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1450const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1451const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1452
1453impl RecognitionArena {
1454 fn reset(&mut self) {
1455 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1456 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1457 reset_arena_vec(
1458 &mut self.diagnostic_links,
1459 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1460 );
1461 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1462 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1463 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1464 }
1465
1466 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1467 let id = RecognizedNodeId(
1468 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1469 );
1470 self.nodes.push(node);
1471 id
1472 }
1473
1474 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1475 let id = RecognitionExtraId(
1476 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1477 );
1478 self.extras.push(extra);
1479 id
1480 }
1481
1482 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1483 let id = NodeSeqId(
1484 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1485 );
1486 self.seq_links.push(SeqLink { head, tail });
1487 id
1488 }
1489
1490 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1491 let id = FastDeferredNodeId(
1492 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
1493 );
1494 self.deferred_nodes.push(node);
1495 id
1496 }
1497
1498 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
1499 let id = FastDeferredRuleId(
1500 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
1501 );
1502 self.deferred_rules.push(rule);
1503 id
1504 }
1505
1506 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
1507 if nodes.is_empty() {
1508 FastDeferredNodeId::EMPTY
1509 } else {
1510 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
1511 }
1512 }
1513
1514 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
1515 let rule = self.push_deferred_rule(rule);
1516 self.push_deferred_node(FastDeferredNode::Rule(rule))
1517 }
1518
1519 fn concat_deferred_nodes(
1520 &mut self,
1521 prefix: FastDeferredNodeId,
1522 suffix: FastDeferredNodeId,
1523 ) -> FastDeferredNodeId {
1524 if prefix.is_empty() {
1525 return suffix;
1526 }
1527 if suffix.is_empty() {
1528 return prefix;
1529 }
1530 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
1531 }
1532
1533 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
1534 self.deferred_nodes[id.0 as usize]
1535 }
1536
1537 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
1538 self.deferred_rules[id.0 as usize]
1539 }
1540
1541 fn prepend_diagnostic(
1542 &mut self,
1543 tail: DiagnosticSeqId,
1544 diagnostic: ParserDiagnostic,
1545 ) -> DiagnosticSeqId {
1546 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
1547 self.prepend_diagnostic_id(tail, head)
1548 }
1549
1550 fn prepend_diagnostic_id(
1551 &mut self,
1552 tail: DiagnosticSeqId,
1553 head: RecognitionExtraId,
1554 ) -> DiagnosticSeqId {
1555 let id = DiagnosticSeqId(
1556 u32::try_from(self.diagnostic_links.len())
1557 .expect("diagnostic sequence arena fits in u32"),
1558 );
1559 self.diagnostic_links.push(DiagnosticLink { head, tail });
1560 id
1561 }
1562
1563 fn concat_diagnostics(
1564 &mut self,
1565 prefix: DiagnosticSeqId,
1566 mut suffix: DiagnosticSeqId,
1567 ) -> DiagnosticSeqId {
1568 if prefix.is_empty() {
1569 return suffix;
1570 }
1571 if suffix.is_empty() {
1572 return prefix;
1573 }
1574 let mut reversed = DiagnosticSeqId::EMPTY;
1575 let mut cursor = prefix;
1576 while let Some(link) = self.diagnostic_link(cursor) {
1577 reversed = self.prepend_diagnostic_id(reversed, link.head);
1578 cursor = link.tail;
1579 }
1580 while let Some(link) = self.diagnostic_link(reversed) {
1581 suffix = self.prepend_diagnostic_id(suffix, link.head);
1582 reversed = link.tail;
1583 }
1584 suffix
1585 }
1586
1587 #[cfg(test)]
1588 fn diagnostic_sequence(
1589 &mut self,
1590 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
1591 ) -> DiagnosticSeqId {
1592 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
1593 let mut sequence = DiagnosticSeqId::EMPTY;
1594 for diagnostic in diagnostics.into_iter().rev() {
1595 sequence = self.prepend_diagnostic(sequence, diagnostic);
1596 }
1597 sequence
1598 }
1599
1600 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
1601 self.nodes[id.0 as usize]
1602 }
1603
1604 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
1605 &self.extras[id.0 as usize]
1606 }
1607
1608 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
1609 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
1610 }
1611
1612 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
1613 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
1614 }
1615
1616 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
1617 NodeSeqIter {
1618 arena: self,
1619 cursor: sequence,
1620 }
1621 }
1622
1623 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
1624 DiagnosticSeqIter {
1625 arena: self,
1626 cursor: sequence,
1627 }
1628 }
1629
1630 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
1631 self.diagnostics(sequence).count()
1632 }
1633
1634 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
1635 self.diagnostics(sequence)
1636 .filter(|diagnostic| {
1637 diagnostic.message.starts_with("mismatched input ")
1638 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
1639 })
1640 .count()
1641 }
1642
1643 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
1644 self.diagnostics(left).cmp(self.diagnostics(right))
1645 }
1646
1647 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
1648 self.iter(sequence).count()
1649 }
1650
1651 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
1652 self.iter(sequence).any(|node| match self.node(node) {
1653 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1654 ArenaRecognizedNode::Rule { children, .. } => {
1655 self.sequence_has_left_recursive_boundary(children)
1656 }
1657 ArenaRecognizedNode::Token { .. }
1658 | ArenaRecognizedNode::ErrorToken { .. }
1659 | ArenaRecognizedNode::MissingToken { .. } => false,
1660 })
1661 }
1662
1663 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
1664 self.iter(sequence).any(|node| {
1665 matches!(
1666 self.node(node),
1667 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
1668 )
1669 })
1670 }
1671
1672 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
1673 self.iter(sequence).any(|node| {
1674 matches!(
1675 self.node(node),
1676 ArenaRecognizedNode::Token { .. }
1677 | ArenaRecognizedNode::ErrorToken { .. }
1678 | ArenaRecognizedNode::MissingToken { .. }
1679 )
1680 })
1681 }
1682
1683 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
1684 match self.node(node) {
1685 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1686 Some(token.index())
1687 }
1688 ArenaRecognizedNode::MissingToken { extra } => {
1689 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1690 unreachable!("missing-token node must reference missing-token extra");
1691 };
1692 Some(*at_index as usize)
1693 }
1694 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
1695 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1696 }
1697 }
1698
1699 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
1700 match self.node(node) {
1701 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1702 Some(token.index())
1703 }
1704 ArenaRecognizedNode::MissingToken { extra } => {
1705 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1706 unreachable!("missing-token node must reference missing-token extra");
1707 };
1708 (*at_index as usize).checked_sub(1)
1709 }
1710 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
1711 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1712 }
1713 }
1714
1715 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
1716 let start = self.node_start_index(node)?;
1717 let stop = self.node_stop_index(node);
1718 Some((start, stop))
1719 }
1720
1721 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
1722 self.iter(sequence)
1723 .find_map(|node| self.node_start_index(node))
1724 }
1725
1726 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
1727 let mut stop = None;
1728 for node in self.iter(sequence) {
1729 if let Some(index) = self.node_stop_index(node) {
1730 stop = Some(index);
1731 }
1732 }
1733 stop
1734 }
1735
1736 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
1737 self.iter(sequence)
1738 .any(|node| self.node_needs_stable_tie(node))
1739 }
1740
1741 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
1742 match self.node(node) {
1743 ArenaRecognizedNode::Token { .. }
1744 | ArenaRecognizedNode::ErrorToken { .. }
1745 | ArenaRecognizedNode::MissingToken { .. } => false,
1746 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1747 ArenaRecognizedNode::Rule {
1748 rule_index,
1749 children,
1750 ..
1751 } => self.iter(children).any(|child| {
1752 matches!(
1753 self.node(child),
1754 ArenaRecognizedNode::Rule {
1755 rule_index: child_rule,
1756 ..
1757 } if child_rule == rule_index
1758 ) || self.node_needs_stable_tie(child)
1759 }),
1760 }
1761 }
1762
1763 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
1764 loop {
1765 match (self.link(left), self.link(right)) {
1766 (Some(left_link), Some(right_link)) => {
1767 let order = self.compare_nodes(left_link.head, right_link.head);
1768 if order != Ordering::Equal {
1769 return order;
1770 }
1771 left = left_link.tail;
1772 right = right_link.tail;
1773 }
1774 (None, None) => return Ordering::Equal,
1775 (None, Some(_)) => return Ordering::Less,
1776 (Some(_), None) => return Ordering::Greater,
1777 }
1778 }
1779 }
1780
1781 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
1782 let left = self.node(left);
1783 let right = self.node(right);
1784 match (left, right) {
1785 (
1786 ArenaRecognizedNode::Token { token: left },
1787 ArenaRecognizedNode::Token { token: right },
1788 )
1789 | (
1790 ArenaRecognizedNode::ErrorToken { token: left },
1791 ArenaRecognizedNode::ErrorToken { token: right },
1792 ) => left.cmp(&right),
1793 (
1794 ArenaRecognizedNode::MissingToken { extra: left },
1795 ArenaRecognizedNode::MissingToken { extra: right },
1796 ) => self.extra(left).cmp(self.extra(right)),
1797 (
1798 ArenaRecognizedNode::Rule {
1799 rule_index: left_rule,
1800 invoking_state: left_invoking,
1801 alt_number: left_alt,
1802 start_index: left_start,
1803 stop_index: left_stop,
1804 return_values: left_returns,
1805 children: left_children,
1806 },
1807 ArenaRecognizedNode::Rule {
1808 rule_index: right_rule,
1809 invoking_state: right_invoking,
1810 alt_number: right_alt,
1811 start_index: right_start,
1812 stop_index: right_stop,
1813 return_values: right_returns,
1814 children: right_children,
1815 },
1816 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
1817 .cmp(&(
1818 right_rule,
1819 right_invoking,
1820 right_alt,
1821 right_start,
1822 right_stop,
1823 ))
1824 .then_with(|| {
1825 left_returns
1826 .map(|id| self.extra(id))
1827 .cmp(&right_returns.map(|id| self.extra(id)))
1828 })
1829 .then_with(|| self.compare_sequences(left_children, right_children)),
1830 (
1831 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: left },
1832 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: right },
1833 ) => left.cmp(&right),
1834 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
1835 }
1836 }
1837
1838 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1839 let mut reversed = NodeSeqId::EMPTY;
1840 while let Some(link) = self.link(sequence) {
1841 reversed = self.prepend(reversed, link.head);
1842 sequence = link.tail;
1843 }
1844 reversed
1845 }
1846
1847 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1848 if !self.sequence_has_direct_boundary(sequence) {
1849 return sequence;
1850 }
1851 let mut reversed = NodeSeqId::EMPTY;
1852 while let Some(link) = self.link(sequence) {
1853 match self.node(link.head) {
1854 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index } => {
1855 if !reversed.is_empty() {
1856 let children = self.reverse_sequence(reversed);
1857 let start_index = self.sequence_start_index(children).unwrap_or_default();
1858 let stop_index = self.sequence_stop_index(children);
1859 let rule = self.push_node(ArenaRecognizedNode::Rule {
1860 rule_index,
1861 invoking_state: -1,
1862 alt_number: 0,
1863 start_index: u32::try_from(start_index)
1864 .expect("left-recursive start index fits in u32"),
1865 stop_index: stop_index.map(|index| {
1866 u32::try_from(index).expect("left-recursive stop index fits in u32")
1867 }),
1868 return_values: None,
1869 children,
1870 });
1871 reversed = self.prepend(NodeSeqId::EMPTY, rule);
1872 }
1873 }
1874 _ => {
1875 reversed = self.prepend(reversed, link.head);
1876 }
1877 }
1878 sequence = link.tail;
1879 }
1880 self.reverse_sequence(reversed)
1881 }
1882
1883 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
1884 let mut live_nodes = vec![false; self.nodes.len()];
1885 let mut live_links = vec![false; self.seq_links.len()];
1886 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
1887 let mut live_extras = vec![false; self.extras.len()];
1888 let mut pending = vec![root];
1889 while let Some(mut sequence) = pending.pop() {
1890 while let Some(link) = self.link(sequence) {
1891 let link_index = sequence.0 as usize;
1892 if live_links[link_index] {
1893 break;
1894 }
1895 live_links[link_index] = true;
1896 let node_index = link.head.0 as usize;
1897 if !live_nodes[node_index] {
1898 live_nodes[node_index] = true;
1899 match self.node(link.head) {
1900 ArenaRecognizedNode::MissingToken { extra } => {
1901 live_extras[extra.0 as usize] = true;
1902 }
1903 ArenaRecognizedNode::Rule {
1904 return_values,
1905 children,
1906 ..
1907 } => {
1908 if let Some(extra) = return_values {
1909 live_extras[extra.0 as usize] = true;
1910 }
1911 pending.push(children);
1912 }
1913 ArenaRecognizedNode::Token { .. }
1914 | ArenaRecognizedNode::ErrorToken { .. }
1915 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
1916 }
1917 }
1918 sequence = link.tail;
1919 }
1920 }
1921 let mut diagnostics = diagnostics;
1922 while let Some(link) = self.diagnostic_link(diagnostics) {
1923 let link_index = diagnostics.0 as usize;
1924 if live_diagnostic_links[link_index] {
1925 break;
1926 }
1927 live_diagnostic_links[link_index] = true;
1928 live_extras[link.head.0 as usize] = true;
1929 diagnostics = link.tail;
1930 }
1931 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
1932 let live_link_count = live_links.into_iter().filter(|live| *live).count()
1933 + live_diagnostic_links
1934 .into_iter()
1935 .filter(|live| *live)
1936 .count();
1937 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
1938 let total_links = self.seq_links.len() + self.diagnostic_links.len();
1939 RecognitionArenaStats {
1940 total_nodes: self.nodes.len(),
1941 live_nodes: live_node_count,
1942 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
1943 node_capacity: self.nodes.capacity(),
1944 total_links,
1945 live_links: live_link_count,
1946 dead_links: total_links.saturating_sub(live_link_count),
1947 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
1948 total_extras: self.extras.len(),
1949 live_extras: live_extra_count,
1950 dead_extras: self.extras.len().saturating_sub(live_extra_count),
1951 extra_capacity: self.extras.capacity(),
1952 }
1953 }
1954}
1955
1956fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
1957 if storage.capacity() > max_retained_capacity {
1958 *storage = Vec::new();
1959 } else {
1960 storage.clear();
1961 }
1962}
1963
1964const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
1965 match node {
1966 ArenaRecognizedNode::Token { .. } => 0,
1967 ArenaRecognizedNode::ErrorToken { .. } => 1,
1968 ArenaRecognizedNode::MissingToken { .. } => 2,
1969 ArenaRecognizedNode::Rule { .. } => 3,
1970 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
1971 }
1972}
1973
1974struct NodeSeqIter<'a> {
1975 arena: &'a RecognitionArena,
1976 cursor: NodeSeqId,
1977}
1978
1979impl Iterator for NodeSeqIter<'_> {
1980 type Item = RecognizedNodeId;
1981
1982 fn next(&mut self) -> Option<Self::Item> {
1983 let link = self.arena.link(self.cursor)?;
1984 self.cursor = link.tail;
1985 Some(link.head)
1986 }
1987}
1988
1989struct DiagnosticSeqIter<'a> {
1990 arena: &'a RecognitionArena,
1991 cursor: DiagnosticSeqId,
1992}
1993
1994impl<'a> Iterator for DiagnosticSeqIter<'a> {
1995 type Item = &'a ParserDiagnostic;
1996
1997 fn next(&mut self) -> Option<Self::Item> {
1998 let link = self.arena.diagnostic_link(self.cursor)?;
1999 self.cursor = link.tail;
2000 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2001 unreachable!("diagnostic link must reference diagnostic extra");
2002 };
2003 Some(diagnostic)
2004 }
2005}
2006
2007#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2008struct ParserDiagnostic {
2009 line: usize,
2010 column: usize,
2011 message: String,
2012}
2013
2014#[derive(Clone, Debug, Default, Eq, PartialEq)]
2015struct ExpectedTokens {
2016 index: Option<usize>,
2017 symbols: BTreeSet<i32>,
2018 no_viable: Option<NoViableAlternative>,
2019}
2020
2021#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2022struct NoViableAlternative {
2023 start_index: usize,
2024 error_index: usize,
2025}
2026
2027impl ExpectedTokens {
2028 fn record_transition(
2031 &mut self,
2032 index: usize,
2033 transition: ParserTransition<'_>,
2034 max_token_type: i32,
2035 ) {
2036 let symbols = transition_expected_symbols(transition, max_token_type);
2037 match self.index {
2038 Some(current) if index < current => {}
2039 Some(current) if index == current => self.symbols.extend(symbols),
2040 _ => {
2041 self.index = Some(index);
2042 self.symbols = symbols;
2043 }
2044 }
2045 }
2046
2047 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2050 match self.no_viable {
2051 Some(current) if error_index < current.error_index => {}
2052 _ => {
2053 self.no_viable = Some(NoViableAlternative {
2054 start_index,
2055 error_index,
2056 });
2057 }
2058 }
2059 }
2060}
2061
2062#[derive(Clone, Debug, Default, Eq, PartialEq)]
2069struct TokenBitSet {
2070 words: Vec<u64>,
2071}
2072
2073impl TokenBitSet {
2074 fn insert(&mut self, symbol: i32) {
2075 let Some(slot) = token_bit_slot(symbol) else {
2076 return;
2077 };
2078 let word = slot / u64::BITS as usize;
2079 if word >= self.words.len() {
2080 self.words.resize(word + 1, 0);
2081 }
2082 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2083 }
2084
2085 fn extend_range(&mut self, start: i32, stop: i32) {
2086 let (start, stop) = if start <= stop {
2087 (start, stop)
2088 } else {
2089 (stop, start)
2090 };
2091 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2092 self.insert(TOKEN_EOF);
2093 }
2094 let positive_start = start.max(1);
2095 if positive_start > stop {
2096 return;
2097 }
2098 let Some(start_slot) = token_bit_slot(positive_start) else {
2099 return;
2100 };
2101 let Some(stop_slot) = token_bit_slot(stop) else {
2102 return;
2103 };
2104 self.extend_slot_range(start_slot, stop_slot);
2105 }
2106
2107 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2108 if start_slot > stop_slot {
2109 return;
2110 }
2111 let start_word = start_slot / u64::BITS as usize;
2112 let stop_word = stop_slot / u64::BITS as usize;
2113 if stop_word >= self.words.len() {
2114 self.words.resize(stop_word + 1, 0);
2115 }
2116 let start_offset = start_slot % u64::BITS as usize;
2117 let stop_offset = stop_slot % u64::BITS as usize;
2118 if start_word == stop_word {
2119 self.words[start_word] |=
2120 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2121 return;
2122 }
2123 self.words[start_word] |= !0_u64 << start_offset;
2124 for word in &mut self.words[(start_word + 1)..stop_word] {
2125 *word = !0_u64;
2126 }
2127 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2128 }
2129
2130 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2131 for symbol in symbols {
2132 self.insert(symbol);
2133 }
2134 }
2135
2136 fn extend_from(&mut self, other: &Self) {
2137 if other.words.len() > self.words.len() {
2138 self.words.resize(other.words.len(), 0);
2139 }
2140 for (left, right) in self.words.iter_mut().zip(&other.words) {
2141 *left |= *right;
2142 }
2143 }
2144
2145 fn contains(&self, symbol: i32) -> bool {
2146 let Some(slot) = token_bit_slot(symbol) else {
2147 return false;
2148 };
2149 let word = slot / u64::BITS as usize;
2150 self.words
2151 .get(word)
2152 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2153 }
2154
2155 fn is_empty(&self) -> bool {
2156 self.words.iter().all(|word| *word == 0)
2157 }
2158
2159 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2160 for (word_index, word) in self.words.iter().copied().enumerate() {
2161 let mut bits = word;
2162 while bits != 0 {
2163 let bit = bits.trailing_zeros() as usize;
2164 if let Some(symbol) = token_bit_symbol(word_index * u64::BITS as usize + bit) {
2165 target.insert(symbol);
2166 }
2167 bits &= bits - 1;
2168 }
2169 }
2170 }
2171
2172 fn to_btree_set(&self) -> BTreeSet<i32> {
2173 let mut out = BTreeSet::new();
2174 self.extend_btree_set(&mut out);
2175 out
2176 }
2177}
2178
2179fn token_bit_slot(symbol: i32) -> Option<usize> {
2180 if symbol == TOKEN_EOF {
2181 Some(0)
2182 } else if symbol > 0 {
2183 usize::try_from(symbol).ok()
2184 } else {
2185 None
2186 }
2187}
2188
2189fn token_bit_symbol(slot: usize) -> Option<i32> {
2190 if slot == 0 {
2191 Some(TOKEN_EOF)
2192 } else {
2193 i32::try_from(slot).ok()
2194 }
2195}
2196
2197fn transition_expected_symbols(
2200 transition: ParserTransition<'_>,
2201 max_token_type: i32,
2202) -> BTreeSet<i32> {
2203 let mut symbols = BTreeSet::new();
2204 match &transition.data() {
2205 Transition::Atom { label, .. } => {
2206 symbols.insert(*label);
2207 }
2208 Transition::Range { start, stop, .. } => {
2209 symbols.extend(*start..=*stop);
2210 }
2211 Transition::Set { set, .. } => {
2212 for (start, stop) in set.ranges() {
2213 symbols.extend(start..=stop);
2214 }
2215 }
2216 Transition::NotSet { set, .. } => {
2217 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2218 }
2219 Transition::Wildcard { .. } => {
2220 symbols.extend(1..=max_token_type);
2221 }
2222 Transition::Epsilon { .. }
2223 | Transition::Rule { .. }
2224 | Transition::Predicate { .. }
2225 | Transition::Action { .. }
2226 | Transition::Precedence { .. } => {}
2227 }
2228 symbols
2229}
2230
2231fn transition_expected_token_set(
2232 transition: ParserTransition<'_>,
2233 max_token_type: i32,
2234) -> TokenBitSet {
2235 let mut symbols = TokenBitSet::default();
2236 match &transition.data() {
2237 Transition::Atom { label, .. } => {
2238 symbols.insert(*label);
2239 }
2240 Transition::Range { start, stop, .. } => {
2241 symbols.extend_range(*start, *stop);
2242 }
2243 Transition::Set { set, .. } => {
2244 for (start, stop) in set.ranges() {
2245 symbols.extend_range(start, stop);
2246 }
2247 }
2248 Transition::NotSet { set, .. } => {
2249 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2250 }
2251 Transition::Wildcard { .. } => {
2252 symbols.extend_range(1, max_token_type);
2253 }
2254 Transition::Epsilon { .. }
2255 | Transition::Rule { .. }
2256 | Transition::Predicate { .. }
2257 | Transition::Action { .. }
2258 | Transition::Precedence { .. } => {}
2259 }
2260 symbols
2261}
2262
2263fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2267 let mut symbols = BTreeSet::new();
2268 let mut stack = vec![state_number];
2269 let mut visited = BTreeSet::new();
2270 while let Some(current) = stack.pop() {
2271 if !visited.insert(current) {
2272 continue;
2273 }
2274 let Some(state) = atn.state(current) else {
2275 continue;
2276 };
2277 for transition in &state.transitions() {
2278 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2279 if transition_symbols.is_empty() {
2280 if transition.is_epsilon() {
2281 stack.push(transition.target());
2282 }
2283 } else {
2284 symbols.extend(transition_symbols);
2285 }
2286 }
2287 }
2288 symbols
2289}
2290
2291fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2292 let mut symbols = TokenBitSet::default();
2293 let mut stack = vec![state_number];
2294 let mut visited = BTreeSet::new();
2295 while let Some(current) = stack.pop() {
2296 if !visited.insert(current) {
2297 continue;
2298 }
2299 let Some(state) = atn.state(current) else {
2300 continue;
2301 };
2302 for transition in &state.transitions() {
2303 let transition_symbols =
2304 transition_expected_token_set(transition, atn.max_token_type());
2305 if transition_symbols.is_empty() {
2306 if transition.is_epsilon() {
2307 stack.push(transition.target());
2308 }
2309 } else {
2310 symbols.extend_from(&transition_symbols);
2311 }
2312 }
2313 }
2314 symbols
2315}
2316
2317fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2318 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2319 return false;
2320 };
2321 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2322 return false;
2323 };
2324 epsilon_reaches_state(atn, state_number, stop_state)
2325}
2326
2327fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2328 let mut stack = vec![start];
2329 let mut visited = BTreeSet::new();
2330 while let Some(current) = stack.pop() {
2331 if current == target {
2332 return true;
2333 }
2334 if !visited.insert(current) {
2335 continue;
2336 }
2337 let Some(state) = atn.state(current) else {
2338 continue;
2339 };
2340 stack.extend(
2341 state
2342 .transitions()
2343 .iter()
2344 .filter(|transition| transition.is_epsilon())
2345 .map(ParserTransition::target),
2346 );
2347 }
2348 false
2349}
2350
2351#[derive(Clone, Debug, Default, Eq, PartialEq)]
2358struct FirstSet {
2359 symbols: TokenBitSet,
2360 nullable: bool,
2361}
2362
2363type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2370
2371type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2378
2379#[derive(Debug, Default)]
2380struct LeftRecursiveOperatorLookahead {
2381 single_token: TokenBitSet,
2385 multi_token_prefix: TokenBitSet,
2390 predicate_dependent: TokenBitSet,
2391}
2392
2393#[derive(Default)]
2394struct SharedAtnCache {
2395 first_set: FirstSetCache,
2396 decision_lookahead: DecisionLookaheadCache,
2397 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2398 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2399 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2400 rule_stop_reach: FxHashMap<usize, bool>,
2401 observable_action_transitions: Option<bool>,
2402 predicate_transitions: Option<bool>,
2403}
2404
2405thread_local! {
2406 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2407 RefCell::new(FxHashMap::default());
2408}
2409
2410#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2421struct SharedAtnCacheKey {
2422 atn: usize,
2423 states: usize,
2424 state_count: usize,
2425 max_token_type: i32,
2426}
2427
2428impl SharedAtnCacheKey {
2429 fn for_atn(atn: &Atn) -> Self {
2430 let (states, state_count) = atn.storage_identity();
2431 Self {
2432 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2433 states,
2434 state_count,
2435 max_token_type: atn.max_token_type(),
2436 }
2437 }
2438}
2439
2440fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2441 SHARED_ATN_CACHES.with(|cell| {
2442 let key = SharedAtnCacheKey::for_atn(atn);
2443 let mut map = cell.borrow_mut();
2444 let cache = map.entry(key).or_default();
2445 f(&mut cache.first_set)
2446 })
2447}
2448
2449fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
2450 SHARED_ATN_CACHES.with(|cell| {
2451 let key = SharedAtnCacheKey::for_atn(atn);
2452 let mut map = cell.borrow_mut();
2453 let cache = map.entry(key).or_default();
2454 f(cache)
2455 })
2456}
2457
2458#[derive(Debug, Default)]
2467struct DecisionLookahead {
2468 transitions: Vec<TransitionLookSet>,
2469}
2470
2471#[derive(Clone, Debug, Default)]
2478struct TransitionLookSet {
2479 symbols: TokenBitSet,
2480 nullable: bool,
2481}
2482
2483struct FirstSetCtx<'a> {
2487 cache: &'a mut FirstSetCache,
2488 in_progress: BTreeSet<(usize, usize)>,
2489 hit_cycle: bool,
2490}
2491
2492fn rule_first_set(
2501 atn: &Atn,
2502 target: usize,
2503 rule_stop_state: usize,
2504 cache: &mut FirstSetCache,
2505) -> Rc<FirstSet> {
2506 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
2507 return Rc::clone(cached);
2508 }
2509 let mut ctx = FirstSetCtx {
2510 cache,
2511 in_progress: BTreeSet::new(),
2512 hit_cycle: false,
2513 };
2514 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
2515}
2516
2517fn rule_first_set_cached(
2518 atn: &Atn,
2519 target: usize,
2520 rule_stop_state: usize,
2521 ctx: &mut FirstSetCtx<'_>,
2522) -> Rc<FirstSet> {
2523 let key = (target, rule_stop_state);
2524 if let Some(cached) = ctx.cache.get(&key) {
2525 return Rc::clone(cached);
2526 }
2527 if !ctx.in_progress.insert(key) {
2528 return Rc::new(FirstSet::default());
2532 }
2533 let saved_hit_cycle = ctx.hit_cycle;
2534 ctx.hit_cycle = false;
2535 let mut first = FirstSet::default();
2536 let mut visited = BTreeSet::new();
2537 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
2538 ctx.in_progress.remove(&key);
2539 let entry = Rc::new(first);
2540 if !ctx.hit_cycle {
2541 ctx.cache.insert(key, Rc::clone(&entry));
2542 }
2543 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
2544 entry
2545}
2546
2547fn transition_first_set(
2551 atn: &Atn,
2552 transition: ParserTransition<'_>,
2553 rule_stop_state: usize,
2554 cache: &mut FirstSetCache,
2555) -> TransitionLookSet {
2556 match &transition.data() {
2557 Transition::Atom { label, .. } => {
2558 let mut symbols = TokenBitSet::default();
2559 symbols.insert(*label);
2560 TransitionLookSet {
2561 symbols,
2562 nullable: false,
2563 }
2564 }
2565 Transition::Range { start, stop, .. } => {
2566 let mut symbols = TokenBitSet::default();
2567 symbols.extend_range(*start, *stop);
2568 TransitionLookSet {
2569 symbols,
2570 nullable: false,
2571 }
2572 }
2573 Transition::Set { set, .. } => {
2574 let mut symbols = TokenBitSet::default();
2575 for (start, stop) in set.ranges() {
2576 symbols.extend_range(start, stop);
2577 }
2578 TransitionLookSet {
2579 symbols,
2580 nullable: false,
2581 }
2582 }
2583 Transition::NotSet { set, .. } => {
2584 let max = atn.max_token_type();
2585 let mut symbols = TokenBitSet::default();
2586 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
2587 TransitionLookSet {
2588 symbols,
2589 nullable: false,
2590 }
2591 }
2592 Transition::Wildcard { .. } => {
2593 let mut symbols = TokenBitSet::default();
2594 symbols.extend_range(1, atn.max_token_type());
2595 TransitionLookSet {
2596 symbols,
2597 nullable: false,
2598 }
2599 }
2600 Transition::Epsilon { target }
2601 | Transition::Action { target, .. }
2602 | Transition::Predicate { target, .. }
2603 | Transition::Precedence { target, .. } => {
2604 let first = rule_first_set(atn, *target, rule_stop_state, cache);
2607 TransitionLookSet {
2608 symbols: first.symbols.clone(),
2609 nullable: first.nullable,
2610 }
2611 }
2612 Transition::Rule {
2613 target,
2614 rule_index,
2615 follow_state,
2616 ..
2617 } => {
2618 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2619 return TransitionLookSet::default();
2620 };
2621 let child = rule_first_set(atn, *target, child_stop, cache);
2622 let mut symbols = child.symbols.clone();
2623 let nullable = if child.nullable {
2624 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
2625 symbols.extend_from(&follow.symbols);
2626 follow.nullable
2627 } else {
2628 false
2629 };
2630 TransitionLookSet { symbols, nullable }
2631 }
2632 }
2633}
2634
2635fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
2656 let mut chosen: Option<usize> = None;
2657 for (index, transition) in entry.transitions.iter().enumerate() {
2658 if transition.nullable {
2659 return None;
2660 }
2661 if transition.symbols.contains(symbol) {
2662 if chosen.is_some() {
2663 return None;
2664 }
2665 chosen = Some(index);
2666 }
2667 }
2668 chosen
2669}
2670
2671fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
2680 let mut matching_non_nullable_alt = None;
2681 let mut nullable_alt = None;
2682 for (index, transition) in entry.transitions.iter().enumerate() {
2683 if transition.nullable {
2684 if nullable_alt.is_some() {
2685 return None;
2686 }
2687 nullable_alt = Some(index);
2688 }
2689 if transition.symbols.contains(symbol) {
2690 if transition.nullable {
2691 continue;
2692 }
2693 if matching_non_nullable_alt.is_some() {
2694 return None;
2695 }
2696 matching_non_nullable_alt = Some(index);
2697 }
2698 }
2699 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
2700 return None;
2701 }
2702 if non_greedy {
2703 nullable_alt.or(matching_non_nullable_alt)
2704 } else {
2705 matching_non_nullable_alt.or(nullable_alt)
2706 }
2707}
2708
2709fn should_skip_via_lookahead(
2710 transition_kind: ParserTransitionKind,
2711 transition_index: usize,
2712 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
2713 index: usize,
2714 record_expected: bool,
2715 expected: &mut ExpectedTokens,
2716) -> bool {
2717 let prune_non_consuming = matches!(
2718 transition_kind,
2719 ParserTransitionKind::Epsilon
2720 | ParserTransitionKind::Action
2721 | ParserTransitionKind::Predicate
2722 | ParserTransitionKind::Rule
2723 | ParserTransitionKind::Precedence
2724 );
2725 if !prune_non_consuming {
2726 return false;
2727 }
2728 let Some((symbol, entry)) = lookahead_filter else {
2729 return false;
2730 };
2731 let Some(set) = entry.transitions.get(transition_index) else {
2732 return false;
2733 };
2734 if set.symbols.contains(*symbol) || set.nullable {
2735 return false;
2736 }
2737 if record_expected && !set.symbols.is_empty() {
2738 record_pruned_transition_expected(set, index, expected);
2739 }
2740 true
2741}
2742
2743fn should_skip_rule_via_first_set(
2744 first: &FirstSet,
2745 symbol: i32,
2746 record_expected: bool,
2747 index: usize,
2748 expected: &mut ExpectedTokens,
2749) -> bool {
2750 if first.nullable || first.symbols.contains(symbol) {
2751 return false;
2752 }
2753 if record_expected && !first.symbols.is_empty() {
2754 record_token_bit_expected(&first.symbols, index, expected);
2755 }
2756 true
2757}
2758
2759fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
2760 match expected.index {
2761 Some(current) if index < current => {}
2762 Some(current) if index == current => {
2763 symbols.extend_btree_set(&mut expected.symbols);
2764 }
2765 _ => {
2766 expected.index = Some(index);
2767 expected.symbols = symbols.to_btree_set();
2768 }
2769 }
2770}
2771
2772fn record_pruned_transition_expected(
2774 set: &TransitionLookSet,
2775 index: usize,
2776 expected: &mut ExpectedTokens,
2777) {
2778 match expected.index {
2779 Some(current) if index < current => {}
2780 Some(current) if index == current => {
2781 set.symbols.extend_btree_set(&mut expected.symbols);
2782 }
2783 _ => {
2784 expected.index = Some(index);
2785 expected.symbols = set.symbols.to_btree_set();
2786 }
2787 }
2788}
2789
2790fn rule_first_set_inner(
2791 atn: &Atn,
2792 state_number: usize,
2793 rule_stop_state: usize,
2794 ctx: &mut FirstSetCtx<'_>,
2795 visited: &mut BTreeSet<usize>,
2796 first: &mut FirstSet,
2797) {
2798 if !visited.insert(state_number) {
2799 return;
2800 }
2801 if state_number == rule_stop_state {
2802 first.nullable = true;
2803 return;
2804 }
2805 let Some(state) = atn.state(state_number) else {
2806 return;
2807 };
2808 for transition in &state.transitions() {
2809 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2810 if !transition_symbols.is_empty() {
2811 first.symbols.extend_iter(transition_symbols);
2812 continue;
2813 }
2814 match &transition.data() {
2815 Transition::Epsilon { target }
2816 | Transition::Action { target, .. }
2817 | Transition::Predicate { target, .. }
2818 | Transition::Precedence { target, .. } => {
2819 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
2820 }
2821 Transition::Rule {
2822 target,
2823 rule_index,
2824 follow_state,
2825 ..
2826 } => {
2827 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2828 continue;
2829 };
2830 let child_key = (*target, child_stop);
2831 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
2832 ctx.hit_cycle = true;
2833 }
2834 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
2835 first.symbols.extend_from(&child.symbols);
2836 if child.nullable {
2837 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
2838 }
2839 }
2840 Transition::Atom { .. }
2841 | Transition::Range { .. }
2842 | Transition::Set { .. }
2843 | Transition::NotSet { .. }
2844 | Transition::Wildcard { .. } => {}
2845 }
2846 }
2847}
2848
2849fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
2852 let mut symbols = BTreeSet::new();
2853 state_sync_symbols_inner(
2854 atn,
2855 state_number,
2856 stop_state,
2857 &mut BTreeSet::new(),
2858 &mut symbols,
2859 );
2860 symbols
2861}
2862
2863fn state_sync_symbols_inner(
2866 atn: &Atn,
2867 state_number: usize,
2868 stop_state: usize,
2869 visited: &mut BTreeSet<usize>,
2870 symbols: &mut BTreeSet<i32>,
2871) {
2872 if !visited.insert(state_number) {
2873 return;
2874 }
2875 if state_number == stop_state {
2876 symbols.insert(TOKEN_EOF);
2877 return;
2878 }
2879 let Some(state) = atn.state(state_number) else {
2880 return;
2881 };
2882 for transition in &state.transitions() {
2883 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2884 if transition_symbols.is_empty() {
2885 match &transition.data() {
2886 Transition::Rule { target, .. }
2887 | Transition::Epsilon { target }
2888 | Transition::Action { target, .. }
2889 | Transition::Predicate { target, .. }
2890 | Transition::Precedence { target, .. } => {
2891 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
2892 }
2893 Transition::Atom { .. }
2894 | Transition::Range { .. }
2895 | Transition::Set { .. }
2896 | Transition::NotSet { .. }
2897 | Transition::Wildcard { .. } => {}
2898 }
2899 } else {
2900 symbols.extend(transition_symbols);
2901 }
2902 }
2903}
2904
2905#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
2906struct OperatorSymbolReachability {
2907 single_token: bool,
2909 multi_token: bool,
2911 predicate_dependent: bool,
2913}
2914
2915impl OperatorSymbolReachability {
2916 const ADAPTIVE_FALLBACK: Self = Self {
2917 single_token: false,
2918 multi_token: false,
2919 predicate_dependent: true,
2920 };
2921
2922 const fn single_token(predicate_dependent: bool) -> Self {
2923 if predicate_dependent {
2924 Self {
2925 single_token: false,
2926 multi_token: false,
2927 predicate_dependent: true,
2928 }
2929 } else {
2930 Self {
2931 single_token: true,
2932 multi_token: false,
2933 predicate_dependent: false,
2934 }
2935 }
2936 }
2937
2938 const fn multi_token(predicate_dependent: bool) -> Self {
2939 if predicate_dependent {
2940 Self {
2941 single_token: false,
2942 multi_token: false,
2943 predicate_dependent: true,
2944 }
2945 } else {
2946 Self {
2947 single_token: false,
2948 multi_token: true,
2949 predicate_dependent: false,
2950 }
2951 }
2952 }
2953
2954 const fn union(self, other: Self) -> Self {
2955 Self {
2956 single_token: self.single_token || other.single_token,
2957 multi_token: self.multi_token || other.multi_token,
2958 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
2959 }
2960 }
2961}
2962
2963#[derive(Clone, Copy)]
2964struct OperatorReachabilityRequest {
2965 symbol: i32,
2966 precedence: i32,
2967 predicate_dependent: bool,
2968 operator_rule_index: usize,
2969}
2970
2971#[derive(Clone, Copy, Debug)]
2972struct OperatorRuleContinuation {
2973 stop_state: usize,
2974 follow_state: usize,
2975 return_precedence: i32,
2976}
2977
2978struct NullablePrecedenceCtx {
2979 cache: FxHashMap<(usize, usize, i32, bool), bool>,
2980 in_progress: BTreeSet<(usize, usize, i32, bool)>,
2981 hit_cycle: bool,
2982}
2983
2984fn state_is_nullable_with_precedence(
2985 atn: &Atn,
2986 state_number: usize,
2987 stop_state_number: usize,
2988 precedence: i32,
2989 allow_predicates: bool,
2990 ctx: &mut NullablePrecedenceCtx,
2991) -> bool {
2992 let saved_hit_cycle = ctx.hit_cycle;
2993 ctx.hit_cycle = false;
2994 let nullable = state_is_nullable_with_precedence_cached(
2995 atn,
2996 state_number,
2997 stop_state_number,
2998 precedence,
2999 allow_predicates,
3000 ctx,
3001 );
3002 ctx.hit_cycle = saved_hit_cycle;
3003 nullable
3004}
3005
3006fn state_is_nullable_with_precedence_cached(
3007 atn: &Atn,
3008 state_number: usize,
3009 stop_state_number: usize,
3010 precedence: i32,
3011 allow_predicates: bool,
3012 ctx: &mut NullablePrecedenceCtx,
3013) -> bool {
3014 if state_number == stop_state_number {
3015 return true;
3016 }
3017 let key = (
3018 state_number,
3019 stop_state_number,
3020 precedence,
3021 allow_predicates,
3022 );
3023 if let Some(cached) = ctx.cache.get(&key) {
3024 return *cached;
3025 }
3026 if !ctx.in_progress.insert(key) {
3027 ctx.hit_cycle = true;
3028 return false;
3029 }
3030 let saved_hit_cycle = ctx.hit_cycle;
3031 ctx.hit_cycle = false;
3032 let nullable = atn.state(state_number).is_some_and(|state| {
3033 state
3034 .transitions()
3035 .iter()
3036 .any(|transition| match &transition.data() {
3037 Transition::Rule {
3038 target,
3039 rule_index,
3040 follow_state,
3041 precedence: rule_precedence,
3042 } => {
3043 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3044 return false;
3045 };
3046 state_is_nullable_with_precedence_cached(
3047 atn,
3048 *target,
3049 child_stop,
3050 *rule_precedence,
3051 allow_predicates,
3052 ctx,
3053 ) && state_is_nullable_with_precedence_cached(
3054 atn,
3055 *follow_state,
3056 stop_state_number,
3057 precedence,
3058 allow_predicates,
3059 ctx,
3060 )
3061 }
3062 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3063 state_is_nullable_with_precedence_cached(
3064 atn,
3065 *target,
3066 stop_state_number,
3067 precedence,
3068 allow_predicates,
3069 ctx,
3070 )
3071 }
3072 Transition::Predicate { target, .. } if allow_predicates => {
3073 state_is_nullable_with_precedence_cached(
3074 atn,
3075 *target,
3076 stop_state_number,
3077 precedence,
3078 allow_predicates,
3079 ctx,
3080 )
3081 }
3082 Transition::Precedence {
3083 target,
3084 precedence: transition_precedence,
3085 } if *transition_precedence >= precedence => {
3086 state_is_nullable_with_precedence_cached(
3087 atn,
3088 *target,
3089 stop_state_number,
3090 precedence,
3091 allow_predicates,
3092 ctx,
3093 )
3094 }
3095 Transition::Atom { .. }
3096 | Transition::Range { .. }
3097 | Transition::Set { .. }
3098 | Transition::NotSet { .. }
3099 | Transition::Wildcard { .. }
3100 | Transition::Predicate { .. }
3101 | Transition::Precedence { .. } => false,
3102 })
3103 });
3104 ctx.in_progress.remove(&key);
3105 if !ctx.hit_cycle {
3106 ctx.cache.insert(key, nullable);
3107 }
3108 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3109 nullable
3110}
3111
3112fn state_operator_token_prefix_reachability(
3114 atn: &Atn,
3115 state_number: usize,
3116 request: OperatorReachabilityRequest,
3117 continuations: &[OperatorRuleContinuation],
3118 visited: &mut BTreeSet<(usize, i32, bool)>,
3119) -> OperatorSymbolReachability {
3120 let key = (
3121 state_number,
3122 request.precedence,
3123 request.predicate_dependent,
3124 );
3125 if !visited.insert(key) {
3126 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3130 }
3131 if let Some((continuation, remaining)) = continuations.split_last()
3132 && state_number == continuation.stop_state
3133 {
3134 let result = state_operator_token_prefix_reachability(
3135 atn,
3136 continuation.follow_state,
3137 OperatorReachabilityRequest {
3138 precedence: continuation.return_precedence,
3139 ..request
3140 },
3141 remaining,
3142 visited,
3143 );
3144 visited.remove(&key);
3145 return result;
3146 }
3147 let Some(state) = atn.state(state_number) else {
3148 visited.remove(&key);
3149 return OperatorSymbolReachability::default();
3150 };
3151 let completes_operator = match state.kind() {
3152 AtnStateKind::RuleStop => continuations.is_empty(),
3153 AtnStateKind::StarLoopBack
3154 | AtnStateKind::StarLoopEntry
3155 | AtnStateKind::PlusLoopBack
3156 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3157 _ => false,
3158 };
3159 if completes_operator {
3160 visited.remove(&key);
3161 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3162 }
3163 let mut reachability = OperatorSymbolReachability::default();
3164 for transition in &state.transitions() {
3165 let transition_reachability = match &transition.data() {
3166 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3167 OperatorSymbolReachability::single_token(request.predicate_dependent)
3168 }
3169 Transition::Rule {
3170 target,
3171 rule_index,
3172 follow_state,
3173 precedence: rule_precedence,
3174 } => {
3175 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3176 continue;
3177 };
3178 let mut nested = continuations.to_vec();
3179 nested.push(OperatorRuleContinuation {
3180 stop_state: child_stop,
3181 follow_state: *follow_state,
3182 return_precedence: request.precedence,
3183 });
3184 state_operator_token_prefix_reachability(
3185 atn,
3186 *target,
3187 OperatorReachabilityRequest {
3188 precedence: *rule_precedence,
3189 ..request
3190 },
3191 &nested,
3192 visited,
3193 )
3194 }
3195 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3196 state_operator_token_prefix_reachability(
3197 atn,
3198 *target,
3199 request,
3200 continuations,
3201 visited,
3202 )
3203 }
3204 Transition::Precedence {
3205 target,
3206 precedence: transition_precedence,
3207 } => {
3208 if *transition_precedence < request.precedence {
3209 OperatorSymbolReachability::default()
3210 } else {
3211 state_operator_token_prefix_reachability(
3212 atn,
3213 *target,
3214 request,
3215 continuations,
3216 visited,
3217 )
3218 }
3219 }
3220 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3221 atn,
3222 *target,
3223 OperatorReachabilityRequest {
3224 predicate_dependent: true,
3225 ..request
3226 },
3227 continuations,
3228 visited,
3229 ),
3230 Transition::Atom { .. }
3231 | Transition::Range { .. }
3232 | Transition::Set { .. }
3233 | Transition::NotSet { .. }
3234 | Transition::Wildcard { .. } => {
3235 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3236 }
3237 };
3238 reachability = reachability.union(transition_reachability);
3239 }
3240 visited.remove(&key);
3241 reachability
3242}
3243
3244fn state_can_reach_symbol_with_precedence(
3245 atn: &Atn,
3246 state_number: usize,
3247 request: OperatorReachabilityRequest,
3248 nullable_ctx: &mut NullablePrecedenceCtx,
3249 continuations: &mut Vec<OperatorRuleContinuation>,
3250 visited: &mut BTreeSet<(usize, i32, bool)>,
3251) -> OperatorSymbolReachability {
3252 let key = (
3253 state_number,
3254 request.precedence,
3255 request.predicate_dependent,
3256 );
3257 if !visited.insert(key) {
3258 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3259 }
3260 let Some(state) = atn.state(state_number) else {
3261 visited.remove(&key);
3262 return OperatorSymbolReachability::default();
3263 };
3264 let mut reachability = OperatorSymbolReachability::default();
3265 for transition in &state.transitions() {
3266 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3267 reachability = reachability.union(state_operator_token_prefix_reachability(
3268 atn,
3269 transition.target(),
3270 request,
3271 continuations,
3272 &mut BTreeSet::new(),
3273 ));
3274 continue;
3275 }
3276 let transition_reachability = match &transition.data() {
3277 Transition::Rule {
3278 target,
3279 rule_index,
3280 follow_state,
3281 precedence: rule_precedence,
3282 } => {
3283 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3284 continue;
3285 };
3286 continuations.push(OperatorRuleContinuation {
3287 stop_state: child_stop,
3288 follow_state: *follow_state,
3289 return_precedence: request.precedence,
3290 });
3291 let mut result = state_can_reach_symbol_with_precedence(
3292 atn,
3293 *target,
3294 OperatorReachabilityRequest {
3295 precedence: *rule_precedence,
3296 ..request
3297 },
3298 nullable_ctx,
3299 continuations,
3300 visited,
3301 );
3302 continuations.pop();
3303 if state_is_nullable_with_precedence(
3304 atn,
3305 *target,
3306 child_stop,
3307 *rule_precedence,
3308 true,
3309 nullable_ctx,
3310 ) {
3311 let child_predicate_dependent = request.predicate_dependent
3312 || !state_is_nullable_with_precedence(
3313 atn,
3314 *target,
3315 child_stop,
3316 *rule_precedence,
3317 false,
3318 nullable_ctx,
3319 );
3320 result = result.union(state_can_reach_symbol_with_precedence(
3321 atn,
3322 *follow_state,
3323 OperatorReachabilityRequest {
3324 predicate_dependent: child_predicate_dependent,
3325 ..request
3326 },
3327 nullable_ctx,
3328 continuations,
3329 visited,
3330 ));
3331 }
3332 result
3333 }
3334 Transition::Epsilon { target }
3335 | Transition::Action { target, .. }
3336 | Transition::Precedence { target, .. } => {
3337 if matches!(
3338 &transition.data(),
3339 Transition::Precedence {
3340 precedence: transition_precedence,
3341 ..
3342 } if *transition_precedence < request.precedence
3343 ) {
3344 continue;
3345 }
3346 state_can_reach_symbol_with_precedence(
3347 atn,
3348 *target,
3349 request,
3350 nullable_ctx,
3351 continuations,
3352 visited,
3353 )
3354 }
3355 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3356 atn,
3357 *target,
3358 OperatorReachabilityRequest {
3359 predicate_dependent: true,
3360 ..request
3361 },
3362 nullable_ctx,
3363 continuations,
3364 visited,
3365 ),
3366 Transition::Atom { .. }
3367 | Transition::Range { .. }
3368 | Transition::Set { .. }
3369 | Transition::NotSet { .. }
3370 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3371 };
3372 reachability = reachability.union(transition_reachability);
3373 }
3374 visited.remove(&key);
3375 reachability
3376}
3377
3378fn left_recursive_operator_lookahead(
3379 atn: &Atn,
3380 state_number: usize,
3381 precedence: i32,
3382) -> LeftRecursiveOperatorLookahead {
3383 let Some(state) = atn.state(state_number) else {
3384 return LeftRecursiveOperatorLookahead::default();
3385 };
3386 let Some(operator_rule_index) = state.rule_index() else {
3387 return LeftRecursiveOperatorLookahead::default();
3388 };
3389 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3390 let mut nullable_ctx = NullablePrecedenceCtx {
3391 cache: FxHashMap::default(),
3392 in_progress: BTreeSet::new(),
3393 hit_cycle: false,
3394 };
3395 for transition in &state.transitions() {
3396 let target = transition.target();
3397 if atn
3398 .state(target)
3399 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3400 {
3401 continue;
3402 }
3403 for symbol in 1..=atn.max_token_type() {
3404 let reachability = state_can_reach_symbol_with_precedence(
3405 atn,
3406 target,
3407 OperatorReachabilityRequest {
3408 symbol,
3409 precedence,
3410 predicate_dependent: false,
3411 operator_rule_index,
3412 },
3413 &mut nullable_ctx,
3414 &mut Vec::new(),
3415 &mut BTreeSet::new(),
3416 );
3417 if reachability.single_token {
3418 lookahead.single_token.insert(symbol);
3419 }
3420 if reachability.multi_token {
3421 lookahead.multi_token_prefix.insert(symbol);
3422 }
3423 if reachability.predicate_dependent {
3424 lookahead.predicate_dependent.insert(symbol);
3425 }
3426 }
3427 }
3428 lookahead
3429}
3430
3431#[derive(Debug, Default)]
3432struct StateBeforeStopLookahead {
3433 symbols: TokenBitSet,
3434 reaches_context_boundary: bool,
3435}
3436
3437fn state_before_stop_lookahead(
3438 atn: &Atn,
3439 state_number: usize,
3440 stop_state_number: usize,
3441) -> Rc<StateBeforeStopLookahead> {
3442 with_shared_atn_caches(atn, |cache| {
3443 let key = (state_number, stop_state_number);
3444 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
3445 return Rc::clone(cached);
3446 }
3447 let mut lookahead = StateBeforeStopLookahead::default();
3448 state_before_stop_lookahead_inner(
3449 atn,
3450 state_number,
3451 stop_state_number,
3452 &mut BTreeSet::new(),
3453 &mut cache.first_set,
3454 &mut lookahead,
3455 );
3456 let lookahead = Rc::new(lookahead);
3457 cache
3458 .state_before_stop_lookahead
3459 .insert(key, Rc::clone(&lookahead));
3460 lookahead
3461 })
3462}
3463
3464fn state_before_stop_lookahead_inner(
3465 atn: &Atn,
3466 state_number: usize,
3467 stop_state_number: usize,
3468 visited: &mut BTreeSet<usize>,
3469 first_set_cache: &mut FirstSetCache,
3470 lookahead: &mut StateBeforeStopLookahead,
3471) {
3472 if state_number == stop_state_number {
3473 lookahead.reaches_context_boundary = true;
3474 return;
3475 }
3476 if !visited.insert(state_number) {
3477 return;
3478 }
3479 let Some(state) = atn.state(state_number) else {
3480 return;
3481 };
3482 if state.kind() == AtnStateKind::RuleStop {
3483 lookahead.reaches_context_boundary = true;
3484 return;
3485 }
3486 for transition in &state.transitions() {
3487 match &transition.data() {
3488 Transition::Epsilon { target }
3489 | Transition::Action { target, .. }
3490 | Transition::Predicate { target, .. }
3491 | Transition::Precedence { target, .. } => {
3492 state_before_stop_lookahead_inner(
3493 atn,
3494 *target,
3495 stop_state_number,
3496 visited,
3497 first_set_cache,
3498 lookahead,
3499 );
3500 }
3501 Transition::Rule {
3502 target,
3503 rule_index,
3504 follow_state,
3505 ..
3506 } => {
3507 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3508 continue;
3509 };
3510 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
3511 lookahead.symbols.extend_from(&child.symbols);
3512 if child.nullable {
3513 state_before_stop_lookahead_inner(
3514 atn,
3515 *follow_state,
3516 stop_state_number,
3517 visited,
3518 first_set_cache,
3519 lookahead,
3520 );
3521 }
3522 }
3523 Transition::Atom { .. }
3524 | Transition::Range { .. }
3525 | Transition::Set { .. }
3526 | Transition::NotSet { .. }
3527 | Transition::Wildcard { .. } => {
3528 lookahead.symbols.extend_iter(transition_expected_symbols(
3529 transition,
3530 atn.max_token_type(),
3531 ));
3532 }
3533 }
3534 }
3535}
3536
3537fn caller_context_can_match_symbol_before_state(
3538 atn: &Atn,
3539 return_states: impl DoubleEndedIterator<Item = usize>,
3540 stop_state_number: usize,
3541 symbol: i32,
3542) -> bool {
3543 for return_state in return_states.rev() {
3544 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
3545 if lookahead.symbols.contains(symbol) {
3546 return true;
3547 }
3548 if !lookahead.reaches_context_boundary {
3549 return false;
3550 }
3551 }
3552 false
3553}
3554
3555fn next_recovery_context(
3559 atn: &Atn,
3560 state: AtnState<'_>,
3561 inherited: &BTreeSet<i32>,
3562 inherited_state: Option<usize>,
3563) -> (BTreeSet<i32>, Option<usize>) {
3564 let state_symbols = state_expected_symbols(atn, state.state_number());
3565 if state.transitions().len() > 1 && !state_symbols.is_empty() {
3566 let mut symbols = state_symbols;
3567 symbols.extend(inherited.iter().copied());
3568 return (symbols, Some(state.state_number()));
3569 }
3570 (inherited.clone(), inherited_state)
3571}
3572
3573fn recovery_expected_symbols(
3574 atn: &Atn,
3575 state_number: usize,
3576 inherited: &BTreeSet<i32>,
3577) -> BTreeSet<i32> {
3578 let mut symbols = state_expected_symbols(atn, state_number);
3579 symbols.extend(inherited.iter().copied());
3580 symbols
3581}
3582
3583fn fast_next_recovery_context<S, H>(
3587 parser: &mut BaseParser<S, H>,
3588 atn: &Atn,
3589 state: AtnState<'_>,
3590 inherited: &Rc<BTreeSet<i32>>,
3591 inherited_state: Option<usize>,
3592) -> (Rc<BTreeSet<i32>>, Option<usize>)
3593where
3594 S: TokenSource,
3595 H: SemanticHooks,
3596{
3597 if state.transitions().len() <= 1 {
3598 return (Rc::clone(inherited), inherited_state);
3599 }
3600 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
3601 if state_symbols.is_empty() {
3602 return (Rc::clone(inherited), inherited_state);
3603 }
3604 if inherited.is_empty() {
3605 return (state_symbols, Some(state.state_number()));
3606 }
3607 if Rc::ptr_eq(&state_symbols, inherited) {
3608 return (state_symbols, Some(state.state_number()));
3609 }
3610 let mut combined = (*state_symbols).clone();
3611 combined.extend(inherited.iter().copied());
3612 (
3613 parser.intern_recovery_symbols(combined),
3614 Some(state.state_number()),
3615 )
3616}
3617
3618fn fast_recovery_expected_symbols<S, H>(
3622 parser: &mut BaseParser<S, H>,
3623 atn: &Atn,
3624 state_number: usize,
3625 inherited: &Rc<BTreeSet<i32>>,
3626) -> Rc<BTreeSet<i32>>
3627where
3628 S: TokenSource,
3629 H: SemanticHooks,
3630{
3631 let cached = parser.cached_state_expected_symbols(atn, state_number);
3632 if inherited.is_empty() {
3633 return cached;
3634 }
3635 if cached.is_empty() {
3636 return Rc::clone(inherited);
3637 }
3638 if Rc::ptr_eq(&cached, inherited) {
3639 return cached;
3640 }
3641 let mut combined = (*cached).clone();
3642 combined.extend(inherited.iter().copied());
3643 parser.intern_recovery_symbols(combined)
3644}
3645
3646struct ParserTableSemCtx<'a> {
3647 member_values: &'a mut BTreeMap<usize, i64>,
3648 return_values: &'a mut BTreeMap<String, i64>,
3649}
3650
3651impl semir::PredContext for ParserTableSemCtx<'_> {
3652 type TokenText<'a>
3653 = &'a str
3654 where
3655 Self: 'a;
3656
3657 fn la(&mut self, _offset: isize) -> i64 {
3658 i64::from(TOKEN_EOF)
3659 }
3660
3661 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
3662 None
3663 }
3664
3665 fn token_index_adjacent(&mut self) -> bool {
3666 false
3667 }
3668
3669 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
3670 None
3671 }
3672
3673 fn member(&self, member: usize) -> Option<i64> {
3674 Some(self.member_values.get(&member).copied().unwrap_or_default())
3675 }
3676
3677 fn local_arg(&self) -> Option<i64> {
3678 None
3679 }
3680
3681 fn column(&self) -> Option<i64> {
3682 None
3683 }
3684
3685 fn token_start_column(&self) -> Option<i64> {
3686 None
3687 }
3688
3689 fn token_text_so_far(&self) -> Option<String> {
3690 None
3691 }
3692
3693 fn hook(&mut self, _hook: HookId) -> bool {
3694 false
3695 }
3696}
3697
3698impl semir::ActContext for ParserTableSemCtx<'_> {
3699 fn set_member(&mut self, member: usize, value: i64) {
3700 self.member_values.insert(member, value);
3701 }
3702
3703 fn set_return(&mut self, name: &str, value: i64) {
3704 self.return_values.insert(name.to_owned(), value);
3705 }
3706
3707 fn action_hook(&mut self, _hook: HookId) {}
3708}
3709
3710fn apply_member_actions(
3712 source_state: usize,
3713 actions: &[ParserMemberAction],
3714 semantics: Option<&ParserSemantics>,
3715 values: &mut BTreeMap<usize, i64>,
3716) {
3717 for action in actions
3718 .iter()
3719 .filter(|action| action.source_state == source_state)
3720 {
3721 *values.entry(action.member).or_default() += action.delta;
3722 }
3723 let Some(semantics) = semantics else {
3724 return;
3725 };
3726 let mut return_values = BTreeMap::new();
3727 let mut ctx = ParserTableSemCtx {
3728 member_values: values,
3729 return_values: &mut return_values,
3730 };
3731 for action in semantics
3732 .actions
3733 .iter()
3734 .filter(|action| action.source_state == source_state && action.speculative)
3735 {
3736 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3737 }
3738}
3739
3740fn member_values_after_action(
3742 source_state: usize,
3743 actions: &[ParserMemberAction],
3744 semantics: Option<&ParserSemantics>,
3745 values: &BTreeMap<usize, i64>,
3746) -> BTreeMap<usize, i64> {
3747 let mut values = values.clone();
3748 apply_member_actions(source_state, actions, semantics, &mut values);
3749 values
3750}
3751
3752fn return_values_after_action(
3754 source_state: usize,
3755 rule_index: usize,
3756 actions: &[ParserReturnAction],
3757 semantics: Option<&ParserSemantics>,
3758 values: &BTreeMap<String, i64>,
3759) -> BTreeMap<String, i64> {
3760 let mut values = values.clone();
3761 for action in actions
3762 .iter()
3763 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
3764 {
3765 values.insert(action.name.to_owned(), action.value);
3766 }
3767 if let Some(semantics) = semantics {
3768 let mut member_values = BTreeMap::new();
3769 let mut ctx = ParserTableSemCtx {
3770 member_values: &mut member_values,
3771 return_values: &mut values,
3772 };
3773 for action in semantics.actions.iter().filter(|action| {
3774 action.source_state == source_state
3775 && action.rule_index == rule_index
3776 && !action.speculative
3777 }) {
3778 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3779 }
3780 }
3781 values
3782}
3783
3784fn rule_local_int_arg(
3786 rule_args: &[ParserRuleArg],
3787 source_state: usize,
3788 rule_index: usize,
3789 local_int_arg: Option<(usize, i64)>,
3790) -> Option<(usize, i64)> {
3791 rule_args
3792 .iter()
3793 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
3794 .map(|arg| {
3795 let value = if arg.inherit_local {
3796 local_int_arg.map_or(arg.value, |(_, value)| value)
3797 } else {
3798 arg.value
3799 };
3800 (rule_index, value)
3801 })
3802}
3803
3804fn stop_outcome(
3807 index: usize,
3808 consumed_eof: bool,
3809 rule_alt_number: usize,
3810 member_values: BTreeMap<usize, i64>,
3811 return_values: BTreeMap<String, i64>,
3812) -> Vec<RecognizeOutcome> {
3813 vec![RecognizeOutcome {
3814 index,
3815 consumed_eof,
3816 alt_number: rule_alt_number,
3817 member_values,
3818 return_values,
3819 diagnostics: DiagnosticSeqId::EMPTY,
3820 decisions: Vec::new(),
3821 actions: Vec::new(),
3822 nodes: NodeSeqId::EMPTY,
3823 }]
3824}
3825
3826fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
3827 with_shared_atn_caches(atn, |cache| {
3828 *cache.observable_action_transitions.get_or_insert_with(|| {
3829 atn.states().any(|state| {
3830 state.transitions().iter().any(|transition| {
3831 matches!(
3832 &transition.data(),
3833 Transition::Action {
3834 action_index: Some(_),
3835 ..
3836 }
3837 )
3838 })
3839 })
3840 })
3841 })
3842}
3843
3844fn atn_has_predicate_transitions(atn: &Atn) -> bool {
3845 with_shared_atn_caches(atn, |cache| {
3846 *cache.predicate_transitions.get_or_insert_with(|| {
3847 atn.states().any(|state| {
3848 state
3849 .transitions()
3850 .iter()
3851 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
3852 })
3853 })
3854 })
3855}
3856
3857fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
3862 options.init_action_rules.is_empty()
3863 && !options.track_alt_numbers
3864 && options
3865 .predicates
3866 .iter()
3867 .all(|(_, _, predicate)| predicate.failure_message().is_none())
3868 && options.semantics.is_none_or(|semantics| {
3869 semantics.actions.is_empty()
3870 && semantics
3871 .predicates
3872 .iter()
3873 .all(|predicate| predicate.failure_message.is_none())
3874 })
3875 && options.rule_args.is_empty()
3876 && options.member_actions.is_empty()
3877 && options.return_actions.is_empty()
3878 && !atn_has_observable_action_transitions(atn)
3879}
3880
3881#[derive(Clone, Debug, Eq, PartialEq)]
3882struct RecognizeRequest<'a> {
3883 state_number: usize,
3884 stop_state: usize,
3885 index: usize,
3886 rule_start_index: usize,
3887 decision_start_index: Option<usize>,
3888 init_action_rules: &'a BTreeSet<usize>,
3889 predicates: &'a [(usize, usize, ParserPredicate)],
3890 semantics: Option<&'a ParserSemantics>,
3891 rule_args: &'a [ParserRuleArg],
3892 member_actions: &'a [ParserMemberAction],
3893 return_actions: &'a [ParserReturnAction],
3894 local_int_arg: Option<(usize, i64)>,
3895 member_values: BTreeMap<usize, i64>,
3896 return_values: BTreeMap<String, i64>,
3897 rule_alt_number: usize,
3898 track_alt_numbers: bool,
3899 consumed_eof: bool,
3900 precedence: i32,
3903 depth: usize,
3904 recovery_symbols: BTreeSet<i32>,
3905 recovery_state: Option<usize>,
3906}
3907
3908#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
3909struct RecognizeKey {
3910 state_number: usize,
3911 stop_state: usize,
3912 index: usize,
3913 rule_start_index: usize,
3914 decision_start_index: Option<usize>,
3915 local_int_arg: Option<(usize, i64)>,
3916 member_values: BTreeMap<usize, i64>,
3917 return_values: BTreeMap<String, i64>,
3918 rule_alt_number: usize,
3919 track_alt_numbers: bool,
3920 consumed_eof: bool,
3921 precedence: i32,
3922 recovery_symbols: BTreeSet<i32>,
3923 recovery_state: Option<usize>,
3924}
3925
3926#[derive(Clone, Debug, Eq, PartialEq)]
3927struct EpsilonActionStep {
3928 source_state: usize,
3929 target: usize,
3930 action_rule_index: Option<usize>,
3931 left_recursive_boundary: Option<usize>,
3932 decision: Option<usize>,
3933 decision_start_index: Option<usize>,
3934 alt_number: usize,
3935 recovery_symbols: BTreeSet<i32>,
3936 recovery_state: Option<usize>,
3937}
3938
3939struct RecognizeScratch<'a> {
3940 visiting: &'a mut BTreeSet<RecognizeKey>,
3941 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
3942 expected: &'a mut ExpectedTokens,
3943}
3944
3945#[derive(Clone, Debug, Eq, PartialEq)]
3946struct FastRecognizeRequest {
3947 state_number: usize,
3948 stop_state: usize,
3949 index: usize,
3950 rule_start_index: usize,
3951 decision_start_index: Option<usize>,
3952 precedence: i32,
3953 depth: usize,
3954 recovery_symbols: Rc<BTreeSet<i32>>,
3955 recovery_state: Option<usize>,
3956}
3957
3958#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3959struct FastRecognizeTopRequest {
3960 start_state: usize,
3961 stop_state: usize,
3962 start_index: usize,
3963 precedence: i32,
3964 caller_follow_state: Option<usize>,
3965}
3966
3967#[derive(Clone, Copy, Debug)]
3968struct FastPredicateContext<'a> {
3969 predicates: &'a [(usize, usize, ParserPredicate)],
3970 semantics: Option<&'a ParserSemantics>,
3971 member_values: &'a BTreeMap<usize, i64>,
3972}
3973
3974struct FastRecognizeScratch<'a, 'b> {
3975 predicate_context: Option<FastPredicateContext<'a>>,
3976 visiting: &'b mut FxHashSet<FastRecognizeKey>,
3977 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
3978 expected: &'b mut ExpectedTokens,
3979}
3980
3981#[derive(Clone, Copy, Debug)]
3982struct FastRepetitionShape {
3983 enter_target: usize,
3984 exit_target: usize,
3985 body_stop_state: usize,
3986 enter_transition_index: usize,
3987 exit_transition_index: usize,
3988}
3989
3990#[derive(Clone, Copy, Debug)]
3991struct FastRepetitionPath {
3992 index: usize,
3993 deferred_nodes: FastDeferredNodeId,
3994 diagnostics: DiagnosticSeqId,
3995 consumed_eof: bool,
3996}
3997
3998enum FastRepetitionWork {
3999 Enter(FastRepetitionPath),
4000 Exit(FastRepetitionPath),
4001}
4002
4003struct FastRepetitionCoordinates {
4008 base_index: usize,
4009 base_state: u8,
4010 later_states: Vec<u8>,
4011}
4012
4013impl FastRepetitionCoordinates {
4014 const ENTERED: u8 = 0;
4015 const EXITED: u8 = 2;
4016
4017 const fn new(base_index: usize) -> Self {
4018 Self {
4019 base_index,
4020 base_state: 0,
4021 later_states: Vec::new(),
4022 }
4023 }
4024
4025 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4026 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4027 }
4028
4029 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4030 self.insert(path.index, path.consumed_eof, Self::EXITED)
4031 }
4032
4033 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4034 let Some(offset) = index.checked_sub(self.base_index) else {
4035 return false;
4036 };
4037 let state = if offset == 0 {
4038 &mut self.base_state
4039 } else {
4040 if self.later_states.len() < offset {
4041 self.later_states.resize(offset, 0);
4042 }
4043 &mut self.later_states[offset - 1]
4044 };
4045 let bit = 1 << (base_bit + u8::from(consumed_eof));
4046 let is_new = *state & bit == 0;
4047 *state |= bit;
4048 is_new
4049 }
4050}
4051
4052fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4053 if state.precedence_rule_decision()
4054 || !matches!(
4055 state.kind(),
4056 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4057 )
4058 || state.transitions().len() != 2
4059 {
4060 return None;
4061 }
4062 let mut enter = None;
4063 let mut exit = None;
4064 for (index, transition) in state.transitions().iter().enumerate() {
4065 if transition.kind() != ParserTransitionKind::Epsilon {
4066 return None;
4067 }
4068 let target = transition.target();
4069 if atn
4070 .state(target)
4071 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4072 {
4073 if exit.replace((index, target)).is_some() {
4074 return None;
4075 }
4076 } else if enter.replace((index, target)).is_some() {
4077 return None;
4078 }
4079 }
4080 let (enter_transition_index, enter_target) = enter?;
4081 let (exit_transition_index, exit_target) = exit?;
4082 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4083 atn.state(exit_target)?.loop_back_state()?
4084 } else {
4085 state.state_number()
4086 };
4087 Some(FastRepetitionShape {
4088 enter_target,
4089 exit_target,
4090 body_stop_state,
4091 enter_transition_index,
4092 exit_transition_index,
4093 })
4094}
4095
4096fn push_fast_repetition_work(
4097 work: &mut Vec<FastRepetitionWork>,
4098 shape: FastRepetitionShape,
4099 path: FastRepetitionPath,
4100 lookahead: Option<&DecisionLookahead>,
4101 symbol: i32,
4102) {
4103 let transition_is_viable = |transition_index: usize| {
4106 let Some(entry) = lookahead else {
4107 return true;
4108 };
4109 let Some(transition) = entry.transitions.get(transition_index) else {
4110 return true;
4111 };
4112 transition.nullable || transition.symbols.contains(symbol)
4113 };
4114 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4115 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4116 if shape.enter_transition_index < shape.exit_transition_index {
4117 if exit_is_viable {
4118 work.push(FastRepetitionWork::Exit(path));
4119 }
4120 if enter_is_viable {
4121 work.push(FastRepetitionWork::Enter(path));
4122 }
4123 } else {
4124 if enter_is_viable {
4125 work.push(FastRepetitionWork::Enter(path));
4126 }
4127 if exit_is_viable {
4128 work.push(FastRepetitionWork::Exit(path));
4129 }
4130 }
4131}
4132
4133#[derive(Clone, Debug)]
4140struct FastRecognizeKey {
4141 state_number: usize,
4142 stop_state: usize,
4143 index: usize,
4144 rule_start_index: usize,
4145 decision_start_index: Option<usize>,
4146 precedence: i32,
4147 recovery_symbols_id: usize,
4148 recovery_state: Option<usize>,
4149}
4150
4151impl PartialEq for FastRecognizeKey {
4152 fn eq(&self, other: &Self) -> bool {
4153 if self.state_number != other.state_number
4154 || self.stop_state != other.stop_state
4155 || self.index != other.index
4156 || self.rule_start_index != other.rule_start_index
4157 || self.decision_start_index != other.decision_start_index
4158 || self.precedence != other.precedence
4159 || self.recovery_state != other.recovery_state
4160 || self.recovery_symbols_id != other.recovery_symbols_id
4161 {
4162 return false;
4163 }
4164 true
4165 }
4166}
4167
4168impl Eq for FastRecognizeKey {}
4169
4170impl Hash for FastRecognizeKey {
4171 fn hash<H: Hasher>(&self, hasher: &mut H) {
4172 self.state_number.hash(hasher);
4173 self.stop_state.hash(hasher);
4174 self.index.hash(hasher);
4175 self.rule_start_index.hash(hasher);
4176 self.decision_start_index.hash(hasher);
4177 self.precedence.hash(hasher);
4178 self.recovery_state.hash(hasher);
4179 self.recovery_symbols_id.hash(hasher);
4180 }
4181}
4182
4183struct FastRecoveryRequest<'a, 'b> {
4184 atn: &'a Atn,
4185 transition: ParserTransition<'a>,
4186 expected_symbols: Rc<BTreeSet<i32>>,
4187 target: usize,
4188 request: FastRecognizeRequest,
4189 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4190 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4191 expected: &'b mut ExpectedTokens,
4192}
4193
4194struct FastCurrentTokenDeletionRequest<'a, 'b> {
4195 atn: &'a Atn,
4196 expected_symbols: Rc<BTreeSet<i32>>,
4197 request: FastRecognizeRequest,
4198 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4199 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4200 expected: &'b mut ExpectedTokens,
4201}
4202
4203#[derive(Clone, Copy)]
4204struct FastChildRuleFailureRecoveryRequest<'a> {
4205 atn: &'a Atn,
4206 rule_index: usize,
4207 start_index: usize,
4208 follow_state: usize,
4209 stop_state: usize,
4210 expected: &'a ExpectedTokens,
4211}
4212
4213struct RecoveryRequest<'a, 'b> {
4214 atn: &'a Atn,
4215 transition: ParserTransition<'a>,
4216 expected_symbols: BTreeSet<i32>,
4217 target: usize,
4218 request: RecognizeRequest<'a>,
4219 visiting: &'b mut BTreeSet<RecognizeKey>,
4220 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4221 expected: &'b mut ExpectedTokens,
4222}
4223
4224struct CurrentTokenDeletionRequest<'a, 'b> {
4225 atn: &'a Atn,
4226 expected_symbols: BTreeSet<i32>,
4227 request: RecognizeRequest<'a>,
4228 visiting: &'b mut BTreeSet<RecognizeKey>,
4229 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4230 expected: &'b mut ExpectedTokens,
4231}
4232
4233struct ConsumingFailureFallback<'a> {
4236 atn: &'a Atn,
4237 target: usize,
4238 request: RecognizeRequest<'a>,
4239 symbol: i32,
4240 expected_symbols: BTreeSet<i32>,
4241 decision_start_index: Option<usize>,
4242 decision: Option<usize>,
4243}
4244
4245struct ChildRuleFailureRecovery<'a> {
4248 atn: &'a Atn,
4249 rule_index: usize,
4250 start_index: usize,
4251 follow_state: usize,
4252 stop_state: usize,
4253 member_values: BTreeMap<usize, i64>,
4254 expected: &'a ExpectedTokens,
4255}
4256
4257#[derive(Clone, Copy, Debug)]
4259struct PredicateEval<'a> {
4260 index: usize,
4261 rule_index: usize,
4262 pred_index: usize,
4263 predicates: &'a [(usize, usize, ParserPredicate)],
4264 semantics: Option<&'a ParserSemantics>,
4265 context: Option<&'a ParserRuleContext>,
4266 local_int_arg: Option<(usize, i64)>,
4267 member_values: &'a BTreeMap<usize, i64>,
4268}
4269
4270#[derive(Clone, Copy, Debug)]
4271struct ParserSemanticHookRequest<'a> {
4272 index: usize,
4273 rule_index: usize,
4274 pred_index: usize,
4275 context: Option<&'a ParserRuleContext>,
4276 local_int_arg: Option<(usize, i64)>,
4277 member_values: &'a BTreeMap<usize, i64>,
4278}
4279
4280struct ParserSemIrCtx<'a, S, H>
4289where
4290 S: TokenSource,
4291 H: SemanticHooks,
4292{
4293 input: &'a mut CommonTokenStream<S>,
4294 tree_storage: &'a ParseTreeStorage,
4295 semantic_hooks: &'a mut H,
4296 rule_index: usize,
4297 coordinate_index: usize,
4298 rule_name: Option<&'a str>,
4299 context: Option<&'a ParserRuleContext>,
4300 local_int_arg: Option<(usize, i64)>,
4301 member_values: &'a BTreeMap<usize, i64>,
4302 invoked_predicates: &'a mut Vec<(usize, usize)>,
4303 unknown_predicate_policy: UnknownSemanticPolicy,
4307 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4308}
4309
4310impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4311where
4312 S: TokenSource,
4313 H: SemanticHooks,
4314{
4315 type TokenText<'a>
4316 = TokenView<'a>
4317 where
4318 Self: 'a;
4319
4320 fn la(&mut self, offset: isize) -> i64 {
4321 i64::from(self.input.la(offset))
4322 }
4323
4324 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4325 self.input.lt(offset)
4326 }
4327
4328 fn token_index_adjacent(&mut self) -> bool {
4329 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4330 return false;
4331 };
4332 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4333 return false;
4334 };
4335 first + 1 == second
4336 }
4337
4338 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4339 self.context.and_then(|context| {
4340 context
4341 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4342 .next()
4343 .map(crate::tree::RuleNodeView::text)
4344 })
4345 }
4346
4347 fn member(&self, member: usize) -> Option<i64> {
4348 Some(self.member_values.get(&member).copied().unwrap_or_default())
4349 }
4350
4351 fn local_arg(&self) -> Option<i64> {
4352 self.local_int_arg.map(|(_, value)| value)
4353 }
4354
4355 fn column(&self) -> Option<i64> {
4356 None
4357 }
4358
4359 fn token_start_column(&self) -> Option<i64> {
4360 None
4361 }
4362
4363 fn token_text_so_far(&self) -> Option<String> {
4364 None
4365 }
4366
4367 fn hook(&mut self, _hook: HookId) -> bool {
4368 let mut ctx = ParserSemCtx {
4369 input: &mut *self.input,
4370 tree_storage: self.tree_storage,
4371 rule_index: self.rule_index,
4372 coordinate_index: self.coordinate_index,
4373 rule_name: self.rule_name.map(str::to_owned),
4374 context: self.context,
4375 tree: None,
4376 local_int_arg: self.local_int_arg,
4377 member_values: self.member_values,
4378 action: None,
4379 };
4380 match self
4381 .semantic_hooks
4382 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4383 {
4384 Some(result) => result,
4385 None => apply_unknown_predicate_policy(
4389 self.unknown_predicate_policy,
4390 self.rule_index,
4391 self.coordinate_index,
4392 self.unknown_predicate_hits,
4393 ),
4394 }
4395 }
4396
4397 fn trace_bool(&mut self, value: bool) -> bool {
4398 let key = (self.rule_index, self.coordinate_index);
4399 if !self.invoked_predicates.contains(&key) {
4400 self.invoked_predicates.push(key);
4401 use std::io::Write as _;
4402 let mut stdout = std::io::stdout().lock();
4403 let _ = writeln!(stdout, "eval={value}");
4404 }
4405 value
4406 }
4407}
4408
4409struct PredicateFailureRecovery<'a> {
4411 rule_index: usize,
4412 index: usize,
4413 message: &'a str,
4414 member_values: BTreeMap<usize, i64>,
4415 return_values: BTreeMap<String, i64>,
4416 rule_alt_number: usize,
4417}
4418
4419#[derive(Debug)]
4420enum DirectAdaptiveParseControl {
4421 Fallback(DirectAdaptiveFallback),
4422}
4423
4424#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4425enum DirectAdaptiveFallback {
4426 Action,
4427 InvalidAlt,
4428 LeftRecursiveBoundary,
4429 MissingAtn,
4430 NoTransition,
4431 Predicate,
4432 Prediction,
4433 Precedence,
4434 RuleStop,
4435 SemanticContext,
4436 StepLimit,
4437 TokenMismatch,
4438 UnknownDecision,
4439}
4440
4441type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
4442
4443struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
4444where
4445 S: TokenSource,
4446 H: SemanticHooks,
4447{
4448 parser: &'sim mut BaseParser<S, H>,
4449 atn: &'atn Atn,
4450 simulator: &'sim mut ParserAtnSimulator<'atn>,
4451 decision_by_state: Vec<Option<usize>>,
4452 steps: usize,
4453}
4454
4455#[derive(Clone, Debug, Eq, PartialEq)]
4465pub struct GeneratedMatch {
4466 children: GeneratedMatchChildren,
4467 consumed_eof: bool,
4468}
4469
4470#[derive(Clone, Debug, Eq, PartialEq)]
4471enum GeneratedMatchChildren {
4472 One(ParseTree),
4473 Many(Vec<ParseTree>),
4474}
4475
4476struct GeneratedMatchChildrenIntoIter {
4477 one: Option<ParseTree>,
4478 many: Option<std::vec::IntoIter<ParseTree>>,
4479}
4480
4481impl Iterator for GeneratedMatchChildrenIntoIter {
4482 type Item = ParseTree;
4483
4484 fn next(&mut self) -> Option<Self::Item> {
4485 self.one
4486 .take()
4487 .or_else(|| self.many.as_mut().and_then(Iterator::next))
4488 }
4489}
4490
4491impl GeneratedMatch {
4492 #[must_use]
4496 pub fn children(&self) -> &[ParseTree] {
4497 match &self.children {
4498 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
4499 GeneratedMatchChildren::Many(children) => children,
4500 }
4501 }
4502
4503 #[must_use]
4506 pub fn into_children(self) -> Vec<ParseTree> {
4507 match self.children {
4508 GeneratedMatchChildren::One(child) => vec![child],
4509 GeneratedMatchChildren::Many(children) => children,
4510 }
4511 }
4512
4513 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
4515 match self.children {
4516 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
4517 one: Some(child),
4518 many: None,
4519 },
4520 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
4521 one: None,
4522 many: Some(children.into_iter()),
4523 },
4524 }
4525 }
4526
4527 #[must_use]
4529 pub const fn consumed_eof(&self) -> bool {
4530 self.consumed_eof
4531 }
4532}
4533
4534impl<S> BaseParser<S, NoSemanticHooks>
4535where
4536 S: TokenSource,
4537{
4538 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
4541 Self::with_semantic_hooks(input, data, NoSemanticHooks)
4542 }
4543}
4544
4545impl<S, H> BaseParser<S, H>
4546where
4547 S: TokenSource,
4548 H: SemanticHooks,
4549{
4550 pub fn with_semantic_hooks(
4552 input: CommonTokenStream<S>,
4553 data: RecognizerData,
4554 semantic_hooks: H,
4555 ) -> Self {
4556 Self {
4557 input,
4558 tree: ParseTreeStorage::new(),
4559 data,
4560 semantic_hooks,
4561 build_parse_trees: true,
4562 syntax_errors: 0,
4563 report_diagnostic_errors: false,
4564 prediction_mode: PredictionMode::Ll,
4565 prediction_diagnostics: Vec::new(),
4566 reported_prediction_diagnostics: BTreeSet::new(),
4567 generated_parser_diagnostics: Vec::new(),
4568 generated_sync_expected: None,
4569 int_members: BTreeMap::new(),
4570 rule_context_stack: Vec::new(),
4571 rule_context_version: 0,
4572 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
4573 pending_invoking_states: Vec::new(),
4574 precedence_stack: vec![0],
4575 invoked_predicates: Vec::new(),
4576 bail_on_error: false,
4577 unknown_predicate_policy: UnknownSemanticPolicy::default(),
4578 unknown_predicate_hits: Vec::new(),
4579 unhandled_action_hits: Vec::new(),
4580 rule_first_set_cache: Vec::new(),
4581 state_expected_cache: FxHashMap::default(),
4582 state_expected_token_cache: FxHashMap::default(),
4583 rule_stop_reach_cache: Vec::new(),
4584 recovery_symbols_intern: FxHashMap::default(),
4585 decision_lookahead_cache: FxHashMap::default(),
4586 ll1_decision_cache: FxHashMap::default(),
4587 fast_predicate_cache: FxHashMap::default(),
4588 empty_cycle_cache: Vec::new(),
4589 single_outcome_memo_mode: SingleOutcomeMemoMode::Probe,
4590 single_outcome_probe_seen: FxHashSet::default(),
4591 single_outcome_probe_samples: 0,
4592 single_outcome_probe_repeats: 0,
4593 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
4594 empty_recovery_symbols: Rc::new(BTreeSet::new()),
4595 fast_first_set_prefilter: true,
4596 fast_recovery_enabled: true,
4597 fast_token_nodes_enabled: true,
4598 recognition_arena: RecognitionArena::default(),
4599 last_recognition_arena_root: NodeSeqId::EMPTY,
4600 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
4601 }
4602 }
4603
4604 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
4605 &mut self.input
4606 }
4607
4608 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
4619 self.unknown_predicate_policy = policy;
4620 }
4621
4622 #[must_use]
4628 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
4629 let error = self.unknown_semantic_error();
4630 self.unknown_predicate_hits.clear();
4631 self.unhandled_action_hits.clear();
4632 error
4633 }
4634
4635 pub fn reset_unknown_semantic_hits(&mut self) {
4642 self.unknown_predicate_hits.clear();
4643 self.unhandled_action_hits.clear();
4644 }
4645
4646 #[must_use]
4648 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
4649 &self.input
4650 }
4651
4652 #[must_use]
4654 pub const fn token_store(&self) -> &TokenStore {
4655 self.input.token_store()
4656 }
4657
4658 #[must_use]
4660 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
4661 &self.tree
4662 }
4663
4664 #[must_use]
4666 pub fn node(&self, id: NodeId) -> Node<'_> {
4667 self.tree
4668 .node(self.input.token_store(), id)
4669 .expect("parser-produced node ID should remain valid")
4670 }
4671
4672 #[must_use]
4674 pub fn into_token_stream(self) -> CommonTokenStream<S> {
4675 self.input
4676 }
4677
4678 #[must_use]
4680 pub fn into_token_store(self) -> TokenStore {
4681 self.input.into_token_store()
4682 }
4683
4684 #[must_use]
4686 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
4687 ParsedFile::new(self.input.into_token_store(), self.tree, root)
4688 }
4689
4690 pub const fn number_of_syntax_errors(&self) -> usize {
4693 self.syntax_errors
4694 }
4695
4696 #[must_use]
4702 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
4703 self.recognition_arena.stats(
4704 self.last_recognition_arena_root,
4705 self.last_recognition_arena_diagnostics,
4706 )
4707 }
4708
4709 pub const fn record_generated_syntax_error(&mut self) {
4712 self.record_syntax_errors(1);
4713 }
4714
4715 const fn record_syntax_errors(&mut self, count: usize) {
4716 self.syntax_errors = self.syntax_errors.saturating_add(count);
4717 }
4718
4719 pub fn report_token_source_errors(&mut self) {
4722 report_token_source_errors(&self.input.drain_source_errors());
4723 }
4724
4725 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
4728 GeneratedDiagnosticsCheckpoint {
4729 diagnostics_len: self.generated_parser_diagnostics.len(),
4730 syntax_errors: self.syntax_errors,
4731 tree: self.tree.checkpoint(),
4732 }
4733 }
4734
4735 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
4737 self.generated_parser_diagnostics
4738 .truncate(marker.diagnostics_len);
4739 self.syntax_errors = marker.syntax_errors;
4740 self.generated_sync_expected = None;
4741 self.tree.rollback(marker.tree);
4742 }
4743
4744 pub fn report_generated_parser_diagnostics(&mut self) {
4746 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
4747 let token_errors = self.input.drain_source_errors();
4748 report_generated_diagnostics(&parser_diagnostics, &token_errors);
4749 }
4750
4751 pub fn record_generated_ambiguity_diagnostic(
4754 &mut self,
4755 atn: &Atn,
4756 state_number: usize,
4757 start_index: usize,
4758 stop_index: usize,
4759 alts: &[usize],
4760 ) {
4761 if !self.report_diagnostic_errors || alts.len() < 2 {
4762 return;
4763 }
4764 let Some(decision) = atn
4765 .decision_to_state()
4766 .iter()
4767 .position(|candidate| candidate == state_number)
4768 else {
4769 return;
4770 };
4771 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
4772 return;
4773 };
4774 let rule_name = self
4775 .rule_names()
4776 .get(rule_index)
4777 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
4778 let input = display_input_text(&self.input.text(start_index, stop_index));
4779 let alts = alts
4780 .iter()
4781 .map(usize::to_string)
4782 .collect::<Vec<_>>()
4783 .join(", ");
4784 let key = (decision, start_index, format!("{alts}:{input}"));
4785 if !self.reported_prediction_diagnostics.insert(key) {
4786 return;
4787 }
4788 let start_diagnostic = diagnostic_for_token(
4789 self.token_at(start_index),
4790 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
4791 );
4792 let stop_diagnostic = diagnostic_for_token(
4793 self.token_at(stop_index),
4794 format!(
4795 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
4796 ),
4797 );
4798 self.generated_parser_diagnostics.push(start_diagnostic);
4799 self.generated_parser_diagnostics.push(stop_diagnostic);
4800 }
4801
4802 pub fn record_generated_prediction_diagnostic(
4805 &mut self,
4806 atn: &Atn,
4807 state_number: usize,
4808 prediction: &ParserAtnPrediction,
4809 ) {
4810 let Some(diagnostic) = &prediction.diagnostic else {
4811 return;
4812 };
4813 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
4814 return;
4815 }
4816 let Some(decision) = atn
4817 .decision_to_state()
4818 .iter()
4819 .position(|candidate| candidate == state_number)
4820 else {
4821 return;
4822 };
4823 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
4824 return;
4825 };
4826 let rule_name = self
4827 .rule_names()
4828 .get(rule_index)
4829 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
4830 let attempt_input = display_input_text(
4831 &self
4832 .input
4833 .text(diagnostic.start_index, diagnostic.sll_stop_index),
4834 );
4835 let result_input = display_input_text(
4836 &self
4837 .input
4838 .text(diagnostic.start_index, diagnostic.ll_stop_index),
4839 );
4840 let alts = diagnostic
4841 .conflicting_alts
4842 .iter()
4843 .map(usize::to_string)
4844 .collect::<Vec<_>>()
4845 .join(", ");
4846 let key = (
4847 decision,
4848 diagnostic.start_index,
4849 format!(
4850 "{:?}:{alts}:{attempt_input}:{result_input}",
4851 diagnostic.kind
4852 ),
4853 );
4854 if !self.reported_prediction_diagnostics.insert(key) {
4855 return;
4856 }
4857 let attempt_diagnostic = diagnostic_for_token(
4858 self.token_at(diagnostic.sll_stop_index),
4859 format!(
4860 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
4861 ),
4862 );
4863 self.generated_parser_diagnostics.push(attempt_diagnostic);
4864 let message = match diagnostic.kind {
4865 ParserAtnPredictionDiagnosticKind::Ambiguity => {
4866 if !diagnostic.exact {
4871 return;
4872 }
4873 format!(
4874 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
4875 )
4876 }
4877 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
4878 format!(
4879 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
4880 )
4881 }
4882 };
4883 let result_diagnostic =
4884 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
4885 self.generated_parser_diagnostics.push(result_diagnostic);
4886 }
4887
4888 pub fn la(&self, offset: isize) -> i32 {
4889 self.input.la_token(offset)
4890 }
4891
4892 pub fn consume(&mut self) {
4893 IntStream::consume(&mut self.input);
4894 }
4895
4896 pub fn set_int_member(&mut self, member: usize, value: i64) {
4898 self.int_members.insert(member, value);
4899 }
4900
4901 pub fn int_member(&self, member: usize) -> Option<i64> {
4903 self.int_members.get(&member).copied()
4904 }
4905
4906 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
4909 self.int_members.clone()
4910 }
4911
4912 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
4914 self.int_members = members;
4915 }
4916
4917 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
4919 let value = self.int_members.entry(member).or_default();
4920 *value += delta;
4921 *value
4922 }
4923
4924 fn token_type_for_id(&self, id: TokenId) -> i32 {
4925 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
4926 }
4927
4928 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
4929 if self.build_parse_trees {
4930 self.tree.terminal(id)
4931 } else {
4932 NodeId::placeholder()
4933 }
4934 }
4935
4936 fn error_tree(&mut self, id: TokenId) -> ParseTree {
4937 if self.build_parse_trees {
4938 self.tree.error(id)
4939 } else {
4940 NodeId::placeholder()
4941 }
4942 }
4943
4944 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
4945 context.set_start_id(id);
4946 }
4947
4948 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
4949 context.set_stop_id(id);
4950 }
4951
4952 fn insert_synthetic_token(
4953 &mut self,
4954 token_type: i32,
4955 text: String,
4956 line: usize,
4957 column: usize,
4958 ) -> Result<TokenId, AntlrError> {
4959 self.input
4960 .insert(
4961 TokenSpec::explicit(token_type, text)
4962 .with_span(usize::MAX, usize::MAX)
4963 .with_byte_span(0, 0)
4964 .with_position(line, column),
4965 )
4966 .map_err(|error| AntlrError::Unsupported(error.to_string()))
4967 }
4968
4969 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
4976 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
4977 line: 0,
4978 column: 0,
4979 message: "missing current token".to_owned(),
4980 })?;
4981 let current_type = self.token_type_for_id(current);
4982 if current_type == token_type {
4983 self.consume();
4984 Ok(self.terminal_tree(current))
4985 } else {
4986 Err(AntlrError::MismatchedInput {
4987 expected: self.vocabulary().display_name(token_type),
4988 found: self.vocabulary().display_name(current_type),
4989 })
4990 }
4991 }
4992
4993 pub fn match_token_recovering(
4997 &mut self,
4998 token_type: i32,
4999 follow_state: usize,
5000 atn: &Atn,
5001 ) -> Result<GeneratedMatch, AntlrError> {
5002 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5003 line: 0,
5004 column: 0,
5005 message: "missing current token".to_owned(),
5006 })?;
5007 let current_type = self.token_type_for_id(current);
5008 if current_type == token_type {
5009 self.generated_sync_expected = None;
5010 let consumed_eof = current_type == TOKEN_EOF;
5011 self.consume();
5012 return Ok(GeneratedMatch {
5013 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5014 consumed_eof,
5015 });
5016 }
5017 let mut expected_symbols = BTreeSet::new();
5018 expected_symbols.insert(token_type);
5019 self.recover_generated_match(current, &expected_symbols, follow_state, atn, |symbol| {
5020 symbol == token_type
5021 })
5022 }
5023
5024 pub fn match_set_recovering(
5025 &mut self,
5026 intervals: &[(i32, i32)],
5027 follow_state: usize,
5028 atn: &Atn,
5029 ) -> Result<GeneratedMatch, AntlrError> {
5030 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5031 line: 0,
5032 column: 0,
5033 message: "missing current token".to_owned(),
5034 })?;
5035 let current_type = self.token_type_for_id(current);
5036 if interval_set_contains(intervals, current_type) {
5037 self.generated_sync_expected = None;
5038 let consumed_eof = current_type == TOKEN_EOF;
5039 self.consume();
5040 return Ok(GeneratedMatch {
5041 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5042 consumed_eof,
5043 });
5044 }
5045 let expected_symbols = interval_symbols(intervals);
5046 self.recover_generated_match(current, &expected_symbols, follow_state, atn, |symbol| {
5047 interval_set_contains(intervals, symbol)
5048 })
5049 }
5050
5051 pub fn match_not_set_recovering(
5052 &mut self,
5053 intervals: &[(i32, i32)],
5054 min_vocabulary: i32,
5055 max_vocabulary: i32,
5056 follow_state: usize,
5057 atn: &Atn,
5058 ) -> Result<GeneratedMatch, AntlrError> {
5059 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5060 line: 0,
5061 column: 0,
5062 message: "missing current token".to_owned(),
5063 })?;
5064 let current_type = self.token_type_for_id(current);
5065 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5066 && !interval_set_contains(intervals, current_type)
5067 {
5068 self.generated_sync_expected = None;
5069 let consumed_eof = current_type == TOKEN_EOF;
5070 self.consume();
5071 return Ok(GeneratedMatch {
5072 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5073 consumed_eof,
5074 });
5075 }
5076 let expected_symbols =
5077 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
5078 self.recover_generated_match(current, &expected_symbols, follow_state, atn, |symbol| {
5079 (min_vocabulary..=max_vocabulary).contains(&symbol)
5080 && !interval_set_contains(intervals, symbol)
5081 })
5082 }
5083
5084 fn recover_generated_match(
5085 &mut self,
5086 current: TokenId,
5087 expected_symbols: &BTreeSet<i32>,
5088 follow_state: usize,
5089 atn: &Atn,
5090 matches: impl Fn(i32) -> bool,
5091 ) -> Result<GeneratedMatch, AntlrError> {
5092 let expected_display = self.expected_symbols_display(expected_symbols);
5093 let (current_type, current_line, current_column, current_display) = {
5094 let token = self
5095 .input
5096 .token_view(current)
5097 .expect("current token ID should be valid");
5098 (
5099 token.token_type(),
5100 token.line(),
5101 token.column(),
5102 token_input_display(&token),
5103 )
5104 };
5105 if self.bail_on_error {
5106 return Err(AntlrError::ParserError {
5107 line: current_line,
5108 column: current_column,
5109 message: format!("mismatched input {current_display} expecting {expected_display}"),
5110 });
5111 }
5112 if current_type != TOKEN_EOF
5113 && let Some(next) = self.input.lt_id(2)
5114 && matches(self.token_type_for_id(next))
5115 {
5116 let message =
5117 format!("extraneous input {current_display} expecting {expected_display}");
5118 self.push_generated_parser_diagnostic(ParserDiagnostic {
5119 line: current_line,
5120 column: current_column,
5121 message,
5122 });
5123 self.record_syntax_errors(1);
5124 self.generated_sync_expected = None;
5125 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
5128 self.consume();
5129 self.consume();
5130 return Ok(GeneratedMatch {
5131 children: GeneratedMatchChildren::Many(vec![
5132 self.error_tree(current),
5133 self.terminal_tree(next),
5134 ]),
5135 consumed_eof,
5136 });
5137 }
5138 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
5139 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
5148 && self
5149 .cached_state_expected_symbols(atn, follow_state)
5150 .contains(&TOKEN_EOF);
5151 if follow_symbols.contains(¤t_type)
5152 && (current_type != TOKEN_EOF
5153 || self.rule_context_stack.len() > 1
5154 || expected_symbols.is_empty()
5155 || follow_explicitly_expects_eof)
5156 {
5157 let message = format!("missing {expected_display} at {current_display}");
5158 self.push_generated_parser_diagnostic(ParserDiagnostic {
5159 line: current_line,
5160 column: current_column,
5161 message,
5162 });
5163 self.record_syntax_errors(1);
5164 self.generated_sync_expected = None;
5165 let token_type = expected_symbols.iter().next().copied().unwrap_or(TOKEN_EOF);
5166 let mut missing_symbol = BTreeSet::new();
5167 missing_symbol.insert(token_type);
5168 let missing_display = self.expected_symbols_display(&missing_symbol);
5169 let token = self.insert_synthetic_token(
5170 token_type,
5171 format!("<missing {missing_display}>"),
5172 current_line,
5173 current_column,
5174 )?;
5175 return Ok(GeneratedMatch {
5180 children: GeneratedMatchChildren::One(self.error_tree(token)),
5181 consumed_eof: false,
5182 });
5183 }
5184 let mismatch_expected = self.generated_sync_expected.take().map_or_else(
5185 || expected_symbols.clone(),
5186 |symbols| symbols.to_btree_set(),
5187 );
5188 let mismatch_expected_display = self.expected_symbols_display(&mismatch_expected);
5189 Err(AntlrError::ParserError {
5190 line: current_line,
5191 column: current_column,
5192 message: format!(
5193 "mismatched input {current_display} expecting {mismatch_expected_display}"
5194 ),
5195 })
5196 }
5197
5198 fn generated_recovery_follow_symbols(
5199 &mut self,
5200 atn: &Atn,
5201 follow_state: usize,
5202 ) -> BTreeSet<i32> {
5203 let mut follow = self
5204 .cached_state_expected_symbols(atn, follow_state)
5205 .as_ref()
5206 .clone();
5207 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
5208 follow.extend(self.context_expected_symbols(atn));
5209 }
5210 follow
5211 }
5212
5213 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
5214 self.match_token(TOKEN_EOF)
5215 }
5216
5217 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
5218 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
5219 }
5220
5221 pub fn match_not_set(
5222 &mut self,
5223 intervals: &[(i32, i32)],
5224 min_vocabulary: i32,
5225 max_vocabulary: i32,
5226 ) -> Result<ParseTree, AntlrError> {
5227 self.match_interval_condition(intervals, |symbol| {
5228 (min_vocabulary..=max_vocabulary).contains(&symbol)
5229 && !interval_set_contains(intervals, symbol)
5230 })
5231 }
5232
5233 fn match_interval_condition(
5234 &mut self,
5235 intervals: &[(i32, i32)],
5236 matches: impl FnOnce(i32) -> bool,
5237 ) -> Result<ParseTree, AntlrError> {
5238 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5239 line: 0,
5240 column: 0,
5241 message: "missing current token".to_owned(),
5242 })?;
5243 let current_type = self.token_type_for_id(current);
5244 if matches(current_type) {
5245 self.consume();
5246 Ok(self.terminal_tree(current))
5247 } else {
5248 Err(AntlrError::MismatchedInput {
5249 expected: self.interval_display(intervals),
5250 found: self.vocabulary().display_name(current_type),
5251 })
5252 }
5253 }
5254
5255 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
5256 let values = intervals
5257 .iter()
5258 .map(|(start, stop)| {
5259 if start == stop {
5260 self.vocabulary().display_name(*start)
5261 } else {
5262 format!(
5263 "{}..{}",
5264 self.vocabulary().display_name(*start),
5265 self.vocabulary().display_name(*stop)
5266 )
5267 }
5268 })
5269 .collect::<Vec<_>>()
5270 .join(", ");
5271 format!("{{{values}}}")
5272 }
5273
5274 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
5275 if self.build_parse_trees {
5276 self.tree.finish_rule(context)
5277 } else {
5278 NodeId::placeholder()
5279 }
5280 }
5281
5282 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
5285 self.set_state(state);
5286 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
5287 self.rule_context_stack.push(RuleContextFrame {
5288 rule_index,
5289 invoking_state,
5290 });
5291 self.advance_rule_context_version();
5292 let start_index = self.current_visible_index();
5293 let mut context = ParserRuleContext::new(rule_index, invoking_state);
5294 if let Some(token) = self.token_id_at(start_index) {
5295 self.set_context_start(&mut context, token);
5296 }
5297 context
5298 }
5299
5300 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
5307 let marker = self.pending_invoking_states.len();
5308 self.pending_invoking_states.push(invoking_state);
5309 marker
5310 }
5311
5312 pub fn discard_invoking_state(&mut self, marker: usize) {
5314 self.pending_invoking_states.truncate(marker);
5315 }
5316
5317 pub fn exit_rule(&mut self) {
5319 self.rule_context_stack.pop();
5320 self.advance_rule_context_version();
5321 }
5322
5323 pub fn prediction_context_return_states<'a>(
5326 &'a self,
5327 atn: &'a Atn,
5328 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
5329 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
5330 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
5331 return None;
5332 };
5333 let Some(Transition::Rule { follow_state, .. }) = atn
5334 .state(state_number)
5335 .and_then(|state| state.transitions().first())
5336 .map(ParserTransition::data)
5337 else {
5338 return None;
5339 };
5340 Some(follow_state)
5341 })
5342 }
5343
5344 pub const fn rule_context_version(&self) -> usize {
5349 self.rule_context_version
5350 }
5351
5352 const fn advance_rule_context_version(&mut self) {
5353 self.rule_context_version = self.rule_context_version.wrapping_add(1);
5354 }
5355
5356 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
5361 if self.build_parse_trees {
5362 self.tree.add_child(context, child);
5363 } else {
5364 context.note_matched_child();
5365 }
5366 }
5367
5368 fn release_tree_scratch_if_idle(&mut self) {
5369 if self.rule_context_stack.is_empty() {
5370 self.tree.release_scratch();
5371 }
5372 }
5373
5374 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
5376 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5377 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5378 self.set_context_stop(&mut context, token);
5379 }
5380 let node = self.rule_node(context);
5381 self.exit_rule();
5382 self.release_tree_scratch_if_idle();
5383 node
5384 }
5385
5386 pub fn recover_generated_rule(
5393 &mut self,
5394 context: &mut ParserRuleContext,
5395 atn: &Atn,
5396 error: AntlrError,
5397 ) {
5398 let diagnostic = self.generated_rule_error_diagnostic(error);
5399 self.push_generated_parser_diagnostic(diagnostic);
5400 self.generated_sync_expected = None;
5401 let recovery_symbols = self.context_expected_symbols(atn);
5402 loop {
5403 let symbol = self.la(1);
5404 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
5405 break;
5406 }
5407 let Some(token) = self.input.lt_id(1) else {
5408 break;
5409 };
5410 self.consume();
5411 let child = self.error_tree(token);
5412 self.add_parse_child(context, child);
5413 }
5414 self.record_syntax_errors(1);
5415 }
5416
5417 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
5418 if self
5419 .generated_parser_diagnostics
5420 .iter()
5421 .any(|existing| existing == &diagnostic)
5422 {
5423 return;
5424 }
5425 self.generated_parser_diagnostics.push(diagnostic);
5426 }
5427
5428 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
5429 match error {
5430 AntlrError::ParserError {
5431 line,
5432 column,
5433 message,
5434 } => ParserDiagnostic {
5435 line,
5436 column,
5437 message,
5438 },
5439 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
5440 self.input.lt(1),
5441 format!("mismatched input {found} expecting {expected}"),
5442 ),
5443 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
5444 self.input.lt(1),
5445 format!("no viable alternative at input {input}"),
5446 ),
5447 AntlrError::LexerError {
5448 line,
5449 column,
5450 message,
5451 } => ParserDiagnostic {
5452 line,
5453 column,
5454 message,
5455 },
5456 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
5457 }
5458 }
5459
5460 pub fn finish_recursion_rule(
5462 &mut self,
5463 mut context: ParserRuleContext,
5464 consumed_eof: bool,
5465 ) -> ParseTree {
5466 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5467 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5468 self.set_context_stop(&mut context, token);
5469 }
5470 let node = self.rule_node(context);
5471 self.unroll_recursion_context();
5472 self.release_tree_scratch_if_idle();
5473 node
5474 }
5475
5476 pub fn enter_recursion_rule(
5478 &mut self,
5479 state: isize,
5480 rule_index: usize,
5481 precedence: i32,
5482 ) -> ParserRuleContext {
5483 self.precedence_stack.push(precedence);
5484 self.enter_rule(state, rule_index)
5485 }
5486
5487 pub fn push_new_recursion_context(
5489 &mut self,
5490 state: isize,
5491 rule_index: usize,
5492 ) -> ParserRuleContext {
5493 self.set_state(state);
5494 ParserRuleContext::new(rule_index, state)
5495 }
5496
5497 pub fn push_new_recursion_context_with_previous(
5500 &mut self,
5501 state: isize,
5502 rule_index: usize,
5503 current: &mut ParserRuleContext,
5504 ) {
5505 self.set_state(state);
5506 if let Some(stop) = self
5507 .rule_stop_token_index(self.input.index(), false)
5508 .and_then(|index| self.token_id_at(index))
5509 {
5510 self.set_context_stop(current, stop);
5511 }
5512 let invoking_state = current.invoking_state();
5513 let start = current.start_id();
5514 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
5515 if start.is_some() {
5516 replacement.set_start_from_context(current);
5517 }
5518 let previous = std::mem::replace(current, replacement);
5519 if self.build_parse_trees {
5520 let previous = self.rule_node(previous);
5521 self.tree.add_child(current, previous);
5522 }
5523 }
5524
5525 pub fn unroll_recursion_context(&mut self) {
5527 if self.precedence_stack.len() > 1 {
5528 self.precedence_stack.pop();
5529 }
5530 self.exit_rule();
5531 }
5532
5533 pub fn left_recursive_loop_enter_prediction(
5547 &mut self,
5548 atn: &Atn,
5549 state_number: usize,
5550 precedence: i32,
5551 ) -> Option<bool> {
5552 let symbol = self.la(1);
5553 if symbol == TOKEN_EOF {
5554 return Some(false);
5555 }
5556 let operator_lookahead =
5557 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
5558 let can_single = operator_lookahead.single_token.contains(symbol);
5559 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
5560 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
5561 if !can_single && !can_multi && !can_predicate {
5562 return Some(false);
5563 }
5564 if can_predicate && !can_single {
5565 return None;
5566 }
5567 if !can_single && can_multi && precedence > 0 {
5571 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
5572 if baseline.single_token.contains(symbol) {
5573 return None;
5574 }
5575 }
5576 let atn_key = SharedAtnCacheKey::for_atn(atn);
5577 let cached_overlap = self
5578 .left_recursive_caller_overlap_cache
5579 .iter()
5580 .flatten()
5581 .find(|entry| {
5582 entry.atn_key == atn_key
5583 && entry.state_number == state_number
5584 && entry.symbol == symbol
5585 && entry.context_version == self.rule_context_version
5586 })
5587 .map(|entry| entry.overlaps);
5588 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
5589 let overlaps = caller_context_can_match_symbol_before_state(
5590 atn,
5591 self.prediction_context_return_states(atn),
5592 state_number,
5593 symbol,
5594 );
5595 if let Some(slot) = self
5596 .left_recursive_caller_overlap_cache
5597 .iter_mut()
5598 .find(|slot| slot.is_none())
5599 {
5600 *slot = Some(LeftRecursiveCallerOverlap {
5601 atn_key,
5602 state_number,
5603 symbol,
5604 context_version: self.rule_context_version,
5605 overlaps,
5606 });
5607 }
5608 overlaps
5609 });
5610 if caller_overlaps {
5611 return None;
5612 }
5613 Some(true)
5614 }
5615
5616 fn cached_left_recursive_operator_lookahead(
5617 atn: &Atn,
5618 state_number: usize,
5619 precedence: i32,
5620 ) -> Rc<LeftRecursiveOperatorLookahead> {
5621 with_shared_atn_caches(atn, |cache| {
5622 let key = (state_number, precedence);
5623 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
5624 return Rc::clone(cached);
5625 }
5626 let lookahead = Rc::new(left_recursive_operator_lookahead(
5627 atn,
5628 state_number,
5629 precedence,
5630 ));
5631 cache
5632 .left_recursive_operator_lookahead
5633 .insert(key, Rc::clone(&lookahead));
5634 lookahead
5635 })
5636 }
5637
5638 pub fn left_recursive_loop_enter_matches(
5641 &mut self,
5642 atn: &Atn,
5643 state_number: usize,
5644 precedence: i32,
5645 ) -> bool {
5646 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
5647 }
5648
5649 pub fn precpred(&self, precedence: i32) -> bool {
5651 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
5652 }
5653
5654 pub fn parser_semantic_predicate_matches(
5657 &mut self,
5658 predicates: &[(usize, usize, ParserPredicate)],
5659 rule_index: usize,
5660 pred_index: usize,
5661 ) -> bool {
5662 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
5663 }
5664
5665 pub fn parser_semantic_predicate_matches_with_local(
5668 &mut self,
5669 predicates: &[(usize, usize, ParserPredicate)],
5670 rule_index: usize,
5671 pred_index: usize,
5672 local_int_arg: i32,
5673 ) -> bool {
5674 self.parser_semantic_predicate_matches_inner(
5675 predicates,
5676 rule_index,
5677 pred_index,
5678 Some((rule_index, i64::from(local_int_arg))),
5679 )
5680 }
5681
5682 fn parser_semantic_predicate_matches_inner(
5683 &mut self,
5684 predicates: &[(usize, usize, ParserPredicate)],
5685 rule_index: usize,
5686 pred_index: usize,
5687 local_int_arg: Option<(usize, i64)>,
5688 ) -> bool {
5689 let index = self.input.index();
5690 let member_values = self.int_members.clone();
5691 self.parser_predicate_matches(PredicateEval {
5692 index,
5693 rule_index,
5694 pred_index,
5695 predicates,
5696 semantics: None,
5697 context: None,
5698 local_int_arg,
5699 member_values: &member_values,
5700 })
5701 }
5702
5703 pub fn parser_semantic_predicate_matches_with_context_and_local(
5706 &mut self,
5707 predicates: &[(usize, usize, ParserPredicate)],
5708 rule_index: usize,
5709 pred_index: usize,
5710 context: &ParserRuleContext,
5711 local_int_arg: i32,
5712 ) -> bool {
5713 let index = self.input.index();
5714 let member_values = self.int_members.clone();
5715 self.parser_predicate_matches(PredicateEval {
5716 index,
5717 rule_index,
5718 pred_index,
5719 predicates,
5720 semantics: None,
5721 context: Some(context),
5722 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
5723 member_values: &member_values,
5724 })
5725 }
5726
5727 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
5730 &mut self,
5731 semantics: &ParserSemantics,
5732 rule_index: usize,
5733 pred_index: usize,
5734 context: &ParserRuleContext,
5735 local_int_arg: i32,
5736 ) -> bool {
5737 let index = self.input.index();
5738 let member_values = self.int_members.clone();
5739 self.parser_predicate_matches(PredicateEval {
5740 index,
5741 rule_index,
5742 pred_index,
5743 predicates: &[],
5744 semantics: Some(semantics),
5745 context: Some(context),
5746 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
5747 member_values: &member_values,
5748 })
5749 }
5750
5751 pub fn parser_semantic_predicate_failure_message(
5754 &self,
5755 rule_index: usize,
5756 pred_index: usize,
5757 predicates: &[(usize, usize, ParserPredicate)],
5758 ) -> Option<&'static str> {
5759 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
5760 }
5761
5762 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
5764 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5765 line: 0,
5766 column: 0,
5767 message: "missing current token".to_owned(),
5768 })?;
5769 if self.token_type_for_id(current) == TOKEN_EOF {
5770 return Err(AntlrError::MismatchedInput {
5771 expected: "wildcard".to_owned(),
5772 found: self.vocabulary().display_name(TOKEN_EOF),
5773 });
5774 }
5775 self.consume();
5776 Ok(self.terminal_tree(current))
5777 }
5778
5779 #[allow(clippy::unnecessary_wraps)]
5783 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
5784 self.set_state(state);
5785 Ok(())
5786 }
5787
5788 pub fn sync_decision(
5796 &mut self,
5797 atn: &Atn,
5798 state_number: usize,
5799 current_context_empty: bool,
5800 loop_back: bool,
5801 ) -> Result<Vec<ParseTree>, AntlrError> {
5802 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
5803 self.generated_sync_expected = None;
5804 let Some(state) = atn.state(state_number) else {
5805 return Ok(Vec::new());
5806 };
5807 let Some(rule_index) = state.rule_index() else {
5808 return Ok(Vec::new());
5809 };
5810 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
5811 return Ok(Vec::new());
5812 };
5813 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
5814 let symbol = self.la(1);
5815 let mut has_expected_symbols = false;
5816 let mut nullable = false;
5817 let mut explicit_eof_expected = false;
5825 for transition in &entry.transitions {
5826 if transition.symbols.contains(symbol) {
5827 return Ok(Vec::new());
5828 }
5829 has_expected_symbols |= !transition.symbols.is_empty();
5830 nullable |= transition.nullable;
5831 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
5832 }
5833 if nullable && self.context_expected_contains(atn, symbol) {
5838 return Ok(Vec::new());
5839 }
5840 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
5841 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
5842 return Ok(Vec::new());
5843 }
5844 let mut expected = TokenBitSet::default();
5845 for transition in &entry.transitions {
5846 expected.extend_from(&transition.symbols);
5847 }
5848 if let Some(context_expected) = context_expected {
5849 expected.extend_from(&context_expected);
5850 }
5851 let can_delete_in_place =
5852 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
5853 let loop_sync = loop_back;
5870 if symbol != TOKEN_EOF && can_delete_in_place {
5871 let mut cursor = self.input.index();
5872 let mut skipped = Vec::new();
5873 loop {
5874 let current = self.token_type_at(cursor);
5875 if current == TOKEN_EOF {
5876 break;
5877 }
5878 skipped.push(cursor);
5879 let next = self.consume_index(cursor, current);
5880 if next == cursor {
5881 break;
5882 }
5883 let next_symbol = self.token_type_at(next);
5884 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
5892 explicit_eof_expected
5893 } else {
5894 expected.contains(next_symbol)
5895 };
5896 if next_is_expected_stop {
5897 let current_token = self.input.lt(1);
5898 let expected_symbols = expected.to_btree_set();
5899 let message = format!(
5900 "extraneous input {} expecting {}",
5901 current_token
5902 .as_ref()
5903 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
5904 self.expected_symbols_display(&expected_symbols)
5905 );
5906 self.push_generated_parser_diagnostic(diagnostic_for_token(
5907 current_token,
5908 message,
5909 ));
5910 self.record_syntax_errors(1);
5911 let mut children = Vec::with_capacity(skipped.len());
5912 for index in skipped {
5913 if let Some(token) = self.token_id_at(index) {
5914 self.consume();
5915 children.push(self.error_tree(token));
5916 }
5917 }
5918 return Ok(children);
5919 }
5920 if !loop_sync {
5924 break;
5925 }
5926 cursor = next;
5927 }
5928 }
5929 if nullable {
5930 self.generated_sync_expected = Some(expected);
5931 return Ok(Vec::new());
5932 }
5933 let current = self.input.lt(1);
5934 let expected_symbols = expected.to_btree_set();
5935 Err(AntlrError::ParserError {
5936 line: current.as_ref().map(Token::line).unwrap_or_default(),
5937 column: current.as_ref().map(Token::column).unwrap_or_default(),
5938 message: format!(
5939 "mismatched input {} expecting {}",
5940 current
5941 .as_ref()
5942 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
5943 self.expected_symbols_display(&expected_symbols)
5944 ),
5945 })
5946 }
5947
5948 pub fn ll1_decision_prediction(
5955 &mut self,
5956 atn: &Atn,
5957 state_number: usize,
5958 ) -> Option<ParserAtnPrediction> {
5959 let state = atn.state(state_number)?;
5960 if state.precedence_rule_decision() {
5961 return None;
5962 }
5963 let rule_stop = state
5964 .rule_index()
5965 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
5966 let symbol = self.la(1);
5967 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
5968 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
5969 alt: alt + 1,
5970 requires_full_context: false,
5971 has_semantic_context: false,
5972 diagnostic: None,
5973 })
5974 }
5975
5976 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
5977 let mut expected = BTreeSet::new();
5978 for index in (1..self.rule_context_stack.len()).rev() {
5979 let invoking_state = self.rule_context_stack[index].invoking_state;
5980 let Ok(state_number) = usize::try_from(invoking_state) else {
5981 continue;
5982 };
5983 let Some(Transition::Rule { follow_state, .. }) = atn
5984 .state(state_number)
5985 .and_then(|state| state.transitions().first())
5986 .map(ParserTransition::data)
5987 else {
5988 continue;
5989 };
5990 let return_state = follow_state;
5991 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
5992 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
5993 return expected;
5994 }
5995 }
5996 expected.insert(TOKEN_EOF);
5997 expected
5998 }
5999
6000 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
6001 let mut expected = TokenBitSet::default();
6002 for index in (1..self.rule_context_stack.len()).rev() {
6003 let invoking_state = self.rule_context_stack[index].invoking_state;
6004 let Ok(state_number) = usize::try_from(invoking_state) else {
6005 continue;
6006 };
6007 let Some(Transition::Rule { follow_state, .. }) = atn
6008 .state(state_number)
6009 .and_then(|state| state.transitions().first())
6010 .map(ParserTransition::data)
6011 else {
6012 continue;
6013 };
6014 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
6015 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6016 return expected;
6017 }
6018 }
6019 expected.insert(TOKEN_EOF);
6020 expected
6021 }
6022
6023 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
6034 for index in (1..self.rule_context_stack.len()).rev() {
6035 let invoking_state = self.rule_context_stack[index].invoking_state;
6036 let Ok(state_number) = usize::try_from(invoking_state) else {
6037 continue;
6038 };
6039 let Some(Transition::Rule { follow_state, .. }) = atn
6040 .state(state_number)
6041 .and_then(|state| state.transitions().first())
6042 .map(ParserTransition::data)
6043 else {
6044 continue;
6045 };
6046 if self
6047 .cached_state_expected_token_set(atn, follow_state)
6048 .contains(symbol)
6049 {
6050 return true;
6051 }
6052 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6053 return false;
6054 }
6055 }
6056 symbol == TOKEN_EOF
6057 }
6058
6059 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
6061 let error_index = self.input.index();
6062 self.no_viable_alternative_error_at(start_index, error_index)
6063 }
6064
6065 pub fn no_viable_alternative_error_at(
6070 &self,
6071 start_index: usize,
6072 error_index: usize,
6073 ) -> AntlrError {
6074 let diagnostic = self.no_viable_alternative(start_index, error_index);
6075 AntlrError::ParserError {
6076 line: diagnostic.line,
6077 column: diagnostic.column,
6078 message: diagnostic.message,
6079 }
6080 }
6081
6082 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
6084 let current = self.input.lt(1);
6085 AntlrError::ParserError {
6086 line: current.as_ref().map(Token::line).unwrap_or_default(),
6087 column: current.as_ref().map(Token::column).unwrap_or_default(),
6088 message: format!("rule failed predicate: {}", message.into()),
6089 }
6090 }
6091
6092 pub fn failed_predicate_option_error(
6095 &self,
6096 rule_index: usize,
6097 message: impl Into<String>,
6098 ) -> AntlrError {
6099 let current = self.input.lt(1);
6100 let rule_name = self
6101 .rule_names()
6102 .get(rule_index)
6103 .map_or_else(|| rule_index.to_string(), Clone::clone);
6104 AntlrError::ParserError {
6105 line: current.as_ref().map(Token::line).unwrap_or_default(),
6106 column: current.as_ref().map(Token::column).unwrap_or_default(),
6107 message: format!("rule {rule_name} {}", message.into()),
6108 }
6109 }
6110
6111 pub fn parser_action_at_current(
6113 &mut self,
6114 source_state: usize,
6115 rule_index: usize,
6116 start_index: usize,
6117 consumed_eof: bool,
6118 ) -> ParserAction {
6119 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6120 ParserAction::new(source_state, rule_index, start_index, stop_index)
6121 }
6122
6123 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
6128 let rule_index = action.rule_index();
6129 let rule_name = self.rule_names().get(rule_index).cloned();
6130 let context = None;
6131 let input = &mut self.input;
6132 let semantic_hooks = &mut self.semantic_hooks;
6133 let member_values = &self.int_members;
6134 let mut ctx = ParserSemCtx {
6135 input,
6136 tree_storage: &self.tree,
6137 rule_index,
6138 coordinate_index: usize::MAX,
6139 rule_name,
6140 context,
6141 tree: Some(tree),
6142 local_int_arg: None,
6143 member_values,
6144 action: Some(action),
6145 };
6146 let handled = semantic_hooks.action(&mut ctx, action);
6147 if !handled && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error) {
6153 let coordinate = (rule_index, action.source_state());
6154 if !self.unhandled_action_hits.contains(&coordinate) {
6155 self.unhandled_action_hits.push(coordinate);
6156 }
6157 }
6158 handled
6159 }
6160
6161 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
6166 &mut self,
6167 atn: &'atn Atn,
6168 simulator: &mut ParserAtnSimulator<'atn>,
6169 rule_index: usize,
6170 ) -> Result<ParseTree, AntlrError> {
6171 let start_index = self.current_visible_index();
6172 self.clear_prediction_diagnostics();
6173 self.reset_per_parse_caches();
6174 self.reset_recognition_arena();
6175 let tree_checkpoint = self.tree.checkpoint();
6176 let mut decision_by_state = vec![None; atn.states().len()];
6177 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
6178 if let Some(slot) = decision_by_state.get_mut(state_number) {
6179 *slot = Some(decision);
6180 }
6181 }
6182
6183 let result = DirectAdaptiveParser {
6184 parser: self,
6185 atn,
6186 simulator,
6187 decision_by_state,
6188 steps: 0,
6189 }
6190 .parse_rule(rule_index, -1, 0);
6191
6192 match result {
6193 Ok(tree) => {
6194 report_token_source_errors(&self.input.drain_source_errors());
6195 self.release_tree_scratch_if_idle();
6196 Ok(tree)
6197 }
6198 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
6199 let _ = reason;
6200 self.tree.rollback(tree_checkpoint);
6201 self.input.seek(start_index);
6202 self.parse_atn_rule(atn, rule_index)
6203 }
6204 }
6205 }
6206
6207 pub fn parse_atn_rule(
6217 &mut self,
6218 atn: &Atn,
6219 rule_index: usize,
6220 ) -> Result<ParseTree, AntlrError> {
6221 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
6222 }
6223
6224 pub fn parse_atn_rule_with_precedence(
6227 &mut self,
6228 atn: &Atn,
6229 rule_index: usize,
6230 precedence: i32,
6231 ) -> Result<ParseTree, AntlrError> {
6232 self.parse_atn_rule_with_precedence_inner(atn, rule_index, precedence, None)
6233 }
6234
6235 fn parse_atn_rule_with_precedence_inner(
6236 &mut self,
6237 atn: &Atn,
6238 rule_index: usize,
6239 precedence: i32,
6240 predicate_context: Option<FastPredicateContext<'_>>,
6241 ) -> Result<ParseTree, AntlrError> {
6242 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
6243 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
6244 })?;
6245 let stop_state = atn
6246 .rule_to_stop_state()
6247 .get(rule_index)
6248 .filter(|state| *state != usize::MAX)
6249 .ok_or_else(|| {
6250 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
6251 })?;
6252
6253 let start_index = self.current_visible_index();
6254 self.clear_prediction_diagnostics();
6255 self.reset_per_parse_caches();
6256 self.reset_recognition_arena();
6257 let caller_follow_state = self.pending_invoking_follow_state(atn);
6258 self.fast_recovery_enabled = false;
6259 self.fast_token_nodes_enabled = false;
6260 let top_request = FastRecognizeTopRequest {
6261 start_state,
6262 stop_state,
6263 start_index,
6264 precedence,
6265 caller_follow_state,
6266 };
6267 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
6268 self.fast_token_nodes_enabled = true;
6269 let needs_tree_retry = matches!(
6270 &first_pass,
6271 Ok((outcome, _))
6272 if self.build_parse_trees
6273 && self
6274 .recognition_arena
6275 .sequence_has_left_recursive_boundary(outcome.nodes)
6276 );
6277 let needs_retry = match &first_pass {
6278 Err(_) => true,
6291 Ok((outcome, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
6292 };
6293 let (outcome, _expected) = if needs_retry {
6294 self.fast_first_set_prefilter = false;
6295 self.fast_recovery_enabled = false;
6296 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6297 let clean_selected = if needs_tree_retry {
6298 match clean_retry {
6299 ok @ Ok(_) => ok,
6300 Err(_) => first_pass,
6301 }
6302 } else {
6303 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
6304 };
6305 let selected = if clean_selected.is_err()
6306 || matches!(&clean_selected, Ok((outcome, _)) if !outcome.diagnostics.is_empty())
6307 {
6308 self.fast_recovery_enabled = true;
6309 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6310 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
6311 } else {
6312 clean_selected
6313 };
6314 self.fast_first_set_prefilter = true;
6315 self.fast_recovery_enabled = true;
6316 selected.map_err(|expected| {
6317 if predicate_context.is_some()
6318 && let Some(error) = self.unknown_semantic_error()
6319 {
6320 report_token_source_errors(&self.input.drain_source_errors());
6321 return error;
6322 }
6323 let error = self.recognition_error(rule_index, start_index, &expected);
6324 self.record_syntax_errors(1);
6325 report_token_source_errors(&self.input.drain_source_errors());
6326 error
6327 })?
6328 } else {
6329 first_pass.expect("first_pass is Ok in the no-retry branch")
6330 };
6331 if predicate_context.is_some()
6332 && let Some(error) = self.unknown_semantic_error()
6333 {
6334 report_token_source_errors(&self.input.drain_source_errors());
6335 return Err(error);
6336 }
6337 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
6338 report_parser_diagnostics(&self.prediction_diagnostics);
6339 report_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
6340 report_token_source_errors(&self.input.drain_source_errors());
6341 let mut context = ParserRuleContext::with_child_capacity(
6342 rule_index,
6343 self.state(),
6344 if self.build_parse_trees {
6345 self.recognition_arena.sequence_len(outcome.nodes)
6346 } else {
6347 0
6348 },
6349 );
6350 if let Some(token) = self.token_id_at(start_index) {
6351 self.set_context_start(&mut context, token);
6352 }
6353 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
6354 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
6355 self.set_context_stop(&mut context, token);
6356 }
6357 let live_root = if self.build_parse_trees {
6358 self.recognition_arena
6359 .fold_left_recursive_boundaries(outcome.nodes)
6360 } else {
6361 outcome.nodes
6362 };
6363 if self.build_parse_trees {
6364 if self
6365 .recognition_arena
6366 .sequence_has_explicit_token(live_root)
6367 {
6368 let mut cursor = live_root;
6369 while let Some(link) = self.recognition_arena.link(cursor) {
6370 let child = self.arena_recognized_node_tree(link.head, false)?;
6371 self.tree.add_child(&mut context, child);
6372 cursor = link.tail;
6373 }
6374 } else {
6375 self.add_arena_implicit_token_children(
6376 &mut context,
6377 start_index,
6378 stop_index,
6379 live_root,
6380 )?;
6381 }
6382 }
6383 self.finish_recognition_arena(live_root, outcome.diagnostics);
6384 self.input.seek(outcome.index);
6385
6386 let tree = self.rule_node(context);
6387 self.release_tree_scratch_if_idle();
6388 Ok(tree)
6389 }
6390
6391 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
6392 let invoking_state = self.pending_invoking_states.last().copied()?;
6393 let state_number = usize::try_from(invoking_state).ok()?;
6394 match atn.state(state_number)?.transitions().first()?.data() {
6395 Transition::Rule { follow_state, .. } => Some(follow_state),
6396 _ => None,
6397 }
6398 }
6399
6400 #[cfg(test)]
6401 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
6402 caller_follow_token_info_for_stream(&mut self.input, index)
6403 }
6404
6405 fn fast_recognize_top(
6410 &mut self,
6411 atn: &Atn,
6412 request: FastRecognizeTopRequest,
6413 predicate_context: Option<FastPredicateContext<'_>>,
6414 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
6415 let FastRecognizeTopRequest {
6416 start_state,
6417 stop_state,
6418 start_index,
6419 precedence,
6420 caller_follow_state,
6421 } = request;
6422 let memo_capacity = self.input.size().saturating_mul(8).clamp(65_536, 524_288);
6431 let mut visiting = FxHashSet::with_capacity_and_hasher(256, FxBuildHasher::default());
6432 let mut memo = FxHashMap::with_capacity_and_hasher(memo_capacity, FxBuildHasher::default());
6433 let mut expected = ExpectedTokens::default();
6434 let empty_recovery = self.empty_recovery_symbols();
6435 let outcomes = self.recognize_state_fast(
6436 atn,
6437 FastRecognizeRequest {
6438 state_number: start_state,
6439 stop_state,
6440 index: start_index,
6441 rule_start_index: start_index,
6442 decision_start_index: None,
6443 precedence,
6444 depth: 0,
6445 recovery_symbols: empty_recovery,
6446 recovery_state: None,
6447 },
6448 FastRecognizeScratch {
6449 predicate_context,
6450 visiting: &mut visiting,
6451 memo: &mut memo,
6452 expected: &mut expected,
6453 },
6454 );
6455 #[cfg(feature = "perf-counters")]
6456 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
6457 perf_counters::dump();
6458 perf_counters::reset();
6459 }
6460 let caller_follow =
6461 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
6462 let selected = {
6463 let arena = &self.recognition_arena;
6464 let input = &mut self.input;
6465 select_best_fast_outcome(
6466 outcomes.into_iter(),
6467 self.prediction_mode,
6468 caller_follow.as_deref(),
6469 |index| caller_follow_token_info_for_stream(input, index),
6470 arena,
6471 )
6472 };
6473 match selected {
6474 Some(mut outcome) => {
6475 self.materialize_fast_outcome_nodes(&mut outcome);
6476 Ok((outcome, expected))
6477 }
6478 None => Err(expected),
6479 }
6480 }
6481
6482 fn arena_recognized_node_tree(
6484 &mut self,
6485 node_id: RecognizedNodeId,
6486 track_alt_numbers: bool,
6487 ) -> Result<ParseTree, AntlrError> {
6488 let node = self.recognition_arena.node(node_id);
6489 match node {
6490 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
6491 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
6492 ArenaRecognizedNode::MissingToken { extra } => {
6493 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
6494 RecognitionExtra::MissingToken {
6495 token_type,
6496 at_index,
6497 text,
6498 } => (*token_type, *at_index as usize, text.clone()),
6499 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
6500 unreachable!("missing-token node must reference missing-token extra")
6501 }
6502 };
6503 let (line, column) = self
6504 .token_at(at_index)
6505 .map_or((0, 0), |token| (token.line(), token.column()));
6506 let token = self.insert_synthetic_token(token_type, text, line, column)?;
6507 Ok(self.error_tree(token))
6508 }
6509 ArenaRecognizedNode::Rule {
6510 rule_index,
6511 invoking_state,
6512 alt_number,
6513 start_index,
6514 stop_index,
6515 return_values,
6516 children,
6517 } => {
6518 let mut context = ParserRuleContext::with_child_capacity(
6519 rule_index as usize,
6520 invoking_state as isize,
6521 self.recognition_arena.sequence_len(children),
6522 );
6523 if track_alt_numbers {
6524 context.set_alt_number(alt_number as usize);
6525 }
6526 if let Some(extra) = return_values {
6527 let RecognitionExtra::ReturnValues(values) =
6528 self.recognition_arena.extra(extra)
6529 else {
6530 unreachable!("rule node must reference return-values extra");
6531 };
6532 for (name, value) in values {
6533 context.set_int_return(name.clone(), *value);
6534 }
6535 }
6536 if let Some(token) = self.token_id_at(start_index as usize) {
6537 self.set_context_start(&mut context, token);
6538 }
6539 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
6540 self.set_context_stop(&mut context, token);
6541 }
6542 let mut cursor = self
6543 .recognition_arena
6544 .fold_left_recursive_boundaries(children);
6545 while let Some(link) = self.recognition_arena.link(cursor) {
6546 let child = self.arena_recognized_node_tree(link.head, track_alt_numbers)?;
6547 self.tree.add_child(&mut context, child);
6548 cursor = link.tail;
6549 }
6550 Ok(self.rule_node(context))
6551 }
6552 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index } => {
6553 Err(AntlrError::Unsupported(format!(
6554 "unfolded left-recursive boundary for rule {rule_index}"
6555 )))
6556 }
6557 }
6558 }
6559
6560 fn arena_recognized_node_tree_with_implicit_tokens(
6561 &mut self,
6562 node_id: RecognizedNodeId,
6563 ) -> Result<ParseTree, AntlrError> {
6564 let node = self.recognition_arena.node(node_id);
6565 match node {
6566 ArenaRecognizedNode::Rule {
6567 rule_index,
6568 invoking_state,
6569 start_index,
6570 stop_index,
6571 children,
6572 ..
6573 } => {
6574 let mut context = ParserRuleContext::with_child_capacity(
6575 rule_index as usize,
6576 invoking_state as isize,
6577 self.recognition_arena.sequence_len(children),
6578 );
6579 if let Some(token) = self.token_id_at(start_index as usize) {
6580 self.set_context_start(&mut context, token);
6581 }
6582 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
6583 self.set_context_stop(&mut context, token);
6584 }
6585 let children = self
6586 .recognition_arena
6587 .fold_left_recursive_boundaries(children);
6588 self.add_arena_implicit_token_children(
6589 &mut context,
6590 start_index as usize,
6591 stop_index.map(|index| index as usize),
6592 children,
6593 )?;
6594 Ok(self.rule_node(context))
6595 }
6596 _ => self.arena_recognized_node_tree(node_id, false),
6597 }
6598 }
6599
6600 fn add_arena_implicit_token_children(
6601 &mut self,
6602 context: &mut ParserRuleContext,
6603 start_index: usize,
6604 stop_index: Option<usize>,
6605 mut children: NodeSeqId,
6606 ) -> Result<(), AntlrError> {
6607 let mut cursor = Some(start_index);
6608 while let Some(link) = self.recognition_arena.link(children) {
6609 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
6610 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
6611 let child = self.arena_recognized_node_tree_with_implicit_tokens(link.head)?;
6612 self.tree.add_child(context, child);
6613 if let Some(child_stop) = child_stop {
6614 cursor = self.next_visible_after_token(child_stop);
6615 }
6616 } else {
6617 let child = self.arena_recognized_node_tree_with_implicit_tokens(link.head)?;
6618 self.tree.add_child(context, child);
6619 }
6620 children = link.tail;
6621 }
6622 if let Some(stop) = stop_index {
6623 self.add_visible_terminals_through(context, cursor, stop)?;
6624 }
6625 Ok(())
6626 }
6627
6628 fn add_visible_terminals_before(
6629 &mut self,
6630 context: &mut ParserRuleContext,
6631 cursor: &mut Option<usize>,
6632 before: usize,
6633 ) -> Result<(), AntlrError> {
6634 let Some(stop) = before.checked_sub(1) else {
6635 return Ok(());
6636 };
6637 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
6638 *cursor = next;
6639 Ok(())
6640 }
6641
6642 fn add_visible_terminals_through(
6643 &mut self,
6644 context: &mut ParserRuleContext,
6645 mut cursor: Option<usize>,
6646 stop: usize,
6647 ) -> Result<Option<usize>, AntlrError> {
6648 while let Some(index) = cursor {
6649 if index > stop {
6650 return Ok(Some(index));
6651 }
6652 let token = self
6653 .input
6654 .get_id(index)
6655 .ok_or_else(|| AntlrError::ParserError {
6656 line: 0,
6657 column: 0,
6658 message: format!("missing token at index {index}"),
6659 })?;
6660 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
6661 let child = self.terminal_tree(token);
6662 self.tree.add_child(context, child);
6663 if is_eof {
6664 return Ok(None);
6665 }
6666 cursor = self.next_visible_after_token(index);
6667 }
6668 Ok(None)
6669 }
6670
6671 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
6672 let next = self.input.next_visible_after(index);
6673 (next != index).then_some(next)
6674 }
6675
6676 pub fn parse_atn_rule_with_actions(
6683 &mut self,
6684 atn: &Atn,
6685 rule_index: usize,
6686 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
6687 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
6688 }
6689
6690 pub fn parse_atn_rule_with_action_inits(
6698 &mut self,
6699 atn: &Atn,
6700 rule_index: usize,
6701 init_action_rules: &[usize],
6702 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
6703 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
6704 }
6705
6706 pub fn parse_atn_rule_with_action_options(
6712 &mut self,
6713 atn: &Atn,
6714 rule_index: usize,
6715 init_action_rules: &[usize],
6716 track_alt_numbers: bool,
6717 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
6718 self.parse_atn_rule_with_runtime_options(
6719 atn,
6720 rule_index,
6721 ParserRuntimeOptions {
6722 init_action_rules,
6723 track_alt_numbers,
6724 ..ParserRuntimeOptions::default()
6725 },
6726 )
6727 }
6728
6729 pub fn parse_atn_rule_with_runtime_options(
6736 &mut self,
6737 atn: &Atn,
6738 rule_index: usize,
6739 options: ParserRuntimeOptions<'_>,
6740 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
6741 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
6742 }
6743
6744 pub fn parse_atn_rule_with_runtime_options_and_precedence(
6747 &mut self,
6748 atn: &Atn,
6749 rule_index: usize,
6750 precedence: i32,
6751 options: ParserRuntimeOptions<'_>,
6752 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
6753 let ParserRuntimeOptions {
6754 init_action_rules,
6755 track_alt_numbers,
6756 predicates,
6757 semantics,
6758 rule_args,
6759 member_actions,
6760 return_actions,
6761 unknown_predicate_policy,
6762 } = options;
6763 if init_action_rules.is_empty()
6764 && !track_alt_numbers
6765 && predicates.is_empty()
6766 && semantics.is_none()
6767 && rule_args.is_empty()
6768 && member_actions.is_empty()
6769 && return_actions.is_empty()
6770 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
6771 && !atn_has_observable_action_transitions(atn)
6772 && (!self.semantic_hooks.observes_parser_predicates()
6773 || !atn_has_predicate_transitions(atn))
6774 {
6775 return self
6776 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
6777 .map(|tree| (tree, Vec::new()));
6778 }
6779 if can_use_fast_predicate_recognizer(atn, &options) {
6780 self.unknown_predicate_policy = unknown_predicate_policy;
6781 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
6782 let member_values = self.int_members.clone();
6783 let result = self
6784 .parse_atn_rule_with_precedence_inner(
6785 atn,
6786 rule_index,
6787 precedence,
6788 Some(FastPredicateContext {
6789 predicates,
6790 semantics,
6791 member_values: &member_values,
6792 }),
6793 )
6794 .map(|tree| (tree, Vec::new()));
6795 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
6796 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
6797 }
6798 return result;
6799 }
6800 self.unknown_predicate_policy = unknown_predicate_policy;
6801 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
6808 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
6809 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
6810 })?;
6811 let stop_state = atn
6812 .rule_to_stop_state()
6813 .get(rule_index)
6814 .filter(|state| *state != usize::MAX)
6815 .ok_or_else(|| {
6816 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
6817 })?;
6818
6819 let start_index = self.current_visible_index();
6820 self.clear_prediction_diagnostics();
6821 self.reset_per_parse_caches();
6822 self.reset_recognition_arena();
6823 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
6824 let invoking_state = self.pending_invoking_states.pop();
6825 let local_int_arg = invoking_state
6826 .and_then(|state| usize::try_from(state).ok())
6827 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
6828 let mut visiting = BTreeSet::new();
6829 let mut memo = BTreeMap::new();
6830 let mut expected = ExpectedTokens::default();
6831 let member_values = self.int_members.clone();
6832 let return_values = BTreeMap::new();
6833 let outcomes = self.recognize_state(
6834 atn,
6835 RecognizeRequest {
6836 state_number: start_state,
6837 stop_state,
6838 index: start_index,
6839 rule_start_index: start_index,
6840 decision_start_index: None,
6841 init_action_rules: &init_action_rules,
6842 predicates,
6843 semantics,
6844 rule_args,
6845 member_actions,
6846 return_actions,
6847 local_int_arg,
6848 member_values,
6849 return_values,
6850 rule_alt_number: 0,
6851 track_alt_numbers,
6852 consumed_eof: false,
6853 precedence,
6854 depth: 0,
6855 recovery_symbols: BTreeSet::new(),
6856 recovery_state: None,
6857 },
6858 &mut visiting,
6859 &mut memo,
6860 &mut expected,
6861 );
6862 if let Some(error) = self.unknown_semantic_error() {
6863 report_token_source_errors(&self.input.drain_source_errors());
6864 return Err(error);
6871 }
6872 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
6875 let Some(outcome) = select_best_outcome(
6876 outcomes.into_iter(),
6877 self.prediction_mode,
6878 &self.recognition_arena,
6879 ) else {
6880 let error = self.recognition_error(rule_index, start_index, &expected);
6881 self.record_syntax_errors(1);
6882 report_token_source_errors(&self.input.drain_source_errors());
6883 return Err(error);
6884 };
6885
6886 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
6887 report_parser_diagnostics(&self.prediction_diagnostics);
6888 report_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
6889 report_token_source_errors(&self.input.drain_source_errors());
6890 let mut actions = outcome.actions;
6891 if init_action_rules.contains(&rule_index) {
6892 actions.insert(
6893 0,
6894 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
6895 );
6896 }
6897 let mut context =
6898 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
6899 if track_alt_numbers {
6900 context.set_alt_number(outcome.alt_number);
6901 }
6902 for (name, value) in outcome.return_values {
6903 context.set_int_return(name, value);
6904 }
6905 if let Some(token) = self.token_id_at(start_index) {
6906 self.set_context_start(&mut context, token);
6907 }
6908 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
6909 self.set_context_stop(&mut context, token);
6910 }
6911 let live_root = if self.build_parse_trees {
6912 self.recognition_arena
6913 .fold_left_recursive_boundaries(outcome.nodes)
6914 } else {
6915 outcome.nodes
6916 };
6917 if self.build_parse_trees {
6918 let mut nodes = live_root;
6919 while let Some(link) = self.recognition_arena.link(nodes) {
6920 let child = self.arena_recognized_node_tree(link.head, track_alt_numbers)?;
6921 self.tree.add_child(&mut context, child);
6922 nodes = link.tail;
6923 }
6924 }
6925 self.finish_recognition_arena(live_root, outcome.diagnostics);
6926 self.input.seek(outcome.index);
6927
6928 let tree = self.rule_node(context);
6929 self.release_tree_scratch_if_idle();
6930 Ok((tree, actions))
6931 }
6932
6933 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
6940 let mut context = ParserRuleContext::new(rule_index, self.state());
6941 while self.la(1) != TOKEN_EOF {
6942 let token_type = self.la(1);
6943 let child = self.match_token(token_type)?;
6944 if self.build_parse_trees {
6945 self.tree.add_child(&mut context, child);
6946 }
6947 }
6948 if self.build_parse_trees {
6949 let child = self.match_eof()?;
6950 self.tree.add_child(&mut context, child);
6951 }
6952 let tree = self.rule_node(context);
6953 self.release_tree_scratch_if_idle();
6954 Ok(tree)
6955 }
6956
6957 fn recognition_error(
6960 &mut self,
6961 rule_index: usize,
6962 start_index: usize,
6963 expected: &ExpectedTokens,
6964 ) -> AntlrError {
6965 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
6966 self.input.seek(index);
6967 let current = self.input.lt(1);
6968 let line = current.as_ref().map(Token::line).unwrap_or_default();
6969 let column = current.as_ref().map(Token::column).unwrap_or_default();
6970 AntlrError::ParserError {
6971 line,
6972 column,
6973 message,
6974 }
6975 }
6976
6977 fn expected_error_message(
6979 &mut self,
6980 rule_index: usize,
6981 start_index: usize,
6982 expected: &ExpectedTokens,
6983 ) -> (usize, String) {
6984 let index = expected
6985 .index
6986 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
6987 .unwrap_or_else(|| self.input.index());
6988 self.input.seek(index);
6989 let current = self.input.lt(1);
6990 let message = if expected
6991 .no_viable
6992 .as_ref()
6993 .is_some_and(|no_viable| no_viable.error_index == index)
6994 {
6995 let start = expected
6996 .no_viable
6997 .as_ref()
6998 .map_or(start_index, |no_viable| no_viable.start_index);
6999 let text = display_input_text(&self.input.text(start, index));
7000 format!("no viable alternative at input '{text}'")
7001 } else if expected.symbols.is_empty() {
7002 if expected.index.is_some() {
7003 let found = current
7004 .as_ref()
7005 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
7006 if current
7007 .as_ref()
7008 .is_some_and(|token| token.token_type() == TOKEN_EOF)
7009 {
7010 format!(
7011 "missing {} at {found}",
7012 self.expected_symbols_display(&expected.symbols)
7013 )
7014 } else {
7015 format!("mismatched input {found}")
7016 }
7017 } else {
7018 format!("no viable alternative while parsing rule {rule_index}")
7019 }
7020 } else {
7021 format!(
7022 "mismatched input {} expecting {}",
7023 current
7024 .as_ref()
7025 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7026 self.expected_symbols_display(&expected.symbols)
7027 )
7028 };
7029 (index, message)
7030 }
7031
7032 fn child_rule_failure_recovery(
7035 &mut self,
7036 rule_index: usize,
7037 start_index: usize,
7038 sync_symbols: &BTreeSet<i32>,
7039 member_values: BTreeMap<usize, i64>,
7040 expected: &ExpectedTokens,
7041 ) -> Option<RecognizeOutcome> {
7042 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7043 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7044 let mut next_index = error_index;
7045 loop {
7046 let symbol = self.token_type_at(next_index);
7047 if sync_symbols.contains(&symbol) {
7048 if next_index == error_index {
7049 return None;
7050 }
7051 break;
7052 }
7053 if symbol == TOKEN_EOF {
7054 break;
7055 }
7056 let after = self.consume_index(next_index, symbol);
7057 if after == next_index {
7058 break;
7059 }
7060 next_index = after;
7061 }
7062 let mut nodes = NodeSeqId::EMPTY;
7063 let error = self.arena_token_node(error_index, true);
7064 self.arena_prepend(&mut nodes, error);
7065 let diagnostics = self
7066 .recognition_arena
7067 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7068 Some(RecognizeOutcome {
7069 index: next_index,
7070 consumed_eof: false,
7071 alt_number: 0,
7072 member_values,
7073 return_values: BTreeMap::new(),
7074 diagnostics,
7075 decisions: Vec::new(),
7076 actions: Vec::new(),
7077 nodes,
7078 })
7079 }
7080
7081 fn child_rule_failure_recovery_outcomes(
7084 &mut self,
7085 request: ChildRuleFailureRecovery<'_>,
7086 ) -> Vec<RecognizeOutcome> {
7087 let sync_symbols =
7088 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
7089 self.child_rule_failure_recovery(
7090 request.rule_index,
7091 request.start_index,
7092 &sync_symbols,
7093 request.member_values,
7094 request.expected,
7095 )
7096 .into_iter()
7097 .collect()
7098 }
7099
7100 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
7102 expected_symbols_display(symbols, self.vocabulary())
7103 }
7104
7105 fn single_token_deletion(
7108 &mut self,
7109 transition: ParserTransition<'_>,
7110 index: usize,
7111 max_token_type: i32,
7112 expected_symbols: &BTreeSet<i32>,
7113 ) -> Option<(ParserDiagnostic, usize, i32)> {
7114 let current_symbol = self.token_type_at(index);
7115 if current_symbol == TOKEN_EOF {
7116 return None;
7117 }
7118 let next_index = self.consume_index(index, current_symbol);
7119 if next_index == index {
7120 return None;
7121 }
7122 let next_symbol = self.token_type_at(next_index);
7123 if !transition.matches(next_symbol, 1, max_token_type) {
7124 return None;
7125 }
7126 let transition_expected = transition_expected_symbols(transition, max_token_type);
7127 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7128 &transition_expected
7129 } else {
7130 expected_symbols
7131 });
7132 let current = self.token_at(index);
7133 let message = format!(
7134 "extraneous input {} expecting {expected_display}",
7135 current
7136 .as_ref()
7137 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7138 );
7139 Some((
7140 diagnostic_for_token(current, message),
7141 next_index,
7142 next_symbol,
7143 ))
7144 }
7145
7146 fn current_token_deletion(
7149 &mut self,
7150 index: usize,
7151 expected_symbols: &BTreeSet<i32>,
7152 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
7153 if expected_symbols.is_empty() {
7154 return None;
7155 }
7156 let current_symbol = self.token_type_at(index);
7157 if current_symbol == TOKEN_EOF {
7158 return None;
7159 }
7160 let current = self.token_at(index);
7161 let message = format!(
7162 "extraneous input {} expecting {}",
7163 current
7164 .as_ref()
7165 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7166 self.expected_symbols_display(expected_symbols)
7167 );
7168 let diagnostic = diagnostic_for_token(current, message);
7169 let mut skipped = Vec::new();
7170 let mut cursor = index;
7171 loop {
7172 let symbol = self.token_type_at(cursor);
7173 if symbol == TOKEN_EOF {
7174 return None;
7175 }
7176 skipped.push(cursor);
7177 let next_index = self.consume_index(cursor, symbol);
7178 if next_index == cursor {
7179 return None;
7180 }
7181 let next_symbol = self.token_type_at(next_index);
7182 if expected_symbols.contains(&next_symbol) {
7183 return Some((diagnostic, next_index, skipped));
7184 }
7185 cursor = next_index;
7186 }
7187 }
7188
7189 fn single_token_insertion(
7193 &mut self,
7194 transition: ParserTransition<'_>,
7195 index: usize,
7196 max_token_type: i32,
7197 expected_symbols: &BTreeSet<i32>,
7198 follow_symbols: &BTreeSet<i32>,
7199 ) -> Option<(ParserDiagnostic, i32, String)> {
7200 let current_symbol = self.token_type_at(index);
7201 if !follow_symbols.contains(¤t_symbol) {
7202 return None;
7203 }
7204 let transition_expected = transition_expected_symbols(transition, max_token_type);
7205 let token_type = transition_expected.iter().next().copied()?;
7206 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7207 &transition_expected
7208 } else {
7209 expected_symbols
7210 });
7211 let mut token_symbols = BTreeSet::new();
7212 token_symbols.insert(token_type);
7213 let missing_token_display = self.expected_symbols_display(&token_symbols);
7214 let current = self.token_at(index);
7215 let message = format!(
7216 "missing {expected_display} at {}",
7217 current
7218 .as_ref()
7219 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7220 );
7221 let text = format!("<missing {missing_token_display}>");
7222 Some((
7223 diagnostic_for_token(current.as_ref(), message),
7224 token_type,
7225 text,
7226 ))
7227 }
7228
7229 fn fast_single_token_deletion_recovery(
7233 &mut self,
7234 recovery: FastRecoveryRequest<'_, '_>,
7235 predicate_context: Option<FastPredicateContext<'_>>,
7236 ) -> Vec<FastRecognizeOutcome> {
7237 let FastRecoveryRequest {
7238 atn,
7239 transition,
7240 expected_symbols,
7241 target,
7242 request,
7243 visiting,
7244 memo,
7245 expected,
7246 } = recovery;
7247 let FastRecognizeRequest {
7248 stop_state,
7249 index,
7250 rule_start_index,
7251 decision_start_index,
7252 precedence,
7253 depth,
7254 ..
7255 } = request;
7256 let Some((diagnostic, next_index, next_symbol)) =
7257 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
7258 else {
7259 return Vec::new();
7260 };
7261 let after_next = self.consume_index(next_index, next_symbol);
7262 let empty_recovery = self.empty_recovery_symbols();
7263 self.recognize_state_fast(
7264 atn,
7265 FastRecognizeRequest {
7266 state_number: target,
7267 stop_state,
7268 index: after_next,
7269 rule_start_index,
7270 decision_start_index,
7271 precedence,
7272 depth: depth + 1,
7273 recovery_symbols: empty_recovery,
7274 recovery_state: None,
7275 },
7276 FastRecognizeScratch {
7277 predicate_context,
7278 visiting,
7279 memo,
7280 expected,
7281 },
7282 )
7283 .into_iter()
7284 .map(|mut outcome| {
7285 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
7286 outcome.diagnostics = self
7287 .recognition_arena
7288 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7289 if self.fast_token_nodes_enabled {
7290 let token = self.arena_token_node(next_index, false);
7291 self.defer_fast_outcome_node(&mut outcome, token);
7292 let error = self.arena_token_node(index, true);
7293 self.defer_fast_outcome_node(&mut outcome, error);
7294 }
7295 outcome
7296 })
7297 .collect()
7298 }
7299
7300 fn fast_single_token_insertion_recovery(
7304 &mut self,
7305 recovery: FastRecoveryRequest<'_, '_>,
7306 predicate_context: Option<FastPredicateContext<'_>>,
7307 ) -> Vec<FastRecognizeOutcome> {
7308 let FastRecoveryRequest {
7309 atn,
7310 transition,
7311 expected_symbols,
7312 target,
7313 request,
7314 visiting,
7315 memo,
7316 expected,
7317 } = recovery;
7318 let FastRecognizeRequest {
7319 stop_state,
7320 index,
7321 rule_start_index,
7322 decision_start_index,
7323 precedence,
7324 depth,
7325 ..
7326 } = request;
7327 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
7328 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
7329 transition,
7330 index,
7331 atn.max_token_type(),
7332 &expected_symbols,
7333 &follow_symbols,
7334 ) else {
7335 return Vec::new();
7336 };
7337 let empty_recovery = self.empty_recovery_symbols();
7338 self.recognize_state_fast(
7339 atn,
7340 FastRecognizeRequest {
7341 state_number: target,
7342 stop_state,
7343 index,
7344 rule_start_index,
7345 decision_start_index,
7346 precedence,
7347 depth: depth + 1,
7348 recovery_symbols: empty_recovery,
7349 recovery_state: None,
7350 },
7351 FastRecognizeScratch {
7352 predicate_context,
7353 visiting,
7354 memo,
7355 expected,
7356 },
7357 )
7358 .into_iter()
7359 .map(|mut outcome| {
7360 outcome.diagnostics = self
7361 .recognition_arena
7362 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7363 let missing = self.arena_missing_token_node(token_type, index, text.clone());
7364 self.defer_fast_outcome_node(&mut outcome, missing);
7365 outcome
7366 })
7367 .collect()
7368 }
7369
7370 fn fast_current_token_deletion_recovery(
7373 &mut self,
7374 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
7375 predicate_context: Option<FastPredicateContext<'_>>,
7376 ) -> Vec<FastRecognizeOutcome> {
7377 let FastCurrentTokenDeletionRequest {
7378 atn,
7379 expected_symbols,
7380 mut request,
7381 visiting,
7382 memo,
7383 expected,
7384 } = recovery;
7385 if request.index == request.rule_start_index {
7386 return Vec::new();
7387 }
7388 let Some((diagnostic, next_index, skipped)) =
7389 self.current_token_deletion(request.index, &expected_symbols)
7390 else {
7391 return Vec::new();
7392 };
7393 request.state_number = request.recovery_state.unwrap_or(request.state_number);
7394 request.index = next_index;
7395 request.depth += 1;
7396 request.recovery_state = None;
7397 self.recognize_state_fast(
7398 atn,
7399 request,
7400 FastRecognizeScratch {
7401 predicate_context,
7402 visiting,
7403 memo,
7404 expected,
7405 },
7406 )
7407 .into_iter()
7408 .map(|mut outcome| {
7409 outcome.diagnostics = self
7410 .recognition_arena
7411 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7412 for index in skipped.iter().rev() {
7413 let error = self.arena_token_node(*index, true);
7414 self.defer_fast_outcome_node(&mut outcome, error);
7415 }
7416 outcome
7417 })
7418 .collect()
7419 }
7420
7421 fn fast_child_rule_failure_recovery(
7424 &mut self,
7425 rule_index: usize,
7426 start_index: usize,
7427 sync_symbols: &BTreeSet<i32>,
7428 expected: &ExpectedTokens,
7429 ) -> Option<FastRecognizeOutcome> {
7430 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7431 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7432 let mut next_index = error_index;
7433 loop {
7434 let symbol = self.token_type_at(next_index);
7435 if sync_symbols.contains(&symbol) {
7436 if next_index == error_index {
7437 return None;
7438 }
7439 break;
7440 }
7441 if symbol == TOKEN_EOF {
7442 break;
7443 }
7444 let after = self.consume_index(next_index, symbol);
7445 if after == next_index {
7446 break;
7447 }
7448 next_index = after;
7449 }
7450 let diagnostics = self
7451 .recognition_arena
7452 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7453 let mut nodes = NodeSeqId::EMPTY;
7454 if self.fast_token_nodes_enabled {
7455 let error = self.arena_token_node(error_index, true);
7456 self.arena_prepend(&mut nodes, error);
7457 }
7458 Some(FastRecognizeOutcome {
7459 index: next_index,
7460 consumed_eof: false,
7461 diagnostics,
7462 deferred_nodes: FastDeferredNodeId::EMPTY,
7463 nodes,
7464 })
7465 }
7466
7467 fn fast_child_rule_failure_recovery_outcomes(
7470 &mut self,
7471 request: FastChildRuleFailureRecoveryRequest<'_>,
7472 ) -> Vec<FastRecognizeOutcome> {
7473 let FastChildRuleFailureRecoveryRequest {
7474 atn,
7475 rule_index,
7476 start_index,
7477 follow_state,
7478 stop_state,
7479 expected,
7480 } = request;
7481 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
7482 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
7483 .into_iter()
7484 .collect()
7485 }
7486
7487 fn defer_fast_outcome_node(
7488 &mut self,
7489 outcome: &mut FastRecognizeOutcome,
7490 node: RecognizedNodeId,
7491 ) {
7492 if outcome.deferred_nodes.is_empty() {
7493 self.arena_prepend(&mut outcome.nodes, node);
7494 return;
7495 }
7496 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
7497 let fragment = self.recognition_arena.deferred_fragment(fragment);
7498 outcome.deferred_nodes = self
7499 .recognition_arena
7500 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
7501 }
7502
7503 fn materialize_fast_deferred_nodes(
7504 &mut self,
7505 root: FastDeferredNodeId,
7506 initial_suffix: NodeSeqId,
7507 ) -> NodeSeqId {
7508 if root.is_empty() {
7509 return initial_suffix;
7510 }
7511
7512 enum Frame {
7513 Visit(FastDeferredNodeId),
7514 ContinuePrefix(FastDeferredNodeId),
7515 FinishRule {
7516 rule: FastDeferredRule,
7517 parent_suffix: NodeSeqId,
7518 },
7519 }
7520
7521 let mut result = initial_suffix;
7522 let mut pending = Vec::with_capacity(16);
7523 pending.push(Frame::Visit(root));
7524 let mut fragment_nodes = Vec::new();
7525 while let Some(frame) = pending.pop() {
7526 match frame {
7527 Frame::Visit(deferred) => {
7528 if deferred.is_empty() {
7529 continue;
7530 }
7531
7532 match self.recognition_arena.deferred_node(deferred) {
7533 FastDeferredNode::Fragment(sequence) => {
7534 fragment_nodes.clear();
7535 fragment_nodes.extend(self.recognition_arena.iter(sequence));
7536 while let Some(node) = fragment_nodes.pop() {
7537 self.arena_prepend(&mut result, node);
7538 }
7539 }
7540 FastDeferredNode::Rule(rule) => {
7541 let rule = self.recognition_arena.deferred_rule(rule);
7542 let parent_suffix = result;
7543 result = rule.children;
7544 pending.push(Frame::FinishRule {
7545 rule,
7546 parent_suffix,
7547 });
7548 pending.push(Frame::Visit(rule.deferred_children));
7549 }
7550 FastDeferredNode::Concat {
7551 prefix,
7552 suffix: deferred_suffix,
7553 } => {
7554 pending.push(Frame::ContinuePrefix(prefix));
7555 pending.push(Frame::Visit(deferred_suffix));
7556 }
7557 }
7558 }
7559 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
7560 Frame::FinishRule {
7561 rule,
7562 parent_suffix,
7563 } => {
7564 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
7565 rule_index: rule.rule_index,
7566 invoking_state: rule.invoking_state,
7567 alt_number: 0,
7568 start_index: rule.start_index,
7569 stop_index: rule.stop_index,
7570 return_values: None,
7571 children: result,
7572 });
7573 result = parent_suffix;
7574 self.arena_prepend(&mut result, node);
7575 }
7576 }
7577 }
7578 result
7579 }
7580
7581 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) {
7582 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
7583 outcome.nodes = self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
7584 }
7585
7586 fn recognize_repetition_fast(
7589 &mut self,
7590 atn: &Atn,
7591 request: &FastRecognizeRequest,
7592 shape: FastRepetitionShape,
7593 scratch: FastRecognizeScratch<'_, '_>,
7594 ) -> Vec<FastRecognizeOutcome> {
7595 let FastRecognizeScratch {
7596 predicate_context,
7597 visiting,
7598 memo,
7599 expected,
7600 } = scratch;
7601 let lookahead = if self.fast_first_set_prefilter {
7602 atn.state(request.state_number).and_then(|state| {
7603 state
7604 .rule_index()
7605 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
7606 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
7607 })
7608 } else {
7609 None
7610 };
7611 let mut work = Vec::with_capacity(2);
7612 push_fast_repetition_work(
7613 &mut work,
7614 shape,
7615 FastRepetitionPath {
7616 index: request.index,
7617 deferred_nodes: FastDeferredNodeId::EMPTY,
7618 diagnostics: DiagnosticSeqId::EMPTY,
7619 consumed_eof: false,
7620 },
7621 lookahead.as_deref(),
7622 self.token_type_at(request.index),
7623 );
7624 let mut coordinates = FastRepetitionCoordinates::new(request.index);
7625 let mut outcomes = Vec::new();
7626 while let Some(item) = work.pop() {
7627 match item {
7628 FastRepetitionWork::Enter(path) => {
7629 if !coordinates.insert_entered(path) {
7630 continue;
7631 }
7632 let body_outcomes = self.recognize_state_fast(
7633 atn,
7634 FastRecognizeRequest {
7635 state_number: shape.enter_target,
7636 stop_state: shape.body_stop_state,
7637 index: path.index,
7638 rule_start_index: request.rule_start_index,
7639 decision_start_index: request.decision_start_index,
7640 precedence: request.precedence,
7641 depth: request.depth.saturating_add(1),
7642 recovery_symbols: Rc::clone(&request.recovery_symbols),
7643 recovery_state: request.recovery_state,
7644 },
7645 FastRecognizeScratch {
7646 predicate_context,
7647 visiting: &mut *visiting,
7648 memo: &mut *memo,
7649 expected: &mut *expected,
7650 },
7651 );
7652 for body in body_outcomes.into_iter().rev() {
7653 if body.index <= path.index {
7657 continue;
7658 }
7659 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
7660 let body_nodes = self
7661 .recognition_arena
7662 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
7663 let deferred_nodes = self
7664 .recognition_arena
7665 .concat_deferred_nodes(path.deferred_nodes, body_nodes);
7666 let next_path = FastRepetitionPath {
7667 index: body.index,
7668 deferred_nodes,
7669 diagnostics: self
7670 .recognition_arena
7671 .concat_diagnostics(path.diagnostics, body.diagnostics),
7672 consumed_eof: path.consumed_eof || body.consumed_eof,
7673 };
7674 let symbol = self.token_type_at(next_path.index);
7675 push_fast_repetition_work(
7676 &mut work,
7677 shape,
7678 next_path,
7679 lookahead.as_deref(),
7680 symbol,
7681 );
7682 }
7683 }
7684 FastRepetitionWork::Exit(path) => {
7685 if !coordinates.insert_exited(path) {
7686 continue;
7687 }
7688 let suffixes = self.recognize_state_fast(
7689 atn,
7690 FastRecognizeRequest {
7691 state_number: shape.exit_target,
7692 stop_state: request.stop_state,
7693 index: path.index,
7694 rule_start_index: request.rule_start_index,
7695 decision_start_index: request.decision_start_index,
7696 precedence: request.precedence,
7697 depth: request.depth.saturating_add(1),
7698 recovery_symbols: Rc::clone(&request.recovery_symbols),
7699 recovery_state: request.recovery_state,
7700 },
7701 FastRecognizeScratch {
7702 predicate_context,
7703 visiting: &mut *visiting,
7704 memo: &mut *memo,
7705 expected: &mut *expected,
7706 },
7707 );
7708 for mut outcome in suffixes {
7709 outcome.deferred_nodes = self
7710 .recognition_arena
7711 .concat_deferred_nodes(path.deferred_nodes, outcome.deferred_nodes);
7712 outcome.diagnostics = self
7713 .recognition_arena
7714 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
7715 outcome.consumed_eof |= path.consumed_eof;
7716 outcomes.push(outcome);
7717 }
7718 }
7719 }
7720 }
7721 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
7722 outcomes
7723 }
7724
7725 #[allow(clippy::too_many_lines)]
7728 fn recognize_state_fast(
7729 &mut self,
7730 atn: &Atn,
7731 request: FastRecognizeRequest,
7732 scratch: FastRecognizeScratch<'_, '_>,
7733 ) -> Vec<FastRecognizeOutcome> {
7734 #[cfg(feature = "perf-counters")]
7735 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
7736 let FastRecognizeScratch {
7737 predicate_context,
7738 visiting,
7739 memo,
7740 expected,
7741 } = scratch;
7742 let FastRecognizeRequest {
7743 mut state_number,
7744 stop_state,
7745 mut index,
7746 rule_start_index,
7747 decision_start_index,
7748 precedence,
7749 mut depth,
7750 recovery_symbols,
7751 recovery_state,
7752 } = request;
7753 let max_token_type = atn.max_token_type();
7754 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
7773 let mut inline_consumed_eof = false;
7774 loop {
7775 if depth > RECOGNITION_DEPTH_LIMIT {
7776 return Vec::new();
7777 }
7778 if state_number == stop_state {
7779 let mut nodes = NodeSeqId::EMPTY;
7780 if self.fast_token_nodes_enabled {
7781 for token_index in inline_consumed_tokens.iter().rev() {
7782 let token = self.arena_token_node(*token_index, false);
7783 self.arena_prepend(&mut nodes, token);
7784 }
7785 }
7786 return vec![FastRecognizeOutcome {
7787 index,
7788 consumed_eof: inline_consumed_eof,
7789 diagnostics: DiagnosticSeqId::EMPTY,
7790 deferred_nodes: FastDeferredNodeId::EMPTY,
7791 nodes,
7792 }];
7793 }
7794 let Some(state) = atn.state(state_number) else {
7795 return Vec::new();
7796 };
7797 let transitions = state.transitions();
7798 if transitions.len() == 1 && !state.precedence_rule_decision() {
7799 let transition = transitions
7800 .first()
7801 .expect("single transition checked above");
7802 let transition_kind = transition.kind();
7803 let target = transition.target();
7804 match transition_kind {
7805 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
7806 if left_recursive_boundary(atn, state, target).is_none() =>
7807 {
7808 #[cfg(feature = "perf-counters")]
7809 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
7810 state_number = target;
7811 depth += 1;
7812 continue;
7813 }
7814 ParserTransitionKind::Predicate
7815 if left_recursive_boundary(atn, state, target).is_none() =>
7816 {
7817 #[cfg(feature = "perf-counters")]
7818 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
7819 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
7820 {
7821 record_predicate_no_viable(expected, decision_start_index, index);
7822 return Vec::new();
7823 }
7824 state_number = target;
7825 depth += 1;
7826 continue;
7827 }
7828 ParserTransitionKind::Precedence
7829 if packed_i32(transition.arg0()) >= precedence
7830 && left_recursive_boundary(atn, state, target).is_none() =>
7831 {
7832 #[cfg(feature = "perf-counters")]
7833 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
7834 state_number = target;
7835 depth += 1;
7836 continue;
7837 }
7838 ParserTransitionKind::Atom
7848 | ParserTransitionKind::Range
7849 | ParserTransitionKind::Set
7850 | ParserTransitionKind::NotSet
7851 | ParserTransitionKind::Wildcard
7852 if !self.fast_recovery_enabled =>
7853 {
7854 let symbol = self.token_type_at(index);
7855 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
7856 #[cfg(feature = "perf-counters")]
7857 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
7858 if self.fast_token_nodes_enabled {
7859 inline_consumed_tokens.push(index);
7860 }
7861 inline_consumed_eof |= symbol == TOKEN_EOF;
7862 index = self.consume_index(index, symbol);
7863 state_number = target;
7864 depth += 1;
7865 continue;
7866 }
7867 }
7870 _ => {}
7871 }
7872 }
7873 break;
7874 }
7875 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
7879 let Some(state) = atn.state(state_number) else {
7880 return Vec::new();
7881 };
7882 let transitions = state.transitions();
7883 let transition_count = transitions.len();
7884 if !self.fast_recovery_enabled
7885 && let Some(shape) = fast_repetition_shape(atn, state)
7886 {
7887 let mut outcomes = self.recognize_repetition_fast(
7888 atn,
7889 &FastRecognizeRequest {
7890 state_number,
7891 stop_state,
7892 index,
7893 rule_start_index,
7894 decision_start_index,
7895 precedence,
7896 depth,
7897 recovery_symbols: Rc::clone(&recovery_symbols),
7898 recovery_state,
7899 },
7900 shape,
7901 FastRecognizeScratch {
7902 predicate_context,
7903 visiting: &mut *visiting,
7904 memo: &mut *memo,
7905 expected: &mut *expected,
7906 },
7907 );
7908 if inline_pending {
7909 for outcome in &mut outcomes {
7910 outcome.consumed_eof |= inline_consumed_eof;
7911 if self.fast_token_nodes_enabled {
7912 for token_index in inline_consumed_tokens.iter().rev() {
7913 let token = self.arena_token_node(*token_index, false);
7914 self.defer_fast_outcome_node(outcome, token);
7915 }
7916 }
7917 }
7918 }
7919 return outcomes;
7920 }
7921 let memo_lookup_enabled = self.fast_recovery_enabled || transition_count > 1;
7922 let key = if self.fast_recovery_enabled {
7932 FastRecognizeKey {
7933 state_number,
7934 stop_state,
7935 index,
7936 rule_start_index,
7937 decision_start_index,
7938 precedence,
7939 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
7940 recovery_state,
7941 }
7942 } else {
7943 FastRecognizeKey {
7944 state_number,
7945 stop_state,
7946 index,
7947 rule_start_index: 0,
7948 decision_start_index: None,
7949 precedence,
7950 recovery_symbols_id: 0,
7951 recovery_state: None,
7952 }
7953 };
7954 if memo_lookup_enabled {
7955 if let Some(outcomes) = memo.get(&key) {
7956 #[cfg(feature = "perf-counters")]
7957 {
7958 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
7959 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
7960 }
7961 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
7965 let inline_eof = inline_consumed_eof;
7966 let inline_tokens = &inline_consumed_tokens;
7967 return outcomes
7968 .iter()
7969 .copied()
7970 .map(|mut outcome| {
7971 if inline_eof {
7972 outcome.consumed_eof = true;
7973 }
7974 if self.fast_token_nodes_enabled {
7975 for token_index in inline_tokens.iter().rev() {
7976 let token = self.arena_token_node(*token_index, false);
7977 self.defer_fast_outcome_node(&mut outcome, token);
7978 }
7979 }
7980 outcome
7981 })
7982 .collect();
7983 }
7984 return outcomes.to_vec();
7985 }
7986 #[cfg(feature = "perf-counters")]
7987 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
7988 }
7989
7990 let needs_cycle_guard = if self.fast_recovery_enabled {
7995 transitions.iter().any(ParserTransition::is_epsilon)
7996 } else {
7997 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
7998 };
7999 #[cfg(feature = "perf-counters")]
8000 if needs_cycle_guard {
8001 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
8002 } else {
8003 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
8004 match state
8005 .transitions()
8006 .first()
8007 .expect("single-transition path requires one transition")
8008 .data()
8009 {
8010 Transition::Rule { .. } => {
8011 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
8012 }
8013 Transition::Atom { .. }
8014 | Transition::Range { .. }
8015 | Transition::Set { .. }
8016 | Transition::NotSet { .. }
8017 | Transition::Wildcard { .. } => {
8018 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
8019 }
8020 _ => {
8021 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
8022 }
8023 }
8024 }
8025 let has_inserted_cycle_guard = if needs_cycle_guard {
8026 if !visiting.insert(key.clone()) {
8027 #[cfg(feature = "perf-counters")]
8028 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
8029 return Vec::new();
8030 }
8031 true
8032 } else {
8033 false
8034 };
8035 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
8036 Some(index)
8037 } else {
8038 decision_start_index
8039 };
8040 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
8041 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
8042 } else {
8043 (Rc::clone(&recovery_symbols), recovery_state)
8044 };
8045
8046 let lookahead_filter = if transition_count > 1
8065 && self.fast_first_set_prefilter
8066 && !state.precedence_rule_decision()
8067 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
8068 {
8069 state
8070 .rule_index()
8071 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8072 .map(|rule_stop| {
8073 let symbol = self.token_type_at(index);
8074 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
8075 (symbol, entry)
8076 })
8077 } else {
8078 None
8079 };
8080 let ll1_only_alt: Option<usize> = if transition_count > 1
8089 && let Some((symbol, entry)) = lookahead_filter.as_ref()
8090 {
8091 let key = (state.state_number(), *symbol);
8092 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
8093 cached
8094 } else {
8095 let result = ll1_unique_alt(entry, *symbol);
8096 self.ll1_decision_cache.insert(key, result);
8097 result
8098 }
8099 } else {
8100 None
8101 };
8102 let lookahead_filter = lookahead_filter.as_ref();
8103 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
8109 for (transition_index, transition) in transitions.iter().enumerate() {
8110 if let Some(alt) = ll1_only_alt {
8111 if alt != transition_index {
8113 continue;
8114 }
8115 }
8116 let transition_kind = transition.kind();
8117 if ll1_only_alt.is_none()
8118 && should_skip_via_lookahead(
8119 transition_kind,
8120 transition_index,
8121 lookahead_filter,
8122 index,
8123 self.fast_recovery_enabled,
8124 expected,
8125 )
8126 {
8127 continue;
8128 }
8129 let target = transition.target();
8130 match transition_kind {
8131 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
8132 #[cfg(feature = "perf-counters")]
8133 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8134 let boundary = left_recursive_boundary(atn, state, target);
8135 outcomes.extend(
8136 self.recognize_state_fast(
8137 atn,
8138 FastRecognizeRequest {
8139 state_number: target,
8140 stop_state,
8141 index,
8142 rule_start_index,
8143 decision_start_index: next_decision_start_index,
8144 precedence,
8145 depth: depth + 1,
8146 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8147 recovery_state: epsilon_recovery_state,
8148 },
8149 FastRecognizeScratch {
8150 predicate_context,
8151 visiting,
8152 memo,
8153 expected,
8154 },
8155 )
8156 .into_iter()
8157 .map(|mut outcome| {
8158 if let Some(rule_index) = boundary {
8159 let boundary = self.arena_boundary_node(rule_index);
8160 self.defer_fast_outcome_node(&mut outcome, boundary);
8161 }
8162 outcome
8163 }),
8164 );
8165 }
8166 ParserTransitionKind::Predicate => {
8167 #[cfg(feature = "perf-counters")]
8168 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8169 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
8170 let boundary = left_recursive_boundary(atn, state, target);
8171 outcomes.extend(
8172 self.recognize_state_fast(
8173 atn,
8174 FastRecognizeRequest {
8175 state_number: target,
8176 stop_state,
8177 index,
8178 rule_start_index,
8179 decision_start_index: next_decision_start_index,
8180 precedence,
8181 depth: depth + 1,
8182 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8183 recovery_state: epsilon_recovery_state,
8184 },
8185 FastRecognizeScratch {
8186 predicate_context,
8187 visiting,
8188 memo,
8189 expected,
8190 },
8191 )
8192 .into_iter()
8193 .map(|mut outcome| {
8194 if let Some(rule_index) = boundary {
8195 let boundary = self.arena_boundary_node(rule_index);
8196 self.defer_fast_outcome_node(&mut outcome, boundary);
8197 }
8198 outcome
8199 }),
8200 );
8201 } else {
8202 record_predicate_no_viable(expected, next_decision_start_index, index);
8203 }
8204 }
8205 ParserTransitionKind::Precedence => {
8206 let transition_precedence = packed_i32(transition.arg0());
8207 if transition_precedence >= precedence {
8208 let boundary = left_recursive_boundary(atn, state, target);
8209 outcomes.extend(
8210 self.recognize_state_fast(
8211 atn,
8212 FastRecognizeRequest {
8213 state_number: target,
8214 stop_state,
8215 index,
8216 rule_start_index,
8217 decision_start_index: next_decision_start_index,
8218 precedence,
8219 depth: depth + 1,
8220 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8221 recovery_state: epsilon_recovery_state,
8222 },
8223 FastRecognizeScratch {
8224 predicate_context,
8225 visiting,
8226 memo,
8227 expected,
8228 },
8229 )
8230 .into_iter()
8231 .map(|mut outcome| {
8232 if let Some(rule_index) = boundary {
8233 let boundary = self.arena_boundary_node(rule_index);
8234 self.defer_fast_outcome_node(&mut outcome, boundary);
8235 }
8236 outcome
8237 }),
8238 );
8239 }
8240 }
8241 ParserTransitionKind::Rule => {
8242 let rule_index = transition.arg0() as usize;
8243 let follow_state = transition.arg1() as usize;
8244 let rule_precedence = packed_i32(transition.arg2());
8245 #[cfg(feature = "perf-counters")]
8246 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
8247 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
8248 continue;
8249 };
8250 let symbol = self.token_type_at(index);
8262 if self.fast_first_set_prefilter {
8263 let first = self.cached_rule_first_set(atn, target, child_stop);
8276 if should_skip_rule_via_first_set(
8277 &first,
8278 symbol,
8279 self.fast_recovery_enabled,
8280 index,
8281 expected,
8282 ) {
8283 continue;
8284 }
8285 }
8286 let expected_before_child =
8287 self.fast_recovery_enabled.then(|| expected.clone());
8288 let mut children = self.recognize_state_fast(
8289 atn,
8290 FastRecognizeRequest {
8291 state_number: target,
8292 stop_state: child_stop,
8293 index,
8294 rule_start_index: index,
8295 decision_start_index: None,
8296 precedence: rule_precedence,
8297 depth: depth + 1,
8298 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8299 recovery_state: epsilon_recovery_state,
8300 },
8301 FastRecognizeScratch {
8302 predicate_context,
8303 visiting,
8304 memo,
8305 expected,
8306 },
8307 );
8308 if children.is_empty() && self.fast_recovery_enabled {
8309 children = self.fast_child_rule_failure_recovery_outcomes(
8310 FastChildRuleFailureRecoveryRequest {
8311 atn,
8312 rule_index,
8313 start_index: index,
8314 follow_state,
8315 stop_state,
8316 expected,
8317 },
8318 );
8319 }
8320 if let Some(expected_before_child) = expected_before_child {
8321 if children
8322 .iter()
8323 .any(|child| child.diagnostics.is_empty() && child.index > index)
8324 {
8325 *expected = expected_before_child;
8326 }
8327 }
8328 for child in children {
8329 let child_index = child.index;
8330 let child_consumed_eof = child.consumed_eof;
8331 let child_diagnostics = child.diagnostics;
8332 let empty_recovery = self.empty_recovery_symbols();
8333 let follow_outcomes = self.recognize_state_fast(
8334 atn,
8335 FastRecognizeRequest {
8336 state_number: follow_state,
8337 stop_state,
8338 index: child_index,
8339 rule_start_index,
8340 decision_start_index: next_decision_start_index,
8341 precedence,
8342 depth: depth + 1,
8343 recovery_symbols: empty_recovery,
8344 recovery_state: None,
8345 },
8346 FastRecognizeScratch {
8347 predicate_context,
8348 visiting,
8349 memo,
8350 expected,
8351 },
8352 );
8353 if follow_outcomes.is_empty() {
8354 continue;
8355 }
8356 let child_stop_index =
8357 self.rule_stop_token_index(child_index, child_consumed_eof);
8358 let child_node =
8359 self.recognition_arena.deferred_rule_node(FastDeferredRule {
8360 rule_index: u32::try_from(rule_index)
8361 .expect("rule index fits in u32"),
8362 invoking_state: i32::try_from(invoking_state_number(state_number))
8363 .expect("invoking state fits in i32"),
8364 start_index: u32::try_from(index)
8365 .expect("rule start index fits in u32"),
8366 stop_index: child_stop_index.map(|stop_index| {
8367 u32::try_from(stop_index).expect("rule stop index fits in u32")
8368 }),
8369 deferred_children: child.deferred_nodes,
8370 children: child.nodes,
8371 });
8372 let child_diags_empty = child_diagnostics.is_empty();
8373 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
8374 outcome.consumed_eof |= child_consumed_eof;
8375 if !child_diags_empty {
8378 outcome.diagnostics = self
8379 .recognition_arena
8380 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
8381 }
8382 outcome.deferred_nodes = self
8383 .recognition_arena
8384 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
8385 outcome
8386 }));
8387 }
8388 }
8389 ParserTransitionKind::Atom
8390 | ParserTransitionKind::Range
8391 | ParserTransitionKind::Set
8392 | ParserTransitionKind::NotSet
8393 | ParserTransitionKind::Wildcard => {
8394 #[cfg(feature = "perf-counters")]
8395 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
8396 let symbol = self.token_type_at(index);
8397 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
8398 let next_index = self.consume_index(index, symbol);
8399 let empty_recovery = self.empty_recovery_symbols();
8400 outcomes.extend(
8401 self.recognize_state_fast(
8402 atn,
8403 FastRecognizeRequest {
8404 state_number: target,
8405 stop_state,
8406 index: next_index,
8407 rule_start_index,
8408 decision_start_index: next_decision_start_index,
8409 precedence,
8410 depth: depth + 1,
8411 recovery_symbols: empty_recovery,
8412 recovery_state: None,
8413 },
8414 FastRecognizeScratch {
8415 predicate_context,
8416 visiting,
8417 memo,
8418 expected,
8419 },
8420 )
8421 .into_iter()
8422 .map(|mut outcome| {
8423 outcome.consumed_eof |= symbol == TOKEN_EOF;
8424 if self.fast_token_nodes_enabled {
8425 let token = self.arena_token_node(index, false);
8426 self.defer_fast_outcome_node(&mut outcome, token);
8427 }
8428 outcome
8429 }),
8430 );
8431 } else {
8432 if !self.fast_recovery_enabled {
8433 continue;
8441 }
8442 let expected_symbols = fast_recovery_expected_symbols(
8443 self,
8444 atn,
8445 state.state_number(),
8446 &recovery_symbols,
8447 );
8448 if expected_symbols.contains(&symbol) {
8449 continue;
8450 }
8451 {
8452 expected.record_transition(index, transition, max_token_type);
8453 record_no_viable_if_ambiguous(
8454 expected,
8455 next_decision_start_index,
8456 index,
8457 );
8458 outcomes.extend(self.fast_single_token_deletion_recovery(
8459 FastRecoveryRequest {
8460 atn,
8461 transition,
8462 expected_symbols: Rc::clone(&expected_symbols),
8463 target,
8464 request: FastRecognizeRequest {
8465 state_number,
8466 stop_state,
8467 index,
8468 rule_start_index,
8469 decision_start_index,
8470 precedence,
8471 depth,
8472 recovery_symbols: Rc::clone(&recovery_symbols),
8473 recovery_state,
8474 },
8475 visiting,
8476 memo,
8477 expected,
8478 },
8479 predicate_context,
8480 ));
8481 if !state_is_left_recursive_rule(atn, state) {
8482 outcomes.extend(self.fast_single_token_insertion_recovery(
8483 FastRecoveryRequest {
8484 atn,
8485 transition,
8486 expected_symbols: Rc::clone(&expected_symbols),
8487 target,
8488 request: FastRecognizeRequest {
8489 state_number,
8490 stop_state,
8491 index,
8492 rule_start_index,
8493 decision_start_index,
8494 precedence,
8495 depth,
8496 recovery_symbols: Rc::clone(&recovery_symbols),
8497 recovery_state,
8498 },
8499 visiting,
8500 memo,
8501 expected,
8502 },
8503 predicate_context,
8504 ));
8505 }
8506 outcomes.extend(self.fast_current_token_deletion_recovery(
8507 FastCurrentTokenDeletionRequest {
8508 atn,
8509 expected_symbols,
8510 request: FastRecognizeRequest {
8511 state_number,
8512 stop_state,
8513 index,
8514 rule_start_index,
8515 decision_start_index,
8516 precedence,
8517 depth,
8518 recovery_symbols: Rc::clone(&recovery_symbols),
8519 recovery_state,
8520 },
8521 visiting,
8522 memo,
8523 expected,
8524 },
8525 predicate_context,
8526 ));
8527 }
8528 }
8529 }
8530 }
8531 }
8532
8533 if has_inserted_cycle_guard {
8534 visiting.remove(&key);
8535 }
8536 if matches!(
8537 self.prediction_mode,
8538 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
8539 ) && self.fast_recovery_enabled
8540 {
8541 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
8545 }
8546 if self.fast_recovery_enabled {
8547 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
8548 } else {
8549 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8550 }
8551 let should_memoize = self.fast_recovery_enabled
8561 || (transition_count > 1
8562 && (outcomes.is_empty()
8563 || outcomes.len() > 1
8564 || (outcomes.len() == 1 && self.should_memoize_single_outcome(&key))));
8565 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
8569 if inline_consumed_eof {
8570 outcome.consumed_eof = true;
8571 }
8572 if !inline_consumed_tokens.is_empty() {
8573 for token_index in inline_consumed_tokens.iter().rev() {
8574 let token = self.arena_token_node(*token_index, false);
8575 self.defer_fast_outcome_node(&mut outcome, token);
8576 }
8577 }
8578 outcome
8579 };
8580 if should_memoize {
8581 #[cfg(feature = "perf-counters")]
8582 {
8583 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
8584 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
8585 match outcomes.len() {
8586 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
8587 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
8588 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
8589 }
8590 }
8591 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
8596 memo.insert(key, Rc::clone(&stored));
8597 if inline_pending {
8598 return stored
8599 .iter()
8600 .copied()
8601 .map(&mut apply_inline_pending)
8602 .collect();
8603 }
8604 return stored.to_vec();
8605 }
8606 #[cfg(feature = "perf-counters")]
8607 match outcomes.len() {
8608 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
8609 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
8610 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
8611 }
8612 if inline_pending {
8613 return outcomes.into_iter().map(apply_inline_pending).collect();
8614 }
8615 outcomes
8616 }
8617
8618 fn single_token_deletion_recovery(
8621 &mut self,
8622 recovery: RecoveryRequest<'_, '_>,
8623 ) -> Vec<RecognizeOutcome> {
8624 let RecoveryRequest {
8625 atn,
8626 transition,
8627 expected_symbols,
8628 target,
8629 request,
8630 visiting,
8631 memo,
8632 expected,
8633 } = recovery;
8634 let RecognizeRequest {
8635 stop_state,
8636 index,
8637 rule_start_index,
8638 decision_start_index,
8639 init_action_rules,
8640 predicates,
8641 semantics,
8642 rule_args,
8643 member_actions,
8644 return_actions,
8645 local_int_arg,
8646 member_values,
8647 return_values,
8648 rule_alt_number,
8649 track_alt_numbers,
8650 consumed_eof,
8651 precedence,
8652 depth,
8653 ..
8654 } = request;
8655 let Some((diagnostic, next_index, next_symbol)) =
8656 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
8657 else {
8658 return Vec::new();
8659 };
8660 let after_next = self.consume_index(next_index, next_symbol);
8661 self.recognize_state(
8662 atn,
8663 RecognizeRequest {
8664 state_number: target,
8665 stop_state,
8666 index: after_next,
8667 rule_start_index,
8668 decision_start_index,
8669 init_action_rules,
8670 predicates,
8671 semantics,
8672 rule_args,
8673 member_actions,
8674 return_actions,
8675 local_int_arg,
8676 member_values,
8677 return_values,
8678 rule_alt_number,
8679 track_alt_numbers,
8680 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
8681 precedence,
8682 depth: depth + 1,
8683 recovery_symbols: BTreeSet::new(),
8684 recovery_state: None,
8685 },
8686 visiting,
8687 memo,
8688 expected,
8689 )
8690 .into_iter()
8691 .map(|mut outcome| {
8692 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
8693 outcome.diagnostics = self
8694 .recognition_arena
8695 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8696 let token = self.arena_token_node(next_index, false);
8697 self.arena_prepend(&mut outcome.nodes, token);
8698 let error = self.arena_token_node(index, true);
8699 self.arena_prepend(&mut outcome.nodes, error);
8700 outcome
8701 })
8702 .collect()
8703 }
8704
8705 fn current_token_deletion_recovery(
8708 &mut self,
8709 recovery: CurrentTokenDeletionRequest<'_, '_>,
8710 ) -> Vec<RecognizeOutcome> {
8711 let CurrentTokenDeletionRequest {
8712 atn,
8713 expected_symbols,
8714 mut request,
8715 visiting,
8716 memo,
8717 expected,
8718 } = recovery;
8719 let error_index = request.index;
8720 if error_index == request.rule_start_index {
8721 return Vec::new();
8722 }
8723 let Some((diagnostic, next_index, skipped)) =
8724 self.current_token_deletion(error_index, &expected_symbols)
8725 else {
8726 return Vec::new();
8727 };
8728 request.state_number = request.recovery_state.unwrap_or(request.state_number);
8729 request.index = next_index;
8730 request.depth += 1;
8731 request.recovery_state = None;
8732 self.recognize_state(atn, request, visiting, memo, expected)
8733 .into_iter()
8734 .map(|mut outcome| {
8735 outcome.diagnostics = self
8736 .recognition_arena
8737 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8738 for index in skipped.iter().rev() {
8739 let error = self.arena_token_node(*index, true);
8740 self.arena_prepend(&mut outcome.nodes, error);
8741 }
8742 outcome
8743 })
8744 .collect()
8745 }
8746
8747 fn consuming_failure_fallback(
8750 &mut self,
8751 fallback: ConsumingFailureFallback<'_>,
8752 visiting: &mut BTreeSet<RecognizeKey>,
8753 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
8754 expected: &mut ExpectedTokens,
8755 ) -> Vec<RecognizeOutcome> {
8756 if fallback.expected_symbols.is_empty() {
8757 return Vec::new();
8758 }
8759 if fallback.symbol == TOKEN_EOF {
8760 return self.eof_consuming_failure_fallback(fallback, expected);
8761 }
8762 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
8763 }
8764
8765 fn non_eof_consuming_failure_fallback(
8768 &mut self,
8769 fallback: ConsumingFailureFallback<'_>,
8770 visiting: &mut BTreeSet<RecognizeKey>,
8771 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
8772 expected: &mut ExpectedTokens,
8773 ) -> Vec<RecognizeOutcome> {
8774 let ConsumingFailureFallback {
8775 atn,
8776 target,
8777 request,
8778 symbol,
8779 expected_symbols,
8780 decision_start_index,
8781 decision,
8782 } = fallback;
8783 let error_index = request.index;
8784 let diagnostic =
8785 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
8786 let next_index = self.consume_index(error_index, symbol);
8787 self.recognize_state(
8788 atn,
8789 RecognizeRequest {
8790 state_number: target,
8791 stop_state: request.stop_state,
8792 index: next_index,
8793 rule_start_index: request.rule_start_index,
8794 decision_start_index,
8795 init_action_rules: request.init_action_rules,
8796 predicates: request.predicates,
8797 semantics: request.semantics,
8798 rule_args: request.rule_args,
8799 member_actions: request.member_actions,
8800 return_actions: request.return_actions,
8801 local_int_arg: request.local_int_arg,
8802 member_values: request.member_values,
8803 return_values: request.return_values,
8804 rule_alt_number: request.rule_alt_number,
8805 track_alt_numbers: request.track_alt_numbers,
8806 consumed_eof: request.consumed_eof,
8807 precedence: request.precedence,
8808 depth: request.depth + 1,
8809 recovery_symbols: BTreeSet::new(),
8810 recovery_state: None,
8811 },
8812 visiting,
8813 memo,
8814 expected,
8815 )
8816 .into_iter()
8817 .map(|mut outcome| {
8818 prepend_decision(&mut outcome, decision);
8819 outcome.diagnostics = self
8820 .recognition_arena
8821 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8822 let error = self.arena_token_node(error_index, true);
8823 self.arena_prepend(&mut outcome.nodes, error);
8824 outcome
8825 })
8826 .collect()
8827 }
8828
8829 fn eof_consuming_failure_fallback(
8832 &mut self,
8833 fallback: ConsumingFailureFallback<'_>,
8834 expected: &ExpectedTokens,
8835 ) -> Vec<RecognizeOutcome> {
8836 let request = fallback.request;
8837 if request.index == request.rule_start_index {
8838 return Vec::new();
8839 }
8840 let diagnostic =
8841 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
8842 let diagnostics = self
8843 .recognition_arena
8844 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8845 vec![RecognizeOutcome {
8846 index: request.index,
8847 consumed_eof: request.consumed_eof,
8848 alt_number: request.rule_alt_number,
8849 member_values: request.member_values,
8850 return_values: request.return_values,
8851 diagnostics,
8852 decisions: Vec::new(),
8853 actions: Vec::new(),
8854 nodes: NodeSeqId::EMPTY,
8855 }]
8856 }
8857
8858 fn single_token_insertion_recovery(
8861 &mut self,
8862 recovery: RecoveryRequest<'_, '_>,
8863 ) -> Vec<RecognizeOutcome> {
8864 let RecoveryRequest {
8865 atn,
8866 transition,
8867 expected_symbols,
8868 target,
8869 request,
8870 visiting,
8871 memo,
8872 expected,
8873 } = recovery;
8874 let RecognizeRequest {
8875 stop_state,
8876 index,
8877 rule_start_index,
8878 decision_start_index,
8879 init_action_rules,
8880 predicates,
8881 semantics,
8882 rule_args,
8883 member_actions,
8884 return_actions,
8885 local_int_arg,
8886 member_values,
8887 return_values,
8888 rule_alt_number,
8889 track_alt_numbers,
8890 consumed_eof,
8891 precedence,
8892 depth,
8893 ..
8894 } = request;
8895 let follow_symbols = state_expected_symbols(atn, transition.target());
8896 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
8897 transition,
8898 index,
8899 atn.max_token_type(),
8900 &expected_symbols,
8901 &follow_symbols,
8902 ) else {
8903 return Vec::new();
8904 };
8905 self.recognize_state(
8906 atn,
8907 RecognizeRequest {
8908 state_number: target,
8909 stop_state,
8910 index,
8911 rule_start_index,
8912 decision_start_index,
8913 init_action_rules,
8914 predicates,
8915 semantics,
8916 rule_args,
8917 member_actions,
8918 return_actions,
8919 local_int_arg,
8920 member_values,
8921 return_values,
8922 rule_alt_number,
8923 track_alt_numbers,
8924 consumed_eof,
8925 precedence,
8926 depth: depth + 1,
8927 recovery_symbols: BTreeSet::new(),
8928 recovery_state: None,
8929 },
8930 visiting,
8931 memo,
8932 expected,
8933 )
8934 .into_iter()
8935 .map(|mut outcome| {
8936 outcome.diagnostics = self
8937 .recognition_arena
8938 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8939 let missing = self.arena_missing_token_node(token_type, index, text.clone());
8940 self.arena_prepend(&mut outcome.nodes, missing);
8941 outcome
8942 })
8943 .collect()
8944 }
8945
8946 #[allow(clippy::too_many_lines)]
8949 fn recognize_state(
8950 &mut self,
8951 atn: &Atn,
8952 request: RecognizeRequest<'_>,
8953 visiting: &mut BTreeSet<RecognizeKey>,
8954 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
8955 expected: &mut ExpectedTokens,
8956 ) -> Vec<RecognizeOutcome> {
8957 let request_template = request.clone();
8958 let RecognizeRequest {
8959 state_number,
8960 stop_state,
8961 index,
8962 rule_start_index,
8963 decision_start_index,
8964 init_action_rules,
8965 predicates,
8966 semantics,
8967 rule_args,
8968 member_actions,
8969 return_actions,
8970 local_int_arg,
8971 member_values,
8972 return_values,
8973 rule_alt_number,
8974 track_alt_numbers,
8975 consumed_eof,
8976 precedence,
8977 depth,
8978 recovery_symbols,
8979 recovery_state,
8980 } = request;
8981 if depth > RECOGNITION_DEPTH_LIMIT {
8982 return Vec::new();
8983 }
8984 if state_number == stop_state {
8985 return stop_outcome(
8986 index,
8987 consumed_eof,
8988 rule_alt_number,
8989 member_values,
8990 return_values,
8991 );
8992 }
8993 let key = RecognizeKey {
8994 state_number,
8995 stop_state,
8996 index,
8997 rule_start_index,
8998 decision_start_index,
8999 local_int_arg,
9000 member_values: member_values.clone(),
9001 return_values: return_values.clone(),
9002 rule_alt_number,
9003 track_alt_numbers,
9004 consumed_eof,
9005 precedence,
9006 recovery_symbols: recovery_symbols.clone(),
9007 recovery_state,
9008 };
9009 if let Some(outcomes) = memo.get(&key) {
9010 return outcomes.clone();
9011 }
9012
9013 let visit_key = key.clone();
9014 if !visiting.insert(visit_key.clone()) {
9015 return Vec::new();
9016 }
9017
9018 let Some(state) = atn.state(state_number) else {
9019 visiting.remove(&visit_key);
9020 return Vec::new();
9021 };
9022 let transitions = state.transitions();
9023 let transition_count = transitions.len();
9024 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9025 Some(index)
9026 } else {
9027 decision_start_index
9028 };
9029 let (epsilon_recovery_symbols, epsilon_recovery_state) =
9030 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
9031 let mut outcomes = Vec::new();
9032 for (transition_index, transition) in transitions.iter().enumerate() {
9033 let decision =
9034 transition_decision(atn, state, transition_count, transition_index, predicates);
9035 let next_alt_number = next_alt_number(
9036 state,
9037 transition_count,
9038 transition_index,
9039 rule_alt_number,
9040 track_alt_numbers,
9041 );
9042 let transition_data = transition.data();
9043 match &transition_data {
9044 Transition::Epsilon { target } | Transition::Action { target, .. } => {
9045 let action_rule_index = match &transition_data {
9046 Transition::Action { rule_index, .. } => Some(*rule_index),
9047 _ => None,
9048 };
9049 outcomes.extend(self.recognize_epsilon_or_action_step(
9050 atn,
9051 &request_template,
9052 EpsilonActionStep {
9053 source_state: state_number,
9054 target: *target,
9055 action_rule_index,
9056 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
9057 decision,
9058 decision_start_index: next_decision_start_index,
9059 alt_number: next_alt_number,
9060 recovery_symbols: epsilon_recovery_symbols.clone(),
9061 recovery_state: epsilon_recovery_state,
9062 },
9063 RecognizeScratch {
9064 visiting,
9065 memo,
9066 expected,
9067 },
9068 ));
9069 }
9070 Transition::Predicate {
9071 target,
9072 rule_index,
9073 pred_index,
9074 ..
9075 } => {
9076 let predicate = PredicateEval {
9077 index,
9078 rule_index: *rule_index,
9079 pred_index: *pred_index,
9080 predicates,
9081 semantics,
9082 context: None,
9083 local_int_arg,
9084 member_values: &member_values,
9085 };
9086 if self.parser_predicate_matches(predicate) {
9087 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
9088 outcomes.extend(
9089 self.recognize_state(
9090 atn,
9091 RecognizeRequest {
9092 state_number: *target,
9093 stop_state,
9094 index,
9095 rule_start_index,
9096 decision_start_index: next_decision_start_index,
9097 init_action_rules,
9098 predicates,
9099 semantics,
9100 rule_args,
9101 member_actions,
9102 return_actions,
9103 local_int_arg,
9104 member_values: member_values.clone(),
9105 return_values: return_values.clone(),
9106 rule_alt_number: next_alt_number,
9107 track_alt_numbers,
9108 consumed_eof,
9109 precedence,
9110 depth: depth + 1,
9111 recovery_symbols: epsilon_recovery_symbols.clone(),
9112 recovery_state: epsilon_recovery_state,
9113 },
9114 visiting,
9115 memo,
9116 expected,
9117 )
9118 .into_iter()
9119 .map(|mut outcome| {
9120 prepend_decision(&mut outcome, decision);
9121 if let Some(rule_index) = left_recursive_boundary {
9122 let boundary = self.arena_boundary_node(rule_index);
9123 self.arena_prepend(&mut outcome.nodes, boundary);
9124 }
9125 outcome
9126 }),
9127 );
9128 } else if let Some(message) = semantics
9129 .and_then(|semantics| {
9130 self.parser_semantic_ir_predicate_failure_message(
9131 *rule_index,
9132 *pred_index,
9133 semantics,
9134 )
9135 })
9136 .or_else(|| {
9137 self.parser_predicate_failure_message(
9138 *rule_index,
9139 *pred_index,
9140 predicates,
9141 )
9142 })
9143 {
9144 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
9145 rule_index: *rule_index,
9146 index,
9147 message,
9148 member_values: member_values.clone(),
9149 return_values: return_values.clone(),
9150 rule_alt_number,
9151 }));
9152 } else {
9153 record_predicate_no_viable(expected, next_decision_start_index, index);
9154 }
9155 }
9156 Transition::Precedence {
9157 target,
9158 precedence: transition_precedence,
9159 } => {
9160 if *transition_precedence >= precedence {
9161 outcomes.extend(
9162 self.recognize_state(
9163 atn,
9164 RecognizeRequest {
9165 state_number: *target,
9166 stop_state,
9167 index,
9168 rule_start_index,
9169 decision_start_index: next_decision_start_index,
9170 init_action_rules,
9171 predicates,
9172 semantics,
9173 rule_args,
9174 member_actions,
9175 return_actions,
9176 local_int_arg,
9177 member_values: member_values.clone(),
9178 return_values: return_values.clone(),
9179 rule_alt_number: next_alt_number,
9180 track_alt_numbers,
9181 consumed_eof,
9182 precedence,
9183 depth: depth + 1,
9184 recovery_symbols: epsilon_recovery_symbols.clone(),
9185 recovery_state: epsilon_recovery_state,
9186 },
9187 visiting,
9188 memo,
9189 expected,
9190 )
9191 .into_iter()
9192 .map(|mut outcome| {
9193 prepend_decision(&mut outcome, decision);
9194 outcome
9195 }),
9196 );
9197 }
9198 }
9199 Transition::Rule {
9200 target,
9201 rule_index,
9202 follow_state,
9203 precedence: rule_precedence,
9204 ..
9205 } => {
9206 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
9207 continue;
9208 };
9209 let child_local_int_arg =
9210 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
9211 let expected_before_child = expected.clone();
9212 let children = self.recognize_state(
9213 atn,
9214 RecognizeRequest {
9215 state_number: *target,
9216 stop_state: child_stop,
9217 index,
9218 rule_start_index: index,
9219 decision_start_index: None,
9220 init_action_rules,
9221 predicates,
9222 semantics,
9223 rule_args,
9224 member_actions,
9225 return_actions,
9226 local_int_arg: child_local_int_arg,
9227 member_values: member_values.clone(),
9228 return_values: BTreeMap::new(),
9229 rule_alt_number: 0,
9230 track_alt_numbers,
9231 consumed_eof: false,
9232 precedence: *rule_precedence,
9233 depth: depth + 1,
9234 recovery_symbols: epsilon_recovery_symbols.clone(),
9235 recovery_state: epsilon_recovery_state,
9236 },
9237 visiting,
9238 memo,
9239 expected,
9240 );
9241 let children = if children.is_empty() {
9242 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
9243 atn,
9244 rule_index: *rule_index,
9245 start_index: index,
9246 follow_state: *follow_state,
9247 stop_state,
9248 member_values: member_values.clone(),
9249 expected,
9250 })
9251 } else {
9252 children
9253 };
9254 let preserve_child_expected =
9255 self.child_expected_reaches_clean_eof(&children, expected);
9256 restore_expected(
9257 &children,
9258 index,
9259 expected,
9260 expected_before_child,
9261 preserve_child_expected,
9262 );
9263 for child in children {
9264 let child_stop_index =
9265 self.rule_stop_token_index(child.index, child.consumed_eof);
9266 let child_nodes = self
9267 .recognition_arena
9268 .fold_left_recursive_boundaries(child.nodes);
9269 let child_node = self.arena_rule_node(ArenaRuleSpec {
9270 rule_index: *rule_index,
9271 invoking_state: invoking_state_number(state_number),
9272 alt_number: child.alt_number,
9273 start_index: index,
9274 stop_index: child_stop_index,
9275 return_values: child.return_values.clone(),
9276 children: child_nodes,
9277 });
9278 outcomes.extend(
9279 self.recognize_state(
9280 atn,
9281 RecognizeRequest {
9282 state_number: *follow_state,
9283 stop_state,
9284 index: child.index,
9285 rule_start_index,
9286 decision_start_index: next_decision_start_index,
9287 init_action_rules,
9288 predicates,
9289 semantics,
9290 rule_args,
9291 member_actions,
9292 return_actions,
9293 local_int_arg,
9294 member_values: child.member_values.clone(),
9295 return_values: return_values.clone(),
9296 rule_alt_number,
9297 track_alt_numbers,
9298 consumed_eof: consumed_eof || child.consumed_eof,
9299 precedence,
9300 depth: depth + 1,
9301 recovery_symbols: BTreeSet::new(),
9302 recovery_state: None,
9303 },
9304 visiting,
9305 memo,
9306 expected,
9307 )
9308 .into_iter()
9309 .map(|mut outcome| {
9310 outcome.consumed_eof |= child.consumed_eof;
9311 outcome.diagnostics = self
9312 .recognition_arena
9313 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
9314 let mut decisions = child.decisions.clone();
9315 decisions.append(&mut outcome.decisions);
9316 outcome.decisions = decisions;
9317 prepend_decision(&mut outcome, decision);
9318 let mut actions = child.actions.clone();
9319 if init_action_rules.contains(rule_index) {
9320 actions.insert(
9321 0,
9322 ParserAction::new_rule_init(
9323 *rule_index,
9324 index,
9325 Some(*follow_state),
9326 ),
9327 );
9328 }
9329 actions.append(&mut outcome.actions);
9330 outcome.actions = actions;
9331 self.arena_prepend(&mut outcome.nodes, child_node);
9332 outcome
9333 }),
9334 );
9335 }
9336 }
9337 Transition::Atom { target, .. }
9338 | Transition::Range { target, .. }
9339 | Transition::Set { target, .. }
9340 | Transition::NotSet { target, .. }
9341 | Transition::Wildcard { target, .. } => {
9342 let symbol = self.token_type_at(index);
9343 if transition_data.matches(symbol, 1, atn.max_token_type()) {
9344 let next_index = self.consume_index(index, symbol);
9345 outcomes.extend(
9346 self.recognize_state(
9347 atn,
9348 RecognizeRequest {
9349 state_number: *target,
9350 stop_state,
9351 index: next_index,
9352 rule_start_index,
9353 decision_start_index: next_decision_start_index,
9354 init_action_rules,
9355 predicates,
9356 semantics,
9357 rule_args,
9358 member_actions,
9359 return_actions,
9360 local_int_arg,
9361 member_values: member_values.clone(),
9362 return_values: return_values.clone(),
9363 rule_alt_number: next_alt_number,
9364 track_alt_numbers,
9365 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
9366 precedence,
9367 depth: depth + 1,
9368 recovery_symbols: BTreeSet::new(),
9369 recovery_state: None,
9370 },
9371 visiting,
9372 memo,
9373 expected,
9374 )
9375 .into_iter()
9376 .map(|mut outcome| {
9377 prepend_decision(&mut outcome, decision);
9378 outcome.consumed_eof |= symbol == TOKEN_EOF;
9379 let token = self.arena_token_node(index, false);
9380 self.arena_prepend(&mut outcome.nodes, token);
9381 outcome
9382 }),
9383 );
9384 } else {
9385 let expected_symbols =
9386 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
9387 if expected_symbols.contains(&symbol) {
9388 continue;
9389 }
9390 expected.record_transition(index, transition, atn.max_token_type());
9391 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
9392 let before_recovery = outcomes.len();
9393 let recovery_request = request_template.clone();
9394 outcomes.extend(
9395 self.single_token_deletion_recovery(RecoveryRequest {
9396 atn,
9397 transition,
9398 expected_symbols: expected_symbols.clone(),
9399 target: *target,
9400 request: recovery_request.clone(),
9401 visiting,
9402 memo,
9403 expected,
9404 })
9405 .into_iter()
9406 .map(|mut outcome| {
9407 prepend_decision(&mut outcome, decision);
9408 outcome
9409 }),
9410 );
9411 if !state_is_left_recursive_rule(atn, state) {
9412 outcomes.extend(
9413 self.single_token_insertion_recovery(RecoveryRequest {
9414 atn,
9415 transition,
9416 expected_symbols: expected_symbols.clone(),
9417 target: *target,
9418 request: recovery_request.clone(),
9419 visiting,
9420 memo,
9421 expected,
9422 })
9423 .into_iter()
9424 .map(|mut outcome| {
9425 prepend_decision(&mut outcome, decision);
9426 outcome
9427 }),
9428 );
9429 }
9430 outcomes.extend(self.current_token_deletion_recovery(
9431 CurrentTokenDeletionRequest {
9432 atn,
9433 expected_symbols: expected_symbols.clone(),
9434 request: recovery_request.clone(),
9435 visiting,
9436 memo,
9437 expected,
9438 },
9439 ));
9440 if outcomes.len() == before_recovery {
9441 outcomes.extend(self.consuming_failure_fallback(
9442 ConsumingFailureFallback {
9443 atn,
9444 target: *target,
9445 request: recovery_request,
9446 symbol,
9447 expected_symbols,
9448 decision_start_index: next_decision_start_index,
9449 decision,
9450 },
9451 visiting,
9452 memo,
9453 expected,
9454 ));
9455 }
9456 }
9457 }
9458 }
9459 }
9460
9461 visiting.remove(&visit_key);
9462 self.record_prediction_diagnostics(atn, state, index, &outcomes);
9463 if matches!(
9464 self.prediction_mode,
9465 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9466 ) {
9467 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
9468 }
9469 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
9470 memo.insert(key, outcomes.clone());
9471 outcomes
9472 }
9473
9474 fn recognize_epsilon_or_action_step(
9477 &mut self,
9478 atn: &Atn,
9479 request: &RecognizeRequest<'_>,
9480 step: EpsilonActionStep,
9481 scratch: RecognizeScratch<'_>,
9482 ) -> Vec<RecognizeOutcome> {
9483 let RecognizeScratch {
9484 visiting,
9485 memo,
9486 expected,
9487 } = scratch;
9488 let action = step.action_rule_index.map(|rule_index| {
9489 ParserAction::new(
9490 step.source_state,
9491 rule_index,
9492 request.rule_start_index,
9493 self.rule_stop_token_index(request.index, request.consumed_eof),
9494 )
9495 });
9496 let next_member_values = if action.is_some() {
9497 member_values_after_action(
9498 step.source_state,
9499 request.member_actions,
9500 request.semantics,
9501 &request.member_values,
9502 )
9503 } else {
9504 request.member_values.clone()
9505 };
9506 let next_return_values = action.map_or_else(
9507 || request.return_values.clone(),
9508 |action| {
9509 return_values_after_action(
9510 step.source_state,
9511 action.rule_index(),
9512 request.return_actions,
9513 request.semantics,
9514 &request.return_values,
9515 )
9516 },
9517 );
9518
9519 self.recognize_state(
9520 atn,
9521 RecognizeRequest {
9522 state_number: step.target,
9523 stop_state: request.stop_state,
9524 index: request.index,
9525 rule_start_index: request.rule_start_index,
9526 decision_start_index: step.decision_start_index,
9527 init_action_rules: request.init_action_rules,
9528 predicates: request.predicates,
9529 semantics: request.semantics,
9530 rule_args: request.rule_args,
9531 member_actions: request.member_actions,
9532 return_actions: request.return_actions,
9533 local_int_arg: request.local_int_arg,
9534 member_values: next_member_values,
9535 return_values: next_return_values,
9536 rule_alt_number: step.alt_number,
9537 track_alt_numbers: request.track_alt_numbers,
9538 consumed_eof: request.consumed_eof,
9539 precedence: request.precedence,
9540 depth: request.depth + 1,
9541 recovery_symbols: step.recovery_symbols,
9542 recovery_state: step.recovery_state,
9543 },
9544 visiting,
9545 memo,
9546 expected,
9547 )
9548 .into_iter()
9549 .map(|mut outcome| {
9550 prepend_decision(&mut outcome, step.decision);
9551 if let Some(rule_index) = step.left_recursive_boundary {
9552 let boundary = self.arena_boundary_node(rule_index);
9553 self.arena_prepend(&mut outcome.nodes, boundary);
9554 }
9555 if let Some(action) = action {
9556 outcome.actions.insert(0, action);
9557 }
9558 outcome
9559 })
9560 .collect()
9561 }
9562
9563 fn token_type_at(&mut self, index: usize) -> i32 {
9568 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
9569 self.input.fill();
9570 }
9571 self.input.token_type_at_index(index)
9572 }
9573
9574 fn cached_state_expected_symbols(
9586 &mut self,
9587 atn: &Atn,
9588 state_number: usize,
9589 ) -> Rc<BTreeSet<i32>> {
9590 if let Some(cached) = self.state_expected_cache.get(&state_number) {
9591 return Rc::clone(cached);
9592 }
9593 let symbols = state_expected_symbols(atn, state_number);
9594 let entry = self.intern_recovery_symbols(symbols);
9595 self.state_expected_cache
9596 .insert(state_number, Rc::clone(&entry));
9597 entry
9598 }
9599
9600 fn cached_state_expected_token_set(
9601 &mut self,
9602 atn: &Atn,
9603 state_number: usize,
9604 ) -> Rc<TokenBitSet> {
9605 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
9606 return Rc::clone(cached);
9607 }
9608 let symbols = with_shared_atn_caches(atn, |cache| {
9612 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
9613 return Rc::clone(cached);
9614 }
9615 let symbols = Rc::new(state_expected_token_set(atn, state_number));
9616 cache
9617 .state_expected_tokens
9618 .insert(state_number, Rc::clone(&symbols));
9619 symbols
9620 });
9621 self.state_expected_token_cache
9622 .insert(state_number, Rc::clone(&symbols));
9623 symbols
9624 }
9625
9626 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
9627 if self.rule_stop_reach_cache.len() <= state_number {
9628 self.rule_stop_reach_cache
9629 .resize_with(atn.states().len().max(state_number + 1), || None);
9630 }
9631 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
9632 return reaches;
9633 }
9634 let reaches = with_shared_atn_caches(atn, |cache| {
9635 *cache
9636 .rule_stop_reach
9637 .entry(state_number)
9638 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
9639 });
9640 self.rule_stop_reach_cache[state_number] = Some(reaches);
9641 reaches
9642 }
9643
9644 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
9647 Rc::clone(&self.empty_recovery_symbols)
9648 }
9649
9650 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
9659 if set.is_empty() {
9660 return Rc::clone(&self.empty_recovery_symbols);
9661 }
9662 let candidate = Rc::new(set);
9663 match self.recovery_symbols_intern.get(&candidate) {
9664 Some(existing) => Rc::clone(existing),
9665 None => {
9666 self.recovery_symbols_intern
9667 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
9668 candidate
9669 }
9670 }
9671 }
9672
9673 fn cached_decision_lookahead(
9678 &mut self,
9679 atn: &Atn,
9680 state: AtnState<'_>,
9681 rule_stop_state: usize,
9682 ) -> Rc<DecisionLookahead> {
9683 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
9690 return Rc::clone(cached);
9691 }
9692 let entry = with_shared_atn_caches(atn, |cache| {
9693 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
9694 return Rc::clone(cached);
9695 }
9696 let mut entry = DecisionLookahead {
9697 transitions: Vec::with_capacity(state.transitions().len()),
9698 };
9699 for transition in &state.transitions() {
9700 entry.transitions.push(transition_first_set(
9701 atn,
9702 transition,
9703 rule_stop_state,
9704 &mut cache.first_set,
9705 ));
9706 }
9707 let entry = Rc::new(entry);
9708 cache
9709 .decision_lookahead
9710 .insert(state.state_number(), Rc::clone(&entry));
9711 entry
9712 });
9713 self.decision_lookahead_cache
9714 .insert(state.state_number(), Rc::clone(&entry));
9715 entry
9716 }
9717
9718 fn cached_rule_first_set(
9719 &mut self,
9720 atn: &Atn,
9721 target: usize,
9722 child_stop: usize,
9723 ) -> Rc<FirstSet> {
9724 if self.rule_first_set_cache.len() <= target {
9725 self.rule_first_set_cache
9726 .resize_with(atn.states().len().max(target + 1), || None);
9727 }
9728 if let Some(cached) = self
9729 .rule_first_set_cache
9730 .get(target)
9731 .and_then(Option::as_ref)
9732 {
9733 return Rc::clone(cached);
9734 }
9735 let first = with_shared_first_set_cache(atn, |cache| {
9736 rule_first_set(atn, target, child_stop, cache)
9737 });
9738 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
9739 first
9740 }
9741
9742 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
9743 if self.empty_cycle_cache.len() <= state_number {
9744 self.empty_cycle_cache
9745 .resize_with(atn.states().len().max(state_number + 1), || None);
9746 }
9747 if let Some(cached) = self.empty_cycle_cache[state_number] {
9748 return cached;
9749 }
9750 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
9751 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
9752 self.empty_cycle_cache[state_number] = Some(result);
9753 result
9754 }
9755
9756 fn empty_path_reaches_state(
9757 &mut self,
9758 atn: &Atn,
9759 state_number: usize,
9760 target_state: usize,
9761 visited: &mut FxHashSet<usize>,
9762 ) -> bool {
9763 if !visited.insert(state_number) {
9764 return false;
9765 }
9766 let Some(state) = atn.state(state_number) else {
9767 return false;
9768 };
9769 for transition in &state.transitions() {
9770 let kind = transition.kind();
9771 let target = transition.target();
9772 match kind {
9773 ParserTransitionKind::Atom
9774 | ParserTransitionKind::Range
9775 | ParserTransitionKind::Set
9776 | ParserTransitionKind::NotSet
9777 | ParserTransitionKind::Wildcard => {}
9778 ParserTransitionKind::Rule => {
9779 let rule_index = transition.arg0() as usize;
9780 let follow_state = transition.arg1() as usize;
9781 if target == target_state
9782 || self.empty_path_reaches_state(atn, target, target_state, visited)
9783 {
9784 return true;
9785 }
9786 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
9787 continue;
9788 };
9789 if self.cached_rule_first_set(atn, target, child_stop).nullable
9790 && (follow_state == target_state
9791 || self.empty_path_reaches_state(
9792 atn,
9793 follow_state,
9794 target_state,
9795 visited,
9796 ))
9797 {
9798 return true;
9799 }
9800 }
9801 ParserTransitionKind::Epsilon
9802 | ParserTransitionKind::Predicate
9803 | ParserTransitionKind::Action
9804 | ParserTransitionKind::Precedence => {
9805 if target == target_state
9806 || self.empty_path_reaches_state(atn, target, target_state, visited)
9807 {
9808 return true;
9809 }
9810 }
9811 }
9812 }
9813 false
9814 }
9815
9816 fn should_memoize_single_outcome(&mut self, key: &FastRecognizeKey) -> bool {
9819 match self.single_outcome_memo_mode {
9820 SingleOutcomeMemoMode::Promote => true,
9821 SingleOutcomeMemoMode::Sparse => false,
9822 SingleOutcomeMemoMode::Probe => {
9823 self.single_outcome_probe_samples += 1;
9824 if !self.single_outcome_probe_seen.insert(key.clone()) {
9825 self.single_outcome_probe_repeats += 1;
9826 }
9827 if self.single_outcome_probe_repeats >= CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
9828 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Promote;
9829 self.single_outcome_probe_seen.clear();
9830 return true;
9831 }
9832 if self.single_outcome_probe_samples >= CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT {
9833 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Sparse;
9834 self.single_outcome_probe_seen.clear();
9835 return false;
9836 }
9837 true
9838 }
9839 }
9840 }
9841
9842 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
9844 self.input.get(index)
9845 }
9846
9847 fn token_id_at(&self, index: usize) -> Option<TokenId> {
9849 self.input.get_id(index)
9850 }
9851
9852 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
9853 let token = self
9854 .token_id_at(index)
9855 .expect("recognized token index must exist in the token store");
9856 let node = if error {
9857 ArenaRecognizedNode::ErrorToken { token }
9858 } else {
9859 ArenaRecognizedNode::Token { token }
9860 };
9861 self.recognition_arena.push_node(node)
9862 }
9863
9864 fn arena_missing_token_node(
9865 &mut self,
9866 token_type: i32,
9867 at_index: usize,
9868 text: String,
9869 ) -> RecognizedNodeId {
9870 let extra = self
9871 .recognition_arena
9872 .push_extra(RecognitionExtra::MissingToken {
9873 token_type,
9874 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
9875 text,
9876 });
9877 self.recognition_arena
9878 .push_node(ArenaRecognizedNode::MissingToken { extra })
9879 }
9880
9881 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
9882 let ArenaRuleSpec {
9883 rule_index,
9884 invoking_state,
9885 alt_number,
9886 start_index,
9887 stop_index,
9888 return_values,
9889 children,
9890 } = spec;
9891 let return_values = (!return_values.is_empty()).then(|| {
9892 self.recognition_arena
9893 .push_extra(RecognitionExtra::ReturnValues(return_values))
9894 });
9895 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
9896 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
9897 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
9898 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
9899 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
9900 stop_index: stop_index
9901 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
9902 return_values,
9903 children,
9904 })
9905 }
9906
9907 fn arena_boundary_node(&mut self, rule_index: usize) -> RecognizedNodeId {
9908 self.recognition_arena
9909 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
9910 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
9911 })
9912 }
9913
9914 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
9915 *sequence = self.recognition_arena.prepend(*sequence, node);
9916 }
9917
9918 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
9919 self.last_recognition_arena_root = root;
9920 self.last_recognition_arena_diagnostics = diagnostics;
9921 #[cfg(feature = "perf-counters")]
9922 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
9923 let stats = self.recognition_arena_stats();
9924 #[allow(clippy::print_stderr)]
9925 {
9926 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
9927 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
9928 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
9929 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
9930 eprintln!("perf recognition_links_total={}", stats.total_links);
9931 eprintln!("perf recognition_links_live={}", stats.live_links);
9932 eprintln!("perf recognition_links_dead={}", stats.dead_links);
9933 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
9934 eprintln!("perf recognition_extras_total={}", stats.total_extras);
9935 eprintln!("perf recognition_extras_live={}", stats.live_extras);
9936 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
9937 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
9938 }
9939 }
9940 }
9941
9942 fn reset_recognition_arena(&mut self) {
9943 self.recognition_arena.reset();
9944 self.last_recognition_arena_root = NodeSeqId::EMPTY;
9945 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
9946 }
9947
9948 fn current_visible_index(&mut self) -> usize {
9951 let index = self.input.index();
9952 self.input.seek(index);
9953 self.input.index()
9954 }
9955
9956 fn child_expected_reaches_clean_eof(
9959 &mut self,
9960 children: &[RecognizeOutcome],
9961 expected: &ExpectedTokens,
9962 ) -> bool {
9963 let Some(index) = expected.index else {
9964 return false;
9965 };
9966 self.token_type_at(index) == TOKEN_EOF
9967 && children
9968 .iter()
9969 .any(|child| child.diagnostics.is_empty() && child.index == index)
9970 }
9971
9972 fn previous_token_index(&self, index: usize) -> Option<usize> {
9979 self.input.previous_visible_token_index(index)
9980 }
9981
9982 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
9987 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
9988 Some(index)
9989 } else {
9990 self.previous_token_index(index)
9991 }
9992 }
9993
9994 #[must_use]
10011 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
10012 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
10013 self.rule_stop_token_index(current_index, consumed_eof)
10014 }
10015
10016 #[must_use]
10025 pub fn after_action_stop_index_for_tree(
10026 &mut self,
10027 tree: ParseTree,
10028 current_index: usize,
10029 ) -> Option<usize> {
10030 if let Some(stop) = self
10031 .node(tree)
10032 .as_rule()
10033 .and_then(crate::tree::RuleNodeView::stop_id)
10034 {
10035 return Some(stop.index());
10036 }
10037 self.after_action_stop_index(current_index)
10038 }
10039
10040 #[must_use]
10050 pub fn after_action_start_index_for_tree(
10051 &self,
10052 tree: ParseTree,
10053 fallback_index: usize,
10054 ) -> usize {
10055 if let Some(start) = self
10056 .node(tree)
10057 .as_rule()
10058 .and_then(crate::tree::RuleNodeView::start_id)
10059 {
10060 return start.index();
10061 }
10062 fallback_index
10063 }
10064
10065 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
10070 self.rule_stop_token_index(index, consumed_eof)
10071 .and_then(|token_index| self.token_id_at(token_index))
10072 }
10073
10074 fn predicate_failure_recovery(
10081 &mut self,
10082 request: PredicateFailureRecovery<'_>,
10083 ) -> RecognizeOutcome {
10084 let PredicateFailureRecovery {
10085 rule_index,
10086 index,
10087 message,
10088 member_values,
10089 return_values,
10090 rule_alt_number,
10091 } = request;
10092 let rule_name = self
10093 .rule_names()
10094 .get(rule_index)
10095 .map_or_else(|| rule_index.to_string(), Clone::clone);
10096 let diagnostic = diagnostic_for_token(
10097 self.token_at(index).as_ref(),
10098 format!("rule {rule_name} {message}"),
10099 );
10100 let mut reversed_nodes = NodeSeqId::EMPTY;
10101 let mut next_index = index;
10102 loop {
10103 let symbol = self.token_type_at(next_index);
10104 if symbol == TOKEN_EOF {
10105 break;
10106 }
10107 let error = self.arena_token_node(next_index, true);
10108 self.arena_prepend(&mut reversed_nodes, error);
10109 let after = self.consume_index(next_index, symbol);
10110 if after == next_index {
10111 break;
10112 }
10113 next_index = after;
10114 }
10115 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
10116 let diagnostics = self
10117 .recognition_arena
10118 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10119 RecognizeOutcome {
10120 index: next_index,
10121 consumed_eof: false,
10122 alt_number: rule_alt_number,
10123 member_values,
10124 return_values,
10125 diagnostics,
10126 decisions: Vec::new(),
10127 actions: Vec::new(),
10128 nodes,
10129 }
10130 }
10131
10132 fn parser_semantic_hook_result(
10135 &mut self,
10136 request: ParserSemanticHookRequest<'_>,
10137 ) -> Option<bool> {
10138 let ParserSemanticHookRequest {
10139 index,
10140 rule_index,
10141 pred_index,
10142 context,
10143 local_int_arg,
10144 member_values,
10145 } = request;
10146 let rule_name = self.rule_names().get(rule_index).cloned();
10147 self.input.seek(index);
10148 let input = &mut self.input;
10149 let semantic_hooks = &mut self.semantic_hooks;
10150 let mut ctx = ParserSemCtx {
10151 input,
10152 tree_storage: &self.tree,
10153 rule_index,
10154 coordinate_index: pred_index,
10155 rule_name,
10156 context,
10157 tree: None,
10158 local_int_arg,
10159 member_values,
10160 action: None,
10161 };
10162 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
10163 }
10164
10165 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
10170 if prior.is_empty() {
10171 return;
10172 }
10173 let mut merged = prior;
10174 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
10175 if !merged.contains(&coordinate) {
10176 merged.push(coordinate);
10177 }
10178 }
10179 self.unknown_predicate_hits = merged;
10180 }
10181
10182 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
10191 apply_unknown_predicate_policy(
10192 self.unknown_predicate_policy,
10193 rule_index,
10194 pred_index,
10195 &mut self.unknown_predicate_hits,
10196 )
10197 }
10198
10199 fn unknown_semantic_error(&self) -> Option<AntlrError> {
10202 use std::fmt::Write as _;
10203 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
10204 return None;
10205 }
10206 let mut message = String::new();
10207 for (rule_index, pred_index) in &self.unknown_predicate_hits {
10208 if !message.is_empty() {
10209 message.push_str("; ");
10210 }
10211 let _ = match self.rule_names().get(*rule_index) {
10212 Some(rule_name) => write!(
10213 message,
10214 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
10215 ),
10216 None => write!(
10217 message,
10218 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
10219 ),
10220 };
10221 }
10222 for (rule_index, source_state) in &self.unhandled_action_hits {
10223 if !message.is_empty() {
10224 message.push_str("; ");
10225 }
10226 let _ = match self.rule_names().get(*rule_index) {
10227 Some(rule_name) => write!(
10228 message,
10229 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
10230 ),
10231 None => write!(
10232 message,
10233 "unhandled semantic action: rule_index={rule_index} state={source_state}"
10234 ),
10235 };
10236 }
10237 Some(AntlrError::Unsupported(message))
10238 }
10239
10240 fn parser_semir_predicate_matches(
10248 &mut self,
10249 semantics: &ParserSemantics,
10250 predicate: &ParserSemanticPredicate,
10251 request: ParserSemanticHookRequest<'_>,
10252 ) -> bool {
10253 self.input.seek(request.index);
10254 let rule_name = self
10255 .data
10256 .rule_names()
10257 .get(request.rule_index)
10258 .map(String::as_str);
10259 let unknown_predicate_policy = self.unknown_predicate_policy;
10260 let mut ctx = ParserSemIrCtx {
10261 input: &mut self.input,
10262 tree_storage: &self.tree,
10263 semantic_hooks: &mut self.semantic_hooks,
10264 rule_index: request.rule_index,
10265 coordinate_index: request.pred_index,
10266 rule_name,
10267 context: request.context,
10268 local_int_arg: request.local_int_arg,
10269 member_values: request.member_values,
10270 invoked_predicates: &mut self.invoked_predicates,
10271 unknown_predicate_policy,
10272 unknown_predicate_hits: &mut self.unknown_predicate_hits,
10273 };
10274 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
10275 }
10276
10277 fn fast_parser_predicate_matches(
10278 &mut self,
10279 context: Option<FastPredicateContext<'_>>,
10280 transition: ParserTransition<'_>,
10281 index: usize,
10282 ) -> bool {
10283 let Some(context) = context else {
10284 return true;
10285 };
10286 let rule_index = transition.arg0() as usize;
10287 let pred_index = transition.arg1() as usize;
10288 let key = (index, rule_index, pred_index);
10289 if let Some(result) = self.fast_predicate_cache.get(&key) {
10290 return *result;
10291 }
10292 let result = self.parser_predicate_matches(PredicateEval {
10293 index,
10294 rule_index,
10295 pred_index,
10296 predicates: context.predicates,
10297 semantics: context.semantics,
10298 context: None,
10299 local_int_arg: None,
10300 member_values: context.member_values,
10301 });
10302 self.fast_predicate_cache.insert(key, result);
10303 result
10304 }
10305
10306 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
10307 let PredicateEval {
10308 index,
10309 rule_index,
10310 pred_index,
10311 predicates,
10312 semantics,
10313 context,
10314 local_int_arg,
10315 member_values,
10316 } = eval;
10317 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
10318 semantics
10319 .predicates
10320 .iter()
10321 .find(|predicate| {
10322 predicate.rule_index == rule_index && predicate.pred_index == pred_index
10323 })
10324 .map(|predicate| (semantics, predicate))
10325 }) {
10326 return self.parser_semir_predicate_matches(
10327 semantics,
10328 predicate,
10329 ParserSemanticHookRequest {
10330 index,
10331 rule_index,
10332 pred_index,
10333 context,
10334 local_int_arg,
10335 member_values,
10336 },
10337 );
10338 }
10339 let Some((_, _, predicate)) = predicates
10340 .iter()
10341 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
10342 else {
10343 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
10344 index,
10345 rule_index,
10346 pred_index,
10347 context,
10348 local_int_arg,
10349 member_values,
10350 }) {
10351 return result;
10352 }
10353 return self.unknown_predicate_result(rule_index, pred_index);
10354 };
10355 self.input.seek(index);
10356 match predicate {
10357 ParserPredicate::True => true,
10358 ParserPredicate::False => false,
10359 ParserPredicate::FalseWithMessage { .. } => false,
10360 ParserPredicate::Invoke { value } => {
10361 let key = (rule_index, pred_index);
10362 if !self.invoked_predicates.contains(&key) {
10363 self.invoked_predicates.push(key);
10364 use std::io::Write as _;
10365 let mut stdout = std::io::stdout().lock();
10366 let _ = writeln!(stdout, "eval={value}");
10367 }
10368 *value
10369 }
10370 ParserPredicate::LookaheadTextEquals { offset, text } => self
10371 .input
10372 .lt(*offset)
10373 .is_some_and(|token| Token::text(&token) == Some(*text)),
10374 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
10375 self.la(*offset) != *token_type
10376 }
10377 ParserPredicate::TokenPairAdjacent => {
10378 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
10379 return false;
10380 };
10381 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
10382 return false;
10383 };
10384 first + 1 == second
10385 }
10386 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
10387 .and_then(|context| {
10388 context
10389 .child_rules(&self.tree, self.input.token_store(), *rule_index)
10390 .next()
10391 .map(crate::tree::RuleNodeView::text)
10392 })
10393 .is_none_or(|actual| actual != *text),
10394 ParserPredicate::LocalIntEquals { value } => {
10395 local_int_arg.is_none_or(|(_, actual)| actual == *value)
10396 }
10397 ParserPredicate::LocalIntLessOrEqual { value } => {
10398 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
10399 }
10400 ParserPredicate::MemberModuloEquals {
10401 member,
10402 modulus,
10403 value,
10404 equals,
10405 } => {
10406 if *modulus == 0 {
10407 return false;
10408 }
10409 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
10410 (actual == *value) == *equals
10411 }
10412 ParserPredicate::MemberEquals {
10413 member,
10414 value,
10415 equals,
10416 } => {
10417 let actual = member_values.get(member).copied().unwrap_or_default();
10418 (actual == *value) == *equals
10419 }
10420 }
10421 }
10422
10423 fn parser_predicate_failure_message(
10425 &self,
10426 rule_index: usize,
10427 pred_index: usize,
10428 predicates: &[(usize, usize, ParserPredicate)],
10429 ) -> Option<&'static str> {
10430 predicates
10431 .iter()
10432 .find_map(|(rule, pred, predicate)| match predicate {
10433 ParserPredicate::FalseWithMessage { message }
10434 if *rule == rule_index && *pred == pred_index =>
10435 {
10436 Some(*message)
10437 }
10438 _ => None,
10439 })
10440 }
10441
10442 pub fn parser_semantic_ir_predicate_failure_message(
10445 &self,
10446 rule_index: usize,
10447 pred_index: usize,
10448 semantics: &ParserSemantics,
10449 ) -> Option<&'static str> {
10450 semantics
10451 .predicates
10452 .iter()
10453 .find(|predicate| {
10454 predicate.rule_index == rule_index && predicate.pred_index == pred_index
10455 })
10456 .and_then(|predicate| predicate.failure_message)
10457 }
10458
10459 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
10468 if symbol == TOKEN_EOF {
10469 return index;
10470 }
10471 self.input.next_visible_after(index)
10472 }
10473
10474 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
10477 let text = display_input_text(&self.input.text(start_index, error_index));
10478 diagnostic_for_token(
10479 self.token_at(error_index).as_ref(),
10480 format!("no viable alternative at input '{text}'"),
10481 )
10482 }
10483
10484 fn recovery_failure_diagnostic(
10487 &self,
10488 index: usize,
10489 decision_start_index: Option<usize>,
10490 expected_symbols: &BTreeSet<i32>,
10491 ) -> ParserDiagnostic {
10492 if expected_symbols.len() > 1 {
10493 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
10494 return self.no_viable_alternative(decision_start, index);
10495 }
10496 }
10497 diagnostic_for_token(
10498 self.token_at(index).as_ref(),
10499 format!(
10500 "mismatched input {} expecting {}",
10501 self.token_at(index)
10502 .as_ref()
10503 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
10504 self.expected_symbols_display(expected_symbols)
10505 ),
10506 )
10507 }
10508
10509 fn eof_rule_recovery_diagnostic(
10512 &self,
10513 index: usize,
10514 expected_symbols: &BTreeSet<i32>,
10515 expected: &ExpectedTokens,
10516 ) -> ParserDiagnostic {
10517 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
10518 &expected.symbols
10519 } else {
10520 expected_symbols
10521 };
10522 diagnostic_for_token(
10523 self.token_at(index).as_ref(),
10524 format!(
10525 "mismatched input {} expecting {}",
10526 self.token_at(index)
10527 .as_ref()
10528 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
10529 self.expected_symbols_display(symbols)
10530 ),
10531 )
10532 }
10533
10534 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
10540 let Some(stop) = stop else {
10541 return String::new();
10542 };
10543 let stop = if self
10544 .token_at(stop)
10545 .is_some_and(|token| token.token_type() == TOKEN_EOF)
10546 {
10547 let Some(previous) = self.previous_token_index(stop) else {
10548 return String::new();
10549 };
10550 previous
10551 } else {
10552 stop
10553 };
10554 self.input.text(start, stop)
10555 }
10556
10557 fn clear_prediction_diagnostics(&mut self) {
10560 self.prediction_diagnostics.clear();
10561 self.reported_prediction_diagnostics.clear();
10562 }
10563
10564 fn reset_per_parse_caches(&mut self) {
10586 self.rule_first_set_cache.clear();
10587 self.decision_lookahead_cache.clear();
10588 self.ll1_decision_cache.clear();
10589 self.fast_predicate_cache.clear();
10590 self.empty_cycle_cache.clear();
10591 self.rule_stop_reach_cache.clear();
10592 self.single_outcome_memo_mode = SingleOutcomeMemoMode::Probe;
10593 self.single_outcome_probe_seen.clear();
10594 self.single_outcome_probe_samples = 0;
10595 self.single_outcome_probe_repeats = 0;
10596 self.recovery_symbols_intern.clear();
10597 self.state_expected_cache.clear();
10598 self.state_expected_token_cache.clear();
10599 }
10600
10601 fn record_prediction_diagnostics(
10604 &mut self,
10605 atn: &Atn,
10606 state: AtnState<'_>,
10607 start_index: usize,
10608 outcomes: &[RecognizeOutcome],
10609 ) {
10610 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
10611 return;
10612 }
10613 let Some(decision) = atn
10614 .decision_to_state()
10615 .iter()
10616 .position(|state_number| state_number == state.state_number())
10617 else {
10618 return;
10619 };
10620 let Some(rule_index) = state.rule_index() else {
10621 return;
10622 };
10623 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
10624 for outcome in outcomes
10625 .iter()
10626 .filter(|outcome| outcome.diagnostics.is_empty())
10627 {
10628 let Some(alt) = outcome.decisions.first() else {
10629 continue;
10630 };
10631 alts_by_end
10632 .entry(outcome.index)
10633 .or_default()
10634 .insert(alt + 1);
10635 }
10636 let Some((&end_index, ambig_alts)) = alts_by_end
10637 .iter()
10638 .filter(|(_, alts)| alts.len() > 1)
10639 .max_by_key(|(end, _)| *end)
10640 else {
10641 return;
10642 };
10643 let rule_name = self
10644 .rule_names()
10645 .get(rule_index)
10646 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
10647 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
10648 let input = display_input_text(&self.input.text(start_index, stop_index));
10649 let alts = ambig_alts
10650 .iter()
10651 .map(usize::to_string)
10652 .collect::<Vec<_>>()
10653 .join(", ");
10654 let key = (decision, start_index, format!("{alts}:{input}"));
10655 if !self.reported_prediction_diagnostics.insert(key) {
10656 return;
10657 }
10658 let start_diagnostic = diagnostic_for_token(
10659 self.token_at(start_index),
10660 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
10661 );
10662 let stop_diagnostic = diagnostic_for_token(
10663 self.token_at(stop_index),
10664 format!(
10665 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
10666 ),
10667 );
10668 self.prediction_diagnostics.push(start_diagnostic);
10669 self.prediction_diagnostics.push(stop_diagnostic);
10670 }
10671
10672 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
10674 expected_symbols_display(
10675 &state_expected_symbols(atn, state_number),
10676 self.vocabulary(),
10677 )
10678 }
10679
10680 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
10685 let state = usize::try_from(self.data().state()).unwrap_or(0);
10686 ExpectedTokenSet {
10687 symbols: state_expected_symbols(atn, state),
10688 }
10689 }
10690
10691 pub const fn set_bail_on_error(&mut self, bail: bool) {
10694 self.bail_on_error = bail;
10695 }
10696
10697 #[must_use]
10699 pub const fn bail_on_error(&self) -> bool {
10700 self.bail_on_error
10701 }
10702
10703 pub fn rule_invocation_stack(&self) -> Vec<String> {
10706 self.rule_context_stack
10707 .iter()
10708 .rev()
10709 .map(|frame| {
10710 self.data()
10711 .rule_names()
10712 .get(frame.rule_index)
10713 .cloned()
10714 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
10715 })
10716 .collect()
10717 }
10718
10719 pub fn active_invocation_states(&self) -> Vec<isize> {
10723 self.rule_context_stack
10724 .iter()
10725 .skip(1)
10726 .rev()
10727 .map(|frame| frame.invoking_state)
10728 .collect()
10729 }
10730
10731 pub fn token_display_at(&self, index: usize) -> Option<String> {
10733 self.token_at(index).map(|token| format!("{token}"))
10734 }
10735}
10736
10737impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
10738where
10739 S: TokenSource,
10740 H: SemanticHooks,
10741{
10742 fn parse_rule(
10743 &mut self,
10744 rule_index: usize,
10745 invoking_state: isize,
10746 precedence: i32,
10747 ) -> DirectAdaptiveParseResult<ParseTree> {
10748 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
10749 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
10750 )?;
10751 let stop_state = self
10752 .atn
10753 .rule_to_stop_state()
10754 .get(rule_index)
10755 .filter(|state| *state != usize::MAX)
10756 .ok_or(DirectAdaptiveParseControl::Fallback(
10757 DirectAdaptiveFallback::MissingAtn,
10758 ))?;
10759 let start_index = self.parser.current_visible_index();
10760 let mut context = ParserRuleContext::new(rule_index, invoking_state);
10761 if let Some(token) = self.parser.token_id_at(start_index) {
10762 self.parser.set_context_start(&mut context, token);
10763 }
10764 let mut state_number = start_state;
10765 let mut consumed_eof = false;
10766 while state_number != stop_state {
10767 self.step()?;
10768 let (transition, boundary) = self.next_transition(state_number, precedence)?;
10769 if boundary.is_some() {
10770 return Err(DirectAdaptiveParseControl::Fallback(
10771 DirectAdaptiveFallback::LeftRecursiveBoundary,
10772 ));
10773 }
10774 match transition.data() {
10775 Transition::Epsilon { target } => {
10776 state_number = target;
10777 }
10778 Transition::Precedence {
10779 target,
10780 precedence: transition_precedence,
10781 } => {
10782 if transition_precedence < precedence {
10783 return Err(DirectAdaptiveParseControl::Fallback(
10784 DirectAdaptiveFallback::Precedence,
10785 ));
10786 }
10787 state_number = target;
10788 }
10789 Transition::Rule {
10790 rule_index,
10791 follow_state,
10792 precedence: rule_precedence,
10793 ..
10794 } => {
10795 let child = self.parse_rule(
10796 rule_index,
10797 invoking_state_number(state_number),
10798 rule_precedence,
10799 )?;
10800 if self.parser.build_parse_trees {
10801 self.parser.tree.add_child(&mut context, child);
10802 }
10803 state_number = follow_state;
10804 }
10805 Transition::Atom { .. }
10806 | Transition::Range { .. }
10807 | Transition::Set { .. }
10808 | Transition::NotSet { .. }
10809 | Transition::Wildcard { .. } => {
10810 let (matched_eof, child) = self.consume_transition(transition)?;
10811 consumed_eof |= matched_eof;
10812 if let Some(child) = child {
10813 self.parser.tree.add_child(&mut context, child);
10814 }
10815 state_number = transition.target();
10816 }
10817 Transition::Predicate { .. } => {
10818 return Err(DirectAdaptiveParseControl::Fallback(
10819 DirectAdaptiveFallback::Predicate,
10820 ));
10821 }
10822 Transition::Action { .. } => {
10823 return Err(DirectAdaptiveParseControl::Fallback(
10824 DirectAdaptiveFallback::Action,
10825 ));
10826 }
10827 }
10828 }
10829
10830 let stop_index = self
10831 .parser
10832 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
10833 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
10834 self.parser.set_context_stop(&mut context, token);
10835 }
10836 Ok(self.parser.rule_node(context))
10837 }
10838
10839 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
10840 self.steps += 1;
10841 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
10842 return Err(DirectAdaptiveParseControl::Fallback(
10843 DirectAdaptiveFallback::StepLimit,
10844 ));
10845 }
10846 Ok(())
10847 }
10848
10849 fn next_transition(
10850 &mut self,
10851 state_number: usize,
10852 precedence: i32,
10853 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
10854 let state = self
10855 .atn
10856 .state(state_number)
10857 .ok_or(DirectAdaptiveParseControl::Fallback(
10858 DirectAdaptiveFallback::MissingAtn,
10859 ))?;
10860 if state.is_rule_stop() {
10861 return Err(DirectAdaptiveParseControl::Fallback(
10862 DirectAdaptiveFallback::RuleStop,
10863 ));
10864 }
10865 let transition_index =
10866 self.transition_index(state_number, state.transitions().len(), precedence)?;
10867 let transition = state.transitions().get(transition_index).ok_or(
10868 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
10869 )?;
10870 let boundary = match &transition.data() {
10871 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
10872 left_recursive_boundary(self.atn, state, *target)
10873 }
10874 _ => None,
10875 };
10876 Ok((transition, boundary))
10877 }
10878
10879 fn transition_index(
10880 &mut self,
10881 state_number: usize,
10882 transition_count: usize,
10883 precedence: i32,
10884 ) -> DirectAdaptiveParseResult<usize> {
10885 match transition_count {
10886 0 => Err(DirectAdaptiveParseControl::Fallback(
10887 DirectAdaptiveFallback::NoTransition,
10888 )),
10889 1 => Ok(0),
10890 _ => {
10891 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
10892 return Ok(alt);
10893 }
10894 let decision = self
10895 .decision_by_state
10896 .get(state_number)
10897 .and_then(|decision| *decision)
10898 .ok_or(DirectAdaptiveParseControl::Fallback(
10899 DirectAdaptiveFallback::UnknownDecision,
10900 ))?;
10901 let prediction = self
10902 .simulator
10903 .adaptive_predict_stream_info_with_precedence(
10904 decision,
10905 direct_precedence(precedence),
10906 &mut self.parser.input,
10907 )
10908 .map_err(|_| {
10909 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
10910 })?;
10911 if prediction.has_semantic_context {
10912 return Err(DirectAdaptiveParseControl::Fallback(
10913 DirectAdaptiveFallback::SemanticContext,
10914 ));
10915 }
10916 prediction
10917 .alt
10918 .checked_sub(1)
10919 .filter(|index| *index < transition_count)
10920 .ok_or(DirectAdaptiveParseControl::Fallback(
10921 DirectAdaptiveFallback::InvalidAlt,
10922 ))
10923 }
10924 }
10925 }
10926
10927 fn ll1_transition_index(
10928 &mut self,
10929 state_number: usize,
10930 transition_count: usize,
10931 ) -> DirectAdaptiveParseResult<Option<usize>> {
10932 let state = self
10933 .atn
10934 .state(state_number)
10935 .ok_or(DirectAdaptiveParseControl::Fallback(
10936 DirectAdaptiveFallback::MissingAtn,
10937 ))?;
10938 if state.precedence_rule_decision() {
10939 return Ok(None);
10940 }
10941 let Some(rule_stop) = state
10942 .rule_index()
10943 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
10944 else {
10945 return Ok(None);
10946 };
10947 let symbol = self.parser.input.la_token(1);
10948 let entry = self
10949 .parser
10950 .cached_decision_lookahead(self.atn, state, rule_stop);
10951 Ok(
10952 ll1_greedy_alt(&entry, symbol, state.non_greedy())
10953 .filter(|alt| *alt < transition_count),
10954 )
10955 }
10956
10957 fn consume_transition(
10958 &mut self,
10959 transition: ParserTransition<'_>,
10960 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
10961 let symbol = self.parser.input.la_token(1);
10962 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
10963 return Err(DirectAdaptiveParseControl::Fallback(
10964 DirectAdaptiveFallback::TokenMismatch,
10965 ));
10966 }
10967 let token = self
10968 .parser
10969 .input
10970 .lt_id(1)
10971 .ok_or(DirectAdaptiveParseControl::Fallback(
10972 DirectAdaptiveFallback::TokenMismatch,
10973 ))?;
10974 let matched_eof = symbol == TOKEN_EOF;
10975 if !matched_eof {
10976 self.parser.consume();
10977 }
10978 let child = self
10979 .parser
10980 .build_parse_trees
10981 .then(|| self.parser.terminal_tree(token));
10982 Ok((matched_eof, child))
10983 }
10984}
10985
10986fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
10989 if !state.precedence_rule_decision() {
10990 return None;
10991 }
10992 let target_state = atn.state(target)?;
10993 if target_state.kind() == AtnStateKind::LoopEnd {
10994 return None;
10995 }
10996 state.rule_index()
10997}
10998
10999fn next_alt_number(
11006 state: AtnState<'_>,
11007 transition_count: usize,
11008 transition_index: usize,
11009 current_alt_number: usize,
11010 track_alt_numbers: bool,
11011) -> usize {
11012 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
11013 return current_alt_number;
11014 }
11015 if matches!(
11016 state.kind(),
11017 AtnStateKind::Basic
11018 | AtnStateKind::BlockStart
11019 | AtnStateKind::PlusBlockStart
11020 | AtnStateKind::StarBlockStart
11021 | AtnStateKind::StarLoopEntry
11022 ) && !state.precedence_rule_decision()
11023 {
11024 return transition_index + 1;
11025 }
11026 current_alt_number
11027}
11028
11029fn invoking_state_number(state_number: usize) -> isize {
11032 isize::try_from(state_number).unwrap_or(isize::MAX)
11033}
11034
11035const fn packed_i32(value: u32) -> i32 {
11036 i32::from_le_bytes(value.to_le_bytes())
11037}
11038
11039fn direct_precedence(precedence: i32) -> usize {
11040 usize::try_from(precedence.max(0)).unwrap_or_default()
11041}
11042
11043fn token_input_display(token: &impl Token) -> String {
11044 format!("'{}'", token.text().unwrap_or("<EOF>"))
11045}
11046
11047fn display_input_text(text: &str) -> String {
11048 let mut out = String::new();
11049 for ch in text.chars() {
11050 match ch {
11051 '\n' => out.push_str("\\n"),
11052 '\r' => out.push_str("\\r"),
11053 '\t' => out.push_str("\\t"),
11054 other => out.push(other),
11055 }
11056 }
11057 out
11058}
11059
11060fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
11061 let (line, column) = token.map_or((0, 0), |token| (token.line(), token.column()));
11062 ParserDiagnostic {
11063 line,
11064 column,
11065 message,
11066 }
11067}
11068
11069#[allow(clippy::print_stderr)]
11071fn report_parser_diagnostics<'a>(diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>) {
11072 for diagnostic in diagnostics {
11073 eprintln!(
11074 "line {}:{} {}",
11075 diagnostic.line, diagnostic.column, diagnostic.message
11076 );
11077 }
11078}
11079
11080#[allow(clippy::print_stderr)]
11083fn report_generated_diagnostics(
11084 parser_diagnostics: &[ParserDiagnostic],
11085 token_errors: &[TokenSourceError],
11086) {
11087 let mut token_iter = token_errors.iter().peekable();
11094 for diagnostic in parser_diagnostics {
11095 while let Some(error) = token_iter.peek() {
11096 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
11097 eprintln!("line {}:{} {}", error.line, error.column, error.message);
11098 token_iter.next();
11099 } else {
11100 break;
11101 }
11102 }
11103 eprintln!(
11104 "line {}:{} {}",
11105 diagnostic.line, diagnostic.column, diagnostic.message
11106 );
11107 }
11108 for error in token_iter {
11109 eprintln!("line {}:{} {}", error.line, error.column, error.message);
11110 }
11111}
11112
11113#[allow(clippy::print_stderr)]
11116fn report_token_source_errors(errors: &[TokenSourceError]) {
11117 for error in errors {
11118 eprintln!("line {}:{} {}", error.line, error.column, error.message);
11119 }
11120}
11121
11122fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
11123 let items = symbols
11124 .iter()
11125 .map(|symbol| expected_symbol_display(*symbol, vocabulary))
11126 .collect::<Vec<_>>();
11127 if let [single] = items.as_slice() {
11128 return single.clone();
11129 }
11130 format!("{{{}}}", items.join(", "))
11131}
11132
11133fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
11134 if symbol == TOKEN_EOF {
11135 return "<EOF>".to_owned();
11136 }
11137 vocabulary.display_name(symbol)
11138}
11139
11140fn caller_follow_token_info_for_stream<S: TokenSource>(
11141 input: &mut CommonTokenStream<S>,
11142 index: usize,
11143) -> (i32, bool, bool) {
11144 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
11147 input.fill();
11148 }
11149 let token_type = input.token_type_at_index(index);
11150 let visible_channel = input.channel();
11151 let token = input.get(index);
11152 let is_boundary = token
11153 .as_ref()
11154 .and_then(Token::text)
11155 .is_some_and(is_caller_follow_boundary_text);
11156 let is_boundary_gap = token.as_ref().is_some_and(|token| {
11157 token.channel() != visible_channel || is_caller_follow_boundary_gap_text(token.text())
11158 });
11159 (token_type, is_boundary, is_boundary_gap)
11160}
11161
11162fn is_caller_follow_boundary_text(text: &str) -> bool {
11163 text.chars().any(|ch| ch == ';' || ch == '\n')
11164 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11165}
11166
11167fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
11168 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11169}
11170
11171fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
11175 let Some(rule_index) = state.rule_index() else {
11176 return false;
11177 };
11178 atn.rule_to_start_state()
11179 .get(rule_index)
11180 .and_then(|state_number| atn.state(state_number))
11181 .is_some_and(AtnState::left_recursive_rule)
11182}
11183
11184fn select_better_top_outcome(
11191 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
11192 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
11193 arena: &RecognitionArena,
11194) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
11195 match (first, second) {
11196 (Ok(first), Ok(second)) => {
11197 if arena.diagnostics(first.0.diagnostics).next().is_none() {
11198 Ok(first)
11199 } else {
11200 Ok(second)
11201 }
11202 }
11203 (Ok(first), Err(_)) => Ok(first),
11204 (Err(_), Ok(second)) => Ok(second),
11205 (Err(_), Err(second_expected)) => Err(second_expected),
11206 }
11207}
11208
11209fn select_best_fast_outcome(
11215 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
11216 prediction_mode: PredictionMode,
11217 caller_follow: Option<&TokenBitSet>,
11218 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
11219 arena: &RecognitionArena,
11220) -> Option<FastRecognizeOutcome> {
11221 let mut best = None;
11222 let mut best_caller_follow = None;
11223 for outcome in outcomes {
11224 if matches!(
11225 prediction_mode,
11226 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
11227 ) && outcome.diagnostics.is_empty()
11228 && let Some(follow) = caller_follow
11229 {
11230 let (token_type, is_boundary, _) = token_info_at(outcome.index);
11231 if is_boundary && follow.contains(token_type) {
11232 let replace =
11233 best_caller_follow
11234 .as_ref()
11235 .is_none_or(|existing: &FastRecognizeOutcome| {
11236 (outcome.index, outcome.consumed_eof)
11237 < (existing.index, existing.consumed_eof)
11238 });
11239 if replace {
11240 best_caller_follow = Some(outcome);
11241 }
11242 }
11243 }
11244 let Some(existing) = best else {
11245 best = Some(outcome);
11246 continue;
11247 };
11248 let outcome_position = (outcome.index, outcome.consumed_eof);
11249 let best_position = (existing.index, existing.consumed_eof);
11250 let better = match prediction_mode {
11251 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
11252 outcome_position,
11253 outcome.diagnostics,
11254 best_position,
11255 existing.diagnostics,
11256 arena,
11257 ),
11258 PredictionMode::Sll => outcome.index > existing.index,
11259 };
11260 best = Some(if better { outcome } else { existing });
11261 }
11262 let should_use_caller_follow =
11263 best_caller_follow
11264 .as_ref()
11265 .zip(best.as_ref())
11266 .is_some_and(|(candidate, selected)| {
11267 if !selected.diagnostics.is_empty() {
11268 return true;
11269 }
11270 candidate.index < selected.index
11271 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
11272 });
11273 if should_use_caller_follow {
11274 best_caller_follow
11275 } else {
11276 best
11277 }
11278}
11279
11280fn select_best_outcome(
11281 outcomes: impl Iterator<Item = RecognizeOutcome>,
11282 prediction_mode: PredictionMode,
11283 arena: &RecognitionArena,
11284) -> Option<RecognizeOutcome> {
11285 let outcomes = outcomes.collect::<Vec<_>>();
11286 let prefer_first_tie = outcomes
11287 .iter()
11288 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
11289 outcomes.into_iter().reduce(|best, outcome| {
11290 let outcome_position = (outcome.index, outcome.consumed_eof);
11291 let best_position = (best.index, best.consumed_eof);
11292 let better = match prediction_mode {
11293 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
11294 outcome_is_better(
11295 outcome_position,
11296 outcome.diagnostics,
11297 best_position,
11298 best.diagnostics,
11299 arena,
11300 ) || (!prefer_first_tie
11301 && outcome_position == best_position
11302 && arena.diagnostics_len(outcome.diagnostics)
11303 == arena.diagnostics_len(best.diagnostics)
11304 && arena.diagnostics_recovery_rank(outcome.diagnostics)
11305 == arena.diagnostics_recovery_rank(best.diagnostics)
11306 && (outcome.decisions < best.decisions
11307 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
11308 }
11309 PredictionMode::Sll => {
11310 outcome_position > best_position
11311 || (outcome_position == best_position
11312 && !prefer_first_tie
11313 && (outcome.decisions < best.decisions
11314 || (outcome.decisions == best.decisions
11315 && outcome_is_better(
11316 outcome_position,
11317 outcome.diagnostics,
11318 best_position,
11319 best.diagnostics,
11320 arena,
11321 ))))
11322 }
11323 };
11324 if better {
11325 return outcome;
11326 }
11327 best
11328 })
11329}
11330
11331fn transition_decision(
11338 atn: &Atn,
11339 state: AtnState<'_>,
11340 transition_count: usize,
11341 transition_index: usize,
11342 predicates: &[(usize, usize, ParserPredicate)],
11343) -> Option<usize> {
11344 if transition_count <= 1
11345 || state.precedence_rule_decision()
11346 || decision_reaches_unsupported_predicate(atn, state, predicates)
11347 {
11348 return None;
11349 }
11350 Some(transition_index)
11351}
11352
11353fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
11359 transition_count > 1
11360 && !matches!(
11361 state.kind(),
11362 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
11363 )
11364}
11365
11366fn record_no_viable_if_ambiguous(
11369 expected: &mut ExpectedTokens,
11370 decision_start_index: Option<usize>,
11371 index: usize,
11372) {
11373 if expected.index == Some(index) && expected.symbols.len() > 1 {
11374 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
11375 expected.record_no_viable(decision_start, index);
11376 }
11377 }
11378}
11379
11380const fn record_predicate_no_viable(
11383 expected: &mut ExpectedTokens,
11384 decision_start_index: Option<usize>,
11385 index: usize,
11386) {
11387 if let Some(decision_start) = decision_start_index {
11388 expected.record_no_viable(decision_start, index);
11389 }
11390}
11391
11392const fn no_viable_decision_start(
11394 decision_start_index: Option<usize>,
11395 index: usize,
11396) -> Option<usize> {
11397 match decision_start_index {
11398 Some(start) if index > start => Some(start),
11399 _ => None,
11400 }
11401}
11402
11403fn restore_expected(
11407 children: &[RecognizeOutcome],
11408 child_start_index: usize,
11409 expected: &mut ExpectedTokens,
11410 snapshot: ExpectedTokens,
11411 preserve_child_expected: bool,
11412) {
11413 if preserve_child_expected {
11414 return;
11415 }
11416 if children
11417 .iter()
11418 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
11419 {
11420 *expected = snapshot;
11421 }
11422}
11423
11424fn decision_reaches_unsupported_predicate(
11427 atn: &Atn,
11428 state: AtnState<'_>,
11429 predicates: &[(usize, usize, ParserPredicate)],
11430) -> bool {
11431 state.transitions().iter().any(|transition| {
11432 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
11433 })
11434}
11435
11436fn transition_reaches_unsupported_predicate(
11438 atn: &Atn,
11439 transition: ParserTransition<'_>,
11440 predicates: &[(usize, usize, ParserPredicate)],
11441 visited: &mut BTreeSet<usize>,
11442) -> bool {
11443 match &transition.data() {
11444 Transition::Predicate {
11445 rule_index,
11446 pred_index,
11447 ..
11448 } => !predicates
11449 .iter()
11450 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
11451 Transition::Epsilon { target }
11452 | Transition::Action { target, .. }
11453 | Transition::Rule { target, .. } => {
11454 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
11455 }
11456 Transition::Precedence { .. }
11457 | Transition::Atom { .. }
11458 | Transition::Range { .. }
11459 | Transition::Set { .. }
11460 | Transition::NotSet { .. }
11461 | Transition::Wildcard { .. } => false,
11462 }
11463}
11464
11465fn state_reaches_unsupported_predicate(
11467 atn: &Atn,
11468 state_number: usize,
11469 predicates: &[(usize, usize, ParserPredicate)],
11470 visited: &mut BTreeSet<usize>,
11471) -> bool {
11472 if !visited.insert(state_number) {
11473 return false;
11474 }
11475 let Some(state) = atn.state(state_number) else {
11476 return false;
11477 };
11478 state.transitions().iter().any(|transition| {
11479 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
11480 })
11481}
11482
11483fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
11485 if let Some(decision) = decision {
11486 outcome.decisions.insert(0, decision);
11487 }
11488}
11489
11490fn outcome_is_better(
11491 outcome_position: (usize, bool),
11492 outcome_diagnostics: DiagnosticSeqId,
11493 best_position: (usize, bool),
11494 best_diagnostics: DiagnosticSeqId,
11495 arena: &RecognitionArena,
11496) -> bool {
11497 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
11498 let best_len = arena.diagnostics_len(best_diagnostics);
11499 outcome_position > best_position
11500 || (outcome_position == best_position
11501 && (outcome_len < best_len
11502 || (outcome_len == best_len
11503 && arena.diagnostics_recovery_rank(outcome_diagnostics)
11504 < arena.diagnostics_recovery_rank(best_diagnostics))))
11505}
11506
11507fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
11508 if outcomes
11509 .iter()
11510 .any(|outcome| outcome.diagnostics.is_empty())
11511 {
11512 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
11513 }
11514}
11515
11516fn discard_recovered_outcomes_if_clean_path_exists(
11517 outcomes: &mut Vec<RecognizeOutcome>,
11518 arena: &RecognitionArena,
11519) {
11520 if outcomes
11521 .iter()
11522 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
11523 {
11524 return;
11525 }
11526 if outcomes
11527 .iter()
11528 .any(|outcome| outcome.diagnostics.is_empty())
11529 {
11530 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
11531 }
11532}
11533
11534fn outcome_has_rule_failure_diagnostic(
11537 outcome: &RecognizeOutcome,
11538 arena: &RecognitionArena,
11539) -> bool {
11540 arena
11541 .diagnostics(outcome.diagnostics)
11542 .any(|diagnostic| diagnostic.message.starts_with("rule "))
11543}
11544
11545fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
11559 if outcomes.len() < 2 {
11560 return;
11561 }
11562 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
11563 outcomes.retain(|outcome| {
11564 seen.insert((
11565 outcome.index,
11566 outcome.consumed_eof,
11567 arena.diagnostics_len(outcome.diagnostics),
11568 arena.diagnostics_recovery_rank(outcome.diagnostics),
11569 ))
11570 });
11571}
11572
11573const FAST_OUTCOME_INLINE_KEYS: usize = 8;
11574const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
11575const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
11576const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
11577
11578#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11579enum FastOutcomeDedupStrategy {
11580 Inline,
11581 Dense,
11582 Sparse,
11583}
11584
11585impl FastOutcomeDedupScratch {
11586 fn prepare_dense(&mut self, word_count: usize) {
11587 while let Some(word_index) = self.touched_dense_words.pop() {
11588 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
11589 }
11590 if self.dense_words.len() < word_count {
11591 self.dense_words.resize(word_count, 0);
11592 }
11593 }
11594}
11595
11596fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
11597 let first_index = outcomes.first()?.index;
11598 let (min_index, max_index) = outcomes[1..].iter().fold(
11599 (first_index, first_index),
11600 |(min_index, max_index), outcome| {
11601 (min_index.min(outcome.index), max_index.max(outcome.index))
11602 },
11603 );
11604 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
11605 let bit_count = index_span.checked_mul(2)?;
11606 let word_count =
11607 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
11608 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
11609 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
11610 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
11611 .then_some((min_index, word_count))
11612}
11613
11614#[cfg(feature = "perf-counters")]
11615fn record_clean_fast_outcome_dedup(
11616 strategy: FastOutcomeDedupStrategy,
11617 input_len: usize,
11618 output_len: usize,
11619 dense_words: usize,
11620) {
11621 let counter = match strategy {
11622 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
11623 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
11624 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
11625 };
11626 perf_counters::inc(
11627 &perf_counters::OUTCOME_DEDUPE_INPUTS,
11628 u64::try_from(input_len).unwrap_or(u64::MAX),
11629 );
11630 perf_counters::inc(
11631 &perf_counters::OUTCOME_DEDUPE_REMOVED,
11632 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
11633 );
11634 perf_counters::inc(counter, 1);
11635 perf_counters::inc(
11636 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
11637 u64::try_from(dense_words).unwrap_or(u64::MAX),
11638 );
11639}
11640
11641fn dedupe_clean_fast_outcomes(
11645 outcomes: &mut Vec<FastRecognizeOutcome>,
11646 scratch: &mut FastOutcomeDedupScratch,
11647) -> FastOutcomeDedupStrategy {
11648 #[cfg(feature = "perf-counters")]
11649 let input_len = outcomes.len();
11650 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
11651 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
11652 let mut inline_len = 0_usize;
11653 outcomes.retain(|outcome| {
11654 let key = (outcome.index, outcome.consumed_eof);
11655 if inline_keys[..inline_len].contains(&key) {
11656 return false;
11657 }
11658 inline_keys[inline_len] = key;
11659 inline_len += 1;
11660 true
11661 });
11662 #[cfg(feature = "perf-counters")]
11663 record_clean_fast_outcome_dedup(
11664 FastOutcomeDedupStrategy::Inline,
11665 input_len,
11666 outcomes.len(),
11667 0,
11668 );
11669 return FastOutcomeDedupStrategy::Inline;
11670 }
11671
11672 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
11673 scratch.prepare_dense(word_count);
11674 outcomes.retain(|outcome| {
11675 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
11676 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
11677 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
11678 let word = &mut scratch.dense_words[word_index];
11679 if *word & bit != 0 {
11680 return false;
11681 }
11682 if *word == 0 {
11683 scratch
11684 .touched_dense_words
11685 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
11686 }
11687 *word |= bit;
11688 true
11689 });
11690 #[cfg(feature = "perf-counters")]
11691 record_clean_fast_outcome_dedup(
11692 FastOutcomeDedupStrategy::Dense,
11693 input_len,
11694 outcomes.len(),
11695 word_count,
11696 );
11697 return FastOutcomeDedupStrategy::Dense;
11698 }
11699
11700 scratch.sparse_keys.clear();
11701 scratch.sparse_keys.reserve(outcomes.len());
11702 outcomes.retain(|outcome| {
11703 scratch
11704 .sparse_keys
11705 .insert((outcome.index, outcome.consumed_eof))
11706 });
11707 #[cfg(feature = "perf-counters")]
11708 record_clean_fast_outcome_dedup(
11709 FastOutcomeDedupStrategy::Sparse,
11710 input_len,
11711 outcomes.len(),
11712 0,
11713 );
11714 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
11715 scratch.sparse_keys = FxHashSet::default();
11716 }
11717 FastOutcomeDedupStrategy::Sparse
11718}
11719
11720fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
11723 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
11724 outcomes
11725 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
11726}
11727
11728fn compare_recognize_outcomes(
11729 left: &RecognizeOutcome,
11730 right: &RecognizeOutcome,
11731 arena: &RecognitionArena,
11732) -> Ordering {
11733 left.index
11734 .cmp(&right.index)
11735 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
11736 .then_with(|| left.alt_number.cmp(&right.alt_number))
11737 .then_with(|| left.member_values.cmp(&right.member_values))
11738 .then_with(|| left.return_values.cmp(&right.return_values))
11739 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
11740 .then_with(|| left.decisions.cmp(&right.decisions))
11741 .then_with(|| left.actions.cmp(&right.actions))
11742 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
11743}
11744
11745impl<S, H> Recognizer for BaseParser<S, H>
11746where
11747 S: TokenSource,
11748 H: SemanticHooks,
11749{
11750 fn data(&self) -> &RecognizerData {
11751 &self.data
11752 }
11753
11754 fn data_mut(&mut self) -> &mut RecognizerData {
11755 &mut self.data
11756 }
11757}
11758
11759impl<S, H> Parser for BaseParser<S, H>
11760where
11761 S: TokenSource,
11762 H: SemanticHooks,
11763{
11764 fn build_parse_trees(&self) -> bool {
11765 self.build_parse_trees
11766 }
11767
11768 fn set_build_parse_trees(&mut self, build: bool) {
11769 self.build_parse_trees = build;
11770 }
11771
11772 fn number_of_syntax_errors(&self) -> usize {
11773 Self::number_of_syntax_errors(self)
11774 }
11775
11776 fn report_diagnostic_errors(&self) -> bool {
11777 self.report_diagnostic_errors
11778 }
11779
11780 fn set_report_diagnostic_errors(&mut self, report: bool) {
11781 self.report_diagnostic_errors = report;
11782 }
11783
11784 fn prediction_mode(&self) -> PredictionMode {
11785 self.prediction_mode
11786 }
11787
11788 fn set_prediction_mode(&mut self, mode: PredictionMode) {
11789 self.prediction_mode = mode;
11790 }
11791}
11792
11793#[cfg(test)]
11794mod tests {
11795 use super::*;
11796 use crate::atn::parser::{
11797 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
11798 };
11799 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
11800 use crate::token::{HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError};
11801 use crate::token_stream::CommonTokenStream;
11802 use crate::tree::{NodeKind, ParseTreeStats};
11803 use crate::vocabulary::Vocabulary;
11804 use std::mem::size_of;
11805
11806 #[test]
11807 fn fx_hasher_write_matches_typed_methods_for_full_words() {
11808 let value: u64 = 0x0102_0304_0506_0708;
11815 let mut typed = FxHasher::default();
11816 typed.write_u64(value);
11817 let mut bytewise = FxHasher::default();
11818 bytewise.write(&value.to_le_bytes());
11819 assert_eq!(typed.finish(), bytewise.finish());
11820 }
11821
11822 #[derive(Clone, Debug)]
11823 struct TestToken {
11824 spec: TokenSpec,
11825 id: TokenId,
11826 source_name: String,
11827 }
11828
11829 impl TestToken {
11830 fn new(token_type: i32) -> Self {
11831 Self {
11832 spec: TokenSpec::explicit(token_type, ""),
11833 id: TokenId::try_from(0).expect("zero token ID"),
11834 source_name: String::new(),
11835 }
11836 }
11837
11838 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
11839 Self {
11840 spec: TokenSpec::eof(index, index, line, column),
11841 id: TokenId::try_from(0).expect("zero token ID"),
11842 source_name: source_name.to_owned(),
11843 }
11844 }
11845
11846 fn with_text(mut self, text: impl Into<String>) -> Self {
11847 self.spec.text = Some(text.into());
11848 self
11849 }
11850
11851 const fn with_channel(mut self, channel: i32) -> Self {
11852 self.spec.channel = channel;
11853 self
11854 }
11855
11856 const fn with_span(mut self, start: usize, stop: usize) -> Self {
11857 self.spec.start = start;
11858 self.spec.stop = stop;
11859 self.spec.start_byte = start;
11860 self.spec.stop_byte = match stop.checked_add(1) {
11861 Some(end) if end >= start => end,
11862 Some(_) | None => start,
11863 };
11864 self
11865 }
11866
11867 const fn with_position(mut self, line: usize, column: usize) -> Self {
11868 self.spec.line = line;
11869 self.spec.column = column;
11870 self
11871 }
11872
11873 fn set_token_index(&mut self, index: isize) {
11874 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
11875 }
11876 }
11877
11878 impl Token for TestToken {
11879 fn token_id(&self) -> TokenId {
11880 self.id
11881 }
11882
11883 fn token_type(&self) -> i32 {
11884 self.spec.token_type
11885 }
11886
11887 fn channel(&self) -> i32 {
11888 self.spec.channel
11889 }
11890
11891 fn start(&self) -> usize {
11892 self.spec.start
11893 }
11894
11895 fn stop(&self) -> usize {
11896 self.spec.stop
11897 }
11898
11899 fn line(&self) -> usize {
11900 self.spec.line
11901 }
11902
11903 fn column(&self) -> usize {
11904 self.spec.column
11905 }
11906
11907 fn text(&self) -> Option<&str> {
11908 self.spec.text.as_deref()
11909 }
11910
11911 fn source_name(&self) -> &str {
11912 &self.source_name
11913 }
11914
11915 fn start_byte(&self) -> usize {
11916 self.spec.start_byte
11917 }
11918
11919 fn stop_byte(&self) -> usize {
11920 self.spec.stop_byte
11921 }
11922 }
11923
11924 #[derive(Debug)]
11925 struct Source {
11926 tokens: Vec<TestToken>,
11927 index: usize,
11928 }
11929
11930 impl TokenSource for Source {
11931 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
11932 let token = self
11933 .tokens
11934 .get(self.index)
11935 .cloned()
11936 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
11937 self.index += 1;
11938 sink.push(token.spec)
11939 }
11940
11941 fn line(&self) -> usize {
11942 1
11943 }
11944
11945 fn column(&self) -> usize {
11946 self.index
11947 }
11948
11949 fn source_name(&self) -> &'static str {
11950 "parser-test"
11951 }
11952 }
11953
11954 fn mini_parser_data() -> RecognizerData {
11955 RecognizerData::new(
11956 "Mini.g4",
11957 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
11958 )
11959 .with_rule_names(["s"])
11960 }
11961
11962 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
11963 let data = mini_parser_data();
11964 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
11965 }
11966
11967 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
11968 where
11969 H: SemanticHooks,
11970 {
11971 BaseParser::with_semantic_hooks(
11972 CommonTokenStream::new(Source { tokens, index: 0 }),
11973 mini_parser_data(),
11974 hooks,
11975 )
11976 }
11977
11978 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
11979 builder.finish().expect("valid packed parser ATN")
11980 }
11981
11982 fn ordinary_star_loop_atn() -> Atn {
11983 let mut atn = ParserAtnBuilder::new(2);
11984 for (state_number, kind, rule_index) in [
11985 (0, AtnStateKind::RuleStart, 0),
11986 (1, AtnStateKind::StarLoopEntry, 0),
11987 (2, AtnStateKind::Basic, 0),
11988 (3, AtnStateKind::StarLoopBack, 0),
11989 (4, AtnStateKind::LoopEnd, 0),
11990 (5, AtnStateKind::Basic, 0),
11991 (6, AtnStateKind::RuleStop, 0),
11992 (7, AtnStateKind::RuleStart, 1),
11993 (8, AtnStateKind::Basic, 1),
11994 (9, AtnStateKind::RuleStop, 1),
11995 ] {
11996 assert_eq!(
11997 atn.add_state(kind, Some(rule_index))
11998 .expect("state")
11999 .index(),
12000 state_number
12001 );
12002 }
12003 atn.set_rule_to_start_state(vec![0, 7])
12004 .expect("rule start states");
12005 atn.set_rule_to_stop_state(vec![6, 9])
12006 .expect("rule stop states");
12007 atn.add_decision_state(1).expect("decision state");
12008 atn.set_loop_back_state(4, 3).expect("loop back state");
12009 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12010 .expect("transition");
12011 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12012 .expect("transition");
12013 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
12014 .expect("transition");
12015 atn.add_transition(
12016 2,
12017 ParserTransitionSpec::Rule {
12018 target: 7,
12019 rule_index: 1,
12020 follow_state: 3,
12021 precedence: 0,
12022 },
12023 )
12024 .expect("transition");
12025 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
12026 .expect("transition");
12027 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12028 .expect("transition");
12029 atn.add_transition(
12030 5,
12031 ParserTransitionSpec::Atom {
12032 target: 6,
12033 label: TOKEN_EOF,
12034 },
12035 )
12036 .expect("transition");
12037 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
12038 .expect("transition");
12039 atn.add_transition(
12040 8,
12041 ParserTransitionSpec::Atom {
12042 target: 9,
12043 label: 1,
12044 },
12045 )
12046 .expect("transition");
12047 finish_atn(atn)
12048 }
12049
12050 fn ambiguous_ordinary_star_loop_atn() -> Atn {
12052 let mut atn = ParserAtnBuilder::new(1);
12053 for (state_number, kind) in [
12054 (0, AtnStateKind::RuleStart),
12055 (1, AtnStateKind::StarLoopEntry),
12056 (2, AtnStateKind::StarBlockStart),
12057 (3, AtnStateKind::Basic),
12058 (4, AtnStateKind::BlockEnd),
12059 (5, AtnStateKind::StarLoopBack),
12060 (6, AtnStateKind::LoopEnd),
12061 (7, AtnStateKind::Basic),
12062 (8, AtnStateKind::RuleStop),
12063 ] {
12064 assert_eq!(
12065 atn.add_state(kind, Some(0)).expect("state").index(),
12066 state_number
12067 );
12068 }
12069 atn.set_rule_to_start_state(vec![0])
12070 .expect("rule start states");
12071 atn.set_rule_to_stop_state(vec![8])
12072 .expect("rule stop states");
12073 atn.set_end_state(2, 4).expect("block end state");
12074 atn.set_loop_back_state(6, 5).expect("loop back state");
12075 atn.add_decision_state(1).expect("decision state");
12076 atn.add_decision_state(2).expect("decision state");
12077 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12078 .expect("transition");
12079 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12080 .expect("transition");
12081 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
12082 .expect("transition");
12083 atn.add_transition(
12084 2,
12085 ParserTransitionSpec::Atom {
12086 target: 4,
12087 label: 1,
12088 },
12089 )
12090 .expect("transition");
12091 atn.add_transition(
12092 2,
12093 ParserTransitionSpec::Atom {
12094 target: 3,
12095 label: 1,
12096 },
12097 )
12098 .expect("transition");
12099 atn.add_transition(
12100 3,
12101 ParserTransitionSpec::Atom {
12102 target: 4,
12103 label: 1,
12104 },
12105 )
12106 .expect("transition");
12107 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12108 .expect("transition");
12109 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
12110 .expect("transition");
12111 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12112 .expect("transition");
12113 atn.add_transition(
12114 7,
12115 ParserTransitionSpec::Atom {
12116 target: 8,
12117 label: TOKEN_EOF,
12118 },
12119 )
12120 .expect("transition");
12121 finish_atn(atn)
12122 }
12123
12124 fn ordinary_plus_loop_atn() -> Atn {
12125 let mut atn = ParserAtnBuilder::new(2);
12126 for (state_number, kind, rule_index) in [
12127 (0, AtnStateKind::RuleStart, 0),
12128 (1, AtnStateKind::Basic, 0),
12129 (2, AtnStateKind::PlusLoopBack, 0),
12130 (3, AtnStateKind::LoopEnd, 0),
12131 (4, AtnStateKind::Basic, 0),
12132 (5, AtnStateKind::RuleStop, 0),
12133 (6, AtnStateKind::RuleStart, 1),
12134 (7, AtnStateKind::Basic, 1),
12135 (8, AtnStateKind::RuleStop, 1),
12136 ] {
12137 assert_eq!(
12138 atn.add_state(kind, Some(rule_index))
12139 .expect("state")
12140 .index(),
12141 state_number
12142 );
12143 }
12144 atn.set_rule_to_start_state(vec![0, 6])
12145 .expect("rule start states");
12146 atn.set_rule_to_stop_state(vec![5, 8])
12147 .expect("rule stop states");
12148 atn.add_decision_state(2).expect("decision state");
12149 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12150 .expect("transition");
12151 atn.add_transition(
12152 1,
12153 ParserTransitionSpec::Rule {
12154 target: 6,
12155 rule_index: 1,
12156 follow_state: 2,
12157 precedence: 0,
12158 },
12159 )
12160 .expect("transition");
12161 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
12162 .expect("transition");
12163 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12164 .expect("transition");
12165 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
12166 .expect("transition");
12167 atn.add_transition(
12168 4,
12169 ParserTransitionSpec::Atom {
12170 target: 5,
12171 label: TOKEN_EOF,
12172 },
12173 )
12174 .expect("transition");
12175 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12176 .expect("transition");
12177 atn.add_transition(
12178 7,
12179 ParserTransitionSpec::Atom {
12180 target: 8,
12181 label: 1,
12182 },
12183 )
12184 .expect("transition");
12185 finish_atn(atn)
12186 }
12187
12188 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
12189 let mut tokens = (0..count)
12190 .map(|_| TestToken::new(1).with_text("x"))
12191 .collect::<Vec<_>>();
12192 tokens.push(TestToken::eof("parser-test", count, 1, count));
12193 tokens
12194 }
12195
12196 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
12197 let mut atn = ParserAtnBuilder::new(2);
12198 assert_eq!(
12199 atn.add_state(AtnStateKind::RuleStart, Some(0))
12200 .expect("state")
12201 .index(),
12202 0
12203 );
12204 assert_eq!(
12205 atn.add_state(AtnStateKind::Basic, Some(0))
12206 .expect("state")
12207 .index(),
12208 1
12209 );
12210 assert_eq!(
12211 atn.add_state(AtnStateKind::Basic, Some(0))
12212 .expect("state")
12213 .index(),
12214 2
12215 );
12216 assert_eq!(
12217 atn.add_state(AtnStateKind::RuleStart, Some(1))
12218 .expect("state")
12219 .index(),
12220 3
12221 );
12222 atn.set_left_recursive_rule(3)
12223 .expect("left-recursive rule start");
12224 assert_eq!(
12225 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
12226 .expect("state")
12227 .index(),
12228 4
12229 );
12230 atn.set_precedence_rule_decision(4)
12231 .expect("precedence decision");
12232 assert_eq!(
12233 atn.add_state(AtnStateKind::Basic, Some(1))
12234 .expect("state")
12235 .index(),
12236 5
12237 );
12238 assert_eq!(
12239 atn.add_state(AtnStateKind::Basic, Some(1))
12240 .expect("state")
12241 .index(),
12242 6
12243 );
12244 assert_eq!(
12245 atn.add_state(AtnStateKind::LoopEnd, Some(1))
12246 .expect("state")
12247 .index(),
12248 7
12249 );
12250 assert_eq!(
12251 atn.add_state(AtnStateKind::RuleStop, Some(1))
12252 .expect("state")
12253 .index(),
12254 8
12255 );
12256 assert_eq!(
12257 atn.add_state(AtnStateKind::RuleStop, Some(0))
12258 .expect("state")
12259 .index(),
12260 9
12261 );
12262 atn.set_rule_to_start_state(vec![0, 3])
12263 .expect("rule start states");
12264 atn.set_rule_to_stop_state(vec![9, 8])
12265 .expect("rule stop states");
12266 atn.add_transition(
12267 1,
12268 ParserTransitionSpec::Rule {
12269 target: 3,
12270 rule_index: 1,
12271 follow_state: 2,
12272 precedence: 0,
12273 },
12274 )
12275 .expect("transition");
12276 atn.add_transition(
12277 2,
12278 ParserTransitionSpec::Atom {
12279 target: 9,
12280 label: caller_symbol,
12281 },
12282 )
12283 .expect("transition");
12284 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12285 .expect("transition");
12286 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
12287 .expect("transition");
12288 atn.add_transition(
12289 5,
12290 ParserTransitionSpec::Precedence {
12291 target: 6,
12292 precedence: 1,
12293 },
12294 )
12295 .expect("transition");
12296 atn.add_transition(
12297 6,
12298 ParserTransitionSpec::Atom {
12299 target: 4,
12300 label: 1,
12301 },
12302 )
12303 .expect("transition");
12304 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
12305 .expect("transition");
12306 finish_atn(atn)
12307 }
12308
12309 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
12310 let mut parser = mini_parser(vec![
12311 TestToken::new(symbol).with_text("lookahead"),
12312 TestToken::eof("parser-test", 1, 1, 1),
12313 ]);
12314 parser.rule_context_stack = vec![
12315 RuleContextFrame {
12316 rule_index: 0,
12317 invoking_state: -1,
12318 },
12319 RuleContextFrame {
12320 rule_index: 1,
12321 invoking_state: 1,
12322 },
12323 ];
12324 parser
12325 }
12326
12327 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
12328 let mut atn = ParserAtnBuilder::new(1);
12332 for (state, kind, rule) in [
12333 (0, AtnStateKind::RuleStart, 0),
12334 (1, AtnStateKind::StarLoopEntry, 0),
12335 (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),
12342 (9, AtnStateKind::RuleStop, 0),
12343 ] {
12344 assert_eq!(
12345 atn.add_state(kind, Some(rule)).expect("state").index(),
12346 state
12347 );
12348 if state == 0 {
12349 atn.set_left_recursive_rule(state)
12350 .expect("left-recursive rule start");
12351 } else if state == 1 {
12352 atn.set_precedence_rule_decision(state)
12353 .expect("precedence decision");
12354 }
12355 }
12356 atn.set_rule_to_start_state(vec![0])
12357 .expect("rule start states");
12358 atn.set_rule_to_stop_state(vec![9])
12359 .expect("rule stop states");
12360 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12361 .expect("ops");
12362 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
12363 .expect("exit");
12364 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12365 .expect("to shift");
12366 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
12367 .expect("to rel");
12368 atn.add_transition(
12369 3,
12370 ParserTransitionSpec::Precedence {
12371 target: 4,
12372 precedence: 2,
12373 },
12374 )
12375 .expect("shift prec");
12376 atn.add_transition(
12377 4,
12378 ParserTransitionSpec::Atom {
12379 target: 5,
12380 label: 1,
12381 },
12382 )
12383 .expect("shift first >");
12384 atn.add_transition(
12385 5,
12386 ParserTransitionSpec::Atom {
12387 target: 1,
12388 label: 1,
12389 },
12390 )
12391 .expect("shift second >");
12392 atn.add_transition(
12393 6,
12394 ParserTransitionSpec::Precedence {
12395 target: 7,
12396 precedence: 1,
12397 },
12398 )
12399 .expect("rel prec");
12400 atn.add_transition(
12401 7,
12402 ParserTransitionSpec::Atom {
12403 target: 1,
12404 label: 1,
12405 },
12406 )
12407 .expect("rel >");
12408 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
12409 .expect("loop end");
12410 finish_atn(atn)
12411 }
12412
12413 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
12414 let mut atn = ParserAtnBuilder::new(2);
12415 for (state, kind, rule) in [
12416 (0, AtnStateKind::RuleStart, 0),
12417 (1, AtnStateKind::StarLoopEntry, 0),
12418 (2, AtnStateKind::Basic, 0),
12419 (3, AtnStateKind::Basic, 0),
12420 (4, AtnStateKind::Basic, 0),
12421 (5, AtnStateKind::Basic, 0),
12422 (6, AtnStateKind::Basic, 0),
12423 (7, AtnStateKind::Basic, 0),
12424 (8, AtnStateKind::LoopEnd, 0),
12425 (9, AtnStateKind::RuleStop, 0),
12426 (10, AtnStateKind::RuleStart, 1),
12427 (11, AtnStateKind::Basic, 1),
12428 (12, AtnStateKind::RuleStop, 1),
12429 ] {
12430 assert_eq!(
12431 atn.add_state(kind, Some(rule)).expect("state").index(),
12432 state
12433 );
12434 if state == 0 {
12435 atn.set_left_recursive_rule(state)
12436 .expect("left-recursive rule start");
12437 } else if state == 1 {
12438 atn.set_precedence_rule_decision(state)
12439 .expect("precedence decision");
12440 }
12441 }
12442 atn.set_rule_to_start_state(vec![0, 10])
12443 .expect("rule start states");
12444 atn.set_rule_to_stop_state(vec![9, 12])
12445 .expect("rule stop states");
12446 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12447 .expect("ops");
12448 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
12449 .expect("exit");
12450 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12451 .expect("to shift");
12452 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
12453 .expect("to relational");
12454 atn.add_transition(
12455 3,
12456 ParserTransitionSpec::Precedence {
12457 target: 4,
12458 precedence: 2,
12459 },
12460 )
12461 .expect("shift precedence");
12462 atn.add_transition(
12463 4,
12464 ParserTransitionSpec::Rule {
12465 target: 10,
12466 rule_index: 1,
12467 follow_state: 5,
12468 precedence: 0,
12469 },
12470 )
12471 .expect("first shift token helper");
12472 atn.add_transition(
12473 5,
12474 ParserTransitionSpec::Atom {
12475 target: 1,
12476 label: 1,
12477 },
12478 )
12479 .expect("second shift token");
12480 atn.add_transition(
12481 6,
12482 ParserTransitionSpec::Precedence {
12483 target: 7,
12484 precedence: 1,
12485 },
12486 )
12487 .expect("relational precedence");
12488 atn.add_transition(
12489 7,
12490 ParserTransitionSpec::Atom {
12491 target: 1,
12492 label: 1,
12493 },
12494 )
12495 .expect("relational token");
12496 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
12497 .expect("loop end");
12498 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
12499 .expect("helper entry");
12500 atn.add_transition(
12501 11,
12502 ParserTransitionSpec::Atom {
12503 target: 12,
12504 label: 1,
12505 },
12506 )
12507 .expect("first shift token");
12508 finish_atn(atn)
12509 }
12510
12511 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
12512 let mut atn = ParserAtnBuilder::new(1);
12513 for (state, kind) in [
12514 (0, AtnStateKind::RuleStart),
12515 (1, AtnStateKind::StarLoopEntry),
12516 (2, AtnStateKind::Basic),
12517 (3, AtnStateKind::Basic),
12518 (4, AtnStateKind::Basic),
12519 (5, AtnStateKind::Basic),
12520 (6, AtnStateKind::Basic),
12521 (7, AtnStateKind::Basic),
12522 (8, AtnStateKind::Basic),
12523 (9, AtnStateKind::LoopEnd),
12524 (10, AtnStateKind::RuleStop),
12525 ] {
12526 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
12527 if state == 0 {
12528 atn.set_left_recursive_rule(state)
12529 .expect("left-recursive rule start");
12530 } else if state == 1 {
12531 atn.set_precedence_rule_decision(state)
12532 .expect("precedence decision");
12533 }
12534 }
12535 atn.set_rule_to_start_state(vec![0])
12536 .expect("rule start states");
12537 atn.set_rule_to_stop_state(vec![10])
12538 .expect("rule stop states");
12539 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12540 .expect("ops");
12541 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
12542 .expect("exit");
12543 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12544 .expect("to multi-token operator");
12545 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
12546 .expect("to predicate operator");
12547 atn.add_transition(
12548 3,
12549 ParserTransitionSpec::Precedence {
12550 target: 4,
12551 precedence: 2,
12552 },
12553 )
12554 .expect("multi-token precedence");
12555 atn.add_transition(
12556 4,
12557 ParserTransitionSpec::Atom {
12558 target: 5,
12559 label: 1,
12560 },
12561 )
12562 .expect("multi-token first");
12563 atn.add_transition(
12564 5,
12565 ParserTransitionSpec::Atom {
12566 target: 1,
12567 label: 1,
12568 },
12569 )
12570 .expect("multi-token second");
12571 atn.add_transition(
12572 6,
12573 ParserTransitionSpec::Precedence {
12574 target: 7,
12575 precedence: 2,
12576 },
12577 )
12578 .expect("predicate precedence");
12579 atn.add_transition(
12580 7,
12581 ParserTransitionSpec::Predicate {
12582 target: 8,
12583 rule_index: 0,
12584 pred_index: 0,
12585 context_dependent: false,
12586 },
12587 )
12588 .expect("operator predicate");
12589 atn.add_transition(
12590 8,
12591 ParserTransitionSpec::Atom {
12592 target: 1,
12593 label: 1,
12594 },
12595 )
12596 .expect("predicate single token");
12597 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
12598 .expect("loop end");
12599 finish_atn(atn)
12600 }
12601
12602 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
12603 let mut atn = ParserAtnBuilder::new(2);
12604 for (state, kind, rule) in [
12605 (0, AtnStateKind::RuleStart, 0),
12606 (1, AtnStateKind::StarLoopEntry, 0),
12607 (2, AtnStateKind::Basic, 0),
12608 (3, AtnStateKind::Basic, 0),
12609 (4, AtnStateKind::Basic, 0),
12610 (5, AtnStateKind::LoopEnd, 0),
12611 (6, AtnStateKind::RuleStop, 0),
12612 (7, AtnStateKind::RuleStart, 1),
12613 (8, AtnStateKind::RuleStop, 1),
12614 (9, AtnStateKind::Basic, 1),
12615 ] {
12616 assert_eq!(
12617 atn.add_state(kind, Some(rule)).expect("state").index(),
12618 state
12619 );
12620 if state == 0 {
12621 atn.set_left_recursive_rule(state)
12622 .expect("left-recursive rule start");
12623 } else if state == 1 {
12624 atn.set_precedence_rule_decision(state)
12625 .expect("precedence decision");
12626 }
12627 }
12628 atn.set_rule_to_start_state(vec![0, 7])
12629 .expect("rule start states");
12630 atn.set_rule_to_stop_state(vec![6, 8])
12631 .expect("rule stop states");
12632 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12633 .expect("transition");
12634 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
12635 .expect("transition");
12636 atn.add_transition(
12637 2,
12638 ParserTransitionSpec::Precedence {
12639 target: 3,
12640 precedence: 3,
12641 },
12642 )
12643 .expect("transition");
12644 atn.add_transition(
12645 3,
12646 ParserTransitionSpec::Rule {
12647 target: 7,
12648 rule_index: 1,
12649 follow_state: 4,
12650 precedence: 0,
12651 },
12652 )
12653 .expect("transition");
12654 atn.add_transition(
12655 4,
12656 ParserTransitionSpec::Atom {
12657 target: 1,
12658 label: 1,
12659 },
12660 )
12661 .expect("transition");
12662 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
12663 .expect("transition");
12664 atn.add_transition(
12665 7,
12666 ParserTransitionSpec::Precedence {
12667 target: 9,
12668 precedence: 1,
12669 },
12670 )
12671 .expect("transition");
12672 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
12673 .expect("transition");
12674 finish_atn(atn)
12675 }
12676
12677 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
12678 let mut atn = ParserAtnBuilder::new(2);
12679 for (state, kind) in [
12680 (0, AtnStateKind::RuleStart),
12681 (1, AtnStateKind::StarLoopEntry),
12682 (2, AtnStateKind::Basic),
12683 (3, AtnStateKind::Basic),
12684 (4, AtnStateKind::Basic),
12685 (5, AtnStateKind::LoopEnd),
12686 (6, AtnStateKind::RuleStop),
12687 ] {
12688 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
12689 if state == 0 {
12690 atn.set_left_recursive_rule(state)
12691 .expect("left-recursive rule start");
12692 } else if state == 1 {
12693 atn.set_precedence_rule_decision(state)
12694 .expect("precedence decision");
12695 }
12696 }
12697 atn.set_rule_to_start_state(vec![0])
12698 .expect("rule start states");
12699 atn.set_rule_to_stop_state(vec![6])
12700 .expect("rule stop states");
12701 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12702 .expect("transition");
12703 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
12704 .expect("transition");
12705 atn.add_transition(
12706 2,
12707 ParserTransitionSpec::Precedence {
12708 target: 3,
12709 precedence: 1,
12710 },
12711 )
12712 .expect("transition");
12713 atn.add_transition(
12714 3,
12715 ParserTransitionSpec::Predicate {
12716 target: 4,
12717 rule_index: 0,
12718 pred_index: 0,
12719 context_dependent: false,
12720 },
12721 )
12722 .expect("transition");
12723 atn.add_transition(
12724 4,
12725 ParserTransitionSpec::Atom {
12726 target: 1,
12727 label: 1,
12728 },
12729 )
12730 .expect("transition");
12731 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
12732 .expect("transition");
12733 finish_atn(atn)
12734 }
12735
12736 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
12737 let mut atn = ParserAtnBuilder::new(2);
12738 for (state, kind, rule) in [
12739 (0, AtnStateKind::RuleStart, 0),
12740 (1, AtnStateKind::Basic, 0),
12741 (2, AtnStateKind::Basic, 0),
12742 (3, AtnStateKind::Basic, 0),
12743 (4, AtnStateKind::RuleStop, 0),
12744 (5, AtnStateKind::RuleStart, 1),
12745 (6, AtnStateKind::StarLoopEntry, 1),
12746 (7, AtnStateKind::Basic, 1),
12747 (8, AtnStateKind::Basic, 1),
12748 (9, AtnStateKind::LoopEnd, 1),
12749 (10, AtnStateKind::RuleStop, 1),
12750 (11, AtnStateKind::RuleStart, 2),
12751 (12, AtnStateKind::RuleStop, 2),
12752 ] {
12753 assert_eq!(
12754 atn.add_state(kind, Some(rule)).expect("state").index(),
12755 state
12756 );
12757 if state == 5 {
12758 atn.set_left_recursive_rule(state)
12759 .expect("left-recursive rule start");
12760 } else if state == 6 {
12761 atn.set_precedence_rule_decision(state)
12762 .expect("precedence decision");
12763 }
12764 }
12765 atn.set_rule_to_start_state(vec![0, 5, 11])
12766 .expect("rule start states");
12767 atn.set_rule_to_stop_state(vec![4, 10, 12])
12768 .expect("rule stop states");
12769 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12770 .expect("transition");
12771 atn.add_transition(
12772 1,
12773 ParserTransitionSpec::Rule {
12774 target: 5,
12775 rule_index: 1,
12776 follow_state: 2,
12777 precedence: 0,
12778 },
12779 )
12780 .expect("transition");
12781 atn.add_transition(
12782 2,
12783 ParserTransitionSpec::Rule {
12784 target: 11,
12785 rule_index: 2,
12786 follow_state: 3,
12787 precedence: 0,
12788 },
12789 )
12790 .expect("transition");
12791 atn.add_transition(
12792 3,
12793 ParserTransitionSpec::Atom {
12794 target: 4,
12795 label: caller_symbol,
12796 },
12797 )
12798 .expect("transition");
12799 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12800 .expect("transition");
12801 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
12802 .expect("transition");
12803 atn.add_transition(
12804 7,
12805 ParserTransitionSpec::Precedence {
12806 target: 8,
12807 precedence: 1,
12808 },
12809 )
12810 .expect("transition");
12811 atn.add_transition(
12812 8,
12813 ParserTransitionSpec::Atom {
12814 target: 6,
12815 label: 1,
12816 },
12817 )
12818 .expect("transition");
12819 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
12820 .expect("transition");
12821 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
12822 .expect("transition");
12823 finish_atn(atn)
12824 }
12825
12826 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
12827 let mut atn = ParserAtnBuilder::new(2);
12828 for (state, kind, rule) in [
12829 (0, AtnStateKind::RuleStart, 0),
12830 (1, AtnStateKind::Basic, 0),
12831 (2, AtnStateKind::Basic, 0),
12832 (3, AtnStateKind::RuleStop, 0),
12833 (4, AtnStateKind::RuleStart, 1),
12834 (5, AtnStateKind::Basic, 1),
12835 (6, AtnStateKind::Basic, 1),
12836 (7, AtnStateKind::RuleStop, 1),
12837 (8, AtnStateKind::RuleStart, 2),
12838 (9, AtnStateKind::StarLoopEntry, 2),
12839 (10, AtnStateKind::Basic, 2),
12840 (11, AtnStateKind::Basic, 2),
12841 (12, AtnStateKind::LoopEnd, 2),
12842 (13, AtnStateKind::RuleStop, 2),
12843 ] {
12844 assert_eq!(
12845 atn.add_state(kind, Some(rule)).expect("state").index(),
12846 state
12847 );
12848 if state == 8 {
12849 atn.set_left_recursive_rule(state)
12850 .expect("left-recursive rule start");
12851 } else if state == 9 {
12852 atn.set_precedence_rule_decision(state)
12853 .expect("precedence decision");
12854 }
12855 }
12856 atn.set_rule_to_start_state(vec![0, 4, 8])
12857 .expect("rule start states");
12858 atn.set_rule_to_stop_state(vec![3, 7, 13])
12859 .expect("rule stop states");
12860 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12861 .expect("transition");
12862 atn.add_transition(
12863 1,
12864 ParserTransitionSpec::Rule {
12865 target: 4,
12866 rule_index: 1,
12867 follow_state: 2,
12868 precedence: 0,
12869 },
12870 )
12871 .expect("transition");
12872 atn.add_transition(
12873 2,
12874 ParserTransitionSpec::Atom {
12875 target: 3,
12876 label: caller_symbol,
12877 },
12878 )
12879 .expect("transition");
12880 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12881 .expect("transition");
12882 atn.add_transition(
12883 5,
12884 ParserTransitionSpec::Rule {
12885 target: 8,
12886 rule_index: 2,
12887 follow_state: 6,
12888 precedence: 0,
12889 },
12890 )
12891 .expect("transition");
12892 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12893 .expect("transition");
12894 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
12895 .expect("transition");
12896 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
12897 .expect("transition");
12898 atn.add_transition(
12899 10,
12900 ParserTransitionSpec::Precedence {
12901 target: 11,
12902 precedence: 1,
12903 },
12904 )
12905 .expect("transition");
12906 atn.add_transition(
12907 11,
12908 ParserTransitionSpec::Atom {
12909 target: 9,
12910 label: 1,
12911 },
12912 )
12913 .expect("transition");
12914 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
12915 .expect("transition");
12916 finish_atn(atn)
12917 }
12918
12919 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
12920 let mut atn = ParserAtnBuilder::new(2);
12921 for (state, kind, rule) in [
12922 (0, AtnStateKind::RuleStart, 0),
12923 (1, AtnStateKind::Basic, 0),
12924 (2, AtnStateKind::Basic, 0),
12925 (3, AtnStateKind::RuleStop, 0),
12926 (4, AtnStateKind::RuleStart, 1),
12927 (5, AtnStateKind::StarLoopEntry, 1),
12928 (6, AtnStateKind::Basic, 1),
12929 (7, AtnStateKind::Basic, 1),
12930 (8, AtnStateKind::Basic, 1),
12931 (9, AtnStateKind::Basic, 1),
12932 (10, AtnStateKind::LoopEnd, 1),
12933 (11, AtnStateKind::RuleStop, 1),
12934 ] {
12935 assert_eq!(
12936 atn.add_state(kind, Some(rule)).expect("state").index(),
12937 state
12938 );
12939 if state == 4 {
12940 atn.set_left_recursive_rule(state)
12941 .expect("left-recursive rule start");
12942 } else if state == 5 {
12943 atn.set_precedence_rule_decision(state)
12944 .expect("precedence decision");
12945 }
12946 }
12947 atn.set_rule_to_start_state(vec![0, 4])
12948 .expect("rule start states");
12949 atn.set_rule_to_stop_state(vec![3, 11])
12950 .expect("rule stop states");
12951 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12952 .expect("transition");
12953 atn.add_transition(
12954 1,
12955 ParserTransitionSpec::Rule {
12956 target: 4,
12957 rule_index: 1,
12958 follow_state: 2,
12959 precedence: 0,
12960 },
12961 )
12962 .expect("transition");
12963 atn.add_transition(
12964 2,
12965 ParserTransitionSpec::Atom {
12966 target: 3,
12967 label: caller_symbol,
12968 },
12969 )
12970 .expect("transition");
12971 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
12972 .expect("transition");
12973 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
12974 .expect("transition");
12975 atn.add_transition(
12976 6,
12977 ParserTransitionSpec::Precedence {
12978 target: 7,
12979 precedence: 1,
12980 },
12981 )
12982 .expect("transition");
12983 atn.add_transition(
12984 7,
12985 ParserTransitionSpec::Atom {
12986 target: 8,
12987 label: 1,
12988 },
12989 )
12990 .expect("transition");
12991 atn.add_transition(
12992 8,
12993 ParserTransitionSpec::Rule {
12994 target: 4,
12995 rule_index: 1,
12996 follow_state: 9,
12997 precedence: 2,
12998 },
12999 )
13000 .expect("transition");
13001 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
13002 .expect("transition");
13003 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
13004 .expect("transition");
13005 finish_atn(atn)
13006 }
13007
13008 #[test]
13009 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
13010 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
13011 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
13012
13013 let mut overlapping = parser_inside_left_recursive_callee(1);
13014 assert_eq!(
13015 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
13016 None
13017 );
13018
13019 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
13020 assert_eq!(
13021 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13022 Some(true)
13023 );
13024
13025 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
13026 assert_eq!(
13027 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13028 Some(false)
13029 );
13030
13031 assert_eq!(
13032 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13033 Some(true),
13034 "overlap results must not leak across ATNs"
13035 );
13036 }
13037
13038 #[test]
13039 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
13040 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
13041 let mut parser = mini_parser(vec![
13042 TestToken::new(1).with_text("operator"),
13043 TestToken::eof("parser-test", 1, 1, 1),
13044 ]);
13045 parser.rule_context_stack = vec![RuleContextFrame {
13046 rule_index: 0,
13047 invoking_state: -1,
13048 }];
13049
13050 assert_eq!(
13051 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13052 Some(true)
13053 );
13054 assert_eq!(
13055 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13056 Some(true),
13057 "cached operator lookahead must preserve the nullable prefix return path"
13058 );
13059 assert_eq!(
13060 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13061 Some(true),
13062 "the nullable child must use its rule-call precedence, not the caller precedence"
13063 );
13064 }
13065
13066 #[test]
13067 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
13068 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
13073 let mut parser = mini_parser(vec![
13074 TestToken::new(1).with_text(">"),
13075 TestToken::new(2).with_text("id"),
13076 TestToken::eof("parser-test", 1, 1, 1),
13077 ]);
13078 parser.rule_context_stack = vec![RuleContextFrame {
13079 rule_index: 0,
13080 invoking_state: -1,
13081 }];
13082
13083 assert_eq!(
13084 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13085 Some(true),
13086 "at low precedence relational `>` is a single-token operator"
13087 );
13088 assert_eq!(
13089 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
13090 Some(true),
13091 "relational remains single-token at its own precedence"
13092 );
13093 assert_eq!(
13094 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13095 None,
13096 "at shift precedence, bare `>` must not force enter"
13097 );
13098 }
13099
13100 #[test]
13101 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
13102 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
13103 let mut parser = mini_parser(vec![
13104 TestToken::new(1).with_text(">"),
13105 TestToken::new(2).with_text("id"),
13106 TestToken::eof("parser-test", 1, 1, 1),
13107 ]);
13108 parser.rule_context_stack = vec![RuleContextFrame {
13109 rule_index: 0,
13110 invoking_state: -1,
13111 }];
13112
13113 assert_eq!(
13114 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13115 Some(true),
13116 "the direct relational alternative remains a one-token operator"
13117 );
13118 assert_eq!(
13119 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13120 None,
13121 "a token matched in the helper rule must return to the second shift token"
13122 );
13123 }
13124
13125 #[test]
13126 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
13127 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
13128 let mut parser = mini_parser(vec![
13129 TestToken::new(1).with_text(">"),
13130 TestToken::new(2).with_text("id"),
13131 TestToken::eof("parser-test", 1, 1, 1),
13132 ]);
13133 parser.rule_context_stack = vec![RuleContextFrame {
13134 rule_index: 0,
13135 invoking_state: -1,
13136 }];
13137
13138 assert_eq!(
13139 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13140 None,
13141 "a predicate-gated single-token path must not be hidden by a multi-token path"
13142 );
13143 }
13144
13145 #[test]
13146 fn left_recursive_loop_defers_predicate_guarded_operator() {
13147 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
13148 let mut parser = mini_parser_with_hooks(
13149 vec![
13150 TestToken::new(1).with_text("operator"),
13151 TestToken::eof("parser-test", 1, 1, 1),
13152 ],
13153 RejectingPredicateHooks::default(),
13154 );
13155 parser.rule_context_stack = vec![RuleContextFrame {
13156 rule_index: 0,
13157 invoking_state: -1,
13158 }];
13159
13160 assert_eq!(
13161 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13162 None,
13163 "a false predicate must be evaluated before entering the operator alternative"
13164 );
13165 assert_eq!(
13166 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13167 None,
13168 "cached predicate-dependent lookahead must keep deferring"
13169 );
13170 }
13171
13172 #[test]
13173 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
13174 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
13175 let mut parser = parser_inside_left_recursive_callee(1);
13176
13177 assert_eq!(
13178 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
13179 None
13180 );
13181 assert_eq!(
13182 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
13183 None,
13184 "the cached overlap must preserve the nullable child return path"
13185 );
13186 }
13187
13188 #[test]
13189 fn left_recursive_loop_defers_through_nullable_parent_return() {
13190 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
13191 let mut parser = mini_parser(vec![
13192 TestToken::new(1).with_text("lookahead"),
13193 TestToken::eof("parser-test", 1, 1, 1),
13194 ]);
13195 parser.rule_context_stack = vec![
13196 RuleContextFrame {
13197 rule_index: 0,
13198 invoking_state: -1,
13199 },
13200 RuleContextFrame {
13201 rule_index: 1,
13202 invoking_state: 1,
13203 },
13204 RuleContextFrame {
13205 rule_index: 2,
13206 invoking_state: 5,
13207 },
13208 ];
13209
13210 assert_eq!(
13211 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
13212 None,
13213 "a nullable caller must unwind to its parent's consuming follow path"
13214 );
13215 assert_eq!(
13216 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
13217 None,
13218 "the caller-overlap cache must not retain a false negative"
13219 );
13220 }
13221
13222 #[test]
13223 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
13224 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
13225 let mut parser = mini_parser(vec![
13226 TestToken::new(1).with_text("lookahead"),
13227 TestToken::eof("parser-test", 1, 1, 1),
13228 ]);
13229 parser.rule_context_stack = vec![
13230 RuleContextFrame {
13231 rule_index: 0,
13232 invoking_state: -1,
13233 },
13234 RuleContextFrame {
13235 rule_index: 1,
13236 invoking_state: 1,
13237 },
13238 RuleContextFrame {
13239 rule_index: 1,
13240 invoking_state: 8,
13241 },
13242 ];
13243
13244 assert_eq!(
13245 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
13246 None,
13247 "a recursive operand return must preserve its parent caller context"
13248 );
13249 assert_eq!(
13250 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
13251 None,
13252 "the caller-overlap cache must preserve the loop-boundary return"
13253 );
13254 }
13255
13256 fn token_then_eof_atn() -> Atn {
13257 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13258 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, ]))
13274 .deserialize_parser()
13275 .expect("artificial parser ATN should deserialize")
13276 }
13277
13278 fn eof_then_action_atn() -> Atn {
13279 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13280 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, ]))
13296 .deserialize_parser()
13297 .expect("artificial parser ATN should deserialize")
13298 }
13299
13300 fn noop_action_then_token_then_eof_atn() -> Atn {
13301 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13302 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, ]))
13320 .deserialize_parser()
13321 .expect("artificial no-op action ATN should deserialize")
13322 }
13323
13324 fn two_alt_decision_atn() -> Atn {
13325 let mut atn = ParserAtnBuilder::new(2);
13326 assert_eq!(
13327 atn.add_state(AtnStateKind::RuleStart, Some(0))
13328 .expect("state")
13329 .index(),
13330 0
13331 );
13332 assert_eq!(
13333 atn.add_state(AtnStateKind::BlockStart, Some(0))
13334 .expect("state")
13335 .index(),
13336 1
13337 );
13338 assert_eq!(
13339 atn.add_state(AtnStateKind::Basic, Some(0))
13340 .expect("state")
13341 .index(),
13342 2
13343 );
13344 assert_eq!(
13345 atn.add_state(AtnStateKind::Basic, Some(0))
13346 .expect("state")
13347 .index(),
13348 3
13349 );
13350 assert_eq!(
13351 atn.add_state(AtnStateKind::BlockEnd, Some(0))
13352 .expect("state")
13353 .index(),
13354 4
13355 );
13356 assert_eq!(
13357 atn.add_state(AtnStateKind::RuleStop, Some(0))
13358 .expect("state")
13359 .index(),
13360 5
13361 );
13362 atn.set_rule_to_start_state(vec![0])
13363 .expect("rule start states");
13364 atn.set_rule_to_stop_state(vec![5])
13365 .expect("rule stop states");
13366 atn.add_decision_state(1).expect("decision state");
13367 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13368 .expect("transition");
13369 atn.add_transition(
13370 1,
13371 ParserTransitionSpec::Atom {
13372 target: 2,
13373 label: 1,
13374 },
13375 )
13376 .expect("transition");
13377 atn.add_transition(
13378 1,
13379 ParserTransitionSpec::Atom {
13380 target: 3,
13381 label: 2,
13382 },
13383 )
13384 .expect("transition");
13385 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
13386 .expect("transition");
13387 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
13388 .expect("transition");
13389 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13390 .expect("transition");
13391 finish_atn(atn)
13392 }
13393
13394 fn optional_then_b_eof_atn() -> Atn {
13397 let mut atn = ParserAtnBuilder::new(3);
13398 assert_eq!(
13399 atn.add_state(AtnStateKind::RuleStart, Some(0))
13400 .expect("state")
13401 .index(),
13402 0
13403 );
13404 assert_eq!(
13405 atn.add_state(AtnStateKind::BlockStart, Some(0))
13406 .expect("state")
13407 .index(),
13408 1
13409 );
13410 assert_eq!(
13411 atn.add_state(AtnStateKind::Basic, Some(0))
13412 .expect("state")
13413 .index(),
13414 2
13415 );
13416 assert_eq!(
13417 atn.add_state(AtnStateKind::Basic, Some(0))
13418 .expect("state")
13419 .index(),
13420 3
13421 );
13422 assert_eq!(
13423 atn.add_state(AtnStateKind::Basic, Some(0))
13424 .expect("state")
13425 .index(),
13426 4
13427 );
13428 assert_eq!(
13429 atn.add_state(AtnStateKind::RuleStop, Some(0))
13430 .expect("state")
13431 .index(),
13432 5
13433 );
13434 atn.set_rule_to_start_state(vec![0])
13435 .expect("rule start states");
13436 atn.set_rule_to_stop_state(vec![5])
13437 .expect("rule stop states");
13438 atn.add_decision_state(1).expect("decision state");
13439 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13440 .expect("transition");
13441 atn.add_transition(
13443 1,
13444 ParserTransitionSpec::Atom {
13445 target: 3,
13446 label: 1,
13447 },
13448 )
13449 .expect("transition");
13450 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
13451 .expect("transition");
13452 atn.add_transition(
13454 3,
13455 ParserTransitionSpec::Atom {
13456 target: 4,
13457 label: 2,
13458 },
13459 )
13460 .expect("transition");
13461 atn.add_transition(
13462 4,
13463 ParserTransitionSpec::Atom {
13464 target: 5,
13465 label: TOKEN_EOF,
13466 },
13467 )
13468 .expect("transition");
13469 finish_atn(atn)
13470 }
13471
13472 #[test]
13473 fn sync_decision_deletes_only_a_single_token() {
13474 let atn = optional_then_b_eof_atn();
13482
13483 let mut single = mini_parser(vec![
13484 TestToken::new(3).with_text("c"),
13485 TestToken::new(2).with_text("b"),
13486 TestToken::eof("parser-test", 1, 2, 2),
13487 ]);
13488 single.rule_context_stack = vec![RuleContextFrame {
13489 rule_index: 0,
13490 invoking_state: 0,
13491 }];
13492 let children = single
13493 .sync_decision(&atn, 1, true, false)
13494 .expect("single extraneous token recovers");
13495 assert_eq!(children.len(), 1);
13496 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
13497 assert_eq!(single.number_of_syntax_errors(), 1);
13498 assert_eq!(single.la(1), 2);
13500
13501 let mut double = mini_parser(vec![
13502 TestToken::new(3).with_text("c"),
13503 TestToken::new(3).with_text("c"),
13504 TestToken::new(2).with_text("b"),
13505 TestToken::eof("parser-test", 1, 3, 3),
13506 ]);
13507 double.rule_context_stack = vec![RuleContextFrame {
13508 rule_index: 0,
13509 invoking_state: 0,
13510 }];
13511 let result = double.sync_decision(&atn, 1, true, false);
13512 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
13517 match error {
13518 AntlrError::ParserError { message, .. } => {
13519 assert!(message.starts_with("mismatched input"), "got: {message}");
13520 }
13521 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
13522 }
13523 assert_eq!(double.la(1), 3);
13524 }
13525
13526 fn star_loop_then_eof_atn() -> Atn {
13530 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13531 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,
13532 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,
13533 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,
13534 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
13535 ]))
13536 .deserialize_parser()
13537 .expect("star-loop-then-EOF ATN should deserialize")
13538 }
13539
13540 fn plus_loop_with_recovering_body_atn() -> Atn {
13546 let mut atn = ParserAtnBuilder::new(2);
13547 assert_eq!(
13548 atn.add_state(AtnStateKind::RuleStart, Some(0))
13549 .expect("state")
13550 .index(),
13551 0
13552 );
13553 assert_eq!(
13554 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
13555 .expect("state")
13556 .index(),
13557 1
13558 );
13559 assert_eq!(
13560 atn.add_state(AtnStateKind::Basic, Some(0))
13561 .expect("state")
13562 .index(),
13563 2
13564 );
13565 assert_eq!(
13566 atn.add_state(AtnStateKind::BlockEnd, Some(0))
13567 .expect("state")
13568 .index(),
13569 3
13570 );
13571 assert_eq!(
13572 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
13573 .expect("state")
13574 .index(),
13575 4
13576 );
13577 assert_eq!(
13578 atn.add_state(AtnStateKind::LoopEnd, Some(0))
13579 .expect("state")
13580 .index(),
13581 5
13582 );
13583 assert_eq!(
13584 atn.add_state(AtnStateKind::RuleStop, Some(0))
13585 .expect("state")
13586 .index(),
13587 6
13588 );
13589 assert_eq!(
13590 atn.add_state(AtnStateKind::RuleStart, Some(1))
13591 .expect("state")
13592 .index(),
13593 7
13594 );
13595 assert_eq!(
13596 atn.add_state(AtnStateKind::Basic, Some(1))
13597 .expect("state")
13598 .index(),
13599 8
13600 );
13601 assert_eq!(
13602 atn.add_state(AtnStateKind::RuleStop, Some(1))
13603 .expect("state")
13604 .index(),
13605 9
13606 );
13607 atn.set_rule_to_start_state(vec![0, 7])
13608 .expect("rule start states");
13609 atn.set_rule_to_stop_state(vec![6, 9])
13610 .expect("rule stop states");
13611 atn.set_end_state(1, 3).expect("block end state");
13612 atn.set_loop_back_state(5, 4).expect("loop back state");
13613 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13614 .expect("transition");
13615 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13616 .expect("transition");
13617 atn.add_transition(
13618 2,
13619 ParserTransitionSpec::Rule {
13620 target: 7,
13621 rule_index: 1,
13622 follow_state: 3,
13623 precedence: 0,
13624 },
13625 )
13626 .expect("transition");
13627 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
13628 .expect("transition");
13629 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
13630 .expect("transition");
13631 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13632 .expect("transition");
13633 atn.add_transition(
13634 5,
13635 ParserTransitionSpec::Atom {
13636 target: 6,
13637 label: 2,
13638 },
13639 )
13640 .expect("transition");
13641 atn.add_transition(
13642 7,
13643 ParserTransitionSpec::Atom {
13644 target: 8,
13645 label: 1,
13646 },
13647 )
13648 .expect("transition");
13649 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
13650 .expect("transition");
13651 finish_atn(atn)
13652 }
13653
13654 #[test]
13655 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
13656 let atn = plus_loop_with_recovering_body_atn();
13657 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
13658
13659 let error = parser
13660 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
13661 .expect_err("EOF recovery should report a bounded mismatch");
13662
13663 let AntlrError::ParserError { message, .. } = error else {
13664 panic!("expected ParserError, got {error:?}");
13665 };
13666 assert_eq!(message, "mismatched input '<EOF>' expecting {'x', 2}");
13667 assert_eq!(parser.number_of_syntax_errors(), 1);
13668 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
13669 }
13670
13671 #[test]
13672 fn sync_decision_deletes_token_before_eof_at_loop_back() {
13673 let atn = star_loop_then_eof_atn();
13679 let mut parser = mini_parser(vec![
13680 TestToken::new(2).with_text("c"),
13681 TestToken::eof("parser-test", 1, 1, 1),
13682 ]);
13683 parser.rule_context_stack = vec![RuleContextFrame {
13684 rule_index: 0,
13685 invoking_state: 0,
13686 }];
13687 let children = parser
13688 .sync_decision(&atn, 5, true, false)
13689 .expect("single token before EOF recovers");
13690 assert_eq!(children.len(), 1);
13691 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
13692 assert_eq!(parser.number_of_syntax_errors(), 1);
13693 assert_eq!(
13694 parser.la(1),
13695 TOKEN_EOF,
13696 "EOF is left for the rule's EOF match"
13697 );
13698 }
13699
13700 #[test]
13701 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
13702 let atn = star_loop_then_eof_atn();
13707 let mut parser = mini_parser(vec![
13708 TestToken::new(2).with_text("c"),
13709 TestToken::new(2).with_text("c"),
13710 TestToken::eof("parser-test", 1, 2, 2),
13711 ]);
13712 parser.rule_context_stack = vec![RuleContextFrame {
13713 rule_index: 0,
13714 invoking_state: 0,
13715 }];
13716 let error = parser
13717 .sync_decision(&atn, 5, true, false)
13718 .expect_err("two tokens at the loop entry must not be deleted");
13719 match error {
13720 AntlrError::ParserError { message, .. } => {
13721 assert!(message.starts_with("mismatched input"), "got: {message}");
13722 }
13723 other => panic!("expected mismatched-input ParserError, got {other:?}"),
13724 }
13725 assert_eq!(
13726 parser.la(1),
13727 2,
13728 "nothing consumed; cursor still on first `c`"
13729 );
13730 }
13731
13732 #[test]
13733 fn sync_decision_consumes_until_eof_at_loop_back() {
13734 let atn = star_loop_then_eof_atn();
13740 let mut parser = mini_parser(vec![
13741 TestToken::new(2).with_text("c"),
13742 TestToken::new(2).with_text("c"),
13743 TestToken::eof("parser-test", 1, 2, 2),
13744 ]);
13745 parser.rule_context_stack = vec![RuleContextFrame {
13746 rule_index: 0,
13747 invoking_state: 0,
13748 }];
13749 let children = parser
13750 .sync_decision(&atn, 5, false, true)
13751 .expect("loop-back multi-token deletion recovers onto EOF");
13752 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
13753 assert!(
13754 children
13755 .iter()
13756 .all(|child| parser.node(*child).kind() == NodeKind::Error)
13757 );
13758 assert_eq!(parser.number_of_syntax_errors(), 1);
13759 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
13760 }
13761
13762 fn predicate_after_token_atn() -> Atn {
13763 let mut atn = ParserAtnBuilder::new(2);
13764 assert_eq!(
13765 atn.add_state(AtnStateKind::RuleStart, Some(0))
13766 .expect("state")
13767 .index(),
13768 0
13769 );
13770 assert_eq!(
13771 atn.add_state(AtnStateKind::Basic, Some(0))
13772 .expect("state")
13773 .index(),
13774 1
13775 );
13776 assert_eq!(
13777 atn.add_state(AtnStateKind::Basic, Some(0))
13778 .expect("state")
13779 .index(),
13780 2
13781 );
13782 assert_eq!(
13783 atn.add_state(AtnStateKind::Basic, Some(0))
13784 .expect("state")
13785 .index(),
13786 3
13787 );
13788 assert_eq!(
13789 atn.add_state(AtnStateKind::RuleStop, Some(0))
13790 .expect("state")
13791 .index(),
13792 4
13793 );
13794 atn.set_rule_to_start_state(vec![0])
13795 .expect("rule start states");
13796 atn.set_rule_to_stop_state(vec![4])
13797 .expect("rule stop states");
13798 atn.add_transition(
13799 0,
13800 ParserTransitionSpec::Atom {
13801 target: 1,
13802 label: 1,
13803 },
13804 )
13805 .expect("transition");
13806 atn.add_transition(
13807 1,
13808 ParserTransitionSpec::Predicate {
13809 target: 2,
13810 rule_index: 0,
13811 pred_index: 0,
13812 context_dependent: false,
13813 },
13814 )
13815 .expect("transition");
13816 atn.add_transition(
13817 2,
13818 ParserTransitionSpec::Atom {
13819 target: 3,
13820 label: 2,
13821 },
13822 )
13823 .expect("transition");
13824 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
13825 .expect("transition");
13826 finish_atn(atn)
13827 }
13828
13829 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
13830 let mut atn = ParserAtnBuilder::new(1);
13831 for (state_number, kind) in [
13832 (0, AtnStateKind::RuleStart),
13833 (1, AtnStateKind::BlockStart),
13834 (2, AtnStateKind::Basic),
13835 (3, AtnStateKind::Basic),
13836 (4, AtnStateKind::Basic),
13837 (5, AtnStateKind::Basic),
13838 (6, AtnStateKind::BlockEnd),
13839 (7, AtnStateKind::RuleStop),
13840 ] {
13841 assert_eq!(
13842 atn.add_state(kind, Some(0)).expect("state").index(),
13843 state_number
13844 );
13845 }
13846 atn.set_rule_to_start_state(vec![0])
13847 .expect("rule start states");
13848 atn.set_rule_to_stop_state(vec![7])
13849 .expect("rule stop states");
13850 atn.add_decision_state(1).expect("decision state");
13851 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13852 .expect("transition");
13853 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13854 .expect("transition");
13855 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
13856 .expect("transition");
13857 atn.add_transition(
13858 2,
13859 ParserTransitionSpec::Predicate {
13860 target: 4,
13861 rule_index: 0,
13862 pred_index: pred_indexes[0],
13863 context_dependent: false,
13864 },
13865 )
13866 .expect("transition");
13867 atn.add_transition(
13868 3,
13869 ParserTransitionSpec::Predicate {
13870 target: 5,
13871 rule_index: 0,
13872 pred_index: pred_indexes[1],
13873 context_dependent: false,
13874 },
13875 )
13876 .expect("transition");
13877 atn.add_transition(
13878 4,
13879 ParserTransitionSpec::Atom {
13880 target: 6,
13881 label: 1,
13882 },
13883 )
13884 .expect("transition");
13885 atn.add_transition(
13886 5,
13887 ParserTransitionSpec::Atom {
13888 target: 6,
13889 label: 1,
13890 },
13891 )
13892 .expect("transition");
13893 atn.add_transition(
13894 6,
13895 ParserTransitionSpec::Atom {
13896 target: 7,
13897 label: TOKEN_EOF,
13898 },
13899 )
13900 .expect("transition");
13901 finish_atn(atn)
13902 }
13903
13904 fn nested_nullable_context_atn() -> Atn {
13905 let mut atn = ParserAtnBuilder::new(1);
13906 for state_number in 0..=20 {
13907 let kind = match state_number {
13908 0 | 10 | 16 => AtnStateKind::RuleStart,
13909 9 | 15 | 20 => AtnStateKind::RuleStop,
13910 _ => AtnStateKind::Basic,
13911 };
13912 let rule_index = match state_number {
13913 0..=9 => 0,
13914 10..=15 => 1,
13915 _ => 2,
13916 };
13917 assert_eq!(
13918 atn.add_state(kind, Some(rule_index))
13919 .expect("state")
13920 .index(),
13921 state_number
13922 );
13923 }
13924 atn.set_rule_to_start_state(vec![0, 10, 16])
13925 .expect("rule start states");
13926 atn.set_rule_to_stop_state(vec![9, 15, 20])
13927 .expect("rule stop states");
13928 atn.add_transition(
13929 1,
13930 ParserTransitionSpec::Rule {
13931 target: 10,
13932 rule_index: 1,
13933 follow_state: 8,
13934 precedence: 0,
13935 },
13936 )
13937 .expect("transition");
13938 atn.add_transition(
13939 8,
13940 ParserTransitionSpec::Atom {
13941 target: 9,
13942 label: 1,
13943 },
13944 )
13945 .expect("transition");
13946 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
13947 .expect("transition");
13948 atn.add_transition(
13949 2,
13950 ParserTransitionSpec::Rule {
13951 target: 16,
13952 rule_index: 2,
13953 follow_state: 14,
13954 precedence: 0,
13955 },
13956 )
13957 .expect("transition");
13958 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
13959 .expect("transition");
13960 finish_atn(atn)
13961 }
13962
13963 fn generated_match_recovery_atn() -> Atn {
13964 let mut atn = ParserAtnBuilder::new(2);
13965 assert_eq!(
13966 atn.add_state(AtnStateKind::RuleStart, Some(0))
13967 .expect("state")
13968 .index(),
13969 0
13970 );
13971 assert_eq!(
13972 atn.add_state(AtnStateKind::Basic, Some(0))
13973 .expect("state")
13974 .index(),
13975 1
13976 );
13977 assert_eq!(
13978 atn.add_state(AtnStateKind::Basic, Some(0))
13979 .expect("state")
13980 .index(),
13981 2
13982 );
13983 assert_eq!(
13984 atn.add_state(AtnStateKind::RuleStop, Some(0))
13985 .expect("state")
13986 .index(),
13987 3
13988 );
13989 assert_eq!(
13990 atn.add_state(AtnStateKind::RuleStart, Some(1))
13991 .expect("state")
13992 .index(),
13993 4
13994 );
13995 assert_eq!(
13996 atn.add_state(AtnStateKind::RuleStop, Some(1))
13997 .expect("state")
13998 .index(),
13999 5
14000 );
14001 atn.set_rule_to_start_state(vec![0, 4])
14002 .expect("rule start states");
14003 atn.set_rule_to_stop_state(vec![3, 5])
14004 .expect("rule stop states");
14005 atn.add_transition(
14006 1,
14007 ParserTransitionSpec::Rule {
14008 target: 4,
14009 rule_index: 1,
14010 follow_state: 2,
14011 precedence: 0,
14012 },
14013 )
14014 .expect("transition");
14015 atn.add_transition(
14016 2,
14017 ParserTransitionSpec::Atom {
14018 target: 3,
14019 label: TOKEN_EOF,
14020 },
14021 )
14022 .expect("transition");
14023 finish_atn(atn)
14024 }
14025
14026 fn complement_set_atn() -> Atn {
14027 let mut atn = ParserAtnBuilder::new(1);
14028 assert_eq!(
14029 atn.add_state(AtnStateKind::RuleStart, Some(0))
14030 .expect("state")
14031 .index(),
14032 0
14033 );
14034 assert_eq!(
14035 atn.add_state(AtnStateKind::RuleStop, Some(0))
14036 .expect("state")
14037 .index(),
14038 1
14039 );
14040 atn.set_rule_to_start_state(vec![0])
14041 .expect("rule start states");
14042 atn.set_rule_to_stop_state(vec![1])
14043 .expect("rule stop states");
14044 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
14045 atn.add_transition(
14046 0,
14047 ParserTransitionSpec::NotSet {
14048 target: 1,
14049 set: excluded,
14050 },
14051 )
14052 .expect("transition");
14053 finish_atn(atn)
14054 }
14055
14056 fn wildcard_then_eof_atn() -> Atn {
14059 let mut atn = ParserAtnBuilder::new(1);
14060 assert_eq!(
14061 atn.add_state(AtnStateKind::RuleStart, Some(0))
14062 .expect("state")
14063 .index(),
14064 0
14065 );
14066 assert_eq!(
14067 atn.add_state(AtnStateKind::RuleStop, Some(0))
14068 .expect("state")
14069 .index(),
14070 1
14071 );
14072 assert_eq!(
14073 atn.add_state(AtnStateKind::Basic, Some(0))
14074 .expect("state")
14075 .index(),
14076 2
14077 );
14078 atn.set_rule_to_start_state(vec![0])
14079 .expect("rule start states");
14080 atn.set_rule_to_stop_state(vec![1])
14081 .expect("rule stop states");
14082 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
14083 .expect("transition");
14084 atn.add_transition(
14085 2,
14086 ParserTransitionSpec::Atom {
14087 target: 1,
14088 label: TOKEN_EOF,
14089 },
14090 )
14091 .expect("transition");
14092 finish_atn(atn)
14093 }
14094
14095 #[test]
14096 fn parser_matches_token_and_reports_mismatch() {
14097 let source = Source {
14098 tokens: vec![
14099 TestToken::new(1).with_text("x"),
14100 TestToken::eof("parser-test", 1, 1, 1),
14101 ],
14102 index: 0,
14103 };
14104 let data = RecognizerData::new(
14105 "Mini.g4",
14106 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
14107 );
14108 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
14109 let matched = parser.match_token(1).expect("token 1 should match");
14110 assert_eq!(parser.node(matched).text(), "x");
14111 assert!(parser.match_token(1).is_err());
14112 }
14113
14114 #[test]
14115 fn parser_matches_token_sets() {
14116 let mut parser = mini_parser(vec![
14117 TestToken::new(1).with_text("x"),
14118 TestToken::eof("parser-test", 1, 1, 1),
14119 ]);
14120
14121 let matched = parser
14122 .match_set(&[(1, 1), (3, 4)])
14123 .expect("token set should match");
14124 assert_eq!(parser.node(matched).text(), "x");
14125 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
14126 }
14127
14128 #[test]
14129 fn generated_rule_api_tracks_state_and_precedence() {
14130 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14131
14132 let context = parser.enter_rule(7, 2);
14133 assert_eq!(context.rule_index(), 2);
14134 assert_eq!(parser.state(), 7);
14135 assert_eq!(
14136 parser.rule_context_stack,
14137 vec![RuleContextFrame {
14138 rule_index: 2,
14139 invoking_state: 7
14140 }]
14141 );
14142
14143 let recursive = parser.enter_recursion_rule(11, 3, 4);
14144 assert_eq!(recursive.rule_index(), 3);
14145 assert!(parser.precpred(4));
14146 assert!(parser.precpred(5));
14147 assert!(!parser.precpred(3));
14148
14149 let next = parser.push_new_recursion_context(13, 3);
14150 assert_eq!(next.invoking_state(), 13);
14151 parser.unroll_recursion_context();
14152 assert_eq!(parser.precedence_stack, vec![0]);
14153 assert_eq!(
14154 parser.rule_context_stack,
14155 vec![RuleContextFrame {
14156 rule_index: 2,
14157 invoking_state: 7
14158 }]
14159 );
14160
14161 parser.exit_rule();
14162 assert!(parser.rule_context_stack.is_empty());
14163 }
14164
14165 #[test]
14166 fn active_invocation_states_exclude_the_root_frame() {
14167 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14168
14169 let _root = parser.enter_rule(0, 0);
14170 assert!(parser.active_invocation_states().is_empty());
14171
14172 let marker = parser.push_invoking_state(6);
14173 let _child = parser.enter_rule(2, 1);
14174 parser.discard_invoking_state(marker);
14175 assert_eq!(parser.active_invocation_states(), [6]);
14176
14177 let marker = parser.push_invoking_state(13);
14178 let _grandchild = parser.enter_rule(4, 2);
14179 parser.discard_invoking_state(marker);
14180 assert_eq!(parser.active_invocation_states(), [13, 6]);
14181
14182 parser.exit_rule();
14183 parser.exit_rule();
14184 parser.exit_rule();
14185 }
14186
14187 #[test]
14188 fn parser_predicates_support_token_adjacency() {
14189 let mut parser = mini_parser(vec![
14190 TestToken::new(1).with_text("=").with_span(0, 0),
14191 TestToken::new(1).with_text(">").with_span(1, 1),
14192 TestToken::eof("parser-test", 2, 1, 2),
14193 ]);
14194 parser.consume();
14195 parser.consume();
14196
14197 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
14198
14199 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
14200
14201 let mut parser = mini_parser(vec![
14202 TestToken::new(1).with_text("=").with_span(0, 0),
14203 TestToken::new(1)
14204 .with_text(" ")
14205 .with_channel(HIDDEN_CHANNEL)
14206 .with_span(1, 1),
14207 TestToken::new(1).with_text(">").with_span(2, 2),
14208 TestToken::eof("parser-test", 3, 1, 3),
14209 ]);
14210 parser.consume();
14211 parser.consume();
14212
14213 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
14214 }
14215
14216 #[test]
14217 fn parser_predicates_support_context_child_text_checks() {
14218 let mut parser = mini_parser(vec![
14219 TestToken::new(1).with_text("var"),
14220 TestToken::eof("parser-test", 1, 1, 1),
14221 ]);
14222 let mut context = ParserRuleContext::new(1, 0);
14223 let mut child_context = ParserRuleContext::new(2, 0);
14224 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
14225 parser.tree.add_child(&mut child_context, terminal);
14226 let child = parser.rule_node(child_context);
14227 parser.tree.add_child(&mut context, child);
14228 let predicates = [(
14229 1,
14230 0,
14231 ParserPredicate::ContextChildRuleTextNotEquals {
14232 rule_index: 2,
14233 text: "var",
14234 },
14235 )];
14236
14237 assert!(
14238 !parser.parser_semantic_predicate_matches_with_context_and_local(
14239 &predicates,
14240 1,
14241 0,
14242 &context,
14243 0,
14244 )
14245 );
14246 }
14247
14248 #[test]
14249 fn context_expected_symbols_walks_nullable_parent_contexts() {
14250 let atn = nested_nullable_context_atn();
14251 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14252 parser.rule_context_stack = vec![
14253 RuleContextFrame {
14254 rule_index: 0,
14255 invoking_state: 0,
14256 },
14257 RuleContextFrame {
14258 rule_index: 1,
14259 invoking_state: 1,
14260 },
14261 RuleContextFrame {
14262 rule_index: 2,
14263 invoking_state: 2,
14264 },
14265 ];
14266
14267 let expected = parser.context_expected_symbols(&atn);
14268
14269 assert!(expected.contains(&1));
14270 assert!(expected.contains(&TOKEN_EOF));
14271 }
14272
14273 #[test]
14274 fn prediction_context_return_states_track_rule_stack_changes() {
14275 let atn = nested_nullable_context_atn();
14276 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14277 parser.rule_context_stack = vec![
14278 RuleContextFrame {
14279 rule_index: 0,
14280 invoking_state: 0,
14281 },
14282 RuleContextFrame {
14283 rule_index: 1,
14284 invoking_state: 1,
14285 },
14286 RuleContextFrame {
14287 rule_index: 2,
14288 invoking_state: 2,
14289 },
14290 ];
14291
14292 let initial_version = parser.rule_context_version();
14293 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14294 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14295 assert_eq!(first, second);
14296 assert_eq!(parser.rule_context_version(), initial_version);
14297
14298 parser.exit_rule();
14299 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14300 assert_ne!(first, after_pop);
14301 assert_ne!(parser.rule_context_version(), initial_version);
14302 }
14303
14304 #[test]
14305 fn generated_match_token_recovers_missing_token_from_context_follow() {
14306 let atn = generated_match_recovery_atn();
14307 let data = RecognizerData::new(
14308 "Mini.g4",
14309 Vocabulary::new(
14310 [None, Some("'X'"), Some("'Y'")],
14311 [None, Some("X"), Some("Y")],
14312 [None::<&str>, None, None],
14313 ),
14314 );
14315 let mut parser = BaseParser::new(
14316 CommonTokenStream::new(Source {
14317 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
14318 index: 0,
14319 }),
14320 data,
14321 );
14322 parser.rule_context_stack = vec![
14323 RuleContextFrame {
14324 rule_index: 0,
14325 invoking_state: 0,
14326 },
14327 RuleContextFrame {
14328 rule_index: 1,
14329 invoking_state: 1,
14330 },
14331 ];
14332 assert_eq!(parser.number_of_syntax_errors(), 0);
14333
14334 let node = parser
14335 .match_token_recovering(2, 5, &atn)
14336 .expect("generated match should insert missing token");
14337
14338 assert_eq!(node.children().len(), 1);
14339 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
14340 assert_eq!(
14341 node.clone()
14342 .into_child_iter()
14343 .map(|child| parser.node(child).text())
14344 .collect::<Vec<_>>(),
14345 ["<missing 'Y'>"]
14346 );
14347 assert!(!node.consumed_eof());
14350 assert_eq!(parser.la(1), TOKEN_EOF);
14351 assert_eq!(parser.number_of_syntax_errors(), 1);
14352 assert_eq!(
14353 parser.generated_parser_diagnostics,
14354 [ParserDiagnostic {
14355 line: 1,
14356 column: 3,
14357 message: "missing 'Y' at '<EOF>'".to_owned(),
14358 }]
14359 );
14360 }
14361
14362 #[test]
14363 fn generated_match_token_counts_single_token_deletion_recovery() {
14364 let atn = generated_match_recovery_atn();
14365 let data = RecognizerData::new(
14366 "Mini.g4",
14367 Vocabulary::new(
14368 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
14369 [None, Some("X"), Some("Y"), Some("Z")],
14370 [None::<&str>, None, None, None],
14371 ),
14372 );
14373 let mut parser = BaseParser::new(
14374 CommonTokenStream::new(Source {
14375 tokens: vec![
14376 TestToken::new(3).with_text("z"),
14377 TestToken::new(2).with_text("y"),
14378 TestToken::eof("parser-test", 3, 1, 3),
14379 ],
14380 index: 0,
14381 }),
14382 data,
14383 );
14384
14385 let node = parser
14386 .match_token_recovering(2, 5, &atn)
14387 .expect("generated match should delete the extraneous token");
14388
14389 assert_eq!(node.children().len(), 2);
14390 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
14391 assert_eq!(parser.node(node.children()[0]).text(), "z");
14392 assert_eq!(parser.node(node.children()[1]).text(), "y");
14393 assert_eq!(
14394 node.into_child_iter()
14395 .map(|child| parser.node(child).text())
14396 .collect::<Vec<_>>(),
14397 ["z", "y"]
14398 );
14399 assert_eq!(parser.number_of_syntax_errors(), 1);
14400 }
14401
14402 #[test]
14403 fn generated_match_token_iterates_single_success_without_a_children_vec() {
14404 let atn = generated_match_recovery_atn();
14405 let data = RecognizerData::new(
14406 "Mini.g4",
14407 Vocabulary::new(
14408 [None, Some("'X'"), Some("'Y'")],
14409 [None, Some("X"), Some("Y")],
14410 [None::<&str>, None, None],
14411 ),
14412 );
14413 let mut parser = BaseParser::new(
14414 CommonTokenStream::new(Source {
14415 tokens: vec![
14416 TestToken::new(2).with_text("y"),
14417 TestToken::eof("parser-test", 1, 1, 1),
14418 ],
14419 index: 0,
14420 }),
14421 data,
14422 );
14423
14424 let node = parser
14425 .match_token_recovering(2, 5, &atn)
14426 .expect("generated match should consume the expected token");
14427
14428 assert_eq!(
14429 node.into_child_iter()
14430 .map(|child| parser.node(child).text())
14431 .collect::<Vec<_>>(),
14432 ["y"]
14433 );
14434 assert_eq!(parser.number_of_syntax_errors(), 0);
14435 }
14436
14437 #[test]
14438 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
14439 let atn = generated_match_recovery_atn();
14440 let data = RecognizerData::new(
14441 "Mini.g4",
14442 Vocabulary::new(
14443 [None, Some("'X'"), Some("'Y'")],
14444 [None, Some("X"), Some("Y")],
14445 [None::<&str>, None, None],
14446 ),
14447 );
14448 let mut parser = BaseParser::new(
14449 CommonTokenStream::new(Source {
14450 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
14451 index: 0,
14452 }),
14453 data,
14454 );
14455 parser.rule_context_stack = vec![
14456 RuleContextFrame {
14457 rule_index: 0,
14458 invoking_state: 0,
14459 },
14460 RuleContextFrame {
14461 rule_index: 1,
14462 invoking_state: 1,
14463 },
14464 ];
14465 let marker = parser.generated_diagnostics_checkpoint();
14466
14467 let _ = parser
14468 .match_token_recovering(2, 5, &atn)
14469 .expect("generated match should insert missing token");
14470 assert_eq!(parser.number_of_syntax_errors(), 1);
14471
14472 parser.restore_generated_diagnostics(marker);
14473
14474 assert_eq!(parser.number_of_syntax_errors(), 0);
14475 assert!(parser.generated_parser_diagnostics.is_empty());
14476 }
14477
14478 #[test]
14479 fn generated_prediction_diagnostics_use_adaptive_context() {
14480 let atn = two_alt_decision_atn();
14481 let data = RecognizerData::new(
14482 "Mini.g4",
14483 Vocabulary::new(
14484 [None, Some("'x'"), Some("'y'")],
14485 [None, Some("X"), Some("Y")],
14486 [None::<&str>, None, None],
14487 ),
14488 )
14489 .with_rule_names(["s"]);
14490 let mut parser = BaseParser::new(
14491 CommonTokenStream::new(Source {
14492 tokens: vec![
14493 TestToken::new(1)
14494 .with_text("x")
14495 .with_position(1, 0)
14496 .with_span(0, 0),
14497 TestToken::new(2)
14498 .with_text("y")
14499 .with_position(1, 2)
14500 .with_span(1, 1),
14501 TestToken::eof("parser-test", 2, 1, 3),
14502 ],
14503 index: 0,
14504 }),
14505 data,
14506 );
14507 parser.set_report_diagnostic_errors(true);
14508
14509 parser.record_generated_prediction_diagnostic(
14510 &atn,
14511 1,
14512 &ParserAtnPrediction {
14513 alt: 1,
14514 requires_full_context: true,
14515 has_semantic_context: false,
14516 diagnostic: Some(ParserAtnPredictionDiagnostic {
14517 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
14518 start_index: 0,
14519 sll_stop_index: 1,
14520 ll_stop_index: 0,
14521 conflicting_alts: vec![1, 2],
14522 exact: false,
14523 }),
14524 },
14525 );
14526 parser.record_generated_prediction_diagnostic(
14531 &atn,
14532 1,
14533 &ParserAtnPrediction {
14534 alt: 1,
14535 requires_full_context: true,
14536 has_semantic_context: false,
14537 diagnostic: Some(ParserAtnPredictionDiagnostic {
14538 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
14539 start_index: 0,
14540 sll_stop_index: 1,
14541 ll_stop_index: 1,
14542 conflicting_alts: vec![1, 2],
14543 exact: false,
14544 }),
14545 },
14546 );
14547
14548 assert_eq!(
14549 parser.generated_parser_diagnostics,
14550 [
14551 ParserDiagnostic {
14552 line: 1,
14553 column: 2,
14554 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
14555 },
14556 ParserDiagnostic {
14557 line: 1,
14558 column: 0,
14559 message: "reportContextSensitivity d=0 (s), input='x'".to_owned(),
14560 },
14561 ParserDiagnostic {
14562 line: 1,
14563 column: 2,
14564 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
14565 },
14566 ]
14567 );
14568 }
14569
14570 #[test]
14571 fn generated_match_not_set_recovers_empty_complement_at_eof() {
14572 let atn = complement_set_atn();
14573 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14574 parser.rule_context_stack = vec![RuleContextFrame {
14575 rule_index: 0,
14576 invoking_state: 0,
14577 }];
14578
14579 let node = parser
14580 .match_not_set_recovering(&[(1, 1)], 1, 1, 1, &atn)
14581 .expect("empty complement should recover at EOF");
14582
14583 assert_eq!(node.children().len(), 1);
14584 assert!(!node.consumed_eof());
14587 assert_eq!(parser.la(1), TOKEN_EOF);
14588 assert_eq!(
14589 parser.generated_parser_diagnostics,
14590 [ParserDiagnostic {
14591 line: 1,
14592 column: 1,
14593 message: "missing {} at '<EOF>'".to_owned(),
14594 }]
14595 );
14596 }
14597
14598 #[test]
14599 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
14600 let atn = wildcard_then_eof_atn();
14606 let data = RecognizerData::new(
14607 "Mini.g4",
14608 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
14609 );
14610 let mut parser = BaseParser::new(
14611 CommonTokenStream::new(Source {
14612 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
14613 index: 0,
14614 }),
14615 data,
14616 );
14617 parser.rule_context_stack = vec![RuleContextFrame {
14618 rule_index: 0,
14619 invoking_state: 0,
14620 }];
14621
14622 let node = parser
14623 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
14624 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
14625
14626 assert_eq!(node.children().len(), 1);
14628 assert!(!node.consumed_eof());
14629 assert!(
14630 parser
14631 .node(node.children()[0])
14632 .text()
14633 .starts_with("<missing")
14634 );
14635 assert_eq!(parser.la(1), TOKEN_EOF);
14636 assert_eq!(
14637 parser.generated_parser_diagnostics,
14638 [ParserDiagnostic {
14639 line: 1,
14640 column: 1,
14641 message: "missing 'x' at '<EOF>'".to_owned(),
14642 }]
14643 );
14644 }
14645
14646 #[test]
14647 fn generated_rule_recovery_consumes_to_parent_follow() {
14648 let atn = generated_match_recovery_atn();
14649 let data = RecognizerData::new(
14650 "Mini.g4",
14651 Vocabulary::new(
14652 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
14653 [None, Some("X"), Some("Y"), Some("Z")],
14654 [None::<&str>, None, None, None],
14655 ),
14656 );
14657 let mut parser = BaseParser::new(
14658 CommonTokenStream::new(Source {
14659 tokens: vec![
14660 TestToken::new(3).with_text("z"),
14661 TestToken::eof("parser-test", 1, 1, 1),
14662 ],
14663 index: 0,
14664 }),
14665 data,
14666 );
14667 let _parent = parser.enter_rule(0, 0);
14668 let marker = parser.push_invoking_state(1);
14669 let mut child = parser.enter_rule(4, 1);
14670 parser.discard_invoking_state(marker);
14671
14672 parser.recover_generated_rule(
14673 &mut child,
14674 &atn,
14675 AntlrError::ParserError {
14676 line: 1,
14677 column: 0,
14678 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
14679 },
14680 );
14681 let tree = parser.finish_rule(child, false);
14682
14683 assert_eq!(parser.la(1), TOKEN_EOF);
14684 assert_eq!(
14685 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
14686 "(a z)"
14687 );
14688 assert_eq!(parser.number_of_syntax_errors(), 1);
14689 assert_eq!(
14690 parser.generated_parser_diagnostics,
14691 [ParserDiagnostic {
14692 line: 1,
14693 column: 0,
14694 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
14695 }]
14696 );
14697 parser.exit_rule();
14698 }
14699
14700 #[test]
14701 fn greedy_ll1_alt_handles_nullable_loop_exit() {
14702 let mut body_symbols = TokenBitSet::default();
14703 body_symbols.insert(1);
14704 let entry = DecisionLookahead {
14705 transitions: vec![
14706 TransitionLookSet {
14707 symbols: body_symbols,
14708 nullable: false,
14709 },
14710 TransitionLookSet {
14711 symbols: TokenBitSet::default(),
14712 nullable: true,
14713 },
14714 ],
14715 };
14716
14717 assert_eq!(ll1_unique_alt(&entry, 2), None);
14718 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
14719 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
14720 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
14721 }
14722
14723 #[test]
14724 fn ordinary_repetition_builds_tree_in_input_order() {
14725 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
14726 let mut parser = mini_parser(repeated_x_tokens(3));
14727 let tree = parser
14728 .parse_atn_rule(&atn, 0)
14729 .expect("ordinary repetition should parse");
14730
14731 let root = parser
14732 .node(tree)
14733 .as_rule()
14734 .expect("entry result should be a rule");
14735 let body_rules = root.child_rules(1).collect::<Vec<_>>();
14736 assert_eq!(root.text(), "xxx<EOF>");
14737 assert_eq!(body_rules.len(), 3);
14738 assert_eq!(
14739 body_rules
14740 .iter()
14741 .map(|rule| rule.start_id().expect("body start").index())
14742 .collect::<Vec<_>>(),
14743 [0, 1, 2]
14744 );
14745 assert_eq!(
14746 body_rules
14747 .iter()
14748 .map(|rule| rule.stop_id().expect("body stop").index())
14749 .collect::<Vec<_>>(),
14750 [0, 1, 2]
14751 );
14752 assert_eq!(parser.number_of_syntax_errors(), 0);
14753 }
14754 }
14755
14756 #[test]
14757 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
14758 const DEPTH: usize = 20_000;
14759
14760 std::thread::Builder::new()
14761 .name("deferred-rule-materialization".to_owned())
14762 .stack_size(256 * 1024)
14763 .spawn(|| {
14764 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
14765 let mut root = FastDeferredNodeId::EMPTY;
14766 for depth in 0..DEPTH {
14767 root = parser
14768 .recognition_arena
14769 .deferred_rule_node(FastDeferredRule {
14770 rule_index: u32::try_from(depth).expect("depth fits in u32"),
14771 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
14772 start_index: 0,
14773 stop_index: None,
14774 deferred_children: root,
14775 children: NodeSeqId::EMPTY,
14776 });
14777 }
14778
14779 let mut children = parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
14780 for expected_rule in (0..DEPTH).rev() {
14781 let mut nodes = parser.recognition_arena.iter(children);
14782 let node = nodes.next().expect("nested rule node");
14783 assert!(nodes.next().is_none(), "each rule has one child");
14784 let ArenaRecognizedNode::Rule {
14785 rule_index,
14786 children: nested,
14787 ..
14788 } = parser.recognition_arena.node(node)
14789 else {
14790 panic!("expected nested rule");
14791 };
14792 assert_eq!(rule_index as usize, expected_rule);
14793 children = nested;
14794 }
14795 assert!(children.is_empty());
14796 })
14797 .expect("small-stack thread should start")
14798 .join()
14799 .expect("deferred rules should materialize without recursion");
14800 }
14801
14802 #[test]
14803 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
14804 const REPETITIONS: usize = 64;
14805
14806 let atn = ambiguous_ordinary_star_loop_atn();
14807 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
14808 let tree = parser
14809 .parse_atn_rule(&atn, 0)
14810 .expect("ambiguous ordinary repetition should parse");
14811
14812 let root = parser
14813 .node(tree)
14814 .as_rule()
14815 .expect("entry result should be a rule");
14816 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
14817 assert_eq!(parser.input.index(), REPETITIONS);
14818 assert!(
14819 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
14820 "equivalent segmentations should keep deferred storage linear"
14821 );
14822 assert_eq!(parser.number_of_syntax_errors(), 0);
14823 }
14824
14825 #[test]
14826 fn long_ordinary_repetition_does_not_consume_native_stack() {
14827 const REPETITIONS: usize = 20_000;
14828
14829 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
14830 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
14831 parser.set_build_parse_trees(false);
14832 parser
14833 .parse_atn_rule(&atn, 0)
14834 .expect("long ordinary repetition should parse");
14835
14836 assert_eq!(parser.input.index(), REPETITIONS);
14837 assert_eq!(parser.number_of_syntax_errors(), 0);
14838 }
14839 }
14840
14841 #[test]
14842 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
14843 const REPETITIONS: usize = 2_000;
14844 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
14845
14846 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
14847 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
14848 let tree = parser
14849 .parse_atn_rule(&atn, 0)
14850 .expect("long rule repetition should parse");
14851
14852 let root = parser
14853 .node(tree)
14854 .as_rule()
14855 .expect("entry result should be a rule");
14856 assert_eq!(root.text(), expected_text);
14857 assert_eq!(root.child_rules(1).count(), REPETITIONS);
14858 let first_body = root.child_rules(1).next().expect("first body rule");
14859 let last_body = root.child_rules(1).next_back().expect("last body rule");
14860 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
14861 assert_eq!(
14862 last_body.stop_id().expect("last body stop").index(),
14863 REPETITIONS - 1
14864 );
14865
14866 let stats = parser.recognition_arena_stats();
14867 assert_eq!(
14868 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
14869 (REPETITIONS, REPETITIONS, 0)
14870 );
14871 assert_eq!(
14872 (stats.total_links, stats.live_links, stats.dead_links),
14873 (REPETITIONS, REPETITIONS, 0)
14874 );
14875 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
14876 assert_eq!(
14877 parser.recognition_arena.deferred_nodes.len(),
14878 REPETITIONS * 2 - 1
14879 );
14880 assert_eq!(parser.number_of_syntax_errors(), 0);
14881 }
14882 }
14883
14884 #[test]
14885 fn single_outcome_memo_probe_selects_sparse_or_promote_mode() {
14886 let key = |state_number| FastRecognizeKey {
14887 state_number,
14888 stop_state: 10,
14889 index: state_number,
14890 rule_start_index: 0,
14891 decision_start_index: None,
14892 precedence: 0,
14893 recovery_symbols_id: 0,
14894 recovery_state: None,
14895 };
14896
14897 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14898 for state_number in 0..(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT - 1) {
14899 assert!(sparse.should_memoize_single_outcome(&key(state_number)));
14900 }
14901 assert!(!sparse.should_memoize_single_outcome(&key(CLEAN_SINGLE_OUTCOME_MEMO_PROBE_LIMIT)));
14902 assert_eq!(
14903 sparse.single_outcome_memo_mode,
14904 SingleOutcomeMemoMode::Sparse
14905 );
14906
14907 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14908 let repeated = key(1);
14909 for _ in 0..=CLEAN_SINGLE_OUTCOME_MEMO_REPEAT_LIMIT {
14910 assert!(promote.should_memoize_single_outcome(&repeated));
14911 }
14912 assert_eq!(
14913 promote.single_outcome_memo_mode,
14914 SingleOutcomeMemoMode::Promote
14915 );
14916 }
14917
14918 #[test]
14919 fn clean_empty_multi_alt_outcomes_are_memoized() {
14920 let mut atn = ParserAtnBuilder::new(2);
14921 assert_eq!(
14922 atn.add_state(AtnStateKind::RuleStart, Some(0))
14923 .expect("state")
14924 .index(),
14925 0
14926 );
14927 assert_eq!(
14928 atn.add_state(AtnStateKind::BlockStart, Some(0))
14929 .expect("state")
14930 .index(),
14931 1
14932 );
14933 assert_eq!(
14934 atn.add_state(AtnStateKind::RuleStop, Some(0))
14935 .expect("state")
14936 .index(),
14937 2
14938 );
14939 atn.set_rule_to_start_state(vec![0])
14940 .expect("rule start states");
14941 atn.set_rule_to_stop_state(vec![2])
14942 .expect("rule stop states");
14943 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14944 .expect("transition");
14945 atn.add_transition(
14946 1,
14947 ParserTransitionSpec::Atom {
14948 target: 2,
14949 label: 1,
14950 },
14951 )
14952 .expect("transition");
14953 atn.add_transition(
14954 1,
14955 ParserTransitionSpec::Atom {
14956 target: 2,
14957 label: 2,
14958 },
14959 )
14960 .expect("transition");
14961 let atn = finish_atn(atn);
14962
14963 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
14964 parser.fast_recovery_enabled = false;
14965 let mut visiting = FxHashSet::default();
14966 let mut memo = FxHashMap::default();
14967 let mut expected = ExpectedTokens::default();
14968 let outcomes = parser.recognize_state_fast(
14969 &atn,
14970 FastRecognizeRequest {
14971 state_number: 1,
14972 stop_state: 2,
14973 index: 0,
14974 rule_start_index: 0,
14975 decision_start_index: None,
14976 precedence: 0,
14977 depth: 0,
14978 recovery_symbols: parser.empty_recovery_symbols(),
14979 recovery_state: None,
14980 },
14981 FastRecognizeScratch {
14982 predicate_context: None,
14983 visiting: &mut visiting,
14984 memo: &mut memo,
14985 expected: &mut expected,
14986 },
14987 );
14988
14989 assert!(outcomes.is_empty());
14990 assert_eq!(memo.len(), 1);
14991 assert!(memo.values().next().expect("memo entry").is_empty());
14992 }
14993
14994 #[test]
14995 fn wildcard_matches_non_eof_only() {
14996 let mut parser = mini_parser(vec![
14997 TestToken::new(1).with_text("x"),
14998 TestToken::eof("parser-test", 1, 1, 1),
14999 ]);
15000 let matched = parser.match_wildcard().expect("wildcard");
15001 assert_eq!(parser.node(matched).text(), "x");
15002 assert!(parser.match_wildcard().is_err());
15003 }
15004
15005 #[test]
15006 fn add_parse_child_records_match_even_without_tree_building() {
15007 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15012 let token = TestToken::new(1).with_text("x");
15013
15014 parser.set_build_parse_trees(false);
15015 let mut ctx = ParserRuleContext::new(0, 0);
15016 assert!(!ctx.has_matched_child());
15017 let child = parser.terminal_tree(token.id);
15018 parser.add_parse_child(&mut ctx, child);
15019 assert_eq!(ctx.child_count(), 0);
15021 assert_eq!(parser.parse_tree_storage().node_count(), 0);
15022 assert!(ctx.has_matched_child());
15024
15025 parser.set_build_parse_trees(true);
15027 let mut ctx = ParserRuleContext::new(0, 0);
15028 let child = parser.terminal_tree(token.id);
15029 parser.add_parse_child(&mut ctx, child);
15030 assert_eq!(ctx.child_count(), 1);
15031 assert!(ctx.has_matched_child());
15032 }
15033
15034 #[test]
15035 fn disabled_tree_building_does_not_grow_flat_storage() {
15036 let mut parser = mini_parser(vec![
15037 TestToken::new(1).with_text("x"),
15038 TestToken::new(1).with_text("y"),
15039 TestToken::eof("parser-test", 2, 1, 2),
15040 ]);
15041 parser.set_build_parse_trees(false);
15042 let mut context = ParserRuleContext::new(0, -1);
15043
15044 for _ in 0..2 {
15045 let child = parser.match_token(1).expect("token should match");
15046 parser.add_parse_child(&mut context, child);
15047 }
15048 let current = parser.input.lt_id(1).expect("EOF token");
15049 let error = parser.error_tree(current);
15050 parser.add_parse_child(&mut context, error);
15051 let root = parser.rule_node(context);
15052
15053 assert_eq!(
15054 parser.parse_tree_storage().stats(),
15055 ParseTreeStats::default()
15056 );
15057 assert!(
15058 parser
15059 .parse_tree_storage()
15060 .node(parser.token_store(), root)
15061 .is_none(),
15062 "the no-tree sentinel must not resolve to stored data"
15063 );
15064 }
15065
15066 #[test]
15067 fn parser_interprets_simple_atn_rule() {
15068 let atn = token_then_eof_atn();
15069 let mut parser = mini_parser(vec![
15070 TestToken::new(1).with_text("x"),
15071 TestToken::eof("parser-test", 1, 1, 1),
15072 ]);
15073
15074 let tree = parser
15075 .parse_atn_rule(&atn, 0)
15076 .expect("artificial parser rule should parse");
15077 assert_eq!(parser.node(tree).text(), "x<EOF>");
15078 assert_eq!(parser.number_of_syntax_errors(), 0);
15079 assert_eq!(
15080 parser
15081 .node(tree)
15082 .first_rule_stop(0)
15083 .expect("rule should stop at EOF")
15084 .token_type(),
15085 TOKEN_EOF
15086 );
15087
15088 let mut parser = mini_parser(vec![
15089 TestToken::new(1).with_text("x"),
15090 TestToken::eof("parser-test", 1, 1, 1),
15091 ]);
15092 let (tree, actions) = parser
15093 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15094 .expect("runtime-option parser rule should parse");
15095 assert!(actions.is_empty());
15096 assert_eq!(
15097 parser
15098 .node(tree)
15099 .first_rule_stop(0)
15100 .expect("rule should stop at EOF")
15101 .token_type(),
15102 TOKEN_EOF
15103 );
15104 }
15105
15106 #[test]
15107 fn runtime_options_default_ignores_noop_action_transitions() {
15108 let atn = noop_action_then_token_then_eof_atn();
15109 let mut parser = mini_parser(vec![
15110 TestToken::new(1).with_text("x"),
15111 TestToken::eof("parser-test", 1, 1, 1),
15112 ]);
15113
15114 let (tree, actions) = parser
15115 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15116 .expect("no-op parser action should not force action replay");
15117
15118 assert_eq!(parser.node(tree).text(), "x<EOF>");
15119 assert!(
15120 actions.is_empty(),
15121 "action_index=None transitions are ANTLR metadata, not replay actions"
15122 );
15123 assert_eq!(parser.number_of_syntax_errors(), 0);
15124 }
15125
15126 #[test]
15127 fn parser_exposes_buffered_token_stream_after_parse() {
15128 let atn = token_then_eof_atn();
15129 let mut parser = mini_parser(vec![
15130 TestToken::new(1).with_text("x"),
15131 TestToken::eof("parser-test", 1, 1, 1),
15132 ]);
15133
15134 let tree = parser
15135 .parse_atn_rule(&atn, 0)
15136 .expect("artificial parser rule should parse");
15137 assert_eq!(parser.node(tree).text(), "x<EOF>");
15138
15139 let stream = parser.token_stream();
15140 let source_index_after_parse = stream.token_source().index;
15141 let buffered = stream.tokens().collect::<Vec<_>>();
15142 assert_eq!(buffered.len(), 2);
15143 assert_eq!(buffered[0].text(), "x");
15144 assert_eq!(buffered[0].token_id().index(), 0);
15145 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
15146 assert_eq!(stream.token_source().index, source_index_after_parse);
15147 drop(buffered);
15148
15149 let stream = parser.into_token_stream();
15150 assert_eq!(stream.token_source().index, source_index_after_parse);
15151 assert_eq!(stream.tokens().next().expect("first token").text(), "x");
15152 assert_eq!(
15153 stream.tokens().nth(1).expect("EOF token").token_type(),
15154 TOKEN_EOF
15155 );
15156 }
15157
15158 #[test]
15159 fn parser_syntax_error_count_tracks_interpreted_recovery() {
15160 let atn = token_then_eof_atn();
15161 let mut parser = mini_parser(vec![
15162 TestToken::new(1).with_text("x"),
15163 TestToken::new(2).with_text("y"),
15164 TestToken::eof("parser-test", 2, 1, 2),
15165 ]);
15166
15167 let tree = parser
15168 .parse_atn_rule(&atn, 0)
15169 .expect("invalid token should recover into an error node");
15170
15171 assert_eq!(parser.number_of_syntax_errors(), 1);
15172 assert_eq!(
15173 parser
15174 .node(tree)
15175 .first_error_token()
15176 .expect("recovery should embed an error token")
15177 .text(),
15178 "y"
15179 );
15180 }
15181
15182 #[test]
15183 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
15184 let atn = token_then_eof_atn();
15185 let mut parser = mini_parser(vec![
15186 TestToken::new(2).with_text("y"),
15187 TestToken::eof("parser-test", 1, 1, 1),
15188 ]);
15189
15190 let error = parser
15191 .parse_atn_rule(&atn, 0)
15192 .expect_err("start-rule mismatch should remain a parser error");
15193
15194 assert_eq!(parser.number_of_syntax_errors(), 1);
15195 assert!(matches!(error, AntlrError::ParserError { .. }));
15196 }
15197
15198 #[test]
15199 fn adaptive_direct_rule_uses_simulator_decision() {
15200 let atn = two_alt_decision_atn();
15201 let mut simulator = ParserAtnSimulator::new(&atn);
15202 let mut parser = mini_parser(vec![
15203 TestToken::new(2).with_text("y"),
15204 TestToken::eof("parser-test", 1, 1, 1),
15205 ]);
15206
15207 let tree = parser
15208 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
15209 .expect("direct adaptive rule should parse");
15210
15211 assert_eq!(parser.node(tree).text(), "y");
15212 assert_eq!(parser.input.index(), 1);
15213 }
15214
15215 #[test]
15216 fn adaptive_direct_rule_restores_input_on_fallback() {
15217 let atn = predicate_after_token_atn();
15218 let mut simulator = ParserAtnSimulator::new(&atn);
15219 let mut parser = mini_parser(vec![
15220 TestToken::new(1).with_text("x"),
15221 TestToken::new(2).with_text("y"),
15222 TestToken::eof("parser-test", 2, 1, 2),
15223 ]);
15224
15225 let tree = parser
15226 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
15227 .expect("fallback recognizer should parse");
15228
15229 assert_eq!(parser.node(tree).text(), "xy");
15230 assert_eq!(parser.input.index(), 2);
15231 let stats = parser.parse_tree_storage().stats();
15232 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
15233 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
15234 assert_eq!(stats.scratch_links, 0);
15235 }
15236
15237 #[test]
15238 fn unknown_predicate_policy_defaults_to_assume_true() {
15239 let atn = predicate_after_token_atn();
15240 let mut parser = mini_parser(vec![
15241 TestToken::new(1).with_text("x"),
15242 TestToken::new(2).with_text("y"),
15243 TestToken::eof("parser-test", 2, 1, 2),
15244 ]);
15245
15246 let (tree, _) = parser
15247 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15248 .expect("unknown predicate should pass under the default policy");
15249
15250 assert_eq!(parser.node(tree).text(), "xy");
15251 assert_eq!(parser.number_of_syntax_errors(), 0);
15252 }
15253
15254 #[test]
15255 fn predicate_gated_same_lookahead_uses_viable_alternative() {
15256 let atn = predicate_gated_same_lookahead_atn([0, 1]);
15257 let mut parser = mini_parser(vec![
15258 TestToken::new(1).with_text("x"),
15259 TestToken::eof("parser-test", 1, 1, 1),
15260 ]);
15261
15262 let (tree, _) = parser
15263 .parse_atn_rule_with_runtime_options(
15264 &atn,
15265 0,
15266 ParserRuntimeOptions {
15267 predicates: &[
15268 (0, 0, ParserPredicate::False),
15269 (0, 1, ParserPredicate::True),
15270 ],
15271 ..ParserRuntimeOptions::default()
15272 },
15273 )
15274 .expect("the second predicate-gated alternative should match");
15275
15276 assert_eq!(parser.node(tree).text(), "x<EOF>");
15277 assert_eq!(parser.number_of_syntax_errors(), 0);
15278 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
15279 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
15280 }
15281
15282 #[test]
15283 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
15284 let atn = token_then_eof_atn();
15288 let mut parser = mini_parser(vec![
15289 TestToken::new(1).with_text("x"),
15290 TestToken::eof("parser-test", 1, 1, 1),
15291 ]);
15292
15293 parser.unknown_predicate_hits.push((7, 3));
15295
15296 parser
15298 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15299 .expect("child rule parses");
15300
15301 let error = parser
15303 .take_unknown_semantic_error()
15304 .expect("parent's recorded coordinate must survive the nested interpreted parse");
15305 let AntlrError::Unsupported(message) = error else {
15306 panic!("expected AntlrError::Unsupported, got {error:?}");
15307 };
15308 assert!(message.contains("pred_index=3"), "message: {message}");
15309 }
15310
15311 #[test]
15312 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
15313 let atn = predicate_after_token_atn();
15314 let mut parser = mini_parser(vec![
15315 TestToken::new(1).with_text("x"),
15316 TestToken::new(2).with_text("y"),
15317 TestToken::eof("parser-test", 2, 1, 2),
15318 ]);
15319
15320 let result = parser.parse_atn_rule_with_runtime_options(
15321 &atn,
15322 0,
15323 ParserRuntimeOptions {
15324 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
15325 ..ParserRuntimeOptions::default()
15326 },
15327 );
15328
15329 assert!(
15330 result.is_err(),
15331 "the only path is predicate-guarded, so assume-false must fail the parse"
15332 );
15333 }
15334
15335 #[test]
15336 fn predicate_failure_message_keeps_semantic_recovery_path() {
15337 let atn = predicate_after_token_atn();
15338 let mut parser = mini_parser(vec![
15339 TestToken::new(1).with_text("x"),
15340 TestToken::new(2).with_text("y"),
15341 TestToken::eof("parser-test", 2, 1, 2),
15342 ]);
15343
15344 let (tree, _) = parser
15345 .parse_atn_rule_with_runtime_options(
15346 &atn,
15347 0,
15348 ParserRuntimeOptions {
15349 predicates: &[(
15350 0,
15351 0,
15352 ParserPredicate::FalseWithMessage {
15353 message: "predicate rejected input",
15354 },
15355 )],
15356 ..ParserRuntimeOptions::default()
15357 },
15358 )
15359 .expect("failure-message predicates recover through the semantic interpreter");
15360
15361 assert_eq!(parser.node(tree).text(), "xy");
15362 assert_eq!(parser.number_of_syntax_errors(), 1);
15363 assert!(
15364 parser.fast_predicate_cache.is_empty(),
15365 "failure-message predicates need the semantic interpreter's recovery outcome"
15366 );
15367 }
15368
15369 #[test]
15370 fn unknown_predicate_policy_error_names_the_coordinate() {
15371 let atn = predicate_after_token_atn();
15372 let mut parser = mini_parser(vec![
15373 TestToken::new(1).with_text("x"),
15374 TestToken::new(2).with_text("y"),
15375 TestToken::eof("parser-test", 2, 1, 2),
15376 ]);
15377
15378 let error = parser
15379 .parse_atn_rule_with_runtime_options(
15380 &atn,
15381 0,
15382 ParserRuntimeOptions {
15383 unknown_predicate_policy: UnknownSemanticPolicy::Error,
15384 ..ParserRuntimeOptions::default()
15385 },
15386 )
15387 .expect_err("evaluating an unknown predicate under Error policy must fail");
15388
15389 let AntlrError::Unsupported(message) = error else {
15390 panic!("expected AntlrError::Unsupported, got {error:?}");
15391 };
15392 assert!(
15393 message.contains("unsupported semantic predicate"),
15394 "message should name the failure class: {message}"
15395 );
15396 assert!(
15397 message.contains("pred_index=0"),
15398 "message should carry the coordinate: {message}"
15399 );
15400 }
15401
15402 #[test]
15403 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
15404 let atn = predicate_after_token_atn();
15410 let mut parser = mini_parser(vec![
15411 TestToken::new(1).with_text("x"),
15412 TestToken::new(2).with_text("y"),
15413 TestToken::eof("parser-test", 2, 1, 2),
15414 ]);
15415
15416 parser
15417 .parse_atn_rule_with_runtime_options(
15418 &atn,
15419 0,
15420 ParserRuntimeOptions {
15421 unknown_predicate_policy: UnknownSemanticPolicy::Error,
15422 ..ParserRuntimeOptions::default()
15423 },
15424 )
15425 .expect_err("first parse fails loud under the Error policy");
15426
15427 parser.reset_unknown_semantic_hits();
15432 assert!(
15433 parser.take_unknown_semantic_error().is_none(),
15434 "reset must drop stale unknown-predicate coordinates before a reused parse"
15435 );
15436 }
15437
15438 #[derive(Debug, Default)]
15439 struct RecordingHooks {
15440 predicates: Vec<(usize, usize, usize, Option<String>)>,
15441 actions: Vec<(usize, String, Option<String>)>,
15442 action_trees: Vec<Option<String>>,
15443 }
15444
15445 impl SemanticHooks for RecordingHooks {
15446 fn sempred<S>(
15447 &mut self,
15448 ctx: &mut ParserSemCtx<'_, S>,
15449 rule_index: usize,
15450 pred_index: usize,
15451 ) -> Option<bool>
15452 where
15453 S: TokenSource,
15454 {
15455 self.predicates.push((
15456 ctx.input_index(),
15457 rule_index,
15458 pred_index,
15459 ctx.token_text(1).map(|token| token.text().to_owned()),
15460 ));
15461 Some(true)
15462 }
15463
15464 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
15465 where
15466 S: TokenSource,
15467 {
15468 self.actions.push((
15469 action.source_state(),
15470 ctx.action_text(),
15471 ctx.rule_name().map(str::to_owned),
15472 ));
15473 self.action_trees.push(ctx.tree().map(Node::text));
15474 true
15475 }
15476 }
15477
15478 #[derive(Debug, Default)]
15479 struct RejectingPredicateHooks {
15480 predicates: Vec<(usize, usize, usize, Option<String>)>,
15481 }
15482
15483 impl SemanticHooks for RejectingPredicateHooks {
15484 fn sempred<S>(
15485 &mut self,
15486 ctx: &mut ParserSemCtx<'_, S>,
15487 rule_index: usize,
15488 pred_index: usize,
15489 ) -> Option<bool>
15490 where
15491 S: TokenSource,
15492 {
15493 self.predicates.push((
15494 ctx.input_index(),
15495 rule_index,
15496 pred_index,
15497 ctx.token_text(1).map(|token| token.text().to_owned()),
15498 ));
15499 Some(false)
15500 }
15501 }
15502
15503 #[test]
15504 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
15505 let atn = predicate_gated_same_lookahead_atn([0, 0]);
15506 let mut parser = mini_parser_with_hooks(
15507 vec![
15508 TestToken::new(1).with_text("x"),
15509 TestToken::eof("parser-test", 1, 1, 1),
15510 ],
15511 RecordingHooks::default(),
15512 );
15513
15514 let (tree, _) = parser
15515 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15516 .expect("both alternatives share one replay-safe predicate result");
15517
15518 assert_eq!(parser.node(tree).text(), "x<EOF>");
15519 assert_eq!(
15520 parser.semantic_hooks.predicates,
15521 vec![(0, 0, 0, Some("x".to_owned()))]
15522 );
15523 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
15524 }
15525
15526 #[test]
15527 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
15528 let atn = predicate_after_token_atn();
15529 let mut parser = mini_parser_with_hooks(
15530 vec![
15531 TestToken::new(1).with_text("x"),
15532 TestToken::new(2).with_text("y"),
15533 TestToken::eof("parser-test", 2, 1, 2),
15534 ],
15535 RecordingHooks::default(),
15536 );
15537
15538 let (tree, _) = parser
15539 .parse_atn_rule_with_runtime_options(
15540 &atn,
15541 0,
15542 ParserRuntimeOptions {
15543 unknown_predicate_policy: UnknownSemanticPolicy::Error,
15544 ..ParserRuntimeOptions::default()
15545 },
15546 )
15547 .expect("hook supplies the missing predicate result");
15548
15549 assert_eq!(parser.node(tree).text(), "xy");
15550 assert_eq!(
15551 parser.semantic_hooks.predicates,
15552 vec![(1, 0, 0, Some("y".to_owned()))]
15553 );
15554 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
15555 }
15556
15557 #[test]
15558 fn runtime_options_default_preserves_semantic_hook_predicates() {
15559 let atn = predicate_after_token_atn();
15560 let mut parser = mini_parser_with_hooks(
15561 vec![
15562 TestToken::new(1).with_text("x"),
15563 TestToken::new(2).with_text("y"),
15564 TestToken::eof("parser-test", 2, 1, 2),
15565 ],
15566 RejectingPredicateHooks::default(),
15567 );
15568
15569 let result =
15570 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
15571
15572 assert!(
15573 result.is_err(),
15574 "default runtime options must not bypass semantic hooks for predicate ATNs"
15575 );
15576 assert_eq!(
15577 parser.semantic_hooks.predicates,
15578 vec![(1, 0, 0, Some("y".to_owned()))]
15579 );
15580 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
15581 }
15582
15583 #[test]
15584 fn semantic_hook_handles_committed_parser_action() {
15585 let atn = token_then_eof_atn();
15586 let mut parser = mini_parser_with_hooks(
15587 vec![
15588 TestToken::new(1).with_text("x"),
15589 TestToken::eof("parser-test", 1, 1, 1),
15590 ],
15591 RecordingHooks::default(),
15592 );
15593 let (tree, _) = parser
15594 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15595 .expect("rule parses before action hook is tested");
15596
15597 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
15598 assert_eq!(
15599 parser.semantic_hooks.actions,
15600 vec![(42, "x".to_owned(), Some("s".to_owned()))]
15601 );
15602 assert_eq!(
15603 parser.semantic_hooks.action_trees,
15604 [Some("x<EOF>".to_owned())]
15605 );
15606 }
15607
15608 #[test]
15609 fn unhandled_committed_action_fails_loud_under_error_policy() {
15610 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
15614 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
15615 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
15616
15617 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
15619
15620 let error = parser
15621 .take_unknown_semantic_error()
15622 .expect("an unhandled committed action under Error policy must fail loud");
15623 let AntlrError::Unsupported(message) = error else {
15624 panic!("expected AntlrError::Unsupported, got {error:?}");
15625 };
15626 assert!(
15627 message.contains("unhandled semantic action") && message.contains("state=42"),
15628 "message should name the dropped action coordinate: {message}"
15629 );
15630
15631 let mut lenient =
15633 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
15634 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
15635 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
15636 assert!(lenient.take_unknown_semantic_error().is_none());
15637 }
15638
15639 #[test]
15640 fn translated_predicate_is_unaffected_by_error_policy() {
15641 let atn = predicate_after_token_atn();
15642 let mut parser = mini_parser(vec![
15643 TestToken::new(1).with_text("x"),
15644 TestToken::new(2).with_text("y"),
15645 TestToken::eof("parser-test", 2, 1, 2),
15646 ]);
15647
15648 let (tree, _) = parser
15649 .parse_atn_rule_with_runtime_options(
15650 &atn,
15651 0,
15652 ParserRuntimeOptions {
15653 predicates: &[(0, 0, ParserPredicate::True)],
15654 unknown_predicate_policy: UnknownSemanticPolicy::Error,
15655 ..ParserRuntimeOptions::default()
15656 },
15657 )
15658 .expect("a predicate covered by the table is not an unknown coordinate");
15659
15660 assert_eq!(parser.node(tree).text(), "xy");
15661 }
15662
15663 fn hook_predicate_semantics() -> ParserSemantics {
15668 let mut ir = SemIr::new();
15669 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
15670 ParserSemantics {
15671 ir,
15672 predicates: vec![ParserSemanticPredicate {
15673 rule_index: 0,
15674 pred_index: 0,
15675 expr,
15676 failure_message: None,
15677 }],
15678 actions: Vec::new(),
15679 }
15680 }
15681
15682 #[derive(Debug, Default)]
15683 struct DecliningHooks;
15684
15685 impl SemanticHooks for DecliningHooks {}
15686
15687 #[test]
15688 fn semir_hook_none_falls_through_to_assume_true() {
15689 let atn = predicate_after_token_atn();
15690 let semantics = hook_predicate_semantics();
15691 let mut parser = mini_parser_with_hooks(
15692 vec![
15693 TestToken::new(1).with_text("x"),
15694 TestToken::new(2).with_text("y"),
15695 TestToken::eof("parser-test", 2, 1, 2),
15696 ],
15697 DecliningHooks,
15698 );
15699
15700 let (tree, _) = parser
15701 .parse_atn_rule_with_runtime_options(
15702 &atn,
15703 0,
15704 ParserRuntimeOptions {
15705 semantics: Some(&semantics),
15706 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
15707 ..ParserRuntimeOptions::default()
15708 },
15709 )
15710 .expect("a declined SemIR hook must pass under assume-true");
15711
15712 assert_eq!(parser.node(tree).text(), "xy");
15713 }
15714
15715 #[test]
15716 fn semir_hook_none_falls_through_to_assume_false() {
15717 let atn = predicate_after_token_atn();
15718 let semantics = hook_predicate_semantics();
15719 let mut parser = mini_parser_with_hooks(
15720 vec![
15721 TestToken::new(1).with_text("x"),
15722 TestToken::new(2).with_text("y"),
15723 TestToken::eof("parser-test", 2, 1, 2),
15724 ],
15725 DecliningHooks,
15726 );
15727
15728 let result = parser.parse_atn_rule_with_runtime_options(
15729 &atn,
15730 0,
15731 ParserRuntimeOptions {
15732 semantics: Some(&semantics),
15733 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
15734 ..ParserRuntimeOptions::default()
15735 },
15736 );
15737
15738 assert!(
15739 result.is_err(),
15740 "a declined SemIR hook must fail the only guarded path under assume-false"
15741 );
15742 }
15743
15744 #[test]
15745 fn semir_hook_none_records_coordinate_under_error_policy() {
15746 let atn = predicate_after_token_atn();
15747 let semantics = hook_predicate_semantics();
15748 let mut parser = mini_parser_with_hooks(
15749 vec![
15750 TestToken::new(1).with_text("x"),
15751 TestToken::new(2).with_text("y"),
15752 TestToken::eof("parser-test", 2, 1, 2),
15753 ],
15754 DecliningHooks,
15755 );
15756
15757 let error = parser
15758 .parse_atn_rule_with_runtime_options(
15759 &atn,
15760 0,
15761 ParserRuntimeOptions {
15762 semantics: Some(&semantics),
15763 unknown_predicate_policy: UnknownSemanticPolicy::Error,
15764 ..ParserRuntimeOptions::default()
15765 },
15766 )
15767 .expect_err("a declined SemIR hook under Error policy must fail the parse");
15768
15769 let AntlrError::Unsupported(message) = error else {
15770 panic!("expected AntlrError::Unsupported, got {error:?}");
15771 };
15772 assert!(
15773 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
15774 "message should name the unresolved coordinate: {message}"
15775 );
15776 }
15777
15778 #[test]
15779 fn generated_direct_predicate_honors_installed_policy() {
15780 let semantics = hook_predicate_semantics();
15786 let context = ParserRuleContext::new(0, -1);
15787
15788 let mut assume_true =
15789 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
15790 assert!(
15791 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
15792 &semantics, 0, 0, &context, 0
15793 ),
15794 "default AssumeTrue accepts a declined hook"
15795 );
15796 assert!(assume_true.take_unknown_semantic_error().is_none());
15797
15798 let mut error_policy =
15799 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
15800 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
15801 assert!(
15802 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
15803 &semantics, 0, 0, &context, 0
15804 ),
15805 "Error policy rejects a declined hook on the generated-direct path"
15806 );
15807 let error = error_policy
15808 .take_unknown_semantic_error()
15809 .expect("Error policy records the unresolved coordinate for the generated path");
15810 let AntlrError::Unsupported(message) = error else {
15811 panic!("expected AntlrError::Unsupported, got {error:?}");
15812 };
15813 assert!(message.contains("pred_index=0"), "message: {message}");
15814 }
15815
15816 #[test]
15817 fn parser_rule_start_skips_leading_hidden_tokens() {
15818 let atn = token_then_eof_atn();
15819 let mut parser = mini_parser(vec![
15820 TestToken::new(99)
15821 .with_text(" ")
15822 .with_channel(HIDDEN_CHANNEL),
15823 TestToken::new(1).with_text("x"),
15824 TestToken::eof("parser-test", 2, 1, 2),
15825 ]);
15826
15827 let tree = parser
15828 .parse_atn_rule(&atn, 0)
15829 .expect("artificial parser rule should parse");
15830 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
15831 panic!("rule node should be present");
15832 };
15833 assert_eq!(
15834 rule.start()
15835 .expect("rule should have a start token")
15836 .token_type(),
15837 1
15838 );
15839 }
15840
15841 #[test]
15842 fn parser_action_after_eof_stops_at_eof_token() {
15843 let atn = eof_then_action_atn();
15844 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
15845
15846 let (_, actions) = parser
15847 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15848 .expect("EOF action rule should parse");
15849
15850 assert_eq!(actions.len(), 1);
15851 assert_eq!(actions[0].stop_index(), Some(0));
15852 assert_eq!(
15853 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
15854 ""
15855 );
15856 }
15857
15858 #[test]
15859 fn after_action_stop_uses_rule_context_stop_not_cursor() {
15860 let mut id = TestToken::new(1).with_text("x");
15865 id.set_token_index(0);
15866 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
15867 eof.set_token_index(1);
15868 let mut parser = mini_parser(vec![id.clone(), eof]);
15869 parser.consume();
15871 assert_eq!(parser.la(1), TOKEN_EOF);
15872
15873 let mut ctx = ParserRuleContext::new(0, 0);
15876 parser.set_context_stop(
15877 &mut ctx,
15878 parser.token_id_at(0).expect("ID token should be buffered"),
15879 );
15880 let tree = parser.rule_node(ctx);
15881
15882 let current_index = parser.input.index();
15883 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
15885 assert_eq!(
15887 parser.after_action_stop_index_for_tree(tree, current_index),
15888 Some(0)
15889 );
15890 }
15891
15892 #[test]
15893 fn after_action_start_uses_rule_context_start_not_cursor() {
15894 let mut parser = mini_parser(vec![
15899 TestToken::new(9)
15900 .with_text(" ")
15901 .with_channel(HIDDEN_CHANNEL),
15902 TestToken::new(9)
15903 .with_text(" ")
15904 .with_channel(HIDDEN_CHANNEL),
15905 TestToken::new(1).with_text("x"),
15906 TestToken::eof("parser-test", 3, 1, 3),
15907 ]);
15908
15909 let mut ctx = ParserRuleContext::new(0, 0);
15910 parser.set_context_start(
15911 &mut ctx,
15912 parser.token_id_at(2).expect("ID token should be buffered"),
15913 );
15914 let tree = parser.rule_node(ctx);
15915
15916 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
15919
15920 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
15922 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
15923 }
15924
15925 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
15926 FastRecognizeOutcome {
15927 index,
15928 consumed_eof,
15929 diagnostics: DiagnosticSeqId::EMPTY,
15930 deferred_nodes: FastDeferredNodeId::EMPTY,
15931 nodes: NodeSeqId(marker),
15932 }
15933 }
15934
15935 #[test]
15936 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
15937 let mut outcomes = vec![
15938 clean_fast_outcome(4, false, 0),
15939 clean_fast_outcome(2, false, 1),
15940 clean_fast_outcome(4, false, 2),
15941 clean_fast_outcome(4, true, 3),
15942 clean_fast_outcome(2, false, 4),
15943 ];
15944 let mut scratch = FastOutcomeDedupScratch::default();
15945
15946 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
15947
15948 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
15949 assert_eq!(
15950 outcomes
15951 .iter()
15952 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
15953 .collect::<Vec<_>>(),
15954 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
15955 );
15956 assert!(scratch.dense_words.is_empty());
15957 assert!(scratch.sparse_keys.is_empty());
15958 }
15959
15960 #[test]
15961 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
15962 let mut scratch = FastOutcomeDedupScratch::default();
15963 let mut outcomes = (100..109)
15964 .flat_map(|index| {
15965 [
15966 clean_fast_outcome(
15967 index,
15968 false,
15969 u32::try_from(index).expect("test index fits in u32"),
15970 ),
15971 clean_fast_outcome(index, false, u32::MAX),
15972 ]
15973 })
15974 .collect();
15975
15976 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
15977
15978 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
15979 assert_eq!(outcomes.len(), 9);
15980 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
15981 let dense_capacity = scratch.dense_words.capacity();
15982
15983 let mut reused = (1_000..1_009)
15984 .map(|index| {
15985 clean_fast_outcome(
15986 index,
15987 false,
15988 u32::try_from(index).expect("test index fits in u32"),
15989 )
15990 })
15991 .collect();
15992 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
15993
15994 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
15995 assert_eq!(reused.len(), 9);
15996 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
15997 }
15998
15999 #[test]
16000 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
16001 let mut scratch = FastOutcomeDedupScratch::default();
16002 let sparse_indexes = [
16003 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
16004 ];
16005 let mut outcomes = sparse_indexes
16006 .into_iter()
16007 .chain([400_000])
16008 .enumerate()
16009 .map(|(marker, index)| {
16010 clean_fast_outcome(
16011 index,
16012 false,
16013 u32::try_from(marker).expect("test marker fits in u32"),
16014 )
16015 })
16016 .collect();
16017
16018 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16019
16020 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16021 assert_eq!(outcomes.len(), sparse_indexes.len());
16022 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
16023 let sparse_capacity = scratch.sparse_keys.capacity();
16024
16025 let mut reused = sparse_indexes
16026 .into_iter()
16027 .map(|index| {
16028 clean_fast_outcome(
16029 index,
16030 false,
16031 u32::try_from(index).expect("test index fits in u32"),
16032 )
16033 })
16034 .collect();
16035 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
16036
16037 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16038 assert_eq!(reused.len(), sparse_indexes.len());
16039 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
16040 }
16041
16042 #[test]
16043 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
16044 let mut scratch = FastOutcomeDedupScratch::default();
16045 scratch
16046 .sparse_keys
16047 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
16048 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
16049 let mut outcomes = (0..9)
16050 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
16051 .collect();
16052
16053 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16054
16055 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16056 assert!(scratch.sparse_keys.is_empty());
16057 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
16058 }
16059
16060 #[test]
16061 fn fast_outcome_selection_respects_sll_tie_order() {
16062 let mut arena = RecognitionArena::default();
16063 let first = FastRecognizeOutcome {
16064 index: 1,
16065 consumed_eof: false,
16066 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16067 line: 1,
16068 column: 0,
16069 message: "mismatched input 'x'".to_owned(),
16070 }]),
16071 deferred_nodes: FastDeferredNodeId::EMPTY,
16072 nodes: NodeSeqId::EMPTY,
16073 };
16074 let second = FastRecognizeOutcome {
16075 index: first.index,
16076 consumed_eof: first.consumed_eof,
16077 diagnostics: DiagnosticSeqId::EMPTY,
16078 deferred_nodes: FastDeferredNodeId::EMPTY,
16079 nodes: NodeSeqId::EMPTY,
16080 };
16081
16082 let selected = select_best_fast_outcome(
16083 [first, second].into_iter(),
16084 PredictionMode::Sll,
16085 None,
16086 |_| panic!("caller-follow token probe should not run"),
16087 &arena,
16088 )
16089 .expect("one outcome should be selected");
16090 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
16091 let eof_second = FastRecognizeOutcome {
16092 index: second.index,
16093 consumed_eof: true,
16094 diagnostics: DiagnosticSeqId::EMPTY,
16095 deferred_nodes: FastDeferredNodeId::EMPTY,
16096 nodes: NodeSeqId::EMPTY,
16097 };
16098 let selected = select_best_fast_outcome(
16099 [first, eof_second].into_iter(),
16100 PredictionMode::Sll,
16101 None,
16102 |_| panic!("caller-follow token probe should not run"),
16103 &arena,
16104 )
16105 .expect("one outcome should be selected");
16106 assert!(!selected.consumed_eof);
16107 let selected = select_best_fast_outcome(
16108 [first, second].into_iter(),
16109 PredictionMode::Ll,
16110 None,
16111 |_| panic!("caller-follow token probe should not run"),
16112 &arena,
16113 )
16114 .expect("one outcome should be selected");
16115 assert!(selected.diagnostics.is_empty());
16116 }
16117
16118 #[test]
16119 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
16120 let mut arena = RecognitionArena::default();
16121 let first = FastRecognizeOutcome {
16122 index: 3,
16123 consumed_eof: false,
16124 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16125 line: 1,
16126 column: 0,
16127 message: "mismatched input 'x' expecting 'a'".to_owned(),
16128 }]),
16129 deferred_nodes: FastDeferredNodeId::EMPTY,
16130 nodes: NodeSeqId::EMPTY,
16131 };
16132 let same_rank = FastRecognizeOutcome {
16133 index: first.index,
16134 consumed_eof: first.consumed_eof,
16135 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16136 line: 1,
16137 column: 0,
16138 message: "mismatched input 'x' expecting 'b'".to_owned(),
16139 }]),
16140 deferred_nodes: FastDeferredNodeId::EMPTY,
16141 nodes: NodeSeqId::EMPTY,
16142 };
16143 let better_rank = FastRecognizeOutcome {
16144 index: first.index,
16145 consumed_eof: first.consumed_eof,
16146 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16147 line: 1,
16148 column: 0,
16149 message: "missing 'a' at 'x'".to_owned(),
16150 }]),
16151 deferred_nodes: FastDeferredNodeId::EMPTY,
16152 nodes: NodeSeqId::EMPTY,
16153 };
16154 let mut outcomes = vec![first, same_rank, better_rank];
16155
16156 dedupe_fast_outcomes(&mut outcomes, &arena);
16157
16158 assert_eq!(outcomes.len(), 2);
16159 assert_eq!(
16160 arena
16161 .diagnostics(outcomes[0].diagnostics)
16162 .next()
16163 .expect("first diagnostic")
16164 .message,
16165 "mismatched input 'x' expecting 'a'"
16166 );
16167 assert_eq!(
16168 arena
16169 .diagnostics(outcomes[1].diagnostics)
16170 .next()
16171 .expect("second diagnostic")
16172 .message,
16173 "missing 'a' at 'x'"
16174 );
16175 }
16176
16177 #[test]
16178 fn fast_outcome_selection_prefers_generated_caller_follow() {
16179 let arena = RecognitionArena::default();
16180 let earlier = FastRecognizeOutcome {
16181 index: 7,
16182 consumed_eof: false,
16183 diagnostics: DiagnosticSeqId::EMPTY,
16184 deferred_nodes: FastDeferredNodeId::EMPTY,
16185 nodes: NodeSeqId::EMPTY,
16186 };
16187 let later = FastRecognizeOutcome {
16188 index: 8,
16189 consumed_eof: false,
16190 diagnostics: DiagnosticSeqId::EMPTY,
16191 deferred_nodes: FastDeferredNodeId::EMPTY,
16192 nodes: NodeSeqId::EMPTY,
16193 };
16194 let mut follow = TokenBitSet::default();
16195 follow.insert(5);
16196
16197 let selected = select_best_fast_outcome(
16198 [later, earlier].into_iter(),
16199 PredictionMode::Ll,
16200 Some(&follow),
16201 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
16202 &arena,
16203 )
16204 .expect("one outcome should be selected");
16205 assert_eq!(selected.index, 7);
16206
16207 let selected = select_best_fast_outcome(
16208 [later, earlier].into_iter(),
16209 PredictionMode::Ll,
16210 Some(&follow),
16211 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
16212 &arena,
16213 )
16214 .expect("one outcome should be selected");
16215 assert_eq!(selected.index, 8);
16216
16217 let indented_next_statement = FastRecognizeOutcome {
16218 index: 9,
16219 consumed_eof: false,
16220 diagnostics: DiagnosticSeqId::EMPTY,
16221 deferred_nodes: FastDeferredNodeId::EMPTY,
16222 nodes: NodeSeqId::EMPTY,
16223 };
16224 let selected = select_best_fast_outcome(
16225 [indented_next_statement, earlier].into_iter(),
16226 PredictionMode::Ll,
16227 Some(&follow),
16228 |index| {
16229 let is_boundary = index == 7;
16230 let is_boundary_gap = matches!(index, 7 | 8);
16231 (
16232 if index == 7 { 5 } else { TOKEN_EOF },
16233 is_boundary,
16234 is_boundary_gap,
16235 )
16236 },
16237 &arena,
16238 )
16239 .expect("one outcome should be selected");
16240 assert_eq!(selected.index, 7);
16241
16242 let continuation = FastRecognizeOutcome {
16243 index: 10,
16244 consumed_eof: false,
16245 diagnostics: DiagnosticSeqId::EMPTY,
16246 deferred_nodes: FastDeferredNodeId::EMPTY,
16247 nodes: NodeSeqId::EMPTY,
16248 };
16249 let selected = select_best_fast_outcome(
16250 [continuation, earlier].into_iter(),
16251 PredictionMode::Ll,
16252 Some(&follow),
16253 |index| {
16254 let is_boundary = matches!(index, 7 | 9);
16255 (
16256 if index == 7 { 5 } else { TOKEN_EOF },
16257 is_boundary,
16258 is_boundary,
16259 )
16260 },
16261 &arena,
16262 )
16263 .expect("one outcome should be selected");
16264 assert_eq!(selected.index, 10);
16265
16266 let selected = select_best_fast_outcome(
16267 [earlier, later].into_iter(),
16268 PredictionMode::Sll,
16269 Some(&follow),
16270 |_| panic!("caller-follow token probe should not run in SLL mode"),
16271 &arena,
16272 )
16273 .expect("one outcome should be selected");
16274 assert_eq!(selected.index, 8);
16275 }
16276
16277 #[test]
16278 fn caller_follow_boundary_text_requires_separator_shape() {
16279 assert!(is_caller_follow_boundary_text(";"));
16280 assert!(is_caller_follow_boundary_text("\n"));
16281 assert!(is_caller_follow_boundary_text("\r\n "));
16282 assert!(is_caller_follow_boundary_text(";\n"));
16283 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
16284 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
16285 assert!(!is_caller_follow_boundary_text("identifier"));
16286 assert!(is_caller_follow_boundary_gap_text(" \t "));
16287 assert!(is_caller_follow_boundary_gap_text("\n "));
16288 assert!(is_caller_follow_boundary_gap_text(";\t"));
16289 assert!(!is_caller_follow_boundary_gap_text(
16290 "\"\"\"line1\nline2\"\"\""
16291 ));
16292 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
16293 }
16294
16295 #[test]
16296 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
16297 let mut parser = mini_parser(vec![
16298 TestToken::new(5).with_text("\n"),
16299 TestToken::new(6)
16300 .with_text("// comment\n")
16301 .with_channel(HIDDEN_CHANNEL),
16302 TestToken::new(1).with_text("x"),
16303 TestToken::eof("parser-test", 1, 2, 0),
16304 ]);
16305
16306 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
16307 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
16308 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
16309 }
16310
16311 #[test]
16312 fn caller_follow_token_info_uses_stream_visible_channel() {
16313 let source = Source {
16314 tokens: vec![
16315 TestToken::new(5).with_text("\n").with_channel(2),
16316 TestToken::new(1).with_text("x").with_channel(2),
16317 TestToken::new(6)
16318 .with_text("// comment\n")
16319 .with_channel(HIDDEN_CHANNEL),
16320 TestToken::eof("parser-test", 1, 2, 0),
16321 ],
16322 index: 0,
16323 };
16324 let data = RecognizerData::new(
16325 "Mini.g4",
16326 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
16327 );
16328 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
16329
16330 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
16331 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
16332 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
16333 }
16334
16335 #[test]
16336 fn reset_per_parse_caches_clears_state_expected_token_cache() {
16337 let atn = token_then_eof_atn();
16338 let mut parser = mini_parser(Vec::new());
16339
16340 let _ = parser.cached_state_expected_token_set(&atn, 0);
16341 assert!(!parser.state_expected_token_cache.is_empty());
16342
16343 parser.reset_per_parse_caches();
16344 assert!(parser.state_expected_token_cache.is_empty());
16345 }
16346
16347 #[test]
16348 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
16349 let source = Source {
16350 tokens: vec![
16351 TestToken::new(1).with_text("x"),
16352 TestToken::eof("parser-test", 1, 1, 1),
16353 ],
16354 index: 0,
16355 };
16356 let data = RecognizerData::new(
16357 "Mini.g4",
16358 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
16359 );
16360 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
16361 let expected = ExpectedTokens {
16362 index: Some(0),
16363 symbols: BTreeSet::new(),
16364 no_viable: None,
16365 };
16366
16367 let (_, message) = parser.expected_error_message(0, 0, &expected);
16368
16369 assert_eq!(message, "mismatched input 'x'");
16370 }
16371
16372 #[test]
16373 fn eof_rule_stop_index_points_at_eof_token() {
16374 let source = Source {
16375 tokens: vec![
16376 TestToken::new(1).with_text("x"),
16377 TestToken::eof("parser-test", 1, 1, 1),
16378 ],
16379 index: 0,
16380 };
16381 let data = RecognizerData::new(
16382 "Mini.g4",
16383 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
16384 );
16385 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
16386
16387 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
16388 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
16389 }
16390
16391 #[test]
16392 fn generated_parser_action_uses_current_rule_stop_boundary() {
16393 let mut parser = mini_parser(vec![
16394 TestToken::new(1).with_text("x"),
16395 TestToken::eof("parser-test", 1, 1, 1),
16396 ]);
16397
16398 parser.match_token(1).expect("token should match");
16399 let action = parser.parser_action_at_current(7, 0, 0, false);
16400 assert_eq!(action.source_state(), 7);
16401 assert_eq!(action.rule_index(), 0);
16402 assert_eq!(action.start_index(), 0);
16403 assert_eq!(action.stop_index(), Some(0));
16404
16405 parser.match_eof().expect("EOF should match");
16406 let action = parser.parser_action_at_current(8, 0, 0, true);
16407 assert_eq!(action.stop_index(), Some(1));
16408 }
16409
16410 #[test]
16411 fn folds_left_recursive_boundary_into_rule_node() {
16412 let mut arena = RecognitionArena::default();
16413 let first = arena.push_node(ArenaRecognizedNode::Token {
16414 token: TokenId::try_from(0).expect("test token ID"),
16415 });
16416 let boundary =
16417 arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: 1 });
16418 let second = arena.push_node(ArenaRecognizedNode::Token {
16419 token: TokenId::try_from(1).expect("test token ID"),
16420 });
16421 let mut nodes = NodeSeqId::EMPTY;
16422 for node in [first, boundary, second].into_iter().rev() {
16423 nodes = arena.prepend(nodes, node);
16424 }
16425
16426 let folded = arena.fold_left_recursive_boundaries(nodes);
16427 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
16428
16429 assert_eq!(folded_nodes.len(), 2);
16430 let ArenaRecognizedNode::Rule {
16431 rule_index,
16432 invoking_state,
16433 start_index,
16434 stop_index,
16435 children,
16436 ..
16437 } = arena.node(folded_nodes[0])
16438 else {
16439 panic!("first folded node should be a rule");
16440 };
16441 assert_eq!(rule_index, 1);
16442 assert_eq!(invoking_state, -1);
16443 assert_eq!(start_index, 0);
16444 assert_eq!(stop_index, Some(0));
16445 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
16446 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
16447
16448 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
16449 assert_eq!(
16450 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
16451 (4, 3, 1)
16452 );
16453 assert_eq!(
16454 (stats.total_links, stats.live_links, stats.dead_links),
16455 (9, 3, 6)
16456 );
16457 }
16458
16459 #[test]
16460 fn recognition_arena_reports_live_dead_and_retained_capacity() {
16461 let mut arena = RecognitionArena::default();
16462 let token = arena.push_node(ArenaRecognizedNode::Token {
16463 token: TokenId::try_from(0).expect("test token ID"),
16464 });
16465 let extra = arena.push_extra(RecognitionExtra::MissingToken {
16466 token_type: 2,
16467 at_index: 1,
16468 text: "<missing X>".to_owned(),
16469 });
16470 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
16471 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
16472 token: TokenId::try_from(1).expect("test token ID"),
16473 });
16474 let mut live = NodeSeqId::EMPTY;
16475 live = arena.prepend(live, missing);
16476 live = arena.prepend(live, token);
16477 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
16478 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
16479 line: 1,
16480 column: 0,
16481 message: "missing X".to_owned(),
16482 }]);
16483 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
16484 line: 1,
16485 column: 1,
16486 message: "discarded".to_owned(),
16487 }]);
16488 let deferred_children = arena.deferred_fragment(live);
16489 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
16490 rule_index: 0,
16491 invoking_state: -1,
16492 start_index: 0,
16493 stop_index: Some(1),
16494 deferred_children,
16495 children: NodeSeqId::EMPTY,
16496 });
16497
16498 let stats = arena.stats(live, live_diagnostics);
16499
16500 assert_eq!(
16501 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
16502 (3, 2, 1)
16503 );
16504 assert_eq!(
16505 (stats.total_links, stats.live_links, stats.dead_links),
16506 (5, 3, 2)
16507 );
16508 assert_eq!(
16509 (stats.total_extras, stats.live_extras, stats.dead_extras),
16510 (3, 2, 1)
16511 );
16512 assert!(size_of::<SeqLink>() <= 8);
16513 assert!(size_of::<DiagnosticLink>() <= 8);
16514 assert!(size_of::<FastDeferredNode>() <= 12);
16515 assert!(size_of::<FastDeferredRule>() <= 28);
16516 assert!(size_of::<FastRecognizeOutcome>() <= 24);
16517 let capacities = (
16518 stats.node_capacity,
16519 stats.link_capacity,
16520 stats.extra_capacity,
16521 );
16522 let deferred_capacities = (
16523 arena.deferred_nodes.capacity(),
16524 arena.deferred_rules.capacity(),
16525 );
16526
16527 arena.reset();
16528 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
16529 assert_eq!(
16530 (reset.total_nodes, reset.total_links, reset.total_extras),
16531 (0, 0, 0)
16532 );
16533 assert_eq!(
16534 (
16535 reset.node_capacity,
16536 reset.link_capacity,
16537 reset.extra_capacity,
16538 ),
16539 capacities
16540 );
16541 assert!(arena.deferred_nodes.is_empty());
16542 assert!(arena.deferred_rules.is_empty());
16543 assert_eq!(
16544 (
16545 arena.deferred_nodes.capacity(),
16546 arena.deferred_rules.capacity(),
16547 ),
16548 deferred_capacities
16549 );
16550 }
16551
16552 #[test]
16553 fn parser_computes_recognition_arena_stats_on_demand() {
16554 let mut parser = mini_parser(Vec::new());
16555 let live = parser
16556 .recognition_arena
16557 .push_node(ArenaRecognizedNode::Token {
16558 token: TokenId::try_from(0).expect("test token ID"),
16559 });
16560 let discarded = parser
16561 .recognition_arena
16562 .push_node(ArenaRecognizedNode::ErrorToken {
16563 token: TokenId::try_from(1).expect("test token ID"),
16564 });
16565 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
16566 let _discarded_root = parser
16567 .recognition_arena
16568 .prepend(NodeSeqId::EMPTY, discarded);
16569 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
16570
16571 let stats = parser.recognition_arena_stats();
16572
16573 assert_eq!(
16574 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
16575 (2, 1, 1)
16576 );
16577 assert_eq!(
16578 (stats.total_links, stats.live_links, stats.dead_links),
16579 (2, 1, 1)
16580 );
16581 }
16582
16583 #[test]
16584 fn recognition_arena_drops_capacity_above_retention_limit() {
16585 let mut storage = Vec::<u8>::with_capacity(4);
16586 storage.extend([1, 2, 3]);
16587
16588 reset_arena_vec(&mut storage, 3);
16589
16590 assert!(storage.is_empty());
16591 assert_eq!(storage.capacity(), 0);
16592 }
16593
16594 #[test]
16595 fn recognition_arena_concatenates_diagnostics_in_source_order() {
16596 let mut arena = RecognitionArena::default();
16597 let prefix = arena.diagnostic_sequence([
16598 ParserDiagnostic {
16599 line: 1,
16600 column: 0,
16601 message: "first".to_owned(),
16602 },
16603 ParserDiagnostic {
16604 line: 1,
16605 column: 1,
16606 message: "second".to_owned(),
16607 },
16608 ]);
16609 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
16610 line: 1,
16611 column: 2,
16612 message: "third".to_owned(),
16613 }]);
16614 let extras_before = arena.extras.len();
16615
16616 let combined = arena.concat_diagnostics(prefix, suffix);
16617 let messages = arena
16618 .diagnostics(combined)
16619 .map(|diagnostic| diagnostic.message.as_str())
16620 .collect::<Vec<_>>();
16621
16622 assert_eq!(messages, ["first", "second", "third"]);
16623 assert_eq!(arena.extras.len(), extras_before);
16624 }
16625
16626 #[test]
16627 fn outcome_ties_keep_later_non_recursive_alternative() {
16628 let arena = RecognitionArena::default();
16629 let first = RecognizeOutcome {
16630 index: 1,
16631 consumed_eof: false,
16632 alt_number: 0,
16633 member_values: BTreeMap::new(),
16634 return_values: BTreeMap::new(),
16635 diagnostics: DiagnosticSeqId::EMPTY,
16636 decisions: Vec::new(),
16637 actions: vec![ParserAction::new(1, 0, 0, None)],
16638 nodes: NodeSeqId::EMPTY,
16639 };
16640 let second = RecognizeOutcome {
16641 actions: vec![ParserAction::new(2, 0, 0, None)],
16642 ..first.clone()
16643 };
16644
16645 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
16646 .expect("one outcome should be selected");
16647 assert_eq!(selected.actions[0].source_state(), 2);
16648 }
16649
16650 #[test]
16651 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
16652 let arena = RecognitionArena::default();
16653 let first = RecognizeOutcome {
16654 index: 1,
16655 consumed_eof: false,
16656 alt_number: 0,
16657 member_values: BTreeMap::new(),
16658 return_values: BTreeMap::new(),
16659 diagnostics: DiagnosticSeqId::EMPTY,
16660 decisions: Vec::new(),
16661 actions: vec![ParserAction::new(1, 0, 0, None)],
16662 nodes: NodeSeqId::EMPTY,
16663 };
16664 let second = RecognizeOutcome {
16665 actions: vec![
16666 ParserAction::new(2, 0, 0, None),
16667 ParserAction::new(3, 0, 0, None),
16668 ],
16669 ..first.clone()
16670 };
16671
16672 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
16673 .expect("one outcome should be selected");
16674 assert_eq!(selected.actions.len(), 2);
16675 }
16676
16677 #[test]
16678 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
16679 let arena = RecognitionArena::default();
16680 let first = RecognizeOutcome {
16681 index: 7,
16682 consumed_eof: false,
16683 alt_number: 0,
16684 member_values: BTreeMap::new(),
16685 return_values: BTreeMap::new(),
16686 diagnostics: DiagnosticSeqId::EMPTY,
16687 decisions: vec![1, 0],
16688 actions: vec![
16689 ParserAction::new(23, 2, 2, Some(4)),
16690 ParserAction::new(23, 2, 0, Some(6)),
16691 ],
16692 nodes: NodeSeqId::EMPTY,
16693 };
16694 let second = RecognizeOutcome {
16695 decisions: vec![0, 1],
16696 actions: vec![
16697 ParserAction::new(23, 2, 2, Some(6)),
16698 ParserAction::new(23, 2, 0, Some(6)),
16699 ],
16700 ..first.clone()
16701 };
16702
16703 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
16704 .expect("one outcome should be selected");
16705 assert_eq!(selected.actions[0].stop_index(), Some(6));
16706 }
16707
16708 #[test]
16709 fn outcome_ties_keep_first_recursive_tree_shape() {
16710 let mut arena = RecognitionArena::default();
16711 let token = arena.push_node(ArenaRecognizedNode::Token {
16712 token: TokenId::try_from(0).expect("test token ID"),
16713 });
16714 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
16715 let inner = arena.push_node(ArenaRecognizedNode::Rule {
16716 rule_index: 1,
16717 invoking_state: -1,
16718 alt_number: 0,
16719 start_index: 0,
16720 stop_index: Some(0),
16721 return_values: None,
16722 children: token_children,
16723 });
16724 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
16725 let outer = arena.push_node(ArenaRecognizedNode::Rule {
16726 rule_index: 1,
16727 invoking_state: -1,
16728 alt_number: 0,
16729 start_index: 0,
16730 stop_index: Some(0),
16731 return_values: None,
16732 children: inner_children,
16733 });
16734 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
16735 let first = RecognizeOutcome {
16736 index: 1,
16737 consumed_eof: false,
16738 alt_number: 0,
16739 member_values: BTreeMap::new(),
16740 return_values: BTreeMap::new(),
16741 diagnostics: DiagnosticSeqId::EMPTY,
16742 decisions: Vec::new(),
16743 actions: vec![ParserAction::new(1, 0, 0, None)],
16744 nodes: recursive_nodes,
16745 };
16746 let second = RecognizeOutcome {
16747 index: 1,
16748 consumed_eof: false,
16749 alt_number: 0,
16750 member_values: BTreeMap::new(),
16751 return_values: BTreeMap::new(),
16752 diagnostics: DiagnosticSeqId::EMPTY,
16753 decisions: Vec::new(),
16754 actions: vec![ParserAction::new(2, 0, 0, None)],
16755 nodes: recursive_nodes,
16756 };
16757
16758 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
16759 .expect("one outcome should be selected");
16760 assert_eq!(selected.actions[0].source_state(), 1);
16761 }
16762
16763 #[test]
16764 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
16765 let mut arena = RecognitionArena::default();
16766 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
16767 line: 1,
16768 column: 3,
16769 message: "missing 'Y' at '<EOF>'".to_owned(),
16770 }]);
16771 let first_alt = RecognizeOutcome {
16772 index: 2,
16773 consumed_eof: true,
16774 alt_number: 0,
16775 member_values: BTreeMap::new(),
16776 return_values: BTreeMap::new(),
16777 diagnostics: recovered_diagnostics,
16778 decisions: vec![0],
16779 actions: vec![ParserAction::new(1, 0, 0, None)],
16780 nodes: NodeSeqId::EMPTY,
16781 };
16782 let second_alt = RecognizeOutcome {
16783 diagnostics: DiagnosticSeqId::EMPTY,
16784 decisions: vec![1],
16785 actions: vec![ParserAction::new(2, 0, 0, None)],
16786 ..first_alt.clone()
16787 };
16788
16789 let selected = select_best_outcome(
16790 [second_alt, first_alt].into_iter(),
16791 PredictionMode::Sll,
16792 &arena,
16793 )
16794 .expect("one outcome should be selected");
16795 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
16796 assert_eq!(selected.decisions, [0]);
16797 }
16798}