1use std::cell::RefCell;
7use std::cmp::Ordering;
8#[allow(clippy::disallowed_types)]
9use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
10use std::hash::{BuildHasherDefault, Hash, Hasher};
11use std::rc::Rc;
12
13#[derive(Clone, Copy, Default)]
20struct FxHasher {
21 hash: u64,
22}
23
24const FX_ROT: u32 = 5;
25const FX_SEED: u64 = 0x51_7c_c1_b7_27_22_0a_95;
26
27impl Hasher for FxHasher {
28 #[inline]
36 fn write(&mut self, mut bytes: &[u8]) {
37 while bytes.len() >= 8 {
38 let (head, rest) = bytes.split_at(8);
39 let word = u64::from_le_bytes(head.try_into().expect("8-byte chunk"));
40 self.hash = (self.hash.rotate_left(FX_ROT) ^ word).wrapping_mul(FX_SEED);
41 bytes = rest;
42 }
43 for byte in bytes {
44 self.hash = (self.hash.rotate_left(FX_ROT) ^ u64::from(*byte)).wrapping_mul(FX_SEED);
45 }
46 }
47 #[inline]
48 fn write_u64(&mut self, value: u64) {
49 self.hash = (self.hash.rotate_left(FX_ROT) ^ value).wrapping_mul(FX_SEED);
50 }
51 #[inline]
52 fn write_usize(&mut self, value: usize) {
53 self.write_u64(value as u64);
54 }
55 #[inline]
56 fn write_u32(&mut self, value: u32) {
57 self.write_u64(u64::from(value));
58 }
59 #[inline]
60 fn write_i32(&mut self, value: i32) {
61 self.write_u64(u64::from(i32::cast_unsigned(value)));
62 }
63 #[inline]
64 fn finish(&self) -> u64 {
65 self.hash
66 }
67}
68
69type FxBuildHasher = BuildHasherDefault<FxHasher>;
70#[allow(clippy::disallowed_types)]
71type FxHashMap<K, V> = HashMap<K, V, FxBuildHasher>;
72#[allow(clippy::disallowed_types)]
73type FxHashSet<K> = HashSet<K, FxBuildHasher>;
74
75use crate::atn::AtnStateKind;
76use crate::atn::parser::{
77 ParserAtnPrediction, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
78};
79use crate::atn::parser_atn::{
80 ParserAtn as Atn, ParserAtnState as AtnState, ParserIntervalSet, ParserTransition,
81 ParserTransitionData as Transition, ParserTransitionKind,
82};
83#[cfg(test)]
84use crate::atn::parser_atn::{ParserAtnBuilder, ParserTransitionSpec};
85use crate::char_stream::CharStream;
86use crate::errors::AntlrError;
87use crate::int_stream::IntStream;
88use crate::lexer::{LexerCustomAction, LexerLifecycleCtx, LexerSemCtx};
89use crate::recognizer::{Recognizer, RecognizerData};
90use crate::semir::{self, AStmt, ArithOp, CmpOp, ExprId, HookId, PExpr, SemIr, StmtId};
91use crate::token::{
92 TOKEN_EOF, Token, TokenId, TokenSource, TokenSourceError, TokenSpec, TokenStore, TokenView,
93};
94use crate::token_stream::CommonTokenStream;
95use crate::tree::{
96 Node, NodeId, ParseTreeCheckpoint, ParseTreeStorage, ParsedFile, ParserRuleContext,
97};
98use crate::vocabulary::Vocabulary;
99
100type ParseTree = NodeId;
101
102const RECOGNITION_DEPTH_LIMIT: usize = 32_768;
106const ADAPTIVE_DIRECT_STEP_LIMIT: usize = RECOGNITION_DEPTH_LIMIT;
110const CLEAN_MEMO_PROBE_LIMIT: usize = 4096;
114const CLEAN_MEMO_REPEAT_LIMIT: usize = 8;
115const CLEAN_MEMO_REPROBE_INTERVAL: usize = 262_144;
118const FAST_RECOGNIZE_VISITING_CAPACITY: usize = 256;
119const FAST_RECOGNIZE_MIN_MEMO_CAPACITY: usize = 256;
120const FAST_RECOGNIZE_MAX_MEMO_CAPACITY: usize = 524_288;
121const FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY: usize = 65_536;
122
123#[derive(Clone, Copy, Debug, Eq, PartialEq)]
124enum CleanMemoMode {
125 Probe,
126 Promote,
127 Sparse,
128}
129
130fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
131 intervals
132 .iter()
133 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
134}
135
136fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
137 let mut symbols = BTreeSet::new();
138 for (start, stop) in intervals {
139 symbols.extend(*start..=*stop);
140 }
141 symbols
142}
143
144fn interval_complement_symbols(
145 intervals: &[(i32, i32)],
146 min_vocabulary: i32,
147 max_vocabulary: i32,
148) -> BTreeSet<i32> {
149 (min_vocabulary..=max_vocabulary)
150 .filter(|symbol| !interval_set_contains(intervals, *symbol))
151 .collect()
152}
153
154#[cfg(feature = "perf-counters")]
155mod perf_counters {
156 use std::cell::Cell;
157 thread_local! {
158 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
159 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
160 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
161 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
162 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
163 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
164 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
165 pub(super) static OUTCOME_DEDUPE_INPUTS: Cell<u64> = const { Cell::new(0) };
166 pub(super) static OUTCOME_DEDUPE_REMOVED: Cell<u64> = const { Cell::new(0) };
167 pub(super) static OUTCOME_DEDUPE_INLINE: Cell<u64> = const { Cell::new(0) };
168 pub(super) static OUTCOME_DEDUPE_DENSE: Cell<u64> = const { Cell::new(0) };
169 pub(super) static OUTCOME_DEDUPE_SPARSE: Cell<u64> = const { Cell::new(0) };
170 pub(super) static OUTCOME_DEDUPE_DENSE_WORDS: Cell<u64> = const { Cell::new(0) };
171 }
172 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
173 c.with(|v| v.set(v.get() + n));
174 }
175 thread_local! {
176 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
177 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
178 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
179 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
180 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
181 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
182 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
183 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
184 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
185 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
186 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
187 }
188 pub(super) fn snapshot() -> [(&'static str, u64); 24] {
189 [
190 ("rfs_calls", RFS_CALLS.with(Cell::get)),
191 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
192 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
193 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
194 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
195 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
196 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
197 (
198 "outcome_dedupe_inputs",
199 OUTCOME_DEDUPE_INPUTS.with(Cell::get),
200 ),
201 (
202 "outcome_dedupe_removed",
203 OUTCOME_DEDUPE_REMOVED.with(Cell::get),
204 ),
205 (
206 "outcome_dedupe_inline",
207 OUTCOME_DEDUPE_INLINE.with(Cell::get),
208 ),
209 ("outcome_dedupe_dense", OUTCOME_DEDUPE_DENSE.with(Cell::get)),
210 (
211 "outcome_dedupe_sparse",
212 OUTCOME_DEDUPE_SPARSE.with(Cell::get),
213 ),
214 (
215 "outcome_dedupe_dense_words",
216 OUTCOME_DEDUPE_DENSE_WORDS.with(Cell::get),
217 ),
218 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
219 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
220 (
221 "atom_range_transitions",
222 ATOM_RANGE_TRANSITIONS.with(Cell::get),
223 ),
224 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
225 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
226 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
227 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
228 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
229 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
230 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
231 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
232 ]
233 }
234 pub fn reset() {
235 RFS_CALLS.with(|c| c.set(0));
236 RFS_MEMO_HITS.with(|c| c.set(0));
237 RFS_MEMO_MISSES.with(|c| c.set(0));
238 RFS_VISITING_CYCLE.with(|c| c.set(0));
239 MEMO_INSERTED.with(|c| c.set(0));
240 OUTCOMES_PUSHED.with(|c| c.set(0));
241 OUTCOMES_CLONED.with(|c| c.set(0));
242 OUTCOME_DEDUPE_INPUTS.with(|c| c.set(0));
243 OUTCOME_DEDUPE_REMOVED.with(|c| c.set(0));
244 OUTCOME_DEDUPE_INLINE.with(|c| c.set(0));
245 OUTCOME_DEDUPE_DENSE.with(|c| c.set(0));
246 OUTCOME_DEDUPE_SPARSE.with(|c| c.set(0));
247 OUTCOME_DEDUPE_DENSE_WORDS.with(|c| c.set(0));
248 EPSILON_TRANSITIONS.with(|c| c.set(0));
249 RULE_TRANSITIONS.with(|c| c.set(0));
250 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
251 SINGLE_TRANS_BODY.with(|c| c.set(0));
252 MULTI_TRANS_BODY.with(|c| c.set(0));
253 SINGLE_TRANS_RULE.with(|c| c.set(0));
254 SINGLE_TRANS_ATOM.with(|c| c.set(0));
255 SINGLE_TRANS_OTHER.with(|c| c.set(0));
256 OUTCOMES_RETURN_0.with(|c| c.set(0));
257 OUTCOMES_RETURN_1.with(|c| c.set(0));
258 OUTCOMES_RETURN_N.with(|c| c.set(0));
259 }
260 pub fn dump() {
261 for (name, value) in snapshot() {
262 #[allow(clippy::print_stderr)]
263 {
264 eprintln!("perf {name}={value}");
265 }
266 }
267 }
268}
269
270#[cfg(feature = "perf-counters")]
271pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
272const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
277#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
286pub struct ParserAction {
287 source_state: usize,
288 rule_index: usize,
289 start_index: usize,
290 stop_index: Option<usize>,
291 rule_init: bool,
292 expected_state: Option<usize>,
293}
294
295impl ParserAction {
296 pub const fn new(
298 source_state: usize,
299 rule_index: usize,
300 start_index: usize,
301 stop_index: Option<usize>,
302 ) -> Self {
303 Self {
304 source_state,
305 rule_index,
306 start_index,
307 stop_index,
308 rule_init: false,
309 expected_state: None,
310 }
311 }
312
313 pub const fn new_rule_init(
315 rule_index: usize,
316 start_index: usize,
317 expected_state: Option<usize>,
318 ) -> Self {
319 Self {
320 source_state: usize::MAX,
321 rule_index,
322 start_index,
323 stop_index: None,
324 rule_init: true,
325 expected_state,
326 }
327 }
328
329 pub const fn source_state(&self) -> usize {
331 self.source_state
332 }
333
334 pub const fn rule_index(&self) -> usize {
336 self.rule_index
337 }
338
339 pub const fn start_index(&self) -> usize {
341 self.start_index
342 }
343
344 pub const fn stop_index(&self) -> Option<usize> {
346 self.stop_index
347 }
348
349 pub const fn is_rule_init(&self) -> bool {
351 self.rule_init
352 }
353
354 pub const fn expected_state(&self) -> Option<usize> {
356 self.expected_state
357 }
358}
359
360pub struct ParserSemCtx<'a, S>
368where
369 S: TokenSource,
370{
371 input: &'a mut CommonTokenStream<S>,
372 tree_storage: &'a ParseTreeStorage,
373 rule_index: usize,
374 coordinate_index: usize,
375 rule_name: Option<String>,
376 context: Option<&'a ParserRuleContext>,
377 tree: Option<ParseTree>,
378 local_int_arg: Option<(usize, i64)>,
379 member_values: &'a BTreeMap<usize, i64>,
380 action: Option<ParserAction>,
381}
382
383impl<S> std::fmt::Debug for ParserSemCtx<'_, S>
384where
385 S: TokenSource,
386{
387 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
388 f.debug_struct("ParserSemCtx")
389 .field("rule_index", &self.rule_index)
390 .field("coordinate_index", &self.coordinate_index)
391 .field("rule_name", &self.rule_name)
392 .field("context", &self.context)
393 .field("tree", &self.tree)
394 .field("local_int_arg", &self.local_int_arg)
395 .field("member_values", &self.member_values)
396 .field("action", &self.action)
397 .finish_non_exhaustive()
398 }
399}
400
401impl<'a, S> ParserSemCtx<'a, S>
402where
403 S: TokenSource,
404{
405 #[must_use]
407 pub const fn rule_index(&self) -> usize {
408 self.rule_index
409 }
410
411 #[must_use]
413 pub fn rule_name(&self) -> Option<&str> {
414 self.rule_name.as_deref()
415 }
416
417 #[must_use]
421 pub const fn coordinate_index(&self) -> usize {
422 self.coordinate_index
423 }
424
425 #[must_use]
427 pub fn input_index(&self) -> usize {
428 self.input.index()
429 }
430
431 pub fn la(&mut self, offset: isize) -> i32 {
433 self.input.la(offset)
434 }
435
436 pub fn lt(&self, offset: isize) -> Option<TokenView<'_>> {
438 self.input.lt(offset)
439 }
440
441 pub fn token_text(&self, offset: isize) -> Option<TokenView<'_>> {
443 self.lt(offset)
444 }
445
446 pub fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
453 self.input.get(index)
454 }
455
456 #[must_use]
459 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
460 self.context
461 }
462
463 #[must_use]
465 pub const fn parse_tree_storage(&self) -> &'a ParseTreeStorage {
466 self.tree_storage
467 }
468
469 #[must_use]
471 pub const fn token_store(&self) -> &TokenStore {
472 self.input.token_store()
473 }
474
475 #[must_use]
477 pub const fn tree_id(&self) -> Option<NodeId> {
478 self.tree
479 }
480
481 #[must_use]
484 pub fn tree(&self) -> Option<Node<'_>> {
485 self.tree
486 .and_then(|id| self.tree_storage.node(self.input.token_store(), id))
487 }
488
489 #[must_use]
491 pub fn local_int_arg(&self) -> Option<i64> {
492 self.local_int_arg.map(|(_, value)| value)
493 }
494
495 #[must_use]
497 pub fn member_int(&self, member: usize) -> Option<i64> {
498 self.member_values.get(&member).copied()
499 }
500
501 #[must_use]
504 pub const fn action(&self) -> Option<ParserAction> {
505 self.action
506 }
507
508 pub fn action_text(&self) -> String {
516 let Some(action) = self.action else {
517 return String::new();
518 };
519 let Some(stop) = action.stop_index() else {
520 return String::new();
521 };
522 let stop = if self
523 .input
524 .get(stop)
525 .is_some_and(|token| token.token_type() == TOKEN_EOF)
526 {
527 let Some(previous) = self.input.previous_visible_token_index(stop) else {
528 return String::new();
529 };
530 previous
531 } else {
532 stop
533 };
534 self.input.text(action.start_index(), stop)
535 }
536}
537
538pub trait SemanticHooks {
545 const ENABLES_LEXER_LIFECYCLE: bool = true;
552
553 fn observes_parser_predicates(&self) -> bool {
558 true
559 }
560
561 fn sempred<S>(
562 &mut self,
563 ctx: &mut ParserSemCtx<'_, S>,
564 rule_index: usize,
565 pred_index: usize,
566 ) -> Option<bool>
567 where
568 S: TokenSource,
569 {
570 let _ = (ctx, rule_index, pred_index);
571 None
572 }
573
574 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
575 where
576 S: TokenSource,
577 {
578 let _ = (ctx, action);
579 false
580 }
581
582 fn lexer_sempred<I>(
583 &mut self,
584 ctx: &mut LexerSemCtx<'_, I>,
585 rule_index: usize,
586 pred_index: usize,
587 ) -> Option<bool>
588 where
589 I: CharStream,
590 {
591 let _ = (ctx, rule_index, pred_index);
592 None
593 }
594
595 fn lexer_action<I>(&mut self, ctx: &mut LexerSemCtx<'_, I>, action: LexerCustomAction) -> bool
605 where
606 I: CharStream,
607 {
608 let _ = (ctx, action);
609 false
610 }
611
612 fn lexer_reset<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
616 where
617 I: CharStream,
618 {
619 let _ = ctx;
620 }
621
622 fn lexer_before_token<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
628 where
629 I: CharStream,
630 {
631 let _ = ctx;
632 }
633
634 fn lexer_after_accept<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
643 where
644 I: CharStream,
645 {
646 let _ = ctx;
647 }
648
649 fn lexer_token_emitted(&mut self, token: TokenView<'_>) {
656 let _ = token;
657 }
658}
659
660#[derive(Clone, Copy, Debug, Default)]
663pub struct NoSemanticHooks;
664
665impl SemanticHooks for NoSemanticHooks {
666 const ENABLES_LEXER_LIFECYCLE: bool = false;
667
668 fn observes_parser_predicates(&self) -> bool {
669 false
670 }
671}
672
673#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
680pub enum ParserPredicate {
681 True,
682 False,
683 FalseWithMessage {
685 message: &'static str,
686 },
687 Invoke {
690 value: bool,
691 },
692 LookaheadTextEquals {
693 offset: isize,
694 text: &'static str,
695 },
696 LookaheadNotEquals {
697 offset: isize,
698 token_type: i32,
699 },
700 TokenPairAdjacent,
703 ContextChildRuleTextNotEquals {
708 rule_index: usize,
709 text: &'static str,
710 },
711 LocalIntEquals {
714 value: i64,
715 },
716 LocalIntLessOrEqual {
719 value: i64,
720 },
721 MemberModuloEquals {
723 member: usize,
724 modulus: i64,
725 value: i64,
726 equals: bool,
727 },
728 MemberEquals {
730 member: usize,
731 value: i64,
732 equals: bool,
733 },
734}
735
736impl ParserPredicate {
737 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
743 match self {
744 Self::True => ir.expr(PExpr::Bool(true)),
745 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
746 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
747 Self::LookaheadTextEquals { offset, text } => {
748 let token = ir.expr(PExpr::TokenText(offset));
749 let text = ir.intern(text);
750 let text = ir.expr(PExpr::Str(text));
751 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
752 }
753 Self::LookaheadNotEquals { offset, token_type } => {
754 let actual = ir.expr(PExpr::La(offset));
755 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
756 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
757 }
758 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
759 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
760 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
761 let expected = ir.intern(text);
762 let expected = ir.expr(PExpr::Str(expected));
763 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
764 }
765 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
766 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
767 Self::MemberModuloEquals {
768 member,
769 modulus,
770 value,
771 equals,
772 } => {
773 if modulus == 0 {
774 return ir.expr(PExpr::Bool(false));
775 }
776 let member = ir.expr(PExpr::Member(member));
777 let modulus = ir.expr(PExpr::Int(modulus));
778 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
779 let expected = ir.expr(PExpr::Int(value));
780 ir.expr(PExpr::Cmp(
781 if equals { CmpOp::Eq } else { CmpOp::Ne },
782 actual,
783 expected,
784 ))
785 }
786 Self::MemberEquals {
787 member,
788 value,
789 equals,
790 } => {
791 let actual = ir.expr(PExpr::Member(member));
792 let expected = ir.expr(PExpr::Int(value));
793 ir.expr(PExpr::Cmp(
794 if equals { CmpOp::Eq } else { CmpOp::Ne },
795 actual,
796 expected,
797 ))
798 }
799 }
800 }
801
802 #[must_use]
803 pub const fn failure_message(self) -> Option<&'static str> {
804 match self {
805 Self::FalseWithMessage { message } => Some(message),
806 Self::True
807 | Self::False
808 | Self::Invoke { .. }
809 | Self::LookaheadTextEquals { .. }
810 | Self::LookaheadNotEquals { .. }
811 | Self::TokenPairAdjacent
812 | Self::ContextChildRuleTextNotEquals { .. }
813 | Self::LocalIntEquals { .. }
814 | Self::LocalIntLessOrEqual { .. }
815 | Self::MemberModuloEquals { .. }
816 | Self::MemberEquals { .. } => None,
817 }
818 }
819}
820
821fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
822 let local = ir.expr(PExpr::LocalArg);
823 let absent = ir.expr(PExpr::IsNull(local));
824 let expected = ir.expr(PExpr::Int(value));
825 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
826 ir.expr(PExpr::Or([absent, comparison].into()))
827}
828
829#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
842pub enum UnknownSemanticPolicy {
843 #[default]
845 AssumeTrue,
846 AssumeFalse,
848 Error,
851}
852
853fn apply_unknown_predicate_policy(
862 policy: UnknownSemanticPolicy,
863 rule_index: usize,
864 pred_index: usize,
865 hits: &mut Vec<(usize, usize)>,
866) -> bool {
867 match policy {
868 UnknownSemanticPolicy::AssumeTrue => true,
869 UnknownSemanticPolicy::AssumeFalse => false,
870 UnknownSemanticPolicy::Error => {
871 let coordinate = (rule_index, pred_index);
872 if !hits.contains(&coordinate) {
873 hits.push(coordinate);
874 }
875 false
876 }
877 }
878}
879
880#[derive(Clone, Debug, Eq, PartialEq)]
884pub struct ExpectedTokenSet {
885 symbols: BTreeSet<i32>,
886}
887
888impl ExpectedTokenSet {
889 #[must_use]
891 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
892 expected_symbols_display(&self.symbols, vocabulary)
893 }
894}
895
896#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
901pub struct BailErrorStrategy;
902
903impl BailErrorStrategy {
904 #[must_use]
905 pub const fn new() -> Self {
906 Self
907 }
908}
909
910#[derive(Clone, Copy, Debug, Eq, PartialEq)]
912pub enum PredictionMode {
913 Ll,
916 Sll,
919 LlExactAmbigDetection,
921}
922
923#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
929pub struct ParserRuleArg {
930 pub source_state: usize,
932 pub rule_index: usize,
934 pub value: i64,
936 pub inherit_local: bool,
938}
939
940#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
942pub struct ParserMemberAction {
943 pub source_state: usize,
945 pub member: usize,
947 pub delta: i64,
949}
950
951#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
958pub struct ParserReturnAction {
959 pub source_state: usize,
961 pub rule_index: usize,
963 pub name: &'static str,
965 pub value: i64,
967}
968
969impl ParserMemberAction {
970 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
972 let delta = ir.expr(PExpr::Int(self.delta));
973 ParserSemanticAction {
974 source_state: self.source_state,
975 rule_index: usize::MAX,
976 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
977 speculative: true,
978 }
979 }
980}
981
982impl ParserReturnAction {
983 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
985 let name = ir.intern(self.name);
986 let value = ir.expr(PExpr::Int(self.value));
987 ParserSemanticAction {
988 source_state: self.source_state,
989 rule_index: self.rule_index,
990 stmt: ir.stmt(AStmt::SetReturn(name, value)),
991 speculative: false,
992 }
993 }
994}
995
996#[derive(Clone, Copy, Debug, Eq, PartialEq)]
998pub struct ParserSemanticPredicate {
999 pub rule_index: usize,
1001 pub pred_index: usize,
1003 pub expr: ExprId,
1005 pub failure_message: Option<&'static str>,
1007}
1008
1009#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1011pub struct ParserSemanticAction {
1012 pub source_state: usize,
1014 pub rule_index: usize,
1016 pub stmt: StmtId,
1018 pub speculative: bool,
1020}
1021
1022#[derive(Clone, Debug, Default, Eq, PartialEq)]
1029pub struct ParserSemantics {
1030 pub ir: SemIr,
1031 pub predicates: Vec<ParserSemanticPredicate>,
1032 pub actions: Vec<ParserSemanticAction>,
1033}
1034
1035#[derive(Clone, Copy, Debug, Default)]
1037pub struct ParserRuntimeOptions<'a> {
1038 pub init_action_rules: &'a [usize],
1040 pub track_alt_numbers: bool,
1042 pub predicates: &'a [(usize, usize, ParserPredicate)],
1044 pub semantics: Option<&'a ParserSemantics>,
1046 pub rule_args: &'a [ParserRuleArg],
1048 pub member_actions: &'a [ParserMemberAction],
1050 pub return_actions: &'a [ParserReturnAction],
1052 pub unknown_predicate_policy: UnknownSemanticPolicy,
1055}
1056
1057pub trait Parser: Recognizer {
1058 fn build_parse_trees(&self) -> bool;
1061
1062 fn set_build_parse_trees(&mut self, build: bool);
1064
1065 fn number_of_syntax_errors(&self) -> usize {
1068 0
1069 }
1070
1071 fn report_diagnostic_errors(&self) -> bool {
1074 false
1075 }
1076
1077 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
1080
1081 fn prediction_mode(&self) -> PredictionMode {
1083 PredictionMode::Ll
1084 }
1085
1086 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
1088}
1089
1090#[derive(Debug)]
1091struct LeftRecursiveCallerOverlap {
1092 atn_key: SharedAtnCacheKey,
1093 state_number: usize,
1094 symbol: i32,
1095 context_version: usize,
1096 overlaps: bool,
1097}
1098
1099const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
1100
1101#[derive(Debug)]
1102pub struct BaseParser<S, H = NoSemanticHooks> {
1103 input: CommonTokenStream<S>,
1104 tree: ParseTreeStorage,
1105 data: RecognizerData,
1106 semantic_hooks: H,
1107 build_parse_trees: bool,
1108 syntax_errors: usize,
1109 report_diagnostic_errors: bool,
1110 prediction_mode: PredictionMode,
1111 prediction_diagnostics: Vec<ParserDiagnostic>,
1112 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1113 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1114 generated_sync_expected: Option<TokenBitSet>,
1115 int_members: BTreeMap<usize, i64>,
1116 rule_context_stack: Vec<RuleContextFrame>,
1117 rule_context_version: usize,
1118 left_recursive_caller_overlap_cache:
1119 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1120 pending_invoking_states: Vec<isize>,
1121 precedence_stack: Vec<i32>,
1122 invoked_predicates: Vec<(usize, usize)>,
1126 bail_on_error: bool,
1130 unknown_predicate_policy: UnknownSemanticPolicy,
1133 unknown_predicate_hits: Vec<(usize, usize)>,
1136 unhandled_action_hits: Vec<(usize, usize)>,
1141 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1146 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1152 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1157 rule_stop_reach_cache: Vec<Option<bool>>,
1162 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1167 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1173 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1179 fast_predicate_cache: FxHashMap<(usize, usize, usize), bool>,
1183 empty_cycle_cache: Vec<Option<bool>>,
1189 empty_cycle_cache_atn: Option<SharedAtnCacheKey>,
1190 clean_memo_mode: CleanMemoMode,
1193 clean_memo_probe_seen: FxHashSet<FastRecognizeKey>,
1194 clean_memo_probe_samples: usize,
1195 clean_memo_probe_repeats: usize,
1196 clean_memo_sparse_samples: usize,
1197 fast_recognize_scratch: FastRecognizeTopScratch,
1199 fast_outcome_dedup: FastOutcomeDedupScratch,
1201 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1204 fast_first_set_prefilter: bool,
1212 fast_recovery_enabled: bool,
1216 fast_token_nodes_enabled: bool,
1221 recognition_arena: RecognitionArena,
1225 last_recognition_arena_root: NodeSeqId,
1226 last_recognition_arena_diagnostics: DiagnosticSeqId,
1227}
1228
1229#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1231pub struct GeneratedDiagnosticsCheckpoint {
1232 diagnostics_len: usize,
1233 syntax_errors: usize,
1234 tree: ParseTreeCheckpoint,
1235}
1236
1237#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1240pub struct RecognitionArenaStats {
1241 pub total_nodes: usize,
1242 pub live_nodes: usize,
1243 pub dead_nodes: usize,
1244 pub node_capacity: usize,
1245 pub total_links: usize,
1246 pub live_links: usize,
1247 pub dead_links: usize,
1248 pub link_capacity: usize,
1249 pub total_extras: usize,
1250 pub live_extras: usize,
1251 pub dead_extras: usize,
1252 pub extra_capacity: usize,
1253}
1254
1255#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1256struct RuleContextFrame {
1257 rule_index: usize,
1258 invoking_state: isize,
1259}
1260
1261#[derive(Clone, Debug, Eq, PartialEq)]
1262struct RecognizeOutcome {
1263 index: usize,
1264 consumed_eof: bool,
1265 alt_number: usize,
1266 member_values: BTreeMap<usize, i64>,
1267 return_values: BTreeMap<String, i64>,
1268 diagnostics: DiagnosticSeqId,
1269 decisions: Vec<usize>,
1270 actions: Vec<ParserAction>,
1271 nodes: NodeSeqId,
1272}
1273
1274#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1275struct FastRecognizeOutcome {
1276 index: usize,
1277 consumed_eof: bool,
1278 diagnostics: DiagnosticSeqId,
1279 deferred_nodes: FastDeferredNodeId,
1280 nodes: NodeSeqId,
1284}
1285
1286#[derive(Debug, Default)]
1287struct FastRecognizeTopScratch {
1288 visiting: FxHashSet<FastRecognizeKey>,
1289 memo: FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
1290}
1291
1292impl FastRecognizeTopScratch {
1293 fn prepare(&mut self, memo_capacity: usize) {
1294 self.visiting.clear();
1295 self.visiting.reserve(FAST_RECOGNIZE_VISITING_CAPACITY);
1296 self.memo.clear();
1297 self.memo.reserve(memo_capacity);
1298 }
1299
1300 fn release_oversized_memo(&mut self) {
1301 self.memo.clear();
1302 if self.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY {
1303 self.memo = FxHashMap::default();
1304 }
1305 }
1306}
1307
1308fn fast_recognize_memo_capacity(buffered_tokens: usize) -> usize {
1309 buffered_tokens.saturating_mul(8).clamp(
1310 FAST_RECOGNIZE_MIN_MEMO_CAPACITY,
1311 FAST_RECOGNIZE_MAX_MEMO_CAPACITY,
1312 )
1313}
1314
1315#[derive(Debug, Default)]
1316struct FastOutcomeDedupScratch {
1317 dense_words: Vec<u64>,
1318 touched_dense_words: Vec<u32>,
1319 sparse_keys: FxHashSet<(usize, bool)>,
1320}
1321
1322#[repr(transparent)]
1327#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1328struct FastDeferredNodeId(u32);
1329
1330impl FastDeferredNodeId {
1331 const EMPTY: Self = Self(u32::MAX);
1332
1333 const fn is_empty(self) -> bool {
1334 self.0 == Self::EMPTY.0
1335 }
1336}
1337
1338impl Default for FastDeferredNodeId {
1339 fn default() -> Self {
1340 Self::EMPTY
1341 }
1342}
1343
1344#[repr(transparent)]
1345#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1346struct FastDeferredRuleId(u32);
1347
1348#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1350enum FastDeferredNode {
1351 Fragment(NodeSeqId),
1352 Rule(FastDeferredRuleId),
1353 Concat {
1354 prefix: FastDeferredNodeId,
1355 suffix: FastDeferredNodeId,
1356 },
1357}
1358
1359#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1360struct FastDeferredRule {
1361 rule_index: u32,
1362 invoking_state: i32,
1363 start_index: u32,
1364 stop_index: Option<u32>,
1365 deferred_children: FastDeferredNodeId,
1366 children: NodeSeqId,
1367}
1368
1369#[repr(transparent)]
1370#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1371struct RecognizedNodeId(u32);
1372
1373#[repr(transparent)]
1374#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1375struct NodeSeqId(u32);
1376
1377impl NodeSeqId {
1378 const EMPTY: Self = Self(u32::MAX);
1379
1380 const fn is_empty(self) -> bool {
1381 self.0 == Self::EMPTY.0
1382 }
1383}
1384
1385impl Default for NodeSeqId {
1386 fn default() -> Self {
1387 Self::EMPTY
1388 }
1389}
1390
1391#[repr(transparent)]
1392#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1393struct DiagnosticSeqId(u32);
1394
1395impl DiagnosticSeqId {
1396 const EMPTY: Self = Self(u32::MAX);
1397
1398 const fn is_empty(self) -> bool {
1399 self.0 == Self::EMPTY.0
1400 }
1401}
1402
1403impl Default for DiagnosticSeqId {
1404 fn default() -> Self {
1405 Self::EMPTY
1406 }
1407}
1408
1409#[repr(transparent)]
1410#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1411struct RecognitionExtraId(u32);
1412
1413#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1414struct SeqLink {
1415 head: RecognizedNodeId,
1416 tail: NodeSeqId,
1417}
1418
1419#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1420struct DiagnosticLink {
1421 head: RecognitionExtraId,
1422 tail: DiagnosticSeqId,
1423}
1424
1425struct ArenaRuleSpec {
1426 rule_index: usize,
1427 invoking_state: isize,
1428 alt_number: usize,
1429 start_index: usize,
1430 stop_index: Option<usize>,
1431 return_values: BTreeMap<String, i64>,
1432 children: NodeSeqId,
1433}
1434
1435#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1438enum ArenaRecognizedNode {
1439 Token {
1440 token: TokenId,
1441 },
1442 ErrorToken {
1443 token: TokenId,
1444 },
1445 MissingToken {
1446 extra: RecognitionExtraId,
1447 },
1448 Rule {
1449 rule_index: u32,
1450 invoking_state: i32,
1451 alt_number: u32,
1452 start_index: u32,
1453 stop_index: Option<u32>,
1454 return_values: Option<RecognitionExtraId>,
1455 children: NodeSeqId,
1456 },
1457 LeftRecursiveBoundary {
1461 rule_index: u32,
1462 },
1463}
1464
1465#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1466enum RecognitionExtra {
1467 MissingToken {
1468 token_type: i32,
1469 at_index: u32,
1470 text: String,
1471 },
1472 ReturnValues(BTreeMap<String, i64>),
1473 Diagnostic(ParserDiagnostic),
1474}
1475
1476#[derive(Debug, Default)]
1477struct RecognitionArena {
1478 nodes: Vec<ArenaRecognizedNode>,
1479 seq_links: Vec<SeqLink>,
1480 diagnostic_links: Vec<DiagnosticLink>,
1481 extras: Vec<RecognitionExtra>,
1482 deferred_nodes: Vec<FastDeferredNode>,
1483 deferred_rules: Vec<FastDeferredRule>,
1484}
1485
1486const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1489const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1490const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1491const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1492const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1493const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1494
1495impl RecognitionArena {
1496 fn reset(&mut self) {
1497 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1498 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1499 reset_arena_vec(
1500 &mut self.diagnostic_links,
1501 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1502 );
1503 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1504 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1505 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1506 }
1507
1508 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1509 let id = RecognizedNodeId(
1510 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1511 );
1512 self.nodes.push(node);
1513 id
1514 }
1515
1516 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1517 let id = RecognitionExtraId(
1518 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1519 );
1520 self.extras.push(extra);
1521 id
1522 }
1523
1524 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1525 let id = NodeSeqId(
1526 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1527 );
1528 self.seq_links.push(SeqLink { head, tail });
1529 id
1530 }
1531
1532 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1533 let id = FastDeferredNodeId(
1534 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
1535 );
1536 self.deferred_nodes.push(node);
1537 id
1538 }
1539
1540 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
1541 let id = FastDeferredRuleId(
1542 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
1543 );
1544 self.deferred_rules.push(rule);
1545 id
1546 }
1547
1548 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
1549 if nodes.is_empty() {
1550 FastDeferredNodeId::EMPTY
1551 } else {
1552 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
1553 }
1554 }
1555
1556 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
1557 let rule = self.push_deferred_rule(rule);
1558 self.push_deferred_node(FastDeferredNode::Rule(rule))
1559 }
1560
1561 fn concat_deferred_nodes(
1562 &mut self,
1563 prefix: FastDeferredNodeId,
1564 suffix: FastDeferredNodeId,
1565 ) -> FastDeferredNodeId {
1566 if prefix.is_empty() {
1567 return suffix;
1568 }
1569 if suffix.is_empty() {
1570 return prefix;
1571 }
1572 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
1573 }
1574
1575 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
1576 self.deferred_nodes[id.0 as usize]
1577 }
1578
1579 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
1580 self.deferred_rules[id.0 as usize]
1581 }
1582
1583 fn prepend_diagnostic(
1584 &mut self,
1585 tail: DiagnosticSeqId,
1586 diagnostic: ParserDiagnostic,
1587 ) -> DiagnosticSeqId {
1588 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
1589 self.prepend_diagnostic_id(tail, head)
1590 }
1591
1592 fn prepend_diagnostic_id(
1593 &mut self,
1594 tail: DiagnosticSeqId,
1595 head: RecognitionExtraId,
1596 ) -> DiagnosticSeqId {
1597 let id = DiagnosticSeqId(
1598 u32::try_from(self.diagnostic_links.len())
1599 .expect("diagnostic sequence arena fits in u32"),
1600 );
1601 self.diagnostic_links.push(DiagnosticLink { head, tail });
1602 id
1603 }
1604
1605 fn concat_diagnostics(
1606 &mut self,
1607 prefix: DiagnosticSeqId,
1608 mut suffix: DiagnosticSeqId,
1609 ) -> DiagnosticSeqId {
1610 if prefix.is_empty() {
1611 return suffix;
1612 }
1613 if suffix.is_empty() {
1614 return prefix;
1615 }
1616 let mut reversed = DiagnosticSeqId::EMPTY;
1617 let mut cursor = prefix;
1618 while let Some(link) = self.diagnostic_link(cursor) {
1619 reversed = self.prepend_diagnostic_id(reversed, link.head);
1620 cursor = link.tail;
1621 }
1622 while let Some(link) = self.diagnostic_link(reversed) {
1623 suffix = self.prepend_diagnostic_id(suffix, link.head);
1624 reversed = link.tail;
1625 }
1626 suffix
1627 }
1628
1629 #[cfg(test)]
1630 fn diagnostic_sequence(
1631 &mut self,
1632 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
1633 ) -> DiagnosticSeqId {
1634 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
1635 let mut sequence = DiagnosticSeqId::EMPTY;
1636 for diagnostic in diagnostics.into_iter().rev() {
1637 sequence = self.prepend_diagnostic(sequence, diagnostic);
1638 }
1639 sequence
1640 }
1641
1642 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
1643 self.nodes[id.0 as usize]
1644 }
1645
1646 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
1647 &self.extras[id.0 as usize]
1648 }
1649
1650 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
1651 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
1652 }
1653
1654 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
1655 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
1656 }
1657
1658 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
1659 NodeSeqIter {
1660 arena: self,
1661 cursor: sequence,
1662 }
1663 }
1664
1665 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
1666 DiagnosticSeqIter {
1667 arena: self,
1668 cursor: sequence,
1669 }
1670 }
1671
1672 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
1673 self.diagnostics(sequence).count()
1674 }
1675
1676 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
1677 self.diagnostics(sequence)
1678 .filter(|diagnostic| {
1679 diagnostic.message.starts_with("mismatched input ")
1680 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
1681 })
1682 .count()
1683 }
1684
1685 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
1686 self.diagnostics(left).cmp(self.diagnostics(right))
1687 }
1688
1689 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
1690 self.iter(sequence).count()
1691 }
1692
1693 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
1694 self.iter(sequence).any(|node| match self.node(node) {
1695 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1696 ArenaRecognizedNode::Rule { children, .. } => {
1697 self.sequence_has_left_recursive_boundary(children)
1698 }
1699 ArenaRecognizedNode::Token { .. }
1700 | ArenaRecognizedNode::ErrorToken { .. }
1701 | ArenaRecognizedNode::MissingToken { .. } => false,
1702 })
1703 }
1704
1705 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
1706 self.iter(sequence).any(|node| {
1707 matches!(
1708 self.node(node),
1709 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
1710 )
1711 })
1712 }
1713
1714 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
1715 self.iter(sequence).any(|node| {
1716 matches!(
1717 self.node(node),
1718 ArenaRecognizedNode::Token { .. }
1719 | ArenaRecognizedNode::ErrorToken { .. }
1720 | ArenaRecognizedNode::MissingToken { .. }
1721 )
1722 })
1723 }
1724
1725 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
1726 match self.node(node) {
1727 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1728 Some(token.index())
1729 }
1730 ArenaRecognizedNode::MissingToken { extra } => {
1731 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1732 unreachable!("missing-token node must reference missing-token extra");
1733 };
1734 Some(*at_index as usize)
1735 }
1736 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
1737 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1738 }
1739 }
1740
1741 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
1742 match self.node(node) {
1743 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1744 Some(token.index())
1745 }
1746 ArenaRecognizedNode::MissingToken { extra } => {
1747 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1748 unreachable!("missing-token node must reference missing-token extra");
1749 };
1750 (*at_index as usize).checked_sub(1)
1751 }
1752 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
1753 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1754 }
1755 }
1756
1757 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
1758 let start = self.node_start_index(node)?;
1759 let stop = self.node_stop_index(node);
1760 Some((start, stop))
1761 }
1762
1763 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
1764 self.iter(sequence)
1765 .find_map(|node| self.node_start_index(node))
1766 }
1767
1768 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
1769 let mut stop = None;
1770 for node in self.iter(sequence) {
1771 if let Some(index) = self.node_stop_index(node) {
1772 stop = Some(index);
1773 }
1774 }
1775 stop
1776 }
1777
1778 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
1779 self.iter(sequence)
1780 .any(|node| self.node_needs_stable_tie(node))
1781 }
1782
1783 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
1784 match self.node(node) {
1785 ArenaRecognizedNode::Token { .. }
1786 | ArenaRecognizedNode::ErrorToken { .. }
1787 | ArenaRecognizedNode::MissingToken { .. } => false,
1788 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1789 ArenaRecognizedNode::Rule {
1790 rule_index,
1791 children,
1792 ..
1793 } => self.iter(children).any(|child| {
1794 matches!(
1795 self.node(child),
1796 ArenaRecognizedNode::Rule {
1797 rule_index: child_rule,
1798 ..
1799 } if child_rule == rule_index
1800 ) || self.node_needs_stable_tie(child)
1801 }),
1802 }
1803 }
1804
1805 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
1806 loop {
1807 match (self.link(left), self.link(right)) {
1808 (Some(left_link), Some(right_link)) => {
1809 let order = self.compare_nodes(left_link.head, right_link.head);
1810 if order != Ordering::Equal {
1811 return order;
1812 }
1813 left = left_link.tail;
1814 right = right_link.tail;
1815 }
1816 (None, None) => return Ordering::Equal,
1817 (None, Some(_)) => return Ordering::Less,
1818 (Some(_), None) => return Ordering::Greater,
1819 }
1820 }
1821 }
1822
1823 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
1824 let left = self.node(left);
1825 let right = self.node(right);
1826 match (left, right) {
1827 (
1828 ArenaRecognizedNode::Token { token: left },
1829 ArenaRecognizedNode::Token { token: right },
1830 )
1831 | (
1832 ArenaRecognizedNode::ErrorToken { token: left },
1833 ArenaRecognizedNode::ErrorToken { token: right },
1834 ) => left.cmp(&right),
1835 (
1836 ArenaRecognizedNode::MissingToken { extra: left },
1837 ArenaRecognizedNode::MissingToken { extra: right },
1838 ) => self.extra(left).cmp(self.extra(right)),
1839 (
1840 ArenaRecognizedNode::Rule {
1841 rule_index: left_rule,
1842 invoking_state: left_invoking,
1843 alt_number: left_alt,
1844 start_index: left_start,
1845 stop_index: left_stop,
1846 return_values: left_returns,
1847 children: left_children,
1848 },
1849 ArenaRecognizedNode::Rule {
1850 rule_index: right_rule,
1851 invoking_state: right_invoking,
1852 alt_number: right_alt,
1853 start_index: right_start,
1854 stop_index: right_stop,
1855 return_values: right_returns,
1856 children: right_children,
1857 },
1858 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
1859 .cmp(&(
1860 right_rule,
1861 right_invoking,
1862 right_alt,
1863 right_start,
1864 right_stop,
1865 ))
1866 .then_with(|| {
1867 left_returns
1868 .map(|id| self.extra(id))
1869 .cmp(&right_returns.map(|id| self.extra(id)))
1870 })
1871 .then_with(|| self.compare_sequences(left_children, right_children)),
1872 (
1873 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: left },
1874 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: right },
1875 ) => left.cmp(&right),
1876 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
1877 }
1878 }
1879
1880 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1881 let mut reversed = NodeSeqId::EMPTY;
1882 while let Some(link) = self.link(sequence) {
1883 reversed = self.prepend(reversed, link.head);
1884 sequence = link.tail;
1885 }
1886 reversed
1887 }
1888
1889 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1890 if !self.sequence_has_direct_boundary(sequence) {
1891 return sequence;
1892 }
1893 let mut reversed = NodeSeqId::EMPTY;
1894 while let Some(link) = self.link(sequence) {
1895 match self.node(link.head) {
1896 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index } => {
1897 if !reversed.is_empty() {
1898 let children = self.reverse_sequence(reversed);
1899 let start_index = self.sequence_start_index(children).unwrap_or_default();
1900 let stop_index = self.sequence_stop_index(children);
1901 let rule = self.push_node(ArenaRecognizedNode::Rule {
1902 rule_index,
1903 invoking_state: -1,
1904 alt_number: 0,
1905 start_index: u32::try_from(start_index)
1906 .expect("left-recursive start index fits in u32"),
1907 stop_index: stop_index.map(|index| {
1908 u32::try_from(index).expect("left-recursive stop index fits in u32")
1909 }),
1910 return_values: None,
1911 children,
1912 });
1913 reversed = self.prepend(NodeSeqId::EMPTY, rule);
1914 }
1915 }
1916 _ => {
1917 reversed = self.prepend(reversed, link.head);
1918 }
1919 }
1920 sequence = link.tail;
1921 }
1922 self.reverse_sequence(reversed)
1923 }
1924
1925 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
1926 let mut live_nodes = vec![false; self.nodes.len()];
1927 let mut live_links = vec![false; self.seq_links.len()];
1928 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
1929 let mut live_extras = vec![false; self.extras.len()];
1930 let mut pending = vec![root];
1931 while let Some(mut sequence) = pending.pop() {
1932 while let Some(link) = self.link(sequence) {
1933 let link_index = sequence.0 as usize;
1934 if live_links[link_index] {
1935 break;
1936 }
1937 live_links[link_index] = true;
1938 let node_index = link.head.0 as usize;
1939 if !live_nodes[node_index] {
1940 live_nodes[node_index] = true;
1941 match self.node(link.head) {
1942 ArenaRecognizedNode::MissingToken { extra } => {
1943 live_extras[extra.0 as usize] = true;
1944 }
1945 ArenaRecognizedNode::Rule {
1946 return_values,
1947 children,
1948 ..
1949 } => {
1950 if let Some(extra) = return_values {
1951 live_extras[extra.0 as usize] = true;
1952 }
1953 pending.push(children);
1954 }
1955 ArenaRecognizedNode::Token { .. }
1956 | ArenaRecognizedNode::ErrorToken { .. }
1957 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
1958 }
1959 }
1960 sequence = link.tail;
1961 }
1962 }
1963 let mut diagnostics = diagnostics;
1964 while let Some(link) = self.diagnostic_link(diagnostics) {
1965 let link_index = diagnostics.0 as usize;
1966 if live_diagnostic_links[link_index] {
1967 break;
1968 }
1969 live_diagnostic_links[link_index] = true;
1970 live_extras[link.head.0 as usize] = true;
1971 diagnostics = link.tail;
1972 }
1973 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
1974 let live_link_count = live_links.into_iter().filter(|live| *live).count()
1975 + live_diagnostic_links
1976 .into_iter()
1977 .filter(|live| *live)
1978 .count();
1979 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
1980 let total_links = self.seq_links.len() + self.diagnostic_links.len();
1981 RecognitionArenaStats {
1982 total_nodes: self.nodes.len(),
1983 live_nodes: live_node_count,
1984 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
1985 node_capacity: self.nodes.capacity(),
1986 total_links,
1987 live_links: live_link_count,
1988 dead_links: total_links.saturating_sub(live_link_count),
1989 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
1990 total_extras: self.extras.len(),
1991 live_extras: live_extra_count,
1992 dead_extras: self.extras.len().saturating_sub(live_extra_count),
1993 extra_capacity: self.extras.capacity(),
1994 }
1995 }
1996}
1997
1998fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
1999 if storage.capacity() > max_retained_capacity {
2000 *storage = Vec::new();
2001 } else {
2002 storage.clear();
2003 }
2004}
2005
2006const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
2007 match node {
2008 ArenaRecognizedNode::Token { .. } => 0,
2009 ArenaRecognizedNode::ErrorToken { .. } => 1,
2010 ArenaRecognizedNode::MissingToken { .. } => 2,
2011 ArenaRecognizedNode::Rule { .. } => 3,
2012 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
2013 }
2014}
2015
2016struct NodeSeqIter<'a> {
2017 arena: &'a RecognitionArena,
2018 cursor: NodeSeqId,
2019}
2020
2021impl Iterator for NodeSeqIter<'_> {
2022 type Item = RecognizedNodeId;
2023
2024 fn next(&mut self) -> Option<Self::Item> {
2025 let link = self.arena.link(self.cursor)?;
2026 self.cursor = link.tail;
2027 Some(link.head)
2028 }
2029}
2030
2031struct DiagnosticSeqIter<'a> {
2032 arena: &'a RecognitionArena,
2033 cursor: DiagnosticSeqId,
2034}
2035
2036impl<'a> Iterator for DiagnosticSeqIter<'a> {
2037 type Item = &'a ParserDiagnostic;
2038
2039 fn next(&mut self) -> Option<Self::Item> {
2040 let link = self.arena.diagnostic_link(self.cursor)?;
2041 self.cursor = link.tail;
2042 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2043 unreachable!("diagnostic link must reference diagnostic extra");
2044 };
2045 Some(diagnostic)
2046 }
2047}
2048
2049#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2050struct ParserDiagnostic {
2051 line: usize,
2052 column: usize,
2053 message: String,
2054}
2055
2056#[derive(Clone, Debug, Default, Eq, PartialEq)]
2057struct ExpectedTokens {
2058 index: Option<usize>,
2059 symbols: BTreeSet<i32>,
2060 no_viable: Option<NoViableAlternative>,
2061}
2062
2063#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2064struct NoViableAlternative {
2065 start_index: usize,
2066 error_index: usize,
2067}
2068
2069impl ExpectedTokens {
2070 fn record_transition(
2073 &mut self,
2074 index: usize,
2075 transition: ParserTransition<'_>,
2076 max_token_type: i32,
2077 ) {
2078 let symbols = transition_expected_symbols(transition, max_token_type);
2079 match self.index {
2080 Some(current) if index < current => {}
2081 Some(current) if index == current => self.symbols.extend(symbols),
2082 _ => {
2083 self.index = Some(index);
2084 self.symbols = symbols;
2085 }
2086 }
2087 }
2088
2089 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2092 match self.no_viable {
2093 Some(current) if error_index < current.error_index => {}
2094 _ => {
2095 self.no_viable = Some(NoViableAlternative {
2096 start_index,
2097 error_index,
2098 });
2099 }
2100 }
2101 }
2102}
2103
2104#[derive(Clone, Debug, Default, Eq, PartialEq)]
2111struct TokenBitSet {
2112 words: Vec<u64>,
2113}
2114
2115impl TokenBitSet {
2116 fn insert(&mut self, symbol: i32) {
2117 let Some(slot) = token_bit_slot(symbol) else {
2118 return;
2119 };
2120 let word = slot / u64::BITS as usize;
2121 if word >= self.words.len() {
2122 self.words.resize(word + 1, 0);
2123 }
2124 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2125 }
2126
2127 fn extend_range(&mut self, start: i32, stop: i32) {
2128 let (start, stop) = if start <= stop {
2129 (start, stop)
2130 } else {
2131 (stop, start)
2132 };
2133 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2134 self.insert(TOKEN_EOF);
2135 }
2136 let positive_start = start.max(1);
2137 if positive_start > stop {
2138 return;
2139 }
2140 let Some(start_slot) = token_bit_slot(positive_start) else {
2141 return;
2142 };
2143 let Some(stop_slot) = token_bit_slot(stop) else {
2144 return;
2145 };
2146 self.extend_slot_range(start_slot, stop_slot);
2147 }
2148
2149 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2150 if start_slot > stop_slot {
2151 return;
2152 }
2153 let start_word = start_slot / u64::BITS as usize;
2154 let stop_word = stop_slot / u64::BITS as usize;
2155 if stop_word >= self.words.len() {
2156 self.words.resize(stop_word + 1, 0);
2157 }
2158 let start_offset = start_slot % u64::BITS as usize;
2159 let stop_offset = stop_slot % u64::BITS as usize;
2160 if start_word == stop_word {
2161 self.words[start_word] |=
2162 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2163 return;
2164 }
2165 self.words[start_word] |= !0_u64 << start_offset;
2166 for word in &mut self.words[(start_word + 1)..stop_word] {
2167 *word = !0_u64;
2168 }
2169 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2170 }
2171
2172 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2173 for symbol in symbols {
2174 self.insert(symbol);
2175 }
2176 }
2177
2178 fn extend_from(&mut self, other: &Self) {
2179 if other.words.len() > self.words.len() {
2180 self.words.resize(other.words.len(), 0);
2181 }
2182 for (left, right) in self.words.iter_mut().zip(&other.words) {
2183 *left |= *right;
2184 }
2185 }
2186
2187 fn contains(&self, symbol: i32) -> bool {
2188 let Some(slot) = token_bit_slot(symbol) else {
2189 return false;
2190 };
2191 let word = slot / u64::BITS as usize;
2192 self.words
2193 .get(word)
2194 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2195 }
2196
2197 fn is_empty(&self) -> bool {
2198 self.words.iter().all(|word| *word == 0)
2199 }
2200
2201 fn symbols(&self) -> impl Iterator<Item = i32> + '_ {
2202 self.words
2203 .iter()
2204 .copied()
2205 .enumerate()
2206 .flat_map(|(word_index, mut bits)| {
2207 std::iter::from_fn(move || {
2208 while bits != 0 {
2209 let bit = bits.trailing_zeros() as usize;
2210 bits &= bits - 1;
2211 if let Some(symbol) =
2212 token_bit_symbol(word_index * u64::BITS as usize + bit)
2213 {
2214 return Some(symbol);
2215 }
2216 }
2217 None
2218 })
2219 })
2220 }
2221
2222 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2223 target.extend(self.symbols());
2224 }
2225
2226 fn to_btree_set(&self) -> BTreeSet<i32> {
2227 let mut out = BTreeSet::new();
2228 self.extend_btree_set(&mut out);
2229 out
2230 }
2231}
2232
2233fn token_bit_slot(symbol: i32) -> Option<usize> {
2234 if symbol == TOKEN_EOF {
2235 Some(0)
2236 } else if symbol > 0 {
2237 usize::try_from(symbol).ok()
2238 } else {
2239 None
2240 }
2241}
2242
2243fn token_bit_symbol(slot: usize) -> Option<i32> {
2244 if slot == 0 {
2245 Some(TOKEN_EOF)
2246 } else {
2247 i32::try_from(slot).ok()
2248 }
2249}
2250
2251fn transition_expected_symbols(
2254 transition: ParserTransition<'_>,
2255 max_token_type: i32,
2256) -> BTreeSet<i32> {
2257 let mut symbols = BTreeSet::new();
2258 match &transition.data() {
2259 Transition::Atom { label, .. } => {
2260 symbols.insert(*label);
2261 }
2262 Transition::Range { start, stop, .. } => {
2263 symbols.extend(*start..=*stop);
2264 }
2265 Transition::Set { set, .. } => {
2266 for (start, stop) in set.ranges() {
2267 symbols.extend(start..=stop);
2268 }
2269 }
2270 Transition::NotSet { set, .. } => {
2271 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2272 }
2273 Transition::Wildcard { .. } => {
2274 symbols.extend(1..=max_token_type);
2275 }
2276 Transition::Epsilon { .. }
2277 | Transition::Rule { .. }
2278 | Transition::Predicate { .. }
2279 | Transition::Action { .. }
2280 | Transition::Precedence { .. } => {}
2281 }
2282 symbols
2283}
2284
2285fn transition_expected_token_set(
2286 transition: ParserTransition<'_>,
2287 max_token_type: i32,
2288) -> TokenBitSet {
2289 let mut symbols = TokenBitSet::default();
2290 match &transition.data() {
2291 Transition::Atom { label, .. } => {
2292 symbols.insert(*label);
2293 }
2294 Transition::Range { start, stop, .. } => {
2295 symbols.extend_range(*start, *stop);
2296 }
2297 Transition::Set { set, .. } => {
2298 for (start, stop) in set.ranges() {
2299 symbols.extend_range(start, stop);
2300 }
2301 }
2302 Transition::NotSet { set, .. } => {
2303 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2304 }
2305 Transition::Wildcard { .. } => {
2306 symbols.extend_range(1, max_token_type);
2307 }
2308 Transition::Epsilon { .. }
2309 | Transition::Rule { .. }
2310 | Transition::Predicate { .. }
2311 | Transition::Action { .. }
2312 | Transition::Precedence { .. } => {}
2313 }
2314 symbols
2315}
2316
2317fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2321 let mut symbols = BTreeSet::new();
2322 let mut stack = vec![state_number];
2323 let mut visited = BTreeSet::new();
2324 while let Some(current) = stack.pop() {
2325 if !visited.insert(current) {
2326 continue;
2327 }
2328 let Some(state) = atn.state(current) else {
2329 continue;
2330 };
2331 for transition in &state.transitions() {
2332 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2333 if transition_symbols.is_empty() {
2334 if transition.is_epsilon() {
2335 stack.push(transition.target());
2336 }
2337 } else {
2338 symbols.extend(transition_symbols);
2339 }
2340 }
2341 }
2342 symbols
2343}
2344
2345fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2346 let mut symbols = TokenBitSet::default();
2347 let mut stack = vec![state_number];
2348 let mut visited = BTreeSet::new();
2349 while let Some(current) = stack.pop() {
2350 if !visited.insert(current) {
2351 continue;
2352 }
2353 let Some(state) = atn.state(current) else {
2354 continue;
2355 };
2356 for transition in &state.transitions() {
2357 let transition_symbols =
2358 transition_expected_token_set(transition, atn.max_token_type());
2359 if transition_symbols.is_empty() {
2360 if transition.is_epsilon() {
2361 stack.push(transition.target());
2362 }
2363 } else {
2364 symbols.extend_from(&transition_symbols);
2365 }
2366 }
2367 }
2368 symbols
2369}
2370
2371fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2372 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2373 return false;
2374 };
2375 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2376 return false;
2377 };
2378 epsilon_reaches_state(atn, state_number, stop_state)
2379}
2380
2381fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2382 let mut stack = vec![start];
2383 let mut visited = BTreeSet::new();
2384 while let Some(current) = stack.pop() {
2385 if current == target {
2386 return true;
2387 }
2388 if !visited.insert(current) {
2389 continue;
2390 }
2391 let Some(state) = atn.state(current) else {
2392 continue;
2393 };
2394 stack.extend(
2395 state
2396 .transitions()
2397 .iter()
2398 .filter(|transition| transition.is_epsilon())
2399 .map(ParserTransition::target),
2400 );
2401 }
2402 false
2403}
2404
2405#[derive(Clone, Debug, Default, Eq, PartialEq)]
2412struct FirstSet {
2413 symbols: TokenBitSet,
2414 nullable: bool,
2415}
2416
2417type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2424
2425type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2432
2433#[derive(Debug, Default)]
2434struct LeftRecursiveOperatorLookahead {
2435 single_token: TokenBitSet,
2439 multi_token_prefix: TokenBitSet,
2444 predicate_dependent: TokenBitSet,
2445}
2446
2447#[derive(Default)]
2448struct SharedAtnCache {
2449 first_set: FirstSetCache,
2450 decision_lookahead: DecisionLookaheadCache,
2451 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2452 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2453 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2454 rule_stop_reach: FxHashMap<usize, bool>,
2455 observable_action_transitions: Option<bool>,
2456 predicate_transitions: Option<bool>,
2457}
2458
2459thread_local! {
2460 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2461 RefCell::new(FxHashMap::default());
2462}
2463
2464#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2475struct SharedAtnCacheKey {
2476 atn: usize,
2477 states: usize,
2478 state_count: usize,
2479 max_token_type: i32,
2480}
2481
2482impl SharedAtnCacheKey {
2483 fn for_atn(atn: &Atn) -> Self {
2484 let (states, state_count) = atn.storage_identity();
2485 Self {
2486 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2487 states,
2488 state_count,
2489 max_token_type: atn.max_token_type(),
2490 }
2491 }
2492}
2493
2494fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2495 SHARED_ATN_CACHES.with(|cell| {
2496 let key = SharedAtnCacheKey::for_atn(atn);
2497 let mut map = cell.borrow_mut();
2498 let cache = map.entry(key).or_default();
2499 f(&mut cache.first_set)
2500 })
2501}
2502
2503fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
2504 SHARED_ATN_CACHES.with(|cell| {
2505 let key = SharedAtnCacheKey::for_atn(atn);
2506 let mut map = cell.borrow_mut();
2507 let cache = map.entry(key).or_default();
2508 f(cache)
2509 })
2510}
2511
2512#[derive(Debug, Default)]
2521struct DecisionLookahead {
2522 transitions: Vec<TransitionLookSet>,
2523}
2524
2525#[derive(Clone, Debug, Default)]
2532struct TransitionLookSet {
2533 symbols: TokenBitSet,
2534 nullable: bool,
2535}
2536
2537struct FirstSetCtx<'a> {
2541 cache: &'a mut FirstSetCache,
2542 in_progress: BTreeSet<(usize, usize)>,
2543 hit_cycle: bool,
2544}
2545
2546fn rule_first_set(
2555 atn: &Atn,
2556 target: usize,
2557 rule_stop_state: usize,
2558 cache: &mut FirstSetCache,
2559) -> Rc<FirstSet> {
2560 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
2561 return Rc::clone(cached);
2562 }
2563 let mut ctx = FirstSetCtx {
2564 cache,
2565 in_progress: BTreeSet::new(),
2566 hit_cycle: false,
2567 };
2568 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
2569}
2570
2571fn rule_first_set_cached(
2572 atn: &Atn,
2573 target: usize,
2574 rule_stop_state: usize,
2575 ctx: &mut FirstSetCtx<'_>,
2576) -> Rc<FirstSet> {
2577 let key = (target, rule_stop_state);
2578 if let Some(cached) = ctx.cache.get(&key) {
2579 return Rc::clone(cached);
2580 }
2581 if !ctx.in_progress.insert(key) {
2582 return Rc::new(FirstSet::default());
2586 }
2587 let saved_hit_cycle = ctx.hit_cycle;
2588 ctx.hit_cycle = false;
2589 let mut first = FirstSet::default();
2590 let mut visited = BTreeSet::new();
2591 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
2592 ctx.in_progress.remove(&key);
2593 let entry = Rc::new(first);
2594 if !ctx.hit_cycle {
2595 ctx.cache.insert(key, Rc::clone(&entry));
2596 }
2597 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
2598 entry
2599}
2600
2601fn transition_first_set(
2605 atn: &Atn,
2606 transition: ParserTransition<'_>,
2607 rule_stop_state: usize,
2608 cache: &mut FirstSetCache,
2609) -> TransitionLookSet {
2610 match &transition.data() {
2611 Transition::Atom { label, .. } => {
2612 let mut symbols = TokenBitSet::default();
2613 symbols.insert(*label);
2614 TransitionLookSet {
2615 symbols,
2616 nullable: false,
2617 }
2618 }
2619 Transition::Range { start, stop, .. } => {
2620 let mut symbols = TokenBitSet::default();
2621 symbols.extend_range(*start, *stop);
2622 TransitionLookSet {
2623 symbols,
2624 nullable: false,
2625 }
2626 }
2627 Transition::Set { set, .. } => {
2628 let mut symbols = TokenBitSet::default();
2629 for (start, stop) in set.ranges() {
2630 symbols.extend_range(start, stop);
2631 }
2632 TransitionLookSet {
2633 symbols,
2634 nullable: false,
2635 }
2636 }
2637 Transition::NotSet { set, .. } => {
2638 let max = atn.max_token_type();
2639 let mut symbols = TokenBitSet::default();
2640 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
2641 TransitionLookSet {
2642 symbols,
2643 nullable: false,
2644 }
2645 }
2646 Transition::Wildcard { .. } => {
2647 let mut symbols = TokenBitSet::default();
2648 symbols.extend_range(1, atn.max_token_type());
2649 TransitionLookSet {
2650 symbols,
2651 nullable: false,
2652 }
2653 }
2654 Transition::Epsilon { target }
2655 | Transition::Action { target, .. }
2656 | Transition::Predicate { target, .. }
2657 | Transition::Precedence { target, .. } => {
2658 let first = rule_first_set(atn, *target, rule_stop_state, cache);
2661 TransitionLookSet {
2662 symbols: first.symbols.clone(),
2663 nullable: first.nullable,
2664 }
2665 }
2666 Transition::Rule {
2667 target,
2668 rule_index,
2669 follow_state,
2670 ..
2671 } => {
2672 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2673 return TransitionLookSet::default();
2674 };
2675 let child = rule_first_set(atn, *target, child_stop, cache);
2676 let mut symbols = child.symbols.clone();
2677 let nullable = if child.nullable {
2678 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
2679 symbols.extend_from(&follow.symbols);
2680 follow.nullable
2681 } else {
2682 false
2683 };
2684 TransitionLookSet { symbols, nullable }
2685 }
2686 }
2687}
2688
2689fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
2710 let mut chosen: Option<usize> = None;
2711 for (index, transition) in entry.transitions.iter().enumerate() {
2712 if transition.nullable {
2713 return None;
2714 }
2715 if transition.symbols.contains(symbol) {
2716 if chosen.is_some() {
2717 return None;
2718 }
2719 chosen = Some(index);
2720 }
2721 }
2722 chosen
2723}
2724
2725fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
2734 let mut matching_non_nullable_alt = None;
2735 let mut nullable_alt = None;
2736 for (index, transition) in entry.transitions.iter().enumerate() {
2737 if transition.nullable {
2738 if nullable_alt.is_some() {
2739 return None;
2740 }
2741 nullable_alt = Some(index);
2742 }
2743 if transition.symbols.contains(symbol) {
2744 if transition.nullable {
2745 continue;
2746 }
2747 if matching_non_nullable_alt.is_some() {
2748 return None;
2749 }
2750 matching_non_nullable_alt = Some(index);
2751 }
2752 }
2753 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
2754 return None;
2755 }
2756 if non_greedy {
2757 nullable_alt.or(matching_non_nullable_alt)
2758 } else {
2759 matching_non_nullable_alt.or(nullable_alt)
2760 }
2761}
2762
2763fn should_skip_via_lookahead(
2764 transition_kind: ParserTransitionKind,
2765 transition_index: usize,
2766 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
2767 index: usize,
2768 record_expected: bool,
2769 expected: &mut ExpectedTokens,
2770) -> bool {
2771 let prune_non_consuming = matches!(
2772 transition_kind,
2773 ParserTransitionKind::Epsilon
2774 | ParserTransitionKind::Action
2775 | ParserTransitionKind::Predicate
2776 | ParserTransitionKind::Rule
2777 | ParserTransitionKind::Precedence
2778 );
2779 if !prune_non_consuming {
2780 return false;
2781 }
2782 let Some((symbol, entry)) = lookahead_filter else {
2783 return false;
2784 };
2785 let Some(set) = entry.transitions.get(transition_index) else {
2786 return false;
2787 };
2788 if set.symbols.contains(*symbol) || set.nullable {
2789 return false;
2790 }
2791 if record_expected && !set.symbols.is_empty() {
2792 record_pruned_transition_expected(set, index, expected);
2793 }
2794 true
2795}
2796
2797fn should_skip_rule_via_first_set(
2798 first: &FirstSet,
2799 symbol: i32,
2800 record_expected: bool,
2801 index: usize,
2802 expected: &mut ExpectedTokens,
2803) -> bool {
2804 if first.nullable || first.symbols.contains(symbol) {
2805 return false;
2806 }
2807 if record_expected && !first.symbols.is_empty() {
2808 record_token_bit_expected(&first.symbols, index, expected);
2809 }
2810 true
2811}
2812
2813fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
2814 match expected.index {
2815 Some(current) if index < current => {}
2816 Some(current) if index == current => {
2817 symbols.extend_btree_set(&mut expected.symbols);
2818 }
2819 _ => {
2820 expected.index = Some(index);
2821 expected.symbols = symbols.to_btree_set();
2822 }
2823 }
2824}
2825
2826fn record_pruned_transition_expected(
2828 set: &TransitionLookSet,
2829 index: usize,
2830 expected: &mut ExpectedTokens,
2831) {
2832 match expected.index {
2833 Some(current) if index < current => {}
2834 Some(current) if index == current => {
2835 set.symbols.extend_btree_set(&mut expected.symbols);
2836 }
2837 _ => {
2838 expected.index = Some(index);
2839 expected.symbols = set.symbols.to_btree_set();
2840 }
2841 }
2842}
2843
2844fn rule_first_set_inner(
2845 atn: &Atn,
2846 state_number: usize,
2847 rule_stop_state: usize,
2848 ctx: &mut FirstSetCtx<'_>,
2849 visited: &mut BTreeSet<usize>,
2850 first: &mut FirstSet,
2851) {
2852 if !visited.insert(state_number) {
2853 return;
2854 }
2855 if state_number == rule_stop_state {
2856 first.nullable = true;
2857 return;
2858 }
2859 let Some(state) = atn.state(state_number) else {
2860 return;
2861 };
2862 for transition in &state.transitions() {
2863 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2864 if !transition_symbols.is_empty() {
2865 first.symbols.extend_iter(transition_symbols);
2866 continue;
2867 }
2868 match &transition.data() {
2869 Transition::Epsilon { target }
2870 | Transition::Action { target, .. }
2871 | Transition::Predicate { target, .. }
2872 | Transition::Precedence { target, .. } => {
2873 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
2874 }
2875 Transition::Rule {
2876 target,
2877 rule_index,
2878 follow_state,
2879 ..
2880 } => {
2881 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2882 continue;
2883 };
2884 let child_key = (*target, child_stop);
2885 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
2886 ctx.hit_cycle = true;
2887 }
2888 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
2889 first.symbols.extend_from(&child.symbols);
2890 if child.nullable {
2891 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
2892 }
2893 }
2894 Transition::Atom { .. }
2895 | Transition::Range { .. }
2896 | Transition::Set { .. }
2897 | Transition::NotSet { .. }
2898 | Transition::Wildcard { .. } => {}
2899 }
2900 }
2901}
2902
2903fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
2906 let mut symbols = BTreeSet::new();
2907 state_sync_symbols_inner(
2908 atn,
2909 state_number,
2910 stop_state,
2911 &mut BTreeSet::new(),
2912 &mut symbols,
2913 );
2914 symbols
2915}
2916
2917fn state_sync_symbols_inner(
2920 atn: &Atn,
2921 state_number: usize,
2922 stop_state: usize,
2923 visited: &mut BTreeSet<usize>,
2924 symbols: &mut BTreeSet<i32>,
2925) {
2926 if !visited.insert(state_number) {
2927 return;
2928 }
2929 if state_number == stop_state {
2930 symbols.insert(TOKEN_EOF);
2931 return;
2932 }
2933 let Some(state) = atn.state(state_number) else {
2934 return;
2935 };
2936 for transition in &state.transitions() {
2937 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2938 if transition_symbols.is_empty() {
2939 match &transition.data() {
2940 Transition::Rule { target, .. }
2941 | Transition::Epsilon { target }
2942 | Transition::Action { target, .. }
2943 | Transition::Predicate { target, .. }
2944 | Transition::Precedence { target, .. } => {
2945 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
2946 }
2947 Transition::Atom { .. }
2948 | Transition::Range { .. }
2949 | Transition::Set { .. }
2950 | Transition::NotSet { .. }
2951 | Transition::Wildcard { .. } => {}
2952 }
2953 } else {
2954 symbols.extend(transition_symbols);
2955 }
2956 }
2957}
2958
2959#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
2960struct OperatorSymbolReachability {
2961 single_token: bool,
2963 multi_token: bool,
2965 predicate_dependent: bool,
2967}
2968
2969impl OperatorSymbolReachability {
2970 const ADAPTIVE_FALLBACK: Self = Self {
2971 single_token: false,
2972 multi_token: false,
2973 predicate_dependent: true,
2974 };
2975
2976 const fn single_token(predicate_dependent: bool) -> Self {
2977 if predicate_dependent {
2978 Self {
2979 single_token: false,
2980 multi_token: false,
2981 predicate_dependent: true,
2982 }
2983 } else {
2984 Self {
2985 single_token: true,
2986 multi_token: false,
2987 predicate_dependent: false,
2988 }
2989 }
2990 }
2991
2992 const fn multi_token(predicate_dependent: bool) -> Self {
2993 if predicate_dependent {
2994 Self {
2995 single_token: false,
2996 multi_token: false,
2997 predicate_dependent: true,
2998 }
2999 } else {
3000 Self {
3001 single_token: false,
3002 multi_token: true,
3003 predicate_dependent: false,
3004 }
3005 }
3006 }
3007
3008 const fn union(self, other: Self) -> Self {
3009 Self {
3010 single_token: self.single_token || other.single_token,
3011 multi_token: self.multi_token || other.multi_token,
3012 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
3013 }
3014 }
3015}
3016
3017#[derive(Clone, Copy)]
3018struct OperatorReachabilityRequest {
3019 symbol: i32,
3020 precedence: i32,
3021 predicate_dependent: bool,
3022 operator_rule_index: usize,
3023}
3024
3025#[derive(Clone, Copy, Debug)]
3026struct OperatorRuleContinuation {
3027 stop_state: usize,
3028 follow_state: usize,
3029 return_precedence: i32,
3030}
3031
3032struct NullablePrecedenceCtx {
3033 cache: FxHashMap<(usize, usize, i32, bool), bool>,
3034 in_progress: BTreeSet<(usize, usize, i32, bool)>,
3035 hit_cycle: bool,
3036}
3037
3038fn state_is_nullable_with_precedence(
3039 atn: &Atn,
3040 state_number: usize,
3041 stop_state_number: usize,
3042 precedence: i32,
3043 allow_predicates: bool,
3044 ctx: &mut NullablePrecedenceCtx,
3045) -> bool {
3046 let saved_hit_cycle = ctx.hit_cycle;
3047 ctx.hit_cycle = false;
3048 let nullable = state_is_nullable_with_precedence_cached(
3049 atn,
3050 state_number,
3051 stop_state_number,
3052 precedence,
3053 allow_predicates,
3054 ctx,
3055 );
3056 ctx.hit_cycle = saved_hit_cycle;
3057 nullable
3058}
3059
3060fn state_is_nullable_with_precedence_cached(
3061 atn: &Atn,
3062 state_number: usize,
3063 stop_state_number: usize,
3064 precedence: i32,
3065 allow_predicates: bool,
3066 ctx: &mut NullablePrecedenceCtx,
3067) -> bool {
3068 if state_number == stop_state_number {
3069 return true;
3070 }
3071 let key = (
3072 state_number,
3073 stop_state_number,
3074 precedence,
3075 allow_predicates,
3076 );
3077 if let Some(cached) = ctx.cache.get(&key) {
3078 return *cached;
3079 }
3080 if !ctx.in_progress.insert(key) {
3081 ctx.hit_cycle = true;
3082 return false;
3083 }
3084 let saved_hit_cycle = ctx.hit_cycle;
3085 ctx.hit_cycle = false;
3086 let nullable = atn.state(state_number).is_some_and(|state| {
3087 state
3088 .transitions()
3089 .iter()
3090 .any(|transition| match &transition.data() {
3091 Transition::Rule {
3092 target,
3093 rule_index,
3094 follow_state,
3095 precedence: rule_precedence,
3096 } => {
3097 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3098 return false;
3099 };
3100 state_is_nullable_with_precedence_cached(
3101 atn,
3102 *target,
3103 child_stop,
3104 *rule_precedence,
3105 allow_predicates,
3106 ctx,
3107 ) && state_is_nullable_with_precedence_cached(
3108 atn,
3109 *follow_state,
3110 stop_state_number,
3111 precedence,
3112 allow_predicates,
3113 ctx,
3114 )
3115 }
3116 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3117 state_is_nullable_with_precedence_cached(
3118 atn,
3119 *target,
3120 stop_state_number,
3121 precedence,
3122 allow_predicates,
3123 ctx,
3124 )
3125 }
3126 Transition::Predicate { target, .. } if allow_predicates => {
3127 state_is_nullable_with_precedence_cached(
3128 atn,
3129 *target,
3130 stop_state_number,
3131 precedence,
3132 allow_predicates,
3133 ctx,
3134 )
3135 }
3136 Transition::Precedence {
3137 target,
3138 precedence: transition_precedence,
3139 } if *transition_precedence >= precedence => {
3140 state_is_nullable_with_precedence_cached(
3141 atn,
3142 *target,
3143 stop_state_number,
3144 precedence,
3145 allow_predicates,
3146 ctx,
3147 )
3148 }
3149 Transition::Atom { .. }
3150 | Transition::Range { .. }
3151 | Transition::Set { .. }
3152 | Transition::NotSet { .. }
3153 | Transition::Wildcard { .. }
3154 | Transition::Predicate { .. }
3155 | Transition::Precedence { .. } => false,
3156 })
3157 });
3158 ctx.in_progress.remove(&key);
3159 if !ctx.hit_cycle {
3160 ctx.cache.insert(key, nullable);
3161 }
3162 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3163 nullable
3164}
3165
3166fn state_operator_token_prefix_reachability(
3168 atn: &Atn,
3169 state_number: usize,
3170 request: OperatorReachabilityRequest,
3171 continuations: &[OperatorRuleContinuation],
3172 visited: &mut BTreeSet<(usize, i32, bool)>,
3173) -> OperatorSymbolReachability {
3174 let key = (
3175 state_number,
3176 request.precedence,
3177 request.predicate_dependent,
3178 );
3179 if !visited.insert(key) {
3180 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3184 }
3185 if let Some((continuation, remaining)) = continuations.split_last()
3186 && state_number == continuation.stop_state
3187 {
3188 let result = state_operator_token_prefix_reachability(
3189 atn,
3190 continuation.follow_state,
3191 OperatorReachabilityRequest {
3192 precedence: continuation.return_precedence,
3193 ..request
3194 },
3195 remaining,
3196 visited,
3197 );
3198 visited.remove(&key);
3199 return result;
3200 }
3201 let Some(state) = atn.state(state_number) else {
3202 visited.remove(&key);
3203 return OperatorSymbolReachability::default();
3204 };
3205 let completes_operator = match state.kind() {
3206 AtnStateKind::RuleStop => continuations.is_empty(),
3207 AtnStateKind::StarLoopBack
3208 | AtnStateKind::StarLoopEntry
3209 | AtnStateKind::PlusLoopBack
3210 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3211 _ => false,
3212 };
3213 if completes_operator {
3214 visited.remove(&key);
3215 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3216 }
3217 let mut reachability = OperatorSymbolReachability::default();
3218 for transition in &state.transitions() {
3219 let transition_reachability = match &transition.data() {
3220 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3221 OperatorSymbolReachability::single_token(request.predicate_dependent)
3222 }
3223 Transition::Rule {
3224 target,
3225 rule_index,
3226 follow_state,
3227 precedence: rule_precedence,
3228 } => {
3229 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3230 continue;
3231 };
3232 let mut nested = continuations.to_vec();
3233 nested.push(OperatorRuleContinuation {
3234 stop_state: child_stop,
3235 follow_state: *follow_state,
3236 return_precedence: request.precedence,
3237 });
3238 state_operator_token_prefix_reachability(
3239 atn,
3240 *target,
3241 OperatorReachabilityRequest {
3242 precedence: *rule_precedence,
3243 ..request
3244 },
3245 &nested,
3246 visited,
3247 )
3248 }
3249 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3250 state_operator_token_prefix_reachability(
3251 atn,
3252 *target,
3253 request,
3254 continuations,
3255 visited,
3256 )
3257 }
3258 Transition::Precedence {
3259 target,
3260 precedence: transition_precedence,
3261 } => {
3262 if *transition_precedence < request.precedence {
3263 OperatorSymbolReachability::default()
3264 } else {
3265 state_operator_token_prefix_reachability(
3266 atn,
3267 *target,
3268 request,
3269 continuations,
3270 visited,
3271 )
3272 }
3273 }
3274 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3275 atn,
3276 *target,
3277 OperatorReachabilityRequest {
3278 predicate_dependent: true,
3279 ..request
3280 },
3281 continuations,
3282 visited,
3283 ),
3284 Transition::Atom { .. }
3285 | Transition::Range { .. }
3286 | Transition::Set { .. }
3287 | Transition::NotSet { .. }
3288 | Transition::Wildcard { .. } => {
3289 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3290 }
3291 };
3292 reachability = reachability.union(transition_reachability);
3293 }
3294 visited.remove(&key);
3295 reachability
3296}
3297
3298fn state_can_reach_symbol_with_precedence(
3299 atn: &Atn,
3300 state_number: usize,
3301 request: OperatorReachabilityRequest,
3302 nullable_ctx: &mut NullablePrecedenceCtx,
3303 continuations: &mut Vec<OperatorRuleContinuation>,
3304 visited: &mut BTreeSet<(usize, i32, bool)>,
3305) -> OperatorSymbolReachability {
3306 let key = (
3307 state_number,
3308 request.precedence,
3309 request.predicate_dependent,
3310 );
3311 if !visited.insert(key) {
3312 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3313 }
3314 let Some(state) = atn.state(state_number) else {
3315 visited.remove(&key);
3316 return OperatorSymbolReachability::default();
3317 };
3318 let mut reachability = OperatorSymbolReachability::default();
3319 for transition in &state.transitions() {
3320 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3321 reachability = reachability.union(state_operator_token_prefix_reachability(
3322 atn,
3323 transition.target(),
3324 request,
3325 continuations,
3326 &mut BTreeSet::new(),
3327 ));
3328 continue;
3329 }
3330 let transition_reachability = match &transition.data() {
3331 Transition::Rule {
3332 target,
3333 rule_index,
3334 follow_state,
3335 precedence: rule_precedence,
3336 } => {
3337 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3338 continue;
3339 };
3340 continuations.push(OperatorRuleContinuation {
3341 stop_state: child_stop,
3342 follow_state: *follow_state,
3343 return_precedence: request.precedence,
3344 });
3345 let mut result = state_can_reach_symbol_with_precedence(
3346 atn,
3347 *target,
3348 OperatorReachabilityRequest {
3349 precedence: *rule_precedence,
3350 ..request
3351 },
3352 nullable_ctx,
3353 continuations,
3354 visited,
3355 );
3356 continuations.pop();
3357 if state_is_nullable_with_precedence(
3358 atn,
3359 *target,
3360 child_stop,
3361 *rule_precedence,
3362 true,
3363 nullable_ctx,
3364 ) {
3365 let child_predicate_dependent = request.predicate_dependent
3366 || !state_is_nullable_with_precedence(
3367 atn,
3368 *target,
3369 child_stop,
3370 *rule_precedence,
3371 false,
3372 nullable_ctx,
3373 );
3374 result = result.union(state_can_reach_symbol_with_precedence(
3375 atn,
3376 *follow_state,
3377 OperatorReachabilityRequest {
3378 predicate_dependent: child_predicate_dependent,
3379 ..request
3380 },
3381 nullable_ctx,
3382 continuations,
3383 visited,
3384 ));
3385 }
3386 result
3387 }
3388 Transition::Epsilon { target }
3389 | Transition::Action { target, .. }
3390 | Transition::Precedence { target, .. } => {
3391 if matches!(
3392 &transition.data(),
3393 Transition::Precedence {
3394 precedence: transition_precedence,
3395 ..
3396 } if *transition_precedence < request.precedence
3397 ) {
3398 continue;
3399 }
3400 state_can_reach_symbol_with_precedence(
3401 atn,
3402 *target,
3403 request,
3404 nullable_ctx,
3405 continuations,
3406 visited,
3407 )
3408 }
3409 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3410 atn,
3411 *target,
3412 OperatorReachabilityRequest {
3413 predicate_dependent: true,
3414 ..request
3415 },
3416 nullable_ctx,
3417 continuations,
3418 visited,
3419 ),
3420 Transition::Atom { .. }
3421 | Transition::Range { .. }
3422 | Transition::Set { .. }
3423 | Transition::NotSet { .. }
3424 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3425 };
3426 reachability = reachability.union(transition_reachability);
3427 }
3428 visited.remove(&key);
3429 reachability
3430}
3431
3432fn left_recursive_operator_lookahead(
3433 atn: &Atn,
3434 state_number: usize,
3435 precedence: i32,
3436) -> LeftRecursiveOperatorLookahead {
3437 let Some(state) = atn.state(state_number) else {
3438 return LeftRecursiveOperatorLookahead::default();
3439 };
3440 let Some(operator_rule_index) = state.rule_index() else {
3441 return LeftRecursiveOperatorLookahead::default();
3442 };
3443 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3444 let mut nullable_ctx = NullablePrecedenceCtx {
3445 cache: FxHashMap::default(),
3446 in_progress: BTreeSet::new(),
3447 hit_cycle: false,
3448 };
3449 for transition in &state.transitions() {
3450 let target = transition.target();
3451 if atn
3452 .state(target)
3453 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3454 {
3455 continue;
3456 }
3457 for symbol in 1..=atn.max_token_type() {
3458 let reachability = state_can_reach_symbol_with_precedence(
3459 atn,
3460 target,
3461 OperatorReachabilityRequest {
3462 symbol,
3463 precedence,
3464 predicate_dependent: false,
3465 operator_rule_index,
3466 },
3467 &mut nullable_ctx,
3468 &mut Vec::new(),
3469 &mut BTreeSet::new(),
3470 );
3471 if reachability.single_token {
3472 lookahead.single_token.insert(symbol);
3473 }
3474 if reachability.multi_token {
3475 lookahead.multi_token_prefix.insert(symbol);
3476 }
3477 if reachability.predicate_dependent {
3478 lookahead.predicate_dependent.insert(symbol);
3479 }
3480 }
3481 }
3482 lookahead
3483}
3484
3485#[derive(Debug, Default)]
3486struct StateBeforeStopLookahead {
3487 symbols: TokenBitSet,
3488 reaches_context_boundary: bool,
3489}
3490
3491fn state_before_stop_lookahead(
3492 atn: &Atn,
3493 state_number: usize,
3494 stop_state_number: usize,
3495) -> Rc<StateBeforeStopLookahead> {
3496 with_shared_atn_caches(atn, |cache| {
3497 let key = (state_number, stop_state_number);
3498 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
3499 return Rc::clone(cached);
3500 }
3501 let mut lookahead = StateBeforeStopLookahead::default();
3502 state_before_stop_lookahead_inner(
3503 atn,
3504 state_number,
3505 stop_state_number,
3506 &mut BTreeSet::new(),
3507 &mut cache.first_set,
3508 &mut lookahead,
3509 );
3510 let lookahead = Rc::new(lookahead);
3511 cache
3512 .state_before_stop_lookahead
3513 .insert(key, Rc::clone(&lookahead));
3514 lookahead
3515 })
3516}
3517
3518fn state_before_stop_lookahead_inner(
3519 atn: &Atn,
3520 state_number: usize,
3521 stop_state_number: usize,
3522 visited: &mut BTreeSet<usize>,
3523 first_set_cache: &mut FirstSetCache,
3524 lookahead: &mut StateBeforeStopLookahead,
3525) {
3526 if state_number == stop_state_number {
3527 lookahead.reaches_context_boundary = true;
3528 return;
3529 }
3530 if !visited.insert(state_number) {
3531 return;
3532 }
3533 let Some(state) = atn.state(state_number) else {
3534 return;
3535 };
3536 if state.kind() == AtnStateKind::RuleStop {
3537 lookahead.reaches_context_boundary = true;
3538 return;
3539 }
3540 for transition in &state.transitions() {
3541 match &transition.data() {
3542 Transition::Epsilon { target }
3543 | Transition::Action { target, .. }
3544 | Transition::Predicate { target, .. }
3545 | Transition::Precedence { target, .. } => {
3546 state_before_stop_lookahead_inner(
3547 atn,
3548 *target,
3549 stop_state_number,
3550 visited,
3551 first_set_cache,
3552 lookahead,
3553 );
3554 }
3555 Transition::Rule {
3556 target,
3557 rule_index,
3558 follow_state,
3559 ..
3560 } => {
3561 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3562 continue;
3563 };
3564 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
3565 lookahead.symbols.extend_from(&child.symbols);
3566 if child.nullable {
3567 state_before_stop_lookahead_inner(
3568 atn,
3569 *follow_state,
3570 stop_state_number,
3571 visited,
3572 first_set_cache,
3573 lookahead,
3574 );
3575 }
3576 }
3577 Transition::Atom { .. }
3578 | Transition::Range { .. }
3579 | Transition::Set { .. }
3580 | Transition::NotSet { .. }
3581 | Transition::Wildcard { .. } => {
3582 lookahead.symbols.extend_iter(transition_expected_symbols(
3583 transition,
3584 atn.max_token_type(),
3585 ));
3586 }
3587 }
3588 }
3589}
3590
3591fn caller_context_can_match_symbol_before_state(
3592 atn: &Atn,
3593 return_states: impl DoubleEndedIterator<Item = usize>,
3594 stop_state_number: usize,
3595 symbol: i32,
3596) -> bool {
3597 for return_state in return_states.rev() {
3598 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
3599 if lookahead.symbols.contains(symbol) {
3600 return true;
3601 }
3602 if !lookahead.reaches_context_boundary {
3603 return false;
3604 }
3605 }
3606 false
3607}
3608
3609fn next_recovery_context(
3613 atn: &Atn,
3614 state: AtnState<'_>,
3615 inherited: &BTreeSet<i32>,
3616 inherited_state: Option<usize>,
3617) -> (BTreeSet<i32>, Option<usize>) {
3618 let state_symbols = state_expected_symbols(atn, state.state_number());
3619 if state.transitions().len() > 1 && !state_symbols.is_empty() {
3620 let mut symbols = state_symbols;
3621 symbols.extend(inherited.iter().copied());
3622 return (symbols, Some(state.state_number()));
3623 }
3624 (inherited.clone(), inherited_state)
3625}
3626
3627fn recovery_expected_symbols(
3628 atn: &Atn,
3629 state_number: usize,
3630 inherited: &BTreeSet<i32>,
3631) -> BTreeSet<i32> {
3632 let mut symbols = state_expected_symbols(atn, state_number);
3633 symbols.extend(inherited.iter().copied());
3634 symbols
3635}
3636
3637fn fast_next_recovery_context<S, H>(
3641 parser: &mut BaseParser<S, H>,
3642 atn: &Atn,
3643 state: AtnState<'_>,
3644 inherited: &Rc<BTreeSet<i32>>,
3645 inherited_state: Option<usize>,
3646) -> (Rc<BTreeSet<i32>>, Option<usize>)
3647where
3648 S: TokenSource,
3649 H: SemanticHooks,
3650{
3651 if state.transitions().len() <= 1 {
3652 return (Rc::clone(inherited), inherited_state);
3653 }
3654 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
3655 if state_symbols.is_empty() {
3656 return (Rc::clone(inherited), inherited_state);
3657 }
3658 if inherited.is_empty() {
3659 return (state_symbols, Some(state.state_number()));
3660 }
3661 if Rc::ptr_eq(&state_symbols, inherited) {
3662 return (state_symbols, Some(state.state_number()));
3663 }
3664 let mut combined = (*state_symbols).clone();
3665 combined.extend(inherited.iter().copied());
3666 (
3667 parser.intern_recovery_symbols(combined),
3668 Some(state.state_number()),
3669 )
3670}
3671
3672fn fast_recovery_expected_symbols<S, H>(
3676 parser: &mut BaseParser<S, H>,
3677 atn: &Atn,
3678 state_number: usize,
3679 inherited: &Rc<BTreeSet<i32>>,
3680) -> Rc<BTreeSet<i32>>
3681where
3682 S: TokenSource,
3683 H: SemanticHooks,
3684{
3685 let cached = parser.cached_state_expected_symbols(atn, state_number);
3686 if inherited.is_empty() {
3687 return cached;
3688 }
3689 if cached.is_empty() {
3690 return Rc::clone(inherited);
3691 }
3692 if Rc::ptr_eq(&cached, inherited) {
3693 return cached;
3694 }
3695 let mut combined = (*cached).clone();
3696 combined.extend(inherited.iter().copied());
3697 parser.intern_recovery_symbols(combined)
3698}
3699
3700struct ParserTableSemCtx<'a> {
3701 member_values: &'a mut BTreeMap<usize, i64>,
3702 return_values: &'a mut BTreeMap<String, i64>,
3703}
3704
3705impl semir::PredContext for ParserTableSemCtx<'_> {
3706 type TokenText<'a>
3707 = &'a str
3708 where
3709 Self: 'a;
3710
3711 fn la(&mut self, _offset: isize) -> i64 {
3712 i64::from(TOKEN_EOF)
3713 }
3714
3715 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
3716 None
3717 }
3718
3719 fn token_index_adjacent(&mut self) -> bool {
3720 false
3721 }
3722
3723 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
3724 None
3725 }
3726
3727 fn member(&self, member: usize) -> Option<i64> {
3728 Some(self.member_values.get(&member).copied().unwrap_or_default())
3729 }
3730
3731 fn local_arg(&self) -> Option<i64> {
3732 None
3733 }
3734
3735 fn column(&self) -> Option<i64> {
3736 None
3737 }
3738
3739 fn token_start_column(&self) -> Option<i64> {
3740 None
3741 }
3742
3743 fn token_text_so_far(&self) -> Option<String> {
3744 None
3745 }
3746
3747 fn hook(&mut self, _hook: HookId) -> bool {
3748 false
3749 }
3750}
3751
3752impl semir::ActContext for ParserTableSemCtx<'_> {
3753 fn set_member(&mut self, member: usize, value: i64) {
3754 self.member_values.insert(member, value);
3755 }
3756
3757 fn set_return(&mut self, name: &str, value: i64) {
3758 self.return_values.insert(name.to_owned(), value);
3759 }
3760
3761 fn action_hook(&mut self, _hook: HookId) {}
3762}
3763
3764fn apply_member_actions(
3766 source_state: usize,
3767 actions: &[ParserMemberAction],
3768 semantics: Option<&ParserSemantics>,
3769 values: &mut BTreeMap<usize, i64>,
3770) {
3771 for action in actions
3772 .iter()
3773 .filter(|action| action.source_state == source_state)
3774 {
3775 *values.entry(action.member).or_default() += action.delta;
3776 }
3777 let Some(semantics) = semantics else {
3778 return;
3779 };
3780 let mut return_values = BTreeMap::new();
3781 let mut ctx = ParserTableSemCtx {
3782 member_values: values,
3783 return_values: &mut return_values,
3784 };
3785 for action in semantics
3786 .actions
3787 .iter()
3788 .filter(|action| action.source_state == source_state && action.speculative)
3789 {
3790 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3791 }
3792}
3793
3794fn member_values_after_action(
3796 source_state: usize,
3797 actions: &[ParserMemberAction],
3798 semantics: Option<&ParserSemantics>,
3799 values: &BTreeMap<usize, i64>,
3800) -> BTreeMap<usize, i64> {
3801 let mut values = values.clone();
3802 apply_member_actions(source_state, actions, semantics, &mut values);
3803 values
3804}
3805
3806fn return_values_after_action(
3808 source_state: usize,
3809 rule_index: usize,
3810 actions: &[ParserReturnAction],
3811 semantics: Option<&ParserSemantics>,
3812 values: &BTreeMap<String, i64>,
3813) -> BTreeMap<String, i64> {
3814 let mut values = values.clone();
3815 for action in actions
3816 .iter()
3817 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
3818 {
3819 values.insert(action.name.to_owned(), action.value);
3820 }
3821 if let Some(semantics) = semantics {
3822 let mut member_values = BTreeMap::new();
3823 let mut ctx = ParserTableSemCtx {
3824 member_values: &mut member_values,
3825 return_values: &mut values,
3826 };
3827 for action in semantics.actions.iter().filter(|action| {
3828 action.source_state == source_state
3829 && action.rule_index == rule_index
3830 && !action.speculative
3831 }) {
3832 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3833 }
3834 }
3835 values
3836}
3837
3838fn rule_local_int_arg(
3840 rule_args: &[ParserRuleArg],
3841 source_state: usize,
3842 rule_index: usize,
3843 local_int_arg: Option<(usize, i64)>,
3844) -> Option<(usize, i64)> {
3845 rule_args
3846 .iter()
3847 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
3848 .map(|arg| {
3849 let value = if arg.inherit_local {
3850 local_int_arg.map_or(arg.value, |(_, value)| value)
3851 } else {
3852 arg.value
3853 };
3854 (rule_index, value)
3855 })
3856}
3857
3858fn stop_outcome(
3861 index: usize,
3862 consumed_eof: bool,
3863 rule_alt_number: usize,
3864 member_values: BTreeMap<usize, i64>,
3865 return_values: BTreeMap<String, i64>,
3866) -> Vec<RecognizeOutcome> {
3867 vec![RecognizeOutcome {
3868 index,
3869 consumed_eof,
3870 alt_number: rule_alt_number,
3871 member_values,
3872 return_values,
3873 diagnostics: DiagnosticSeqId::EMPTY,
3874 decisions: Vec::new(),
3875 actions: Vec::new(),
3876 nodes: NodeSeqId::EMPTY,
3877 }]
3878}
3879
3880fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
3881 with_shared_atn_caches(atn, |cache| {
3882 *cache.observable_action_transitions.get_or_insert_with(|| {
3883 atn.states().any(|state| {
3884 state.transitions().iter().any(|transition| {
3885 matches!(
3886 &transition.data(),
3887 Transition::Action {
3888 action_index: Some(_),
3889 ..
3890 }
3891 )
3892 })
3893 })
3894 })
3895 })
3896}
3897
3898fn atn_has_predicate_transitions(atn: &Atn) -> bool {
3899 with_shared_atn_caches(atn, |cache| {
3900 *cache.predicate_transitions.get_or_insert_with(|| {
3901 atn.states().any(|state| {
3902 state
3903 .transitions()
3904 .iter()
3905 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
3906 })
3907 })
3908 })
3909}
3910
3911fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
3916 options.init_action_rules.is_empty()
3917 && !options.track_alt_numbers
3918 && options
3919 .predicates
3920 .iter()
3921 .all(|(_, _, predicate)| predicate.failure_message().is_none())
3922 && options.semantics.is_none_or(|semantics| {
3923 semantics.actions.is_empty()
3924 && semantics
3925 .predicates
3926 .iter()
3927 .all(|predicate| predicate.failure_message.is_none())
3928 })
3929 && options.rule_args.is_empty()
3930 && options.member_actions.is_empty()
3931 && options.return_actions.is_empty()
3932 && !atn_has_observable_action_transitions(atn)
3933}
3934
3935#[derive(Clone, Debug, Eq, PartialEq)]
3936struct RecognizeRequest<'a> {
3937 state_number: usize,
3938 stop_state: usize,
3939 index: usize,
3940 rule_start_index: usize,
3941 decision_start_index: Option<usize>,
3942 init_action_rules: &'a BTreeSet<usize>,
3943 predicates: &'a [(usize, usize, ParserPredicate)],
3944 semantics: Option<&'a ParserSemantics>,
3945 rule_args: &'a [ParserRuleArg],
3946 member_actions: &'a [ParserMemberAction],
3947 return_actions: &'a [ParserReturnAction],
3948 local_int_arg: Option<(usize, i64)>,
3949 member_values: BTreeMap<usize, i64>,
3950 return_values: BTreeMap<String, i64>,
3951 rule_alt_number: usize,
3952 track_alt_numbers: bool,
3953 consumed_eof: bool,
3954 precedence: i32,
3957 depth: usize,
3958 recovery_symbols: BTreeSet<i32>,
3959 recovery_state: Option<usize>,
3960}
3961
3962#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
3963struct RecognizeKey {
3964 state_number: usize,
3965 stop_state: usize,
3966 index: usize,
3967 rule_start_index: usize,
3968 decision_start_index: Option<usize>,
3969 local_int_arg: Option<(usize, i64)>,
3970 member_values: BTreeMap<usize, i64>,
3971 return_values: BTreeMap<String, i64>,
3972 rule_alt_number: usize,
3973 track_alt_numbers: bool,
3974 consumed_eof: bool,
3975 precedence: i32,
3976 recovery_symbols: BTreeSet<i32>,
3977 recovery_state: Option<usize>,
3978}
3979
3980#[derive(Clone, Debug, Eq, PartialEq)]
3981struct EpsilonActionStep {
3982 source_state: usize,
3983 target: usize,
3984 action_rule_index: Option<usize>,
3985 left_recursive_boundary: Option<usize>,
3986 decision: Option<usize>,
3987 decision_start_index: Option<usize>,
3988 alt_number: usize,
3989 recovery_symbols: BTreeSet<i32>,
3990 recovery_state: Option<usize>,
3991}
3992
3993struct RecognizeScratch<'a> {
3994 visiting: &'a mut BTreeSet<RecognizeKey>,
3995 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
3996 expected: &'a mut ExpectedTokens,
3997}
3998
3999#[derive(Clone, Debug, Eq, PartialEq)]
4000struct FastRecognizeRequest {
4001 state_number: usize,
4002 stop_state: usize,
4003 index: usize,
4004 rule_start_index: usize,
4005 decision_start_index: Option<usize>,
4006 precedence: i32,
4007 depth: usize,
4008 recovery_symbols: Rc<BTreeSet<i32>>,
4009 recovery_state: Option<usize>,
4010}
4011
4012#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4013struct FastRecognizeTopRequest {
4014 start_state: usize,
4015 stop_state: usize,
4016 start_index: usize,
4017 precedence: i32,
4018 caller_follow_state: Option<usize>,
4019}
4020
4021#[derive(Clone, Copy, Debug)]
4022struct FastPredicateContext<'a> {
4023 predicates: &'a [(usize, usize, ParserPredicate)],
4024 semantics: Option<&'a ParserSemantics>,
4025 member_values: &'a BTreeMap<usize, i64>,
4026}
4027
4028struct FastRecognizeScratch<'a, 'b> {
4029 predicate_context: Option<FastPredicateContext<'a>>,
4030 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4031 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4032 expected: &'b mut ExpectedTokens,
4033}
4034
4035#[derive(Clone, Copy, Debug)]
4036struct FastRepetitionShape {
4037 enter_target: usize,
4038 exit_target: usize,
4039 body_stop_state: usize,
4040 enter_transition_index: usize,
4041 exit_transition_index: usize,
4042}
4043
4044#[derive(Clone, Copy, Debug)]
4045struct FastRepetitionPath {
4046 index: usize,
4047 deferred_nodes: FastDeferredNodeId,
4048 diagnostics: DiagnosticSeqId,
4049 consumed_eof: bool,
4050}
4051
4052enum FastRepetitionWork {
4053 Enter(FastRepetitionPath),
4054 Exit(FastRepetitionPath),
4055}
4056
4057struct FastRepetitionCoordinates {
4062 base_index: usize,
4063 base_state: u8,
4064 later_states: Vec<u8>,
4065}
4066
4067impl FastRepetitionCoordinates {
4068 const ENTERED: u8 = 0;
4069 const EXITED: u8 = 2;
4070
4071 const fn new(base_index: usize) -> Self {
4072 Self {
4073 base_index,
4074 base_state: 0,
4075 later_states: Vec::new(),
4076 }
4077 }
4078
4079 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4080 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4081 }
4082
4083 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4084 self.insert(path.index, path.consumed_eof, Self::EXITED)
4085 }
4086
4087 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4088 let Some(offset) = index.checked_sub(self.base_index) else {
4089 return false;
4090 };
4091 let state = if offset == 0 {
4092 &mut self.base_state
4093 } else {
4094 if self.later_states.len() < offset {
4095 self.later_states.resize(offset, 0);
4096 }
4097 &mut self.later_states[offset - 1]
4098 };
4099 let bit = 1 << (base_bit + u8::from(consumed_eof));
4100 let is_new = *state & bit == 0;
4101 *state |= bit;
4102 is_new
4103 }
4104}
4105
4106fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4107 if state.precedence_rule_decision()
4108 || !matches!(
4109 state.kind(),
4110 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4111 )
4112 || state.transitions().len() != 2
4113 {
4114 return None;
4115 }
4116 let mut enter = None;
4117 let mut exit = None;
4118 for (index, transition) in state.transitions().iter().enumerate() {
4119 if transition.kind() != ParserTransitionKind::Epsilon {
4120 return None;
4121 }
4122 let target = transition.target();
4123 if atn
4124 .state(target)
4125 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4126 {
4127 if exit.replace((index, target)).is_some() {
4128 return None;
4129 }
4130 } else if enter.replace((index, target)).is_some() {
4131 return None;
4132 }
4133 }
4134 let (enter_transition_index, enter_target) = enter?;
4135 let (exit_transition_index, exit_target) = exit?;
4136 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4137 atn.state(exit_target)?.loop_back_state()?
4138 } else {
4139 state.state_number()
4140 };
4141 Some(FastRepetitionShape {
4142 enter_target,
4143 exit_target,
4144 body_stop_state,
4145 enter_transition_index,
4146 exit_transition_index,
4147 })
4148}
4149
4150fn push_fast_repetition_work(
4151 work: &mut Vec<FastRepetitionWork>,
4152 shape: FastRepetitionShape,
4153 path: FastRepetitionPath,
4154 lookahead: Option<&DecisionLookahead>,
4155 symbol: i32,
4156) {
4157 let transition_is_viable = |transition_index: usize| {
4160 let Some(entry) = lookahead else {
4161 return true;
4162 };
4163 let Some(transition) = entry.transitions.get(transition_index) else {
4164 return true;
4165 };
4166 transition.nullable || transition.symbols.contains(symbol)
4167 };
4168 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4169 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4170 if shape.enter_transition_index < shape.exit_transition_index {
4171 if exit_is_viable {
4172 work.push(FastRepetitionWork::Exit(path));
4173 }
4174 if enter_is_viable {
4175 work.push(FastRepetitionWork::Enter(path));
4176 }
4177 } else {
4178 if enter_is_viable {
4179 work.push(FastRepetitionWork::Enter(path));
4180 }
4181 if exit_is_viable {
4182 work.push(FastRepetitionWork::Exit(path));
4183 }
4184 }
4185}
4186
4187#[derive(Clone, Debug)]
4194struct FastRecognizeKey {
4195 state_number: usize,
4196 stop_state: usize,
4197 index: usize,
4198 rule_start_index: usize,
4199 decision_start_index: Option<usize>,
4200 precedence: i32,
4201 recovery_symbols_id: usize,
4202 recovery_state: Option<usize>,
4203}
4204
4205impl PartialEq for FastRecognizeKey {
4206 fn eq(&self, other: &Self) -> bool {
4207 if self.state_number != other.state_number
4208 || self.stop_state != other.stop_state
4209 || self.index != other.index
4210 || self.rule_start_index != other.rule_start_index
4211 || self.decision_start_index != other.decision_start_index
4212 || self.precedence != other.precedence
4213 || self.recovery_state != other.recovery_state
4214 || self.recovery_symbols_id != other.recovery_symbols_id
4215 {
4216 return false;
4217 }
4218 true
4219 }
4220}
4221
4222impl Eq for FastRecognizeKey {}
4223
4224impl Hash for FastRecognizeKey {
4225 fn hash<H: Hasher>(&self, hasher: &mut H) {
4226 self.state_number.hash(hasher);
4227 self.stop_state.hash(hasher);
4228 self.index.hash(hasher);
4229 self.rule_start_index.hash(hasher);
4230 self.decision_start_index.hash(hasher);
4231 self.precedence.hash(hasher);
4232 self.recovery_state.hash(hasher);
4233 self.recovery_symbols_id.hash(hasher);
4234 }
4235}
4236
4237struct FastRecoveryRequest<'a, 'b> {
4238 atn: &'a Atn,
4239 transition: ParserTransition<'a>,
4240 expected_symbols: Rc<BTreeSet<i32>>,
4241 target: usize,
4242 request: FastRecognizeRequest,
4243 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4244 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4245 expected: &'b mut ExpectedTokens,
4246}
4247
4248struct FastCurrentTokenDeletionRequest<'a, 'b> {
4249 atn: &'a Atn,
4250 expected_symbols: Rc<BTreeSet<i32>>,
4251 request: FastRecognizeRequest,
4252 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4253 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4254 expected: &'b mut ExpectedTokens,
4255}
4256
4257#[derive(Clone, Copy)]
4258struct FastChildRuleFailureRecoveryRequest<'a> {
4259 atn: &'a Atn,
4260 rule_index: usize,
4261 start_index: usize,
4262 follow_state: usize,
4263 stop_state: usize,
4264 expected: &'a ExpectedTokens,
4265}
4266
4267struct RecoveryRequest<'a, 'b> {
4268 atn: &'a Atn,
4269 transition: ParserTransition<'a>,
4270 expected_symbols: BTreeSet<i32>,
4271 target: usize,
4272 request: RecognizeRequest<'a>,
4273 visiting: &'b mut BTreeSet<RecognizeKey>,
4274 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4275 expected: &'b mut ExpectedTokens,
4276}
4277
4278struct CurrentTokenDeletionRequest<'a, 'b> {
4279 atn: &'a Atn,
4280 expected_symbols: BTreeSet<i32>,
4281 request: RecognizeRequest<'a>,
4282 visiting: &'b mut BTreeSet<RecognizeKey>,
4283 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4284 expected: &'b mut ExpectedTokens,
4285}
4286
4287struct ConsumingFailureFallback<'a> {
4290 atn: &'a Atn,
4291 target: usize,
4292 request: RecognizeRequest<'a>,
4293 symbol: i32,
4294 expected_symbols: BTreeSet<i32>,
4295 decision_start_index: Option<usize>,
4296 decision: Option<usize>,
4297}
4298
4299struct ChildRuleFailureRecovery<'a> {
4302 atn: &'a Atn,
4303 rule_index: usize,
4304 start_index: usize,
4305 follow_state: usize,
4306 stop_state: usize,
4307 member_values: BTreeMap<usize, i64>,
4308 expected: &'a ExpectedTokens,
4309}
4310
4311#[derive(Clone, Copy, Debug)]
4313struct PredicateEval<'a> {
4314 index: usize,
4315 rule_index: usize,
4316 pred_index: usize,
4317 predicates: &'a [(usize, usize, ParserPredicate)],
4318 semantics: Option<&'a ParserSemantics>,
4319 context: Option<&'a ParserRuleContext>,
4320 local_int_arg: Option<(usize, i64)>,
4321 member_values: &'a BTreeMap<usize, i64>,
4322}
4323
4324#[derive(Clone, Copy, Debug)]
4325struct ParserSemanticHookRequest<'a> {
4326 index: usize,
4327 rule_index: usize,
4328 pred_index: usize,
4329 context: Option<&'a ParserRuleContext>,
4330 local_int_arg: Option<(usize, i64)>,
4331 member_values: &'a BTreeMap<usize, i64>,
4332}
4333
4334struct ParserSemIrCtx<'a, S, H>
4343where
4344 S: TokenSource,
4345 H: SemanticHooks,
4346{
4347 input: &'a mut CommonTokenStream<S>,
4348 tree_storage: &'a ParseTreeStorage,
4349 semantic_hooks: &'a mut H,
4350 rule_index: usize,
4351 coordinate_index: usize,
4352 rule_name: Option<&'a str>,
4353 context: Option<&'a ParserRuleContext>,
4354 local_int_arg: Option<(usize, i64)>,
4355 member_values: &'a BTreeMap<usize, i64>,
4356 invoked_predicates: &'a mut Vec<(usize, usize)>,
4357 unknown_predicate_policy: UnknownSemanticPolicy,
4361 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4362}
4363
4364impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4365where
4366 S: TokenSource,
4367 H: SemanticHooks,
4368{
4369 type TokenText<'a>
4370 = TokenView<'a>
4371 where
4372 Self: 'a;
4373
4374 fn la(&mut self, offset: isize) -> i64 {
4375 i64::from(self.input.la(offset))
4376 }
4377
4378 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4379 self.input.lt(offset)
4380 }
4381
4382 fn token_index_adjacent(&mut self) -> bool {
4383 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4384 return false;
4385 };
4386 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4387 return false;
4388 };
4389 first + 1 == second
4390 }
4391
4392 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4393 self.context.and_then(|context| {
4394 context
4395 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4396 .next()
4397 .map(crate::tree::RuleNodeView::text)
4398 })
4399 }
4400
4401 fn member(&self, member: usize) -> Option<i64> {
4402 Some(self.member_values.get(&member).copied().unwrap_or_default())
4403 }
4404
4405 fn local_arg(&self) -> Option<i64> {
4406 self.local_int_arg.map(|(_, value)| value)
4407 }
4408
4409 fn column(&self) -> Option<i64> {
4410 None
4411 }
4412
4413 fn token_start_column(&self) -> Option<i64> {
4414 None
4415 }
4416
4417 fn token_text_so_far(&self) -> Option<String> {
4418 None
4419 }
4420
4421 fn hook(&mut self, _hook: HookId) -> bool {
4422 let mut ctx = ParserSemCtx {
4423 input: &mut *self.input,
4424 tree_storage: self.tree_storage,
4425 rule_index: self.rule_index,
4426 coordinate_index: self.coordinate_index,
4427 rule_name: self.rule_name.map(str::to_owned),
4428 context: self.context,
4429 tree: None,
4430 local_int_arg: self.local_int_arg,
4431 member_values: self.member_values,
4432 action: None,
4433 };
4434 match self
4435 .semantic_hooks
4436 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4437 {
4438 Some(result) => result,
4439 None => apply_unknown_predicate_policy(
4443 self.unknown_predicate_policy,
4444 self.rule_index,
4445 self.coordinate_index,
4446 self.unknown_predicate_hits,
4447 ),
4448 }
4449 }
4450
4451 fn trace_bool(&mut self, value: bool) -> bool {
4452 let key = (self.rule_index, self.coordinate_index);
4453 if !self.invoked_predicates.contains(&key) {
4454 self.invoked_predicates.push(key);
4455 use std::io::Write as _;
4456 let mut stdout = std::io::stdout().lock();
4457 let _ = writeln!(stdout, "eval={value}");
4458 }
4459 value
4460 }
4461}
4462
4463struct PredicateFailureRecovery<'a> {
4465 rule_index: usize,
4466 index: usize,
4467 message: &'a str,
4468 member_values: BTreeMap<usize, i64>,
4469 return_values: BTreeMap<String, i64>,
4470 rule_alt_number: usize,
4471}
4472
4473#[derive(Debug)]
4474enum DirectAdaptiveParseControl {
4475 Fallback(DirectAdaptiveFallback),
4476}
4477
4478#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4479enum DirectAdaptiveFallback {
4480 Action,
4481 InvalidAlt,
4482 LeftRecursiveBoundary,
4483 MissingAtn,
4484 NoTransition,
4485 Predicate,
4486 Prediction,
4487 Precedence,
4488 RuleStop,
4489 SemanticContext,
4490 StepLimit,
4491 TokenMismatch,
4492 UnknownDecision,
4493}
4494
4495type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
4496
4497struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
4498where
4499 S: TokenSource,
4500 H: SemanticHooks,
4501{
4502 parser: &'sim mut BaseParser<S, H>,
4503 atn: &'atn Atn,
4504 simulator: &'sim mut ParserAtnSimulator<'atn>,
4505 decision_by_state: Vec<Option<usize>>,
4506 steps: usize,
4507}
4508
4509#[derive(Clone, Debug, Eq, PartialEq)]
4519pub struct GeneratedMatch {
4520 children: GeneratedMatchChildren,
4521 consumed_eof: bool,
4522}
4523
4524#[derive(Clone, Copy)]
4525enum GeneratedExpectedSymbols<'a> {
4526 Tree(&'a BTreeSet<i32>),
4527 TokenSet(ParserIntervalSet<'a>),
4528 TokenSetComplement {
4529 set: ParserIntervalSet<'a>,
4530 min_vocabulary: i32,
4531 max_vocabulary: i32,
4532 },
4533}
4534
4535impl GeneratedExpectedSymbols<'_> {
4536 fn is_empty(self) -> bool {
4537 match self {
4538 Self::Tree(symbols) => symbols.is_empty(),
4539 Self::TokenSet(set) => set.is_empty(),
4540 Self::TokenSetComplement {
4541 set,
4542 min_vocabulary,
4543 max_vocabulary,
4544 } => (min_vocabulary..=max_vocabulary).all(|symbol| set.contains(symbol)),
4545 }
4546 }
4547
4548 fn first(self) -> Option<i32> {
4549 match self {
4550 Self::Tree(symbols) => symbols.iter().next().copied(),
4551 Self::TokenSet(set) => set.ranges().next().map(|(start, _)| start),
4552 Self::TokenSetComplement {
4553 set,
4554 min_vocabulary,
4555 max_vocabulary,
4556 } => (min_vocabulary..=max_vocabulary).find(|symbol| !set.contains(*symbol)),
4557 }
4558 }
4559
4560 fn display(self, vocabulary: &Vocabulary) -> String {
4561 match self {
4562 Self::Tree(symbols) => expected_symbols_display(symbols, vocabulary),
4563 Self::TokenSet(set) => expected_symbols_display_iter(
4564 set.ranges().flat_map(|(start, stop)| start..=stop),
4565 vocabulary,
4566 ),
4567 Self::TokenSetComplement {
4568 set,
4569 min_vocabulary,
4570 max_vocabulary,
4571 } => expected_symbols_display_iter(
4572 (min_vocabulary..=max_vocabulary).filter(|symbol| !set.contains(*symbol)),
4573 vocabulary,
4574 ),
4575 }
4576 }
4577}
4578
4579#[derive(Clone, Debug, Eq, PartialEq)]
4580enum GeneratedMatchChildren {
4581 One(ParseTree),
4582 Many(Vec<ParseTree>),
4583}
4584
4585struct GeneratedMatchChildrenIntoIter {
4586 one: Option<ParseTree>,
4587 many: Option<std::vec::IntoIter<ParseTree>>,
4588}
4589
4590impl Iterator for GeneratedMatchChildrenIntoIter {
4591 type Item = ParseTree;
4592
4593 fn next(&mut self) -> Option<Self::Item> {
4594 self.one
4595 .take()
4596 .or_else(|| self.many.as_mut().and_then(Iterator::next))
4597 }
4598}
4599
4600impl GeneratedMatch {
4601 #[must_use]
4605 pub fn children(&self) -> &[ParseTree] {
4606 match &self.children {
4607 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
4608 GeneratedMatchChildren::Many(children) => children,
4609 }
4610 }
4611
4612 #[must_use]
4615 pub fn into_children(self) -> Vec<ParseTree> {
4616 match self.children {
4617 GeneratedMatchChildren::One(child) => vec![child],
4618 GeneratedMatchChildren::Many(children) => children,
4619 }
4620 }
4621
4622 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
4624 match self.children {
4625 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
4626 one: Some(child),
4627 many: None,
4628 },
4629 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
4630 one: None,
4631 many: Some(children.into_iter()),
4632 },
4633 }
4634 }
4635
4636 #[must_use]
4638 pub const fn consumed_eof(&self) -> bool {
4639 self.consumed_eof
4640 }
4641}
4642
4643impl<S> BaseParser<S, NoSemanticHooks>
4644where
4645 S: TokenSource,
4646{
4647 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
4650 Self::with_semantic_hooks(input, data, NoSemanticHooks)
4651 }
4652}
4653
4654impl<S, H> BaseParser<S, H>
4655where
4656 S: TokenSource,
4657 H: SemanticHooks,
4658{
4659 pub fn with_semantic_hooks(
4661 input: CommonTokenStream<S>,
4662 data: RecognizerData,
4663 semantic_hooks: H,
4664 ) -> Self {
4665 Self {
4666 input,
4667 tree: ParseTreeStorage::new(),
4668 data,
4669 semantic_hooks,
4670 build_parse_trees: true,
4671 syntax_errors: 0,
4672 report_diagnostic_errors: false,
4673 prediction_mode: PredictionMode::Ll,
4674 prediction_diagnostics: Vec::new(),
4675 reported_prediction_diagnostics: BTreeSet::new(),
4676 generated_parser_diagnostics: Vec::new(),
4677 generated_sync_expected: None,
4678 int_members: BTreeMap::new(),
4679 rule_context_stack: Vec::new(),
4680 rule_context_version: 0,
4681 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
4682 pending_invoking_states: Vec::new(),
4683 precedence_stack: vec![0],
4684 invoked_predicates: Vec::new(),
4685 bail_on_error: false,
4686 unknown_predicate_policy: UnknownSemanticPolicy::default(),
4687 unknown_predicate_hits: Vec::new(),
4688 unhandled_action_hits: Vec::new(),
4689 rule_first_set_cache: Vec::new(),
4690 state_expected_cache: FxHashMap::default(),
4691 state_expected_token_cache: FxHashMap::default(),
4692 rule_stop_reach_cache: Vec::new(),
4693 recovery_symbols_intern: FxHashMap::default(),
4694 decision_lookahead_cache: FxHashMap::default(),
4695 ll1_decision_cache: FxHashMap::default(),
4696 fast_predicate_cache: FxHashMap::default(),
4697 empty_cycle_cache: Vec::new(),
4698 empty_cycle_cache_atn: None,
4699 clean_memo_mode: CleanMemoMode::Probe,
4700 clean_memo_probe_seen: FxHashSet::default(),
4701 clean_memo_probe_samples: 0,
4702 clean_memo_probe_repeats: 0,
4703 clean_memo_sparse_samples: 0,
4704 fast_recognize_scratch: FastRecognizeTopScratch::default(),
4705 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
4706 empty_recovery_symbols: Rc::new(BTreeSet::new()),
4707 fast_first_set_prefilter: true,
4708 fast_recovery_enabled: true,
4709 fast_token_nodes_enabled: true,
4710 recognition_arena: RecognitionArena::default(),
4711 last_recognition_arena_root: NodeSeqId::EMPTY,
4712 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
4713 }
4714 }
4715
4716 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
4717 &mut self.input
4718 }
4719
4720 pub fn reset(&mut self) {
4725 self.input.seek(0);
4726 self.tree.reset();
4727 self.data.set_state(-1);
4728 self.syntax_errors = 0;
4729 self.prediction_diagnostics.clear();
4730 self.reported_prediction_diagnostics.clear();
4731 self.generated_parser_diagnostics.clear();
4732 self.generated_sync_expected = None;
4733 self.rule_context_stack.clear();
4734 self.advance_rule_context_version();
4735 self.left_recursive_caller_overlap_cache = std::array::from_fn(|_| None);
4736 self.pending_invoking_states.clear();
4737 self.precedence_stack.clear();
4738 self.precedence_stack.push(0);
4739 self.invoked_predicates.clear();
4740 self.unknown_predicate_hits.clear();
4741 self.unhandled_action_hits.clear();
4742 self.reset_per_parse_caches();
4743 self.fast_first_set_prefilter = true;
4744 self.fast_recovery_enabled = true;
4745 self.fast_token_nodes_enabled = self.build_parse_trees;
4746 self.reset_recognition_arena();
4747 }
4748
4749 pub fn set_token_stream(&mut self, input: CommonTokenStream<S>) {
4751 self.input = input;
4752 self.reset();
4753 }
4754
4755 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
4766 self.unknown_predicate_policy = policy;
4767 }
4768
4769 #[must_use]
4775 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
4776 let error = self.unknown_semantic_error();
4777 self.unknown_predicate_hits.clear();
4778 self.unhandled_action_hits.clear();
4779 error
4780 }
4781
4782 pub fn reset_unknown_semantic_hits(&mut self) {
4789 self.unknown_predicate_hits.clear();
4790 self.unhandled_action_hits.clear();
4791 }
4792
4793 #[must_use]
4795 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
4796 &self.input
4797 }
4798
4799 #[must_use]
4801 pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<S> {
4802 &mut self.input
4803 }
4804
4805 #[must_use]
4807 pub const fn token_store(&self) -> &TokenStore {
4808 self.input.token_store()
4809 }
4810
4811 #[must_use]
4813 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
4814 &self.tree
4815 }
4816
4817 #[must_use]
4819 pub fn node(&self, id: NodeId) -> Node<'_> {
4820 self.tree
4821 .node(self.input.token_store(), id)
4822 .expect("parser-produced node ID should remain valid")
4823 }
4824
4825 #[must_use]
4827 pub fn into_token_stream(self) -> CommonTokenStream<S> {
4828 self.input
4829 }
4830
4831 #[must_use]
4833 pub fn into_token_store(self) -> TokenStore {
4834 self.input.into_token_store()
4835 }
4836
4837 #[must_use]
4839 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
4840 ParsedFile::new(self.input.into_token_store(), self.tree, root)
4841 }
4842
4843 pub const fn number_of_syntax_errors(&self) -> usize {
4846 self.syntax_errors
4847 }
4848
4849 #[must_use]
4855 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
4856 self.recognition_arena.stats(
4857 self.last_recognition_arena_root,
4858 self.last_recognition_arena_diagnostics,
4859 )
4860 }
4861
4862 pub const fn record_generated_syntax_error(&mut self) {
4865 self.record_syntax_errors(1);
4866 }
4867
4868 const fn record_syntax_errors(&mut self, count: usize) {
4869 self.syntax_errors = self.syntax_errors.saturating_add(count);
4870 }
4871
4872 pub fn report_token_source_errors(&mut self) {
4875 let errors = self.input.drain_source_errors();
4876 self.dispatch_token_source_errors(&errors);
4877 }
4878
4879 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
4882 GeneratedDiagnosticsCheckpoint {
4883 diagnostics_len: self.generated_parser_diagnostics.len(),
4884 syntax_errors: self.syntax_errors,
4885 tree: self.tree.checkpoint(),
4886 }
4887 }
4888
4889 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
4891 self.generated_parser_diagnostics
4892 .truncate(marker.diagnostics_len);
4893 self.syntax_errors = marker.syntax_errors;
4894 self.generated_sync_expected = None;
4895 self.tree.rollback(marker.tree);
4896 }
4897
4898 pub fn report_generated_parser_diagnostics(&mut self) {
4900 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
4901 let token_errors = self.input.drain_source_errors();
4902 self.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
4903 }
4904
4905 fn dispatch_parser_diagnostic(&self, diagnostic: &ParserDiagnostic) {
4906 self.notify_error_listeners(
4907 diagnostic.line,
4908 diagnostic.column,
4909 &diagnostic.message,
4910 None,
4911 );
4912 }
4913
4914 fn dispatch_parser_diagnostics<'a>(
4915 &self,
4916 diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>,
4917 ) {
4918 for diagnostic in diagnostics {
4919 self.dispatch_parser_diagnostic(diagnostic);
4920 }
4921 }
4922
4923 fn dispatch_token_source_error(&self, source_error: &TokenSourceError) {
4924 if self.input.token_source().report_error(source_error) {
4925 return;
4926 }
4927 self.notify_error_listeners(
4928 source_error.line,
4929 source_error.column,
4930 &source_error.message,
4931 None,
4932 );
4933 }
4934
4935 fn dispatch_token_source_errors(&self, errors: &[TokenSourceError]) {
4936 for error in errors {
4937 self.dispatch_token_source_error(error);
4938 }
4939 }
4940
4941 fn dispatch_generated_diagnostics(
4944 &self,
4945 parser_diagnostics: &[ParserDiagnostic],
4946 token_errors: &[TokenSourceError],
4947 ) {
4948 let mut token_iter = token_errors.iter().peekable();
4954 for diagnostic in parser_diagnostics {
4955 while let Some(error) = token_iter.peek() {
4956 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
4957 self.dispatch_token_source_error(error);
4958 token_iter.next();
4959 } else {
4960 break;
4961 }
4962 }
4963 self.dispatch_parser_diagnostic(diagnostic);
4964 }
4965 for error in token_iter {
4966 self.dispatch_token_source_error(error);
4967 }
4968 }
4969
4970 pub fn record_generated_ambiguity_diagnostic(
4973 &mut self,
4974 atn: &Atn,
4975 state_number: usize,
4976 start_index: usize,
4977 stop_index: usize,
4978 alts: &[usize],
4979 ) {
4980 if !self.report_diagnostic_errors || alts.len() < 2 {
4981 return;
4982 }
4983 let Some(decision) = atn
4984 .decision_to_state()
4985 .iter()
4986 .position(|candidate| candidate == state_number)
4987 else {
4988 return;
4989 };
4990 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
4991 return;
4992 };
4993 let rule_name = self
4994 .rule_names()
4995 .get(rule_index)
4996 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
4997 let input = display_input_text(&self.input.text(start_index, stop_index));
4998 let alts = alts
4999 .iter()
5000 .map(usize::to_string)
5001 .collect::<Vec<_>>()
5002 .join(", ");
5003 let key = (decision, start_index, format!("{alts}:{input}"));
5004 if !self.reported_prediction_diagnostics.insert(key) {
5005 return;
5006 }
5007 let start_diagnostic = diagnostic_for_token(
5008 self.token_at(start_index),
5009 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
5010 );
5011 let stop_diagnostic = diagnostic_for_token(
5012 self.token_at(stop_index),
5013 format!(
5014 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
5015 ),
5016 );
5017 self.generated_parser_diagnostics.push(start_diagnostic);
5018 self.generated_parser_diagnostics.push(stop_diagnostic);
5019 }
5020
5021 pub fn record_generated_prediction_diagnostic(
5024 &mut self,
5025 atn: &Atn,
5026 state_number: usize,
5027 prediction: &ParserAtnPrediction,
5028 ) {
5029 let Some(diagnostic) = &prediction.diagnostic else {
5030 return;
5031 };
5032 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5033 return;
5034 }
5035 let Some(decision) = atn
5036 .decision_to_state()
5037 .iter()
5038 .position(|candidate| candidate == state_number)
5039 else {
5040 return;
5041 };
5042 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5043 return;
5044 };
5045 let rule_name = self
5046 .rule_names()
5047 .get(rule_index)
5048 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5049 let attempt_input = display_input_text(
5050 &self
5051 .input
5052 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5053 );
5054 let result_input = display_input_text(
5055 &self
5056 .input
5057 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5058 );
5059 let alts = diagnostic
5060 .conflicting_alts
5061 .iter()
5062 .map(usize::to_string)
5063 .collect::<Vec<_>>()
5064 .join(", ");
5065 let key = (
5066 decision,
5067 diagnostic.start_index,
5068 format!(
5069 "{:?}:{alts}:{attempt_input}:{result_input}",
5070 diagnostic.kind
5071 ),
5072 );
5073 if !self.reported_prediction_diagnostics.insert(key) {
5074 return;
5075 }
5076 let attempt_diagnostic = diagnostic_for_token(
5077 self.token_at(diagnostic.sll_stop_index),
5078 format!(
5079 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5080 ),
5081 );
5082 self.generated_parser_diagnostics.push(attempt_diagnostic);
5083 let message = match diagnostic.kind {
5084 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5085 if !diagnostic.exact {
5090 return;
5091 }
5092 format!(
5093 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5094 )
5095 }
5096 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5097 format!(
5098 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5099 )
5100 }
5101 };
5102 let result_diagnostic =
5103 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5104 self.generated_parser_diagnostics.push(result_diagnostic);
5105 }
5106
5107 pub fn la(&self, offset: isize) -> i32 {
5108 self.input.la_token(offset)
5109 }
5110
5111 pub fn consume(&mut self) {
5112 IntStream::consume(&mut self.input);
5113 }
5114
5115 pub fn set_int_member(&mut self, member: usize, value: i64) {
5117 self.int_members.insert(member, value);
5118 }
5119
5120 pub fn int_member(&self, member: usize) -> Option<i64> {
5122 self.int_members.get(&member).copied()
5123 }
5124
5125 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
5128 self.int_members.clone()
5129 }
5130
5131 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
5133 self.int_members = members;
5134 }
5135
5136 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5138 let value = self.int_members.entry(member).or_default();
5139 *value += delta;
5140 *value
5141 }
5142
5143 fn token_type_for_id(&self, id: TokenId) -> i32 {
5144 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5145 }
5146
5147 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5148 if self.build_parse_trees {
5149 self.tree.terminal(id)
5150 } else {
5151 NodeId::placeholder()
5152 }
5153 }
5154
5155 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5156 if self.build_parse_trees {
5157 self.tree.error(id)
5158 } else {
5159 NodeId::placeholder()
5160 }
5161 }
5162
5163 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5164 context.set_start_id(id);
5165 }
5166
5167 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5168 context.set_stop_id(id);
5169 }
5170
5171 fn insert_synthetic_token(
5172 &mut self,
5173 token_type: i32,
5174 text: String,
5175 line: usize,
5176 column: usize,
5177 ) -> Result<TokenId, AntlrError> {
5178 self.input
5179 .insert(
5180 TokenSpec::explicit(token_type, text)
5181 .with_span(usize::MAX, usize::MAX)
5182 .with_byte_span(0, 0)
5183 .with_position(line, column),
5184 )
5185 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5186 }
5187
5188 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5195 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5196 line: 0,
5197 column: 0,
5198 message: "missing current token".to_owned(),
5199 })?;
5200 let current_type = self.token_type_for_id(current);
5201 if current_type == token_type {
5202 self.consume();
5203 Ok(self.terminal_tree(current))
5204 } else {
5205 Err(AntlrError::MismatchedInput {
5206 expected: self.vocabulary().display_name(token_type),
5207 found: self.vocabulary().display_name(current_type),
5208 })
5209 }
5210 }
5211
5212 pub fn match_token_recovering(
5216 &mut self,
5217 token_type: i32,
5218 follow_state: usize,
5219 atn: &Atn,
5220 ) -> Result<GeneratedMatch, AntlrError> {
5221 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5222 line: 0,
5223 column: 0,
5224 message: "missing current token".to_owned(),
5225 })?;
5226 let current_type = self.token_type_for_id(current);
5227 if current_type == token_type {
5228 self.generated_sync_expected = None;
5229 let consumed_eof = current_type == TOKEN_EOF;
5230 self.consume();
5231 return Ok(GeneratedMatch {
5232 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5233 consumed_eof,
5234 });
5235 }
5236 let mut expected_symbols = BTreeSet::new();
5237 expected_symbols.insert(token_type);
5238 self.recover_generated_match(
5239 current,
5240 GeneratedExpectedSymbols::Tree(&expected_symbols),
5241 follow_state,
5242 atn,
5243 |symbol| symbol == token_type,
5244 )
5245 }
5246
5247 pub fn match_set_recovering(
5248 &mut self,
5249 intervals: &[(i32, i32)],
5250 follow_state: usize,
5251 atn: &Atn,
5252 ) -> Result<GeneratedMatch, AntlrError> {
5253 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5254 line: 0,
5255 column: 0,
5256 message: "missing current token".to_owned(),
5257 })?;
5258 let current_type = self.token_type_for_id(current);
5259 if interval_set_contains(intervals, current_type) {
5260 self.generated_sync_expected = None;
5261 let consumed_eof = current_type == TOKEN_EOF;
5262 self.consume();
5263 return Ok(GeneratedMatch {
5264 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5265 consumed_eof,
5266 });
5267 }
5268 let expected_symbols = interval_symbols(intervals);
5269 self.recover_generated_match(
5270 current,
5271 GeneratedExpectedSymbols::Tree(&expected_symbols),
5272 follow_state,
5273 atn,
5274 |symbol| interval_set_contains(intervals, symbol),
5275 )
5276 }
5277
5278 pub fn match_token_set_recovering(
5279 &mut self,
5280 set: ParserIntervalSet<'_>,
5281 follow_state: usize,
5282 atn: &Atn,
5283 ) -> Result<GeneratedMatch, AntlrError> {
5284 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5285 line: 0,
5286 column: 0,
5287 message: "missing current token".to_owned(),
5288 })?;
5289 let current_type = self.token_type_for_id(current);
5290 if set.contains(current_type) {
5291 self.generated_sync_expected = None;
5292 let consumed_eof = current_type == TOKEN_EOF;
5293 self.consume();
5294 return Ok(GeneratedMatch {
5295 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5296 consumed_eof,
5297 });
5298 }
5299 self.recover_generated_match(
5300 current,
5301 GeneratedExpectedSymbols::TokenSet(set),
5302 follow_state,
5303 atn,
5304 |symbol| set.contains(symbol),
5305 )
5306 }
5307
5308 pub fn match_not_set_recovering(
5309 &mut self,
5310 intervals: &[(i32, i32)],
5311 min_vocabulary: i32,
5312 max_vocabulary: i32,
5313 follow_state: usize,
5314 atn: &Atn,
5315 ) -> Result<GeneratedMatch, AntlrError> {
5316 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5317 line: 0,
5318 column: 0,
5319 message: "missing current token".to_owned(),
5320 })?;
5321 let current_type = self.token_type_for_id(current);
5322 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5323 && !interval_set_contains(intervals, current_type)
5324 {
5325 self.generated_sync_expected = None;
5326 let consumed_eof = current_type == TOKEN_EOF;
5327 self.consume();
5328 return Ok(GeneratedMatch {
5329 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5330 consumed_eof,
5331 });
5332 }
5333 let expected_symbols =
5334 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
5335 self.recover_generated_match(
5336 current,
5337 GeneratedExpectedSymbols::Tree(&expected_symbols),
5338 follow_state,
5339 atn,
5340 |symbol| {
5341 (min_vocabulary..=max_vocabulary).contains(&symbol)
5342 && !interval_set_contains(intervals, symbol)
5343 },
5344 )
5345 }
5346
5347 pub fn match_not_token_set_recovering(
5348 &mut self,
5349 set: ParserIntervalSet<'_>,
5350 min_vocabulary: i32,
5351 max_vocabulary: i32,
5352 follow_state: usize,
5353 atn: &Atn,
5354 ) -> Result<GeneratedMatch, AntlrError> {
5355 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5356 line: 0,
5357 column: 0,
5358 message: "missing current token".to_owned(),
5359 })?;
5360 let current_type = self.token_type_for_id(current);
5361 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
5362 {
5363 self.generated_sync_expected = None;
5364 let consumed_eof = current_type == TOKEN_EOF;
5365 self.consume();
5366 return Ok(GeneratedMatch {
5367 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5368 consumed_eof,
5369 });
5370 }
5371 self.recover_generated_match(
5372 current,
5373 GeneratedExpectedSymbols::TokenSetComplement {
5374 set,
5375 min_vocabulary,
5376 max_vocabulary,
5377 },
5378 follow_state,
5379 atn,
5380 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
5381 )
5382 }
5383
5384 fn recover_generated_match(
5385 &mut self,
5386 current: TokenId,
5387 expected_symbols: GeneratedExpectedSymbols<'_>,
5388 follow_state: usize,
5389 atn: &Atn,
5390 matches: impl Fn(i32) -> bool,
5391 ) -> Result<GeneratedMatch, AntlrError> {
5392 let expected_display = expected_symbols.display(self.vocabulary());
5393 let (current_type, current_line, current_column, current_display) = {
5394 let token = self
5395 .input
5396 .token_view(current)
5397 .expect("current token ID should be valid");
5398 (
5399 token.token_type(),
5400 token.line(),
5401 token.column(),
5402 token_input_display(&token),
5403 )
5404 };
5405 if self.bail_on_error {
5406 return Err(AntlrError::ParserError {
5407 line: current_line,
5408 column: current_column,
5409 message: format!("mismatched input {current_display} expecting {expected_display}"),
5410 });
5411 }
5412 if current_type != TOKEN_EOF
5413 && let Some(next) = self.input.lt_id(2)
5414 && matches(self.token_type_for_id(next))
5415 {
5416 let message =
5417 format!("extraneous input {current_display} expecting {expected_display}");
5418 self.push_generated_parser_diagnostic(ParserDiagnostic {
5419 line: current_line,
5420 column: current_column,
5421 message,
5422 });
5423 self.record_syntax_errors(1);
5424 self.generated_sync_expected = None;
5425 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
5428 self.consume();
5429 self.consume();
5430 return Ok(GeneratedMatch {
5431 children: GeneratedMatchChildren::Many(vec![
5432 self.error_tree(current),
5433 self.terminal_tree(next),
5434 ]),
5435 consumed_eof,
5436 });
5437 }
5438 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
5439 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
5448 && self
5449 .cached_state_expected_symbols(atn, follow_state)
5450 .contains(&TOKEN_EOF);
5451 if follow_symbols.contains(¤t_type)
5452 && (current_type != TOKEN_EOF
5453 || self.rule_context_stack.len() > 1
5454 || expected_symbols.is_empty()
5455 || follow_explicitly_expects_eof)
5456 {
5457 let message = format!("missing {expected_display} at {current_display}");
5458 self.push_generated_parser_diagnostic(ParserDiagnostic {
5459 line: current_line,
5460 column: current_column,
5461 message,
5462 });
5463 self.record_syntax_errors(1);
5464 self.generated_sync_expected = None;
5465 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
5466 let missing_display = expected_symbol_display(token_type, self.vocabulary());
5467 let token = self.insert_synthetic_token(
5468 token_type,
5469 format!("<missing {missing_display}>"),
5470 current_line,
5471 current_column,
5472 )?;
5473 return Ok(GeneratedMatch {
5478 children: GeneratedMatchChildren::One(self.error_tree(token)),
5479 consumed_eof: false,
5480 });
5481 }
5482 let mismatch_expected_display = self
5483 .generated_sync_expected
5484 .take()
5485 .map_or(expected_display, |symbols| {
5486 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
5487 });
5488 Err(AntlrError::ParserError {
5489 line: current_line,
5490 column: current_column,
5491 message: format!(
5492 "mismatched input {current_display} expecting {mismatch_expected_display}"
5493 ),
5494 })
5495 }
5496
5497 fn generated_recovery_follow_symbols(
5498 &mut self,
5499 atn: &Atn,
5500 follow_state: usize,
5501 ) -> BTreeSet<i32> {
5502 let mut follow = self
5503 .cached_state_expected_symbols(atn, follow_state)
5504 .as_ref()
5505 .clone();
5506 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
5507 follow.extend(self.context_expected_symbols(atn));
5508 }
5509 follow
5510 }
5511
5512 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
5513 self.match_token(TOKEN_EOF)
5514 }
5515
5516 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
5517 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
5518 }
5519
5520 pub fn match_not_set(
5521 &mut self,
5522 intervals: &[(i32, i32)],
5523 min_vocabulary: i32,
5524 max_vocabulary: i32,
5525 ) -> Result<ParseTree, AntlrError> {
5526 self.match_interval_condition(intervals, |symbol| {
5527 (min_vocabulary..=max_vocabulary).contains(&symbol)
5528 && !interval_set_contains(intervals, symbol)
5529 })
5530 }
5531
5532 fn match_interval_condition(
5533 &mut self,
5534 intervals: &[(i32, i32)],
5535 matches: impl FnOnce(i32) -> bool,
5536 ) -> Result<ParseTree, AntlrError> {
5537 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5538 line: 0,
5539 column: 0,
5540 message: "missing current token".to_owned(),
5541 })?;
5542 let current_type = self.token_type_for_id(current);
5543 if matches(current_type) {
5544 self.consume();
5545 Ok(self.terminal_tree(current))
5546 } else {
5547 Err(AntlrError::MismatchedInput {
5548 expected: self.interval_display(intervals),
5549 found: self.vocabulary().display_name(current_type),
5550 })
5551 }
5552 }
5553
5554 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
5555 let values = intervals
5556 .iter()
5557 .map(|(start, stop)| {
5558 if start == stop {
5559 self.vocabulary().display_name(*start)
5560 } else {
5561 format!(
5562 "{}..{}",
5563 self.vocabulary().display_name(*start),
5564 self.vocabulary().display_name(*stop)
5565 )
5566 }
5567 })
5568 .collect::<Vec<_>>()
5569 .join(", ");
5570 format!("{{{values}}}")
5571 }
5572
5573 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
5574 if self.build_parse_trees {
5575 self.tree.finish_rule(context)
5576 } else {
5577 NodeId::placeholder()
5578 }
5579 }
5580
5581 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
5584 self.set_state(state);
5585 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
5586 self.rule_context_stack.push(RuleContextFrame {
5587 rule_index,
5588 invoking_state,
5589 });
5590 self.advance_rule_context_version();
5591 let start_index = self.current_visible_index();
5592 let mut context = ParserRuleContext::new(rule_index, invoking_state);
5593 if let Some(token) = self.token_id_at(start_index) {
5594 self.set_context_start(&mut context, token);
5595 }
5596 context
5597 }
5598
5599 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
5606 let marker = self.pending_invoking_states.len();
5607 self.pending_invoking_states.push(invoking_state);
5608 marker
5609 }
5610
5611 pub fn discard_invoking_state(&mut self, marker: usize) {
5613 self.pending_invoking_states.truncate(marker);
5614 }
5615
5616 pub fn exit_rule(&mut self) {
5618 self.rule_context_stack.pop();
5619 self.advance_rule_context_version();
5620 }
5621
5622 pub fn prediction_context_return_states<'a>(
5625 &'a self,
5626 atn: &'a Atn,
5627 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
5628 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
5629 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
5630 return None;
5631 };
5632 let Some(Transition::Rule { follow_state, .. }) = atn
5633 .state(state_number)
5634 .and_then(|state| state.transitions().first())
5635 .map(ParserTransition::data)
5636 else {
5637 return None;
5638 };
5639 Some(follow_state)
5640 })
5641 }
5642
5643 pub const fn rule_context_version(&self) -> usize {
5648 self.rule_context_version
5649 }
5650
5651 const fn advance_rule_context_version(&mut self) {
5652 self.rule_context_version = self.rule_context_version.wrapping_add(1);
5653 }
5654
5655 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
5660 if self.build_parse_trees {
5661 self.tree.add_child(context, child);
5662 } else {
5663 context.note_matched_child();
5664 }
5665 }
5666
5667 fn release_tree_scratch_if_idle(&mut self) {
5668 if self.rule_context_stack.is_empty() {
5669 self.tree.release_scratch();
5670 }
5671 }
5672
5673 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
5675 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5676 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5677 self.set_context_stop(&mut context, token);
5678 }
5679 let node = self.rule_node(context);
5680 self.exit_rule();
5681 self.release_tree_scratch_if_idle();
5682 node
5683 }
5684
5685 pub fn recover_generated_rule(
5692 &mut self,
5693 context: &mut ParserRuleContext,
5694 atn: &Atn,
5695 error: AntlrError,
5696 ) {
5697 let diagnostic = self.generated_rule_error_diagnostic(error);
5698 self.push_generated_parser_diagnostic(diagnostic);
5699 self.generated_sync_expected = None;
5700 let recovery_symbols = self.context_expected_symbols(atn);
5701 loop {
5702 let symbol = self.la(1);
5703 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
5704 break;
5705 }
5706 let Some(token) = self.input.lt_id(1) else {
5707 break;
5708 };
5709 self.consume();
5710 let child = self.error_tree(token);
5711 self.add_parse_child(context, child);
5712 }
5713 self.record_syntax_errors(1);
5714 }
5715
5716 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
5717 if self
5718 .generated_parser_diagnostics
5719 .iter()
5720 .any(|existing| existing == &diagnostic)
5721 {
5722 return;
5723 }
5724 self.generated_parser_diagnostics.push(diagnostic);
5725 }
5726
5727 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
5728 match error {
5729 AntlrError::ParserError {
5730 line,
5731 column,
5732 message,
5733 } => ParserDiagnostic {
5734 line,
5735 column,
5736 message,
5737 },
5738 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
5739 self.input.lt(1),
5740 format!("mismatched input {found} expecting {expected}"),
5741 ),
5742 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
5743 self.input.lt(1),
5744 format!("no viable alternative at input {input}"),
5745 ),
5746 AntlrError::LexerError {
5747 line,
5748 column,
5749 message,
5750 } => ParserDiagnostic {
5751 line,
5752 column,
5753 message,
5754 },
5755 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
5756 }
5757 }
5758
5759 pub fn finish_recursion_rule(
5761 &mut self,
5762 mut context: ParserRuleContext,
5763 consumed_eof: bool,
5764 ) -> ParseTree {
5765 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5766 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5767 self.set_context_stop(&mut context, token);
5768 }
5769 let node = self.rule_node(context);
5770 self.unroll_recursion_context();
5771 self.release_tree_scratch_if_idle();
5772 node
5773 }
5774
5775 pub fn enter_recursion_rule(
5777 &mut self,
5778 state: isize,
5779 rule_index: usize,
5780 precedence: i32,
5781 ) -> ParserRuleContext {
5782 self.precedence_stack.push(precedence);
5783 self.enter_rule(state, rule_index)
5784 }
5785
5786 pub fn push_new_recursion_context(
5788 &mut self,
5789 state: isize,
5790 rule_index: usize,
5791 ) -> ParserRuleContext {
5792 self.set_state(state);
5793 ParserRuleContext::new(rule_index, state)
5794 }
5795
5796 pub fn push_new_recursion_context_with_previous(
5799 &mut self,
5800 state: isize,
5801 rule_index: usize,
5802 current: &mut ParserRuleContext,
5803 ) {
5804 self.set_state(state);
5805 if let Some(stop) = self
5806 .rule_stop_token_index(self.input.index(), false)
5807 .and_then(|index| self.token_id_at(index))
5808 {
5809 self.set_context_stop(current, stop);
5810 }
5811 let invoking_state = current.invoking_state();
5812 let start = current.start_id();
5813 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
5814 if start.is_some() {
5815 replacement.set_start_from_context(current);
5816 }
5817 let previous = std::mem::replace(current, replacement);
5818 if self.build_parse_trees {
5819 let previous = self.rule_node(previous);
5820 self.tree.add_child(current, previous);
5821 }
5822 }
5823
5824 pub fn unroll_recursion_context(&mut self) {
5826 if self.precedence_stack.len() > 1 {
5827 self.precedence_stack.pop();
5828 }
5829 self.exit_rule();
5830 }
5831
5832 pub fn left_recursive_loop_enter_prediction(
5846 &mut self,
5847 atn: &Atn,
5848 state_number: usize,
5849 precedence: i32,
5850 ) -> Option<bool> {
5851 let symbol = self.la(1);
5852 if symbol == TOKEN_EOF {
5853 return Some(false);
5854 }
5855 let operator_lookahead =
5856 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
5857 let can_single = operator_lookahead.single_token.contains(symbol);
5858 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
5859 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
5860 if !can_single && !can_multi && !can_predicate {
5861 return Some(false);
5862 }
5863 if can_predicate && !can_single {
5864 return None;
5865 }
5866 if !can_single && can_multi && precedence > 0 {
5870 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
5871 if baseline.single_token.contains(symbol) {
5872 return None;
5873 }
5874 }
5875 let atn_key = SharedAtnCacheKey::for_atn(atn);
5876 let cached_overlap = self
5877 .left_recursive_caller_overlap_cache
5878 .iter()
5879 .flatten()
5880 .find(|entry| {
5881 entry.atn_key == atn_key
5882 && entry.state_number == state_number
5883 && entry.symbol == symbol
5884 && entry.context_version == self.rule_context_version
5885 })
5886 .map(|entry| entry.overlaps);
5887 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
5888 let overlaps = caller_context_can_match_symbol_before_state(
5889 atn,
5890 self.prediction_context_return_states(atn),
5891 state_number,
5892 symbol,
5893 );
5894 if let Some(slot) = self
5895 .left_recursive_caller_overlap_cache
5896 .iter_mut()
5897 .find(|slot| slot.is_none())
5898 {
5899 *slot = Some(LeftRecursiveCallerOverlap {
5900 atn_key,
5901 state_number,
5902 symbol,
5903 context_version: self.rule_context_version,
5904 overlaps,
5905 });
5906 }
5907 overlaps
5908 });
5909 if caller_overlaps {
5910 return None;
5911 }
5912 Some(true)
5913 }
5914
5915 fn cached_left_recursive_operator_lookahead(
5916 atn: &Atn,
5917 state_number: usize,
5918 precedence: i32,
5919 ) -> Rc<LeftRecursiveOperatorLookahead> {
5920 with_shared_atn_caches(atn, |cache| {
5921 let key = (state_number, precedence);
5922 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
5923 return Rc::clone(cached);
5924 }
5925 let lookahead = Rc::new(left_recursive_operator_lookahead(
5926 atn,
5927 state_number,
5928 precedence,
5929 ));
5930 cache
5931 .left_recursive_operator_lookahead
5932 .insert(key, Rc::clone(&lookahead));
5933 lookahead
5934 })
5935 }
5936
5937 pub fn left_recursive_loop_enter_matches(
5940 &mut self,
5941 atn: &Atn,
5942 state_number: usize,
5943 precedence: i32,
5944 ) -> bool {
5945 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
5946 }
5947
5948 pub fn precpred(&self, precedence: i32) -> bool {
5950 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
5951 }
5952
5953 pub fn parser_semantic_predicate_matches(
5956 &mut self,
5957 predicates: &[(usize, usize, ParserPredicate)],
5958 rule_index: usize,
5959 pred_index: usize,
5960 ) -> bool {
5961 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
5962 }
5963
5964 pub fn parser_semantic_predicate_matches_with_local(
5967 &mut self,
5968 predicates: &[(usize, usize, ParserPredicate)],
5969 rule_index: usize,
5970 pred_index: usize,
5971 local_int_arg: i32,
5972 ) -> bool {
5973 self.parser_semantic_predicate_matches_inner(
5974 predicates,
5975 rule_index,
5976 pred_index,
5977 Some((rule_index, i64::from(local_int_arg))),
5978 )
5979 }
5980
5981 fn parser_semantic_predicate_matches_inner(
5982 &mut self,
5983 predicates: &[(usize, usize, ParserPredicate)],
5984 rule_index: usize,
5985 pred_index: usize,
5986 local_int_arg: Option<(usize, i64)>,
5987 ) -> bool {
5988 let index = self.input.index();
5989 let member_values = self.int_members.clone();
5990 self.parser_predicate_matches(PredicateEval {
5991 index,
5992 rule_index,
5993 pred_index,
5994 predicates,
5995 semantics: None,
5996 context: None,
5997 local_int_arg,
5998 member_values: &member_values,
5999 })
6000 }
6001
6002 pub fn parser_semantic_predicate_matches_with_context_and_local(
6005 &mut self,
6006 predicates: &[(usize, usize, ParserPredicate)],
6007 rule_index: usize,
6008 pred_index: usize,
6009 context: &ParserRuleContext,
6010 local_int_arg: i32,
6011 ) -> bool {
6012 let index = self.input.index();
6013 let member_values = self.int_members.clone();
6014 self.parser_predicate_matches(PredicateEval {
6015 index,
6016 rule_index,
6017 pred_index,
6018 predicates,
6019 semantics: None,
6020 context: Some(context),
6021 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6022 member_values: &member_values,
6023 })
6024 }
6025
6026 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
6029 &mut self,
6030 semantics: &ParserSemantics,
6031 rule_index: usize,
6032 pred_index: usize,
6033 context: &ParserRuleContext,
6034 local_int_arg: i32,
6035 ) -> bool {
6036 let index = self.input.index();
6037 let member_values = self.int_members.clone();
6038 self.parser_predicate_matches(PredicateEval {
6039 index,
6040 rule_index,
6041 pred_index,
6042 predicates: &[],
6043 semantics: Some(semantics),
6044 context: Some(context),
6045 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6046 member_values: &member_values,
6047 })
6048 }
6049
6050 pub fn parser_semantic_predicate_failure_message(
6053 &self,
6054 rule_index: usize,
6055 pred_index: usize,
6056 predicates: &[(usize, usize, ParserPredicate)],
6057 ) -> Option<&'static str> {
6058 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
6059 }
6060
6061 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
6063 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6064 line: 0,
6065 column: 0,
6066 message: "missing current token".to_owned(),
6067 })?;
6068 if self.token_type_for_id(current) == TOKEN_EOF {
6069 return Err(AntlrError::MismatchedInput {
6070 expected: "wildcard".to_owned(),
6071 found: self.vocabulary().display_name(TOKEN_EOF),
6072 });
6073 }
6074 self.consume();
6075 Ok(self.terminal_tree(current))
6076 }
6077
6078 #[allow(clippy::unnecessary_wraps)]
6082 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
6083 self.set_state(state);
6084 Ok(())
6085 }
6086
6087 pub fn sync_decision(
6095 &mut self,
6096 atn: &Atn,
6097 state_number: usize,
6098 current_context_empty: bool,
6099 loop_back: bool,
6100 ) -> Result<Vec<ParseTree>, AntlrError> {
6101 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
6102 self.generated_sync_expected = None;
6103 let Some(state) = atn.state(state_number) else {
6104 return Ok(Vec::new());
6105 };
6106 let Some(rule_index) = state.rule_index() else {
6107 return Ok(Vec::new());
6108 };
6109 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
6110 return Ok(Vec::new());
6111 };
6112 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6113 let symbol = self.la(1);
6114 let mut has_expected_symbols = false;
6115 let mut nullable = false;
6116 let mut explicit_eof_expected = false;
6124 for transition in &entry.transitions {
6125 if transition.symbols.contains(symbol) {
6126 return Ok(Vec::new());
6127 }
6128 has_expected_symbols |= !transition.symbols.is_empty();
6129 nullable |= transition.nullable;
6130 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
6131 }
6132 if nullable && self.context_expected_contains(atn, symbol) {
6137 return Ok(Vec::new());
6138 }
6139 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
6140 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
6141 return Ok(Vec::new());
6142 }
6143 let mut expected = TokenBitSet::default();
6144 for transition in &entry.transitions {
6145 expected.extend_from(&transition.symbols);
6146 }
6147 if let Some(context_expected) = context_expected {
6148 expected.extend_from(&context_expected);
6149 }
6150 let can_delete_in_place =
6151 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
6152 let loop_sync = loop_back;
6169 if symbol != TOKEN_EOF && can_delete_in_place {
6170 let mut cursor = self.input.index();
6171 let mut skipped = Vec::new();
6172 loop {
6173 let current = self.token_type_at(cursor);
6174 if current == TOKEN_EOF {
6175 break;
6176 }
6177 skipped.push(cursor);
6178 let next = self.consume_index(cursor, current);
6179 if next == cursor {
6180 break;
6181 }
6182 let next_symbol = self.token_type_at(next);
6183 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
6191 explicit_eof_expected
6192 } else {
6193 expected.contains(next_symbol)
6194 };
6195 if next_is_expected_stop {
6196 let current_token = self.input.lt(1);
6197 let expected_symbols = expected.to_btree_set();
6198 let message = format!(
6199 "extraneous input {} expecting {}",
6200 current_token
6201 .as_ref()
6202 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6203 self.expected_symbols_display(&expected_symbols)
6204 );
6205 self.push_generated_parser_diagnostic(diagnostic_for_token(
6206 current_token,
6207 message,
6208 ));
6209 self.record_syntax_errors(1);
6210 let mut children = Vec::with_capacity(skipped.len());
6211 for index in skipped {
6212 if let Some(token) = self.token_id_at(index) {
6213 self.consume();
6214 children.push(self.error_tree(token));
6215 }
6216 }
6217 return Ok(children);
6218 }
6219 if !loop_sync {
6223 break;
6224 }
6225 cursor = next;
6226 }
6227 }
6228 if nullable {
6229 self.generated_sync_expected = Some(expected);
6230 return Ok(Vec::new());
6231 }
6232 let current = self.input.lt(1);
6233 let expected_symbols = expected.to_btree_set();
6234 Err(AntlrError::ParserError {
6235 line: current.as_ref().map(Token::line).unwrap_or_default(),
6236 column: current.as_ref().map(Token::column).unwrap_or_default(),
6237 message: format!(
6238 "mismatched input {} expecting {}",
6239 current
6240 .as_ref()
6241 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6242 self.expected_symbols_display(&expected_symbols)
6243 ),
6244 })
6245 }
6246
6247 pub fn ll1_decision_prediction(
6254 &mut self,
6255 atn: &Atn,
6256 state_number: usize,
6257 ) -> Option<ParserAtnPrediction> {
6258 let state = atn.state(state_number)?;
6259 if state.precedence_rule_decision() {
6260 return None;
6261 }
6262 let rule_stop = state
6263 .rule_index()
6264 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
6265 let symbol = self.la(1);
6266 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6267 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
6268 alt: alt + 1,
6269 requires_full_context: false,
6270 has_semantic_context: false,
6271 diagnostic: None,
6272 })
6273 }
6274
6275 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
6276 let mut expected = BTreeSet::new();
6277 for index in (1..self.rule_context_stack.len()).rev() {
6278 let invoking_state = self.rule_context_stack[index].invoking_state;
6279 let Ok(state_number) = usize::try_from(invoking_state) else {
6280 continue;
6281 };
6282 let Some(Transition::Rule { follow_state, .. }) = atn
6283 .state(state_number)
6284 .and_then(|state| state.transitions().first())
6285 .map(ParserTransition::data)
6286 else {
6287 continue;
6288 };
6289 let return_state = follow_state;
6290 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
6291 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
6292 return expected;
6293 }
6294 }
6295 expected.insert(TOKEN_EOF);
6296 expected
6297 }
6298
6299 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
6300 let mut expected = TokenBitSet::default();
6301 for index in (1..self.rule_context_stack.len()).rev() {
6302 let invoking_state = self.rule_context_stack[index].invoking_state;
6303 let Ok(state_number) = usize::try_from(invoking_state) else {
6304 continue;
6305 };
6306 let Some(Transition::Rule { follow_state, .. }) = atn
6307 .state(state_number)
6308 .and_then(|state| state.transitions().first())
6309 .map(ParserTransition::data)
6310 else {
6311 continue;
6312 };
6313 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
6314 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6315 return expected;
6316 }
6317 }
6318 expected.insert(TOKEN_EOF);
6319 expected
6320 }
6321
6322 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
6333 for index in (1..self.rule_context_stack.len()).rev() {
6334 let invoking_state = self.rule_context_stack[index].invoking_state;
6335 let Ok(state_number) = usize::try_from(invoking_state) else {
6336 continue;
6337 };
6338 let Some(Transition::Rule { follow_state, .. }) = atn
6339 .state(state_number)
6340 .and_then(|state| state.transitions().first())
6341 .map(ParserTransition::data)
6342 else {
6343 continue;
6344 };
6345 if self
6346 .cached_state_expected_token_set(atn, follow_state)
6347 .contains(symbol)
6348 {
6349 return true;
6350 }
6351 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6352 return false;
6353 }
6354 }
6355 symbol == TOKEN_EOF
6356 }
6357
6358 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
6360 let error_index = self.input.index();
6361 self.no_viable_alternative_error_at(start_index, error_index)
6362 }
6363
6364 pub fn no_viable_alternative_error_at(
6369 &self,
6370 start_index: usize,
6371 error_index: usize,
6372 ) -> AntlrError {
6373 let diagnostic = self.no_viable_alternative(start_index, error_index);
6374 AntlrError::ParserError {
6375 line: diagnostic.line,
6376 column: diagnostic.column,
6377 message: diagnostic.message,
6378 }
6379 }
6380
6381 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
6383 let current = self.input.lt(1);
6384 AntlrError::ParserError {
6385 line: current.as_ref().map(Token::line).unwrap_or_default(),
6386 column: current.as_ref().map(Token::column).unwrap_or_default(),
6387 message: format!("rule failed predicate: {}", message.into()),
6388 }
6389 }
6390
6391 pub fn failed_predicate_option_error(
6394 &self,
6395 rule_index: usize,
6396 message: impl Into<String>,
6397 ) -> AntlrError {
6398 let current = self.input.lt(1);
6399 let rule_name = self
6400 .rule_names()
6401 .get(rule_index)
6402 .map_or_else(|| rule_index.to_string(), Clone::clone);
6403 AntlrError::ParserError {
6404 line: current.as_ref().map(Token::line).unwrap_or_default(),
6405 column: current.as_ref().map(Token::column).unwrap_or_default(),
6406 message: format!("rule {rule_name} {}", message.into()),
6407 }
6408 }
6409
6410 pub fn parser_action_at_current(
6412 &mut self,
6413 source_state: usize,
6414 rule_index: usize,
6415 start_index: usize,
6416 consumed_eof: bool,
6417 ) -> ParserAction {
6418 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6419 ParserAction::new(source_state, rule_index, start_index, stop_index)
6420 }
6421
6422 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
6427 let rule_index = action.rule_index();
6428 let rule_name = self.rule_names().get(rule_index).cloned();
6429 let context = None;
6430 let input = &mut self.input;
6431 let semantic_hooks = &mut self.semantic_hooks;
6432 let member_values = &self.int_members;
6433 let mut ctx = ParserSemCtx {
6434 input,
6435 tree_storage: &self.tree,
6436 rule_index,
6437 coordinate_index: usize::MAX,
6438 rule_name,
6439 context,
6440 tree: Some(tree),
6441 local_int_arg: None,
6442 member_values,
6443 action: Some(action),
6444 };
6445 let handled = semantic_hooks.action(&mut ctx, action);
6446 if !handled && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error) {
6452 let coordinate = (rule_index, action.source_state());
6453 if !self.unhandled_action_hits.contains(&coordinate) {
6454 self.unhandled_action_hits.push(coordinate);
6455 }
6456 }
6457 handled
6458 }
6459
6460 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
6465 &mut self,
6466 atn: &'atn Atn,
6467 simulator: &mut ParserAtnSimulator<'atn>,
6468 rule_index: usize,
6469 ) -> Result<ParseTree, AntlrError> {
6470 let start_index = self.current_visible_index();
6471 self.clear_prediction_diagnostics();
6472 self.reset_per_parse_caches();
6473 self.reset_recognition_arena();
6474 let tree_checkpoint = self.tree.checkpoint();
6475 let mut decision_by_state = vec![None; atn.states().len()];
6476 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
6477 if let Some(slot) = decision_by_state.get_mut(state_number) {
6478 *slot = Some(decision);
6479 }
6480 }
6481
6482 let result = DirectAdaptiveParser {
6483 parser: self,
6484 atn,
6485 simulator,
6486 decision_by_state,
6487 steps: 0,
6488 }
6489 .parse_rule(rule_index, -1, 0);
6490
6491 match result {
6492 Ok(tree) => {
6493 self.report_token_source_errors();
6494 self.release_tree_scratch_if_idle();
6495 Ok(tree)
6496 }
6497 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
6498 let _ = reason;
6499 self.tree.rollback(tree_checkpoint);
6500 self.input.seek(start_index);
6501 self.parse_atn_rule(atn, rule_index)
6502 }
6503 }
6504 }
6505
6506 pub fn parse_atn_rule(
6516 &mut self,
6517 atn: &Atn,
6518 rule_index: usize,
6519 ) -> Result<ParseTree, AntlrError> {
6520 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
6521 }
6522
6523 pub fn parse_atn_rule_with_precedence(
6526 &mut self,
6527 atn: &Atn,
6528 rule_index: usize,
6529 precedence: i32,
6530 ) -> Result<ParseTree, AntlrError> {
6531 self.parse_atn_rule_with_precedence_inner(atn, rule_index, precedence, None)
6532 }
6533
6534 fn parse_atn_rule_with_precedence_inner(
6535 &mut self,
6536 atn: &Atn,
6537 rule_index: usize,
6538 precedence: i32,
6539 predicate_context: Option<FastPredicateContext<'_>>,
6540 ) -> Result<ParseTree, AntlrError> {
6541 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
6542 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
6543 })?;
6544 let stop_state = atn
6545 .rule_to_stop_state()
6546 .get(rule_index)
6547 .filter(|state| *state != usize::MAX)
6548 .ok_or_else(|| {
6549 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
6550 })?;
6551
6552 let start_index = self.current_visible_index();
6553 self.clear_prediction_diagnostics();
6554 self.reset_per_parse_caches();
6555 self.reset_recognition_arena();
6556 let caller_follow_state = self.pending_invoking_follow_state(atn);
6557 self.fast_recovery_enabled = false;
6558 self.fast_token_nodes_enabled = false;
6559 let top_request = FastRecognizeTopRequest {
6560 start_state,
6561 stop_state,
6562 start_index,
6563 precedence,
6564 caller_follow_state,
6565 };
6566 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
6567 self.fast_token_nodes_enabled = self.build_parse_trees;
6568 let needs_tree_retry = matches!(
6569 &first_pass,
6570 Ok((outcome, _))
6571 if self.build_parse_trees
6572 && self
6573 .recognition_arena
6574 .sequence_has_left_recursive_boundary(outcome.nodes)
6575 );
6576 let needs_retry = match &first_pass {
6577 Err(_) => true,
6590 Ok((outcome, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
6591 };
6592 let (outcome, _expected) = if needs_retry {
6593 self.fast_first_set_prefilter = false;
6594 self.fast_recovery_enabled = false;
6595 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6596 let clean_selected = if needs_tree_retry {
6597 match clean_retry {
6598 ok @ Ok(_) => ok,
6599 Err(_) => first_pass,
6600 }
6601 } else {
6602 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
6603 };
6604 let selected = if clean_selected.is_err()
6605 || matches!(&clean_selected, Ok((outcome, _)) if !outcome.diagnostics.is_empty())
6606 {
6607 self.fast_recovery_enabled = true;
6608 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6609 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
6610 } else {
6611 clean_selected
6612 };
6613 self.fast_first_set_prefilter = true;
6614 self.fast_recovery_enabled = true;
6615 selected.map_err(|expected| {
6616 if predicate_context.is_some()
6617 && let Some(error) = self.unknown_semantic_error()
6618 {
6619 self.report_token_source_errors();
6620 return error;
6621 }
6622 let error = self.recognition_error(rule_index, start_index, &expected);
6623 self.record_syntax_errors(1);
6624 self.report_token_source_errors();
6625 error
6626 })?
6627 } else {
6628 first_pass.expect("first_pass is Ok in the no-retry branch")
6629 };
6630 if predicate_context.is_some()
6631 && let Some(error) = self.unknown_semantic_error()
6632 {
6633 self.report_token_source_errors();
6634 return Err(error);
6635 }
6636 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
6637 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
6638 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
6639 self.report_token_source_errors();
6640 let mut context = ParserRuleContext::with_child_capacity(
6641 rule_index,
6642 self.state(),
6643 if self.build_parse_trees {
6644 self.recognition_arena.sequence_len(outcome.nodes)
6645 } else {
6646 0
6647 },
6648 );
6649 if let Some(token) = self.token_id_at(start_index) {
6650 self.set_context_start(&mut context, token);
6651 }
6652 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
6653 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
6654 self.set_context_stop(&mut context, token);
6655 }
6656 let live_root = if self.build_parse_trees {
6657 self.recognition_arena
6658 .fold_left_recursive_boundaries(outcome.nodes)
6659 } else {
6660 outcome.nodes
6661 };
6662 if self.build_parse_trees {
6663 if self
6664 .recognition_arena
6665 .sequence_has_explicit_token(live_root)
6666 {
6667 let mut cursor = live_root;
6668 while let Some(link) = self.recognition_arena.link(cursor) {
6669 let child = self.arena_recognized_node_tree(link.head, false)?;
6670 self.tree.add_child(&mut context, child);
6671 cursor = link.tail;
6672 }
6673 } else {
6674 self.add_arena_implicit_token_children(
6675 &mut context,
6676 start_index,
6677 stop_index,
6678 live_root,
6679 )?;
6680 }
6681 }
6682 self.finish_recognition_arena(live_root, outcome.diagnostics);
6683 self.input.seek(outcome.index);
6684
6685 let tree = self.rule_node(context);
6686 self.release_tree_scratch_if_idle();
6687 Ok(tree)
6688 }
6689
6690 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
6691 let invoking_state = self.pending_invoking_states.last().copied()?;
6692 let state_number = usize::try_from(invoking_state).ok()?;
6693 match atn.state(state_number)?.transitions().first()?.data() {
6694 Transition::Rule { follow_state, .. } => Some(follow_state),
6695 _ => None,
6696 }
6697 }
6698
6699 #[cfg(test)]
6700 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
6701 caller_follow_token_info_for_stream(&mut self.input, index)
6702 }
6703
6704 fn fast_recognize_top(
6709 &mut self,
6710 atn: &Atn,
6711 request: FastRecognizeTopRequest,
6712 predicate_context: Option<FastPredicateContext<'_>>,
6713 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
6714 let FastRecognizeTopRequest {
6715 start_state,
6716 stop_state,
6717 start_index,
6718 precedence,
6719 caller_follow_state,
6720 } = request;
6721 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
6730 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
6731 recognize_scratch.prepare(memo_capacity);
6732 let mut expected = ExpectedTokens::default();
6733 let empty_recovery = self.empty_recovery_symbols();
6734 let outcomes = self.recognize_state_fast(
6735 atn,
6736 FastRecognizeRequest {
6737 state_number: start_state,
6738 stop_state,
6739 index: start_index,
6740 rule_start_index: start_index,
6741 decision_start_index: None,
6742 precedence,
6743 depth: 0,
6744 recovery_symbols: empty_recovery,
6745 recovery_state: None,
6746 },
6747 FastRecognizeScratch {
6748 predicate_context,
6749 visiting: &mut recognize_scratch.visiting,
6750 memo: &mut recognize_scratch.memo,
6751 expected: &mut expected,
6752 },
6753 );
6754 recognize_scratch.release_oversized_memo();
6755 self.fast_recognize_scratch = recognize_scratch;
6756 #[cfg(feature = "perf-counters")]
6757 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
6758 perf_counters::dump();
6759 perf_counters::reset();
6760 }
6761 let caller_follow =
6762 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
6763 let selected = {
6764 let arena = &self.recognition_arena;
6765 let input = &mut self.input;
6766 select_best_fast_outcome(
6767 outcomes.into_iter(),
6768 self.prediction_mode,
6769 caller_follow.as_deref(),
6770 |index| caller_follow_token_info_for_stream(input, index),
6771 arena,
6772 )
6773 };
6774 match selected {
6775 Some(mut outcome) => {
6776 if self.build_parse_trees {
6777 self.materialize_fast_outcome_nodes(&mut outcome);
6778 }
6779 Ok((outcome, expected))
6780 }
6781 None => Err(expected),
6782 }
6783 }
6784
6785 fn arena_recognized_node_tree(
6787 &mut self,
6788 node_id: RecognizedNodeId,
6789 track_alt_numbers: bool,
6790 ) -> Result<ParseTree, AntlrError> {
6791 let node = self.recognition_arena.node(node_id);
6792 match node {
6793 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
6794 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
6795 ArenaRecognizedNode::MissingToken { extra } => {
6796 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
6797 RecognitionExtra::MissingToken {
6798 token_type,
6799 at_index,
6800 text,
6801 } => (*token_type, *at_index as usize, text.clone()),
6802 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
6803 unreachable!("missing-token node must reference missing-token extra")
6804 }
6805 };
6806 let (line, column) = self
6807 .token_at(at_index)
6808 .map_or((0, 0), |token| (token.line(), token.column()));
6809 let token = self.insert_synthetic_token(token_type, text, line, column)?;
6810 Ok(self.error_tree(token))
6811 }
6812 ArenaRecognizedNode::Rule {
6813 rule_index,
6814 invoking_state,
6815 alt_number,
6816 start_index,
6817 stop_index,
6818 return_values,
6819 children,
6820 } => {
6821 let mut context = ParserRuleContext::with_child_capacity(
6822 rule_index as usize,
6823 invoking_state as isize,
6824 self.recognition_arena.sequence_len(children),
6825 );
6826 if track_alt_numbers {
6827 context.set_alt_number(alt_number as usize);
6828 }
6829 if let Some(extra) = return_values {
6830 let RecognitionExtra::ReturnValues(values) =
6831 self.recognition_arena.extra(extra)
6832 else {
6833 unreachable!("rule node must reference return-values extra");
6834 };
6835 for (name, value) in values {
6836 context.set_int_return(name.clone(), *value);
6837 }
6838 }
6839 if let Some(token) = self.token_id_at(start_index as usize) {
6840 self.set_context_start(&mut context, token);
6841 }
6842 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
6843 self.set_context_stop(&mut context, token);
6844 }
6845 let mut cursor = self
6846 .recognition_arena
6847 .fold_left_recursive_boundaries(children);
6848 while let Some(link) = self.recognition_arena.link(cursor) {
6849 let child = self.arena_recognized_node_tree(link.head, track_alt_numbers)?;
6850 self.tree.add_child(&mut context, child);
6851 cursor = link.tail;
6852 }
6853 Ok(self.rule_node(context))
6854 }
6855 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index } => {
6856 Err(AntlrError::Unsupported(format!(
6857 "unfolded left-recursive boundary for rule {rule_index}"
6858 )))
6859 }
6860 }
6861 }
6862
6863 fn arena_recognized_node_tree_with_implicit_tokens(
6864 &mut self,
6865 node_id: RecognizedNodeId,
6866 ) -> Result<ParseTree, AntlrError> {
6867 let node = self.recognition_arena.node(node_id);
6868 match node {
6869 ArenaRecognizedNode::Rule {
6870 rule_index,
6871 invoking_state,
6872 start_index,
6873 stop_index,
6874 children,
6875 ..
6876 } => {
6877 let mut context = ParserRuleContext::with_child_capacity(
6878 rule_index as usize,
6879 invoking_state as isize,
6880 self.recognition_arena.sequence_len(children),
6881 );
6882 if let Some(token) = self.token_id_at(start_index as usize) {
6883 self.set_context_start(&mut context, token);
6884 }
6885 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
6886 self.set_context_stop(&mut context, token);
6887 }
6888 let children = self
6889 .recognition_arena
6890 .fold_left_recursive_boundaries(children);
6891 self.add_arena_implicit_token_children(
6892 &mut context,
6893 start_index as usize,
6894 stop_index.map(|index| index as usize),
6895 children,
6896 )?;
6897 Ok(self.rule_node(context))
6898 }
6899 _ => self.arena_recognized_node_tree(node_id, false),
6900 }
6901 }
6902
6903 fn add_arena_implicit_token_children(
6904 &mut self,
6905 context: &mut ParserRuleContext,
6906 start_index: usize,
6907 stop_index: Option<usize>,
6908 mut children: NodeSeqId,
6909 ) -> Result<(), AntlrError> {
6910 let mut cursor = Some(start_index);
6911 while let Some(link) = self.recognition_arena.link(children) {
6912 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
6913 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
6914 let child = self.arena_recognized_node_tree_with_implicit_tokens(link.head)?;
6915 self.tree.add_child(context, child);
6916 if let Some(child_stop) = child_stop {
6917 cursor = self.next_visible_after_token(child_stop);
6918 }
6919 } else {
6920 let child = self.arena_recognized_node_tree_with_implicit_tokens(link.head)?;
6921 self.tree.add_child(context, child);
6922 }
6923 children = link.tail;
6924 }
6925 if let Some(stop) = stop_index {
6926 self.add_visible_terminals_through(context, cursor, stop)?;
6927 }
6928 Ok(())
6929 }
6930
6931 fn add_visible_terminals_before(
6932 &mut self,
6933 context: &mut ParserRuleContext,
6934 cursor: &mut Option<usize>,
6935 before: usize,
6936 ) -> Result<(), AntlrError> {
6937 let Some(stop) = before.checked_sub(1) else {
6938 return Ok(());
6939 };
6940 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
6941 *cursor = next;
6942 Ok(())
6943 }
6944
6945 fn add_visible_terminals_through(
6946 &mut self,
6947 context: &mut ParserRuleContext,
6948 mut cursor: Option<usize>,
6949 stop: usize,
6950 ) -> Result<Option<usize>, AntlrError> {
6951 while let Some(index) = cursor {
6952 if index > stop {
6953 return Ok(Some(index));
6954 }
6955 let token = self
6956 .input
6957 .get_id(index)
6958 .ok_or_else(|| AntlrError::ParserError {
6959 line: 0,
6960 column: 0,
6961 message: format!("missing token at index {index}"),
6962 })?;
6963 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
6964 let child = self.terminal_tree(token);
6965 self.tree.add_child(context, child);
6966 if is_eof {
6967 return Ok(None);
6968 }
6969 cursor = self.next_visible_after_token(index);
6970 }
6971 Ok(None)
6972 }
6973
6974 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
6975 let next = self.input.next_visible_after(index);
6976 (next != index).then_some(next)
6977 }
6978
6979 pub fn parse_atn_rule_with_actions(
6986 &mut self,
6987 atn: &Atn,
6988 rule_index: usize,
6989 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
6990 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
6991 }
6992
6993 pub fn parse_atn_rule_with_action_inits(
7001 &mut self,
7002 atn: &Atn,
7003 rule_index: usize,
7004 init_action_rules: &[usize],
7005 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7006 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
7007 }
7008
7009 pub fn parse_atn_rule_with_action_options(
7015 &mut self,
7016 atn: &Atn,
7017 rule_index: usize,
7018 init_action_rules: &[usize],
7019 track_alt_numbers: bool,
7020 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7021 self.parse_atn_rule_with_runtime_options(
7022 atn,
7023 rule_index,
7024 ParserRuntimeOptions {
7025 init_action_rules,
7026 track_alt_numbers,
7027 ..ParserRuntimeOptions::default()
7028 },
7029 )
7030 }
7031
7032 pub fn parse_atn_rule_with_runtime_options(
7039 &mut self,
7040 atn: &Atn,
7041 rule_index: usize,
7042 options: ParserRuntimeOptions<'_>,
7043 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7044 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
7045 }
7046
7047 pub fn parse_atn_rule_with_runtime_options_and_precedence(
7050 &mut self,
7051 atn: &Atn,
7052 rule_index: usize,
7053 precedence: i32,
7054 options: ParserRuntimeOptions<'_>,
7055 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7056 let ParserRuntimeOptions {
7057 init_action_rules,
7058 track_alt_numbers,
7059 predicates,
7060 semantics,
7061 rule_args,
7062 member_actions,
7063 return_actions,
7064 unknown_predicate_policy,
7065 } = options;
7066 if init_action_rules.is_empty()
7067 && !track_alt_numbers
7068 && predicates.is_empty()
7069 && semantics.is_none()
7070 && rule_args.is_empty()
7071 && member_actions.is_empty()
7072 && return_actions.is_empty()
7073 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
7074 && !atn_has_observable_action_transitions(atn)
7075 && (!self.semantic_hooks.observes_parser_predicates()
7076 || !atn_has_predicate_transitions(atn))
7077 {
7078 return self
7079 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
7080 .map(|tree| (tree, Vec::new()));
7081 }
7082 if can_use_fast_predicate_recognizer(atn, &options) {
7083 self.unknown_predicate_policy = unknown_predicate_policy;
7084 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7085 let member_values = self.int_members.clone();
7086 let result = self
7087 .parse_atn_rule_with_precedence_inner(
7088 atn,
7089 rule_index,
7090 precedence,
7091 Some(FastPredicateContext {
7092 predicates,
7093 semantics,
7094 member_values: &member_values,
7095 }),
7096 )
7097 .map(|tree| (tree, Vec::new()));
7098 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
7099 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7100 }
7101 return result;
7102 }
7103 self.unknown_predicate_policy = unknown_predicate_policy;
7104 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7111 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7112 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7113 })?;
7114 let stop_state = atn
7115 .rule_to_stop_state()
7116 .get(rule_index)
7117 .filter(|state| *state != usize::MAX)
7118 .ok_or_else(|| {
7119 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7120 })?;
7121
7122 let start_index = self.current_visible_index();
7123 self.clear_prediction_diagnostics();
7124 self.reset_per_parse_caches();
7125 self.reset_recognition_arena();
7126 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
7127 let invoking_state = self.pending_invoking_states.pop();
7128 let local_int_arg = invoking_state
7129 .and_then(|state| usize::try_from(state).ok())
7130 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
7131 let mut visiting = BTreeSet::new();
7132 let mut memo = BTreeMap::new();
7133 let mut expected = ExpectedTokens::default();
7134 let member_values = self.int_members.clone();
7135 let return_values = BTreeMap::new();
7136 let outcomes = self.recognize_state(
7137 atn,
7138 RecognizeRequest {
7139 state_number: start_state,
7140 stop_state,
7141 index: start_index,
7142 rule_start_index: start_index,
7143 decision_start_index: None,
7144 init_action_rules: &init_action_rules,
7145 predicates,
7146 semantics,
7147 rule_args,
7148 member_actions,
7149 return_actions,
7150 local_int_arg,
7151 member_values,
7152 return_values,
7153 rule_alt_number: 0,
7154 track_alt_numbers,
7155 consumed_eof: false,
7156 precedence,
7157 depth: 0,
7158 recovery_symbols: BTreeSet::new(),
7159 recovery_state: None,
7160 },
7161 &mut visiting,
7162 &mut memo,
7163 &mut expected,
7164 );
7165 if let Some(error) = self.unknown_semantic_error() {
7166 self.report_token_source_errors();
7167 return Err(error);
7174 }
7175 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7178 let Some(outcome) = select_best_outcome(
7179 outcomes.into_iter(),
7180 self.prediction_mode,
7181 &self.recognition_arena,
7182 ) else {
7183 let error = self.recognition_error(rule_index, start_index, &expected);
7184 self.record_syntax_errors(1);
7185 self.report_token_source_errors();
7186 return Err(error);
7187 };
7188
7189 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7190 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7191 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7192 self.report_token_source_errors();
7193 let mut actions = outcome.actions;
7194 if init_action_rules.contains(&rule_index) {
7195 actions.insert(
7196 0,
7197 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
7198 );
7199 }
7200 let mut context =
7201 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
7202 if track_alt_numbers {
7203 context.set_alt_number(outcome.alt_number);
7204 }
7205 for (name, value) in outcome.return_values {
7206 context.set_int_return(name, value);
7207 }
7208 if let Some(token) = self.token_id_at(start_index) {
7209 self.set_context_start(&mut context, token);
7210 }
7211 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
7212 self.set_context_stop(&mut context, token);
7213 }
7214 let live_root = if self.build_parse_trees {
7215 self.recognition_arena
7216 .fold_left_recursive_boundaries(outcome.nodes)
7217 } else {
7218 outcome.nodes
7219 };
7220 if self.build_parse_trees {
7221 let mut nodes = live_root;
7222 while let Some(link) = self.recognition_arena.link(nodes) {
7223 let child = self.arena_recognized_node_tree(link.head, track_alt_numbers)?;
7224 self.tree.add_child(&mut context, child);
7225 nodes = link.tail;
7226 }
7227 }
7228 self.finish_recognition_arena(live_root, outcome.diagnostics);
7229 self.input.seek(outcome.index);
7230
7231 let tree = self.rule_node(context);
7232 self.release_tree_scratch_if_idle();
7233 Ok((tree, actions))
7234 }
7235
7236 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
7243 let mut context = ParserRuleContext::new(rule_index, self.state());
7244 while self.la(1) != TOKEN_EOF {
7245 let token_type = self.la(1);
7246 let child = self.match_token(token_type)?;
7247 if self.build_parse_trees {
7248 self.tree.add_child(&mut context, child);
7249 }
7250 }
7251 if self.build_parse_trees {
7252 let child = self.match_eof()?;
7253 self.tree.add_child(&mut context, child);
7254 }
7255 let tree = self.rule_node(context);
7256 self.release_tree_scratch_if_idle();
7257 Ok(tree)
7258 }
7259
7260 fn recognition_error(
7263 &mut self,
7264 rule_index: usize,
7265 start_index: usize,
7266 expected: &ExpectedTokens,
7267 ) -> AntlrError {
7268 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
7269 self.input.seek(index);
7270 let current = self.input.lt(1);
7271 let line = current.as_ref().map(Token::line).unwrap_or_default();
7272 let column = current.as_ref().map(Token::column).unwrap_or_default();
7273 AntlrError::ParserError {
7274 line,
7275 column,
7276 message,
7277 }
7278 }
7279
7280 fn expected_error_message(
7282 &mut self,
7283 rule_index: usize,
7284 start_index: usize,
7285 expected: &ExpectedTokens,
7286 ) -> (usize, String) {
7287 let index = expected
7288 .index
7289 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
7290 .unwrap_or_else(|| self.input.index());
7291 self.input.seek(index);
7292 let current = self.input.lt(1);
7293 let message = if expected
7294 .no_viable
7295 .as_ref()
7296 .is_some_and(|no_viable| no_viable.error_index == index)
7297 {
7298 let start = expected
7299 .no_viable
7300 .as_ref()
7301 .map_or(start_index, |no_viable| no_viable.start_index);
7302 let text = display_input_text(&self.input.text(start, index));
7303 format!("no viable alternative at input '{text}'")
7304 } else if expected.symbols.is_empty() {
7305 if expected.index.is_some() {
7306 let found = current
7307 .as_ref()
7308 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
7309 if current
7310 .as_ref()
7311 .is_some_and(|token| token.token_type() == TOKEN_EOF)
7312 {
7313 format!(
7314 "missing {} at {found}",
7315 self.expected_symbols_display(&expected.symbols)
7316 )
7317 } else {
7318 format!("mismatched input {found}")
7319 }
7320 } else {
7321 format!("no viable alternative while parsing rule {rule_index}")
7322 }
7323 } else {
7324 format!(
7325 "mismatched input {} expecting {}",
7326 current
7327 .as_ref()
7328 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7329 self.expected_symbols_display(&expected.symbols)
7330 )
7331 };
7332 (index, message)
7333 }
7334
7335 fn child_rule_failure_recovery(
7338 &mut self,
7339 rule_index: usize,
7340 start_index: usize,
7341 sync_symbols: &BTreeSet<i32>,
7342 member_values: BTreeMap<usize, i64>,
7343 expected: &ExpectedTokens,
7344 ) -> Option<RecognizeOutcome> {
7345 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7346 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7347 let mut next_index = error_index;
7348 loop {
7349 let symbol = self.token_type_at(next_index);
7350 if sync_symbols.contains(&symbol) {
7351 if next_index == error_index {
7352 return None;
7353 }
7354 break;
7355 }
7356 if symbol == TOKEN_EOF {
7357 break;
7358 }
7359 let after = self.consume_index(next_index, symbol);
7360 if after == next_index {
7361 break;
7362 }
7363 next_index = after;
7364 }
7365 let mut nodes = NodeSeqId::EMPTY;
7366 let error = self.arena_token_node(error_index, true);
7367 self.arena_prepend(&mut nodes, error);
7368 let diagnostics = self
7369 .recognition_arena
7370 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7371 Some(RecognizeOutcome {
7372 index: next_index,
7373 consumed_eof: false,
7374 alt_number: 0,
7375 member_values,
7376 return_values: BTreeMap::new(),
7377 diagnostics,
7378 decisions: Vec::new(),
7379 actions: Vec::new(),
7380 nodes,
7381 })
7382 }
7383
7384 fn child_rule_failure_recovery_outcomes(
7387 &mut self,
7388 request: ChildRuleFailureRecovery<'_>,
7389 ) -> Vec<RecognizeOutcome> {
7390 let sync_symbols =
7391 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
7392 self.child_rule_failure_recovery(
7393 request.rule_index,
7394 request.start_index,
7395 &sync_symbols,
7396 request.member_values,
7397 request.expected,
7398 )
7399 .into_iter()
7400 .collect()
7401 }
7402
7403 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
7405 expected_symbols_display(symbols, self.vocabulary())
7406 }
7407
7408 fn single_token_deletion(
7411 &mut self,
7412 transition: ParserTransition<'_>,
7413 index: usize,
7414 max_token_type: i32,
7415 expected_symbols: &BTreeSet<i32>,
7416 ) -> Option<(ParserDiagnostic, usize, i32)> {
7417 let current_symbol = self.token_type_at(index);
7418 if current_symbol == TOKEN_EOF {
7419 return None;
7420 }
7421 let next_index = self.consume_index(index, current_symbol);
7422 if next_index == index {
7423 return None;
7424 }
7425 let next_symbol = self.token_type_at(next_index);
7426 if !transition.matches(next_symbol, 1, max_token_type) {
7427 return None;
7428 }
7429 let transition_expected = transition_expected_symbols(transition, max_token_type);
7430 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7431 &transition_expected
7432 } else {
7433 expected_symbols
7434 });
7435 let current = self.token_at(index);
7436 let message = format!(
7437 "extraneous input {} expecting {expected_display}",
7438 current
7439 .as_ref()
7440 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7441 );
7442 Some((
7443 diagnostic_for_token(current, message),
7444 next_index,
7445 next_symbol,
7446 ))
7447 }
7448
7449 fn current_token_deletion(
7452 &mut self,
7453 index: usize,
7454 expected_symbols: &BTreeSet<i32>,
7455 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
7456 if expected_symbols.is_empty() {
7457 return None;
7458 }
7459 let current_symbol = self.token_type_at(index);
7460 if current_symbol == TOKEN_EOF {
7461 return None;
7462 }
7463 let current = self.token_at(index);
7464 let message = format!(
7465 "extraneous input {} expecting {}",
7466 current
7467 .as_ref()
7468 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7469 self.expected_symbols_display(expected_symbols)
7470 );
7471 let diagnostic = diagnostic_for_token(current, message);
7472 let mut skipped = Vec::new();
7473 let mut cursor = index;
7474 loop {
7475 let symbol = self.token_type_at(cursor);
7476 if symbol == TOKEN_EOF {
7477 return None;
7478 }
7479 skipped.push(cursor);
7480 let next_index = self.consume_index(cursor, symbol);
7481 if next_index == cursor {
7482 return None;
7483 }
7484 let next_symbol = self.token_type_at(next_index);
7485 if expected_symbols.contains(&next_symbol) {
7486 return Some((diagnostic, next_index, skipped));
7487 }
7488 cursor = next_index;
7489 }
7490 }
7491
7492 fn single_token_insertion(
7496 &mut self,
7497 transition: ParserTransition<'_>,
7498 index: usize,
7499 max_token_type: i32,
7500 expected_symbols: &BTreeSet<i32>,
7501 follow_symbols: &BTreeSet<i32>,
7502 ) -> Option<(ParserDiagnostic, i32, String)> {
7503 let current_symbol = self.token_type_at(index);
7504 if !follow_symbols.contains(¤t_symbol) {
7505 return None;
7506 }
7507 let transition_expected = transition_expected_symbols(transition, max_token_type);
7508 let token_type = transition_expected.iter().next().copied()?;
7509 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7510 &transition_expected
7511 } else {
7512 expected_symbols
7513 });
7514 let mut token_symbols = BTreeSet::new();
7515 token_symbols.insert(token_type);
7516 let missing_token_display = self.expected_symbols_display(&token_symbols);
7517 let current = self.token_at(index);
7518 let message = format!(
7519 "missing {expected_display} at {}",
7520 current
7521 .as_ref()
7522 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7523 );
7524 let text = format!("<missing {missing_token_display}>");
7525 Some((
7526 diagnostic_for_token(current.as_ref(), message),
7527 token_type,
7528 text,
7529 ))
7530 }
7531
7532 fn fast_single_token_deletion_recovery(
7536 &mut self,
7537 recovery: FastRecoveryRequest<'_, '_>,
7538 predicate_context: Option<FastPredicateContext<'_>>,
7539 ) -> Vec<FastRecognizeOutcome> {
7540 let FastRecoveryRequest {
7541 atn,
7542 transition,
7543 expected_symbols,
7544 target,
7545 request,
7546 visiting,
7547 memo,
7548 expected,
7549 } = recovery;
7550 let FastRecognizeRequest {
7551 stop_state,
7552 index,
7553 rule_start_index,
7554 decision_start_index,
7555 precedence,
7556 depth,
7557 ..
7558 } = request;
7559 let Some((diagnostic, next_index, next_symbol)) =
7560 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
7561 else {
7562 return Vec::new();
7563 };
7564 let after_next = self.consume_index(next_index, next_symbol);
7565 let empty_recovery = self.empty_recovery_symbols();
7566 self.recognize_state_fast(
7567 atn,
7568 FastRecognizeRequest {
7569 state_number: target,
7570 stop_state,
7571 index: after_next,
7572 rule_start_index,
7573 decision_start_index,
7574 precedence,
7575 depth: depth + 1,
7576 recovery_symbols: empty_recovery,
7577 recovery_state: None,
7578 },
7579 FastRecognizeScratch {
7580 predicate_context,
7581 visiting,
7582 memo,
7583 expected,
7584 },
7585 )
7586 .into_iter()
7587 .map(|mut outcome| {
7588 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
7589 outcome.diagnostics = self
7590 .recognition_arena
7591 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7592 if self.fast_token_nodes_enabled {
7593 let token = self.arena_token_node(next_index, false);
7594 self.defer_fast_outcome_node(&mut outcome, token);
7595 let error = self.arena_token_node(index, true);
7596 self.defer_fast_outcome_node(&mut outcome, error);
7597 }
7598 outcome
7599 })
7600 .collect()
7601 }
7602
7603 fn fast_single_token_insertion_recovery(
7607 &mut self,
7608 recovery: FastRecoveryRequest<'_, '_>,
7609 predicate_context: Option<FastPredicateContext<'_>>,
7610 ) -> Vec<FastRecognizeOutcome> {
7611 let FastRecoveryRequest {
7612 atn,
7613 transition,
7614 expected_symbols,
7615 target,
7616 request,
7617 visiting,
7618 memo,
7619 expected,
7620 } = recovery;
7621 let FastRecognizeRequest {
7622 stop_state,
7623 index,
7624 rule_start_index,
7625 decision_start_index,
7626 precedence,
7627 depth,
7628 ..
7629 } = request;
7630 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
7631 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
7632 transition,
7633 index,
7634 atn.max_token_type(),
7635 &expected_symbols,
7636 &follow_symbols,
7637 ) else {
7638 return Vec::new();
7639 };
7640 let empty_recovery = self.empty_recovery_symbols();
7641 self.recognize_state_fast(
7642 atn,
7643 FastRecognizeRequest {
7644 state_number: target,
7645 stop_state,
7646 index,
7647 rule_start_index,
7648 decision_start_index,
7649 precedence,
7650 depth: depth + 1,
7651 recovery_symbols: empty_recovery,
7652 recovery_state: None,
7653 },
7654 FastRecognizeScratch {
7655 predicate_context,
7656 visiting,
7657 memo,
7658 expected,
7659 },
7660 )
7661 .into_iter()
7662 .map(|mut outcome| {
7663 outcome.diagnostics = self
7664 .recognition_arena
7665 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7666 let missing = self.arena_missing_token_node(token_type, index, text.clone());
7667 self.defer_fast_outcome_node(&mut outcome, missing);
7668 outcome
7669 })
7670 .collect()
7671 }
7672
7673 fn fast_current_token_deletion_recovery(
7676 &mut self,
7677 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
7678 predicate_context: Option<FastPredicateContext<'_>>,
7679 ) -> Vec<FastRecognizeOutcome> {
7680 let FastCurrentTokenDeletionRequest {
7681 atn,
7682 expected_symbols,
7683 mut request,
7684 visiting,
7685 memo,
7686 expected,
7687 } = recovery;
7688 if request.index == request.rule_start_index {
7689 return Vec::new();
7690 }
7691 let Some((diagnostic, next_index, skipped)) =
7692 self.current_token_deletion(request.index, &expected_symbols)
7693 else {
7694 return Vec::new();
7695 };
7696 request.state_number = request.recovery_state.unwrap_or(request.state_number);
7697 request.index = next_index;
7698 request.depth += 1;
7699 request.recovery_state = None;
7700 self.recognize_state_fast(
7701 atn,
7702 request,
7703 FastRecognizeScratch {
7704 predicate_context,
7705 visiting,
7706 memo,
7707 expected,
7708 },
7709 )
7710 .into_iter()
7711 .map(|mut outcome| {
7712 outcome.diagnostics = self
7713 .recognition_arena
7714 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7715 for index in skipped.iter().rev() {
7716 let error = self.arena_token_node(*index, true);
7717 self.defer_fast_outcome_node(&mut outcome, error);
7718 }
7719 outcome
7720 })
7721 .collect()
7722 }
7723
7724 fn fast_child_rule_failure_recovery(
7727 &mut self,
7728 rule_index: usize,
7729 start_index: usize,
7730 sync_symbols: &BTreeSet<i32>,
7731 expected: &ExpectedTokens,
7732 ) -> Option<FastRecognizeOutcome> {
7733 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7734 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7735 let mut next_index = error_index;
7736 loop {
7737 let symbol = self.token_type_at(next_index);
7738 if sync_symbols.contains(&symbol) {
7739 if next_index == error_index {
7740 return None;
7741 }
7742 break;
7743 }
7744 if symbol == TOKEN_EOF {
7745 break;
7746 }
7747 let after = self.consume_index(next_index, symbol);
7748 if after == next_index {
7749 break;
7750 }
7751 next_index = after;
7752 }
7753 let diagnostics = self
7754 .recognition_arena
7755 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7756 let mut nodes = NodeSeqId::EMPTY;
7757 if self.fast_token_nodes_enabled {
7758 let error = self.arena_token_node(error_index, true);
7759 self.arena_prepend(&mut nodes, error);
7760 }
7761 Some(FastRecognizeOutcome {
7762 index: next_index,
7763 consumed_eof: false,
7764 diagnostics,
7765 deferred_nodes: FastDeferredNodeId::EMPTY,
7766 nodes,
7767 })
7768 }
7769
7770 fn fast_child_rule_failure_recovery_outcomes(
7773 &mut self,
7774 request: FastChildRuleFailureRecoveryRequest<'_>,
7775 ) -> Vec<FastRecognizeOutcome> {
7776 let FastChildRuleFailureRecoveryRequest {
7777 atn,
7778 rule_index,
7779 start_index,
7780 follow_state,
7781 stop_state,
7782 expected,
7783 } = request;
7784 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
7785 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
7786 .into_iter()
7787 .collect()
7788 }
7789
7790 fn defer_fast_outcome_node(
7791 &mut self,
7792 outcome: &mut FastRecognizeOutcome,
7793 node: RecognizedNodeId,
7794 ) {
7795 if outcome.deferred_nodes.is_empty() {
7796 self.arena_prepend(&mut outcome.nodes, node);
7797 return;
7798 }
7799 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
7800 let fragment = self.recognition_arena.deferred_fragment(fragment);
7801 outcome.deferred_nodes = self
7802 .recognition_arena
7803 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
7804 }
7805
7806 fn materialize_fast_deferred_nodes(
7807 &mut self,
7808 root: FastDeferredNodeId,
7809 initial_suffix: NodeSeqId,
7810 ) -> NodeSeqId {
7811 if root.is_empty() {
7812 return initial_suffix;
7813 }
7814
7815 enum Frame {
7816 Visit(FastDeferredNodeId),
7817 ContinuePrefix(FastDeferredNodeId),
7818 FinishRule {
7819 rule: FastDeferredRule,
7820 parent_suffix: NodeSeqId,
7821 },
7822 }
7823
7824 let mut result = initial_suffix;
7825 let mut pending = Vec::with_capacity(16);
7826 pending.push(Frame::Visit(root));
7827 let mut fragment_nodes = Vec::new();
7828 while let Some(frame) = pending.pop() {
7829 match frame {
7830 Frame::Visit(deferred) => {
7831 if deferred.is_empty() {
7832 continue;
7833 }
7834
7835 match self.recognition_arena.deferred_node(deferred) {
7836 FastDeferredNode::Fragment(sequence) => {
7837 fragment_nodes.clear();
7838 fragment_nodes.extend(self.recognition_arena.iter(sequence));
7839 while let Some(node) = fragment_nodes.pop() {
7840 self.arena_prepend(&mut result, node);
7841 }
7842 }
7843 FastDeferredNode::Rule(rule) => {
7844 let rule = self.recognition_arena.deferred_rule(rule);
7845 let parent_suffix = result;
7846 result = rule.children;
7847 pending.push(Frame::FinishRule {
7848 rule,
7849 parent_suffix,
7850 });
7851 pending.push(Frame::Visit(rule.deferred_children));
7852 }
7853 FastDeferredNode::Concat {
7854 prefix,
7855 suffix: deferred_suffix,
7856 } => {
7857 pending.push(Frame::ContinuePrefix(prefix));
7858 pending.push(Frame::Visit(deferred_suffix));
7859 }
7860 }
7861 }
7862 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
7863 Frame::FinishRule {
7864 rule,
7865 parent_suffix,
7866 } => {
7867 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
7868 rule_index: rule.rule_index,
7869 invoking_state: rule.invoking_state,
7870 alt_number: 0,
7871 start_index: rule.start_index,
7872 stop_index: rule.stop_index,
7873 return_values: None,
7874 children: result,
7875 });
7876 result = parent_suffix;
7877 self.arena_prepend(&mut result, node);
7878 }
7879 }
7880 }
7881 result
7882 }
7883
7884 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) {
7885 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
7886 outcome.nodes = self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
7887 }
7888
7889 fn recognize_repetition_fast(
7892 &mut self,
7893 atn: &Atn,
7894 request: &FastRecognizeRequest,
7895 shape: FastRepetitionShape,
7896 scratch: FastRecognizeScratch<'_, '_>,
7897 ) -> Vec<FastRecognizeOutcome> {
7898 let FastRecognizeScratch {
7899 predicate_context,
7900 visiting,
7901 memo,
7902 expected,
7903 } = scratch;
7904 let lookahead = if self.fast_first_set_prefilter {
7905 atn.state(request.state_number).and_then(|state| {
7906 state
7907 .rule_index()
7908 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
7909 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
7910 })
7911 } else {
7912 None
7913 };
7914 let mut work = Vec::with_capacity(2);
7915 push_fast_repetition_work(
7916 &mut work,
7917 shape,
7918 FastRepetitionPath {
7919 index: request.index,
7920 deferred_nodes: FastDeferredNodeId::EMPTY,
7921 diagnostics: DiagnosticSeqId::EMPTY,
7922 consumed_eof: false,
7923 },
7924 lookahead.as_deref(),
7925 self.token_type_at(request.index),
7926 );
7927 let mut coordinates = FastRepetitionCoordinates::new(request.index);
7928 let mut outcomes = Vec::new();
7929 while let Some(item) = work.pop() {
7930 match item {
7931 FastRepetitionWork::Enter(path) => {
7932 if !coordinates.insert_entered(path) {
7933 continue;
7934 }
7935 let body_outcomes = self.recognize_state_fast(
7936 atn,
7937 FastRecognizeRequest {
7938 state_number: shape.enter_target,
7939 stop_state: shape.body_stop_state,
7940 index: path.index,
7941 rule_start_index: request.rule_start_index,
7942 decision_start_index: request.decision_start_index,
7943 precedence: request.precedence,
7944 depth: request.depth.saturating_add(1),
7945 recovery_symbols: Rc::clone(&request.recovery_symbols),
7946 recovery_state: request.recovery_state,
7947 },
7948 FastRecognizeScratch {
7949 predicate_context,
7950 visiting: &mut *visiting,
7951 memo: &mut *memo,
7952 expected: &mut *expected,
7953 },
7954 );
7955 for body in body_outcomes.into_iter().rev() {
7956 if body.index <= path.index {
7960 continue;
7961 }
7962 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
7963 let body_nodes = self
7964 .recognition_arena
7965 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
7966 let deferred_nodes = self
7967 .recognition_arena
7968 .concat_deferred_nodes(path.deferred_nodes, body_nodes);
7969 let next_path = FastRepetitionPath {
7970 index: body.index,
7971 deferred_nodes,
7972 diagnostics: self
7973 .recognition_arena
7974 .concat_diagnostics(path.diagnostics, body.diagnostics),
7975 consumed_eof: path.consumed_eof || body.consumed_eof,
7976 };
7977 let symbol = self.token_type_at(next_path.index);
7978 push_fast_repetition_work(
7979 &mut work,
7980 shape,
7981 next_path,
7982 lookahead.as_deref(),
7983 symbol,
7984 );
7985 }
7986 }
7987 FastRepetitionWork::Exit(path) => {
7988 if !coordinates.insert_exited(path) {
7989 continue;
7990 }
7991 let suffixes = self.recognize_state_fast(
7992 atn,
7993 FastRecognizeRequest {
7994 state_number: shape.exit_target,
7995 stop_state: request.stop_state,
7996 index: path.index,
7997 rule_start_index: request.rule_start_index,
7998 decision_start_index: request.decision_start_index,
7999 precedence: request.precedence,
8000 depth: request.depth.saturating_add(1),
8001 recovery_symbols: Rc::clone(&request.recovery_symbols),
8002 recovery_state: request.recovery_state,
8003 },
8004 FastRecognizeScratch {
8005 predicate_context,
8006 visiting: &mut *visiting,
8007 memo: &mut *memo,
8008 expected: &mut *expected,
8009 },
8010 );
8011 for mut outcome in suffixes {
8012 outcome.deferred_nodes = self
8013 .recognition_arena
8014 .concat_deferred_nodes(path.deferred_nodes, outcome.deferred_nodes);
8015 outcome.diagnostics = self
8016 .recognition_arena
8017 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
8018 outcome.consumed_eof |= path.consumed_eof;
8019 outcomes.push(outcome);
8020 }
8021 }
8022 }
8023 }
8024 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8025 outcomes
8026 }
8027
8028 #[allow(clippy::too_many_lines)]
8031 fn recognize_state_fast(
8032 &mut self,
8033 atn: &Atn,
8034 request: FastRecognizeRequest,
8035 scratch: FastRecognizeScratch<'_, '_>,
8036 ) -> Vec<FastRecognizeOutcome> {
8037 #[cfg(feature = "perf-counters")]
8038 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
8039 let FastRecognizeScratch {
8040 predicate_context,
8041 visiting,
8042 memo,
8043 expected,
8044 } = scratch;
8045 let FastRecognizeRequest {
8046 mut state_number,
8047 stop_state,
8048 mut index,
8049 rule_start_index,
8050 decision_start_index,
8051 precedence,
8052 mut depth,
8053 recovery_symbols,
8054 recovery_state,
8055 } = request;
8056 let max_token_type = atn.max_token_type();
8057 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
8076 let mut inline_consumed_eof = false;
8077 loop {
8078 if depth > RECOGNITION_DEPTH_LIMIT {
8079 return Vec::new();
8080 }
8081 if state_number == stop_state {
8082 let mut nodes = NodeSeqId::EMPTY;
8083 if self.fast_token_nodes_enabled {
8084 for token_index in inline_consumed_tokens.iter().rev() {
8085 let token = self.arena_token_node(*token_index, false);
8086 self.arena_prepend(&mut nodes, token);
8087 }
8088 }
8089 return vec![FastRecognizeOutcome {
8090 index,
8091 consumed_eof: inline_consumed_eof,
8092 diagnostics: DiagnosticSeqId::EMPTY,
8093 deferred_nodes: FastDeferredNodeId::EMPTY,
8094 nodes,
8095 }];
8096 }
8097 let Some(state) = atn.state(state_number) else {
8098 return Vec::new();
8099 };
8100 let transitions = state.transitions();
8101 if transitions.len() == 1 && !state.precedence_rule_decision() {
8102 let transition = transitions
8103 .first()
8104 .expect("single transition checked above");
8105 let transition_kind = transition.kind();
8106 let target = transition.target();
8107 match transition_kind {
8108 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
8109 if left_recursive_boundary(atn, state, target).is_none() =>
8110 {
8111 #[cfg(feature = "perf-counters")]
8112 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8113 state_number = target;
8114 depth += 1;
8115 continue;
8116 }
8117 ParserTransitionKind::Predicate
8118 if left_recursive_boundary(atn, state, target).is_none() =>
8119 {
8120 #[cfg(feature = "perf-counters")]
8121 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8122 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
8123 {
8124 record_predicate_no_viable(expected, decision_start_index, index);
8125 return Vec::new();
8126 }
8127 state_number = target;
8128 depth += 1;
8129 continue;
8130 }
8131 ParserTransitionKind::Precedence
8132 if packed_i32(transition.arg0()) >= precedence
8133 && left_recursive_boundary(atn, state, target).is_none() =>
8134 {
8135 #[cfg(feature = "perf-counters")]
8136 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8137 state_number = target;
8138 depth += 1;
8139 continue;
8140 }
8141 ParserTransitionKind::Atom
8151 | ParserTransitionKind::Range
8152 | ParserTransitionKind::Set
8153 | ParserTransitionKind::NotSet
8154 | ParserTransitionKind::Wildcard
8155 if !self.fast_recovery_enabled =>
8156 {
8157 let symbol = self.token_type_at(index);
8158 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
8159 #[cfg(feature = "perf-counters")]
8160 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
8161 if self.fast_token_nodes_enabled {
8162 inline_consumed_tokens.push(index);
8163 }
8164 inline_consumed_eof |= symbol == TOKEN_EOF;
8165 index = self.consume_index(index, symbol);
8166 state_number = target;
8167 depth += 1;
8168 continue;
8169 }
8170 }
8173 _ => {}
8174 }
8175 }
8176 break;
8177 }
8178 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
8182 let Some(state) = atn.state(state_number) else {
8183 return Vec::new();
8184 };
8185 let transitions = state.transitions();
8186 let transition_count = transitions.len();
8187 if !self.fast_recovery_enabled
8188 && let Some(shape) = fast_repetition_shape(atn, state)
8189 {
8190 let mut outcomes = self.recognize_repetition_fast(
8191 atn,
8192 &FastRecognizeRequest {
8193 state_number,
8194 stop_state,
8195 index,
8196 rule_start_index,
8197 decision_start_index,
8198 precedence,
8199 depth,
8200 recovery_symbols: Rc::clone(&recovery_symbols),
8201 recovery_state,
8202 },
8203 shape,
8204 FastRecognizeScratch {
8205 predicate_context,
8206 visiting: &mut *visiting,
8207 memo: &mut *memo,
8208 expected: &mut *expected,
8209 },
8210 );
8211 if inline_pending {
8212 for outcome in &mut outcomes {
8213 outcome.consumed_eof |= inline_consumed_eof;
8214 if self.fast_token_nodes_enabled {
8215 for token_index in inline_consumed_tokens.iter().rev() {
8216 let token = self.arena_token_node(*token_index, false);
8217 self.defer_fast_outcome_node(outcome, token);
8218 }
8219 }
8220 }
8221 }
8222 return outcomes;
8223 }
8224 let key = if self.fast_recovery_enabled {
8234 FastRecognizeKey {
8235 state_number,
8236 stop_state,
8237 index,
8238 rule_start_index,
8239 decision_start_index,
8240 precedence,
8241 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
8242 recovery_state,
8243 }
8244 } else {
8245 FastRecognizeKey {
8246 state_number,
8247 stop_state,
8248 index,
8249 rule_start_index: 0,
8250 decision_start_index: None,
8251 precedence,
8252 recovery_symbols_id: 0,
8253 recovery_state: None,
8254 }
8255 };
8256 let memo_lookup_enabled = self.fast_recovery_enabled
8261 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
8262 if memo_lookup_enabled {
8263 if let Some(outcomes) = memo.get(&key) {
8264 #[cfg(feature = "perf-counters")]
8265 {
8266 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
8267 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
8268 }
8269 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
8273 let inline_eof = inline_consumed_eof;
8274 let inline_tokens = &inline_consumed_tokens;
8275 return outcomes
8276 .iter()
8277 .copied()
8278 .map(|mut outcome| {
8279 if inline_eof {
8280 outcome.consumed_eof = true;
8281 }
8282 if self.fast_token_nodes_enabled {
8283 for token_index in inline_tokens.iter().rev() {
8284 let token = self.arena_token_node(*token_index, false);
8285 self.defer_fast_outcome_node(&mut outcome, token);
8286 }
8287 }
8288 outcome
8289 })
8290 .collect();
8291 }
8292 return outcomes.to_vec();
8293 }
8294 #[cfg(feature = "perf-counters")]
8295 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
8296 }
8297
8298 let needs_cycle_guard = if self.fast_recovery_enabled {
8303 transitions.iter().any(ParserTransition::is_epsilon)
8304 } else {
8305 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
8306 };
8307 #[cfg(feature = "perf-counters")]
8308 if needs_cycle_guard {
8309 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
8310 } else {
8311 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
8312 match state
8313 .transitions()
8314 .first()
8315 .expect("single-transition path requires one transition")
8316 .data()
8317 {
8318 Transition::Rule { .. } => {
8319 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
8320 }
8321 Transition::Atom { .. }
8322 | Transition::Range { .. }
8323 | Transition::Set { .. }
8324 | Transition::NotSet { .. }
8325 | Transition::Wildcard { .. } => {
8326 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
8327 }
8328 _ => {
8329 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
8330 }
8331 }
8332 }
8333 let has_inserted_cycle_guard = if needs_cycle_guard {
8334 if !visiting.insert(key.clone()) {
8335 #[cfg(feature = "perf-counters")]
8336 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
8337 return Vec::new();
8338 }
8339 true
8340 } else {
8341 false
8342 };
8343 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
8344 Some(index)
8345 } else {
8346 decision_start_index
8347 };
8348 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
8349 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
8350 } else {
8351 (Rc::clone(&recovery_symbols), recovery_state)
8352 };
8353
8354 let lookahead_filter = if transition_count > 1
8373 && self.fast_first_set_prefilter
8374 && !state.precedence_rule_decision()
8375 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
8376 {
8377 state
8378 .rule_index()
8379 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8380 .map(|rule_stop| {
8381 let symbol = self.token_type_at(index);
8382 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
8383 (symbol, entry)
8384 })
8385 } else {
8386 None
8387 };
8388 let ll1_only_alt: Option<usize> = if transition_count > 1
8397 && let Some((symbol, entry)) = lookahead_filter.as_ref()
8398 {
8399 let key = (state.state_number(), *symbol);
8400 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
8401 cached
8402 } else {
8403 let result = ll1_unique_alt(entry, *symbol);
8404 self.ll1_decision_cache.insert(key, result);
8405 result
8406 }
8407 } else {
8408 None
8409 };
8410 let lookahead_filter = lookahead_filter.as_ref();
8411 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
8417 for (transition_index, transition) in transitions.iter().enumerate() {
8418 if let Some(alt) = ll1_only_alt {
8419 if alt != transition_index {
8421 continue;
8422 }
8423 }
8424 let transition_kind = transition.kind();
8425 if ll1_only_alt.is_none()
8426 && should_skip_via_lookahead(
8427 transition_kind,
8428 transition_index,
8429 lookahead_filter,
8430 index,
8431 self.fast_recovery_enabled,
8432 expected,
8433 )
8434 {
8435 continue;
8436 }
8437 let target = transition.target();
8438 match transition_kind {
8439 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
8440 #[cfg(feature = "perf-counters")]
8441 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8442 let boundary = left_recursive_boundary(atn, state, target);
8443 outcomes.extend(
8444 self.recognize_state_fast(
8445 atn,
8446 FastRecognizeRequest {
8447 state_number: target,
8448 stop_state,
8449 index,
8450 rule_start_index,
8451 decision_start_index: next_decision_start_index,
8452 precedence,
8453 depth: depth + 1,
8454 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8455 recovery_state: epsilon_recovery_state,
8456 },
8457 FastRecognizeScratch {
8458 predicate_context,
8459 visiting,
8460 memo,
8461 expected,
8462 },
8463 )
8464 .into_iter()
8465 .map(|mut outcome| {
8466 if let Some(rule_index) = boundary {
8467 let boundary = self.arena_boundary_node(rule_index);
8468 self.defer_fast_outcome_node(&mut outcome, boundary);
8469 }
8470 outcome
8471 }),
8472 );
8473 }
8474 ParserTransitionKind::Predicate => {
8475 #[cfg(feature = "perf-counters")]
8476 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8477 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
8478 let boundary = left_recursive_boundary(atn, state, target);
8479 outcomes.extend(
8480 self.recognize_state_fast(
8481 atn,
8482 FastRecognizeRequest {
8483 state_number: target,
8484 stop_state,
8485 index,
8486 rule_start_index,
8487 decision_start_index: next_decision_start_index,
8488 precedence,
8489 depth: depth + 1,
8490 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8491 recovery_state: epsilon_recovery_state,
8492 },
8493 FastRecognizeScratch {
8494 predicate_context,
8495 visiting,
8496 memo,
8497 expected,
8498 },
8499 )
8500 .into_iter()
8501 .map(|mut outcome| {
8502 if let Some(rule_index) = boundary {
8503 let boundary = self.arena_boundary_node(rule_index);
8504 self.defer_fast_outcome_node(&mut outcome, boundary);
8505 }
8506 outcome
8507 }),
8508 );
8509 } else {
8510 record_predicate_no_viable(expected, next_decision_start_index, index);
8511 }
8512 }
8513 ParserTransitionKind::Precedence => {
8514 let transition_precedence = packed_i32(transition.arg0());
8515 if transition_precedence >= precedence {
8516 let boundary = left_recursive_boundary(atn, state, target);
8517 outcomes.extend(
8518 self.recognize_state_fast(
8519 atn,
8520 FastRecognizeRequest {
8521 state_number: target,
8522 stop_state,
8523 index,
8524 rule_start_index,
8525 decision_start_index: next_decision_start_index,
8526 precedence,
8527 depth: depth + 1,
8528 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8529 recovery_state: epsilon_recovery_state,
8530 },
8531 FastRecognizeScratch {
8532 predicate_context,
8533 visiting,
8534 memo,
8535 expected,
8536 },
8537 )
8538 .into_iter()
8539 .map(|mut outcome| {
8540 if let Some(rule_index) = boundary {
8541 let boundary = self.arena_boundary_node(rule_index);
8542 self.defer_fast_outcome_node(&mut outcome, boundary);
8543 }
8544 outcome
8545 }),
8546 );
8547 }
8548 }
8549 ParserTransitionKind::Rule => {
8550 let rule_index = transition.arg0() as usize;
8551 let follow_state = transition.arg1() as usize;
8552 let rule_precedence = packed_i32(transition.arg2());
8553 #[cfg(feature = "perf-counters")]
8554 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
8555 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
8556 continue;
8557 };
8558 let symbol = self.token_type_at(index);
8570 if self.fast_first_set_prefilter {
8571 let first = self.cached_rule_first_set(atn, target, child_stop);
8584 if should_skip_rule_via_first_set(
8585 &first,
8586 symbol,
8587 self.fast_recovery_enabled,
8588 index,
8589 expected,
8590 ) {
8591 continue;
8592 }
8593 }
8594 let expected_before_child =
8595 self.fast_recovery_enabled.then(|| expected.clone());
8596 let mut children = self.recognize_state_fast(
8597 atn,
8598 FastRecognizeRequest {
8599 state_number: target,
8600 stop_state: child_stop,
8601 index,
8602 rule_start_index: index,
8603 decision_start_index: None,
8604 precedence: rule_precedence,
8605 depth: depth + 1,
8606 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8607 recovery_state: epsilon_recovery_state,
8608 },
8609 FastRecognizeScratch {
8610 predicate_context,
8611 visiting,
8612 memo,
8613 expected,
8614 },
8615 );
8616 if children.is_empty() && self.fast_recovery_enabled {
8617 children = self.fast_child_rule_failure_recovery_outcomes(
8618 FastChildRuleFailureRecoveryRequest {
8619 atn,
8620 rule_index,
8621 start_index: index,
8622 follow_state,
8623 stop_state,
8624 expected,
8625 },
8626 );
8627 }
8628 if let Some(expected_before_child) = expected_before_child {
8629 if children
8630 .iter()
8631 .any(|child| child.diagnostics.is_empty() && child.index > index)
8632 {
8633 *expected = expected_before_child;
8634 }
8635 }
8636 for child in children {
8637 let child_index = child.index;
8638 let child_consumed_eof = child.consumed_eof;
8639 let child_diagnostics = child.diagnostics;
8640 let empty_recovery = self.empty_recovery_symbols();
8641 let follow_outcomes = self.recognize_state_fast(
8642 atn,
8643 FastRecognizeRequest {
8644 state_number: follow_state,
8645 stop_state,
8646 index: child_index,
8647 rule_start_index,
8648 decision_start_index: next_decision_start_index,
8649 precedence,
8650 depth: depth + 1,
8651 recovery_symbols: empty_recovery,
8652 recovery_state: None,
8653 },
8654 FastRecognizeScratch {
8655 predicate_context,
8656 visiting,
8657 memo,
8658 expected,
8659 },
8660 );
8661 if follow_outcomes.is_empty() {
8662 continue;
8663 }
8664 let child_stop_index =
8665 self.rule_stop_token_index(child_index, child_consumed_eof);
8666 let child_node = self.build_parse_trees.then(|| {
8667 self.recognition_arena.deferred_rule_node(FastDeferredRule {
8668 rule_index: u32::try_from(rule_index)
8669 .expect("rule index fits in u32"),
8670 invoking_state: i32::try_from(invoking_state_number(state_number))
8671 .expect("invoking state fits in i32"),
8672 start_index: u32::try_from(index)
8673 .expect("rule start index fits in u32"),
8674 stop_index: child_stop_index.map(|stop_index| {
8675 u32::try_from(stop_index).expect("rule stop index fits in u32")
8676 }),
8677 deferred_children: child.deferred_nodes,
8678 children: child.nodes,
8679 })
8680 });
8681 let child_diags_empty = child_diagnostics.is_empty();
8682 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
8683 outcome.consumed_eof |= child_consumed_eof;
8684 if !child_diags_empty {
8687 outcome.diagnostics = self
8688 .recognition_arena
8689 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
8690 }
8691 if let Some(child_node) = child_node {
8692 outcome.deferred_nodes = self
8693 .recognition_arena
8694 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
8695 }
8696 outcome
8697 }));
8698 }
8699 }
8700 ParserTransitionKind::Atom
8701 | ParserTransitionKind::Range
8702 | ParserTransitionKind::Set
8703 | ParserTransitionKind::NotSet
8704 | ParserTransitionKind::Wildcard => {
8705 #[cfg(feature = "perf-counters")]
8706 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
8707 let symbol = self.token_type_at(index);
8708 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
8709 let next_index = self.consume_index(index, symbol);
8710 let empty_recovery = self.empty_recovery_symbols();
8711 outcomes.extend(
8712 self.recognize_state_fast(
8713 atn,
8714 FastRecognizeRequest {
8715 state_number: target,
8716 stop_state,
8717 index: next_index,
8718 rule_start_index,
8719 decision_start_index: next_decision_start_index,
8720 precedence,
8721 depth: depth + 1,
8722 recovery_symbols: empty_recovery,
8723 recovery_state: None,
8724 },
8725 FastRecognizeScratch {
8726 predicate_context,
8727 visiting,
8728 memo,
8729 expected,
8730 },
8731 )
8732 .into_iter()
8733 .map(|mut outcome| {
8734 outcome.consumed_eof |= symbol == TOKEN_EOF;
8735 if self.fast_token_nodes_enabled {
8736 let token = self.arena_token_node(index, false);
8737 self.defer_fast_outcome_node(&mut outcome, token);
8738 }
8739 outcome
8740 }),
8741 );
8742 } else {
8743 if !self.fast_recovery_enabled {
8744 continue;
8752 }
8753 let expected_symbols = fast_recovery_expected_symbols(
8754 self,
8755 atn,
8756 state.state_number(),
8757 &recovery_symbols,
8758 );
8759 if expected_symbols.contains(&symbol) {
8760 continue;
8761 }
8762 {
8763 expected.record_transition(index, transition, max_token_type);
8764 record_no_viable_if_ambiguous(
8765 expected,
8766 next_decision_start_index,
8767 index,
8768 );
8769 outcomes.extend(self.fast_single_token_deletion_recovery(
8770 FastRecoveryRequest {
8771 atn,
8772 transition,
8773 expected_symbols: Rc::clone(&expected_symbols),
8774 target,
8775 request: FastRecognizeRequest {
8776 state_number,
8777 stop_state,
8778 index,
8779 rule_start_index,
8780 decision_start_index,
8781 precedence,
8782 depth,
8783 recovery_symbols: Rc::clone(&recovery_symbols),
8784 recovery_state,
8785 },
8786 visiting,
8787 memo,
8788 expected,
8789 },
8790 predicate_context,
8791 ));
8792 if !state_is_left_recursive_rule(atn, state) {
8793 outcomes.extend(self.fast_single_token_insertion_recovery(
8794 FastRecoveryRequest {
8795 atn,
8796 transition,
8797 expected_symbols: Rc::clone(&expected_symbols),
8798 target,
8799 request: FastRecognizeRequest {
8800 state_number,
8801 stop_state,
8802 index,
8803 rule_start_index,
8804 decision_start_index,
8805 precedence,
8806 depth,
8807 recovery_symbols: Rc::clone(&recovery_symbols),
8808 recovery_state,
8809 },
8810 visiting,
8811 memo,
8812 expected,
8813 },
8814 predicate_context,
8815 ));
8816 }
8817 outcomes.extend(self.fast_current_token_deletion_recovery(
8818 FastCurrentTokenDeletionRequest {
8819 atn,
8820 expected_symbols,
8821 request: FastRecognizeRequest {
8822 state_number,
8823 stop_state,
8824 index,
8825 rule_start_index,
8826 decision_start_index,
8827 precedence,
8828 depth,
8829 recovery_symbols: Rc::clone(&recovery_symbols),
8830 recovery_state,
8831 },
8832 visiting,
8833 memo,
8834 expected,
8835 },
8836 predicate_context,
8837 ));
8838 }
8839 }
8840 }
8841 }
8842 }
8843
8844 if has_inserted_cycle_guard {
8845 visiting.remove(&key);
8846 }
8847 if matches!(
8848 self.prediction_mode,
8849 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
8850 ) && self.fast_recovery_enabled
8851 {
8852 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
8856 }
8857 if self.fast_recovery_enabled {
8858 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
8859 } else {
8860 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8861 }
8862 let should_memoize = self.fast_recovery_enabled
8872 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
8873 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
8877 if inline_consumed_eof {
8878 outcome.consumed_eof = true;
8879 }
8880 if !inline_consumed_tokens.is_empty() {
8881 for token_index in inline_consumed_tokens.iter().rev() {
8882 let token = self.arena_token_node(*token_index, false);
8883 self.defer_fast_outcome_node(&mut outcome, token);
8884 }
8885 }
8886 outcome
8887 };
8888 if should_memoize {
8889 #[cfg(feature = "perf-counters")]
8890 {
8891 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
8892 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
8893 match outcomes.len() {
8894 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
8895 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
8896 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
8897 }
8898 }
8899 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
8904 memo.insert(key, Rc::clone(&stored));
8905 if inline_pending {
8906 return stored
8907 .iter()
8908 .copied()
8909 .map(&mut apply_inline_pending)
8910 .collect();
8911 }
8912 return stored.to_vec();
8913 }
8914 #[cfg(feature = "perf-counters")]
8915 match outcomes.len() {
8916 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
8917 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
8918 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
8919 }
8920 if inline_pending {
8921 return outcomes.into_iter().map(apply_inline_pending).collect();
8922 }
8923 outcomes
8924 }
8925
8926 fn single_token_deletion_recovery(
8929 &mut self,
8930 recovery: RecoveryRequest<'_, '_>,
8931 ) -> Vec<RecognizeOutcome> {
8932 let RecoveryRequest {
8933 atn,
8934 transition,
8935 expected_symbols,
8936 target,
8937 request,
8938 visiting,
8939 memo,
8940 expected,
8941 } = recovery;
8942 let RecognizeRequest {
8943 stop_state,
8944 index,
8945 rule_start_index,
8946 decision_start_index,
8947 init_action_rules,
8948 predicates,
8949 semantics,
8950 rule_args,
8951 member_actions,
8952 return_actions,
8953 local_int_arg,
8954 member_values,
8955 return_values,
8956 rule_alt_number,
8957 track_alt_numbers,
8958 consumed_eof,
8959 precedence,
8960 depth,
8961 ..
8962 } = request;
8963 let Some((diagnostic, next_index, next_symbol)) =
8964 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
8965 else {
8966 return Vec::new();
8967 };
8968 let after_next = self.consume_index(next_index, next_symbol);
8969 self.recognize_state(
8970 atn,
8971 RecognizeRequest {
8972 state_number: target,
8973 stop_state,
8974 index: after_next,
8975 rule_start_index,
8976 decision_start_index,
8977 init_action_rules,
8978 predicates,
8979 semantics,
8980 rule_args,
8981 member_actions,
8982 return_actions,
8983 local_int_arg,
8984 member_values,
8985 return_values,
8986 rule_alt_number,
8987 track_alt_numbers,
8988 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
8989 precedence,
8990 depth: depth + 1,
8991 recovery_symbols: BTreeSet::new(),
8992 recovery_state: None,
8993 },
8994 visiting,
8995 memo,
8996 expected,
8997 )
8998 .into_iter()
8999 .map(|mut outcome| {
9000 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
9001 outcome.diagnostics = self
9002 .recognition_arena
9003 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9004 let token = self.arena_token_node(next_index, false);
9005 self.arena_prepend(&mut outcome.nodes, token);
9006 let error = self.arena_token_node(index, true);
9007 self.arena_prepend(&mut outcome.nodes, error);
9008 outcome
9009 })
9010 .collect()
9011 }
9012
9013 fn current_token_deletion_recovery(
9016 &mut self,
9017 recovery: CurrentTokenDeletionRequest<'_, '_>,
9018 ) -> Vec<RecognizeOutcome> {
9019 let CurrentTokenDeletionRequest {
9020 atn,
9021 expected_symbols,
9022 mut request,
9023 visiting,
9024 memo,
9025 expected,
9026 } = recovery;
9027 let error_index = request.index;
9028 if error_index == request.rule_start_index {
9029 return Vec::new();
9030 }
9031 let Some((diagnostic, next_index, skipped)) =
9032 self.current_token_deletion(error_index, &expected_symbols)
9033 else {
9034 return Vec::new();
9035 };
9036 request.state_number = request.recovery_state.unwrap_or(request.state_number);
9037 request.index = next_index;
9038 request.depth += 1;
9039 request.recovery_state = None;
9040 self.recognize_state(atn, request, visiting, memo, expected)
9041 .into_iter()
9042 .map(|mut outcome| {
9043 outcome.diagnostics = self
9044 .recognition_arena
9045 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9046 for index in skipped.iter().rev() {
9047 let error = self.arena_token_node(*index, true);
9048 self.arena_prepend(&mut outcome.nodes, error);
9049 }
9050 outcome
9051 })
9052 .collect()
9053 }
9054
9055 fn consuming_failure_fallback(
9058 &mut self,
9059 fallback: ConsumingFailureFallback<'_>,
9060 visiting: &mut BTreeSet<RecognizeKey>,
9061 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9062 expected: &mut ExpectedTokens,
9063 ) -> Vec<RecognizeOutcome> {
9064 if fallback.expected_symbols.is_empty() {
9065 return Vec::new();
9066 }
9067 if fallback.symbol == TOKEN_EOF {
9068 return self.eof_consuming_failure_fallback(fallback, expected);
9069 }
9070 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
9071 }
9072
9073 fn non_eof_consuming_failure_fallback(
9076 &mut self,
9077 fallback: ConsumingFailureFallback<'_>,
9078 visiting: &mut BTreeSet<RecognizeKey>,
9079 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9080 expected: &mut ExpectedTokens,
9081 ) -> Vec<RecognizeOutcome> {
9082 let ConsumingFailureFallback {
9083 atn,
9084 target,
9085 request,
9086 symbol,
9087 expected_symbols,
9088 decision_start_index,
9089 decision,
9090 } = fallback;
9091 let error_index = request.index;
9092 let diagnostic =
9093 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
9094 let next_index = self.consume_index(error_index, symbol);
9095 self.recognize_state(
9096 atn,
9097 RecognizeRequest {
9098 state_number: target,
9099 stop_state: request.stop_state,
9100 index: next_index,
9101 rule_start_index: request.rule_start_index,
9102 decision_start_index,
9103 init_action_rules: request.init_action_rules,
9104 predicates: request.predicates,
9105 semantics: request.semantics,
9106 rule_args: request.rule_args,
9107 member_actions: request.member_actions,
9108 return_actions: request.return_actions,
9109 local_int_arg: request.local_int_arg,
9110 member_values: request.member_values,
9111 return_values: request.return_values,
9112 rule_alt_number: request.rule_alt_number,
9113 track_alt_numbers: request.track_alt_numbers,
9114 consumed_eof: request.consumed_eof,
9115 precedence: request.precedence,
9116 depth: request.depth + 1,
9117 recovery_symbols: BTreeSet::new(),
9118 recovery_state: None,
9119 },
9120 visiting,
9121 memo,
9122 expected,
9123 )
9124 .into_iter()
9125 .map(|mut outcome| {
9126 prepend_decision(&mut outcome, decision);
9127 outcome.diagnostics = self
9128 .recognition_arena
9129 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9130 let error = self.arena_token_node(error_index, true);
9131 self.arena_prepend(&mut outcome.nodes, error);
9132 outcome
9133 })
9134 .collect()
9135 }
9136
9137 fn eof_consuming_failure_fallback(
9140 &mut self,
9141 fallback: ConsumingFailureFallback<'_>,
9142 expected: &ExpectedTokens,
9143 ) -> Vec<RecognizeOutcome> {
9144 let request = fallback.request;
9145 if request.index == request.rule_start_index {
9146 return Vec::new();
9147 }
9148 let diagnostic =
9149 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
9150 let diagnostics = self
9151 .recognition_arena
9152 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
9153 vec![RecognizeOutcome {
9154 index: request.index,
9155 consumed_eof: request.consumed_eof,
9156 alt_number: request.rule_alt_number,
9157 member_values: request.member_values,
9158 return_values: request.return_values,
9159 diagnostics,
9160 decisions: Vec::new(),
9161 actions: Vec::new(),
9162 nodes: NodeSeqId::EMPTY,
9163 }]
9164 }
9165
9166 fn single_token_insertion_recovery(
9169 &mut self,
9170 recovery: RecoveryRequest<'_, '_>,
9171 ) -> Vec<RecognizeOutcome> {
9172 let RecoveryRequest {
9173 atn,
9174 transition,
9175 expected_symbols,
9176 target,
9177 request,
9178 visiting,
9179 memo,
9180 expected,
9181 } = recovery;
9182 let RecognizeRequest {
9183 stop_state,
9184 index,
9185 rule_start_index,
9186 decision_start_index,
9187 init_action_rules,
9188 predicates,
9189 semantics,
9190 rule_args,
9191 member_actions,
9192 return_actions,
9193 local_int_arg,
9194 member_values,
9195 return_values,
9196 rule_alt_number,
9197 track_alt_numbers,
9198 consumed_eof,
9199 precedence,
9200 depth,
9201 ..
9202 } = request;
9203 let follow_symbols = state_expected_symbols(atn, transition.target());
9204 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
9205 transition,
9206 index,
9207 atn.max_token_type(),
9208 &expected_symbols,
9209 &follow_symbols,
9210 ) else {
9211 return Vec::new();
9212 };
9213 self.recognize_state(
9214 atn,
9215 RecognizeRequest {
9216 state_number: target,
9217 stop_state,
9218 index,
9219 rule_start_index,
9220 decision_start_index,
9221 init_action_rules,
9222 predicates,
9223 semantics,
9224 rule_args,
9225 member_actions,
9226 return_actions,
9227 local_int_arg,
9228 member_values,
9229 return_values,
9230 rule_alt_number,
9231 track_alt_numbers,
9232 consumed_eof,
9233 precedence,
9234 depth: depth + 1,
9235 recovery_symbols: BTreeSet::new(),
9236 recovery_state: None,
9237 },
9238 visiting,
9239 memo,
9240 expected,
9241 )
9242 .into_iter()
9243 .map(|mut outcome| {
9244 outcome.diagnostics = self
9245 .recognition_arena
9246 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9247 let missing = self.arena_missing_token_node(token_type, index, text.clone());
9248 self.arena_prepend(&mut outcome.nodes, missing);
9249 outcome
9250 })
9251 .collect()
9252 }
9253
9254 #[allow(clippy::too_many_lines)]
9257 fn recognize_state(
9258 &mut self,
9259 atn: &Atn,
9260 request: RecognizeRequest<'_>,
9261 visiting: &mut BTreeSet<RecognizeKey>,
9262 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9263 expected: &mut ExpectedTokens,
9264 ) -> Vec<RecognizeOutcome> {
9265 let request_template = request.clone();
9266 let RecognizeRequest {
9267 state_number,
9268 stop_state,
9269 index,
9270 rule_start_index,
9271 decision_start_index,
9272 init_action_rules,
9273 predicates,
9274 semantics,
9275 rule_args,
9276 member_actions,
9277 return_actions,
9278 local_int_arg,
9279 member_values,
9280 return_values,
9281 rule_alt_number,
9282 track_alt_numbers,
9283 consumed_eof,
9284 precedence,
9285 depth,
9286 recovery_symbols,
9287 recovery_state,
9288 } = request;
9289 if depth > RECOGNITION_DEPTH_LIMIT {
9290 return Vec::new();
9291 }
9292 if state_number == stop_state {
9293 return stop_outcome(
9294 index,
9295 consumed_eof,
9296 rule_alt_number,
9297 member_values,
9298 return_values,
9299 );
9300 }
9301 let key = RecognizeKey {
9302 state_number,
9303 stop_state,
9304 index,
9305 rule_start_index,
9306 decision_start_index,
9307 local_int_arg,
9308 member_values: member_values.clone(),
9309 return_values: return_values.clone(),
9310 rule_alt_number,
9311 track_alt_numbers,
9312 consumed_eof,
9313 precedence,
9314 recovery_symbols: recovery_symbols.clone(),
9315 recovery_state,
9316 };
9317 if let Some(outcomes) = memo.get(&key) {
9318 return outcomes.clone();
9319 }
9320
9321 let visit_key = key.clone();
9322 if !visiting.insert(visit_key.clone()) {
9323 return Vec::new();
9324 }
9325
9326 let Some(state) = atn.state(state_number) else {
9327 visiting.remove(&visit_key);
9328 return Vec::new();
9329 };
9330 let transitions = state.transitions();
9331 let transition_count = transitions.len();
9332 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9333 Some(index)
9334 } else {
9335 decision_start_index
9336 };
9337 let (epsilon_recovery_symbols, epsilon_recovery_state) =
9338 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
9339 let mut outcomes = Vec::new();
9340 for (transition_index, transition) in transitions.iter().enumerate() {
9341 let decision =
9342 transition_decision(atn, state, transition_count, transition_index, predicates);
9343 let next_alt_number = next_alt_number(
9344 state,
9345 transition_count,
9346 transition_index,
9347 rule_alt_number,
9348 track_alt_numbers,
9349 );
9350 let transition_data = transition.data();
9351 match &transition_data {
9352 Transition::Epsilon { target } | Transition::Action { target, .. } => {
9353 let action_rule_index = match &transition_data {
9354 Transition::Action { rule_index, .. } => Some(*rule_index),
9355 _ => None,
9356 };
9357 outcomes.extend(self.recognize_epsilon_or_action_step(
9358 atn,
9359 &request_template,
9360 EpsilonActionStep {
9361 source_state: state_number,
9362 target: *target,
9363 action_rule_index,
9364 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
9365 decision,
9366 decision_start_index: next_decision_start_index,
9367 alt_number: next_alt_number,
9368 recovery_symbols: epsilon_recovery_symbols.clone(),
9369 recovery_state: epsilon_recovery_state,
9370 },
9371 RecognizeScratch {
9372 visiting,
9373 memo,
9374 expected,
9375 },
9376 ));
9377 }
9378 Transition::Predicate {
9379 target,
9380 rule_index,
9381 pred_index,
9382 ..
9383 } => {
9384 let predicate = PredicateEval {
9385 index,
9386 rule_index: *rule_index,
9387 pred_index: *pred_index,
9388 predicates,
9389 semantics,
9390 context: None,
9391 local_int_arg,
9392 member_values: &member_values,
9393 };
9394 if self.parser_predicate_matches(predicate) {
9395 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
9396 outcomes.extend(
9397 self.recognize_state(
9398 atn,
9399 RecognizeRequest {
9400 state_number: *target,
9401 stop_state,
9402 index,
9403 rule_start_index,
9404 decision_start_index: next_decision_start_index,
9405 init_action_rules,
9406 predicates,
9407 semantics,
9408 rule_args,
9409 member_actions,
9410 return_actions,
9411 local_int_arg,
9412 member_values: member_values.clone(),
9413 return_values: return_values.clone(),
9414 rule_alt_number: next_alt_number,
9415 track_alt_numbers,
9416 consumed_eof,
9417 precedence,
9418 depth: depth + 1,
9419 recovery_symbols: epsilon_recovery_symbols.clone(),
9420 recovery_state: epsilon_recovery_state,
9421 },
9422 visiting,
9423 memo,
9424 expected,
9425 )
9426 .into_iter()
9427 .map(|mut outcome| {
9428 prepend_decision(&mut outcome, decision);
9429 if let Some(rule_index) = left_recursive_boundary {
9430 let boundary = self.arena_boundary_node(rule_index);
9431 self.arena_prepend(&mut outcome.nodes, boundary);
9432 }
9433 outcome
9434 }),
9435 );
9436 } else if let Some(message) = semantics
9437 .and_then(|semantics| {
9438 self.parser_semantic_ir_predicate_failure_message(
9439 *rule_index,
9440 *pred_index,
9441 semantics,
9442 )
9443 })
9444 .or_else(|| {
9445 self.parser_predicate_failure_message(
9446 *rule_index,
9447 *pred_index,
9448 predicates,
9449 )
9450 })
9451 {
9452 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
9453 rule_index: *rule_index,
9454 index,
9455 message,
9456 member_values: member_values.clone(),
9457 return_values: return_values.clone(),
9458 rule_alt_number,
9459 }));
9460 } else {
9461 record_predicate_no_viable(expected, next_decision_start_index, index);
9462 }
9463 }
9464 Transition::Precedence {
9465 target,
9466 precedence: transition_precedence,
9467 } => {
9468 if *transition_precedence >= precedence {
9469 outcomes.extend(
9470 self.recognize_state(
9471 atn,
9472 RecognizeRequest {
9473 state_number: *target,
9474 stop_state,
9475 index,
9476 rule_start_index,
9477 decision_start_index: next_decision_start_index,
9478 init_action_rules,
9479 predicates,
9480 semantics,
9481 rule_args,
9482 member_actions,
9483 return_actions,
9484 local_int_arg,
9485 member_values: member_values.clone(),
9486 return_values: return_values.clone(),
9487 rule_alt_number: next_alt_number,
9488 track_alt_numbers,
9489 consumed_eof,
9490 precedence,
9491 depth: depth + 1,
9492 recovery_symbols: epsilon_recovery_symbols.clone(),
9493 recovery_state: epsilon_recovery_state,
9494 },
9495 visiting,
9496 memo,
9497 expected,
9498 )
9499 .into_iter()
9500 .map(|mut outcome| {
9501 prepend_decision(&mut outcome, decision);
9502 outcome
9503 }),
9504 );
9505 }
9506 }
9507 Transition::Rule {
9508 target,
9509 rule_index,
9510 follow_state,
9511 precedence: rule_precedence,
9512 ..
9513 } => {
9514 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
9515 continue;
9516 };
9517 let child_local_int_arg =
9518 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
9519 let expected_before_child = expected.clone();
9520 let children = self.recognize_state(
9521 atn,
9522 RecognizeRequest {
9523 state_number: *target,
9524 stop_state: child_stop,
9525 index,
9526 rule_start_index: index,
9527 decision_start_index: None,
9528 init_action_rules,
9529 predicates,
9530 semantics,
9531 rule_args,
9532 member_actions,
9533 return_actions,
9534 local_int_arg: child_local_int_arg,
9535 member_values: member_values.clone(),
9536 return_values: BTreeMap::new(),
9537 rule_alt_number: 0,
9538 track_alt_numbers,
9539 consumed_eof: false,
9540 precedence: *rule_precedence,
9541 depth: depth + 1,
9542 recovery_symbols: epsilon_recovery_symbols.clone(),
9543 recovery_state: epsilon_recovery_state,
9544 },
9545 visiting,
9546 memo,
9547 expected,
9548 );
9549 let children = if children.is_empty() {
9550 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
9551 atn,
9552 rule_index: *rule_index,
9553 start_index: index,
9554 follow_state: *follow_state,
9555 stop_state,
9556 member_values: member_values.clone(),
9557 expected,
9558 })
9559 } else {
9560 children
9561 };
9562 let preserve_child_expected =
9563 self.child_expected_reaches_clean_eof(&children, expected);
9564 restore_expected(
9565 &children,
9566 index,
9567 expected,
9568 expected_before_child,
9569 preserve_child_expected,
9570 );
9571 for child in children {
9572 let child_stop_index =
9573 self.rule_stop_token_index(child.index, child.consumed_eof);
9574 let child_nodes = self
9575 .recognition_arena
9576 .fold_left_recursive_boundaries(child.nodes);
9577 let child_node = self.arena_rule_node(ArenaRuleSpec {
9578 rule_index: *rule_index,
9579 invoking_state: invoking_state_number(state_number),
9580 alt_number: child.alt_number,
9581 start_index: index,
9582 stop_index: child_stop_index,
9583 return_values: child.return_values.clone(),
9584 children: child_nodes,
9585 });
9586 outcomes.extend(
9587 self.recognize_state(
9588 atn,
9589 RecognizeRequest {
9590 state_number: *follow_state,
9591 stop_state,
9592 index: child.index,
9593 rule_start_index,
9594 decision_start_index: next_decision_start_index,
9595 init_action_rules,
9596 predicates,
9597 semantics,
9598 rule_args,
9599 member_actions,
9600 return_actions,
9601 local_int_arg,
9602 member_values: child.member_values.clone(),
9603 return_values: return_values.clone(),
9604 rule_alt_number,
9605 track_alt_numbers,
9606 consumed_eof: consumed_eof || child.consumed_eof,
9607 precedence,
9608 depth: depth + 1,
9609 recovery_symbols: BTreeSet::new(),
9610 recovery_state: None,
9611 },
9612 visiting,
9613 memo,
9614 expected,
9615 )
9616 .into_iter()
9617 .map(|mut outcome| {
9618 outcome.consumed_eof |= child.consumed_eof;
9619 outcome.diagnostics = self
9620 .recognition_arena
9621 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
9622 let mut decisions = child.decisions.clone();
9623 decisions.append(&mut outcome.decisions);
9624 outcome.decisions = decisions;
9625 prepend_decision(&mut outcome, decision);
9626 let mut actions = child.actions.clone();
9627 if init_action_rules.contains(rule_index) {
9628 actions.insert(
9629 0,
9630 ParserAction::new_rule_init(
9631 *rule_index,
9632 index,
9633 Some(*follow_state),
9634 ),
9635 );
9636 }
9637 actions.append(&mut outcome.actions);
9638 outcome.actions = actions;
9639 self.arena_prepend(&mut outcome.nodes, child_node);
9640 outcome
9641 }),
9642 );
9643 }
9644 }
9645 Transition::Atom { target, .. }
9646 | Transition::Range { target, .. }
9647 | Transition::Set { target, .. }
9648 | Transition::NotSet { target, .. }
9649 | Transition::Wildcard { target, .. } => {
9650 let symbol = self.token_type_at(index);
9651 if transition_data.matches(symbol, 1, atn.max_token_type()) {
9652 let next_index = self.consume_index(index, symbol);
9653 outcomes.extend(
9654 self.recognize_state(
9655 atn,
9656 RecognizeRequest {
9657 state_number: *target,
9658 stop_state,
9659 index: next_index,
9660 rule_start_index,
9661 decision_start_index: next_decision_start_index,
9662 init_action_rules,
9663 predicates,
9664 semantics,
9665 rule_args,
9666 member_actions,
9667 return_actions,
9668 local_int_arg,
9669 member_values: member_values.clone(),
9670 return_values: return_values.clone(),
9671 rule_alt_number: next_alt_number,
9672 track_alt_numbers,
9673 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
9674 precedence,
9675 depth: depth + 1,
9676 recovery_symbols: BTreeSet::new(),
9677 recovery_state: None,
9678 },
9679 visiting,
9680 memo,
9681 expected,
9682 )
9683 .into_iter()
9684 .map(|mut outcome| {
9685 prepend_decision(&mut outcome, decision);
9686 outcome.consumed_eof |= symbol == TOKEN_EOF;
9687 let token = self.arena_token_node(index, false);
9688 self.arena_prepend(&mut outcome.nodes, token);
9689 outcome
9690 }),
9691 );
9692 } else {
9693 let expected_symbols =
9694 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
9695 if expected_symbols.contains(&symbol) {
9696 continue;
9697 }
9698 expected.record_transition(index, transition, atn.max_token_type());
9699 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
9700 let before_recovery = outcomes.len();
9701 let recovery_request = request_template.clone();
9702 outcomes.extend(
9703 self.single_token_deletion_recovery(RecoveryRequest {
9704 atn,
9705 transition,
9706 expected_symbols: expected_symbols.clone(),
9707 target: *target,
9708 request: recovery_request.clone(),
9709 visiting,
9710 memo,
9711 expected,
9712 })
9713 .into_iter()
9714 .map(|mut outcome| {
9715 prepend_decision(&mut outcome, decision);
9716 outcome
9717 }),
9718 );
9719 if !state_is_left_recursive_rule(atn, state) {
9720 outcomes.extend(
9721 self.single_token_insertion_recovery(RecoveryRequest {
9722 atn,
9723 transition,
9724 expected_symbols: expected_symbols.clone(),
9725 target: *target,
9726 request: recovery_request.clone(),
9727 visiting,
9728 memo,
9729 expected,
9730 })
9731 .into_iter()
9732 .map(|mut outcome| {
9733 prepend_decision(&mut outcome, decision);
9734 outcome
9735 }),
9736 );
9737 }
9738 outcomes.extend(self.current_token_deletion_recovery(
9739 CurrentTokenDeletionRequest {
9740 atn,
9741 expected_symbols: expected_symbols.clone(),
9742 request: recovery_request.clone(),
9743 visiting,
9744 memo,
9745 expected,
9746 },
9747 ));
9748 if outcomes.len() == before_recovery {
9749 outcomes.extend(self.consuming_failure_fallback(
9750 ConsumingFailureFallback {
9751 atn,
9752 target: *target,
9753 request: recovery_request,
9754 symbol,
9755 expected_symbols,
9756 decision_start_index: next_decision_start_index,
9757 decision,
9758 },
9759 visiting,
9760 memo,
9761 expected,
9762 ));
9763 }
9764 }
9765 }
9766 }
9767 }
9768
9769 visiting.remove(&visit_key);
9770 self.record_prediction_diagnostics(atn, state, index, &outcomes);
9771 if matches!(
9772 self.prediction_mode,
9773 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9774 ) {
9775 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
9776 }
9777 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
9778 memo.insert(key, outcomes.clone());
9779 outcomes
9780 }
9781
9782 fn recognize_epsilon_or_action_step(
9785 &mut self,
9786 atn: &Atn,
9787 request: &RecognizeRequest<'_>,
9788 step: EpsilonActionStep,
9789 scratch: RecognizeScratch<'_>,
9790 ) -> Vec<RecognizeOutcome> {
9791 let RecognizeScratch {
9792 visiting,
9793 memo,
9794 expected,
9795 } = scratch;
9796 let action = step.action_rule_index.map(|rule_index| {
9797 ParserAction::new(
9798 step.source_state,
9799 rule_index,
9800 request.rule_start_index,
9801 self.rule_stop_token_index(request.index, request.consumed_eof),
9802 )
9803 });
9804 let next_member_values = if action.is_some() {
9805 member_values_after_action(
9806 step.source_state,
9807 request.member_actions,
9808 request.semantics,
9809 &request.member_values,
9810 )
9811 } else {
9812 request.member_values.clone()
9813 };
9814 let next_return_values = action.map_or_else(
9815 || request.return_values.clone(),
9816 |action| {
9817 return_values_after_action(
9818 step.source_state,
9819 action.rule_index(),
9820 request.return_actions,
9821 request.semantics,
9822 &request.return_values,
9823 )
9824 },
9825 );
9826
9827 self.recognize_state(
9828 atn,
9829 RecognizeRequest {
9830 state_number: step.target,
9831 stop_state: request.stop_state,
9832 index: request.index,
9833 rule_start_index: request.rule_start_index,
9834 decision_start_index: step.decision_start_index,
9835 init_action_rules: request.init_action_rules,
9836 predicates: request.predicates,
9837 semantics: request.semantics,
9838 rule_args: request.rule_args,
9839 member_actions: request.member_actions,
9840 return_actions: request.return_actions,
9841 local_int_arg: request.local_int_arg,
9842 member_values: next_member_values,
9843 return_values: next_return_values,
9844 rule_alt_number: step.alt_number,
9845 track_alt_numbers: request.track_alt_numbers,
9846 consumed_eof: request.consumed_eof,
9847 precedence: request.precedence,
9848 depth: request.depth + 1,
9849 recovery_symbols: step.recovery_symbols,
9850 recovery_state: step.recovery_state,
9851 },
9852 visiting,
9853 memo,
9854 expected,
9855 )
9856 .into_iter()
9857 .map(|mut outcome| {
9858 prepend_decision(&mut outcome, step.decision);
9859 if let Some(rule_index) = step.left_recursive_boundary {
9860 let boundary = self.arena_boundary_node(rule_index);
9861 self.arena_prepend(&mut outcome.nodes, boundary);
9862 }
9863 if let Some(action) = action {
9864 outcome.actions.insert(0, action);
9865 }
9866 outcome
9867 })
9868 .collect()
9869 }
9870
9871 fn token_type_at(&mut self, index: usize) -> i32 {
9876 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
9877 self.input.fill();
9878 }
9879 self.input.token_type_at_index(index)
9880 }
9881
9882 fn cached_state_expected_symbols(
9894 &mut self,
9895 atn: &Atn,
9896 state_number: usize,
9897 ) -> Rc<BTreeSet<i32>> {
9898 if let Some(cached) = self.state_expected_cache.get(&state_number) {
9899 return Rc::clone(cached);
9900 }
9901 let symbols = state_expected_symbols(atn, state_number);
9902 let entry = self.intern_recovery_symbols(symbols);
9903 self.state_expected_cache
9904 .insert(state_number, Rc::clone(&entry));
9905 entry
9906 }
9907
9908 fn cached_state_expected_token_set(
9909 &mut self,
9910 atn: &Atn,
9911 state_number: usize,
9912 ) -> Rc<TokenBitSet> {
9913 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
9914 return Rc::clone(cached);
9915 }
9916 let symbols = with_shared_atn_caches(atn, |cache| {
9920 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
9921 return Rc::clone(cached);
9922 }
9923 let symbols = Rc::new(state_expected_token_set(atn, state_number));
9924 cache
9925 .state_expected_tokens
9926 .insert(state_number, Rc::clone(&symbols));
9927 symbols
9928 });
9929 self.state_expected_token_cache
9930 .insert(state_number, Rc::clone(&symbols));
9931 symbols
9932 }
9933
9934 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
9935 if self.rule_stop_reach_cache.len() <= state_number {
9936 self.rule_stop_reach_cache
9937 .resize_with(atn.states().len().max(state_number + 1), || None);
9938 }
9939 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
9940 return reaches;
9941 }
9942 let reaches = with_shared_atn_caches(atn, |cache| {
9943 *cache
9944 .rule_stop_reach
9945 .entry(state_number)
9946 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
9947 });
9948 self.rule_stop_reach_cache[state_number] = Some(reaches);
9949 reaches
9950 }
9951
9952 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
9955 Rc::clone(&self.empty_recovery_symbols)
9956 }
9957
9958 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
9967 if set.is_empty() {
9968 return Rc::clone(&self.empty_recovery_symbols);
9969 }
9970 let candidate = Rc::new(set);
9971 match self.recovery_symbols_intern.get(&candidate) {
9972 Some(existing) => Rc::clone(existing),
9973 None => {
9974 self.recovery_symbols_intern
9975 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
9976 candidate
9977 }
9978 }
9979 }
9980
9981 fn cached_decision_lookahead(
9986 &mut self,
9987 atn: &Atn,
9988 state: AtnState<'_>,
9989 rule_stop_state: usize,
9990 ) -> Rc<DecisionLookahead> {
9991 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
9998 return Rc::clone(cached);
9999 }
10000 let entry = with_shared_atn_caches(atn, |cache| {
10001 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
10002 return Rc::clone(cached);
10003 }
10004 let mut entry = DecisionLookahead {
10005 transitions: Vec::with_capacity(state.transitions().len()),
10006 };
10007 for transition in &state.transitions() {
10008 entry.transitions.push(transition_first_set(
10009 atn,
10010 transition,
10011 rule_stop_state,
10012 &mut cache.first_set,
10013 ));
10014 }
10015 let entry = Rc::new(entry);
10016 cache
10017 .decision_lookahead
10018 .insert(state.state_number(), Rc::clone(&entry));
10019 entry
10020 });
10021 self.decision_lookahead_cache
10022 .insert(state.state_number(), Rc::clone(&entry));
10023 entry
10024 }
10025
10026 fn cached_rule_first_set(
10027 &mut self,
10028 atn: &Atn,
10029 target: usize,
10030 child_stop: usize,
10031 ) -> Rc<FirstSet> {
10032 if self.rule_first_set_cache.len() <= target {
10033 self.rule_first_set_cache
10034 .resize_with(atn.states().len().max(target + 1), || None);
10035 }
10036 if let Some(cached) = self
10037 .rule_first_set_cache
10038 .get(target)
10039 .and_then(Option::as_ref)
10040 {
10041 return Rc::clone(cached);
10042 }
10043 let first = with_shared_first_set_cache(atn, |cache| {
10044 rule_first_set(atn, target, child_stop, cache)
10045 });
10046 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
10047 first
10048 }
10049
10050 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
10051 let atn_key = SharedAtnCacheKey::for_atn(atn);
10052 if self.empty_cycle_cache_atn != Some(atn_key) {
10053 self.empty_cycle_cache.clear();
10054 self.empty_cycle_cache_atn = Some(atn_key);
10055 }
10056 if self.empty_cycle_cache.len() <= state_number {
10057 self.empty_cycle_cache
10058 .resize_with(atn.state_count().max(state_number + 1), || None);
10059 }
10060 if let Some(cached) = self.empty_cycle_cache[state_number] {
10061 return cached;
10062 }
10063 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
10064 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
10065 self.empty_cycle_cache[state_number] = Some(result);
10066 result
10067 }
10068
10069 fn empty_path_reaches_state(
10070 &mut self,
10071 atn: &Atn,
10072 state_number: usize,
10073 target_state: usize,
10074 visited: &mut FxHashSet<usize>,
10075 ) -> bool {
10076 if !visited.insert(state_number) {
10077 return false;
10078 }
10079 let Some(state) = atn.state(state_number) else {
10080 return false;
10081 };
10082 for transition in &state.transitions() {
10083 let kind = transition.kind();
10084 let target = transition.target();
10085 match kind {
10086 ParserTransitionKind::Atom
10087 | ParserTransitionKind::Range
10088 | ParserTransitionKind::Set
10089 | ParserTransitionKind::NotSet
10090 | ParserTransitionKind::Wildcard => {}
10091 ParserTransitionKind::Rule => {
10092 let rule_index = transition.arg0() as usize;
10093 let follow_state = transition.arg1() as usize;
10094 if target == target_state
10095 || self.empty_path_reaches_state(atn, target, target_state, visited)
10096 {
10097 return true;
10098 }
10099 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
10100 continue;
10101 };
10102 if self.cached_rule_first_set(atn, target, child_stop).nullable
10103 && (follow_state == target_state
10104 || self.empty_path_reaches_state(
10105 atn,
10106 follow_state,
10107 target_state,
10108 visited,
10109 ))
10110 {
10111 return true;
10112 }
10113 }
10114 ParserTransitionKind::Epsilon
10115 | ParserTransitionKind::Predicate
10116 | ParserTransitionKind::Action
10117 | ParserTransitionKind::Precedence => {
10118 if target == target_state
10119 || self.empty_path_reaches_state(atn, target, target_state, visited)
10120 {
10121 return true;
10122 }
10123 }
10124 }
10125 }
10126 false
10127 }
10128
10129 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
10132 match self.clean_memo_mode {
10133 CleanMemoMode::Promote => true,
10134 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
10135 CleanMemoMode::Sparse => {
10136 self.clean_memo_sparse_samples += 1;
10137 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
10138 return false;
10139 }
10140 self.clean_memo_sparse_samples = 0;
10141 self.clean_memo_mode = CleanMemoMode::Probe;
10142 self.clean_memo_probe_samples = 0;
10143 self.clean_memo_probe_repeats = 0;
10144 self.clean_memo_probe_seen.clear();
10145 self.observe_clean_memo_probe(key)
10146 }
10147 }
10148 }
10149
10150 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
10151 self.clean_memo_probe_samples += 1;
10152 if !self.clean_memo_probe_seen.insert(key.clone()) {
10153 self.clean_memo_probe_repeats += 1;
10154 }
10155 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
10156 self.clean_memo_mode = CleanMemoMode::Promote;
10157 self.clean_memo_probe_seen.clear();
10158 return true;
10159 }
10160 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
10161 self.clean_memo_mode = CleanMemoMode::Sparse;
10162 self.clean_memo_sparse_samples = 0;
10163 self.clean_memo_probe_seen.clear();
10164 return false;
10165 }
10166 true
10167 }
10168
10169 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
10171 self.input.get(index)
10172 }
10173
10174 fn token_id_at(&self, index: usize) -> Option<TokenId> {
10176 self.input.get_id(index)
10177 }
10178
10179 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
10180 let token = self
10181 .token_id_at(index)
10182 .expect("recognized token index must exist in the token store");
10183 let node = if error {
10184 ArenaRecognizedNode::ErrorToken { token }
10185 } else {
10186 ArenaRecognizedNode::Token { token }
10187 };
10188 self.recognition_arena.push_node(node)
10189 }
10190
10191 fn arena_missing_token_node(
10192 &mut self,
10193 token_type: i32,
10194 at_index: usize,
10195 text: String,
10196 ) -> RecognizedNodeId {
10197 let extra = self
10198 .recognition_arena
10199 .push_extra(RecognitionExtra::MissingToken {
10200 token_type,
10201 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
10202 text,
10203 });
10204 self.recognition_arena
10205 .push_node(ArenaRecognizedNode::MissingToken { extra })
10206 }
10207
10208 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
10209 let ArenaRuleSpec {
10210 rule_index,
10211 invoking_state,
10212 alt_number,
10213 start_index,
10214 stop_index,
10215 return_values,
10216 children,
10217 } = spec;
10218 let return_values = (!return_values.is_empty()).then(|| {
10219 self.recognition_arena
10220 .push_extra(RecognitionExtra::ReturnValues(return_values))
10221 });
10222 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
10223 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10224 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
10225 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
10226 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
10227 stop_index: stop_index
10228 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
10229 return_values,
10230 children,
10231 })
10232 }
10233
10234 fn arena_boundary_node(&mut self, rule_index: usize) -> RecognizedNodeId {
10235 self.recognition_arena
10236 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
10237 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10238 })
10239 }
10240
10241 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
10242 *sequence = self.recognition_arena.prepend(*sequence, node);
10243 }
10244
10245 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
10246 self.last_recognition_arena_root = root;
10247 self.last_recognition_arena_diagnostics = diagnostics;
10248 #[cfg(feature = "perf-counters")]
10249 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
10250 let stats = self.recognition_arena_stats();
10251 #[allow(clippy::print_stderr)]
10252 {
10253 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
10254 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
10255 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
10256 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
10257 eprintln!("perf recognition_links_total={}", stats.total_links);
10258 eprintln!("perf recognition_links_live={}", stats.live_links);
10259 eprintln!("perf recognition_links_dead={}", stats.dead_links);
10260 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
10261 eprintln!("perf recognition_extras_total={}", stats.total_extras);
10262 eprintln!("perf recognition_extras_live={}", stats.live_extras);
10263 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
10264 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
10265 }
10266 }
10267 }
10268
10269 fn reset_recognition_arena(&mut self) {
10270 self.recognition_arena.reset();
10271 self.last_recognition_arena_root = NodeSeqId::EMPTY;
10272 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
10273 }
10274
10275 fn current_visible_index(&mut self) -> usize {
10278 let index = self.input.index();
10279 self.input.seek(index);
10280 self.input.index()
10281 }
10282
10283 fn child_expected_reaches_clean_eof(
10286 &mut self,
10287 children: &[RecognizeOutcome],
10288 expected: &ExpectedTokens,
10289 ) -> bool {
10290 let Some(index) = expected.index else {
10291 return false;
10292 };
10293 self.token_type_at(index) == TOKEN_EOF
10294 && children
10295 .iter()
10296 .any(|child| child.diagnostics.is_empty() && child.index == index)
10297 }
10298
10299 fn previous_token_index(&self, index: usize) -> Option<usize> {
10306 self.input.previous_visible_token_index(index)
10307 }
10308
10309 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
10314 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
10315 Some(index)
10316 } else {
10317 self.previous_token_index(index)
10318 }
10319 }
10320
10321 #[must_use]
10338 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
10339 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
10340 self.rule_stop_token_index(current_index, consumed_eof)
10341 }
10342
10343 #[must_use]
10352 pub fn after_action_stop_index_for_tree(
10353 &mut self,
10354 tree: ParseTree,
10355 current_index: usize,
10356 ) -> Option<usize> {
10357 if let Some(stop) = self
10358 .node(tree)
10359 .as_rule()
10360 .and_then(crate::tree::RuleNodeView::stop_id)
10361 {
10362 return Some(stop.index());
10363 }
10364 self.after_action_stop_index(current_index)
10365 }
10366
10367 #[must_use]
10377 pub fn after_action_start_index_for_tree(
10378 &self,
10379 tree: ParseTree,
10380 fallback_index: usize,
10381 ) -> usize {
10382 if let Some(start) = self
10383 .node(tree)
10384 .as_rule()
10385 .and_then(crate::tree::RuleNodeView::start_id)
10386 {
10387 return start.index();
10388 }
10389 fallback_index
10390 }
10391
10392 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
10397 self.rule_stop_token_index(index, consumed_eof)
10398 .and_then(|token_index| self.token_id_at(token_index))
10399 }
10400
10401 fn predicate_failure_recovery(
10408 &mut self,
10409 request: PredicateFailureRecovery<'_>,
10410 ) -> RecognizeOutcome {
10411 let PredicateFailureRecovery {
10412 rule_index,
10413 index,
10414 message,
10415 member_values,
10416 return_values,
10417 rule_alt_number,
10418 } = request;
10419 let rule_name = self
10420 .rule_names()
10421 .get(rule_index)
10422 .map_or_else(|| rule_index.to_string(), Clone::clone);
10423 let diagnostic = diagnostic_for_token(
10424 self.token_at(index).as_ref(),
10425 format!("rule {rule_name} {message}"),
10426 );
10427 let mut reversed_nodes = NodeSeqId::EMPTY;
10428 let mut next_index = index;
10429 loop {
10430 let symbol = self.token_type_at(next_index);
10431 if symbol == TOKEN_EOF {
10432 break;
10433 }
10434 let error = self.arena_token_node(next_index, true);
10435 self.arena_prepend(&mut reversed_nodes, error);
10436 let after = self.consume_index(next_index, symbol);
10437 if after == next_index {
10438 break;
10439 }
10440 next_index = after;
10441 }
10442 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
10443 let diagnostics = self
10444 .recognition_arena
10445 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10446 RecognizeOutcome {
10447 index: next_index,
10448 consumed_eof: false,
10449 alt_number: rule_alt_number,
10450 member_values,
10451 return_values,
10452 diagnostics,
10453 decisions: Vec::new(),
10454 actions: Vec::new(),
10455 nodes,
10456 }
10457 }
10458
10459 fn parser_semantic_hook_result(
10462 &mut self,
10463 request: ParserSemanticHookRequest<'_>,
10464 ) -> Option<bool> {
10465 let ParserSemanticHookRequest {
10466 index,
10467 rule_index,
10468 pred_index,
10469 context,
10470 local_int_arg,
10471 member_values,
10472 } = request;
10473 let rule_name = self.rule_names().get(rule_index).cloned();
10474 self.input.seek(index);
10475 let input = &mut self.input;
10476 let semantic_hooks = &mut self.semantic_hooks;
10477 let mut ctx = ParserSemCtx {
10478 input,
10479 tree_storage: &self.tree,
10480 rule_index,
10481 coordinate_index: pred_index,
10482 rule_name,
10483 context,
10484 tree: None,
10485 local_int_arg,
10486 member_values,
10487 action: None,
10488 };
10489 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
10490 }
10491
10492 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
10497 if prior.is_empty() {
10498 return;
10499 }
10500 let mut merged = prior;
10501 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
10502 if !merged.contains(&coordinate) {
10503 merged.push(coordinate);
10504 }
10505 }
10506 self.unknown_predicate_hits = merged;
10507 }
10508
10509 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
10518 apply_unknown_predicate_policy(
10519 self.unknown_predicate_policy,
10520 rule_index,
10521 pred_index,
10522 &mut self.unknown_predicate_hits,
10523 )
10524 }
10525
10526 fn unknown_semantic_error(&self) -> Option<AntlrError> {
10529 use std::fmt::Write as _;
10530 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
10531 return None;
10532 }
10533 let mut message = String::new();
10534 for (rule_index, pred_index) in &self.unknown_predicate_hits {
10535 if !message.is_empty() {
10536 message.push_str("; ");
10537 }
10538 let _ = match self.rule_names().get(*rule_index) {
10539 Some(rule_name) => write!(
10540 message,
10541 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
10542 ),
10543 None => write!(
10544 message,
10545 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
10546 ),
10547 };
10548 }
10549 for (rule_index, source_state) in &self.unhandled_action_hits {
10550 if !message.is_empty() {
10551 message.push_str("; ");
10552 }
10553 let _ = match self.rule_names().get(*rule_index) {
10554 Some(rule_name) => write!(
10555 message,
10556 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
10557 ),
10558 None => write!(
10559 message,
10560 "unhandled semantic action: rule_index={rule_index} state={source_state}"
10561 ),
10562 };
10563 }
10564 Some(AntlrError::Unsupported(message))
10565 }
10566
10567 fn parser_semir_predicate_matches(
10575 &mut self,
10576 semantics: &ParserSemantics,
10577 predicate: &ParserSemanticPredicate,
10578 request: ParserSemanticHookRequest<'_>,
10579 ) -> bool {
10580 self.input.seek(request.index);
10581 let rule_name = self
10582 .data
10583 .rule_names()
10584 .get(request.rule_index)
10585 .map(String::as_str);
10586 let unknown_predicate_policy = self.unknown_predicate_policy;
10587 let mut ctx = ParserSemIrCtx {
10588 input: &mut self.input,
10589 tree_storage: &self.tree,
10590 semantic_hooks: &mut self.semantic_hooks,
10591 rule_index: request.rule_index,
10592 coordinate_index: request.pred_index,
10593 rule_name,
10594 context: request.context,
10595 local_int_arg: request.local_int_arg,
10596 member_values: request.member_values,
10597 invoked_predicates: &mut self.invoked_predicates,
10598 unknown_predicate_policy,
10599 unknown_predicate_hits: &mut self.unknown_predicate_hits,
10600 };
10601 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
10602 }
10603
10604 fn fast_parser_predicate_matches(
10605 &mut self,
10606 context: Option<FastPredicateContext<'_>>,
10607 transition: ParserTransition<'_>,
10608 index: usize,
10609 ) -> bool {
10610 let Some(context) = context else {
10611 return true;
10612 };
10613 let rule_index = transition.arg0() as usize;
10614 let pred_index = transition.arg1() as usize;
10615 let key = (index, rule_index, pred_index);
10616 if let Some(result) = self.fast_predicate_cache.get(&key) {
10617 return *result;
10618 }
10619 let result = self.parser_predicate_matches(PredicateEval {
10620 index,
10621 rule_index,
10622 pred_index,
10623 predicates: context.predicates,
10624 semantics: context.semantics,
10625 context: None,
10626 local_int_arg: None,
10627 member_values: context.member_values,
10628 });
10629 self.fast_predicate_cache.insert(key, result);
10630 result
10631 }
10632
10633 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
10634 let PredicateEval {
10635 index,
10636 rule_index,
10637 pred_index,
10638 predicates,
10639 semantics,
10640 context,
10641 local_int_arg,
10642 member_values,
10643 } = eval;
10644 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
10645 semantics
10646 .predicates
10647 .iter()
10648 .find(|predicate| {
10649 predicate.rule_index == rule_index && predicate.pred_index == pred_index
10650 })
10651 .map(|predicate| (semantics, predicate))
10652 }) {
10653 return self.parser_semir_predicate_matches(
10654 semantics,
10655 predicate,
10656 ParserSemanticHookRequest {
10657 index,
10658 rule_index,
10659 pred_index,
10660 context,
10661 local_int_arg,
10662 member_values,
10663 },
10664 );
10665 }
10666 let Some((_, _, predicate)) = predicates
10667 .iter()
10668 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
10669 else {
10670 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
10671 index,
10672 rule_index,
10673 pred_index,
10674 context,
10675 local_int_arg,
10676 member_values,
10677 }) {
10678 return result;
10679 }
10680 return self.unknown_predicate_result(rule_index, pred_index);
10681 };
10682 self.input.seek(index);
10683 match predicate {
10684 ParserPredicate::True => true,
10685 ParserPredicate::False => false,
10686 ParserPredicate::FalseWithMessage { .. } => false,
10687 ParserPredicate::Invoke { value } => {
10688 let key = (rule_index, pred_index);
10689 if !self.invoked_predicates.contains(&key) {
10690 self.invoked_predicates.push(key);
10691 use std::io::Write as _;
10692 let mut stdout = std::io::stdout().lock();
10693 let _ = writeln!(stdout, "eval={value}");
10694 }
10695 *value
10696 }
10697 ParserPredicate::LookaheadTextEquals { offset, text } => self
10698 .input
10699 .lt(*offset)
10700 .is_some_and(|token| Token::text(&token) == Some(*text)),
10701 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
10702 self.la(*offset) != *token_type
10703 }
10704 ParserPredicate::TokenPairAdjacent => {
10705 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
10706 return false;
10707 };
10708 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
10709 return false;
10710 };
10711 first + 1 == second
10712 }
10713 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
10714 .and_then(|context| {
10715 context
10716 .child_rules(&self.tree, self.input.token_store(), *rule_index)
10717 .next()
10718 .map(crate::tree::RuleNodeView::text)
10719 })
10720 .is_none_or(|actual| actual != *text),
10721 ParserPredicate::LocalIntEquals { value } => {
10722 local_int_arg.is_none_or(|(_, actual)| actual == *value)
10723 }
10724 ParserPredicate::LocalIntLessOrEqual { value } => {
10725 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
10726 }
10727 ParserPredicate::MemberModuloEquals {
10728 member,
10729 modulus,
10730 value,
10731 equals,
10732 } => {
10733 if *modulus == 0 {
10734 return false;
10735 }
10736 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
10737 (actual == *value) == *equals
10738 }
10739 ParserPredicate::MemberEquals {
10740 member,
10741 value,
10742 equals,
10743 } => {
10744 let actual = member_values.get(member).copied().unwrap_or_default();
10745 (actual == *value) == *equals
10746 }
10747 }
10748 }
10749
10750 fn parser_predicate_failure_message(
10752 &self,
10753 rule_index: usize,
10754 pred_index: usize,
10755 predicates: &[(usize, usize, ParserPredicate)],
10756 ) -> Option<&'static str> {
10757 predicates
10758 .iter()
10759 .find_map(|(rule, pred, predicate)| match predicate {
10760 ParserPredicate::FalseWithMessage { message }
10761 if *rule == rule_index && *pred == pred_index =>
10762 {
10763 Some(*message)
10764 }
10765 _ => None,
10766 })
10767 }
10768
10769 pub fn parser_semantic_ir_predicate_failure_message(
10772 &self,
10773 rule_index: usize,
10774 pred_index: usize,
10775 semantics: &ParserSemantics,
10776 ) -> Option<&'static str> {
10777 semantics
10778 .predicates
10779 .iter()
10780 .find(|predicate| {
10781 predicate.rule_index == rule_index && predicate.pred_index == pred_index
10782 })
10783 .and_then(|predicate| predicate.failure_message)
10784 }
10785
10786 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
10795 if symbol == TOKEN_EOF {
10796 return index;
10797 }
10798 self.input.next_visible_after(index)
10799 }
10800
10801 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
10804 let text = display_input_text(&self.input.text(start_index, error_index));
10805 diagnostic_for_token(
10806 self.token_at(error_index).as_ref(),
10807 format!("no viable alternative at input '{text}'"),
10808 )
10809 }
10810
10811 fn recovery_failure_diagnostic(
10814 &self,
10815 index: usize,
10816 decision_start_index: Option<usize>,
10817 expected_symbols: &BTreeSet<i32>,
10818 ) -> ParserDiagnostic {
10819 if expected_symbols.len() > 1 {
10820 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
10821 return self.no_viable_alternative(decision_start, index);
10822 }
10823 }
10824 diagnostic_for_token(
10825 self.token_at(index).as_ref(),
10826 format!(
10827 "mismatched input {} expecting {}",
10828 self.token_at(index)
10829 .as_ref()
10830 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
10831 self.expected_symbols_display(expected_symbols)
10832 ),
10833 )
10834 }
10835
10836 fn eof_rule_recovery_diagnostic(
10839 &self,
10840 index: usize,
10841 expected_symbols: &BTreeSet<i32>,
10842 expected: &ExpectedTokens,
10843 ) -> ParserDiagnostic {
10844 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
10845 &expected.symbols
10846 } else {
10847 expected_symbols
10848 };
10849 diagnostic_for_token(
10850 self.token_at(index).as_ref(),
10851 format!(
10852 "mismatched input {} expecting {}",
10853 self.token_at(index)
10854 .as_ref()
10855 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
10856 self.expected_symbols_display(symbols)
10857 ),
10858 )
10859 }
10860
10861 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
10867 let Some(stop) = stop else {
10868 return String::new();
10869 };
10870 let stop = if self
10871 .token_at(stop)
10872 .is_some_and(|token| token.token_type() == TOKEN_EOF)
10873 {
10874 let Some(previous) = self.previous_token_index(stop) else {
10875 return String::new();
10876 };
10877 previous
10878 } else {
10879 stop
10880 };
10881 self.input.text(start, stop)
10882 }
10883
10884 fn clear_prediction_diagnostics(&mut self) {
10887 self.prediction_diagnostics.clear();
10888 self.reported_prediction_diagnostics.clear();
10889 }
10890
10891 fn reset_per_parse_caches(&mut self) {
10915 self.rule_first_set_cache.clear();
10916 self.decision_lookahead_cache.clear();
10917 self.ll1_decision_cache.clear();
10918 self.fast_predicate_cache.clear();
10919 self.rule_stop_reach_cache.clear();
10920 self.clean_memo_mode = CleanMemoMode::Probe;
10921 self.clean_memo_probe_seen.clear();
10922 self.clean_memo_probe_samples = 0;
10923 self.clean_memo_probe_repeats = 0;
10924 self.clean_memo_sparse_samples = 0;
10925 self.recovery_symbols_intern.clear();
10926 self.state_expected_cache.clear();
10927 self.state_expected_token_cache.clear();
10928 }
10929
10930 fn record_prediction_diagnostics(
10933 &mut self,
10934 atn: &Atn,
10935 state: AtnState<'_>,
10936 start_index: usize,
10937 outcomes: &[RecognizeOutcome],
10938 ) {
10939 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
10940 return;
10941 }
10942 let Some(decision) = atn
10943 .decision_to_state()
10944 .iter()
10945 .position(|state_number| state_number == state.state_number())
10946 else {
10947 return;
10948 };
10949 let Some(rule_index) = state.rule_index() else {
10950 return;
10951 };
10952 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
10953 for outcome in outcomes
10954 .iter()
10955 .filter(|outcome| outcome.diagnostics.is_empty())
10956 {
10957 let Some(alt) = outcome.decisions.first() else {
10958 continue;
10959 };
10960 alts_by_end
10961 .entry(outcome.index)
10962 .or_default()
10963 .insert(alt + 1);
10964 }
10965 let Some((&end_index, ambig_alts)) = alts_by_end
10966 .iter()
10967 .filter(|(_, alts)| alts.len() > 1)
10968 .max_by_key(|(end, _)| *end)
10969 else {
10970 return;
10971 };
10972 let rule_name = self
10973 .rule_names()
10974 .get(rule_index)
10975 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
10976 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
10977 let input = display_input_text(&self.input.text(start_index, stop_index));
10978 let alts = ambig_alts
10979 .iter()
10980 .map(usize::to_string)
10981 .collect::<Vec<_>>()
10982 .join(", ");
10983 let key = (decision, start_index, format!("{alts}:{input}"));
10984 if !self.reported_prediction_diagnostics.insert(key) {
10985 return;
10986 }
10987 let start_diagnostic = diagnostic_for_token(
10988 self.token_at(start_index),
10989 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
10990 );
10991 let stop_diagnostic = diagnostic_for_token(
10992 self.token_at(stop_index),
10993 format!(
10994 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
10995 ),
10996 );
10997 self.prediction_diagnostics.push(start_diagnostic);
10998 self.prediction_diagnostics.push(stop_diagnostic);
10999 }
11000
11001 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
11003 expected_symbols_display(
11004 &state_expected_symbols(atn, state_number),
11005 self.vocabulary(),
11006 )
11007 }
11008
11009 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
11014 let state = usize::try_from(self.data().state()).unwrap_or(0);
11015 ExpectedTokenSet {
11016 symbols: state_expected_symbols(atn, state),
11017 }
11018 }
11019
11020 pub const fn set_bail_on_error(&mut self, bail: bool) {
11023 self.bail_on_error = bail;
11024 }
11025
11026 #[must_use]
11028 pub const fn bail_on_error(&self) -> bool {
11029 self.bail_on_error
11030 }
11031
11032 pub fn rule_invocation_stack(&self) -> Vec<String> {
11035 self.rule_context_stack
11036 .iter()
11037 .rev()
11038 .map(|frame| {
11039 self.data()
11040 .rule_names()
11041 .get(frame.rule_index)
11042 .cloned()
11043 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
11044 })
11045 .collect()
11046 }
11047
11048 pub fn active_invocation_states(&self) -> Vec<isize> {
11052 self.rule_context_stack
11053 .iter()
11054 .skip(1)
11055 .rev()
11056 .map(|frame| frame.invoking_state)
11057 .collect()
11058 }
11059
11060 pub fn token_display_at(&self, index: usize) -> Option<String> {
11062 self.token_at(index).map(|token| format!("{token}"))
11063 }
11064}
11065
11066impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
11067where
11068 S: TokenSource,
11069 H: SemanticHooks,
11070{
11071 fn parse_rule(
11072 &mut self,
11073 rule_index: usize,
11074 invoking_state: isize,
11075 precedence: i32,
11076 ) -> DirectAdaptiveParseResult<ParseTree> {
11077 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
11078 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
11079 )?;
11080 let stop_state = self
11081 .atn
11082 .rule_to_stop_state()
11083 .get(rule_index)
11084 .filter(|state| *state != usize::MAX)
11085 .ok_or(DirectAdaptiveParseControl::Fallback(
11086 DirectAdaptiveFallback::MissingAtn,
11087 ))?;
11088 let start_index = self.parser.current_visible_index();
11089 let mut context = ParserRuleContext::new(rule_index, invoking_state);
11090 if let Some(token) = self.parser.token_id_at(start_index) {
11091 self.parser.set_context_start(&mut context, token);
11092 }
11093 let mut state_number = start_state;
11094 let mut consumed_eof = false;
11095 while state_number != stop_state {
11096 self.step()?;
11097 let (transition, boundary) = self.next_transition(state_number, precedence)?;
11098 if boundary.is_some() {
11099 return Err(DirectAdaptiveParseControl::Fallback(
11100 DirectAdaptiveFallback::LeftRecursiveBoundary,
11101 ));
11102 }
11103 match transition.data() {
11104 Transition::Epsilon { target } => {
11105 state_number = target;
11106 }
11107 Transition::Precedence {
11108 target,
11109 precedence: transition_precedence,
11110 } => {
11111 if transition_precedence < precedence {
11112 return Err(DirectAdaptiveParseControl::Fallback(
11113 DirectAdaptiveFallback::Precedence,
11114 ));
11115 }
11116 state_number = target;
11117 }
11118 Transition::Rule {
11119 rule_index,
11120 follow_state,
11121 precedence: rule_precedence,
11122 ..
11123 } => {
11124 let child = self.parse_rule(
11125 rule_index,
11126 invoking_state_number(state_number),
11127 rule_precedence,
11128 )?;
11129 if self.parser.build_parse_trees {
11130 self.parser.tree.add_child(&mut context, child);
11131 }
11132 state_number = follow_state;
11133 }
11134 Transition::Atom { .. }
11135 | Transition::Range { .. }
11136 | Transition::Set { .. }
11137 | Transition::NotSet { .. }
11138 | Transition::Wildcard { .. } => {
11139 let (matched_eof, child) = self.consume_transition(transition)?;
11140 consumed_eof |= matched_eof;
11141 if let Some(child) = child {
11142 self.parser.tree.add_child(&mut context, child);
11143 }
11144 state_number = transition.target();
11145 }
11146 Transition::Predicate { .. } => {
11147 return Err(DirectAdaptiveParseControl::Fallback(
11148 DirectAdaptiveFallback::Predicate,
11149 ));
11150 }
11151 Transition::Action { .. } => {
11152 return Err(DirectAdaptiveParseControl::Fallback(
11153 DirectAdaptiveFallback::Action,
11154 ));
11155 }
11156 }
11157 }
11158
11159 let stop_index = self
11160 .parser
11161 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
11162 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
11163 self.parser.set_context_stop(&mut context, token);
11164 }
11165 Ok(self.parser.rule_node(context))
11166 }
11167
11168 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
11169 self.steps += 1;
11170 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
11171 return Err(DirectAdaptiveParseControl::Fallback(
11172 DirectAdaptiveFallback::StepLimit,
11173 ));
11174 }
11175 Ok(())
11176 }
11177
11178 fn next_transition(
11179 &mut self,
11180 state_number: usize,
11181 precedence: i32,
11182 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
11183 let state = self
11184 .atn
11185 .state(state_number)
11186 .ok_or(DirectAdaptiveParseControl::Fallback(
11187 DirectAdaptiveFallback::MissingAtn,
11188 ))?;
11189 if state.is_rule_stop() {
11190 return Err(DirectAdaptiveParseControl::Fallback(
11191 DirectAdaptiveFallback::RuleStop,
11192 ));
11193 }
11194 let transition_index =
11195 self.transition_index(state_number, state.transitions().len(), precedence)?;
11196 let transition = state.transitions().get(transition_index).ok_or(
11197 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
11198 )?;
11199 let boundary = match &transition.data() {
11200 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
11201 left_recursive_boundary(self.atn, state, *target)
11202 }
11203 _ => None,
11204 };
11205 Ok((transition, boundary))
11206 }
11207
11208 fn transition_index(
11209 &mut self,
11210 state_number: usize,
11211 transition_count: usize,
11212 precedence: i32,
11213 ) -> DirectAdaptiveParseResult<usize> {
11214 match transition_count {
11215 0 => Err(DirectAdaptiveParseControl::Fallback(
11216 DirectAdaptiveFallback::NoTransition,
11217 )),
11218 1 => Ok(0),
11219 _ => {
11220 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
11221 return Ok(alt);
11222 }
11223 let decision = self
11224 .decision_by_state
11225 .get(state_number)
11226 .and_then(|decision| *decision)
11227 .ok_or(DirectAdaptiveParseControl::Fallback(
11228 DirectAdaptiveFallback::UnknownDecision,
11229 ))?;
11230 let prediction = self
11231 .simulator
11232 .adaptive_predict_stream_info_with_precedence(
11233 decision,
11234 direct_precedence(precedence),
11235 &mut self.parser.input,
11236 )
11237 .map_err(|_| {
11238 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
11239 })?;
11240 if prediction.has_semantic_context {
11241 return Err(DirectAdaptiveParseControl::Fallback(
11242 DirectAdaptiveFallback::SemanticContext,
11243 ));
11244 }
11245 prediction
11246 .alt
11247 .checked_sub(1)
11248 .filter(|index| *index < transition_count)
11249 .ok_or(DirectAdaptiveParseControl::Fallback(
11250 DirectAdaptiveFallback::InvalidAlt,
11251 ))
11252 }
11253 }
11254 }
11255
11256 fn ll1_transition_index(
11257 &mut self,
11258 state_number: usize,
11259 transition_count: usize,
11260 ) -> DirectAdaptiveParseResult<Option<usize>> {
11261 let state = self
11262 .atn
11263 .state(state_number)
11264 .ok_or(DirectAdaptiveParseControl::Fallback(
11265 DirectAdaptiveFallback::MissingAtn,
11266 ))?;
11267 if state.precedence_rule_decision() {
11268 return Ok(None);
11269 }
11270 let Some(rule_stop) = state
11271 .rule_index()
11272 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
11273 else {
11274 return Ok(None);
11275 };
11276 let symbol = self.parser.input.la_token(1);
11277 let entry = self
11278 .parser
11279 .cached_decision_lookahead(self.atn, state, rule_stop);
11280 Ok(
11281 ll1_greedy_alt(&entry, symbol, state.non_greedy())
11282 .filter(|alt| *alt < transition_count),
11283 )
11284 }
11285
11286 fn consume_transition(
11287 &mut self,
11288 transition: ParserTransition<'_>,
11289 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
11290 let symbol = self.parser.input.la_token(1);
11291 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
11292 return Err(DirectAdaptiveParseControl::Fallback(
11293 DirectAdaptiveFallback::TokenMismatch,
11294 ));
11295 }
11296 let token = self
11297 .parser
11298 .input
11299 .lt_id(1)
11300 .ok_or(DirectAdaptiveParseControl::Fallback(
11301 DirectAdaptiveFallback::TokenMismatch,
11302 ))?;
11303 let matched_eof = symbol == TOKEN_EOF;
11304 if !matched_eof {
11305 self.parser.consume();
11306 }
11307 let child = self
11308 .parser
11309 .build_parse_trees
11310 .then(|| self.parser.terminal_tree(token));
11311 Ok((matched_eof, child))
11312 }
11313}
11314
11315fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
11318 if !state.precedence_rule_decision() {
11319 return None;
11320 }
11321 let target_state = atn.state(target)?;
11322 if target_state.kind() == AtnStateKind::LoopEnd {
11323 return None;
11324 }
11325 state.rule_index()
11326}
11327
11328fn next_alt_number(
11335 state: AtnState<'_>,
11336 transition_count: usize,
11337 transition_index: usize,
11338 current_alt_number: usize,
11339 track_alt_numbers: bool,
11340) -> usize {
11341 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
11342 return current_alt_number;
11343 }
11344 if matches!(
11345 state.kind(),
11346 AtnStateKind::Basic
11347 | AtnStateKind::BlockStart
11348 | AtnStateKind::PlusBlockStart
11349 | AtnStateKind::StarBlockStart
11350 | AtnStateKind::StarLoopEntry
11351 ) && !state.precedence_rule_decision()
11352 {
11353 return transition_index + 1;
11354 }
11355 current_alt_number
11356}
11357
11358fn invoking_state_number(state_number: usize) -> isize {
11361 isize::try_from(state_number).unwrap_or(isize::MAX)
11362}
11363
11364const fn packed_i32(value: u32) -> i32 {
11365 i32::from_le_bytes(value.to_le_bytes())
11366}
11367
11368fn direct_precedence(precedence: i32) -> usize {
11369 usize::try_from(precedence.max(0)).unwrap_or_default()
11370}
11371
11372fn token_input_display(token: &impl Token) -> String {
11373 format!("'{}'", token.text().unwrap_or("<EOF>"))
11374}
11375
11376fn display_input_text(text: &str) -> String {
11377 let mut out = String::new();
11378 for ch in text.chars() {
11379 match ch {
11380 '\n' => out.push_str("\\n"),
11381 '\r' => out.push_str("\\r"),
11382 '\t' => out.push_str("\\t"),
11383 other => out.push(other),
11384 }
11385 }
11386 out
11387}
11388
11389fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
11390 let (line, column) = token.map_or((0, 0), |token| (token.line(), token.column()));
11391 ParserDiagnostic {
11392 line,
11393 column,
11394 message,
11395 }
11396}
11397
11398fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
11399 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
11400}
11401
11402fn expected_symbols_display_iter(
11403 symbols: impl IntoIterator<Item = i32>,
11404 vocabulary: &Vocabulary,
11405) -> String {
11406 let items = symbols
11407 .into_iter()
11408 .map(|symbol| expected_symbol_display(symbol, vocabulary))
11409 .collect::<Vec<_>>();
11410 if let [single] = items.as_slice() {
11411 return single.clone();
11412 }
11413 format!("{{{}}}", items.join(", "))
11414}
11415
11416fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
11417 if symbol == TOKEN_EOF {
11418 return "<EOF>".to_owned();
11419 }
11420 vocabulary.display_name(symbol)
11421}
11422
11423fn caller_follow_token_info_for_stream<S: TokenSource>(
11424 input: &mut CommonTokenStream<S>,
11425 index: usize,
11426) -> (i32, bool, bool) {
11427 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
11430 input.fill();
11431 }
11432 let token_type = input.token_type_at_index(index);
11433 let visible_channel = input.channel();
11434 let token = input.get(index);
11435 let is_boundary = token
11436 .as_ref()
11437 .and_then(Token::text)
11438 .is_some_and(is_caller_follow_boundary_text);
11439 let is_boundary_gap = token.as_ref().is_some_and(|token| {
11440 token.channel() != visible_channel || is_caller_follow_boundary_gap_text(token.text())
11441 });
11442 (token_type, is_boundary, is_boundary_gap)
11443}
11444
11445fn is_caller_follow_boundary_text(text: &str) -> bool {
11446 text.chars().any(|ch| ch == ';' || ch == '\n')
11447 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11448}
11449
11450fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
11451 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11452}
11453
11454fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
11458 let Some(rule_index) = state.rule_index() else {
11459 return false;
11460 };
11461 atn.rule_to_start_state()
11462 .get(rule_index)
11463 .and_then(|state_number| atn.state(state_number))
11464 .is_some_and(AtnState::left_recursive_rule)
11465}
11466
11467fn select_better_top_outcome(
11474 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
11475 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
11476 arena: &RecognitionArena,
11477) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
11478 match (first, second) {
11479 (Ok(first), Ok(second)) => {
11480 if arena.diagnostics(first.0.diagnostics).next().is_none() {
11481 Ok(first)
11482 } else {
11483 Ok(second)
11484 }
11485 }
11486 (Ok(first), Err(_)) => Ok(first),
11487 (Err(_), Ok(second)) => Ok(second),
11488 (Err(_), Err(second_expected)) => Err(second_expected),
11489 }
11490}
11491
11492fn select_best_fast_outcome(
11498 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
11499 prediction_mode: PredictionMode,
11500 caller_follow: Option<&TokenBitSet>,
11501 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
11502 arena: &RecognitionArena,
11503) -> Option<FastRecognizeOutcome> {
11504 let mut best = None;
11505 let mut best_caller_follow = None;
11506 for outcome in outcomes {
11507 if matches!(
11508 prediction_mode,
11509 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
11510 ) && outcome.diagnostics.is_empty()
11511 && let Some(follow) = caller_follow
11512 {
11513 let (token_type, is_boundary, _) = token_info_at(outcome.index);
11514 if is_boundary && follow.contains(token_type) {
11515 let replace =
11516 best_caller_follow
11517 .as_ref()
11518 .is_none_or(|existing: &FastRecognizeOutcome| {
11519 (outcome.index, outcome.consumed_eof)
11520 < (existing.index, existing.consumed_eof)
11521 });
11522 if replace {
11523 best_caller_follow = Some(outcome);
11524 }
11525 }
11526 }
11527 let Some(existing) = best else {
11528 best = Some(outcome);
11529 continue;
11530 };
11531 let outcome_position = (outcome.index, outcome.consumed_eof);
11532 let best_position = (existing.index, existing.consumed_eof);
11533 let better = match prediction_mode {
11534 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
11535 outcome_position,
11536 outcome.diagnostics,
11537 best_position,
11538 existing.diagnostics,
11539 arena,
11540 ),
11541 PredictionMode::Sll => outcome.index > existing.index,
11542 };
11543 best = Some(if better { outcome } else { existing });
11544 }
11545 let should_use_caller_follow =
11546 best_caller_follow
11547 .as_ref()
11548 .zip(best.as_ref())
11549 .is_some_and(|(candidate, selected)| {
11550 if !selected.diagnostics.is_empty() {
11551 return true;
11552 }
11553 candidate.index < selected.index
11554 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
11555 });
11556 if should_use_caller_follow {
11557 best_caller_follow
11558 } else {
11559 best
11560 }
11561}
11562
11563fn select_best_outcome(
11564 outcomes: impl Iterator<Item = RecognizeOutcome>,
11565 prediction_mode: PredictionMode,
11566 arena: &RecognitionArena,
11567) -> Option<RecognizeOutcome> {
11568 let outcomes = outcomes.collect::<Vec<_>>();
11569 let prefer_first_tie = outcomes
11570 .iter()
11571 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
11572 outcomes.into_iter().reduce(|best, outcome| {
11573 let outcome_position = (outcome.index, outcome.consumed_eof);
11574 let best_position = (best.index, best.consumed_eof);
11575 let better = match prediction_mode {
11576 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
11577 outcome_is_better(
11578 outcome_position,
11579 outcome.diagnostics,
11580 best_position,
11581 best.diagnostics,
11582 arena,
11583 ) || (!prefer_first_tie
11584 && outcome_position == best_position
11585 && arena.diagnostics_len(outcome.diagnostics)
11586 == arena.diagnostics_len(best.diagnostics)
11587 && arena.diagnostics_recovery_rank(outcome.diagnostics)
11588 == arena.diagnostics_recovery_rank(best.diagnostics)
11589 && (outcome.decisions < best.decisions
11590 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
11591 }
11592 PredictionMode::Sll => {
11593 outcome_position > best_position
11594 || (outcome_position == best_position
11595 && !prefer_first_tie
11596 && (outcome.decisions < best.decisions
11597 || (outcome.decisions == best.decisions
11598 && outcome_is_better(
11599 outcome_position,
11600 outcome.diagnostics,
11601 best_position,
11602 best.diagnostics,
11603 arena,
11604 ))))
11605 }
11606 };
11607 if better {
11608 return outcome;
11609 }
11610 best
11611 })
11612}
11613
11614fn transition_decision(
11621 atn: &Atn,
11622 state: AtnState<'_>,
11623 transition_count: usize,
11624 transition_index: usize,
11625 predicates: &[(usize, usize, ParserPredicate)],
11626) -> Option<usize> {
11627 if transition_count <= 1
11628 || state.precedence_rule_decision()
11629 || decision_reaches_unsupported_predicate(atn, state, predicates)
11630 {
11631 return None;
11632 }
11633 Some(transition_index)
11634}
11635
11636fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
11642 transition_count > 1
11643 && !matches!(
11644 state.kind(),
11645 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
11646 )
11647}
11648
11649fn record_no_viable_if_ambiguous(
11652 expected: &mut ExpectedTokens,
11653 decision_start_index: Option<usize>,
11654 index: usize,
11655) {
11656 if expected.index == Some(index) && expected.symbols.len() > 1 {
11657 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
11658 expected.record_no_viable(decision_start, index);
11659 }
11660 }
11661}
11662
11663const fn record_predicate_no_viable(
11666 expected: &mut ExpectedTokens,
11667 decision_start_index: Option<usize>,
11668 index: usize,
11669) {
11670 if let Some(decision_start) = decision_start_index {
11671 expected.record_no_viable(decision_start, index);
11672 }
11673}
11674
11675const fn no_viable_decision_start(
11677 decision_start_index: Option<usize>,
11678 index: usize,
11679) -> Option<usize> {
11680 match decision_start_index {
11681 Some(start) if index > start => Some(start),
11682 _ => None,
11683 }
11684}
11685
11686fn restore_expected(
11690 children: &[RecognizeOutcome],
11691 child_start_index: usize,
11692 expected: &mut ExpectedTokens,
11693 snapshot: ExpectedTokens,
11694 preserve_child_expected: bool,
11695) {
11696 if preserve_child_expected {
11697 return;
11698 }
11699 if children
11700 .iter()
11701 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
11702 {
11703 *expected = snapshot;
11704 }
11705}
11706
11707fn decision_reaches_unsupported_predicate(
11710 atn: &Atn,
11711 state: AtnState<'_>,
11712 predicates: &[(usize, usize, ParserPredicate)],
11713) -> bool {
11714 state.transitions().iter().any(|transition| {
11715 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
11716 })
11717}
11718
11719fn transition_reaches_unsupported_predicate(
11721 atn: &Atn,
11722 transition: ParserTransition<'_>,
11723 predicates: &[(usize, usize, ParserPredicate)],
11724 visited: &mut BTreeSet<usize>,
11725) -> bool {
11726 match &transition.data() {
11727 Transition::Predicate {
11728 rule_index,
11729 pred_index,
11730 ..
11731 } => !predicates
11732 .iter()
11733 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
11734 Transition::Epsilon { target }
11735 | Transition::Action { target, .. }
11736 | Transition::Rule { target, .. } => {
11737 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
11738 }
11739 Transition::Precedence { .. }
11740 | Transition::Atom { .. }
11741 | Transition::Range { .. }
11742 | Transition::Set { .. }
11743 | Transition::NotSet { .. }
11744 | Transition::Wildcard { .. } => false,
11745 }
11746}
11747
11748fn state_reaches_unsupported_predicate(
11750 atn: &Atn,
11751 state_number: usize,
11752 predicates: &[(usize, usize, ParserPredicate)],
11753 visited: &mut BTreeSet<usize>,
11754) -> bool {
11755 if !visited.insert(state_number) {
11756 return false;
11757 }
11758 let Some(state) = atn.state(state_number) else {
11759 return false;
11760 };
11761 state.transitions().iter().any(|transition| {
11762 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
11763 })
11764}
11765
11766fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
11768 if let Some(decision) = decision {
11769 outcome.decisions.insert(0, decision);
11770 }
11771}
11772
11773fn outcome_is_better(
11774 outcome_position: (usize, bool),
11775 outcome_diagnostics: DiagnosticSeqId,
11776 best_position: (usize, bool),
11777 best_diagnostics: DiagnosticSeqId,
11778 arena: &RecognitionArena,
11779) -> bool {
11780 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
11781 let best_len = arena.diagnostics_len(best_diagnostics);
11782 outcome_position > best_position
11783 || (outcome_position == best_position
11784 && (outcome_len < best_len
11785 || (outcome_len == best_len
11786 && arena.diagnostics_recovery_rank(outcome_diagnostics)
11787 < arena.diagnostics_recovery_rank(best_diagnostics))))
11788}
11789
11790fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
11791 if outcomes
11792 .iter()
11793 .any(|outcome| outcome.diagnostics.is_empty())
11794 {
11795 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
11796 }
11797}
11798
11799fn discard_recovered_outcomes_if_clean_path_exists(
11800 outcomes: &mut Vec<RecognizeOutcome>,
11801 arena: &RecognitionArena,
11802) {
11803 if outcomes
11804 .iter()
11805 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
11806 {
11807 return;
11808 }
11809 if outcomes
11810 .iter()
11811 .any(|outcome| outcome.diagnostics.is_empty())
11812 {
11813 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
11814 }
11815}
11816
11817fn outcome_has_rule_failure_diagnostic(
11820 outcome: &RecognizeOutcome,
11821 arena: &RecognitionArena,
11822) -> bool {
11823 arena
11824 .diagnostics(outcome.diagnostics)
11825 .any(|diagnostic| diagnostic.message.starts_with("rule "))
11826}
11827
11828fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
11842 if outcomes.len() < 2 {
11843 return;
11844 }
11845 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
11846 outcomes.retain(|outcome| {
11847 seen.insert((
11848 outcome.index,
11849 outcome.consumed_eof,
11850 arena.diagnostics_len(outcome.diagnostics),
11851 arena.diagnostics_recovery_rank(outcome.diagnostics),
11852 ))
11853 });
11854}
11855
11856const FAST_OUTCOME_INLINE_KEYS: usize = 8;
11857const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
11858const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
11859const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
11860
11861#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11862enum FastOutcomeDedupStrategy {
11863 Inline,
11864 Dense,
11865 Sparse,
11866}
11867
11868impl FastOutcomeDedupScratch {
11869 fn prepare_dense(&mut self, word_count: usize) {
11870 while let Some(word_index) = self.touched_dense_words.pop() {
11871 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
11872 }
11873 if self.dense_words.len() < word_count {
11874 self.dense_words.resize(word_count, 0);
11875 }
11876 }
11877}
11878
11879fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
11880 let first_index = outcomes.first()?.index;
11881 let (min_index, max_index) = outcomes[1..].iter().fold(
11882 (first_index, first_index),
11883 |(min_index, max_index), outcome| {
11884 (min_index.min(outcome.index), max_index.max(outcome.index))
11885 },
11886 );
11887 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
11888 let bit_count = index_span.checked_mul(2)?;
11889 let word_count =
11890 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
11891 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
11892 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
11893 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
11894 .then_some((min_index, word_count))
11895}
11896
11897#[cfg(feature = "perf-counters")]
11898fn record_clean_fast_outcome_dedup(
11899 strategy: FastOutcomeDedupStrategy,
11900 input_len: usize,
11901 output_len: usize,
11902 dense_words: usize,
11903) {
11904 let counter = match strategy {
11905 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
11906 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
11907 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
11908 };
11909 perf_counters::inc(
11910 &perf_counters::OUTCOME_DEDUPE_INPUTS,
11911 u64::try_from(input_len).unwrap_or(u64::MAX),
11912 );
11913 perf_counters::inc(
11914 &perf_counters::OUTCOME_DEDUPE_REMOVED,
11915 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
11916 );
11917 perf_counters::inc(counter, 1);
11918 perf_counters::inc(
11919 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
11920 u64::try_from(dense_words).unwrap_or(u64::MAX),
11921 );
11922}
11923
11924fn dedupe_clean_fast_outcomes(
11928 outcomes: &mut Vec<FastRecognizeOutcome>,
11929 scratch: &mut FastOutcomeDedupScratch,
11930) -> FastOutcomeDedupStrategy {
11931 #[cfg(feature = "perf-counters")]
11932 let input_len = outcomes.len();
11933 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
11934 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
11935 let mut inline_len = 0_usize;
11936 outcomes.retain(|outcome| {
11937 let key = (outcome.index, outcome.consumed_eof);
11938 if inline_keys[..inline_len].contains(&key) {
11939 return false;
11940 }
11941 inline_keys[inline_len] = key;
11942 inline_len += 1;
11943 true
11944 });
11945 #[cfg(feature = "perf-counters")]
11946 record_clean_fast_outcome_dedup(
11947 FastOutcomeDedupStrategy::Inline,
11948 input_len,
11949 outcomes.len(),
11950 0,
11951 );
11952 return FastOutcomeDedupStrategy::Inline;
11953 }
11954
11955 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
11956 scratch.prepare_dense(word_count);
11957 outcomes.retain(|outcome| {
11958 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
11959 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
11960 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
11961 let word = &mut scratch.dense_words[word_index];
11962 if *word & bit != 0 {
11963 return false;
11964 }
11965 if *word == 0 {
11966 scratch
11967 .touched_dense_words
11968 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
11969 }
11970 *word |= bit;
11971 true
11972 });
11973 #[cfg(feature = "perf-counters")]
11974 record_clean_fast_outcome_dedup(
11975 FastOutcomeDedupStrategy::Dense,
11976 input_len,
11977 outcomes.len(),
11978 word_count,
11979 );
11980 return FastOutcomeDedupStrategy::Dense;
11981 }
11982
11983 scratch.sparse_keys.clear();
11984 scratch.sparse_keys.reserve(outcomes.len());
11985 outcomes.retain(|outcome| {
11986 scratch
11987 .sparse_keys
11988 .insert((outcome.index, outcome.consumed_eof))
11989 });
11990 #[cfg(feature = "perf-counters")]
11991 record_clean_fast_outcome_dedup(
11992 FastOutcomeDedupStrategy::Sparse,
11993 input_len,
11994 outcomes.len(),
11995 0,
11996 );
11997 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
11998 scratch.sparse_keys = FxHashSet::default();
11999 }
12000 FastOutcomeDedupStrategy::Sparse
12001}
12002
12003fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
12006 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
12007 outcomes
12008 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
12009}
12010
12011fn compare_recognize_outcomes(
12012 left: &RecognizeOutcome,
12013 right: &RecognizeOutcome,
12014 arena: &RecognitionArena,
12015) -> Ordering {
12016 left.index
12017 .cmp(&right.index)
12018 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
12019 .then_with(|| left.alt_number.cmp(&right.alt_number))
12020 .then_with(|| left.member_values.cmp(&right.member_values))
12021 .then_with(|| left.return_values.cmp(&right.return_values))
12022 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
12023 .then_with(|| left.decisions.cmp(&right.decisions))
12024 .then_with(|| left.actions.cmp(&right.actions))
12025 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
12026}
12027
12028impl<S, H> Recognizer for BaseParser<S, H>
12029where
12030 S: TokenSource,
12031 H: SemanticHooks,
12032{
12033 fn data(&self) -> &RecognizerData {
12034 &self.data
12035 }
12036
12037 fn data_mut(&mut self) -> &mut RecognizerData {
12038 &mut self.data
12039 }
12040}
12041
12042impl<S, H> Parser for BaseParser<S, H>
12043where
12044 S: TokenSource,
12045 H: SemanticHooks,
12046{
12047 fn build_parse_trees(&self) -> bool {
12048 self.build_parse_trees
12049 }
12050
12051 fn set_build_parse_trees(&mut self, build: bool) {
12052 self.build_parse_trees = build;
12053 }
12054
12055 fn number_of_syntax_errors(&self) -> usize {
12056 Self::number_of_syntax_errors(self)
12057 }
12058
12059 fn report_diagnostic_errors(&self) -> bool {
12060 self.report_diagnostic_errors
12061 }
12062
12063 fn set_report_diagnostic_errors(&mut self, report: bool) {
12064 self.report_diagnostic_errors = report;
12065 }
12066
12067 fn prediction_mode(&self) -> PredictionMode {
12068 self.prediction_mode
12069 }
12070
12071 fn set_prediction_mode(&mut self, mode: PredictionMode) {
12072 self.prediction_mode = mode;
12073 }
12074}
12075
12076#[cfg(test)]
12077mod tests {
12078 use super::*;
12079 use crate::atn::parser::{
12080 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
12081 };
12082 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
12083 use crate::token::{HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError};
12084 use crate::token_stream::CommonTokenStream;
12085 use crate::tree::{NodeKind, ParseTreeStats};
12086 use crate::vocabulary::Vocabulary;
12087 use std::cell::RefCell;
12088 use std::mem::size_of;
12089 use std::rc::Rc;
12090 use std::sync::{Arc, Mutex};
12091
12092 #[test]
12093 fn fx_hasher_write_matches_typed_methods_for_full_words() {
12094 let value: u64 = 0x0102_0304_0506_0708;
12101 let mut typed = FxHasher::default();
12102 typed.write_u64(value);
12103 let mut bytewise = FxHasher::default();
12104 bytewise.write(&value.to_le_bytes());
12105 assert_eq!(typed.finish(), bytewise.finish());
12106 }
12107
12108 #[derive(Clone, Debug)]
12109 struct TestToken {
12110 spec: TokenSpec,
12111 id: TokenId,
12112 source_name: String,
12113 }
12114
12115 impl TestToken {
12116 fn new(token_type: i32) -> Self {
12117 Self {
12118 spec: TokenSpec::explicit(token_type, ""),
12119 id: TokenId::try_from(0).expect("zero token ID"),
12120 source_name: String::new(),
12121 }
12122 }
12123
12124 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
12125 Self {
12126 spec: TokenSpec::eof(index, index, line, column),
12127 id: TokenId::try_from(0).expect("zero token ID"),
12128 source_name: source_name.to_owned(),
12129 }
12130 }
12131
12132 fn with_text(mut self, text: impl Into<String>) -> Self {
12133 self.spec.text = Some(text.into());
12134 self
12135 }
12136
12137 const fn with_channel(mut self, channel: i32) -> Self {
12138 self.spec.channel = channel;
12139 self
12140 }
12141
12142 const fn with_span(mut self, start: usize, stop: usize) -> Self {
12143 self.spec.start = start;
12144 self.spec.stop = stop;
12145 self.spec.start_byte = start;
12146 self.spec.stop_byte = match stop.checked_add(1) {
12147 Some(end) if end >= start => end,
12148 Some(_) | None => start,
12149 };
12150 self
12151 }
12152
12153 const fn with_position(mut self, line: usize, column: usize) -> Self {
12154 self.spec.line = line;
12155 self.spec.column = column;
12156 self
12157 }
12158
12159 fn set_token_index(&mut self, index: isize) {
12160 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
12161 }
12162 }
12163
12164 impl Token for TestToken {
12165 fn token_id(&self) -> TokenId {
12166 self.id
12167 }
12168
12169 fn token_type(&self) -> i32 {
12170 self.spec.token_type
12171 }
12172
12173 fn channel(&self) -> i32 {
12174 self.spec.channel
12175 }
12176
12177 fn start(&self) -> usize {
12178 self.spec.start
12179 }
12180
12181 fn stop(&self) -> usize {
12182 self.spec.stop
12183 }
12184
12185 fn line(&self) -> usize {
12186 self.spec.line
12187 }
12188
12189 fn column(&self) -> usize {
12190 self.spec.column
12191 }
12192
12193 fn text(&self) -> Option<&str> {
12194 self.spec.text.as_deref()
12195 }
12196
12197 fn source_name(&self) -> &str {
12198 &self.source_name
12199 }
12200
12201 fn start_byte(&self) -> usize {
12202 self.spec.start_byte
12203 }
12204
12205 fn stop_byte(&self) -> usize {
12206 self.spec.stop_byte
12207 }
12208 }
12209
12210 #[derive(Debug)]
12211 struct Source {
12212 tokens: Vec<TestToken>,
12213 index: usize,
12214 }
12215
12216 impl TokenSource for Source {
12217 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
12218 let token = self
12219 .tokens
12220 .get(self.index)
12221 .cloned()
12222 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
12223 self.index += 1;
12224 sink.push(token.spec)
12225 }
12226
12227 fn line(&self) -> usize {
12228 1
12229 }
12230
12231 fn column(&self) -> usize {
12232 self.index
12233 }
12234
12235 fn source_name(&self) -> &'static str {
12236 "parser-test"
12237 }
12238 }
12239
12240 #[derive(Clone, Debug, Eq, PartialEq)]
12241 struct RecordedDiagnostic {
12242 grammar_file_name: String,
12243 line: usize,
12244 column: usize,
12245 message: String,
12246 error: Option<AntlrError>,
12247 }
12248
12249 #[derive(Clone, Debug)]
12250 struct RecordingErrorListener {
12251 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
12252 }
12253
12254 impl<R> crate::ErrorListener<R> for RecordingErrorListener
12255 where
12256 R: Recognizer + ?Sized,
12257 {
12258 fn syntax_error(
12259 &mut self,
12260 recognizer: &R,
12261 line: usize,
12262 column: usize,
12263 message: &str,
12264 error: Option<&AntlrError>,
12265 ) {
12266 self.diagnostics
12267 .lock()
12268 .expect("recorded diagnostics lock")
12269 .push(RecordedDiagnostic {
12270 grammar_file_name: recognizer.grammar_file_name().to_owned(),
12271 line,
12272 column,
12273 message: message.to_owned(),
12274 error: error.cloned(),
12275 });
12276 }
12277 }
12278
12279 #[derive(Debug)]
12280 struct ReportingSource {
12281 source: Source,
12282 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
12283 }
12284
12285 impl TokenSource for ReportingSource {
12286 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
12287 self.source.next_token(sink)
12288 }
12289
12290 fn line(&self) -> usize {
12291 self.source.line()
12292 }
12293
12294 fn column(&self) -> usize {
12295 self.source.column()
12296 }
12297
12298 fn source_name(&self) -> &str {
12299 self.source.source_name()
12300 }
12301
12302 fn report_error(&self, error: &TokenSourceError) -> bool {
12303 self.diagnostics.borrow_mut().push(error.clone());
12304 true
12305 }
12306 }
12307
12308 fn mini_parser_data() -> RecognizerData {
12309 RecognizerData::new(
12310 "Mini.g4",
12311 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
12312 )
12313 .with_rule_names(["s"])
12314 }
12315
12316 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
12317 let data = mini_parser_data();
12318 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
12319 }
12320
12321 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
12322 where
12323 H: SemanticHooks,
12324 {
12325 BaseParser::with_semantic_hooks(
12326 CommonTokenStream::new(Source { tokens, index: 0 }),
12327 mini_parser_data(),
12328 hooks,
12329 )
12330 }
12331
12332 #[test]
12333 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
12334 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
12335 parser.remove_error_listeners();
12336 let diagnostics = Arc::new(Mutex::new(Vec::new()));
12337 parser.add_error_listener(RecordingErrorListener {
12338 diagnostics: Arc::clone(&diagnostics),
12339 });
12340 let parser_diagnostics = [ParserDiagnostic {
12341 line: 1,
12342 column: 2,
12343 message: "missing 'x' at 'y'".to_owned(),
12344 }];
12345 let token_errors = [
12346 TokenSourceError::new(1, 1, "token recognition error at: '@'"),
12347 TokenSourceError::new(1, 3, "token recognition error at: '#'"),
12348 ];
12349
12350 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
12351
12352 assert_eq!(
12353 *diagnostics.lock().expect("recorded diagnostics lock"),
12354 [
12355 RecordedDiagnostic {
12356 grammar_file_name: "Mini.g4".to_owned(),
12357 line: 1,
12358 column: 1,
12359 message: "token recognition error at: '@'".to_owned(),
12360 error: None,
12361 },
12362 RecordedDiagnostic {
12363 grammar_file_name: "Mini.g4".to_owned(),
12364 line: 1,
12365 column: 2,
12366 message: "missing 'x' at 'y'".to_owned(),
12367 error: None,
12368 },
12369 RecordedDiagnostic {
12370 grammar_file_name: "Mini.g4".to_owned(),
12371 line: 1,
12372 column: 3,
12373 message: "token recognition error at: '#'".to_owned(),
12374 error: None,
12375 },
12376 ]
12377 );
12378
12379 parser.remove_error_listeners();
12380 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
12381 assert_eq!(
12382 diagnostics.lock().expect("recorded diagnostics lock").len(),
12383 3
12384 );
12385 }
12386
12387 #[test]
12388 fn parser_leaves_token_errors_to_source_owned_listeners() {
12389 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
12390 let source = ReportingSource {
12391 source: Source {
12392 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
12393 index: 0,
12394 },
12395 diagnostics: Rc::clone(&source_diagnostics),
12396 };
12397 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
12398 parser.remove_error_listeners();
12399 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
12400 parser.add_error_listener(RecordingErrorListener {
12401 diagnostics: Arc::clone(&parser_diagnostics),
12402 });
12403 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
12404
12405 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
12406
12407 assert_eq!(*source_diagnostics.borrow(), [source_error]);
12408 assert!(
12409 parser_diagnostics
12410 .lock()
12411 .expect("recorded diagnostics lock")
12412 .is_empty()
12413 );
12414 }
12415
12416 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
12417 builder.finish().expect("valid packed parser ATN")
12418 }
12419
12420 fn nested_rule_chain_atn(depth: usize) -> Atn {
12421 assert!(depth > 0);
12422 let mut atn = ParserAtnBuilder::new(1);
12423 let mut starts = Vec::with_capacity(depth);
12424 let mut stops = Vec::with_capacity(depth);
12425 for rule_index in 0..depth {
12426 starts.push(
12427 atn.add_state(AtnStateKind::RuleStart, Some(rule_index))
12428 .expect("rule start")
12429 .index(),
12430 );
12431 }
12432 for rule_index in 0..depth {
12433 stops.push(
12434 atn.add_state(AtnStateKind::RuleStop, Some(rule_index))
12435 .expect("rule stop")
12436 .index(),
12437 );
12438 }
12439 atn.set_rule_to_start_state(starts.clone())
12440 .expect("rule start states");
12441 atn.set_rule_to_stop_state(stops.clone())
12442 .expect("rule stop states");
12443 for rule_index in 0..depth - 1 {
12444 atn.add_transition(
12445 starts[rule_index],
12446 ParserTransitionSpec::Rule {
12447 target: starts[rule_index + 1],
12448 rule_index: rule_index + 1,
12449 follow_state: stops[rule_index],
12450 precedence: 0,
12451 },
12452 )
12453 .expect("nested rule transition");
12454 }
12455 let token_set = atn.add_interval_set([(1, 1)]).expect("token set");
12456 atn.add_transition(
12457 starts[depth - 1],
12458 ParserTransitionSpec::Set {
12459 target: stops[depth - 1],
12460 set: token_set,
12461 },
12462 )
12463 .expect("terminal set transition");
12464 finish_atn(atn)
12465 }
12466
12467 fn ordinary_star_loop_atn() -> Atn {
12468 let mut atn = ParserAtnBuilder::new(2);
12469 for (state_number, kind, rule_index) in [
12470 (0, AtnStateKind::RuleStart, 0),
12471 (1, AtnStateKind::StarLoopEntry, 0),
12472 (2, AtnStateKind::Basic, 0),
12473 (3, AtnStateKind::StarLoopBack, 0),
12474 (4, AtnStateKind::LoopEnd, 0),
12475 (5, AtnStateKind::Basic, 0),
12476 (6, AtnStateKind::RuleStop, 0),
12477 (7, AtnStateKind::RuleStart, 1),
12478 (8, AtnStateKind::Basic, 1),
12479 (9, AtnStateKind::RuleStop, 1),
12480 ] {
12481 assert_eq!(
12482 atn.add_state(kind, Some(rule_index))
12483 .expect("state")
12484 .index(),
12485 state_number
12486 );
12487 }
12488 atn.set_rule_to_start_state(vec![0, 7])
12489 .expect("rule start states");
12490 atn.set_rule_to_stop_state(vec![6, 9])
12491 .expect("rule stop states");
12492 atn.add_decision_state(1).expect("decision state");
12493 atn.set_loop_back_state(4, 3).expect("loop back state");
12494 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12495 .expect("transition");
12496 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12497 .expect("transition");
12498 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
12499 .expect("transition");
12500 atn.add_transition(
12501 2,
12502 ParserTransitionSpec::Rule {
12503 target: 7,
12504 rule_index: 1,
12505 follow_state: 3,
12506 precedence: 0,
12507 },
12508 )
12509 .expect("transition");
12510 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
12511 .expect("transition");
12512 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12513 .expect("transition");
12514 atn.add_transition(
12515 5,
12516 ParserTransitionSpec::Atom {
12517 target: 6,
12518 label: TOKEN_EOF,
12519 },
12520 )
12521 .expect("transition");
12522 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
12523 .expect("transition");
12524 atn.add_transition(
12525 8,
12526 ParserTransitionSpec::Atom {
12527 target: 9,
12528 label: 1,
12529 },
12530 )
12531 .expect("transition");
12532 finish_atn(atn)
12533 }
12534
12535 fn ambiguous_ordinary_star_loop_atn() -> Atn {
12537 let mut atn = ParserAtnBuilder::new(1);
12538 for (state_number, kind) in [
12539 (0, AtnStateKind::RuleStart),
12540 (1, AtnStateKind::StarLoopEntry),
12541 (2, AtnStateKind::StarBlockStart),
12542 (3, AtnStateKind::Basic),
12543 (4, AtnStateKind::BlockEnd),
12544 (5, AtnStateKind::StarLoopBack),
12545 (6, AtnStateKind::LoopEnd),
12546 (7, AtnStateKind::Basic),
12547 (8, AtnStateKind::RuleStop),
12548 ] {
12549 assert_eq!(
12550 atn.add_state(kind, Some(0)).expect("state").index(),
12551 state_number
12552 );
12553 }
12554 atn.set_rule_to_start_state(vec![0])
12555 .expect("rule start states");
12556 atn.set_rule_to_stop_state(vec![8])
12557 .expect("rule stop states");
12558 atn.set_end_state(2, 4).expect("block end state");
12559 atn.set_loop_back_state(6, 5).expect("loop back state");
12560 atn.add_decision_state(1).expect("decision state");
12561 atn.add_decision_state(2).expect("decision state");
12562 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12563 .expect("transition");
12564 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12565 .expect("transition");
12566 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
12567 .expect("transition");
12568 atn.add_transition(
12569 2,
12570 ParserTransitionSpec::Atom {
12571 target: 4,
12572 label: 1,
12573 },
12574 )
12575 .expect("transition");
12576 atn.add_transition(
12577 2,
12578 ParserTransitionSpec::Atom {
12579 target: 3,
12580 label: 1,
12581 },
12582 )
12583 .expect("transition");
12584 atn.add_transition(
12585 3,
12586 ParserTransitionSpec::Atom {
12587 target: 4,
12588 label: 1,
12589 },
12590 )
12591 .expect("transition");
12592 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12593 .expect("transition");
12594 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
12595 .expect("transition");
12596 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12597 .expect("transition");
12598 atn.add_transition(
12599 7,
12600 ParserTransitionSpec::Atom {
12601 target: 8,
12602 label: TOKEN_EOF,
12603 },
12604 )
12605 .expect("transition");
12606 finish_atn(atn)
12607 }
12608
12609 fn ordinary_plus_loop_atn() -> Atn {
12610 let mut atn = ParserAtnBuilder::new(2);
12611 for (state_number, kind, rule_index) in [
12612 (0, AtnStateKind::RuleStart, 0),
12613 (1, AtnStateKind::Basic, 0),
12614 (2, AtnStateKind::PlusLoopBack, 0),
12615 (3, AtnStateKind::LoopEnd, 0),
12616 (4, AtnStateKind::Basic, 0),
12617 (5, AtnStateKind::RuleStop, 0),
12618 (6, AtnStateKind::RuleStart, 1),
12619 (7, AtnStateKind::Basic, 1),
12620 (8, AtnStateKind::RuleStop, 1),
12621 ] {
12622 assert_eq!(
12623 atn.add_state(kind, Some(rule_index))
12624 .expect("state")
12625 .index(),
12626 state_number
12627 );
12628 }
12629 atn.set_rule_to_start_state(vec![0, 6])
12630 .expect("rule start states");
12631 atn.set_rule_to_stop_state(vec![5, 8])
12632 .expect("rule stop states");
12633 atn.add_decision_state(2).expect("decision state");
12634 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12635 .expect("transition");
12636 atn.add_transition(
12637 1,
12638 ParserTransitionSpec::Rule {
12639 target: 6,
12640 rule_index: 1,
12641 follow_state: 2,
12642 precedence: 0,
12643 },
12644 )
12645 .expect("transition");
12646 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
12647 .expect("transition");
12648 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12649 .expect("transition");
12650 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
12651 .expect("transition");
12652 atn.add_transition(
12653 4,
12654 ParserTransitionSpec::Atom {
12655 target: 5,
12656 label: TOKEN_EOF,
12657 },
12658 )
12659 .expect("transition");
12660 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12661 .expect("transition");
12662 atn.add_transition(
12663 7,
12664 ParserTransitionSpec::Atom {
12665 target: 8,
12666 label: 1,
12667 },
12668 )
12669 .expect("transition");
12670 finish_atn(atn)
12671 }
12672
12673 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
12674 let mut tokens = (0..count)
12675 .map(|_| TestToken::new(1).with_text("x"))
12676 .collect::<Vec<_>>();
12677 tokens.push(TestToken::eof("parser-test", count, 1, count));
12678 tokens
12679 }
12680
12681 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
12682 let mut atn = ParserAtnBuilder::new(2);
12683 assert_eq!(
12684 atn.add_state(AtnStateKind::RuleStart, Some(0))
12685 .expect("state")
12686 .index(),
12687 0
12688 );
12689 assert_eq!(
12690 atn.add_state(AtnStateKind::Basic, Some(0))
12691 .expect("state")
12692 .index(),
12693 1
12694 );
12695 assert_eq!(
12696 atn.add_state(AtnStateKind::Basic, Some(0))
12697 .expect("state")
12698 .index(),
12699 2
12700 );
12701 assert_eq!(
12702 atn.add_state(AtnStateKind::RuleStart, Some(1))
12703 .expect("state")
12704 .index(),
12705 3
12706 );
12707 atn.set_left_recursive_rule(3)
12708 .expect("left-recursive rule start");
12709 assert_eq!(
12710 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
12711 .expect("state")
12712 .index(),
12713 4
12714 );
12715 atn.set_precedence_rule_decision(4)
12716 .expect("precedence decision");
12717 assert_eq!(
12718 atn.add_state(AtnStateKind::Basic, Some(1))
12719 .expect("state")
12720 .index(),
12721 5
12722 );
12723 assert_eq!(
12724 atn.add_state(AtnStateKind::Basic, Some(1))
12725 .expect("state")
12726 .index(),
12727 6
12728 );
12729 assert_eq!(
12730 atn.add_state(AtnStateKind::LoopEnd, Some(1))
12731 .expect("state")
12732 .index(),
12733 7
12734 );
12735 assert_eq!(
12736 atn.add_state(AtnStateKind::RuleStop, Some(1))
12737 .expect("state")
12738 .index(),
12739 8
12740 );
12741 assert_eq!(
12742 atn.add_state(AtnStateKind::RuleStop, Some(0))
12743 .expect("state")
12744 .index(),
12745 9
12746 );
12747 atn.set_rule_to_start_state(vec![0, 3])
12748 .expect("rule start states");
12749 atn.set_rule_to_stop_state(vec![9, 8])
12750 .expect("rule stop states");
12751 atn.add_transition(
12752 1,
12753 ParserTransitionSpec::Rule {
12754 target: 3,
12755 rule_index: 1,
12756 follow_state: 2,
12757 precedence: 0,
12758 },
12759 )
12760 .expect("transition");
12761 atn.add_transition(
12762 2,
12763 ParserTransitionSpec::Atom {
12764 target: 9,
12765 label: caller_symbol,
12766 },
12767 )
12768 .expect("transition");
12769 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12770 .expect("transition");
12771 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
12772 .expect("transition");
12773 atn.add_transition(
12774 5,
12775 ParserTransitionSpec::Precedence {
12776 target: 6,
12777 precedence: 1,
12778 },
12779 )
12780 .expect("transition");
12781 atn.add_transition(
12782 6,
12783 ParserTransitionSpec::Atom {
12784 target: 4,
12785 label: 1,
12786 },
12787 )
12788 .expect("transition");
12789 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
12790 .expect("transition");
12791 finish_atn(atn)
12792 }
12793
12794 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
12795 let mut parser = mini_parser(vec![
12796 TestToken::new(symbol).with_text("lookahead"),
12797 TestToken::eof("parser-test", 1, 1, 1),
12798 ]);
12799 parser.rule_context_stack = vec![
12800 RuleContextFrame {
12801 rule_index: 0,
12802 invoking_state: -1,
12803 },
12804 RuleContextFrame {
12805 rule_index: 1,
12806 invoking_state: 1,
12807 },
12808 ];
12809 parser
12810 }
12811
12812 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
12813 let mut atn = ParserAtnBuilder::new(1);
12817 for (state, kind, rule) in [
12818 (0, AtnStateKind::RuleStart, 0),
12819 (1, AtnStateKind::StarLoopEntry, 0),
12820 (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),
12827 (9, AtnStateKind::RuleStop, 0),
12828 ] {
12829 assert_eq!(
12830 atn.add_state(kind, Some(rule)).expect("state").index(),
12831 state
12832 );
12833 if state == 0 {
12834 atn.set_left_recursive_rule(state)
12835 .expect("left-recursive rule start");
12836 } else if state == 1 {
12837 atn.set_precedence_rule_decision(state)
12838 .expect("precedence decision");
12839 }
12840 }
12841 atn.set_rule_to_start_state(vec![0])
12842 .expect("rule start states");
12843 atn.set_rule_to_stop_state(vec![9])
12844 .expect("rule stop states");
12845 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12846 .expect("ops");
12847 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
12848 .expect("exit");
12849 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12850 .expect("to shift");
12851 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
12852 .expect("to rel");
12853 atn.add_transition(
12854 3,
12855 ParserTransitionSpec::Precedence {
12856 target: 4,
12857 precedence: 2,
12858 },
12859 )
12860 .expect("shift prec");
12861 atn.add_transition(
12862 4,
12863 ParserTransitionSpec::Atom {
12864 target: 5,
12865 label: 1,
12866 },
12867 )
12868 .expect("shift first >");
12869 atn.add_transition(
12870 5,
12871 ParserTransitionSpec::Atom {
12872 target: 1,
12873 label: 1,
12874 },
12875 )
12876 .expect("shift second >");
12877 atn.add_transition(
12878 6,
12879 ParserTransitionSpec::Precedence {
12880 target: 7,
12881 precedence: 1,
12882 },
12883 )
12884 .expect("rel prec");
12885 atn.add_transition(
12886 7,
12887 ParserTransitionSpec::Atom {
12888 target: 1,
12889 label: 1,
12890 },
12891 )
12892 .expect("rel >");
12893 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
12894 .expect("loop end");
12895 finish_atn(atn)
12896 }
12897
12898 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
12899 let mut atn = ParserAtnBuilder::new(2);
12900 for (state, kind, rule) in [
12901 (0, AtnStateKind::RuleStart, 0),
12902 (1, AtnStateKind::StarLoopEntry, 0),
12903 (2, AtnStateKind::Basic, 0),
12904 (3, AtnStateKind::Basic, 0),
12905 (4, AtnStateKind::Basic, 0),
12906 (5, AtnStateKind::Basic, 0),
12907 (6, AtnStateKind::Basic, 0),
12908 (7, AtnStateKind::Basic, 0),
12909 (8, AtnStateKind::LoopEnd, 0),
12910 (9, AtnStateKind::RuleStop, 0),
12911 (10, AtnStateKind::RuleStart, 1),
12912 (11, AtnStateKind::Basic, 1),
12913 (12, AtnStateKind::RuleStop, 1),
12914 ] {
12915 assert_eq!(
12916 atn.add_state(kind, Some(rule)).expect("state").index(),
12917 state
12918 );
12919 if state == 0 {
12920 atn.set_left_recursive_rule(state)
12921 .expect("left-recursive rule start");
12922 } else if state == 1 {
12923 atn.set_precedence_rule_decision(state)
12924 .expect("precedence decision");
12925 }
12926 }
12927 atn.set_rule_to_start_state(vec![0, 10])
12928 .expect("rule start states");
12929 atn.set_rule_to_stop_state(vec![9, 12])
12930 .expect("rule stop states");
12931 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12932 .expect("ops");
12933 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
12934 .expect("exit");
12935 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12936 .expect("to shift");
12937 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
12938 .expect("to relational");
12939 atn.add_transition(
12940 3,
12941 ParserTransitionSpec::Precedence {
12942 target: 4,
12943 precedence: 2,
12944 },
12945 )
12946 .expect("shift precedence");
12947 atn.add_transition(
12948 4,
12949 ParserTransitionSpec::Rule {
12950 target: 10,
12951 rule_index: 1,
12952 follow_state: 5,
12953 precedence: 0,
12954 },
12955 )
12956 .expect("first shift token helper");
12957 atn.add_transition(
12958 5,
12959 ParserTransitionSpec::Atom {
12960 target: 1,
12961 label: 1,
12962 },
12963 )
12964 .expect("second shift token");
12965 atn.add_transition(
12966 6,
12967 ParserTransitionSpec::Precedence {
12968 target: 7,
12969 precedence: 1,
12970 },
12971 )
12972 .expect("relational precedence");
12973 atn.add_transition(
12974 7,
12975 ParserTransitionSpec::Atom {
12976 target: 1,
12977 label: 1,
12978 },
12979 )
12980 .expect("relational token");
12981 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
12982 .expect("loop end");
12983 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
12984 .expect("helper entry");
12985 atn.add_transition(
12986 11,
12987 ParserTransitionSpec::Atom {
12988 target: 12,
12989 label: 1,
12990 },
12991 )
12992 .expect("first shift token");
12993 finish_atn(atn)
12994 }
12995
12996 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
12997 let mut atn = ParserAtnBuilder::new(1);
12998 for (state, kind) in [
12999 (0, AtnStateKind::RuleStart),
13000 (1, AtnStateKind::StarLoopEntry),
13001 (2, AtnStateKind::Basic),
13002 (3, AtnStateKind::Basic),
13003 (4, AtnStateKind::Basic),
13004 (5, AtnStateKind::Basic),
13005 (6, AtnStateKind::Basic),
13006 (7, AtnStateKind::Basic),
13007 (8, AtnStateKind::Basic),
13008 (9, AtnStateKind::LoopEnd),
13009 (10, AtnStateKind::RuleStop),
13010 ] {
13011 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13012 if state == 0 {
13013 atn.set_left_recursive_rule(state)
13014 .expect("left-recursive rule start");
13015 } else if state == 1 {
13016 atn.set_precedence_rule_decision(state)
13017 .expect("precedence decision");
13018 }
13019 }
13020 atn.set_rule_to_start_state(vec![0])
13021 .expect("rule start states");
13022 atn.set_rule_to_stop_state(vec![10])
13023 .expect("rule stop states");
13024 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13025 .expect("ops");
13026 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
13027 .expect("exit");
13028 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13029 .expect("to multi-token operator");
13030 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13031 .expect("to predicate operator");
13032 atn.add_transition(
13033 3,
13034 ParserTransitionSpec::Precedence {
13035 target: 4,
13036 precedence: 2,
13037 },
13038 )
13039 .expect("multi-token precedence");
13040 atn.add_transition(
13041 4,
13042 ParserTransitionSpec::Atom {
13043 target: 5,
13044 label: 1,
13045 },
13046 )
13047 .expect("multi-token first");
13048 atn.add_transition(
13049 5,
13050 ParserTransitionSpec::Atom {
13051 target: 1,
13052 label: 1,
13053 },
13054 )
13055 .expect("multi-token second");
13056 atn.add_transition(
13057 6,
13058 ParserTransitionSpec::Precedence {
13059 target: 7,
13060 precedence: 2,
13061 },
13062 )
13063 .expect("predicate precedence");
13064 atn.add_transition(
13065 7,
13066 ParserTransitionSpec::Predicate {
13067 target: 8,
13068 rule_index: 0,
13069 pred_index: 0,
13070 context_dependent: false,
13071 },
13072 )
13073 .expect("operator predicate");
13074 atn.add_transition(
13075 8,
13076 ParserTransitionSpec::Atom {
13077 target: 1,
13078 label: 1,
13079 },
13080 )
13081 .expect("predicate single token");
13082 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13083 .expect("loop end");
13084 finish_atn(atn)
13085 }
13086
13087 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
13088 let mut atn = ParserAtnBuilder::new(2);
13089 for (state, kind, rule) in [
13090 (0, AtnStateKind::RuleStart, 0),
13091 (1, AtnStateKind::StarLoopEntry, 0),
13092 (2, AtnStateKind::Basic, 0),
13093 (3, AtnStateKind::Basic, 0),
13094 (4, AtnStateKind::Basic, 0),
13095 (5, AtnStateKind::LoopEnd, 0),
13096 (6, AtnStateKind::RuleStop, 0),
13097 (7, AtnStateKind::RuleStart, 1),
13098 (8, AtnStateKind::RuleStop, 1),
13099 (9, AtnStateKind::Basic, 1),
13100 ] {
13101 assert_eq!(
13102 atn.add_state(kind, Some(rule)).expect("state").index(),
13103 state
13104 );
13105 if state == 0 {
13106 atn.set_left_recursive_rule(state)
13107 .expect("left-recursive rule start");
13108 } else if state == 1 {
13109 atn.set_precedence_rule_decision(state)
13110 .expect("precedence decision");
13111 }
13112 }
13113 atn.set_rule_to_start_state(vec![0, 7])
13114 .expect("rule start states");
13115 atn.set_rule_to_stop_state(vec![6, 8])
13116 .expect("rule stop states");
13117 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13118 .expect("transition");
13119 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
13120 .expect("transition");
13121 atn.add_transition(
13122 2,
13123 ParserTransitionSpec::Precedence {
13124 target: 3,
13125 precedence: 3,
13126 },
13127 )
13128 .expect("transition");
13129 atn.add_transition(
13130 3,
13131 ParserTransitionSpec::Rule {
13132 target: 7,
13133 rule_index: 1,
13134 follow_state: 4,
13135 precedence: 0,
13136 },
13137 )
13138 .expect("transition");
13139 atn.add_transition(
13140 4,
13141 ParserTransitionSpec::Atom {
13142 target: 1,
13143 label: 1,
13144 },
13145 )
13146 .expect("transition");
13147 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13148 .expect("transition");
13149 atn.add_transition(
13150 7,
13151 ParserTransitionSpec::Precedence {
13152 target: 9,
13153 precedence: 1,
13154 },
13155 )
13156 .expect("transition");
13157 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
13158 .expect("transition");
13159 finish_atn(atn)
13160 }
13161
13162 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
13163 let mut atn = ParserAtnBuilder::new(2);
13164 for (state, kind) in [
13165 (0, AtnStateKind::RuleStart),
13166 (1, AtnStateKind::StarLoopEntry),
13167 (2, AtnStateKind::Basic),
13168 (3, AtnStateKind::Basic),
13169 (4, AtnStateKind::Basic),
13170 (5, AtnStateKind::LoopEnd),
13171 (6, AtnStateKind::RuleStop),
13172 ] {
13173 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13174 if state == 0 {
13175 atn.set_left_recursive_rule(state)
13176 .expect("left-recursive rule start");
13177 } else if state == 1 {
13178 atn.set_precedence_rule_decision(state)
13179 .expect("precedence decision");
13180 }
13181 }
13182 atn.set_rule_to_start_state(vec![0])
13183 .expect("rule start states");
13184 atn.set_rule_to_stop_state(vec![6])
13185 .expect("rule stop states");
13186 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13187 .expect("transition");
13188 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
13189 .expect("transition");
13190 atn.add_transition(
13191 2,
13192 ParserTransitionSpec::Precedence {
13193 target: 3,
13194 precedence: 1,
13195 },
13196 )
13197 .expect("transition");
13198 atn.add_transition(
13199 3,
13200 ParserTransitionSpec::Predicate {
13201 target: 4,
13202 rule_index: 0,
13203 pred_index: 0,
13204 context_dependent: false,
13205 },
13206 )
13207 .expect("transition");
13208 atn.add_transition(
13209 4,
13210 ParserTransitionSpec::Atom {
13211 target: 1,
13212 label: 1,
13213 },
13214 )
13215 .expect("transition");
13216 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13217 .expect("transition");
13218 finish_atn(atn)
13219 }
13220
13221 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
13222 let mut atn = ParserAtnBuilder::new(2);
13223 for (state, kind, rule) in [
13224 (0, AtnStateKind::RuleStart, 0),
13225 (1, AtnStateKind::Basic, 0),
13226 (2, AtnStateKind::Basic, 0),
13227 (3, AtnStateKind::Basic, 0),
13228 (4, AtnStateKind::RuleStop, 0),
13229 (5, AtnStateKind::RuleStart, 1),
13230 (6, AtnStateKind::StarLoopEntry, 1),
13231 (7, AtnStateKind::Basic, 1),
13232 (8, AtnStateKind::Basic, 1),
13233 (9, AtnStateKind::LoopEnd, 1),
13234 (10, AtnStateKind::RuleStop, 1),
13235 (11, AtnStateKind::RuleStart, 2),
13236 (12, AtnStateKind::RuleStop, 2),
13237 ] {
13238 assert_eq!(
13239 atn.add_state(kind, Some(rule)).expect("state").index(),
13240 state
13241 );
13242 if state == 5 {
13243 atn.set_left_recursive_rule(state)
13244 .expect("left-recursive rule start");
13245 } else if state == 6 {
13246 atn.set_precedence_rule_decision(state)
13247 .expect("precedence decision");
13248 }
13249 }
13250 atn.set_rule_to_start_state(vec![0, 5, 11])
13251 .expect("rule start states");
13252 atn.set_rule_to_stop_state(vec![4, 10, 12])
13253 .expect("rule stop states");
13254 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13255 .expect("transition");
13256 atn.add_transition(
13257 1,
13258 ParserTransitionSpec::Rule {
13259 target: 5,
13260 rule_index: 1,
13261 follow_state: 2,
13262 precedence: 0,
13263 },
13264 )
13265 .expect("transition");
13266 atn.add_transition(
13267 2,
13268 ParserTransitionSpec::Rule {
13269 target: 11,
13270 rule_index: 2,
13271 follow_state: 3,
13272 precedence: 0,
13273 },
13274 )
13275 .expect("transition");
13276 atn.add_transition(
13277 3,
13278 ParserTransitionSpec::Atom {
13279 target: 4,
13280 label: caller_symbol,
13281 },
13282 )
13283 .expect("transition");
13284 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13285 .expect("transition");
13286 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
13287 .expect("transition");
13288 atn.add_transition(
13289 7,
13290 ParserTransitionSpec::Precedence {
13291 target: 8,
13292 precedence: 1,
13293 },
13294 )
13295 .expect("transition");
13296 atn.add_transition(
13297 8,
13298 ParserTransitionSpec::Atom {
13299 target: 6,
13300 label: 1,
13301 },
13302 )
13303 .expect("transition");
13304 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13305 .expect("transition");
13306 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
13307 .expect("transition");
13308 finish_atn(atn)
13309 }
13310
13311 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
13312 let mut atn = ParserAtnBuilder::new(2);
13313 for (state, kind, rule) in [
13314 (0, AtnStateKind::RuleStart, 0),
13315 (1, AtnStateKind::Basic, 0),
13316 (2, AtnStateKind::Basic, 0),
13317 (3, AtnStateKind::RuleStop, 0),
13318 (4, AtnStateKind::RuleStart, 1),
13319 (5, AtnStateKind::Basic, 1),
13320 (6, AtnStateKind::Basic, 1),
13321 (7, AtnStateKind::RuleStop, 1),
13322 (8, AtnStateKind::RuleStart, 2),
13323 (9, AtnStateKind::StarLoopEntry, 2),
13324 (10, AtnStateKind::Basic, 2),
13325 (11, AtnStateKind::Basic, 2),
13326 (12, AtnStateKind::LoopEnd, 2),
13327 (13, AtnStateKind::RuleStop, 2),
13328 ] {
13329 assert_eq!(
13330 atn.add_state(kind, Some(rule)).expect("state").index(),
13331 state
13332 );
13333 if state == 8 {
13334 atn.set_left_recursive_rule(state)
13335 .expect("left-recursive rule start");
13336 } else if state == 9 {
13337 atn.set_precedence_rule_decision(state)
13338 .expect("precedence decision");
13339 }
13340 }
13341 atn.set_rule_to_start_state(vec![0, 4, 8])
13342 .expect("rule start states");
13343 atn.set_rule_to_stop_state(vec![3, 7, 13])
13344 .expect("rule stop states");
13345 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13346 .expect("transition");
13347 atn.add_transition(
13348 1,
13349 ParserTransitionSpec::Rule {
13350 target: 4,
13351 rule_index: 1,
13352 follow_state: 2,
13353 precedence: 0,
13354 },
13355 )
13356 .expect("transition");
13357 atn.add_transition(
13358 2,
13359 ParserTransitionSpec::Atom {
13360 target: 3,
13361 label: caller_symbol,
13362 },
13363 )
13364 .expect("transition");
13365 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13366 .expect("transition");
13367 atn.add_transition(
13368 5,
13369 ParserTransitionSpec::Rule {
13370 target: 8,
13371 rule_index: 2,
13372 follow_state: 6,
13373 precedence: 0,
13374 },
13375 )
13376 .expect("transition");
13377 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13378 .expect("transition");
13379 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13380 .expect("transition");
13381 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
13382 .expect("transition");
13383 atn.add_transition(
13384 10,
13385 ParserTransitionSpec::Precedence {
13386 target: 11,
13387 precedence: 1,
13388 },
13389 )
13390 .expect("transition");
13391 atn.add_transition(
13392 11,
13393 ParserTransitionSpec::Atom {
13394 target: 9,
13395 label: 1,
13396 },
13397 )
13398 .expect("transition");
13399 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
13400 .expect("transition");
13401 finish_atn(atn)
13402 }
13403
13404 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
13405 let mut atn = ParserAtnBuilder::new(2);
13406 for (state, kind, rule) in [
13407 (0, AtnStateKind::RuleStart, 0),
13408 (1, AtnStateKind::Basic, 0),
13409 (2, AtnStateKind::Basic, 0),
13410 (3, AtnStateKind::RuleStop, 0),
13411 (4, AtnStateKind::RuleStart, 1),
13412 (5, AtnStateKind::StarLoopEntry, 1),
13413 (6, AtnStateKind::Basic, 1),
13414 (7, AtnStateKind::Basic, 1),
13415 (8, AtnStateKind::Basic, 1),
13416 (9, AtnStateKind::Basic, 1),
13417 (10, AtnStateKind::LoopEnd, 1),
13418 (11, AtnStateKind::RuleStop, 1),
13419 ] {
13420 assert_eq!(
13421 atn.add_state(kind, Some(rule)).expect("state").index(),
13422 state
13423 );
13424 if state == 4 {
13425 atn.set_left_recursive_rule(state)
13426 .expect("left-recursive rule start");
13427 } else if state == 5 {
13428 atn.set_precedence_rule_decision(state)
13429 .expect("precedence decision");
13430 }
13431 }
13432 atn.set_rule_to_start_state(vec![0, 4])
13433 .expect("rule start states");
13434 atn.set_rule_to_stop_state(vec![3, 11])
13435 .expect("rule stop states");
13436 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13437 .expect("transition");
13438 atn.add_transition(
13439 1,
13440 ParserTransitionSpec::Rule {
13441 target: 4,
13442 rule_index: 1,
13443 follow_state: 2,
13444 precedence: 0,
13445 },
13446 )
13447 .expect("transition");
13448 atn.add_transition(
13449 2,
13450 ParserTransitionSpec::Atom {
13451 target: 3,
13452 label: caller_symbol,
13453 },
13454 )
13455 .expect("transition");
13456 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13457 .expect("transition");
13458 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
13459 .expect("transition");
13460 atn.add_transition(
13461 6,
13462 ParserTransitionSpec::Precedence {
13463 target: 7,
13464 precedence: 1,
13465 },
13466 )
13467 .expect("transition");
13468 atn.add_transition(
13469 7,
13470 ParserTransitionSpec::Atom {
13471 target: 8,
13472 label: 1,
13473 },
13474 )
13475 .expect("transition");
13476 atn.add_transition(
13477 8,
13478 ParserTransitionSpec::Rule {
13479 target: 4,
13480 rule_index: 1,
13481 follow_state: 9,
13482 precedence: 2,
13483 },
13484 )
13485 .expect("transition");
13486 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
13487 .expect("transition");
13488 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
13489 .expect("transition");
13490 finish_atn(atn)
13491 }
13492
13493 #[test]
13494 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
13495 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
13496 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
13497
13498 let mut overlapping = parser_inside_left_recursive_callee(1);
13499 assert_eq!(
13500 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
13501 None
13502 );
13503
13504 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
13505 assert_eq!(
13506 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13507 Some(true)
13508 );
13509
13510 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
13511 assert_eq!(
13512 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13513 Some(false)
13514 );
13515
13516 assert_eq!(
13517 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13518 Some(true),
13519 "overlap results must not leak across ATNs"
13520 );
13521 }
13522
13523 #[test]
13524 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
13525 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
13526 let mut parser = mini_parser(vec![
13527 TestToken::new(1).with_text("operator"),
13528 TestToken::eof("parser-test", 1, 1, 1),
13529 ]);
13530 parser.rule_context_stack = vec![RuleContextFrame {
13531 rule_index: 0,
13532 invoking_state: -1,
13533 }];
13534
13535 assert_eq!(
13536 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13537 Some(true)
13538 );
13539 assert_eq!(
13540 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13541 Some(true),
13542 "cached operator lookahead must preserve the nullable prefix return path"
13543 );
13544 assert_eq!(
13545 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13546 Some(true),
13547 "the nullable child must use its rule-call precedence, not the caller precedence"
13548 );
13549 }
13550
13551 #[test]
13552 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
13553 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
13558 let mut parser = mini_parser(vec![
13559 TestToken::new(1).with_text(">"),
13560 TestToken::new(2).with_text("id"),
13561 TestToken::eof("parser-test", 1, 1, 1),
13562 ]);
13563 parser.rule_context_stack = vec![RuleContextFrame {
13564 rule_index: 0,
13565 invoking_state: -1,
13566 }];
13567
13568 assert_eq!(
13569 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13570 Some(true),
13571 "at low precedence relational `>` is a single-token operator"
13572 );
13573 assert_eq!(
13574 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
13575 Some(true),
13576 "relational remains single-token at its own precedence"
13577 );
13578 assert_eq!(
13579 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13580 None,
13581 "at shift precedence, bare `>` must not force enter"
13582 );
13583 }
13584
13585 #[test]
13586 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
13587 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
13588 let mut parser = mini_parser(vec![
13589 TestToken::new(1).with_text(">"),
13590 TestToken::new(2).with_text("id"),
13591 TestToken::eof("parser-test", 1, 1, 1),
13592 ]);
13593 parser.rule_context_stack = vec![RuleContextFrame {
13594 rule_index: 0,
13595 invoking_state: -1,
13596 }];
13597
13598 assert_eq!(
13599 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13600 Some(true),
13601 "the direct relational alternative remains a one-token operator"
13602 );
13603 assert_eq!(
13604 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13605 None,
13606 "a token matched in the helper rule must return to the second shift token"
13607 );
13608 }
13609
13610 #[test]
13611 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
13612 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
13613 let mut parser = mini_parser(vec![
13614 TestToken::new(1).with_text(">"),
13615 TestToken::new(2).with_text("id"),
13616 TestToken::eof("parser-test", 1, 1, 1),
13617 ]);
13618 parser.rule_context_stack = vec![RuleContextFrame {
13619 rule_index: 0,
13620 invoking_state: -1,
13621 }];
13622
13623 assert_eq!(
13624 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13625 None,
13626 "a predicate-gated single-token path must not be hidden by a multi-token path"
13627 );
13628 }
13629
13630 #[test]
13631 fn left_recursive_loop_defers_predicate_guarded_operator() {
13632 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
13633 let mut parser = mini_parser_with_hooks(
13634 vec![
13635 TestToken::new(1).with_text("operator"),
13636 TestToken::eof("parser-test", 1, 1, 1),
13637 ],
13638 RejectingPredicateHooks::default(),
13639 );
13640 parser.rule_context_stack = vec![RuleContextFrame {
13641 rule_index: 0,
13642 invoking_state: -1,
13643 }];
13644
13645 assert_eq!(
13646 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13647 None,
13648 "a false predicate must be evaluated before entering the operator alternative"
13649 );
13650 assert_eq!(
13651 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13652 None,
13653 "cached predicate-dependent lookahead must keep deferring"
13654 );
13655 }
13656
13657 #[test]
13658 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
13659 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
13660 let mut parser = parser_inside_left_recursive_callee(1);
13661
13662 assert_eq!(
13663 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
13664 None
13665 );
13666 assert_eq!(
13667 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
13668 None,
13669 "the cached overlap must preserve the nullable child return path"
13670 );
13671 }
13672
13673 #[test]
13674 fn left_recursive_loop_defers_through_nullable_parent_return() {
13675 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
13676 let mut parser = mini_parser(vec![
13677 TestToken::new(1).with_text("lookahead"),
13678 TestToken::eof("parser-test", 1, 1, 1),
13679 ]);
13680 parser.rule_context_stack = vec![
13681 RuleContextFrame {
13682 rule_index: 0,
13683 invoking_state: -1,
13684 },
13685 RuleContextFrame {
13686 rule_index: 1,
13687 invoking_state: 1,
13688 },
13689 RuleContextFrame {
13690 rule_index: 2,
13691 invoking_state: 5,
13692 },
13693 ];
13694
13695 assert_eq!(
13696 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
13697 None,
13698 "a nullable caller must unwind to its parent's consuming follow path"
13699 );
13700 assert_eq!(
13701 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
13702 None,
13703 "the caller-overlap cache must not retain a false negative"
13704 );
13705 }
13706
13707 #[test]
13708 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
13709 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
13710 let mut parser = mini_parser(vec![
13711 TestToken::new(1).with_text("lookahead"),
13712 TestToken::eof("parser-test", 1, 1, 1),
13713 ]);
13714 parser.rule_context_stack = vec![
13715 RuleContextFrame {
13716 rule_index: 0,
13717 invoking_state: -1,
13718 },
13719 RuleContextFrame {
13720 rule_index: 1,
13721 invoking_state: 1,
13722 },
13723 RuleContextFrame {
13724 rule_index: 1,
13725 invoking_state: 8,
13726 },
13727 ];
13728
13729 assert_eq!(
13730 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
13731 None,
13732 "a recursive operand return must preserve its parent caller context"
13733 );
13734 assert_eq!(
13735 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
13736 None,
13737 "the caller-overlap cache must preserve the loop-boundary return"
13738 );
13739 }
13740
13741 fn token_then_eof_atn() -> Atn {
13742 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13743 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, ]))
13759 .deserialize_parser()
13760 .expect("artificial parser ATN should deserialize")
13761 }
13762
13763 fn epsilon_cycle_atn() -> Atn {
13764 let mut atn = ParserAtnBuilder::new(1);
13765 for (state_number, kind) in [
13766 (0, AtnStateKind::RuleStart),
13767 (1, AtnStateKind::Basic),
13768 (2, AtnStateKind::RuleStop),
13769 ] {
13770 assert_eq!(
13771 atn.add_state(kind, Some(0)).expect("state").index(),
13772 state_number
13773 );
13774 }
13775 atn.set_rule_to_start_state(vec![0])
13776 .expect("rule start states");
13777 atn.set_rule_to_stop_state(vec![2])
13778 .expect("rule stop states");
13779 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13780 .expect("transition");
13781 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
13782 .expect("self-cycle transition");
13783 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13784 .expect("exit transition");
13785 finish_atn(atn)
13786 }
13787
13788 fn eof_then_action_atn() -> Atn {
13789 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13790 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, ]))
13806 .deserialize_parser()
13807 .expect("artificial parser ATN should deserialize")
13808 }
13809
13810 fn noop_action_then_token_then_eof_atn() -> Atn {
13811 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13812 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, ]))
13830 .deserialize_parser()
13831 .expect("artificial no-op action ATN should deserialize")
13832 }
13833
13834 fn two_alt_decision_atn() -> Atn {
13835 let mut atn = ParserAtnBuilder::new(2);
13836 assert_eq!(
13837 atn.add_state(AtnStateKind::RuleStart, Some(0))
13838 .expect("state")
13839 .index(),
13840 0
13841 );
13842 assert_eq!(
13843 atn.add_state(AtnStateKind::BlockStart, Some(0))
13844 .expect("state")
13845 .index(),
13846 1
13847 );
13848 assert_eq!(
13849 atn.add_state(AtnStateKind::Basic, Some(0))
13850 .expect("state")
13851 .index(),
13852 2
13853 );
13854 assert_eq!(
13855 atn.add_state(AtnStateKind::Basic, Some(0))
13856 .expect("state")
13857 .index(),
13858 3
13859 );
13860 assert_eq!(
13861 atn.add_state(AtnStateKind::BlockEnd, Some(0))
13862 .expect("state")
13863 .index(),
13864 4
13865 );
13866 assert_eq!(
13867 atn.add_state(AtnStateKind::RuleStop, Some(0))
13868 .expect("state")
13869 .index(),
13870 5
13871 );
13872 atn.set_rule_to_start_state(vec![0])
13873 .expect("rule start states");
13874 atn.set_rule_to_stop_state(vec![5])
13875 .expect("rule stop states");
13876 atn.add_decision_state(1).expect("decision state");
13877 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13878 .expect("transition");
13879 atn.add_transition(
13880 1,
13881 ParserTransitionSpec::Atom {
13882 target: 2,
13883 label: 1,
13884 },
13885 )
13886 .expect("transition");
13887 atn.add_transition(
13888 1,
13889 ParserTransitionSpec::Atom {
13890 target: 3,
13891 label: 2,
13892 },
13893 )
13894 .expect("transition");
13895 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
13896 .expect("transition");
13897 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
13898 .expect("transition");
13899 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13900 .expect("transition");
13901 finish_atn(atn)
13902 }
13903
13904 fn optional_then_b_eof_atn() -> Atn {
13907 let mut atn = ParserAtnBuilder::new(3);
13908 assert_eq!(
13909 atn.add_state(AtnStateKind::RuleStart, Some(0))
13910 .expect("state")
13911 .index(),
13912 0
13913 );
13914 assert_eq!(
13915 atn.add_state(AtnStateKind::BlockStart, Some(0))
13916 .expect("state")
13917 .index(),
13918 1
13919 );
13920 assert_eq!(
13921 atn.add_state(AtnStateKind::Basic, Some(0))
13922 .expect("state")
13923 .index(),
13924 2
13925 );
13926 assert_eq!(
13927 atn.add_state(AtnStateKind::Basic, Some(0))
13928 .expect("state")
13929 .index(),
13930 3
13931 );
13932 assert_eq!(
13933 atn.add_state(AtnStateKind::Basic, Some(0))
13934 .expect("state")
13935 .index(),
13936 4
13937 );
13938 assert_eq!(
13939 atn.add_state(AtnStateKind::RuleStop, Some(0))
13940 .expect("state")
13941 .index(),
13942 5
13943 );
13944 atn.set_rule_to_start_state(vec![0])
13945 .expect("rule start states");
13946 atn.set_rule_to_stop_state(vec![5])
13947 .expect("rule stop states");
13948 atn.add_decision_state(1).expect("decision state");
13949 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13950 .expect("transition");
13951 atn.add_transition(
13953 1,
13954 ParserTransitionSpec::Atom {
13955 target: 3,
13956 label: 1,
13957 },
13958 )
13959 .expect("transition");
13960 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
13961 .expect("transition");
13962 atn.add_transition(
13964 3,
13965 ParserTransitionSpec::Atom {
13966 target: 4,
13967 label: 2,
13968 },
13969 )
13970 .expect("transition");
13971 atn.add_transition(
13972 4,
13973 ParserTransitionSpec::Atom {
13974 target: 5,
13975 label: TOKEN_EOF,
13976 },
13977 )
13978 .expect("transition");
13979 finish_atn(atn)
13980 }
13981
13982 #[test]
13983 fn sync_decision_deletes_only_a_single_token() {
13984 let atn = optional_then_b_eof_atn();
13992
13993 let mut single = mini_parser(vec![
13994 TestToken::new(3).with_text("c"),
13995 TestToken::new(2).with_text("b"),
13996 TestToken::eof("parser-test", 1, 2, 2),
13997 ]);
13998 single.rule_context_stack = vec![RuleContextFrame {
13999 rule_index: 0,
14000 invoking_state: 0,
14001 }];
14002 let children = single
14003 .sync_decision(&atn, 1, true, false)
14004 .expect("single extraneous token recovers");
14005 assert_eq!(children.len(), 1);
14006 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
14007 assert_eq!(single.number_of_syntax_errors(), 1);
14008 assert_eq!(single.la(1), 2);
14010
14011 let mut double = mini_parser(vec![
14012 TestToken::new(3).with_text("c"),
14013 TestToken::new(3).with_text("c"),
14014 TestToken::new(2).with_text("b"),
14015 TestToken::eof("parser-test", 1, 3, 3),
14016 ]);
14017 double.rule_context_stack = vec![RuleContextFrame {
14018 rule_index: 0,
14019 invoking_state: 0,
14020 }];
14021 let result = double.sync_decision(&atn, 1, true, false);
14022 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
14027 match error {
14028 AntlrError::ParserError { message, .. } => {
14029 assert!(message.starts_with("mismatched input"), "got: {message}");
14030 }
14031 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
14032 }
14033 assert_eq!(double.la(1), 3);
14034 }
14035
14036 fn star_loop_then_eof_atn() -> Atn {
14040 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14041 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,
14042 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,
14043 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,
14044 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
14045 ]))
14046 .deserialize_parser()
14047 .expect("star-loop-then-EOF ATN should deserialize")
14048 }
14049
14050 fn plus_loop_with_recovering_body_atn() -> Atn {
14056 let mut atn = ParserAtnBuilder::new(2);
14057 assert_eq!(
14058 atn.add_state(AtnStateKind::RuleStart, Some(0))
14059 .expect("state")
14060 .index(),
14061 0
14062 );
14063 assert_eq!(
14064 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
14065 .expect("state")
14066 .index(),
14067 1
14068 );
14069 assert_eq!(
14070 atn.add_state(AtnStateKind::Basic, Some(0))
14071 .expect("state")
14072 .index(),
14073 2
14074 );
14075 assert_eq!(
14076 atn.add_state(AtnStateKind::BlockEnd, Some(0))
14077 .expect("state")
14078 .index(),
14079 3
14080 );
14081 assert_eq!(
14082 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
14083 .expect("state")
14084 .index(),
14085 4
14086 );
14087 assert_eq!(
14088 atn.add_state(AtnStateKind::LoopEnd, Some(0))
14089 .expect("state")
14090 .index(),
14091 5
14092 );
14093 assert_eq!(
14094 atn.add_state(AtnStateKind::RuleStop, Some(0))
14095 .expect("state")
14096 .index(),
14097 6
14098 );
14099 assert_eq!(
14100 atn.add_state(AtnStateKind::RuleStart, Some(1))
14101 .expect("state")
14102 .index(),
14103 7
14104 );
14105 assert_eq!(
14106 atn.add_state(AtnStateKind::Basic, Some(1))
14107 .expect("state")
14108 .index(),
14109 8
14110 );
14111 assert_eq!(
14112 atn.add_state(AtnStateKind::RuleStop, Some(1))
14113 .expect("state")
14114 .index(),
14115 9
14116 );
14117 atn.set_rule_to_start_state(vec![0, 7])
14118 .expect("rule start states");
14119 atn.set_rule_to_stop_state(vec![6, 9])
14120 .expect("rule stop states");
14121 atn.set_end_state(1, 3).expect("block end state");
14122 atn.set_loop_back_state(5, 4).expect("loop back state");
14123 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14124 .expect("transition");
14125 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14126 .expect("transition");
14127 atn.add_transition(
14128 2,
14129 ParserTransitionSpec::Rule {
14130 target: 7,
14131 rule_index: 1,
14132 follow_state: 3,
14133 precedence: 0,
14134 },
14135 )
14136 .expect("transition");
14137 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14138 .expect("transition");
14139 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
14140 .expect("transition");
14141 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14142 .expect("transition");
14143 atn.add_transition(
14144 5,
14145 ParserTransitionSpec::Atom {
14146 target: 6,
14147 label: 2,
14148 },
14149 )
14150 .expect("transition");
14151 atn.add_transition(
14152 7,
14153 ParserTransitionSpec::Atom {
14154 target: 8,
14155 label: 1,
14156 },
14157 )
14158 .expect("transition");
14159 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14160 .expect("transition");
14161 finish_atn(atn)
14162 }
14163
14164 #[test]
14165 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
14166 let atn = plus_loop_with_recovering_body_atn();
14167 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14168
14169 let error = parser
14170 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
14171 .expect_err("EOF recovery should report a bounded mismatch");
14172
14173 let AntlrError::ParserError { message, .. } = error else {
14174 panic!("expected ParserError, got {error:?}");
14175 };
14176 assert_eq!(message, "mismatched input '<EOF>' expecting {'x', 2}");
14177 assert_eq!(parser.number_of_syntax_errors(), 1);
14178 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
14179 }
14180
14181 #[test]
14182 fn sync_decision_deletes_token_before_eof_at_loop_back() {
14183 let atn = star_loop_then_eof_atn();
14189 let mut parser = mini_parser(vec![
14190 TestToken::new(2).with_text("c"),
14191 TestToken::eof("parser-test", 1, 1, 1),
14192 ]);
14193 parser.rule_context_stack = vec![RuleContextFrame {
14194 rule_index: 0,
14195 invoking_state: 0,
14196 }];
14197 let children = parser
14198 .sync_decision(&atn, 5, true, false)
14199 .expect("single token before EOF recovers");
14200 assert_eq!(children.len(), 1);
14201 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
14202 assert_eq!(parser.number_of_syntax_errors(), 1);
14203 assert_eq!(
14204 parser.la(1),
14205 TOKEN_EOF,
14206 "EOF is left for the rule's EOF match"
14207 );
14208 }
14209
14210 #[test]
14211 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
14212 let atn = star_loop_then_eof_atn();
14217 let mut parser = mini_parser(vec![
14218 TestToken::new(2).with_text("c"),
14219 TestToken::new(2).with_text("c"),
14220 TestToken::eof("parser-test", 1, 2, 2),
14221 ]);
14222 parser.rule_context_stack = vec![RuleContextFrame {
14223 rule_index: 0,
14224 invoking_state: 0,
14225 }];
14226 let error = parser
14227 .sync_decision(&atn, 5, true, false)
14228 .expect_err("two tokens at the loop entry must not be deleted");
14229 match error {
14230 AntlrError::ParserError { message, .. } => {
14231 assert!(message.starts_with("mismatched input"), "got: {message}");
14232 }
14233 other => panic!("expected mismatched-input ParserError, got {other:?}"),
14234 }
14235 assert_eq!(
14236 parser.la(1),
14237 2,
14238 "nothing consumed; cursor still on first `c`"
14239 );
14240 }
14241
14242 #[test]
14243 fn sync_decision_consumes_until_eof_at_loop_back() {
14244 let atn = star_loop_then_eof_atn();
14250 let mut parser = mini_parser(vec![
14251 TestToken::new(2).with_text("c"),
14252 TestToken::new(2).with_text("c"),
14253 TestToken::eof("parser-test", 1, 2, 2),
14254 ]);
14255 parser.rule_context_stack = vec![RuleContextFrame {
14256 rule_index: 0,
14257 invoking_state: 0,
14258 }];
14259 let children = parser
14260 .sync_decision(&atn, 5, false, true)
14261 .expect("loop-back multi-token deletion recovers onto EOF");
14262 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
14263 assert!(
14264 children
14265 .iter()
14266 .all(|child| parser.node(*child).kind() == NodeKind::Error)
14267 );
14268 assert_eq!(parser.number_of_syntax_errors(), 1);
14269 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
14270 }
14271
14272 fn predicate_after_token_atn() -> Atn {
14273 let mut atn = ParserAtnBuilder::new(2);
14274 assert_eq!(
14275 atn.add_state(AtnStateKind::RuleStart, Some(0))
14276 .expect("state")
14277 .index(),
14278 0
14279 );
14280 assert_eq!(
14281 atn.add_state(AtnStateKind::Basic, Some(0))
14282 .expect("state")
14283 .index(),
14284 1
14285 );
14286 assert_eq!(
14287 atn.add_state(AtnStateKind::Basic, Some(0))
14288 .expect("state")
14289 .index(),
14290 2
14291 );
14292 assert_eq!(
14293 atn.add_state(AtnStateKind::Basic, Some(0))
14294 .expect("state")
14295 .index(),
14296 3
14297 );
14298 assert_eq!(
14299 atn.add_state(AtnStateKind::RuleStop, Some(0))
14300 .expect("state")
14301 .index(),
14302 4
14303 );
14304 atn.set_rule_to_start_state(vec![0])
14305 .expect("rule start states");
14306 atn.set_rule_to_stop_state(vec![4])
14307 .expect("rule stop states");
14308 atn.add_transition(
14309 0,
14310 ParserTransitionSpec::Atom {
14311 target: 1,
14312 label: 1,
14313 },
14314 )
14315 .expect("transition");
14316 atn.add_transition(
14317 1,
14318 ParserTransitionSpec::Predicate {
14319 target: 2,
14320 rule_index: 0,
14321 pred_index: 0,
14322 context_dependent: false,
14323 },
14324 )
14325 .expect("transition");
14326 atn.add_transition(
14327 2,
14328 ParserTransitionSpec::Atom {
14329 target: 3,
14330 label: 2,
14331 },
14332 )
14333 .expect("transition");
14334 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14335 .expect("transition");
14336 finish_atn(atn)
14337 }
14338
14339 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
14340 let mut atn = ParserAtnBuilder::new(1);
14341 for (state_number, kind) in [
14342 (0, AtnStateKind::RuleStart),
14343 (1, AtnStateKind::BlockStart),
14344 (2, AtnStateKind::Basic),
14345 (3, AtnStateKind::Basic),
14346 (4, AtnStateKind::Basic),
14347 (5, AtnStateKind::Basic),
14348 (6, AtnStateKind::BlockEnd),
14349 (7, AtnStateKind::RuleStop),
14350 ] {
14351 assert_eq!(
14352 atn.add_state(kind, Some(0)).expect("state").index(),
14353 state_number
14354 );
14355 }
14356 atn.set_rule_to_start_state(vec![0])
14357 .expect("rule start states");
14358 atn.set_rule_to_stop_state(vec![7])
14359 .expect("rule stop states");
14360 atn.add_decision_state(1).expect("decision state");
14361 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14362 .expect("transition");
14363 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14364 .expect("transition");
14365 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
14366 .expect("transition");
14367 atn.add_transition(
14368 2,
14369 ParserTransitionSpec::Predicate {
14370 target: 4,
14371 rule_index: 0,
14372 pred_index: pred_indexes[0],
14373 context_dependent: false,
14374 },
14375 )
14376 .expect("transition");
14377 atn.add_transition(
14378 3,
14379 ParserTransitionSpec::Predicate {
14380 target: 5,
14381 rule_index: 0,
14382 pred_index: pred_indexes[1],
14383 context_dependent: false,
14384 },
14385 )
14386 .expect("transition");
14387 atn.add_transition(
14388 4,
14389 ParserTransitionSpec::Atom {
14390 target: 6,
14391 label: 1,
14392 },
14393 )
14394 .expect("transition");
14395 atn.add_transition(
14396 5,
14397 ParserTransitionSpec::Atom {
14398 target: 6,
14399 label: 1,
14400 },
14401 )
14402 .expect("transition");
14403 atn.add_transition(
14404 6,
14405 ParserTransitionSpec::Atom {
14406 target: 7,
14407 label: TOKEN_EOF,
14408 },
14409 )
14410 .expect("transition");
14411 finish_atn(atn)
14412 }
14413
14414 fn nested_nullable_context_atn() -> Atn {
14415 let mut atn = ParserAtnBuilder::new(1);
14416 for state_number in 0..=20 {
14417 let kind = match state_number {
14418 0 | 10 | 16 => AtnStateKind::RuleStart,
14419 9 | 15 | 20 => AtnStateKind::RuleStop,
14420 _ => AtnStateKind::Basic,
14421 };
14422 let rule_index = match state_number {
14423 0..=9 => 0,
14424 10..=15 => 1,
14425 _ => 2,
14426 };
14427 assert_eq!(
14428 atn.add_state(kind, Some(rule_index))
14429 .expect("state")
14430 .index(),
14431 state_number
14432 );
14433 }
14434 atn.set_rule_to_start_state(vec![0, 10, 16])
14435 .expect("rule start states");
14436 atn.set_rule_to_stop_state(vec![9, 15, 20])
14437 .expect("rule stop states");
14438 atn.add_transition(
14439 1,
14440 ParserTransitionSpec::Rule {
14441 target: 10,
14442 rule_index: 1,
14443 follow_state: 8,
14444 precedence: 0,
14445 },
14446 )
14447 .expect("transition");
14448 atn.add_transition(
14449 8,
14450 ParserTransitionSpec::Atom {
14451 target: 9,
14452 label: 1,
14453 },
14454 )
14455 .expect("transition");
14456 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14457 .expect("transition");
14458 atn.add_transition(
14459 2,
14460 ParserTransitionSpec::Rule {
14461 target: 16,
14462 rule_index: 2,
14463 follow_state: 14,
14464 precedence: 0,
14465 },
14466 )
14467 .expect("transition");
14468 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
14469 .expect("transition");
14470 finish_atn(atn)
14471 }
14472
14473 fn generated_match_recovery_atn() -> Atn {
14474 let mut atn = ParserAtnBuilder::new(2);
14475 assert_eq!(
14476 atn.add_state(AtnStateKind::RuleStart, Some(0))
14477 .expect("state")
14478 .index(),
14479 0
14480 );
14481 assert_eq!(
14482 atn.add_state(AtnStateKind::Basic, Some(0))
14483 .expect("state")
14484 .index(),
14485 1
14486 );
14487 assert_eq!(
14488 atn.add_state(AtnStateKind::Basic, Some(0))
14489 .expect("state")
14490 .index(),
14491 2
14492 );
14493 assert_eq!(
14494 atn.add_state(AtnStateKind::RuleStop, Some(0))
14495 .expect("state")
14496 .index(),
14497 3
14498 );
14499 assert_eq!(
14500 atn.add_state(AtnStateKind::RuleStart, Some(1))
14501 .expect("state")
14502 .index(),
14503 4
14504 );
14505 assert_eq!(
14506 atn.add_state(AtnStateKind::RuleStop, Some(1))
14507 .expect("state")
14508 .index(),
14509 5
14510 );
14511 atn.set_rule_to_start_state(vec![0, 4])
14512 .expect("rule start states");
14513 atn.set_rule_to_stop_state(vec![3, 5])
14514 .expect("rule stop states");
14515 atn.add_transition(
14516 1,
14517 ParserTransitionSpec::Rule {
14518 target: 4,
14519 rule_index: 1,
14520 follow_state: 2,
14521 precedence: 0,
14522 },
14523 )
14524 .expect("transition");
14525 atn.add_transition(
14526 2,
14527 ParserTransitionSpec::Atom {
14528 target: 3,
14529 label: TOKEN_EOF,
14530 },
14531 )
14532 .expect("transition");
14533 finish_atn(atn)
14534 }
14535
14536 fn complement_set_atn() -> Atn {
14537 let mut atn = ParserAtnBuilder::new(1);
14538 assert_eq!(
14539 atn.add_state(AtnStateKind::RuleStart, Some(0))
14540 .expect("state")
14541 .index(),
14542 0
14543 );
14544 assert_eq!(
14545 atn.add_state(AtnStateKind::RuleStop, Some(0))
14546 .expect("state")
14547 .index(),
14548 1
14549 );
14550 atn.set_rule_to_start_state(vec![0])
14551 .expect("rule start states");
14552 atn.set_rule_to_stop_state(vec![1])
14553 .expect("rule stop states");
14554 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
14555 atn.add_transition(
14556 0,
14557 ParserTransitionSpec::NotSet {
14558 target: 1,
14559 set: excluded,
14560 },
14561 )
14562 .expect("transition");
14563 finish_atn(atn)
14564 }
14565
14566 fn wildcard_then_eof_atn() -> Atn {
14569 let mut atn = ParserAtnBuilder::new(1);
14570 assert_eq!(
14571 atn.add_state(AtnStateKind::RuleStart, Some(0))
14572 .expect("state")
14573 .index(),
14574 0
14575 );
14576 assert_eq!(
14577 atn.add_state(AtnStateKind::RuleStop, Some(0))
14578 .expect("state")
14579 .index(),
14580 1
14581 );
14582 assert_eq!(
14583 atn.add_state(AtnStateKind::Basic, Some(0))
14584 .expect("state")
14585 .index(),
14586 2
14587 );
14588 atn.set_rule_to_start_state(vec![0])
14589 .expect("rule start states");
14590 atn.set_rule_to_stop_state(vec![1])
14591 .expect("rule stop states");
14592 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
14593 .expect("transition");
14594 atn.add_transition(
14595 2,
14596 ParserTransitionSpec::Atom {
14597 target: 1,
14598 label: TOKEN_EOF,
14599 },
14600 )
14601 .expect("transition");
14602 finish_atn(atn)
14603 }
14604
14605 #[test]
14606 fn parser_matches_token_and_reports_mismatch() {
14607 let source = Source {
14608 tokens: vec![
14609 TestToken::new(1).with_text("x"),
14610 TestToken::eof("parser-test", 1, 1, 1),
14611 ],
14612 index: 0,
14613 };
14614 let data = RecognizerData::new(
14615 "Mini.g4",
14616 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
14617 );
14618 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
14619 let matched = parser.match_token(1).expect("token 1 should match");
14620 assert_eq!(parser.node(matched).text(), "x");
14621 assert!(parser.match_token(1).is_err());
14622 }
14623
14624 #[test]
14625 fn parser_matches_token_sets() {
14626 let mut parser = mini_parser(vec![
14627 TestToken::new(1).with_text("x"),
14628 TestToken::eof("parser-test", 1, 1, 1),
14629 ]);
14630
14631 let matched = parser
14632 .match_set(&[(1, 1), (3, 4)])
14633 .expect("token set should match");
14634 assert_eq!(parser.node(matched).text(), "x");
14635 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
14636 }
14637
14638 #[test]
14639 fn generated_rule_api_tracks_state_and_precedence() {
14640 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14641
14642 let context = parser.enter_rule(7, 2);
14643 assert_eq!(context.rule_index(), 2);
14644 assert_eq!(parser.state(), 7);
14645 assert_eq!(
14646 parser.rule_context_stack,
14647 vec![RuleContextFrame {
14648 rule_index: 2,
14649 invoking_state: 7
14650 }]
14651 );
14652
14653 let recursive = parser.enter_recursion_rule(11, 3, 4);
14654 assert_eq!(recursive.rule_index(), 3);
14655 assert!(parser.precpred(4));
14656 assert!(parser.precpred(5));
14657 assert!(!parser.precpred(3));
14658
14659 let next = parser.push_new_recursion_context(13, 3);
14660 assert_eq!(next.invoking_state(), 13);
14661 parser.unroll_recursion_context();
14662 assert_eq!(parser.precedence_stack, vec![0]);
14663 assert_eq!(
14664 parser.rule_context_stack,
14665 vec![RuleContextFrame {
14666 rule_index: 2,
14667 invoking_state: 7
14668 }]
14669 );
14670
14671 parser.exit_rule();
14672 assert!(parser.rule_context_stack.is_empty());
14673 }
14674
14675 #[test]
14676 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
14677 let mut parser = mini_parser(vec![
14678 TestToken::new(1).with_text("x"),
14679 TestToken::eof("parser-test", 1, 1, 1),
14680 ]);
14681 let matched = parser.match_token(1).expect("token should match");
14682 assert_eq!(parser.node(matched).text(), "x");
14683 parser.record_generated_syntax_error();
14684 parser.set_int_member(7, 11);
14685 parser.set_build_parse_trees(false);
14686 parser.set_report_diagnostic_errors(true);
14687 parser.set_prediction_mode(PredictionMode::Sll);
14688 parser.set_bail_on_error(true);
14689 let _context = parser.enter_recursion_rule(9, 0, 4);
14690 parser.pending_invoking_states.push(5);
14691 parser.unknown_predicate_hits.push((0, 1));
14692 parser.unhandled_action_hits.push((0, 2));
14693
14694 parser.reset();
14695
14696 assert_eq!(parser.input.index(), 0);
14697 assert_eq!(parser.la(1), 1);
14698 assert_eq!(parser.state(), -1);
14699 assert_eq!(parser.number_of_syntax_errors(), 0);
14700 assert_eq!(parser.parse_tree_storage().node_count(), 0);
14701 assert!(parser.rule_context_stack.is_empty());
14702 assert!(parser.pending_invoking_states.is_empty());
14703 assert_eq!(parser.precedence_stack, [0]);
14704 assert!(parser.unknown_predicate_hits.is_empty());
14705 assert!(parser.unhandled_action_hits.is_empty());
14706 assert_eq!(parser.int_member(7), Some(11));
14707 assert!(!parser.build_parse_trees());
14708 assert!(parser.report_diagnostic_errors());
14709 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
14710 assert!(parser.bail_on_error());
14711 }
14712
14713 #[test]
14714 fn set_token_stream_replaces_input_and_resets_parser() {
14715 let mut parser = mini_parser(vec![
14716 TestToken::new(1).with_text("old"),
14717 TestToken::eof("parser-test", 1, 1, 1),
14718 ]);
14719 parser.consume();
14720 parser.record_generated_syntax_error();
14721 let replacement = CommonTokenStream::new(Source {
14722 tokens: vec![
14723 TestToken::new(2).with_text("new"),
14724 TestToken::eof("parser-test", 1, 1, 1),
14725 ],
14726 index: 0,
14727 });
14728
14729 parser.set_token_stream(replacement);
14730
14731 assert_eq!(parser.input.index(), 0);
14732 assert_eq!(parser.la(1), 2);
14733 assert_eq!(parser.input.text_all(), "new");
14734 assert_eq!(parser.number_of_syntax_errors(), 0);
14735 }
14736
14737 #[test]
14738 fn active_invocation_states_exclude_the_root_frame() {
14739 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14740
14741 let _root = parser.enter_rule(0, 0);
14742 assert!(parser.active_invocation_states().is_empty());
14743
14744 let marker = parser.push_invoking_state(6);
14745 let _child = parser.enter_rule(2, 1);
14746 parser.discard_invoking_state(marker);
14747 assert_eq!(parser.active_invocation_states(), [6]);
14748
14749 let marker = parser.push_invoking_state(13);
14750 let _grandchild = parser.enter_rule(4, 2);
14751 parser.discard_invoking_state(marker);
14752 assert_eq!(parser.active_invocation_states(), [13, 6]);
14753
14754 parser.exit_rule();
14755 parser.exit_rule();
14756 parser.exit_rule();
14757 }
14758
14759 #[test]
14760 fn parser_predicates_support_token_adjacency() {
14761 let mut parser = mini_parser(vec![
14762 TestToken::new(1).with_text("=").with_span(0, 0),
14763 TestToken::new(1).with_text(">").with_span(1, 1),
14764 TestToken::eof("parser-test", 2, 1, 2),
14765 ]);
14766 parser.consume();
14767 parser.consume();
14768
14769 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
14770
14771 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
14772
14773 let mut parser = mini_parser(vec![
14774 TestToken::new(1).with_text("=").with_span(0, 0),
14775 TestToken::new(1)
14776 .with_text(" ")
14777 .with_channel(HIDDEN_CHANNEL)
14778 .with_span(1, 1),
14779 TestToken::new(1).with_text(">").with_span(2, 2),
14780 TestToken::eof("parser-test", 3, 1, 3),
14781 ]);
14782 parser.consume();
14783 parser.consume();
14784
14785 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
14786 }
14787
14788 #[test]
14789 fn parser_predicates_support_context_child_text_checks() {
14790 let mut parser = mini_parser(vec![
14791 TestToken::new(1).with_text("var"),
14792 TestToken::eof("parser-test", 1, 1, 1),
14793 ]);
14794 let mut context = ParserRuleContext::new(1, 0);
14795 let mut child_context = ParserRuleContext::new(2, 0);
14796 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
14797 parser.tree.add_child(&mut child_context, terminal);
14798 let child = parser.rule_node(child_context);
14799 parser.tree.add_child(&mut context, child);
14800 let predicates = [(
14801 1,
14802 0,
14803 ParserPredicate::ContextChildRuleTextNotEquals {
14804 rule_index: 2,
14805 text: "var",
14806 },
14807 )];
14808
14809 assert!(
14810 !parser.parser_semantic_predicate_matches_with_context_and_local(
14811 &predicates,
14812 1,
14813 0,
14814 &context,
14815 0,
14816 )
14817 );
14818 }
14819
14820 #[test]
14821 fn context_expected_symbols_walks_nullable_parent_contexts() {
14822 let atn = nested_nullable_context_atn();
14823 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14824 parser.rule_context_stack = vec![
14825 RuleContextFrame {
14826 rule_index: 0,
14827 invoking_state: 0,
14828 },
14829 RuleContextFrame {
14830 rule_index: 1,
14831 invoking_state: 1,
14832 },
14833 RuleContextFrame {
14834 rule_index: 2,
14835 invoking_state: 2,
14836 },
14837 ];
14838
14839 let expected = parser.context_expected_symbols(&atn);
14840
14841 assert!(expected.contains(&1));
14842 assert!(expected.contains(&TOKEN_EOF));
14843 }
14844
14845 #[test]
14846 fn prediction_context_return_states_track_rule_stack_changes() {
14847 let atn = nested_nullable_context_atn();
14848 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14849 parser.rule_context_stack = vec![
14850 RuleContextFrame {
14851 rule_index: 0,
14852 invoking_state: 0,
14853 },
14854 RuleContextFrame {
14855 rule_index: 1,
14856 invoking_state: 1,
14857 },
14858 RuleContextFrame {
14859 rule_index: 2,
14860 invoking_state: 2,
14861 },
14862 ];
14863
14864 let initial_version = parser.rule_context_version();
14865 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14866 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14867 assert_eq!(first, second);
14868 assert_eq!(parser.rule_context_version(), initial_version);
14869
14870 parser.exit_rule();
14871 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14872 assert_ne!(first, after_pop);
14873 assert_ne!(parser.rule_context_version(), initial_version);
14874 }
14875
14876 #[test]
14877 fn generated_match_token_recovers_missing_token_from_context_follow() {
14878 let atn = generated_match_recovery_atn();
14879 let data = RecognizerData::new(
14880 "Mini.g4",
14881 Vocabulary::new(
14882 [None, Some("'X'"), Some("'Y'")],
14883 [None, Some("X"), Some("Y")],
14884 [None::<&str>, None, None],
14885 ),
14886 );
14887 let mut parser = BaseParser::new(
14888 CommonTokenStream::new(Source {
14889 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
14890 index: 0,
14891 }),
14892 data,
14893 );
14894 parser.rule_context_stack = vec![
14895 RuleContextFrame {
14896 rule_index: 0,
14897 invoking_state: 0,
14898 },
14899 RuleContextFrame {
14900 rule_index: 1,
14901 invoking_state: 1,
14902 },
14903 ];
14904 assert_eq!(parser.number_of_syntax_errors(), 0);
14905
14906 let node = parser
14907 .match_token_recovering(2, 5, &atn)
14908 .expect("generated match should insert missing token");
14909
14910 assert_eq!(node.children().len(), 1);
14911 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
14912 assert_eq!(
14913 node.clone()
14914 .into_child_iter()
14915 .map(|child| parser.node(child).text())
14916 .collect::<Vec<_>>(),
14917 ["<missing 'Y'>"]
14918 );
14919 assert!(!node.consumed_eof());
14922 assert_eq!(parser.la(1), TOKEN_EOF);
14923 assert_eq!(parser.number_of_syntax_errors(), 1);
14924 assert_eq!(
14925 parser.generated_parser_diagnostics,
14926 [ParserDiagnostic {
14927 line: 1,
14928 column: 3,
14929 message: "missing 'Y' at '<EOF>'".to_owned(),
14930 }]
14931 );
14932 }
14933
14934 #[test]
14935 fn generated_match_token_counts_single_token_deletion_recovery() {
14936 let atn = generated_match_recovery_atn();
14937 let data = RecognizerData::new(
14938 "Mini.g4",
14939 Vocabulary::new(
14940 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
14941 [None, Some("X"), Some("Y"), Some("Z")],
14942 [None::<&str>, None, None, None],
14943 ),
14944 );
14945 let mut parser = BaseParser::new(
14946 CommonTokenStream::new(Source {
14947 tokens: vec![
14948 TestToken::new(3).with_text("z"),
14949 TestToken::new(2).with_text("y"),
14950 TestToken::eof("parser-test", 3, 1, 3),
14951 ],
14952 index: 0,
14953 }),
14954 data,
14955 );
14956
14957 let node = parser
14958 .match_token_recovering(2, 5, &atn)
14959 .expect("generated match should delete the extraneous token");
14960
14961 assert_eq!(node.children().len(), 2);
14962 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
14963 assert_eq!(parser.node(node.children()[0]).text(), "z");
14964 assert_eq!(parser.node(node.children()[1]).text(), "y");
14965 assert_eq!(
14966 node.into_child_iter()
14967 .map(|child| parser.node(child).text())
14968 .collect::<Vec<_>>(),
14969 ["z", "y"]
14970 );
14971 assert_eq!(parser.number_of_syntax_errors(), 1);
14972 }
14973
14974 #[test]
14975 fn generated_match_token_iterates_single_success_without_a_children_vec() {
14976 let atn = generated_match_recovery_atn();
14977 let data = RecognizerData::new(
14978 "Mini.g4",
14979 Vocabulary::new(
14980 [None, Some("'X'"), Some("'Y'")],
14981 [None, Some("X"), Some("Y")],
14982 [None::<&str>, None, None],
14983 ),
14984 );
14985 let mut parser = BaseParser::new(
14986 CommonTokenStream::new(Source {
14987 tokens: vec![
14988 TestToken::new(2).with_text("y"),
14989 TestToken::eof("parser-test", 1, 1, 1),
14990 ],
14991 index: 0,
14992 }),
14993 data,
14994 );
14995
14996 let node = parser
14997 .match_token_recovering(2, 5, &atn)
14998 .expect("generated match should consume the expected token");
14999
15000 assert_eq!(
15001 node.into_child_iter()
15002 .map(|child| parser.node(child).text())
15003 .collect::<Vec<_>>(),
15004 ["y"]
15005 );
15006 assert_eq!(parser.number_of_syntax_errors(), 0);
15007 }
15008
15009 #[test]
15010 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
15011 let atn = generated_match_recovery_atn();
15012 let data = RecognizerData::new(
15013 "Mini.g4",
15014 Vocabulary::new(
15015 [None, Some("'X'"), Some("'Y'")],
15016 [None, Some("X"), Some("Y")],
15017 [None::<&str>, None, None],
15018 ),
15019 );
15020 let mut parser = BaseParser::new(
15021 CommonTokenStream::new(Source {
15022 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
15023 index: 0,
15024 }),
15025 data,
15026 );
15027 parser.rule_context_stack = vec![
15028 RuleContextFrame {
15029 rule_index: 0,
15030 invoking_state: 0,
15031 },
15032 RuleContextFrame {
15033 rule_index: 1,
15034 invoking_state: 1,
15035 },
15036 ];
15037 let marker = parser.generated_diagnostics_checkpoint();
15038
15039 let _ = parser
15040 .match_token_recovering(2, 5, &atn)
15041 .expect("generated match should insert missing token");
15042 assert_eq!(parser.number_of_syntax_errors(), 1);
15043
15044 parser.restore_generated_diagnostics(marker);
15045
15046 assert_eq!(parser.number_of_syntax_errors(), 0);
15047 assert!(parser.generated_parser_diagnostics.is_empty());
15048 }
15049
15050 #[test]
15051 fn generated_prediction_diagnostics_use_adaptive_context() {
15052 let atn = two_alt_decision_atn();
15053 let data = RecognizerData::new(
15054 "Mini.g4",
15055 Vocabulary::new(
15056 [None, Some("'x'"), Some("'y'")],
15057 [None, Some("X"), Some("Y")],
15058 [None::<&str>, None, None],
15059 ),
15060 )
15061 .with_rule_names(["s"]);
15062 let mut parser = BaseParser::new(
15063 CommonTokenStream::new(Source {
15064 tokens: vec![
15065 TestToken::new(1)
15066 .with_text("x")
15067 .with_position(1, 0)
15068 .with_span(0, 0),
15069 TestToken::new(2)
15070 .with_text("y")
15071 .with_position(1, 2)
15072 .with_span(1, 1),
15073 TestToken::eof("parser-test", 2, 1, 3),
15074 ],
15075 index: 0,
15076 }),
15077 data,
15078 );
15079 parser.set_report_diagnostic_errors(true);
15080
15081 parser.record_generated_prediction_diagnostic(
15082 &atn,
15083 1,
15084 &ParserAtnPrediction {
15085 alt: 1,
15086 requires_full_context: true,
15087 has_semantic_context: false,
15088 diagnostic: Some(ParserAtnPredictionDiagnostic {
15089 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
15090 start_index: 0,
15091 sll_stop_index: 1,
15092 ll_stop_index: 0,
15093 conflicting_alts: vec![1, 2],
15094 exact: false,
15095 }),
15096 },
15097 );
15098 parser.record_generated_prediction_diagnostic(
15103 &atn,
15104 1,
15105 &ParserAtnPrediction {
15106 alt: 1,
15107 requires_full_context: true,
15108 has_semantic_context: false,
15109 diagnostic: Some(ParserAtnPredictionDiagnostic {
15110 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
15111 start_index: 0,
15112 sll_stop_index: 1,
15113 ll_stop_index: 1,
15114 conflicting_alts: vec![1, 2],
15115 exact: false,
15116 }),
15117 },
15118 );
15119
15120 assert_eq!(
15121 parser.generated_parser_diagnostics,
15122 [
15123 ParserDiagnostic {
15124 line: 1,
15125 column: 2,
15126 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
15127 },
15128 ParserDiagnostic {
15129 line: 1,
15130 column: 0,
15131 message: "reportContextSensitivity d=0 (s), input='x'".to_owned(),
15132 },
15133 ParserDiagnostic {
15134 line: 1,
15135 column: 2,
15136 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
15137 },
15138 ]
15139 );
15140 }
15141
15142 #[test]
15143 fn generated_match_not_set_recovers_empty_complement_at_eof() {
15144 let atn = complement_set_atn();
15145 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15146 parser.rule_context_stack = vec![RuleContextFrame {
15147 rule_index: 0,
15148 invoking_state: 0,
15149 }];
15150
15151 let node = parser
15152 .match_not_token_set_recovering(
15153 atn.token_set(0).expect("excluded token set"),
15154 1,
15155 1,
15156 1,
15157 &atn,
15158 )
15159 .expect("empty complement should recover at EOF");
15160
15161 assert_eq!(node.children().len(), 1);
15162 assert!(!node.consumed_eof());
15165 assert_eq!(parser.la(1), TOKEN_EOF);
15166 assert_eq!(
15167 parser.generated_parser_diagnostics,
15168 [ParserDiagnostic {
15169 line: 1,
15170 column: 1,
15171 message: "missing {} at '<EOF>'".to_owned(),
15172 }]
15173 );
15174 }
15175
15176 #[test]
15177 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
15178 let atn = wildcard_then_eof_atn();
15184 let data = RecognizerData::new(
15185 "Mini.g4",
15186 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
15187 );
15188 let mut parser = BaseParser::new(
15189 CommonTokenStream::new(Source {
15190 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
15191 index: 0,
15192 }),
15193 data,
15194 );
15195 parser.rule_context_stack = vec![RuleContextFrame {
15196 rule_index: 0,
15197 invoking_state: 0,
15198 }];
15199
15200 let node = parser
15201 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
15202 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
15203
15204 assert_eq!(node.children().len(), 1);
15206 assert!(!node.consumed_eof());
15207 assert!(
15208 parser
15209 .node(node.children()[0])
15210 .text()
15211 .starts_with("<missing")
15212 );
15213 assert_eq!(parser.la(1), TOKEN_EOF);
15214 assert_eq!(
15215 parser.generated_parser_diagnostics,
15216 [ParserDiagnostic {
15217 line: 1,
15218 column: 1,
15219 message: "missing 'x' at '<EOF>'".to_owned(),
15220 }]
15221 );
15222 }
15223
15224 #[test]
15225 fn generated_rule_recovery_consumes_to_parent_follow() {
15226 let atn = generated_match_recovery_atn();
15227 let data = RecognizerData::new(
15228 "Mini.g4",
15229 Vocabulary::new(
15230 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
15231 [None, Some("X"), Some("Y"), Some("Z")],
15232 [None::<&str>, None, None, None],
15233 ),
15234 );
15235 let mut parser = BaseParser::new(
15236 CommonTokenStream::new(Source {
15237 tokens: vec![
15238 TestToken::new(3).with_text("z"),
15239 TestToken::eof("parser-test", 1, 1, 1),
15240 ],
15241 index: 0,
15242 }),
15243 data,
15244 );
15245 let _parent = parser.enter_rule(0, 0);
15246 let marker = parser.push_invoking_state(1);
15247 let mut child = parser.enter_rule(4, 1);
15248 parser.discard_invoking_state(marker);
15249
15250 parser.recover_generated_rule(
15251 &mut child,
15252 &atn,
15253 AntlrError::ParserError {
15254 line: 1,
15255 column: 0,
15256 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
15257 },
15258 );
15259 let tree = parser.finish_rule(child, false);
15260
15261 assert_eq!(parser.la(1), TOKEN_EOF);
15262 assert_eq!(
15263 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
15264 "(a z)"
15265 );
15266 assert_eq!(parser.number_of_syntax_errors(), 1);
15267 assert_eq!(
15268 parser.generated_parser_diagnostics,
15269 [ParserDiagnostic {
15270 line: 1,
15271 column: 0,
15272 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
15273 }]
15274 );
15275 parser.exit_rule();
15276 }
15277
15278 #[test]
15279 fn greedy_ll1_alt_handles_nullable_loop_exit() {
15280 let mut body_symbols = TokenBitSet::default();
15281 body_symbols.insert(1);
15282 let entry = DecisionLookahead {
15283 transitions: vec![
15284 TransitionLookSet {
15285 symbols: body_symbols,
15286 nullable: false,
15287 },
15288 TransitionLookSet {
15289 symbols: TokenBitSet::default(),
15290 nullable: true,
15291 },
15292 ],
15293 };
15294
15295 assert_eq!(ll1_unique_alt(&entry, 2), None);
15296 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
15297 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
15298 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
15299 }
15300
15301 #[test]
15302 fn ordinary_repetition_builds_tree_in_input_order() {
15303 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15304 let mut parser = mini_parser(repeated_x_tokens(3));
15305 let tree = parser
15306 .parse_atn_rule(&atn, 0)
15307 .expect("ordinary repetition should parse");
15308
15309 let root = parser
15310 .node(tree)
15311 .as_rule()
15312 .expect("entry result should be a rule");
15313 let body_rules = root.child_rules(1).collect::<Vec<_>>();
15314 assert_eq!(root.text(), "xxx<EOF>");
15315 assert_eq!(body_rules.len(), 3);
15316 assert_eq!(
15317 body_rules
15318 .iter()
15319 .map(|rule| rule.start_id().expect("body start").index())
15320 .collect::<Vec<_>>(),
15321 [0, 1, 2]
15322 );
15323 assert_eq!(
15324 body_rules
15325 .iter()
15326 .map(|rule| rule.stop_id().expect("body stop").index())
15327 .collect::<Vec<_>>(),
15328 [0, 1, 2]
15329 );
15330 assert_eq!(parser.number_of_syntax_errors(), 0);
15331 }
15332 }
15333
15334 #[test]
15335 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
15336 const DEPTH: usize = 20_000;
15337
15338 std::thread::Builder::new()
15339 .name("deferred-rule-materialization".to_owned())
15340 .stack_size(256 * 1024)
15341 .spawn(|| {
15342 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
15343 let mut root = FastDeferredNodeId::EMPTY;
15344 for depth in 0..DEPTH {
15345 root = parser
15346 .recognition_arena
15347 .deferred_rule_node(FastDeferredRule {
15348 rule_index: u32::try_from(depth).expect("depth fits in u32"),
15349 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
15350 start_index: 0,
15351 stop_index: None,
15352 deferred_children: root,
15353 children: NodeSeqId::EMPTY,
15354 });
15355 }
15356
15357 let mut children = parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
15358 for expected_rule in (0..DEPTH).rev() {
15359 let mut nodes = parser.recognition_arena.iter(children);
15360 let node = nodes.next().expect("nested rule node");
15361 assert!(nodes.next().is_none(), "each rule has one child");
15362 let ArenaRecognizedNode::Rule {
15363 rule_index,
15364 children: nested,
15365 ..
15366 } = parser.recognition_arena.node(node)
15367 else {
15368 panic!("expected nested rule");
15369 };
15370 assert_eq!(rule_index as usize, expected_rule);
15371 children = nested;
15372 }
15373 assert!(children.is_empty());
15374 })
15375 .expect("small-stack thread should start")
15376 .join()
15377 .expect("deferred rules should materialize without recursion");
15378 }
15379
15380 #[test]
15381 fn nested_rule_chain_with_adaptive_set_fits_default_stack() {
15382 const DEPTH: usize = 130;
15384 const STACK_SIZE: usize = 2 * 1024 * 1024;
15385
15386 std::thread::Builder::new()
15387 .name("nested-adaptive-set-rules".to_owned())
15388 .stack_size(STACK_SIZE)
15389 .spawn(|| {
15390 let atn = nested_rule_chain_atn(DEPTH);
15391 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
15392 parser.set_build_parse_trees(false);
15393 parser
15394 .parse_atn_rule(&atn, 0)
15395 .expect("nested rule chain should parse on the default-sized stack");
15396 assert_eq!(parser.input.index(), 1);
15397 })
15398 .expect("small-stack thread should start")
15399 .join()
15400 .expect("nested rule chain should not overflow its stack");
15401 }
15402
15403 #[test]
15404 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
15405 const REPETITIONS: usize = 64;
15406
15407 let atn = ambiguous_ordinary_star_loop_atn();
15408 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15409 let tree = parser
15410 .parse_atn_rule(&atn, 0)
15411 .expect("ambiguous ordinary repetition should parse");
15412
15413 let root = parser
15414 .node(tree)
15415 .as_rule()
15416 .expect("entry result should be a rule");
15417 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
15418 assert_eq!(parser.input.index(), REPETITIONS);
15419 assert!(
15420 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
15421 "equivalent segmentations should keep deferred storage linear"
15422 );
15423 assert_eq!(parser.number_of_syntax_errors(), 0);
15424 }
15425
15426 #[test]
15427 fn long_ordinary_repetition_does_not_consume_native_stack() {
15428 const REPETITIONS: usize = 20_000;
15429
15430 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15431 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15432 parser.set_build_parse_trees(false);
15433 parser
15434 .parse_atn_rule(&atn, 0)
15435 .expect("long ordinary repetition should parse");
15436
15437 assert_eq!(parser.input.index(), REPETITIONS);
15438 assert_eq!(parser.number_of_syntax_errors(), 0);
15439 }
15440 }
15441
15442 #[test]
15443 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
15444 const REPETITIONS: usize = 2_000;
15445 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
15446
15447 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15448 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15449 let tree = parser
15450 .parse_atn_rule(&atn, 0)
15451 .expect("long rule repetition should parse");
15452
15453 let root = parser
15454 .node(tree)
15455 .as_rule()
15456 .expect("entry result should be a rule");
15457 assert_eq!(root.text(), expected_text);
15458 assert_eq!(root.child_rules(1).count(), REPETITIONS);
15459 let first_body = root.child_rules(1).next().expect("first body rule");
15460 let last_body = root.child_rules(1).next_back().expect("last body rule");
15461 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
15462 assert_eq!(
15463 last_body.stop_id().expect("last body stop").index(),
15464 REPETITIONS - 1
15465 );
15466
15467 let stats = parser.recognition_arena_stats();
15468 assert_eq!(
15469 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
15470 (REPETITIONS, REPETITIONS, 0)
15471 );
15472 assert_eq!(
15473 (stats.total_links, stats.live_links, stats.dead_links),
15474 (REPETITIONS, REPETITIONS, 0)
15475 );
15476 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
15477 assert_eq!(
15478 parser.recognition_arena.deferred_nodes.len(),
15479 REPETITIONS * 2 - 1
15480 );
15481 assert_eq!(parser.number_of_syntax_errors(), 0);
15482 }
15483 }
15484
15485 #[test]
15486 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
15487 let key = |state_number| FastRecognizeKey {
15488 state_number,
15489 stop_state: 10,
15490 index: state_number,
15491 rule_start_index: 0,
15492 decision_start_index: None,
15493 precedence: 0,
15494 recovery_symbols_id: 0,
15495 recovery_state: None,
15496 };
15497
15498 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15499 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
15500 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
15501 }
15502 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
15503 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
15504
15505 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15506 let repeated = key(1);
15507 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
15508 assert!(promote.clean_memo_enabled_for_key(&repeated));
15509 }
15510 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
15511
15512 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
15513 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
15514 }
15515 assert!(sparse.clean_memo_enabled_for_key(&repeated));
15516 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
15517 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
15518 assert!(sparse.clean_memo_enabled_for_key(&repeated));
15519 }
15520 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
15521 }
15522
15523 #[test]
15524 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
15525 assert_eq!(
15526 fast_recognize_memo_capacity(0),
15527 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
15528 );
15529 assert_eq!(
15530 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
15531 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
15532 );
15533 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
15534 assert_eq!(
15535 fast_recognize_memo_capacity(usize::MAX),
15536 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
15537 );
15538 }
15539
15540 #[test]
15541 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
15542 let mut scratch = FastRecognizeTopScratch::default();
15543 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
15544 let retained_capacity = scratch.memo.capacity();
15545 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
15546 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15547
15548 let larger_capacity = retained_capacity + 1;
15549 scratch.prepare(larger_capacity);
15550 let grown_capacity = scratch.memo.capacity();
15551 assert!(grown_capacity >= larger_capacity);
15552 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15553
15554 scratch.memo.insert(
15555 FastRecognizeKey {
15556 state_number: 0,
15557 stop_state: 0,
15558 index: 0,
15559 rule_start_index: 0,
15560 decision_start_index: None,
15561 precedence: 0,
15562 recovery_symbols_id: 0,
15563 recovery_state: None,
15564 },
15565 Rc::from([FastRecognizeOutcome {
15566 index: 0,
15567 consumed_eof: false,
15568 diagnostics: DiagnosticSeqId::EMPTY,
15569 deferred_nodes: FastDeferredNodeId::EMPTY,
15570 nodes: NodeSeqId::EMPTY,
15571 }]),
15572 );
15573 scratch.release_oversized_memo();
15574 assert!(scratch.memo.is_empty());
15575 assert_eq!(scratch.memo.capacity(), grown_capacity);
15576
15577 scratch
15578 .memo
15579 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
15580 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15581
15582 scratch.release_oversized_memo();
15583 assert!(scratch.memo.is_empty());
15584 assert_eq!(scratch.memo.capacity(), 0);
15585 }
15586
15587 #[test]
15588 fn clean_empty_multi_alt_outcomes_are_memoized() {
15589 let mut atn = ParserAtnBuilder::new(2);
15590 assert_eq!(
15591 atn.add_state(AtnStateKind::RuleStart, Some(0))
15592 .expect("state")
15593 .index(),
15594 0
15595 );
15596 assert_eq!(
15597 atn.add_state(AtnStateKind::BlockStart, Some(0))
15598 .expect("state")
15599 .index(),
15600 1
15601 );
15602 assert_eq!(
15603 atn.add_state(AtnStateKind::RuleStop, Some(0))
15604 .expect("state")
15605 .index(),
15606 2
15607 );
15608 atn.set_rule_to_start_state(vec![0])
15609 .expect("rule start states");
15610 atn.set_rule_to_stop_state(vec![2])
15611 .expect("rule stop states");
15612 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15613 .expect("transition");
15614 atn.add_transition(
15615 1,
15616 ParserTransitionSpec::Atom {
15617 target: 2,
15618 label: 1,
15619 },
15620 )
15621 .expect("transition");
15622 atn.add_transition(
15623 1,
15624 ParserTransitionSpec::Atom {
15625 target: 2,
15626 label: 2,
15627 },
15628 )
15629 .expect("transition");
15630 let atn = finish_atn(atn);
15631
15632 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
15633 parser.fast_recovery_enabled = false;
15634 let mut visiting = FxHashSet::default();
15635 let mut memo = FxHashMap::default();
15636 let mut expected = ExpectedTokens::default();
15637 let outcomes = parser.recognize_state_fast(
15638 &atn,
15639 FastRecognizeRequest {
15640 state_number: 1,
15641 stop_state: 2,
15642 index: 0,
15643 rule_start_index: 0,
15644 decision_start_index: None,
15645 precedence: 0,
15646 depth: 0,
15647 recovery_symbols: parser.empty_recovery_symbols(),
15648 recovery_state: None,
15649 },
15650 FastRecognizeScratch {
15651 predicate_context: None,
15652 visiting: &mut visiting,
15653 memo: &mut memo,
15654 expected: &mut expected,
15655 },
15656 );
15657
15658 assert!(outcomes.is_empty());
15659 assert_eq!(memo.len(), 1);
15660 assert!(memo.values().next().expect("memo entry").is_empty());
15661
15662 parser.clean_memo_mode = CleanMemoMode::Sparse;
15663 visiting.clear();
15664 memo.clear();
15665 expected = ExpectedTokens::default();
15666 let sparse_outcomes = parser.recognize_state_fast(
15667 &atn,
15668 FastRecognizeRequest {
15669 state_number: 1,
15670 stop_state: 2,
15671 index: 0,
15672 rule_start_index: 0,
15673 decision_start_index: None,
15674 precedence: 0,
15675 depth: 0,
15676 recovery_symbols: parser.empty_recovery_symbols(),
15677 recovery_state: None,
15678 },
15679 FastRecognizeScratch {
15680 predicate_context: None,
15681 visiting: &mut visiting,
15682 memo: &mut memo,
15683 expected: &mut expected,
15684 },
15685 );
15686
15687 assert!(sparse_outcomes.is_empty());
15688 assert!(memo.is_empty());
15689 }
15690
15691 #[test]
15692 fn wildcard_matches_non_eof_only() {
15693 let mut parser = mini_parser(vec![
15694 TestToken::new(1).with_text("x"),
15695 TestToken::eof("parser-test", 1, 1, 1),
15696 ]);
15697 let matched = parser.match_wildcard().expect("wildcard");
15698 assert_eq!(parser.node(matched).text(), "x");
15699 assert!(parser.match_wildcard().is_err());
15700 }
15701
15702 #[test]
15703 fn add_parse_child_records_match_even_without_tree_building() {
15704 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15709 let token = TestToken::new(1).with_text("x");
15710
15711 parser.set_build_parse_trees(false);
15712 let mut ctx = ParserRuleContext::new(0, 0);
15713 assert!(!ctx.has_matched_child());
15714 let child = parser.terminal_tree(token.id);
15715 parser.add_parse_child(&mut ctx, child);
15716 assert_eq!(ctx.child_count(), 0);
15718 assert_eq!(parser.parse_tree_storage().node_count(), 0);
15719 assert!(ctx.has_matched_child());
15721
15722 parser.set_build_parse_trees(true);
15724 let mut ctx = ParserRuleContext::new(0, 0);
15725 let child = parser.terminal_tree(token.id);
15726 parser.add_parse_child(&mut ctx, child);
15727 assert_eq!(ctx.child_count(), 1);
15728 assert!(ctx.has_matched_child());
15729 }
15730
15731 #[test]
15732 fn disabled_tree_building_does_not_grow_flat_storage() {
15733 let mut parser = mini_parser(vec![
15734 TestToken::new(1).with_text("x"),
15735 TestToken::new(1).with_text("y"),
15736 TestToken::eof("parser-test", 2, 1, 2),
15737 ]);
15738 parser.set_build_parse_trees(false);
15739 let mut context = ParserRuleContext::new(0, -1);
15740
15741 for _ in 0..2 {
15742 let child = parser.match_token(1).expect("token should match");
15743 parser.add_parse_child(&mut context, child);
15744 }
15745 let current = parser.input.lt_id(1).expect("EOF token");
15746 let error = parser.error_tree(current);
15747 parser.add_parse_child(&mut context, error);
15748 let root = parser.rule_node(context);
15749
15750 assert_eq!(
15751 parser.parse_tree_storage().stats(),
15752 ParseTreeStats::default()
15753 );
15754 assert!(
15755 parser
15756 .parse_tree_storage()
15757 .node(parser.token_store(), root)
15758 .is_none(),
15759 "the no-tree sentinel must not resolve to stored data"
15760 );
15761 }
15762
15763 #[test]
15764 fn disabled_tree_building_skips_recognition_rule_node_storage() {
15765 let atn = ordinary_star_loop_atn();
15766 let mut parser = mini_parser(repeated_x_tokens(3));
15767 parser.set_build_parse_trees(false);
15768
15769 parser
15770 .parse_atn_rule(&atn, 0)
15771 .expect("ordinary repetition should parse without a tree");
15772
15773 assert_eq!(parser.input.index(), 3);
15774 assert!(parser.recognition_arena.nodes.is_empty());
15775 assert!(parser.recognition_arena.seq_links.is_empty());
15776 assert!(parser.recognition_arena.deferred_nodes.is_empty());
15777 assert!(parser.recognition_arena.deferred_rules.is_empty());
15778 assert!(!parser.fast_token_nodes_enabled);
15779 assert!(parser.fast_recognize_scratch.memo.is_empty());
15780 }
15781
15782 #[test]
15783 fn parser_interprets_simple_atn_rule() {
15784 let atn = token_then_eof_atn();
15785 let mut parser = mini_parser(vec![
15786 TestToken::new(1).with_text("x"),
15787 TestToken::eof("parser-test", 1, 1, 1),
15788 ]);
15789
15790 let tree = parser
15791 .parse_atn_rule(&atn, 0)
15792 .expect("artificial parser rule should parse");
15793 assert_eq!(parser.node(tree).text(), "x<EOF>");
15794 assert_eq!(parser.number_of_syntax_errors(), 0);
15795 assert_eq!(
15796 parser
15797 .node(tree)
15798 .first_rule_stop(0)
15799 .expect("rule should stop at EOF")
15800 .token_type(),
15801 TOKEN_EOF
15802 );
15803
15804 let mut parser = mini_parser(vec![
15805 TestToken::new(1).with_text("x"),
15806 TestToken::eof("parser-test", 1, 1, 1),
15807 ]);
15808 let (tree, actions) = parser
15809 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15810 .expect("runtime-option parser rule should parse");
15811 assert!(actions.is_empty());
15812 assert_eq!(
15813 parser
15814 .node(tree)
15815 .first_rule_stop(0)
15816 .expect("rule should stop at EOF")
15817 .token_type(),
15818 TOKEN_EOF
15819 );
15820 }
15821
15822 #[test]
15823 fn runtime_options_default_ignores_noop_action_transitions() {
15824 let atn = noop_action_then_token_then_eof_atn();
15825 let mut parser = mini_parser(vec![
15826 TestToken::new(1).with_text("x"),
15827 TestToken::eof("parser-test", 1, 1, 1),
15828 ]);
15829
15830 let (tree, actions) = parser
15831 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15832 .expect("no-op parser action should not force action replay");
15833
15834 assert_eq!(parser.node(tree).text(), "x<EOF>");
15835 assert!(
15836 actions.is_empty(),
15837 "action_index=None transitions are ANTLR metadata, not replay actions"
15838 );
15839 assert_eq!(parser.number_of_syntax_errors(), 0);
15840 }
15841
15842 #[test]
15843 fn parser_exposes_buffered_token_stream_after_parse() {
15844 let atn = token_then_eof_atn();
15845 let mut parser = mini_parser(vec![
15846 TestToken::new(1).with_text("x"),
15847 TestToken::eof("parser-test", 1, 1, 1),
15848 ]);
15849
15850 let tree = parser
15851 .parse_atn_rule(&atn, 0)
15852 .expect("artificial parser rule should parse");
15853 assert_eq!(parser.node(tree).text(), "x<EOF>");
15854
15855 let stream = parser.token_stream();
15856 let source_index_after_parse = stream.token_source().index;
15857 let buffered = stream.tokens().collect::<Vec<_>>();
15858 assert_eq!(buffered.len(), 2);
15859 assert_eq!(buffered[0].text(), "x");
15860 assert_eq!(buffered[0].token_id().index(), 0);
15861 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
15862 assert_eq!(stream.token_source().index, source_index_after_parse);
15863 drop(buffered);
15864
15865 let stream = parser.into_token_stream();
15866 assert_eq!(stream.token_source().index, source_index_after_parse);
15867 assert_eq!(stream.tokens().next().expect("first token").text(), "x");
15868 assert_eq!(
15869 stream.tokens().nth(1).expect("EOF token").token_type(),
15870 TOKEN_EOF
15871 );
15872 }
15873
15874 #[test]
15875 fn parser_syntax_error_count_tracks_interpreted_recovery() {
15876 let atn = token_then_eof_atn();
15877 let mut parser = mini_parser(vec![
15878 TestToken::new(1).with_text("x"),
15879 TestToken::new(2).with_text("y"),
15880 TestToken::eof("parser-test", 2, 1, 2),
15881 ]);
15882
15883 let tree = parser
15884 .parse_atn_rule(&atn, 0)
15885 .expect("invalid token should recover into an error node");
15886
15887 assert_eq!(parser.number_of_syntax_errors(), 1);
15888 assert_eq!(
15889 parser
15890 .node(tree)
15891 .first_error_token()
15892 .expect("recovery should embed an error token")
15893 .text(),
15894 "y"
15895 );
15896 }
15897
15898 #[test]
15899 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
15900 let atn = token_then_eof_atn();
15901 let mut parser = mini_parser(vec![
15902 TestToken::new(2).with_text("y"),
15903 TestToken::eof("parser-test", 1, 1, 1),
15904 ]);
15905
15906 let error = parser
15907 .parse_atn_rule(&atn, 0)
15908 .expect_err("start-rule mismatch should remain a parser error");
15909
15910 assert_eq!(parser.number_of_syntax_errors(), 1);
15911 assert!(matches!(error, AntlrError::ParserError { .. }));
15912 }
15913
15914 #[test]
15915 fn adaptive_direct_rule_uses_simulator_decision() {
15916 let atn = two_alt_decision_atn();
15917 let mut simulator = ParserAtnSimulator::new(&atn);
15918 let mut parser = mini_parser(vec![
15919 TestToken::new(2).with_text("y"),
15920 TestToken::eof("parser-test", 1, 1, 1),
15921 ]);
15922
15923 let tree = parser
15924 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
15925 .expect("direct adaptive rule should parse");
15926
15927 assert_eq!(parser.node(tree).text(), "y");
15928 assert_eq!(parser.input.index(), 1);
15929 }
15930
15931 #[test]
15932 fn adaptive_direct_rule_restores_input_on_fallback() {
15933 let atn = predicate_after_token_atn();
15934 let mut simulator = ParserAtnSimulator::new(&atn);
15935 let mut parser = mini_parser(vec![
15936 TestToken::new(1).with_text("x"),
15937 TestToken::new(2).with_text("y"),
15938 TestToken::eof("parser-test", 2, 1, 2),
15939 ]);
15940
15941 let tree = parser
15942 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
15943 .expect("fallback recognizer should parse");
15944
15945 assert_eq!(parser.node(tree).text(), "xy");
15946 assert_eq!(parser.input.index(), 2);
15947 let stats = parser.parse_tree_storage().stats();
15948 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
15949 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
15950 assert_eq!(stats.scratch_links, 0);
15951 }
15952
15953 #[test]
15954 fn unknown_predicate_policy_defaults_to_assume_true() {
15955 let atn = predicate_after_token_atn();
15956 let mut parser = mini_parser(vec![
15957 TestToken::new(1).with_text("x"),
15958 TestToken::new(2).with_text("y"),
15959 TestToken::eof("parser-test", 2, 1, 2),
15960 ]);
15961
15962 let (tree, _) = parser
15963 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15964 .expect("unknown predicate should pass under the default policy");
15965
15966 assert_eq!(parser.node(tree).text(), "xy");
15967 assert_eq!(parser.number_of_syntax_errors(), 0);
15968 }
15969
15970 #[test]
15971 fn predicate_gated_same_lookahead_uses_viable_alternative() {
15972 let atn = predicate_gated_same_lookahead_atn([0, 1]);
15973 let mut parser = mini_parser(vec![
15974 TestToken::new(1).with_text("x"),
15975 TestToken::eof("parser-test", 1, 1, 1),
15976 ]);
15977
15978 let (tree, _) = parser
15979 .parse_atn_rule_with_runtime_options(
15980 &atn,
15981 0,
15982 ParserRuntimeOptions {
15983 predicates: &[
15984 (0, 0, ParserPredicate::False),
15985 (0, 1, ParserPredicate::True),
15986 ],
15987 ..ParserRuntimeOptions::default()
15988 },
15989 )
15990 .expect("the second predicate-gated alternative should match");
15991
15992 assert_eq!(parser.node(tree).text(), "x<EOF>");
15993 assert_eq!(parser.number_of_syntax_errors(), 0);
15994 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
15995 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
15996 }
15997
15998 #[test]
15999 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
16000 let atn = token_then_eof_atn();
16004 let mut parser = mini_parser(vec![
16005 TestToken::new(1).with_text("x"),
16006 TestToken::eof("parser-test", 1, 1, 1),
16007 ]);
16008
16009 parser.unknown_predicate_hits.push((7, 3));
16011
16012 parser
16014 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16015 .expect("child rule parses");
16016
16017 let error = parser
16019 .take_unknown_semantic_error()
16020 .expect("parent's recorded coordinate must survive the nested interpreted parse");
16021 let AntlrError::Unsupported(message) = error else {
16022 panic!("expected AntlrError::Unsupported, got {error:?}");
16023 };
16024 assert!(message.contains("pred_index=3"), "message: {message}");
16025 }
16026
16027 #[test]
16028 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
16029 let atn = predicate_after_token_atn();
16030 let mut parser = mini_parser(vec![
16031 TestToken::new(1).with_text("x"),
16032 TestToken::new(2).with_text("y"),
16033 TestToken::eof("parser-test", 2, 1, 2),
16034 ]);
16035
16036 let result = parser.parse_atn_rule_with_runtime_options(
16037 &atn,
16038 0,
16039 ParserRuntimeOptions {
16040 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
16041 ..ParserRuntimeOptions::default()
16042 },
16043 );
16044
16045 assert!(
16046 result.is_err(),
16047 "the only path is predicate-guarded, so assume-false must fail the parse"
16048 );
16049 }
16050
16051 #[test]
16052 fn predicate_failure_message_keeps_semantic_recovery_path() {
16053 let atn = predicate_after_token_atn();
16054 let mut parser = mini_parser(vec![
16055 TestToken::new(1).with_text("x"),
16056 TestToken::new(2).with_text("y"),
16057 TestToken::eof("parser-test", 2, 1, 2),
16058 ]);
16059
16060 let (tree, _) = parser
16061 .parse_atn_rule_with_runtime_options(
16062 &atn,
16063 0,
16064 ParserRuntimeOptions {
16065 predicates: &[(
16066 0,
16067 0,
16068 ParserPredicate::FalseWithMessage {
16069 message: "predicate rejected input",
16070 },
16071 )],
16072 ..ParserRuntimeOptions::default()
16073 },
16074 )
16075 .expect("failure-message predicates recover through the semantic interpreter");
16076
16077 assert_eq!(parser.node(tree).text(), "xy");
16078 assert_eq!(parser.number_of_syntax_errors(), 1);
16079 assert!(
16080 parser.fast_predicate_cache.is_empty(),
16081 "failure-message predicates need the semantic interpreter's recovery outcome"
16082 );
16083 }
16084
16085 #[test]
16086 fn unknown_predicate_policy_error_names_the_coordinate() {
16087 let atn = predicate_after_token_atn();
16088 let mut parser = mini_parser(vec![
16089 TestToken::new(1).with_text("x"),
16090 TestToken::new(2).with_text("y"),
16091 TestToken::eof("parser-test", 2, 1, 2),
16092 ]);
16093
16094 let error = parser
16095 .parse_atn_rule_with_runtime_options(
16096 &atn,
16097 0,
16098 ParserRuntimeOptions {
16099 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16100 ..ParserRuntimeOptions::default()
16101 },
16102 )
16103 .expect_err("evaluating an unknown predicate under Error policy must fail");
16104
16105 let AntlrError::Unsupported(message) = error else {
16106 panic!("expected AntlrError::Unsupported, got {error:?}");
16107 };
16108 assert!(
16109 message.contains("unsupported semantic predicate"),
16110 "message should name the failure class: {message}"
16111 );
16112 assert!(
16113 message.contains("pred_index=0"),
16114 "message should carry the coordinate: {message}"
16115 );
16116 }
16117
16118 #[test]
16119 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
16120 let atn = predicate_after_token_atn();
16126 let mut parser = mini_parser(vec![
16127 TestToken::new(1).with_text("x"),
16128 TestToken::new(2).with_text("y"),
16129 TestToken::eof("parser-test", 2, 1, 2),
16130 ]);
16131
16132 parser
16133 .parse_atn_rule_with_runtime_options(
16134 &atn,
16135 0,
16136 ParserRuntimeOptions {
16137 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16138 ..ParserRuntimeOptions::default()
16139 },
16140 )
16141 .expect_err("first parse fails loud under the Error policy");
16142
16143 parser.reset_unknown_semantic_hits();
16148 assert!(
16149 parser.take_unknown_semantic_error().is_none(),
16150 "reset must drop stale unknown-predicate coordinates before a reused parse"
16151 );
16152 }
16153
16154 #[derive(Debug, Default)]
16155 struct RecordingHooks {
16156 predicates: Vec<(usize, usize, usize, Option<String>)>,
16157 actions: Vec<(usize, String, Option<String>)>,
16158 action_trees: Vec<Option<String>>,
16159 }
16160
16161 impl SemanticHooks for RecordingHooks {
16162 fn sempred<S>(
16163 &mut self,
16164 ctx: &mut ParserSemCtx<'_, S>,
16165 rule_index: usize,
16166 pred_index: usize,
16167 ) -> Option<bool>
16168 where
16169 S: TokenSource,
16170 {
16171 self.predicates.push((
16172 ctx.input_index(),
16173 rule_index,
16174 pred_index,
16175 ctx.token_text(1).map(|token| token.text().to_owned()),
16176 ));
16177 Some(true)
16178 }
16179
16180 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
16181 where
16182 S: TokenSource,
16183 {
16184 self.actions.push((
16185 action.source_state(),
16186 ctx.action_text(),
16187 ctx.rule_name().map(str::to_owned),
16188 ));
16189 self.action_trees.push(ctx.tree().map(Node::text));
16190 true
16191 }
16192 }
16193
16194 #[derive(Debug, Default)]
16195 struct RejectingPredicateHooks {
16196 predicates: Vec<(usize, usize, usize, Option<String>)>,
16197 }
16198
16199 impl SemanticHooks for RejectingPredicateHooks {
16200 fn sempred<S>(
16201 &mut self,
16202 ctx: &mut ParserSemCtx<'_, S>,
16203 rule_index: usize,
16204 pred_index: usize,
16205 ) -> Option<bool>
16206 where
16207 S: TokenSource,
16208 {
16209 self.predicates.push((
16210 ctx.input_index(),
16211 rule_index,
16212 pred_index,
16213 ctx.token_text(1).map(|token| token.text().to_owned()),
16214 ));
16215 Some(false)
16216 }
16217 }
16218
16219 #[test]
16220 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
16221 let atn = predicate_gated_same_lookahead_atn([0, 0]);
16222 let mut parser = mini_parser_with_hooks(
16223 vec![
16224 TestToken::new(1).with_text("x"),
16225 TestToken::eof("parser-test", 1, 1, 1),
16226 ],
16227 RecordingHooks::default(),
16228 );
16229
16230 let (tree, _) = parser
16231 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16232 .expect("both alternatives share one replay-safe predicate result");
16233
16234 assert_eq!(parser.node(tree).text(), "x<EOF>");
16235 assert_eq!(
16236 parser.semantic_hooks.predicates,
16237 vec![(0, 0, 0, Some("x".to_owned()))]
16238 );
16239 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
16240 }
16241
16242 #[test]
16243 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
16244 let atn = predicate_after_token_atn();
16245 let mut parser = mini_parser_with_hooks(
16246 vec![
16247 TestToken::new(1).with_text("x"),
16248 TestToken::new(2).with_text("y"),
16249 TestToken::eof("parser-test", 2, 1, 2),
16250 ],
16251 RecordingHooks::default(),
16252 );
16253
16254 let (tree, _) = parser
16255 .parse_atn_rule_with_runtime_options(
16256 &atn,
16257 0,
16258 ParserRuntimeOptions {
16259 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16260 ..ParserRuntimeOptions::default()
16261 },
16262 )
16263 .expect("hook supplies the missing predicate result");
16264
16265 assert_eq!(parser.node(tree).text(), "xy");
16266 assert_eq!(
16267 parser.semantic_hooks.predicates,
16268 vec![(1, 0, 0, Some("y".to_owned()))]
16269 );
16270 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
16271 }
16272
16273 #[test]
16274 fn runtime_options_default_preserves_semantic_hook_predicates() {
16275 let atn = predicate_after_token_atn();
16276 let mut parser = mini_parser_with_hooks(
16277 vec![
16278 TestToken::new(1).with_text("x"),
16279 TestToken::new(2).with_text("y"),
16280 TestToken::eof("parser-test", 2, 1, 2),
16281 ],
16282 RejectingPredicateHooks::default(),
16283 );
16284
16285 let result =
16286 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
16287
16288 assert!(
16289 result.is_err(),
16290 "default runtime options must not bypass semantic hooks for predicate ATNs"
16291 );
16292 assert_eq!(
16293 parser.semantic_hooks.predicates,
16294 vec![(1, 0, 0, Some("y".to_owned()))]
16295 );
16296 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
16297 }
16298
16299 #[test]
16300 fn semantic_hook_handles_committed_parser_action() {
16301 let atn = token_then_eof_atn();
16302 let mut parser = mini_parser_with_hooks(
16303 vec![
16304 TestToken::new(1).with_text("x"),
16305 TestToken::eof("parser-test", 1, 1, 1),
16306 ],
16307 RecordingHooks::default(),
16308 );
16309 let (tree, _) = parser
16310 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16311 .expect("rule parses before action hook is tested");
16312
16313 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
16314 assert_eq!(
16315 parser.semantic_hooks.actions,
16316 vec![(42, "x".to_owned(), Some("s".to_owned()))]
16317 );
16318 assert_eq!(
16319 parser.semantic_hooks.action_trees,
16320 [Some("x<EOF>".to_owned())]
16321 );
16322 }
16323
16324 #[test]
16325 fn unhandled_committed_action_fails_loud_under_error_policy() {
16326 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16330 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
16331 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
16332
16333 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
16335
16336 let error = parser
16337 .take_unknown_semantic_error()
16338 .expect("an unhandled committed action under Error policy must fail loud");
16339 let AntlrError::Unsupported(message) = error else {
16340 panic!("expected AntlrError::Unsupported, got {error:?}");
16341 };
16342 assert!(
16343 message.contains("unhandled semantic action") && message.contains("state=42"),
16344 "message should name the dropped action coordinate: {message}"
16345 );
16346
16347 let mut lenient =
16349 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16350 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
16351 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
16352 assert!(lenient.take_unknown_semantic_error().is_none());
16353 }
16354
16355 #[test]
16356 fn translated_predicate_is_unaffected_by_error_policy() {
16357 let atn = predicate_after_token_atn();
16358 let mut parser = mini_parser(vec![
16359 TestToken::new(1).with_text("x"),
16360 TestToken::new(2).with_text("y"),
16361 TestToken::eof("parser-test", 2, 1, 2),
16362 ]);
16363
16364 let (tree, _) = parser
16365 .parse_atn_rule_with_runtime_options(
16366 &atn,
16367 0,
16368 ParserRuntimeOptions {
16369 predicates: &[(0, 0, ParserPredicate::True)],
16370 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16371 ..ParserRuntimeOptions::default()
16372 },
16373 )
16374 .expect("a predicate covered by the table is not an unknown coordinate");
16375
16376 assert_eq!(parser.node(tree).text(), "xy");
16377 }
16378
16379 fn hook_predicate_semantics() -> ParserSemantics {
16384 let mut ir = SemIr::new();
16385 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
16386 ParserSemantics {
16387 ir,
16388 predicates: vec![ParserSemanticPredicate {
16389 rule_index: 0,
16390 pred_index: 0,
16391 expr,
16392 failure_message: None,
16393 }],
16394 actions: Vec::new(),
16395 }
16396 }
16397
16398 #[derive(Debug, Default)]
16399 struct DecliningHooks;
16400
16401 impl SemanticHooks for DecliningHooks {}
16402
16403 #[test]
16404 fn semir_hook_none_falls_through_to_assume_true() {
16405 let atn = predicate_after_token_atn();
16406 let semantics = hook_predicate_semantics();
16407 let mut parser = mini_parser_with_hooks(
16408 vec![
16409 TestToken::new(1).with_text("x"),
16410 TestToken::new(2).with_text("y"),
16411 TestToken::eof("parser-test", 2, 1, 2),
16412 ],
16413 DecliningHooks,
16414 );
16415
16416 let (tree, _) = parser
16417 .parse_atn_rule_with_runtime_options(
16418 &atn,
16419 0,
16420 ParserRuntimeOptions {
16421 semantics: Some(&semantics),
16422 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
16423 ..ParserRuntimeOptions::default()
16424 },
16425 )
16426 .expect("a declined SemIR hook must pass under assume-true");
16427
16428 assert_eq!(parser.node(tree).text(), "xy");
16429 }
16430
16431 #[test]
16432 fn semir_hook_none_falls_through_to_assume_false() {
16433 let atn = predicate_after_token_atn();
16434 let semantics = hook_predicate_semantics();
16435 let mut parser = mini_parser_with_hooks(
16436 vec![
16437 TestToken::new(1).with_text("x"),
16438 TestToken::new(2).with_text("y"),
16439 TestToken::eof("parser-test", 2, 1, 2),
16440 ],
16441 DecliningHooks,
16442 );
16443
16444 let result = parser.parse_atn_rule_with_runtime_options(
16445 &atn,
16446 0,
16447 ParserRuntimeOptions {
16448 semantics: Some(&semantics),
16449 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
16450 ..ParserRuntimeOptions::default()
16451 },
16452 );
16453
16454 assert!(
16455 result.is_err(),
16456 "a declined SemIR hook must fail the only guarded path under assume-false"
16457 );
16458 }
16459
16460 #[test]
16461 fn semir_hook_none_records_coordinate_under_error_policy() {
16462 let atn = predicate_after_token_atn();
16463 let semantics = hook_predicate_semantics();
16464 let mut parser = mini_parser_with_hooks(
16465 vec![
16466 TestToken::new(1).with_text("x"),
16467 TestToken::new(2).with_text("y"),
16468 TestToken::eof("parser-test", 2, 1, 2),
16469 ],
16470 DecliningHooks,
16471 );
16472
16473 let error = parser
16474 .parse_atn_rule_with_runtime_options(
16475 &atn,
16476 0,
16477 ParserRuntimeOptions {
16478 semantics: Some(&semantics),
16479 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16480 ..ParserRuntimeOptions::default()
16481 },
16482 )
16483 .expect_err("a declined SemIR hook under Error policy must fail the parse");
16484
16485 let AntlrError::Unsupported(message) = error else {
16486 panic!("expected AntlrError::Unsupported, got {error:?}");
16487 };
16488 assert!(
16489 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
16490 "message should name the unresolved coordinate: {message}"
16491 );
16492 }
16493
16494 #[test]
16495 fn generated_direct_predicate_honors_installed_policy() {
16496 let semantics = hook_predicate_semantics();
16502 let context = ParserRuleContext::new(0, -1);
16503
16504 let mut assume_true =
16505 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16506 assert!(
16507 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
16508 &semantics, 0, 0, &context, 0
16509 ),
16510 "default AssumeTrue accepts a declined hook"
16511 );
16512 assert!(assume_true.take_unknown_semantic_error().is_none());
16513
16514 let mut error_policy =
16515 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16516 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
16517 assert!(
16518 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
16519 &semantics, 0, 0, &context, 0
16520 ),
16521 "Error policy rejects a declined hook on the generated-direct path"
16522 );
16523 let error = error_policy
16524 .take_unknown_semantic_error()
16525 .expect("Error policy records the unresolved coordinate for the generated path");
16526 let AntlrError::Unsupported(message) = error else {
16527 panic!("expected AntlrError::Unsupported, got {error:?}");
16528 };
16529 assert!(message.contains("pred_index=0"), "message: {message}");
16530 }
16531
16532 #[test]
16533 fn parser_rule_start_skips_leading_hidden_tokens() {
16534 let atn = token_then_eof_atn();
16535 let mut parser = mini_parser(vec![
16536 TestToken::new(99)
16537 .with_text(" ")
16538 .with_channel(HIDDEN_CHANNEL),
16539 TestToken::new(1).with_text("x"),
16540 TestToken::eof("parser-test", 2, 1, 2),
16541 ]);
16542
16543 let tree = parser
16544 .parse_atn_rule(&atn, 0)
16545 .expect("artificial parser rule should parse");
16546 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
16547 panic!("rule node should be present");
16548 };
16549 assert_eq!(
16550 rule.start()
16551 .expect("rule should have a start token")
16552 .token_type(),
16553 1
16554 );
16555 }
16556
16557 #[test]
16558 fn parser_action_after_eof_stops_at_eof_token() {
16559 let atn = eof_then_action_atn();
16560 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
16561
16562 let (_, actions) = parser
16563 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16564 .expect("EOF action rule should parse");
16565
16566 assert_eq!(actions.len(), 1);
16567 assert_eq!(actions[0].stop_index(), Some(0));
16568 assert_eq!(
16569 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
16570 ""
16571 );
16572 }
16573
16574 #[test]
16575 fn after_action_stop_uses_rule_context_stop_not_cursor() {
16576 let mut id = TestToken::new(1).with_text("x");
16581 id.set_token_index(0);
16582 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
16583 eof.set_token_index(1);
16584 let mut parser = mini_parser(vec![id.clone(), eof]);
16585 parser.consume();
16587 assert_eq!(parser.la(1), TOKEN_EOF);
16588
16589 let mut ctx = ParserRuleContext::new(0, 0);
16592 parser.set_context_stop(
16593 &mut ctx,
16594 parser.token_id_at(0).expect("ID token should be buffered"),
16595 );
16596 let tree = parser.rule_node(ctx);
16597
16598 let current_index = parser.input.index();
16599 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
16601 assert_eq!(
16603 parser.after_action_stop_index_for_tree(tree, current_index),
16604 Some(0)
16605 );
16606 }
16607
16608 #[test]
16609 fn after_action_start_uses_rule_context_start_not_cursor() {
16610 let mut parser = mini_parser(vec![
16615 TestToken::new(9)
16616 .with_text(" ")
16617 .with_channel(HIDDEN_CHANNEL),
16618 TestToken::new(9)
16619 .with_text(" ")
16620 .with_channel(HIDDEN_CHANNEL),
16621 TestToken::new(1).with_text("x"),
16622 TestToken::eof("parser-test", 3, 1, 3),
16623 ]);
16624
16625 let mut ctx = ParserRuleContext::new(0, 0);
16626 parser.set_context_start(
16627 &mut ctx,
16628 parser.token_id_at(2).expect("ID token should be buffered"),
16629 );
16630 let tree = parser.rule_node(ctx);
16631
16632 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
16635
16636 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
16638 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
16639 }
16640
16641 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
16642 FastRecognizeOutcome {
16643 index,
16644 consumed_eof,
16645 diagnostics: DiagnosticSeqId::EMPTY,
16646 deferred_nodes: FastDeferredNodeId::EMPTY,
16647 nodes: NodeSeqId(marker),
16648 }
16649 }
16650
16651 #[test]
16652 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
16653 let mut outcomes = vec![
16654 clean_fast_outcome(4, false, 0),
16655 clean_fast_outcome(2, false, 1),
16656 clean_fast_outcome(4, false, 2),
16657 clean_fast_outcome(4, true, 3),
16658 clean_fast_outcome(2, false, 4),
16659 ];
16660 let mut scratch = FastOutcomeDedupScratch::default();
16661
16662 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16663
16664 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
16665 assert_eq!(
16666 outcomes
16667 .iter()
16668 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
16669 .collect::<Vec<_>>(),
16670 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
16671 );
16672 assert!(scratch.dense_words.is_empty());
16673 assert!(scratch.sparse_keys.is_empty());
16674 }
16675
16676 #[test]
16677 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
16678 let mut scratch = FastOutcomeDedupScratch::default();
16679 let mut outcomes = (100..109)
16680 .flat_map(|index| {
16681 [
16682 clean_fast_outcome(
16683 index,
16684 false,
16685 u32::try_from(index).expect("test index fits in u32"),
16686 ),
16687 clean_fast_outcome(index, false, u32::MAX),
16688 ]
16689 })
16690 .collect();
16691
16692 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16693
16694 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
16695 assert_eq!(outcomes.len(), 9);
16696 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
16697 let dense_capacity = scratch.dense_words.capacity();
16698
16699 let mut reused = (1_000..1_009)
16700 .map(|index| {
16701 clean_fast_outcome(
16702 index,
16703 false,
16704 u32::try_from(index).expect("test index fits in u32"),
16705 )
16706 })
16707 .collect();
16708 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
16709
16710 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
16711 assert_eq!(reused.len(), 9);
16712 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
16713 }
16714
16715 #[test]
16716 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
16717 let mut scratch = FastOutcomeDedupScratch::default();
16718 let sparse_indexes = [
16719 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
16720 ];
16721 let mut outcomes = sparse_indexes
16722 .into_iter()
16723 .chain([400_000])
16724 .enumerate()
16725 .map(|(marker, index)| {
16726 clean_fast_outcome(
16727 index,
16728 false,
16729 u32::try_from(marker).expect("test marker fits in u32"),
16730 )
16731 })
16732 .collect();
16733
16734 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16735
16736 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16737 assert_eq!(outcomes.len(), sparse_indexes.len());
16738 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
16739 let sparse_capacity = scratch.sparse_keys.capacity();
16740
16741 let mut reused = sparse_indexes
16742 .into_iter()
16743 .map(|index| {
16744 clean_fast_outcome(
16745 index,
16746 false,
16747 u32::try_from(index).expect("test index fits in u32"),
16748 )
16749 })
16750 .collect();
16751 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
16752
16753 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16754 assert_eq!(reused.len(), sparse_indexes.len());
16755 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
16756 }
16757
16758 #[test]
16759 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
16760 let mut scratch = FastOutcomeDedupScratch::default();
16761 scratch
16762 .sparse_keys
16763 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
16764 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
16765 let mut outcomes = (0..9)
16766 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
16767 .collect();
16768
16769 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16770
16771 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16772 assert!(scratch.sparse_keys.is_empty());
16773 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
16774 }
16775
16776 #[test]
16777 fn fast_outcome_selection_respects_sll_tie_order() {
16778 let mut arena = RecognitionArena::default();
16779 let first = FastRecognizeOutcome {
16780 index: 1,
16781 consumed_eof: false,
16782 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16783 line: 1,
16784 column: 0,
16785 message: "mismatched input 'x'".to_owned(),
16786 }]),
16787 deferred_nodes: FastDeferredNodeId::EMPTY,
16788 nodes: NodeSeqId::EMPTY,
16789 };
16790 let second = FastRecognizeOutcome {
16791 index: first.index,
16792 consumed_eof: first.consumed_eof,
16793 diagnostics: DiagnosticSeqId::EMPTY,
16794 deferred_nodes: FastDeferredNodeId::EMPTY,
16795 nodes: NodeSeqId::EMPTY,
16796 };
16797
16798 let selected = select_best_fast_outcome(
16799 [first, second].into_iter(),
16800 PredictionMode::Sll,
16801 None,
16802 |_| panic!("caller-follow token probe should not run"),
16803 &arena,
16804 )
16805 .expect("one outcome should be selected");
16806 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
16807 let eof_second = FastRecognizeOutcome {
16808 index: second.index,
16809 consumed_eof: true,
16810 diagnostics: DiagnosticSeqId::EMPTY,
16811 deferred_nodes: FastDeferredNodeId::EMPTY,
16812 nodes: NodeSeqId::EMPTY,
16813 };
16814 let selected = select_best_fast_outcome(
16815 [first, eof_second].into_iter(),
16816 PredictionMode::Sll,
16817 None,
16818 |_| panic!("caller-follow token probe should not run"),
16819 &arena,
16820 )
16821 .expect("one outcome should be selected");
16822 assert!(!selected.consumed_eof);
16823 let selected = select_best_fast_outcome(
16824 [first, second].into_iter(),
16825 PredictionMode::Ll,
16826 None,
16827 |_| panic!("caller-follow token probe should not run"),
16828 &arena,
16829 )
16830 .expect("one outcome should be selected");
16831 assert!(selected.diagnostics.is_empty());
16832 }
16833
16834 #[test]
16835 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
16836 let mut arena = RecognitionArena::default();
16837 let first = FastRecognizeOutcome {
16838 index: 3,
16839 consumed_eof: false,
16840 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16841 line: 1,
16842 column: 0,
16843 message: "mismatched input 'x' expecting 'a'".to_owned(),
16844 }]),
16845 deferred_nodes: FastDeferredNodeId::EMPTY,
16846 nodes: NodeSeqId::EMPTY,
16847 };
16848 let same_rank = FastRecognizeOutcome {
16849 index: first.index,
16850 consumed_eof: first.consumed_eof,
16851 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16852 line: 1,
16853 column: 0,
16854 message: "mismatched input 'x' expecting 'b'".to_owned(),
16855 }]),
16856 deferred_nodes: FastDeferredNodeId::EMPTY,
16857 nodes: NodeSeqId::EMPTY,
16858 };
16859 let better_rank = FastRecognizeOutcome {
16860 index: first.index,
16861 consumed_eof: first.consumed_eof,
16862 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16863 line: 1,
16864 column: 0,
16865 message: "missing 'a' at 'x'".to_owned(),
16866 }]),
16867 deferred_nodes: FastDeferredNodeId::EMPTY,
16868 nodes: NodeSeqId::EMPTY,
16869 };
16870 let mut outcomes = vec![first, same_rank, better_rank];
16871
16872 dedupe_fast_outcomes(&mut outcomes, &arena);
16873
16874 assert_eq!(outcomes.len(), 2);
16875 assert_eq!(
16876 arena
16877 .diagnostics(outcomes[0].diagnostics)
16878 .next()
16879 .expect("first diagnostic")
16880 .message,
16881 "mismatched input 'x' expecting 'a'"
16882 );
16883 assert_eq!(
16884 arena
16885 .diagnostics(outcomes[1].diagnostics)
16886 .next()
16887 .expect("second diagnostic")
16888 .message,
16889 "missing 'a' at 'x'"
16890 );
16891 }
16892
16893 #[test]
16894 fn fast_outcome_selection_prefers_generated_caller_follow() {
16895 let arena = RecognitionArena::default();
16896 let earlier = FastRecognizeOutcome {
16897 index: 7,
16898 consumed_eof: false,
16899 diagnostics: DiagnosticSeqId::EMPTY,
16900 deferred_nodes: FastDeferredNodeId::EMPTY,
16901 nodes: NodeSeqId::EMPTY,
16902 };
16903 let later = FastRecognizeOutcome {
16904 index: 8,
16905 consumed_eof: false,
16906 diagnostics: DiagnosticSeqId::EMPTY,
16907 deferred_nodes: FastDeferredNodeId::EMPTY,
16908 nodes: NodeSeqId::EMPTY,
16909 };
16910 let mut follow = TokenBitSet::default();
16911 follow.insert(5);
16912
16913 let selected = select_best_fast_outcome(
16914 [later, earlier].into_iter(),
16915 PredictionMode::Ll,
16916 Some(&follow),
16917 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
16918 &arena,
16919 )
16920 .expect("one outcome should be selected");
16921 assert_eq!(selected.index, 7);
16922
16923 let selected = select_best_fast_outcome(
16924 [later, earlier].into_iter(),
16925 PredictionMode::Ll,
16926 Some(&follow),
16927 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
16928 &arena,
16929 )
16930 .expect("one outcome should be selected");
16931 assert_eq!(selected.index, 8);
16932
16933 let indented_next_statement = FastRecognizeOutcome {
16934 index: 9,
16935 consumed_eof: false,
16936 diagnostics: DiagnosticSeqId::EMPTY,
16937 deferred_nodes: FastDeferredNodeId::EMPTY,
16938 nodes: NodeSeqId::EMPTY,
16939 };
16940 let selected = select_best_fast_outcome(
16941 [indented_next_statement, earlier].into_iter(),
16942 PredictionMode::Ll,
16943 Some(&follow),
16944 |index| {
16945 let is_boundary = index == 7;
16946 let is_boundary_gap = matches!(index, 7 | 8);
16947 (
16948 if index == 7 { 5 } else { TOKEN_EOF },
16949 is_boundary,
16950 is_boundary_gap,
16951 )
16952 },
16953 &arena,
16954 )
16955 .expect("one outcome should be selected");
16956 assert_eq!(selected.index, 7);
16957
16958 let continuation = FastRecognizeOutcome {
16959 index: 10,
16960 consumed_eof: false,
16961 diagnostics: DiagnosticSeqId::EMPTY,
16962 deferred_nodes: FastDeferredNodeId::EMPTY,
16963 nodes: NodeSeqId::EMPTY,
16964 };
16965 let selected = select_best_fast_outcome(
16966 [continuation, earlier].into_iter(),
16967 PredictionMode::Ll,
16968 Some(&follow),
16969 |index| {
16970 let is_boundary = matches!(index, 7 | 9);
16971 (
16972 if index == 7 { 5 } else { TOKEN_EOF },
16973 is_boundary,
16974 is_boundary,
16975 )
16976 },
16977 &arena,
16978 )
16979 .expect("one outcome should be selected");
16980 assert_eq!(selected.index, 10);
16981
16982 let selected = select_best_fast_outcome(
16983 [earlier, later].into_iter(),
16984 PredictionMode::Sll,
16985 Some(&follow),
16986 |_| panic!("caller-follow token probe should not run in SLL mode"),
16987 &arena,
16988 )
16989 .expect("one outcome should be selected");
16990 assert_eq!(selected.index, 8);
16991 }
16992
16993 #[test]
16994 fn caller_follow_boundary_text_requires_separator_shape() {
16995 assert!(is_caller_follow_boundary_text(";"));
16996 assert!(is_caller_follow_boundary_text("\n"));
16997 assert!(is_caller_follow_boundary_text("\r\n "));
16998 assert!(is_caller_follow_boundary_text(";\n"));
16999 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
17000 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
17001 assert!(!is_caller_follow_boundary_text("identifier"));
17002 assert!(is_caller_follow_boundary_gap_text(" \t "));
17003 assert!(is_caller_follow_boundary_gap_text("\n "));
17004 assert!(is_caller_follow_boundary_gap_text(";\t"));
17005 assert!(!is_caller_follow_boundary_gap_text(
17006 "\"\"\"line1\nline2\"\"\""
17007 ));
17008 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
17009 }
17010
17011 #[test]
17012 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
17013 let mut parser = mini_parser(vec![
17014 TestToken::new(5).with_text("\n"),
17015 TestToken::new(6)
17016 .with_text("// comment\n")
17017 .with_channel(HIDDEN_CHANNEL),
17018 TestToken::new(1).with_text("x"),
17019 TestToken::eof("parser-test", 1, 2, 0),
17020 ]);
17021
17022 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
17023 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
17024 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
17025 }
17026
17027 #[test]
17028 fn caller_follow_token_info_uses_stream_visible_channel() {
17029 let source = Source {
17030 tokens: vec![
17031 TestToken::new(5).with_text("\n").with_channel(2),
17032 TestToken::new(1).with_text("x").with_channel(2),
17033 TestToken::new(6)
17034 .with_text("// comment\n")
17035 .with_channel(HIDDEN_CHANNEL),
17036 TestToken::eof("parser-test", 1, 2, 0),
17037 ],
17038 index: 0,
17039 };
17040 let data = RecognizerData::new(
17041 "Mini.g4",
17042 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17043 );
17044 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
17045
17046 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
17047 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
17048 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
17049 }
17050
17051 #[test]
17052 fn reset_per_parse_caches_clears_state_expected_token_cache() {
17053 let atn = token_then_eof_atn();
17054 let mut parser = mini_parser(Vec::new());
17055
17056 let _ = parser.cached_state_expected_token_set(&atn, 0);
17057 assert!(!parser.state_expected_token_cache.is_empty());
17058
17059 parser.reset_per_parse_caches();
17060 assert!(parser.state_expected_token_cache.is_empty());
17061 }
17062
17063 #[test]
17064 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
17065 let cyclic = epsilon_cycle_atn();
17066 let acyclic = token_then_eof_atn();
17067 let mut parser = mini_parser(Vec::new());
17068
17069 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
17070 assert_eq!(
17071 parser.empty_cycle_cache_atn,
17072 Some(SharedAtnCacheKey::for_atn(&cyclic))
17073 );
17074 assert_eq!(parser.empty_cycle_cache[1], Some(true));
17075
17076 parser.reset_per_parse_caches();
17077 assert_eq!(parser.empty_cycle_cache[1], Some(true));
17078 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
17079
17080 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
17081 assert_eq!(
17082 parser.empty_cycle_cache_atn,
17083 Some(SharedAtnCacheKey::for_atn(&acyclic))
17084 );
17085 assert_eq!(parser.empty_cycle_cache[1], Some(false));
17086 }
17087
17088 #[test]
17089 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
17090 let source = Source {
17091 tokens: vec![
17092 TestToken::new(1).with_text("x"),
17093 TestToken::eof("parser-test", 1, 1, 1),
17094 ],
17095 index: 0,
17096 };
17097 let data = RecognizerData::new(
17098 "Mini.g4",
17099 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17100 );
17101 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17102 let expected = ExpectedTokens {
17103 index: Some(0),
17104 symbols: BTreeSet::new(),
17105 no_viable: None,
17106 };
17107
17108 let (_, message) = parser.expected_error_message(0, 0, &expected);
17109
17110 assert_eq!(message, "mismatched input 'x'");
17111 }
17112
17113 #[test]
17114 fn eof_rule_stop_index_points_at_eof_token() {
17115 let source = Source {
17116 tokens: vec![
17117 TestToken::new(1).with_text("x"),
17118 TestToken::eof("parser-test", 1, 1, 1),
17119 ],
17120 index: 0,
17121 };
17122 let data = RecognizerData::new(
17123 "Mini.g4",
17124 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17125 );
17126 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17127
17128 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
17129 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
17130 }
17131
17132 #[test]
17133 fn generated_parser_action_uses_current_rule_stop_boundary() {
17134 let mut parser = mini_parser(vec![
17135 TestToken::new(1).with_text("x"),
17136 TestToken::eof("parser-test", 1, 1, 1),
17137 ]);
17138
17139 parser.match_token(1).expect("token should match");
17140 let action = parser.parser_action_at_current(7, 0, 0, false);
17141 assert_eq!(action.source_state(), 7);
17142 assert_eq!(action.rule_index(), 0);
17143 assert_eq!(action.start_index(), 0);
17144 assert_eq!(action.stop_index(), Some(0));
17145
17146 parser.match_eof().expect("EOF should match");
17147 let action = parser.parser_action_at_current(8, 0, 0, true);
17148 assert_eq!(action.stop_index(), Some(1));
17149 }
17150
17151 #[test]
17152 fn folds_left_recursive_boundary_into_rule_node() {
17153 let mut arena = RecognitionArena::default();
17154 let first = arena.push_node(ArenaRecognizedNode::Token {
17155 token: TokenId::try_from(0).expect("test token ID"),
17156 });
17157 let boundary =
17158 arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: 1 });
17159 let second = arena.push_node(ArenaRecognizedNode::Token {
17160 token: TokenId::try_from(1).expect("test token ID"),
17161 });
17162 let mut nodes = NodeSeqId::EMPTY;
17163 for node in [first, boundary, second].into_iter().rev() {
17164 nodes = arena.prepend(nodes, node);
17165 }
17166
17167 let folded = arena.fold_left_recursive_boundaries(nodes);
17168 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
17169
17170 assert_eq!(folded_nodes.len(), 2);
17171 let ArenaRecognizedNode::Rule {
17172 rule_index,
17173 invoking_state,
17174 start_index,
17175 stop_index,
17176 children,
17177 ..
17178 } = arena.node(folded_nodes[0])
17179 else {
17180 panic!("first folded node should be a rule");
17181 };
17182 assert_eq!(rule_index, 1);
17183 assert_eq!(invoking_state, -1);
17184 assert_eq!(start_index, 0);
17185 assert_eq!(stop_index, Some(0));
17186 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
17187 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
17188
17189 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
17190 assert_eq!(
17191 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17192 (4, 3, 1)
17193 );
17194 assert_eq!(
17195 (stats.total_links, stats.live_links, stats.dead_links),
17196 (9, 3, 6)
17197 );
17198 }
17199
17200 #[test]
17201 fn recognition_arena_reports_live_dead_and_retained_capacity() {
17202 let mut arena = RecognitionArena::default();
17203 let token = arena.push_node(ArenaRecognizedNode::Token {
17204 token: TokenId::try_from(0).expect("test token ID"),
17205 });
17206 let extra = arena.push_extra(RecognitionExtra::MissingToken {
17207 token_type: 2,
17208 at_index: 1,
17209 text: "<missing X>".to_owned(),
17210 });
17211 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
17212 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
17213 token: TokenId::try_from(1).expect("test token ID"),
17214 });
17215 let mut live = NodeSeqId::EMPTY;
17216 live = arena.prepend(live, missing);
17217 live = arena.prepend(live, token);
17218 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
17219 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17220 line: 1,
17221 column: 0,
17222 message: "missing X".to_owned(),
17223 }]);
17224 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17225 line: 1,
17226 column: 1,
17227 message: "discarded".to_owned(),
17228 }]);
17229 let deferred_children = arena.deferred_fragment(live);
17230 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
17231 rule_index: 0,
17232 invoking_state: -1,
17233 start_index: 0,
17234 stop_index: Some(1),
17235 deferred_children,
17236 children: NodeSeqId::EMPTY,
17237 });
17238
17239 let stats = arena.stats(live, live_diagnostics);
17240
17241 assert_eq!(
17242 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17243 (3, 2, 1)
17244 );
17245 assert_eq!(
17246 (stats.total_links, stats.live_links, stats.dead_links),
17247 (5, 3, 2)
17248 );
17249 assert_eq!(
17250 (stats.total_extras, stats.live_extras, stats.dead_extras),
17251 (3, 2, 1)
17252 );
17253 assert!(size_of::<SeqLink>() <= 8);
17254 assert!(size_of::<DiagnosticLink>() <= 8);
17255 assert!(size_of::<FastDeferredNode>() <= 12);
17256 assert!(size_of::<FastDeferredRule>() <= 28);
17257 assert!(size_of::<FastRecognizeOutcome>() <= 24);
17258 let capacities = (
17259 stats.node_capacity,
17260 stats.link_capacity,
17261 stats.extra_capacity,
17262 );
17263 let deferred_capacities = (
17264 arena.deferred_nodes.capacity(),
17265 arena.deferred_rules.capacity(),
17266 );
17267
17268 arena.reset();
17269 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
17270 assert_eq!(
17271 (reset.total_nodes, reset.total_links, reset.total_extras),
17272 (0, 0, 0)
17273 );
17274 assert_eq!(
17275 (
17276 reset.node_capacity,
17277 reset.link_capacity,
17278 reset.extra_capacity,
17279 ),
17280 capacities
17281 );
17282 assert!(arena.deferred_nodes.is_empty());
17283 assert!(arena.deferred_rules.is_empty());
17284 assert_eq!(
17285 (
17286 arena.deferred_nodes.capacity(),
17287 arena.deferred_rules.capacity(),
17288 ),
17289 deferred_capacities
17290 );
17291 }
17292
17293 #[test]
17294 fn parser_computes_recognition_arena_stats_on_demand() {
17295 let mut parser = mini_parser(Vec::new());
17296 let live = parser
17297 .recognition_arena
17298 .push_node(ArenaRecognizedNode::Token {
17299 token: TokenId::try_from(0).expect("test token ID"),
17300 });
17301 let discarded = parser
17302 .recognition_arena
17303 .push_node(ArenaRecognizedNode::ErrorToken {
17304 token: TokenId::try_from(1).expect("test token ID"),
17305 });
17306 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
17307 let _discarded_root = parser
17308 .recognition_arena
17309 .prepend(NodeSeqId::EMPTY, discarded);
17310 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
17311
17312 let stats = parser.recognition_arena_stats();
17313
17314 assert_eq!(
17315 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17316 (2, 1, 1)
17317 );
17318 assert_eq!(
17319 (stats.total_links, stats.live_links, stats.dead_links),
17320 (2, 1, 1)
17321 );
17322 }
17323
17324 #[test]
17325 fn recognition_arena_drops_capacity_above_retention_limit() {
17326 let mut storage = Vec::<u8>::with_capacity(4);
17327 storage.extend([1, 2, 3]);
17328
17329 reset_arena_vec(&mut storage, 3);
17330
17331 assert!(storage.is_empty());
17332 assert_eq!(storage.capacity(), 0);
17333 }
17334
17335 #[test]
17336 fn recognition_arena_concatenates_diagnostics_in_source_order() {
17337 let mut arena = RecognitionArena::default();
17338 let prefix = arena.diagnostic_sequence([
17339 ParserDiagnostic {
17340 line: 1,
17341 column: 0,
17342 message: "first".to_owned(),
17343 },
17344 ParserDiagnostic {
17345 line: 1,
17346 column: 1,
17347 message: "second".to_owned(),
17348 },
17349 ]);
17350 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
17351 line: 1,
17352 column: 2,
17353 message: "third".to_owned(),
17354 }]);
17355 let extras_before = arena.extras.len();
17356
17357 let combined = arena.concat_diagnostics(prefix, suffix);
17358 let messages = arena
17359 .diagnostics(combined)
17360 .map(|diagnostic| diagnostic.message.as_str())
17361 .collect::<Vec<_>>();
17362
17363 assert_eq!(messages, ["first", "second", "third"]);
17364 assert_eq!(arena.extras.len(), extras_before);
17365 }
17366
17367 #[test]
17368 fn outcome_ties_keep_later_non_recursive_alternative() {
17369 let arena = RecognitionArena::default();
17370 let first = RecognizeOutcome {
17371 index: 1,
17372 consumed_eof: false,
17373 alt_number: 0,
17374 member_values: BTreeMap::new(),
17375 return_values: BTreeMap::new(),
17376 diagnostics: DiagnosticSeqId::EMPTY,
17377 decisions: Vec::new(),
17378 actions: vec![ParserAction::new(1, 0, 0, None)],
17379 nodes: NodeSeqId::EMPTY,
17380 };
17381 let second = RecognizeOutcome {
17382 actions: vec![ParserAction::new(2, 0, 0, None)],
17383 ..first.clone()
17384 };
17385
17386 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17387 .expect("one outcome should be selected");
17388 assert_eq!(selected.actions[0].source_state(), 2);
17389 }
17390
17391 #[test]
17392 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
17393 let arena = RecognitionArena::default();
17394 let first = RecognizeOutcome {
17395 index: 1,
17396 consumed_eof: false,
17397 alt_number: 0,
17398 member_values: BTreeMap::new(),
17399 return_values: BTreeMap::new(),
17400 diagnostics: DiagnosticSeqId::EMPTY,
17401 decisions: Vec::new(),
17402 actions: vec![ParserAction::new(1, 0, 0, None)],
17403 nodes: NodeSeqId::EMPTY,
17404 };
17405 let second = RecognizeOutcome {
17406 actions: vec![
17407 ParserAction::new(2, 0, 0, None),
17408 ParserAction::new(3, 0, 0, None),
17409 ],
17410 ..first.clone()
17411 };
17412
17413 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
17414 .expect("one outcome should be selected");
17415 assert_eq!(selected.actions.len(), 2);
17416 }
17417
17418 #[test]
17419 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
17420 let arena = RecognitionArena::default();
17421 let first = RecognizeOutcome {
17422 index: 7,
17423 consumed_eof: false,
17424 alt_number: 0,
17425 member_values: BTreeMap::new(),
17426 return_values: BTreeMap::new(),
17427 diagnostics: DiagnosticSeqId::EMPTY,
17428 decisions: vec![1, 0],
17429 actions: vec![
17430 ParserAction::new(23, 2, 2, Some(4)),
17431 ParserAction::new(23, 2, 0, Some(6)),
17432 ],
17433 nodes: NodeSeqId::EMPTY,
17434 };
17435 let second = RecognizeOutcome {
17436 decisions: vec![0, 1],
17437 actions: vec![
17438 ParserAction::new(23, 2, 2, Some(6)),
17439 ParserAction::new(23, 2, 0, Some(6)),
17440 ],
17441 ..first.clone()
17442 };
17443
17444 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17445 .expect("one outcome should be selected");
17446 assert_eq!(selected.actions[0].stop_index(), Some(6));
17447 }
17448
17449 #[test]
17450 fn outcome_ties_keep_first_recursive_tree_shape() {
17451 let mut arena = RecognitionArena::default();
17452 let token = arena.push_node(ArenaRecognizedNode::Token {
17453 token: TokenId::try_from(0).expect("test token ID"),
17454 });
17455 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
17456 let inner = arena.push_node(ArenaRecognizedNode::Rule {
17457 rule_index: 1,
17458 invoking_state: -1,
17459 alt_number: 0,
17460 start_index: 0,
17461 stop_index: Some(0),
17462 return_values: None,
17463 children: token_children,
17464 });
17465 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
17466 let outer = arena.push_node(ArenaRecognizedNode::Rule {
17467 rule_index: 1,
17468 invoking_state: -1,
17469 alt_number: 0,
17470 start_index: 0,
17471 stop_index: Some(0),
17472 return_values: None,
17473 children: inner_children,
17474 });
17475 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
17476 let first = RecognizeOutcome {
17477 index: 1,
17478 consumed_eof: false,
17479 alt_number: 0,
17480 member_values: BTreeMap::new(),
17481 return_values: BTreeMap::new(),
17482 diagnostics: DiagnosticSeqId::EMPTY,
17483 decisions: Vec::new(),
17484 actions: vec![ParserAction::new(1, 0, 0, None)],
17485 nodes: recursive_nodes,
17486 };
17487 let second = RecognizeOutcome {
17488 index: 1,
17489 consumed_eof: false,
17490 alt_number: 0,
17491 member_values: BTreeMap::new(),
17492 return_values: BTreeMap::new(),
17493 diagnostics: DiagnosticSeqId::EMPTY,
17494 decisions: Vec::new(),
17495 actions: vec![ParserAction::new(2, 0, 0, None)],
17496 nodes: recursive_nodes,
17497 };
17498
17499 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17500 .expect("one outcome should be selected");
17501 assert_eq!(selected.actions[0].source_state(), 1);
17502 }
17503
17504 #[test]
17505 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
17506 let mut arena = RecognitionArena::default();
17507 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17508 line: 1,
17509 column: 3,
17510 message: "missing 'Y' at '<EOF>'".to_owned(),
17511 }]);
17512 let first_alt = RecognizeOutcome {
17513 index: 2,
17514 consumed_eof: true,
17515 alt_number: 0,
17516 member_values: BTreeMap::new(),
17517 return_values: BTreeMap::new(),
17518 diagnostics: recovered_diagnostics,
17519 decisions: vec![0],
17520 actions: vec![ParserAction::new(1, 0, 0, None)],
17521 nodes: NodeSeqId::EMPTY,
17522 };
17523 let second_alt = RecognizeOutcome {
17524 diagnostics: DiagnosticSeqId::EMPTY,
17525 decisions: vec![1],
17526 actions: vec![ParserAction::new(2, 0, 0, None)],
17527 ..first_alt.clone()
17528 };
17529
17530 let selected = select_best_outcome(
17531 [second_alt, first_alt].into_iter(),
17532 PredictionMode::Sll,
17533 &arena,
17534 )
17535 .expect("one outcome should be selected");
17536 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
17537 assert_eq!(selected.decisions, [0]);
17538 }
17539}