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_MEMO_PROBE_LIMIT: usize = 4096;
114const CLEAN_MEMO_REPEAT_LIMIT: usize = 8;
115const CLEAN_MEMO_REPROBE_INTERVAL: usize = 262_144;
118const FAST_RECOGNIZE_VISITING_CAPACITY: usize = 256;
119const FAST_RECOGNIZE_MIN_MEMO_CAPACITY: usize = 256;
120const FAST_RECOGNIZE_MAX_MEMO_CAPACITY: usize = 524_288;
121const FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY: usize = 65_536;
122
123#[derive(Clone, Copy, Debug, Eq, PartialEq)]
124enum CleanMemoMode {
125 Probe,
126 Promote,
127 Sparse,
128}
129
130fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
131 intervals
132 .iter()
133 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
134}
135
136fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
137 let mut symbols = BTreeSet::new();
138 for (start, stop) in intervals {
139 symbols.extend(*start..=*stop);
140 }
141 symbols
142}
143
144fn interval_complement_symbols(
145 intervals: &[(i32, i32)],
146 min_vocabulary: i32,
147 max_vocabulary: i32,
148) -> BTreeSet<i32> {
149 (min_vocabulary..=max_vocabulary)
150 .filter(|symbol| !interval_set_contains(intervals, *symbol))
151 .collect()
152}
153
154#[cfg(feature = "perf-counters")]
155mod perf_counters {
156 use std::cell::Cell;
157 thread_local! {
158 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
159 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
160 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
161 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
162 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
163 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
164 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
165 pub(super) static OUTCOME_DEDUPE_INPUTS: Cell<u64> = const { Cell::new(0) };
166 pub(super) static OUTCOME_DEDUPE_REMOVED: Cell<u64> = const { Cell::new(0) };
167 pub(super) static OUTCOME_DEDUPE_INLINE: Cell<u64> = const { Cell::new(0) };
168 pub(super) static OUTCOME_DEDUPE_DENSE: Cell<u64> = const { Cell::new(0) };
169 pub(super) static OUTCOME_DEDUPE_SPARSE: Cell<u64> = const { Cell::new(0) };
170 pub(super) static OUTCOME_DEDUPE_DENSE_WORDS: Cell<u64> = const { Cell::new(0) };
171 }
172 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
173 c.with(|v| v.set(v.get() + n));
174 }
175 thread_local! {
176 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
177 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
178 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
179 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
180 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
181 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
182 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
183 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
184 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
185 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
186 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
187 }
188 pub(super) fn snapshot() -> [(&'static str, u64); 24] {
189 [
190 ("rfs_calls", RFS_CALLS.with(Cell::get)),
191 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
192 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
193 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
194 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
195 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
196 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
197 (
198 "outcome_dedupe_inputs",
199 OUTCOME_DEDUPE_INPUTS.with(Cell::get),
200 ),
201 (
202 "outcome_dedupe_removed",
203 OUTCOME_DEDUPE_REMOVED.with(Cell::get),
204 ),
205 (
206 "outcome_dedupe_inline",
207 OUTCOME_DEDUPE_INLINE.with(Cell::get),
208 ),
209 ("outcome_dedupe_dense", OUTCOME_DEDUPE_DENSE.with(Cell::get)),
210 (
211 "outcome_dedupe_sparse",
212 OUTCOME_DEDUPE_SPARSE.with(Cell::get),
213 ),
214 (
215 "outcome_dedupe_dense_words",
216 OUTCOME_DEDUPE_DENSE_WORDS.with(Cell::get),
217 ),
218 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
219 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
220 (
221 "atom_range_transitions",
222 ATOM_RANGE_TRANSITIONS.with(Cell::get),
223 ),
224 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
225 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
226 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
227 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
228 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
229 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
230 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
231 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
232 ]
233 }
234 pub fn reset() {
235 RFS_CALLS.with(|c| c.set(0));
236 RFS_MEMO_HITS.with(|c| c.set(0));
237 RFS_MEMO_MISSES.with(|c| c.set(0));
238 RFS_VISITING_CYCLE.with(|c| c.set(0));
239 MEMO_INSERTED.with(|c| c.set(0));
240 OUTCOMES_PUSHED.with(|c| c.set(0));
241 OUTCOMES_CLONED.with(|c| c.set(0));
242 OUTCOME_DEDUPE_INPUTS.with(|c| c.set(0));
243 OUTCOME_DEDUPE_REMOVED.with(|c| c.set(0));
244 OUTCOME_DEDUPE_INLINE.with(|c| c.set(0));
245 OUTCOME_DEDUPE_DENSE.with(|c| c.set(0));
246 OUTCOME_DEDUPE_SPARSE.with(|c| c.set(0));
247 OUTCOME_DEDUPE_DENSE_WORDS.with(|c| c.set(0));
248 EPSILON_TRANSITIONS.with(|c| c.set(0));
249 RULE_TRANSITIONS.with(|c| c.set(0));
250 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
251 SINGLE_TRANS_BODY.with(|c| c.set(0));
252 MULTI_TRANS_BODY.with(|c| c.set(0));
253 SINGLE_TRANS_RULE.with(|c| c.set(0));
254 SINGLE_TRANS_ATOM.with(|c| c.set(0));
255 SINGLE_TRANS_OTHER.with(|c| c.set(0));
256 OUTCOMES_RETURN_0.with(|c| c.set(0));
257 OUTCOMES_RETURN_1.with(|c| c.set(0));
258 OUTCOMES_RETURN_N.with(|c| c.set(0));
259 }
260 pub fn dump() {
261 for (name, value) in snapshot() {
262 #[allow(clippy::print_stderr)]
263 {
264 eprintln!("perf {name}={value}");
265 }
266 }
267 }
268}
269
270#[cfg(feature = "perf-counters")]
271pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
272const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
277#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
286pub struct ParserAction {
287 source_state: usize,
288 rule_index: usize,
289 start_index: usize,
290 stop_index: Option<usize>,
291 rule_init: bool,
292 expected_state: Option<usize>,
293}
294
295impl ParserAction {
296 pub const fn new(
298 source_state: usize,
299 rule_index: usize,
300 start_index: usize,
301 stop_index: Option<usize>,
302 ) -> Self {
303 Self {
304 source_state,
305 rule_index,
306 start_index,
307 stop_index,
308 rule_init: false,
309 expected_state: None,
310 }
311 }
312
313 pub const fn new_rule_init(
315 rule_index: usize,
316 start_index: usize,
317 expected_state: Option<usize>,
318 ) -> Self {
319 Self {
320 source_state: usize::MAX,
321 rule_index,
322 start_index,
323 stop_index: None,
324 rule_init: true,
325 expected_state,
326 }
327 }
328
329 pub const fn source_state(&self) -> usize {
331 self.source_state
332 }
333
334 pub const fn rule_index(&self) -> usize {
336 self.rule_index
337 }
338
339 pub const fn start_index(&self) -> usize {
341 self.start_index
342 }
343
344 pub const fn stop_index(&self) -> Option<usize> {
346 self.stop_index
347 }
348
349 pub const fn is_rule_init(&self) -> bool {
351 self.rule_init
352 }
353
354 pub const fn expected_state(&self) -> Option<usize> {
356 self.expected_state
357 }
358}
359
360pub struct ParserSemCtx<'a, S>
368where
369 S: TokenSource,
370{
371 input: &'a mut CommonTokenStream<S>,
372 tree_storage: &'a ParseTreeStorage,
373 rule_index: usize,
374 coordinate_index: usize,
375 rule_name: Option<String>,
376 context: Option<&'a ParserRuleContext>,
377 tree: Option<ParseTree>,
378 local_int_arg: Option<(usize, i64)>,
379 member_values: &'a BTreeMap<usize, i64>,
380 action: Option<ParserAction>,
381}
382
383impl<S> std::fmt::Debug for ParserSemCtx<'_, S>
384where
385 S: TokenSource,
386{
387 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
388 f.debug_struct("ParserSemCtx")
389 .field("rule_index", &self.rule_index)
390 .field("coordinate_index", &self.coordinate_index)
391 .field("rule_name", &self.rule_name)
392 .field("context", &self.context)
393 .field("tree", &self.tree)
394 .field("local_int_arg", &self.local_int_arg)
395 .field("member_values", &self.member_values)
396 .field("action", &self.action)
397 .finish_non_exhaustive()
398 }
399}
400
401impl<'a, S> ParserSemCtx<'a, S>
402where
403 S: TokenSource,
404{
405 #[must_use]
407 pub const fn rule_index(&self) -> usize {
408 self.rule_index
409 }
410
411 #[must_use]
413 pub fn rule_name(&self) -> Option<&str> {
414 self.rule_name.as_deref()
415 }
416
417 #[must_use]
421 pub const fn coordinate_index(&self) -> usize {
422 self.coordinate_index
423 }
424
425 #[must_use]
427 pub fn input_index(&self) -> usize {
428 self.input.index()
429 }
430
431 pub fn la(&mut self, offset: isize) -> i32 {
433 self.input.la(offset)
434 }
435
436 pub fn lt(&self, offset: isize) -> Option<TokenView<'_>> {
438 self.input.lt(offset)
439 }
440
441 pub fn token_text(&self, offset: isize) -> Option<TokenView<'_>> {
443 self.lt(offset)
444 }
445
446 pub fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
453 self.input.get(index)
454 }
455
456 #[must_use]
459 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
460 self.context
461 }
462
463 #[must_use]
465 pub const fn parse_tree_storage(&self) -> &'a ParseTreeStorage {
466 self.tree_storage
467 }
468
469 #[must_use]
471 pub const fn token_store(&self) -> &TokenStore {
472 self.input.token_store()
473 }
474
475 #[must_use]
477 pub const fn tree_id(&self) -> Option<NodeId> {
478 self.tree
479 }
480
481 #[must_use]
484 pub fn tree(&self) -> Option<Node<'_>> {
485 self.tree
486 .and_then(|id| self.tree_storage.node(self.input.token_store(), id))
487 }
488
489 #[must_use]
491 pub fn local_int_arg(&self) -> Option<i64> {
492 self.local_int_arg.map(|(_, value)| value)
493 }
494
495 #[must_use]
497 pub fn member_int(&self, member: usize) -> Option<i64> {
498 self.member_values.get(&member).copied()
499 }
500
501 #[must_use]
504 pub const fn action(&self) -> Option<ParserAction> {
505 self.action
506 }
507
508 pub fn action_text(&self) -> String {
516 let Some(action) = self.action else {
517 return String::new();
518 };
519 let Some(stop) = action.stop_index() else {
520 return String::new();
521 };
522 let stop = if self
523 .input
524 .get(stop)
525 .is_some_and(|token| token.token_type() == TOKEN_EOF)
526 {
527 let Some(previous) = self.input.previous_visible_token_index(stop) else {
528 return String::new();
529 };
530 previous
531 } else {
532 stop
533 };
534 self.input.text(action.start_index(), stop)
535 }
536}
537
538pub trait SemanticHooks {
545 const ENABLES_LEXER_LIFECYCLE: bool = true;
552
553 fn observes_parser_predicates(&self) -> bool {
558 true
559 }
560
561 fn sempred<S>(
562 &mut self,
563 ctx: &mut ParserSemCtx<'_, S>,
564 rule_index: usize,
565 pred_index: usize,
566 ) -> Option<bool>
567 where
568 S: TokenSource,
569 {
570 let _ = (ctx, rule_index, pred_index);
571 None
572 }
573
574 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
575 where
576 S: TokenSource,
577 {
578 let _ = (ctx, action);
579 false
580 }
581
582 fn lexer_sempred<I>(
583 &mut self,
584 ctx: &mut LexerSemCtx<'_, I>,
585 rule_index: usize,
586 pred_index: usize,
587 ) -> Option<bool>
588 where
589 I: CharStream,
590 {
591 let _ = (ctx, rule_index, pred_index);
592 None
593 }
594
595 fn lexer_action<I>(&mut self, ctx: &mut LexerSemCtx<'_, I>, action: LexerCustomAction) -> bool
605 where
606 I: CharStream,
607 {
608 let _ = (ctx, action);
609 false
610 }
611
612 fn lexer_reset<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
616 where
617 I: CharStream,
618 {
619 let _ = ctx;
620 }
621
622 fn lexer_before_token<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
628 where
629 I: CharStream,
630 {
631 let _ = ctx;
632 }
633
634 fn lexer_after_accept<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
643 where
644 I: CharStream,
645 {
646 let _ = ctx;
647 }
648
649 fn lexer_token_emitted(&mut self, token: TokenView<'_>) {
656 let _ = token;
657 }
658}
659
660#[derive(Clone, Copy, Debug, Default)]
663pub struct NoSemanticHooks;
664
665impl SemanticHooks for NoSemanticHooks {
666 const ENABLES_LEXER_LIFECYCLE: bool = false;
667
668 fn observes_parser_predicates(&self) -> bool {
669 false
670 }
671}
672
673#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
680pub enum ParserPredicate {
681 True,
682 False,
683 FalseWithMessage {
685 message: &'static str,
686 },
687 Invoke {
690 value: bool,
691 },
692 LookaheadTextEquals {
693 offset: isize,
694 text: &'static str,
695 },
696 LookaheadNotEquals {
697 offset: isize,
698 token_type: i32,
699 },
700 TokenPairAdjacent,
703 ContextChildRuleTextNotEquals {
708 rule_index: usize,
709 text: &'static str,
710 },
711 LocalIntEquals {
714 value: i64,
715 },
716 LocalIntLessOrEqual {
719 value: i64,
720 },
721 MemberModuloEquals {
723 member: usize,
724 modulus: i64,
725 value: i64,
726 equals: bool,
727 },
728 MemberEquals {
730 member: usize,
731 value: i64,
732 equals: bool,
733 },
734}
735
736impl ParserPredicate {
737 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
743 match self {
744 Self::True => ir.expr(PExpr::Bool(true)),
745 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
746 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
747 Self::LookaheadTextEquals { offset, text } => {
748 let token = ir.expr(PExpr::TokenText(offset));
749 let text = ir.intern(text);
750 let text = ir.expr(PExpr::Str(text));
751 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
752 }
753 Self::LookaheadNotEquals { offset, token_type } => {
754 let actual = ir.expr(PExpr::La(offset));
755 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
756 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
757 }
758 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
759 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
760 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
761 let expected = ir.intern(text);
762 let expected = ir.expr(PExpr::Str(expected));
763 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
764 }
765 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
766 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
767 Self::MemberModuloEquals {
768 member,
769 modulus,
770 value,
771 equals,
772 } => {
773 if modulus == 0 {
774 return ir.expr(PExpr::Bool(false));
775 }
776 let member = ir.expr(PExpr::Member(member));
777 let modulus = ir.expr(PExpr::Int(modulus));
778 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
779 let expected = ir.expr(PExpr::Int(value));
780 ir.expr(PExpr::Cmp(
781 if equals { CmpOp::Eq } else { CmpOp::Ne },
782 actual,
783 expected,
784 ))
785 }
786 Self::MemberEquals {
787 member,
788 value,
789 equals,
790 } => {
791 let actual = ir.expr(PExpr::Member(member));
792 let expected = ir.expr(PExpr::Int(value));
793 ir.expr(PExpr::Cmp(
794 if equals { CmpOp::Eq } else { CmpOp::Ne },
795 actual,
796 expected,
797 ))
798 }
799 }
800 }
801
802 #[must_use]
803 pub const fn failure_message(self) -> Option<&'static str> {
804 match self {
805 Self::FalseWithMessage { message } => Some(message),
806 Self::True
807 | Self::False
808 | Self::Invoke { .. }
809 | Self::LookaheadTextEquals { .. }
810 | Self::LookaheadNotEquals { .. }
811 | Self::TokenPairAdjacent
812 | Self::ContextChildRuleTextNotEquals { .. }
813 | Self::LocalIntEquals { .. }
814 | Self::LocalIntLessOrEqual { .. }
815 | Self::MemberModuloEquals { .. }
816 | Self::MemberEquals { .. } => None,
817 }
818 }
819}
820
821fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
822 let local = ir.expr(PExpr::LocalArg);
823 let absent = ir.expr(PExpr::IsNull(local));
824 let expected = ir.expr(PExpr::Int(value));
825 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
826 ir.expr(PExpr::Or([absent, comparison].into()))
827}
828
829#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
842pub enum UnknownSemanticPolicy {
843 #[default]
845 AssumeTrue,
846 AssumeFalse,
848 Error,
851}
852
853fn apply_unknown_predicate_policy(
862 policy: UnknownSemanticPolicy,
863 rule_index: usize,
864 pred_index: usize,
865 hits: &mut Vec<(usize, usize)>,
866) -> bool {
867 match policy {
868 UnknownSemanticPolicy::AssumeTrue => true,
869 UnknownSemanticPolicy::AssumeFalse => false,
870 UnknownSemanticPolicy::Error => {
871 let coordinate = (rule_index, pred_index);
872 if !hits.contains(&coordinate) {
873 hits.push(coordinate);
874 }
875 false
876 }
877 }
878}
879
880#[derive(Clone, Debug, Eq, PartialEq)]
884pub struct ExpectedTokenSet {
885 symbols: BTreeSet<i32>,
886}
887
888impl ExpectedTokenSet {
889 #[must_use]
891 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
892 expected_symbols_display(&self.symbols, vocabulary)
893 }
894}
895
896#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
901pub struct BailErrorStrategy;
902
903impl BailErrorStrategy {
904 #[must_use]
905 pub const fn new() -> Self {
906 Self
907 }
908}
909
910#[derive(Clone, Copy, Debug, Eq, PartialEq)]
912pub enum PredictionMode {
913 Ll,
916 Sll,
919 LlExactAmbigDetection,
921}
922
923#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
929pub struct ParserRuleArg {
930 pub source_state: usize,
932 pub rule_index: usize,
934 pub value: i64,
936 pub inherit_local: bool,
938}
939
940#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
942pub struct ParserMemberAction {
943 pub source_state: usize,
945 pub member: usize,
947 pub delta: i64,
949}
950
951#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
958pub struct ParserReturnAction {
959 pub source_state: usize,
961 pub rule_index: usize,
963 pub name: &'static str,
965 pub value: i64,
967}
968
969impl ParserMemberAction {
970 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
972 let delta = ir.expr(PExpr::Int(self.delta));
973 ParserSemanticAction {
974 source_state: self.source_state,
975 rule_index: usize::MAX,
976 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
977 speculative: true,
978 }
979 }
980}
981
982impl ParserReturnAction {
983 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
985 let name = ir.intern(self.name);
986 let value = ir.expr(PExpr::Int(self.value));
987 ParserSemanticAction {
988 source_state: self.source_state,
989 rule_index: self.rule_index,
990 stmt: ir.stmt(AStmt::SetReturn(name, value)),
991 speculative: false,
992 }
993 }
994}
995
996#[derive(Clone, Copy, Debug, Eq, PartialEq)]
998pub struct ParserSemanticPredicate {
999 pub rule_index: usize,
1001 pub pred_index: usize,
1003 pub expr: ExprId,
1005 pub failure_message: Option<&'static str>,
1007}
1008
1009#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1011pub struct ParserSemanticAction {
1012 pub source_state: usize,
1014 pub rule_index: usize,
1016 pub stmt: StmtId,
1018 pub speculative: bool,
1020}
1021
1022#[derive(Clone, Debug, Default, Eq, PartialEq)]
1029pub struct ParserSemantics {
1030 pub ir: SemIr,
1031 pub predicates: Vec<ParserSemanticPredicate>,
1032 pub actions: Vec<ParserSemanticAction>,
1033}
1034
1035#[derive(Clone, Copy, Debug, Default)]
1037pub struct ParserRuntimeOptions<'a> {
1038 pub init_action_rules: &'a [usize],
1040 pub track_alt_numbers: bool,
1042 pub predicates: &'a [(usize, usize, ParserPredicate)],
1044 pub semantics: Option<&'a ParserSemantics>,
1046 pub rule_args: &'a [ParserRuleArg],
1048 pub member_actions: &'a [ParserMemberAction],
1050 pub return_actions: &'a [ParserReturnAction],
1052 pub unknown_predicate_policy: UnknownSemanticPolicy,
1055}
1056
1057pub trait Parser: Recognizer {
1058 fn build_parse_trees(&self) -> bool;
1061
1062 fn set_build_parse_trees(&mut self, build: bool);
1064
1065 fn number_of_syntax_errors(&self) -> usize {
1068 0
1069 }
1070
1071 fn report_diagnostic_errors(&self) -> bool {
1074 false
1075 }
1076
1077 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
1080
1081 fn prediction_mode(&self) -> PredictionMode {
1083 PredictionMode::Ll
1084 }
1085
1086 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
1088}
1089
1090#[derive(Debug)]
1091struct LeftRecursiveCallerOverlap {
1092 atn_key: SharedAtnCacheKey,
1093 state_number: usize,
1094 symbol: i32,
1095 context_version: usize,
1096 overlaps: bool,
1097}
1098
1099const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
1100
1101#[derive(Debug)]
1102pub struct BaseParser<S, H = NoSemanticHooks> {
1103 input: CommonTokenStream<S>,
1104 tree: ParseTreeStorage,
1105 data: RecognizerData,
1106 semantic_hooks: H,
1107 build_parse_trees: bool,
1108 syntax_errors: usize,
1109 report_diagnostic_errors: bool,
1110 prediction_mode: PredictionMode,
1111 prediction_diagnostics: Vec<ParserDiagnostic>,
1112 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1113 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1114 generated_sync_expected: Option<TokenBitSet>,
1115 int_members: BTreeMap<usize, i64>,
1116 rule_context_stack: Vec<RuleContextFrame>,
1117 rule_context_version: usize,
1118 left_recursive_caller_overlap_cache:
1119 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1120 pending_invoking_states: Vec<isize>,
1121 precedence_stack: Vec<i32>,
1122 invoked_predicates: Vec<(usize, usize)>,
1126 bail_on_error: bool,
1130 unknown_predicate_policy: UnknownSemanticPolicy,
1133 unknown_predicate_hits: Vec<(usize, usize)>,
1136 unhandled_action_hits: Vec<(usize, usize)>,
1141 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1146 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1152 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1157 rule_stop_reach_cache: Vec<Option<bool>>,
1162 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1167 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1173 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1179 fast_predicate_cache: FxHashMap<(usize, usize, usize), bool>,
1183 empty_cycle_cache: Vec<Option<bool>>,
1189 empty_cycle_cache_atn: Option<SharedAtnCacheKey>,
1190 clean_memo_mode: CleanMemoMode,
1193 clean_memo_probe_seen: FxHashSet<FastRecognizeKey>,
1194 clean_memo_probe_samples: usize,
1195 clean_memo_probe_repeats: usize,
1196 clean_memo_sparse_samples: usize,
1197 fast_recognize_scratch: FastRecognizeTopScratch,
1199 fast_outcome_dedup: FastOutcomeDedupScratch,
1201 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1204 fast_first_set_prefilter: bool,
1212 fast_recovery_enabled: bool,
1216 fast_token_nodes_enabled: bool,
1221 recognition_arena: RecognitionArena,
1225 last_recognition_arena_root: NodeSeqId,
1226 last_recognition_arena_diagnostics: DiagnosticSeqId,
1227}
1228
1229#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1231pub struct GeneratedDiagnosticsCheckpoint {
1232 diagnostics_len: usize,
1233 syntax_errors: usize,
1234 tree: ParseTreeCheckpoint,
1235}
1236
1237#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1240pub struct RecognitionArenaStats {
1241 pub total_nodes: usize,
1242 pub live_nodes: usize,
1243 pub dead_nodes: usize,
1244 pub node_capacity: usize,
1245 pub total_links: usize,
1246 pub live_links: usize,
1247 pub dead_links: usize,
1248 pub link_capacity: usize,
1249 pub total_extras: usize,
1250 pub live_extras: usize,
1251 pub dead_extras: usize,
1252 pub extra_capacity: usize,
1253}
1254
1255#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1256struct RuleContextFrame {
1257 rule_index: usize,
1258 invoking_state: isize,
1259}
1260
1261#[derive(Clone, Debug, Eq, PartialEq)]
1262struct RecognizeOutcome {
1263 index: usize,
1264 consumed_eof: bool,
1265 alt_number: usize,
1266 member_values: BTreeMap<usize, i64>,
1267 return_values: BTreeMap<String, i64>,
1268 diagnostics: DiagnosticSeqId,
1269 decisions: Vec<usize>,
1270 actions: Vec<ParserAction>,
1271 nodes: NodeSeqId,
1272}
1273
1274#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1275struct FastRecognizeOutcome {
1276 index: usize,
1277 consumed_eof: bool,
1278 diagnostics: DiagnosticSeqId,
1279 deferred_nodes: FastDeferredNodeId,
1280 nodes: NodeSeqId,
1284}
1285
1286#[derive(Debug, Default)]
1287struct FastRecognizeTopScratch {
1288 visiting: FxHashSet<FastRecognizeKey>,
1289 memo: FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
1290}
1291
1292impl FastRecognizeTopScratch {
1293 fn prepare(&mut self, memo_capacity: usize) {
1294 self.visiting.clear();
1295 self.visiting.reserve(FAST_RECOGNIZE_VISITING_CAPACITY);
1296 self.memo.clear();
1297 self.memo.reserve(memo_capacity);
1298 }
1299
1300 fn release_oversized_memo(&mut self) {
1301 self.memo.clear();
1302 if self.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY {
1303 self.memo = FxHashMap::default();
1304 }
1305 }
1306}
1307
1308fn fast_recognize_memo_capacity(buffered_tokens: usize) -> usize {
1309 buffered_tokens.saturating_mul(8).clamp(
1310 FAST_RECOGNIZE_MIN_MEMO_CAPACITY,
1311 FAST_RECOGNIZE_MAX_MEMO_CAPACITY,
1312 )
1313}
1314
1315#[derive(Debug, Default)]
1316struct FastOutcomeDedupScratch {
1317 dense_words: Vec<u64>,
1318 touched_dense_words: Vec<u32>,
1319 sparse_keys: FxHashSet<(usize, bool)>,
1320}
1321
1322#[repr(transparent)]
1327#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1328struct FastDeferredNodeId(u32);
1329
1330impl FastDeferredNodeId {
1331 const EMPTY: Self = Self(u32::MAX);
1332
1333 const fn is_empty(self) -> bool {
1334 self.0 == Self::EMPTY.0
1335 }
1336}
1337
1338impl Default for FastDeferredNodeId {
1339 fn default() -> Self {
1340 Self::EMPTY
1341 }
1342}
1343
1344#[repr(transparent)]
1345#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1346struct FastDeferredRuleId(u32);
1347
1348#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1350enum FastDeferredNode {
1351 Fragment(NodeSeqId),
1352 Rule(FastDeferredRuleId),
1353 Concat {
1354 prefix: FastDeferredNodeId,
1355 suffix: FastDeferredNodeId,
1356 },
1357}
1358
1359#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1360struct FastDeferredRule {
1361 rule_index: u32,
1362 invoking_state: i32,
1363 start_index: u32,
1364 stop_index: Option<u32>,
1365 deferred_children: FastDeferredNodeId,
1366 children: NodeSeqId,
1367}
1368
1369#[repr(transparent)]
1370#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1371struct RecognizedNodeId(u32);
1372
1373#[repr(transparent)]
1374#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1375struct NodeSeqId(u32);
1376
1377impl NodeSeqId {
1378 const EMPTY: Self = Self(u32::MAX);
1379
1380 const fn is_empty(self) -> bool {
1381 self.0 == Self::EMPTY.0
1382 }
1383}
1384
1385impl Default for NodeSeqId {
1386 fn default() -> Self {
1387 Self::EMPTY
1388 }
1389}
1390
1391#[repr(transparent)]
1392#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1393struct DiagnosticSeqId(u32);
1394
1395impl DiagnosticSeqId {
1396 const EMPTY: Self = Self(u32::MAX);
1397
1398 const fn is_empty(self) -> bool {
1399 self.0 == Self::EMPTY.0
1400 }
1401}
1402
1403impl Default for DiagnosticSeqId {
1404 fn default() -> Self {
1405 Self::EMPTY
1406 }
1407}
1408
1409#[repr(transparent)]
1410#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1411struct RecognitionExtraId(u32);
1412
1413#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1414struct SeqLink {
1415 head: RecognizedNodeId,
1416 tail: NodeSeqId,
1417}
1418
1419#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1420struct DiagnosticLink {
1421 head: RecognitionExtraId,
1422 tail: DiagnosticSeqId,
1423}
1424
1425struct ArenaRuleSpec {
1426 rule_index: usize,
1427 invoking_state: isize,
1428 alt_number: usize,
1429 start_index: usize,
1430 stop_index: Option<usize>,
1431 return_values: BTreeMap<String, i64>,
1432 children: NodeSeqId,
1433}
1434
1435#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1438enum ArenaRecognizedNode {
1439 Token {
1440 token: TokenId,
1441 },
1442 ErrorToken {
1443 token: TokenId,
1444 },
1445 MissingToken {
1446 extra: RecognitionExtraId,
1447 },
1448 Rule {
1449 rule_index: u32,
1450 invoking_state: i32,
1451 alt_number: u32,
1452 start_index: u32,
1453 stop_index: Option<u32>,
1454 return_values: Option<RecognitionExtraId>,
1455 children: NodeSeqId,
1456 },
1457 LeftRecursiveBoundary {
1461 rule_index: u32,
1462 },
1463}
1464
1465#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1466enum RecognitionExtra {
1467 MissingToken {
1468 token_type: i32,
1469 at_index: u32,
1470 text: String,
1471 },
1472 ReturnValues(BTreeMap<String, i64>),
1473 Diagnostic(ParserDiagnostic),
1474}
1475
1476#[derive(Debug, Default)]
1477struct RecognitionArena {
1478 nodes: Vec<ArenaRecognizedNode>,
1479 seq_links: Vec<SeqLink>,
1480 diagnostic_links: Vec<DiagnosticLink>,
1481 extras: Vec<RecognitionExtra>,
1482 deferred_nodes: Vec<FastDeferredNode>,
1483 deferred_rules: Vec<FastDeferredRule>,
1484}
1485
1486const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1489const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1490const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1491const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1492const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1493const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1494
1495impl RecognitionArena {
1496 fn reset(&mut self) {
1497 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1498 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1499 reset_arena_vec(
1500 &mut self.diagnostic_links,
1501 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1502 );
1503 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1504 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1505 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1506 }
1507
1508 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1509 let id = RecognizedNodeId(
1510 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1511 );
1512 self.nodes.push(node);
1513 id
1514 }
1515
1516 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1517 let id = RecognitionExtraId(
1518 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1519 );
1520 self.extras.push(extra);
1521 id
1522 }
1523
1524 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1525 let id = NodeSeqId(
1526 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1527 );
1528 self.seq_links.push(SeqLink { head, tail });
1529 id
1530 }
1531
1532 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1533 let id = FastDeferredNodeId(
1534 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
1535 );
1536 self.deferred_nodes.push(node);
1537 id
1538 }
1539
1540 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
1541 let id = FastDeferredRuleId(
1542 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
1543 );
1544 self.deferred_rules.push(rule);
1545 id
1546 }
1547
1548 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
1549 if nodes.is_empty() {
1550 FastDeferredNodeId::EMPTY
1551 } else {
1552 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
1553 }
1554 }
1555
1556 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
1557 let rule = self.push_deferred_rule(rule);
1558 self.push_deferred_node(FastDeferredNode::Rule(rule))
1559 }
1560
1561 fn concat_deferred_nodes(
1562 &mut self,
1563 prefix: FastDeferredNodeId,
1564 suffix: FastDeferredNodeId,
1565 ) -> FastDeferredNodeId {
1566 if prefix.is_empty() {
1567 return suffix;
1568 }
1569 if suffix.is_empty() {
1570 return prefix;
1571 }
1572 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
1573 }
1574
1575 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
1576 self.deferred_nodes[id.0 as usize]
1577 }
1578
1579 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
1580 self.deferred_rules[id.0 as usize]
1581 }
1582
1583 fn prepend_diagnostic(
1584 &mut self,
1585 tail: DiagnosticSeqId,
1586 diagnostic: ParserDiagnostic,
1587 ) -> DiagnosticSeqId {
1588 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
1589 self.prepend_diagnostic_id(tail, head)
1590 }
1591
1592 fn prepend_diagnostic_id(
1593 &mut self,
1594 tail: DiagnosticSeqId,
1595 head: RecognitionExtraId,
1596 ) -> DiagnosticSeqId {
1597 let id = DiagnosticSeqId(
1598 u32::try_from(self.diagnostic_links.len())
1599 .expect("diagnostic sequence arena fits in u32"),
1600 );
1601 self.diagnostic_links.push(DiagnosticLink { head, tail });
1602 id
1603 }
1604
1605 fn concat_diagnostics(
1606 &mut self,
1607 prefix: DiagnosticSeqId,
1608 mut suffix: DiagnosticSeqId,
1609 ) -> DiagnosticSeqId {
1610 if prefix.is_empty() {
1611 return suffix;
1612 }
1613 if suffix.is_empty() {
1614 return prefix;
1615 }
1616 let mut reversed = DiagnosticSeqId::EMPTY;
1617 let mut cursor = prefix;
1618 while let Some(link) = self.diagnostic_link(cursor) {
1619 reversed = self.prepend_diagnostic_id(reversed, link.head);
1620 cursor = link.tail;
1621 }
1622 while let Some(link) = self.diagnostic_link(reversed) {
1623 suffix = self.prepend_diagnostic_id(suffix, link.head);
1624 reversed = link.tail;
1625 }
1626 suffix
1627 }
1628
1629 #[cfg(test)]
1630 fn diagnostic_sequence(
1631 &mut self,
1632 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
1633 ) -> DiagnosticSeqId {
1634 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
1635 let mut sequence = DiagnosticSeqId::EMPTY;
1636 for diagnostic in diagnostics.into_iter().rev() {
1637 sequence = self.prepend_diagnostic(sequence, diagnostic);
1638 }
1639 sequence
1640 }
1641
1642 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
1643 self.nodes[id.0 as usize]
1644 }
1645
1646 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
1647 &self.extras[id.0 as usize]
1648 }
1649
1650 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
1651 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
1652 }
1653
1654 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
1655 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
1656 }
1657
1658 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
1659 NodeSeqIter {
1660 arena: self,
1661 cursor: sequence,
1662 }
1663 }
1664
1665 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
1666 DiagnosticSeqIter {
1667 arena: self,
1668 cursor: sequence,
1669 }
1670 }
1671
1672 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
1673 self.diagnostics(sequence).count()
1674 }
1675
1676 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
1677 self.diagnostics(sequence)
1678 .filter(|diagnostic| {
1679 diagnostic.message.starts_with("mismatched input ")
1680 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
1681 })
1682 .count()
1683 }
1684
1685 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
1686 self.diagnostics(left).cmp(self.diagnostics(right))
1687 }
1688
1689 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
1690 self.iter(sequence).count()
1691 }
1692
1693 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
1694 self.iter(sequence).any(|node| match self.node(node) {
1695 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1696 ArenaRecognizedNode::Rule { children, .. } => {
1697 self.sequence_has_left_recursive_boundary(children)
1698 }
1699 ArenaRecognizedNode::Token { .. }
1700 | ArenaRecognizedNode::ErrorToken { .. }
1701 | ArenaRecognizedNode::MissingToken { .. } => false,
1702 })
1703 }
1704
1705 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
1706 self.iter(sequence).any(|node| {
1707 matches!(
1708 self.node(node),
1709 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
1710 )
1711 })
1712 }
1713
1714 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
1715 self.iter(sequence).any(|node| {
1716 matches!(
1717 self.node(node),
1718 ArenaRecognizedNode::Token { .. }
1719 | ArenaRecognizedNode::ErrorToken { .. }
1720 | ArenaRecognizedNode::MissingToken { .. }
1721 )
1722 })
1723 }
1724
1725 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
1726 match self.node(node) {
1727 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1728 Some(token.index())
1729 }
1730 ArenaRecognizedNode::MissingToken { extra } => {
1731 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1732 unreachable!("missing-token node must reference missing-token extra");
1733 };
1734 Some(*at_index as usize)
1735 }
1736 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
1737 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1738 }
1739 }
1740
1741 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
1742 match self.node(node) {
1743 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1744 Some(token.index())
1745 }
1746 ArenaRecognizedNode::MissingToken { extra } => {
1747 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1748 unreachable!("missing-token node must reference missing-token extra");
1749 };
1750 (*at_index as usize).checked_sub(1)
1751 }
1752 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
1753 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1754 }
1755 }
1756
1757 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
1758 let start = self.node_start_index(node)?;
1759 let stop = self.node_stop_index(node);
1760 Some((start, stop))
1761 }
1762
1763 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
1764 self.iter(sequence)
1765 .find_map(|node| self.node_start_index(node))
1766 }
1767
1768 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
1769 let mut stop = None;
1770 for node in self.iter(sequence) {
1771 if let Some(index) = self.node_stop_index(node) {
1772 stop = Some(index);
1773 }
1774 }
1775 stop
1776 }
1777
1778 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
1779 self.iter(sequence)
1780 .any(|node| self.node_needs_stable_tie(node))
1781 }
1782
1783 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
1784 match self.node(node) {
1785 ArenaRecognizedNode::Token { .. }
1786 | ArenaRecognizedNode::ErrorToken { .. }
1787 | ArenaRecognizedNode::MissingToken { .. } => false,
1788 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1789 ArenaRecognizedNode::Rule {
1790 rule_index,
1791 children,
1792 ..
1793 } => self.iter(children).any(|child| {
1794 matches!(
1795 self.node(child),
1796 ArenaRecognizedNode::Rule {
1797 rule_index: child_rule,
1798 ..
1799 } if child_rule == rule_index
1800 ) || self.node_needs_stable_tie(child)
1801 }),
1802 }
1803 }
1804
1805 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
1806 loop {
1807 match (self.link(left), self.link(right)) {
1808 (Some(left_link), Some(right_link)) => {
1809 let order = self.compare_nodes(left_link.head, right_link.head);
1810 if order != Ordering::Equal {
1811 return order;
1812 }
1813 left = left_link.tail;
1814 right = right_link.tail;
1815 }
1816 (None, None) => return Ordering::Equal,
1817 (None, Some(_)) => return Ordering::Less,
1818 (Some(_), None) => return Ordering::Greater,
1819 }
1820 }
1821 }
1822
1823 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
1824 let left = self.node(left);
1825 let right = self.node(right);
1826 match (left, right) {
1827 (
1828 ArenaRecognizedNode::Token { token: left },
1829 ArenaRecognizedNode::Token { token: right },
1830 )
1831 | (
1832 ArenaRecognizedNode::ErrorToken { token: left },
1833 ArenaRecognizedNode::ErrorToken { token: right },
1834 ) => left.cmp(&right),
1835 (
1836 ArenaRecognizedNode::MissingToken { extra: left },
1837 ArenaRecognizedNode::MissingToken { extra: right },
1838 ) => self.extra(left).cmp(self.extra(right)),
1839 (
1840 ArenaRecognizedNode::Rule {
1841 rule_index: left_rule,
1842 invoking_state: left_invoking,
1843 alt_number: left_alt,
1844 start_index: left_start,
1845 stop_index: left_stop,
1846 return_values: left_returns,
1847 children: left_children,
1848 },
1849 ArenaRecognizedNode::Rule {
1850 rule_index: right_rule,
1851 invoking_state: right_invoking,
1852 alt_number: right_alt,
1853 start_index: right_start,
1854 stop_index: right_stop,
1855 return_values: right_returns,
1856 children: right_children,
1857 },
1858 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
1859 .cmp(&(
1860 right_rule,
1861 right_invoking,
1862 right_alt,
1863 right_start,
1864 right_stop,
1865 ))
1866 .then_with(|| {
1867 left_returns
1868 .map(|id| self.extra(id))
1869 .cmp(&right_returns.map(|id| self.extra(id)))
1870 })
1871 .then_with(|| self.compare_sequences(left_children, right_children)),
1872 (
1873 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: left },
1874 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: right },
1875 ) => left.cmp(&right),
1876 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
1877 }
1878 }
1879
1880 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1881 let mut reversed = NodeSeqId::EMPTY;
1882 while let Some(link) = self.link(sequence) {
1883 reversed = self.prepend(reversed, link.head);
1884 sequence = link.tail;
1885 }
1886 reversed
1887 }
1888
1889 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1890 if !self.sequence_has_direct_boundary(sequence) {
1891 return sequence;
1892 }
1893 let mut reversed = NodeSeqId::EMPTY;
1894 while let Some(link) = self.link(sequence) {
1895 match self.node(link.head) {
1896 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index } => {
1897 if !reversed.is_empty() {
1898 let children = self.reverse_sequence(reversed);
1899 let start_index = self.sequence_start_index(children).unwrap_or_default();
1900 let stop_index = self.sequence_stop_index(children);
1901 let rule = self.push_node(ArenaRecognizedNode::Rule {
1902 rule_index,
1903 invoking_state: -1,
1904 alt_number: 0,
1905 start_index: u32::try_from(start_index)
1906 .expect("left-recursive start index fits in u32"),
1907 stop_index: stop_index.map(|index| {
1908 u32::try_from(index).expect("left-recursive stop index fits in u32")
1909 }),
1910 return_values: None,
1911 children,
1912 });
1913 reversed = self.prepend(NodeSeqId::EMPTY, rule);
1914 }
1915 }
1916 _ => {
1917 reversed = self.prepend(reversed, link.head);
1918 }
1919 }
1920 sequence = link.tail;
1921 }
1922 self.reverse_sequence(reversed)
1923 }
1924
1925 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
1926 let mut live_nodes = vec![false; self.nodes.len()];
1927 let mut live_links = vec![false; self.seq_links.len()];
1928 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
1929 let mut live_extras = vec![false; self.extras.len()];
1930 let mut pending = vec![root];
1931 while let Some(mut sequence) = pending.pop() {
1932 while let Some(link) = self.link(sequence) {
1933 let link_index = sequence.0 as usize;
1934 if live_links[link_index] {
1935 break;
1936 }
1937 live_links[link_index] = true;
1938 let node_index = link.head.0 as usize;
1939 if !live_nodes[node_index] {
1940 live_nodes[node_index] = true;
1941 match self.node(link.head) {
1942 ArenaRecognizedNode::MissingToken { extra } => {
1943 live_extras[extra.0 as usize] = true;
1944 }
1945 ArenaRecognizedNode::Rule {
1946 return_values,
1947 children,
1948 ..
1949 } => {
1950 if let Some(extra) = return_values {
1951 live_extras[extra.0 as usize] = true;
1952 }
1953 pending.push(children);
1954 }
1955 ArenaRecognizedNode::Token { .. }
1956 | ArenaRecognizedNode::ErrorToken { .. }
1957 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
1958 }
1959 }
1960 sequence = link.tail;
1961 }
1962 }
1963 let mut diagnostics = diagnostics;
1964 while let Some(link) = self.diagnostic_link(diagnostics) {
1965 let link_index = diagnostics.0 as usize;
1966 if live_diagnostic_links[link_index] {
1967 break;
1968 }
1969 live_diagnostic_links[link_index] = true;
1970 live_extras[link.head.0 as usize] = true;
1971 diagnostics = link.tail;
1972 }
1973 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
1974 let live_link_count = live_links.into_iter().filter(|live| *live).count()
1975 + live_diagnostic_links
1976 .into_iter()
1977 .filter(|live| *live)
1978 .count();
1979 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
1980 let total_links = self.seq_links.len() + self.diagnostic_links.len();
1981 RecognitionArenaStats {
1982 total_nodes: self.nodes.len(),
1983 live_nodes: live_node_count,
1984 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
1985 node_capacity: self.nodes.capacity(),
1986 total_links,
1987 live_links: live_link_count,
1988 dead_links: total_links.saturating_sub(live_link_count),
1989 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
1990 total_extras: self.extras.len(),
1991 live_extras: live_extra_count,
1992 dead_extras: self.extras.len().saturating_sub(live_extra_count),
1993 extra_capacity: self.extras.capacity(),
1994 }
1995 }
1996}
1997
1998fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
1999 if storage.capacity() > max_retained_capacity {
2000 *storage = Vec::new();
2001 } else {
2002 storage.clear();
2003 }
2004}
2005
2006const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
2007 match node {
2008 ArenaRecognizedNode::Token { .. } => 0,
2009 ArenaRecognizedNode::ErrorToken { .. } => 1,
2010 ArenaRecognizedNode::MissingToken { .. } => 2,
2011 ArenaRecognizedNode::Rule { .. } => 3,
2012 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
2013 }
2014}
2015
2016struct NodeSeqIter<'a> {
2017 arena: &'a RecognitionArena,
2018 cursor: NodeSeqId,
2019}
2020
2021impl Iterator for NodeSeqIter<'_> {
2022 type Item = RecognizedNodeId;
2023
2024 fn next(&mut self) -> Option<Self::Item> {
2025 let link = self.arena.link(self.cursor)?;
2026 self.cursor = link.tail;
2027 Some(link.head)
2028 }
2029}
2030
2031struct DiagnosticSeqIter<'a> {
2032 arena: &'a RecognitionArena,
2033 cursor: DiagnosticSeqId,
2034}
2035
2036impl<'a> Iterator for DiagnosticSeqIter<'a> {
2037 type Item = &'a ParserDiagnostic;
2038
2039 fn next(&mut self) -> Option<Self::Item> {
2040 let link = self.arena.diagnostic_link(self.cursor)?;
2041 self.cursor = link.tail;
2042 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2043 unreachable!("diagnostic link must reference diagnostic extra");
2044 };
2045 Some(diagnostic)
2046 }
2047}
2048
2049#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2050struct ParserDiagnostic {
2051 line: usize,
2052 column: usize,
2053 message: String,
2054}
2055
2056#[derive(Clone, Debug, Default, Eq, PartialEq)]
2057struct ExpectedTokens {
2058 index: Option<usize>,
2059 symbols: BTreeSet<i32>,
2060 no_viable: Option<NoViableAlternative>,
2061}
2062
2063#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2064struct NoViableAlternative {
2065 start_index: usize,
2066 error_index: usize,
2067}
2068
2069impl ExpectedTokens {
2070 fn record_transition(
2073 &mut self,
2074 index: usize,
2075 transition: ParserTransition<'_>,
2076 max_token_type: i32,
2077 ) {
2078 let symbols = transition_expected_symbols(transition, max_token_type);
2079 match self.index {
2080 Some(current) if index < current => {}
2081 Some(current) if index == current => self.symbols.extend(symbols),
2082 _ => {
2083 self.index = Some(index);
2084 self.symbols = symbols;
2085 }
2086 }
2087 }
2088
2089 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2092 match self.no_viable {
2093 Some(current) if error_index < current.error_index => {}
2094 _ => {
2095 self.no_viable = Some(NoViableAlternative {
2096 start_index,
2097 error_index,
2098 });
2099 }
2100 }
2101 }
2102}
2103
2104#[derive(Clone, Debug, Default, Eq, PartialEq)]
2111struct TokenBitSet {
2112 words: Vec<u64>,
2113}
2114
2115impl TokenBitSet {
2116 fn insert(&mut self, symbol: i32) {
2117 let Some(slot) = token_bit_slot(symbol) else {
2118 return;
2119 };
2120 let word = slot / u64::BITS as usize;
2121 if word >= self.words.len() {
2122 self.words.resize(word + 1, 0);
2123 }
2124 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2125 }
2126
2127 fn extend_range(&mut self, start: i32, stop: i32) {
2128 let (start, stop) = if start <= stop {
2129 (start, stop)
2130 } else {
2131 (stop, start)
2132 };
2133 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2134 self.insert(TOKEN_EOF);
2135 }
2136 let positive_start = start.max(1);
2137 if positive_start > stop {
2138 return;
2139 }
2140 let Some(start_slot) = token_bit_slot(positive_start) else {
2141 return;
2142 };
2143 let Some(stop_slot) = token_bit_slot(stop) else {
2144 return;
2145 };
2146 self.extend_slot_range(start_slot, stop_slot);
2147 }
2148
2149 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2150 if start_slot > stop_slot {
2151 return;
2152 }
2153 let start_word = start_slot / u64::BITS as usize;
2154 let stop_word = stop_slot / u64::BITS as usize;
2155 if stop_word >= self.words.len() {
2156 self.words.resize(stop_word + 1, 0);
2157 }
2158 let start_offset = start_slot % u64::BITS as usize;
2159 let stop_offset = stop_slot % u64::BITS as usize;
2160 if start_word == stop_word {
2161 self.words[start_word] |=
2162 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2163 return;
2164 }
2165 self.words[start_word] |= !0_u64 << start_offset;
2166 for word in &mut self.words[(start_word + 1)..stop_word] {
2167 *word = !0_u64;
2168 }
2169 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2170 }
2171
2172 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2173 for symbol in symbols {
2174 self.insert(symbol);
2175 }
2176 }
2177
2178 fn extend_from(&mut self, other: &Self) {
2179 if other.words.len() > self.words.len() {
2180 self.words.resize(other.words.len(), 0);
2181 }
2182 for (left, right) in self.words.iter_mut().zip(&other.words) {
2183 *left |= *right;
2184 }
2185 }
2186
2187 fn contains(&self, symbol: i32) -> bool {
2188 let Some(slot) = token_bit_slot(symbol) else {
2189 return false;
2190 };
2191 let word = slot / u64::BITS as usize;
2192 self.words
2193 .get(word)
2194 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2195 }
2196
2197 fn is_empty(&self) -> bool {
2198 self.words.iter().all(|word| *word == 0)
2199 }
2200
2201 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2202 for (word_index, word) in self.words.iter().copied().enumerate() {
2203 let mut bits = word;
2204 while bits != 0 {
2205 let bit = bits.trailing_zeros() as usize;
2206 if let Some(symbol) = token_bit_symbol(word_index * u64::BITS as usize + bit) {
2207 target.insert(symbol);
2208 }
2209 bits &= bits - 1;
2210 }
2211 }
2212 }
2213
2214 fn to_btree_set(&self) -> BTreeSet<i32> {
2215 let mut out = BTreeSet::new();
2216 self.extend_btree_set(&mut out);
2217 out
2218 }
2219}
2220
2221fn token_bit_slot(symbol: i32) -> Option<usize> {
2222 if symbol == TOKEN_EOF {
2223 Some(0)
2224 } else if symbol > 0 {
2225 usize::try_from(symbol).ok()
2226 } else {
2227 None
2228 }
2229}
2230
2231fn token_bit_symbol(slot: usize) -> Option<i32> {
2232 if slot == 0 {
2233 Some(TOKEN_EOF)
2234 } else {
2235 i32::try_from(slot).ok()
2236 }
2237}
2238
2239fn transition_expected_symbols(
2242 transition: ParserTransition<'_>,
2243 max_token_type: i32,
2244) -> BTreeSet<i32> {
2245 let mut symbols = BTreeSet::new();
2246 match &transition.data() {
2247 Transition::Atom { label, .. } => {
2248 symbols.insert(*label);
2249 }
2250 Transition::Range { start, stop, .. } => {
2251 symbols.extend(*start..=*stop);
2252 }
2253 Transition::Set { set, .. } => {
2254 for (start, stop) in set.ranges() {
2255 symbols.extend(start..=stop);
2256 }
2257 }
2258 Transition::NotSet { set, .. } => {
2259 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2260 }
2261 Transition::Wildcard { .. } => {
2262 symbols.extend(1..=max_token_type);
2263 }
2264 Transition::Epsilon { .. }
2265 | Transition::Rule { .. }
2266 | Transition::Predicate { .. }
2267 | Transition::Action { .. }
2268 | Transition::Precedence { .. } => {}
2269 }
2270 symbols
2271}
2272
2273fn transition_expected_token_set(
2274 transition: ParserTransition<'_>,
2275 max_token_type: i32,
2276) -> TokenBitSet {
2277 let mut symbols = TokenBitSet::default();
2278 match &transition.data() {
2279 Transition::Atom { label, .. } => {
2280 symbols.insert(*label);
2281 }
2282 Transition::Range { start, stop, .. } => {
2283 symbols.extend_range(*start, *stop);
2284 }
2285 Transition::Set { set, .. } => {
2286 for (start, stop) in set.ranges() {
2287 symbols.extend_range(start, stop);
2288 }
2289 }
2290 Transition::NotSet { set, .. } => {
2291 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2292 }
2293 Transition::Wildcard { .. } => {
2294 symbols.extend_range(1, max_token_type);
2295 }
2296 Transition::Epsilon { .. }
2297 | Transition::Rule { .. }
2298 | Transition::Predicate { .. }
2299 | Transition::Action { .. }
2300 | Transition::Precedence { .. } => {}
2301 }
2302 symbols
2303}
2304
2305fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2309 let mut symbols = BTreeSet::new();
2310 let mut stack = vec![state_number];
2311 let mut visited = BTreeSet::new();
2312 while let Some(current) = stack.pop() {
2313 if !visited.insert(current) {
2314 continue;
2315 }
2316 let Some(state) = atn.state(current) else {
2317 continue;
2318 };
2319 for transition in &state.transitions() {
2320 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2321 if transition_symbols.is_empty() {
2322 if transition.is_epsilon() {
2323 stack.push(transition.target());
2324 }
2325 } else {
2326 symbols.extend(transition_symbols);
2327 }
2328 }
2329 }
2330 symbols
2331}
2332
2333fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2334 let mut symbols = TokenBitSet::default();
2335 let mut stack = vec![state_number];
2336 let mut visited = BTreeSet::new();
2337 while let Some(current) = stack.pop() {
2338 if !visited.insert(current) {
2339 continue;
2340 }
2341 let Some(state) = atn.state(current) else {
2342 continue;
2343 };
2344 for transition in &state.transitions() {
2345 let transition_symbols =
2346 transition_expected_token_set(transition, atn.max_token_type());
2347 if transition_symbols.is_empty() {
2348 if transition.is_epsilon() {
2349 stack.push(transition.target());
2350 }
2351 } else {
2352 symbols.extend_from(&transition_symbols);
2353 }
2354 }
2355 }
2356 symbols
2357}
2358
2359fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2360 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2361 return false;
2362 };
2363 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2364 return false;
2365 };
2366 epsilon_reaches_state(atn, state_number, stop_state)
2367}
2368
2369fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2370 let mut stack = vec![start];
2371 let mut visited = BTreeSet::new();
2372 while let Some(current) = stack.pop() {
2373 if current == target {
2374 return true;
2375 }
2376 if !visited.insert(current) {
2377 continue;
2378 }
2379 let Some(state) = atn.state(current) else {
2380 continue;
2381 };
2382 stack.extend(
2383 state
2384 .transitions()
2385 .iter()
2386 .filter(|transition| transition.is_epsilon())
2387 .map(ParserTransition::target),
2388 );
2389 }
2390 false
2391}
2392
2393#[derive(Clone, Debug, Default, Eq, PartialEq)]
2400struct FirstSet {
2401 symbols: TokenBitSet,
2402 nullable: bool,
2403}
2404
2405type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2412
2413type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2420
2421#[derive(Debug, Default)]
2422struct LeftRecursiveOperatorLookahead {
2423 single_token: TokenBitSet,
2427 multi_token_prefix: TokenBitSet,
2432 predicate_dependent: TokenBitSet,
2433}
2434
2435#[derive(Default)]
2436struct SharedAtnCache {
2437 first_set: FirstSetCache,
2438 decision_lookahead: DecisionLookaheadCache,
2439 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2440 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2441 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2442 rule_stop_reach: FxHashMap<usize, bool>,
2443 observable_action_transitions: Option<bool>,
2444 predicate_transitions: Option<bool>,
2445}
2446
2447thread_local! {
2448 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2449 RefCell::new(FxHashMap::default());
2450}
2451
2452#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2463struct SharedAtnCacheKey {
2464 atn: usize,
2465 states: usize,
2466 state_count: usize,
2467 max_token_type: i32,
2468}
2469
2470impl SharedAtnCacheKey {
2471 fn for_atn(atn: &Atn) -> Self {
2472 let (states, state_count) = atn.storage_identity();
2473 Self {
2474 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2475 states,
2476 state_count,
2477 max_token_type: atn.max_token_type(),
2478 }
2479 }
2480}
2481
2482fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2483 SHARED_ATN_CACHES.with(|cell| {
2484 let key = SharedAtnCacheKey::for_atn(atn);
2485 let mut map = cell.borrow_mut();
2486 let cache = map.entry(key).or_default();
2487 f(&mut cache.first_set)
2488 })
2489}
2490
2491fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
2492 SHARED_ATN_CACHES.with(|cell| {
2493 let key = SharedAtnCacheKey::for_atn(atn);
2494 let mut map = cell.borrow_mut();
2495 let cache = map.entry(key).or_default();
2496 f(cache)
2497 })
2498}
2499
2500#[derive(Debug, Default)]
2509struct DecisionLookahead {
2510 transitions: Vec<TransitionLookSet>,
2511}
2512
2513#[derive(Clone, Debug, Default)]
2520struct TransitionLookSet {
2521 symbols: TokenBitSet,
2522 nullable: bool,
2523}
2524
2525struct FirstSetCtx<'a> {
2529 cache: &'a mut FirstSetCache,
2530 in_progress: BTreeSet<(usize, usize)>,
2531 hit_cycle: bool,
2532}
2533
2534fn rule_first_set(
2543 atn: &Atn,
2544 target: usize,
2545 rule_stop_state: usize,
2546 cache: &mut FirstSetCache,
2547) -> Rc<FirstSet> {
2548 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
2549 return Rc::clone(cached);
2550 }
2551 let mut ctx = FirstSetCtx {
2552 cache,
2553 in_progress: BTreeSet::new(),
2554 hit_cycle: false,
2555 };
2556 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
2557}
2558
2559fn rule_first_set_cached(
2560 atn: &Atn,
2561 target: usize,
2562 rule_stop_state: usize,
2563 ctx: &mut FirstSetCtx<'_>,
2564) -> Rc<FirstSet> {
2565 let key = (target, rule_stop_state);
2566 if let Some(cached) = ctx.cache.get(&key) {
2567 return Rc::clone(cached);
2568 }
2569 if !ctx.in_progress.insert(key) {
2570 return Rc::new(FirstSet::default());
2574 }
2575 let saved_hit_cycle = ctx.hit_cycle;
2576 ctx.hit_cycle = false;
2577 let mut first = FirstSet::default();
2578 let mut visited = BTreeSet::new();
2579 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
2580 ctx.in_progress.remove(&key);
2581 let entry = Rc::new(first);
2582 if !ctx.hit_cycle {
2583 ctx.cache.insert(key, Rc::clone(&entry));
2584 }
2585 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
2586 entry
2587}
2588
2589fn transition_first_set(
2593 atn: &Atn,
2594 transition: ParserTransition<'_>,
2595 rule_stop_state: usize,
2596 cache: &mut FirstSetCache,
2597) -> TransitionLookSet {
2598 match &transition.data() {
2599 Transition::Atom { label, .. } => {
2600 let mut symbols = TokenBitSet::default();
2601 symbols.insert(*label);
2602 TransitionLookSet {
2603 symbols,
2604 nullable: false,
2605 }
2606 }
2607 Transition::Range { start, stop, .. } => {
2608 let mut symbols = TokenBitSet::default();
2609 symbols.extend_range(*start, *stop);
2610 TransitionLookSet {
2611 symbols,
2612 nullable: false,
2613 }
2614 }
2615 Transition::Set { set, .. } => {
2616 let mut symbols = TokenBitSet::default();
2617 for (start, stop) in set.ranges() {
2618 symbols.extend_range(start, stop);
2619 }
2620 TransitionLookSet {
2621 symbols,
2622 nullable: false,
2623 }
2624 }
2625 Transition::NotSet { set, .. } => {
2626 let max = atn.max_token_type();
2627 let mut symbols = TokenBitSet::default();
2628 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
2629 TransitionLookSet {
2630 symbols,
2631 nullable: false,
2632 }
2633 }
2634 Transition::Wildcard { .. } => {
2635 let mut symbols = TokenBitSet::default();
2636 symbols.extend_range(1, atn.max_token_type());
2637 TransitionLookSet {
2638 symbols,
2639 nullable: false,
2640 }
2641 }
2642 Transition::Epsilon { target }
2643 | Transition::Action { target, .. }
2644 | Transition::Predicate { target, .. }
2645 | Transition::Precedence { target, .. } => {
2646 let first = rule_first_set(atn, *target, rule_stop_state, cache);
2649 TransitionLookSet {
2650 symbols: first.symbols.clone(),
2651 nullable: first.nullable,
2652 }
2653 }
2654 Transition::Rule {
2655 target,
2656 rule_index,
2657 follow_state,
2658 ..
2659 } => {
2660 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2661 return TransitionLookSet::default();
2662 };
2663 let child = rule_first_set(atn, *target, child_stop, cache);
2664 let mut symbols = child.symbols.clone();
2665 let nullable = if child.nullable {
2666 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
2667 symbols.extend_from(&follow.symbols);
2668 follow.nullable
2669 } else {
2670 false
2671 };
2672 TransitionLookSet { symbols, nullable }
2673 }
2674 }
2675}
2676
2677fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
2698 let mut chosen: Option<usize> = None;
2699 for (index, transition) in entry.transitions.iter().enumerate() {
2700 if transition.nullable {
2701 return None;
2702 }
2703 if transition.symbols.contains(symbol) {
2704 if chosen.is_some() {
2705 return None;
2706 }
2707 chosen = Some(index);
2708 }
2709 }
2710 chosen
2711}
2712
2713fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
2722 let mut matching_non_nullable_alt = None;
2723 let mut nullable_alt = None;
2724 for (index, transition) in entry.transitions.iter().enumerate() {
2725 if transition.nullable {
2726 if nullable_alt.is_some() {
2727 return None;
2728 }
2729 nullable_alt = Some(index);
2730 }
2731 if transition.symbols.contains(symbol) {
2732 if transition.nullable {
2733 continue;
2734 }
2735 if matching_non_nullable_alt.is_some() {
2736 return None;
2737 }
2738 matching_non_nullable_alt = Some(index);
2739 }
2740 }
2741 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
2742 return None;
2743 }
2744 if non_greedy {
2745 nullable_alt.or(matching_non_nullable_alt)
2746 } else {
2747 matching_non_nullable_alt.or(nullable_alt)
2748 }
2749}
2750
2751fn should_skip_via_lookahead(
2752 transition_kind: ParserTransitionKind,
2753 transition_index: usize,
2754 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
2755 index: usize,
2756 record_expected: bool,
2757 expected: &mut ExpectedTokens,
2758) -> bool {
2759 let prune_non_consuming = matches!(
2760 transition_kind,
2761 ParserTransitionKind::Epsilon
2762 | ParserTransitionKind::Action
2763 | ParserTransitionKind::Predicate
2764 | ParserTransitionKind::Rule
2765 | ParserTransitionKind::Precedence
2766 );
2767 if !prune_non_consuming {
2768 return false;
2769 }
2770 let Some((symbol, entry)) = lookahead_filter else {
2771 return false;
2772 };
2773 let Some(set) = entry.transitions.get(transition_index) else {
2774 return false;
2775 };
2776 if set.symbols.contains(*symbol) || set.nullable {
2777 return false;
2778 }
2779 if record_expected && !set.symbols.is_empty() {
2780 record_pruned_transition_expected(set, index, expected);
2781 }
2782 true
2783}
2784
2785fn should_skip_rule_via_first_set(
2786 first: &FirstSet,
2787 symbol: i32,
2788 record_expected: bool,
2789 index: usize,
2790 expected: &mut ExpectedTokens,
2791) -> bool {
2792 if first.nullable || first.symbols.contains(symbol) {
2793 return false;
2794 }
2795 if record_expected && !first.symbols.is_empty() {
2796 record_token_bit_expected(&first.symbols, index, expected);
2797 }
2798 true
2799}
2800
2801fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
2802 match expected.index {
2803 Some(current) if index < current => {}
2804 Some(current) if index == current => {
2805 symbols.extend_btree_set(&mut expected.symbols);
2806 }
2807 _ => {
2808 expected.index = Some(index);
2809 expected.symbols = symbols.to_btree_set();
2810 }
2811 }
2812}
2813
2814fn record_pruned_transition_expected(
2816 set: &TransitionLookSet,
2817 index: usize,
2818 expected: &mut ExpectedTokens,
2819) {
2820 match expected.index {
2821 Some(current) if index < current => {}
2822 Some(current) if index == current => {
2823 set.symbols.extend_btree_set(&mut expected.symbols);
2824 }
2825 _ => {
2826 expected.index = Some(index);
2827 expected.symbols = set.symbols.to_btree_set();
2828 }
2829 }
2830}
2831
2832fn rule_first_set_inner(
2833 atn: &Atn,
2834 state_number: usize,
2835 rule_stop_state: usize,
2836 ctx: &mut FirstSetCtx<'_>,
2837 visited: &mut BTreeSet<usize>,
2838 first: &mut FirstSet,
2839) {
2840 if !visited.insert(state_number) {
2841 return;
2842 }
2843 if state_number == rule_stop_state {
2844 first.nullable = true;
2845 return;
2846 }
2847 let Some(state) = atn.state(state_number) else {
2848 return;
2849 };
2850 for transition in &state.transitions() {
2851 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2852 if !transition_symbols.is_empty() {
2853 first.symbols.extend_iter(transition_symbols);
2854 continue;
2855 }
2856 match &transition.data() {
2857 Transition::Epsilon { target }
2858 | Transition::Action { target, .. }
2859 | Transition::Predicate { target, .. }
2860 | Transition::Precedence { target, .. } => {
2861 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
2862 }
2863 Transition::Rule {
2864 target,
2865 rule_index,
2866 follow_state,
2867 ..
2868 } => {
2869 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2870 continue;
2871 };
2872 let child_key = (*target, child_stop);
2873 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
2874 ctx.hit_cycle = true;
2875 }
2876 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
2877 first.symbols.extend_from(&child.symbols);
2878 if child.nullable {
2879 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
2880 }
2881 }
2882 Transition::Atom { .. }
2883 | Transition::Range { .. }
2884 | Transition::Set { .. }
2885 | Transition::NotSet { .. }
2886 | Transition::Wildcard { .. } => {}
2887 }
2888 }
2889}
2890
2891fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
2894 let mut symbols = BTreeSet::new();
2895 state_sync_symbols_inner(
2896 atn,
2897 state_number,
2898 stop_state,
2899 &mut BTreeSet::new(),
2900 &mut symbols,
2901 );
2902 symbols
2903}
2904
2905fn state_sync_symbols_inner(
2908 atn: &Atn,
2909 state_number: usize,
2910 stop_state: usize,
2911 visited: &mut BTreeSet<usize>,
2912 symbols: &mut BTreeSet<i32>,
2913) {
2914 if !visited.insert(state_number) {
2915 return;
2916 }
2917 if state_number == stop_state {
2918 symbols.insert(TOKEN_EOF);
2919 return;
2920 }
2921 let Some(state) = atn.state(state_number) else {
2922 return;
2923 };
2924 for transition in &state.transitions() {
2925 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2926 if transition_symbols.is_empty() {
2927 match &transition.data() {
2928 Transition::Rule { target, .. }
2929 | Transition::Epsilon { target }
2930 | Transition::Action { target, .. }
2931 | Transition::Predicate { target, .. }
2932 | Transition::Precedence { target, .. } => {
2933 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
2934 }
2935 Transition::Atom { .. }
2936 | Transition::Range { .. }
2937 | Transition::Set { .. }
2938 | Transition::NotSet { .. }
2939 | Transition::Wildcard { .. } => {}
2940 }
2941 } else {
2942 symbols.extend(transition_symbols);
2943 }
2944 }
2945}
2946
2947#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
2948struct OperatorSymbolReachability {
2949 single_token: bool,
2951 multi_token: bool,
2953 predicate_dependent: bool,
2955}
2956
2957impl OperatorSymbolReachability {
2958 const ADAPTIVE_FALLBACK: Self = Self {
2959 single_token: false,
2960 multi_token: false,
2961 predicate_dependent: true,
2962 };
2963
2964 const fn single_token(predicate_dependent: bool) -> Self {
2965 if predicate_dependent {
2966 Self {
2967 single_token: false,
2968 multi_token: false,
2969 predicate_dependent: true,
2970 }
2971 } else {
2972 Self {
2973 single_token: true,
2974 multi_token: false,
2975 predicate_dependent: false,
2976 }
2977 }
2978 }
2979
2980 const fn multi_token(predicate_dependent: bool) -> Self {
2981 if predicate_dependent {
2982 Self {
2983 single_token: false,
2984 multi_token: false,
2985 predicate_dependent: true,
2986 }
2987 } else {
2988 Self {
2989 single_token: false,
2990 multi_token: true,
2991 predicate_dependent: false,
2992 }
2993 }
2994 }
2995
2996 const fn union(self, other: Self) -> Self {
2997 Self {
2998 single_token: self.single_token || other.single_token,
2999 multi_token: self.multi_token || other.multi_token,
3000 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
3001 }
3002 }
3003}
3004
3005#[derive(Clone, Copy)]
3006struct OperatorReachabilityRequest {
3007 symbol: i32,
3008 precedence: i32,
3009 predicate_dependent: bool,
3010 operator_rule_index: usize,
3011}
3012
3013#[derive(Clone, Copy, Debug)]
3014struct OperatorRuleContinuation {
3015 stop_state: usize,
3016 follow_state: usize,
3017 return_precedence: i32,
3018}
3019
3020struct NullablePrecedenceCtx {
3021 cache: FxHashMap<(usize, usize, i32, bool), bool>,
3022 in_progress: BTreeSet<(usize, usize, i32, bool)>,
3023 hit_cycle: bool,
3024}
3025
3026fn state_is_nullable_with_precedence(
3027 atn: &Atn,
3028 state_number: usize,
3029 stop_state_number: usize,
3030 precedence: i32,
3031 allow_predicates: bool,
3032 ctx: &mut NullablePrecedenceCtx,
3033) -> bool {
3034 let saved_hit_cycle = ctx.hit_cycle;
3035 ctx.hit_cycle = false;
3036 let nullable = state_is_nullable_with_precedence_cached(
3037 atn,
3038 state_number,
3039 stop_state_number,
3040 precedence,
3041 allow_predicates,
3042 ctx,
3043 );
3044 ctx.hit_cycle = saved_hit_cycle;
3045 nullable
3046}
3047
3048fn state_is_nullable_with_precedence_cached(
3049 atn: &Atn,
3050 state_number: usize,
3051 stop_state_number: usize,
3052 precedence: i32,
3053 allow_predicates: bool,
3054 ctx: &mut NullablePrecedenceCtx,
3055) -> bool {
3056 if state_number == stop_state_number {
3057 return true;
3058 }
3059 let key = (
3060 state_number,
3061 stop_state_number,
3062 precedence,
3063 allow_predicates,
3064 );
3065 if let Some(cached) = ctx.cache.get(&key) {
3066 return *cached;
3067 }
3068 if !ctx.in_progress.insert(key) {
3069 ctx.hit_cycle = true;
3070 return false;
3071 }
3072 let saved_hit_cycle = ctx.hit_cycle;
3073 ctx.hit_cycle = false;
3074 let nullable = atn.state(state_number).is_some_and(|state| {
3075 state
3076 .transitions()
3077 .iter()
3078 .any(|transition| match &transition.data() {
3079 Transition::Rule {
3080 target,
3081 rule_index,
3082 follow_state,
3083 precedence: rule_precedence,
3084 } => {
3085 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3086 return false;
3087 };
3088 state_is_nullable_with_precedence_cached(
3089 atn,
3090 *target,
3091 child_stop,
3092 *rule_precedence,
3093 allow_predicates,
3094 ctx,
3095 ) && state_is_nullable_with_precedence_cached(
3096 atn,
3097 *follow_state,
3098 stop_state_number,
3099 precedence,
3100 allow_predicates,
3101 ctx,
3102 )
3103 }
3104 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3105 state_is_nullable_with_precedence_cached(
3106 atn,
3107 *target,
3108 stop_state_number,
3109 precedence,
3110 allow_predicates,
3111 ctx,
3112 )
3113 }
3114 Transition::Predicate { target, .. } if allow_predicates => {
3115 state_is_nullable_with_precedence_cached(
3116 atn,
3117 *target,
3118 stop_state_number,
3119 precedence,
3120 allow_predicates,
3121 ctx,
3122 )
3123 }
3124 Transition::Precedence {
3125 target,
3126 precedence: transition_precedence,
3127 } if *transition_precedence >= precedence => {
3128 state_is_nullable_with_precedence_cached(
3129 atn,
3130 *target,
3131 stop_state_number,
3132 precedence,
3133 allow_predicates,
3134 ctx,
3135 )
3136 }
3137 Transition::Atom { .. }
3138 | Transition::Range { .. }
3139 | Transition::Set { .. }
3140 | Transition::NotSet { .. }
3141 | Transition::Wildcard { .. }
3142 | Transition::Predicate { .. }
3143 | Transition::Precedence { .. } => false,
3144 })
3145 });
3146 ctx.in_progress.remove(&key);
3147 if !ctx.hit_cycle {
3148 ctx.cache.insert(key, nullable);
3149 }
3150 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3151 nullable
3152}
3153
3154fn state_operator_token_prefix_reachability(
3156 atn: &Atn,
3157 state_number: usize,
3158 request: OperatorReachabilityRequest,
3159 continuations: &[OperatorRuleContinuation],
3160 visited: &mut BTreeSet<(usize, i32, bool)>,
3161) -> OperatorSymbolReachability {
3162 let key = (
3163 state_number,
3164 request.precedence,
3165 request.predicate_dependent,
3166 );
3167 if !visited.insert(key) {
3168 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3172 }
3173 if let Some((continuation, remaining)) = continuations.split_last()
3174 && state_number == continuation.stop_state
3175 {
3176 let result = state_operator_token_prefix_reachability(
3177 atn,
3178 continuation.follow_state,
3179 OperatorReachabilityRequest {
3180 precedence: continuation.return_precedence,
3181 ..request
3182 },
3183 remaining,
3184 visited,
3185 );
3186 visited.remove(&key);
3187 return result;
3188 }
3189 let Some(state) = atn.state(state_number) else {
3190 visited.remove(&key);
3191 return OperatorSymbolReachability::default();
3192 };
3193 let completes_operator = match state.kind() {
3194 AtnStateKind::RuleStop => continuations.is_empty(),
3195 AtnStateKind::StarLoopBack
3196 | AtnStateKind::StarLoopEntry
3197 | AtnStateKind::PlusLoopBack
3198 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3199 _ => false,
3200 };
3201 if completes_operator {
3202 visited.remove(&key);
3203 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3204 }
3205 let mut reachability = OperatorSymbolReachability::default();
3206 for transition in &state.transitions() {
3207 let transition_reachability = match &transition.data() {
3208 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3209 OperatorSymbolReachability::single_token(request.predicate_dependent)
3210 }
3211 Transition::Rule {
3212 target,
3213 rule_index,
3214 follow_state,
3215 precedence: rule_precedence,
3216 } => {
3217 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3218 continue;
3219 };
3220 let mut nested = continuations.to_vec();
3221 nested.push(OperatorRuleContinuation {
3222 stop_state: child_stop,
3223 follow_state: *follow_state,
3224 return_precedence: request.precedence,
3225 });
3226 state_operator_token_prefix_reachability(
3227 atn,
3228 *target,
3229 OperatorReachabilityRequest {
3230 precedence: *rule_precedence,
3231 ..request
3232 },
3233 &nested,
3234 visited,
3235 )
3236 }
3237 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3238 state_operator_token_prefix_reachability(
3239 atn,
3240 *target,
3241 request,
3242 continuations,
3243 visited,
3244 )
3245 }
3246 Transition::Precedence {
3247 target,
3248 precedence: transition_precedence,
3249 } => {
3250 if *transition_precedence < request.precedence {
3251 OperatorSymbolReachability::default()
3252 } else {
3253 state_operator_token_prefix_reachability(
3254 atn,
3255 *target,
3256 request,
3257 continuations,
3258 visited,
3259 )
3260 }
3261 }
3262 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3263 atn,
3264 *target,
3265 OperatorReachabilityRequest {
3266 predicate_dependent: true,
3267 ..request
3268 },
3269 continuations,
3270 visited,
3271 ),
3272 Transition::Atom { .. }
3273 | Transition::Range { .. }
3274 | Transition::Set { .. }
3275 | Transition::NotSet { .. }
3276 | Transition::Wildcard { .. } => {
3277 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3278 }
3279 };
3280 reachability = reachability.union(transition_reachability);
3281 }
3282 visited.remove(&key);
3283 reachability
3284}
3285
3286fn state_can_reach_symbol_with_precedence(
3287 atn: &Atn,
3288 state_number: usize,
3289 request: OperatorReachabilityRequest,
3290 nullable_ctx: &mut NullablePrecedenceCtx,
3291 continuations: &mut Vec<OperatorRuleContinuation>,
3292 visited: &mut BTreeSet<(usize, i32, bool)>,
3293) -> OperatorSymbolReachability {
3294 let key = (
3295 state_number,
3296 request.precedence,
3297 request.predicate_dependent,
3298 );
3299 if !visited.insert(key) {
3300 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3301 }
3302 let Some(state) = atn.state(state_number) else {
3303 visited.remove(&key);
3304 return OperatorSymbolReachability::default();
3305 };
3306 let mut reachability = OperatorSymbolReachability::default();
3307 for transition in &state.transitions() {
3308 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3309 reachability = reachability.union(state_operator_token_prefix_reachability(
3310 atn,
3311 transition.target(),
3312 request,
3313 continuations,
3314 &mut BTreeSet::new(),
3315 ));
3316 continue;
3317 }
3318 let transition_reachability = match &transition.data() {
3319 Transition::Rule {
3320 target,
3321 rule_index,
3322 follow_state,
3323 precedence: rule_precedence,
3324 } => {
3325 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3326 continue;
3327 };
3328 continuations.push(OperatorRuleContinuation {
3329 stop_state: child_stop,
3330 follow_state: *follow_state,
3331 return_precedence: request.precedence,
3332 });
3333 let mut result = state_can_reach_symbol_with_precedence(
3334 atn,
3335 *target,
3336 OperatorReachabilityRequest {
3337 precedence: *rule_precedence,
3338 ..request
3339 },
3340 nullable_ctx,
3341 continuations,
3342 visited,
3343 );
3344 continuations.pop();
3345 if state_is_nullable_with_precedence(
3346 atn,
3347 *target,
3348 child_stop,
3349 *rule_precedence,
3350 true,
3351 nullable_ctx,
3352 ) {
3353 let child_predicate_dependent = request.predicate_dependent
3354 || !state_is_nullable_with_precedence(
3355 atn,
3356 *target,
3357 child_stop,
3358 *rule_precedence,
3359 false,
3360 nullable_ctx,
3361 );
3362 result = result.union(state_can_reach_symbol_with_precedence(
3363 atn,
3364 *follow_state,
3365 OperatorReachabilityRequest {
3366 predicate_dependent: child_predicate_dependent,
3367 ..request
3368 },
3369 nullable_ctx,
3370 continuations,
3371 visited,
3372 ));
3373 }
3374 result
3375 }
3376 Transition::Epsilon { target }
3377 | Transition::Action { target, .. }
3378 | Transition::Precedence { target, .. } => {
3379 if matches!(
3380 &transition.data(),
3381 Transition::Precedence {
3382 precedence: transition_precedence,
3383 ..
3384 } if *transition_precedence < request.precedence
3385 ) {
3386 continue;
3387 }
3388 state_can_reach_symbol_with_precedence(
3389 atn,
3390 *target,
3391 request,
3392 nullable_ctx,
3393 continuations,
3394 visited,
3395 )
3396 }
3397 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3398 atn,
3399 *target,
3400 OperatorReachabilityRequest {
3401 predicate_dependent: true,
3402 ..request
3403 },
3404 nullable_ctx,
3405 continuations,
3406 visited,
3407 ),
3408 Transition::Atom { .. }
3409 | Transition::Range { .. }
3410 | Transition::Set { .. }
3411 | Transition::NotSet { .. }
3412 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3413 };
3414 reachability = reachability.union(transition_reachability);
3415 }
3416 visited.remove(&key);
3417 reachability
3418}
3419
3420fn left_recursive_operator_lookahead(
3421 atn: &Atn,
3422 state_number: usize,
3423 precedence: i32,
3424) -> LeftRecursiveOperatorLookahead {
3425 let Some(state) = atn.state(state_number) else {
3426 return LeftRecursiveOperatorLookahead::default();
3427 };
3428 let Some(operator_rule_index) = state.rule_index() else {
3429 return LeftRecursiveOperatorLookahead::default();
3430 };
3431 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3432 let mut nullable_ctx = NullablePrecedenceCtx {
3433 cache: FxHashMap::default(),
3434 in_progress: BTreeSet::new(),
3435 hit_cycle: false,
3436 };
3437 for transition in &state.transitions() {
3438 let target = transition.target();
3439 if atn
3440 .state(target)
3441 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3442 {
3443 continue;
3444 }
3445 for symbol in 1..=atn.max_token_type() {
3446 let reachability = state_can_reach_symbol_with_precedence(
3447 atn,
3448 target,
3449 OperatorReachabilityRequest {
3450 symbol,
3451 precedence,
3452 predicate_dependent: false,
3453 operator_rule_index,
3454 },
3455 &mut nullable_ctx,
3456 &mut Vec::new(),
3457 &mut BTreeSet::new(),
3458 );
3459 if reachability.single_token {
3460 lookahead.single_token.insert(symbol);
3461 }
3462 if reachability.multi_token {
3463 lookahead.multi_token_prefix.insert(symbol);
3464 }
3465 if reachability.predicate_dependent {
3466 lookahead.predicate_dependent.insert(symbol);
3467 }
3468 }
3469 }
3470 lookahead
3471}
3472
3473#[derive(Debug, Default)]
3474struct StateBeforeStopLookahead {
3475 symbols: TokenBitSet,
3476 reaches_context_boundary: bool,
3477}
3478
3479fn state_before_stop_lookahead(
3480 atn: &Atn,
3481 state_number: usize,
3482 stop_state_number: usize,
3483) -> Rc<StateBeforeStopLookahead> {
3484 with_shared_atn_caches(atn, |cache| {
3485 let key = (state_number, stop_state_number);
3486 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
3487 return Rc::clone(cached);
3488 }
3489 let mut lookahead = StateBeforeStopLookahead::default();
3490 state_before_stop_lookahead_inner(
3491 atn,
3492 state_number,
3493 stop_state_number,
3494 &mut BTreeSet::new(),
3495 &mut cache.first_set,
3496 &mut lookahead,
3497 );
3498 let lookahead = Rc::new(lookahead);
3499 cache
3500 .state_before_stop_lookahead
3501 .insert(key, Rc::clone(&lookahead));
3502 lookahead
3503 })
3504}
3505
3506fn state_before_stop_lookahead_inner(
3507 atn: &Atn,
3508 state_number: usize,
3509 stop_state_number: usize,
3510 visited: &mut BTreeSet<usize>,
3511 first_set_cache: &mut FirstSetCache,
3512 lookahead: &mut StateBeforeStopLookahead,
3513) {
3514 if state_number == stop_state_number {
3515 lookahead.reaches_context_boundary = true;
3516 return;
3517 }
3518 if !visited.insert(state_number) {
3519 return;
3520 }
3521 let Some(state) = atn.state(state_number) else {
3522 return;
3523 };
3524 if state.kind() == AtnStateKind::RuleStop {
3525 lookahead.reaches_context_boundary = true;
3526 return;
3527 }
3528 for transition in &state.transitions() {
3529 match &transition.data() {
3530 Transition::Epsilon { target }
3531 | Transition::Action { target, .. }
3532 | Transition::Predicate { target, .. }
3533 | Transition::Precedence { target, .. } => {
3534 state_before_stop_lookahead_inner(
3535 atn,
3536 *target,
3537 stop_state_number,
3538 visited,
3539 first_set_cache,
3540 lookahead,
3541 );
3542 }
3543 Transition::Rule {
3544 target,
3545 rule_index,
3546 follow_state,
3547 ..
3548 } => {
3549 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3550 continue;
3551 };
3552 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
3553 lookahead.symbols.extend_from(&child.symbols);
3554 if child.nullable {
3555 state_before_stop_lookahead_inner(
3556 atn,
3557 *follow_state,
3558 stop_state_number,
3559 visited,
3560 first_set_cache,
3561 lookahead,
3562 );
3563 }
3564 }
3565 Transition::Atom { .. }
3566 | Transition::Range { .. }
3567 | Transition::Set { .. }
3568 | Transition::NotSet { .. }
3569 | Transition::Wildcard { .. } => {
3570 lookahead.symbols.extend_iter(transition_expected_symbols(
3571 transition,
3572 atn.max_token_type(),
3573 ));
3574 }
3575 }
3576 }
3577}
3578
3579fn caller_context_can_match_symbol_before_state(
3580 atn: &Atn,
3581 return_states: impl DoubleEndedIterator<Item = usize>,
3582 stop_state_number: usize,
3583 symbol: i32,
3584) -> bool {
3585 for return_state in return_states.rev() {
3586 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
3587 if lookahead.symbols.contains(symbol) {
3588 return true;
3589 }
3590 if !lookahead.reaches_context_boundary {
3591 return false;
3592 }
3593 }
3594 false
3595}
3596
3597fn next_recovery_context(
3601 atn: &Atn,
3602 state: AtnState<'_>,
3603 inherited: &BTreeSet<i32>,
3604 inherited_state: Option<usize>,
3605) -> (BTreeSet<i32>, Option<usize>) {
3606 let state_symbols = state_expected_symbols(atn, state.state_number());
3607 if state.transitions().len() > 1 && !state_symbols.is_empty() {
3608 let mut symbols = state_symbols;
3609 symbols.extend(inherited.iter().copied());
3610 return (symbols, Some(state.state_number()));
3611 }
3612 (inherited.clone(), inherited_state)
3613}
3614
3615fn recovery_expected_symbols(
3616 atn: &Atn,
3617 state_number: usize,
3618 inherited: &BTreeSet<i32>,
3619) -> BTreeSet<i32> {
3620 let mut symbols = state_expected_symbols(atn, state_number);
3621 symbols.extend(inherited.iter().copied());
3622 symbols
3623}
3624
3625fn fast_next_recovery_context<S, H>(
3629 parser: &mut BaseParser<S, H>,
3630 atn: &Atn,
3631 state: AtnState<'_>,
3632 inherited: &Rc<BTreeSet<i32>>,
3633 inherited_state: Option<usize>,
3634) -> (Rc<BTreeSet<i32>>, Option<usize>)
3635where
3636 S: TokenSource,
3637 H: SemanticHooks,
3638{
3639 if state.transitions().len() <= 1 {
3640 return (Rc::clone(inherited), inherited_state);
3641 }
3642 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
3643 if state_symbols.is_empty() {
3644 return (Rc::clone(inherited), inherited_state);
3645 }
3646 if inherited.is_empty() {
3647 return (state_symbols, Some(state.state_number()));
3648 }
3649 if Rc::ptr_eq(&state_symbols, inherited) {
3650 return (state_symbols, Some(state.state_number()));
3651 }
3652 let mut combined = (*state_symbols).clone();
3653 combined.extend(inherited.iter().copied());
3654 (
3655 parser.intern_recovery_symbols(combined),
3656 Some(state.state_number()),
3657 )
3658}
3659
3660fn fast_recovery_expected_symbols<S, H>(
3664 parser: &mut BaseParser<S, H>,
3665 atn: &Atn,
3666 state_number: usize,
3667 inherited: &Rc<BTreeSet<i32>>,
3668) -> Rc<BTreeSet<i32>>
3669where
3670 S: TokenSource,
3671 H: SemanticHooks,
3672{
3673 let cached = parser.cached_state_expected_symbols(atn, state_number);
3674 if inherited.is_empty() {
3675 return cached;
3676 }
3677 if cached.is_empty() {
3678 return Rc::clone(inherited);
3679 }
3680 if Rc::ptr_eq(&cached, inherited) {
3681 return cached;
3682 }
3683 let mut combined = (*cached).clone();
3684 combined.extend(inherited.iter().copied());
3685 parser.intern_recovery_symbols(combined)
3686}
3687
3688struct ParserTableSemCtx<'a> {
3689 member_values: &'a mut BTreeMap<usize, i64>,
3690 return_values: &'a mut BTreeMap<String, i64>,
3691}
3692
3693impl semir::PredContext for ParserTableSemCtx<'_> {
3694 type TokenText<'a>
3695 = &'a str
3696 where
3697 Self: 'a;
3698
3699 fn la(&mut self, _offset: isize) -> i64 {
3700 i64::from(TOKEN_EOF)
3701 }
3702
3703 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
3704 None
3705 }
3706
3707 fn token_index_adjacent(&mut self) -> bool {
3708 false
3709 }
3710
3711 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
3712 None
3713 }
3714
3715 fn member(&self, member: usize) -> Option<i64> {
3716 Some(self.member_values.get(&member).copied().unwrap_or_default())
3717 }
3718
3719 fn local_arg(&self) -> Option<i64> {
3720 None
3721 }
3722
3723 fn column(&self) -> Option<i64> {
3724 None
3725 }
3726
3727 fn token_start_column(&self) -> Option<i64> {
3728 None
3729 }
3730
3731 fn token_text_so_far(&self) -> Option<String> {
3732 None
3733 }
3734
3735 fn hook(&mut self, _hook: HookId) -> bool {
3736 false
3737 }
3738}
3739
3740impl semir::ActContext for ParserTableSemCtx<'_> {
3741 fn set_member(&mut self, member: usize, value: i64) {
3742 self.member_values.insert(member, value);
3743 }
3744
3745 fn set_return(&mut self, name: &str, value: i64) {
3746 self.return_values.insert(name.to_owned(), value);
3747 }
3748
3749 fn action_hook(&mut self, _hook: HookId) {}
3750}
3751
3752fn apply_member_actions(
3754 source_state: usize,
3755 actions: &[ParserMemberAction],
3756 semantics: Option<&ParserSemantics>,
3757 values: &mut BTreeMap<usize, i64>,
3758) {
3759 for action in actions
3760 .iter()
3761 .filter(|action| action.source_state == source_state)
3762 {
3763 *values.entry(action.member).or_default() += action.delta;
3764 }
3765 let Some(semantics) = semantics else {
3766 return;
3767 };
3768 let mut return_values = BTreeMap::new();
3769 let mut ctx = ParserTableSemCtx {
3770 member_values: values,
3771 return_values: &mut return_values,
3772 };
3773 for action in semantics
3774 .actions
3775 .iter()
3776 .filter(|action| action.source_state == source_state && action.speculative)
3777 {
3778 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3779 }
3780}
3781
3782fn member_values_after_action(
3784 source_state: usize,
3785 actions: &[ParserMemberAction],
3786 semantics: Option<&ParserSemantics>,
3787 values: &BTreeMap<usize, i64>,
3788) -> BTreeMap<usize, i64> {
3789 let mut values = values.clone();
3790 apply_member_actions(source_state, actions, semantics, &mut values);
3791 values
3792}
3793
3794fn return_values_after_action(
3796 source_state: usize,
3797 rule_index: usize,
3798 actions: &[ParserReturnAction],
3799 semantics: Option<&ParserSemantics>,
3800 values: &BTreeMap<String, i64>,
3801) -> BTreeMap<String, i64> {
3802 let mut values = values.clone();
3803 for action in actions
3804 .iter()
3805 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
3806 {
3807 values.insert(action.name.to_owned(), action.value);
3808 }
3809 if let Some(semantics) = semantics {
3810 let mut member_values = BTreeMap::new();
3811 let mut ctx = ParserTableSemCtx {
3812 member_values: &mut member_values,
3813 return_values: &mut values,
3814 };
3815 for action in semantics.actions.iter().filter(|action| {
3816 action.source_state == source_state
3817 && action.rule_index == rule_index
3818 && !action.speculative
3819 }) {
3820 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3821 }
3822 }
3823 values
3824}
3825
3826fn rule_local_int_arg(
3828 rule_args: &[ParserRuleArg],
3829 source_state: usize,
3830 rule_index: usize,
3831 local_int_arg: Option<(usize, i64)>,
3832) -> Option<(usize, i64)> {
3833 rule_args
3834 .iter()
3835 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
3836 .map(|arg| {
3837 let value = if arg.inherit_local {
3838 local_int_arg.map_or(arg.value, |(_, value)| value)
3839 } else {
3840 arg.value
3841 };
3842 (rule_index, value)
3843 })
3844}
3845
3846fn stop_outcome(
3849 index: usize,
3850 consumed_eof: bool,
3851 rule_alt_number: usize,
3852 member_values: BTreeMap<usize, i64>,
3853 return_values: BTreeMap<String, i64>,
3854) -> Vec<RecognizeOutcome> {
3855 vec![RecognizeOutcome {
3856 index,
3857 consumed_eof,
3858 alt_number: rule_alt_number,
3859 member_values,
3860 return_values,
3861 diagnostics: DiagnosticSeqId::EMPTY,
3862 decisions: Vec::new(),
3863 actions: Vec::new(),
3864 nodes: NodeSeqId::EMPTY,
3865 }]
3866}
3867
3868fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
3869 with_shared_atn_caches(atn, |cache| {
3870 *cache.observable_action_transitions.get_or_insert_with(|| {
3871 atn.states().any(|state| {
3872 state.transitions().iter().any(|transition| {
3873 matches!(
3874 &transition.data(),
3875 Transition::Action {
3876 action_index: Some(_),
3877 ..
3878 }
3879 )
3880 })
3881 })
3882 })
3883 })
3884}
3885
3886fn atn_has_predicate_transitions(atn: &Atn) -> bool {
3887 with_shared_atn_caches(atn, |cache| {
3888 *cache.predicate_transitions.get_or_insert_with(|| {
3889 atn.states().any(|state| {
3890 state
3891 .transitions()
3892 .iter()
3893 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
3894 })
3895 })
3896 })
3897}
3898
3899fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
3904 options.init_action_rules.is_empty()
3905 && !options.track_alt_numbers
3906 && options
3907 .predicates
3908 .iter()
3909 .all(|(_, _, predicate)| predicate.failure_message().is_none())
3910 && options.semantics.is_none_or(|semantics| {
3911 semantics.actions.is_empty()
3912 && semantics
3913 .predicates
3914 .iter()
3915 .all(|predicate| predicate.failure_message.is_none())
3916 })
3917 && options.rule_args.is_empty()
3918 && options.member_actions.is_empty()
3919 && options.return_actions.is_empty()
3920 && !atn_has_observable_action_transitions(atn)
3921}
3922
3923#[derive(Clone, Debug, Eq, PartialEq)]
3924struct RecognizeRequest<'a> {
3925 state_number: usize,
3926 stop_state: usize,
3927 index: usize,
3928 rule_start_index: usize,
3929 decision_start_index: Option<usize>,
3930 init_action_rules: &'a BTreeSet<usize>,
3931 predicates: &'a [(usize, usize, ParserPredicate)],
3932 semantics: Option<&'a ParserSemantics>,
3933 rule_args: &'a [ParserRuleArg],
3934 member_actions: &'a [ParserMemberAction],
3935 return_actions: &'a [ParserReturnAction],
3936 local_int_arg: Option<(usize, i64)>,
3937 member_values: BTreeMap<usize, i64>,
3938 return_values: BTreeMap<String, i64>,
3939 rule_alt_number: usize,
3940 track_alt_numbers: bool,
3941 consumed_eof: bool,
3942 precedence: i32,
3945 depth: usize,
3946 recovery_symbols: BTreeSet<i32>,
3947 recovery_state: Option<usize>,
3948}
3949
3950#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
3951struct RecognizeKey {
3952 state_number: usize,
3953 stop_state: usize,
3954 index: usize,
3955 rule_start_index: usize,
3956 decision_start_index: Option<usize>,
3957 local_int_arg: Option<(usize, i64)>,
3958 member_values: BTreeMap<usize, i64>,
3959 return_values: BTreeMap<String, i64>,
3960 rule_alt_number: usize,
3961 track_alt_numbers: bool,
3962 consumed_eof: bool,
3963 precedence: i32,
3964 recovery_symbols: BTreeSet<i32>,
3965 recovery_state: Option<usize>,
3966}
3967
3968#[derive(Clone, Debug, Eq, PartialEq)]
3969struct EpsilonActionStep {
3970 source_state: usize,
3971 target: usize,
3972 action_rule_index: Option<usize>,
3973 left_recursive_boundary: Option<usize>,
3974 decision: Option<usize>,
3975 decision_start_index: Option<usize>,
3976 alt_number: usize,
3977 recovery_symbols: BTreeSet<i32>,
3978 recovery_state: Option<usize>,
3979}
3980
3981struct RecognizeScratch<'a> {
3982 visiting: &'a mut BTreeSet<RecognizeKey>,
3983 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
3984 expected: &'a mut ExpectedTokens,
3985}
3986
3987#[derive(Clone, Debug, Eq, PartialEq)]
3988struct FastRecognizeRequest {
3989 state_number: usize,
3990 stop_state: usize,
3991 index: usize,
3992 rule_start_index: usize,
3993 decision_start_index: Option<usize>,
3994 precedence: i32,
3995 depth: usize,
3996 recovery_symbols: Rc<BTreeSet<i32>>,
3997 recovery_state: Option<usize>,
3998}
3999
4000#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4001struct FastRecognizeTopRequest {
4002 start_state: usize,
4003 stop_state: usize,
4004 start_index: usize,
4005 precedence: i32,
4006 caller_follow_state: Option<usize>,
4007}
4008
4009#[derive(Clone, Copy, Debug)]
4010struct FastPredicateContext<'a> {
4011 predicates: &'a [(usize, usize, ParserPredicate)],
4012 semantics: Option<&'a ParserSemantics>,
4013 member_values: &'a BTreeMap<usize, i64>,
4014}
4015
4016struct FastRecognizeScratch<'a, 'b> {
4017 predicate_context: Option<FastPredicateContext<'a>>,
4018 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4019 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4020 expected: &'b mut ExpectedTokens,
4021}
4022
4023#[derive(Clone, Copy, Debug)]
4024struct FastRepetitionShape {
4025 enter_target: usize,
4026 exit_target: usize,
4027 body_stop_state: usize,
4028 enter_transition_index: usize,
4029 exit_transition_index: usize,
4030}
4031
4032#[derive(Clone, Copy, Debug)]
4033struct FastRepetitionPath {
4034 index: usize,
4035 deferred_nodes: FastDeferredNodeId,
4036 diagnostics: DiagnosticSeqId,
4037 consumed_eof: bool,
4038}
4039
4040enum FastRepetitionWork {
4041 Enter(FastRepetitionPath),
4042 Exit(FastRepetitionPath),
4043}
4044
4045struct FastRepetitionCoordinates {
4050 base_index: usize,
4051 base_state: u8,
4052 later_states: Vec<u8>,
4053}
4054
4055impl FastRepetitionCoordinates {
4056 const ENTERED: u8 = 0;
4057 const EXITED: u8 = 2;
4058
4059 const fn new(base_index: usize) -> Self {
4060 Self {
4061 base_index,
4062 base_state: 0,
4063 later_states: Vec::new(),
4064 }
4065 }
4066
4067 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4068 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4069 }
4070
4071 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4072 self.insert(path.index, path.consumed_eof, Self::EXITED)
4073 }
4074
4075 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4076 let Some(offset) = index.checked_sub(self.base_index) else {
4077 return false;
4078 };
4079 let state = if offset == 0 {
4080 &mut self.base_state
4081 } else {
4082 if self.later_states.len() < offset {
4083 self.later_states.resize(offset, 0);
4084 }
4085 &mut self.later_states[offset - 1]
4086 };
4087 let bit = 1 << (base_bit + u8::from(consumed_eof));
4088 let is_new = *state & bit == 0;
4089 *state |= bit;
4090 is_new
4091 }
4092}
4093
4094fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4095 if state.precedence_rule_decision()
4096 || !matches!(
4097 state.kind(),
4098 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4099 )
4100 || state.transitions().len() != 2
4101 {
4102 return None;
4103 }
4104 let mut enter = None;
4105 let mut exit = None;
4106 for (index, transition) in state.transitions().iter().enumerate() {
4107 if transition.kind() != ParserTransitionKind::Epsilon {
4108 return None;
4109 }
4110 let target = transition.target();
4111 if atn
4112 .state(target)
4113 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4114 {
4115 if exit.replace((index, target)).is_some() {
4116 return None;
4117 }
4118 } else if enter.replace((index, target)).is_some() {
4119 return None;
4120 }
4121 }
4122 let (enter_transition_index, enter_target) = enter?;
4123 let (exit_transition_index, exit_target) = exit?;
4124 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4125 atn.state(exit_target)?.loop_back_state()?
4126 } else {
4127 state.state_number()
4128 };
4129 Some(FastRepetitionShape {
4130 enter_target,
4131 exit_target,
4132 body_stop_state,
4133 enter_transition_index,
4134 exit_transition_index,
4135 })
4136}
4137
4138fn push_fast_repetition_work(
4139 work: &mut Vec<FastRepetitionWork>,
4140 shape: FastRepetitionShape,
4141 path: FastRepetitionPath,
4142 lookahead: Option<&DecisionLookahead>,
4143 symbol: i32,
4144) {
4145 let transition_is_viable = |transition_index: usize| {
4148 let Some(entry) = lookahead else {
4149 return true;
4150 };
4151 let Some(transition) = entry.transitions.get(transition_index) else {
4152 return true;
4153 };
4154 transition.nullable || transition.symbols.contains(symbol)
4155 };
4156 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4157 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4158 if shape.enter_transition_index < shape.exit_transition_index {
4159 if exit_is_viable {
4160 work.push(FastRepetitionWork::Exit(path));
4161 }
4162 if enter_is_viable {
4163 work.push(FastRepetitionWork::Enter(path));
4164 }
4165 } else {
4166 if enter_is_viable {
4167 work.push(FastRepetitionWork::Enter(path));
4168 }
4169 if exit_is_viable {
4170 work.push(FastRepetitionWork::Exit(path));
4171 }
4172 }
4173}
4174
4175#[derive(Clone, Debug)]
4182struct FastRecognizeKey {
4183 state_number: usize,
4184 stop_state: usize,
4185 index: usize,
4186 rule_start_index: usize,
4187 decision_start_index: Option<usize>,
4188 precedence: i32,
4189 recovery_symbols_id: usize,
4190 recovery_state: Option<usize>,
4191}
4192
4193impl PartialEq for FastRecognizeKey {
4194 fn eq(&self, other: &Self) -> bool {
4195 if self.state_number != other.state_number
4196 || self.stop_state != other.stop_state
4197 || self.index != other.index
4198 || self.rule_start_index != other.rule_start_index
4199 || self.decision_start_index != other.decision_start_index
4200 || self.precedence != other.precedence
4201 || self.recovery_state != other.recovery_state
4202 || self.recovery_symbols_id != other.recovery_symbols_id
4203 {
4204 return false;
4205 }
4206 true
4207 }
4208}
4209
4210impl Eq for FastRecognizeKey {}
4211
4212impl Hash for FastRecognizeKey {
4213 fn hash<H: Hasher>(&self, hasher: &mut H) {
4214 self.state_number.hash(hasher);
4215 self.stop_state.hash(hasher);
4216 self.index.hash(hasher);
4217 self.rule_start_index.hash(hasher);
4218 self.decision_start_index.hash(hasher);
4219 self.precedence.hash(hasher);
4220 self.recovery_state.hash(hasher);
4221 self.recovery_symbols_id.hash(hasher);
4222 }
4223}
4224
4225struct FastRecoveryRequest<'a, 'b> {
4226 atn: &'a Atn,
4227 transition: ParserTransition<'a>,
4228 expected_symbols: Rc<BTreeSet<i32>>,
4229 target: usize,
4230 request: FastRecognizeRequest,
4231 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4232 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4233 expected: &'b mut ExpectedTokens,
4234}
4235
4236struct FastCurrentTokenDeletionRequest<'a, 'b> {
4237 atn: &'a Atn,
4238 expected_symbols: Rc<BTreeSet<i32>>,
4239 request: FastRecognizeRequest,
4240 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4241 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4242 expected: &'b mut ExpectedTokens,
4243}
4244
4245#[derive(Clone, Copy)]
4246struct FastChildRuleFailureRecoveryRequest<'a> {
4247 atn: &'a Atn,
4248 rule_index: usize,
4249 start_index: usize,
4250 follow_state: usize,
4251 stop_state: usize,
4252 expected: &'a ExpectedTokens,
4253}
4254
4255struct RecoveryRequest<'a, 'b> {
4256 atn: &'a Atn,
4257 transition: ParserTransition<'a>,
4258 expected_symbols: BTreeSet<i32>,
4259 target: usize,
4260 request: RecognizeRequest<'a>,
4261 visiting: &'b mut BTreeSet<RecognizeKey>,
4262 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4263 expected: &'b mut ExpectedTokens,
4264}
4265
4266struct CurrentTokenDeletionRequest<'a, 'b> {
4267 atn: &'a Atn,
4268 expected_symbols: BTreeSet<i32>,
4269 request: RecognizeRequest<'a>,
4270 visiting: &'b mut BTreeSet<RecognizeKey>,
4271 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4272 expected: &'b mut ExpectedTokens,
4273}
4274
4275struct ConsumingFailureFallback<'a> {
4278 atn: &'a Atn,
4279 target: usize,
4280 request: RecognizeRequest<'a>,
4281 symbol: i32,
4282 expected_symbols: BTreeSet<i32>,
4283 decision_start_index: Option<usize>,
4284 decision: Option<usize>,
4285}
4286
4287struct ChildRuleFailureRecovery<'a> {
4290 atn: &'a Atn,
4291 rule_index: usize,
4292 start_index: usize,
4293 follow_state: usize,
4294 stop_state: usize,
4295 member_values: BTreeMap<usize, i64>,
4296 expected: &'a ExpectedTokens,
4297}
4298
4299#[derive(Clone, Copy, Debug)]
4301struct PredicateEval<'a> {
4302 index: usize,
4303 rule_index: usize,
4304 pred_index: usize,
4305 predicates: &'a [(usize, usize, ParserPredicate)],
4306 semantics: Option<&'a ParserSemantics>,
4307 context: Option<&'a ParserRuleContext>,
4308 local_int_arg: Option<(usize, i64)>,
4309 member_values: &'a BTreeMap<usize, i64>,
4310}
4311
4312#[derive(Clone, Copy, Debug)]
4313struct ParserSemanticHookRequest<'a> {
4314 index: usize,
4315 rule_index: usize,
4316 pred_index: usize,
4317 context: Option<&'a ParserRuleContext>,
4318 local_int_arg: Option<(usize, i64)>,
4319 member_values: &'a BTreeMap<usize, i64>,
4320}
4321
4322struct ParserSemIrCtx<'a, S, H>
4331where
4332 S: TokenSource,
4333 H: SemanticHooks,
4334{
4335 input: &'a mut CommonTokenStream<S>,
4336 tree_storage: &'a ParseTreeStorage,
4337 semantic_hooks: &'a mut H,
4338 rule_index: usize,
4339 coordinate_index: usize,
4340 rule_name: Option<&'a str>,
4341 context: Option<&'a ParserRuleContext>,
4342 local_int_arg: Option<(usize, i64)>,
4343 member_values: &'a BTreeMap<usize, i64>,
4344 invoked_predicates: &'a mut Vec<(usize, usize)>,
4345 unknown_predicate_policy: UnknownSemanticPolicy,
4349 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4350}
4351
4352impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4353where
4354 S: TokenSource,
4355 H: SemanticHooks,
4356{
4357 type TokenText<'a>
4358 = TokenView<'a>
4359 where
4360 Self: 'a;
4361
4362 fn la(&mut self, offset: isize) -> i64 {
4363 i64::from(self.input.la(offset))
4364 }
4365
4366 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4367 self.input.lt(offset)
4368 }
4369
4370 fn token_index_adjacent(&mut self) -> bool {
4371 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4372 return false;
4373 };
4374 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4375 return false;
4376 };
4377 first + 1 == second
4378 }
4379
4380 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4381 self.context.and_then(|context| {
4382 context
4383 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4384 .next()
4385 .map(crate::tree::RuleNodeView::text)
4386 })
4387 }
4388
4389 fn member(&self, member: usize) -> Option<i64> {
4390 Some(self.member_values.get(&member).copied().unwrap_or_default())
4391 }
4392
4393 fn local_arg(&self) -> Option<i64> {
4394 self.local_int_arg.map(|(_, value)| value)
4395 }
4396
4397 fn column(&self) -> Option<i64> {
4398 None
4399 }
4400
4401 fn token_start_column(&self) -> Option<i64> {
4402 None
4403 }
4404
4405 fn token_text_so_far(&self) -> Option<String> {
4406 None
4407 }
4408
4409 fn hook(&mut self, _hook: HookId) -> bool {
4410 let mut ctx = ParserSemCtx {
4411 input: &mut *self.input,
4412 tree_storage: self.tree_storage,
4413 rule_index: self.rule_index,
4414 coordinate_index: self.coordinate_index,
4415 rule_name: self.rule_name.map(str::to_owned),
4416 context: self.context,
4417 tree: None,
4418 local_int_arg: self.local_int_arg,
4419 member_values: self.member_values,
4420 action: None,
4421 };
4422 match self
4423 .semantic_hooks
4424 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4425 {
4426 Some(result) => result,
4427 None => apply_unknown_predicate_policy(
4431 self.unknown_predicate_policy,
4432 self.rule_index,
4433 self.coordinate_index,
4434 self.unknown_predicate_hits,
4435 ),
4436 }
4437 }
4438
4439 fn trace_bool(&mut self, value: bool) -> bool {
4440 let key = (self.rule_index, self.coordinate_index);
4441 if !self.invoked_predicates.contains(&key) {
4442 self.invoked_predicates.push(key);
4443 use std::io::Write as _;
4444 let mut stdout = std::io::stdout().lock();
4445 let _ = writeln!(stdout, "eval={value}");
4446 }
4447 value
4448 }
4449}
4450
4451struct PredicateFailureRecovery<'a> {
4453 rule_index: usize,
4454 index: usize,
4455 message: &'a str,
4456 member_values: BTreeMap<usize, i64>,
4457 return_values: BTreeMap<String, i64>,
4458 rule_alt_number: usize,
4459}
4460
4461#[derive(Debug)]
4462enum DirectAdaptiveParseControl {
4463 Fallback(DirectAdaptiveFallback),
4464}
4465
4466#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4467enum DirectAdaptiveFallback {
4468 Action,
4469 InvalidAlt,
4470 LeftRecursiveBoundary,
4471 MissingAtn,
4472 NoTransition,
4473 Predicate,
4474 Prediction,
4475 Precedence,
4476 RuleStop,
4477 SemanticContext,
4478 StepLimit,
4479 TokenMismatch,
4480 UnknownDecision,
4481}
4482
4483type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
4484
4485struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
4486where
4487 S: TokenSource,
4488 H: SemanticHooks,
4489{
4490 parser: &'sim mut BaseParser<S, H>,
4491 atn: &'atn Atn,
4492 simulator: &'sim mut ParserAtnSimulator<'atn>,
4493 decision_by_state: Vec<Option<usize>>,
4494 steps: usize,
4495}
4496
4497#[derive(Clone, Debug, Eq, PartialEq)]
4507pub struct GeneratedMatch {
4508 children: GeneratedMatchChildren,
4509 consumed_eof: bool,
4510}
4511
4512#[derive(Clone, Debug, Eq, PartialEq)]
4513enum GeneratedMatchChildren {
4514 One(ParseTree),
4515 Many(Vec<ParseTree>),
4516}
4517
4518struct GeneratedMatchChildrenIntoIter {
4519 one: Option<ParseTree>,
4520 many: Option<std::vec::IntoIter<ParseTree>>,
4521}
4522
4523impl Iterator for GeneratedMatchChildrenIntoIter {
4524 type Item = ParseTree;
4525
4526 fn next(&mut self) -> Option<Self::Item> {
4527 self.one
4528 .take()
4529 .or_else(|| self.many.as_mut().and_then(Iterator::next))
4530 }
4531}
4532
4533impl GeneratedMatch {
4534 #[must_use]
4538 pub fn children(&self) -> &[ParseTree] {
4539 match &self.children {
4540 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
4541 GeneratedMatchChildren::Many(children) => children,
4542 }
4543 }
4544
4545 #[must_use]
4548 pub fn into_children(self) -> Vec<ParseTree> {
4549 match self.children {
4550 GeneratedMatchChildren::One(child) => vec![child],
4551 GeneratedMatchChildren::Many(children) => children,
4552 }
4553 }
4554
4555 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
4557 match self.children {
4558 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
4559 one: Some(child),
4560 many: None,
4561 },
4562 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
4563 one: None,
4564 many: Some(children.into_iter()),
4565 },
4566 }
4567 }
4568
4569 #[must_use]
4571 pub const fn consumed_eof(&self) -> bool {
4572 self.consumed_eof
4573 }
4574}
4575
4576impl<S> BaseParser<S, NoSemanticHooks>
4577where
4578 S: TokenSource,
4579{
4580 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
4583 Self::with_semantic_hooks(input, data, NoSemanticHooks)
4584 }
4585}
4586
4587impl<S, H> BaseParser<S, H>
4588where
4589 S: TokenSource,
4590 H: SemanticHooks,
4591{
4592 pub fn with_semantic_hooks(
4594 input: CommonTokenStream<S>,
4595 data: RecognizerData,
4596 semantic_hooks: H,
4597 ) -> Self {
4598 Self {
4599 input,
4600 tree: ParseTreeStorage::new(),
4601 data,
4602 semantic_hooks,
4603 build_parse_trees: true,
4604 syntax_errors: 0,
4605 report_diagnostic_errors: false,
4606 prediction_mode: PredictionMode::Ll,
4607 prediction_diagnostics: Vec::new(),
4608 reported_prediction_diagnostics: BTreeSet::new(),
4609 generated_parser_diagnostics: Vec::new(),
4610 generated_sync_expected: None,
4611 int_members: BTreeMap::new(),
4612 rule_context_stack: Vec::new(),
4613 rule_context_version: 0,
4614 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
4615 pending_invoking_states: Vec::new(),
4616 precedence_stack: vec![0],
4617 invoked_predicates: Vec::new(),
4618 bail_on_error: false,
4619 unknown_predicate_policy: UnknownSemanticPolicy::default(),
4620 unknown_predicate_hits: Vec::new(),
4621 unhandled_action_hits: Vec::new(),
4622 rule_first_set_cache: Vec::new(),
4623 state_expected_cache: FxHashMap::default(),
4624 state_expected_token_cache: FxHashMap::default(),
4625 rule_stop_reach_cache: Vec::new(),
4626 recovery_symbols_intern: FxHashMap::default(),
4627 decision_lookahead_cache: FxHashMap::default(),
4628 ll1_decision_cache: FxHashMap::default(),
4629 fast_predicate_cache: FxHashMap::default(),
4630 empty_cycle_cache: Vec::new(),
4631 empty_cycle_cache_atn: None,
4632 clean_memo_mode: CleanMemoMode::Probe,
4633 clean_memo_probe_seen: FxHashSet::default(),
4634 clean_memo_probe_samples: 0,
4635 clean_memo_probe_repeats: 0,
4636 clean_memo_sparse_samples: 0,
4637 fast_recognize_scratch: FastRecognizeTopScratch::default(),
4638 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
4639 empty_recovery_symbols: Rc::new(BTreeSet::new()),
4640 fast_first_set_prefilter: true,
4641 fast_recovery_enabled: true,
4642 fast_token_nodes_enabled: true,
4643 recognition_arena: RecognitionArena::default(),
4644 last_recognition_arena_root: NodeSeqId::EMPTY,
4645 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
4646 }
4647 }
4648
4649 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
4650 &mut self.input
4651 }
4652
4653 pub fn reset(&mut self) {
4658 self.input.seek(0);
4659 self.tree.reset();
4660 self.data.set_state(-1);
4661 self.syntax_errors = 0;
4662 self.prediction_diagnostics.clear();
4663 self.reported_prediction_diagnostics.clear();
4664 self.generated_parser_diagnostics.clear();
4665 self.generated_sync_expected = None;
4666 self.rule_context_stack.clear();
4667 self.advance_rule_context_version();
4668 self.left_recursive_caller_overlap_cache = std::array::from_fn(|_| None);
4669 self.pending_invoking_states.clear();
4670 self.precedence_stack.clear();
4671 self.precedence_stack.push(0);
4672 self.invoked_predicates.clear();
4673 self.unknown_predicate_hits.clear();
4674 self.unhandled_action_hits.clear();
4675 self.reset_per_parse_caches();
4676 self.fast_first_set_prefilter = true;
4677 self.fast_recovery_enabled = true;
4678 self.fast_token_nodes_enabled = self.build_parse_trees;
4679 self.reset_recognition_arena();
4680 }
4681
4682 pub fn set_token_stream(&mut self, input: CommonTokenStream<S>) {
4684 self.input = input;
4685 self.reset();
4686 }
4687
4688 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
4699 self.unknown_predicate_policy = policy;
4700 }
4701
4702 #[must_use]
4708 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
4709 let error = self.unknown_semantic_error();
4710 self.unknown_predicate_hits.clear();
4711 self.unhandled_action_hits.clear();
4712 error
4713 }
4714
4715 pub fn reset_unknown_semantic_hits(&mut self) {
4722 self.unknown_predicate_hits.clear();
4723 self.unhandled_action_hits.clear();
4724 }
4725
4726 #[must_use]
4728 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
4729 &self.input
4730 }
4731
4732 #[must_use]
4734 pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<S> {
4735 &mut self.input
4736 }
4737
4738 #[must_use]
4740 pub const fn token_store(&self) -> &TokenStore {
4741 self.input.token_store()
4742 }
4743
4744 #[must_use]
4746 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
4747 &self.tree
4748 }
4749
4750 #[must_use]
4752 pub fn node(&self, id: NodeId) -> Node<'_> {
4753 self.tree
4754 .node(self.input.token_store(), id)
4755 .expect("parser-produced node ID should remain valid")
4756 }
4757
4758 #[must_use]
4760 pub fn into_token_stream(self) -> CommonTokenStream<S> {
4761 self.input
4762 }
4763
4764 #[must_use]
4766 pub fn into_token_store(self) -> TokenStore {
4767 self.input.into_token_store()
4768 }
4769
4770 #[must_use]
4772 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
4773 ParsedFile::new(self.input.into_token_store(), self.tree, root)
4774 }
4775
4776 pub const fn number_of_syntax_errors(&self) -> usize {
4779 self.syntax_errors
4780 }
4781
4782 #[must_use]
4788 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
4789 self.recognition_arena.stats(
4790 self.last_recognition_arena_root,
4791 self.last_recognition_arena_diagnostics,
4792 )
4793 }
4794
4795 pub const fn record_generated_syntax_error(&mut self) {
4798 self.record_syntax_errors(1);
4799 }
4800
4801 const fn record_syntax_errors(&mut self, count: usize) {
4802 self.syntax_errors = self.syntax_errors.saturating_add(count);
4803 }
4804
4805 pub fn report_token_source_errors(&mut self) {
4808 report_token_source_errors(&self.input.drain_source_errors());
4809 }
4810
4811 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
4814 GeneratedDiagnosticsCheckpoint {
4815 diagnostics_len: self.generated_parser_diagnostics.len(),
4816 syntax_errors: self.syntax_errors,
4817 tree: self.tree.checkpoint(),
4818 }
4819 }
4820
4821 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
4823 self.generated_parser_diagnostics
4824 .truncate(marker.diagnostics_len);
4825 self.syntax_errors = marker.syntax_errors;
4826 self.generated_sync_expected = None;
4827 self.tree.rollback(marker.tree);
4828 }
4829
4830 pub fn report_generated_parser_diagnostics(&mut self) {
4832 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
4833 let token_errors = self.input.drain_source_errors();
4834 report_generated_diagnostics(&parser_diagnostics, &token_errors);
4835 }
4836
4837 pub fn record_generated_ambiguity_diagnostic(
4840 &mut self,
4841 atn: &Atn,
4842 state_number: usize,
4843 start_index: usize,
4844 stop_index: usize,
4845 alts: &[usize],
4846 ) {
4847 if !self.report_diagnostic_errors || alts.len() < 2 {
4848 return;
4849 }
4850 let Some(decision) = atn
4851 .decision_to_state()
4852 .iter()
4853 .position(|candidate| candidate == state_number)
4854 else {
4855 return;
4856 };
4857 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
4858 return;
4859 };
4860 let rule_name = self
4861 .rule_names()
4862 .get(rule_index)
4863 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
4864 let input = display_input_text(&self.input.text(start_index, stop_index));
4865 let alts = alts
4866 .iter()
4867 .map(usize::to_string)
4868 .collect::<Vec<_>>()
4869 .join(", ");
4870 let key = (decision, start_index, format!("{alts}:{input}"));
4871 if !self.reported_prediction_diagnostics.insert(key) {
4872 return;
4873 }
4874 let start_diagnostic = diagnostic_for_token(
4875 self.token_at(start_index),
4876 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
4877 );
4878 let stop_diagnostic = diagnostic_for_token(
4879 self.token_at(stop_index),
4880 format!(
4881 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
4882 ),
4883 );
4884 self.generated_parser_diagnostics.push(start_diagnostic);
4885 self.generated_parser_diagnostics.push(stop_diagnostic);
4886 }
4887
4888 pub fn record_generated_prediction_diagnostic(
4891 &mut self,
4892 atn: &Atn,
4893 state_number: usize,
4894 prediction: &ParserAtnPrediction,
4895 ) {
4896 let Some(diagnostic) = &prediction.diagnostic else {
4897 return;
4898 };
4899 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
4900 return;
4901 }
4902 let Some(decision) = atn
4903 .decision_to_state()
4904 .iter()
4905 .position(|candidate| candidate == state_number)
4906 else {
4907 return;
4908 };
4909 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
4910 return;
4911 };
4912 let rule_name = self
4913 .rule_names()
4914 .get(rule_index)
4915 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
4916 let attempt_input = display_input_text(
4917 &self
4918 .input
4919 .text(diagnostic.start_index, diagnostic.sll_stop_index),
4920 );
4921 let result_input = display_input_text(
4922 &self
4923 .input
4924 .text(diagnostic.start_index, diagnostic.ll_stop_index),
4925 );
4926 let alts = diagnostic
4927 .conflicting_alts
4928 .iter()
4929 .map(usize::to_string)
4930 .collect::<Vec<_>>()
4931 .join(", ");
4932 let key = (
4933 decision,
4934 diagnostic.start_index,
4935 format!(
4936 "{:?}:{alts}:{attempt_input}:{result_input}",
4937 diagnostic.kind
4938 ),
4939 );
4940 if !self.reported_prediction_diagnostics.insert(key) {
4941 return;
4942 }
4943 let attempt_diagnostic = diagnostic_for_token(
4944 self.token_at(diagnostic.sll_stop_index),
4945 format!(
4946 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
4947 ),
4948 );
4949 self.generated_parser_diagnostics.push(attempt_diagnostic);
4950 let message = match diagnostic.kind {
4951 ParserAtnPredictionDiagnosticKind::Ambiguity => {
4952 if !diagnostic.exact {
4957 return;
4958 }
4959 format!(
4960 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
4961 )
4962 }
4963 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
4964 format!(
4965 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
4966 )
4967 }
4968 };
4969 let result_diagnostic =
4970 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
4971 self.generated_parser_diagnostics.push(result_diagnostic);
4972 }
4973
4974 pub fn la(&self, offset: isize) -> i32 {
4975 self.input.la_token(offset)
4976 }
4977
4978 pub fn consume(&mut self) {
4979 IntStream::consume(&mut self.input);
4980 }
4981
4982 pub fn set_int_member(&mut self, member: usize, value: i64) {
4984 self.int_members.insert(member, value);
4985 }
4986
4987 pub fn int_member(&self, member: usize) -> Option<i64> {
4989 self.int_members.get(&member).copied()
4990 }
4991
4992 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
4995 self.int_members.clone()
4996 }
4997
4998 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
5000 self.int_members = members;
5001 }
5002
5003 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5005 let value = self.int_members.entry(member).or_default();
5006 *value += delta;
5007 *value
5008 }
5009
5010 fn token_type_for_id(&self, id: TokenId) -> i32 {
5011 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5012 }
5013
5014 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5015 if self.build_parse_trees {
5016 self.tree.terminal(id)
5017 } else {
5018 NodeId::placeholder()
5019 }
5020 }
5021
5022 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5023 if self.build_parse_trees {
5024 self.tree.error(id)
5025 } else {
5026 NodeId::placeholder()
5027 }
5028 }
5029
5030 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5031 context.set_start_id(id);
5032 }
5033
5034 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5035 context.set_stop_id(id);
5036 }
5037
5038 fn insert_synthetic_token(
5039 &mut self,
5040 token_type: i32,
5041 text: String,
5042 line: usize,
5043 column: usize,
5044 ) -> Result<TokenId, AntlrError> {
5045 self.input
5046 .insert(
5047 TokenSpec::explicit(token_type, text)
5048 .with_span(usize::MAX, usize::MAX)
5049 .with_byte_span(0, 0)
5050 .with_position(line, column),
5051 )
5052 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5053 }
5054
5055 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5062 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5063 line: 0,
5064 column: 0,
5065 message: "missing current token".to_owned(),
5066 })?;
5067 let current_type = self.token_type_for_id(current);
5068 if current_type == token_type {
5069 self.consume();
5070 Ok(self.terminal_tree(current))
5071 } else {
5072 Err(AntlrError::MismatchedInput {
5073 expected: self.vocabulary().display_name(token_type),
5074 found: self.vocabulary().display_name(current_type),
5075 })
5076 }
5077 }
5078
5079 pub fn match_token_recovering(
5083 &mut self,
5084 token_type: i32,
5085 follow_state: usize,
5086 atn: &Atn,
5087 ) -> Result<GeneratedMatch, AntlrError> {
5088 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5089 line: 0,
5090 column: 0,
5091 message: "missing current token".to_owned(),
5092 })?;
5093 let current_type = self.token_type_for_id(current);
5094 if current_type == token_type {
5095 self.generated_sync_expected = None;
5096 let consumed_eof = current_type == TOKEN_EOF;
5097 self.consume();
5098 return Ok(GeneratedMatch {
5099 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5100 consumed_eof,
5101 });
5102 }
5103 let mut expected_symbols = BTreeSet::new();
5104 expected_symbols.insert(token_type);
5105 self.recover_generated_match(current, &expected_symbols, follow_state, atn, |symbol| {
5106 symbol == token_type
5107 })
5108 }
5109
5110 pub fn match_set_recovering(
5111 &mut self,
5112 intervals: &[(i32, i32)],
5113 follow_state: usize,
5114 atn: &Atn,
5115 ) -> Result<GeneratedMatch, AntlrError> {
5116 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5117 line: 0,
5118 column: 0,
5119 message: "missing current token".to_owned(),
5120 })?;
5121 let current_type = self.token_type_for_id(current);
5122 if interval_set_contains(intervals, current_type) {
5123 self.generated_sync_expected = None;
5124 let consumed_eof = current_type == TOKEN_EOF;
5125 self.consume();
5126 return Ok(GeneratedMatch {
5127 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5128 consumed_eof,
5129 });
5130 }
5131 let expected_symbols = interval_symbols(intervals);
5132 self.recover_generated_match(current, &expected_symbols, follow_state, atn, |symbol| {
5133 interval_set_contains(intervals, symbol)
5134 })
5135 }
5136
5137 pub fn match_not_set_recovering(
5138 &mut self,
5139 intervals: &[(i32, i32)],
5140 min_vocabulary: i32,
5141 max_vocabulary: i32,
5142 follow_state: usize,
5143 atn: &Atn,
5144 ) -> Result<GeneratedMatch, AntlrError> {
5145 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5146 line: 0,
5147 column: 0,
5148 message: "missing current token".to_owned(),
5149 })?;
5150 let current_type = self.token_type_for_id(current);
5151 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5152 && !interval_set_contains(intervals, current_type)
5153 {
5154 self.generated_sync_expected = None;
5155 let consumed_eof = current_type == TOKEN_EOF;
5156 self.consume();
5157 return Ok(GeneratedMatch {
5158 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5159 consumed_eof,
5160 });
5161 }
5162 let expected_symbols =
5163 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
5164 self.recover_generated_match(current, &expected_symbols, follow_state, atn, |symbol| {
5165 (min_vocabulary..=max_vocabulary).contains(&symbol)
5166 && !interval_set_contains(intervals, symbol)
5167 })
5168 }
5169
5170 fn recover_generated_match(
5171 &mut self,
5172 current: TokenId,
5173 expected_symbols: &BTreeSet<i32>,
5174 follow_state: usize,
5175 atn: &Atn,
5176 matches: impl Fn(i32) -> bool,
5177 ) -> Result<GeneratedMatch, AntlrError> {
5178 let expected_display = self.expected_symbols_display(expected_symbols);
5179 let (current_type, current_line, current_column, current_display) = {
5180 let token = self
5181 .input
5182 .token_view(current)
5183 .expect("current token ID should be valid");
5184 (
5185 token.token_type(),
5186 token.line(),
5187 token.column(),
5188 token_input_display(&token),
5189 )
5190 };
5191 if self.bail_on_error {
5192 return Err(AntlrError::ParserError {
5193 line: current_line,
5194 column: current_column,
5195 message: format!("mismatched input {current_display} expecting {expected_display}"),
5196 });
5197 }
5198 if current_type != TOKEN_EOF
5199 && let Some(next) = self.input.lt_id(2)
5200 && matches(self.token_type_for_id(next))
5201 {
5202 let message =
5203 format!("extraneous input {current_display} expecting {expected_display}");
5204 self.push_generated_parser_diagnostic(ParserDiagnostic {
5205 line: current_line,
5206 column: current_column,
5207 message,
5208 });
5209 self.record_syntax_errors(1);
5210 self.generated_sync_expected = None;
5211 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
5214 self.consume();
5215 self.consume();
5216 return Ok(GeneratedMatch {
5217 children: GeneratedMatchChildren::Many(vec![
5218 self.error_tree(current),
5219 self.terminal_tree(next),
5220 ]),
5221 consumed_eof,
5222 });
5223 }
5224 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
5225 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
5234 && self
5235 .cached_state_expected_symbols(atn, follow_state)
5236 .contains(&TOKEN_EOF);
5237 if follow_symbols.contains(¤t_type)
5238 && (current_type != TOKEN_EOF
5239 || self.rule_context_stack.len() > 1
5240 || expected_symbols.is_empty()
5241 || follow_explicitly_expects_eof)
5242 {
5243 let message = format!("missing {expected_display} at {current_display}");
5244 self.push_generated_parser_diagnostic(ParserDiagnostic {
5245 line: current_line,
5246 column: current_column,
5247 message,
5248 });
5249 self.record_syntax_errors(1);
5250 self.generated_sync_expected = None;
5251 let token_type = expected_symbols.iter().next().copied().unwrap_or(TOKEN_EOF);
5252 let mut missing_symbol = BTreeSet::new();
5253 missing_symbol.insert(token_type);
5254 let missing_display = self.expected_symbols_display(&missing_symbol);
5255 let token = self.insert_synthetic_token(
5256 token_type,
5257 format!("<missing {missing_display}>"),
5258 current_line,
5259 current_column,
5260 )?;
5261 return Ok(GeneratedMatch {
5266 children: GeneratedMatchChildren::One(self.error_tree(token)),
5267 consumed_eof: false,
5268 });
5269 }
5270 let mismatch_expected = self.generated_sync_expected.take().map_or_else(
5271 || expected_symbols.clone(),
5272 |symbols| symbols.to_btree_set(),
5273 );
5274 let mismatch_expected_display = self.expected_symbols_display(&mismatch_expected);
5275 Err(AntlrError::ParserError {
5276 line: current_line,
5277 column: current_column,
5278 message: format!(
5279 "mismatched input {current_display} expecting {mismatch_expected_display}"
5280 ),
5281 })
5282 }
5283
5284 fn generated_recovery_follow_symbols(
5285 &mut self,
5286 atn: &Atn,
5287 follow_state: usize,
5288 ) -> BTreeSet<i32> {
5289 let mut follow = self
5290 .cached_state_expected_symbols(atn, follow_state)
5291 .as_ref()
5292 .clone();
5293 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
5294 follow.extend(self.context_expected_symbols(atn));
5295 }
5296 follow
5297 }
5298
5299 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
5300 self.match_token(TOKEN_EOF)
5301 }
5302
5303 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
5304 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
5305 }
5306
5307 pub fn match_not_set(
5308 &mut self,
5309 intervals: &[(i32, i32)],
5310 min_vocabulary: i32,
5311 max_vocabulary: i32,
5312 ) -> Result<ParseTree, AntlrError> {
5313 self.match_interval_condition(intervals, |symbol| {
5314 (min_vocabulary..=max_vocabulary).contains(&symbol)
5315 && !interval_set_contains(intervals, symbol)
5316 })
5317 }
5318
5319 fn match_interval_condition(
5320 &mut self,
5321 intervals: &[(i32, i32)],
5322 matches: impl FnOnce(i32) -> bool,
5323 ) -> Result<ParseTree, AntlrError> {
5324 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5325 line: 0,
5326 column: 0,
5327 message: "missing current token".to_owned(),
5328 })?;
5329 let current_type = self.token_type_for_id(current);
5330 if matches(current_type) {
5331 self.consume();
5332 Ok(self.terminal_tree(current))
5333 } else {
5334 Err(AntlrError::MismatchedInput {
5335 expected: self.interval_display(intervals),
5336 found: self.vocabulary().display_name(current_type),
5337 })
5338 }
5339 }
5340
5341 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
5342 let values = intervals
5343 .iter()
5344 .map(|(start, stop)| {
5345 if start == stop {
5346 self.vocabulary().display_name(*start)
5347 } else {
5348 format!(
5349 "{}..{}",
5350 self.vocabulary().display_name(*start),
5351 self.vocabulary().display_name(*stop)
5352 )
5353 }
5354 })
5355 .collect::<Vec<_>>()
5356 .join(", ");
5357 format!("{{{values}}}")
5358 }
5359
5360 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
5361 if self.build_parse_trees {
5362 self.tree.finish_rule(context)
5363 } else {
5364 NodeId::placeholder()
5365 }
5366 }
5367
5368 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
5371 self.set_state(state);
5372 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
5373 self.rule_context_stack.push(RuleContextFrame {
5374 rule_index,
5375 invoking_state,
5376 });
5377 self.advance_rule_context_version();
5378 let start_index = self.current_visible_index();
5379 let mut context = ParserRuleContext::new(rule_index, invoking_state);
5380 if let Some(token) = self.token_id_at(start_index) {
5381 self.set_context_start(&mut context, token);
5382 }
5383 context
5384 }
5385
5386 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
5393 let marker = self.pending_invoking_states.len();
5394 self.pending_invoking_states.push(invoking_state);
5395 marker
5396 }
5397
5398 pub fn discard_invoking_state(&mut self, marker: usize) {
5400 self.pending_invoking_states.truncate(marker);
5401 }
5402
5403 pub fn exit_rule(&mut self) {
5405 self.rule_context_stack.pop();
5406 self.advance_rule_context_version();
5407 }
5408
5409 pub fn prediction_context_return_states<'a>(
5412 &'a self,
5413 atn: &'a Atn,
5414 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
5415 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
5416 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
5417 return None;
5418 };
5419 let Some(Transition::Rule { follow_state, .. }) = atn
5420 .state(state_number)
5421 .and_then(|state| state.transitions().first())
5422 .map(ParserTransition::data)
5423 else {
5424 return None;
5425 };
5426 Some(follow_state)
5427 })
5428 }
5429
5430 pub const fn rule_context_version(&self) -> usize {
5435 self.rule_context_version
5436 }
5437
5438 const fn advance_rule_context_version(&mut self) {
5439 self.rule_context_version = self.rule_context_version.wrapping_add(1);
5440 }
5441
5442 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
5447 if self.build_parse_trees {
5448 self.tree.add_child(context, child);
5449 } else {
5450 context.note_matched_child();
5451 }
5452 }
5453
5454 fn release_tree_scratch_if_idle(&mut self) {
5455 if self.rule_context_stack.is_empty() {
5456 self.tree.release_scratch();
5457 }
5458 }
5459
5460 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
5462 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5463 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5464 self.set_context_stop(&mut context, token);
5465 }
5466 let node = self.rule_node(context);
5467 self.exit_rule();
5468 self.release_tree_scratch_if_idle();
5469 node
5470 }
5471
5472 pub fn recover_generated_rule(
5479 &mut self,
5480 context: &mut ParserRuleContext,
5481 atn: &Atn,
5482 error: AntlrError,
5483 ) {
5484 let diagnostic = self.generated_rule_error_diagnostic(error);
5485 self.push_generated_parser_diagnostic(diagnostic);
5486 self.generated_sync_expected = None;
5487 let recovery_symbols = self.context_expected_symbols(atn);
5488 loop {
5489 let symbol = self.la(1);
5490 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
5491 break;
5492 }
5493 let Some(token) = self.input.lt_id(1) else {
5494 break;
5495 };
5496 self.consume();
5497 let child = self.error_tree(token);
5498 self.add_parse_child(context, child);
5499 }
5500 self.record_syntax_errors(1);
5501 }
5502
5503 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
5504 if self
5505 .generated_parser_diagnostics
5506 .iter()
5507 .any(|existing| existing == &diagnostic)
5508 {
5509 return;
5510 }
5511 self.generated_parser_diagnostics.push(diagnostic);
5512 }
5513
5514 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
5515 match error {
5516 AntlrError::ParserError {
5517 line,
5518 column,
5519 message,
5520 } => ParserDiagnostic {
5521 line,
5522 column,
5523 message,
5524 },
5525 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
5526 self.input.lt(1),
5527 format!("mismatched input {found} expecting {expected}"),
5528 ),
5529 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
5530 self.input.lt(1),
5531 format!("no viable alternative at input {input}"),
5532 ),
5533 AntlrError::LexerError {
5534 line,
5535 column,
5536 message,
5537 } => ParserDiagnostic {
5538 line,
5539 column,
5540 message,
5541 },
5542 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
5543 }
5544 }
5545
5546 pub fn finish_recursion_rule(
5548 &mut self,
5549 mut context: ParserRuleContext,
5550 consumed_eof: bool,
5551 ) -> ParseTree {
5552 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5553 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5554 self.set_context_stop(&mut context, token);
5555 }
5556 let node = self.rule_node(context);
5557 self.unroll_recursion_context();
5558 self.release_tree_scratch_if_idle();
5559 node
5560 }
5561
5562 pub fn enter_recursion_rule(
5564 &mut self,
5565 state: isize,
5566 rule_index: usize,
5567 precedence: i32,
5568 ) -> ParserRuleContext {
5569 self.precedence_stack.push(precedence);
5570 self.enter_rule(state, rule_index)
5571 }
5572
5573 pub fn push_new_recursion_context(
5575 &mut self,
5576 state: isize,
5577 rule_index: usize,
5578 ) -> ParserRuleContext {
5579 self.set_state(state);
5580 ParserRuleContext::new(rule_index, state)
5581 }
5582
5583 pub fn push_new_recursion_context_with_previous(
5586 &mut self,
5587 state: isize,
5588 rule_index: usize,
5589 current: &mut ParserRuleContext,
5590 ) {
5591 self.set_state(state);
5592 if let Some(stop) = self
5593 .rule_stop_token_index(self.input.index(), false)
5594 .and_then(|index| self.token_id_at(index))
5595 {
5596 self.set_context_stop(current, stop);
5597 }
5598 let invoking_state = current.invoking_state();
5599 let start = current.start_id();
5600 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
5601 if start.is_some() {
5602 replacement.set_start_from_context(current);
5603 }
5604 let previous = std::mem::replace(current, replacement);
5605 if self.build_parse_trees {
5606 let previous = self.rule_node(previous);
5607 self.tree.add_child(current, previous);
5608 }
5609 }
5610
5611 pub fn unroll_recursion_context(&mut self) {
5613 if self.precedence_stack.len() > 1 {
5614 self.precedence_stack.pop();
5615 }
5616 self.exit_rule();
5617 }
5618
5619 pub fn left_recursive_loop_enter_prediction(
5633 &mut self,
5634 atn: &Atn,
5635 state_number: usize,
5636 precedence: i32,
5637 ) -> Option<bool> {
5638 let symbol = self.la(1);
5639 if symbol == TOKEN_EOF {
5640 return Some(false);
5641 }
5642 let operator_lookahead =
5643 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
5644 let can_single = operator_lookahead.single_token.contains(symbol);
5645 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
5646 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
5647 if !can_single && !can_multi && !can_predicate {
5648 return Some(false);
5649 }
5650 if can_predicate && !can_single {
5651 return None;
5652 }
5653 if !can_single && can_multi && precedence > 0 {
5657 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
5658 if baseline.single_token.contains(symbol) {
5659 return None;
5660 }
5661 }
5662 let atn_key = SharedAtnCacheKey::for_atn(atn);
5663 let cached_overlap = self
5664 .left_recursive_caller_overlap_cache
5665 .iter()
5666 .flatten()
5667 .find(|entry| {
5668 entry.atn_key == atn_key
5669 && entry.state_number == state_number
5670 && entry.symbol == symbol
5671 && entry.context_version == self.rule_context_version
5672 })
5673 .map(|entry| entry.overlaps);
5674 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
5675 let overlaps = caller_context_can_match_symbol_before_state(
5676 atn,
5677 self.prediction_context_return_states(atn),
5678 state_number,
5679 symbol,
5680 );
5681 if let Some(slot) = self
5682 .left_recursive_caller_overlap_cache
5683 .iter_mut()
5684 .find(|slot| slot.is_none())
5685 {
5686 *slot = Some(LeftRecursiveCallerOverlap {
5687 atn_key,
5688 state_number,
5689 symbol,
5690 context_version: self.rule_context_version,
5691 overlaps,
5692 });
5693 }
5694 overlaps
5695 });
5696 if caller_overlaps {
5697 return None;
5698 }
5699 Some(true)
5700 }
5701
5702 fn cached_left_recursive_operator_lookahead(
5703 atn: &Atn,
5704 state_number: usize,
5705 precedence: i32,
5706 ) -> Rc<LeftRecursiveOperatorLookahead> {
5707 with_shared_atn_caches(atn, |cache| {
5708 let key = (state_number, precedence);
5709 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
5710 return Rc::clone(cached);
5711 }
5712 let lookahead = Rc::new(left_recursive_operator_lookahead(
5713 atn,
5714 state_number,
5715 precedence,
5716 ));
5717 cache
5718 .left_recursive_operator_lookahead
5719 .insert(key, Rc::clone(&lookahead));
5720 lookahead
5721 })
5722 }
5723
5724 pub fn left_recursive_loop_enter_matches(
5727 &mut self,
5728 atn: &Atn,
5729 state_number: usize,
5730 precedence: i32,
5731 ) -> bool {
5732 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
5733 }
5734
5735 pub fn precpred(&self, precedence: i32) -> bool {
5737 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
5738 }
5739
5740 pub fn parser_semantic_predicate_matches(
5743 &mut self,
5744 predicates: &[(usize, usize, ParserPredicate)],
5745 rule_index: usize,
5746 pred_index: usize,
5747 ) -> bool {
5748 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
5749 }
5750
5751 pub fn parser_semantic_predicate_matches_with_local(
5754 &mut self,
5755 predicates: &[(usize, usize, ParserPredicate)],
5756 rule_index: usize,
5757 pred_index: usize,
5758 local_int_arg: i32,
5759 ) -> bool {
5760 self.parser_semantic_predicate_matches_inner(
5761 predicates,
5762 rule_index,
5763 pred_index,
5764 Some((rule_index, i64::from(local_int_arg))),
5765 )
5766 }
5767
5768 fn parser_semantic_predicate_matches_inner(
5769 &mut self,
5770 predicates: &[(usize, usize, ParserPredicate)],
5771 rule_index: usize,
5772 pred_index: usize,
5773 local_int_arg: Option<(usize, i64)>,
5774 ) -> bool {
5775 let index = self.input.index();
5776 let member_values = self.int_members.clone();
5777 self.parser_predicate_matches(PredicateEval {
5778 index,
5779 rule_index,
5780 pred_index,
5781 predicates,
5782 semantics: None,
5783 context: None,
5784 local_int_arg,
5785 member_values: &member_values,
5786 })
5787 }
5788
5789 pub fn parser_semantic_predicate_matches_with_context_and_local(
5792 &mut self,
5793 predicates: &[(usize, usize, ParserPredicate)],
5794 rule_index: usize,
5795 pred_index: usize,
5796 context: &ParserRuleContext,
5797 local_int_arg: i32,
5798 ) -> bool {
5799 let index = self.input.index();
5800 let member_values = self.int_members.clone();
5801 self.parser_predicate_matches(PredicateEval {
5802 index,
5803 rule_index,
5804 pred_index,
5805 predicates,
5806 semantics: None,
5807 context: Some(context),
5808 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
5809 member_values: &member_values,
5810 })
5811 }
5812
5813 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
5816 &mut self,
5817 semantics: &ParserSemantics,
5818 rule_index: usize,
5819 pred_index: usize,
5820 context: &ParserRuleContext,
5821 local_int_arg: i32,
5822 ) -> bool {
5823 let index = self.input.index();
5824 let member_values = self.int_members.clone();
5825 self.parser_predicate_matches(PredicateEval {
5826 index,
5827 rule_index,
5828 pred_index,
5829 predicates: &[],
5830 semantics: Some(semantics),
5831 context: Some(context),
5832 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
5833 member_values: &member_values,
5834 })
5835 }
5836
5837 pub fn parser_semantic_predicate_failure_message(
5840 &self,
5841 rule_index: usize,
5842 pred_index: usize,
5843 predicates: &[(usize, usize, ParserPredicate)],
5844 ) -> Option<&'static str> {
5845 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
5846 }
5847
5848 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
5850 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5851 line: 0,
5852 column: 0,
5853 message: "missing current token".to_owned(),
5854 })?;
5855 if self.token_type_for_id(current) == TOKEN_EOF {
5856 return Err(AntlrError::MismatchedInput {
5857 expected: "wildcard".to_owned(),
5858 found: self.vocabulary().display_name(TOKEN_EOF),
5859 });
5860 }
5861 self.consume();
5862 Ok(self.terminal_tree(current))
5863 }
5864
5865 #[allow(clippy::unnecessary_wraps)]
5869 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
5870 self.set_state(state);
5871 Ok(())
5872 }
5873
5874 pub fn sync_decision(
5882 &mut self,
5883 atn: &Atn,
5884 state_number: usize,
5885 current_context_empty: bool,
5886 loop_back: bool,
5887 ) -> Result<Vec<ParseTree>, AntlrError> {
5888 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
5889 self.generated_sync_expected = None;
5890 let Some(state) = atn.state(state_number) else {
5891 return Ok(Vec::new());
5892 };
5893 let Some(rule_index) = state.rule_index() else {
5894 return Ok(Vec::new());
5895 };
5896 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
5897 return Ok(Vec::new());
5898 };
5899 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
5900 let symbol = self.la(1);
5901 let mut has_expected_symbols = false;
5902 let mut nullable = false;
5903 let mut explicit_eof_expected = false;
5911 for transition in &entry.transitions {
5912 if transition.symbols.contains(symbol) {
5913 return Ok(Vec::new());
5914 }
5915 has_expected_symbols |= !transition.symbols.is_empty();
5916 nullable |= transition.nullable;
5917 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
5918 }
5919 if nullable && self.context_expected_contains(atn, symbol) {
5924 return Ok(Vec::new());
5925 }
5926 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
5927 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
5928 return Ok(Vec::new());
5929 }
5930 let mut expected = TokenBitSet::default();
5931 for transition in &entry.transitions {
5932 expected.extend_from(&transition.symbols);
5933 }
5934 if let Some(context_expected) = context_expected {
5935 expected.extend_from(&context_expected);
5936 }
5937 let can_delete_in_place =
5938 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
5939 let loop_sync = loop_back;
5956 if symbol != TOKEN_EOF && can_delete_in_place {
5957 let mut cursor = self.input.index();
5958 let mut skipped = Vec::new();
5959 loop {
5960 let current = self.token_type_at(cursor);
5961 if current == TOKEN_EOF {
5962 break;
5963 }
5964 skipped.push(cursor);
5965 let next = self.consume_index(cursor, current);
5966 if next == cursor {
5967 break;
5968 }
5969 let next_symbol = self.token_type_at(next);
5970 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
5978 explicit_eof_expected
5979 } else {
5980 expected.contains(next_symbol)
5981 };
5982 if next_is_expected_stop {
5983 let current_token = self.input.lt(1);
5984 let expected_symbols = expected.to_btree_set();
5985 let message = format!(
5986 "extraneous input {} expecting {}",
5987 current_token
5988 .as_ref()
5989 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
5990 self.expected_symbols_display(&expected_symbols)
5991 );
5992 self.push_generated_parser_diagnostic(diagnostic_for_token(
5993 current_token,
5994 message,
5995 ));
5996 self.record_syntax_errors(1);
5997 let mut children = Vec::with_capacity(skipped.len());
5998 for index in skipped {
5999 if let Some(token) = self.token_id_at(index) {
6000 self.consume();
6001 children.push(self.error_tree(token));
6002 }
6003 }
6004 return Ok(children);
6005 }
6006 if !loop_sync {
6010 break;
6011 }
6012 cursor = next;
6013 }
6014 }
6015 if nullable {
6016 self.generated_sync_expected = Some(expected);
6017 return Ok(Vec::new());
6018 }
6019 let current = self.input.lt(1);
6020 let expected_symbols = expected.to_btree_set();
6021 Err(AntlrError::ParserError {
6022 line: current.as_ref().map(Token::line).unwrap_or_default(),
6023 column: current.as_ref().map(Token::column).unwrap_or_default(),
6024 message: format!(
6025 "mismatched input {} expecting {}",
6026 current
6027 .as_ref()
6028 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6029 self.expected_symbols_display(&expected_symbols)
6030 ),
6031 })
6032 }
6033
6034 pub fn ll1_decision_prediction(
6041 &mut self,
6042 atn: &Atn,
6043 state_number: usize,
6044 ) -> Option<ParserAtnPrediction> {
6045 let state = atn.state(state_number)?;
6046 if state.precedence_rule_decision() {
6047 return None;
6048 }
6049 let rule_stop = state
6050 .rule_index()
6051 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
6052 let symbol = self.la(1);
6053 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6054 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
6055 alt: alt + 1,
6056 requires_full_context: false,
6057 has_semantic_context: false,
6058 diagnostic: None,
6059 })
6060 }
6061
6062 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
6063 let mut expected = BTreeSet::new();
6064 for index in (1..self.rule_context_stack.len()).rev() {
6065 let invoking_state = self.rule_context_stack[index].invoking_state;
6066 let Ok(state_number) = usize::try_from(invoking_state) else {
6067 continue;
6068 };
6069 let Some(Transition::Rule { follow_state, .. }) = atn
6070 .state(state_number)
6071 .and_then(|state| state.transitions().first())
6072 .map(ParserTransition::data)
6073 else {
6074 continue;
6075 };
6076 let return_state = follow_state;
6077 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
6078 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
6079 return expected;
6080 }
6081 }
6082 expected.insert(TOKEN_EOF);
6083 expected
6084 }
6085
6086 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
6087 let mut expected = TokenBitSet::default();
6088 for index in (1..self.rule_context_stack.len()).rev() {
6089 let invoking_state = self.rule_context_stack[index].invoking_state;
6090 let Ok(state_number) = usize::try_from(invoking_state) else {
6091 continue;
6092 };
6093 let Some(Transition::Rule { follow_state, .. }) = atn
6094 .state(state_number)
6095 .and_then(|state| state.transitions().first())
6096 .map(ParserTransition::data)
6097 else {
6098 continue;
6099 };
6100 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
6101 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6102 return expected;
6103 }
6104 }
6105 expected.insert(TOKEN_EOF);
6106 expected
6107 }
6108
6109 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
6120 for index in (1..self.rule_context_stack.len()).rev() {
6121 let invoking_state = self.rule_context_stack[index].invoking_state;
6122 let Ok(state_number) = usize::try_from(invoking_state) else {
6123 continue;
6124 };
6125 let Some(Transition::Rule { follow_state, .. }) = atn
6126 .state(state_number)
6127 .and_then(|state| state.transitions().first())
6128 .map(ParserTransition::data)
6129 else {
6130 continue;
6131 };
6132 if self
6133 .cached_state_expected_token_set(atn, follow_state)
6134 .contains(symbol)
6135 {
6136 return true;
6137 }
6138 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6139 return false;
6140 }
6141 }
6142 symbol == TOKEN_EOF
6143 }
6144
6145 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
6147 let error_index = self.input.index();
6148 self.no_viable_alternative_error_at(start_index, error_index)
6149 }
6150
6151 pub fn no_viable_alternative_error_at(
6156 &self,
6157 start_index: usize,
6158 error_index: usize,
6159 ) -> AntlrError {
6160 let diagnostic = self.no_viable_alternative(start_index, error_index);
6161 AntlrError::ParserError {
6162 line: diagnostic.line,
6163 column: diagnostic.column,
6164 message: diagnostic.message,
6165 }
6166 }
6167
6168 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
6170 let current = self.input.lt(1);
6171 AntlrError::ParserError {
6172 line: current.as_ref().map(Token::line).unwrap_or_default(),
6173 column: current.as_ref().map(Token::column).unwrap_or_default(),
6174 message: format!("rule failed predicate: {}", message.into()),
6175 }
6176 }
6177
6178 pub fn failed_predicate_option_error(
6181 &self,
6182 rule_index: usize,
6183 message: impl Into<String>,
6184 ) -> AntlrError {
6185 let current = self.input.lt(1);
6186 let rule_name = self
6187 .rule_names()
6188 .get(rule_index)
6189 .map_or_else(|| rule_index.to_string(), Clone::clone);
6190 AntlrError::ParserError {
6191 line: current.as_ref().map(Token::line).unwrap_or_default(),
6192 column: current.as_ref().map(Token::column).unwrap_or_default(),
6193 message: format!("rule {rule_name} {}", message.into()),
6194 }
6195 }
6196
6197 pub fn parser_action_at_current(
6199 &mut self,
6200 source_state: usize,
6201 rule_index: usize,
6202 start_index: usize,
6203 consumed_eof: bool,
6204 ) -> ParserAction {
6205 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6206 ParserAction::new(source_state, rule_index, start_index, stop_index)
6207 }
6208
6209 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
6214 let rule_index = action.rule_index();
6215 let rule_name = self.rule_names().get(rule_index).cloned();
6216 let context = None;
6217 let input = &mut self.input;
6218 let semantic_hooks = &mut self.semantic_hooks;
6219 let member_values = &self.int_members;
6220 let mut ctx = ParserSemCtx {
6221 input,
6222 tree_storage: &self.tree,
6223 rule_index,
6224 coordinate_index: usize::MAX,
6225 rule_name,
6226 context,
6227 tree: Some(tree),
6228 local_int_arg: None,
6229 member_values,
6230 action: Some(action),
6231 };
6232 let handled = semantic_hooks.action(&mut ctx, action);
6233 if !handled && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error) {
6239 let coordinate = (rule_index, action.source_state());
6240 if !self.unhandled_action_hits.contains(&coordinate) {
6241 self.unhandled_action_hits.push(coordinate);
6242 }
6243 }
6244 handled
6245 }
6246
6247 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
6252 &mut self,
6253 atn: &'atn Atn,
6254 simulator: &mut ParserAtnSimulator<'atn>,
6255 rule_index: usize,
6256 ) -> Result<ParseTree, AntlrError> {
6257 let start_index = self.current_visible_index();
6258 self.clear_prediction_diagnostics();
6259 self.reset_per_parse_caches();
6260 self.reset_recognition_arena();
6261 let tree_checkpoint = self.tree.checkpoint();
6262 let mut decision_by_state = vec![None; atn.states().len()];
6263 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
6264 if let Some(slot) = decision_by_state.get_mut(state_number) {
6265 *slot = Some(decision);
6266 }
6267 }
6268
6269 let result = DirectAdaptiveParser {
6270 parser: self,
6271 atn,
6272 simulator,
6273 decision_by_state,
6274 steps: 0,
6275 }
6276 .parse_rule(rule_index, -1, 0);
6277
6278 match result {
6279 Ok(tree) => {
6280 report_token_source_errors(&self.input.drain_source_errors());
6281 self.release_tree_scratch_if_idle();
6282 Ok(tree)
6283 }
6284 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
6285 let _ = reason;
6286 self.tree.rollback(tree_checkpoint);
6287 self.input.seek(start_index);
6288 self.parse_atn_rule(atn, rule_index)
6289 }
6290 }
6291 }
6292
6293 pub fn parse_atn_rule(
6303 &mut self,
6304 atn: &Atn,
6305 rule_index: usize,
6306 ) -> Result<ParseTree, AntlrError> {
6307 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
6308 }
6309
6310 pub fn parse_atn_rule_with_precedence(
6313 &mut self,
6314 atn: &Atn,
6315 rule_index: usize,
6316 precedence: i32,
6317 ) -> Result<ParseTree, AntlrError> {
6318 self.parse_atn_rule_with_precedence_inner(atn, rule_index, precedence, None)
6319 }
6320
6321 fn parse_atn_rule_with_precedence_inner(
6322 &mut self,
6323 atn: &Atn,
6324 rule_index: usize,
6325 precedence: i32,
6326 predicate_context: Option<FastPredicateContext<'_>>,
6327 ) -> Result<ParseTree, AntlrError> {
6328 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
6329 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
6330 })?;
6331 let stop_state = atn
6332 .rule_to_stop_state()
6333 .get(rule_index)
6334 .filter(|state| *state != usize::MAX)
6335 .ok_or_else(|| {
6336 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
6337 })?;
6338
6339 let start_index = self.current_visible_index();
6340 self.clear_prediction_diagnostics();
6341 self.reset_per_parse_caches();
6342 self.reset_recognition_arena();
6343 let caller_follow_state = self.pending_invoking_follow_state(atn);
6344 self.fast_recovery_enabled = false;
6345 self.fast_token_nodes_enabled = false;
6346 let top_request = FastRecognizeTopRequest {
6347 start_state,
6348 stop_state,
6349 start_index,
6350 precedence,
6351 caller_follow_state,
6352 };
6353 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
6354 self.fast_token_nodes_enabled = self.build_parse_trees;
6355 let needs_tree_retry = matches!(
6356 &first_pass,
6357 Ok((outcome, _))
6358 if self.build_parse_trees
6359 && self
6360 .recognition_arena
6361 .sequence_has_left_recursive_boundary(outcome.nodes)
6362 );
6363 let needs_retry = match &first_pass {
6364 Err(_) => true,
6377 Ok((outcome, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
6378 };
6379 let (outcome, _expected) = if needs_retry {
6380 self.fast_first_set_prefilter = false;
6381 self.fast_recovery_enabled = false;
6382 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6383 let clean_selected = if needs_tree_retry {
6384 match clean_retry {
6385 ok @ Ok(_) => ok,
6386 Err(_) => first_pass,
6387 }
6388 } else {
6389 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
6390 };
6391 let selected = if clean_selected.is_err()
6392 || matches!(&clean_selected, Ok((outcome, _)) if !outcome.diagnostics.is_empty())
6393 {
6394 self.fast_recovery_enabled = true;
6395 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6396 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
6397 } else {
6398 clean_selected
6399 };
6400 self.fast_first_set_prefilter = true;
6401 self.fast_recovery_enabled = true;
6402 selected.map_err(|expected| {
6403 if predicate_context.is_some()
6404 && let Some(error) = self.unknown_semantic_error()
6405 {
6406 report_token_source_errors(&self.input.drain_source_errors());
6407 return error;
6408 }
6409 let error = self.recognition_error(rule_index, start_index, &expected);
6410 self.record_syntax_errors(1);
6411 report_token_source_errors(&self.input.drain_source_errors());
6412 error
6413 })?
6414 } else {
6415 first_pass.expect("first_pass is Ok in the no-retry branch")
6416 };
6417 if predicate_context.is_some()
6418 && let Some(error) = self.unknown_semantic_error()
6419 {
6420 report_token_source_errors(&self.input.drain_source_errors());
6421 return Err(error);
6422 }
6423 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
6424 report_parser_diagnostics(&self.prediction_diagnostics);
6425 report_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
6426 report_token_source_errors(&self.input.drain_source_errors());
6427 let mut context = ParserRuleContext::with_child_capacity(
6428 rule_index,
6429 self.state(),
6430 if self.build_parse_trees {
6431 self.recognition_arena.sequence_len(outcome.nodes)
6432 } else {
6433 0
6434 },
6435 );
6436 if let Some(token) = self.token_id_at(start_index) {
6437 self.set_context_start(&mut context, token);
6438 }
6439 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
6440 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
6441 self.set_context_stop(&mut context, token);
6442 }
6443 let live_root = if self.build_parse_trees {
6444 self.recognition_arena
6445 .fold_left_recursive_boundaries(outcome.nodes)
6446 } else {
6447 outcome.nodes
6448 };
6449 if self.build_parse_trees {
6450 if self
6451 .recognition_arena
6452 .sequence_has_explicit_token(live_root)
6453 {
6454 let mut cursor = live_root;
6455 while let Some(link) = self.recognition_arena.link(cursor) {
6456 let child = self.arena_recognized_node_tree(link.head, false)?;
6457 self.tree.add_child(&mut context, child);
6458 cursor = link.tail;
6459 }
6460 } else {
6461 self.add_arena_implicit_token_children(
6462 &mut context,
6463 start_index,
6464 stop_index,
6465 live_root,
6466 )?;
6467 }
6468 }
6469 self.finish_recognition_arena(live_root, outcome.diagnostics);
6470 self.input.seek(outcome.index);
6471
6472 let tree = self.rule_node(context);
6473 self.release_tree_scratch_if_idle();
6474 Ok(tree)
6475 }
6476
6477 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
6478 let invoking_state = self.pending_invoking_states.last().copied()?;
6479 let state_number = usize::try_from(invoking_state).ok()?;
6480 match atn.state(state_number)?.transitions().first()?.data() {
6481 Transition::Rule { follow_state, .. } => Some(follow_state),
6482 _ => None,
6483 }
6484 }
6485
6486 #[cfg(test)]
6487 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
6488 caller_follow_token_info_for_stream(&mut self.input, index)
6489 }
6490
6491 fn fast_recognize_top(
6496 &mut self,
6497 atn: &Atn,
6498 request: FastRecognizeTopRequest,
6499 predicate_context: Option<FastPredicateContext<'_>>,
6500 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
6501 let FastRecognizeTopRequest {
6502 start_state,
6503 stop_state,
6504 start_index,
6505 precedence,
6506 caller_follow_state,
6507 } = request;
6508 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
6517 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
6518 recognize_scratch.prepare(memo_capacity);
6519 let mut expected = ExpectedTokens::default();
6520 let empty_recovery = self.empty_recovery_symbols();
6521 let outcomes = self.recognize_state_fast(
6522 atn,
6523 FastRecognizeRequest {
6524 state_number: start_state,
6525 stop_state,
6526 index: start_index,
6527 rule_start_index: start_index,
6528 decision_start_index: None,
6529 precedence,
6530 depth: 0,
6531 recovery_symbols: empty_recovery,
6532 recovery_state: None,
6533 },
6534 FastRecognizeScratch {
6535 predicate_context,
6536 visiting: &mut recognize_scratch.visiting,
6537 memo: &mut recognize_scratch.memo,
6538 expected: &mut expected,
6539 },
6540 );
6541 recognize_scratch.release_oversized_memo();
6542 self.fast_recognize_scratch = recognize_scratch;
6543 #[cfg(feature = "perf-counters")]
6544 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
6545 perf_counters::dump();
6546 perf_counters::reset();
6547 }
6548 let caller_follow =
6549 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
6550 let selected = {
6551 let arena = &self.recognition_arena;
6552 let input = &mut self.input;
6553 select_best_fast_outcome(
6554 outcomes.into_iter(),
6555 self.prediction_mode,
6556 caller_follow.as_deref(),
6557 |index| caller_follow_token_info_for_stream(input, index),
6558 arena,
6559 )
6560 };
6561 match selected {
6562 Some(mut outcome) => {
6563 if self.build_parse_trees {
6564 self.materialize_fast_outcome_nodes(&mut outcome);
6565 }
6566 Ok((outcome, expected))
6567 }
6568 None => Err(expected),
6569 }
6570 }
6571
6572 fn arena_recognized_node_tree(
6574 &mut self,
6575 node_id: RecognizedNodeId,
6576 track_alt_numbers: bool,
6577 ) -> Result<ParseTree, AntlrError> {
6578 let node = self.recognition_arena.node(node_id);
6579 match node {
6580 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
6581 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
6582 ArenaRecognizedNode::MissingToken { extra } => {
6583 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
6584 RecognitionExtra::MissingToken {
6585 token_type,
6586 at_index,
6587 text,
6588 } => (*token_type, *at_index as usize, text.clone()),
6589 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
6590 unreachable!("missing-token node must reference missing-token extra")
6591 }
6592 };
6593 let (line, column) = self
6594 .token_at(at_index)
6595 .map_or((0, 0), |token| (token.line(), token.column()));
6596 let token = self.insert_synthetic_token(token_type, text, line, column)?;
6597 Ok(self.error_tree(token))
6598 }
6599 ArenaRecognizedNode::Rule {
6600 rule_index,
6601 invoking_state,
6602 alt_number,
6603 start_index,
6604 stop_index,
6605 return_values,
6606 children,
6607 } => {
6608 let mut context = ParserRuleContext::with_child_capacity(
6609 rule_index as usize,
6610 invoking_state as isize,
6611 self.recognition_arena.sequence_len(children),
6612 );
6613 if track_alt_numbers {
6614 context.set_alt_number(alt_number as usize);
6615 }
6616 if let Some(extra) = return_values {
6617 let RecognitionExtra::ReturnValues(values) =
6618 self.recognition_arena.extra(extra)
6619 else {
6620 unreachable!("rule node must reference return-values extra");
6621 };
6622 for (name, value) in values {
6623 context.set_int_return(name.clone(), *value);
6624 }
6625 }
6626 if let Some(token) = self.token_id_at(start_index as usize) {
6627 self.set_context_start(&mut context, token);
6628 }
6629 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
6630 self.set_context_stop(&mut context, token);
6631 }
6632 let mut cursor = self
6633 .recognition_arena
6634 .fold_left_recursive_boundaries(children);
6635 while let Some(link) = self.recognition_arena.link(cursor) {
6636 let child = self.arena_recognized_node_tree(link.head, track_alt_numbers)?;
6637 self.tree.add_child(&mut context, child);
6638 cursor = link.tail;
6639 }
6640 Ok(self.rule_node(context))
6641 }
6642 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index } => {
6643 Err(AntlrError::Unsupported(format!(
6644 "unfolded left-recursive boundary for rule {rule_index}"
6645 )))
6646 }
6647 }
6648 }
6649
6650 fn arena_recognized_node_tree_with_implicit_tokens(
6651 &mut self,
6652 node_id: RecognizedNodeId,
6653 ) -> Result<ParseTree, AntlrError> {
6654 let node = self.recognition_arena.node(node_id);
6655 match node {
6656 ArenaRecognizedNode::Rule {
6657 rule_index,
6658 invoking_state,
6659 start_index,
6660 stop_index,
6661 children,
6662 ..
6663 } => {
6664 let mut context = ParserRuleContext::with_child_capacity(
6665 rule_index as usize,
6666 invoking_state as isize,
6667 self.recognition_arena.sequence_len(children),
6668 );
6669 if let Some(token) = self.token_id_at(start_index as usize) {
6670 self.set_context_start(&mut context, token);
6671 }
6672 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
6673 self.set_context_stop(&mut context, token);
6674 }
6675 let children = self
6676 .recognition_arena
6677 .fold_left_recursive_boundaries(children);
6678 self.add_arena_implicit_token_children(
6679 &mut context,
6680 start_index as usize,
6681 stop_index.map(|index| index as usize),
6682 children,
6683 )?;
6684 Ok(self.rule_node(context))
6685 }
6686 _ => self.arena_recognized_node_tree(node_id, false),
6687 }
6688 }
6689
6690 fn add_arena_implicit_token_children(
6691 &mut self,
6692 context: &mut ParserRuleContext,
6693 start_index: usize,
6694 stop_index: Option<usize>,
6695 mut children: NodeSeqId,
6696 ) -> Result<(), AntlrError> {
6697 let mut cursor = Some(start_index);
6698 while let Some(link) = self.recognition_arena.link(children) {
6699 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
6700 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
6701 let child = self.arena_recognized_node_tree_with_implicit_tokens(link.head)?;
6702 self.tree.add_child(context, child);
6703 if let Some(child_stop) = child_stop {
6704 cursor = self.next_visible_after_token(child_stop);
6705 }
6706 } else {
6707 let child = self.arena_recognized_node_tree_with_implicit_tokens(link.head)?;
6708 self.tree.add_child(context, child);
6709 }
6710 children = link.tail;
6711 }
6712 if let Some(stop) = stop_index {
6713 self.add_visible_terminals_through(context, cursor, stop)?;
6714 }
6715 Ok(())
6716 }
6717
6718 fn add_visible_terminals_before(
6719 &mut self,
6720 context: &mut ParserRuleContext,
6721 cursor: &mut Option<usize>,
6722 before: usize,
6723 ) -> Result<(), AntlrError> {
6724 let Some(stop) = before.checked_sub(1) else {
6725 return Ok(());
6726 };
6727 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
6728 *cursor = next;
6729 Ok(())
6730 }
6731
6732 fn add_visible_terminals_through(
6733 &mut self,
6734 context: &mut ParserRuleContext,
6735 mut cursor: Option<usize>,
6736 stop: usize,
6737 ) -> Result<Option<usize>, AntlrError> {
6738 while let Some(index) = cursor {
6739 if index > stop {
6740 return Ok(Some(index));
6741 }
6742 let token = self
6743 .input
6744 .get_id(index)
6745 .ok_or_else(|| AntlrError::ParserError {
6746 line: 0,
6747 column: 0,
6748 message: format!("missing token at index {index}"),
6749 })?;
6750 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
6751 let child = self.terminal_tree(token);
6752 self.tree.add_child(context, child);
6753 if is_eof {
6754 return Ok(None);
6755 }
6756 cursor = self.next_visible_after_token(index);
6757 }
6758 Ok(None)
6759 }
6760
6761 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
6762 let next = self.input.next_visible_after(index);
6763 (next != index).then_some(next)
6764 }
6765
6766 pub fn parse_atn_rule_with_actions(
6773 &mut self,
6774 atn: &Atn,
6775 rule_index: usize,
6776 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
6777 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
6778 }
6779
6780 pub fn parse_atn_rule_with_action_inits(
6788 &mut self,
6789 atn: &Atn,
6790 rule_index: usize,
6791 init_action_rules: &[usize],
6792 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
6793 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
6794 }
6795
6796 pub fn parse_atn_rule_with_action_options(
6802 &mut self,
6803 atn: &Atn,
6804 rule_index: usize,
6805 init_action_rules: &[usize],
6806 track_alt_numbers: bool,
6807 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
6808 self.parse_atn_rule_with_runtime_options(
6809 atn,
6810 rule_index,
6811 ParserRuntimeOptions {
6812 init_action_rules,
6813 track_alt_numbers,
6814 ..ParserRuntimeOptions::default()
6815 },
6816 )
6817 }
6818
6819 pub fn parse_atn_rule_with_runtime_options(
6826 &mut self,
6827 atn: &Atn,
6828 rule_index: usize,
6829 options: ParserRuntimeOptions<'_>,
6830 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
6831 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
6832 }
6833
6834 pub fn parse_atn_rule_with_runtime_options_and_precedence(
6837 &mut self,
6838 atn: &Atn,
6839 rule_index: usize,
6840 precedence: i32,
6841 options: ParserRuntimeOptions<'_>,
6842 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
6843 let ParserRuntimeOptions {
6844 init_action_rules,
6845 track_alt_numbers,
6846 predicates,
6847 semantics,
6848 rule_args,
6849 member_actions,
6850 return_actions,
6851 unknown_predicate_policy,
6852 } = options;
6853 if init_action_rules.is_empty()
6854 && !track_alt_numbers
6855 && predicates.is_empty()
6856 && semantics.is_none()
6857 && rule_args.is_empty()
6858 && member_actions.is_empty()
6859 && return_actions.is_empty()
6860 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
6861 && !atn_has_observable_action_transitions(atn)
6862 && (!self.semantic_hooks.observes_parser_predicates()
6863 || !atn_has_predicate_transitions(atn))
6864 {
6865 return self
6866 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
6867 .map(|tree| (tree, Vec::new()));
6868 }
6869 if can_use_fast_predicate_recognizer(atn, &options) {
6870 self.unknown_predicate_policy = unknown_predicate_policy;
6871 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
6872 let member_values = self.int_members.clone();
6873 let result = self
6874 .parse_atn_rule_with_precedence_inner(
6875 atn,
6876 rule_index,
6877 precedence,
6878 Some(FastPredicateContext {
6879 predicates,
6880 semantics,
6881 member_values: &member_values,
6882 }),
6883 )
6884 .map(|tree| (tree, Vec::new()));
6885 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
6886 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
6887 }
6888 return result;
6889 }
6890 self.unknown_predicate_policy = unknown_predicate_policy;
6891 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
6898 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
6899 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
6900 })?;
6901 let stop_state = atn
6902 .rule_to_stop_state()
6903 .get(rule_index)
6904 .filter(|state| *state != usize::MAX)
6905 .ok_or_else(|| {
6906 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
6907 })?;
6908
6909 let start_index = self.current_visible_index();
6910 self.clear_prediction_diagnostics();
6911 self.reset_per_parse_caches();
6912 self.reset_recognition_arena();
6913 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
6914 let invoking_state = self.pending_invoking_states.pop();
6915 let local_int_arg = invoking_state
6916 .and_then(|state| usize::try_from(state).ok())
6917 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
6918 let mut visiting = BTreeSet::new();
6919 let mut memo = BTreeMap::new();
6920 let mut expected = ExpectedTokens::default();
6921 let member_values = self.int_members.clone();
6922 let return_values = BTreeMap::new();
6923 let outcomes = self.recognize_state(
6924 atn,
6925 RecognizeRequest {
6926 state_number: start_state,
6927 stop_state,
6928 index: start_index,
6929 rule_start_index: start_index,
6930 decision_start_index: None,
6931 init_action_rules: &init_action_rules,
6932 predicates,
6933 semantics,
6934 rule_args,
6935 member_actions,
6936 return_actions,
6937 local_int_arg,
6938 member_values,
6939 return_values,
6940 rule_alt_number: 0,
6941 track_alt_numbers,
6942 consumed_eof: false,
6943 precedence,
6944 depth: 0,
6945 recovery_symbols: BTreeSet::new(),
6946 recovery_state: None,
6947 },
6948 &mut visiting,
6949 &mut memo,
6950 &mut expected,
6951 );
6952 if let Some(error) = self.unknown_semantic_error() {
6953 report_token_source_errors(&self.input.drain_source_errors());
6954 return Err(error);
6961 }
6962 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
6965 let Some(outcome) = select_best_outcome(
6966 outcomes.into_iter(),
6967 self.prediction_mode,
6968 &self.recognition_arena,
6969 ) else {
6970 let error = self.recognition_error(rule_index, start_index, &expected);
6971 self.record_syntax_errors(1);
6972 report_token_source_errors(&self.input.drain_source_errors());
6973 return Err(error);
6974 };
6975
6976 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
6977 report_parser_diagnostics(&self.prediction_diagnostics);
6978 report_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
6979 report_token_source_errors(&self.input.drain_source_errors());
6980 let mut actions = outcome.actions;
6981 if init_action_rules.contains(&rule_index) {
6982 actions.insert(
6983 0,
6984 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
6985 );
6986 }
6987 let mut context =
6988 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
6989 if track_alt_numbers {
6990 context.set_alt_number(outcome.alt_number);
6991 }
6992 for (name, value) in outcome.return_values {
6993 context.set_int_return(name, value);
6994 }
6995 if let Some(token) = self.token_id_at(start_index) {
6996 self.set_context_start(&mut context, token);
6997 }
6998 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
6999 self.set_context_stop(&mut context, token);
7000 }
7001 let live_root = if self.build_parse_trees {
7002 self.recognition_arena
7003 .fold_left_recursive_boundaries(outcome.nodes)
7004 } else {
7005 outcome.nodes
7006 };
7007 if self.build_parse_trees {
7008 let mut nodes = live_root;
7009 while let Some(link) = self.recognition_arena.link(nodes) {
7010 let child = self.arena_recognized_node_tree(link.head, track_alt_numbers)?;
7011 self.tree.add_child(&mut context, child);
7012 nodes = link.tail;
7013 }
7014 }
7015 self.finish_recognition_arena(live_root, outcome.diagnostics);
7016 self.input.seek(outcome.index);
7017
7018 let tree = self.rule_node(context);
7019 self.release_tree_scratch_if_idle();
7020 Ok((tree, actions))
7021 }
7022
7023 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
7030 let mut context = ParserRuleContext::new(rule_index, self.state());
7031 while self.la(1) != TOKEN_EOF {
7032 let token_type = self.la(1);
7033 let child = self.match_token(token_type)?;
7034 if self.build_parse_trees {
7035 self.tree.add_child(&mut context, child);
7036 }
7037 }
7038 if self.build_parse_trees {
7039 let child = self.match_eof()?;
7040 self.tree.add_child(&mut context, child);
7041 }
7042 let tree = self.rule_node(context);
7043 self.release_tree_scratch_if_idle();
7044 Ok(tree)
7045 }
7046
7047 fn recognition_error(
7050 &mut self,
7051 rule_index: usize,
7052 start_index: usize,
7053 expected: &ExpectedTokens,
7054 ) -> AntlrError {
7055 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
7056 self.input.seek(index);
7057 let current = self.input.lt(1);
7058 let line = current.as_ref().map(Token::line).unwrap_or_default();
7059 let column = current.as_ref().map(Token::column).unwrap_or_default();
7060 AntlrError::ParserError {
7061 line,
7062 column,
7063 message,
7064 }
7065 }
7066
7067 fn expected_error_message(
7069 &mut self,
7070 rule_index: usize,
7071 start_index: usize,
7072 expected: &ExpectedTokens,
7073 ) -> (usize, String) {
7074 let index = expected
7075 .index
7076 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
7077 .unwrap_or_else(|| self.input.index());
7078 self.input.seek(index);
7079 let current = self.input.lt(1);
7080 let message = if expected
7081 .no_viable
7082 .as_ref()
7083 .is_some_and(|no_viable| no_viable.error_index == index)
7084 {
7085 let start = expected
7086 .no_viable
7087 .as_ref()
7088 .map_or(start_index, |no_viable| no_viable.start_index);
7089 let text = display_input_text(&self.input.text(start, index));
7090 format!("no viable alternative at input '{text}'")
7091 } else if expected.symbols.is_empty() {
7092 if expected.index.is_some() {
7093 let found = current
7094 .as_ref()
7095 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
7096 if current
7097 .as_ref()
7098 .is_some_and(|token| token.token_type() == TOKEN_EOF)
7099 {
7100 format!(
7101 "missing {} at {found}",
7102 self.expected_symbols_display(&expected.symbols)
7103 )
7104 } else {
7105 format!("mismatched input {found}")
7106 }
7107 } else {
7108 format!("no viable alternative while parsing rule {rule_index}")
7109 }
7110 } else {
7111 format!(
7112 "mismatched input {} expecting {}",
7113 current
7114 .as_ref()
7115 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7116 self.expected_symbols_display(&expected.symbols)
7117 )
7118 };
7119 (index, message)
7120 }
7121
7122 fn child_rule_failure_recovery(
7125 &mut self,
7126 rule_index: usize,
7127 start_index: usize,
7128 sync_symbols: &BTreeSet<i32>,
7129 member_values: BTreeMap<usize, i64>,
7130 expected: &ExpectedTokens,
7131 ) -> Option<RecognizeOutcome> {
7132 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7133 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7134 let mut next_index = error_index;
7135 loop {
7136 let symbol = self.token_type_at(next_index);
7137 if sync_symbols.contains(&symbol) {
7138 if next_index == error_index {
7139 return None;
7140 }
7141 break;
7142 }
7143 if symbol == TOKEN_EOF {
7144 break;
7145 }
7146 let after = self.consume_index(next_index, symbol);
7147 if after == next_index {
7148 break;
7149 }
7150 next_index = after;
7151 }
7152 let mut nodes = NodeSeqId::EMPTY;
7153 let error = self.arena_token_node(error_index, true);
7154 self.arena_prepend(&mut nodes, error);
7155 let diagnostics = self
7156 .recognition_arena
7157 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7158 Some(RecognizeOutcome {
7159 index: next_index,
7160 consumed_eof: false,
7161 alt_number: 0,
7162 member_values,
7163 return_values: BTreeMap::new(),
7164 diagnostics,
7165 decisions: Vec::new(),
7166 actions: Vec::new(),
7167 nodes,
7168 })
7169 }
7170
7171 fn child_rule_failure_recovery_outcomes(
7174 &mut self,
7175 request: ChildRuleFailureRecovery<'_>,
7176 ) -> Vec<RecognizeOutcome> {
7177 let sync_symbols =
7178 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
7179 self.child_rule_failure_recovery(
7180 request.rule_index,
7181 request.start_index,
7182 &sync_symbols,
7183 request.member_values,
7184 request.expected,
7185 )
7186 .into_iter()
7187 .collect()
7188 }
7189
7190 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
7192 expected_symbols_display(symbols, self.vocabulary())
7193 }
7194
7195 fn single_token_deletion(
7198 &mut self,
7199 transition: ParserTransition<'_>,
7200 index: usize,
7201 max_token_type: i32,
7202 expected_symbols: &BTreeSet<i32>,
7203 ) -> Option<(ParserDiagnostic, usize, i32)> {
7204 let current_symbol = self.token_type_at(index);
7205 if current_symbol == TOKEN_EOF {
7206 return None;
7207 }
7208 let next_index = self.consume_index(index, current_symbol);
7209 if next_index == index {
7210 return None;
7211 }
7212 let next_symbol = self.token_type_at(next_index);
7213 if !transition.matches(next_symbol, 1, max_token_type) {
7214 return None;
7215 }
7216 let transition_expected = transition_expected_symbols(transition, max_token_type);
7217 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7218 &transition_expected
7219 } else {
7220 expected_symbols
7221 });
7222 let current = self.token_at(index);
7223 let message = format!(
7224 "extraneous input {} expecting {expected_display}",
7225 current
7226 .as_ref()
7227 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7228 );
7229 Some((
7230 diagnostic_for_token(current, message),
7231 next_index,
7232 next_symbol,
7233 ))
7234 }
7235
7236 fn current_token_deletion(
7239 &mut self,
7240 index: usize,
7241 expected_symbols: &BTreeSet<i32>,
7242 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
7243 if expected_symbols.is_empty() {
7244 return None;
7245 }
7246 let current_symbol = self.token_type_at(index);
7247 if current_symbol == TOKEN_EOF {
7248 return None;
7249 }
7250 let current = self.token_at(index);
7251 let message = format!(
7252 "extraneous input {} expecting {}",
7253 current
7254 .as_ref()
7255 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7256 self.expected_symbols_display(expected_symbols)
7257 );
7258 let diagnostic = diagnostic_for_token(current, message);
7259 let mut skipped = Vec::new();
7260 let mut cursor = index;
7261 loop {
7262 let symbol = self.token_type_at(cursor);
7263 if symbol == TOKEN_EOF {
7264 return None;
7265 }
7266 skipped.push(cursor);
7267 let next_index = self.consume_index(cursor, symbol);
7268 if next_index == cursor {
7269 return None;
7270 }
7271 let next_symbol = self.token_type_at(next_index);
7272 if expected_symbols.contains(&next_symbol) {
7273 return Some((diagnostic, next_index, skipped));
7274 }
7275 cursor = next_index;
7276 }
7277 }
7278
7279 fn single_token_insertion(
7283 &mut self,
7284 transition: ParserTransition<'_>,
7285 index: usize,
7286 max_token_type: i32,
7287 expected_symbols: &BTreeSet<i32>,
7288 follow_symbols: &BTreeSet<i32>,
7289 ) -> Option<(ParserDiagnostic, i32, String)> {
7290 let current_symbol = self.token_type_at(index);
7291 if !follow_symbols.contains(¤t_symbol) {
7292 return None;
7293 }
7294 let transition_expected = transition_expected_symbols(transition, max_token_type);
7295 let token_type = transition_expected.iter().next().copied()?;
7296 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7297 &transition_expected
7298 } else {
7299 expected_symbols
7300 });
7301 let mut token_symbols = BTreeSet::new();
7302 token_symbols.insert(token_type);
7303 let missing_token_display = self.expected_symbols_display(&token_symbols);
7304 let current = self.token_at(index);
7305 let message = format!(
7306 "missing {expected_display} at {}",
7307 current
7308 .as_ref()
7309 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7310 );
7311 let text = format!("<missing {missing_token_display}>");
7312 Some((
7313 diagnostic_for_token(current.as_ref(), message),
7314 token_type,
7315 text,
7316 ))
7317 }
7318
7319 fn fast_single_token_deletion_recovery(
7323 &mut self,
7324 recovery: FastRecoveryRequest<'_, '_>,
7325 predicate_context: Option<FastPredicateContext<'_>>,
7326 ) -> Vec<FastRecognizeOutcome> {
7327 let FastRecoveryRequest {
7328 atn,
7329 transition,
7330 expected_symbols,
7331 target,
7332 request,
7333 visiting,
7334 memo,
7335 expected,
7336 } = recovery;
7337 let FastRecognizeRequest {
7338 stop_state,
7339 index,
7340 rule_start_index,
7341 decision_start_index,
7342 precedence,
7343 depth,
7344 ..
7345 } = request;
7346 let Some((diagnostic, next_index, next_symbol)) =
7347 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
7348 else {
7349 return Vec::new();
7350 };
7351 let after_next = self.consume_index(next_index, next_symbol);
7352 let empty_recovery = self.empty_recovery_symbols();
7353 self.recognize_state_fast(
7354 atn,
7355 FastRecognizeRequest {
7356 state_number: target,
7357 stop_state,
7358 index: after_next,
7359 rule_start_index,
7360 decision_start_index,
7361 precedence,
7362 depth: depth + 1,
7363 recovery_symbols: empty_recovery,
7364 recovery_state: None,
7365 },
7366 FastRecognizeScratch {
7367 predicate_context,
7368 visiting,
7369 memo,
7370 expected,
7371 },
7372 )
7373 .into_iter()
7374 .map(|mut outcome| {
7375 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
7376 outcome.diagnostics = self
7377 .recognition_arena
7378 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7379 if self.fast_token_nodes_enabled {
7380 let token = self.arena_token_node(next_index, false);
7381 self.defer_fast_outcome_node(&mut outcome, token);
7382 let error = self.arena_token_node(index, true);
7383 self.defer_fast_outcome_node(&mut outcome, error);
7384 }
7385 outcome
7386 })
7387 .collect()
7388 }
7389
7390 fn fast_single_token_insertion_recovery(
7394 &mut self,
7395 recovery: FastRecoveryRequest<'_, '_>,
7396 predicate_context: Option<FastPredicateContext<'_>>,
7397 ) -> Vec<FastRecognizeOutcome> {
7398 let FastRecoveryRequest {
7399 atn,
7400 transition,
7401 expected_symbols,
7402 target,
7403 request,
7404 visiting,
7405 memo,
7406 expected,
7407 } = recovery;
7408 let FastRecognizeRequest {
7409 stop_state,
7410 index,
7411 rule_start_index,
7412 decision_start_index,
7413 precedence,
7414 depth,
7415 ..
7416 } = request;
7417 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
7418 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
7419 transition,
7420 index,
7421 atn.max_token_type(),
7422 &expected_symbols,
7423 &follow_symbols,
7424 ) else {
7425 return Vec::new();
7426 };
7427 let empty_recovery = self.empty_recovery_symbols();
7428 self.recognize_state_fast(
7429 atn,
7430 FastRecognizeRequest {
7431 state_number: target,
7432 stop_state,
7433 index,
7434 rule_start_index,
7435 decision_start_index,
7436 precedence,
7437 depth: depth + 1,
7438 recovery_symbols: empty_recovery,
7439 recovery_state: None,
7440 },
7441 FastRecognizeScratch {
7442 predicate_context,
7443 visiting,
7444 memo,
7445 expected,
7446 },
7447 )
7448 .into_iter()
7449 .map(|mut outcome| {
7450 outcome.diagnostics = self
7451 .recognition_arena
7452 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7453 let missing = self.arena_missing_token_node(token_type, index, text.clone());
7454 self.defer_fast_outcome_node(&mut outcome, missing);
7455 outcome
7456 })
7457 .collect()
7458 }
7459
7460 fn fast_current_token_deletion_recovery(
7463 &mut self,
7464 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
7465 predicate_context: Option<FastPredicateContext<'_>>,
7466 ) -> Vec<FastRecognizeOutcome> {
7467 let FastCurrentTokenDeletionRequest {
7468 atn,
7469 expected_symbols,
7470 mut request,
7471 visiting,
7472 memo,
7473 expected,
7474 } = recovery;
7475 if request.index == request.rule_start_index {
7476 return Vec::new();
7477 }
7478 let Some((diagnostic, next_index, skipped)) =
7479 self.current_token_deletion(request.index, &expected_symbols)
7480 else {
7481 return Vec::new();
7482 };
7483 request.state_number = request.recovery_state.unwrap_or(request.state_number);
7484 request.index = next_index;
7485 request.depth += 1;
7486 request.recovery_state = None;
7487 self.recognize_state_fast(
7488 atn,
7489 request,
7490 FastRecognizeScratch {
7491 predicate_context,
7492 visiting,
7493 memo,
7494 expected,
7495 },
7496 )
7497 .into_iter()
7498 .map(|mut outcome| {
7499 outcome.diagnostics = self
7500 .recognition_arena
7501 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7502 for index in skipped.iter().rev() {
7503 let error = self.arena_token_node(*index, true);
7504 self.defer_fast_outcome_node(&mut outcome, error);
7505 }
7506 outcome
7507 })
7508 .collect()
7509 }
7510
7511 fn fast_child_rule_failure_recovery(
7514 &mut self,
7515 rule_index: usize,
7516 start_index: usize,
7517 sync_symbols: &BTreeSet<i32>,
7518 expected: &ExpectedTokens,
7519 ) -> Option<FastRecognizeOutcome> {
7520 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7521 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7522 let mut next_index = error_index;
7523 loop {
7524 let symbol = self.token_type_at(next_index);
7525 if sync_symbols.contains(&symbol) {
7526 if next_index == error_index {
7527 return None;
7528 }
7529 break;
7530 }
7531 if symbol == TOKEN_EOF {
7532 break;
7533 }
7534 let after = self.consume_index(next_index, symbol);
7535 if after == next_index {
7536 break;
7537 }
7538 next_index = after;
7539 }
7540 let diagnostics = self
7541 .recognition_arena
7542 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7543 let mut nodes = NodeSeqId::EMPTY;
7544 if self.fast_token_nodes_enabled {
7545 let error = self.arena_token_node(error_index, true);
7546 self.arena_prepend(&mut nodes, error);
7547 }
7548 Some(FastRecognizeOutcome {
7549 index: next_index,
7550 consumed_eof: false,
7551 diagnostics,
7552 deferred_nodes: FastDeferredNodeId::EMPTY,
7553 nodes,
7554 })
7555 }
7556
7557 fn fast_child_rule_failure_recovery_outcomes(
7560 &mut self,
7561 request: FastChildRuleFailureRecoveryRequest<'_>,
7562 ) -> Vec<FastRecognizeOutcome> {
7563 let FastChildRuleFailureRecoveryRequest {
7564 atn,
7565 rule_index,
7566 start_index,
7567 follow_state,
7568 stop_state,
7569 expected,
7570 } = request;
7571 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
7572 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
7573 .into_iter()
7574 .collect()
7575 }
7576
7577 fn defer_fast_outcome_node(
7578 &mut self,
7579 outcome: &mut FastRecognizeOutcome,
7580 node: RecognizedNodeId,
7581 ) {
7582 if outcome.deferred_nodes.is_empty() {
7583 self.arena_prepend(&mut outcome.nodes, node);
7584 return;
7585 }
7586 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
7587 let fragment = self.recognition_arena.deferred_fragment(fragment);
7588 outcome.deferred_nodes = self
7589 .recognition_arena
7590 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
7591 }
7592
7593 fn materialize_fast_deferred_nodes(
7594 &mut self,
7595 root: FastDeferredNodeId,
7596 initial_suffix: NodeSeqId,
7597 ) -> NodeSeqId {
7598 if root.is_empty() {
7599 return initial_suffix;
7600 }
7601
7602 enum Frame {
7603 Visit(FastDeferredNodeId),
7604 ContinuePrefix(FastDeferredNodeId),
7605 FinishRule {
7606 rule: FastDeferredRule,
7607 parent_suffix: NodeSeqId,
7608 },
7609 }
7610
7611 let mut result = initial_suffix;
7612 let mut pending = Vec::with_capacity(16);
7613 pending.push(Frame::Visit(root));
7614 let mut fragment_nodes = Vec::new();
7615 while let Some(frame) = pending.pop() {
7616 match frame {
7617 Frame::Visit(deferred) => {
7618 if deferred.is_empty() {
7619 continue;
7620 }
7621
7622 match self.recognition_arena.deferred_node(deferred) {
7623 FastDeferredNode::Fragment(sequence) => {
7624 fragment_nodes.clear();
7625 fragment_nodes.extend(self.recognition_arena.iter(sequence));
7626 while let Some(node) = fragment_nodes.pop() {
7627 self.arena_prepend(&mut result, node);
7628 }
7629 }
7630 FastDeferredNode::Rule(rule) => {
7631 let rule = self.recognition_arena.deferred_rule(rule);
7632 let parent_suffix = result;
7633 result = rule.children;
7634 pending.push(Frame::FinishRule {
7635 rule,
7636 parent_suffix,
7637 });
7638 pending.push(Frame::Visit(rule.deferred_children));
7639 }
7640 FastDeferredNode::Concat {
7641 prefix,
7642 suffix: deferred_suffix,
7643 } => {
7644 pending.push(Frame::ContinuePrefix(prefix));
7645 pending.push(Frame::Visit(deferred_suffix));
7646 }
7647 }
7648 }
7649 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
7650 Frame::FinishRule {
7651 rule,
7652 parent_suffix,
7653 } => {
7654 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
7655 rule_index: rule.rule_index,
7656 invoking_state: rule.invoking_state,
7657 alt_number: 0,
7658 start_index: rule.start_index,
7659 stop_index: rule.stop_index,
7660 return_values: None,
7661 children: result,
7662 });
7663 result = parent_suffix;
7664 self.arena_prepend(&mut result, node);
7665 }
7666 }
7667 }
7668 result
7669 }
7670
7671 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) {
7672 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
7673 outcome.nodes = self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
7674 }
7675
7676 fn recognize_repetition_fast(
7679 &mut self,
7680 atn: &Atn,
7681 request: &FastRecognizeRequest,
7682 shape: FastRepetitionShape,
7683 scratch: FastRecognizeScratch<'_, '_>,
7684 ) -> Vec<FastRecognizeOutcome> {
7685 let FastRecognizeScratch {
7686 predicate_context,
7687 visiting,
7688 memo,
7689 expected,
7690 } = scratch;
7691 let lookahead = if self.fast_first_set_prefilter {
7692 atn.state(request.state_number).and_then(|state| {
7693 state
7694 .rule_index()
7695 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
7696 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
7697 })
7698 } else {
7699 None
7700 };
7701 let mut work = Vec::with_capacity(2);
7702 push_fast_repetition_work(
7703 &mut work,
7704 shape,
7705 FastRepetitionPath {
7706 index: request.index,
7707 deferred_nodes: FastDeferredNodeId::EMPTY,
7708 diagnostics: DiagnosticSeqId::EMPTY,
7709 consumed_eof: false,
7710 },
7711 lookahead.as_deref(),
7712 self.token_type_at(request.index),
7713 );
7714 let mut coordinates = FastRepetitionCoordinates::new(request.index);
7715 let mut outcomes = Vec::new();
7716 while let Some(item) = work.pop() {
7717 match item {
7718 FastRepetitionWork::Enter(path) => {
7719 if !coordinates.insert_entered(path) {
7720 continue;
7721 }
7722 let body_outcomes = self.recognize_state_fast(
7723 atn,
7724 FastRecognizeRequest {
7725 state_number: shape.enter_target,
7726 stop_state: shape.body_stop_state,
7727 index: path.index,
7728 rule_start_index: request.rule_start_index,
7729 decision_start_index: request.decision_start_index,
7730 precedence: request.precedence,
7731 depth: request.depth.saturating_add(1),
7732 recovery_symbols: Rc::clone(&request.recovery_symbols),
7733 recovery_state: request.recovery_state,
7734 },
7735 FastRecognizeScratch {
7736 predicate_context,
7737 visiting: &mut *visiting,
7738 memo: &mut *memo,
7739 expected: &mut *expected,
7740 },
7741 );
7742 for body in body_outcomes.into_iter().rev() {
7743 if body.index <= path.index {
7747 continue;
7748 }
7749 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
7750 let body_nodes = self
7751 .recognition_arena
7752 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
7753 let deferred_nodes = self
7754 .recognition_arena
7755 .concat_deferred_nodes(path.deferred_nodes, body_nodes);
7756 let next_path = FastRepetitionPath {
7757 index: body.index,
7758 deferred_nodes,
7759 diagnostics: self
7760 .recognition_arena
7761 .concat_diagnostics(path.diagnostics, body.diagnostics),
7762 consumed_eof: path.consumed_eof || body.consumed_eof,
7763 };
7764 let symbol = self.token_type_at(next_path.index);
7765 push_fast_repetition_work(
7766 &mut work,
7767 shape,
7768 next_path,
7769 lookahead.as_deref(),
7770 symbol,
7771 );
7772 }
7773 }
7774 FastRepetitionWork::Exit(path) => {
7775 if !coordinates.insert_exited(path) {
7776 continue;
7777 }
7778 let suffixes = self.recognize_state_fast(
7779 atn,
7780 FastRecognizeRequest {
7781 state_number: shape.exit_target,
7782 stop_state: request.stop_state,
7783 index: path.index,
7784 rule_start_index: request.rule_start_index,
7785 decision_start_index: request.decision_start_index,
7786 precedence: request.precedence,
7787 depth: request.depth.saturating_add(1),
7788 recovery_symbols: Rc::clone(&request.recovery_symbols),
7789 recovery_state: request.recovery_state,
7790 },
7791 FastRecognizeScratch {
7792 predicate_context,
7793 visiting: &mut *visiting,
7794 memo: &mut *memo,
7795 expected: &mut *expected,
7796 },
7797 );
7798 for mut outcome in suffixes {
7799 outcome.deferred_nodes = self
7800 .recognition_arena
7801 .concat_deferred_nodes(path.deferred_nodes, outcome.deferred_nodes);
7802 outcome.diagnostics = self
7803 .recognition_arena
7804 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
7805 outcome.consumed_eof |= path.consumed_eof;
7806 outcomes.push(outcome);
7807 }
7808 }
7809 }
7810 }
7811 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
7812 outcomes
7813 }
7814
7815 #[allow(clippy::too_many_lines)]
7818 fn recognize_state_fast(
7819 &mut self,
7820 atn: &Atn,
7821 request: FastRecognizeRequest,
7822 scratch: FastRecognizeScratch<'_, '_>,
7823 ) -> Vec<FastRecognizeOutcome> {
7824 #[cfg(feature = "perf-counters")]
7825 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
7826 let FastRecognizeScratch {
7827 predicate_context,
7828 visiting,
7829 memo,
7830 expected,
7831 } = scratch;
7832 let FastRecognizeRequest {
7833 mut state_number,
7834 stop_state,
7835 mut index,
7836 rule_start_index,
7837 decision_start_index,
7838 precedence,
7839 mut depth,
7840 recovery_symbols,
7841 recovery_state,
7842 } = request;
7843 let max_token_type = atn.max_token_type();
7844 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
7863 let mut inline_consumed_eof = false;
7864 loop {
7865 if depth > RECOGNITION_DEPTH_LIMIT {
7866 return Vec::new();
7867 }
7868 if state_number == stop_state {
7869 let mut nodes = NodeSeqId::EMPTY;
7870 if self.fast_token_nodes_enabled {
7871 for token_index in inline_consumed_tokens.iter().rev() {
7872 let token = self.arena_token_node(*token_index, false);
7873 self.arena_prepend(&mut nodes, token);
7874 }
7875 }
7876 return vec![FastRecognizeOutcome {
7877 index,
7878 consumed_eof: inline_consumed_eof,
7879 diagnostics: DiagnosticSeqId::EMPTY,
7880 deferred_nodes: FastDeferredNodeId::EMPTY,
7881 nodes,
7882 }];
7883 }
7884 let Some(state) = atn.state(state_number) else {
7885 return Vec::new();
7886 };
7887 let transitions = state.transitions();
7888 if transitions.len() == 1 && !state.precedence_rule_decision() {
7889 let transition = transitions
7890 .first()
7891 .expect("single transition checked above");
7892 let transition_kind = transition.kind();
7893 let target = transition.target();
7894 match transition_kind {
7895 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
7896 if left_recursive_boundary(atn, state, target).is_none() =>
7897 {
7898 #[cfg(feature = "perf-counters")]
7899 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
7900 state_number = target;
7901 depth += 1;
7902 continue;
7903 }
7904 ParserTransitionKind::Predicate
7905 if left_recursive_boundary(atn, state, target).is_none() =>
7906 {
7907 #[cfg(feature = "perf-counters")]
7908 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
7909 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
7910 {
7911 record_predicate_no_viable(expected, decision_start_index, index);
7912 return Vec::new();
7913 }
7914 state_number = target;
7915 depth += 1;
7916 continue;
7917 }
7918 ParserTransitionKind::Precedence
7919 if packed_i32(transition.arg0()) >= precedence
7920 && left_recursive_boundary(atn, state, target).is_none() =>
7921 {
7922 #[cfg(feature = "perf-counters")]
7923 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
7924 state_number = target;
7925 depth += 1;
7926 continue;
7927 }
7928 ParserTransitionKind::Atom
7938 | ParserTransitionKind::Range
7939 | ParserTransitionKind::Set
7940 | ParserTransitionKind::NotSet
7941 | ParserTransitionKind::Wildcard
7942 if !self.fast_recovery_enabled =>
7943 {
7944 let symbol = self.token_type_at(index);
7945 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
7946 #[cfg(feature = "perf-counters")]
7947 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
7948 if self.fast_token_nodes_enabled {
7949 inline_consumed_tokens.push(index);
7950 }
7951 inline_consumed_eof |= symbol == TOKEN_EOF;
7952 index = self.consume_index(index, symbol);
7953 state_number = target;
7954 depth += 1;
7955 continue;
7956 }
7957 }
7960 _ => {}
7961 }
7962 }
7963 break;
7964 }
7965 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
7969 let Some(state) = atn.state(state_number) else {
7970 return Vec::new();
7971 };
7972 let transitions = state.transitions();
7973 let transition_count = transitions.len();
7974 if !self.fast_recovery_enabled
7975 && let Some(shape) = fast_repetition_shape(atn, state)
7976 {
7977 let mut outcomes = self.recognize_repetition_fast(
7978 atn,
7979 &FastRecognizeRequest {
7980 state_number,
7981 stop_state,
7982 index,
7983 rule_start_index,
7984 decision_start_index,
7985 precedence,
7986 depth,
7987 recovery_symbols: Rc::clone(&recovery_symbols),
7988 recovery_state,
7989 },
7990 shape,
7991 FastRecognizeScratch {
7992 predicate_context,
7993 visiting: &mut *visiting,
7994 memo: &mut *memo,
7995 expected: &mut *expected,
7996 },
7997 );
7998 if inline_pending {
7999 for outcome in &mut outcomes {
8000 outcome.consumed_eof |= inline_consumed_eof;
8001 if self.fast_token_nodes_enabled {
8002 for token_index in inline_consumed_tokens.iter().rev() {
8003 let token = self.arena_token_node(*token_index, false);
8004 self.defer_fast_outcome_node(outcome, token);
8005 }
8006 }
8007 }
8008 }
8009 return outcomes;
8010 }
8011 let key = if self.fast_recovery_enabled {
8021 FastRecognizeKey {
8022 state_number,
8023 stop_state,
8024 index,
8025 rule_start_index,
8026 decision_start_index,
8027 precedence,
8028 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
8029 recovery_state,
8030 }
8031 } else {
8032 FastRecognizeKey {
8033 state_number,
8034 stop_state,
8035 index,
8036 rule_start_index: 0,
8037 decision_start_index: None,
8038 precedence,
8039 recovery_symbols_id: 0,
8040 recovery_state: None,
8041 }
8042 };
8043 let memo_lookup_enabled = self.fast_recovery_enabled
8048 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
8049 if memo_lookup_enabled {
8050 if let Some(outcomes) = memo.get(&key) {
8051 #[cfg(feature = "perf-counters")]
8052 {
8053 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
8054 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
8055 }
8056 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
8060 let inline_eof = inline_consumed_eof;
8061 let inline_tokens = &inline_consumed_tokens;
8062 return outcomes
8063 .iter()
8064 .copied()
8065 .map(|mut outcome| {
8066 if inline_eof {
8067 outcome.consumed_eof = true;
8068 }
8069 if self.fast_token_nodes_enabled {
8070 for token_index in inline_tokens.iter().rev() {
8071 let token = self.arena_token_node(*token_index, false);
8072 self.defer_fast_outcome_node(&mut outcome, token);
8073 }
8074 }
8075 outcome
8076 })
8077 .collect();
8078 }
8079 return outcomes.to_vec();
8080 }
8081 #[cfg(feature = "perf-counters")]
8082 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
8083 }
8084
8085 let needs_cycle_guard = if self.fast_recovery_enabled {
8090 transitions.iter().any(ParserTransition::is_epsilon)
8091 } else {
8092 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
8093 };
8094 #[cfg(feature = "perf-counters")]
8095 if needs_cycle_guard {
8096 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
8097 } else {
8098 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
8099 match state
8100 .transitions()
8101 .first()
8102 .expect("single-transition path requires one transition")
8103 .data()
8104 {
8105 Transition::Rule { .. } => {
8106 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
8107 }
8108 Transition::Atom { .. }
8109 | Transition::Range { .. }
8110 | Transition::Set { .. }
8111 | Transition::NotSet { .. }
8112 | Transition::Wildcard { .. } => {
8113 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
8114 }
8115 _ => {
8116 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
8117 }
8118 }
8119 }
8120 let has_inserted_cycle_guard = if needs_cycle_guard {
8121 if !visiting.insert(key.clone()) {
8122 #[cfg(feature = "perf-counters")]
8123 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
8124 return Vec::new();
8125 }
8126 true
8127 } else {
8128 false
8129 };
8130 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
8131 Some(index)
8132 } else {
8133 decision_start_index
8134 };
8135 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
8136 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
8137 } else {
8138 (Rc::clone(&recovery_symbols), recovery_state)
8139 };
8140
8141 let lookahead_filter = if transition_count > 1
8160 && self.fast_first_set_prefilter
8161 && !state.precedence_rule_decision()
8162 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
8163 {
8164 state
8165 .rule_index()
8166 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8167 .map(|rule_stop| {
8168 let symbol = self.token_type_at(index);
8169 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
8170 (symbol, entry)
8171 })
8172 } else {
8173 None
8174 };
8175 let ll1_only_alt: Option<usize> = if transition_count > 1
8184 && let Some((symbol, entry)) = lookahead_filter.as_ref()
8185 {
8186 let key = (state.state_number(), *symbol);
8187 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
8188 cached
8189 } else {
8190 let result = ll1_unique_alt(entry, *symbol);
8191 self.ll1_decision_cache.insert(key, result);
8192 result
8193 }
8194 } else {
8195 None
8196 };
8197 let lookahead_filter = lookahead_filter.as_ref();
8198 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
8204 for (transition_index, transition) in transitions.iter().enumerate() {
8205 if let Some(alt) = ll1_only_alt {
8206 if alt != transition_index {
8208 continue;
8209 }
8210 }
8211 let transition_kind = transition.kind();
8212 if ll1_only_alt.is_none()
8213 && should_skip_via_lookahead(
8214 transition_kind,
8215 transition_index,
8216 lookahead_filter,
8217 index,
8218 self.fast_recovery_enabled,
8219 expected,
8220 )
8221 {
8222 continue;
8223 }
8224 let target = transition.target();
8225 match transition_kind {
8226 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
8227 #[cfg(feature = "perf-counters")]
8228 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8229 let boundary = left_recursive_boundary(atn, state, target);
8230 outcomes.extend(
8231 self.recognize_state_fast(
8232 atn,
8233 FastRecognizeRequest {
8234 state_number: target,
8235 stop_state,
8236 index,
8237 rule_start_index,
8238 decision_start_index: next_decision_start_index,
8239 precedence,
8240 depth: depth + 1,
8241 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8242 recovery_state: epsilon_recovery_state,
8243 },
8244 FastRecognizeScratch {
8245 predicate_context,
8246 visiting,
8247 memo,
8248 expected,
8249 },
8250 )
8251 .into_iter()
8252 .map(|mut outcome| {
8253 if let Some(rule_index) = boundary {
8254 let boundary = self.arena_boundary_node(rule_index);
8255 self.defer_fast_outcome_node(&mut outcome, boundary);
8256 }
8257 outcome
8258 }),
8259 );
8260 }
8261 ParserTransitionKind::Predicate => {
8262 #[cfg(feature = "perf-counters")]
8263 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8264 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
8265 let boundary = left_recursive_boundary(atn, state, target);
8266 outcomes.extend(
8267 self.recognize_state_fast(
8268 atn,
8269 FastRecognizeRequest {
8270 state_number: target,
8271 stop_state,
8272 index,
8273 rule_start_index,
8274 decision_start_index: next_decision_start_index,
8275 precedence,
8276 depth: depth + 1,
8277 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8278 recovery_state: epsilon_recovery_state,
8279 },
8280 FastRecognizeScratch {
8281 predicate_context,
8282 visiting,
8283 memo,
8284 expected,
8285 },
8286 )
8287 .into_iter()
8288 .map(|mut outcome| {
8289 if let Some(rule_index) = boundary {
8290 let boundary = self.arena_boundary_node(rule_index);
8291 self.defer_fast_outcome_node(&mut outcome, boundary);
8292 }
8293 outcome
8294 }),
8295 );
8296 } else {
8297 record_predicate_no_viable(expected, next_decision_start_index, index);
8298 }
8299 }
8300 ParserTransitionKind::Precedence => {
8301 let transition_precedence = packed_i32(transition.arg0());
8302 if transition_precedence >= precedence {
8303 let boundary = left_recursive_boundary(atn, state, target);
8304 outcomes.extend(
8305 self.recognize_state_fast(
8306 atn,
8307 FastRecognizeRequest {
8308 state_number: target,
8309 stop_state,
8310 index,
8311 rule_start_index,
8312 decision_start_index: next_decision_start_index,
8313 precedence,
8314 depth: depth + 1,
8315 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8316 recovery_state: epsilon_recovery_state,
8317 },
8318 FastRecognizeScratch {
8319 predicate_context,
8320 visiting,
8321 memo,
8322 expected,
8323 },
8324 )
8325 .into_iter()
8326 .map(|mut outcome| {
8327 if let Some(rule_index) = boundary {
8328 let boundary = self.arena_boundary_node(rule_index);
8329 self.defer_fast_outcome_node(&mut outcome, boundary);
8330 }
8331 outcome
8332 }),
8333 );
8334 }
8335 }
8336 ParserTransitionKind::Rule => {
8337 let rule_index = transition.arg0() as usize;
8338 let follow_state = transition.arg1() as usize;
8339 let rule_precedence = packed_i32(transition.arg2());
8340 #[cfg(feature = "perf-counters")]
8341 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
8342 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
8343 continue;
8344 };
8345 let symbol = self.token_type_at(index);
8357 if self.fast_first_set_prefilter {
8358 let first = self.cached_rule_first_set(atn, target, child_stop);
8371 if should_skip_rule_via_first_set(
8372 &first,
8373 symbol,
8374 self.fast_recovery_enabled,
8375 index,
8376 expected,
8377 ) {
8378 continue;
8379 }
8380 }
8381 let expected_before_child =
8382 self.fast_recovery_enabled.then(|| expected.clone());
8383 let mut children = self.recognize_state_fast(
8384 atn,
8385 FastRecognizeRequest {
8386 state_number: target,
8387 stop_state: child_stop,
8388 index,
8389 rule_start_index: index,
8390 decision_start_index: None,
8391 precedence: rule_precedence,
8392 depth: depth + 1,
8393 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8394 recovery_state: epsilon_recovery_state,
8395 },
8396 FastRecognizeScratch {
8397 predicate_context,
8398 visiting,
8399 memo,
8400 expected,
8401 },
8402 );
8403 if children.is_empty() && self.fast_recovery_enabled {
8404 children = self.fast_child_rule_failure_recovery_outcomes(
8405 FastChildRuleFailureRecoveryRequest {
8406 atn,
8407 rule_index,
8408 start_index: index,
8409 follow_state,
8410 stop_state,
8411 expected,
8412 },
8413 );
8414 }
8415 if let Some(expected_before_child) = expected_before_child {
8416 if children
8417 .iter()
8418 .any(|child| child.diagnostics.is_empty() && child.index > index)
8419 {
8420 *expected = expected_before_child;
8421 }
8422 }
8423 for child in children {
8424 let child_index = child.index;
8425 let child_consumed_eof = child.consumed_eof;
8426 let child_diagnostics = child.diagnostics;
8427 let empty_recovery = self.empty_recovery_symbols();
8428 let follow_outcomes = self.recognize_state_fast(
8429 atn,
8430 FastRecognizeRequest {
8431 state_number: follow_state,
8432 stop_state,
8433 index: child_index,
8434 rule_start_index,
8435 decision_start_index: next_decision_start_index,
8436 precedence,
8437 depth: depth + 1,
8438 recovery_symbols: empty_recovery,
8439 recovery_state: None,
8440 },
8441 FastRecognizeScratch {
8442 predicate_context,
8443 visiting,
8444 memo,
8445 expected,
8446 },
8447 );
8448 if follow_outcomes.is_empty() {
8449 continue;
8450 }
8451 let child_stop_index =
8452 self.rule_stop_token_index(child_index, child_consumed_eof);
8453 let child_node = self.build_parse_trees.then(|| {
8454 self.recognition_arena.deferred_rule_node(FastDeferredRule {
8455 rule_index: u32::try_from(rule_index)
8456 .expect("rule index fits in u32"),
8457 invoking_state: i32::try_from(invoking_state_number(state_number))
8458 .expect("invoking state fits in i32"),
8459 start_index: u32::try_from(index)
8460 .expect("rule start index fits in u32"),
8461 stop_index: child_stop_index.map(|stop_index| {
8462 u32::try_from(stop_index).expect("rule stop index fits in u32")
8463 }),
8464 deferred_children: child.deferred_nodes,
8465 children: child.nodes,
8466 })
8467 });
8468 let child_diags_empty = child_diagnostics.is_empty();
8469 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
8470 outcome.consumed_eof |= child_consumed_eof;
8471 if !child_diags_empty {
8474 outcome.diagnostics = self
8475 .recognition_arena
8476 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
8477 }
8478 if let Some(child_node) = child_node {
8479 outcome.deferred_nodes = self
8480 .recognition_arena
8481 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
8482 }
8483 outcome
8484 }));
8485 }
8486 }
8487 ParserTransitionKind::Atom
8488 | ParserTransitionKind::Range
8489 | ParserTransitionKind::Set
8490 | ParserTransitionKind::NotSet
8491 | ParserTransitionKind::Wildcard => {
8492 #[cfg(feature = "perf-counters")]
8493 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
8494 let symbol = self.token_type_at(index);
8495 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
8496 let next_index = self.consume_index(index, symbol);
8497 let empty_recovery = self.empty_recovery_symbols();
8498 outcomes.extend(
8499 self.recognize_state_fast(
8500 atn,
8501 FastRecognizeRequest {
8502 state_number: target,
8503 stop_state,
8504 index: next_index,
8505 rule_start_index,
8506 decision_start_index: next_decision_start_index,
8507 precedence,
8508 depth: depth + 1,
8509 recovery_symbols: empty_recovery,
8510 recovery_state: None,
8511 },
8512 FastRecognizeScratch {
8513 predicate_context,
8514 visiting,
8515 memo,
8516 expected,
8517 },
8518 )
8519 .into_iter()
8520 .map(|mut outcome| {
8521 outcome.consumed_eof |= symbol == TOKEN_EOF;
8522 if self.fast_token_nodes_enabled {
8523 let token = self.arena_token_node(index, false);
8524 self.defer_fast_outcome_node(&mut outcome, token);
8525 }
8526 outcome
8527 }),
8528 );
8529 } else {
8530 if !self.fast_recovery_enabled {
8531 continue;
8539 }
8540 let expected_symbols = fast_recovery_expected_symbols(
8541 self,
8542 atn,
8543 state.state_number(),
8544 &recovery_symbols,
8545 );
8546 if expected_symbols.contains(&symbol) {
8547 continue;
8548 }
8549 {
8550 expected.record_transition(index, transition, max_token_type);
8551 record_no_viable_if_ambiguous(
8552 expected,
8553 next_decision_start_index,
8554 index,
8555 );
8556 outcomes.extend(self.fast_single_token_deletion_recovery(
8557 FastRecoveryRequest {
8558 atn,
8559 transition,
8560 expected_symbols: Rc::clone(&expected_symbols),
8561 target,
8562 request: FastRecognizeRequest {
8563 state_number,
8564 stop_state,
8565 index,
8566 rule_start_index,
8567 decision_start_index,
8568 precedence,
8569 depth,
8570 recovery_symbols: Rc::clone(&recovery_symbols),
8571 recovery_state,
8572 },
8573 visiting,
8574 memo,
8575 expected,
8576 },
8577 predicate_context,
8578 ));
8579 if !state_is_left_recursive_rule(atn, state) {
8580 outcomes.extend(self.fast_single_token_insertion_recovery(
8581 FastRecoveryRequest {
8582 atn,
8583 transition,
8584 expected_symbols: Rc::clone(&expected_symbols),
8585 target,
8586 request: FastRecognizeRequest {
8587 state_number,
8588 stop_state,
8589 index,
8590 rule_start_index,
8591 decision_start_index,
8592 precedence,
8593 depth,
8594 recovery_symbols: Rc::clone(&recovery_symbols),
8595 recovery_state,
8596 },
8597 visiting,
8598 memo,
8599 expected,
8600 },
8601 predicate_context,
8602 ));
8603 }
8604 outcomes.extend(self.fast_current_token_deletion_recovery(
8605 FastCurrentTokenDeletionRequest {
8606 atn,
8607 expected_symbols,
8608 request: FastRecognizeRequest {
8609 state_number,
8610 stop_state,
8611 index,
8612 rule_start_index,
8613 decision_start_index,
8614 precedence,
8615 depth,
8616 recovery_symbols: Rc::clone(&recovery_symbols),
8617 recovery_state,
8618 },
8619 visiting,
8620 memo,
8621 expected,
8622 },
8623 predicate_context,
8624 ));
8625 }
8626 }
8627 }
8628 }
8629 }
8630
8631 if has_inserted_cycle_guard {
8632 visiting.remove(&key);
8633 }
8634 if matches!(
8635 self.prediction_mode,
8636 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
8637 ) && self.fast_recovery_enabled
8638 {
8639 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
8643 }
8644 if self.fast_recovery_enabled {
8645 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
8646 } else {
8647 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8648 }
8649 let should_memoize = self.fast_recovery_enabled
8659 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
8660 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
8664 if inline_consumed_eof {
8665 outcome.consumed_eof = true;
8666 }
8667 if !inline_consumed_tokens.is_empty() {
8668 for token_index in inline_consumed_tokens.iter().rev() {
8669 let token = self.arena_token_node(*token_index, false);
8670 self.defer_fast_outcome_node(&mut outcome, token);
8671 }
8672 }
8673 outcome
8674 };
8675 if should_memoize {
8676 #[cfg(feature = "perf-counters")]
8677 {
8678 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
8679 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
8680 match outcomes.len() {
8681 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
8682 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
8683 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
8684 }
8685 }
8686 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
8691 memo.insert(key, Rc::clone(&stored));
8692 if inline_pending {
8693 return stored
8694 .iter()
8695 .copied()
8696 .map(&mut apply_inline_pending)
8697 .collect();
8698 }
8699 return stored.to_vec();
8700 }
8701 #[cfg(feature = "perf-counters")]
8702 match outcomes.len() {
8703 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
8704 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
8705 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
8706 }
8707 if inline_pending {
8708 return outcomes.into_iter().map(apply_inline_pending).collect();
8709 }
8710 outcomes
8711 }
8712
8713 fn single_token_deletion_recovery(
8716 &mut self,
8717 recovery: RecoveryRequest<'_, '_>,
8718 ) -> Vec<RecognizeOutcome> {
8719 let RecoveryRequest {
8720 atn,
8721 transition,
8722 expected_symbols,
8723 target,
8724 request,
8725 visiting,
8726 memo,
8727 expected,
8728 } = recovery;
8729 let RecognizeRequest {
8730 stop_state,
8731 index,
8732 rule_start_index,
8733 decision_start_index,
8734 init_action_rules,
8735 predicates,
8736 semantics,
8737 rule_args,
8738 member_actions,
8739 return_actions,
8740 local_int_arg,
8741 member_values,
8742 return_values,
8743 rule_alt_number,
8744 track_alt_numbers,
8745 consumed_eof,
8746 precedence,
8747 depth,
8748 ..
8749 } = request;
8750 let Some((diagnostic, next_index, next_symbol)) =
8751 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
8752 else {
8753 return Vec::new();
8754 };
8755 let after_next = self.consume_index(next_index, next_symbol);
8756 self.recognize_state(
8757 atn,
8758 RecognizeRequest {
8759 state_number: target,
8760 stop_state,
8761 index: after_next,
8762 rule_start_index,
8763 decision_start_index,
8764 init_action_rules,
8765 predicates,
8766 semantics,
8767 rule_args,
8768 member_actions,
8769 return_actions,
8770 local_int_arg,
8771 member_values,
8772 return_values,
8773 rule_alt_number,
8774 track_alt_numbers,
8775 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
8776 precedence,
8777 depth: depth + 1,
8778 recovery_symbols: BTreeSet::new(),
8779 recovery_state: None,
8780 },
8781 visiting,
8782 memo,
8783 expected,
8784 )
8785 .into_iter()
8786 .map(|mut outcome| {
8787 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
8788 outcome.diagnostics = self
8789 .recognition_arena
8790 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8791 let token = self.arena_token_node(next_index, false);
8792 self.arena_prepend(&mut outcome.nodes, token);
8793 let error = self.arena_token_node(index, true);
8794 self.arena_prepend(&mut outcome.nodes, error);
8795 outcome
8796 })
8797 .collect()
8798 }
8799
8800 fn current_token_deletion_recovery(
8803 &mut self,
8804 recovery: CurrentTokenDeletionRequest<'_, '_>,
8805 ) -> Vec<RecognizeOutcome> {
8806 let CurrentTokenDeletionRequest {
8807 atn,
8808 expected_symbols,
8809 mut request,
8810 visiting,
8811 memo,
8812 expected,
8813 } = recovery;
8814 let error_index = request.index;
8815 if error_index == request.rule_start_index {
8816 return Vec::new();
8817 }
8818 let Some((diagnostic, next_index, skipped)) =
8819 self.current_token_deletion(error_index, &expected_symbols)
8820 else {
8821 return Vec::new();
8822 };
8823 request.state_number = request.recovery_state.unwrap_or(request.state_number);
8824 request.index = next_index;
8825 request.depth += 1;
8826 request.recovery_state = None;
8827 self.recognize_state(atn, request, visiting, memo, expected)
8828 .into_iter()
8829 .map(|mut outcome| {
8830 outcome.diagnostics = self
8831 .recognition_arena
8832 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8833 for index in skipped.iter().rev() {
8834 let error = self.arena_token_node(*index, true);
8835 self.arena_prepend(&mut outcome.nodes, error);
8836 }
8837 outcome
8838 })
8839 .collect()
8840 }
8841
8842 fn consuming_failure_fallback(
8845 &mut self,
8846 fallback: ConsumingFailureFallback<'_>,
8847 visiting: &mut BTreeSet<RecognizeKey>,
8848 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
8849 expected: &mut ExpectedTokens,
8850 ) -> Vec<RecognizeOutcome> {
8851 if fallback.expected_symbols.is_empty() {
8852 return Vec::new();
8853 }
8854 if fallback.symbol == TOKEN_EOF {
8855 return self.eof_consuming_failure_fallback(fallback, expected);
8856 }
8857 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
8858 }
8859
8860 fn non_eof_consuming_failure_fallback(
8863 &mut self,
8864 fallback: ConsumingFailureFallback<'_>,
8865 visiting: &mut BTreeSet<RecognizeKey>,
8866 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
8867 expected: &mut ExpectedTokens,
8868 ) -> Vec<RecognizeOutcome> {
8869 let ConsumingFailureFallback {
8870 atn,
8871 target,
8872 request,
8873 symbol,
8874 expected_symbols,
8875 decision_start_index,
8876 decision,
8877 } = fallback;
8878 let error_index = request.index;
8879 let diagnostic =
8880 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
8881 let next_index = self.consume_index(error_index, symbol);
8882 self.recognize_state(
8883 atn,
8884 RecognizeRequest {
8885 state_number: target,
8886 stop_state: request.stop_state,
8887 index: next_index,
8888 rule_start_index: request.rule_start_index,
8889 decision_start_index,
8890 init_action_rules: request.init_action_rules,
8891 predicates: request.predicates,
8892 semantics: request.semantics,
8893 rule_args: request.rule_args,
8894 member_actions: request.member_actions,
8895 return_actions: request.return_actions,
8896 local_int_arg: request.local_int_arg,
8897 member_values: request.member_values,
8898 return_values: request.return_values,
8899 rule_alt_number: request.rule_alt_number,
8900 track_alt_numbers: request.track_alt_numbers,
8901 consumed_eof: request.consumed_eof,
8902 precedence: request.precedence,
8903 depth: request.depth + 1,
8904 recovery_symbols: BTreeSet::new(),
8905 recovery_state: None,
8906 },
8907 visiting,
8908 memo,
8909 expected,
8910 )
8911 .into_iter()
8912 .map(|mut outcome| {
8913 prepend_decision(&mut outcome, decision);
8914 outcome.diagnostics = self
8915 .recognition_arena
8916 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8917 let error = self.arena_token_node(error_index, true);
8918 self.arena_prepend(&mut outcome.nodes, error);
8919 outcome
8920 })
8921 .collect()
8922 }
8923
8924 fn eof_consuming_failure_fallback(
8927 &mut self,
8928 fallback: ConsumingFailureFallback<'_>,
8929 expected: &ExpectedTokens,
8930 ) -> Vec<RecognizeOutcome> {
8931 let request = fallback.request;
8932 if request.index == request.rule_start_index {
8933 return Vec::new();
8934 }
8935 let diagnostic =
8936 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
8937 let diagnostics = self
8938 .recognition_arena
8939 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8940 vec![RecognizeOutcome {
8941 index: request.index,
8942 consumed_eof: request.consumed_eof,
8943 alt_number: request.rule_alt_number,
8944 member_values: request.member_values,
8945 return_values: request.return_values,
8946 diagnostics,
8947 decisions: Vec::new(),
8948 actions: Vec::new(),
8949 nodes: NodeSeqId::EMPTY,
8950 }]
8951 }
8952
8953 fn single_token_insertion_recovery(
8956 &mut self,
8957 recovery: RecoveryRequest<'_, '_>,
8958 ) -> Vec<RecognizeOutcome> {
8959 let RecoveryRequest {
8960 atn,
8961 transition,
8962 expected_symbols,
8963 target,
8964 request,
8965 visiting,
8966 memo,
8967 expected,
8968 } = recovery;
8969 let RecognizeRequest {
8970 stop_state,
8971 index,
8972 rule_start_index,
8973 decision_start_index,
8974 init_action_rules,
8975 predicates,
8976 semantics,
8977 rule_args,
8978 member_actions,
8979 return_actions,
8980 local_int_arg,
8981 member_values,
8982 return_values,
8983 rule_alt_number,
8984 track_alt_numbers,
8985 consumed_eof,
8986 precedence,
8987 depth,
8988 ..
8989 } = request;
8990 let follow_symbols = state_expected_symbols(atn, transition.target());
8991 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
8992 transition,
8993 index,
8994 atn.max_token_type(),
8995 &expected_symbols,
8996 &follow_symbols,
8997 ) else {
8998 return Vec::new();
8999 };
9000 self.recognize_state(
9001 atn,
9002 RecognizeRequest {
9003 state_number: target,
9004 stop_state,
9005 index,
9006 rule_start_index,
9007 decision_start_index,
9008 init_action_rules,
9009 predicates,
9010 semantics,
9011 rule_args,
9012 member_actions,
9013 return_actions,
9014 local_int_arg,
9015 member_values,
9016 return_values,
9017 rule_alt_number,
9018 track_alt_numbers,
9019 consumed_eof,
9020 precedence,
9021 depth: depth + 1,
9022 recovery_symbols: BTreeSet::new(),
9023 recovery_state: None,
9024 },
9025 visiting,
9026 memo,
9027 expected,
9028 )
9029 .into_iter()
9030 .map(|mut outcome| {
9031 outcome.diagnostics = self
9032 .recognition_arena
9033 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9034 let missing = self.arena_missing_token_node(token_type, index, text.clone());
9035 self.arena_prepend(&mut outcome.nodes, missing);
9036 outcome
9037 })
9038 .collect()
9039 }
9040
9041 #[allow(clippy::too_many_lines)]
9044 fn recognize_state(
9045 &mut self,
9046 atn: &Atn,
9047 request: RecognizeRequest<'_>,
9048 visiting: &mut BTreeSet<RecognizeKey>,
9049 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9050 expected: &mut ExpectedTokens,
9051 ) -> Vec<RecognizeOutcome> {
9052 let request_template = request.clone();
9053 let RecognizeRequest {
9054 state_number,
9055 stop_state,
9056 index,
9057 rule_start_index,
9058 decision_start_index,
9059 init_action_rules,
9060 predicates,
9061 semantics,
9062 rule_args,
9063 member_actions,
9064 return_actions,
9065 local_int_arg,
9066 member_values,
9067 return_values,
9068 rule_alt_number,
9069 track_alt_numbers,
9070 consumed_eof,
9071 precedence,
9072 depth,
9073 recovery_symbols,
9074 recovery_state,
9075 } = request;
9076 if depth > RECOGNITION_DEPTH_LIMIT {
9077 return Vec::new();
9078 }
9079 if state_number == stop_state {
9080 return stop_outcome(
9081 index,
9082 consumed_eof,
9083 rule_alt_number,
9084 member_values,
9085 return_values,
9086 );
9087 }
9088 let key = RecognizeKey {
9089 state_number,
9090 stop_state,
9091 index,
9092 rule_start_index,
9093 decision_start_index,
9094 local_int_arg,
9095 member_values: member_values.clone(),
9096 return_values: return_values.clone(),
9097 rule_alt_number,
9098 track_alt_numbers,
9099 consumed_eof,
9100 precedence,
9101 recovery_symbols: recovery_symbols.clone(),
9102 recovery_state,
9103 };
9104 if let Some(outcomes) = memo.get(&key) {
9105 return outcomes.clone();
9106 }
9107
9108 let visit_key = key.clone();
9109 if !visiting.insert(visit_key.clone()) {
9110 return Vec::new();
9111 }
9112
9113 let Some(state) = atn.state(state_number) else {
9114 visiting.remove(&visit_key);
9115 return Vec::new();
9116 };
9117 let transitions = state.transitions();
9118 let transition_count = transitions.len();
9119 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9120 Some(index)
9121 } else {
9122 decision_start_index
9123 };
9124 let (epsilon_recovery_symbols, epsilon_recovery_state) =
9125 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
9126 let mut outcomes = Vec::new();
9127 for (transition_index, transition) in transitions.iter().enumerate() {
9128 let decision =
9129 transition_decision(atn, state, transition_count, transition_index, predicates);
9130 let next_alt_number = next_alt_number(
9131 state,
9132 transition_count,
9133 transition_index,
9134 rule_alt_number,
9135 track_alt_numbers,
9136 );
9137 let transition_data = transition.data();
9138 match &transition_data {
9139 Transition::Epsilon { target } | Transition::Action { target, .. } => {
9140 let action_rule_index = match &transition_data {
9141 Transition::Action { rule_index, .. } => Some(*rule_index),
9142 _ => None,
9143 };
9144 outcomes.extend(self.recognize_epsilon_or_action_step(
9145 atn,
9146 &request_template,
9147 EpsilonActionStep {
9148 source_state: state_number,
9149 target: *target,
9150 action_rule_index,
9151 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
9152 decision,
9153 decision_start_index: next_decision_start_index,
9154 alt_number: next_alt_number,
9155 recovery_symbols: epsilon_recovery_symbols.clone(),
9156 recovery_state: epsilon_recovery_state,
9157 },
9158 RecognizeScratch {
9159 visiting,
9160 memo,
9161 expected,
9162 },
9163 ));
9164 }
9165 Transition::Predicate {
9166 target,
9167 rule_index,
9168 pred_index,
9169 ..
9170 } => {
9171 let predicate = PredicateEval {
9172 index,
9173 rule_index: *rule_index,
9174 pred_index: *pred_index,
9175 predicates,
9176 semantics,
9177 context: None,
9178 local_int_arg,
9179 member_values: &member_values,
9180 };
9181 if self.parser_predicate_matches(predicate) {
9182 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
9183 outcomes.extend(
9184 self.recognize_state(
9185 atn,
9186 RecognizeRequest {
9187 state_number: *target,
9188 stop_state,
9189 index,
9190 rule_start_index,
9191 decision_start_index: next_decision_start_index,
9192 init_action_rules,
9193 predicates,
9194 semantics,
9195 rule_args,
9196 member_actions,
9197 return_actions,
9198 local_int_arg,
9199 member_values: member_values.clone(),
9200 return_values: return_values.clone(),
9201 rule_alt_number: next_alt_number,
9202 track_alt_numbers,
9203 consumed_eof,
9204 precedence,
9205 depth: depth + 1,
9206 recovery_symbols: epsilon_recovery_symbols.clone(),
9207 recovery_state: epsilon_recovery_state,
9208 },
9209 visiting,
9210 memo,
9211 expected,
9212 )
9213 .into_iter()
9214 .map(|mut outcome| {
9215 prepend_decision(&mut outcome, decision);
9216 if let Some(rule_index) = left_recursive_boundary {
9217 let boundary = self.arena_boundary_node(rule_index);
9218 self.arena_prepend(&mut outcome.nodes, boundary);
9219 }
9220 outcome
9221 }),
9222 );
9223 } else if let Some(message) = semantics
9224 .and_then(|semantics| {
9225 self.parser_semantic_ir_predicate_failure_message(
9226 *rule_index,
9227 *pred_index,
9228 semantics,
9229 )
9230 })
9231 .or_else(|| {
9232 self.parser_predicate_failure_message(
9233 *rule_index,
9234 *pred_index,
9235 predicates,
9236 )
9237 })
9238 {
9239 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
9240 rule_index: *rule_index,
9241 index,
9242 message,
9243 member_values: member_values.clone(),
9244 return_values: return_values.clone(),
9245 rule_alt_number,
9246 }));
9247 } else {
9248 record_predicate_no_viable(expected, next_decision_start_index, index);
9249 }
9250 }
9251 Transition::Precedence {
9252 target,
9253 precedence: transition_precedence,
9254 } => {
9255 if *transition_precedence >= precedence {
9256 outcomes.extend(
9257 self.recognize_state(
9258 atn,
9259 RecognizeRequest {
9260 state_number: *target,
9261 stop_state,
9262 index,
9263 rule_start_index,
9264 decision_start_index: next_decision_start_index,
9265 init_action_rules,
9266 predicates,
9267 semantics,
9268 rule_args,
9269 member_actions,
9270 return_actions,
9271 local_int_arg,
9272 member_values: member_values.clone(),
9273 return_values: return_values.clone(),
9274 rule_alt_number: next_alt_number,
9275 track_alt_numbers,
9276 consumed_eof,
9277 precedence,
9278 depth: depth + 1,
9279 recovery_symbols: epsilon_recovery_symbols.clone(),
9280 recovery_state: epsilon_recovery_state,
9281 },
9282 visiting,
9283 memo,
9284 expected,
9285 )
9286 .into_iter()
9287 .map(|mut outcome| {
9288 prepend_decision(&mut outcome, decision);
9289 outcome
9290 }),
9291 );
9292 }
9293 }
9294 Transition::Rule {
9295 target,
9296 rule_index,
9297 follow_state,
9298 precedence: rule_precedence,
9299 ..
9300 } => {
9301 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
9302 continue;
9303 };
9304 let child_local_int_arg =
9305 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
9306 let expected_before_child = expected.clone();
9307 let children = self.recognize_state(
9308 atn,
9309 RecognizeRequest {
9310 state_number: *target,
9311 stop_state: child_stop,
9312 index,
9313 rule_start_index: index,
9314 decision_start_index: None,
9315 init_action_rules,
9316 predicates,
9317 semantics,
9318 rule_args,
9319 member_actions,
9320 return_actions,
9321 local_int_arg: child_local_int_arg,
9322 member_values: member_values.clone(),
9323 return_values: BTreeMap::new(),
9324 rule_alt_number: 0,
9325 track_alt_numbers,
9326 consumed_eof: false,
9327 precedence: *rule_precedence,
9328 depth: depth + 1,
9329 recovery_symbols: epsilon_recovery_symbols.clone(),
9330 recovery_state: epsilon_recovery_state,
9331 },
9332 visiting,
9333 memo,
9334 expected,
9335 );
9336 let children = if children.is_empty() {
9337 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
9338 atn,
9339 rule_index: *rule_index,
9340 start_index: index,
9341 follow_state: *follow_state,
9342 stop_state,
9343 member_values: member_values.clone(),
9344 expected,
9345 })
9346 } else {
9347 children
9348 };
9349 let preserve_child_expected =
9350 self.child_expected_reaches_clean_eof(&children, expected);
9351 restore_expected(
9352 &children,
9353 index,
9354 expected,
9355 expected_before_child,
9356 preserve_child_expected,
9357 );
9358 for child in children {
9359 let child_stop_index =
9360 self.rule_stop_token_index(child.index, child.consumed_eof);
9361 let child_nodes = self
9362 .recognition_arena
9363 .fold_left_recursive_boundaries(child.nodes);
9364 let child_node = self.arena_rule_node(ArenaRuleSpec {
9365 rule_index: *rule_index,
9366 invoking_state: invoking_state_number(state_number),
9367 alt_number: child.alt_number,
9368 start_index: index,
9369 stop_index: child_stop_index,
9370 return_values: child.return_values.clone(),
9371 children: child_nodes,
9372 });
9373 outcomes.extend(
9374 self.recognize_state(
9375 atn,
9376 RecognizeRequest {
9377 state_number: *follow_state,
9378 stop_state,
9379 index: child.index,
9380 rule_start_index,
9381 decision_start_index: next_decision_start_index,
9382 init_action_rules,
9383 predicates,
9384 semantics,
9385 rule_args,
9386 member_actions,
9387 return_actions,
9388 local_int_arg,
9389 member_values: child.member_values.clone(),
9390 return_values: return_values.clone(),
9391 rule_alt_number,
9392 track_alt_numbers,
9393 consumed_eof: consumed_eof || child.consumed_eof,
9394 precedence,
9395 depth: depth + 1,
9396 recovery_symbols: BTreeSet::new(),
9397 recovery_state: None,
9398 },
9399 visiting,
9400 memo,
9401 expected,
9402 )
9403 .into_iter()
9404 .map(|mut outcome| {
9405 outcome.consumed_eof |= child.consumed_eof;
9406 outcome.diagnostics = self
9407 .recognition_arena
9408 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
9409 let mut decisions = child.decisions.clone();
9410 decisions.append(&mut outcome.decisions);
9411 outcome.decisions = decisions;
9412 prepend_decision(&mut outcome, decision);
9413 let mut actions = child.actions.clone();
9414 if init_action_rules.contains(rule_index) {
9415 actions.insert(
9416 0,
9417 ParserAction::new_rule_init(
9418 *rule_index,
9419 index,
9420 Some(*follow_state),
9421 ),
9422 );
9423 }
9424 actions.append(&mut outcome.actions);
9425 outcome.actions = actions;
9426 self.arena_prepend(&mut outcome.nodes, child_node);
9427 outcome
9428 }),
9429 );
9430 }
9431 }
9432 Transition::Atom { target, .. }
9433 | Transition::Range { target, .. }
9434 | Transition::Set { target, .. }
9435 | Transition::NotSet { target, .. }
9436 | Transition::Wildcard { target, .. } => {
9437 let symbol = self.token_type_at(index);
9438 if transition_data.matches(symbol, 1, atn.max_token_type()) {
9439 let next_index = self.consume_index(index, symbol);
9440 outcomes.extend(
9441 self.recognize_state(
9442 atn,
9443 RecognizeRequest {
9444 state_number: *target,
9445 stop_state,
9446 index: next_index,
9447 rule_start_index,
9448 decision_start_index: next_decision_start_index,
9449 init_action_rules,
9450 predicates,
9451 semantics,
9452 rule_args,
9453 member_actions,
9454 return_actions,
9455 local_int_arg,
9456 member_values: member_values.clone(),
9457 return_values: return_values.clone(),
9458 rule_alt_number: next_alt_number,
9459 track_alt_numbers,
9460 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
9461 precedence,
9462 depth: depth + 1,
9463 recovery_symbols: BTreeSet::new(),
9464 recovery_state: None,
9465 },
9466 visiting,
9467 memo,
9468 expected,
9469 )
9470 .into_iter()
9471 .map(|mut outcome| {
9472 prepend_decision(&mut outcome, decision);
9473 outcome.consumed_eof |= symbol == TOKEN_EOF;
9474 let token = self.arena_token_node(index, false);
9475 self.arena_prepend(&mut outcome.nodes, token);
9476 outcome
9477 }),
9478 );
9479 } else {
9480 let expected_symbols =
9481 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
9482 if expected_symbols.contains(&symbol) {
9483 continue;
9484 }
9485 expected.record_transition(index, transition, atn.max_token_type());
9486 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
9487 let before_recovery = outcomes.len();
9488 let recovery_request = request_template.clone();
9489 outcomes.extend(
9490 self.single_token_deletion_recovery(RecoveryRequest {
9491 atn,
9492 transition,
9493 expected_symbols: expected_symbols.clone(),
9494 target: *target,
9495 request: recovery_request.clone(),
9496 visiting,
9497 memo,
9498 expected,
9499 })
9500 .into_iter()
9501 .map(|mut outcome| {
9502 prepend_decision(&mut outcome, decision);
9503 outcome
9504 }),
9505 );
9506 if !state_is_left_recursive_rule(atn, state) {
9507 outcomes.extend(
9508 self.single_token_insertion_recovery(RecoveryRequest {
9509 atn,
9510 transition,
9511 expected_symbols: expected_symbols.clone(),
9512 target: *target,
9513 request: recovery_request.clone(),
9514 visiting,
9515 memo,
9516 expected,
9517 })
9518 .into_iter()
9519 .map(|mut outcome| {
9520 prepend_decision(&mut outcome, decision);
9521 outcome
9522 }),
9523 );
9524 }
9525 outcomes.extend(self.current_token_deletion_recovery(
9526 CurrentTokenDeletionRequest {
9527 atn,
9528 expected_symbols: expected_symbols.clone(),
9529 request: recovery_request.clone(),
9530 visiting,
9531 memo,
9532 expected,
9533 },
9534 ));
9535 if outcomes.len() == before_recovery {
9536 outcomes.extend(self.consuming_failure_fallback(
9537 ConsumingFailureFallback {
9538 atn,
9539 target: *target,
9540 request: recovery_request,
9541 symbol,
9542 expected_symbols,
9543 decision_start_index: next_decision_start_index,
9544 decision,
9545 },
9546 visiting,
9547 memo,
9548 expected,
9549 ));
9550 }
9551 }
9552 }
9553 }
9554 }
9555
9556 visiting.remove(&visit_key);
9557 self.record_prediction_diagnostics(atn, state, index, &outcomes);
9558 if matches!(
9559 self.prediction_mode,
9560 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9561 ) {
9562 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
9563 }
9564 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
9565 memo.insert(key, outcomes.clone());
9566 outcomes
9567 }
9568
9569 fn recognize_epsilon_or_action_step(
9572 &mut self,
9573 atn: &Atn,
9574 request: &RecognizeRequest<'_>,
9575 step: EpsilonActionStep,
9576 scratch: RecognizeScratch<'_>,
9577 ) -> Vec<RecognizeOutcome> {
9578 let RecognizeScratch {
9579 visiting,
9580 memo,
9581 expected,
9582 } = scratch;
9583 let action = step.action_rule_index.map(|rule_index| {
9584 ParserAction::new(
9585 step.source_state,
9586 rule_index,
9587 request.rule_start_index,
9588 self.rule_stop_token_index(request.index, request.consumed_eof),
9589 )
9590 });
9591 let next_member_values = if action.is_some() {
9592 member_values_after_action(
9593 step.source_state,
9594 request.member_actions,
9595 request.semantics,
9596 &request.member_values,
9597 )
9598 } else {
9599 request.member_values.clone()
9600 };
9601 let next_return_values = action.map_or_else(
9602 || request.return_values.clone(),
9603 |action| {
9604 return_values_after_action(
9605 step.source_state,
9606 action.rule_index(),
9607 request.return_actions,
9608 request.semantics,
9609 &request.return_values,
9610 )
9611 },
9612 );
9613
9614 self.recognize_state(
9615 atn,
9616 RecognizeRequest {
9617 state_number: step.target,
9618 stop_state: request.stop_state,
9619 index: request.index,
9620 rule_start_index: request.rule_start_index,
9621 decision_start_index: step.decision_start_index,
9622 init_action_rules: request.init_action_rules,
9623 predicates: request.predicates,
9624 semantics: request.semantics,
9625 rule_args: request.rule_args,
9626 member_actions: request.member_actions,
9627 return_actions: request.return_actions,
9628 local_int_arg: request.local_int_arg,
9629 member_values: next_member_values,
9630 return_values: next_return_values,
9631 rule_alt_number: step.alt_number,
9632 track_alt_numbers: request.track_alt_numbers,
9633 consumed_eof: request.consumed_eof,
9634 precedence: request.precedence,
9635 depth: request.depth + 1,
9636 recovery_symbols: step.recovery_symbols,
9637 recovery_state: step.recovery_state,
9638 },
9639 visiting,
9640 memo,
9641 expected,
9642 )
9643 .into_iter()
9644 .map(|mut outcome| {
9645 prepend_decision(&mut outcome, step.decision);
9646 if let Some(rule_index) = step.left_recursive_boundary {
9647 let boundary = self.arena_boundary_node(rule_index);
9648 self.arena_prepend(&mut outcome.nodes, boundary);
9649 }
9650 if let Some(action) = action {
9651 outcome.actions.insert(0, action);
9652 }
9653 outcome
9654 })
9655 .collect()
9656 }
9657
9658 fn token_type_at(&mut self, index: usize) -> i32 {
9663 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
9664 self.input.fill();
9665 }
9666 self.input.token_type_at_index(index)
9667 }
9668
9669 fn cached_state_expected_symbols(
9681 &mut self,
9682 atn: &Atn,
9683 state_number: usize,
9684 ) -> Rc<BTreeSet<i32>> {
9685 if let Some(cached) = self.state_expected_cache.get(&state_number) {
9686 return Rc::clone(cached);
9687 }
9688 let symbols = state_expected_symbols(atn, state_number);
9689 let entry = self.intern_recovery_symbols(symbols);
9690 self.state_expected_cache
9691 .insert(state_number, Rc::clone(&entry));
9692 entry
9693 }
9694
9695 fn cached_state_expected_token_set(
9696 &mut self,
9697 atn: &Atn,
9698 state_number: usize,
9699 ) -> Rc<TokenBitSet> {
9700 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
9701 return Rc::clone(cached);
9702 }
9703 let symbols = with_shared_atn_caches(atn, |cache| {
9707 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
9708 return Rc::clone(cached);
9709 }
9710 let symbols = Rc::new(state_expected_token_set(atn, state_number));
9711 cache
9712 .state_expected_tokens
9713 .insert(state_number, Rc::clone(&symbols));
9714 symbols
9715 });
9716 self.state_expected_token_cache
9717 .insert(state_number, Rc::clone(&symbols));
9718 symbols
9719 }
9720
9721 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
9722 if self.rule_stop_reach_cache.len() <= state_number {
9723 self.rule_stop_reach_cache
9724 .resize_with(atn.states().len().max(state_number + 1), || None);
9725 }
9726 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
9727 return reaches;
9728 }
9729 let reaches = with_shared_atn_caches(atn, |cache| {
9730 *cache
9731 .rule_stop_reach
9732 .entry(state_number)
9733 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
9734 });
9735 self.rule_stop_reach_cache[state_number] = Some(reaches);
9736 reaches
9737 }
9738
9739 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
9742 Rc::clone(&self.empty_recovery_symbols)
9743 }
9744
9745 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
9754 if set.is_empty() {
9755 return Rc::clone(&self.empty_recovery_symbols);
9756 }
9757 let candidate = Rc::new(set);
9758 match self.recovery_symbols_intern.get(&candidate) {
9759 Some(existing) => Rc::clone(existing),
9760 None => {
9761 self.recovery_symbols_intern
9762 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
9763 candidate
9764 }
9765 }
9766 }
9767
9768 fn cached_decision_lookahead(
9773 &mut self,
9774 atn: &Atn,
9775 state: AtnState<'_>,
9776 rule_stop_state: usize,
9777 ) -> Rc<DecisionLookahead> {
9778 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
9785 return Rc::clone(cached);
9786 }
9787 let entry = with_shared_atn_caches(atn, |cache| {
9788 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
9789 return Rc::clone(cached);
9790 }
9791 let mut entry = DecisionLookahead {
9792 transitions: Vec::with_capacity(state.transitions().len()),
9793 };
9794 for transition in &state.transitions() {
9795 entry.transitions.push(transition_first_set(
9796 atn,
9797 transition,
9798 rule_stop_state,
9799 &mut cache.first_set,
9800 ));
9801 }
9802 let entry = Rc::new(entry);
9803 cache
9804 .decision_lookahead
9805 .insert(state.state_number(), Rc::clone(&entry));
9806 entry
9807 });
9808 self.decision_lookahead_cache
9809 .insert(state.state_number(), Rc::clone(&entry));
9810 entry
9811 }
9812
9813 fn cached_rule_first_set(
9814 &mut self,
9815 atn: &Atn,
9816 target: usize,
9817 child_stop: usize,
9818 ) -> Rc<FirstSet> {
9819 if self.rule_first_set_cache.len() <= target {
9820 self.rule_first_set_cache
9821 .resize_with(atn.states().len().max(target + 1), || None);
9822 }
9823 if let Some(cached) = self
9824 .rule_first_set_cache
9825 .get(target)
9826 .and_then(Option::as_ref)
9827 {
9828 return Rc::clone(cached);
9829 }
9830 let first = with_shared_first_set_cache(atn, |cache| {
9831 rule_first_set(atn, target, child_stop, cache)
9832 });
9833 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
9834 first
9835 }
9836
9837 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
9838 let atn_key = SharedAtnCacheKey::for_atn(atn);
9839 if self.empty_cycle_cache_atn != Some(atn_key) {
9840 self.empty_cycle_cache.clear();
9841 self.empty_cycle_cache_atn = Some(atn_key);
9842 }
9843 if self.empty_cycle_cache.len() <= state_number {
9844 self.empty_cycle_cache
9845 .resize_with(atn.state_count().max(state_number + 1), || None);
9846 }
9847 if let Some(cached) = self.empty_cycle_cache[state_number] {
9848 return cached;
9849 }
9850 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
9851 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
9852 self.empty_cycle_cache[state_number] = Some(result);
9853 result
9854 }
9855
9856 fn empty_path_reaches_state(
9857 &mut self,
9858 atn: &Atn,
9859 state_number: usize,
9860 target_state: usize,
9861 visited: &mut FxHashSet<usize>,
9862 ) -> bool {
9863 if !visited.insert(state_number) {
9864 return false;
9865 }
9866 let Some(state) = atn.state(state_number) else {
9867 return false;
9868 };
9869 for transition in &state.transitions() {
9870 let kind = transition.kind();
9871 let target = transition.target();
9872 match kind {
9873 ParserTransitionKind::Atom
9874 | ParserTransitionKind::Range
9875 | ParserTransitionKind::Set
9876 | ParserTransitionKind::NotSet
9877 | ParserTransitionKind::Wildcard => {}
9878 ParserTransitionKind::Rule => {
9879 let rule_index = transition.arg0() as usize;
9880 let follow_state = transition.arg1() as usize;
9881 if target == target_state
9882 || self.empty_path_reaches_state(atn, target, target_state, visited)
9883 {
9884 return true;
9885 }
9886 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
9887 continue;
9888 };
9889 if self.cached_rule_first_set(atn, target, child_stop).nullable
9890 && (follow_state == target_state
9891 || self.empty_path_reaches_state(
9892 atn,
9893 follow_state,
9894 target_state,
9895 visited,
9896 ))
9897 {
9898 return true;
9899 }
9900 }
9901 ParserTransitionKind::Epsilon
9902 | ParserTransitionKind::Predicate
9903 | ParserTransitionKind::Action
9904 | ParserTransitionKind::Precedence => {
9905 if target == target_state
9906 || self.empty_path_reaches_state(atn, target, target_state, visited)
9907 {
9908 return true;
9909 }
9910 }
9911 }
9912 }
9913 false
9914 }
9915
9916 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
9919 match self.clean_memo_mode {
9920 CleanMemoMode::Promote => true,
9921 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
9922 CleanMemoMode::Sparse => {
9923 self.clean_memo_sparse_samples += 1;
9924 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
9925 return false;
9926 }
9927 self.clean_memo_sparse_samples = 0;
9928 self.clean_memo_mode = CleanMemoMode::Probe;
9929 self.clean_memo_probe_samples = 0;
9930 self.clean_memo_probe_repeats = 0;
9931 self.clean_memo_probe_seen.clear();
9932 self.observe_clean_memo_probe(key)
9933 }
9934 }
9935 }
9936
9937 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
9938 self.clean_memo_probe_samples += 1;
9939 if !self.clean_memo_probe_seen.insert(key.clone()) {
9940 self.clean_memo_probe_repeats += 1;
9941 }
9942 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
9943 self.clean_memo_mode = CleanMemoMode::Promote;
9944 self.clean_memo_probe_seen.clear();
9945 return true;
9946 }
9947 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
9948 self.clean_memo_mode = CleanMemoMode::Sparse;
9949 self.clean_memo_sparse_samples = 0;
9950 self.clean_memo_probe_seen.clear();
9951 return false;
9952 }
9953 true
9954 }
9955
9956 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
9958 self.input.get(index)
9959 }
9960
9961 fn token_id_at(&self, index: usize) -> Option<TokenId> {
9963 self.input.get_id(index)
9964 }
9965
9966 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
9967 let token = self
9968 .token_id_at(index)
9969 .expect("recognized token index must exist in the token store");
9970 let node = if error {
9971 ArenaRecognizedNode::ErrorToken { token }
9972 } else {
9973 ArenaRecognizedNode::Token { token }
9974 };
9975 self.recognition_arena.push_node(node)
9976 }
9977
9978 fn arena_missing_token_node(
9979 &mut self,
9980 token_type: i32,
9981 at_index: usize,
9982 text: String,
9983 ) -> RecognizedNodeId {
9984 let extra = self
9985 .recognition_arena
9986 .push_extra(RecognitionExtra::MissingToken {
9987 token_type,
9988 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
9989 text,
9990 });
9991 self.recognition_arena
9992 .push_node(ArenaRecognizedNode::MissingToken { extra })
9993 }
9994
9995 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
9996 let ArenaRuleSpec {
9997 rule_index,
9998 invoking_state,
9999 alt_number,
10000 start_index,
10001 stop_index,
10002 return_values,
10003 children,
10004 } = spec;
10005 let return_values = (!return_values.is_empty()).then(|| {
10006 self.recognition_arena
10007 .push_extra(RecognitionExtra::ReturnValues(return_values))
10008 });
10009 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
10010 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10011 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
10012 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
10013 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
10014 stop_index: stop_index
10015 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
10016 return_values,
10017 children,
10018 })
10019 }
10020
10021 fn arena_boundary_node(&mut self, rule_index: usize) -> RecognizedNodeId {
10022 self.recognition_arena
10023 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
10024 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10025 })
10026 }
10027
10028 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
10029 *sequence = self.recognition_arena.prepend(*sequence, node);
10030 }
10031
10032 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
10033 self.last_recognition_arena_root = root;
10034 self.last_recognition_arena_diagnostics = diagnostics;
10035 #[cfg(feature = "perf-counters")]
10036 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
10037 let stats = self.recognition_arena_stats();
10038 #[allow(clippy::print_stderr)]
10039 {
10040 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
10041 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
10042 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
10043 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
10044 eprintln!("perf recognition_links_total={}", stats.total_links);
10045 eprintln!("perf recognition_links_live={}", stats.live_links);
10046 eprintln!("perf recognition_links_dead={}", stats.dead_links);
10047 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
10048 eprintln!("perf recognition_extras_total={}", stats.total_extras);
10049 eprintln!("perf recognition_extras_live={}", stats.live_extras);
10050 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
10051 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
10052 }
10053 }
10054 }
10055
10056 fn reset_recognition_arena(&mut self) {
10057 self.recognition_arena.reset();
10058 self.last_recognition_arena_root = NodeSeqId::EMPTY;
10059 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
10060 }
10061
10062 fn current_visible_index(&mut self) -> usize {
10065 let index = self.input.index();
10066 self.input.seek(index);
10067 self.input.index()
10068 }
10069
10070 fn child_expected_reaches_clean_eof(
10073 &mut self,
10074 children: &[RecognizeOutcome],
10075 expected: &ExpectedTokens,
10076 ) -> bool {
10077 let Some(index) = expected.index else {
10078 return false;
10079 };
10080 self.token_type_at(index) == TOKEN_EOF
10081 && children
10082 .iter()
10083 .any(|child| child.diagnostics.is_empty() && child.index == index)
10084 }
10085
10086 fn previous_token_index(&self, index: usize) -> Option<usize> {
10093 self.input.previous_visible_token_index(index)
10094 }
10095
10096 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
10101 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
10102 Some(index)
10103 } else {
10104 self.previous_token_index(index)
10105 }
10106 }
10107
10108 #[must_use]
10125 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
10126 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
10127 self.rule_stop_token_index(current_index, consumed_eof)
10128 }
10129
10130 #[must_use]
10139 pub fn after_action_stop_index_for_tree(
10140 &mut self,
10141 tree: ParseTree,
10142 current_index: usize,
10143 ) -> Option<usize> {
10144 if let Some(stop) = self
10145 .node(tree)
10146 .as_rule()
10147 .and_then(crate::tree::RuleNodeView::stop_id)
10148 {
10149 return Some(stop.index());
10150 }
10151 self.after_action_stop_index(current_index)
10152 }
10153
10154 #[must_use]
10164 pub fn after_action_start_index_for_tree(
10165 &self,
10166 tree: ParseTree,
10167 fallback_index: usize,
10168 ) -> usize {
10169 if let Some(start) = self
10170 .node(tree)
10171 .as_rule()
10172 .and_then(crate::tree::RuleNodeView::start_id)
10173 {
10174 return start.index();
10175 }
10176 fallback_index
10177 }
10178
10179 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
10184 self.rule_stop_token_index(index, consumed_eof)
10185 .and_then(|token_index| self.token_id_at(token_index))
10186 }
10187
10188 fn predicate_failure_recovery(
10195 &mut self,
10196 request: PredicateFailureRecovery<'_>,
10197 ) -> RecognizeOutcome {
10198 let PredicateFailureRecovery {
10199 rule_index,
10200 index,
10201 message,
10202 member_values,
10203 return_values,
10204 rule_alt_number,
10205 } = request;
10206 let rule_name = self
10207 .rule_names()
10208 .get(rule_index)
10209 .map_or_else(|| rule_index.to_string(), Clone::clone);
10210 let diagnostic = diagnostic_for_token(
10211 self.token_at(index).as_ref(),
10212 format!("rule {rule_name} {message}"),
10213 );
10214 let mut reversed_nodes = NodeSeqId::EMPTY;
10215 let mut next_index = index;
10216 loop {
10217 let symbol = self.token_type_at(next_index);
10218 if symbol == TOKEN_EOF {
10219 break;
10220 }
10221 let error = self.arena_token_node(next_index, true);
10222 self.arena_prepend(&mut reversed_nodes, error);
10223 let after = self.consume_index(next_index, symbol);
10224 if after == next_index {
10225 break;
10226 }
10227 next_index = after;
10228 }
10229 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
10230 let diagnostics = self
10231 .recognition_arena
10232 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10233 RecognizeOutcome {
10234 index: next_index,
10235 consumed_eof: false,
10236 alt_number: rule_alt_number,
10237 member_values,
10238 return_values,
10239 diagnostics,
10240 decisions: Vec::new(),
10241 actions: Vec::new(),
10242 nodes,
10243 }
10244 }
10245
10246 fn parser_semantic_hook_result(
10249 &mut self,
10250 request: ParserSemanticHookRequest<'_>,
10251 ) -> Option<bool> {
10252 let ParserSemanticHookRequest {
10253 index,
10254 rule_index,
10255 pred_index,
10256 context,
10257 local_int_arg,
10258 member_values,
10259 } = request;
10260 let rule_name = self.rule_names().get(rule_index).cloned();
10261 self.input.seek(index);
10262 let input = &mut self.input;
10263 let semantic_hooks = &mut self.semantic_hooks;
10264 let mut ctx = ParserSemCtx {
10265 input,
10266 tree_storage: &self.tree,
10267 rule_index,
10268 coordinate_index: pred_index,
10269 rule_name,
10270 context,
10271 tree: None,
10272 local_int_arg,
10273 member_values,
10274 action: None,
10275 };
10276 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
10277 }
10278
10279 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
10284 if prior.is_empty() {
10285 return;
10286 }
10287 let mut merged = prior;
10288 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
10289 if !merged.contains(&coordinate) {
10290 merged.push(coordinate);
10291 }
10292 }
10293 self.unknown_predicate_hits = merged;
10294 }
10295
10296 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
10305 apply_unknown_predicate_policy(
10306 self.unknown_predicate_policy,
10307 rule_index,
10308 pred_index,
10309 &mut self.unknown_predicate_hits,
10310 )
10311 }
10312
10313 fn unknown_semantic_error(&self) -> Option<AntlrError> {
10316 use std::fmt::Write as _;
10317 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
10318 return None;
10319 }
10320 let mut message = String::new();
10321 for (rule_index, pred_index) in &self.unknown_predicate_hits {
10322 if !message.is_empty() {
10323 message.push_str("; ");
10324 }
10325 let _ = match self.rule_names().get(*rule_index) {
10326 Some(rule_name) => write!(
10327 message,
10328 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
10329 ),
10330 None => write!(
10331 message,
10332 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
10333 ),
10334 };
10335 }
10336 for (rule_index, source_state) in &self.unhandled_action_hits {
10337 if !message.is_empty() {
10338 message.push_str("; ");
10339 }
10340 let _ = match self.rule_names().get(*rule_index) {
10341 Some(rule_name) => write!(
10342 message,
10343 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
10344 ),
10345 None => write!(
10346 message,
10347 "unhandled semantic action: rule_index={rule_index} state={source_state}"
10348 ),
10349 };
10350 }
10351 Some(AntlrError::Unsupported(message))
10352 }
10353
10354 fn parser_semir_predicate_matches(
10362 &mut self,
10363 semantics: &ParserSemantics,
10364 predicate: &ParserSemanticPredicate,
10365 request: ParserSemanticHookRequest<'_>,
10366 ) -> bool {
10367 self.input.seek(request.index);
10368 let rule_name = self
10369 .data
10370 .rule_names()
10371 .get(request.rule_index)
10372 .map(String::as_str);
10373 let unknown_predicate_policy = self.unknown_predicate_policy;
10374 let mut ctx = ParserSemIrCtx {
10375 input: &mut self.input,
10376 tree_storage: &self.tree,
10377 semantic_hooks: &mut self.semantic_hooks,
10378 rule_index: request.rule_index,
10379 coordinate_index: request.pred_index,
10380 rule_name,
10381 context: request.context,
10382 local_int_arg: request.local_int_arg,
10383 member_values: request.member_values,
10384 invoked_predicates: &mut self.invoked_predicates,
10385 unknown_predicate_policy,
10386 unknown_predicate_hits: &mut self.unknown_predicate_hits,
10387 };
10388 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
10389 }
10390
10391 fn fast_parser_predicate_matches(
10392 &mut self,
10393 context: Option<FastPredicateContext<'_>>,
10394 transition: ParserTransition<'_>,
10395 index: usize,
10396 ) -> bool {
10397 let Some(context) = context else {
10398 return true;
10399 };
10400 let rule_index = transition.arg0() as usize;
10401 let pred_index = transition.arg1() as usize;
10402 let key = (index, rule_index, pred_index);
10403 if let Some(result) = self.fast_predicate_cache.get(&key) {
10404 return *result;
10405 }
10406 let result = self.parser_predicate_matches(PredicateEval {
10407 index,
10408 rule_index,
10409 pred_index,
10410 predicates: context.predicates,
10411 semantics: context.semantics,
10412 context: None,
10413 local_int_arg: None,
10414 member_values: context.member_values,
10415 });
10416 self.fast_predicate_cache.insert(key, result);
10417 result
10418 }
10419
10420 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
10421 let PredicateEval {
10422 index,
10423 rule_index,
10424 pred_index,
10425 predicates,
10426 semantics,
10427 context,
10428 local_int_arg,
10429 member_values,
10430 } = eval;
10431 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
10432 semantics
10433 .predicates
10434 .iter()
10435 .find(|predicate| {
10436 predicate.rule_index == rule_index && predicate.pred_index == pred_index
10437 })
10438 .map(|predicate| (semantics, predicate))
10439 }) {
10440 return self.parser_semir_predicate_matches(
10441 semantics,
10442 predicate,
10443 ParserSemanticHookRequest {
10444 index,
10445 rule_index,
10446 pred_index,
10447 context,
10448 local_int_arg,
10449 member_values,
10450 },
10451 );
10452 }
10453 let Some((_, _, predicate)) = predicates
10454 .iter()
10455 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
10456 else {
10457 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
10458 index,
10459 rule_index,
10460 pred_index,
10461 context,
10462 local_int_arg,
10463 member_values,
10464 }) {
10465 return result;
10466 }
10467 return self.unknown_predicate_result(rule_index, pred_index);
10468 };
10469 self.input.seek(index);
10470 match predicate {
10471 ParserPredicate::True => true,
10472 ParserPredicate::False => false,
10473 ParserPredicate::FalseWithMessage { .. } => false,
10474 ParserPredicate::Invoke { value } => {
10475 let key = (rule_index, pred_index);
10476 if !self.invoked_predicates.contains(&key) {
10477 self.invoked_predicates.push(key);
10478 use std::io::Write as _;
10479 let mut stdout = std::io::stdout().lock();
10480 let _ = writeln!(stdout, "eval={value}");
10481 }
10482 *value
10483 }
10484 ParserPredicate::LookaheadTextEquals { offset, text } => self
10485 .input
10486 .lt(*offset)
10487 .is_some_and(|token| Token::text(&token) == Some(*text)),
10488 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
10489 self.la(*offset) != *token_type
10490 }
10491 ParserPredicate::TokenPairAdjacent => {
10492 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
10493 return false;
10494 };
10495 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
10496 return false;
10497 };
10498 first + 1 == second
10499 }
10500 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
10501 .and_then(|context| {
10502 context
10503 .child_rules(&self.tree, self.input.token_store(), *rule_index)
10504 .next()
10505 .map(crate::tree::RuleNodeView::text)
10506 })
10507 .is_none_or(|actual| actual != *text),
10508 ParserPredicate::LocalIntEquals { value } => {
10509 local_int_arg.is_none_or(|(_, actual)| actual == *value)
10510 }
10511 ParserPredicate::LocalIntLessOrEqual { value } => {
10512 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
10513 }
10514 ParserPredicate::MemberModuloEquals {
10515 member,
10516 modulus,
10517 value,
10518 equals,
10519 } => {
10520 if *modulus == 0 {
10521 return false;
10522 }
10523 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
10524 (actual == *value) == *equals
10525 }
10526 ParserPredicate::MemberEquals {
10527 member,
10528 value,
10529 equals,
10530 } => {
10531 let actual = member_values.get(member).copied().unwrap_or_default();
10532 (actual == *value) == *equals
10533 }
10534 }
10535 }
10536
10537 fn parser_predicate_failure_message(
10539 &self,
10540 rule_index: usize,
10541 pred_index: usize,
10542 predicates: &[(usize, usize, ParserPredicate)],
10543 ) -> Option<&'static str> {
10544 predicates
10545 .iter()
10546 .find_map(|(rule, pred, predicate)| match predicate {
10547 ParserPredicate::FalseWithMessage { message }
10548 if *rule == rule_index && *pred == pred_index =>
10549 {
10550 Some(*message)
10551 }
10552 _ => None,
10553 })
10554 }
10555
10556 pub fn parser_semantic_ir_predicate_failure_message(
10559 &self,
10560 rule_index: usize,
10561 pred_index: usize,
10562 semantics: &ParserSemantics,
10563 ) -> Option<&'static str> {
10564 semantics
10565 .predicates
10566 .iter()
10567 .find(|predicate| {
10568 predicate.rule_index == rule_index && predicate.pred_index == pred_index
10569 })
10570 .and_then(|predicate| predicate.failure_message)
10571 }
10572
10573 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
10582 if symbol == TOKEN_EOF {
10583 return index;
10584 }
10585 self.input.next_visible_after(index)
10586 }
10587
10588 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
10591 let text = display_input_text(&self.input.text(start_index, error_index));
10592 diagnostic_for_token(
10593 self.token_at(error_index).as_ref(),
10594 format!("no viable alternative at input '{text}'"),
10595 )
10596 }
10597
10598 fn recovery_failure_diagnostic(
10601 &self,
10602 index: usize,
10603 decision_start_index: Option<usize>,
10604 expected_symbols: &BTreeSet<i32>,
10605 ) -> ParserDiagnostic {
10606 if expected_symbols.len() > 1 {
10607 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
10608 return self.no_viable_alternative(decision_start, index);
10609 }
10610 }
10611 diagnostic_for_token(
10612 self.token_at(index).as_ref(),
10613 format!(
10614 "mismatched input {} expecting {}",
10615 self.token_at(index)
10616 .as_ref()
10617 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
10618 self.expected_symbols_display(expected_symbols)
10619 ),
10620 )
10621 }
10622
10623 fn eof_rule_recovery_diagnostic(
10626 &self,
10627 index: usize,
10628 expected_symbols: &BTreeSet<i32>,
10629 expected: &ExpectedTokens,
10630 ) -> ParserDiagnostic {
10631 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
10632 &expected.symbols
10633 } else {
10634 expected_symbols
10635 };
10636 diagnostic_for_token(
10637 self.token_at(index).as_ref(),
10638 format!(
10639 "mismatched input {} expecting {}",
10640 self.token_at(index)
10641 .as_ref()
10642 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
10643 self.expected_symbols_display(symbols)
10644 ),
10645 )
10646 }
10647
10648 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
10654 let Some(stop) = stop else {
10655 return String::new();
10656 };
10657 let stop = if self
10658 .token_at(stop)
10659 .is_some_and(|token| token.token_type() == TOKEN_EOF)
10660 {
10661 let Some(previous) = self.previous_token_index(stop) else {
10662 return String::new();
10663 };
10664 previous
10665 } else {
10666 stop
10667 };
10668 self.input.text(start, stop)
10669 }
10670
10671 fn clear_prediction_diagnostics(&mut self) {
10674 self.prediction_diagnostics.clear();
10675 self.reported_prediction_diagnostics.clear();
10676 }
10677
10678 fn reset_per_parse_caches(&mut self) {
10702 self.rule_first_set_cache.clear();
10703 self.decision_lookahead_cache.clear();
10704 self.ll1_decision_cache.clear();
10705 self.fast_predicate_cache.clear();
10706 self.rule_stop_reach_cache.clear();
10707 self.clean_memo_mode = CleanMemoMode::Probe;
10708 self.clean_memo_probe_seen.clear();
10709 self.clean_memo_probe_samples = 0;
10710 self.clean_memo_probe_repeats = 0;
10711 self.clean_memo_sparse_samples = 0;
10712 self.recovery_symbols_intern.clear();
10713 self.state_expected_cache.clear();
10714 self.state_expected_token_cache.clear();
10715 }
10716
10717 fn record_prediction_diagnostics(
10720 &mut self,
10721 atn: &Atn,
10722 state: AtnState<'_>,
10723 start_index: usize,
10724 outcomes: &[RecognizeOutcome],
10725 ) {
10726 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
10727 return;
10728 }
10729 let Some(decision) = atn
10730 .decision_to_state()
10731 .iter()
10732 .position(|state_number| state_number == state.state_number())
10733 else {
10734 return;
10735 };
10736 let Some(rule_index) = state.rule_index() else {
10737 return;
10738 };
10739 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
10740 for outcome in outcomes
10741 .iter()
10742 .filter(|outcome| outcome.diagnostics.is_empty())
10743 {
10744 let Some(alt) = outcome.decisions.first() else {
10745 continue;
10746 };
10747 alts_by_end
10748 .entry(outcome.index)
10749 .or_default()
10750 .insert(alt + 1);
10751 }
10752 let Some((&end_index, ambig_alts)) = alts_by_end
10753 .iter()
10754 .filter(|(_, alts)| alts.len() > 1)
10755 .max_by_key(|(end, _)| *end)
10756 else {
10757 return;
10758 };
10759 let rule_name = self
10760 .rule_names()
10761 .get(rule_index)
10762 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
10763 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
10764 let input = display_input_text(&self.input.text(start_index, stop_index));
10765 let alts = ambig_alts
10766 .iter()
10767 .map(usize::to_string)
10768 .collect::<Vec<_>>()
10769 .join(", ");
10770 let key = (decision, start_index, format!("{alts}:{input}"));
10771 if !self.reported_prediction_diagnostics.insert(key) {
10772 return;
10773 }
10774 let start_diagnostic = diagnostic_for_token(
10775 self.token_at(start_index),
10776 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
10777 );
10778 let stop_diagnostic = diagnostic_for_token(
10779 self.token_at(stop_index),
10780 format!(
10781 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
10782 ),
10783 );
10784 self.prediction_diagnostics.push(start_diagnostic);
10785 self.prediction_diagnostics.push(stop_diagnostic);
10786 }
10787
10788 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
10790 expected_symbols_display(
10791 &state_expected_symbols(atn, state_number),
10792 self.vocabulary(),
10793 )
10794 }
10795
10796 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
10801 let state = usize::try_from(self.data().state()).unwrap_or(0);
10802 ExpectedTokenSet {
10803 symbols: state_expected_symbols(atn, state),
10804 }
10805 }
10806
10807 pub const fn set_bail_on_error(&mut self, bail: bool) {
10810 self.bail_on_error = bail;
10811 }
10812
10813 #[must_use]
10815 pub const fn bail_on_error(&self) -> bool {
10816 self.bail_on_error
10817 }
10818
10819 pub fn rule_invocation_stack(&self) -> Vec<String> {
10822 self.rule_context_stack
10823 .iter()
10824 .rev()
10825 .map(|frame| {
10826 self.data()
10827 .rule_names()
10828 .get(frame.rule_index)
10829 .cloned()
10830 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
10831 })
10832 .collect()
10833 }
10834
10835 pub fn active_invocation_states(&self) -> Vec<isize> {
10839 self.rule_context_stack
10840 .iter()
10841 .skip(1)
10842 .rev()
10843 .map(|frame| frame.invoking_state)
10844 .collect()
10845 }
10846
10847 pub fn token_display_at(&self, index: usize) -> Option<String> {
10849 self.token_at(index).map(|token| format!("{token}"))
10850 }
10851}
10852
10853impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
10854where
10855 S: TokenSource,
10856 H: SemanticHooks,
10857{
10858 fn parse_rule(
10859 &mut self,
10860 rule_index: usize,
10861 invoking_state: isize,
10862 precedence: i32,
10863 ) -> DirectAdaptiveParseResult<ParseTree> {
10864 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
10865 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
10866 )?;
10867 let stop_state = self
10868 .atn
10869 .rule_to_stop_state()
10870 .get(rule_index)
10871 .filter(|state| *state != usize::MAX)
10872 .ok_or(DirectAdaptiveParseControl::Fallback(
10873 DirectAdaptiveFallback::MissingAtn,
10874 ))?;
10875 let start_index = self.parser.current_visible_index();
10876 let mut context = ParserRuleContext::new(rule_index, invoking_state);
10877 if let Some(token) = self.parser.token_id_at(start_index) {
10878 self.parser.set_context_start(&mut context, token);
10879 }
10880 let mut state_number = start_state;
10881 let mut consumed_eof = false;
10882 while state_number != stop_state {
10883 self.step()?;
10884 let (transition, boundary) = self.next_transition(state_number, precedence)?;
10885 if boundary.is_some() {
10886 return Err(DirectAdaptiveParseControl::Fallback(
10887 DirectAdaptiveFallback::LeftRecursiveBoundary,
10888 ));
10889 }
10890 match transition.data() {
10891 Transition::Epsilon { target } => {
10892 state_number = target;
10893 }
10894 Transition::Precedence {
10895 target,
10896 precedence: transition_precedence,
10897 } => {
10898 if transition_precedence < precedence {
10899 return Err(DirectAdaptiveParseControl::Fallback(
10900 DirectAdaptiveFallback::Precedence,
10901 ));
10902 }
10903 state_number = target;
10904 }
10905 Transition::Rule {
10906 rule_index,
10907 follow_state,
10908 precedence: rule_precedence,
10909 ..
10910 } => {
10911 let child = self.parse_rule(
10912 rule_index,
10913 invoking_state_number(state_number),
10914 rule_precedence,
10915 )?;
10916 if self.parser.build_parse_trees {
10917 self.parser.tree.add_child(&mut context, child);
10918 }
10919 state_number = follow_state;
10920 }
10921 Transition::Atom { .. }
10922 | Transition::Range { .. }
10923 | Transition::Set { .. }
10924 | Transition::NotSet { .. }
10925 | Transition::Wildcard { .. } => {
10926 let (matched_eof, child) = self.consume_transition(transition)?;
10927 consumed_eof |= matched_eof;
10928 if let Some(child) = child {
10929 self.parser.tree.add_child(&mut context, child);
10930 }
10931 state_number = transition.target();
10932 }
10933 Transition::Predicate { .. } => {
10934 return Err(DirectAdaptiveParseControl::Fallback(
10935 DirectAdaptiveFallback::Predicate,
10936 ));
10937 }
10938 Transition::Action { .. } => {
10939 return Err(DirectAdaptiveParseControl::Fallback(
10940 DirectAdaptiveFallback::Action,
10941 ));
10942 }
10943 }
10944 }
10945
10946 let stop_index = self
10947 .parser
10948 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
10949 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
10950 self.parser.set_context_stop(&mut context, token);
10951 }
10952 Ok(self.parser.rule_node(context))
10953 }
10954
10955 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
10956 self.steps += 1;
10957 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
10958 return Err(DirectAdaptiveParseControl::Fallback(
10959 DirectAdaptiveFallback::StepLimit,
10960 ));
10961 }
10962 Ok(())
10963 }
10964
10965 fn next_transition(
10966 &mut self,
10967 state_number: usize,
10968 precedence: i32,
10969 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
10970 let state = self
10971 .atn
10972 .state(state_number)
10973 .ok_or(DirectAdaptiveParseControl::Fallback(
10974 DirectAdaptiveFallback::MissingAtn,
10975 ))?;
10976 if state.is_rule_stop() {
10977 return Err(DirectAdaptiveParseControl::Fallback(
10978 DirectAdaptiveFallback::RuleStop,
10979 ));
10980 }
10981 let transition_index =
10982 self.transition_index(state_number, state.transitions().len(), precedence)?;
10983 let transition = state.transitions().get(transition_index).ok_or(
10984 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
10985 )?;
10986 let boundary = match &transition.data() {
10987 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
10988 left_recursive_boundary(self.atn, state, *target)
10989 }
10990 _ => None,
10991 };
10992 Ok((transition, boundary))
10993 }
10994
10995 fn transition_index(
10996 &mut self,
10997 state_number: usize,
10998 transition_count: usize,
10999 precedence: i32,
11000 ) -> DirectAdaptiveParseResult<usize> {
11001 match transition_count {
11002 0 => Err(DirectAdaptiveParseControl::Fallback(
11003 DirectAdaptiveFallback::NoTransition,
11004 )),
11005 1 => Ok(0),
11006 _ => {
11007 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
11008 return Ok(alt);
11009 }
11010 let decision = self
11011 .decision_by_state
11012 .get(state_number)
11013 .and_then(|decision| *decision)
11014 .ok_or(DirectAdaptiveParseControl::Fallback(
11015 DirectAdaptiveFallback::UnknownDecision,
11016 ))?;
11017 let prediction = self
11018 .simulator
11019 .adaptive_predict_stream_info_with_precedence(
11020 decision,
11021 direct_precedence(precedence),
11022 &mut self.parser.input,
11023 )
11024 .map_err(|_| {
11025 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
11026 })?;
11027 if prediction.has_semantic_context {
11028 return Err(DirectAdaptiveParseControl::Fallback(
11029 DirectAdaptiveFallback::SemanticContext,
11030 ));
11031 }
11032 prediction
11033 .alt
11034 .checked_sub(1)
11035 .filter(|index| *index < transition_count)
11036 .ok_or(DirectAdaptiveParseControl::Fallback(
11037 DirectAdaptiveFallback::InvalidAlt,
11038 ))
11039 }
11040 }
11041 }
11042
11043 fn ll1_transition_index(
11044 &mut self,
11045 state_number: usize,
11046 transition_count: usize,
11047 ) -> DirectAdaptiveParseResult<Option<usize>> {
11048 let state = self
11049 .atn
11050 .state(state_number)
11051 .ok_or(DirectAdaptiveParseControl::Fallback(
11052 DirectAdaptiveFallback::MissingAtn,
11053 ))?;
11054 if state.precedence_rule_decision() {
11055 return Ok(None);
11056 }
11057 let Some(rule_stop) = state
11058 .rule_index()
11059 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
11060 else {
11061 return Ok(None);
11062 };
11063 let symbol = self.parser.input.la_token(1);
11064 let entry = self
11065 .parser
11066 .cached_decision_lookahead(self.atn, state, rule_stop);
11067 Ok(
11068 ll1_greedy_alt(&entry, symbol, state.non_greedy())
11069 .filter(|alt| *alt < transition_count),
11070 )
11071 }
11072
11073 fn consume_transition(
11074 &mut self,
11075 transition: ParserTransition<'_>,
11076 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
11077 let symbol = self.parser.input.la_token(1);
11078 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
11079 return Err(DirectAdaptiveParseControl::Fallback(
11080 DirectAdaptiveFallback::TokenMismatch,
11081 ));
11082 }
11083 let token = self
11084 .parser
11085 .input
11086 .lt_id(1)
11087 .ok_or(DirectAdaptiveParseControl::Fallback(
11088 DirectAdaptiveFallback::TokenMismatch,
11089 ))?;
11090 let matched_eof = symbol == TOKEN_EOF;
11091 if !matched_eof {
11092 self.parser.consume();
11093 }
11094 let child = self
11095 .parser
11096 .build_parse_trees
11097 .then(|| self.parser.terminal_tree(token));
11098 Ok((matched_eof, child))
11099 }
11100}
11101
11102fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
11105 if !state.precedence_rule_decision() {
11106 return None;
11107 }
11108 let target_state = atn.state(target)?;
11109 if target_state.kind() == AtnStateKind::LoopEnd {
11110 return None;
11111 }
11112 state.rule_index()
11113}
11114
11115fn next_alt_number(
11122 state: AtnState<'_>,
11123 transition_count: usize,
11124 transition_index: usize,
11125 current_alt_number: usize,
11126 track_alt_numbers: bool,
11127) -> usize {
11128 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
11129 return current_alt_number;
11130 }
11131 if matches!(
11132 state.kind(),
11133 AtnStateKind::Basic
11134 | AtnStateKind::BlockStart
11135 | AtnStateKind::PlusBlockStart
11136 | AtnStateKind::StarBlockStart
11137 | AtnStateKind::StarLoopEntry
11138 ) && !state.precedence_rule_decision()
11139 {
11140 return transition_index + 1;
11141 }
11142 current_alt_number
11143}
11144
11145fn invoking_state_number(state_number: usize) -> isize {
11148 isize::try_from(state_number).unwrap_or(isize::MAX)
11149}
11150
11151const fn packed_i32(value: u32) -> i32 {
11152 i32::from_le_bytes(value.to_le_bytes())
11153}
11154
11155fn direct_precedence(precedence: i32) -> usize {
11156 usize::try_from(precedence.max(0)).unwrap_or_default()
11157}
11158
11159fn token_input_display(token: &impl Token) -> String {
11160 format!("'{}'", token.text().unwrap_or("<EOF>"))
11161}
11162
11163fn display_input_text(text: &str) -> String {
11164 let mut out = String::new();
11165 for ch in text.chars() {
11166 match ch {
11167 '\n' => out.push_str("\\n"),
11168 '\r' => out.push_str("\\r"),
11169 '\t' => out.push_str("\\t"),
11170 other => out.push(other),
11171 }
11172 }
11173 out
11174}
11175
11176fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
11177 let (line, column) = token.map_or((0, 0), |token| (token.line(), token.column()));
11178 ParserDiagnostic {
11179 line,
11180 column,
11181 message,
11182 }
11183}
11184
11185#[allow(clippy::print_stderr)]
11187fn report_parser_diagnostics<'a>(diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>) {
11188 for diagnostic in diagnostics {
11189 eprintln!(
11190 "line {}:{} {}",
11191 diagnostic.line, diagnostic.column, diagnostic.message
11192 );
11193 }
11194}
11195
11196#[allow(clippy::print_stderr)]
11199fn report_generated_diagnostics(
11200 parser_diagnostics: &[ParserDiagnostic],
11201 token_errors: &[TokenSourceError],
11202) {
11203 let mut token_iter = token_errors.iter().peekable();
11210 for diagnostic in parser_diagnostics {
11211 while let Some(error) = token_iter.peek() {
11212 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
11213 eprintln!("line {}:{} {}", error.line, error.column, error.message);
11214 token_iter.next();
11215 } else {
11216 break;
11217 }
11218 }
11219 eprintln!(
11220 "line {}:{} {}",
11221 diagnostic.line, diagnostic.column, diagnostic.message
11222 );
11223 }
11224 for error in token_iter {
11225 eprintln!("line {}:{} {}", error.line, error.column, error.message);
11226 }
11227}
11228
11229#[allow(clippy::print_stderr)]
11232fn report_token_source_errors(errors: &[TokenSourceError]) {
11233 for error in errors {
11234 eprintln!("line {}:{} {}", error.line, error.column, error.message);
11235 }
11236}
11237
11238fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
11239 let items = symbols
11240 .iter()
11241 .map(|symbol| expected_symbol_display(*symbol, vocabulary))
11242 .collect::<Vec<_>>();
11243 if let [single] = items.as_slice() {
11244 return single.clone();
11245 }
11246 format!("{{{}}}", items.join(", "))
11247}
11248
11249fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
11250 if symbol == TOKEN_EOF {
11251 return "<EOF>".to_owned();
11252 }
11253 vocabulary.display_name(symbol)
11254}
11255
11256fn caller_follow_token_info_for_stream<S: TokenSource>(
11257 input: &mut CommonTokenStream<S>,
11258 index: usize,
11259) -> (i32, bool, bool) {
11260 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
11263 input.fill();
11264 }
11265 let token_type = input.token_type_at_index(index);
11266 let visible_channel = input.channel();
11267 let token = input.get(index);
11268 let is_boundary = token
11269 .as_ref()
11270 .and_then(Token::text)
11271 .is_some_and(is_caller_follow_boundary_text);
11272 let is_boundary_gap = token.as_ref().is_some_and(|token| {
11273 token.channel() != visible_channel || is_caller_follow_boundary_gap_text(token.text())
11274 });
11275 (token_type, is_boundary, is_boundary_gap)
11276}
11277
11278fn is_caller_follow_boundary_text(text: &str) -> bool {
11279 text.chars().any(|ch| ch == ';' || ch == '\n')
11280 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11281}
11282
11283fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
11284 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11285}
11286
11287fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
11291 let Some(rule_index) = state.rule_index() else {
11292 return false;
11293 };
11294 atn.rule_to_start_state()
11295 .get(rule_index)
11296 .and_then(|state_number| atn.state(state_number))
11297 .is_some_and(AtnState::left_recursive_rule)
11298}
11299
11300fn select_better_top_outcome(
11307 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
11308 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
11309 arena: &RecognitionArena,
11310) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
11311 match (first, second) {
11312 (Ok(first), Ok(second)) => {
11313 if arena.diagnostics(first.0.diagnostics).next().is_none() {
11314 Ok(first)
11315 } else {
11316 Ok(second)
11317 }
11318 }
11319 (Ok(first), Err(_)) => Ok(first),
11320 (Err(_), Ok(second)) => Ok(second),
11321 (Err(_), Err(second_expected)) => Err(second_expected),
11322 }
11323}
11324
11325fn select_best_fast_outcome(
11331 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
11332 prediction_mode: PredictionMode,
11333 caller_follow: Option<&TokenBitSet>,
11334 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
11335 arena: &RecognitionArena,
11336) -> Option<FastRecognizeOutcome> {
11337 let mut best = None;
11338 let mut best_caller_follow = None;
11339 for outcome in outcomes {
11340 if matches!(
11341 prediction_mode,
11342 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
11343 ) && outcome.diagnostics.is_empty()
11344 && let Some(follow) = caller_follow
11345 {
11346 let (token_type, is_boundary, _) = token_info_at(outcome.index);
11347 if is_boundary && follow.contains(token_type) {
11348 let replace =
11349 best_caller_follow
11350 .as_ref()
11351 .is_none_or(|existing: &FastRecognizeOutcome| {
11352 (outcome.index, outcome.consumed_eof)
11353 < (existing.index, existing.consumed_eof)
11354 });
11355 if replace {
11356 best_caller_follow = Some(outcome);
11357 }
11358 }
11359 }
11360 let Some(existing) = best else {
11361 best = Some(outcome);
11362 continue;
11363 };
11364 let outcome_position = (outcome.index, outcome.consumed_eof);
11365 let best_position = (existing.index, existing.consumed_eof);
11366 let better = match prediction_mode {
11367 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
11368 outcome_position,
11369 outcome.diagnostics,
11370 best_position,
11371 existing.diagnostics,
11372 arena,
11373 ),
11374 PredictionMode::Sll => outcome.index > existing.index,
11375 };
11376 best = Some(if better { outcome } else { existing });
11377 }
11378 let should_use_caller_follow =
11379 best_caller_follow
11380 .as_ref()
11381 .zip(best.as_ref())
11382 .is_some_and(|(candidate, selected)| {
11383 if !selected.diagnostics.is_empty() {
11384 return true;
11385 }
11386 candidate.index < selected.index
11387 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
11388 });
11389 if should_use_caller_follow {
11390 best_caller_follow
11391 } else {
11392 best
11393 }
11394}
11395
11396fn select_best_outcome(
11397 outcomes: impl Iterator<Item = RecognizeOutcome>,
11398 prediction_mode: PredictionMode,
11399 arena: &RecognitionArena,
11400) -> Option<RecognizeOutcome> {
11401 let outcomes = outcomes.collect::<Vec<_>>();
11402 let prefer_first_tie = outcomes
11403 .iter()
11404 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
11405 outcomes.into_iter().reduce(|best, outcome| {
11406 let outcome_position = (outcome.index, outcome.consumed_eof);
11407 let best_position = (best.index, best.consumed_eof);
11408 let better = match prediction_mode {
11409 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
11410 outcome_is_better(
11411 outcome_position,
11412 outcome.diagnostics,
11413 best_position,
11414 best.diagnostics,
11415 arena,
11416 ) || (!prefer_first_tie
11417 && outcome_position == best_position
11418 && arena.diagnostics_len(outcome.diagnostics)
11419 == arena.diagnostics_len(best.diagnostics)
11420 && arena.diagnostics_recovery_rank(outcome.diagnostics)
11421 == arena.diagnostics_recovery_rank(best.diagnostics)
11422 && (outcome.decisions < best.decisions
11423 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
11424 }
11425 PredictionMode::Sll => {
11426 outcome_position > best_position
11427 || (outcome_position == best_position
11428 && !prefer_first_tie
11429 && (outcome.decisions < best.decisions
11430 || (outcome.decisions == best.decisions
11431 && outcome_is_better(
11432 outcome_position,
11433 outcome.diagnostics,
11434 best_position,
11435 best.diagnostics,
11436 arena,
11437 ))))
11438 }
11439 };
11440 if better {
11441 return outcome;
11442 }
11443 best
11444 })
11445}
11446
11447fn transition_decision(
11454 atn: &Atn,
11455 state: AtnState<'_>,
11456 transition_count: usize,
11457 transition_index: usize,
11458 predicates: &[(usize, usize, ParserPredicate)],
11459) -> Option<usize> {
11460 if transition_count <= 1
11461 || state.precedence_rule_decision()
11462 || decision_reaches_unsupported_predicate(atn, state, predicates)
11463 {
11464 return None;
11465 }
11466 Some(transition_index)
11467}
11468
11469fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
11475 transition_count > 1
11476 && !matches!(
11477 state.kind(),
11478 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
11479 )
11480}
11481
11482fn record_no_viable_if_ambiguous(
11485 expected: &mut ExpectedTokens,
11486 decision_start_index: Option<usize>,
11487 index: usize,
11488) {
11489 if expected.index == Some(index) && expected.symbols.len() > 1 {
11490 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
11491 expected.record_no_viable(decision_start, index);
11492 }
11493 }
11494}
11495
11496const fn record_predicate_no_viable(
11499 expected: &mut ExpectedTokens,
11500 decision_start_index: Option<usize>,
11501 index: usize,
11502) {
11503 if let Some(decision_start) = decision_start_index {
11504 expected.record_no_viable(decision_start, index);
11505 }
11506}
11507
11508const fn no_viable_decision_start(
11510 decision_start_index: Option<usize>,
11511 index: usize,
11512) -> Option<usize> {
11513 match decision_start_index {
11514 Some(start) if index > start => Some(start),
11515 _ => None,
11516 }
11517}
11518
11519fn restore_expected(
11523 children: &[RecognizeOutcome],
11524 child_start_index: usize,
11525 expected: &mut ExpectedTokens,
11526 snapshot: ExpectedTokens,
11527 preserve_child_expected: bool,
11528) {
11529 if preserve_child_expected {
11530 return;
11531 }
11532 if children
11533 .iter()
11534 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
11535 {
11536 *expected = snapshot;
11537 }
11538}
11539
11540fn decision_reaches_unsupported_predicate(
11543 atn: &Atn,
11544 state: AtnState<'_>,
11545 predicates: &[(usize, usize, ParserPredicate)],
11546) -> bool {
11547 state.transitions().iter().any(|transition| {
11548 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
11549 })
11550}
11551
11552fn transition_reaches_unsupported_predicate(
11554 atn: &Atn,
11555 transition: ParserTransition<'_>,
11556 predicates: &[(usize, usize, ParserPredicate)],
11557 visited: &mut BTreeSet<usize>,
11558) -> bool {
11559 match &transition.data() {
11560 Transition::Predicate {
11561 rule_index,
11562 pred_index,
11563 ..
11564 } => !predicates
11565 .iter()
11566 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
11567 Transition::Epsilon { target }
11568 | Transition::Action { target, .. }
11569 | Transition::Rule { target, .. } => {
11570 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
11571 }
11572 Transition::Precedence { .. }
11573 | Transition::Atom { .. }
11574 | Transition::Range { .. }
11575 | Transition::Set { .. }
11576 | Transition::NotSet { .. }
11577 | Transition::Wildcard { .. } => false,
11578 }
11579}
11580
11581fn state_reaches_unsupported_predicate(
11583 atn: &Atn,
11584 state_number: usize,
11585 predicates: &[(usize, usize, ParserPredicate)],
11586 visited: &mut BTreeSet<usize>,
11587) -> bool {
11588 if !visited.insert(state_number) {
11589 return false;
11590 }
11591 let Some(state) = atn.state(state_number) else {
11592 return false;
11593 };
11594 state.transitions().iter().any(|transition| {
11595 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
11596 })
11597}
11598
11599fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
11601 if let Some(decision) = decision {
11602 outcome.decisions.insert(0, decision);
11603 }
11604}
11605
11606fn outcome_is_better(
11607 outcome_position: (usize, bool),
11608 outcome_diagnostics: DiagnosticSeqId,
11609 best_position: (usize, bool),
11610 best_diagnostics: DiagnosticSeqId,
11611 arena: &RecognitionArena,
11612) -> bool {
11613 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
11614 let best_len = arena.diagnostics_len(best_diagnostics);
11615 outcome_position > best_position
11616 || (outcome_position == best_position
11617 && (outcome_len < best_len
11618 || (outcome_len == best_len
11619 && arena.diagnostics_recovery_rank(outcome_diagnostics)
11620 < arena.diagnostics_recovery_rank(best_diagnostics))))
11621}
11622
11623fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
11624 if outcomes
11625 .iter()
11626 .any(|outcome| outcome.diagnostics.is_empty())
11627 {
11628 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
11629 }
11630}
11631
11632fn discard_recovered_outcomes_if_clean_path_exists(
11633 outcomes: &mut Vec<RecognizeOutcome>,
11634 arena: &RecognitionArena,
11635) {
11636 if outcomes
11637 .iter()
11638 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
11639 {
11640 return;
11641 }
11642 if outcomes
11643 .iter()
11644 .any(|outcome| outcome.diagnostics.is_empty())
11645 {
11646 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
11647 }
11648}
11649
11650fn outcome_has_rule_failure_diagnostic(
11653 outcome: &RecognizeOutcome,
11654 arena: &RecognitionArena,
11655) -> bool {
11656 arena
11657 .diagnostics(outcome.diagnostics)
11658 .any(|diagnostic| diagnostic.message.starts_with("rule "))
11659}
11660
11661fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
11675 if outcomes.len() < 2 {
11676 return;
11677 }
11678 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
11679 outcomes.retain(|outcome| {
11680 seen.insert((
11681 outcome.index,
11682 outcome.consumed_eof,
11683 arena.diagnostics_len(outcome.diagnostics),
11684 arena.diagnostics_recovery_rank(outcome.diagnostics),
11685 ))
11686 });
11687}
11688
11689const FAST_OUTCOME_INLINE_KEYS: usize = 8;
11690const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
11691const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
11692const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
11693
11694#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11695enum FastOutcomeDedupStrategy {
11696 Inline,
11697 Dense,
11698 Sparse,
11699}
11700
11701impl FastOutcomeDedupScratch {
11702 fn prepare_dense(&mut self, word_count: usize) {
11703 while let Some(word_index) = self.touched_dense_words.pop() {
11704 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
11705 }
11706 if self.dense_words.len() < word_count {
11707 self.dense_words.resize(word_count, 0);
11708 }
11709 }
11710}
11711
11712fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
11713 let first_index = outcomes.first()?.index;
11714 let (min_index, max_index) = outcomes[1..].iter().fold(
11715 (first_index, first_index),
11716 |(min_index, max_index), outcome| {
11717 (min_index.min(outcome.index), max_index.max(outcome.index))
11718 },
11719 );
11720 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
11721 let bit_count = index_span.checked_mul(2)?;
11722 let word_count =
11723 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
11724 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
11725 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
11726 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
11727 .then_some((min_index, word_count))
11728}
11729
11730#[cfg(feature = "perf-counters")]
11731fn record_clean_fast_outcome_dedup(
11732 strategy: FastOutcomeDedupStrategy,
11733 input_len: usize,
11734 output_len: usize,
11735 dense_words: usize,
11736) {
11737 let counter = match strategy {
11738 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
11739 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
11740 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
11741 };
11742 perf_counters::inc(
11743 &perf_counters::OUTCOME_DEDUPE_INPUTS,
11744 u64::try_from(input_len).unwrap_or(u64::MAX),
11745 );
11746 perf_counters::inc(
11747 &perf_counters::OUTCOME_DEDUPE_REMOVED,
11748 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
11749 );
11750 perf_counters::inc(counter, 1);
11751 perf_counters::inc(
11752 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
11753 u64::try_from(dense_words).unwrap_or(u64::MAX),
11754 );
11755}
11756
11757fn dedupe_clean_fast_outcomes(
11761 outcomes: &mut Vec<FastRecognizeOutcome>,
11762 scratch: &mut FastOutcomeDedupScratch,
11763) -> FastOutcomeDedupStrategy {
11764 #[cfg(feature = "perf-counters")]
11765 let input_len = outcomes.len();
11766 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
11767 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
11768 let mut inline_len = 0_usize;
11769 outcomes.retain(|outcome| {
11770 let key = (outcome.index, outcome.consumed_eof);
11771 if inline_keys[..inline_len].contains(&key) {
11772 return false;
11773 }
11774 inline_keys[inline_len] = key;
11775 inline_len += 1;
11776 true
11777 });
11778 #[cfg(feature = "perf-counters")]
11779 record_clean_fast_outcome_dedup(
11780 FastOutcomeDedupStrategy::Inline,
11781 input_len,
11782 outcomes.len(),
11783 0,
11784 );
11785 return FastOutcomeDedupStrategy::Inline;
11786 }
11787
11788 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
11789 scratch.prepare_dense(word_count);
11790 outcomes.retain(|outcome| {
11791 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
11792 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
11793 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
11794 let word = &mut scratch.dense_words[word_index];
11795 if *word & bit != 0 {
11796 return false;
11797 }
11798 if *word == 0 {
11799 scratch
11800 .touched_dense_words
11801 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
11802 }
11803 *word |= bit;
11804 true
11805 });
11806 #[cfg(feature = "perf-counters")]
11807 record_clean_fast_outcome_dedup(
11808 FastOutcomeDedupStrategy::Dense,
11809 input_len,
11810 outcomes.len(),
11811 word_count,
11812 );
11813 return FastOutcomeDedupStrategy::Dense;
11814 }
11815
11816 scratch.sparse_keys.clear();
11817 scratch.sparse_keys.reserve(outcomes.len());
11818 outcomes.retain(|outcome| {
11819 scratch
11820 .sparse_keys
11821 .insert((outcome.index, outcome.consumed_eof))
11822 });
11823 #[cfg(feature = "perf-counters")]
11824 record_clean_fast_outcome_dedup(
11825 FastOutcomeDedupStrategy::Sparse,
11826 input_len,
11827 outcomes.len(),
11828 0,
11829 );
11830 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
11831 scratch.sparse_keys = FxHashSet::default();
11832 }
11833 FastOutcomeDedupStrategy::Sparse
11834}
11835
11836fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
11839 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
11840 outcomes
11841 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
11842}
11843
11844fn compare_recognize_outcomes(
11845 left: &RecognizeOutcome,
11846 right: &RecognizeOutcome,
11847 arena: &RecognitionArena,
11848) -> Ordering {
11849 left.index
11850 .cmp(&right.index)
11851 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
11852 .then_with(|| left.alt_number.cmp(&right.alt_number))
11853 .then_with(|| left.member_values.cmp(&right.member_values))
11854 .then_with(|| left.return_values.cmp(&right.return_values))
11855 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
11856 .then_with(|| left.decisions.cmp(&right.decisions))
11857 .then_with(|| left.actions.cmp(&right.actions))
11858 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
11859}
11860
11861impl<S, H> Recognizer for BaseParser<S, H>
11862where
11863 S: TokenSource,
11864 H: SemanticHooks,
11865{
11866 fn data(&self) -> &RecognizerData {
11867 &self.data
11868 }
11869
11870 fn data_mut(&mut self) -> &mut RecognizerData {
11871 &mut self.data
11872 }
11873}
11874
11875impl<S, H> Parser for BaseParser<S, H>
11876where
11877 S: TokenSource,
11878 H: SemanticHooks,
11879{
11880 fn build_parse_trees(&self) -> bool {
11881 self.build_parse_trees
11882 }
11883
11884 fn set_build_parse_trees(&mut self, build: bool) {
11885 self.build_parse_trees = build;
11886 }
11887
11888 fn number_of_syntax_errors(&self) -> usize {
11889 Self::number_of_syntax_errors(self)
11890 }
11891
11892 fn report_diagnostic_errors(&self) -> bool {
11893 self.report_diagnostic_errors
11894 }
11895
11896 fn set_report_diagnostic_errors(&mut self, report: bool) {
11897 self.report_diagnostic_errors = report;
11898 }
11899
11900 fn prediction_mode(&self) -> PredictionMode {
11901 self.prediction_mode
11902 }
11903
11904 fn set_prediction_mode(&mut self, mode: PredictionMode) {
11905 self.prediction_mode = mode;
11906 }
11907}
11908
11909#[cfg(test)]
11910mod tests {
11911 use super::*;
11912 use crate::atn::parser::{
11913 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
11914 };
11915 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
11916 use crate::token::{HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError};
11917 use crate::token_stream::CommonTokenStream;
11918 use crate::tree::{NodeKind, ParseTreeStats};
11919 use crate::vocabulary::Vocabulary;
11920 use std::mem::size_of;
11921
11922 #[test]
11923 fn fx_hasher_write_matches_typed_methods_for_full_words() {
11924 let value: u64 = 0x0102_0304_0506_0708;
11931 let mut typed = FxHasher::default();
11932 typed.write_u64(value);
11933 let mut bytewise = FxHasher::default();
11934 bytewise.write(&value.to_le_bytes());
11935 assert_eq!(typed.finish(), bytewise.finish());
11936 }
11937
11938 #[derive(Clone, Debug)]
11939 struct TestToken {
11940 spec: TokenSpec,
11941 id: TokenId,
11942 source_name: String,
11943 }
11944
11945 impl TestToken {
11946 fn new(token_type: i32) -> Self {
11947 Self {
11948 spec: TokenSpec::explicit(token_type, ""),
11949 id: TokenId::try_from(0).expect("zero token ID"),
11950 source_name: String::new(),
11951 }
11952 }
11953
11954 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
11955 Self {
11956 spec: TokenSpec::eof(index, index, line, column),
11957 id: TokenId::try_from(0).expect("zero token ID"),
11958 source_name: source_name.to_owned(),
11959 }
11960 }
11961
11962 fn with_text(mut self, text: impl Into<String>) -> Self {
11963 self.spec.text = Some(text.into());
11964 self
11965 }
11966
11967 const fn with_channel(mut self, channel: i32) -> Self {
11968 self.spec.channel = channel;
11969 self
11970 }
11971
11972 const fn with_span(mut self, start: usize, stop: usize) -> Self {
11973 self.spec.start = start;
11974 self.spec.stop = stop;
11975 self.spec.start_byte = start;
11976 self.spec.stop_byte = match stop.checked_add(1) {
11977 Some(end) if end >= start => end,
11978 Some(_) | None => start,
11979 };
11980 self
11981 }
11982
11983 const fn with_position(mut self, line: usize, column: usize) -> Self {
11984 self.spec.line = line;
11985 self.spec.column = column;
11986 self
11987 }
11988
11989 fn set_token_index(&mut self, index: isize) {
11990 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
11991 }
11992 }
11993
11994 impl Token for TestToken {
11995 fn token_id(&self) -> TokenId {
11996 self.id
11997 }
11998
11999 fn token_type(&self) -> i32 {
12000 self.spec.token_type
12001 }
12002
12003 fn channel(&self) -> i32 {
12004 self.spec.channel
12005 }
12006
12007 fn start(&self) -> usize {
12008 self.spec.start
12009 }
12010
12011 fn stop(&self) -> usize {
12012 self.spec.stop
12013 }
12014
12015 fn line(&self) -> usize {
12016 self.spec.line
12017 }
12018
12019 fn column(&self) -> usize {
12020 self.spec.column
12021 }
12022
12023 fn text(&self) -> Option<&str> {
12024 self.spec.text.as_deref()
12025 }
12026
12027 fn source_name(&self) -> &str {
12028 &self.source_name
12029 }
12030
12031 fn start_byte(&self) -> usize {
12032 self.spec.start_byte
12033 }
12034
12035 fn stop_byte(&self) -> usize {
12036 self.spec.stop_byte
12037 }
12038 }
12039
12040 #[derive(Debug)]
12041 struct Source {
12042 tokens: Vec<TestToken>,
12043 index: usize,
12044 }
12045
12046 impl TokenSource for Source {
12047 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
12048 let token = self
12049 .tokens
12050 .get(self.index)
12051 .cloned()
12052 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
12053 self.index += 1;
12054 sink.push(token.spec)
12055 }
12056
12057 fn line(&self) -> usize {
12058 1
12059 }
12060
12061 fn column(&self) -> usize {
12062 self.index
12063 }
12064
12065 fn source_name(&self) -> &'static str {
12066 "parser-test"
12067 }
12068 }
12069
12070 fn mini_parser_data() -> RecognizerData {
12071 RecognizerData::new(
12072 "Mini.g4",
12073 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
12074 )
12075 .with_rule_names(["s"])
12076 }
12077
12078 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
12079 let data = mini_parser_data();
12080 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
12081 }
12082
12083 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
12084 where
12085 H: SemanticHooks,
12086 {
12087 BaseParser::with_semantic_hooks(
12088 CommonTokenStream::new(Source { tokens, index: 0 }),
12089 mini_parser_data(),
12090 hooks,
12091 )
12092 }
12093
12094 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
12095 builder.finish().expect("valid packed parser ATN")
12096 }
12097
12098 fn ordinary_star_loop_atn() -> Atn {
12099 let mut atn = ParserAtnBuilder::new(2);
12100 for (state_number, kind, rule_index) in [
12101 (0, AtnStateKind::RuleStart, 0),
12102 (1, AtnStateKind::StarLoopEntry, 0),
12103 (2, AtnStateKind::Basic, 0),
12104 (3, AtnStateKind::StarLoopBack, 0),
12105 (4, AtnStateKind::LoopEnd, 0),
12106 (5, AtnStateKind::Basic, 0),
12107 (6, AtnStateKind::RuleStop, 0),
12108 (7, AtnStateKind::RuleStart, 1),
12109 (8, AtnStateKind::Basic, 1),
12110 (9, AtnStateKind::RuleStop, 1),
12111 ] {
12112 assert_eq!(
12113 atn.add_state(kind, Some(rule_index))
12114 .expect("state")
12115 .index(),
12116 state_number
12117 );
12118 }
12119 atn.set_rule_to_start_state(vec![0, 7])
12120 .expect("rule start states");
12121 atn.set_rule_to_stop_state(vec![6, 9])
12122 .expect("rule stop states");
12123 atn.add_decision_state(1).expect("decision state");
12124 atn.set_loop_back_state(4, 3).expect("loop back state");
12125 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12126 .expect("transition");
12127 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12128 .expect("transition");
12129 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
12130 .expect("transition");
12131 atn.add_transition(
12132 2,
12133 ParserTransitionSpec::Rule {
12134 target: 7,
12135 rule_index: 1,
12136 follow_state: 3,
12137 precedence: 0,
12138 },
12139 )
12140 .expect("transition");
12141 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
12142 .expect("transition");
12143 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12144 .expect("transition");
12145 atn.add_transition(
12146 5,
12147 ParserTransitionSpec::Atom {
12148 target: 6,
12149 label: TOKEN_EOF,
12150 },
12151 )
12152 .expect("transition");
12153 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
12154 .expect("transition");
12155 atn.add_transition(
12156 8,
12157 ParserTransitionSpec::Atom {
12158 target: 9,
12159 label: 1,
12160 },
12161 )
12162 .expect("transition");
12163 finish_atn(atn)
12164 }
12165
12166 fn ambiguous_ordinary_star_loop_atn() -> Atn {
12168 let mut atn = ParserAtnBuilder::new(1);
12169 for (state_number, kind) in [
12170 (0, AtnStateKind::RuleStart),
12171 (1, AtnStateKind::StarLoopEntry),
12172 (2, AtnStateKind::StarBlockStart),
12173 (3, AtnStateKind::Basic),
12174 (4, AtnStateKind::BlockEnd),
12175 (5, AtnStateKind::StarLoopBack),
12176 (6, AtnStateKind::LoopEnd),
12177 (7, AtnStateKind::Basic),
12178 (8, AtnStateKind::RuleStop),
12179 ] {
12180 assert_eq!(
12181 atn.add_state(kind, Some(0)).expect("state").index(),
12182 state_number
12183 );
12184 }
12185 atn.set_rule_to_start_state(vec![0])
12186 .expect("rule start states");
12187 atn.set_rule_to_stop_state(vec![8])
12188 .expect("rule stop states");
12189 atn.set_end_state(2, 4).expect("block end state");
12190 atn.set_loop_back_state(6, 5).expect("loop back state");
12191 atn.add_decision_state(1).expect("decision state");
12192 atn.add_decision_state(2).expect("decision state");
12193 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12194 .expect("transition");
12195 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12196 .expect("transition");
12197 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
12198 .expect("transition");
12199 atn.add_transition(
12200 2,
12201 ParserTransitionSpec::Atom {
12202 target: 4,
12203 label: 1,
12204 },
12205 )
12206 .expect("transition");
12207 atn.add_transition(
12208 2,
12209 ParserTransitionSpec::Atom {
12210 target: 3,
12211 label: 1,
12212 },
12213 )
12214 .expect("transition");
12215 atn.add_transition(
12216 3,
12217 ParserTransitionSpec::Atom {
12218 target: 4,
12219 label: 1,
12220 },
12221 )
12222 .expect("transition");
12223 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12224 .expect("transition");
12225 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
12226 .expect("transition");
12227 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12228 .expect("transition");
12229 atn.add_transition(
12230 7,
12231 ParserTransitionSpec::Atom {
12232 target: 8,
12233 label: TOKEN_EOF,
12234 },
12235 )
12236 .expect("transition");
12237 finish_atn(atn)
12238 }
12239
12240 fn ordinary_plus_loop_atn() -> Atn {
12241 let mut atn = ParserAtnBuilder::new(2);
12242 for (state_number, kind, rule_index) in [
12243 (0, AtnStateKind::RuleStart, 0),
12244 (1, AtnStateKind::Basic, 0),
12245 (2, AtnStateKind::PlusLoopBack, 0),
12246 (3, AtnStateKind::LoopEnd, 0),
12247 (4, AtnStateKind::Basic, 0),
12248 (5, AtnStateKind::RuleStop, 0),
12249 (6, AtnStateKind::RuleStart, 1),
12250 (7, AtnStateKind::Basic, 1),
12251 (8, AtnStateKind::RuleStop, 1),
12252 ] {
12253 assert_eq!(
12254 atn.add_state(kind, Some(rule_index))
12255 .expect("state")
12256 .index(),
12257 state_number
12258 );
12259 }
12260 atn.set_rule_to_start_state(vec![0, 6])
12261 .expect("rule start states");
12262 atn.set_rule_to_stop_state(vec![5, 8])
12263 .expect("rule stop states");
12264 atn.add_decision_state(2).expect("decision state");
12265 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12266 .expect("transition");
12267 atn.add_transition(
12268 1,
12269 ParserTransitionSpec::Rule {
12270 target: 6,
12271 rule_index: 1,
12272 follow_state: 2,
12273 precedence: 0,
12274 },
12275 )
12276 .expect("transition");
12277 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
12278 .expect("transition");
12279 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12280 .expect("transition");
12281 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
12282 .expect("transition");
12283 atn.add_transition(
12284 4,
12285 ParserTransitionSpec::Atom {
12286 target: 5,
12287 label: TOKEN_EOF,
12288 },
12289 )
12290 .expect("transition");
12291 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12292 .expect("transition");
12293 atn.add_transition(
12294 7,
12295 ParserTransitionSpec::Atom {
12296 target: 8,
12297 label: 1,
12298 },
12299 )
12300 .expect("transition");
12301 finish_atn(atn)
12302 }
12303
12304 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
12305 let mut tokens = (0..count)
12306 .map(|_| TestToken::new(1).with_text("x"))
12307 .collect::<Vec<_>>();
12308 tokens.push(TestToken::eof("parser-test", count, 1, count));
12309 tokens
12310 }
12311
12312 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
12313 let mut atn = ParserAtnBuilder::new(2);
12314 assert_eq!(
12315 atn.add_state(AtnStateKind::RuleStart, Some(0))
12316 .expect("state")
12317 .index(),
12318 0
12319 );
12320 assert_eq!(
12321 atn.add_state(AtnStateKind::Basic, Some(0))
12322 .expect("state")
12323 .index(),
12324 1
12325 );
12326 assert_eq!(
12327 atn.add_state(AtnStateKind::Basic, Some(0))
12328 .expect("state")
12329 .index(),
12330 2
12331 );
12332 assert_eq!(
12333 atn.add_state(AtnStateKind::RuleStart, Some(1))
12334 .expect("state")
12335 .index(),
12336 3
12337 );
12338 atn.set_left_recursive_rule(3)
12339 .expect("left-recursive rule start");
12340 assert_eq!(
12341 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
12342 .expect("state")
12343 .index(),
12344 4
12345 );
12346 atn.set_precedence_rule_decision(4)
12347 .expect("precedence decision");
12348 assert_eq!(
12349 atn.add_state(AtnStateKind::Basic, Some(1))
12350 .expect("state")
12351 .index(),
12352 5
12353 );
12354 assert_eq!(
12355 atn.add_state(AtnStateKind::Basic, Some(1))
12356 .expect("state")
12357 .index(),
12358 6
12359 );
12360 assert_eq!(
12361 atn.add_state(AtnStateKind::LoopEnd, Some(1))
12362 .expect("state")
12363 .index(),
12364 7
12365 );
12366 assert_eq!(
12367 atn.add_state(AtnStateKind::RuleStop, Some(1))
12368 .expect("state")
12369 .index(),
12370 8
12371 );
12372 assert_eq!(
12373 atn.add_state(AtnStateKind::RuleStop, Some(0))
12374 .expect("state")
12375 .index(),
12376 9
12377 );
12378 atn.set_rule_to_start_state(vec![0, 3])
12379 .expect("rule start states");
12380 atn.set_rule_to_stop_state(vec![9, 8])
12381 .expect("rule stop states");
12382 atn.add_transition(
12383 1,
12384 ParserTransitionSpec::Rule {
12385 target: 3,
12386 rule_index: 1,
12387 follow_state: 2,
12388 precedence: 0,
12389 },
12390 )
12391 .expect("transition");
12392 atn.add_transition(
12393 2,
12394 ParserTransitionSpec::Atom {
12395 target: 9,
12396 label: caller_symbol,
12397 },
12398 )
12399 .expect("transition");
12400 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12401 .expect("transition");
12402 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
12403 .expect("transition");
12404 atn.add_transition(
12405 5,
12406 ParserTransitionSpec::Precedence {
12407 target: 6,
12408 precedence: 1,
12409 },
12410 )
12411 .expect("transition");
12412 atn.add_transition(
12413 6,
12414 ParserTransitionSpec::Atom {
12415 target: 4,
12416 label: 1,
12417 },
12418 )
12419 .expect("transition");
12420 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
12421 .expect("transition");
12422 finish_atn(atn)
12423 }
12424
12425 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
12426 let mut parser = mini_parser(vec![
12427 TestToken::new(symbol).with_text("lookahead"),
12428 TestToken::eof("parser-test", 1, 1, 1),
12429 ]);
12430 parser.rule_context_stack = vec![
12431 RuleContextFrame {
12432 rule_index: 0,
12433 invoking_state: -1,
12434 },
12435 RuleContextFrame {
12436 rule_index: 1,
12437 invoking_state: 1,
12438 },
12439 ];
12440 parser
12441 }
12442
12443 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
12444 let mut atn = ParserAtnBuilder::new(1);
12448 for (state, kind, rule) in [
12449 (0, AtnStateKind::RuleStart, 0),
12450 (1, AtnStateKind::StarLoopEntry, 0),
12451 (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),
12458 (9, AtnStateKind::RuleStop, 0),
12459 ] {
12460 assert_eq!(
12461 atn.add_state(kind, Some(rule)).expect("state").index(),
12462 state
12463 );
12464 if state == 0 {
12465 atn.set_left_recursive_rule(state)
12466 .expect("left-recursive rule start");
12467 } else if state == 1 {
12468 atn.set_precedence_rule_decision(state)
12469 .expect("precedence decision");
12470 }
12471 }
12472 atn.set_rule_to_start_state(vec![0])
12473 .expect("rule start states");
12474 atn.set_rule_to_stop_state(vec![9])
12475 .expect("rule stop states");
12476 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12477 .expect("ops");
12478 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
12479 .expect("exit");
12480 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12481 .expect("to shift");
12482 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
12483 .expect("to rel");
12484 atn.add_transition(
12485 3,
12486 ParserTransitionSpec::Precedence {
12487 target: 4,
12488 precedence: 2,
12489 },
12490 )
12491 .expect("shift prec");
12492 atn.add_transition(
12493 4,
12494 ParserTransitionSpec::Atom {
12495 target: 5,
12496 label: 1,
12497 },
12498 )
12499 .expect("shift first >");
12500 atn.add_transition(
12501 5,
12502 ParserTransitionSpec::Atom {
12503 target: 1,
12504 label: 1,
12505 },
12506 )
12507 .expect("shift second >");
12508 atn.add_transition(
12509 6,
12510 ParserTransitionSpec::Precedence {
12511 target: 7,
12512 precedence: 1,
12513 },
12514 )
12515 .expect("rel prec");
12516 atn.add_transition(
12517 7,
12518 ParserTransitionSpec::Atom {
12519 target: 1,
12520 label: 1,
12521 },
12522 )
12523 .expect("rel >");
12524 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
12525 .expect("loop end");
12526 finish_atn(atn)
12527 }
12528
12529 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
12530 let mut atn = ParserAtnBuilder::new(2);
12531 for (state, kind, rule) in [
12532 (0, AtnStateKind::RuleStart, 0),
12533 (1, AtnStateKind::StarLoopEntry, 0),
12534 (2, AtnStateKind::Basic, 0),
12535 (3, AtnStateKind::Basic, 0),
12536 (4, AtnStateKind::Basic, 0),
12537 (5, AtnStateKind::Basic, 0),
12538 (6, AtnStateKind::Basic, 0),
12539 (7, AtnStateKind::Basic, 0),
12540 (8, AtnStateKind::LoopEnd, 0),
12541 (9, AtnStateKind::RuleStop, 0),
12542 (10, AtnStateKind::RuleStart, 1),
12543 (11, AtnStateKind::Basic, 1),
12544 (12, AtnStateKind::RuleStop, 1),
12545 ] {
12546 assert_eq!(
12547 atn.add_state(kind, Some(rule)).expect("state").index(),
12548 state
12549 );
12550 if state == 0 {
12551 atn.set_left_recursive_rule(state)
12552 .expect("left-recursive rule start");
12553 } else if state == 1 {
12554 atn.set_precedence_rule_decision(state)
12555 .expect("precedence decision");
12556 }
12557 }
12558 atn.set_rule_to_start_state(vec![0, 10])
12559 .expect("rule start states");
12560 atn.set_rule_to_stop_state(vec![9, 12])
12561 .expect("rule stop states");
12562 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12563 .expect("ops");
12564 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
12565 .expect("exit");
12566 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12567 .expect("to shift");
12568 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
12569 .expect("to relational");
12570 atn.add_transition(
12571 3,
12572 ParserTransitionSpec::Precedence {
12573 target: 4,
12574 precedence: 2,
12575 },
12576 )
12577 .expect("shift precedence");
12578 atn.add_transition(
12579 4,
12580 ParserTransitionSpec::Rule {
12581 target: 10,
12582 rule_index: 1,
12583 follow_state: 5,
12584 precedence: 0,
12585 },
12586 )
12587 .expect("first shift token helper");
12588 atn.add_transition(
12589 5,
12590 ParserTransitionSpec::Atom {
12591 target: 1,
12592 label: 1,
12593 },
12594 )
12595 .expect("second shift token");
12596 atn.add_transition(
12597 6,
12598 ParserTransitionSpec::Precedence {
12599 target: 7,
12600 precedence: 1,
12601 },
12602 )
12603 .expect("relational precedence");
12604 atn.add_transition(
12605 7,
12606 ParserTransitionSpec::Atom {
12607 target: 1,
12608 label: 1,
12609 },
12610 )
12611 .expect("relational token");
12612 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
12613 .expect("loop end");
12614 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
12615 .expect("helper entry");
12616 atn.add_transition(
12617 11,
12618 ParserTransitionSpec::Atom {
12619 target: 12,
12620 label: 1,
12621 },
12622 )
12623 .expect("first shift token");
12624 finish_atn(atn)
12625 }
12626
12627 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
12628 let mut atn = ParserAtnBuilder::new(1);
12629 for (state, kind) in [
12630 (0, AtnStateKind::RuleStart),
12631 (1, AtnStateKind::StarLoopEntry),
12632 (2, AtnStateKind::Basic),
12633 (3, AtnStateKind::Basic),
12634 (4, AtnStateKind::Basic),
12635 (5, AtnStateKind::Basic),
12636 (6, AtnStateKind::Basic),
12637 (7, AtnStateKind::Basic),
12638 (8, AtnStateKind::Basic),
12639 (9, AtnStateKind::LoopEnd),
12640 (10, AtnStateKind::RuleStop),
12641 ] {
12642 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
12643 if state == 0 {
12644 atn.set_left_recursive_rule(state)
12645 .expect("left-recursive rule start");
12646 } else if state == 1 {
12647 atn.set_precedence_rule_decision(state)
12648 .expect("precedence decision");
12649 }
12650 }
12651 atn.set_rule_to_start_state(vec![0])
12652 .expect("rule start states");
12653 atn.set_rule_to_stop_state(vec![10])
12654 .expect("rule stop states");
12655 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12656 .expect("ops");
12657 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
12658 .expect("exit");
12659 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12660 .expect("to multi-token operator");
12661 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
12662 .expect("to predicate operator");
12663 atn.add_transition(
12664 3,
12665 ParserTransitionSpec::Precedence {
12666 target: 4,
12667 precedence: 2,
12668 },
12669 )
12670 .expect("multi-token precedence");
12671 atn.add_transition(
12672 4,
12673 ParserTransitionSpec::Atom {
12674 target: 5,
12675 label: 1,
12676 },
12677 )
12678 .expect("multi-token first");
12679 atn.add_transition(
12680 5,
12681 ParserTransitionSpec::Atom {
12682 target: 1,
12683 label: 1,
12684 },
12685 )
12686 .expect("multi-token second");
12687 atn.add_transition(
12688 6,
12689 ParserTransitionSpec::Precedence {
12690 target: 7,
12691 precedence: 2,
12692 },
12693 )
12694 .expect("predicate precedence");
12695 atn.add_transition(
12696 7,
12697 ParserTransitionSpec::Predicate {
12698 target: 8,
12699 rule_index: 0,
12700 pred_index: 0,
12701 context_dependent: false,
12702 },
12703 )
12704 .expect("operator predicate");
12705 atn.add_transition(
12706 8,
12707 ParserTransitionSpec::Atom {
12708 target: 1,
12709 label: 1,
12710 },
12711 )
12712 .expect("predicate single token");
12713 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
12714 .expect("loop end");
12715 finish_atn(atn)
12716 }
12717
12718 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
12719 let mut atn = ParserAtnBuilder::new(2);
12720 for (state, kind, rule) in [
12721 (0, AtnStateKind::RuleStart, 0),
12722 (1, AtnStateKind::StarLoopEntry, 0),
12723 (2, AtnStateKind::Basic, 0),
12724 (3, AtnStateKind::Basic, 0),
12725 (4, AtnStateKind::Basic, 0),
12726 (5, AtnStateKind::LoopEnd, 0),
12727 (6, AtnStateKind::RuleStop, 0),
12728 (7, AtnStateKind::RuleStart, 1),
12729 (8, AtnStateKind::RuleStop, 1),
12730 (9, AtnStateKind::Basic, 1),
12731 ] {
12732 assert_eq!(
12733 atn.add_state(kind, Some(rule)).expect("state").index(),
12734 state
12735 );
12736 if state == 0 {
12737 atn.set_left_recursive_rule(state)
12738 .expect("left-recursive rule start");
12739 } else if state == 1 {
12740 atn.set_precedence_rule_decision(state)
12741 .expect("precedence decision");
12742 }
12743 }
12744 atn.set_rule_to_start_state(vec![0, 7])
12745 .expect("rule start states");
12746 atn.set_rule_to_stop_state(vec![6, 8])
12747 .expect("rule stop states");
12748 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12749 .expect("transition");
12750 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
12751 .expect("transition");
12752 atn.add_transition(
12753 2,
12754 ParserTransitionSpec::Precedence {
12755 target: 3,
12756 precedence: 3,
12757 },
12758 )
12759 .expect("transition");
12760 atn.add_transition(
12761 3,
12762 ParserTransitionSpec::Rule {
12763 target: 7,
12764 rule_index: 1,
12765 follow_state: 4,
12766 precedence: 0,
12767 },
12768 )
12769 .expect("transition");
12770 atn.add_transition(
12771 4,
12772 ParserTransitionSpec::Atom {
12773 target: 1,
12774 label: 1,
12775 },
12776 )
12777 .expect("transition");
12778 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
12779 .expect("transition");
12780 atn.add_transition(
12781 7,
12782 ParserTransitionSpec::Precedence {
12783 target: 9,
12784 precedence: 1,
12785 },
12786 )
12787 .expect("transition");
12788 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
12789 .expect("transition");
12790 finish_atn(atn)
12791 }
12792
12793 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
12794 let mut atn = ParserAtnBuilder::new(2);
12795 for (state, kind) in [
12796 (0, AtnStateKind::RuleStart),
12797 (1, AtnStateKind::StarLoopEntry),
12798 (2, AtnStateKind::Basic),
12799 (3, AtnStateKind::Basic),
12800 (4, AtnStateKind::Basic),
12801 (5, AtnStateKind::LoopEnd),
12802 (6, AtnStateKind::RuleStop),
12803 ] {
12804 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
12805 if state == 0 {
12806 atn.set_left_recursive_rule(state)
12807 .expect("left-recursive rule start");
12808 } else if state == 1 {
12809 atn.set_precedence_rule_decision(state)
12810 .expect("precedence decision");
12811 }
12812 }
12813 atn.set_rule_to_start_state(vec![0])
12814 .expect("rule start states");
12815 atn.set_rule_to_stop_state(vec![6])
12816 .expect("rule stop states");
12817 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12818 .expect("transition");
12819 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
12820 .expect("transition");
12821 atn.add_transition(
12822 2,
12823 ParserTransitionSpec::Precedence {
12824 target: 3,
12825 precedence: 1,
12826 },
12827 )
12828 .expect("transition");
12829 atn.add_transition(
12830 3,
12831 ParserTransitionSpec::Predicate {
12832 target: 4,
12833 rule_index: 0,
12834 pred_index: 0,
12835 context_dependent: false,
12836 },
12837 )
12838 .expect("transition");
12839 atn.add_transition(
12840 4,
12841 ParserTransitionSpec::Atom {
12842 target: 1,
12843 label: 1,
12844 },
12845 )
12846 .expect("transition");
12847 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
12848 .expect("transition");
12849 finish_atn(atn)
12850 }
12851
12852 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
12853 let mut atn = ParserAtnBuilder::new(2);
12854 for (state, kind, rule) in [
12855 (0, AtnStateKind::RuleStart, 0),
12856 (1, AtnStateKind::Basic, 0),
12857 (2, AtnStateKind::Basic, 0),
12858 (3, AtnStateKind::Basic, 0),
12859 (4, AtnStateKind::RuleStop, 0),
12860 (5, AtnStateKind::RuleStart, 1),
12861 (6, AtnStateKind::StarLoopEntry, 1),
12862 (7, AtnStateKind::Basic, 1),
12863 (8, AtnStateKind::Basic, 1),
12864 (9, AtnStateKind::LoopEnd, 1),
12865 (10, AtnStateKind::RuleStop, 1),
12866 (11, AtnStateKind::RuleStart, 2),
12867 (12, AtnStateKind::RuleStop, 2),
12868 ] {
12869 assert_eq!(
12870 atn.add_state(kind, Some(rule)).expect("state").index(),
12871 state
12872 );
12873 if state == 5 {
12874 atn.set_left_recursive_rule(state)
12875 .expect("left-recursive rule start");
12876 } else if state == 6 {
12877 atn.set_precedence_rule_decision(state)
12878 .expect("precedence decision");
12879 }
12880 }
12881 atn.set_rule_to_start_state(vec![0, 5, 11])
12882 .expect("rule start states");
12883 atn.set_rule_to_stop_state(vec![4, 10, 12])
12884 .expect("rule stop states");
12885 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12886 .expect("transition");
12887 atn.add_transition(
12888 1,
12889 ParserTransitionSpec::Rule {
12890 target: 5,
12891 rule_index: 1,
12892 follow_state: 2,
12893 precedence: 0,
12894 },
12895 )
12896 .expect("transition");
12897 atn.add_transition(
12898 2,
12899 ParserTransitionSpec::Rule {
12900 target: 11,
12901 rule_index: 2,
12902 follow_state: 3,
12903 precedence: 0,
12904 },
12905 )
12906 .expect("transition");
12907 atn.add_transition(
12908 3,
12909 ParserTransitionSpec::Atom {
12910 target: 4,
12911 label: caller_symbol,
12912 },
12913 )
12914 .expect("transition");
12915 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12916 .expect("transition");
12917 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
12918 .expect("transition");
12919 atn.add_transition(
12920 7,
12921 ParserTransitionSpec::Precedence {
12922 target: 8,
12923 precedence: 1,
12924 },
12925 )
12926 .expect("transition");
12927 atn.add_transition(
12928 8,
12929 ParserTransitionSpec::Atom {
12930 target: 6,
12931 label: 1,
12932 },
12933 )
12934 .expect("transition");
12935 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
12936 .expect("transition");
12937 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
12938 .expect("transition");
12939 finish_atn(atn)
12940 }
12941
12942 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
12943 let mut atn = ParserAtnBuilder::new(2);
12944 for (state, kind, rule) in [
12945 (0, AtnStateKind::RuleStart, 0),
12946 (1, AtnStateKind::Basic, 0),
12947 (2, AtnStateKind::Basic, 0),
12948 (3, AtnStateKind::RuleStop, 0),
12949 (4, AtnStateKind::RuleStart, 1),
12950 (5, AtnStateKind::Basic, 1),
12951 (6, AtnStateKind::Basic, 1),
12952 (7, AtnStateKind::RuleStop, 1),
12953 (8, AtnStateKind::RuleStart, 2),
12954 (9, AtnStateKind::StarLoopEntry, 2),
12955 (10, AtnStateKind::Basic, 2),
12956 (11, AtnStateKind::Basic, 2),
12957 (12, AtnStateKind::LoopEnd, 2),
12958 (13, AtnStateKind::RuleStop, 2),
12959 ] {
12960 assert_eq!(
12961 atn.add_state(kind, Some(rule)).expect("state").index(),
12962 state
12963 );
12964 if state == 8 {
12965 atn.set_left_recursive_rule(state)
12966 .expect("left-recursive rule start");
12967 } else if state == 9 {
12968 atn.set_precedence_rule_decision(state)
12969 .expect("precedence decision");
12970 }
12971 }
12972 atn.set_rule_to_start_state(vec![0, 4, 8])
12973 .expect("rule start states");
12974 atn.set_rule_to_stop_state(vec![3, 7, 13])
12975 .expect("rule stop states");
12976 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12977 .expect("transition");
12978 atn.add_transition(
12979 1,
12980 ParserTransitionSpec::Rule {
12981 target: 4,
12982 rule_index: 1,
12983 follow_state: 2,
12984 precedence: 0,
12985 },
12986 )
12987 .expect("transition");
12988 atn.add_transition(
12989 2,
12990 ParserTransitionSpec::Atom {
12991 target: 3,
12992 label: caller_symbol,
12993 },
12994 )
12995 .expect("transition");
12996 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12997 .expect("transition");
12998 atn.add_transition(
12999 5,
13000 ParserTransitionSpec::Rule {
13001 target: 8,
13002 rule_index: 2,
13003 follow_state: 6,
13004 precedence: 0,
13005 },
13006 )
13007 .expect("transition");
13008 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13009 .expect("transition");
13010 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13011 .expect("transition");
13012 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
13013 .expect("transition");
13014 atn.add_transition(
13015 10,
13016 ParserTransitionSpec::Precedence {
13017 target: 11,
13018 precedence: 1,
13019 },
13020 )
13021 .expect("transition");
13022 atn.add_transition(
13023 11,
13024 ParserTransitionSpec::Atom {
13025 target: 9,
13026 label: 1,
13027 },
13028 )
13029 .expect("transition");
13030 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
13031 .expect("transition");
13032 finish_atn(atn)
13033 }
13034
13035 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
13036 let mut atn = ParserAtnBuilder::new(2);
13037 for (state, kind, rule) in [
13038 (0, AtnStateKind::RuleStart, 0),
13039 (1, AtnStateKind::Basic, 0),
13040 (2, AtnStateKind::Basic, 0),
13041 (3, AtnStateKind::RuleStop, 0),
13042 (4, AtnStateKind::RuleStart, 1),
13043 (5, AtnStateKind::StarLoopEntry, 1),
13044 (6, AtnStateKind::Basic, 1),
13045 (7, AtnStateKind::Basic, 1),
13046 (8, AtnStateKind::Basic, 1),
13047 (9, AtnStateKind::Basic, 1),
13048 (10, AtnStateKind::LoopEnd, 1),
13049 (11, AtnStateKind::RuleStop, 1),
13050 ] {
13051 assert_eq!(
13052 atn.add_state(kind, Some(rule)).expect("state").index(),
13053 state
13054 );
13055 if state == 4 {
13056 atn.set_left_recursive_rule(state)
13057 .expect("left-recursive rule start");
13058 } else if state == 5 {
13059 atn.set_precedence_rule_decision(state)
13060 .expect("precedence decision");
13061 }
13062 }
13063 atn.set_rule_to_start_state(vec![0, 4])
13064 .expect("rule start states");
13065 atn.set_rule_to_stop_state(vec![3, 11])
13066 .expect("rule stop states");
13067 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13068 .expect("transition");
13069 atn.add_transition(
13070 1,
13071 ParserTransitionSpec::Rule {
13072 target: 4,
13073 rule_index: 1,
13074 follow_state: 2,
13075 precedence: 0,
13076 },
13077 )
13078 .expect("transition");
13079 atn.add_transition(
13080 2,
13081 ParserTransitionSpec::Atom {
13082 target: 3,
13083 label: caller_symbol,
13084 },
13085 )
13086 .expect("transition");
13087 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13088 .expect("transition");
13089 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
13090 .expect("transition");
13091 atn.add_transition(
13092 6,
13093 ParserTransitionSpec::Precedence {
13094 target: 7,
13095 precedence: 1,
13096 },
13097 )
13098 .expect("transition");
13099 atn.add_transition(
13100 7,
13101 ParserTransitionSpec::Atom {
13102 target: 8,
13103 label: 1,
13104 },
13105 )
13106 .expect("transition");
13107 atn.add_transition(
13108 8,
13109 ParserTransitionSpec::Rule {
13110 target: 4,
13111 rule_index: 1,
13112 follow_state: 9,
13113 precedence: 2,
13114 },
13115 )
13116 .expect("transition");
13117 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
13118 .expect("transition");
13119 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
13120 .expect("transition");
13121 finish_atn(atn)
13122 }
13123
13124 #[test]
13125 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
13126 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
13127 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
13128
13129 let mut overlapping = parser_inside_left_recursive_callee(1);
13130 assert_eq!(
13131 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
13132 None
13133 );
13134
13135 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
13136 assert_eq!(
13137 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13138 Some(true)
13139 );
13140
13141 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
13142 assert_eq!(
13143 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13144 Some(false)
13145 );
13146
13147 assert_eq!(
13148 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13149 Some(true),
13150 "overlap results must not leak across ATNs"
13151 );
13152 }
13153
13154 #[test]
13155 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
13156 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
13157 let mut parser = mini_parser(vec![
13158 TestToken::new(1).with_text("operator"),
13159 TestToken::eof("parser-test", 1, 1, 1),
13160 ]);
13161 parser.rule_context_stack = vec![RuleContextFrame {
13162 rule_index: 0,
13163 invoking_state: -1,
13164 }];
13165
13166 assert_eq!(
13167 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13168 Some(true)
13169 );
13170 assert_eq!(
13171 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13172 Some(true),
13173 "cached operator lookahead must preserve the nullable prefix return path"
13174 );
13175 assert_eq!(
13176 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13177 Some(true),
13178 "the nullable child must use its rule-call precedence, not the caller precedence"
13179 );
13180 }
13181
13182 #[test]
13183 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
13184 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
13189 let mut parser = mini_parser(vec![
13190 TestToken::new(1).with_text(">"),
13191 TestToken::new(2).with_text("id"),
13192 TestToken::eof("parser-test", 1, 1, 1),
13193 ]);
13194 parser.rule_context_stack = vec![RuleContextFrame {
13195 rule_index: 0,
13196 invoking_state: -1,
13197 }];
13198
13199 assert_eq!(
13200 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13201 Some(true),
13202 "at low precedence relational `>` is a single-token operator"
13203 );
13204 assert_eq!(
13205 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
13206 Some(true),
13207 "relational remains single-token at its own precedence"
13208 );
13209 assert_eq!(
13210 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13211 None,
13212 "at shift precedence, bare `>` must not force enter"
13213 );
13214 }
13215
13216 #[test]
13217 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
13218 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
13219 let mut parser = mini_parser(vec![
13220 TestToken::new(1).with_text(">"),
13221 TestToken::new(2).with_text("id"),
13222 TestToken::eof("parser-test", 1, 1, 1),
13223 ]);
13224 parser.rule_context_stack = vec![RuleContextFrame {
13225 rule_index: 0,
13226 invoking_state: -1,
13227 }];
13228
13229 assert_eq!(
13230 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13231 Some(true),
13232 "the direct relational alternative remains a one-token operator"
13233 );
13234 assert_eq!(
13235 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13236 None,
13237 "a token matched in the helper rule must return to the second shift token"
13238 );
13239 }
13240
13241 #[test]
13242 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
13243 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
13244 let mut parser = mini_parser(vec![
13245 TestToken::new(1).with_text(">"),
13246 TestToken::new(2).with_text("id"),
13247 TestToken::eof("parser-test", 1, 1, 1),
13248 ]);
13249 parser.rule_context_stack = vec![RuleContextFrame {
13250 rule_index: 0,
13251 invoking_state: -1,
13252 }];
13253
13254 assert_eq!(
13255 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13256 None,
13257 "a predicate-gated single-token path must not be hidden by a multi-token path"
13258 );
13259 }
13260
13261 #[test]
13262 fn left_recursive_loop_defers_predicate_guarded_operator() {
13263 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
13264 let mut parser = mini_parser_with_hooks(
13265 vec![
13266 TestToken::new(1).with_text("operator"),
13267 TestToken::eof("parser-test", 1, 1, 1),
13268 ],
13269 RejectingPredicateHooks::default(),
13270 );
13271 parser.rule_context_stack = vec![RuleContextFrame {
13272 rule_index: 0,
13273 invoking_state: -1,
13274 }];
13275
13276 assert_eq!(
13277 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13278 None,
13279 "a false predicate must be evaluated before entering the operator alternative"
13280 );
13281 assert_eq!(
13282 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13283 None,
13284 "cached predicate-dependent lookahead must keep deferring"
13285 );
13286 }
13287
13288 #[test]
13289 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
13290 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
13291 let mut parser = parser_inside_left_recursive_callee(1);
13292
13293 assert_eq!(
13294 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
13295 None
13296 );
13297 assert_eq!(
13298 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
13299 None,
13300 "the cached overlap must preserve the nullable child return path"
13301 );
13302 }
13303
13304 #[test]
13305 fn left_recursive_loop_defers_through_nullable_parent_return() {
13306 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
13307 let mut parser = mini_parser(vec![
13308 TestToken::new(1).with_text("lookahead"),
13309 TestToken::eof("parser-test", 1, 1, 1),
13310 ]);
13311 parser.rule_context_stack = vec![
13312 RuleContextFrame {
13313 rule_index: 0,
13314 invoking_state: -1,
13315 },
13316 RuleContextFrame {
13317 rule_index: 1,
13318 invoking_state: 1,
13319 },
13320 RuleContextFrame {
13321 rule_index: 2,
13322 invoking_state: 5,
13323 },
13324 ];
13325
13326 assert_eq!(
13327 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
13328 None,
13329 "a nullable caller must unwind to its parent's consuming follow path"
13330 );
13331 assert_eq!(
13332 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
13333 None,
13334 "the caller-overlap cache must not retain a false negative"
13335 );
13336 }
13337
13338 #[test]
13339 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
13340 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
13341 let mut parser = mini_parser(vec![
13342 TestToken::new(1).with_text("lookahead"),
13343 TestToken::eof("parser-test", 1, 1, 1),
13344 ]);
13345 parser.rule_context_stack = vec![
13346 RuleContextFrame {
13347 rule_index: 0,
13348 invoking_state: -1,
13349 },
13350 RuleContextFrame {
13351 rule_index: 1,
13352 invoking_state: 1,
13353 },
13354 RuleContextFrame {
13355 rule_index: 1,
13356 invoking_state: 8,
13357 },
13358 ];
13359
13360 assert_eq!(
13361 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
13362 None,
13363 "a recursive operand return must preserve its parent caller context"
13364 );
13365 assert_eq!(
13366 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
13367 None,
13368 "the caller-overlap cache must preserve the loop-boundary return"
13369 );
13370 }
13371
13372 fn token_then_eof_atn() -> Atn {
13373 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13374 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, ]))
13390 .deserialize_parser()
13391 .expect("artificial parser ATN should deserialize")
13392 }
13393
13394 fn epsilon_cycle_atn() -> Atn {
13395 let mut atn = ParserAtnBuilder::new(1);
13396 for (state_number, kind) in [
13397 (0, AtnStateKind::RuleStart),
13398 (1, AtnStateKind::Basic),
13399 (2, AtnStateKind::RuleStop),
13400 ] {
13401 assert_eq!(
13402 atn.add_state(kind, Some(0)).expect("state").index(),
13403 state_number
13404 );
13405 }
13406 atn.set_rule_to_start_state(vec![0])
13407 .expect("rule start states");
13408 atn.set_rule_to_stop_state(vec![2])
13409 .expect("rule stop states");
13410 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13411 .expect("transition");
13412 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
13413 .expect("self-cycle transition");
13414 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13415 .expect("exit transition");
13416 finish_atn(atn)
13417 }
13418
13419 fn eof_then_action_atn() -> Atn {
13420 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13421 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, ]))
13437 .deserialize_parser()
13438 .expect("artificial parser ATN should deserialize")
13439 }
13440
13441 fn noop_action_then_token_then_eof_atn() -> Atn {
13442 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13443 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, ]))
13461 .deserialize_parser()
13462 .expect("artificial no-op action ATN should deserialize")
13463 }
13464
13465 fn two_alt_decision_atn() -> Atn {
13466 let mut atn = ParserAtnBuilder::new(2);
13467 assert_eq!(
13468 atn.add_state(AtnStateKind::RuleStart, Some(0))
13469 .expect("state")
13470 .index(),
13471 0
13472 );
13473 assert_eq!(
13474 atn.add_state(AtnStateKind::BlockStart, Some(0))
13475 .expect("state")
13476 .index(),
13477 1
13478 );
13479 assert_eq!(
13480 atn.add_state(AtnStateKind::Basic, Some(0))
13481 .expect("state")
13482 .index(),
13483 2
13484 );
13485 assert_eq!(
13486 atn.add_state(AtnStateKind::Basic, Some(0))
13487 .expect("state")
13488 .index(),
13489 3
13490 );
13491 assert_eq!(
13492 atn.add_state(AtnStateKind::BlockEnd, Some(0))
13493 .expect("state")
13494 .index(),
13495 4
13496 );
13497 assert_eq!(
13498 atn.add_state(AtnStateKind::RuleStop, Some(0))
13499 .expect("state")
13500 .index(),
13501 5
13502 );
13503 atn.set_rule_to_start_state(vec![0])
13504 .expect("rule start states");
13505 atn.set_rule_to_stop_state(vec![5])
13506 .expect("rule stop states");
13507 atn.add_decision_state(1).expect("decision state");
13508 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13509 .expect("transition");
13510 atn.add_transition(
13511 1,
13512 ParserTransitionSpec::Atom {
13513 target: 2,
13514 label: 1,
13515 },
13516 )
13517 .expect("transition");
13518 atn.add_transition(
13519 1,
13520 ParserTransitionSpec::Atom {
13521 target: 3,
13522 label: 2,
13523 },
13524 )
13525 .expect("transition");
13526 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
13527 .expect("transition");
13528 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
13529 .expect("transition");
13530 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13531 .expect("transition");
13532 finish_atn(atn)
13533 }
13534
13535 fn optional_then_b_eof_atn() -> Atn {
13538 let mut atn = ParserAtnBuilder::new(3);
13539 assert_eq!(
13540 atn.add_state(AtnStateKind::RuleStart, Some(0))
13541 .expect("state")
13542 .index(),
13543 0
13544 );
13545 assert_eq!(
13546 atn.add_state(AtnStateKind::BlockStart, Some(0))
13547 .expect("state")
13548 .index(),
13549 1
13550 );
13551 assert_eq!(
13552 atn.add_state(AtnStateKind::Basic, Some(0))
13553 .expect("state")
13554 .index(),
13555 2
13556 );
13557 assert_eq!(
13558 atn.add_state(AtnStateKind::Basic, Some(0))
13559 .expect("state")
13560 .index(),
13561 3
13562 );
13563 assert_eq!(
13564 atn.add_state(AtnStateKind::Basic, Some(0))
13565 .expect("state")
13566 .index(),
13567 4
13568 );
13569 assert_eq!(
13570 atn.add_state(AtnStateKind::RuleStop, Some(0))
13571 .expect("state")
13572 .index(),
13573 5
13574 );
13575 atn.set_rule_to_start_state(vec![0])
13576 .expect("rule start states");
13577 atn.set_rule_to_stop_state(vec![5])
13578 .expect("rule stop states");
13579 atn.add_decision_state(1).expect("decision state");
13580 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13581 .expect("transition");
13582 atn.add_transition(
13584 1,
13585 ParserTransitionSpec::Atom {
13586 target: 3,
13587 label: 1,
13588 },
13589 )
13590 .expect("transition");
13591 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
13592 .expect("transition");
13593 atn.add_transition(
13595 3,
13596 ParserTransitionSpec::Atom {
13597 target: 4,
13598 label: 2,
13599 },
13600 )
13601 .expect("transition");
13602 atn.add_transition(
13603 4,
13604 ParserTransitionSpec::Atom {
13605 target: 5,
13606 label: TOKEN_EOF,
13607 },
13608 )
13609 .expect("transition");
13610 finish_atn(atn)
13611 }
13612
13613 #[test]
13614 fn sync_decision_deletes_only_a_single_token() {
13615 let atn = optional_then_b_eof_atn();
13623
13624 let mut single = mini_parser(vec![
13625 TestToken::new(3).with_text("c"),
13626 TestToken::new(2).with_text("b"),
13627 TestToken::eof("parser-test", 1, 2, 2),
13628 ]);
13629 single.rule_context_stack = vec![RuleContextFrame {
13630 rule_index: 0,
13631 invoking_state: 0,
13632 }];
13633 let children = single
13634 .sync_decision(&atn, 1, true, false)
13635 .expect("single extraneous token recovers");
13636 assert_eq!(children.len(), 1);
13637 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
13638 assert_eq!(single.number_of_syntax_errors(), 1);
13639 assert_eq!(single.la(1), 2);
13641
13642 let mut double = mini_parser(vec![
13643 TestToken::new(3).with_text("c"),
13644 TestToken::new(3).with_text("c"),
13645 TestToken::new(2).with_text("b"),
13646 TestToken::eof("parser-test", 1, 3, 3),
13647 ]);
13648 double.rule_context_stack = vec![RuleContextFrame {
13649 rule_index: 0,
13650 invoking_state: 0,
13651 }];
13652 let result = double.sync_decision(&atn, 1, true, false);
13653 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
13658 match error {
13659 AntlrError::ParserError { message, .. } => {
13660 assert!(message.starts_with("mismatched input"), "got: {message}");
13661 }
13662 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
13663 }
13664 assert_eq!(double.la(1), 3);
13665 }
13666
13667 fn star_loop_then_eof_atn() -> Atn {
13671 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13672 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,
13673 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,
13674 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,
13675 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
13676 ]))
13677 .deserialize_parser()
13678 .expect("star-loop-then-EOF ATN should deserialize")
13679 }
13680
13681 fn plus_loop_with_recovering_body_atn() -> Atn {
13687 let mut atn = ParserAtnBuilder::new(2);
13688 assert_eq!(
13689 atn.add_state(AtnStateKind::RuleStart, Some(0))
13690 .expect("state")
13691 .index(),
13692 0
13693 );
13694 assert_eq!(
13695 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
13696 .expect("state")
13697 .index(),
13698 1
13699 );
13700 assert_eq!(
13701 atn.add_state(AtnStateKind::Basic, Some(0))
13702 .expect("state")
13703 .index(),
13704 2
13705 );
13706 assert_eq!(
13707 atn.add_state(AtnStateKind::BlockEnd, Some(0))
13708 .expect("state")
13709 .index(),
13710 3
13711 );
13712 assert_eq!(
13713 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
13714 .expect("state")
13715 .index(),
13716 4
13717 );
13718 assert_eq!(
13719 atn.add_state(AtnStateKind::LoopEnd, Some(0))
13720 .expect("state")
13721 .index(),
13722 5
13723 );
13724 assert_eq!(
13725 atn.add_state(AtnStateKind::RuleStop, Some(0))
13726 .expect("state")
13727 .index(),
13728 6
13729 );
13730 assert_eq!(
13731 atn.add_state(AtnStateKind::RuleStart, Some(1))
13732 .expect("state")
13733 .index(),
13734 7
13735 );
13736 assert_eq!(
13737 atn.add_state(AtnStateKind::Basic, Some(1))
13738 .expect("state")
13739 .index(),
13740 8
13741 );
13742 assert_eq!(
13743 atn.add_state(AtnStateKind::RuleStop, Some(1))
13744 .expect("state")
13745 .index(),
13746 9
13747 );
13748 atn.set_rule_to_start_state(vec![0, 7])
13749 .expect("rule start states");
13750 atn.set_rule_to_stop_state(vec![6, 9])
13751 .expect("rule stop states");
13752 atn.set_end_state(1, 3).expect("block end state");
13753 atn.set_loop_back_state(5, 4).expect("loop back state");
13754 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13755 .expect("transition");
13756 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13757 .expect("transition");
13758 atn.add_transition(
13759 2,
13760 ParserTransitionSpec::Rule {
13761 target: 7,
13762 rule_index: 1,
13763 follow_state: 3,
13764 precedence: 0,
13765 },
13766 )
13767 .expect("transition");
13768 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
13769 .expect("transition");
13770 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
13771 .expect("transition");
13772 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13773 .expect("transition");
13774 atn.add_transition(
13775 5,
13776 ParserTransitionSpec::Atom {
13777 target: 6,
13778 label: 2,
13779 },
13780 )
13781 .expect("transition");
13782 atn.add_transition(
13783 7,
13784 ParserTransitionSpec::Atom {
13785 target: 8,
13786 label: 1,
13787 },
13788 )
13789 .expect("transition");
13790 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
13791 .expect("transition");
13792 finish_atn(atn)
13793 }
13794
13795 #[test]
13796 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
13797 let atn = plus_loop_with_recovering_body_atn();
13798 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
13799
13800 let error = parser
13801 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
13802 .expect_err("EOF recovery should report a bounded mismatch");
13803
13804 let AntlrError::ParserError { message, .. } = error else {
13805 panic!("expected ParserError, got {error:?}");
13806 };
13807 assert_eq!(message, "mismatched input '<EOF>' expecting {'x', 2}");
13808 assert_eq!(parser.number_of_syntax_errors(), 1);
13809 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
13810 }
13811
13812 #[test]
13813 fn sync_decision_deletes_token_before_eof_at_loop_back() {
13814 let atn = star_loop_then_eof_atn();
13820 let mut parser = mini_parser(vec![
13821 TestToken::new(2).with_text("c"),
13822 TestToken::eof("parser-test", 1, 1, 1),
13823 ]);
13824 parser.rule_context_stack = vec![RuleContextFrame {
13825 rule_index: 0,
13826 invoking_state: 0,
13827 }];
13828 let children = parser
13829 .sync_decision(&atn, 5, true, false)
13830 .expect("single token before EOF recovers");
13831 assert_eq!(children.len(), 1);
13832 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
13833 assert_eq!(parser.number_of_syntax_errors(), 1);
13834 assert_eq!(
13835 parser.la(1),
13836 TOKEN_EOF,
13837 "EOF is left for the rule's EOF match"
13838 );
13839 }
13840
13841 #[test]
13842 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
13843 let atn = star_loop_then_eof_atn();
13848 let mut parser = mini_parser(vec![
13849 TestToken::new(2).with_text("c"),
13850 TestToken::new(2).with_text("c"),
13851 TestToken::eof("parser-test", 1, 2, 2),
13852 ]);
13853 parser.rule_context_stack = vec![RuleContextFrame {
13854 rule_index: 0,
13855 invoking_state: 0,
13856 }];
13857 let error = parser
13858 .sync_decision(&atn, 5, true, false)
13859 .expect_err("two tokens at the loop entry must not be deleted");
13860 match error {
13861 AntlrError::ParserError { message, .. } => {
13862 assert!(message.starts_with("mismatched input"), "got: {message}");
13863 }
13864 other => panic!("expected mismatched-input ParserError, got {other:?}"),
13865 }
13866 assert_eq!(
13867 parser.la(1),
13868 2,
13869 "nothing consumed; cursor still on first `c`"
13870 );
13871 }
13872
13873 #[test]
13874 fn sync_decision_consumes_until_eof_at_loop_back() {
13875 let atn = star_loop_then_eof_atn();
13881 let mut parser = mini_parser(vec![
13882 TestToken::new(2).with_text("c"),
13883 TestToken::new(2).with_text("c"),
13884 TestToken::eof("parser-test", 1, 2, 2),
13885 ]);
13886 parser.rule_context_stack = vec![RuleContextFrame {
13887 rule_index: 0,
13888 invoking_state: 0,
13889 }];
13890 let children = parser
13891 .sync_decision(&atn, 5, false, true)
13892 .expect("loop-back multi-token deletion recovers onto EOF");
13893 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
13894 assert!(
13895 children
13896 .iter()
13897 .all(|child| parser.node(*child).kind() == NodeKind::Error)
13898 );
13899 assert_eq!(parser.number_of_syntax_errors(), 1);
13900 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
13901 }
13902
13903 fn predicate_after_token_atn() -> Atn {
13904 let mut atn = ParserAtnBuilder::new(2);
13905 assert_eq!(
13906 atn.add_state(AtnStateKind::RuleStart, Some(0))
13907 .expect("state")
13908 .index(),
13909 0
13910 );
13911 assert_eq!(
13912 atn.add_state(AtnStateKind::Basic, Some(0))
13913 .expect("state")
13914 .index(),
13915 1
13916 );
13917 assert_eq!(
13918 atn.add_state(AtnStateKind::Basic, Some(0))
13919 .expect("state")
13920 .index(),
13921 2
13922 );
13923 assert_eq!(
13924 atn.add_state(AtnStateKind::Basic, Some(0))
13925 .expect("state")
13926 .index(),
13927 3
13928 );
13929 assert_eq!(
13930 atn.add_state(AtnStateKind::RuleStop, Some(0))
13931 .expect("state")
13932 .index(),
13933 4
13934 );
13935 atn.set_rule_to_start_state(vec![0])
13936 .expect("rule start states");
13937 atn.set_rule_to_stop_state(vec![4])
13938 .expect("rule stop states");
13939 atn.add_transition(
13940 0,
13941 ParserTransitionSpec::Atom {
13942 target: 1,
13943 label: 1,
13944 },
13945 )
13946 .expect("transition");
13947 atn.add_transition(
13948 1,
13949 ParserTransitionSpec::Predicate {
13950 target: 2,
13951 rule_index: 0,
13952 pred_index: 0,
13953 context_dependent: false,
13954 },
13955 )
13956 .expect("transition");
13957 atn.add_transition(
13958 2,
13959 ParserTransitionSpec::Atom {
13960 target: 3,
13961 label: 2,
13962 },
13963 )
13964 .expect("transition");
13965 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
13966 .expect("transition");
13967 finish_atn(atn)
13968 }
13969
13970 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
13971 let mut atn = ParserAtnBuilder::new(1);
13972 for (state_number, kind) in [
13973 (0, AtnStateKind::RuleStart),
13974 (1, AtnStateKind::BlockStart),
13975 (2, AtnStateKind::Basic),
13976 (3, AtnStateKind::Basic),
13977 (4, AtnStateKind::Basic),
13978 (5, AtnStateKind::Basic),
13979 (6, AtnStateKind::BlockEnd),
13980 (7, AtnStateKind::RuleStop),
13981 ] {
13982 assert_eq!(
13983 atn.add_state(kind, Some(0)).expect("state").index(),
13984 state_number
13985 );
13986 }
13987 atn.set_rule_to_start_state(vec![0])
13988 .expect("rule start states");
13989 atn.set_rule_to_stop_state(vec![7])
13990 .expect("rule stop states");
13991 atn.add_decision_state(1).expect("decision state");
13992 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13993 .expect("transition");
13994 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13995 .expect("transition");
13996 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
13997 .expect("transition");
13998 atn.add_transition(
13999 2,
14000 ParserTransitionSpec::Predicate {
14001 target: 4,
14002 rule_index: 0,
14003 pred_index: pred_indexes[0],
14004 context_dependent: false,
14005 },
14006 )
14007 .expect("transition");
14008 atn.add_transition(
14009 3,
14010 ParserTransitionSpec::Predicate {
14011 target: 5,
14012 rule_index: 0,
14013 pred_index: pred_indexes[1],
14014 context_dependent: false,
14015 },
14016 )
14017 .expect("transition");
14018 atn.add_transition(
14019 4,
14020 ParserTransitionSpec::Atom {
14021 target: 6,
14022 label: 1,
14023 },
14024 )
14025 .expect("transition");
14026 atn.add_transition(
14027 5,
14028 ParserTransitionSpec::Atom {
14029 target: 6,
14030 label: 1,
14031 },
14032 )
14033 .expect("transition");
14034 atn.add_transition(
14035 6,
14036 ParserTransitionSpec::Atom {
14037 target: 7,
14038 label: TOKEN_EOF,
14039 },
14040 )
14041 .expect("transition");
14042 finish_atn(atn)
14043 }
14044
14045 fn nested_nullable_context_atn() -> Atn {
14046 let mut atn = ParserAtnBuilder::new(1);
14047 for state_number in 0..=20 {
14048 let kind = match state_number {
14049 0 | 10 | 16 => AtnStateKind::RuleStart,
14050 9 | 15 | 20 => AtnStateKind::RuleStop,
14051 _ => AtnStateKind::Basic,
14052 };
14053 let rule_index = match state_number {
14054 0..=9 => 0,
14055 10..=15 => 1,
14056 _ => 2,
14057 };
14058 assert_eq!(
14059 atn.add_state(kind, Some(rule_index))
14060 .expect("state")
14061 .index(),
14062 state_number
14063 );
14064 }
14065 atn.set_rule_to_start_state(vec![0, 10, 16])
14066 .expect("rule start states");
14067 atn.set_rule_to_stop_state(vec![9, 15, 20])
14068 .expect("rule stop states");
14069 atn.add_transition(
14070 1,
14071 ParserTransitionSpec::Rule {
14072 target: 10,
14073 rule_index: 1,
14074 follow_state: 8,
14075 precedence: 0,
14076 },
14077 )
14078 .expect("transition");
14079 atn.add_transition(
14080 8,
14081 ParserTransitionSpec::Atom {
14082 target: 9,
14083 label: 1,
14084 },
14085 )
14086 .expect("transition");
14087 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14088 .expect("transition");
14089 atn.add_transition(
14090 2,
14091 ParserTransitionSpec::Rule {
14092 target: 16,
14093 rule_index: 2,
14094 follow_state: 14,
14095 precedence: 0,
14096 },
14097 )
14098 .expect("transition");
14099 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
14100 .expect("transition");
14101 finish_atn(atn)
14102 }
14103
14104 fn generated_match_recovery_atn() -> Atn {
14105 let mut atn = ParserAtnBuilder::new(2);
14106 assert_eq!(
14107 atn.add_state(AtnStateKind::RuleStart, Some(0))
14108 .expect("state")
14109 .index(),
14110 0
14111 );
14112 assert_eq!(
14113 atn.add_state(AtnStateKind::Basic, Some(0))
14114 .expect("state")
14115 .index(),
14116 1
14117 );
14118 assert_eq!(
14119 atn.add_state(AtnStateKind::Basic, Some(0))
14120 .expect("state")
14121 .index(),
14122 2
14123 );
14124 assert_eq!(
14125 atn.add_state(AtnStateKind::RuleStop, Some(0))
14126 .expect("state")
14127 .index(),
14128 3
14129 );
14130 assert_eq!(
14131 atn.add_state(AtnStateKind::RuleStart, Some(1))
14132 .expect("state")
14133 .index(),
14134 4
14135 );
14136 assert_eq!(
14137 atn.add_state(AtnStateKind::RuleStop, Some(1))
14138 .expect("state")
14139 .index(),
14140 5
14141 );
14142 atn.set_rule_to_start_state(vec![0, 4])
14143 .expect("rule start states");
14144 atn.set_rule_to_stop_state(vec![3, 5])
14145 .expect("rule stop states");
14146 atn.add_transition(
14147 1,
14148 ParserTransitionSpec::Rule {
14149 target: 4,
14150 rule_index: 1,
14151 follow_state: 2,
14152 precedence: 0,
14153 },
14154 )
14155 .expect("transition");
14156 atn.add_transition(
14157 2,
14158 ParserTransitionSpec::Atom {
14159 target: 3,
14160 label: TOKEN_EOF,
14161 },
14162 )
14163 .expect("transition");
14164 finish_atn(atn)
14165 }
14166
14167 fn complement_set_atn() -> Atn {
14168 let mut atn = ParserAtnBuilder::new(1);
14169 assert_eq!(
14170 atn.add_state(AtnStateKind::RuleStart, Some(0))
14171 .expect("state")
14172 .index(),
14173 0
14174 );
14175 assert_eq!(
14176 atn.add_state(AtnStateKind::RuleStop, Some(0))
14177 .expect("state")
14178 .index(),
14179 1
14180 );
14181 atn.set_rule_to_start_state(vec![0])
14182 .expect("rule start states");
14183 atn.set_rule_to_stop_state(vec![1])
14184 .expect("rule stop states");
14185 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
14186 atn.add_transition(
14187 0,
14188 ParserTransitionSpec::NotSet {
14189 target: 1,
14190 set: excluded,
14191 },
14192 )
14193 .expect("transition");
14194 finish_atn(atn)
14195 }
14196
14197 fn wildcard_then_eof_atn() -> Atn {
14200 let mut atn = ParserAtnBuilder::new(1);
14201 assert_eq!(
14202 atn.add_state(AtnStateKind::RuleStart, Some(0))
14203 .expect("state")
14204 .index(),
14205 0
14206 );
14207 assert_eq!(
14208 atn.add_state(AtnStateKind::RuleStop, Some(0))
14209 .expect("state")
14210 .index(),
14211 1
14212 );
14213 assert_eq!(
14214 atn.add_state(AtnStateKind::Basic, Some(0))
14215 .expect("state")
14216 .index(),
14217 2
14218 );
14219 atn.set_rule_to_start_state(vec![0])
14220 .expect("rule start states");
14221 atn.set_rule_to_stop_state(vec![1])
14222 .expect("rule stop states");
14223 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
14224 .expect("transition");
14225 atn.add_transition(
14226 2,
14227 ParserTransitionSpec::Atom {
14228 target: 1,
14229 label: TOKEN_EOF,
14230 },
14231 )
14232 .expect("transition");
14233 finish_atn(atn)
14234 }
14235
14236 #[test]
14237 fn parser_matches_token_and_reports_mismatch() {
14238 let source = Source {
14239 tokens: vec![
14240 TestToken::new(1).with_text("x"),
14241 TestToken::eof("parser-test", 1, 1, 1),
14242 ],
14243 index: 0,
14244 };
14245 let data = RecognizerData::new(
14246 "Mini.g4",
14247 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
14248 );
14249 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
14250 let matched = parser.match_token(1).expect("token 1 should match");
14251 assert_eq!(parser.node(matched).text(), "x");
14252 assert!(parser.match_token(1).is_err());
14253 }
14254
14255 #[test]
14256 fn parser_matches_token_sets() {
14257 let mut parser = mini_parser(vec![
14258 TestToken::new(1).with_text("x"),
14259 TestToken::eof("parser-test", 1, 1, 1),
14260 ]);
14261
14262 let matched = parser
14263 .match_set(&[(1, 1), (3, 4)])
14264 .expect("token set should match");
14265 assert_eq!(parser.node(matched).text(), "x");
14266 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
14267 }
14268
14269 #[test]
14270 fn generated_rule_api_tracks_state_and_precedence() {
14271 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14272
14273 let context = parser.enter_rule(7, 2);
14274 assert_eq!(context.rule_index(), 2);
14275 assert_eq!(parser.state(), 7);
14276 assert_eq!(
14277 parser.rule_context_stack,
14278 vec![RuleContextFrame {
14279 rule_index: 2,
14280 invoking_state: 7
14281 }]
14282 );
14283
14284 let recursive = parser.enter_recursion_rule(11, 3, 4);
14285 assert_eq!(recursive.rule_index(), 3);
14286 assert!(parser.precpred(4));
14287 assert!(parser.precpred(5));
14288 assert!(!parser.precpred(3));
14289
14290 let next = parser.push_new_recursion_context(13, 3);
14291 assert_eq!(next.invoking_state(), 13);
14292 parser.unroll_recursion_context();
14293 assert_eq!(parser.precedence_stack, vec![0]);
14294 assert_eq!(
14295 parser.rule_context_stack,
14296 vec![RuleContextFrame {
14297 rule_index: 2,
14298 invoking_state: 7
14299 }]
14300 );
14301
14302 parser.exit_rule();
14303 assert!(parser.rule_context_stack.is_empty());
14304 }
14305
14306 #[test]
14307 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
14308 let mut parser = mini_parser(vec![
14309 TestToken::new(1).with_text("x"),
14310 TestToken::eof("parser-test", 1, 1, 1),
14311 ]);
14312 let matched = parser.match_token(1).expect("token should match");
14313 assert_eq!(parser.node(matched).text(), "x");
14314 parser.record_generated_syntax_error();
14315 parser.set_int_member(7, 11);
14316 parser.set_build_parse_trees(false);
14317 parser.set_report_diagnostic_errors(true);
14318 parser.set_prediction_mode(PredictionMode::Sll);
14319 parser.set_bail_on_error(true);
14320 let _context = parser.enter_recursion_rule(9, 0, 4);
14321 parser.pending_invoking_states.push(5);
14322 parser.unknown_predicate_hits.push((0, 1));
14323 parser.unhandled_action_hits.push((0, 2));
14324
14325 parser.reset();
14326
14327 assert_eq!(parser.input.index(), 0);
14328 assert_eq!(parser.la(1), 1);
14329 assert_eq!(parser.state(), -1);
14330 assert_eq!(parser.number_of_syntax_errors(), 0);
14331 assert_eq!(parser.parse_tree_storage().node_count(), 0);
14332 assert!(parser.rule_context_stack.is_empty());
14333 assert!(parser.pending_invoking_states.is_empty());
14334 assert_eq!(parser.precedence_stack, [0]);
14335 assert!(parser.unknown_predicate_hits.is_empty());
14336 assert!(parser.unhandled_action_hits.is_empty());
14337 assert_eq!(parser.int_member(7), Some(11));
14338 assert!(!parser.build_parse_trees());
14339 assert!(parser.report_diagnostic_errors());
14340 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
14341 assert!(parser.bail_on_error());
14342 }
14343
14344 #[test]
14345 fn set_token_stream_replaces_input_and_resets_parser() {
14346 let mut parser = mini_parser(vec![
14347 TestToken::new(1).with_text("old"),
14348 TestToken::eof("parser-test", 1, 1, 1),
14349 ]);
14350 parser.consume();
14351 parser.record_generated_syntax_error();
14352 let replacement = CommonTokenStream::new(Source {
14353 tokens: vec![
14354 TestToken::new(2).with_text("new"),
14355 TestToken::eof("parser-test", 1, 1, 1),
14356 ],
14357 index: 0,
14358 });
14359
14360 parser.set_token_stream(replacement);
14361
14362 assert_eq!(parser.input.index(), 0);
14363 assert_eq!(parser.la(1), 2);
14364 assert_eq!(parser.input.text_all(), "new");
14365 assert_eq!(parser.number_of_syntax_errors(), 0);
14366 }
14367
14368 #[test]
14369 fn active_invocation_states_exclude_the_root_frame() {
14370 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14371
14372 let _root = parser.enter_rule(0, 0);
14373 assert!(parser.active_invocation_states().is_empty());
14374
14375 let marker = parser.push_invoking_state(6);
14376 let _child = parser.enter_rule(2, 1);
14377 parser.discard_invoking_state(marker);
14378 assert_eq!(parser.active_invocation_states(), [6]);
14379
14380 let marker = parser.push_invoking_state(13);
14381 let _grandchild = parser.enter_rule(4, 2);
14382 parser.discard_invoking_state(marker);
14383 assert_eq!(parser.active_invocation_states(), [13, 6]);
14384
14385 parser.exit_rule();
14386 parser.exit_rule();
14387 parser.exit_rule();
14388 }
14389
14390 #[test]
14391 fn parser_predicates_support_token_adjacency() {
14392 let mut parser = mini_parser(vec![
14393 TestToken::new(1).with_text("=").with_span(0, 0),
14394 TestToken::new(1).with_text(">").with_span(1, 1),
14395 TestToken::eof("parser-test", 2, 1, 2),
14396 ]);
14397 parser.consume();
14398 parser.consume();
14399
14400 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
14401
14402 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
14403
14404 let mut parser = mini_parser(vec![
14405 TestToken::new(1).with_text("=").with_span(0, 0),
14406 TestToken::new(1)
14407 .with_text(" ")
14408 .with_channel(HIDDEN_CHANNEL)
14409 .with_span(1, 1),
14410 TestToken::new(1).with_text(">").with_span(2, 2),
14411 TestToken::eof("parser-test", 3, 1, 3),
14412 ]);
14413 parser.consume();
14414 parser.consume();
14415
14416 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
14417 }
14418
14419 #[test]
14420 fn parser_predicates_support_context_child_text_checks() {
14421 let mut parser = mini_parser(vec![
14422 TestToken::new(1).with_text("var"),
14423 TestToken::eof("parser-test", 1, 1, 1),
14424 ]);
14425 let mut context = ParserRuleContext::new(1, 0);
14426 let mut child_context = ParserRuleContext::new(2, 0);
14427 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
14428 parser.tree.add_child(&mut child_context, terminal);
14429 let child = parser.rule_node(child_context);
14430 parser.tree.add_child(&mut context, child);
14431 let predicates = [(
14432 1,
14433 0,
14434 ParserPredicate::ContextChildRuleTextNotEquals {
14435 rule_index: 2,
14436 text: "var",
14437 },
14438 )];
14439
14440 assert!(
14441 !parser.parser_semantic_predicate_matches_with_context_and_local(
14442 &predicates,
14443 1,
14444 0,
14445 &context,
14446 0,
14447 )
14448 );
14449 }
14450
14451 #[test]
14452 fn context_expected_symbols_walks_nullable_parent_contexts() {
14453 let atn = nested_nullable_context_atn();
14454 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
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 RuleContextFrame {
14465 rule_index: 2,
14466 invoking_state: 2,
14467 },
14468 ];
14469
14470 let expected = parser.context_expected_symbols(&atn);
14471
14472 assert!(expected.contains(&1));
14473 assert!(expected.contains(&TOKEN_EOF));
14474 }
14475
14476 #[test]
14477 fn prediction_context_return_states_track_rule_stack_changes() {
14478 let atn = nested_nullable_context_atn();
14479 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14480 parser.rule_context_stack = vec![
14481 RuleContextFrame {
14482 rule_index: 0,
14483 invoking_state: 0,
14484 },
14485 RuleContextFrame {
14486 rule_index: 1,
14487 invoking_state: 1,
14488 },
14489 RuleContextFrame {
14490 rule_index: 2,
14491 invoking_state: 2,
14492 },
14493 ];
14494
14495 let initial_version = parser.rule_context_version();
14496 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14497 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14498 assert_eq!(first, second);
14499 assert_eq!(parser.rule_context_version(), initial_version);
14500
14501 parser.exit_rule();
14502 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14503 assert_ne!(first, after_pop);
14504 assert_ne!(parser.rule_context_version(), initial_version);
14505 }
14506
14507 #[test]
14508 fn generated_match_token_recovers_missing_token_from_context_follow() {
14509 let atn = generated_match_recovery_atn();
14510 let data = RecognizerData::new(
14511 "Mini.g4",
14512 Vocabulary::new(
14513 [None, Some("'X'"), Some("'Y'")],
14514 [None, Some("X"), Some("Y")],
14515 [None::<&str>, None, None],
14516 ),
14517 );
14518 let mut parser = BaseParser::new(
14519 CommonTokenStream::new(Source {
14520 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
14521 index: 0,
14522 }),
14523 data,
14524 );
14525 parser.rule_context_stack = vec![
14526 RuleContextFrame {
14527 rule_index: 0,
14528 invoking_state: 0,
14529 },
14530 RuleContextFrame {
14531 rule_index: 1,
14532 invoking_state: 1,
14533 },
14534 ];
14535 assert_eq!(parser.number_of_syntax_errors(), 0);
14536
14537 let node = parser
14538 .match_token_recovering(2, 5, &atn)
14539 .expect("generated match should insert missing token");
14540
14541 assert_eq!(node.children().len(), 1);
14542 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
14543 assert_eq!(
14544 node.clone()
14545 .into_child_iter()
14546 .map(|child| parser.node(child).text())
14547 .collect::<Vec<_>>(),
14548 ["<missing 'Y'>"]
14549 );
14550 assert!(!node.consumed_eof());
14553 assert_eq!(parser.la(1), TOKEN_EOF);
14554 assert_eq!(parser.number_of_syntax_errors(), 1);
14555 assert_eq!(
14556 parser.generated_parser_diagnostics,
14557 [ParserDiagnostic {
14558 line: 1,
14559 column: 3,
14560 message: "missing 'Y' at '<EOF>'".to_owned(),
14561 }]
14562 );
14563 }
14564
14565 #[test]
14566 fn generated_match_token_counts_single_token_deletion_recovery() {
14567 let atn = generated_match_recovery_atn();
14568 let data = RecognizerData::new(
14569 "Mini.g4",
14570 Vocabulary::new(
14571 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
14572 [None, Some("X"), Some("Y"), Some("Z")],
14573 [None::<&str>, None, None, None],
14574 ),
14575 );
14576 let mut parser = BaseParser::new(
14577 CommonTokenStream::new(Source {
14578 tokens: vec![
14579 TestToken::new(3).with_text("z"),
14580 TestToken::new(2).with_text("y"),
14581 TestToken::eof("parser-test", 3, 1, 3),
14582 ],
14583 index: 0,
14584 }),
14585 data,
14586 );
14587
14588 let node = parser
14589 .match_token_recovering(2, 5, &atn)
14590 .expect("generated match should delete the extraneous token");
14591
14592 assert_eq!(node.children().len(), 2);
14593 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
14594 assert_eq!(parser.node(node.children()[0]).text(), "z");
14595 assert_eq!(parser.node(node.children()[1]).text(), "y");
14596 assert_eq!(
14597 node.into_child_iter()
14598 .map(|child| parser.node(child).text())
14599 .collect::<Vec<_>>(),
14600 ["z", "y"]
14601 );
14602 assert_eq!(parser.number_of_syntax_errors(), 1);
14603 }
14604
14605 #[test]
14606 fn generated_match_token_iterates_single_success_without_a_children_vec() {
14607 let atn = generated_match_recovery_atn();
14608 let data = RecognizerData::new(
14609 "Mini.g4",
14610 Vocabulary::new(
14611 [None, Some("'X'"), Some("'Y'")],
14612 [None, Some("X"), Some("Y")],
14613 [None::<&str>, None, None],
14614 ),
14615 );
14616 let mut parser = BaseParser::new(
14617 CommonTokenStream::new(Source {
14618 tokens: vec![
14619 TestToken::new(2).with_text("y"),
14620 TestToken::eof("parser-test", 1, 1, 1),
14621 ],
14622 index: 0,
14623 }),
14624 data,
14625 );
14626
14627 let node = parser
14628 .match_token_recovering(2, 5, &atn)
14629 .expect("generated match should consume the expected token");
14630
14631 assert_eq!(
14632 node.into_child_iter()
14633 .map(|child| parser.node(child).text())
14634 .collect::<Vec<_>>(),
14635 ["y"]
14636 );
14637 assert_eq!(parser.number_of_syntax_errors(), 0);
14638 }
14639
14640 #[test]
14641 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
14642 let atn = generated_match_recovery_atn();
14643 let data = RecognizerData::new(
14644 "Mini.g4",
14645 Vocabulary::new(
14646 [None, Some("'X'"), Some("'Y'")],
14647 [None, Some("X"), Some("Y")],
14648 [None::<&str>, None, None],
14649 ),
14650 );
14651 let mut parser = BaseParser::new(
14652 CommonTokenStream::new(Source {
14653 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
14654 index: 0,
14655 }),
14656 data,
14657 );
14658 parser.rule_context_stack = vec![
14659 RuleContextFrame {
14660 rule_index: 0,
14661 invoking_state: 0,
14662 },
14663 RuleContextFrame {
14664 rule_index: 1,
14665 invoking_state: 1,
14666 },
14667 ];
14668 let marker = parser.generated_diagnostics_checkpoint();
14669
14670 let _ = parser
14671 .match_token_recovering(2, 5, &atn)
14672 .expect("generated match should insert missing token");
14673 assert_eq!(parser.number_of_syntax_errors(), 1);
14674
14675 parser.restore_generated_diagnostics(marker);
14676
14677 assert_eq!(parser.number_of_syntax_errors(), 0);
14678 assert!(parser.generated_parser_diagnostics.is_empty());
14679 }
14680
14681 #[test]
14682 fn generated_prediction_diagnostics_use_adaptive_context() {
14683 let atn = two_alt_decision_atn();
14684 let data = RecognizerData::new(
14685 "Mini.g4",
14686 Vocabulary::new(
14687 [None, Some("'x'"), Some("'y'")],
14688 [None, Some("X"), Some("Y")],
14689 [None::<&str>, None, None],
14690 ),
14691 )
14692 .with_rule_names(["s"]);
14693 let mut parser = BaseParser::new(
14694 CommonTokenStream::new(Source {
14695 tokens: vec![
14696 TestToken::new(1)
14697 .with_text("x")
14698 .with_position(1, 0)
14699 .with_span(0, 0),
14700 TestToken::new(2)
14701 .with_text("y")
14702 .with_position(1, 2)
14703 .with_span(1, 1),
14704 TestToken::eof("parser-test", 2, 1, 3),
14705 ],
14706 index: 0,
14707 }),
14708 data,
14709 );
14710 parser.set_report_diagnostic_errors(true);
14711
14712 parser.record_generated_prediction_diagnostic(
14713 &atn,
14714 1,
14715 &ParserAtnPrediction {
14716 alt: 1,
14717 requires_full_context: true,
14718 has_semantic_context: false,
14719 diagnostic: Some(ParserAtnPredictionDiagnostic {
14720 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
14721 start_index: 0,
14722 sll_stop_index: 1,
14723 ll_stop_index: 0,
14724 conflicting_alts: vec![1, 2],
14725 exact: false,
14726 }),
14727 },
14728 );
14729 parser.record_generated_prediction_diagnostic(
14734 &atn,
14735 1,
14736 &ParserAtnPrediction {
14737 alt: 1,
14738 requires_full_context: true,
14739 has_semantic_context: false,
14740 diagnostic: Some(ParserAtnPredictionDiagnostic {
14741 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
14742 start_index: 0,
14743 sll_stop_index: 1,
14744 ll_stop_index: 1,
14745 conflicting_alts: vec![1, 2],
14746 exact: false,
14747 }),
14748 },
14749 );
14750
14751 assert_eq!(
14752 parser.generated_parser_diagnostics,
14753 [
14754 ParserDiagnostic {
14755 line: 1,
14756 column: 2,
14757 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
14758 },
14759 ParserDiagnostic {
14760 line: 1,
14761 column: 0,
14762 message: "reportContextSensitivity d=0 (s), input='x'".to_owned(),
14763 },
14764 ParserDiagnostic {
14765 line: 1,
14766 column: 2,
14767 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
14768 },
14769 ]
14770 );
14771 }
14772
14773 #[test]
14774 fn generated_match_not_set_recovers_empty_complement_at_eof() {
14775 let atn = complement_set_atn();
14776 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14777 parser.rule_context_stack = vec![RuleContextFrame {
14778 rule_index: 0,
14779 invoking_state: 0,
14780 }];
14781
14782 let node = parser
14783 .match_not_set_recovering(&[(1, 1)], 1, 1, 1, &atn)
14784 .expect("empty complement should recover at EOF");
14785
14786 assert_eq!(node.children().len(), 1);
14787 assert!(!node.consumed_eof());
14790 assert_eq!(parser.la(1), TOKEN_EOF);
14791 assert_eq!(
14792 parser.generated_parser_diagnostics,
14793 [ParserDiagnostic {
14794 line: 1,
14795 column: 1,
14796 message: "missing {} at '<EOF>'".to_owned(),
14797 }]
14798 );
14799 }
14800
14801 #[test]
14802 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
14803 let atn = wildcard_then_eof_atn();
14809 let data = RecognizerData::new(
14810 "Mini.g4",
14811 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
14812 );
14813 let mut parser = BaseParser::new(
14814 CommonTokenStream::new(Source {
14815 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
14816 index: 0,
14817 }),
14818 data,
14819 );
14820 parser.rule_context_stack = vec![RuleContextFrame {
14821 rule_index: 0,
14822 invoking_state: 0,
14823 }];
14824
14825 let node = parser
14826 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
14827 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
14828
14829 assert_eq!(node.children().len(), 1);
14831 assert!(!node.consumed_eof());
14832 assert!(
14833 parser
14834 .node(node.children()[0])
14835 .text()
14836 .starts_with("<missing")
14837 );
14838 assert_eq!(parser.la(1), TOKEN_EOF);
14839 assert_eq!(
14840 parser.generated_parser_diagnostics,
14841 [ParserDiagnostic {
14842 line: 1,
14843 column: 1,
14844 message: "missing 'x' at '<EOF>'".to_owned(),
14845 }]
14846 );
14847 }
14848
14849 #[test]
14850 fn generated_rule_recovery_consumes_to_parent_follow() {
14851 let atn = generated_match_recovery_atn();
14852 let data = RecognizerData::new(
14853 "Mini.g4",
14854 Vocabulary::new(
14855 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
14856 [None, Some("X"), Some("Y"), Some("Z")],
14857 [None::<&str>, None, None, None],
14858 ),
14859 );
14860 let mut parser = BaseParser::new(
14861 CommonTokenStream::new(Source {
14862 tokens: vec![
14863 TestToken::new(3).with_text("z"),
14864 TestToken::eof("parser-test", 1, 1, 1),
14865 ],
14866 index: 0,
14867 }),
14868 data,
14869 );
14870 let _parent = parser.enter_rule(0, 0);
14871 let marker = parser.push_invoking_state(1);
14872 let mut child = parser.enter_rule(4, 1);
14873 parser.discard_invoking_state(marker);
14874
14875 parser.recover_generated_rule(
14876 &mut child,
14877 &atn,
14878 AntlrError::ParserError {
14879 line: 1,
14880 column: 0,
14881 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
14882 },
14883 );
14884 let tree = parser.finish_rule(child, false);
14885
14886 assert_eq!(parser.la(1), TOKEN_EOF);
14887 assert_eq!(
14888 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
14889 "(a z)"
14890 );
14891 assert_eq!(parser.number_of_syntax_errors(), 1);
14892 assert_eq!(
14893 parser.generated_parser_diagnostics,
14894 [ParserDiagnostic {
14895 line: 1,
14896 column: 0,
14897 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
14898 }]
14899 );
14900 parser.exit_rule();
14901 }
14902
14903 #[test]
14904 fn greedy_ll1_alt_handles_nullable_loop_exit() {
14905 let mut body_symbols = TokenBitSet::default();
14906 body_symbols.insert(1);
14907 let entry = DecisionLookahead {
14908 transitions: vec![
14909 TransitionLookSet {
14910 symbols: body_symbols,
14911 nullable: false,
14912 },
14913 TransitionLookSet {
14914 symbols: TokenBitSet::default(),
14915 nullable: true,
14916 },
14917 ],
14918 };
14919
14920 assert_eq!(ll1_unique_alt(&entry, 2), None);
14921 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
14922 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
14923 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
14924 }
14925
14926 #[test]
14927 fn ordinary_repetition_builds_tree_in_input_order() {
14928 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
14929 let mut parser = mini_parser(repeated_x_tokens(3));
14930 let tree = parser
14931 .parse_atn_rule(&atn, 0)
14932 .expect("ordinary repetition should parse");
14933
14934 let root = parser
14935 .node(tree)
14936 .as_rule()
14937 .expect("entry result should be a rule");
14938 let body_rules = root.child_rules(1).collect::<Vec<_>>();
14939 assert_eq!(root.text(), "xxx<EOF>");
14940 assert_eq!(body_rules.len(), 3);
14941 assert_eq!(
14942 body_rules
14943 .iter()
14944 .map(|rule| rule.start_id().expect("body start").index())
14945 .collect::<Vec<_>>(),
14946 [0, 1, 2]
14947 );
14948 assert_eq!(
14949 body_rules
14950 .iter()
14951 .map(|rule| rule.stop_id().expect("body stop").index())
14952 .collect::<Vec<_>>(),
14953 [0, 1, 2]
14954 );
14955 assert_eq!(parser.number_of_syntax_errors(), 0);
14956 }
14957 }
14958
14959 #[test]
14960 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
14961 const DEPTH: usize = 20_000;
14962
14963 std::thread::Builder::new()
14964 .name("deferred-rule-materialization".to_owned())
14965 .stack_size(256 * 1024)
14966 .spawn(|| {
14967 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
14968 let mut root = FastDeferredNodeId::EMPTY;
14969 for depth in 0..DEPTH {
14970 root = parser
14971 .recognition_arena
14972 .deferred_rule_node(FastDeferredRule {
14973 rule_index: u32::try_from(depth).expect("depth fits in u32"),
14974 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
14975 start_index: 0,
14976 stop_index: None,
14977 deferred_children: root,
14978 children: NodeSeqId::EMPTY,
14979 });
14980 }
14981
14982 let mut children = parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
14983 for expected_rule in (0..DEPTH).rev() {
14984 let mut nodes = parser.recognition_arena.iter(children);
14985 let node = nodes.next().expect("nested rule node");
14986 assert!(nodes.next().is_none(), "each rule has one child");
14987 let ArenaRecognizedNode::Rule {
14988 rule_index,
14989 children: nested,
14990 ..
14991 } = parser.recognition_arena.node(node)
14992 else {
14993 panic!("expected nested rule");
14994 };
14995 assert_eq!(rule_index as usize, expected_rule);
14996 children = nested;
14997 }
14998 assert!(children.is_empty());
14999 })
15000 .expect("small-stack thread should start")
15001 .join()
15002 .expect("deferred rules should materialize without recursion");
15003 }
15004
15005 #[test]
15006 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
15007 const REPETITIONS: usize = 64;
15008
15009 let atn = ambiguous_ordinary_star_loop_atn();
15010 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15011 let tree = parser
15012 .parse_atn_rule(&atn, 0)
15013 .expect("ambiguous ordinary repetition should parse");
15014
15015 let root = parser
15016 .node(tree)
15017 .as_rule()
15018 .expect("entry result should be a rule");
15019 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
15020 assert_eq!(parser.input.index(), REPETITIONS);
15021 assert!(
15022 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
15023 "equivalent segmentations should keep deferred storage linear"
15024 );
15025 assert_eq!(parser.number_of_syntax_errors(), 0);
15026 }
15027
15028 #[test]
15029 fn long_ordinary_repetition_does_not_consume_native_stack() {
15030 const REPETITIONS: usize = 20_000;
15031
15032 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15033 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15034 parser.set_build_parse_trees(false);
15035 parser
15036 .parse_atn_rule(&atn, 0)
15037 .expect("long ordinary repetition should parse");
15038
15039 assert_eq!(parser.input.index(), REPETITIONS);
15040 assert_eq!(parser.number_of_syntax_errors(), 0);
15041 }
15042 }
15043
15044 #[test]
15045 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
15046 const REPETITIONS: usize = 2_000;
15047 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
15048
15049 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15050 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15051 let tree = parser
15052 .parse_atn_rule(&atn, 0)
15053 .expect("long rule repetition should parse");
15054
15055 let root = parser
15056 .node(tree)
15057 .as_rule()
15058 .expect("entry result should be a rule");
15059 assert_eq!(root.text(), expected_text);
15060 assert_eq!(root.child_rules(1).count(), REPETITIONS);
15061 let first_body = root.child_rules(1).next().expect("first body rule");
15062 let last_body = root.child_rules(1).next_back().expect("last body rule");
15063 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
15064 assert_eq!(
15065 last_body.stop_id().expect("last body stop").index(),
15066 REPETITIONS - 1
15067 );
15068
15069 let stats = parser.recognition_arena_stats();
15070 assert_eq!(
15071 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
15072 (REPETITIONS, REPETITIONS, 0)
15073 );
15074 assert_eq!(
15075 (stats.total_links, stats.live_links, stats.dead_links),
15076 (REPETITIONS, REPETITIONS, 0)
15077 );
15078 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
15079 assert_eq!(
15080 parser.recognition_arena.deferred_nodes.len(),
15081 REPETITIONS * 2 - 1
15082 );
15083 assert_eq!(parser.number_of_syntax_errors(), 0);
15084 }
15085 }
15086
15087 #[test]
15088 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
15089 let key = |state_number| FastRecognizeKey {
15090 state_number,
15091 stop_state: 10,
15092 index: state_number,
15093 rule_start_index: 0,
15094 decision_start_index: None,
15095 precedence: 0,
15096 recovery_symbols_id: 0,
15097 recovery_state: None,
15098 };
15099
15100 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15101 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
15102 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
15103 }
15104 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
15105 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
15106
15107 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15108 let repeated = key(1);
15109 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
15110 assert!(promote.clean_memo_enabled_for_key(&repeated));
15111 }
15112 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
15113
15114 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
15115 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
15116 }
15117 assert!(sparse.clean_memo_enabled_for_key(&repeated));
15118 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
15119 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
15120 assert!(sparse.clean_memo_enabled_for_key(&repeated));
15121 }
15122 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
15123 }
15124
15125 #[test]
15126 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
15127 assert_eq!(
15128 fast_recognize_memo_capacity(0),
15129 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
15130 );
15131 assert_eq!(
15132 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
15133 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
15134 );
15135 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
15136 assert_eq!(
15137 fast_recognize_memo_capacity(usize::MAX),
15138 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
15139 );
15140 }
15141
15142 #[test]
15143 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
15144 let mut scratch = FastRecognizeTopScratch::default();
15145 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
15146 let retained_capacity = scratch.memo.capacity();
15147 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
15148 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15149
15150 let larger_capacity = retained_capacity + 1;
15151 scratch.prepare(larger_capacity);
15152 let grown_capacity = scratch.memo.capacity();
15153 assert!(grown_capacity >= larger_capacity);
15154 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15155
15156 scratch.memo.insert(
15157 FastRecognizeKey {
15158 state_number: 0,
15159 stop_state: 0,
15160 index: 0,
15161 rule_start_index: 0,
15162 decision_start_index: None,
15163 precedence: 0,
15164 recovery_symbols_id: 0,
15165 recovery_state: None,
15166 },
15167 Rc::from([FastRecognizeOutcome {
15168 index: 0,
15169 consumed_eof: false,
15170 diagnostics: DiagnosticSeqId::EMPTY,
15171 deferred_nodes: FastDeferredNodeId::EMPTY,
15172 nodes: NodeSeqId::EMPTY,
15173 }]),
15174 );
15175 scratch.release_oversized_memo();
15176 assert!(scratch.memo.is_empty());
15177 assert_eq!(scratch.memo.capacity(), grown_capacity);
15178
15179 scratch
15180 .memo
15181 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
15182 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15183
15184 scratch.release_oversized_memo();
15185 assert!(scratch.memo.is_empty());
15186 assert_eq!(scratch.memo.capacity(), 0);
15187 }
15188
15189 #[test]
15190 fn clean_empty_multi_alt_outcomes_are_memoized() {
15191 let mut atn = ParserAtnBuilder::new(2);
15192 assert_eq!(
15193 atn.add_state(AtnStateKind::RuleStart, Some(0))
15194 .expect("state")
15195 .index(),
15196 0
15197 );
15198 assert_eq!(
15199 atn.add_state(AtnStateKind::BlockStart, Some(0))
15200 .expect("state")
15201 .index(),
15202 1
15203 );
15204 assert_eq!(
15205 atn.add_state(AtnStateKind::RuleStop, Some(0))
15206 .expect("state")
15207 .index(),
15208 2
15209 );
15210 atn.set_rule_to_start_state(vec![0])
15211 .expect("rule start states");
15212 atn.set_rule_to_stop_state(vec![2])
15213 .expect("rule stop states");
15214 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15215 .expect("transition");
15216 atn.add_transition(
15217 1,
15218 ParserTransitionSpec::Atom {
15219 target: 2,
15220 label: 1,
15221 },
15222 )
15223 .expect("transition");
15224 atn.add_transition(
15225 1,
15226 ParserTransitionSpec::Atom {
15227 target: 2,
15228 label: 2,
15229 },
15230 )
15231 .expect("transition");
15232 let atn = finish_atn(atn);
15233
15234 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
15235 parser.fast_recovery_enabled = false;
15236 let mut visiting = FxHashSet::default();
15237 let mut memo = FxHashMap::default();
15238 let mut expected = ExpectedTokens::default();
15239 let outcomes = parser.recognize_state_fast(
15240 &atn,
15241 FastRecognizeRequest {
15242 state_number: 1,
15243 stop_state: 2,
15244 index: 0,
15245 rule_start_index: 0,
15246 decision_start_index: None,
15247 precedence: 0,
15248 depth: 0,
15249 recovery_symbols: parser.empty_recovery_symbols(),
15250 recovery_state: None,
15251 },
15252 FastRecognizeScratch {
15253 predicate_context: None,
15254 visiting: &mut visiting,
15255 memo: &mut memo,
15256 expected: &mut expected,
15257 },
15258 );
15259
15260 assert!(outcomes.is_empty());
15261 assert_eq!(memo.len(), 1);
15262 assert!(memo.values().next().expect("memo entry").is_empty());
15263
15264 parser.clean_memo_mode = CleanMemoMode::Sparse;
15265 visiting.clear();
15266 memo.clear();
15267 expected = ExpectedTokens::default();
15268 let sparse_outcomes = parser.recognize_state_fast(
15269 &atn,
15270 FastRecognizeRequest {
15271 state_number: 1,
15272 stop_state: 2,
15273 index: 0,
15274 rule_start_index: 0,
15275 decision_start_index: None,
15276 precedence: 0,
15277 depth: 0,
15278 recovery_symbols: parser.empty_recovery_symbols(),
15279 recovery_state: None,
15280 },
15281 FastRecognizeScratch {
15282 predicate_context: None,
15283 visiting: &mut visiting,
15284 memo: &mut memo,
15285 expected: &mut expected,
15286 },
15287 );
15288
15289 assert!(sparse_outcomes.is_empty());
15290 assert!(memo.is_empty());
15291 }
15292
15293 #[test]
15294 fn wildcard_matches_non_eof_only() {
15295 let mut parser = mini_parser(vec![
15296 TestToken::new(1).with_text("x"),
15297 TestToken::eof("parser-test", 1, 1, 1),
15298 ]);
15299 let matched = parser.match_wildcard().expect("wildcard");
15300 assert_eq!(parser.node(matched).text(), "x");
15301 assert!(parser.match_wildcard().is_err());
15302 }
15303
15304 #[test]
15305 fn add_parse_child_records_match_even_without_tree_building() {
15306 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15311 let token = TestToken::new(1).with_text("x");
15312
15313 parser.set_build_parse_trees(false);
15314 let mut ctx = ParserRuleContext::new(0, 0);
15315 assert!(!ctx.has_matched_child());
15316 let child = parser.terminal_tree(token.id);
15317 parser.add_parse_child(&mut ctx, child);
15318 assert_eq!(ctx.child_count(), 0);
15320 assert_eq!(parser.parse_tree_storage().node_count(), 0);
15321 assert!(ctx.has_matched_child());
15323
15324 parser.set_build_parse_trees(true);
15326 let mut ctx = ParserRuleContext::new(0, 0);
15327 let child = parser.terminal_tree(token.id);
15328 parser.add_parse_child(&mut ctx, child);
15329 assert_eq!(ctx.child_count(), 1);
15330 assert!(ctx.has_matched_child());
15331 }
15332
15333 #[test]
15334 fn disabled_tree_building_does_not_grow_flat_storage() {
15335 let mut parser = mini_parser(vec![
15336 TestToken::new(1).with_text("x"),
15337 TestToken::new(1).with_text("y"),
15338 TestToken::eof("parser-test", 2, 1, 2),
15339 ]);
15340 parser.set_build_parse_trees(false);
15341 let mut context = ParserRuleContext::new(0, -1);
15342
15343 for _ in 0..2 {
15344 let child = parser.match_token(1).expect("token should match");
15345 parser.add_parse_child(&mut context, child);
15346 }
15347 let current = parser.input.lt_id(1).expect("EOF token");
15348 let error = parser.error_tree(current);
15349 parser.add_parse_child(&mut context, error);
15350 let root = parser.rule_node(context);
15351
15352 assert_eq!(
15353 parser.parse_tree_storage().stats(),
15354 ParseTreeStats::default()
15355 );
15356 assert!(
15357 parser
15358 .parse_tree_storage()
15359 .node(parser.token_store(), root)
15360 .is_none(),
15361 "the no-tree sentinel must not resolve to stored data"
15362 );
15363 }
15364
15365 #[test]
15366 fn disabled_tree_building_skips_recognition_rule_node_storage() {
15367 let atn = ordinary_star_loop_atn();
15368 let mut parser = mini_parser(repeated_x_tokens(3));
15369 parser.set_build_parse_trees(false);
15370
15371 parser
15372 .parse_atn_rule(&atn, 0)
15373 .expect("ordinary repetition should parse without a tree");
15374
15375 assert_eq!(parser.input.index(), 3);
15376 assert!(parser.recognition_arena.nodes.is_empty());
15377 assert!(parser.recognition_arena.seq_links.is_empty());
15378 assert!(parser.recognition_arena.deferred_nodes.is_empty());
15379 assert!(parser.recognition_arena.deferred_rules.is_empty());
15380 assert!(!parser.fast_token_nodes_enabled);
15381 assert!(parser.fast_recognize_scratch.memo.is_empty());
15382 }
15383
15384 #[test]
15385 fn parser_interprets_simple_atn_rule() {
15386 let atn = token_then_eof_atn();
15387 let mut parser = mini_parser(vec![
15388 TestToken::new(1).with_text("x"),
15389 TestToken::eof("parser-test", 1, 1, 1),
15390 ]);
15391
15392 let tree = parser
15393 .parse_atn_rule(&atn, 0)
15394 .expect("artificial parser rule should parse");
15395 assert_eq!(parser.node(tree).text(), "x<EOF>");
15396 assert_eq!(parser.number_of_syntax_errors(), 0);
15397 assert_eq!(
15398 parser
15399 .node(tree)
15400 .first_rule_stop(0)
15401 .expect("rule should stop at EOF")
15402 .token_type(),
15403 TOKEN_EOF
15404 );
15405
15406 let mut parser = mini_parser(vec![
15407 TestToken::new(1).with_text("x"),
15408 TestToken::eof("parser-test", 1, 1, 1),
15409 ]);
15410 let (tree, actions) = parser
15411 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15412 .expect("runtime-option parser rule should parse");
15413 assert!(actions.is_empty());
15414 assert_eq!(
15415 parser
15416 .node(tree)
15417 .first_rule_stop(0)
15418 .expect("rule should stop at EOF")
15419 .token_type(),
15420 TOKEN_EOF
15421 );
15422 }
15423
15424 #[test]
15425 fn runtime_options_default_ignores_noop_action_transitions() {
15426 let atn = noop_action_then_token_then_eof_atn();
15427 let mut parser = mini_parser(vec![
15428 TestToken::new(1).with_text("x"),
15429 TestToken::eof("parser-test", 1, 1, 1),
15430 ]);
15431
15432 let (tree, actions) = parser
15433 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15434 .expect("no-op parser action should not force action replay");
15435
15436 assert_eq!(parser.node(tree).text(), "x<EOF>");
15437 assert!(
15438 actions.is_empty(),
15439 "action_index=None transitions are ANTLR metadata, not replay actions"
15440 );
15441 assert_eq!(parser.number_of_syntax_errors(), 0);
15442 }
15443
15444 #[test]
15445 fn parser_exposes_buffered_token_stream_after_parse() {
15446 let atn = token_then_eof_atn();
15447 let mut parser = mini_parser(vec![
15448 TestToken::new(1).with_text("x"),
15449 TestToken::eof("parser-test", 1, 1, 1),
15450 ]);
15451
15452 let tree = parser
15453 .parse_atn_rule(&atn, 0)
15454 .expect("artificial parser rule should parse");
15455 assert_eq!(parser.node(tree).text(), "x<EOF>");
15456
15457 let stream = parser.token_stream();
15458 let source_index_after_parse = stream.token_source().index;
15459 let buffered = stream.tokens().collect::<Vec<_>>();
15460 assert_eq!(buffered.len(), 2);
15461 assert_eq!(buffered[0].text(), "x");
15462 assert_eq!(buffered[0].token_id().index(), 0);
15463 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
15464 assert_eq!(stream.token_source().index, source_index_after_parse);
15465 drop(buffered);
15466
15467 let stream = parser.into_token_stream();
15468 assert_eq!(stream.token_source().index, source_index_after_parse);
15469 assert_eq!(stream.tokens().next().expect("first token").text(), "x");
15470 assert_eq!(
15471 stream.tokens().nth(1).expect("EOF token").token_type(),
15472 TOKEN_EOF
15473 );
15474 }
15475
15476 #[test]
15477 fn parser_syntax_error_count_tracks_interpreted_recovery() {
15478 let atn = token_then_eof_atn();
15479 let mut parser = mini_parser(vec![
15480 TestToken::new(1).with_text("x"),
15481 TestToken::new(2).with_text("y"),
15482 TestToken::eof("parser-test", 2, 1, 2),
15483 ]);
15484
15485 let tree = parser
15486 .parse_atn_rule(&atn, 0)
15487 .expect("invalid token should recover into an error node");
15488
15489 assert_eq!(parser.number_of_syntax_errors(), 1);
15490 assert_eq!(
15491 parser
15492 .node(tree)
15493 .first_error_token()
15494 .expect("recovery should embed an error token")
15495 .text(),
15496 "y"
15497 );
15498 }
15499
15500 #[test]
15501 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
15502 let atn = token_then_eof_atn();
15503 let mut parser = mini_parser(vec![
15504 TestToken::new(2).with_text("y"),
15505 TestToken::eof("parser-test", 1, 1, 1),
15506 ]);
15507
15508 let error = parser
15509 .parse_atn_rule(&atn, 0)
15510 .expect_err("start-rule mismatch should remain a parser error");
15511
15512 assert_eq!(parser.number_of_syntax_errors(), 1);
15513 assert!(matches!(error, AntlrError::ParserError { .. }));
15514 }
15515
15516 #[test]
15517 fn adaptive_direct_rule_uses_simulator_decision() {
15518 let atn = two_alt_decision_atn();
15519 let mut simulator = ParserAtnSimulator::new(&atn);
15520 let mut parser = mini_parser(vec![
15521 TestToken::new(2).with_text("y"),
15522 TestToken::eof("parser-test", 1, 1, 1),
15523 ]);
15524
15525 let tree = parser
15526 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
15527 .expect("direct adaptive rule should parse");
15528
15529 assert_eq!(parser.node(tree).text(), "y");
15530 assert_eq!(parser.input.index(), 1);
15531 }
15532
15533 #[test]
15534 fn adaptive_direct_rule_restores_input_on_fallback() {
15535 let atn = predicate_after_token_atn();
15536 let mut simulator = ParserAtnSimulator::new(&atn);
15537 let mut parser = mini_parser(vec![
15538 TestToken::new(1).with_text("x"),
15539 TestToken::new(2).with_text("y"),
15540 TestToken::eof("parser-test", 2, 1, 2),
15541 ]);
15542
15543 let tree = parser
15544 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
15545 .expect("fallback recognizer should parse");
15546
15547 assert_eq!(parser.node(tree).text(), "xy");
15548 assert_eq!(parser.input.index(), 2);
15549 let stats = parser.parse_tree_storage().stats();
15550 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
15551 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
15552 assert_eq!(stats.scratch_links, 0);
15553 }
15554
15555 #[test]
15556 fn unknown_predicate_policy_defaults_to_assume_true() {
15557 let atn = predicate_after_token_atn();
15558 let mut parser = mini_parser(vec![
15559 TestToken::new(1).with_text("x"),
15560 TestToken::new(2).with_text("y"),
15561 TestToken::eof("parser-test", 2, 1, 2),
15562 ]);
15563
15564 let (tree, _) = parser
15565 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15566 .expect("unknown predicate should pass under the default policy");
15567
15568 assert_eq!(parser.node(tree).text(), "xy");
15569 assert_eq!(parser.number_of_syntax_errors(), 0);
15570 }
15571
15572 #[test]
15573 fn predicate_gated_same_lookahead_uses_viable_alternative() {
15574 let atn = predicate_gated_same_lookahead_atn([0, 1]);
15575 let mut parser = mini_parser(vec![
15576 TestToken::new(1).with_text("x"),
15577 TestToken::eof("parser-test", 1, 1, 1),
15578 ]);
15579
15580 let (tree, _) = parser
15581 .parse_atn_rule_with_runtime_options(
15582 &atn,
15583 0,
15584 ParserRuntimeOptions {
15585 predicates: &[
15586 (0, 0, ParserPredicate::False),
15587 (0, 1, ParserPredicate::True),
15588 ],
15589 ..ParserRuntimeOptions::default()
15590 },
15591 )
15592 .expect("the second predicate-gated alternative should match");
15593
15594 assert_eq!(parser.node(tree).text(), "x<EOF>");
15595 assert_eq!(parser.number_of_syntax_errors(), 0);
15596 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
15597 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
15598 }
15599
15600 #[test]
15601 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
15602 let atn = token_then_eof_atn();
15606 let mut parser = mini_parser(vec![
15607 TestToken::new(1).with_text("x"),
15608 TestToken::eof("parser-test", 1, 1, 1),
15609 ]);
15610
15611 parser.unknown_predicate_hits.push((7, 3));
15613
15614 parser
15616 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15617 .expect("child rule parses");
15618
15619 let error = parser
15621 .take_unknown_semantic_error()
15622 .expect("parent's recorded coordinate must survive the nested interpreted parse");
15623 let AntlrError::Unsupported(message) = error else {
15624 panic!("expected AntlrError::Unsupported, got {error:?}");
15625 };
15626 assert!(message.contains("pred_index=3"), "message: {message}");
15627 }
15628
15629 #[test]
15630 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
15631 let atn = predicate_after_token_atn();
15632 let mut parser = mini_parser(vec![
15633 TestToken::new(1).with_text("x"),
15634 TestToken::new(2).with_text("y"),
15635 TestToken::eof("parser-test", 2, 1, 2),
15636 ]);
15637
15638 let result = parser.parse_atn_rule_with_runtime_options(
15639 &atn,
15640 0,
15641 ParserRuntimeOptions {
15642 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
15643 ..ParserRuntimeOptions::default()
15644 },
15645 );
15646
15647 assert!(
15648 result.is_err(),
15649 "the only path is predicate-guarded, so assume-false must fail the parse"
15650 );
15651 }
15652
15653 #[test]
15654 fn predicate_failure_message_keeps_semantic_recovery_path() {
15655 let atn = predicate_after_token_atn();
15656 let mut parser = mini_parser(vec![
15657 TestToken::new(1).with_text("x"),
15658 TestToken::new(2).with_text("y"),
15659 TestToken::eof("parser-test", 2, 1, 2),
15660 ]);
15661
15662 let (tree, _) = parser
15663 .parse_atn_rule_with_runtime_options(
15664 &atn,
15665 0,
15666 ParserRuntimeOptions {
15667 predicates: &[(
15668 0,
15669 0,
15670 ParserPredicate::FalseWithMessage {
15671 message: "predicate rejected input",
15672 },
15673 )],
15674 ..ParserRuntimeOptions::default()
15675 },
15676 )
15677 .expect("failure-message predicates recover through the semantic interpreter");
15678
15679 assert_eq!(parser.node(tree).text(), "xy");
15680 assert_eq!(parser.number_of_syntax_errors(), 1);
15681 assert!(
15682 parser.fast_predicate_cache.is_empty(),
15683 "failure-message predicates need the semantic interpreter's recovery outcome"
15684 );
15685 }
15686
15687 #[test]
15688 fn unknown_predicate_policy_error_names_the_coordinate() {
15689 let atn = predicate_after_token_atn();
15690 let mut parser = mini_parser(vec![
15691 TestToken::new(1).with_text("x"),
15692 TestToken::new(2).with_text("y"),
15693 TestToken::eof("parser-test", 2, 1, 2),
15694 ]);
15695
15696 let error = parser
15697 .parse_atn_rule_with_runtime_options(
15698 &atn,
15699 0,
15700 ParserRuntimeOptions {
15701 unknown_predicate_policy: UnknownSemanticPolicy::Error,
15702 ..ParserRuntimeOptions::default()
15703 },
15704 )
15705 .expect_err("evaluating an unknown predicate under Error policy must fail");
15706
15707 let AntlrError::Unsupported(message) = error else {
15708 panic!("expected AntlrError::Unsupported, got {error:?}");
15709 };
15710 assert!(
15711 message.contains("unsupported semantic predicate"),
15712 "message should name the failure class: {message}"
15713 );
15714 assert!(
15715 message.contains("pred_index=0"),
15716 "message should carry the coordinate: {message}"
15717 );
15718 }
15719
15720 #[test]
15721 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
15722 let atn = predicate_after_token_atn();
15728 let mut parser = mini_parser(vec![
15729 TestToken::new(1).with_text("x"),
15730 TestToken::new(2).with_text("y"),
15731 TestToken::eof("parser-test", 2, 1, 2),
15732 ]);
15733
15734 parser
15735 .parse_atn_rule_with_runtime_options(
15736 &atn,
15737 0,
15738 ParserRuntimeOptions {
15739 unknown_predicate_policy: UnknownSemanticPolicy::Error,
15740 ..ParserRuntimeOptions::default()
15741 },
15742 )
15743 .expect_err("first parse fails loud under the Error policy");
15744
15745 parser.reset_unknown_semantic_hits();
15750 assert!(
15751 parser.take_unknown_semantic_error().is_none(),
15752 "reset must drop stale unknown-predicate coordinates before a reused parse"
15753 );
15754 }
15755
15756 #[derive(Debug, Default)]
15757 struct RecordingHooks {
15758 predicates: Vec<(usize, usize, usize, Option<String>)>,
15759 actions: Vec<(usize, String, Option<String>)>,
15760 action_trees: Vec<Option<String>>,
15761 }
15762
15763 impl SemanticHooks for RecordingHooks {
15764 fn sempred<S>(
15765 &mut self,
15766 ctx: &mut ParserSemCtx<'_, S>,
15767 rule_index: usize,
15768 pred_index: usize,
15769 ) -> Option<bool>
15770 where
15771 S: TokenSource,
15772 {
15773 self.predicates.push((
15774 ctx.input_index(),
15775 rule_index,
15776 pred_index,
15777 ctx.token_text(1).map(|token| token.text().to_owned()),
15778 ));
15779 Some(true)
15780 }
15781
15782 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
15783 where
15784 S: TokenSource,
15785 {
15786 self.actions.push((
15787 action.source_state(),
15788 ctx.action_text(),
15789 ctx.rule_name().map(str::to_owned),
15790 ));
15791 self.action_trees.push(ctx.tree().map(Node::text));
15792 true
15793 }
15794 }
15795
15796 #[derive(Debug, Default)]
15797 struct RejectingPredicateHooks {
15798 predicates: Vec<(usize, usize, usize, Option<String>)>,
15799 }
15800
15801 impl SemanticHooks for RejectingPredicateHooks {
15802 fn sempred<S>(
15803 &mut self,
15804 ctx: &mut ParserSemCtx<'_, S>,
15805 rule_index: usize,
15806 pred_index: usize,
15807 ) -> Option<bool>
15808 where
15809 S: TokenSource,
15810 {
15811 self.predicates.push((
15812 ctx.input_index(),
15813 rule_index,
15814 pred_index,
15815 ctx.token_text(1).map(|token| token.text().to_owned()),
15816 ));
15817 Some(false)
15818 }
15819 }
15820
15821 #[test]
15822 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
15823 let atn = predicate_gated_same_lookahead_atn([0, 0]);
15824 let mut parser = mini_parser_with_hooks(
15825 vec![
15826 TestToken::new(1).with_text("x"),
15827 TestToken::eof("parser-test", 1, 1, 1),
15828 ],
15829 RecordingHooks::default(),
15830 );
15831
15832 let (tree, _) = parser
15833 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15834 .expect("both alternatives share one replay-safe predicate result");
15835
15836 assert_eq!(parser.node(tree).text(), "x<EOF>");
15837 assert_eq!(
15838 parser.semantic_hooks.predicates,
15839 vec![(0, 0, 0, Some("x".to_owned()))]
15840 );
15841 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
15842 }
15843
15844 #[test]
15845 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
15846 let atn = predicate_after_token_atn();
15847 let mut parser = mini_parser_with_hooks(
15848 vec![
15849 TestToken::new(1).with_text("x"),
15850 TestToken::new(2).with_text("y"),
15851 TestToken::eof("parser-test", 2, 1, 2),
15852 ],
15853 RecordingHooks::default(),
15854 );
15855
15856 let (tree, _) = parser
15857 .parse_atn_rule_with_runtime_options(
15858 &atn,
15859 0,
15860 ParserRuntimeOptions {
15861 unknown_predicate_policy: UnknownSemanticPolicy::Error,
15862 ..ParserRuntimeOptions::default()
15863 },
15864 )
15865 .expect("hook supplies the missing predicate result");
15866
15867 assert_eq!(parser.node(tree).text(), "xy");
15868 assert_eq!(
15869 parser.semantic_hooks.predicates,
15870 vec![(1, 0, 0, Some("y".to_owned()))]
15871 );
15872 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
15873 }
15874
15875 #[test]
15876 fn runtime_options_default_preserves_semantic_hook_predicates() {
15877 let atn = predicate_after_token_atn();
15878 let mut parser = mini_parser_with_hooks(
15879 vec![
15880 TestToken::new(1).with_text("x"),
15881 TestToken::new(2).with_text("y"),
15882 TestToken::eof("parser-test", 2, 1, 2),
15883 ],
15884 RejectingPredicateHooks::default(),
15885 );
15886
15887 let result =
15888 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
15889
15890 assert!(
15891 result.is_err(),
15892 "default runtime options must not bypass semantic hooks for predicate ATNs"
15893 );
15894 assert_eq!(
15895 parser.semantic_hooks.predicates,
15896 vec![(1, 0, 0, Some("y".to_owned()))]
15897 );
15898 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
15899 }
15900
15901 #[test]
15902 fn semantic_hook_handles_committed_parser_action() {
15903 let atn = token_then_eof_atn();
15904 let mut parser = mini_parser_with_hooks(
15905 vec![
15906 TestToken::new(1).with_text("x"),
15907 TestToken::eof("parser-test", 1, 1, 1),
15908 ],
15909 RecordingHooks::default(),
15910 );
15911 let (tree, _) = parser
15912 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15913 .expect("rule parses before action hook is tested");
15914
15915 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
15916 assert_eq!(
15917 parser.semantic_hooks.actions,
15918 vec![(42, "x".to_owned(), Some("s".to_owned()))]
15919 );
15920 assert_eq!(
15921 parser.semantic_hooks.action_trees,
15922 [Some("x<EOF>".to_owned())]
15923 );
15924 }
15925
15926 #[test]
15927 fn unhandled_committed_action_fails_loud_under_error_policy() {
15928 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
15932 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
15933 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
15934
15935 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
15937
15938 let error = parser
15939 .take_unknown_semantic_error()
15940 .expect("an unhandled committed action under Error policy must fail loud");
15941 let AntlrError::Unsupported(message) = error else {
15942 panic!("expected AntlrError::Unsupported, got {error:?}");
15943 };
15944 assert!(
15945 message.contains("unhandled semantic action") && message.contains("state=42"),
15946 "message should name the dropped action coordinate: {message}"
15947 );
15948
15949 let mut lenient =
15951 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
15952 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
15953 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
15954 assert!(lenient.take_unknown_semantic_error().is_none());
15955 }
15956
15957 #[test]
15958 fn translated_predicate_is_unaffected_by_error_policy() {
15959 let atn = predicate_after_token_atn();
15960 let mut parser = mini_parser(vec![
15961 TestToken::new(1).with_text("x"),
15962 TestToken::new(2).with_text("y"),
15963 TestToken::eof("parser-test", 2, 1, 2),
15964 ]);
15965
15966 let (tree, _) = parser
15967 .parse_atn_rule_with_runtime_options(
15968 &atn,
15969 0,
15970 ParserRuntimeOptions {
15971 predicates: &[(0, 0, ParserPredicate::True)],
15972 unknown_predicate_policy: UnknownSemanticPolicy::Error,
15973 ..ParserRuntimeOptions::default()
15974 },
15975 )
15976 .expect("a predicate covered by the table is not an unknown coordinate");
15977
15978 assert_eq!(parser.node(tree).text(), "xy");
15979 }
15980
15981 fn hook_predicate_semantics() -> ParserSemantics {
15986 let mut ir = SemIr::new();
15987 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
15988 ParserSemantics {
15989 ir,
15990 predicates: vec![ParserSemanticPredicate {
15991 rule_index: 0,
15992 pred_index: 0,
15993 expr,
15994 failure_message: None,
15995 }],
15996 actions: Vec::new(),
15997 }
15998 }
15999
16000 #[derive(Debug, Default)]
16001 struct DecliningHooks;
16002
16003 impl SemanticHooks for DecliningHooks {}
16004
16005 #[test]
16006 fn semir_hook_none_falls_through_to_assume_true() {
16007 let atn = predicate_after_token_atn();
16008 let semantics = hook_predicate_semantics();
16009 let mut parser = mini_parser_with_hooks(
16010 vec![
16011 TestToken::new(1).with_text("x"),
16012 TestToken::new(2).with_text("y"),
16013 TestToken::eof("parser-test", 2, 1, 2),
16014 ],
16015 DecliningHooks,
16016 );
16017
16018 let (tree, _) = parser
16019 .parse_atn_rule_with_runtime_options(
16020 &atn,
16021 0,
16022 ParserRuntimeOptions {
16023 semantics: Some(&semantics),
16024 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
16025 ..ParserRuntimeOptions::default()
16026 },
16027 )
16028 .expect("a declined SemIR hook must pass under assume-true");
16029
16030 assert_eq!(parser.node(tree).text(), "xy");
16031 }
16032
16033 #[test]
16034 fn semir_hook_none_falls_through_to_assume_false() {
16035 let atn = predicate_after_token_atn();
16036 let semantics = hook_predicate_semantics();
16037 let mut parser = mini_parser_with_hooks(
16038 vec![
16039 TestToken::new(1).with_text("x"),
16040 TestToken::new(2).with_text("y"),
16041 TestToken::eof("parser-test", 2, 1, 2),
16042 ],
16043 DecliningHooks,
16044 );
16045
16046 let result = parser.parse_atn_rule_with_runtime_options(
16047 &atn,
16048 0,
16049 ParserRuntimeOptions {
16050 semantics: Some(&semantics),
16051 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
16052 ..ParserRuntimeOptions::default()
16053 },
16054 );
16055
16056 assert!(
16057 result.is_err(),
16058 "a declined SemIR hook must fail the only guarded path under assume-false"
16059 );
16060 }
16061
16062 #[test]
16063 fn semir_hook_none_records_coordinate_under_error_policy() {
16064 let atn = predicate_after_token_atn();
16065 let semantics = hook_predicate_semantics();
16066 let mut parser = mini_parser_with_hooks(
16067 vec![
16068 TestToken::new(1).with_text("x"),
16069 TestToken::new(2).with_text("y"),
16070 TestToken::eof("parser-test", 2, 1, 2),
16071 ],
16072 DecliningHooks,
16073 );
16074
16075 let error = parser
16076 .parse_atn_rule_with_runtime_options(
16077 &atn,
16078 0,
16079 ParserRuntimeOptions {
16080 semantics: Some(&semantics),
16081 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16082 ..ParserRuntimeOptions::default()
16083 },
16084 )
16085 .expect_err("a declined SemIR hook under Error policy must fail the parse");
16086
16087 let AntlrError::Unsupported(message) = error else {
16088 panic!("expected AntlrError::Unsupported, got {error:?}");
16089 };
16090 assert!(
16091 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
16092 "message should name the unresolved coordinate: {message}"
16093 );
16094 }
16095
16096 #[test]
16097 fn generated_direct_predicate_honors_installed_policy() {
16098 let semantics = hook_predicate_semantics();
16104 let context = ParserRuleContext::new(0, -1);
16105
16106 let mut assume_true =
16107 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16108 assert!(
16109 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
16110 &semantics, 0, 0, &context, 0
16111 ),
16112 "default AssumeTrue accepts a declined hook"
16113 );
16114 assert!(assume_true.take_unknown_semantic_error().is_none());
16115
16116 let mut error_policy =
16117 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16118 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
16119 assert!(
16120 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
16121 &semantics, 0, 0, &context, 0
16122 ),
16123 "Error policy rejects a declined hook on the generated-direct path"
16124 );
16125 let error = error_policy
16126 .take_unknown_semantic_error()
16127 .expect("Error policy records the unresolved coordinate for the generated path");
16128 let AntlrError::Unsupported(message) = error else {
16129 panic!("expected AntlrError::Unsupported, got {error:?}");
16130 };
16131 assert!(message.contains("pred_index=0"), "message: {message}");
16132 }
16133
16134 #[test]
16135 fn parser_rule_start_skips_leading_hidden_tokens() {
16136 let atn = token_then_eof_atn();
16137 let mut parser = mini_parser(vec![
16138 TestToken::new(99)
16139 .with_text(" ")
16140 .with_channel(HIDDEN_CHANNEL),
16141 TestToken::new(1).with_text("x"),
16142 TestToken::eof("parser-test", 2, 1, 2),
16143 ]);
16144
16145 let tree = parser
16146 .parse_atn_rule(&atn, 0)
16147 .expect("artificial parser rule should parse");
16148 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
16149 panic!("rule node should be present");
16150 };
16151 assert_eq!(
16152 rule.start()
16153 .expect("rule should have a start token")
16154 .token_type(),
16155 1
16156 );
16157 }
16158
16159 #[test]
16160 fn parser_action_after_eof_stops_at_eof_token() {
16161 let atn = eof_then_action_atn();
16162 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
16163
16164 let (_, actions) = parser
16165 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16166 .expect("EOF action rule should parse");
16167
16168 assert_eq!(actions.len(), 1);
16169 assert_eq!(actions[0].stop_index(), Some(0));
16170 assert_eq!(
16171 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
16172 ""
16173 );
16174 }
16175
16176 #[test]
16177 fn after_action_stop_uses_rule_context_stop_not_cursor() {
16178 let mut id = TestToken::new(1).with_text("x");
16183 id.set_token_index(0);
16184 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
16185 eof.set_token_index(1);
16186 let mut parser = mini_parser(vec![id.clone(), eof]);
16187 parser.consume();
16189 assert_eq!(parser.la(1), TOKEN_EOF);
16190
16191 let mut ctx = ParserRuleContext::new(0, 0);
16194 parser.set_context_stop(
16195 &mut ctx,
16196 parser.token_id_at(0).expect("ID token should be buffered"),
16197 );
16198 let tree = parser.rule_node(ctx);
16199
16200 let current_index = parser.input.index();
16201 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
16203 assert_eq!(
16205 parser.after_action_stop_index_for_tree(tree, current_index),
16206 Some(0)
16207 );
16208 }
16209
16210 #[test]
16211 fn after_action_start_uses_rule_context_start_not_cursor() {
16212 let mut parser = mini_parser(vec![
16217 TestToken::new(9)
16218 .with_text(" ")
16219 .with_channel(HIDDEN_CHANNEL),
16220 TestToken::new(9)
16221 .with_text(" ")
16222 .with_channel(HIDDEN_CHANNEL),
16223 TestToken::new(1).with_text("x"),
16224 TestToken::eof("parser-test", 3, 1, 3),
16225 ]);
16226
16227 let mut ctx = ParserRuleContext::new(0, 0);
16228 parser.set_context_start(
16229 &mut ctx,
16230 parser.token_id_at(2).expect("ID token should be buffered"),
16231 );
16232 let tree = parser.rule_node(ctx);
16233
16234 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
16237
16238 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
16240 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
16241 }
16242
16243 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
16244 FastRecognizeOutcome {
16245 index,
16246 consumed_eof,
16247 diagnostics: DiagnosticSeqId::EMPTY,
16248 deferred_nodes: FastDeferredNodeId::EMPTY,
16249 nodes: NodeSeqId(marker),
16250 }
16251 }
16252
16253 #[test]
16254 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
16255 let mut outcomes = vec![
16256 clean_fast_outcome(4, false, 0),
16257 clean_fast_outcome(2, false, 1),
16258 clean_fast_outcome(4, false, 2),
16259 clean_fast_outcome(4, true, 3),
16260 clean_fast_outcome(2, false, 4),
16261 ];
16262 let mut scratch = FastOutcomeDedupScratch::default();
16263
16264 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16265
16266 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
16267 assert_eq!(
16268 outcomes
16269 .iter()
16270 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
16271 .collect::<Vec<_>>(),
16272 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
16273 );
16274 assert!(scratch.dense_words.is_empty());
16275 assert!(scratch.sparse_keys.is_empty());
16276 }
16277
16278 #[test]
16279 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
16280 let mut scratch = FastOutcomeDedupScratch::default();
16281 let mut outcomes = (100..109)
16282 .flat_map(|index| {
16283 [
16284 clean_fast_outcome(
16285 index,
16286 false,
16287 u32::try_from(index).expect("test index fits in u32"),
16288 ),
16289 clean_fast_outcome(index, false, u32::MAX),
16290 ]
16291 })
16292 .collect();
16293
16294 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16295
16296 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
16297 assert_eq!(outcomes.len(), 9);
16298 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
16299 let dense_capacity = scratch.dense_words.capacity();
16300
16301 let mut reused = (1_000..1_009)
16302 .map(|index| {
16303 clean_fast_outcome(
16304 index,
16305 false,
16306 u32::try_from(index).expect("test index fits in u32"),
16307 )
16308 })
16309 .collect();
16310 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
16311
16312 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
16313 assert_eq!(reused.len(), 9);
16314 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
16315 }
16316
16317 #[test]
16318 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
16319 let mut scratch = FastOutcomeDedupScratch::default();
16320 let sparse_indexes = [
16321 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
16322 ];
16323 let mut outcomes = sparse_indexes
16324 .into_iter()
16325 .chain([400_000])
16326 .enumerate()
16327 .map(|(marker, index)| {
16328 clean_fast_outcome(
16329 index,
16330 false,
16331 u32::try_from(marker).expect("test marker fits in u32"),
16332 )
16333 })
16334 .collect();
16335
16336 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16337
16338 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16339 assert_eq!(outcomes.len(), sparse_indexes.len());
16340 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
16341 let sparse_capacity = scratch.sparse_keys.capacity();
16342
16343 let mut reused = sparse_indexes
16344 .into_iter()
16345 .map(|index| {
16346 clean_fast_outcome(
16347 index,
16348 false,
16349 u32::try_from(index).expect("test index fits in u32"),
16350 )
16351 })
16352 .collect();
16353 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
16354
16355 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16356 assert_eq!(reused.len(), sparse_indexes.len());
16357 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
16358 }
16359
16360 #[test]
16361 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
16362 let mut scratch = FastOutcomeDedupScratch::default();
16363 scratch
16364 .sparse_keys
16365 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
16366 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
16367 let mut outcomes = (0..9)
16368 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
16369 .collect();
16370
16371 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16372
16373 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16374 assert!(scratch.sparse_keys.is_empty());
16375 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
16376 }
16377
16378 #[test]
16379 fn fast_outcome_selection_respects_sll_tie_order() {
16380 let mut arena = RecognitionArena::default();
16381 let first = FastRecognizeOutcome {
16382 index: 1,
16383 consumed_eof: false,
16384 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16385 line: 1,
16386 column: 0,
16387 message: "mismatched input 'x'".to_owned(),
16388 }]),
16389 deferred_nodes: FastDeferredNodeId::EMPTY,
16390 nodes: NodeSeqId::EMPTY,
16391 };
16392 let second = FastRecognizeOutcome {
16393 index: first.index,
16394 consumed_eof: first.consumed_eof,
16395 diagnostics: DiagnosticSeqId::EMPTY,
16396 deferred_nodes: FastDeferredNodeId::EMPTY,
16397 nodes: NodeSeqId::EMPTY,
16398 };
16399
16400 let selected = select_best_fast_outcome(
16401 [first, second].into_iter(),
16402 PredictionMode::Sll,
16403 None,
16404 |_| panic!("caller-follow token probe should not run"),
16405 &arena,
16406 )
16407 .expect("one outcome should be selected");
16408 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
16409 let eof_second = FastRecognizeOutcome {
16410 index: second.index,
16411 consumed_eof: true,
16412 diagnostics: DiagnosticSeqId::EMPTY,
16413 deferred_nodes: FastDeferredNodeId::EMPTY,
16414 nodes: NodeSeqId::EMPTY,
16415 };
16416 let selected = select_best_fast_outcome(
16417 [first, eof_second].into_iter(),
16418 PredictionMode::Sll,
16419 None,
16420 |_| panic!("caller-follow token probe should not run"),
16421 &arena,
16422 )
16423 .expect("one outcome should be selected");
16424 assert!(!selected.consumed_eof);
16425 let selected = select_best_fast_outcome(
16426 [first, second].into_iter(),
16427 PredictionMode::Ll,
16428 None,
16429 |_| panic!("caller-follow token probe should not run"),
16430 &arena,
16431 )
16432 .expect("one outcome should be selected");
16433 assert!(selected.diagnostics.is_empty());
16434 }
16435
16436 #[test]
16437 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
16438 let mut arena = RecognitionArena::default();
16439 let first = FastRecognizeOutcome {
16440 index: 3,
16441 consumed_eof: false,
16442 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16443 line: 1,
16444 column: 0,
16445 message: "mismatched input 'x' expecting 'a'".to_owned(),
16446 }]),
16447 deferred_nodes: FastDeferredNodeId::EMPTY,
16448 nodes: NodeSeqId::EMPTY,
16449 };
16450 let same_rank = FastRecognizeOutcome {
16451 index: first.index,
16452 consumed_eof: first.consumed_eof,
16453 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16454 line: 1,
16455 column: 0,
16456 message: "mismatched input 'x' expecting 'b'".to_owned(),
16457 }]),
16458 deferred_nodes: FastDeferredNodeId::EMPTY,
16459 nodes: NodeSeqId::EMPTY,
16460 };
16461 let better_rank = FastRecognizeOutcome {
16462 index: first.index,
16463 consumed_eof: first.consumed_eof,
16464 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16465 line: 1,
16466 column: 0,
16467 message: "missing 'a' at 'x'".to_owned(),
16468 }]),
16469 deferred_nodes: FastDeferredNodeId::EMPTY,
16470 nodes: NodeSeqId::EMPTY,
16471 };
16472 let mut outcomes = vec![first, same_rank, better_rank];
16473
16474 dedupe_fast_outcomes(&mut outcomes, &arena);
16475
16476 assert_eq!(outcomes.len(), 2);
16477 assert_eq!(
16478 arena
16479 .diagnostics(outcomes[0].diagnostics)
16480 .next()
16481 .expect("first diagnostic")
16482 .message,
16483 "mismatched input 'x' expecting 'a'"
16484 );
16485 assert_eq!(
16486 arena
16487 .diagnostics(outcomes[1].diagnostics)
16488 .next()
16489 .expect("second diagnostic")
16490 .message,
16491 "missing 'a' at 'x'"
16492 );
16493 }
16494
16495 #[test]
16496 fn fast_outcome_selection_prefers_generated_caller_follow() {
16497 let arena = RecognitionArena::default();
16498 let earlier = FastRecognizeOutcome {
16499 index: 7,
16500 consumed_eof: false,
16501 diagnostics: DiagnosticSeqId::EMPTY,
16502 deferred_nodes: FastDeferredNodeId::EMPTY,
16503 nodes: NodeSeqId::EMPTY,
16504 };
16505 let later = FastRecognizeOutcome {
16506 index: 8,
16507 consumed_eof: false,
16508 diagnostics: DiagnosticSeqId::EMPTY,
16509 deferred_nodes: FastDeferredNodeId::EMPTY,
16510 nodes: NodeSeqId::EMPTY,
16511 };
16512 let mut follow = TokenBitSet::default();
16513 follow.insert(5);
16514
16515 let selected = select_best_fast_outcome(
16516 [later, earlier].into_iter(),
16517 PredictionMode::Ll,
16518 Some(&follow),
16519 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
16520 &arena,
16521 )
16522 .expect("one outcome should be selected");
16523 assert_eq!(selected.index, 7);
16524
16525 let selected = select_best_fast_outcome(
16526 [later, earlier].into_iter(),
16527 PredictionMode::Ll,
16528 Some(&follow),
16529 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
16530 &arena,
16531 )
16532 .expect("one outcome should be selected");
16533 assert_eq!(selected.index, 8);
16534
16535 let indented_next_statement = FastRecognizeOutcome {
16536 index: 9,
16537 consumed_eof: false,
16538 diagnostics: DiagnosticSeqId::EMPTY,
16539 deferred_nodes: FastDeferredNodeId::EMPTY,
16540 nodes: NodeSeqId::EMPTY,
16541 };
16542 let selected = select_best_fast_outcome(
16543 [indented_next_statement, earlier].into_iter(),
16544 PredictionMode::Ll,
16545 Some(&follow),
16546 |index| {
16547 let is_boundary = index == 7;
16548 let is_boundary_gap = matches!(index, 7 | 8);
16549 (
16550 if index == 7 { 5 } else { TOKEN_EOF },
16551 is_boundary,
16552 is_boundary_gap,
16553 )
16554 },
16555 &arena,
16556 )
16557 .expect("one outcome should be selected");
16558 assert_eq!(selected.index, 7);
16559
16560 let continuation = FastRecognizeOutcome {
16561 index: 10,
16562 consumed_eof: false,
16563 diagnostics: DiagnosticSeqId::EMPTY,
16564 deferred_nodes: FastDeferredNodeId::EMPTY,
16565 nodes: NodeSeqId::EMPTY,
16566 };
16567 let selected = select_best_fast_outcome(
16568 [continuation, earlier].into_iter(),
16569 PredictionMode::Ll,
16570 Some(&follow),
16571 |index| {
16572 let is_boundary = matches!(index, 7 | 9);
16573 (
16574 if index == 7 { 5 } else { TOKEN_EOF },
16575 is_boundary,
16576 is_boundary,
16577 )
16578 },
16579 &arena,
16580 )
16581 .expect("one outcome should be selected");
16582 assert_eq!(selected.index, 10);
16583
16584 let selected = select_best_fast_outcome(
16585 [earlier, later].into_iter(),
16586 PredictionMode::Sll,
16587 Some(&follow),
16588 |_| panic!("caller-follow token probe should not run in SLL mode"),
16589 &arena,
16590 )
16591 .expect("one outcome should be selected");
16592 assert_eq!(selected.index, 8);
16593 }
16594
16595 #[test]
16596 fn caller_follow_boundary_text_requires_separator_shape() {
16597 assert!(is_caller_follow_boundary_text(";"));
16598 assert!(is_caller_follow_boundary_text("\n"));
16599 assert!(is_caller_follow_boundary_text("\r\n "));
16600 assert!(is_caller_follow_boundary_text(";\n"));
16601 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
16602 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
16603 assert!(!is_caller_follow_boundary_text("identifier"));
16604 assert!(is_caller_follow_boundary_gap_text(" \t "));
16605 assert!(is_caller_follow_boundary_gap_text("\n "));
16606 assert!(is_caller_follow_boundary_gap_text(";\t"));
16607 assert!(!is_caller_follow_boundary_gap_text(
16608 "\"\"\"line1\nline2\"\"\""
16609 ));
16610 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
16611 }
16612
16613 #[test]
16614 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
16615 let mut parser = mini_parser(vec![
16616 TestToken::new(5).with_text("\n"),
16617 TestToken::new(6)
16618 .with_text("// comment\n")
16619 .with_channel(HIDDEN_CHANNEL),
16620 TestToken::new(1).with_text("x"),
16621 TestToken::eof("parser-test", 1, 2, 0),
16622 ]);
16623
16624 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
16625 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
16626 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
16627 }
16628
16629 #[test]
16630 fn caller_follow_token_info_uses_stream_visible_channel() {
16631 let source = Source {
16632 tokens: vec![
16633 TestToken::new(5).with_text("\n").with_channel(2),
16634 TestToken::new(1).with_text("x").with_channel(2),
16635 TestToken::new(6)
16636 .with_text("// comment\n")
16637 .with_channel(HIDDEN_CHANNEL),
16638 TestToken::eof("parser-test", 1, 2, 0),
16639 ],
16640 index: 0,
16641 };
16642 let data = RecognizerData::new(
16643 "Mini.g4",
16644 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
16645 );
16646 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
16647
16648 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
16649 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
16650 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
16651 }
16652
16653 #[test]
16654 fn reset_per_parse_caches_clears_state_expected_token_cache() {
16655 let atn = token_then_eof_atn();
16656 let mut parser = mini_parser(Vec::new());
16657
16658 let _ = parser.cached_state_expected_token_set(&atn, 0);
16659 assert!(!parser.state_expected_token_cache.is_empty());
16660
16661 parser.reset_per_parse_caches();
16662 assert!(parser.state_expected_token_cache.is_empty());
16663 }
16664
16665 #[test]
16666 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
16667 let cyclic = epsilon_cycle_atn();
16668 let acyclic = token_then_eof_atn();
16669 let mut parser = mini_parser(Vec::new());
16670
16671 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
16672 assert_eq!(
16673 parser.empty_cycle_cache_atn,
16674 Some(SharedAtnCacheKey::for_atn(&cyclic))
16675 );
16676 assert_eq!(parser.empty_cycle_cache[1], Some(true));
16677
16678 parser.reset_per_parse_caches();
16679 assert_eq!(parser.empty_cycle_cache[1], Some(true));
16680 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
16681
16682 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
16683 assert_eq!(
16684 parser.empty_cycle_cache_atn,
16685 Some(SharedAtnCacheKey::for_atn(&acyclic))
16686 );
16687 assert_eq!(parser.empty_cycle_cache[1], Some(false));
16688 }
16689
16690 #[test]
16691 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
16692 let source = Source {
16693 tokens: vec![
16694 TestToken::new(1).with_text("x"),
16695 TestToken::eof("parser-test", 1, 1, 1),
16696 ],
16697 index: 0,
16698 };
16699 let data = RecognizerData::new(
16700 "Mini.g4",
16701 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
16702 );
16703 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
16704 let expected = ExpectedTokens {
16705 index: Some(0),
16706 symbols: BTreeSet::new(),
16707 no_viable: None,
16708 };
16709
16710 let (_, message) = parser.expected_error_message(0, 0, &expected);
16711
16712 assert_eq!(message, "mismatched input 'x'");
16713 }
16714
16715 #[test]
16716 fn eof_rule_stop_index_points_at_eof_token() {
16717 let source = Source {
16718 tokens: vec![
16719 TestToken::new(1).with_text("x"),
16720 TestToken::eof("parser-test", 1, 1, 1),
16721 ],
16722 index: 0,
16723 };
16724 let data = RecognizerData::new(
16725 "Mini.g4",
16726 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
16727 );
16728 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
16729
16730 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
16731 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
16732 }
16733
16734 #[test]
16735 fn generated_parser_action_uses_current_rule_stop_boundary() {
16736 let mut parser = mini_parser(vec![
16737 TestToken::new(1).with_text("x"),
16738 TestToken::eof("parser-test", 1, 1, 1),
16739 ]);
16740
16741 parser.match_token(1).expect("token should match");
16742 let action = parser.parser_action_at_current(7, 0, 0, false);
16743 assert_eq!(action.source_state(), 7);
16744 assert_eq!(action.rule_index(), 0);
16745 assert_eq!(action.start_index(), 0);
16746 assert_eq!(action.stop_index(), Some(0));
16747
16748 parser.match_eof().expect("EOF should match");
16749 let action = parser.parser_action_at_current(8, 0, 0, true);
16750 assert_eq!(action.stop_index(), Some(1));
16751 }
16752
16753 #[test]
16754 fn folds_left_recursive_boundary_into_rule_node() {
16755 let mut arena = RecognitionArena::default();
16756 let first = arena.push_node(ArenaRecognizedNode::Token {
16757 token: TokenId::try_from(0).expect("test token ID"),
16758 });
16759 let boundary =
16760 arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: 1 });
16761 let second = arena.push_node(ArenaRecognizedNode::Token {
16762 token: TokenId::try_from(1).expect("test token ID"),
16763 });
16764 let mut nodes = NodeSeqId::EMPTY;
16765 for node in [first, boundary, second].into_iter().rev() {
16766 nodes = arena.prepend(nodes, node);
16767 }
16768
16769 let folded = arena.fold_left_recursive_boundaries(nodes);
16770 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
16771
16772 assert_eq!(folded_nodes.len(), 2);
16773 let ArenaRecognizedNode::Rule {
16774 rule_index,
16775 invoking_state,
16776 start_index,
16777 stop_index,
16778 children,
16779 ..
16780 } = arena.node(folded_nodes[0])
16781 else {
16782 panic!("first folded node should be a rule");
16783 };
16784 assert_eq!(rule_index, 1);
16785 assert_eq!(invoking_state, -1);
16786 assert_eq!(start_index, 0);
16787 assert_eq!(stop_index, Some(0));
16788 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
16789 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
16790
16791 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
16792 assert_eq!(
16793 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
16794 (4, 3, 1)
16795 );
16796 assert_eq!(
16797 (stats.total_links, stats.live_links, stats.dead_links),
16798 (9, 3, 6)
16799 );
16800 }
16801
16802 #[test]
16803 fn recognition_arena_reports_live_dead_and_retained_capacity() {
16804 let mut arena = RecognitionArena::default();
16805 let token = arena.push_node(ArenaRecognizedNode::Token {
16806 token: TokenId::try_from(0).expect("test token ID"),
16807 });
16808 let extra = arena.push_extra(RecognitionExtra::MissingToken {
16809 token_type: 2,
16810 at_index: 1,
16811 text: "<missing X>".to_owned(),
16812 });
16813 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
16814 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
16815 token: TokenId::try_from(1).expect("test token ID"),
16816 });
16817 let mut live = NodeSeqId::EMPTY;
16818 live = arena.prepend(live, missing);
16819 live = arena.prepend(live, token);
16820 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
16821 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
16822 line: 1,
16823 column: 0,
16824 message: "missing X".to_owned(),
16825 }]);
16826 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
16827 line: 1,
16828 column: 1,
16829 message: "discarded".to_owned(),
16830 }]);
16831 let deferred_children = arena.deferred_fragment(live);
16832 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
16833 rule_index: 0,
16834 invoking_state: -1,
16835 start_index: 0,
16836 stop_index: Some(1),
16837 deferred_children,
16838 children: NodeSeqId::EMPTY,
16839 });
16840
16841 let stats = arena.stats(live, live_diagnostics);
16842
16843 assert_eq!(
16844 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
16845 (3, 2, 1)
16846 );
16847 assert_eq!(
16848 (stats.total_links, stats.live_links, stats.dead_links),
16849 (5, 3, 2)
16850 );
16851 assert_eq!(
16852 (stats.total_extras, stats.live_extras, stats.dead_extras),
16853 (3, 2, 1)
16854 );
16855 assert!(size_of::<SeqLink>() <= 8);
16856 assert!(size_of::<DiagnosticLink>() <= 8);
16857 assert!(size_of::<FastDeferredNode>() <= 12);
16858 assert!(size_of::<FastDeferredRule>() <= 28);
16859 assert!(size_of::<FastRecognizeOutcome>() <= 24);
16860 let capacities = (
16861 stats.node_capacity,
16862 stats.link_capacity,
16863 stats.extra_capacity,
16864 );
16865 let deferred_capacities = (
16866 arena.deferred_nodes.capacity(),
16867 arena.deferred_rules.capacity(),
16868 );
16869
16870 arena.reset();
16871 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
16872 assert_eq!(
16873 (reset.total_nodes, reset.total_links, reset.total_extras),
16874 (0, 0, 0)
16875 );
16876 assert_eq!(
16877 (
16878 reset.node_capacity,
16879 reset.link_capacity,
16880 reset.extra_capacity,
16881 ),
16882 capacities
16883 );
16884 assert!(arena.deferred_nodes.is_empty());
16885 assert!(arena.deferred_rules.is_empty());
16886 assert_eq!(
16887 (
16888 arena.deferred_nodes.capacity(),
16889 arena.deferred_rules.capacity(),
16890 ),
16891 deferred_capacities
16892 );
16893 }
16894
16895 #[test]
16896 fn parser_computes_recognition_arena_stats_on_demand() {
16897 let mut parser = mini_parser(Vec::new());
16898 let live = parser
16899 .recognition_arena
16900 .push_node(ArenaRecognizedNode::Token {
16901 token: TokenId::try_from(0).expect("test token ID"),
16902 });
16903 let discarded = parser
16904 .recognition_arena
16905 .push_node(ArenaRecognizedNode::ErrorToken {
16906 token: TokenId::try_from(1).expect("test token ID"),
16907 });
16908 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
16909 let _discarded_root = parser
16910 .recognition_arena
16911 .prepend(NodeSeqId::EMPTY, discarded);
16912 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
16913
16914 let stats = parser.recognition_arena_stats();
16915
16916 assert_eq!(
16917 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
16918 (2, 1, 1)
16919 );
16920 assert_eq!(
16921 (stats.total_links, stats.live_links, stats.dead_links),
16922 (2, 1, 1)
16923 );
16924 }
16925
16926 #[test]
16927 fn recognition_arena_drops_capacity_above_retention_limit() {
16928 let mut storage = Vec::<u8>::with_capacity(4);
16929 storage.extend([1, 2, 3]);
16930
16931 reset_arena_vec(&mut storage, 3);
16932
16933 assert!(storage.is_empty());
16934 assert_eq!(storage.capacity(), 0);
16935 }
16936
16937 #[test]
16938 fn recognition_arena_concatenates_diagnostics_in_source_order() {
16939 let mut arena = RecognitionArena::default();
16940 let prefix = arena.diagnostic_sequence([
16941 ParserDiagnostic {
16942 line: 1,
16943 column: 0,
16944 message: "first".to_owned(),
16945 },
16946 ParserDiagnostic {
16947 line: 1,
16948 column: 1,
16949 message: "second".to_owned(),
16950 },
16951 ]);
16952 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
16953 line: 1,
16954 column: 2,
16955 message: "third".to_owned(),
16956 }]);
16957 let extras_before = arena.extras.len();
16958
16959 let combined = arena.concat_diagnostics(prefix, suffix);
16960 let messages = arena
16961 .diagnostics(combined)
16962 .map(|diagnostic| diagnostic.message.as_str())
16963 .collect::<Vec<_>>();
16964
16965 assert_eq!(messages, ["first", "second", "third"]);
16966 assert_eq!(arena.extras.len(), extras_before);
16967 }
16968
16969 #[test]
16970 fn outcome_ties_keep_later_non_recursive_alternative() {
16971 let arena = RecognitionArena::default();
16972 let first = RecognizeOutcome {
16973 index: 1,
16974 consumed_eof: false,
16975 alt_number: 0,
16976 member_values: BTreeMap::new(),
16977 return_values: BTreeMap::new(),
16978 diagnostics: DiagnosticSeqId::EMPTY,
16979 decisions: Vec::new(),
16980 actions: vec![ParserAction::new(1, 0, 0, None)],
16981 nodes: NodeSeqId::EMPTY,
16982 };
16983 let second = RecognizeOutcome {
16984 actions: vec![ParserAction::new(2, 0, 0, None)],
16985 ..first.clone()
16986 };
16987
16988 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
16989 .expect("one outcome should be selected");
16990 assert_eq!(selected.actions[0].source_state(), 2);
16991 }
16992
16993 #[test]
16994 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
16995 let arena = RecognitionArena::default();
16996 let first = RecognizeOutcome {
16997 index: 1,
16998 consumed_eof: false,
16999 alt_number: 0,
17000 member_values: BTreeMap::new(),
17001 return_values: BTreeMap::new(),
17002 diagnostics: DiagnosticSeqId::EMPTY,
17003 decisions: Vec::new(),
17004 actions: vec![ParserAction::new(1, 0, 0, None)],
17005 nodes: NodeSeqId::EMPTY,
17006 };
17007 let second = RecognizeOutcome {
17008 actions: vec![
17009 ParserAction::new(2, 0, 0, None),
17010 ParserAction::new(3, 0, 0, None),
17011 ],
17012 ..first.clone()
17013 };
17014
17015 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
17016 .expect("one outcome should be selected");
17017 assert_eq!(selected.actions.len(), 2);
17018 }
17019
17020 #[test]
17021 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
17022 let arena = RecognitionArena::default();
17023 let first = RecognizeOutcome {
17024 index: 7,
17025 consumed_eof: false,
17026 alt_number: 0,
17027 member_values: BTreeMap::new(),
17028 return_values: BTreeMap::new(),
17029 diagnostics: DiagnosticSeqId::EMPTY,
17030 decisions: vec![1, 0],
17031 actions: vec![
17032 ParserAction::new(23, 2, 2, Some(4)),
17033 ParserAction::new(23, 2, 0, Some(6)),
17034 ],
17035 nodes: NodeSeqId::EMPTY,
17036 };
17037 let second = RecognizeOutcome {
17038 decisions: vec![0, 1],
17039 actions: vec![
17040 ParserAction::new(23, 2, 2, Some(6)),
17041 ParserAction::new(23, 2, 0, Some(6)),
17042 ],
17043 ..first.clone()
17044 };
17045
17046 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17047 .expect("one outcome should be selected");
17048 assert_eq!(selected.actions[0].stop_index(), Some(6));
17049 }
17050
17051 #[test]
17052 fn outcome_ties_keep_first_recursive_tree_shape() {
17053 let mut arena = RecognitionArena::default();
17054 let token = arena.push_node(ArenaRecognizedNode::Token {
17055 token: TokenId::try_from(0).expect("test token ID"),
17056 });
17057 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
17058 let inner = arena.push_node(ArenaRecognizedNode::Rule {
17059 rule_index: 1,
17060 invoking_state: -1,
17061 alt_number: 0,
17062 start_index: 0,
17063 stop_index: Some(0),
17064 return_values: None,
17065 children: token_children,
17066 });
17067 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
17068 let outer = arena.push_node(ArenaRecognizedNode::Rule {
17069 rule_index: 1,
17070 invoking_state: -1,
17071 alt_number: 0,
17072 start_index: 0,
17073 stop_index: Some(0),
17074 return_values: None,
17075 children: inner_children,
17076 });
17077 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
17078 let first = RecognizeOutcome {
17079 index: 1,
17080 consumed_eof: false,
17081 alt_number: 0,
17082 member_values: BTreeMap::new(),
17083 return_values: BTreeMap::new(),
17084 diagnostics: DiagnosticSeqId::EMPTY,
17085 decisions: Vec::new(),
17086 actions: vec![ParserAction::new(1, 0, 0, None)],
17087 nodes: recursive_nodes,
17088 };
17089 let second = RecognizeOutcome {
17090 index: 1,
17091 consumed_eof: false,
17092 alt_number: 0,
17093 member_values: BTreeMap::new(),
17094 return_values: BTreeMap::new(),
17095 diagnostics: DiagnosticSeqId::EMPTY,
17096 decisions: Vec::new(),
17097 actions: vec![ParserAction::new(2, 0, 0, None)],
17098 nodes: recursive_nodes,
17099 };
17100
17101 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17102 .expect("one outcome should be selected");
17103 assert_eq!(selected.actions[0].source_state(), 1);
17104 }
17105
17106 #[test]
17107 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
17108 let mut arena = RecognitionArena::default();
17109 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17110 line: 1,
17111 column: 3,
17112 message: "missing 'Y' at '<EOF>'".to_owned(),
17113 }]);
17114 let first_alt = RecognizeOutcome {
17115 index: 2,
17116 consumed_eof: true,
17117 alt_number: 0,
17118 member_values: BTreeMap::new(),
17119 return_values: BTreeMap::new(),
17120 diagnostics: recovered_diagnostics,
17121 decisions: vec![0],
17122 actions: vec![ParserAction::new(1, 0, 0, None)],
17123 nodes: NodeSeqId::EMPTY,
17124 };
17125 let second_alt = RecognizeOutcome {
17126 diagnostics: DiagnosticSeqId::EMPTY,
17127 decisions: vec![1],
17128 actions: vec![ParserAction::new(2, 0, 0, None)],
17129 ..first_alt.clone()
17130 };
17131
17132 let selected = select_best_outcome(
17133 [second_alt, first_alt].into_iter(),
17134 PredictionMode::Sll,
17135 &arena,
17136 )
17137 .expect("one outcome should be selected");
17138 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
17139 assert_eq!(selected.decisions, [0]);
17140 }
17141}