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 FAST_RECOGNIZE_STACK_CHECK_INTERVAL: usize = 8;
109const FAST_RECOGNIZE_RED_ZONE: usize = 1024 * 1024;
110const FAST_RECOGNIZE_STACK_SIZE: usize = 4 * 1024 * 1024;
111const ADAPTIVE_DIRECT_STEP_LIMIT: usize = RECOGNITION_DEPTH_LIMIT;
115const CLEAN_MEMO_PROBE_LIMIT: usize = 4096;
119const CLEAN_MEMO_REPEAT_LIMIT: usize = 8;
120const CLEAN_MEMO_REPROBE_INTERVAL: usize = 262_144;
123const FAST_RECOGNIZE_VISITING_CAPACITY: usize = 256;
124const FAST_RECOGNIZE_MIN_MEMO_CAPACITY: usize = 256;
125const FAST_RECOGNIZE_MAX_MEMO_CAPACITY: usize = 524_288;
126const FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY: usize = 65_536;
127
128#[derive(Clone, Copy, Debug, Eq, PartialEq)]
129enum CleanMemoMode {
130 Probe,
131 Promote,
132 Sparse,
133}
134
135fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
136 intervals
137 .iter()
138 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
139}
140
141fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
142 let mut symbols = BTreeSet::new();
143 for (start, stop) in intervals {
144 symbols.extend(*start..=*stop);
145 }
146 symbols
147}
148
149fn interval_complement_symbols(
150 intervals: &[(i32, i32)],
151 min_vocabulary: i32,
152 max_vocabulary: i32,
153) -> BTreeSet<i32> {
154 (min_vocabulary..=max_vocabulary)
155 .filter(|symbol| !interval_set_contains(intervals, *symbol))
156 .collect()
157}
158
159#[cfg(feature = "perf-counters")]
160mod perf_counters {
161 use std::cell::Cell;
162 thread_local! {
163 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
164 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
165 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
166 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
167 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
168 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
169 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
170 pub(super) static OUTCOME_DEDUPE_INPUTS: Cell<u64> = const { Cell::new(0) };
171 pub(super) static OUTCOME_DEDUPE_REMOVED: Cell<u64> = const { Cell::new(0) };
172 pub(super) static OUTCOME_DEDUPE_INLINE: Cell<u64> = const { Cell::new(0) };
173 pub(super) static OUTCOME_DEDUPE_DENSE: Cell<u64> = const { Cell::new(0) };
174 pub(super) static OUTCOME_DEDUPE_SPARSE: Cell<u64> = const { Cell::new(0) };
175 pub(super) static OUTCOME_DEDUPE_DENSE_WORDS: Cell<u64> = const { Cell::new(0) };
176 }
177 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
178 c.with(|v| v.set(v.get() + n));
179 }
180 thread_local! {
181 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
182 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
183 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
184 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
185 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
186 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
187 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
188 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
189 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
190 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
191 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
192 }
193 pub(super) fn snapshot() -> [(&'static str, u64); 24] {
194 [
195 ("rfs_calls", RFS_CALLS.with(Cell::get)),
196 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
197 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
198 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
199 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
200 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
201 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
202 (
203 "outcome_dedupe_inputs",
204 OUTCOME_DEDUPE_INPUTS.with(Cell::get),
205 ),
206 (
207 "outcome_dedupe_removed",
208 OUTCOME_DEDUPE_REMOVED.with(Cell::get),
209 ),
210 (
211 "outcome_dedupe_inline",
212 OUTCOME_DEDUPE_INLINE.with(Cell::get),
213 ),
214 ("outcome_dedupe_dense", OUTCOME_DEDUPE_DENSE.with(Cell::get)),
215 (
216 "outcome_dedupe_sparse",
217 OUTCOME_DEDUPE_SPARSE.with(Cell::get),
218 ),
219 (
220 "outcome_dedupe_dense_words",
221 OUTCOME_DEDUPE_DENSE_WORDS.with(Cell::get),
222 ),
223 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
224 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
225 (
226 "atom_range_transitions",
227 ATOM_RANGE_TRANSITIONS.with(Cell::get),
228 ),
229 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
230 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
231 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
232 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
233 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
234 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
235 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
236 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
237 ]
238 }
239 pub fn reset() {
240 RFS_CALLS.with(|c| c.set(0));
241 RFS_MEMO_HITS.with(|c| c.set(0));
242 RFS_MEMO_MISSES.with(|c| c.set(0));
243 RFS_VISITING_CYCLE.with(|c| c.set(0));
244 MEMO_INSERTED.with(|c| c.set(0));
245 OUTCOMES_PUSHED.with(|c| c.set(0));
246 OUTCOMES_CLONED.with(|c| c.set(0));
247 OUTCOME_DEDUPE_INPUTS.with(|c| c.set(0));
248 OUTCOME_DEDUPE_REMOVED.with(|c| c.set(0));
249 OUTCOME_DEDUPE_INLINE.with(|c| c.set(0));
250 OUTCOME_DEDUPE_DENSE.with(|c| c.set(0));
251 OUTCOME_DEDUPE_SPARSE.with(|c| c.set(0));
252 OUTCOME_DEDUPE_DENSE_WORDS.with(|c| c.set(0));
253 EPSILON_TRANSITIONS.with(|c| c.set(0));
254 RULE_TRANSITIONS.with(|c| c.set(0));
255 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
256 SINGLE_TRANS_BODY.with(|c| c.set(0));
257 MULTI_TRANS_BODY.with(|c| c.set(0));
258 SINGLE_TRANS_RULE.with(|c| c.set(0));
259 SINGLE_TRANS_ATOM.with(|c| c.set(0));
260 SINGLE_TRANS_OTHER.with(|c| c.set(0));
261 OUTCOMES_RETURN_0.with(|c| c.set(0));
262 OUTCOMES_RETURN_1.with(|c| c.set(0));
263 OUTCOMES_RETURN_N.with(|c| c.set(0));
264 }
265 pub fn dump() {
266 for (name, value) in snapshot() {
267 #[allow(clippy::print_stderr)]
268 {
269 eprintln!("perf {name}={value}");
270 }
271 }
272 }
273}
274
275#[cfg(feature = "perf-counters")]
276pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
277const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
282#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
291pub struct ParserAction {
292 source_state: usize,
293 rule_index: usize,
294 start_index: usize,
295 stop_index: Option<usize>,
296 rule_init: bool,
297 expected_state: Option<usize>,
298}
299
300impl ParserAction {
301 pub const fn new(
303 source_state: usize,
304 rule_index: usize,
305 start_index: usize,
306 stop_index: Option<usize>,
307 ) -> Self {
308 Self {
309 source_state,
310 rule_index,
311 start_index,
312 stop_index,
313 rule_init: false,
314 expected_state: None,
315 }
316 }
317
318 pub const fn new_rule_init(
320 rule_index: usize,
321 start_index: usize,
322 expected_state: Option<usize>,
323 ) -> Self {
324 Self {
325 source_state: usize::MAX,
326 rule_index,
327 start_index,
328 stop_index: None,
329 rule_init: true,
330 expected_state,
331 }
332 }
333
334 pub const fn source_state(&self) -> usize {
336 self.source_state
337 }
338
339 pub const fn rule_index(&self) -> usize {
341 self.rule_index
342 }
343
344 pub const fn start_index(&self) -> usize {
346 self.start_index
347 }
348
349 pub const fn stop_index(&self) -> Option<usize> {
351 self.stop_index
352 }
353
354 pub const fn is_rule_init(&self) -> bool {
356 self.rule_init
357 }
358
359 pub const fn expected_state(&self) -> Option<usize> {
361 self.expected_state
362 }
363}
364
365pub struct ParserSemCtx<'a, S>
373where
374 S: TokenSource,
375{
376 input: &'a mut CommonTokenStream<S>,
377 tree_storage: &'a ParseTreeStorage,
378 rule_index: usize,
379 coordinate_index: usize,
380 rule_name: Option<String>,
381 context: Option<&'a ParserRuleContext>,
382 tree: Option<ParseTree>,
383 local_int_arg: Option<(usize, i64)>,
384 member_values: &'a BTreeMap<usize, i64>,
385 action: Option<ParserAction>,
386}
387
388impl<S> std::fmt::Debug for ParserSemCtx<'_, S>
389where
390 S: TokenSource,
391{
392 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
393 f.debug_struct("ParserSemCtx")
394 .field("rule_index", &self.rule_index)
395 .field("coordinate_index", &self.coordinate_index)
396 .field("rule_name", &self.rule_name)
397 .field("context", &self.context)
398 .field("tree", &self.tree)
399 .field("local_int_arg", &self.local_int_arg)
400 .field("member_values", &self.member_values)
401 .field("action", &self.action)
402 .finish_non_exhaustive()
403 }
404}
405
406impl<'a, S> ParserSemCtx<'a, S>
407where
408 S: TokenSource,
409{
410 #[must_use]
412 pub const fn rule_index(&self) -> usize {
413 self.rule_index
414 }
415
416 #[must_use]
418 pub fn rule_name(&self) -> Option<&str> {
419 self.rule_name.as_deref()
420 }
421
422 #[must_use]
426 pub const fn coordinate_index(&self) -> usize {
427 self.coordinate_index
428 }
429
430 #[must_use]
432 pub fn input_index(&self) -> usize {
433 self.input.index()
434 }
435
436 pub fn la(&mut self, offset: isize) -> i32 {
438 self.input.la(offset)
439 }
440
441 pub fn lt(&self, offset: isize) -> Option<TokenView<'_>> {
443 self.input.lt(offset)
444 }
445
446 pub fn token_text(&self, offset: isize) -> Option<TokenView<'_>> {
448 self.lt(offset)
449 }
450
451 pub fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
458 self.input.get(index)
459 }
460
461 #[must_use]
464 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
465 self.context
466 }
467
468 #[must_use]
470 pub const fn parse_tree_storage(&self) -> &'a ParseTreeStorage {
471 self.tree_storage
472 }
473
474 #[must_use]
476 pub const fn token_store(&self) -> &TokenStore {
477 self.input.token_store()
478 }
479
480 #[must_use]
482 pub const fn tree_id(&self) -> Option<NodeId> {
483 self.tree
484 }
485
486 #[must_use]
489 pub fn tree(&self) -> Option<Node<'_>> {
490 self.tree
491 .and_then(|id| self.tree_storage.node(self.input.token_store(), id))
492 }
493
494 #[must_use]
496 pub fn local_int_arg(&self) -> Option<i64> {
497 self.local_int_arg.map(|(_, value)| value)
498 }
499
500 #[must_use]
502 pub fn member_int(&self, member: usize) -> Option<i64> {
503 self.member_values.get(&member).copied()
504 }
505
506 #[must_use]
509 pub const fn action(&self) -> Option<ParserAction> {
510 self.action
511 }
512
513 pub fn action_text(&self) -> String {
521 let Some(action) = self.action else {
522 return String::new();
523 };
524 let Some(stop) = action.stop_index() else {
525 return String::new();
526 };
527 let stop = if self
528 .input
529 .get(stop)
530 .is_some_and(|token| token.token_type() == TOKEN_EOF)
531 {
532 let Some(previous) = self.input.previous_visible_token_index(stop) else {
533 return String::new();
534 };
535 previous
536 } else {
537 stop
538 };
539 self.input.text(action.start_index(), stop)
540 }
541}
542
543pub trait SemanticHooks {
550 const ENABLES_LEXER_LIFECYCLE: bool = true;
557
558 fn observes_parser_predicates(&self) -> bool {
563 true
564 }
565
566 fn observes_parser_decisions(&self) -> bool {
571 false
572 }
573
574 fn parser_decision_override(
580 &mut self,
581 decision: usize,
582 input_index: usize,
583 alternative_count: usize,
584 ) -> Option<usize> {
585 let _ = (decision, input_index, alternative_count);
586 None
587 }
588
589 fn sempred<S>(
590 &mut self,
591 ctx: &mut ParserSemCtx<'_, S>,
592 rule_index: usize,
593 pred_index: usize,
594 ) -> Option<bool>
595 where
596 S: TokenSource,
597 {
598 let _ = (ctx, rule_index, pred_index);
599 None
600 }
601
602 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
603 where
604 S: TokenSource,
605 {
606 let _ = (ctx, action);
607 false
608 }
609
610 fn lexer_sempred<I>(
611 &mut self,
612 ctx: &mut LexerSemCtx<'_, I>,
613 rule_index: usize,
614 pred_index: usize,
615 ) -> Option<bool>
616 where
617 I: CharStream,
618 {
619 let _ = (ctx, rule_index, pred_index);
620 None
621 }
622
623 fn lexer_action<I>(&mut self, ctx: &mut LexerSemCtx<'_, I>, action: LexerCustomAction) -> bool
633 where
634 I: CharStream,
635 {
636 let _ = (ctx, action);
637 false
638 }
639
640 fn lexer_reset<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
644 where
645 I: CharStream,
646 {
647 let _ = ctx;
648 }
649
650 fn lexer_before_token<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
656 where
657 I: CharStream,
658 {
659 let _ = ctx;
660 }
661
662 fn lexer_after_accept<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
671 where
672 I: CharStream,
673 {
674 let _ = ctx;
675 }
676
677 fn lexer_token_emitted(&mut self, token: TokenView<'_>) {
684 let _ = token;
685 }
686}
687
688#[derive(Clone, Copy, Debug, Default)]
691pub struct NoSemanticHooks;
692
693impl SemanticHooks for NoSemanticHooks {
694 const ENABLES_LEXER_LIFECYCLE: bool = false;
695
696 fn observes_parser_predicates(&self) -> bool {
697 false
698 }
699}
700
701#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
708pub enum ParserPredicate {
709 True,
710 False,
711 FalseWithMessage {
713 message: &'static str,
714 },
715 Invoke {
718 value: bool,
719 },
720 LookaheadTextEquals {
721 offset: isize,
722 text: &'static str,
723 },
724 LookaheadNotEquals {
725 offset: isize,
726 token_type: i32,
727 },
728 TokenPairAdjacent,
731 ContextChildRuleTextNotEquals {
736 rule_index: usize,
737 text: &'static str,
738 },
739 LocalIntEquals {
742 value: i64,
743 },
744 LocalIntLessOrEqual {
747 value: i64,
748 },
749 MemberModuloEquals {
751 member: usize,
752 modulus: i64,
753 value: i64,
754 equals: bool,
755 },
756 MemberEquals {
758 member: usize,
759 value: i64,
760 equals: bool,
761 },
762}
763
764impl ParserPredicate {
765 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
771 match self {
772 Self::True => ir.expr(PExpr::Bool(true)),
773 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
774 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
775 Self::LookaheadTextEquals { offset, text } => {
776 let token = ir.expr(PExpr::TokenText(offset));
777 let text = ir.intern(text);
778 let text = ir.expr(PExpr::Str(text));
779 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
780 }
781 Self::LookaheadNotEquals { offset, token_type } => {
782 let actual = ir.expr(PExpr::La(offset));
783 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
784 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
785 }
786 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
787 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
788 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
789 let expected = ir.intern(text);
790 let expected = ir.expr(PExpr::Str(expected));
791 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
792 }
793 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
794 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
795 Self::MemberModuloEquals {
796 member,
797 modulus,
798 value,
799 equals,
800 } => {
801 if modulus == 0 {
802 return ir.expr(PExpr::Bool(false));
803 }
804 let member = ir.expr(PExpr::Member(member));
805 let modulus = ir.expr(PExpr::Int(modulus));
806 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
807 let expected = ir.expr(PExpr::Int(value));
808 ir.expr(PExpr::Cmp(
809 if equals { CmpOp::Eq } else { CmpOp::Ne },
810 actual,
811 expected,
812 ))
813 }
814 Self::MemberEquals {
815 member,
816 value,
817 equals,
818 } => {
819 let actual = ir.expr(PExpr::Member(member));
820 let expected = ir.expr(PExpr::Int(value));
821 ir.expr(PExpr::Cmp(
822 if equals { CmpOp::Eq } else { CmpOp::Ne },
823 actual,
824 expected,
825 ))
826 }
827 }
828 }
829
830 #[must_use]
831 pub const fn failure_message(self) -> Option<&'static str> {
832 match self {
833 Self::FalseWithMessage { message } => Some(message),
834 Self::True
835 | Self::False
836 | Self::Invoke { .. }
837 | Self::LookaheadTextEquals { .. }
838 | Self::LookaheadNotEquals { .. }
839 | Self::TokenPairAdjacent
840 | Self::ContextChildRuleTextNotEquals { .. }
841 | Self::LocalIntEquals { .. }
842 | Self::LocalIntLessOrEqual { .. }
843 | Self::MemberModuloEquals { .. }
844 | Self::MemberEquals { .. } => None,
845 }
846 }
847}
848
849fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
850 let local = ir.expr(PExpr::LocalArg);
851 let absent = ir.expr(PExpr::IsNull(local));
852 let expected = ir.expr(PExpr::Int(value));
853 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
854 ir.expr(PExpr::Or([absent, comparison].into()))
855}
856
857#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
870pub enum UnknownSemanticPolicy {
871 #[default]
873 AssumeTrue,
874 AssumeFalse,
876 Error,
879}
880
881fn apply_unknown_predicate_policy(
890 policy: UnknownSemanticPolicy,
891 rule_index: usize,
892 pred_index: usize,
893 hits: &mut Vec<(usize, usize)>,
894) -> bool {
895 match policy {
896 UnknownSemanticPolicy::AssumeTrue => true,
897 UnknownSemanticPolicy::AssumeFalse => false,
898 UnknownSemanticPolicy::Error => {
899 let coordinate = (rule_index, pred_index);
900 if !hits.contains(&coordinate) {
901 hits.push(coordinate);
902 }
903 false
904 }
905 }
906}
907
908#[derive(Clone, Debug, Eq, PartialEq)]
912pub struct ExpectedTokenSet {
913 symbols: BTreeSet<i32>,
914}
915
916impl ExpectedTokenSet {
917 #[must_use]
919 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
920 expected_symbols_display(&self.symbols, vocabulary)
921 }
922}
923
924#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
929pub struct BailErrorStrategy;
930
931impl BailErrorStrategy {
932 #[must_use]
933 pub const fn new() -> Self {
934 Self
935 }
936}
937
938#[derive(Clone, Copy, Debug, Eq, PartialEq)]
940pub enum PredictionMode {
941 Ll,
944 Sll,
947 LlExactAmbigDetection,
949}
950
951#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
957pub struct ParserRuleArg {
958 pub source_state: usize,
960 pub rule_index: usize,
962 pub value: i64,
964 pub inherit_local: bool,
966}
967
968#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
970pub struct ParserMemberAction {
971 pub source_state: usize,
973 pub member: usize,
975 pub delta: i64,
977}
978
979#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
986pub struct ParserReturnAction {
987 pub source_state: usize,
989 pub rule_index: usize,
991 pub name: &'static str,
993 pub value: i64,
995}
996
997impl ParserMemberAction {
998 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1000 let delta = ir.expr(PExpr::Int(self.delta));
1001 ParserSemanticAction {
1002 source_state: self.source_state,
1003 rule_index: usize::MAX,
1004 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
1005 speculative: true,
1006 }
1007 }
1008}
1009
1010impl ParserReturnAction {
1011 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1013 let name = ir.intern(self.name);
1014 let value = ir.expr(PExpr::Int(self.value));
1015 ParserSemanticAction {
1016 source_state: self.source_state,
1017 rule_index: self.rule_index,
1018 stmt: ir.stmt(AStmt::SetReturn(name, value)),
1019 speculative: false,
1020 }
1021 }
1022}
1023
1024#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1026pub struct ParserSemanticPredicate {
1027 pub rule_index: usize,
1029 pub pred_index: usize,
1031 pub expr: ExprId,
1033 pub failure_message: Option<&'static str>,
1035}
1036
1037#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1039pub struct ParserSemanticAction {
1040 pub source_state: usize,
1042 pub rule_index: usize,
1044 pub stmt: StmtId,
1046 pub speculative: bool,
1048}
1049
1050#[derive(Clone, Debug, Default, Eq, PartialEq)]
1057pub struct ParserSemantics {
1058 pub ir: SemIr,
1059 pub predicates: Vec<ParserSemanticPredicate>,
1060 pub actions: Vec<ParserSemanticAction>,
1061}
1062
1063#[derive(Clone, Copy, Debug, Default)]
1065pub struct ParserRuntimeOptions<'a> {
1066 pub init_action_rules: &'a [usize],
1068 pub track_alt_numbers: bool,
1070 #[doc(hidden)]
1075 pub track_context_alt_numbers: bool,
1076 pub predicates: &'a [(usize, usize, ParserPredicate)],
1078 pub semantics: Option<&'a ParserSemantics>,
1080 pub rule_args: &'a [ParserRuleArg],
1082 pub member_actions: &'a [ParserMemberAction],
1084 pub return_actions: &'a [ParserReturnAction],
1086 pub unknown_predicate_policy: UnknownSemanticPolicy,
1089}
1090
1091pub trait Parser: Recognizer {
1092 fn build_parse_trees(&self) -> bool;
1095
1096 fn set_build_parse_trees(&mut self, build: bool);
1098
1099 fn number_of_syntax_errors(&self) -> usize {
1102 0
1103 }
1104
1105 fn report_diagnostic_errors(&self) -> bool {
1108 false
1109 }
1110
1111 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
1114
1115 fn prediction_mode(&self) -> PredictionMode {
1117 PredictionMode::Ll
1118 }
1119
1120 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
1122}
1123
1124#[derive(Debug)]
1125struct LeftRecursiveCallerOverlap {
1126 atn_key: SharedAtnCacheKey,
1127 state_number: usize,
1128 symbol: i32,
1129 context_version: usize,
1130 overlaps: bool,
1131}
1132
1133const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
1134
1135#[derive(Debug)]
1136pub struct BaseParser<S, H = NoSemanticHooks> {
1137 input: CommonTokenStream<S>,
1138 tree: ParseTreeStorage,
1139 data: RecognizerData,
1140 semantic_hooks: H,
1141 decision_override_generation: usize,
1142 build_parse_trees: bool,
1143 syntax_errors: usize,
1144 report_diagnostic_errors: bool,
1145 prediction_mode: PredictionMode,
1146 prediction_diagnostics: Vec<ParserDiagnostic>,
1147 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1148 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1149 generated_sync_expected: Option<TokenBitSet>,
1150 generated_recovery_error_index: Option<usize>,
1151 generated_recovery_error_states: BTreeSet<isize>,
1152 int_members: BTreeMap<usize, i64>,
1153 rule_context_stack: Vec<RuleContextFrame>,
1154 rule_context_version: usize,
1155 left_recursive_caller_overlap_cache:
1156 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1157 pending_invoking_states: Vec<isize>,
1158 precedence_stack: Vec<i32>,
1159 invoked_predicates: Vec<(usize, usize)>,
1163 bail_on_error: bool,
1167 unknown_predicate_policy: UnknownSemanticPolicy,
1170 unknown_predicate_hits: Vec<(usize, usize)>,
1173 unhandled_action_hits: Vec<(usize, usize)>,
1178 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1183 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1189 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1194 rule_stop_reach_cache: Vec<Option<bool>>,
1199 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1204 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1210 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1216 fast_predicate_cache: FxHashMap<(usize, usize, usize), bool>,
1220 empty_cycle_cache: Vec<Option<bool>>,
1226 empty_cycle_cache_atn: Option<SharedAtnCacheKey>,
1227 clean_memo_mode: CleanMemoMode,
1230 clean_memo_probe_seen: FxHashSet<FastRecognizeKey>,
1231 clean_memo_probe_samples: usize,
1232 clean_memo_probe_repeats: usize,
1233 clean_memo_sparse_samples: usize,
1234 fast_recognize_scratch: FastRecognizeTopScratch,
1236 fast_outcome_dedup: FastOutcomeDedupScratch,
1238 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1241 fast_first_set_prefilter: bool,
1249 fast_recovery_enabled: bool,
1253 fast_token_nodes_enabled: bool,
1258 fast_track_alt_numbers: bool,
1261 recognition_arena: RecognitionArena,
1265 last_recognition_arena_root: NodeSeqId,
1266 last_recognition_arena_diagnostics: DiagnosticSeqId,
1267}
1268
1269#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1271pub struct GeneratedDiagnosticsCheckpoint {
1272 diagnostics_len: usize,
1273 syntax_errors: usize,
1274 tree: ParseTreeCheckpoint,
1275}
1276
1277#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1280pub struct RecognitionArenaStats {
1281 pub total_nodes: usize,
1282 pub live_nodes: usize,
1283 pub dead_nodes: usize,
1284 pub node_capacity: usize,
1285 pub total_links: usize,
1286 pub live_links: usize,
1287 pub dead_links: usize,
1288 pub link_capacity: usize,
1289 pub total_extras: usize,
1290 pub live_extras: usize,
1291 pub dead_extras: usize,
1292 pub extra_capacity: usize,
1293}
1294
1295#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1296struct RuleContextFrame {
1297 rule_index: usize,
1298 invoking_state: isize,
1299}
1300
1301#[derive(Clone, Debug, Eq, PartialEq)]
1302struct RecognizeOutcome {
1303 index: usize,
1304 consumed_eof: bool,
1305 alt_number: usize,
1306 member_values: BTreeMap<usize, i64>,
1307 return_values: BTreeMap<String, i64>,
1308 diagnostics: DiagnosticSeqId,
1309 decisions: Vec<usize>,
1310 actions: Vec<ParserAction>,
1311 nodes: NodeSeqId,
1312}
1313
1314#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1315struct FastRecognizeOutcome {
1316 index: usize,
1317 consumed_eof: bool,
1318 diagnostics: DiagnosticSeqId,
1319 deferred_nodes: FastDeferredNodeId,
1320 nodes: NodeSeqId,
1324}
1325
1326#[derive(Debug, Default)]
1327struct FastRecognizeTopScratch {
1328 visiting: FxHashSet<FastRecognizeKey>,
1329 memo: FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
1330}
1331
1332impl FastRecognizeTopScratch {
1333 fn prepare(&mut self, memo_capacity: usize) {
1334 self.visiting.clear();
1335 self.visiting.reserve(FAST_RECOGNIZE_VISITING_CAPACITY);
1336 self.memo.clear();
1337 self.memo.reserve(memo_capacity);
1338 }
1339
1340 fn release_oversized_memo(&mut self) {
1341 self.memo.clear();
1342 if self.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY {
1343 self.memo = FxHashMap::default();
1344 }
1345 }
1346}
1347
1348fn fast_recognize_memo_capacity(buffered_tokens: usize) -> usize {
1349 buffered_tokens.saturating_mul(8).clamp(
1350 FAST_RECOGNIZE_MIN_MEMO_CAPACITY,
1351 FAST_RECOGNIZE_MAX_MEMO_CAPACITY,
1352 )
1353}
1354
1355#[derive(Debug, Default)]
1356struct FastOutcomeDedupScratch {
1357 dense_words: Vec<u64>,
1358 touched_dense_words: Vec<u32>,
1359 sparse_keys: FxHashSet<(usize, bool)>,
1360}
1361
1362#[repr(transparent)]
1367#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1368struct FastDeferredNodeId(u32);
1369
1370impl FastDeferredNodeId {
1371 const EMPTY: Self = Self(u32::MAX);
1372
1373 const fn is_empty(self) -> bool {
1374 self.0 == Self::EMPTY.0
1375 }
1376}
1377
1378impl Default for FastDeferredNodeId {
1379 fn default() -> Self {
1380 Self::EMPTY
1381 }
1382}
1383
1384#[repr(transparent)]
1385#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1386struct FastDeferredRuleId(u32);
1387
1388#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1390enum FastDeferredNode {
1391 Fragment(NodeSeqId),
1392 Rule(FastDeferredRuleId),
1393 Alternative(u32),
1394 LeftRecursiveBoundary {
1395 rule_index: u32,
1396 },
1397 Concat {
1398 prefix: FastDeferredNodeId,
1399 suffix: FastDeferredNodeId,
1400 },
1401}
1402
1403#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1404struct FastDeferredRule {
1405 rule_index: u32,
1406 invoking_state: i32,
1407 start_index: u32,
1408 stop_index: Option<u32>,
1409 deferred_children: FastDeferredNodeId,
1410 children: NodeSeqId,
1411}
1412
1413#[repr(transparent)]
1414#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1415struct RecognizedNodeId(u32);
1416
1417#[repr(transparent)]
1418#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1419struct NodeSeqId(u32);
1420
1421impl NodeSeqId {
1422 const EMPTY: Self = Self(u32::MAX);
1423
1424 const fn is_empty(self) -> bool {
1425 self.0 == Self::EMPTY.0
1426 }
1427}
1428
1429impl Default for NodeSeqId {
1430 fn default() -> Self {
1431 Self::EMPTY
1432 }
1433}
1434
1435#[repr(transparent)]
1436#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1437struct DiagnosticSeqId(u32);
1438
1439impl DiagnosticSeqId {
1440 const EMPTY: Self = Self(u32::MAX);
1441
1442 const fn is_empty(self) -> bool {
1443 self.0 == Self::EMPTY.0
1444 }
1445}
1446
1447impl Default for DiagnosticSeqId {
1448 fn default() -> Self {
1449 Self::EMPTY
1450 }
1451}
1452
1453#[repr(transparent)]
1454#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1455struct RecognitionExtraId(u32);
1456
1457#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1458struct SeqLink {
1459 head: RecognizedNodeId,
1460 tail: NodeSeqId,
1461}
1462
1463#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1464struct DiagnosticLink {
1465 head: RecognitionExtraId,
1466 tail: DiagnosticSeqId,
1467}
1468
1469struct ArenaRuleSpec {
1470 rule_index: usize,
1471 invoking_state: isize,
1472 alt_number: usize,
1473 start_index: usize,
1474 stop_index: Option<usize>,
1475 return_values: BTreeMap<String, i64>,
1476 children: NodeSeqId,
1477}
1478
1479#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1482enum ArenaRecognizedNode {
1483 Token {
1484 token: TokenId,
1485 },
1486 ErrorToken {
1487 token: TokenId,
1488 },
1489 MissingToken {
1490 extra: RecognitionExtraId,
1491 },
1492 Rule {
1493 rule_index: u32,
1494 invoking_state: i32,
1495 alt_number: u32,
1496 start_index: u32,
1497 stop_index: Option<u32>,
1498 return_values: Option<RecognitionExtraId>,
1499 children: NodeSeqId,
1500 },
1501 LeftRecursiveBoundary {
1505 rule_index: u32,
1506 alt_number: u32,
1507 },
1508}
1509
1510#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1511enum RecognitionExtra {
1512 MissingToken {
1513 token_type: i32,
1514 at_index: u32,
1515 text: String,
1516 },
1517 ReturnValues(BTreeMap<String, i64>),
1518 Diagnostic(ParserDiagnostic),
1519}
1520
1521#[derive(Debug, Default)]
1522struct RecognitionArena {
1523 nodes: Vec<ArenaRecognizedNode>,
1524 seq_links: Vec<SeqLink>,
1525 diagnostic_links: Vec<DiagnosticLink>,
1526 extras: Vec<RecognitionExtra>,
1527 deferred_nodes: Vec<FastDeferredNode>,
1528 deferred_rules: Vec<FastDeferredRule>,
1529}
1530
1531const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1534const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1535const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1536const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1537const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1538const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1539
1540impl RecognitionArena {
1541 fn reset(&mut self) {
1542 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1543 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1544 reset_arena_vec(
1545 &mut self.diagnostic_links,
1546 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1547 );
1548 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1549 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1550 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1551 }
1552
1553 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1554 let id = RecognizedNodeId(
1555 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1556 );
1557 self.nodes.push(node);
1558 id
1559 }
1560
1561 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1562 let id = RecognitionExtraId(
1563 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1564 );
1565 self.extras.push(extra);
1566 id
1567 }
1568
1569 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1570 let id = NodeSeqId(
1571 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1572 );
1573 self.seq_links.push(SeqLink { head, tail });
1574 id
1575 }
1576
1577 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1578 let id = FastDeferredNodeId(
1579 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
1580 );
1581 self.deferred_nodes.push(node);
1582 id
1583 }
1584
1585 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
1586 let id = FastDeferredRuleId(
1587 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
1588 );
1589 self.deferred_rules.push(rule);
1590 id
1591 }
1592
1593 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
1594 if nodes.is_empty() {
1595 FastDeferredNodeId::EMPTY
1596 } else {
1597 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
1598 }
1599 }
1600
1601 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
1602 let rule = self.push_deferred_rule(rule);
1603 self.push_deferred_node(FastDeferredNode::Rule(rule))
1604 }
1605
1606 fn deferred_alternative(&mut self, alt_number: usize) -> FastDeferredNodeId {
1607 self.push_deferred_node(FastDeferredNode::Alternative(
1608 u32::try_from(alt_number).expect("alternative number fits in u32"),
1609 ))
1610 }
1611
1612 fn deferred_left_recursive_boundary(&mut self, rule_index: usize) -> FastDeferredNodeId {
1613 self.push_deferred_node(FastDeferredNode::LeftRecursiveBoundary {
1614 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
1615 })
1616 }
1617
1618 fn concat_deferred_nodes(
1619 &mut self,
1620 prefix: FastDeferredNodeId,
1621 suffix: FastDeferredNodeId,
1622 ) -> FastDeferredNodeId {
1623 if prefix.is_empty() {
1624 return suffix;
1625 }
1626 if suffix.is_empty() {
1627 return prefix;
1628 }
1629 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
1630 }
1631
1632 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
1633 self.deferred_nodes[id.0 as usize]
1634 }
1635
1636 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
1637 self.deferred_rules[id.0 as usize]
1638 }
1639
1640 fn prepend_diagnostic(
1641 &mut self,
1642 tail: DiagnosticSeqId,
1643 diagnostic: ParserDiagnostic,
1644 ) -> DiagnosticSeqId {
1645 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
1646 self.prepend_diagnostic_id(tail, head)
1647 }
1648
1649 fn prepend_diagnostic_id(
1650 &mut self,
1651 tail: DiagnosticSeqId,
1652 head: RecognitionExtraId,
1653 ) -> DiagnosticSeqId {
1654 let id = DiagnosticSeqId(
1655 u32::try_from(self.diagnostic_links.len())
1656 .expect("diagnostic sequence arena fits in u32"),
1657 );
1658 self.diagnostic_links.push(DiagnosticLink { head, tail });
1659 id
1660 }
1661
1662 fn concat_diagnostics(
1663 &mut self,
1664 prefix: DiagnosticSeqId,
1665 mut suffix: DiagnosticSeqId,
1666 ) -> DiagnosticSeqId {
1667 if prefix.is_empty() {
1668 return suffix;
1669 }
1670 if suffix.is_empty() {
1671 return prefix;
1672 }
1673 let mut reversed = DiagnosticSeqId::EMPTY;
1674 let mut cursor = prefix;
1675 while let Some(link) = self.diagnostic_link(cursor) {
1676 reversed = self.prepend_diagnostic_id(reversed, link.head);
1677 cursor = link.tail;
1678 }
1679 while let Some(link) = self.diagnostic_link(reversed) {
1680 suffix = self.prepend_diagnostic_id(suffix, link.head);
1681 reversed = link.tail;
1682 }
1683 suffix
1684 }
1685
1686 #[cfg(test)]
1687 fn diagnostic_sequence(
1688 &mut self,
1689 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
1690 ) -> DiagnosticSeqId {
1691 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
1692 let mut sequence = DiagnosticSeqId::EMPTY;
1693 for diagnostic in diagnostics.into_iter().rev() {
1694 sequence = self.prepend_diagnostic(sequence, diagnostic);
1695 }
1696 sequence
1697 }
1698
1699 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
1700 self.nodes[id.0 as usize]
1701 }
1702
1703 fn set_boundary_alt_number(&mut self, id: RecognizedNodeId, alt_number: u32) {
1704 let ArenaRecognizedNode::LeftRecursiveBoundary {
1705 alt_number: stored, ..
1706 } = &mut self.nodes[id.0 as usize]
1707 else {
1708 unreachable!("deferred boundary must materialize as a boundary node");
1709 };
1710 *stored = alt_number;
1711 }
1712
1713 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
1714 &self.extras[id.0 as usize]
1715 }
1716
1717 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
1718 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
1719 }
1720
1721 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
1722 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
1723 }
1724
1725 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
1726 NodeSeqIter {
1727 arena: self,
1728 cursor: sequence,
1729 }
1730 }
1731
1732 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
1733 DiagnosticSeqIter {
1734 arena: self,
1735 cursor: sequence,
1736 }
1737 }
1738
1739 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
1740 self.diagnostics(sequence).count()
1741 }
1742
1743 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
1744 self.diagnostics(sequence)
1745 .filter(|diagnostic| {
1746 diagnostic.message.starts_with("mismatched input ")
1747 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
1748 })
1749 .count()
1750 }
1751
1752 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
1753 self.diagnostics(left).cmp(self.diagnostics(right))
1754 }
1755
1756 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
1757 self.iter(sequence).count()
1758 }
1759
1760 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
1761 self.iter(sequence).any(|node| match self.node(node) {
1762 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1763 ArenaRecognizedNode::Rule { children, .. } => {
1764 self.sequence_has_left_recursive_boundary(children)
1765 }
1766 ArenaRecognizedNode::Token { .. }
1767 | ArenaRecognizedNode::ErrorToken { .. }
1768 | ArenaRecognizedNode::MissingToken { .. } => false,
1769 })
1770 }
1771
1772 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
1773 self.iter(sequence).any(|node| {
1774 matches!(
1775 self.node(node),
1776 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
1777 )
1778 })
1779 }
1780
1781 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
1782 self.iter(sequence).any(|node| {
1783 matches!(
1784 self.node(node),
1785 ArenaRecognizedNode::Token { .. }
1786 | ArenaRecognizedNode::ErrorToken { .. }
1787 | ArenaRecognizedNode::MissingToken { .. }
1788 )
1789 })
1790 }
1791
1792 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
1793 match self.node(node) {
1794 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1795 Some(token.index())
1796 }
1797 ArenaRecognizedNode::MissingToken { extra } => {
1798 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1799 unreachable!("missing-token node must reference missing-token extra");
1800 };
1801 Some(*at_index as usize)
1802 }
1803 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
1804 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1805 }
1806 }
1807
1808 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
1809 match self.node(node) {
1810 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1811 Some(token.index())
1812 }
1813 ArenaRecognizedNode::MissingToken { extra } => {
1814 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1815 unreachable!("missing-token node must reference missing-token extra");
1816 };
1817 (*at_index as usize).checked_sub(1)
1818 }
1819 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
1820 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1821 }
1822 }
1823
1824 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
1825 let start = self.node_start_index(node)?;
1826 let stop = self.node_stop_index(node);
1827 Some((start, stop))
1828 }
1829
1830 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
1831 self.iter(sequence)
1832 .find_map(|node| self.node_start_index(node))
1833 }
1834
1835 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
1836 let mut stop = None;
1837 for node in self.iter(sequence) {
1838 if let Some(index) = self.node_stop_index(node) {
1839 stop = Some(index);
1840 }
1841 }
1842 stop
1843 }
1844
1845 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
1846 self.iter(sequence)
1847 .any(|node| self.node_needs_stable_tie(node))
1848 }
1849
1850 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
1851 match self.node(node) {
1852 ArenaRecognizedNode::Token { .. }
1853 | ArenaRecognizedNode::ErrorToken { .. }
1854 | ArenaRecognizedNode::MissingToken { .. } => false,
1855 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1856 ArenaRecognizedNode::Rule {
1857 rule_index,
1858 children,
1859 ..
1860 } => self.iter(children).any(|child| {
1861 matches!(
1862 self.node(child),
1863 ArenaRecognizedNode::Rule {
1864 rule_index: child_rule,
1865 ..
1866 } if child_rule == rule_index
1867 ) || self.node_needs_stable_tie(child)
1868 }),
1869 }
1870 }
1871
1872 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
1873 loop {
1874 match (self.link(left), self.link(right)) {
1875 (Some(left_link), Some(right_link)) => {
1876 let order = self.compare_nodes(left_link.head, right_link.head);
1877 if order != Ordering::Equal {
1878 return order;
1879 }
1880 left = left_link.tail;
1881 right = right_link.tail;
1882 }
1883 (None, None) => return Ordering::Equal,
1884 (None, Some(_)) => return Ordering::Less,
1885 (Some(_), None) => return Ordering::Greater,
1886 }
1887 }
1888 }
1889
1890 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
1891 let left = self.node(left);
1892 let right = self.node(right);
1893 match (left, right) {
1894 (
1895 ArenaRecognizedNode::Token { token: left },
1896 ArenaRecognizedNode::Token { token: right },
1897 )
1898 | (
1899 ArenaRecognizedNode::ErrorToken { token: left },
1900 ArenaRecognizedNode::ErrorToken { token: right },
1901 ) => left.cmp(&right),
1902 (
1903 ArenaRecognizedNode::MissingToken { extra: left },
1904 ArenaRecognizedNode::MissingToken { extra: right },
1905 ) => self.extra(left).cmp(self.extra(right)),
1906 (
1907 ArenaRecognizedNode::Rule {
1908 rule_index: left_rule,
1909 invoking_state: left_invoking,
1910 alt_number: left_alt,
1911 start_index: left_start,
1912 stop_index: left_stop,
1913 return_values: left_returns,
1914 children: left_children,
1915 },
1916 ArenaRecognizedNode::Rule {
1917 rule_index: right_rule,
1918 invoking_state: right_invoking,
1919 alt_number: right_alt,
1920 start_index: right_start,
1921 stop_index: right_stop,
1922 return_values: right_returns,
1923 children: right_children,
1924 },
1925 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
1926 .cmp(&(
1927 right_rule,
1928 right_invoking,
1929 right_alt,
1930 right_start,
1931 right_stop,
1932 ))
1933 .then_with(|| {
1934 left_returns
1935 .map(|id| self.extra(id))
1936 .cmp(&right_returns.map(|id| self.extra(id)))
1937 })
1938 .then_with(|| self.compare_sequences(left_children, right_children)),
1939 (
1940 ArenaRecognizedNode::LeftRecursiveBoundary {
1941 rule_index: left_rule,
1942 alt_number: left_alt,
1943 },
1944 ArenaRecognizedNode::LeftRecursiveBoundary {
1945 rule_index: right_rule,
1946 alt_number: right_alt,
1947 },
1948 ) => (left_rule, left_alt).cmp(&(right_rule, right_alt)),
1949 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
1950 }
1951 }
1952
1953 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1954 let mut reversed = NodeSeqId::EMPTY;
1955 while let Some(link) = self.link(sequence) {
1956 reversed = self.prepend(reversed, link.head);
1957 sequence = link.tail;
1958 }
1959 reversed
1960 }
1961
1962 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1963 if !self.sequence_has_direct_boundary(sequence) {
1964 return sequence;
1965 }
1966 let mut reversed = NodeSeqId::EMPTY;
1967 while let Some(link) = self.link(sequence) {
1968 match self.node(link.head) {
1969 ArenaRecognizedNode::LeftRecursiveBoundary {
1970 rule_index,
1971 alt_number,
1972 } => {
1973 if !reversed.is_empty() {
1974 let children = self.reverse_sequence(reversed);
1975 let start_index = self.sequence_start_index(children).unwrap_or_default();
1976 let stop_index = self.sequence_stop_index(children);
1977 let rule = self.push_node(ArenaRecognizedNode::Rule {
1978 rule_index,
1979 invoking_state: -1,
1980 alt_number,
1981 start_index: u32::try_from(start_index)
1982 .expect("left-recursive start index fits in u32"),
1983 stop_index: stop_index.map(|index| {
1984 u32::try_from(index).expect("left-recursive stop index fits in u32")
1985 }),
1986 return_values: None,
1987 children,
1988 });
1989 reversed = self.prepend(NodeSeqId::EMPTY, rule);
1990 }
1991 }
1992 _ => {
1993 reversed = self.prepend(reversed, link.head);
1994 }
1995 }
1996 sequence = link.tail;
1997 }
1998 self.reverse_sequence(reversed)
1999 }
2000
2001 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
2002 let mut live_nodes = vec![false; self.nodes.len()];
2003 let mut live_links = vec![false; self.seq_links.len()];
2004 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
2005 let mut live_extras = vec![false; self.extras.len()];
2006 let mut pending = vec![root];
2007 while let Some(mut sequence) = pending.pop() {
2008 while let Some(link) = self.link(sequence) {
2009 let link_index = sequence.0 as usize;
2010 if live_links[link_index] {
2011 break;
2012 }
2013 live_links[link_index] = true;
2014 let node_index = link.head.0 as usize;
2015 if !live_nodes[node_index] {
2016 live_nodes[node_index] = true;
2017 match self.node(link.head) {
2018 ArenaRecognizedNode::MissingToken { extra } => {
2019 live_extras[extra.0 as usize] = true;
2020 }
2021 ArenaRecognizedNode::Rule {
2022 return_values,
2023 children,
2024 ..
2025 } => {
2026 if let Some(extra) = return_values {
2027 live_extras[extra.0 as usize] = true;
2028 }
2029 pending.push(children);
2030 }
2031 ArenaRecognizedNode::Token { .. }
2032 | ArenaRecognizedNode::ErrorToken { .. }
2033 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
2034 }
2035 }
2036 sequence = link.tail;
2037 }
2038 }
2039 let mut diagnostics = diagnostics;
2040 while let Some(link) = self.diagnostic_link(diagnostics) {
2041 let link_index = diagnostics.0 as usize;
2042 if live_diagnostic_links[link_index] {
2043 break;
2044 }
2045 live_diagnostic_links[link_index] = true;
2046 live_extras[link.head.0 as usize] = true;
2047 diagnostics = link.tail;
2048 }
2049 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
2050 let live_link_count = live_links.into_iter().filter(|live| *live).count()
2051 + live_diagnostic_links
2052 .into_iter()
2053 .filter(|live| *live)
2054 .count();
2055 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
2056 let total_links = self.seq_links.len() + self.diagnostic_links.len();
2057 RecognitionArenaStats {
2058 total_nodes: self.nodes.len(),
2059 live_nodes: live_node_count,
2060 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
2061 node_capacity: self.nodes.capacity(),
2062 total_links,
2063 live_links: live_link_count,
2064 dead_links: total_links.saturating_sub(live_link_count),
2065 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
2066 total_extras: self.extras.len(),
2067 live_extras: live_extra_count,
2068 dead_extras: self.extras.len().saturating_sub(live_extra_count),
2069 extra_capacity: self.extras.capacity(),
2070 }
2071 }
2072}
2073
2074fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
2075 if storage.capacity() > max_retained_capacity {
2076 *storage = Vec::new();
2077 } else {
2078 storage.clear();
2079 }
2080}
2081
2082const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
2083 match node {
2084 ArenaRecognizedNode::Token { .. } => 0,
2085 ArenaRecognizedNode::ErrorToken { .. } => 1,
2086 ArenaRecognizedNode::MissingToken { .. } => 2,
2087 ArenaRecognizedNode::Rule { .. } => 3,
2088 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
2089 }
2090}
2091
2092struct NodeSeqIter<'a> {
2093 arena: &'a RecognitionArena,
2094 cursor: NodeSeqId,
2095}
2096
2097impl Iterator for NodeSeqIter<'_> {
2098 type Item = RecognizedNodeId;
2099
2100 fn next(&mut self) -> Option<Self::Item> {
2101 let link = self.arena.link(self.cursor)?;
2102 self.cursor = link.tail;
2103 Some(link.head)
2104 }
2105}
2106
2107struct DiagnosticSeqIter<'a> {
2108 arena: &'a RecognitionArena,
2109 cursor: DiagnosticSeqId,
2110}
2111
2112impl<'a> Iterator for DiagnosticSeqIter<'a> {
2113 type Item = &'a ParserDiagnostic;
2114
2115 fn next(&mut self) -> Option<Self::Item> {
2116 let link = self.arena.diagnostic_link(self.cursor)?;
2117 self.cursor = link.tail;
2118 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2119 unreachable!("diagnostic link must reference diagnostic extra");
2120 };
2121 Some(diagnostic)
2122 }
2123}
2124
2125#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2126struct ParserDiagnostic {
2127 line: usize,
2128 column: usize,
2129 message: String,
2130}
2131
2132#[derive(Clone, Debug, Default, Eq, PartialEq)]
2133struct ExpectedTokens {
2134 index: Option<usize>,
2135 symbols: BTreeSet<i32>,
2136 no_viable: Option<NoViableAlternative>,
2137}
2138
2139#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2140struct NoViableAlternative {
2141 start_index: usize,
2142 error_index: usize,
2143}
2144
2145impl ExpectedTokens {
2146 fn record_transition(
2149 &mut self,
2150 index: usize,
2151 transition: ParserTransition<'_>,
2152 max_token_type: i32,
2153 ) {
2154 let symbols = transition_expected_symbols(transition, max_token_type);
2155 match self.index {
2156 Some(current) if index < current => {}
2157 Some(current) if index == current => self.symbols.extend(symbols),
2158 _ => {
2159 self.index = Some(index);
2160 self.symbols = symbols;
2161 }
2162 }
2163 }
2164
2165 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2168 match self.no_viable {
2169 Some(current) if error_index < current.error_index => {}
2170 _ => {
2171 self.no_viable = Some(NoViableAlternative {
2172 start_index,
2173 error_index,
2174 });
2175 }
2176 }
2177 }
2178}
2179
2180#[derive(Clone, Debug, Default, Eq, PartialEq)]
2187struct TokenBitSet {
2188 words: Vec<u64>,
2189}
2190
2191impl TokenBitSet {
2192 fn insert(&mut self, symbol: i32) {
2193 let Some(slot) = token_bit_slot(symbol) else {
2194 return;
2195 };
2196 let word = slot / u64::BITS as usize;
2197 if word >= self.words.len() {
2198 self.words.resize(word + 1, 0);
2199 }
2200 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2201 }
2202
2203 fn extend_range(&mut self, start: i32, stop: i32) {
2204 let (start, stop) = if start <= stop {
2205 (start, stop)
2206 } else {
2207 (stop, start)
2208 };
2209 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2210 self.insert(TOKEN_EOF);
2211 }
2212 let positive_start = start.max(1);
2213 if positive_start > stop {
2214 return;
2215 }
2216 let Some(start_slot) = token_bit_slot(positive_start) else {
2217 return;
2218 };
2219 let Some(stop_slot) = token_bit_slot(stop) else {
2220 return;
2221 };
2222 self.extend_slot_range(start_slot, stop_slot);
2223 }
2224
2225 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2226 if start_slot > stop_slot {
2227 return;
2228 }
2229 let start_word = start_slot / u64::BITS as usize;
2230 let stop_word = stop_slot / u64::BITS as usize;
2231 if stop_word >= self.words.len() {
2232 self.words.resize(stop_word + 1, 0);
2233 }
2234 let start_offset = start_slot % u64::BITS as usize;
2235 let stop_offset = stop_slot % u64::BITS as usize;
2236 if start_word == stop_word {
2237 self.words[start_word] |=
2238 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2239 return;
2240 }
2241 self.words[start_word] |= !0_u64 << start_offset;
2242 for word in &mut self.words[(start_word + 1)..stop_word] {
2243 *word = !0_u64;
2244 }
2245 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2246 }
2247
2248 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2249 for symbol in symbols {
2250 self.insert(symbol);
2251 }
2252 }
2253
2254 fn extend_from(&mut self, other: &Self) {
2255 if other.words.len() > self.words.len() {
2256 self.words.resize(other.words.len(), 0);
2257 }
2258 for (left, right) in self.words.iter_mut().zip(&other.words) {
2259 *left |= *right;
2260 }
2261 }
2262
2263 fn contains(&self, symbol: i32) -> bool {
2264 let Some(slot) = token_bit_slot(symbol) else {
2265 return false;
2266 };
2267 let word = slot / u64::BITS as usize;
2268 self.words
2269 .get(word)
2270 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2271 }
2272
2273 fn is_empty(&self) -> bool {
2274 self.words.iter().all(|word| *word == 0)
2275 }
2276
2277 fn symbols(&self) -> impl Iterator<Item = i32> + '_ {
2278 self.words
2279 .iter()
2280 .copied()
2281 .enumerate()
2282 .flat_map(|(word_index, mut bits)| {
2283 std::iter::from_fn(move || {
2284 while bits != 0 {
2285 let bit = bits.trailing_zeros() as usize;
2286 bits &= bits - 1;
2287 if let Some(symbol) =
2288 token_bit_symbol(word_index * u64::BITS as usize + bit)
2289 {
2290 return Some(symbol);
2291 }
2292 }
2293 None
2294 })
2295 })
2296 }
2297
2298 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2299 target.extend(self.symbols());
2300 }
2301
2302 fn to_btree_set(&self) -> BTreeSet<i32> {
2303 let mut out = BTreeSet::new();
2304 self.extend_btree_set(&mut out);
2305 out
2306 }
2307}
2308
2309fn token_bit_slot(symbol: i32) -> Option<usize> {
2310 if symbol == TOKEN_EOF {
2311 Some(0)
2312 } else if symbol > 0 {
2313 usize::try_from(symbol).ok()
2314 } else {
2315 None
2316 }
2317}
2318
2319fn token_bit_symbol(slot: usize) -> Option<i32> {
2320 if slot == 0 {
2321 Some(TOKEN_EOF)
2322 } else {
2323 i32::try_from(slot).ok()
2324 }
2325}
2326
2327fn transition_expected_symbols(
2330 transition: ParserTransition<'_>,
2331 max_token_type: i32,
2332) -> BTreeSet<i32> {
2333 let mut symbols = BTreeSet::new();
2334 match &transition.data() {
2335 Transition::Atom { label, .. } => {
2336 symbols.insert(*label);
2337 }
2338 Transition::Range { start, stop, .. } => {
2339 symbols.extend(*start..=*stop);
2340 }
2341 Transition::Set { set, .. } => {
2342 for (start, stop) in set.ranges() {
2343 symbols.extend(start..=stop);
2344 }
2345 }
2346 Transition::NotSet { set, .. } => {
2347 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2348 }
2349 Transition::Wildcard { .. } => {
2350 symbols.extend(1..=max_token_type);
2351 }
2352 Transition::Epsilon { .. }
2353 | Transition::Rule { .. }
2354 | Transition::Predicate { .. }
2355 | Transition::Action { .. }
2356 | Transition::Precedence { .. } => {}
2357 }
2358 symbols
2359}
2360
2361fn transition_expected_token_set(
2362 transition: ParserTransition<'_>,
2363 max_token_type: i32,
2364) -> TokenBitSet {
2365 let mut symbols = TokenBitSet::default();
2366 match &transition.data() {
2367 Transition::Atom { label, .. } => {
2368 symbols.insert(*label);
2369 }
2370 Transition::Range { start, stop, .. } => {
2371 symbols.extend_range(*start, *stop);
2372 }
2373 Transition::Set { set, .. } => {
2374 for (start, stop) in set.ranges() {
2375 symbols.extend_range(start, stop);
2376 }
2377 }
2378 Transition::NotSet { set, .. } => {
2379 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2380 }
2381 Transition::Wildcard { .. } => {
2382 symbols.extend_range(1, max_token_type);
2383 }
2384 Transition::Epsilon { .. }
2385 | Transition::Rule { .. }
2386 | Transition::Predicate { .. }
2387 | Transition::Action { .. }
2388 | Transition::Precedence { .. } => {}
2389 }
2390 symbols
2391}
2392
2393fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2397 let mut symbols = BTreeSet::new();
2398 let mut stack = vec![state_number];
2399 let mut visited = BTreeSet::new();
2400 while let Some(current) = stack.pop() {
2401 if !visited.insert(current) {
2402 continue;
2403 }
2404 let Some(state) = atn.state(current) else {
2405 continue;
2406 };
2407 for transition in &state.transitions() {
2408 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2409 if transition_symbols.is_empty() {
2410 if transition.is_epsilon() {
2411 stack.push(transition.target());
2412 }
2413 } else {
2414 symbols.extend(transition_symbols);
2415 }
2416 }
2417 }
2418 symbols
2419}
2420
2421fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2422 let mut symbols = TokenBitSet::default();
2423 let mut stack = vec![state_number];
2424 let mut visited = BTreeSet::new();
2425 while let Some(current) = stack.pop() {
2426 if !visited.insert(current) {
2427 continue;
2428 }
2429 let Some(state) = atn.state(current) else {
2430 continue;
2431 };
2432 for transition in &state.transitions() {
2433 let transition_symbols =
2434 transition_expected_token_set(transition, atn.max_token_type());
2435 if transition_symbols.is_empty() {
2436 if transition.is_epsilon() {
2437 stack.push(transition.target());
2438 }
2439 } else {
2440 symbols.extend_from(&transition_symbols);
2441 }
2442 }
2443 }
2444 symbols
2445}
2446
2447fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2448 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2449 return false;
2450 };
2451 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2452 return false;
2453 };
2454 epsilon_reaches_state(atn, state_number, stop_state)
2455}
2456
2457fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2458 let mut stack = vec![start];
2459 let mut visited = BTreeSet::new();
2460 while let Some(current) = stack.pop() {
2461 if current == target {
2462 return true;
2463 }
2464 if !visited.insert(current) {
2465 continue;
2466 }
2467 let Some(state) = atn.state(current) else {
2468 continue;
2469 };
2470 stack.extend(
2471 state
2472 .transitions()
2473 .iter()
2474 .filter(|transition| transition.is_epsilon())
2475 .map(ParserTransition::target),
2476 );
2477 }
2478 false
2479}
2480
2481#[derive(Clone, Debug, Default, Eq, PartialEq)]
2488struct FirstSet {
2489 symbols: TokenBitSet,
2490 nullable: bool,
2491}
2492
2493type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2500
2501type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2508
2509#[derive(Debug, Default)]
2510struct LeftRecursiveOperatorLookahead {
2511 single_token: TokenBitSet,
2515 multi_token_prefix: TokenBitSet,
2520 predicate_dependent: TokenBitSet,
2521}
2522
2523#[derive(Default)]
2524struct SharedAtnCache {
2525 first_set: FirstSetCache,
2526 decision_lookahead: DecisionLookaheadCache,
2527 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2528 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2529 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2530 rule_stop_reach: FxHashMap<usize, bool>,
2531 observable_action_transitions: Option<bool>,
2532 predicate_transitions: Option<bool>,
2533}
2534
2535thread_local! {
2536 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2537 RefCell::new(FxHashMap::default());
2538}
2539
2540#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2551struct SharedAtnCacheKey {
2552 atn: usize,
2553 states: usize,
2554 state_count: usize,
2555 max_token_type: i32,
2556}
2557
2558impl SharedAtnCacheKey {
2559 fn for_atn(atn: &Atn) -> Self {
2560 let (states, state_count) = atn.storage_identity();
2561 Self {
2562 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2563 states,
2564 state_count,
2565 max_token_type: atn.max_token_type(),
2566 }
2567 }
2568}
2569
2570fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2571 SHARED_ATN_CACHES.with(|cell| {
2572 let key = SharedAtnCacheKey::for_atn(atn);
2573 let mut map = cell.borrow_mut();
2574 let cache = map.entry(key).or_default();
2575 f(&mut cache.first_set)
2576 })
2577}
2578
2579fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
2580 SHARED_ATN_CACHES.with(|cell| {
2581 let key = SharedAtnCacheKey::for_atn(atn);
2582 let mut map = cell.borrow_mut();
2583 let cache = map.entry(key).or_default();
2584 f(cache)
2585 })
2586}
2587
2588#[derive(Debug, Default)]
2597struct DecisionLookahead {
2598 transitions: Vec<TransitionLookSet>,
2599}
2600
2601#[derive(Clone, Debug, Default)]
2608struct TransitionLookSet {
2609 symbols: TokenBitSet,
2610 nullable: bool,
2611}
2612
2613struct FirstSetCtx<'a> {
2617 cache: &'a mut FirstSetCache,
2618 in_progress: BTreeSet<(usize, usize)>,
2619 hit_cycle: bool,
2620}
2621
2622fn rule_first_set(
2631 atn: &Atn,
2632 target: usize,
2633 rule_stop_state: usize,
2634 cache: &mut FirstSetCache,
2635) -> Rc<FirstSet> {
2636 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
2637 return Rc::clone(cached);
2638 }
2639 let mut ctx = FirstSetCtx {
2640 cache,
2641 in_progress: BTreeSet::new(),
2642 hit_cycle: false,
2643 };
2644 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
2645}
2646
2647fn rule_first_set_cached(
2648 atn: &Atn,
2649 target: usize,
2650 rule_stop_state: usize,
2651 ctx: &mut FirstSetCtx<'_>,
2652) -> Rc<FirstSet> {
2653 let key = (target, rule_stop_state);
2654 if let Some(cached) = ctx.cache.get(&key) {
2655 return Rc::clone(cached);
2656 }
2657 if !ctx.in_progress.insert(key) {
2658 return Rc::new(FirstSet::default());
2662 }
2663 let saved_hit_cycle = ctx.hit_cycle;
2664 ctx.hit_cycle = false;
2665 let mut first = FirstSet::default();
2666 let mut visited = BTreeSet::new();
2667 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
2668 ctx.in_progress.remove(&key);
2669 let entry = Rc::new(first);
2670 if !ctx.hit_cycle {
2671 ctx.cache.insert(key, Rc::clone(&entry));
2672 }
2673 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
2674 entry
2675}
2676
2677fn transition_first_set(
2681 atn: &Atn,
2682 transition: ParserTransition<'_>,
2683 rule_stop_state: usize,
2684 cache: &mut FirstSetCache,
2685) -> TransitionLookSet {
2686 match &transition.data() {
2687 Transition::Atom { label, .. } => {
2688 let mut symbols = TokenBitSet::default();
2689 symbols.insert(*label);
2690 TransitionLookSet {
2691 symbols,
2692 nullable: false,
2693 }
2694 }
2695 Transition::Range { start, stop, .. } => {
2696 let mut symbols = TokenBitSet::default();
2697 symbols.extend_range(*start, *stop);
2698 TransitionLookSet {
2699 symbols,
2700 nullable: false,
2701 }
2702 }
2703 Transition::Set { set, .. } => {
2704 let mut symbols = TokenBitSet::default();
2705 for (start, stop) in set.ranges() {
2706 symbols.extend_range(start, stop);
2707 }
2708 TransitionLookSet {
2709 symbols,
2710 nullable: false,
2711 }
2712 }
2713 Transition::NotSet { set, .. } => {
2714 let max = atn.max_token_type();
2715 let mut symbols = TokenBitSet::default();
2716 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
2717 TransitionLookSet {
2718 symbols,
2719 nullable: false,
2720 }
2721 }
2722 Transition::Wildcard { .. } => {
2723 let mut symbols = TokenBitSet::default();
2724 symbols.extend_range(1, atn.max_token_type());
2725 TransitionLookSet {
2726 symbols,
2727 nullable: false,
2728 }
2729 }
2730 Transition::Epsilon { target }
2731 | Transition::Action { target, .. }
2732 | Transition::Predicate { target, .. }
2733 | Transition::Precedence { target, .. } => {
2734 let first = rule_first_set(atn, *target, rule_stop_state, cache);
2737 TransitionLookSet {
2738 symbols: first.symbols.clone(),
2739 nullable: first.nullable,
2740 }
2741 }
2742 Transition::Rule {
2743 target,
2744 rule_index,
2745 follow_state,
2746 ..
2747 } => {
2748 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2749 return TransitionLookSet::default();
2750 };
2751 let child = rule_first_set(atn, *target, child_stop, cache);
2752 let mut symbols = child.symbols.clone();
2753 let nullable = if child.nullable {
2754 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
2755 symbols.extend_from(&follow.symbols);
2756 follow.nullable
2757 } else {
2758 false
2759 };
2760 TransitionLookSet { symbols, nullable }
2761 }
2762 }
2763}
2764
2765fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
2786 let mut chosen: Option<usize> = None;
2787 for (index, transition) in entry.transitions.iter().enumerate() {
2788 if transition.nullable {
2789 return None;
2790 }
2791 if transition.symbols.contains(symbol) {
2792 if chosen.is_some() {
2793 return None;
2794 }
2795 chosen = Some(index);
2796 }
2797 }
2798 chosen
2799}
2800
2801fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
2810 let mut matching_non_nullable_alt = None;
2811 let mut nullable_alt = None;
2812 for (index, transition) in entry.transitions.iter().enumerate() {
2813 if transition.nullable {
2814 if nullable_alt.is_some() {
2815 return None;
2816 }
2817 nullable_alt = Some(index);
2818 }
2819 if transition.symbols.contains(symbol) {
2820 if transition.nullable {
2821 continue;
2822 }
2823 if matching_non_nullable_alt.is_some() {
2824 return None;
2825 }
2826 matching_non_nullable_alt = Some(index);
2827 }
2828 }
2829 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
2830 return None;
2831 }
2832 if non_greedy {
2833 nullable_alt.or(matching_non_nullable_alt)
2834 } else {
2835 matching_non_nullable_alt.or(nullable_alt)
2836 }
2837}
2838
2839fn should_skip_via_lookahead(
2840 transition_kind: ParserTransitionKind,
2841 transition_index: usize,
2842 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
2843 index: usize,
2844 record_expected: bool,
2845 expected: &mut ExpectedTokens,
2846) -> bool {
2847 let prune_non_consuming = matches!(
2848 transition_kind,
2849 ParserTransitionKind::Epsilon
2850 | ParserTransitionKind::Action
2851 | ParserTransitionKind::Predicate
2852 | ParserTransitionKind::Rule
2853 | ParserTransitionKind::Precedence
2854 );
2855 if !prune_non_consuming {
2856 return false;
2857 }
2858 let Some((symbol, entry)) = lookahead_filter else {
2859 return false;
2860 };
2861 let Some(set) = entry.transitions.get(transition_index) else {
2862 return false;
2863 };
2864 if set.symbols.contains(*symbol) || set.nullable {
2865 return false;
2866 }
2867 if record_expected && !set.symbols.is_empty() {
2868 record_pruned_transition_expected(set, index, expected);
2869 }
2870 true
2871}
2872
2873fn should_skip_rule_via_first_set(
2874 first: &FirstSet,
2875 symbol: i32,
2876 record_expected: bool,
2877 index: usize,
2878 expected: &mut ExpectedTokens,
2879) -> bool {
2880 if first.nullable || first.symbols.contains(symbol) {
2881 return false;
2882 }
2883 if record_expected && !first.symbols.is_empty() {
2884 record_token_bit_expected(&first.symbols, index, expected);
2885 }
2886 true
2887}
2888
2889fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
2890 match expected.index {
2891 Some(current) if index < current => {}
2892 Some(current) if index == current => {
2893 symbols.extend_btree_set(&mut expected.symbols);
2894 }
2895 _ => {
2896 expected.index = Some(index);
2897 expected.symbols = symbols.to_btree_set();
2898 }
2899 }
2900}
2901
2902fn record_pruned_transition_expected(
2904 set: &TransitionLookSet,
2905 index: usize,
2906 expected: &mut ExpectedTokens,
2907) {
2908 match expected.index {
2909 Some(current) if index < current => {}
2910 Some(current) if index == current => {
2911 set.symbols.extend_btree_set(&mut expected.symbols);
2912 }
2913 _ => {
2914 expected.index = Some(index);
2915 expected.symbols = set.symbols.to_btree_set();
2916 }
2917 }
2918}
2919
2920fn rule_first_set_inner(
2921 atn: &Atn,
2922 state_number: usize,
2923 rule_stop_state: usize,
2924 ctx: &mut FirstSetCtx<'_>,
2925 visited: &mut BTreeSet<usize>,
2926 first: &mut FirstSet,
2927) {
2928 if !visited.insert(state_number) {
2929 return;
2930 }
2931 if state_number == rule_stop_state {
2932 first.nullable = true;
2933 return;
2934 }
2935 let Some(state) = atn.state(state_number) else {
2936 return;
2937 };
2938 for transition in &state.transitions() {
2939 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2940 if !transition_symbols.is_empty() {
2941 first.symbols.extend_iter(transition_symbols);
2942 continue;
2943 }
2944 match &transition.data() {
2945 Transition::Epsilon { target }
2946 | Transition::Action { target, .. }
2947 | Transition::Predicate { target, .. }
2948 | Transition::Precedence { target, .. } => {
2949 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
2950 }
2951 Transition::Rule {
2952 target,
2953 rule_index,
2954 follow_state,
2955 ..
2956 } => {
2957 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2958 continue;
2959 };
2960 let child_key = (*target, child_stop);
2961 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
2962 ctx.hit_cycle = true;
2963 }
2964 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
2965 first.symbols.extend_from(&child.symbols);
2966 if child.nullable {
2967 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
2968 }
2969 }
2970 Transition::Atom { .. }
2971 | Transition::Range { .. }
2972 | Transition::Set { .. }
2973 | Transition::NotSet { .. }
2974 | Transition::Wildcard { .. } => {}
2975 }
2976 }
2977}
2978
2979fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
2982 let mut symbols = BTreeSet::new();
2983 state_sync_symbols_inner(
2984 atn,
2985 state_number,
2986 stop_state,
2987 &mut BTreeSet::new(),
2988 &mut symbols,
2989 );
2990 symbols
2991}
2992
2993fn state_sync_symbols_inner(
2996 atn: &Atn,
2997 state_number: usize,
2998 stop_state: usize,
2999 visited: &mut BTreeSet<usize>,
3000 symbols: &mut BTreeSet<i32>,
3001) {
3002 if !visited.insert(state_number) {
3003 return;
3004 }
3005 if state_number == stop_state {
3006 symbols.insert(TOKEN_EOF);
3007 return;
3008 }
3009 let Some(state) = atn.state(state_number) else {
3010 return;
3011 };
3012 for transition in &state.transitions() {
3013 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3014 if transition_symbols.is_empty() {
3015 match &transition.data() {
3016 Transition::Rule { target, .. }
3017 | Transition::Epsilon { target }
3018 | Transition::Action { target, .. }
3019 | Transition::Predicate { target, .. }
3020 | Transition::Precedence { target, .. } => {
3021 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
3022 }
3023 Transition::Atom { .. }
3024 | Transition::Range { .. }
3025 | Transition::Set { .. }
3026 | Transition::NotSet { .. }
3027 | Transition::Wildcard { .. } => {}
3028 }
3029 } else {
3030 symbols.extend(transition_symbols);
3031 }
3032 }
3033}
3034
3035#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
3036struct OperatorSymbolReachability {
3037 single_token: bool,
3039 multi_token: bool,
3041 predicate_dependent: bool,
3043}
3044
3045impl OperatorSymbolReachability {
3046 const ADAPTIVE_FALLBACK: Self = Self {
3047 single_token: false,
3048 multi_token: false,
3049 predicate_dependent: true,
3050 };
3051
3052 const fn single_token(predicate_dependent: bool) -> Self {
3053 if predicate_dependent {
3054 Self {
3055 single_token: false,
3056 multi_token: false,
3057 predicate_dependent: true,
3058 }
3059 } else {
3060 Self {
3061 single_token: true,
3062 multi_token: false,
3063 predicate_dependent: false,
3064 }
3065 }
3066 }
3067
3068 const fn multi_token(predicate_dependent: bool) -> Self {
3069 if predicate_dependent {
3070 Self {
3071 single_token: false,
3072 multi_token: false,
3073 predicate_dependent: true,
3074 }
3075 } else {
3076 Self {
3077 single_token: false,
3078 multi_token: true,
3079 predicate_dependent: false,
3080 }
3081 }
3082 }
3083
3084 const fn union(self, other: Self) -> Self {
3085 Self {
3086 single_token: self.single_token || other.single_token,
3087 multi_token: self.multi_token || other.multi_token,
3088 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
3089 }
3090 }
3091}
3092
3093#[derive(Clone, Copy)]
3094struct OperatorReachabilityRequest {
3095 symbol: i32,
3096 precedence: i32,
3097 predicate_dependent: bool,
3098 operator_rule_index: usize,
3099}
3100
3101#[derive(Clone, Copy, Debug)]
3102struct OperatorRuleContinuation {
3103 stop_state: usize,
3104 follow_state: usize,
3105 return_precedence: i32,
3106}
3107
3108struct NullablePrecedenceCtx {
3109 cache: FxHashMap<(usize, usize, i32, bool), bool>,
3110 in_progress: BTreeSet<(usize, usize, i32, bool)>,
3111 hit_cycle: bool,
3112}
3113
3114fn state_is_nullable_with_precedence(
3115 atn: &Atn,
3116 state_number: usize,
3117 stop_state_number: usize,
3118 precedence: i32,
3119 allow_predicates: bool,
3120 ctx: &mut NullablePrecedenceCtx,
3121) -> bool {
3122 let saved_hit_cycle = ctx.hit_cycle;
3123 ctx.hit_cycle = false;
3124 let nullable = state_is_nullable_with_precedence_cached(
3125 atn,
3126 state_number,
3127 stop_state_number,
3128 precedence,
3129 allow_predicates,
3130 ctx,
3131 );
3132 ctx.hit_cycle = saved_hit_cycle;
3133 nullable
3134}
3135
3136fn state_is_nullable_with_precedence_cached(
3137 atn: &Atn,
3138 state_number: usize,
3139 stop_state_number: usize,
3140 precedence: i32,
3141 allow_predicates: bool,
3142 ctx: &mut NullablePrecedenceCtx,
3143) -> bool {
3144 if state_number == stop_state_number {
3145 return true;
3146 }
3147 let key = (
3148 state_number,
3149 stop_state_number,
3150 precedence,
3151 allow_predicates,
3152 );
3153 if let Some(cached) = ctx.cache.get(&key) {
3154 return *cached;
3155 }
3156 if !ctx.in_progress.insert(key) {
3157 ctx.hit_cycle = true;
3158 return false;
3159 }
3160 let saved_hit_cycle = ctx.hit_cycle;
3161 ctx.hit_cycle = false;
3162 let nullable = atn.state(state_number).is_some_and(|state| {
3163 state
3164 .transitions()
3165 .iter()
3166 .any(|transition| match &transition.data() {
3167 Transition::Rule {
3168 target,
3169 rule_index,
3170 follow_state,
3171 precedence: rule_precedence,
3172 } => {
3173 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3174 return false;
3175 };
3176 state_is_nullable_with_precedence_cached(
3177 atn,
3178 *target,
3179 child_stop,
3180 *rule_precedence,
3181 allow_predicates,
3182 ctx,
3183 ) && state_is_nullable_with_precedence_cached(
3184 atn,
3185 *follow_state,
3186 stop_state_number,
3187 precedence,
3188 allow_predicates,
3189 ctx,
3190 )
3191 }
3192 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3193 state_is_nullable_with_precedence_cached(
3194 atn,
3195 *target,
3196 stop_state_number,
3197 precedence,
3198 allow_predicates,
3199 ctx,
3200 )
3201 }
3202 Transition::Predicate { target, .. } if allow_predicates => {
3203 state_is_nullable_with_precedence_cached(
3204 atn,
3205 *target,
3206 stop_state_number,
3207 precedence,
3208 allow_predicates,
3209 ctx,
3210 )
3211 }
3212 Transition::Precedence {
3213 target,
3214 precedence: transition_precedence,
3215 } if *transition_precedence >= precedence => {
3216 state_is_nullable_with_precedence_cached(
3217 atn,
3218 *target,
3219 stop_state_number,
3220 precedence,
3221 allow_predicates,
3222 ctx,
3223 )
3224 }
3225 Transition::Atom { .. }
3226 | Transition::Range { .. }
3227 | Transition::Set { .. }
3228 | Transition::NotSet { .. }
3229 | Transition::Wildcard { .. }
3230 | Transition::Predicate { .. }
3231 | Transition::Precedence { .. } => false,
3232 })
3233 });
3234 ctx.in_progress.remove(&key);
3235 if !ctx.hit_cycle {
3236 ctx.cache.insert(key, nullable);
3237 }
3238 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3239 nullable
3240}
3241
3242fn state_operator_token_prefix_reachability(
3244 atn: &Atn,
3245 state_number: usize,
3246 request: OperatorReachabilityRequest,
3247 continuations: &[OperatorRuleContinuation],
3248 visited: &mut BTreeSet<(usize, i32, bool)>,
3249) -> OperatorSymbolReachability {
3250 let key = (
3251 state_number,
3252 request.precedence,
3253 request.predicate_dependent,
3254 );
3255 if !visited.insert(key) {
3256 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3260 }
3261 if let Some((continuation, remaining)) = continuations.split_last()
3262 && state_number == continuation.stop_state
3263 {
3264 let result = state_operator_token_prefix_reachability(
3265 atn,
3266 continuation.follow_state,
3267 OperatorReachabilityRequest {
3268 precedence: continuation.return_precedence,
3269 ..request
3270 },
3271 remaining,
3272 visited,
3273 );
3274 visited.remove(&key);
3275 return result;
3276 }
3277 let Some(state) = atn.state(state_number) else {
3278 visited.remove(&key);
3279 return OperatorSymbolReachability::default();
3280 };
3281 let completes_operator = match state.kind() {
3282 AtnStateKind::RuleStop => continuations.is_empty(),
3283 AtnStateKind::StarLoopBack
3284 | AtnStateKind::StarLoopEntry
3285 | AtnStateKind::PlusLoopBack
3286 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3287 _ => false,
3288 };
3289 if completes_operator {
3290 visited.remove(&key);
3291 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3292 }
3293 let mut reachability = OperatorSymbolReachability::default();
3294 for transition in &state.transitions() {
3295 let transition_reachability = match &transition.data() {
3296 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3297 OperatorSymbolReachability::single_token(request.predicate_dependent)
3298 }
3299 Transition::Rule {
3300 target,
3301 rule_index,
3302 follow_state,
3303 precedence: rule_precedence,
3304 } => {
3305 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3306 continue;
3307 };
3308 let mut nested = continuations.to_vec();
3309 nested.push(OperatorRuleContinuation {
3310 stop_state: child_stop,
3311 follow_state: *follow_state,
3312 return_precedence: request.precedence,
3313 });
3314 state_operator_token_prefix_reachability(
3315 atn,
3316 *target,
3317 OperatorReachabilityRequest {
3318 precedence: *rule_precedence,
3319 ..request
3320 },
3321 &nested,
3322 visited,
3323 )
3324 }
3325 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3326 state_operator_token_prefix_reachability(
3327 atn,
3328 *target,
3329 request,
3330 continuations,
3331 visited,
3332 )
3333 }
3334 Transition::Precedence {
3335 target,
3336 precedence: transition_precedence,
3337 } => {
3338 if *transition_precedence < request.precedence {
3339 OperatorSymbolReachability::default()
3340 } else {
3341 state_operator_token_prefix_reachability(
3342 atn,
3343 *target,
3344 request,
3345 continuations,
3346 visited,
3347 )
3348 }
3349 }
3350 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3351 atn,
3352 *target,
3353 OperatorReachabilityRequest {
3354 predicate_dependent: true,
3355 ..request
3356 },
3357 continuations,
3358 visited,
3359 ),
3360 Transition::Atom { .. }
3361 | Transition::Range { .. }
3362 | Transition::Set { .. }
3363 | Transition::NotSet { .. }
3364 | Transition::Wildcard { .. } => {
3365 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3366 }
3367 };
3368 reachability = reachability.union(transition_reachability);
3369 }
3370 visited.remove(&key);
3371 reachability
3372}
3373
3374fn state_can_reach_symbol_with_precedence(
3375 atn: &Atn,
3376 state_number: usize,
3377 request: OperatorReachabilityRequest,
3378 nullable_ctx: &mut NullablePrecedenceCtx,
3379 continuations: &mut Vec<OperatorRuleContinuation>,
3380 visited: &mut BTreeSet<(usize, i32, bool)>,
3381) -> OperatorSymbolReachability {
3382 let key = (
3383 state_number,
3384 request.precedence,
3385 request.predicate_dependent,
3386 );
3387 if !visited.insert(key) {
3388 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3389 }
3390 let Some(state) = atn.state(state_number) else {
3391 visited.remove(&key);
3392 return OperatorSymbolReachability::default();
3393 };
3394 let mut reachability = OperatorSymbolReachability::default();
3395 for transition in &state.transitions() {
3396 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3397 reachability = reachability.union(state_operator_token_prefix_reachability(
3398 atn,
3399 transition.target(),
3400 request,
3401 continuations,
3402 &mut BTreeSet::new(),
3403 ));
3404 continue;
3405 }
3406 let transition_reachability = match &transition.data() {
3407 Transition::Rule {
3408 target,
3409 rule_index,
3410 follow_state,
3411 precedence: rule_precedence,
3412 } => {
3413 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3414 continue;
3415 };
3416 continuations.push(OperatorRuleContinuation {
3417 stop_state: child_stop,
3418 follow_state: *follow_state,
3419 return_precedence: request.precedence,
3420 });
3421 let mut result = state_can_reach_symbol_with_precedence(
3422 atn,
3423 *target,
3424 OperatorReachabilityRequest {
3425 precedence: *rule_precedence,
3426 ..request
3427 },
3428 nullable_ctx,
3429 continuations,
3430 visited,
3431 );
3432 continuations.pop();
3433 if state_is_nullable_with_precedence(
3434 atn,
3435 *target,
3436 child_stop,
3437 *rule_precedence,
3438 true,
3439 nullable_ctx,
3440 ) {
3441 let child_predicate_dependent = request.predicate_dependent
3442 || !state_is_nullable_with_precedence(
3443 atn,
3444 *target,
3445 child_stop,
3446 *rule_precedence,
3447 false,
3448 nullable_ctx,
3449 );
3450 result = result.union(state_can_reach_symbol_with_precedence(
3451 atn,
3452 *follow_state,
3453 OperatorReachabilityRequest {
3454 predicate_dependent: child_predicate_dependent,
3455 ..request
3456 },
3457 nullable_ctx,
3458 continuations,
3459 visited,
3460 ));
3461 }
3462 result
3463 }
3464 Transition::Epsilon { target }
3465 | Transition::Action { target, .. }
3466 | Transition::Precedence { target, .. } => {
3467 if matches!(
3468 &transition.data(),
3469 Transition::Precedence {
3470 precedence: transition_precedence,
3471 ..
3472 } if *transition_precedence < request.precedence
3473 ) {
3474 continue;
3475 }
3476 state_can_reach_symbol_with_precedence(
3477 atn,
3478 *target,
3479 request,
3480 nullable_ctx,
3481 continuations,
3482 visited,
3483 )
3484 }
3485 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3486 atn,
3487 *target,
3488 OperatorReachabilityRequest {
3489 predicate_dependent: true,
3490 ..request
3491 },
3492 nullable_ctx,
3493 continuations,
3494 visited,
3495 ),
3496 Transition::Atom { .. }
3497 | Transition::Range { .. }
3498 | Transition::Set { .. }
3499 | Transition::NotSet { .. }
3500 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3501 };
3502 reachability = reachability.union(transition_reachability);
3503 }
3504 visited.remove(&key);
3505 reachability
3506}
3507
3508fn left_recursive_operator_lookahead(
3509 atn: &Atn,
3510 state_number: usize,
3511 precedence: i32,
3512) -> LeftRecursiveOperatorLookahead {
3513 let Some(state) = atn.state(state_number) else {
3514 return LeftRecursiveOperatorLookahead::default();
3515 };
3516 let Some(operator_rule_index) = state.rule_index() else {
3517 return LeftRecursiveOperatorLookahead::default();
3518 };
3519 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3520 let mut nullable_ctx = NullablePrecedenceCtx {
3521 cache: FxHashMap::default(),
3522 in_progress: BTreeSet::new(),
3523 hit_cycle: false,
3524 };
3525 for transition in &state.transitions() {
3526 let target = transition.target();
3527 if atn
3528 .state(target)
3529 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3530 {
3531 continue;
3532 }
3533 for symbol in 1..=atn.max_token_type() {
3534 let reachability = state_can_reach_symbol_with_precedence(
3535 atn,
3536 target,
3537 OperatorReachabilityRequest {
3538 symbol,
3539 precedence,
3540 predicate_dependent: false,
3541 operator_rule_index,
3542 },
3543 &mut nullable_ctx,
3544 &mut Vec::new(),
3545 &mut BTreeSet::new(),
3546 );
3547 if reachability.single_token {
3548 lookahead.single_token.insert(symbol);
3549 }
3550 if reachability.multi_token {
3551 lookahead.multi_token_prefix.insert(symbol);
3552 }
3553 if reachability.predicate_dependent {
3554 lookahead.predicate_dependent.insert(symbol);
3555 }
3556 }
3557 }
3558 lookahead
3559}
3560
3561#[derive(Debug, Default)]
3562struct StateBeforeStopLookahead {
3563 symbols: TokenBitSet,
3564 reaches_context_boundary: bool,
3565}
3566
3567fn state_before_stop_lookahead(
3568 atn: &Atn,
3569 state_number: usize,
3570 stop_state_number: usize,
3571) -> Rc<StateBeforeStopLookahead> {
3572 with_shared_atn_caches(atn, |cache| {
3573 let key = (state_number, stop_state_number);
3574 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
3575 return Rc::clone(cached);
3576 }
3577 let mut lookahead = StateBeforeStopLookahead::default();
3578 state_before_stop_lookahead_inner(
3579 atn,
3580 state_number,
3581 stop_state_number,
3582 &mut BTreeSet::new(),
3583 &mut cache.first_set,
3584 &mut lookahead,
3585 );
3586 let lookahead = Rc::new(lookahead);
3587 cache
3588 .state_before_stop_lookahead
3589 .insert(key, Rc::clone(&lookahead));
3590 lookahead
3591 })
3592}
3593
3594fn state_before_stop_lookahead_inner(
3595 atn: &Atn,
3596 state_number: usize,
3597 stop_state_number: usize,
3598 visited: &mut BTreeSet<usize>,
3599 first_set_cache: &mut FirstSetCache,
3600 lookahead: &mut StateBeforeStopLookahead,
3601) {
3602 if state_number == stop_state_number {
3603 lookahead.reaches_context_boundary = true;
3604 return;
3605 }
3606 if !visited.insert(state_number) {
3607 return;
3608 }
3609 let Some(state) = atn.state(state_number) else {
3610 return;
3611 };
3612 if state.kind() == AtnStateKind::RuleStop {
3613 lookahead.reaches_context_boundary = true;
3614 return;
3615 }
3616 for transition in &state.transitions() {
3617 match &transition.data() {
3618 Transition::Epsilon { target }
3619 | Transition::Action { target, .. }
3620 | Transition::Predicate { target, .. }
3621 | Transition::Precedence { target, .. } => {
3622 state_before_stop_lookahead_inner(
3623 atn,
3624 *target,
3625 stop_state_number,
3626 visited,
3627 first_set_cache,
3628 lookahead,
3629 );
3630 }
3631 Transition::Rule {
3632 target,
3633 rule_index,
3634 follow_state,
3635 ..
3636 } => {
3637 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3638 continue;
3639 };
3640 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
3641 lookahead.symbols.extend_from(&child.symbols);
3642 if child.nullable {
3643 state_before_stop_lookahead_inner(
3644 atn,
3645 *follow_state,
3646 stop_state_number,
3647 visited,
3648 first_set_cache,
3649 lookahead,
3650 );
3651 }
3652 }
3653 Transition::Atom { .. }
3654 | Transition::Range { .. }
3655 | Transition::Set { .. }
3656 | Transition::NotSet { .. }
3657 | Transition::Wildcard { .. } => {
3658 lookahead.symbols.extend_iter(transition_expected_symbols(
3659 transition,
3660 atn.max_token_type(),
3661 ));
3662 }
3663 }
3664 }
3665}
3666
3667fn caller_context_can_match_symbol_before_state(
3668 atn: &Atn,
3669 return_states: impl DoubleEndedIterator<Item = usize>,
3670 stop_state_number: usize,
3671 symbol: i32,
3672) -> bool {
3673 for return_state in return_states.rev() {
3674 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
3675 if lookahead.symbols.contains(symbol) {
3676 return true;
3677 }
3678 if !lookahead.reaches_context_boundary {
3679 return false;
3680 }
3681 }
3682 false
3683}
3684
3685fn next_recovery_context(
3689 atn: &Atn,
3690 state: AtnState<'_>,
3691 inherited: &BTreeSet<i32>,
3692 inherited_state: Option<usize>,
3693) -> (BTreeSet<i32>, Option<usize>) {
3694 let state_symbols = state_expected_symbols(atn, state.state_number());
3695 if state.transitions().len() > 1 && !state_symbols.is_empty() {
3696 let mut symbols = state_symbols;
3697 symbols.extend(inherited.iter().copied());
3698 return (symbols, Some(state.state_number()));
3699 }
3700 (inherited.clone(), inherited_state)
3701}
3702
3703fn recovery_expected_symbols(
3704 atn: &Atn,
3705 state_number: usize,
3706 inherited: &BTreeSet<i32>,
3707) -> BTreeSet<i32> {
3708 let mut symbols = state_expected_symbols(atn, state_number);
3709 symbols.extend(inherited.iter().copied());
3710 symbols
3711}
3712
3713fn fast_next_recovery_context<S, H>(
3717 parser: &mut BaseParser<S, H>,
3718 atn: &Atn,
3719 state: AtnState<'_>,
3720 inherited: &Rc<BTreeSet<i32>>,
3721 inherited_state: Option<usize>,
3722) -> (Rc<BTreeSet<i32>>, Option<usize>)
3723where
3724 S: TokenSource,
3725 H: SemanticHooks,
3726{
3727 if state.transitions().len() <= 1 {
3728 return (Rc::clone(inherited), inherited_state);
3729 }
3730 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
3731 if state_symbols.is_empty() {
3732 return (Rc::clone(inherited), inherited_state);
3733 }
3734 if inherited.is_empty() {
3735 return (state_symbols, Some(state.state_number()));
3736 }
3737 if Rc::ptr_eq(&state_symbols, inherited) {
3738 return (state_symbols, Some(state.state_number()));
3739 }
3740 let mut combined = (*state_symbols).clone();
3741 combined.extend(inherited.iter().copied());
3742 (
3743 parser.intern_recovery_symbols(combined),
3744 Some(state.state_number()),
3745 )
3746}
3747
3748fn fast_recovery_expected_symbols<S, H>(
3752 parser: &mut BaseParser<S, H>,
3753 atn: &Atn,
3754 state_number: usize,
3755 inherited: &Rc<BTreeSet<i32>>,
3756) -> Rc<BTreeSet<i32>>
3757where
3758 S: TokenSource,
3759 H: SemanticHooks,
3760{
3761 let cached = parser.cached_state_expected_symbols(atn, state_number);
3762 if inherited.is_empty() {
3763 return cached;
3764 }
3765 if cached.is_empty() {
3766 return Rc::clone(inherited);
3767 }
3768 if Rc::ptr_eq(&cached, inherited) {
3769 return cached;
3770 }
3771 let mut combined = (*cached).clone();
3772 combined.extend(inherited.iter().copied());
3773 parser.intern_recovery_symbols(combined)
3774}
3775
3776struct ParserTableSemCtx<'a> {
3777 member_values: &'a mut BTreeMap<usize, i64>,
3778 return_values: &'a mut BTreeMap<String, i64>,
3779}
3780
3781impl semir::PredContext for ParserTableSemCtx<'_> {
3782 type TokenText<'a>
3783 = &'a str
3784 where
3785 Self: 'a;
3786
3787 fn la(&mut self, _offset: isize) -> i64 {
3788 i64::from(TOKEN_EOF)
3789 }
3790
3791 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
3792 None
3793 }
3794
3795 fn token_index_adjacent(&mut self) -> bool {
3796 false
3797 }
3798
3799 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
3800 None
3801 }
3802
3803 fn member(&self, member: usize) -> Option<i64> {
3804 Some(self.member_values.get(&member).copied().unwrap_or_default())
3805 }
3806
3807 fn local_arg(&self) -> Option<i64> {
3808 None
3809 }
3810
3811 fn column(&self) -> Option<i64> {
3812 None
3813 }
3814
3815 fn token_start_column(&self) -> Option<i64> {
3816 None
3817 }
3818
3819 fn token_text_so_far(&self) -> Option<String> {
3820 None
3821 }
3822
3823 fn hook(&mut self, _hook: HookId) -> bool {
3824 false
3825 }
3826}
3827
3828impl semir::ActContext for ParserTableSemCtx<'_> {
3829 fn set_member(&mut self, member: usize, value: i64) {
3830 self.member_values.insert(member, value);
3831 }
3832
3833 fn set_return(&mut self, name: &str, value: i64) {
3834 self.return_values.insert(name.to_owned(), value);
3835 }
3836
3837 fn action_hook(&mut self, _hook: HookId) {}
3838}
3839
3840fn apply_member_actions(
3842 source_state: usize,
3843 actions: &[ParserMemberAction],
3844 semantics: Option<&ParserSemantics>,
3845 values: &mut BTreeMap<usize, i64>,
3846) {
3847 for action in actions
3848 .iter()
3849 .filter(|action| action.source_state == source_state)
3850 {
3851 *values.entry(action.member).or_default() += action.delta;
3852 }
3853 let Some(semantics) = semantics else {
3854 return;
3855 };
3856 let mut return_values = BTreeMap::new();
3857 let mut ctx = ParserTableSemCtx {
3858 member_values: values,
3859 return_values: &mut return_values,
3860 };
3861 for action in semantics
3862 .actions
3863 .iter()
3864 .filter(|action| action.source_state == source_state && action.speculative)
3865 {
3866 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3867 }
3868}
3869
3870fn member_values_after_action(
3872 source_state: usize,
3873 actions: &[ParserMemberAction],
3874 semantics: Option<&ParserSemantics>,
3875 values: &BTreeMap<usize, i64>,
3876) -> BTreeMap<usize, i64> {
3877 let mut values = values.clone();
3878 apply_member_actions(source_state, actions, semantics, &mut values);
3879 values
3880}
3881
3882fn return_values_after_action(
3884 source_state: usize,
3885 rule_index: usize,
3886 actions: &[ParserReturnAction],
3887 semantics: Option<&ParserSemantics>,
3888 values: &BTreeMap<String, i64>,
3889) -> BTreeMap<String, i64> {
3890 let mut values = values.clone();
3891 for action in actions
3892 .iter()
3893 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
3894 {
3895 values.insert(action.name.to_owned(), action.value);
3896 }
3897 if let Some(semantics) = semantics {
3898 let mut member_values = BTreeMap::new();
3899 let mut ctx = ParserTableSemCtx {
3900 member_values: &mut member_values,
3901 return_values: &mut values,
3902 };
3903 for action in semantics.actions.iter().filter(|action| {
3904 action.source_state == source_state
3905 && action.rule_index == rule_index
3906 && !action.speculative
3907 }) {
3908 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3909 }
3910 }
3911 values
3912}
3913
3914fn rule_local_int_arg(
3916 rule_args: &[ParserRuleArg],
3917 source_state: usize,
3918 rule_index: usize,
3919 local_int_arg: Option<(usize, i64)>,
3920) -> Option<(usize, i64)> {
3921 rule_args
3922 .iter()
3923 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
3924 .map(|arg| {
3925 let value = if arg.inherit_local {
3926 local_int_arg.map_or(arg.value, |(_, value)| value)
3927 } else {
3928 arg.value
3929 };
3930 (rule_index, value)
3931 })
3932}
3933
3934fn stop_outcome(
3937 index: usize,
3938 consumed_eof: bool,
3939 rule_alt_number: usize,
3940 member_values: BTreeMap<usize, i64>,
3941 return_values: BTreeMap<String, i64>,
3942) -> Vec<RecognizeOutcome> {
3943 vec![RecognizeOutcome {
3944 index,
3945 consumed_eof,
3946 alt_number: rule_alt_number,
3947 member_values,
3948 return_values,
3949 diagnostics: DiagnosticSeqId::EMPTY,
3950 decisions: Vec::new(),
3951 actions: Vec::new(),
3952 nodes: NodeSeqId::EMPTY,
3953 }]
3954}
3955
3956fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
3957 with_shared_atn_caches(atn, |cache| {
3958 *cache.observable_action_transitions.get_or_insert_with(|| {
3959 atn.states().any(|state| {
3960 state.transitions().iter().any(|transition| {
3961 matches!(
3962 &transition.data(),
3963 Transition::Action {
3964 action_index: Some(_),
3965 ..
3966 }
3967 )
3968 })
3969 })
3970 })
3971 })
3972}
3973
3974fn atn_has_predicate_transitions(atn: &Atn) -> bool {
3975 with_shared_atn_caches(atn, |cache| {
3976 *cache.predicate_transitions.get_or_insert_with(|| {
3977 atn.states().any(|state| {
3978 state
3979 .transitions()
3980 .iter()
3981 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
3982 })
3983 })
3984 })
3985}
3986
3987fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
3992 options.init_action_rules.is_empty()
3993 && !options.track_alt_numbers
3994 && options
3995 .predicates
3996 .iter()
3997 .all(|(_, _, predicate)| predicate.failure_message().is_none())
3998 && options.semantics.is_none_or(|semantics| {
3999 semantics.actions.is_empty()
4000 && semantics
4001 .predicates
4002 .iter()
4003 .all(|predicate| predicate.failure_message.is_none())
4004 })
4005 && options.rule_args.is_empty()
4006 && options.member_actions.is_empty()
4007 && options.return_actions.is_empty()
4008 && !atn_has_observable_action_transitions(atn)
4009}
4010
4011#[derive(Clone, Debug, Eq, PartialEq)]
4012struct RecognizeRequest<'a> {
4013 state_number: usize,
4014 stop_state: usize,
4015 index: usize,
4016 rule_start_index: usize,
4017 decision_start_index: Option<usize>,
4018 init_action_rules: &'a BTreeSet<usize>,
4019 predicates: &'a [(usize, usize, ParserPredicate)],
4020 semantics: Option<&'a ParserSemantics>,
4021 rule_args: &'a [ParserRuleArg],
4022 member_actions: &'a [ParserMemberAction],
4023 return_actions: &'a [ParserReturnAction],
4024 local_int_arg: Option<(usize, i64)>,
4025 member_values: BTreeMap<usize, i64>,
4026 return_values: BTreeMap<String, i64>,
4027 rule_alt_number: usize,
4028 track_alt_numbers: bool,
4029 consumed_eof: bool,
4030 committed_decision: bool,
4031 precedence: i32,
4034 depth: usize,
4035 recovery_symbols: BTreeSet<i32>,
4036 recovery_state: Option<usize>,
4037}
4038
4039#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
4040struct RecognizeKey {
4041 state_number: usize,
4042 stop_state: usize,
4043 index: usize,
4044 rule_start_index: usize,
4045 decision_start_index: Option<usize>,
4046 local_int_arg: Option<(usize, i64)>,
4047 member_values: BTreeMap<usize, i64>,
4048 return_values: BTreeMap<String, i64>,
4049 rule_alt_number: usize,
4050 track_alt_numbers: bool,
4051 consumed_eof: bool,
4052 committed_decision: bool,
4053 precedence: i32,
4054 recovery_symbols: BTreeSet<i32>,
4055 recovery_state: Option<usize>,
4056}
4057
4058#[derive(Clone, Debug, Eq, PartialEq)]
4059struct EpsilonActionStep {
4060 source_state: usize,
4061 target: usize,
4062 action_rule_index: Option<usize>,
4063 left_recursive_boundary: Option<usize>,
4064 decision: Option<usize>,
4065 decision_start_index: Option<usize>,
4066 alt_number: usize,
4067 recovery_symbols: BTreeSet<i32>,
4068 recovery_state: Option<usize>,
4069}
4070
4071struct RecognizeScratch<'a> {
4072 visiting: &'a mut BTreeSet<RecognizeKey>,
4073 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4074 expected: &'a mut ExpectedTokens,
4075}
4076
4077#[derive(Clone, Debug, Eq, PartialEq)]
4078struct FastRecognizeRequest {
4079 state_number: usize,
4080 stop_state: usize,
4081 index: usize,
4082 rule_start_index: usize,
4083 decision_start_index: Option<usize>,
4084 precedence: i32,
4085 depth: usize,
4086 recovery_symbols: Rc<BTreeSet<i32>>,
4087 recovery_state: Option<usize>,
4088}
4089
4090#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4091struct FastRecognizeTopRequest {
4092 start_state: usize,
4093 stop_state: usize,
4094 start_index: usize,
4095 precedence: i32,
4096 caller_follow_state: Option<usize>,
4097}
4098
4099#[derive(Clone, Copy, Debug)]
4100struct FastPredicateContext<'a> {
4101 predicates: &'a [(usize, usize, ParserPredicate)],
4102 semantics: Option<&'a ParserSemantics>,
4103 member_values: &'a BTreeMap<usize, i64>,
4104}
4105
4106#[derive(Clone, Copy, Debug, Default)]
4107struct AltNumberTracking {
4108 public: bool,
4109 context: bool,
4110}
4111
4112impl AltNumberTracking {
4113 const fn any(self) -> bool {
4114 self.public || self.context
4115 }
4116}
4117
4118struct FastRecognizeScratch<'a, 'b> {
4119 predicate_context: Option<FastPredicateContext<'a>>,
4120 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4121 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4122 expected: &'b mut ExpectedTokens,
4123 native_depth: usize,
4124}
4125
4126#[derive(Clone, Copy, Debug)]
4127struct FastRepetitionShape {
4128 enter_target: usize,
4129 exit_target: usize,
4130 body_stop_state: usize,
4131 enter_transition_index: usize,
4132 exit_transition_index: usize,
4133}
4134
4135#[derive(Clone, Copy, Debug)]
4136struct FastRepetitionPath {
4137 index: usize,
4138 deferred_nodes: FastDeferredNodeId,
4139 diagnostics: DiagnosticSeqId,
4140 consumed_eof: bool,
4141}
4142
4143enum FastRepetitionWork {
4144 Enter(FastRepetitionPath),
4145 Exit(FastRepetitionPath),
4146}
4147
4148struct FastRepetitionCoordinates {
4153 base_index: usize,
4154 base_state: u8,
4155 later_states: Vec<u8>,
4156}
4157
4158impl FastRepetitionCoordinates {
4159 const ENTERED: u8 = 0;
4160 const EXITED: u8 = 2;
4161
4162 const fn new(base_index: usize) -> Self {
4163 Self {
4164 base_index,
4165 base_state: 0,
4166 later_states: Vec::new(),
4167 }
4168 }
4169
4170 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4171 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4172 }
4173
4174 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4175 self.insert(path.index, path.consumed_eof, Self::EXITED)
4176 }
4177
4178 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4179 let Some(offset) = index.checked_sub(self.base_index) else {
4180 return false;
4181 };
4182 let state = if offset == 0 {
4183 &mut self.base_state
4184 } else {
4185 if self.later_states.len() < offset {
4186 self.later_states.resize(offset, 0);
4187 }
4188 &mut self.later_states[offset - 1]
4189 };
4190 let bit = 1 << (base_bit + u8::from(consumed_eof));
4191 let is_new = *state & bit == 0;
4192 *state |= bit;
4193 is_new
4194 }
4195}
4196
4197fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4198 if state.precedence_rule_decision()
4199 || !matches!(
4200 state.kind(),
4201 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4202 )
4203 || state.transitions().len() != 2
4204 {
4205 return None;
4206 }
4207 let mut enter = None;
4208 let mut exit = None;
4209 for (index, transition) in state.transitions().iter().enumerate() {
4210 if transition.kind() != ParserTransitionKind::Epsilon {
4211 return None;
4212 }
4213 let target = transition.target();
4214 if atn
4215 .state(target)
4216 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4217 {
4218 if exit.replace((index, target)).is_some() {
4219 return None;
4220 }
4221 } else if enter.replace((index, target)).is_some() {
4222 return None;
4223 }
4224 }
4225 let (enter_transition_index, enter_target) = enter?;
4226 let (exit_transition_index, exit_target) = exit?;
4227 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4228 atn.state(exit_target)?.loop_back_state()?
4229 } else {
4230 state.state_number()
4231 };
4232 Some(FastRepetitionShape {
4233 enter_target,
4234 exit_target,
4235 body_stop_state,
4236 enter_transition_index,
4237 exit_transition_index,
4238 })
4239}
4240
4241fn push_fast_repetition_work(
4242 work: &mut Vec<FastRepetitionWork>,
4243 shape: FastRepetitionShape,
4244 path: FastRepetitionPath,
4245 lookahead: Option<&DecisionLookahead>,
4246 symbol: i32,
4247) {
4248 let transition_is_viable = |transition_index: usize| {
4251 let Some(entry) = lookahead else {
4252 return true;
4253 };
4254 let Some(transition) = entry.transitions.get(transition_index) else {
4255 return true;
4256 };
4257 transition.nullable || transition.symbols.contains(symbol)
4258 };
4259 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4260 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4261 if shape.enter_transition_index < shape.exit_transition_index {
4262 if exit_is_viable {
4263 work.push(FastRepetitionWork::Exit(path));
4264 }
4265 if enter_is_viable {
4266 work.push(FastRepetitionWork::Enter(path));
4267 }
4268 } else {
4269 if enter_is_viable {
4270 work.push(FastRepetitionWork::Enter(path));
4271 }
4272 if exit_is_viable {
4273 work.push(FastRepetitionWork::Exit(path));
4274 }
4275 }
4276}
4277
4278#[derive(Clone, Debug)]
4285struct FastRecognizeKey {
4286 state_number: usize,
4287 stop_state: usize,
4288 index: usize,
4289 rule_start_index: usize,
4290 decision_start_index: Option<usize>,
4291 precedence: i32,
4292 recovery_symbols_id: usize,
4293 recovery_state: Option<usize>,
4294}
4295
4296impl PartialEq for FastRecognizeKey {
4297 fn eq(&self, other: &Self) -> bool {
4298 if self.state_number != other.state_number
4299 || self.stop_state != other.stop_state
4300 || self.index != other.index
4301 || self.rule_start_index != other.rule_start_index
4302 || self.decision_start_index != other.decision_start_index
4303 || self.precedence != other.precedence
4304 || self.recovery_state != other.recovery_state
4305 || self.recovery_symbols_id != other.recovery_symbols_id
4306 {
4307 return false;
4308 }
4309 true
4310 }
4311}
4312
4313impl Eq for FastRecognizeKey {}
4314
4315impl Hash for FastRecognizeKey {
4316 fn hash<H: Hasher>(&self, hasher: &mut H) {
4317 self.state_number.hash(hasher);
4318 self.stop_state.hash(hasher);
4319 self.index.hash(hasher);
4320 self.rule_start_index.hash(hasher);
4321 self.decision_start_index.hash(hasher);
4322 self.precedence.hash(hasher);
4323 self.recovery_state.hash(hasher);
4324 self.recovery_symbols_id.hash(hasher);
4325 }
4326}
4327
4328struct FastRecoveryRequest<'a, 'b> {
4329 atn: &'a Atn,
4330 transition: ParserTransition<'a>,
4331 expected_symbols: Rc<BTreeSet<i32>>,
4332 target: usize,
4333 request: FastRecognizeRequest,
4334 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4335 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4336 expected: &'b mut ExpectedTokens,
4337}
4338
4339struct FastCurrentTokenDeletionRequest<'a, 'b> {
4340 atn: &'a Atn,
4341 expected_symbols: Rc<BTreeSet<i32>>,
4342 request: FastRecognizeRequest,
4343 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4344 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4345 expected: &'b mut ExpectedTokens,
4346}
4347
4348#[derive(Clone, Copy)]
4349struct FastChildRuleFailureRecoveryRequest<'a> {
4350 atn: &'a Atn,
4351 rule_index: usize,
4352 start_index: usize,
4353 follow_state: usize,
4354 stop_state: usize,
4355 expected: &'a ExpectedTokens,
4356}
4357
4358struct RecoveryRequest<'a, 'b> {
4359 atn: &'a Atn,
4360 transition: ParserTransition<'a>,
4361 expected_symbols: BTreeSet<i32>,
4362 target: usize,
4363 request: RecognizeRequest<'a>,
4364 visiting: &'b mut BTreeSet<RecognizeKey>,
4365 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4366 expected: &'b mut ExpectedTokens,
4367}
4368
4369struct CurrentTokenDeletionRequest<'a, 'b> {
4370 atn: &'a Atn,
4371 expected_symbols: BTreeSet<i32>,
4372 request: RecognizeRequest<'a>,
4373 visiting: &'b mut BTreeSet<RecognizeKey>,
4374 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4375 expected: &'b mut ExpectedTokens,
4376}
4377
4378struct ConsumingFailureFallback<'a> {
4381 atn: &'a Atn,
4382 target: usize,
4383 request: RecognizeRequest<'a>,
4384 symbol: i32,
4385 expected_symbols: BTreeSet<i32>,
4386 decision_start_index: Option<usize>,
4387 decision: Option<usize>,
4388}
4389
4390struct ChildRuleFailureRecovery<'a> {
4393 atn: &'a Atn,
4394 rule_index: usize,
4395 start_index: usize,
4396 follow_state: usize,
4397 stop_state: usize,
4398 member_values: BTreeMap<usize, i64>,
4399 expected: &'a ExpectedTokens,
4400}
4401
4402#[derive(Clone, Copy, Debug)]
4404struct PredicateEval<'a> {
4405 index: usize,
4406 rule_index: usize,
4407 pred_index: usize,
4408 predicates: &'a [(usize, usize, ParserPredicate)],
4409 semantics: Option<&'a ParserSemantics>,
4410 context: Option<&'a ParserRuleContext>,
4411 local_int_arg: Option<(usize, i64)>,
4412 member_values: &'a BTreeMap<usize, i64>,
4413}
4414
4415#[derive(Clone, Copy, Debug)]
4416struct ParserSemanticHookRequest<'a> {
4417 index: usize,
4418 rule_index: usize,
4419 pred_index: usize,
4420 context: Option<&'a ParserRuleContext>,
4421 local_int_arg: Option<(usize, i64)>,
4422 member_values: &'a BTreeMap<usize, i64>,
4423}
4424
4425struct ParserSemIrCtx<'a, S, H>
4434where
4435 S: TokenSource,
4436 H: SemanticHooks,
4437{
4438 input: &'a mut CommonTokenStream<S>,
4439 tree_storage: &'a ParseTreeStorage,
4440 semantic_hooks: &'a mut H,
4441 rule_index: usize,
4442 coordinate_index: usize,
4443 rule_name: Option<&'a str>,
4444 context: Option<&'a ParserRuleContext>,
4445 local_int_arg: Option<(usize, i64)>,
4446 member_values: &'a BTreeMap<usize, i64>,
4447 invoked_predicates: &'a mut Vec<(usize, usize)>,
4448 unknown_predicate_policy: UnknownSemanticPolicy,
4452 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4453}
4454
4455impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4456where
4457 S: TokenSource,
4458 H: SemanticHooks,
4459{
4460 type TokenText<'a>
4461 = TokenView<'a>
4462 where
4463 Self: 'a;
4464
4465 fn la(&mut self, offset: isize) -> i64 {
4466 i64::from(self.input.la(offset))
4467 }
4468
4469 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4470 self.input.lt(offset)
4471 }
4472
4473 fn token_index_adjacent(&mut self) -> bool {
4474 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4475 return false;
4476 };
4477 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4478 return false;
4479 };
4480 first + 1 == second
4481 }
4482
4483 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4484 self.context.and_then(|context| {
4485 context
4486 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4487 .next()
4488 .map(crate::tree::RuleNodeView::text)
4489 })
4490 }
4491
4492 fn member(&self, member: usize) -> Option<i64> {
4493 Some(self.member_values.get(&member).copied().unwrap_or_default())
4494 }
4495
4496 fn local_arg(&self) -> Option<i64> {
4497 self.local_int_arg.map(|(_, value)| value)
4498 }
4499
4500 fn column(&self) -> Option<i64> {
4501 None
4502 }
4503
4504 fn token_start_column(&self) -> Option<i64> {
4505 None
4506 }
4507
4508 fn token_text_so_far(&self) -> Option<String> {
4509 None
4510 }
4511
4512 fn hook(&mut self, _hook: HookId) -> bool {
4513 let mut ctx = ParserSemCtx {
4514 input: &mut *self.input,
4515 tree_storage: self.tree_storage,
4516 rule_index: self.rule_index,
4517 coordinate_index: self.coordinate_index,
4518 rule_name: self.rule_name.map(str::to_owned),
4519 context: self.context,
4520 tree: None,
4521 local_int_arg: self.local_int_arg,
4522 member_values: self.member_values,
4523 action: None,
4524 };
4525 match self
4526 .semantic_hooks
4527 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4528 {
4529 Some(result) => result,
4530 None => apply_unknown_predicate_policy(
4534 self.unknown_predicate_policy,
4535 self.rule_index,
4536 self.coordinate_index,
4537 self.unknown_predicate_hits,
4538 ),
4539 }
4540 }
4541
4542 fn trace_bool(&mut self, value: bool) -> bool {
4543 let key = (self.rule_index, self.coordinate_index);
4544 if !self.invoked_predicates.contains(&key) {
4545 self.invoked_predicates.push(key);
4546 use std::io::Write as _;
4547 let mut stdout = std::io::stdout().lock();
4548 let _ = writeln!(stdout, "eval={value}");
4549 }
4550 value
4551 }
4552}
4553
4554struct PredicateFailureRecovery<'a> {
4556 rule_index: usize,
4557 index: usize,
4558 message: &'a str,
4559 member_values: BTreeMap<usize, i64>,
4560 return_values: BTreeMap<String, i64>,
4561 rule_alt_number: usize,
4562}
4563
4564#[derive(Debug)]
4565enum DirectAdaptiveParseControl {
4566 Fallback(DirectAdaptiveFallback),
4567}
4568
4569#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4570enum DirectAdaptiveFallback {
4571 Action,
4572 InvalidAlt,
4573 LeftRecursiveBoundary,
4574 MissingAtn,
4575 NoTransition,
4576 Predicate,
4577 Prediction,
4578 Precedence,
4579 RuleStop,
4580 SemanticContext,
4581 StepLimit,
4582 TokenMismatch,
4583 UnknownDecision,
4584}
4585
4586type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
4587
4588struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
4589where
4590 S: TokenSource,
4591 H: SemanticHooks,
4592{
4593 parser: &'sim mut BaseParser<S, H>,
4594 atn: &'atn Atn,
4595 simulator: &'sim mut ParserAtnSimulator<'atn>,
4596 decision_by_state: Vec<Option<usize>>,
4597 steps: usize,
4598}
4599
4600#[derive(Clone, Debug, Eq, PartialEq)]
4610pub struct GeneratedMatch {
4611 children: GeneratedMatchChildren,
4612 consumed_eof: bool,
4613}
4614
4615#[derive(Clone, Copy)]
4616enum GeneratedExpectedSymbols<'a> {
4617 Tree(&'a BTreeSet<i32>),
4618 TokenSet(ParserIntervalSet<'a>),
4619 TokenSetComplement {
4620 set: ParserIntervalSet<'a>,
4621 min_vocabulary: i32,
4622 max_vocabulary: i32,
4623 },
4624}
4625
4626impl GeneratedExpectedSymbols<'_> {
4627 fn is_empty(self) -> bool {
4628 match self {
4629 Self::Tree(symbols) => symbols.is_empty(),
4630 Self::TokenSet(set) => set.is_empty(),
4631 Self::TokenSetComplement {
4632 set,
4633 min_vocabulary,
4634 max_vocabulary,
4635 } => (min_vocabulary..=max_vocabulary).all(|symbol| set.contains(symbol)),
4636 }
4637 }
4638
4639 fn first(self) -> Option<i32> {
4640 match self {
4641 Self::Tree(symbols) => symbols.iter().next().copied(),
4642 Self::TokenSet(set) => set.ranges().next().map(|(start, _)| start),
4643 Self::TokenSetComplement {
4644 set,
4645 min_vocabulary,
4646 max_vocabulary,
4647 } => (min_vocabulary..=max_vocabulary).find(|symbol| !set.contains(*symbol)),
4648 }
4649 }
4650
4651 fn display(self, vocabulary: &Vocabulary) -> String {
4652 match self {
4653 Self::Tree(symbols) => expected_symbols_display(symbols, vocabulary),
4654 Self::TokenSet(set) => expected_symbols_display_iter(
4655 set.ranges().flat_map(|(start, stop)| start..=stop),
4656 vocabulary,
4657 ),
4658 Self::TokenSetComplement {
4659 set,
4660 min_vocabulary,
4661 max_vocabulary,
4662 } => expected_symbols_display_iter(
4663 (min_vocabulary..=max_vocabulary).filter(|symbol| !set.contains(*symbol)),
4664 vocabulary,
4665 ),
4666 }
4667 }
4668}
4669
4670#[derive(Clone, Debug, Eq, PartialEq)]
4671enum GeneratedMatchChildren {
4672 One(ParseTree),
4673 Many(Vec<ParseTree>),
4674}
4675
4676struct GeneratedMatchChildrenIntoIter {
4677 one: Option<ParseTree>,
4678 many: Option<std::vec::IntoIter<ParseTree>>,
4679}
4680
4681impl Iterator for GeneratedMatchChildrenIntoIter {
4682 type Item = ParseTree;
4683
4684 fn next(&mut self) -> Option<Self::Item> {
4685 self.one
4686 .take()
4687 .or_else(|| self.many.as_mut().and_then(Iterator::next))
4688 }
4689}
4690
4691impl GeneratedMatch {
4692 #[must_use]
4696 pub fn children(&self) -> &[ParseTree] {
4697 match &self.children {
4698 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
4699 GeneratedMatchChildren::Many(children) => children,
4700 }
4701 }
4702
4703 #[must_use]
4706 pub fn into_children(self) -> Vec<ParseTree> {
4707 match self.children {
4708 GeneratedMatchChildren::One(child) => vec![child],
4709 GeneratedMatchChildren::Many(children) => children,
4710 }
4711 }
4712
4713 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
4715 match self.children {
4716 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
4717 one: Some(child),
4718 many: None,
4719 },
4720 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
4721 one: None,
4722 many: Some(children.into_iter()),
4723 },
4724 }
4725 }
4726
4727 #[must_use]
4729 pub const fn consumed_eof(&self) -> bool {
4730 self.consumed_eof
4731 }
4732}
4733
4734impl<S> BaseParser<S, NoSemanticHooks>
4735where
4736 S: TokenSource,
4737{
4738 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
4741 Self::with_semantic_hooks(input, data, NoSemanticHooks)
4742 }
4743}
4744
4745impl<S, H> BaseParser<S, H>
4746where
4747 S: TokenSource,
4748 H: SemanticHooks,
4749{
4750 pub fn with_semantic_hooks(
4752 input: CommonTokenStream<S>,
4753 data: RecognizerData,
4754 semantic_hooks: H,
4755 ) -> Self {
4756 Self {
4757 input,
4758 tree: ParseTreeStorage::new(),
4759 data,
4760 semantic_hooks,
4761 decision_override_generation: 0,
4762 build_parse_trees: true,
4763 syntax_errors: 0,
4764 report_diagnostic_errors: false,
4765 prediction_mode: PredictionMode::Ll,
4766 prediction_diagnostics: Vec::new(),
4767 reported_prediction_diagnostics: BTreeSet::new(),
4768 generated_parser_diagnostics: Vec::new(),
4769 generated_sync_expected: None,
4770 generated_recovery_error_index: None,
4771 generated_recovery_error_states: BTreeSet::new(),
4772 int_members: BTreeMap::new(),
4773 rule_context_stack: Vec::new(),
4774 rule_context_version: 0,
4775 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
4776 pending_invoking_states: Vec::new(),
4777 precedence_stack: vec![0],
4778 invoked_predicates: Vec::new(),
4779 bail_on_error: false,
4780 unknown_predicate_policy: UnknownSemanticPolicy::default(),
4781 unknown_predicate_hits: Vec::new(),
4782 unhandled_action_hits: Vec::new(),
4783 rule_first_set_cache: Vec::new(),
4784 state_expected_cache: FxHashMap::default(),
4785 state_expected_token_cache: FxHashMap::default(),
4786 rule_stop_reach_cache: Vec::new(),
4787 recovery_symbols_intern: FxHashMap::default(),
4788 decision_lookahead_cache: FxHashMap::default(),
4789 ll1_decision_cache: FxHashMap::default(),
4790 fast_predicate_cache: FxHashMap::default(),
4791 empty_cycle_cache: Vec::new(),
4792 empty_cycle_cache_atn: None,
4793 clean_memo_mode: CleanMemoMode::Probe,
4794 clean_memo_probe_seen: FxHashSet::default(),
4795 clean_memo_probe_samples: 0,
4796 clean_memo_probe_repeats: 0,
4797 clean_memo_sparse_samples: 0,
4798 fast_recognize_scratch: FastRecognizeTopScratch::default(),
4799 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
4800 empty_recovery_symbols: Rc::new(BTreeSet::new()),
4801 fast_first_set_prefilter: true,
4802 fast_recovery_enabled: true,
4803 fast_token_nodes_enabled: true,
4804 fast_track_alt_numbers: false,
4805 recognition_arena: RecognitionArena::default(),
4806 last_recognition_arena_root: NodeSeqId::EMPTY,
4807 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
4808 }
4809 }
4810
4811 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
4812 &mut self.input
4813 }
4814
4815 pub fn reset(&mut self) {
4820 self.input.seek(0);
4821 self.tree.reset();
4822 self.data.set_state(-1);
4823 self.syntax_errors = 0;
4824 self.prediction_diagnostics.clear();
4825 self.reported_prediction_diagnostics.clear();
4826 self.generated_parser_diagnostics.clear();
4827 self.generated_sync_expected = None;
4828 self.reset_generated_recovery_state();
4829 self.rule_context_stack.clear();
4830 self.advance_rule_context_version();
4831 self.left_recursive_caller_overlap_cache = std::array::from_fn(|_| None);
4832 self.pending_invoking_states.clear();
4833 self.precedence_stack.clear();
4834 self.precedence_stack.push(0);
4835 self.invoked_predicates.clear();
4836 self.decision_override_generation = 0;
4837 self.unknown_predicate_hits.clear();
4838 self.unhandled_action_hits.clear();
4839 self.reset_per_parse_caches();
4840 self.fast_first_set_prefilter = true;
4841 self.fast_recovery_enabled = true;
4842 self.fast_token_nodes_enabled = self.build_parse_trees;
4843 self.fast_track_alt_numbers = false;
4844 self.reset_recognition_arena();
4845 }
4846
4847 pub fn set_token_stream(&mut self, input: CommonTokenStream<S>) {
4849 self.input = input;
4850 self.reset();
4851 }
4852
4853 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
4864 self.unknown_predicate_policy = policy;
4865 }
4866
4867 #[must_use]
4873 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
4874 let error = self.unknown_semantic_error();
4875 self.unknown_predicate_hits.clear();
4876 self.unhandled_action_hits.clear();
4877 error
4878 }
4879
4880 pub fn reset_unknown_semantic_hits(&mut self) {
4887 self.unknown_predicate_hits.clear();
4888 self.unhandled_action_hits.clear();
4889 }
4890
4891 #[must_use]
4893 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
4894 &self.input
4895 }
4896
4897 #[must_use]
4899 pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<S> {
4900 &mut self.input
4901 }
4902
4903 #[must_use]
4905 pub const fn token_store(&self) -> &TokenStore {
4906 self.input.token_store()
4907 }
4908
4909 #[must_use]
4911 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
4912 &self.tree
4913 }
4914
4915 #[must_use]
4917 pub fn node(&self, id: NodeId) -> Node<'_> {
4918 self.tree
4919 .node(self.input.token_store(), id)
4920 .expect("parser-produced node ID should remain valid")
4921 }
4922
4923 #[must_use]
4925 pub fn into_token_stream(self) -> CommonTokenStream<S> {
4926 self.input
4927 }
4928
4929 #[must_use]
4931 pub fn into_token_store(self) -> TokenStore {
4932 self.input.into_token_store()
4933 }
4934
4935 #[must_use]
4937 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
4938 ParsedFile::new(self.input.into_token_store(), self.tree, root)
4939 }
4940
4941 pub const fn number_of_syntax_errors(&self) -> usize {
4944 self.syntax_errors
4945 }
4946
4947 #[must_use]
4953 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
4954 self.recognition_arena.stats(
4955 self.last_recognition_arena_root,
4956 self.last_recognition_arena_diagnostics,
4957 )
4958 }
4959
4960 pub const fn record_generated_syntax_error(&mut self) {
4963 self.record_syntax_errors(1);
4964 }
4965
4966 const fn record_syntax_errors(&mut self, count: usize) {
4967 self.syntax_errors = self.syntax_errors.saturating_add(count);
4968 }
4969
4970 pub fn report_token_source_errors(&mut self) {
4973 let errors = self.input.drain_source_errors();
4974 self.dispatch_token_source_errors(&errors);
4975 }
4976
4977 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
4980 GeneratedDiagnosticsCheckpoint {
4981 diagnostics_len: self.generated_parser_diagnostics.len(),
4982 syntax_errors: self.syntax_errors,
4983 tree: self.tree.checkpoint(),
4984 }
4985 }
4986
4987 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
4989 self.generated_parser_diagnostics
4990 .truncate(marker.diagnostics_len);
4991 self.syntax_errors = marker.syntax_errors;
4992 self.generated_sync_expected = None;
4993 self.tree.rollback(marker.tree);
4994 }
4995
4996 pub fn report_generated_parser_diagnostics(&mut self) {
4998 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
4999 let token_errors = self.input.drain_source_errors();
5000 self.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
5001 }
5002
5003 fn dispatch_parser_diagnostic(&self, diagnostic: &ParserDiagnostic) {
5004 self.notify_error_listeners(
5005 diagnostic.line,
5006 diagnostic.column,
5007 &diagnostic.message,
5008 None,
5009 );
5010 }
5011
5012 fn dispatch_parser_diagnostics<'a>(
5013 &self,
5014 diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>,
5015 ) {
5016 for diagnostic in diagnostics {
5017 self.dispatch_parser_diagnostic(diagnostic);
5018 }
5019 }
5020
5021 fn dispatch_token_source_error(&self, source_error: &TokenSourceError) {
5022 if self.input.token_source().report_error(source_error) {
5023 return;
5024 }
5025 self.notify_error_listeners(
5026 source_error.line,
5027 source_error.column,
5028 &source_error.message,
5029 None,
5030 );
5031 }
5032
5033 fn dispatch_token_source_errors(&self, errors: &[TokenSourceError]) {
5034 for error in errors {
5035 self.dispatch_token_source_error(error);
5036 }
5037 }
5038
5039 fn dispatch_generated_diagnostics(
5042 &self,
5043 parser_diagnostics: &[ParserDiagnostic],
5044 token_errors: &[TokenSourceError],
5045 ) {
5046 let mut token_iter = token_errors.iter().peekable();
5052 for diagnostic in parser_diagnostics {
5053 while let Some(error) = token_iter.peek() {
5054 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
5055 self.dispatch_token_source_error(error);
5056 token_iter.next();
5057 } else {
5058 break;
5059 }
5060 }
5061 self.dispatch_parser_diagnostic(diagnostic);
5062 }
5063 for error in token_iter {
5064 self.dispatch_token_source_error(error);
5065 }
5066 }
5067
5068 pub fn record_generated_ambiguity_diagnostic(
5071 &mut self,
5072 atn: &Atn,
5073 state_number: usize,
5074 start_index: usize,
5075 stop_index: usize,
5076 alts: &[usize],
5077 ) {
5078 if !self.report_diagnostic_errors || alts.len() < 2 {
5079 return;
5080 }
5081 let Some(decision) = atn
5082 .decision_to_state()
5083 .iter()
5084 .position(|candidate| candidate == state_number)
5085 else {
5086 return;
5087 };
5088 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5089 return;
5090 };
5091 let rule_name = self
5092 .rule_names()
5093 .get(rule_index)
5094 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5095 let input = display_input_text(&self.input.text(start_index, stop_index));
5096 let alts = alts
5097 .iter()
5098 .map(usize::to_string)
5099 .collect::<Vec<_>>()
5100 .join(", ");
5101 let key = (decision, start_index, format!("{alts}:{input}"));
5102 if !self.reported_prediction_diagnostics.insert(key) {
5103 return;
5104 }
5105 let start_diagnostic = diagnostic_for_token(
5106 self.token_at(start_index),
5107 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
5108 );
5109 let stop_diagnostic = diagnostic_for_token(
5110 self.token_at(stop_index),
5111 format!(
5112 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
5113 ),
5114 );
5115 self.generated_parser_diagnostics.push(start_diagnostic);
5116 self.generated_parser_diagnostics.push(stop_diagnostic);
5117 }
5118
5119 pub fn record_generated_prediction_diagnostic(
5122 &mut self,
5123 atn: &Atn,
5124 state_number: usize,
5125 prediction: &ParserAtnPrediction,
5126 ) {
5127 let Some(diagnostic) = &prediction.diagnostic else {
5128 return;
5129 };
5130 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5131 return;
5132 }
5133 let Some(decision) = atn
5134 .decision_to_state()
5135 .iter()
5136 .position(|candidate| candidate == state_number)
5137 else {
5138 return;
5139 };
5140 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5141 return;
5142 };
5143 let rule_name = self
5144 .rule_names()
5145 .get(rule_index)
5146 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5147 let attempt_input = display_input_text(
5148 &self
5149 .input
5150 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5151 );
5152 let result_input = display_input_text(
5153 &self
5154 .input
5155 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5156 );
5157 let alts = diagnostic
5158 .conflicting_alts
5159 .iter()
5160 .map(usize::to_string)
5161 .collect::<Vec<_>>()
5162 .join(", ");
5163 let key = (
5164 decision,
5165 diagnostic.start_index,
5166 format!(
5167 "{:?}:{alts}:{attempt_input}:{result_input}",
5168 diagnostic.kind
5169 ),
5170 );
5171 if !self.reported_prediction_diagnostics.insert(key) {
5172 return;
5173 }
5174 let attempt_diagnostic = diagnostic_for_token(
5175 self.token_at(diagnostic.sll_stop_index),
5176 format!(
5177 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5178 ),
5179 );
5180 self.generated_parser_diagnostics.push(attempt_diagnostic);
5181 let message = match diagnostic.kind {
5182 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5183 if !diagnostic.exact {
5188 return;
5189 }
5190 format!(
5191 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5192 )
5193 }
5194 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5195 format!(
5196 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5197 )
5198 }
5199 };
5200 let result_diagnostic =
5201 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5202 self.generated_parser_diagnostics.push(result_diagnostic);
5203 }
5204
5205 pub fn la(&self, offset: isize) -> i32 {
5206 self.input.la_token(offset)
5207 }
5208
5209 pub fn consume(&mut self) {
5210 IntStream::consume(&mut self.input);
5211 }
5212
5213 pub fn set_int_member(&mut self, member: usize, value: i64) {
5215 self.int_members.insert(member, value);
5216 }
5217
5218 pub fn int_member(&self, member: usize) -> Option<i64> {
5220 self.int_members.get(&member).copied()
5221 }
5222
5223 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
5226 self.int_members.clone()
5227 }
5228
5229 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
5231 self.int_members = members;
5232 }
5233
5234 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5236 let value = self.int_members.entry(member).or_default();
5237 *value += delta;
5238 *value
5239 }
5240
5241 fn token_type_for_id(&self, id: TokenId) -> i32 {
5242 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5243 }
5244
5245 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5246 if self.build_parse_trees {
5247 self.tree.terminal(id)
5248 } else {
5249 NodeId::placeholder()
5250 }
5251 }
5252
5253 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5254 if self.build_parse_trees {
5255 self.tree.error(id)
5256 } else {
5257 NodeId::placeholder()
5258 }
5259 }
5260
5261 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5262 context.set_start_id(id);
5263 }
5264
5265 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5266 context.set_stop_id(id);
5267 }
5268
5269 fn insert_synthetic_token(
5270 &mut self,
5271 token_type: i32,
5272 text: String,
5273 line: usize,
5274 column: usize,
5275 ) -> Result<TokenId, AntlrError> {
5276 self.input
5277 .insert(
5278 TokenSpec::explicit(token_type, text)
5279 .with_span(usize::MAX, usize::MAX)
5280 .with_byte_span(0, 0)
5281 .with_position(line, column),
5282 )
5283 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5284 }
5285
5286 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5293 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5294 line: 0,
5295 column: 0,
5296 message: "missing current token".to_owned(),
5297 })?;
5298 let current_type = self.token_type_for_id(current);
5299 if current_type == token_type {
5300 self.reset_generated_recovery_state();
5301 self.consume();
5302 Ok(self.terminal_tree(current))
5303 } else {
5304 Err(AntlrError::MismatchedInput {
5305 expected: self.vocabulary().display_name(token_type),
5306 found: self.vocabulary().display_name(current_type),
5307 })
5308 }
5309 }
5310
5311 pub fn match_token_recovering(
5315 &mut self,
5316 token_type: i32,
5317 follow_state: usize,
5318 atn: &Atn,
5319 ) -> Result<GeneratedMatch, AntlrError> {
5320 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5321 line: 0,
5322 column: 0,
5323 message: "missing current token".to_owned(),
5324 })?;
5325 let current_type = self.token_type_for_id(current);
5326 if current_type == token_type {
5327 self.generated_sync_expected = None;
5328 self.reset_generated_recovery_state();
5329 let consumed_eof = current_type == TOKEN_EOF;
5330 self.consume();
5331 return Ok(GeneratedMatch {
5332 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5333 consumed_eof,
5334 });
5335 }
5336 let mut expected_symbols = BTreeSet::new();
5337 expected_symbols.insert(token_type);
5338 self.recover_generated_match(
5339 current,
5340 GeneratedExpectedSymbols::Tree(&expected_symbols),
5341 follow_state,
5342 atn,
5343 |symbol| symbol == token_type,
5344 )
5345 }
5346
5347 pub fn match_set_recovering(
5348 &mut self,
5349 intervals: &[(i32, i32)],
5350 follow_state: usize,
5351 atn: &Atn,
5352 ) -> Result<GeneratedMatch, AntlrError> {
5353 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5354 line: 0,
5355 column: 0,
5356 message: "missing current token".to_owned(),
5357 })?;
5358 let current_type = self.token_type_for_id(current);
5359 if interval_set_contains(intervals, current_type) {
5360 self.generated_sync_expected = None;
5361 self.reset_generated_recovery_state();
5362 let consumed_eof = current_type == TOKEN_EOF;
5363 self.consume();
5364 return Ok(GeneratedMatch {
5365 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5366 consumed_eof,
5367 });
5368 }
5369 let expected_symbols = interval_symbols(intervals);
5370 self.recover_generated_match(
5371 current,
5372 GeneratedExpectedSymbols::Tree(&expected_symbols),
5373 follow_state,
5374 atn,
5375 |symbol| interval_set_contains(intervals, symbol),
5376 )
5377 }
5378
5379 pub fn match_token_set_recovering(
5380 &mut self,
5381 set: ParserIntervalSet<'_>,
5382 follow_state: usize,
5383 atn: &Atn,
5384 ) -> Result<GeneratedMatch, AntlrError> {
5385 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5386 line: 0,
5387 column: 0,
5388 message: "missing current token".to_owned(),
5389 })?;
5390 let current_type = self.token_type_for_id(current);
5391 if set.contains(current_type) {
5392 self.generated_sync_expected = None;
5393 self.reset_generated_recovery_state();
5394 let consumed_eof = current_type == TOKEN_EOF;
5395 self.consume();
5396 return Ok(GeneratedMatch {
5397 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5398 consumed_eof,
5399 });
5400 }
5401 self.recover_generated_match(
5402 current,
5403 GeneratedExpectedSymbols::TokenSet(set),
5404 follow_state,
5405 atn,
5406 |symbol| set.contains(symbol),
5407 )
5408 }
5409
5410 pub fn match_not_set_recovering(
5411 &mut self,
5412 intervals: &[(i32, i32)],
5413 min_vocabulary: i32,
5414 max_vocabulary: i32,
5415 follow_state: usize,
5416 atn: &Atn,
5417 ) -> Result<GeneratedMatch, AntlrError> {
5418 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5419 line: 0,
5420 column: 0,
5421 message: "missing current token".to_owned(),
5422 })?;
5423 let current_type = self.token_type_for_id(current);
5424 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5425 && !interval_set_contains(intervals, current_type)
5426 {
5427 self.generated_sync_expected = None;
5428 self.reset_generated_recovery_state();
5429 let consumed_eof = current_type == TOKEN_EOF;
5430 self.consume();
5431 return Ok(GeneratedMatch {
5432 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5433 consumed_eof,
5434 });
5435 }
5436 let expected_symbols =
5437 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
5438 self.recover_generated_match(
5439 current,
5440 GeneratedExpectedSymbols::Tree(&expected_symbols),
5441 follow_state,
5442 atn,
5443 |symbol| {
5444 (min_vocabulary..=max_vocabulary).contains(&symbol)
5445 && !interval_set_contains(intervals, symbol)
5446 },
5447 )
5448 }
5449
5450 pub fn match_not_token_set_recovering(
5451 &mut self,
5452 set: ParserIntervalSet<'_>,
5453 min_vocabulary: i32,
5454 max_vocabulary: i32,
5455 follow_state: usize,
5456 atn: &Atn,
5457 ) -> Result<GeneratedMatch, AntlrError> {
5458 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5459 line: 0,
5460 column: 0,
5461 message: "missing current token".to_owned(),
5462 })?;
5463 let current_type = self.token_type_for_id(current);
5464 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
5465 {
5466 self.generated_sync_expected = None;
5467 self.reset_generated_recovery_state();
5468 let consumed_eof = current_type == TOKEN_EOF;
5469 self.consume();
5470 return Ok(GeneratedMatch {
5471 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5472 consumed_eof,
5473 });
5474 }
5475 self.recover_generated_match(
5476 current,
5477 GeneratedExpectedSymbols::TokenSetComplement {
5478 set,
5479 min_vocabulary,
5480 max_vocabulary,
5481 },
5482 follow_state,
5483 atn,
5484 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
5485 )
5486 }
5487
5488 fn recover_generated_match(
5489 &mut self,
5490 current: TokenId,
5491 expected_symbols: GeneratedExpectedSymbols<'_>,
5492 follow_state: usize,
5493 atn: &Atn,
5494 matches: impl Fn(i32) -> bool,
5495 ) -> Result<GeneratedMatch, AntlrError> {
5496 let expected_display = expected_symbols.display(self.vocabulary());
5497 let (current_type, current_line, current_column, current_display) = {
5498 let token = self
5499 .input
5500 .token_view(current)
5501 .expect("current token ID should be valid");
5502 (
5503 token.token_type(),
5504 token.line(),
5505 token.column(),
5506 token_input_display(&token),
5507 )
5508 };
5509 if self.bail_on_error {
5510 return Err(AntlrError::ParserError {
5511 line: current_line,
5512 column: current_column,
5513 message: format!("mismatched input {current_display} expecting {expected_display}"),
5514 });
5515 }
5516 if current_type != TOKEN_EOF
5517 && let Some(next) = self.input.lt_id(2)
5518 && matches(self.token_type_for_id(next))
5519 {
5520 let message =
5521 format!("extraneous input {current_display} expecting {expected_display}");
5522 self.push_generated_parser_diagnostic(ParserDiagnostic {
5523 line: current_line,
5524 column: current_column,
5525 message,
5526 });
5527 self.record_syntax_errors(1);
5528 self.generated_sync_expected = None;
5529 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
5532 self.consume();
5533 self.consume();
5534 self.reset_generated_recovery_state();
5535 return Ok(GeneratedMatch {
5536 children: GeneratedMatchChildren::Many(vec![
5537 self.error_tree(current),
5538 self.terminal_tree(next),
5539 ]),
5540 consumed_eof,
5541 });
5542 }
5543 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
5544 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
5553 && self
5554 .cached_state_expected_symbols(atn, follow_state)
5555 .contains(&TOKEN_EOF);
5556 if follow_symbols.contains(¤t_type)
5557 && (current_type != TOKEN_EOF
5558 || self.rule_context_stack.len() > 1
5559 || expected_symbols.is_empty()
5560 || follow_explicitly_expects_eof)
5561 {
5562 let message = format!("missing {expected_display} at {current_display}");
5563 self.push_generated_parser_diagnostic(ParserDiagnostic {
5564 line: current_line,
5565 column: current_column,
5566 message,
5567 });
5568 self.record_syntax_errors(1);
5569 self.generated_sync_expected = None;
5570 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
5571 let missing_display = expected_symbol_display(token_type, self.vocabulary());
5572 let token = self.insert_synthetic_token(
5573 token_type,
5574 format!("<missing {missing_display}>"),
5575 current_line,
5576 current_column,
5577 )?;
5578 return Ok(GeneratedMatch {
5583 children: GeneratedMatchChildren::One(self.error_tree(token)),
5584 consumed_eof: false,
5585 });
5586 }
5587 let mismatch_expected_display = self
5588 .generated_sync_expected
5589 .take()
5590 .map_or(expected_display, |symbols| {
5591 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
5592 });
5593 Err(AntlrError::ParserError {
5594 line: current_line,
5595 column: current_column,
5596 message: format!(
5597 "mismatched input {current_display} expecting {mismatch_expected_display}"
5598 ),
5599 })
5600 }
5601
5602 fn generated_recovery_follow_symbols(
5603 &mut self,
5604 atn: &Atn,
5605 follow_state: usize,
5606 ) -> BTreeSet<i32> {
5607 let mut follow = self
5608 .cached_state_expected_symbols(atn, follow_state)
5609 .as_ref()
5610 .clone();
5611 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
5612 follow.extend(self.context_expected_symbols(atn));
5613 }
5614 follow
5615 }
5616
5617 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
5618 self.match_token(TOKEN_EOF)
5619 }
5620
5621 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
5622 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
5623 }
5624
5625 pub fn match_not_set(
5626 &mut self,
5627 intervals: &[(i32, i32)],
5628 min_vocabulary: i32,
5629 max_vocabulary: i32,
5630 ) -> Result<ParseTree, AntlrError> {
5631 self.match_interval_condition(intervals, |symbol| {
5632 (min_vocabulary..=max_vocabulary).contains(&symbol)
5633 && !interval_set_contains(intervals, symbol)
5634 })
5635 }
5636
5637 fn match_interval_condition(
5638 &mut self,
5639 intervals: &[(i32, i32)],
5640 matches: impl FnOnce(i32) -> bool,
5641 ) -> Result<ParseTree, AntlrError> {
5642 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5643 line: 0,
5644 column: 0,
5645 message: "missing current token".to_owned(),
5646 })?;
5647 let current_type = self.token_type_for_id(current);
5648 if matches(current_type) {
5649 self.reset_generated_recovery_state();
5650 self.consume();
5651 Ok(self.terminal_tree(current))
5652 } else {
5653 Err(AntlrError::MismatchedInput {
5654 expected: self.interval_display(intervals),
5655 found: self.vocabulary().display_name(current_type),
5656 })
5657 }
5658 }
5659
5660 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
5661 let values = intervals
5662 .iter()
5663 .map(|(start, stop)| {
5664 if start == stop {
5665 self.vocabulary().display_name(*start)
5666 } else {
5667 format!(
5668 "{}..{}",
5669 self.vocabulary().display_name(*start),
5670 self.vocabulary().display_name(*stop)
5671 )
5672 }
5673 })
5674 .collect::<Vec<_>>()
5675 .join(", ");
5676 format!("{{{values}}}")
5677 }
5678
5679 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
5680 if self.build_parse_trees {
5681 self.tree.finish_rule(context)
5682 } else {
5683 NodeId::placeholder()
5684 }
5685 }
5686
5687 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
5690 self.set_state(state);
5691 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
5692 self.rule_context_stack.push(RuleContextFrame {
5693 rule_index,
5694 invoking_state,
5695 });
5696 self.advance_rule_context_version();
5697 let start_index = self.current_visible_index();
5698 let mut context = ParserRuleContext::new(rule_index, invoking_state);
5699 if let Some(token) = self.token_id_at(start_index) {
5700 self.set_context_start(&mut context, token);
5701 }
5702 context
5703 }
5704
5705 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
5712 let marker = self.pending_invoking_states.len();
5713 self.pending_invoking_states.push(invoking_state);
5714 marker
5715 }
5716
5717 pub fn discard_invoking_state(&mut self, marker: usize) {
5719 self.pending_invoking_states.truncate(marker);
5720 }
5721
5722 pub fn exit_rule(&mut self) {
5724 self.rule_context_stack.pop();
5725 self.advance_rule_context_version();
5726 }
5727
5728 pub fn prediction_context_return_states<'a>(
5731 &'a self,
5732 atn: &'a Atn,
5733 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
5734 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
5735 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
5736 return None;
5737 };
5738 let Some(Transition::Rule { follow_state, .. }) = atn
5739 .state(state_number)
5740 .and_then(|state| state.transitions().first())
5741 .map(ParserTransition::data)
5742 else {
5743 return None;
5744 };
5745 Some(follow_state)
5746 })
5747 }
5748
5749 pub const fn rule_context_version(&self) -> usize {
5754 self.rule_context_version
5755 }
5756
5757 const fn advance_rule_context_version(&mut self) {
5758 self.rule_context_version = self.rule_context_version.wrapping_add(1);
5759 }
5760
5761 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
5766 if self.build_parse_trees {
5767 self.tree.add_child(context, child);
5768 } else {
5769 context.note_matched_child();
5770 }
5771 }
5772
5773 fn release_tree_scratch_if_idle(&mut self) {
5774 if self.rule_context_stack.is_empty() {
5775 self.tree.release_scratch();
5776 }
5777 }
5778
5779 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
5781 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5782 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5783 self.set_context_stop(&mut context, token);
5784 }
5785 let node = self.rule_node(context);
5786 self.exit_rule();
5787 self.release_tree_scratch_if_idle();
5788 node
5789 }
5790
5791 pub fn recover_generated_rule(
5798 &mut self,
5799 context: &mut ParserRuleContext,
5800 atn: &Atn,
5801 error: AntlrError,
5802 ) {
5803 let diagnostic = self.generated_rule_error_diagnostic(error);
5804 self.push_generated_parser_diagnostic(diagnostic);
5805 self.generated_sync_expected = None;
5806 let error_index = self.input.index();
5807 let error_state = self.data.state();
5808 if self.generated_recovery_error_index == Some(error_index)
5813 && self.generated_recovery_error_states.contains(&error_state)
5814 && self.la(1) != TOKEN_EOF
5815 && let Some(token) = self.input.lt_id(1)
5816 {
5817 self.consume();
5818 let child = self.error_tree(token);
5819 self.add_parse_child(context, child);
5820 }
5821 let recovery_index = self.input.index();
5822 if self.generated_recovery_error_index != Some(recovery_index) {
5823 self.generated_recovery_error_index = Some(recovery_index);
5824 self.generated_recovery_error_states.clear();
5825 }
5826 self.generated_recovery_error_states.insert(error_state);
5827 let recovery_symbols = self.context_expected_symbols(atn);
5828 loop {
5829 let symbol = self.la(1);
5830 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
5831 break;
5832 }
5833 let Some(token) = self.input.lt_id(1) else {
5834 break;
5835 };
5836 self.consume();
5837 let child = self.error_tree(token);
5838 self.add_parse_child(context, child);
5839 }
5840 self.record_syntax_errors(1);
5841 }
5842
5843 fn reset_generated_recovery_state(&mut self) {
5844 if self.generated_recovery_error_index.is_some() {
5845 self.generated_recovery_error_index = None;
5846 self.generated_recovery_error_states.clear();
5847 }
5848 }
5849
5850 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
5851 if self
5852 .generated_parser_diagnostics
5853 .iter()
5854 .any(|existing| existing == &diagnostic)
5855 {
5856 return;
5857 }
5858 self.generated_parser_diagnostics.push(diagnostic);
5859 }
5860
5861 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
5862 match error {
5863 AntlrError::ParserError {
5864 line,
5865 column,
5866 message,
5867 } => ParserDiagnostic {
5868 line,
5869 column,
5870 message,
5871 },
5872 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
5873 self.input.lt(1),
5874 format!("mismatched input {found} expecting {expected}"),
5875 ),
5876 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
5877 self.input.lt(1),
5878 format!("no viable alternative at input {input}"),
5879 ),
5880 AntlrError::LexerError {
5881 line,
5882 column,
5883 message,
5884 } => ParserDiagnostic {
5885 line,
5886 column,
5887 message,
5888 },
5889 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
5890 }
5891 }
5892
5893 pub fn finish_recursion_rule(
5895 &mut self,
5896 mut context: ParserRuleContext,
5897 consumed_eof: bool,
5898 ) -> ParseTree {
5899 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5900 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5901 self.set_context_stop(&mut context, token);
5902 }
5903 let node = self.rule_node(context);
5904 self.unroll_recursion_context();
5905 self.release_tree_scratch_if_idle();
5906 node
5907 }
5908
5909 pub fn enter_recursion_rule(
5911 &mut self,
5912 state: isize,
5913 rule_index: usize,
5914 precedence: i32,
5915 ) -> ParserRuleContext {
5916 self.precedence_stack.push(precedence);
5917 self.enter_rule(state, rule_index)
5918 }
5919
5920 pub fn push_new_recursion_context(
5922 &mut self,
5923 state: isize,
5924 rule_index: usize,
5925 ) -> ParserRuleContext {
5926 self.set_state(state);
5927 ParserRuleContext::new(rule_index, state)
5928 }
5929
5930 pub fn push_new_recursion_context_with_previous(
5933 &mut self,
5934 state: isize,
5935 rule_index: usize,
5936 current: &mut ParserRuleContext,
5937 ) {
5938 self.set_state(state);
5939 if let Some(stop) = self
5940 .rule_stop_token_index(self.input.index(), false)
5941 .and_then(|index| self.token_id_at(index))
5942 {
5943 self.set_context_stop(current, stop);
5944 }
5945 let invoking_state = current.invoking_state();
5946 let start = current.start_id();
5947 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
5948 if start.is_some() {
5949 replacement.set_start_from_context(current);
5950 }
5951 let previous = std::mem::replace(current, replacement);
5952 if self.build_parse_trees {
5953 let previous = self.rule_node(previous);
5954 self.tree.add_child(current, previous);
5955 }
5956 }
5957
5958 pub fn unroll_recursion_context(&mut self) {
5960 if self.precedence_stack.len() > 1 {
5961 self.precedence_stack.pop();
5962 }
5963 self.exit_rule();
5964 }
5965
5966 pub fn left_recursive_loop_enter_prediction(
5980 &mut self,
5981 atn: &Atn,
5982 state_number: usize,
5983 precedence: i32,
5984 ) -> Option<bool> {
5985 let symbol = self.la(1);
5986 if symbol == TOKEN_EOF {
5987 return Some(false);
5988 }
5989 let operator_lookahead =
5990 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
5991 let can_single = operator_lookahead.single_token.contains(symbol);
5992 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
5993 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
5994 if !can_single && !can_multi && !can_predicate {
5995 return Some(false);
5996 }
5997 if can_predicate && !can_single {
5998 return None;
5999 }
6000 if !can_single && can_multi && precedence > 0 {
6004 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
6005 if baseline.single_token.contains(symbol) {
6006 return None;
6007 }
6008 }
6009 let atn_key = SharedAtnCacheKey::for_atn(atn);
6010 let cached_overlap = self
6011 .left_recursive_caller_overlap_cache
6012 .iter()
6013 .flatten()
6014 .find(|entry| {
6015 entry.atn_key == atn_key
6016 && entry.state_number == state_number
6017 && entry.symbol == symbol
6018 && entry.context_version == self.rule_context_version
6019 })
6020 .map(|entry| entry.overlaps);
6021 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
6022 let overlaps = caller_context_can_match_symbol_before_state(
6023 atn,
6024 self.prediction_context_return_states(atn),
6025 state_number,
6026 symbol,
6027 );
6028 if let Some(slot) = self
6029 .left_recursive_caller_overlap_cache
6030 .iter_mut()
6031 .find(|slot| slot.is_none())
6032 {
6033 *slot = Some(LeftRecursiveCallerOverlap {
6034 atn_key,
6035 state_number,
6036 symbol,
6037 context_version: self.rule_context_version,
6038 overlaps,
6039 });
6040 }
6041 overlaps
6042 });
6043 if caller_overlaps {
6044 return None;
6045 }
6046 Some(true)
6047 }
6048
6049 fn cached_left_recursive_operator_lookahead(
6050 atn: &Atn,
6051 state_number: usize,
6052 precedence: i32,
6053 ) -> Rc<LeftRecursiveOperatorLookahead> {
6054 with_shared_atn_caches(atn, |cache| {
6055 let key = (state_number, precedence);
6056 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
6057 return Rc::clone(cached);
6058 }
6059 let lookahead = Rc::new(left_recursive_operator_lookahead(
6060 atn,
6061 state_number,
6062 precedence,
6063 ));
6064 cache
6065 .left_recursive_operator_lookahead
6066 .insert(key, Rc::clone(&lookahead));
6067 lookahead
6068 })
6069 }
6070
6071 pub fn left_recursive_loop_enter_matches(
6074 &mut self,
6075 atn: &Atn,
6076 state_number: usize,
6077 precedence: i32,
6078 ) -> bool {
6079 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
6080 }
6081
6082 pub fn precpred(&self, precedence: i32) -> bool {
6084 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
6085 }
6086
6087 pub fn parser_semantic_predicate_matches(
6090 &mut self,
6091 predicates: &[(usize, usize, ParserPredicate)],
6092 rule_index: usize,
6093 pred_index: usize,
6094 ) -> bool {
6095 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
6096 }
6097
6098 pub fn parser_semantic_predicate_matches_with_local(
6101 &mut self,
6102 predicates: &[(usize, usize, ParserPredicate)],
6103 rule_index: usize,
6104 pred_index: usize,
6105 local_int_arg: i32,
6106 ) -> bool {
6107 self.parser_semantic_predicate_matches_inner(
6108 predicates,
6109 rule_index,
6110 pred_index,
6111 Some((rule_index, i64::from(local_int_arg))),
6112 )
6113 }
6114
6115 fn parser_semantic_predicate_matches_inner(
6116 &mut self,
6117 predicates: &[(usize, usize, ParserPredicate)],
6118 rule_index: usize,
6119 pred_index: usize,
6120 local_int_arg: Option<(usize, i64)>,
6121 ) -> bool {
6122 let index = self.input.index();
6123 let member_values = self.int_members.clone();
6124 self.parser_predicate_matches(PredicateEval {
6125 index,
6126 rule_index,
6127 pred_index,
6128 predicates,
6129 semantics: None,
6130 context: None,
6131 local_int_arg,
6132 member_values: &member_values,
6133 })
6134 }
6135
6136 pub fn parser_semantic_predicate_matches_with_context_and_local(
6139 &mut self,
6140 predicates: &[(usize, usize, ParserPredicate)],
6141 rule_index: usize,
6142 pred_index: usize,
6143 context: &ParserRuleContext,
6144 local_int_arg: i32,
6145 ) -> bool {
6146 let index = self.input.index();
6147 let member_values = self.int_members.clone();
6148 self.parser_predicate_matches(PredicateEval {
6149 index,
6150 rule_index,
6151 pred_index,
6152 predicates,
6153 semantics: None,
6154 context: Some(context),
6155 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6156 member_values: &member_values,
6157 })
6158 }
6159
6160 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
6163 &mut self,
6164 semantics: &ParserSemantics,
6165 rule_index: usize,
6166 pred_index: usize,
6167 context: &ParserRuleContext,
6168 local_int_arg: i32,
6169 ) -> bool {
6170 let index = self.input.index();
6171 let member_values = self.int_members.clone();
6172 self.parser_predicate_matches(PredicateEval {
6173 index,
6174 rule_index,
6175 pred_index,
6176 predicates: &[],
6177 semantics: Some(semantics),
6178 context: Some(context),
6179 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6180 member_values: &member_values,
6181 })
6182 }
6183
6184 pub fn parser_semantic_predicate_failure_message(
6187 &self,
6188 rule_index: usize,
6189 pred_index: usize,
6190 predicates: &[(usize, usize, ParserPredicate)],
6191 ) -> Option<&'static str> {
6192 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
6193 }
6194
6195 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
6197 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6198 line: 0,
6199 column: 0,
6200 message: "missing current token".to_owned(),
6201 })?;
6202 if self.token_type_for_id(current) == TOKEN_EOF {
6203 return Err(AntlrError::MismatchedInput {
6204 expected: "wildcard".to_owned(),
6205 found: self.vocabulary().display_name(TOKEN_EOF),
6206 });
6207 }
6208 self.reset_generated_recovery_state();
6209 self.consume();
6210 Ok(self.terminal_tree(current))
6211 }
6212
6213 #[allow(clippy::unnecessary_wraps)]
6217 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
6218 self.set_state(state);
6219 Ok(())
6220 }
6221
6222 pub fn sync_decision(
6230 &mut self,
6231 atn: &Atn,
6232 state_number: usize,
6233 current_context_empty: bool,
6234 loop_back: bool,
6235 ) -> Result<Vec<ParseTree>, AntlrError> {
6236 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
6237 self.generated_sync_expected = None;
6238 let Some(state) = atn.state(state_number) else {
6239 return Ok(Vec::new());
6240 };
6241 let Some(rule_index) = state.rule_index() else {
6242 return Ok(Vec::new());
6243 };
6244 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
6245 return Ok(Vec::new());
6246 };
6247 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6248 let symbol = self.la(1);
6249 let mut has_expected_symbols = false;
6250 let mut nullable = false;
6251 let mut explicit_eof_expected = false;
6259 for transition in &entry.transitions {
6260 if transition.symbols.contains(symbol) {
6261 return Ok(Vec::new());
6262 }
6263 has_expected_symbols |= !transition.symbols.is_empty();
6264 nullable |= transition.nullable;
6265 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
6266 }
6267 if nullable && self.context_expected_contains(atn, symbol) {
6272 return Ok(Vec::new());
6273 }
6274 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
6275 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
6276 return Ok(Vec::new());
6277 }
6278 let mut expected = TokenBitSet::default();
6279 for transition in &entry.transitions {
6280 expected.extend_from(&transition.symbols);
6281 }
6282 if let Some(context_expected) = context_expected {
6283 expected.extend_from(&context_expected);
6284 }
6285 let can_delete_in_place =
6286 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
6287 let loop_sync = loop_back;
6304 if symbol != TOKEN_EOF && can_delete_in_place {
6305 let mut cursor = self.input.index();
6306 let mut skipped = Vec::new();
6307 loop {
6308 let current = self.token_type_at(cursor);
6309 if current == TOKEN_EOF {
6310 break;
6311 }
6312 skipped.push(cursor);
6313 let next = self.consume_index(cursor, current);
6314 if next == cursor {
6315 break;
6316 }
6317 let next_symbol = self.token_type_at(next);
6318 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
6326 explicit_eof_expected
6327 } else {
6328 expected.contains(next_symbol)
6329 };
6330 if next_is_expected_stop {
6331 let current_token = self.input.lt(1);
6332 let expected_symbols = expected.to_btree_set();
6333 let message = format!(
6334 "extraneous input {} expecting {}",
6335 current_token
6336 .as_ref()
6337 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6338 self.expected_symbols_display(&expected_symbols)
6339 );
6340 self.push_generated_parser_diagnostic(diagnostic_for_token(
6341 current_token,
6342 message,
6343 ));
6344 self.record_syntax_errors(1);
6345 let mut children = Vec::with_capacity(skipped.len());
6346 for index in skipped {
6347 if let Some(token) = self.token_id_at(index) {
6348 self.consume();
6349 children.push(self.error_tree(token));
6350 }
6351 }
6352 if !loop_sync {
6353 self.reset_generated_recovery_state();
6354 }
6355 return Ok(children);
6356 }
6357 if !loop_sync {
6361 break;
6362 }
6363 cursor = next;
6364 }
6365 }
6366 if nullable {
6367 self.generated_sync_expected = Some(expected);
6368 return Ok(Vec::new());
6369 }
6370 let current = self.input.lt(1);
6371 let expected_symbols = expected.to_btree_set();
6372 Err(AntlrError::ParserError {
6373 line: current.as_ref().map(Token::line).unwrap_or_default(),
6374 column: current.as_ref().map(Token::column).unwrap_or_default(),
6375 message: format!(
6376 "mismatched input {} expecting {}",
6377 current
6378 .as_ref()
6379 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6380 self.expected_symbols_display(&expected_symbols)
6381 ),
6382 })
6383 }
6384
6385 pub fn ll1_decision_prediction(
6392 &mut self,
6393 atn: &Atn,
6394 state_number: usize,
6395 ) -> Option<ParserAtnPrediction> {
6396 let state = atn.state(state_number)?;
6397 if state.precedence_rule_decision() {
6398 return None;
6399 }
6400 let rule_stop = state
6401 .rule_index()
6402 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
6403 let symbol = self.la(1);
6404 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6405 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
6406 alt: alt + 1,
6407 requires_full_context: false,
6408 has_semantic_context: false,
6409 diagnostic: None,
6410 })
6411 }
6412
6413 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
6414 let mut expected = BTreeSet::new();
6415 for index in (1..self.rule_context_stack.len()).rev() {
6416 let invoking_state = self.rule_context_stack[index].invoking_state;
6417 let Ok(state_number) = usize::try_from(invoking_state) else {
6418 continue;
6419 };
6420 let Some(Transition::Rule { follow_state, .. }) = atn
6421 .state(state_number)
6422 .and_then(|state| state.transitions().first())
6423 .map(ParserTransition::data)
6424 else {
6425 continue;
6426 };
6427 let return_state = follow_state;
6428 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
6429 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
6430 return expected;
6431 }
6432 }
6433 expected.insert(TOKEN_EOF);
6434 expected
6435 }
6436
6437 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
6438 let mut expected = TokenBitSet::default();
6439 for index in (1..self.rule_context_stack.len()).rev() {
6440 let invoking_state = self.rule_context_stack[index].invoking_state;
6441 let Ok(state_number) = usize::try_from(invoking_state) else {
6442 continue;
6443 };
6444 let Some(Transition::Rule { follow_state, .. }) = atn
6445 .state(state_number)
6446 .and_then(|state| state.transitions().first())
6447 .map(ParserTransition::data)
6448 else {
6449 continue;
6450 };
6451 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
6452 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6453 return expected;
6454 }
6455 }
6456 expected.insert(TOKEN_EOF);
6457 expected
6458 }
6459
6460 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
6471 for index in (1..self.rule_context_stack.len()).rev() {
6472 let invoking_state = self.rule_context_stack[index].invoking_state;
6473 let Ok(state_number) = usize::try_from(invoking_state) else {
6474 continue;
6475 };
6476 let Some(Transition::Rule { follow_state, .. }) = atn
6477 .state(state_number)
6478 .and_then(|state| state.transitions().first())
6479 .map(ParserTransition::data)
6480 else {
6481 continue;
6482 };
6483 if self
6484 .cached_state_expected_token_set(atn, follow_state)
6485 .contains(symbol)
6486 {
6487 return true;
6488 }
6489 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6490 return false;
6491 }
6492 }
6493 symbol == TOKEN_EOF
6494 }
6495
6496 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
6498 let error_index = self.input.index();
6499 self.no_viable_alternative_error_at(start_index, error_index)
6500 }
6501
6502 pub fn no_viable_alternative_error_at(
6507 &self,
6508 start_index: usize,
6509 error_index: usize,
6510 ) -> AntlrError {
6511 let diagnostic = self.no_viable_alternative(start_index, error_index);
6512 AntlrError::ParserError {
6513 line: diagnostic.line,
6514 column: diagnostic.column,
6515 message: diagnostic.message,
6516 }
6517 }
6518
6519 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
6521 let current = self.input.lt(1);
6522 AntlrError::ParserError {
6523 line: current.as_ref().map(Token::line).unwrap_or_default(),
6524 column: current.as_ref().map(Token::column).unwrap_or_default(),
6525 message: format!("rule failed predicate: {}", message.into()),
6526 }
6527 }
6528
6529 pub fn failed_predicate_option_error(
6532 &self,
6533 rule_index: usize,
6534 message: impl Into<String>,
6535 ) -> AntlrError {
6536 let current = self.input.lt(1);
6537 let rule_name = self
6538 .rule_names()
6539 .get(rule_index)
6540 .map_or_else(|| rule_index.to_string(), Clone::clone);
6541 AntlrError::ParserError {
6542 line: current.as_ref().map(Token::line).unwrap_or_default(),
6543 column: current.as_ref().map(Token::column).unwrap_or_default(),
6544 message: format!("rule {rule_name} {}", message.into()),
6545 }
6546 }
6547
6548 pub fn parser_action_at_current(
6550 &mut self,
6551 source_state: usize,
6552 rule_index: usize,
6553 start_index: usize,
6554 consumed_eof: bool,
6555 ) -> ParserAction {
6556 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6557 ParserAction::new(source_state, rule_index, start_index, stop_index)
6558 }
6559
6560 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
6565 let rule_index = action.rule_index();
6566 let rule_name = self.rule_names().get(rule_index).cloned();
6567 let context = None;
6568 let input = &mut self.input;
6569 let semantic_hooks = &mut self.semantic_hooks;
6570 let member_values = &self.int_members;
6571 let mut ctx = ParserSemCtx {
6572 input,
6573 tree_storage: &self.tree,
6574 rule_index,
6575 coordinate_index: usize::MAX,
6576 rule_name,
6577 context,
6578 tree: Some(tree),
6579 local_int_arg: None,
6580 member_values,
6581 action: Some(action),
6582 };
6583 let handled = semantic_hooks.action(&mut ctx, action);
6584 if !handled && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error) {
6590 let coordinate = (rule_index, action.source_state());
6591 if !self.unhandled_action_hits.contains(&coordinate) {
6592 self.unhandled_action_hits.push(coordinate);
6593 }
6594 }
6595 handled
6596 }
6597
6598 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
6603 &mut self,
6604 atn: &'atn Atn,
6605 simulator: &mut ParserAtnSimulator<'atn>,
6606 rule_index: usize,
6607 ) -> Result<ParseTree, AntlrError> {
6608 let start_index = self.current_visible_index();
6609 self.clear_prediction_diagnostics();
6610 self.reset_per_parse_caches();
6611 self.reset_recognition_arena();
6612 let tree_checkpoint = self.tree.checkpoint();
6613 let mut decision_by_state = vec![None; atn.states().len()];
6614 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
6615 if let Some(slot) = decision_by_state.get_mut(state_number) {
6616 *slot = Some(decision);
6617 }
6618 }
6619
6620 let result = DirectAdaptiveParser {
6621 parser: self,
6622 atn,
6623 simulator,
6624 decision_by_state,
6625 steps: 0,
6626 }
6627 .parse_rule(rule_index, -1, 0);
6628
6629 match result {
6630 Ok(tree) => {
6631 self.report_token_source_errors();
6632 self.release_tree_scratch_if_idle();
6633 Ok(tree)
6634 }
6635 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
6636 let _ = reason;
6637 self.tree.rollback(tree_checkpoint);
6638 self.input.seek(start_index);
6639 self.parse_atn_rule(atn, rule_index)
6640 }
6641 }
6642 }
6643
6644 pub fn parse_atn_rule(
6654 &mut self,
6655 atn: &Atn,
6656 rule_index: usize,
6657 ) -> Result<ParseTree, AntlrError> {
6658 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
6659 }
6660
6661 pub fn parse_atn_rule_with_precedence(
6664 &mut self,
6665 atn: &Atn,
6666 rule_index: usize,
6667 precedence: i32,
6668 ) -> Result<ParseTree, AntlrError> {
6669 self.parse_atn_rule_with_precedence_inner(
6670 atn,
6671 rule_index,
6672 precedence,
6673 None,
6674 AltNumberTracking::default(),
6675 )
6676 }
6677
6678 fn parse_atn_rule_with_precedence_inner(
6679 &mut self,
6680 atn: &Atn,
6681 rule_index: usize,
6682 precedence: i32,
6683 predicate_context: Option<FastPredicateContext<'_>>,
6684 alt_tracking: AltNumberTracking,
6685 ) -> Result<ParseTree, AntlrError> {
6686 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
6687 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
6688 })?;
6689 let stop_state = atn
6690 .rule_to_stop_state()
6691 .get(rule_index)
6692 .filter(|state| *state != usize::MAX)
6693 .ok_or_else(|| {
6694 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
6695 })?;
6696
6697 let start_index = self.current_visible_index();
6698 self.clear_prediction_diagnostics();
6699 self.reset_per_parse_caches();
6700 self.reset_recognition_arena();
6701 let caller_follow_state = self.pending_invoking_follow_state(atn);
6702 self.fast_recovery_enabled = false;
6703 self.fast_token_nodes_enabled = false;
6704 self.fast_track_alt_numbers = alt_tracking.any();
6705 let top_request = FastRecognizeTopRequest {
6706 start_state,
6707 stop_state,
6708 start_index,
6709 precedence,
6710 caller_follow_state,
6711 };
6712 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
6713 self.fast_token_nodes_enabled = self.build_parse_trees;
6714 let needs_tree_retry = matches!(
6715 &first_pass,
6716 Ok((outcome, _, _))
6717 if self.build_parse_trees
6718 && self
6719 .recognition_arena
6720 .sequence_has_left_recursive_boundary(outcome.nodes)
6721 );
6722 let needs_retry = match &first_pass {
6723 Err(_) => true,
6736 Ok((outcome, _, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
6737 };
6738 let (outcome, _expected, alt_number) = if needs_retry {
6739 self.fast_first_set_prefilter = false;
6740 self.fast_recovery_enabled = false;
6741 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6742 let clean_selected = if needs_tree_retry {
6743 match clean_retry {
6744 ok @ Ok(_) => ok,
6745 Err(_) => first_pass,
6746 }
6747 } else {
6748 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
6749 };
6750 let selected = if clean_selected.is_err()
6751 || matches!(&clean_selected, Ok((outcome, _, _)) if !outcome.diagnostics.is_empty())
6752 {
6753 self.fast_recovery_enabled = true;
6754 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6755 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
6756 } else {
6757 clean_selected
6758 };
6759 self.fast_first_set_prefilter = true;
6760 self.fast_recovery_enabled = true;
6761 selected.map_err(|expected| {
6762 if predicate_context.is_some()
6763 && let Some(error) = self.unknown_semantic_error()
6764 {
6765 self.report_token_source_errors();
6766 return error;
6767 }
6768 let error = self.recognition_error(rule_index, start_index, &expected);
6769 self.record_syntax_errors(1);
6770 self.report_token_source_errors();
6771 error
6772 })?
6773 } else {
6774 first_pass.expect("first_pass is Ok in the no-retry branch")
6775 };
6776 if predicate_context.is_some()
6777 && let Some(error) = self.unknown_semantic_error()
6778 {
6779 self.report_token_source_errors();
6780 return Err(error);
6781 }
6782 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
6783 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
6784 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
6785 self.report_token_source_errors();
6786 let mut context = ParserRuleContext::with_child_capacity(
6787 rule_index,
6788 self.state(),
6789 if self.build_parse_trees {
6790 self.recognition_arena.sequence_len(outcome.nodes)
6791 } else {
6792 0
6793 },
6794 );
6795 if alt_tracking.public {
6796 context.set_alt_number(alt_number);
6797 }
6798 if alt_tracking.context {
6799 context.set_context_alt_number(alt_number);
6800 }
6801 if let Some(token) = self.token_id_at(start_index) {
6802 self.set_context_start(&mut context, token);
6803 }
6804 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
6805 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
6806 self.set_context_stop(&mut context, token);
6807 }
6808 let live_root = if self.build_parse_trees {
6809 self.recognition_arena
6810 .fold_left_recursive_boundaries(outcome.nodes)
6811 } else {
6812 outcome.nodes
6813 };
6814 if self.build_parse_trees {
6815 if self
6816 .recognition_arena
6817 .sequence_has_explicit_token(live_root)
6818 {
6819 let mut cursor = live_root;
6820 while let Some(link) = self.recognition_arena.link(cursor) {
6821 let child = self.arena_recognized_node_tree(
6822 link.head,
6823 alt_tracking.public,
6824 alt_tracking.context,
6825 )?;
6826 self.tree.add_child(&mut context, child);
6827 cursor = link.tail;
6828 }
6829 } else {
6830 self.add_arena_implicit_token_children(
6831 &mut context,
6832 start_index,
6833 stop_index,
6834 live_root,
6835 alt_tracking,
6836 )?;
6837 }
6838 }
6839 self.finish_recognition_arena(live_root, outcome.diagnostics);
6840 self.input.seek(outcome.index);
6841
6842 let tree = self.rule_node(context);
6843 self.release_tree_scratch_if_idle();
6844 Ok(tree)
6845 }
6846
6847 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
6848 let invoking_state = self.pending_invoking_states.last().copied()?;
6849 let state_number = usize::try_from(invoking_state).ok()?;
6850 match atn.state(state_number)?.transitions().first()?.data() {
6851 Transition::Rule { follow_state, .. } => Some(follow_state),
6852 _ => None,
6853 }
6854 }
6855
6856 #[cfg(test)]
6857 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
6858 caller_follow_token_info_for_stream(&mut self.input, index)
6859 }
6860
6861 fn fast_recognize_top(
6866 &mut self,
6867 atn: &Atn,
6868 request: FastRecognizeTopRequest,
6869 predicate_context: Option<FastPredicateContext<'_>>,
6870 ) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
6871 let FastRecognizeTopRequest {
6872 start_state,
6873 stop_state,
6874 start_index,
6875 precedence,
6876 caller_follow_state,
6877 } = request;
6878 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
6887 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
6888 recognize_scratch.prepare(memo_capacity);
6889 let mut expected = ExpectedTokens::default();
6890 let empty_recovery = self.empty_recovery_symbols();
6891 let outcomes = self.recognize_state_fast(
6892 atn,
6893 FastRecognizeRequest {
6894 state_number: start_state,
6895 stop_state,
6896 index: start_index,
6897 rule_start_index: start_index,
6898 decision_start_index: None,
6899 precedence,
6900 depth: 0,
6901 recovery_symbols: empty_recovery,
6902 recovery_state: None,
6903 },
6904 FastRecognizeScratch {
6905 predicate_context,
6906 visiting: &mut recognize_scratch.visiting,
6907 memo: &mut recognize_scratch.memo,
6908 expected: &mut expected,
6909 native_depth: 0,
6910 },
6911 );
6912 recognize_scratch.release_oversized_memo();
6913 self.fast_recognize_scratch = recognize_scratch;
6914 #[cfg(feature = "perf-counters")]
6915 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
6916 perf_counters::dump();
6917 perf_counters::reset();
6918 }
6919 let caller_follow =
6920 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
6921 let selected = {
6922 let arena = &self.recognition_arena;
6923 let input = &mut self.input;
6924 select_best_fast_outcome(
6925 outcomes.into_iter(),
6926 self.prediction_mode,
6927 caller_follow.as_deref(),
6928 |index| caller_follow_token_info_for_stream(input, index),
6929 arena,
6930 )
6931 };
6932 match selected {
6933 Some(mut outcome) => {
6934 let alt_number = if self.build_parse_trees || self.fast_track_alt_numbers {
6935 self.materialize_fast_outcome_nodes(&mut outcome)
6936 } else {
6937 0
6938 };
6939 Ok((outcome, expected, alt_number))
6940 }
6941 None => Err(expected),
6942 }
6943 }
6944
6945 fn arena_recognized_node_tree(
6947 &mut self,
6948 node_id: RecognizedNodeId,
6949 track_alt_numbers: bool,
6950 track_context_alt_numbers: bool,
6951 ) -> Result<ParseTree, AntlrError> {
6952 let node = self.recognition_arena.node(node_id);
6953 match node {
6954 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
6955 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
6956 ArenaRecognizedNode::MissingToken { extra } => {
6957 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
6958 RecognitionExtra::MissingToken {
6959 token_type,
6960 at_index,
6961 text,
6962 } => (*token_type, *at_index as usize, text.clone()),
6963 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
6964 unreachable!("missing-token node must reference missing-token extra")
6965 }
6966 };
6967 let (line, column) = self
6968 .token_at(at_index)
6969 .map_or((0, 0), |token| (token.line(), token.column()));
6970 let token = self.insert_synthetic_token(token_type, text, line, column)?;
6971 Ok(self.error_tree(token))
6972 }
6973 ArenaRecognizedNode::Rule {
6974 rule_index,
6975 invoking_state,
6976 alt_number,
6977 start_index,
6978 stop_index,
6979 return_values,
6980 children,
6981 } => {
6982 let mut context = ParserRuleContext::with_child_capacity(
6983 rule_index as usize,
6984 invoking_state as isize,
6985 self.recognition_arena.sequence_len(children),
6986 );
6987 if track_alt_numbers {
6988 context.set_alt_number(alt_number as usize);
6989 }
6990 if track_context_alt_numbers {
6991 context.set_context_alt_number(alt_number as usize);
6992 }
6993 if let Some(extra) = return_values {
6994 let RecognitionExtra::ReturnValues(values) =
6995 self.recognition_arena.extra(extra)
6996 else {
6997 unreachable!("rule node must reference return-values extra");
6998 };
6999 for (name, value) in values {
7000 context.set_int_return(name.clone(), *value);
7001 }
7002 }
7003 if let Some(token) = self.token_id_at(start_index as usize) {
7004 self.set_context_start(&mut context, token);
7005 }
7006 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7007 self.set_context_stop(&mut context, token);
7008 }
7009 let mut cursor = self
7010 .recognition_arena
7011 .fold_left_recursive_boundaries(children);
7012 while let Some(link) = self.recognition_arena.link(cursor) {
7013 let child = self.arena_recognized_node_tree(
7014 link.head,
7015 track_alt_numbers,
7016 track_context_alt_numbers,
7017 )?;
7018 self.tree.add_child(&mut context, child);
7019 cursor = link.tail;
7020 }
7021 Ok(self.rule_node(context))
7022 }
7023 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index, .. } => {
7024 Err(AntlrError::Unsupported(format!(
7025 "unfolded left-recursive boundary for rule {rule_index}"
7026 )))
7027 }
7028 }
7029 }
7030
7031 fn arena_recognized_node_tree_with_implicit_tokens(
7032 &mut self,
7033 node_id: RecognizedNodeId,
7034 alt_tracking: AltNumberTracking,
7035 ) -> Result<ParseTree, AntlrError> {
7036 let node = self.recognition_arena.node(node_id);
7037 match node {
7038 ArenaRecognizedNode::Rule {
7039 rule_index,
7040 invoking_state,
7041 alt_number,
7042 start_index,
7043 stop_index,
7044 children,
7045 ..
7046 } => {
7047 let mut context = ParserRuleContext::with_child_capacity(
7048 rule_index as usize,
7049 invoking_state as isize,
7050 self.recognition_arena.sequence_len(children),
7051 );
7052 if alt_tracking.public {
7053 context.set_alt_number(alt_number as usize);
7054 }
7055 if alt_tracking.context {
7056 context.set_context_alt_number(alt_number as usize);
7057 }
7058 if let Some(token) = self.token_id_at(start_index as usize) {
7059 self.set_context_start(&mut context, token);
7060 }
7061 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7062 self.set_context_stop(&mut context, token);
7063 }
7064 let children = self
7065 .recognition_arena
7066 .fold_left_recursive_boundaries(children);
7067 self.add_arena_implicit_token_children(
7068 &mut context,
7069 start_index as usize,
7070 stop_index.map(|index| index as usize),
7071 children,
7072 alt_tracking,
7073 )?;
7074 Ok(self.rule_node(context))
7075 }
7076 _ => {
7077 self.arena_recognized_node_tree(node_id, alt_tracking.public, alt_tracking.context)
7078 }
7079 }
7080 }
7081
7082 fn add_arena_implicit_token_children(
7083 &mut self,
7084 context: &mut ParserRuleContext,
7085 start_index: usize,
7086 stop_index: Option<usize>,
7087 mut children: NodeSeqId,
7088 alt_tracking: AltNumberTracking,
7089 ) -> Result<(), AntlrError> {
7090 let mut cursor = Some(start_index);
7091 while let Some(link) = self.recognition_arena.link(children) {
7092 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
7093 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
7094 let child =
7095 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7096 self.tree.add_child(context, child);
7097 if let Some(child_stop) = child_stop {
7098 cursor = self.next_visible_after_token(child_stop);
7099 }
7100 } else {
7101 let child =
7102 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7103 self.tree.add_child(context, child);
7104 }
7105 children = link.tail;
7106 }
7107 if let Some(stop) = stop_index {
7108 self.add_visible_terminals_through(context, cursor, stop)?;
7109 }
7110 Ok(())
7111 }
7112
7113 fn add_visible_terminals_before(
7114 &mut self,
7115 context: &mut ParserRuleContext,
7116 cursor: &mut Option<usize>,
7117 before: usize,
7118 ) -> Result<(), AntlrError> {
7119 let Some(stop) = before.checked_sub(1) else {
7120 return Ok(());
7121 };
7122 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
7123 *cursor = next;
7124 Ok(())
7125 }
7126
7127 fn add_visible_terminals_through(
7128 &mut self,
7129 context: &mut ParserRuleContext,
7130 mut cursor: Option<usize>,
7131 stop: usize,
7132 ) -> Result<Option<usize>, AntlrError> {
7133 while let Some(index) = cursor {
7134 if index > stop {
7135 return Ok(Some(index));
7136 }
7137 let token = self
7138 .input
7139 .get_id(index)
7140 .ok_or_else(|| AntlrError::ParserError {
7141 line: 0,
7142 column: 0,
7143 message: format!("missing token at index {index}"),
7144 })?;
7145 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
7146 let child = self.terminal_tree(token);
7147 self.tree.add_child(context, child);
7148 if is_eof {
7149 return Ok(None);
7150 }
7151 cursor = self.next_visible_after_token(index);
7152 }
7153 Ok(None)
7154 }
7155
7156 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
7157 let next = self.input.next_visible_after(index);
7158 (next != index).then_some(next)
7159 }
7160
7161 pub fn parse_atn_rule_with_actions(
7168 &mut self,
7169 atn: &Atn,
7170 rule_index: usize,
7171 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7172 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
7173 }
7174
7175 pub fn parse_atn_rule_with_action_inits(
7183 &mut self,
7184 atn: &Atn,
7185 rule_index: usize,
7186 init_action_rules: &[usize],
7187 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7188 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
7189 }
7190
7191 pub fn parse_atn_rule_with_action_options(
7197 &mut self,
7198 atn: &Atn,
7199 rule_index: usize,
7200 init_action_rules: &[usize],
7201 track_alt_numbers: bool,
7202 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7203 self.parse_atn_rule_with_runtime_options(
7204 atn,
7205 rule_index,
7206 ParserRuntimeOptions {
7207 init_action_rules,
7208 track_alt_numbers,
7209 ..ParserRuntimeOptions::default()
7210 },
7211 )
7212 }
7213
7214 pub fn parse_atn_rule_with_runtime_options(
7221 &mut self,
7222 atn: &Atn,
7223 rule_index: usize,
7224 options: ParserRuntimeOptions<'_>,
7225 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7226 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
7227 }
7228
7229 pub fn parse_atn_rule_with_runtime_options_and_precedence(
7232 &mut self,
7233 atn: &Atn,
7234 rule_index: usize,
7235 precedence: i32,
7236 options: ParserRuntimeOptions<'_>,
7237 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7238 let ParserRuntimeOptions {
7239 init_action_rules,
7240 track_alt_numbers,
7241 track_context_alt_numbers,
7242 predicates,
7243 semantics,
7244 rule_args,
7245 member_actions,
7246 return_actions,
7247 unknown_predicate_policy,
7248 } = options;
7249 let capture_alt_numbers = track_alt_numbers || track_context_alt_numbers;
7250 if init_action_rules.is_empty()
7251 && !capture_alt_numbers
7252 && predicates.is_empty()
7253 && semantics.is_none()
7254 && rule_args.is_empty()
7255 && member_actions.is_empty()
7256 && return_actions.is_empty()
7257 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
7258 && !atn_has_observable_action_transitions(atn)
7259 && !self.semantic_hooks.observes_parser_decisions()
7260 && (!self.semantic_hooks.observes_parser_predicates()
7261 || !atn_has_predicate_transitions(atn))
7262 {
7263 return self
7264 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
7265 .map(|tree| (tree, Vec::new()));
7266 }
7267 if !self.semantic_hooks.observes_parser_decisions()
7268 && can_use_fast_predicate_recognizer(atn, &options)
7269 {
7270 self.unknown_predicate_policy = unknown_predicate_policy;
7271 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7272 let member_values = self.int_members.clone();
7273 let result = self
7274 .parse_atn_rule_with_precedence_inner(
7275 atn,
7276 rule_index,
7277 precedence,
7278 Some(FastPredicateContext {
7279 predicates,
7280 semantics,
7281 member_values: &member_values,
7282 }),
7283 AltNumberTracking {
7284 public: track_alt_numbers,
7285 context: track_context_alt_numbers,
7286 },
7287 )
7288 .map(|tree| (tree, Vec::new()));
7289 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
7290 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7291 }
7292 return result;
7293 }
7294 self.unknown_predicate_policy = unknown_predicate_policy;
7295 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7302 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7303 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7304 })?;
7305 let stop_state = atn
7306 .rule_to_stop_state()
7307 .get(rule_index)
7308 .filter(|state| *state != usize::MAX)
7309 .ok_or_else(|| {
7310 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7311 })?;
7312
7313 let start_index = self.current_visible_index();
7314 self.clear_prediction_diagnostics();
7315 self.reset_per_parse_caches();
7316 self.reset_recognition_arena();
7317 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
7318 let invoking_state = self.pending_invoking_states.pop();
7319 let local_int_arg = invoking_state
7320 .and_then(|state| usize::try_from(state).ok())
7321 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
7322 let mut visiting = BTreeSet::new();
7323 let mut memo = BTreeMap::new();
7324 let mut expected = ExpectedTokens::default();
7325 let member_values = self.int_members.clone();
7326 let return_values = BTreeMap::new();
7327 let outcomes = self.recognize_state(
7328 atn,
7329 RecognizeRequest {
7330 state_number: start_state,
7331 stop_state,
7332 index: start_index,
7333 rule_start_index: start_index,
7334 decision_start_index: None,
7335 init_action_rules: &init_action_rules,
7336 predicates,
7337 semantics,
7338 rule_args,
7339 member_actions,
7340 return_actions,
7341 local_int_arg,
7342 member_values,
7343 return_values,
7344 rule_alt_number: 0,
7345 track_alt_numbers: capture_alt_numbers,
7346 consumed_eof: false,
7347 committed_decision: false,
7348 precedence,
7349 depth: 0,
7350 recovery_symbols: BTreeSet::new(),
7351 recovery_state: None,
7352 },
7353 &mut visiting,
7354 &mut memo,
7355 &mut expected,
7356 );
7357 if let Some(error) = self.unknown_semantic_error() {
7358 self.report_token_source_errors();
7359 return Err(error);
7366 }
7367 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7370 let Some(outcome) = select_best_outcome(
7371 outcomes.into_iter(),
7372 self.prediction_mode,
7373 &self.recognition_arena,
7374 ) else {
7375 let error = self.recognition_error(rule_index, start_index, &expected);
7376 self.record_syntax_errors(1);
7377 self.report_token_source_errors();
7378 return Err(error);
7379 };
7380
7381 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7382 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7383 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7384 self.report_token_source_errors();
7385 let mut actions = outcome.actions;
7386 if init_action_rules.contains(&rule_index) {
7387 actions.insert(
7388 0,
7389 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
7390 );
7391 }
7392 let mut context =
7393 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
7394 if track_alt_numbers {
7395 context.set_alt_number(outcome.alt_number);
7396 }
7397 if track_context_alt_numbers {
7398 context.set_context_alt_number(outcome.alt_number);
7399 }
7400 for (name, value) in outcome.return_values {
7401 context.set_int_return(name, value);
7402 }
7403 if let Some(token) = self.token_id_at(start_index) {
7404 self.set_context_start(&mut context, token);
7405 }
7406 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
7407 self.set_context_stop(&mut context, token);
7408 }
7409 let live_root = if self.build_parse_trees {
7410 self.recognition_arena
7411 .fold_left_recursive_boundaries(outcome.nodes)
7412 } else {
7413 outcome.nodes
7414 };
7415 if self.build_parse_trees {
7416 let mut nodes = live_root;
7417 while let Some(link) = self.recognition_arena.link(nodes) {
7418 let child = self.arena_recognized_node_tree(
7419 link.head,
7420 track_alt_numbers,
7421 track_context_alt_numbers,
7422 )?;
7423 self.tree.add_child(&mut context, child);
7424 nodes = link.tail;
7425 }
7426 }
7427 self.finish_recognition_arena(live_root, outcome.diagnostics);
7428 self.input.seek(outcome.index);
7429
7430 let tree = self.rule_node(context);
7431 self.release_tree_scratch_if_idle();
7432 Ok((tree, actions))
7433 }
7434
7435 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
7442 let mut context = ParserRuleContext::new(rule_index, self.state());
7443 while self.la(1) != TOKEN_EOF {
7444 let token_type = self.la(1);
7445 let child = self.match_token(token_type)?;
7446 if self.build_parse_trees {
7447 self.tree.add_child(&mut context, child);
7448 }
7449 }
7450 if self.build_parse_trees {
7451 let child = self.match_eof()?;
7452 self.tree.add_child(&mut context, child);
7453 }
7454 let tree = self.rule_node(context);
7455 self.release_tree_scratch_if_idle();
7456 Ok(tree)
7457 }
7458
7459 fn recognition_error(
7462 &mut self,
7463 rule_index: usize,
7464 start_index: usize,
7465 expected: &ExpectedTokens,
7466 ) -> AntlrError {
7467 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
7468 self.input.seek(index);
7469 let current = self.input.lt(1);
7470 let line = current.as_ref().map(Token::line).unwrap_or_default();
7471 let column = current.as_ref().map(Token::column).unwrap_or_default();
7472 AntlrError::ParserError {
7473 line,
7474 column,
7475 message,
7476 }
7477 }
7478
7479 fn expected_error_message(
7481 &mut self,
7482 rule_index: usize,
7483 start_index: usize,
7484 expected: &ExpectedTokens,
7485 ) -> (usize, String) {
7486 let index = expected
7487 .index
7488 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
7489 .unwrap_or_else(|| self.input.index());
7490 self.input.seek(index);
7491 let current = self.input.lt(1);
7492 let message = if expected
7493 .no_viable
7494 .as_ref()
7495 .is_some_and(|no_viable| no_viable.error_index == index)
7496 {
7497 let start = expected
7498 .no_viable
7499 .as_ref()
7500 .map_or(start_index, |no_viable| no_viable.start_index);
7501 let text = display_input_text(&self.input.text(start, index));
7502 format!("no viable alternative at input '{text}'")
7503 } else if expected.symbols.is_empty() {
7504 if expected.index.is_some() {
7505 let found = current
7506 .as_ref()
7507 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
7508 if current
7509 .as_ref()
7510 .is_some_and(|token| token.token_type() == TOKEN_EOF)
7511 {
7512 format!(
7513 "missing {} at {found}",
7514 self.expected_symbols_display(&expected.symbols)
7515 )
7516 } else {
7517 format!("mismatched input {found}")
7518 }
7519 } else {
7520 format!("no viable alternative while parsing rule {rule_index}")
7521 }
7522 } else {
7523 format!(
7524 "mismatched input {} expecting {}",
7525 current
7526 .as_ref()
7527 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7528 self.expected_symbols_display(&expected.symbols)
7529 )
7530 };
7531 (index, message)
7532 }
7533
7534 fn child_rule_failure_recovery(
7537 &mut self,
7538 rule_index: usize,
7539 start_index: usize,
7540 sync_symbols: &BTreeSet<i32>,
7541 member_values: BTreeMap<usize, i64>,
7542 expected: &ExpectedTokens,
7543 ) -> Option<RecognizeOutcome> {
7544 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7545 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7546 let mut next_index = error_index;
7547 loop {
7548 let symbol = self.token_type_at(next_index);
7549 if sync_symbols.contains(&symbol) {
7550 if next_index == error_index {
7551 return None;
7552 }
7553 break;
7554 }
7555 if symbol == TOKEN_EOF {
7556 break;
7557 }
7558 let after = self.consume_index(next_index, symbol);
7559 if after == next_index {
7560 break;
7561 }
7562 next_index = after;
7563 }
7564 let mut nodes = NodeSeqId::EMPTY;
7565 let error = self.arena_token_node(error_index, true);
7566 self.arena_prepend(&mut nodes, error);
7567 let diagnostics = self
7568 .recognition_arena
7569 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7570 Some(RecognizeOutcome {
7571 index: next_index,
7572 consumed_eof: false,
7573 alt_number: 0,
7574 member_values,
7575 return_values: BTreeMap::new(),
7576 diagnostics,
7577 decisions: Vec::new(),
7578 actions: Vec::new(),
7579 nodes,
7580 })
7581 }
7582
7583 fn child_rule_failure_recovery_outcomes(
7586 &mut self,
7587 request: ChildRuleFailureRecovery<'_>,
7588 ) -> Vec<RecognizeOutcome> {
7589 let sync_symbols =
7590 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
7591 self.child_rule_failure_recovery(
7592 request.rule_index,
7593 request.start_index,
7594 &sync_symbols,
7595 request.member_values,
7596 request.expected,
7597 )
7598 .into_iter()
7599 .collect()
7600 }
7601
7602 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
7604 expected_symbols_display(symbols, self.vocabulary())
7605 }
7606
7607 fn single_token_deletion(
7610 &mut self,
7611 transition: ParserTransition<'_>,
7612 index: usize,
7613 max_token_type: i32,
7614 expected_symbols: &BTreeSet<i32>,
7615 ) -> Option<(ParserDiagnostic, usize, i32)> {
7616 let current_symbol = self.token_type_at(index);
7617 if current_symbol == TOKEN_EOF {
7618 return None;
7619 }
7620 let next_index = self.consume_index(index, current_symbol);
7621 if next_index == index {
7622 return None;
7623 }
7624 let next_symbol = self.token_type_at(next_index);
7625 if !transition.matches(next_symbol, 1, max_token_type) {
7626 return None;
7627 }
7628 let transition_expected = transition_expected_symbols(transition, max_token_type);
7629 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7630 &transition_expected
7631 } else {
7632 expected_symbols
7633 });
7634 let current = self.token_at(index);
7635 let message = format!(
7636 "extraneous input {} expecting {expected_display}",
7637 current
7638 .as_ref()
7639 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7640 );
7641 Some((
7642 diagnostic_for_token(current, message),
7643 next_index,
7644 next_symbol,
7645 ))
7646 }
7647
7648 fn current_token_deletion(
7651 &mut self,
7652 index: usize,
7653 expected_symbols: &BTreeSet<i32>,
7654 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
7655 if expected_symbols.is_empty() {
7656 return None;
7657 }
7658 let current_symbol = self.token_type_at(index);
7659 if current_symbol == TOKEN_EOF {
7660 return None;
7661 }
7662 let current = self.token_at(index);
7663 let message = format!(
7664 "extraneous input {} expecting {}",
7665 current
7666 .as_ref()
7667 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7668 self.expected_symbols_display(expected_symbols)
7669 );
7670 let diagnostic = diagnostic_for_token(current, message);
7671 let mut skipped = Vec::new();
7672 let mut cursor = index;
7673 loop {
7674 let symbol = self.token_type_at(cursor);
7675 if symbol == TOKEN_EOF {
7676 return None;
7677 }
7678 skipped.push(cursor);
7679 let next_index = self.consume_index(cursor, symbol);
7680 if next_index == cursor {
7681 return None;
7682 }
7683 let next_symbol = self.token_type_at(next_index);
7684 if expected_symbols.contains(&next_symbol) {
7685 return Some((diagnostic, next_index, skipped));
7686 }
7687 cursor = next_index;
7688 }
7689 }
7690
7691 fn single_token_insertion(
7695 &mut self,
7696 transition: ParserTransition<'_>,
7697 index: usize,
7698 max_token_type: i32,
7699 expected_symbols: &BTreeSet<i32>,
7700 follow_symbols: &BTreeSet<i32>,
7701 ) -> Option<(ParserDiagnostic, i32, String)> {
7702 let current_symbol = self.token_type_at(index);
7703 if !follow_symbols.contains(¤t_symbol) {
7704 return None;
7705 }
7706 let transition_expected = transition_expected_symbols(transition, max_token_type);
7707 let token_type = transition_expected.iter().next().copied()?;
7708 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7709 &transition_expected
7710 } else {
7711 expected_symbols
7712 });
7713 let mut token_symbols = BTreeSet::new();
7714 token_symbols.insert(token_type);
7715 let missing_token_display = self.expected_symbols_display(&token_symbols);
7716 let current = self.token_at(index);
7717 let message = format!(
7718 "missing {expected_display} at {}",
7719 current
7720 .as_ref()
7721 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7722 );
7723 let text = format!("<missing {missing_token_display}>");
7724 Some((
7725 diagnostic_for_token(current.as_ref(), message),
7726 token_type,
7727 text,
7728 ))
7729 }
7730
7731 fn fast_single_token_deletion_recovery(
7735 &mut self,
7736 recovery: FastRecoveryRequest<'_, '_>,
7737 predicate_context: Option<FastPredicateContext<'_>>,
7738 ) -> Vec<FastRecognizeOutcome> {
7739 let FastRecoveryRequest {
7740 atn,
7741 transition,
7742 expected_symbols,
7743 target,
7744 request,
7745 visiting,
7746 memo,
7747 expected,
7748 } = recovery;
7749 let FastRecognizeRequest {
7750 stop_state,
7751 index,
7752 rule_start_index,
7753 decision_start_index,
7754 precedence,
7755 depth,
7756 ..
7757 } = request;
7758 let Some((diagnostic, next_index, next_symbol)) =
7759 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
7760 else {
7761 return Vec::new();
7762 };
7763 let after_next = self.consume_index(next_index, next_symbol);
7764 let empty_recovery = self.empty_recovery_symbols();
7765 self.recognize_state_fast(
7766 atn,
7767 FastRecognizeRequest {
7768 state_number: target,
7769 stop_state,
7770 index: after_next,
7771 rule_start_index,
7772 decision_start_index,
7773 precedence,
7774 depth: depth + 1,
7775 recovery_symbols: empty_recovery,
7776 recovery_state: None,
7777 },
7778 FastRecognizeScratch {
7779 predicate_context,
7780 visiting,
7781 memo,
7782 expected,
7783 native_depth: 0,
7784 },
7785 )
7786 .into_iter()
7787 .map(|mut outcome| {
7788 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
7789 outcome.diagnostics = self
7790 .recognition_arena
7791 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7792 if self.fast_token_nodes_enabled {
7793 let token = self.arena_token_node(next_index, false);
7794 self.defer_fast_outcome_node(&mut outcome, token);
7795 let error = self.arena_token_node(index, true);
7796 self.defer_fast_outcome_node(&mut outcome, error);
7797 }
7798 outcome
7799 })
7800 .collect()
7801 }
7802
7803 fn fast_single_token_insertion_recovery(
7807 &mut self,
7808 recovery: FastRecoveryRequest<'_, '_>,
7809 predicate_context: Option<FastPredicateContext<'_>>,
7810 ) -> Vec<FastRecognizeOutcome> {
7811 let FastRecoveryRequest {
7812 atn,
7813 transition,
7814 expected_symbols,
7815 target,
7816 request,
7817 visiting,
7818 memo,
7819 expected,
7820 } = recovery;
7821 let FastRecognizeRequest {
7822 stop_state,
7823 index,
7824 rule_start_index,
7825 decision_start_index,
7826 precedence,
7827 depth,
7828 ..
7829 } = request;
7830 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
7831 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
7832 transition,
7833 index,
7834 atn.max_token_type(),
7835 &expected_symbols,
7836 &follow_symbols,
7837 ) else {
7838 return Vec::new();
7839 };
7840 let empty_recovery = self.empty_recovery_symbols();
7841 self.recognize_state_fast(
7842 atn,
7843 FastRecognizeRequest {
7844 state_number: target,
7845 stop_state,
7846 index,
7847 rule_start_index,
7848 decision_start_index,
7849 precedence,
7850 depth: depth + 1,
7851 recovery_symbols: empty_recovery,
7852 recovery_state: None,
7853 },
7854 FastRecognizeScratch {
7855 predicate_context,
7856 visiting,
7857 memo,
7858 expected,
7859 native_depth: 0,
7860 },
7861 )
7862 .into_iter()
7863 .map(|mut outcome| {
7864 outcome.diagnostics = self
7865 .recognition_arena
7866 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7867 let missing = self.arena_missing_token_node(token_type, index, text.clone());
7868 self.defer_fast_outcome_node(&mut outcome, missing);
7869 outcome
7870 })
7871 .collect()
7872 }
7873
7874 fn fast_current_token_deletion_recovery(
7877 &mut self,
7878 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
7879 predicate_context: Option<FastPredicateContext<'_>>,
7880 ) -> Vec<FastRecognizeOutcome> {
7881 let FastCurrentTokenDeletionRequest {
7882 atn,
7883 expected_symbols,
7884 mut request,
7885 visiting,
7886 memo,
7887 expected,
7888 } = recovery;
7889 if request.index == request.rule_start_index {
7890 return Vec::new();
7891 }
7892 let Some((diagnostic, next_index, skipped)) =
7893 self.current_token_deletion(request.index, &expected_symbols)
7894 else {
7895 return Vec::new();
7896 };
7897 request.state_number = request.recovery_state.unwrap_or(request.state_number);
7898 request.index = next_index;
7899 request.depth += 1;
7900 request.recovery_state = None;
7901 self.recognize_state_fast(
7902 atn,
7903 request,
7904 FastRecognizeScratch {
7905 predicate_context,
7906 visiting,
7907 memo,
7908 expected,
7909 native_depth: 0,
7910 },
7911 )
7912 .into_iter()
7913 .map(|mut outcome| {
7914 outcome.diagnostics = self
7915 .recognition_arena
7916 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7917 for index in skipped.iter().rev() {
7918 let error = self.arena_token_node(*index, true);
7919 self.defer_fast_outcome_node(&mut outcome, error);
7920 }
7921 outcome
7922 })
7923 .collect()
7924 }
7925
7926 fn fast_child_rule_failure_recovery(
7929 &mut self,
7930 rule_index: usize,
7931 start_index: usize,
7932 sync_symbols: &BTreeSet<i32>,
7933 expected: &ExpectedTokens,
7934 ) -> Option<FastRecognizeOutcome> {
7935 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7936 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7937 let mut next_index = error_index;
7938 loop {
7939 let symbol = self.token_type_at(next_index);
7940 if sync_symbols.contains(&symbol) {
7941 if next_index == error_index {
7942 return None;
7943 }
7944 break;
7945 }
7946 if symbol == TOKEN_EOF {
7947 break;
7948 }
7949 let after = self.consume_index(next_index, symbol);
7950 if after == next_index {
7951 break;
7952 }
7953 next_index = after;
7954 }
7955 let diagnostics = self
7956 .recognition_arena
7957 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7958 let mut nodes = NodeSeqId::EMPTY;
7959 if self.fast_token_nodes_enabled {
7960 let error = self.arena_token_node(error_index, true);
7961 self.arena_prepend(&mut nodes, error);
7962 }
7963 Some(FastRecognizeOutcome {
7964 index: next_index,
7965 consumed_eof: false,
7966 diagnostics,
7967 deferred_nodes: FastDeferredNodeId::EMPTY,
7968 nodes,
7969 })
7970 }
7971
7972 fn fast_child_rule_failure_recovery_outcomes(
7975 &mut self,
7976 request: FastChildRuleFailureRecoveryRequest<'_>,
7977 ) -> Vec<FastRecognizeOutcome> {
7978 let FastChildRuleFailureRecoveryRequest {
7979 atn,
7980 rule_index,
7981 start_index,
7982 follow_state,
7983 stop_state,
7984 expected,
7985 } = request;
7986 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
7987 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
7988 .into_iter()
7989 .collect()
7990 }
7991
7992 fn defer_fast_outcome_node(
7993 &mut self,
7994 outcome: &mut FastRecognizeOutcome,
7995 node: RecognizedNodeId,
7996 ) {
7997 if outcome.deferred_nodes.is_empty() {
7998 self.arena_prepend(&mut outcome.nodes, node);
7999 return;
8000 }
8001 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
8002 let fragment = self.recognition_arena.deferred_fragment(fragment);
8003 outcome.deferred_nodes = self
8004 .recognition_arena
8005 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
8006 }
8007
8008 fn defer_fast_outcome_alternative(
8009 &mut self,
8010 outcome: &mut FastRecognizeOutcome,
8011 alt_number: usize,
8012 ) {
8013 let alternative = self.recognition_arena.deferred_alternative(alt_number);
8014 outcome.deferred_nodes = self
8015 .recognition_arena
8016 .concat_deferred_nodes(alternative, outcome.deferred_nodes);
8017 }
8018
8019 fn defer_fast_outcome_boundary(
8020 &mut self,
8021 outcome: &mut FastRecognizeOutcome,
8022 rule_index: usize,
8023 ) {
8024 let boundary = self
8025 .recognition_arena
8026 .deferred_left_recursive_boundary(rule_index);
8027 outcome.deferred_nodes = self
8028 .recognition_arena
8029 .concat_deferred_nodes(boundary, outcome.deferred_nodes);
8030 }
8031
8032 fn materialize_fast_deferred_nodes(
8033 &mut self,
8034 root: FastDeferredNodeId,
8035 initial_suffix: NodeSeqId,
8036 ) -> (NodeSeqId, usize) {
8037 if root.is_empty() {
8038 return (initial_suffix, 0);
8039 }
8040
8041 enum Frame {
8042 Visit(FastDeferredNodeId),
8043 ContinuePrefix(FastDeferredNodeId),
8044 FinishRule {
8045 rule: FastDeferredRule,
8046 parent_suffix: NodeSeqId,
8047 parent_alt_number: u32,
8048 parent_pending_boundary: Option<RecognizedNodeId>,
8049 },
8050 }
8051
8052 let mut result = initial_suffix;
8053 let mut alt_number = 0;
8057 let mut pending_boundary = None;
8058 let mut pending = Vec::with_capacity(16);
8059 pending.push(Frame::Visit(root));
8060 let mut fragment_nodes = Vec::new();
8061 while let Some(frame) = pending.pop() {
8062 match frame {
8063 Frame::Visit(deferred) => {
8064 if deferred.is_empty() {
8065 continue;
8066 }
8067
8068 match self.recognition_arena.deferred_node(deferred) {
8069 FastDeferredNode::Fragment(sequence) => {
8070 fragment_nodes.clear();
8071 fragment_nodes.extend(self.recognition_arena.iter(sequence));
8072 while let Some(node) = fragment_nodes.pop() {
8073 self.arena_prepend(&mut result, node);
8074 }
8075 }
8076 FastDeferredNode::Rule(rule) => {
8077 let rule = self.recognition_arena.deferred_rule(rule);
8078 let parent_suffix = result;
8079 let parent_alt_number = alt_number;
8080 let parent_pending_boundary = pending_boundary;
8081 result = rule.children;
8082 alt_number = 0;
8083 pending_boundary = None;
8084 pending.push(Frame::FinishRule {
8085 rule,
8086 parent_suffix,
8087 parent_alt_number,
8088 parent_pending_boundary,
8089 });
8090 pending.push(Frame::Visit(rule.deferred_children));
8091 }
8092 FastDeferredNode::Alternative(selected) => {
8093 if let Some(boundary) = pending_boundary {
8094 self.recognition_arena
8095 .set_boundary_alt_number(boundary, selected);
8096 } else {
8097 alt_number = selected;
8098 }
8099 }
8100 FastDeferredNode::LeftRecursiveBoundary { rule_index } => {
8101 let boundary = self.arena_boundary_node(rule_index as usize, 0);
8102 self.arena_prepend(&mut result, boundary);
8103 pending_boundary = Some(boundary);
8104 }
8105 FastDeferredNode::Concat {
8106 prefix,
8107 suffix: deferred_suffix,
8108 } => {
8109 pending.push(Frame::ContinuePrefix(prefix));
8110 pending.push(Frame::Visit(deferred_suffix));
8111 }
8112 }
8113 }
8114 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
8115 Frame::FinishRule {
8116 rule,
8117 parent_suffix,
8118 parent_alt_number,
8119 parent_pending_boundary,
8120 } => {
8121 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
8122 rule_index: rule.rule_index,
8123 invoking_state: rule.invoking_state,
8124 alt_number,
8125 start_index: rule.start_index,
8126 stop_index: rule.stop_index,
8127 return_values: None,
8128 children: result,
8129 });
8130 result = parent_suffix;
8131 self.arena_prepend(&mut result, node);
8132 alt_number = parent_alt_number;
8133 pending_boundary = parent_pending_boundary;
8134 }
8135 }
8136 }
8137 (result, alt_number as usize)
8138 }
8139
8140 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) -> usize {
8141 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
8142 let (nodes, alt_number) =
8143 self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
8144 outcome.nodes = nodes;
8145 alt_number
8146 }
8147
8148 fn recognize_repetition_fast(
8151 &mut self,
8152 atn: &Atn,
8153 request: &FastRecognizeRequest,
8154 shape: FastRepetitionShape,
8155 scratch: FastRecognizeScratch<'_, '_>,
8156 ) -> Vec<FastRecognizeOutcome> {
8157 let FastRecognizeScratch {
8158 predicate_context,
8159 visiting,
8160 memo,
8161 expected,
8162 native_depth,
8163 } = scratch;
8164 let lookahead = if self.fast_first_set_prefilter {
8165 atn.state(request.state_number).and_then(|state| {
8166 state
8167 .rule_index()
8168 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8169 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
8170 })
8171 } else {
8172 None
8173 };
8174 let (enter_alt_number, exit_alt_number) = if self.fast_track_alt_numbers {
8175 let state = atn
8176 .state(request.state_number)
8177 .expect("repetition request state must exist");
8178 (
8179 next_alt_number(state, 2, shape.enter_transition_index, 0, true),
8180 next_alt_number(state, 2, shape.exit_transition_index, 0, true),
8181 )
8182 } else {
8183 (0, 0)
8184 };
8185 let mut work = Vec::with_capacity(2);
8186 push_fast_repetition_work(
8187 &mut work,
8188 shape,
8189 FastRepetitionPath {
8190 index: request.index,
8191 deferred_nodes: FastDeferredNodeId::EMPTY,
8192 diagnostics: DiagnosticSeqId::EMPTY,
8193 consumed_eof: false,
8194 },
8195 lookahead.as_deref(),
8196 self.token_type_at(request.index),
8197 );
8198 let mut coordinates = FastRepetitionCoordinates::new(request.index);
8199 let mut outcomes = Vec::new();
8200 while let Some(item) = work.pop() {
8201 match item {
8202 FastRepetitionWork::Enter(path) => {
8203 if !coordinates.insert_entered(path) {
8204 continue;
8205 }
8206 let path_nodes = if enter_alt_number == 0 {
8207 path.deferred_nodes
8208 } else {
8209 let alternative = self
8210 .recognition_arena
8211 .deferred_alternative(enter_alt_number);
8212 self.recognition_arena
8213 .concat_deferred_nodes(path.deferred_nodes, alternative)
8214 };
8215 let body_outcomes = self.recognize_state_fast(
8216 atn,
8217 FastRecognizeRequest {
8218 state_number: shape.enter_target,
8219 stop_state: shape.body_stop_state,
8220 index: path.index,
8221 rule_start_index: request.rule_start_index,
8222 decision_start_index: request.decision_start_index,
8223 precedence: request.precedence,
8224 depth: request.depth.saturating_add(1),
8225 recovery_symbols: Rc::clone(&request.recovery_symbols),
8226 recovery_state: request.recovery_state,
8227 },
8228 FastRecognizeScratch {
8229 predicate_context,
8230 visiting: &mut *visiting,
8231 memo: &mut *memo,
8232 expected: &mut *expected,
8233 native_depth: native_depth + 1,
8234 },
8235 );
8236 for body in body_outcomes.into_iter().rev() {
8237 if body.index <= path.index {
8241 continue;
8242 }
8243 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
8244 let body_nodes = self
8245 .recognition_arena
8246 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
8247 let deferred_nodes = self
8248 .recognition_arena
8249 .concat_deferred_nodes(path_nodes, body_nodes);
8250 let next_path = FastRepetitionPath {
8251 index: body.index,
8252 deferred_nodes,
8253 diagnostics: self
8254 .recognition_arena
8255 .concat_diagnostics(path.diagnostics, body.diagnostics),
8256 consumed_eof: path.consumed_eof || body.consumed_eof,
8257 };
8258 let symbol = self.token_type_at(next_path.index);
8259 push_fast_repetition_work(
8260 &mut work,
8261 shape,
8262 next_path,
8263 lookahead.as_deref(),
8264 symbol,
8265 );
8266 }
8267 }
8268 FastRepetitionWork::Exit(path) => {
8269 if !coordinates.insert_exited(path) {
8270 continue;
8271 }
8272 let path_nodes = if exit_alt_number == 0 {
8273 path.deferred_nodes
8274 } else {
8275 let alternative =
8276 self.recognition_arena.deferred_alternative(exit_alt_number);
8277 self.recognition_arena
8278 .concat_deferred_nodes(path.deferred_nodes, alternative)
8279 };
8280 let suffixes = self.recognize_state_fast(
8281 atn,
8282 FastRecognizeRequest {
8283 state_number: shape.exit_target,
8284 stop_state: request.stop_state,
8285 index: path.index,
8286 rule_start_index: request.rule_start_index,
8287 decision_start_index: request.decision_start_index,
8288 precedence: request.precedence,
8289 depth: request.depth.saturating_add(1),
8290 recovery_symbols: Rc::clone(&request.recovery_symbols),
8291 recovery_state: request.recovery_state,
8292 },
8293 FastRecognizeScratch {
8294 predicate_context,
8295 visiting: &mut *visiting,
8296 memo: &mut *memo,
8297 expected: &mut *expected,
8298 native_depth: native_depth + 1,
8299 },
8300 );
8301 for mut outcome in suffixes {
8302 outcome.deferred_nodes = self
8303 .recognition_arena
8304 .concat_deferred_nodes(path_nodes, outcome.deferred_nodes);
8305 outcome.diagnostics = self
8306 .recognition_arena
8307 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
8308 outcome.consumed_eof |= path.consumed_eof;
8309 outcomes.push(outcome);
8310 }
8311 }
8312 }
8313 }
8314 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8315 outcomes
8316 }
8317
8318 fn recognize_state_fast(
8321 &mut self,
8322 atn: &Atn,
8323 request: FastRecognizeRequest,
8324 scratch: FastRecognizeScratch<'_, '_>,
8325 ) -> Vec<FastRecognizeOutcome> {
8326 if scratch.native_depth != 0 && scratch.native_depth < FAST_RECOGNIZE_STACK_CHECK_INTERVAL {
8327 return self.recognize_state_fast_inner(atn, request, scratch);
8328 }
8329 self.recognize_state_fast_checked(atn, request, scratch)
8330 }
8331
8332 #[inline(never)]
8333 fn recognize_state_fast_checked(
8334 &mut self,
8335 atn: &Atn,
8336 request: FastRecognizeRequest,
8337 mut scratch: FastRecognizeScratch<'_, '_>,
8338 ) -> Vec<FastRecognizeOutcome> {
8339 scratch.native_depth = 1;
8340 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, || {
8341 self.recognize_state_fast_inner(atn, request, scratch)
8342 })
8343 }
8344
8345 #[allow(clippy::too_many_lines)]
8346 fn recognize_state_fast_inner(
8347 &mut self,
8348 atn: &Atn,
8349 request: FastRecognizeRequest,
8350 scratch: FastRecognizeScratch<'_, '_>,
8351 ) -> Vec<FastRecognizeOutcome> {
8352 #[cfg(feature = "perf-counters")]
8353 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
8354 let FastRecognizeScratch {
8355 predicate_context,
8356 visiting,
8357 memo,
8358 expected,
8359 native_depth,
8360 } = scratch;
8361 let FastRecognizeRequest {
8362 mut state_number,
8363 stop_state,
8364 mut index,
8365 rule_start_index,
8366 decision_start_index,
8367 precedence,
8368 mut depth,
8369 recovery_symbols,
8370 recovery_state,
8371 } = request;
8372 let max_token_type = atn.max_token_type();
8373 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
8392 let mut inline_consumed_eof = false;
8393 loop {
8394 if depth > RECOGNITION_DEPTH_LIMIT {
8395 return Vec::new();
8396 }
8397 if state_number == stop_state {
8398 let mut nodes = NodeSeqId::EMPTY;
8399 if self.fast_token_nodes_enabled {
8400 for token_index in inline_consumed_tokens.iter().rev() {
8401 let token = self.arena_token_node(*token_index, false);
8402 self.arena_prepend(&mut nodes, token);
8403 }
8404 }
8405 return vec![FastRecognizeOutcome {
8406 index,
8407 consumed_eof: inline_consumed_eof,
8408 diagnostics: DiagnosticSeqId::EMPTY,
8409 deferred_nodes: FastDeferredNodeId::EMPTY,
8410 nodes,
8411 }];
8412 }
8413 let Some(state) = atn.state(state_number) else {
8414 return Vec::new();
8415 };
8416 let transitions = state.transitions();
8417 if transitions.len() == 1 && !state.precedence_rule_decision() {
8418 let transition = transitions
8419 .first()
8420 .expect("single transition checked above");
8421 let transition_kind = transition.kind();
8422 let target = transition.target();
8423 match transition_kind {
8424 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
8425 if left_recursive_boundary(atn, state, target).is_none() =>
8426 {
8427 #[cfg(feature = "perf-counters")]
8428 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8429 state_number = target;
8430 depth += 1;
8431 continue;
8432 }
8433 ParserTransitionKind::Predicate
8434 if left_recursive_boundary(atn, state, target).is_none() =>
8435 {
8436 #[cfg(feature = "perf-counters")]
8437 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8438 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
8439 {
8440 record_predicate_no_viable(expected, decision_start_index, index);
8441 return Vec::new();
8442 }
8443 state_number = target;
8444 depth += 1;
8445 continue;
8446 }
8447 ParserTransitionKind::Precedence
8448 if packed_i32(transition.arg0()) >= precedence
8449 && left_recursive_boundary(atn, state, target).is_none() =>
8450 {
8451 #[cfg(feature = "perf-counters")]
8452 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8453 state_number = target;
8454 depth += 1;
8455 continue;
8456 }
8457 ParserTransitionKind::Atom
8467 | ParserTransitionKind::Range
8468 | ParserTransitionKind::Set
8469 | ParserTransitionKind::NotSet
8470 | ParserTransitionKind::Wildcard
8471 if !self.fast_recovery_enabled =>
8472 {
8473 let symbol = self.token_type_at(index);
8474 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
8475 #[cfg(feature = "perf-counters")]
8476 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
8477 if self.fast_token_nodes_enabled {
8478 inline_consumed_tokens.push(index);
8479 }
8480 inline_consumed_eof |= symbol == TOKEN_EOF;
8481 index = self.consume_index(index, symbol);
8482 state_number = target;
8483 depth += 1;
8484 continue;
8485 }
8486 }
8489 _ => {}
8490 }
8491 }
8492 break;
8493 }
8494 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
8498 let Some(state) = atn.state(state_number) else {
8499 return Vec::new();
8500 };
8501 let transitions = state.transitions();
8502 let transition_count = transitions.len();
8503 if !self.fast_recovery_enabled
8504 && let Some(shape) = fast_repetition_shape(atn, state)
8505 {
8506 let mut outcomes = self.recognize_repetition_fast(
8507 atn,
8508 &FastRecognizeRequest {
8509 state_number,
8510 stop_state,
8511 index,
8512 rule_start_index,
8513 decision_start_index,
8514 precedence,
8515 depth,
8516 recovery_symbols: Rc::clone(&recovery_symbols),
8517 recovery_state,
8518 },
8519 shape,
8520 FastRecognizeScratch {
8521 predicate_context,
8522 visiting: &mut *visiting,
8523 memo: &mut *memo,
8524 expected: &mut *expected,
8525 native_depth: native_depth + 1,
8526 },
8527 );
8528 if inline_pending {
8529 for outcome in &mut outcomes {
8530 outcome.consumed_eof |= inline_consumed_eof;
8531 if self.fast_token_nodes_enabled {
8532 for token_index in inline_consumed_tokens.iter().rev() {
8533 let token = self.arena_token_node(*token_index, false);
8534 self.defer_fast_outcome_node(outcome, token);
8535 }
8536 }
8537 }
8538 }
8539 return outcomes;
8540 }
8541 let key = if self.fast_recovery_enabled {
8551 FastRecognizeKey {
8552 state_number,
8553 stop_state,
8554 index,
8555 rule_start_index,
8556 decision_start_index,
8557 precedence,
8558 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
8559 recovery_state,
8560 }
8561 } else {
8562 FastRecognizeKey {
8563 state_number,
8564 stop_state,
8565 index,
8566 rule_start_index: 0,
8567 decision_start_index: None,
8568 precedence,
8569 recovery_symbols_id: 0,
8570 recovery_state: None,
8571 }
8572 };
8573 let memo_lookup_enabled = self.fast_recovery_enabled
8578 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
8579 if memo_lookup_enabled {
8580 if let Some(outcomes) = memo.get(&key) {
8581 #[cfg(feature = "perf-counters")]
8582 {
8583 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
8584 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
8585 }
8586 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
8590 let inline_eof = inline_consumed_eof;
8591 let inline_tokens = &inline_consumed_tokens;
8592 return outcomes
8593 .iter()
8594 .copied()
8595 .map(|mut outcome| {
8596 if inline_eof {
8597 outcome.consumed_eof = true;
8598 }
8599 if self.fast_token_nodes_enabled {
8600 for token_index in inline_tokens.iter().rev() {
8601 let token = self.arena_token_node(*token_index, false);
8602 self.defer_fast_outcome_node(&mut outcome, token);
8603 }
8604 }
8605 outcome
8606 })
8607 .collect();
8608 }
8609 return outcomes.to_vec();
8610 }
8611 #[cfg(feature = "perf-counters")]
8612 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
8613 }
8614
8615 let needs_cycle_guard = if self.fast_recovery_enabled {
8620 transitions.iter().any(ParserTransition::is_epsilon)
8621 } else {
8622 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
8623 };
8624 #[cfg(feature = "perf-counters")]
8625 if needs_cycle_guard {
8626 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
8627 } else {
8628 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
8629 match state
8630 .transitions()
8631 .first()
8632 .expect("single-transition path requires one transition")
8633 .data()
8634 {
8635 Transition::Rule { .. } => {
8636 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
8637 }
8638 Transition::Atom { .. }
8639 | Transition::Range { .. }
8640 | Transition::Set { .. }
8641 | Transition::NotSet { .. }
8642 | Transition::Wildcard { .. } => {
8643 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
8644 }
8645 _ => {
8646 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
8647 }
8648 }
8649 }
8650 let has_inserted_cycle_guard = if needs_cycle_guard {
8651 if !visiting.insert(key.clone()) {
8652 #[cfg(feature = "perf-counters")]
8653 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
8654 return Vec::new();
8655 }
8656 true
8657 } else {
8658 false
8659 };
8660 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
8661 Some(index)
8662 } else {
8663 decision_start_index
8664 };
8665 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
8666 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
8667 } else {
8668 (Rc::clone(&recovery_symbols), recovery_state)
8669 };
8670
8671 let lookahead_filter = if transition_count > 1
8690 && self.fast_first_set_prefilter
8691 && !state.precedence_rule_decision()
8692 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
8693 {
8694 state
8695 .rule_index()
8696 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8697 .map(|rule_stop| {
8698 let symbol = self.token_type_at(index);
8699 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
8700 (symbol, entry)
8701 })
8702 } else {
8703 None
8704 };
8705 let ll1_only_alt: Option<usize> = if transition_count > 1
8714 && let Some((symbol, entry)) = lookahead_filter.as_ref()
8715 {
8716 let key = (state.state_number(), *symbol);
8717 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
8718 cached
8719 } else {
8720 let result = ll1_unique_alt(entry, *symbol);
8721 self.ll1_decision_cache.insert(key, result);
8722 result
8723 }
8724 } else {
8725 None
8726 };
8727 let lookahead_filter = lookahead_filter.as_ref();
8728 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
8734 for (transition_index, transition) in transitions.iter().enumerate() {
8735 if let Some(alt) = ll1_only_alt {
8736 if alt != transition_index {
8738 continue;
8739 }
8740 }
8741 let transition_kind = transition.kind();
8742 if ll1_only_alt.is_none()
8743 && should_skip_via_lookahead(
8744 transition_kind,
8745 transition_index,
8746 lookahead_filter,
8747 index,
8748 self.fast_recovery_enabled,
8749 expected,
8750 )
8751 {
8752 continue;
8753 }
8754 let target = transition.target();
8755 let outcomes_before_transition = outcomes.len();
8756 let left_recursive_boundary = match transition_kind {
8757 ParserTransitionKind::Epsilon
8758 | ParserTransitionKind::Action
8759 | ParserTransitionKind::Predicate
8760 | ParserTransitionKind::Precedence => left_recursive_boundary(atn, state, target),
8761 ParserTransitionKind::Atom
8762 | ParserTransitionKind::Range
8763 | ParserTransitionKind::Set
8764 | ParserTransitionKind::NotSet
8765 | ParserTransitionKind::Wildcard
8766 | ParserTransitionKind::Rule => None,
8767 };
8768 match transition_kind {
8769 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
8770 #[cfg(feature = "perf-counters")]
8771 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8772 outcomes.extend(self.recognize_state_fast(
8773 atn,
8774 FastRecognizeRequest {
8775 state_number: target,
8776 stop_state,
8777 index,
8778 rule_start_index,
8779 decision_start_index: next_decision_start_index,
8780 precedence,
8781 depth: depth + 1,
8782 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8783 recovery_state: epsilon_recovery_state,
8784 },
8785 FastRecognizeScratch {
8786 predicate_context,
8787 visiting,
8788 memo,
8789 expected,
8790 native_depth: native_depth + 1,
8791 },
8792 ));
8793 }
8794 ParserTransitionKind::Predicate => {
8795 #[cfg(feature = "perf-counters")]
8796 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8797 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
8798 outcomes.extend(self.recognize_state_fast(
8799 atn,
8800 FastRecognizeRequest {
8801 state_number: target,
8802 stop_state,
8803 index,
8804 rule_start_index,
8805 decision_start_index: next_decision_start_index,
8806 precedence,
8807 depth: depth + 1,
8808 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8809 recovery_state: epsilon_recovery_state,
8810 },
8811 FastRecognizeScratch {
8812 predicate_context,
8813 visiting,
8814 memo,
8815 expected,
8816 native_depth: native_depth + 1,
8817 },
8818 ));
8819 } else {
8820 record_predicate_no_viable(expected, next_decision_start_index, index);
8821 }
8822 }
8823 ParserTransitionKind::Precedence => {
8824 let transition_precedence = packed_i32(transition.arg0());
8825 if transition_precedence >= precedence {
8826 outcomes.extend(self.recognize_state_fast(
8827 atn,
8828 FastRecognizeRequest {
8829 state_number: target,
8830 stop_state,
8831 index,
8832 rule_start_index,
8833 decision_start_index: next_decision_start_index,
8834 precedence,
8835 depth: depth + 1,
8836 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8837 recovery_state: epsilon_recovery_state,
8838 },
8839 FastRecognizeScratch {
8840 predicate_context,
8841 visiting,
8842 memo,
8843 expected,
8844 native_depth: native_depth + 1,
8845 },
8846 ));
8847 }
8848 }
8849 ParserTransitionKind::Rule => {
8850 let rule_index = transition.arg0() as usize;
8851 let follow_state = transition.arg1() as usize;
8852 let rule_precedence = packed_i32(transition.arg2());
8853 #[cfg(feature = "perf-counters")]
8854 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
8855 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
8856 continue;
8857 };
8858 let symbol = self.token_type_at(index);
8870 if self.fast_first_set_prefilter {
8871 let first = self.cached_rule_first_set(atn, target, child_stop);
8884 if should_skip_rule_via_first_set(
8885 &first,
8886 symbol,
8887 self.fast_recovery_enabled,
8888 index,
8889 expected,
8890 ) {
8891 continue;
8892 }
8893 }
8894 let expected_before_child =
8895 self.fast_recovery_enabled.then(|| expected.clone());
8896 let mut children = self.recognize_state_fast(
8897 atn,
8898 FastRecognizeRequest {
8899 state_number: target,
8900 stop_state: child_stop,
8901 index,
8902 rule_start_index: index,
8903 decision_start_index: None,
8904 precedence: rule_precedence,
8905 depth: depth + 1,
8906 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8907 recovery_state: epsilon_recovery_state,
8908 },
8909 FastRecognizeScratch {
8910 predicate_context,
8911 visiting,
8912 memo,
8913 expected,
8914 native_depth: native_depth + 1,
8915 },
8916 );
8917 if children.is_empty() && self.fast_recovery_enabled {
8918 children = self.fast_child_rule_failure_recovery_outcomes(
8919 FastChildRuleFailureRecoveryRequest {
8920 atn,
8921 rule_index,
8922 start_index: index,
8923 follow_state,
8924 stop_state,
8925 expected,
8926 },
8927 );
8928 }
8929 if let Some(expected_before_child) = expected_before_child {
8930 if children
8931 .iter()
8932 .any(|child| child.diagnostics.is_empty() && child.index > index)
8933 {
8934 *expected = expected_before_child;
8935 }
8936 }
8937 for child in children {
8938 let child_index = child.index;
8939 let child_consumed_eof = child.consumed_eof;
8940 let child_diagnostics = child.diagnostics;
8941 let empty_recovery = self.empty_recovery_symbols();
8942 let follow_outcomes = self.recognize_state_fast(
8943 atn,
8944 FastRecognizeRequest {
8945 state_number: follow_state,
8946 stop_state,
8947 index: child_index,
8948 rule_start_index,
8949 decision_start_index: next_decision_start_index,
8950 precedence,
8951 depth: depth + 1,
8952 recovery_symbols: empty_recovery,
8953 recovery_state: None,
8954 },
8955 FastRecognizeScratch {
8956 predicate_context,
8957 visiting,
8958 memo,
8959 expected,
8960 native_depth: native_depth + 1,
8961 },
8962 );
8963 if follow_outcomes.is_empty() {
8964 continue;
8965 }
8966 let child_stop_index =
8967 self.rule_stop_token_index(child_index, child_consumed_eof);
8968 let child_node = self.build_parse_trees.then(|| {
8969 self.recognition_arena.deferred_rule_node(FastDeferredRule {
8970 rule_index: u32::try_from(rule_index)
8971 .expect("rule index fits in u32"),
8972 invoking_state: i32::try_from(invoking_state_number(state_number))
8973 .expect("invoking state fits in i32"),
8974 start_index: u32::try_from(index)
8975 .expect("rule start index fits in u32"),
8976 stop_index: child_stop_index.map(|stop_index| {
8977 u32::try_from(stop_index).expect("rule stop index fits in u32")
8978 }),
8979 deferred_children: child.deferred_nodes,
8980 children: child.nodes,
8981 })
8982 });
8983 let child_diags_empty = child_diagnostics.is_empty();
8984 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
8985 outcome.consumed_eof |= child_consumed_eof;
8986 if !child_diags_empty {
8989 outcome.diagnostics = self
8990 .recognition_arena
8991 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
8992 }
8993 if let Some(child_node) = child_node {
8994 outcome.deferred_nodes = self
8995 .recognition_arena
8996 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
8997 }
8998 outcome
8999 }));
9000 }
9001 }
9002 ParserTransitionKind::Atom
9003 | ParserTransitionKind::Range
9004 | ParserTransitionKind::Set
9005 | ParserTransitionKind::NotSet
9006 | ParserTransitionKind::Wildcard => {
9007 #[cfg(feature = "perf-counters")]
9008 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9009 let symbol = self.token_type_at(index);
9010 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9011 let next_index = self.consume_index(index, symbol);
9012 let empty_recovery = self.empty_recovery_symbols();
9013 outcomes.extend(
9014 self.recognize_state_fast(
9015 atn,
9016 FastRecognizeRequest {
9017 state_number: target,
9018 stop_state,
9019 index: next_index,
9020 rule_start_index,
9021 decision_start_index: next_decision_start_index,
9022 precedence,
9023 depth: depth + 1,
9024 recovery_symbols: empty_recovery,
9025 recovery_state: None,
9026 },
9027 FastRecognizeScratch {
9028 predicate_context,
9029 visiting,
9030 memo,
9031 expected,
9032 native_depth: native_depth + 1,
9033 },
9034 )
9035 .into_iter()
9036 .map(|mut outcome| {
9037 outcome.consumed_eof |= symbol == TOKEN_EOF;
9038 if self.fast_token_nodes_enabled {
9039 let token = self.arena_token_node(index, false);
9040 self.defer_fast_outcome_node(&mut outcome, token);
9041 }
9042 outcome
9043 }),
9044 );
9045 } else {
9046 if !self.fast_recovery_enabled {
9047 continue;
9055 }
9056 let expected_symbols = fast_recovery_expected_symbols(
9057 self,
9058 atn,
9059 state.state_number(),
9060 &recovery_symbols,
9061 );
9062 if expected_symbols.contains(&symbol) {
9063 continue;
9064 }
9065 {
9066 expected.record_transition(index, transition, max_token_type);
9067 record_no_viable_if_ambiguous(
9068 expected,
9069 next_decision_start_index,
9070 index,
9071 );
9072 outcomes.extend(self.fast_single_token_deletion_recovery(
9073 FastRecoveryRequest {
9074 atn,
9075 transition,
9076 expected_symbols: Rc::clone(&expected_symbols),
9077 target,
9078 request: FastRecognizeRequest {
9079 state_number,
9080 stop_state,
9081 index,
9082 rule_start_index,
9083 decision_start_index,
9084 precedence,
9085 depth,
9086 recovery_symbols: Rc::clone(&recovery_symbols),
9087 recovery_state,
9088 },
9089 visiting,
9090 memo,
9091 expected,
9092 },
9093 predicate_context,
9094 ));
9095 if !state_is_left_recursive_rule(atn, state) {
9096 outcomes.extend(self.fast_single_token_insertion_recovery(
9097 FastRecoveryRequest {
9098 atn,
9099 transition,
9100 expected_symbols: Rc::clone(&expected_symbols),
9101 target,
9102 request: FastRecognizeRequest {
9103 state_number,
9104 stop_state,
9105 index,
9106 rule_start_index,
9107 decision_start_index,
9108 precedence,
9109 depth,
9110 recovery_symbols: Rc::clone(&recovery_symbols),
9111 recovery_state,
9112 },
9113 visiting,
9114 memo,
9115 expected,
9116 },
9117 predicate_context,
9118 ));
9119 }
9120 outcomes.extend(self.fast_current_token_deletion_recovery(
9121 FastCurrentTokenDeletionRequest {
9122 atn,
9123 expected_symbols,
9124 request: FastRecognizeRequest {
9125 state_number,
9126 stop_state,
9127 index,
9128 rule_start_index,
9129 decision_start_index,
9130 precedence,
9131 depth,
9132 recovery_symbols: Rc::clone(&recovery_symbols),
9133 recovery_state,
9134 },
9135 visiting,
9136 memo,
9137 expected,
9138 },
9139 predicate_context,
9140 ));
9141 }
9142 }
9143 }
9144 }
9145 let alt_number = next_alt_number(
9146 state,
9147 transition_count,
9148 transition_index,
9149 0,
9150 self.fast_track_alt_numbers,
9151 );
9152 if alt_number != 0 || left_recursive_boundary.is_some() {
9153 for outcome in &mut outcomes[outcomes_before_transition..] {
9154 if alt_number != 0 {
9155 self.defer_fast_outcome_alternative(outcome, alt_number);
9156 }
9157 if let Some(rule_index) = left_recursive_boundary {
9158 self.defer_fast_outcome_boundary(outcome, rule_index);
9159 }
9160 }
9161 }
9162 }
9163
9164 if has_inserted_cycle_guard {
9165 visiting.remove(&key);
9166 }
9167 if matches!(
9168 self.prediction_mode,
9169 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9170 ) && self.fast_recovery_enabled
9171 {
9172 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
9176 }
9177 if self.fast_recovery_enabled {
9178 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
9179 } else {
9180 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
9181 }
9182 let should_memoize = self.fast_recovery_enabled
9192 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
9193 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
9197 if inline_consumed_eof {
9198 outcome.consumed_eof = true;
9199 }
9200 if !inline_consumed_tokens.is_empty() {
9201 for token_index in inline_consumed_tokens.iter().rev() {
9202 let token = self.arena_token_node(*token_index, false);
9203 self.defer_fast_outcome_node(&mut outcome, token);
9204 }
9205 }
9206 outcome
9207 };
9208 if should_memoize {
9209 #[cfg(feature = "perf-counters")]
9210 {
9211 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
9212 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
9213 match outcomes.len() {
9214 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
9215 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
9216 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
9217 }
9218 }
9219 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
9224 memo.insert(key, Rc::clone(&stored));
9225 if inline_pending {
9226 return stored
9227 .iter()
9228 .copied()
9229 .map(&mut apply_inline_pending)
9230 .collect();
9231 }
9232 return stored.to_vec();
9233 }
9234 #[cfg(feature = "perf-counters")]
9235 match outcomes.len() {
9236 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
9237 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
9238 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
9239 }
9240 if inline_pending {
9241 return outcomes.into_iter().map(apply_inline_pending).collect();
9242 }
9243 outcomes
9244 }
9245
9246 fn single_token_deletion_recovery(
9249 &mut self,
9250 recovery: RecoveryRequest<'_, '_>,
9251 ) -> Vec<RecognizeOutcome> {
9252 let RecoveryRequest {
9253 atn,
9254 transition,
9255 expected_symbols,
9256 target,
9257 request,
9258 visiting,
9259 memo,
9260 expected,
9261 } = recovery;
9262 let RecognizeRequest {
9263 stop_state,
9264 index,
9265 rule_start_index,
9266 decision_start_index,
9267 init_action_rules,
9268 predicates,
9269 semantics,
9270 rule_args,
9271 member_actions,
9272 return_actions,
9273 local_int_arg,
9274 member_values,
9275 return_values,
9276 rule_alt_number,
9277 track_alt_numbers,
9278 consumed_eof,
9279 precedence,
9280 depth,
9281 ..
9282 } = request;
9283 let Some((diagnostic, next_index, next_symbol)) =
9284 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
9285 else {
9286 return Vec::new();
9287 };
9288 let after_next = self.consume_index(next_index, next_symbol);
9289 self.recognize_state(
9290 atn,
9291 RecognizeRequest {
9292 state_number: target,
9293 stop_state,
9294 index: after_next,
9295 rule_start_index,
9296 decision_start_index,
9297 init_action_rules,
9298 predicates,
9299 semantics,
9300 rule_args,
9301 member_actions,
9302 return_actions,
9303 local_int_arg,
9304 member_values,
9305 return_values,
9306 rule_alt_number,
9307 track_alt_numbers,
9308 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
9309 committed_decision: false,
9310 precedence,
9311 depth: depth + 1,
9312 recovery_symbols: BTreeSet::new(),
9313 recovery_state: None,
9314 },
9315 visiting,
9316 memo,
9317 expected,
9318 )
9319 .into_iter()
9320 .map(|mut outcome| {
9321 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
9322 outcome.diagnostics = self
9323 .recognition_arena
9324 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9325 let token = self.arena_token_node(next_index, false);
9326 self.arena_prepend(&mut outcome.nodes, token);
9327 let error = self.arena_token_node(index, true);
9328 self.arena_prepend(&mut outcome.nodes, error);
9329 outcome
9330 })
9331 .collect()
9332 }
9333
9334 fn current_token_deletion_recovery(
9337 &mut self,
9338 recovery: CurrentTokenDeletionRequest<'_, '_>,
9339 ) -> Vec<RecognizeOutcome> {
9340 let CurrentTokenDeletionRequest {
9341 atn,
9342 expected_symbols,
9343 mut request,
9344 visiting,
9345 memo,
9346 expected,
9347 } = recovery;
9348 let error_index = request.index;
9349 if error_index == request.rule_start_index {
9350 return Vec::new();
9351 }
9352 let Some((diagnostic, next_index, skipped)) =
9353 self.current_token_deletion(error_index, &expected_symbols)
9354 else {
9355 return Vec::new();
9356 };
9357 request.state_number = request.recovery_state.unwrap_or(request.state_number);
9358 request.index = next_index;
9359 request.committed_decision = false;
9360 request.depth += 1;
9361 request.recovery_state = None;
9362 self.recognize_state(atn, request, visiting, memo, expected)
9363 .into_iter()
9364 .map(|mut outcome| {
9365 outcome.diagnostics = self
9366 .recognition_arena
9367 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9368 for index in skipped.iter().rev() {
9369 let error = self.arena_token_node(*index, true);
9370 self.arena_prepend(&mut outcome.nodes, error);
9371 }
9372 outcome
9373 })
9374 .collect()
9375 }
9376
9377 fn consuming_failure_fallback(
9380 &mut self,
9381 fallback: ConsumingFailureFallback<'_>,
9382 visiting: &mut BTreeSet<RecognizeKey>,
9383 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9384 expected: &mut ExpectedTokens,
9385 ) -> Vec<RecognizeOutcome> {
9386 if fallback.expected_symbols.is_empty() {
9387 return Vec::new();
9388 }
9389 if fallback.symbol == TOKEN_EOF {
9390 return self.eof_consuming_failure_fallback(fallback, expected);
9391 }
9392 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
9393 }
9394
9395 fn non_eof_consuming_failure_fallback(
9398 &mut self,
9399 fallback: ConsumingFailureFallback<'_>,
9400 visiting: &mut BTreeSet<RecognizeKey>,
9401 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9402 expected: &mut ExpectedTokens,
9403 ) -> Vec<RecognizeOutcome> {
9404 let ConsumingFailureFallback {
9405 atn,
9406 target,
9407 request,
9408 symbol,
9409 expected_symbols,
9410 decision_start_index,
9411 decision,
9412 } = fallback;
9413 let error_index = request.index;
9414 let diagnostic =
9415 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
9416 let next_index = self.consume_index(error_index, symbol);
9417 self.recognize_state(
9418 atn,
9419 RecognizeRequest {
9420 state_number: target,
9421 stop_state: request.stop_state,
9422 index: next_index,
9423 rule_start_index: request.rule_start_index,
9424 decision_start_index,
9425 init_action_rules: request.init_action_rules,
9426 predicates: request.predicates,
9427 semantics: request.semantics,
9428 rule_args: request.rule_args,
9429 member_actions: request.member_actions,
9430 return_actions: request.return_actions,
9431 local_int_arg: request.local_int_arg,
9432 member_values: request.member_values,
9433 return_values: request.return_values,
9434 rule_alt_number: request.rule_alt_number,
9435 track_alt_numbers: request.track_alt_numbers,
9436 consumed_eof: request.consumed_eof,
9437 committed_decision: false,
9438 precedence: request.precedence,
9439 depth: request.depth + 1,
9440 recovery_symbols: BTreeSet::new(),
9441 recovery_state: None,
9442 },
9443 visiting,
9444 memo,
9445 expected,
9446 )
9447 .into_iter()
9448 .map(|mut outcome| {
9449 prepend_decision(&mut outcome, decision);
9450 outcome.diagnostics = self
9451 .recognition_arena
9452 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9453 let error = self.arena_token_node(error_index, true);
9454 self.arena_prepend(&mut outcome.nodes, error);
9455 outcome
9456 })
9457 .collect()
9458 }
9459
9460 fn eof_consuming_failure_fallback(
9463 &mut self,
9464 fallback: ConsumingFailureFallback<'_>,
9465 expected: &ExpectedTokens,
9466 ) -> Vec<RecognizeOutcome> {
9467 let request = fallback.request;
9468 if request.index == request.rule_start_index {
9469 return Vec::new();
9470 }
9471 let diagnostic =
9472 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
9473 let diagnostics = self
9474 .recognition_arena
9475 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
9476 vec![RecognizeOutcome {
9477 index: request.index,
9478 consumed_eof: request.consumed_eof,
9479 alt_number: request.rule_alt_number,
9480 member_values: request.member_values,
9481 return_values: request.return_values,
9482 diagnostics,
9483 decisions: Vec::new(),
9484 actions: Vec::new(),
9485 nodes: NodeSeqId::EMPTY,
9486 }]
9487 }
9488
9489 fn single_token_insertion_recovery(
9492 &mut self,
9493 recovery: RecoveryRequest<'_, '_>,
9494 ) -> Vec<RecognizeOutcome> {
9495 let RecoveryRequest {
9496 atn,
9497 transition,
9498 expected_symbols,
9499 target,
9500 request,
9501 visiting,
9502 memo,
9503 expected,
9504 } = recovery;
9505 let RecognizeRequest {
9506 stop_state,
9507 index,
9508 rule_start_index,
9509 decision_start_index,
9510 init_action_rules,
9511 predicates,
9512 semantics,
9513 rule_args,
9514 member_actions,
9515 return_actions,
9516 local_int_arg,
9517 member_values,
9518 return_values,
9519 rule_alt_number,
9520 track_alt_numbers,
9521 consumed_eof,
9522 precedence,
9523 depth,
9524 ..
9525 } = request;
9526 let follow_symbols = state_expected_symbols(atn, transition.target());
9527 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
9528 transition,
9529 index,
9530 atn.max_token_type(),
9531 &expected_symbols,
9532 &follow_symbols,
9533 ) else {
9534 return Vec::new();
9535 };
9536 self.recognize_state(
9537 atn,
9538 RecognizeRequest {
9539 state_number: target,
9540 stop_state,
9541 index,
9542 rule_start_index,
9543 decision_start_index,
9544 init_action_rules,
9545 predicates,
9546 semantics,
9547 rule_args,
9548 member_actions,
9549 return_actions,
9550 local_int_arg,
9551 member_values,
9552 return_values,
9553 rule_alt_number,
9554 track_alt_numbers,
9555 consumed_eof,
9556 committed_decision: false,
9557 precedence,
9558 depth: depth + 1,
9559 recovery_symbols: BTreeSet::new(),
9560 recovery_state: None,
9561 },
9562 visiting,
9563 memo,
9564 expected,
9565 )
9566 .into_iter()
9567 .map(|mut outcome| {
9568 outcome.diagnostics = self
9569 .recognition_arena
9570 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9571 let missing = self.arena_missing_token_node(token_type, index, text.clone());
9572 self.arena_prepend(&mut outcome.nodes, missing);
9573 outcome
9574 })
9575 .collect()
9576 }
9577
9578 #[allow(clippy::too_many_lines)]
9581 fn recognize_state(
9582 &mut self,
9583 atn: &Atn,
9584 request: RecognizeRequest<'_>,
9585 visiting: &mut BTreeSet<RecognizeKey>,
9586 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9587 expected: &mut ExpectedTokens,
9588 ) -> Vec<RecognizeOutcome> {
9589 let request_template = request.clone();
9590 let RecognizeRequest {
9591 state_number,
9592 stop_state,
9593 index,
9594 rule_start_index,
9595 decision_start_index,
9596 init_action_rules,
9597 predicates,
9598 semantics,
9599 rule_args,
9600 member_actions,
9601 return_actions,
9602 local_int_arg,
9603 member_values,
9604 return_values,
9605 rule_alt_number,
9606 track_alt_numbers,
9607 consumed_eof,
9608 committed_decision,
9609 precedence,
9610 depth,
9611 recovery_symbols,
9612 recovery_state,
9613 } = request;
9614 if depth > RECOGNITION_DEPTH_LIMIT {
9615 return Vec::new();
9616 }
9617 if state_number == stop_state {
9618 return stop_outcome(
9619 index,
9620 consumed_eof,
9621 rule_alt_number,
9622 member_values,
9623 return_values,
9624 );
9625 }
9626 let key = RecognizeKey {
9627 state_number,
9628 stop_state,
9629 index,
9630 rule_start_index,
9631 decision_start_index,
9632 local_int_arg,
9633 member_values: member_values.clone(),
9634 return_values: return_values.clone(),
9635 rule_alt_number,
9636 track_alt_numbers,
9637 consumed_eof,
9638 committed_decision,
9639 precedence,
9640 recovery_symbols: recovery_symbols.clone(),
9641 recovery_state,
9642 };
9643 if let Some(outcomes) = memo.get(&key) {
9644 return outcomes.clone();
9645 }
9646
9647 let visit_key = key.clone();
9648 if !visiting.insert(visit_key.clone()) {
9649 return Vec::new();
9650 }
9651
9652 let Some(state) = atn.state(state_number) else {
9653 visiting.remove(&visit_key);
9654 return Vec::new();
9655 };
9656 let decision_override_generation = self.decision_override_generation;
9657 let transitions = state.transitions();
9658 let transition_count = transitions.len();
9659 let overridden_transition = if transition_count > 1
9660 && self.semantic_hooks.observes_parser_decisions()
9661 {
9662 atn.decision_to_state()
9663 .iter()
9664 .position(|candidate| candidate == state_number)
9665 .and_then(|decision| {
9666 self.semantic_hooks
9667 .parser_decision_override(decision, index, transition_count)
9668 })
9669 .and_then(|alternative| alternative.checked_sub(1))
9670 .filter(|alternative| *alternative < transition_count)
9671 } else {
9672 None
9673 };
9674 if overridden_transition.is_some() {
9675 self.decision_override_generation = self.decision_override_generation.wrapping_add(1);
9676 }
9677 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9678 Some(index)
9679 } else {
9680 decision_start_index
9681 };
9682 let (epsilon_recovery_symbols, epsilon_recovery_state) =
9683 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
9684 let mut outcomes = Vec::new();
9685 for (transition_index, transition) in transitions.iter().enumerate() {
9686 if overridden_transition.is_some_and(|forced| forced != transition_index) {
9687 continue;
9688 }
9689 let transition_committed =
9690 committed_decision || overridden_transition == Some(transition_index);
9691 let mut transition_request = request_template.clone();
9692 transition_request.committed_decision = transition_committed;
9693 let decision =
9694 transition_decision(atn, state, transition_count, transition_index, predicates);
9695 let next_alt_number = next_alt_number(
9696 state,
9697 transition_count,
9698 transition_index,
9699 rule_alt_number,
9700 track_alt_numbers,
9701 );
9702 let transition_data = transition.data();
9703 match &transition_data {
9704 Transition::Epsilon { target } | Transition::Action { target, .. } => {
9705 let action_rule_index = match &transition_data {
9706 Transition::Action { rule_index, .. } => Some(*rule_index),
9707 _ => None,
9708 };
9709 outcomes.extend(self.recognize_epsilon_or_action_step(
9710 atn,
9711 &transition_request,
9712 EpsilonActionStep {
9713 source_state: state_number,
9714 target: *target,
9715 action_rule_index,
9716 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
9717 decision,
9718 decision_start_index: next_decision_start_index,
9719 alt_number: next_alt_number,
9720 recovery_symbols: epsilon_recovery_symbols.clone(),
9721 recovery_state: epsilon_recovery_state,
9722 },
9723 RecognizeScratch {
9724 visiting,
9725 memo,
9726 expected,
9727 },
9728 ));
9729 }
9730 Transition::Predicate {
9731 target,
9732 rule_index,
9733 pred_index,
9734 ..
9735 } => {
9736 let predicate = PredicateEval {
9737 index,
9738 rule_index: *rule_index,
9739 pred_index: *pred_index,
9740 predicates,
9741 semantics,
9742 context: None,
9743 local_int_arg,
9744 member_values: &member_values,
9745 };
9746 if self.parser_predicate_matches(predicate) {
9747 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
9748 outcomes.extend(
9749 self.recognize_state(
9750 atn,
9751 RecognizeRequest {
9752 state_number: *target,
9753 stop_state,
9754 index,
9755 rule_start_index,
9756 decision_start_index: next_decision_start_index,
9757 init_action_rules,
9758 predicates,
9759 semantics,
9760 rule_args,
9761 member_actions,
9762 return_actions,
9763 local_int_arg,
9764 member_values: member_values.clone(),
9765 return_values: return_values.clone(),
9766 rule_alt_number: next_alt_number,
9767 track_alt_numbers,
9768 consumed_eof,
9769 committed_decision: transition_committed,
9770 precedence,
9771 depth: depth + 1,
9772 recovery_symbols: epsilon_recovery_symbols.clone(),
9773 recovery_state: epsilon_recovery_state,
9774 },
9775 visiting,
9776 memo,
9777 expected,
9778 )
9779 .into_iter()
9780 .map(|mut outcome| {
9781 prepend_decision(&mut outcome, decision);
9782 if let Some(rule_index) = left_recursive_boundary {
9783 let boundary =
9784 self.arena_boundary_node(rule_index, next_alt_number);
9785 self.arena_prepend(&mut outcome.nodes, boundary);
9786 }
9787 outcome
9788 }),
9789 );
9790 } else if let Some(message) = semantics
9791 .and_then(|semantics| {
9792 self.parser_semantic_ir_predicate_failure_message(
9793 *rule_index,
9794 *pred_index,
9795 semantics,
9796 )
9797 })
9798 .or_else(|| {
9799 self.parser_predicate_failure_message(
9800 *rule_index,
9801 *pred_index,
9802 predicates,
9803 )
9804 })
9805 {
9806 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
9807 rule_index: *rule_index,
9808 index,
9809 message,
9810 member_values: member_values.clone(),
9811 return_values: return_values.clone(),
9812 rule_alt_number,
9813 }));
9814 } else {
9815 record_predicate_no_viable(expected, next_decision_start_index, index);
9816 }
9817 }
9818 Transition::Precedence {
9819 target,
9820 precedence: transition_precedence,
9821 } => {
9822 if *transition_precedence >= precedence {
9823 outcomes.extend(
9824 self.recognize_state(
9825 atn,
9826 RecognizeRequest {
9827 state_number: *target,
9828 stop_state,
9829 index,
9830 rule_start_index,
9831 decision_start_index: next_decision_start_index,
9832 init_action_rules,
9833 predicates,
9834 semantics,
9835 rule_args,
9836 member_actions,
9837 return_actions,
9838 local_int_arg,
9839 member_values: member_values.clone(),
9840 return_values: return_values.clone(),
9841 rule_alt_number: next_alt_number,
9842 track_alt_numbers,
9843 consumed_eof,
9844 committed_decision: transition_committed,
9845 precedence,
9846 depth: depth + 1,
9847 recovery_symbols: epsilon_recovery_symbols.clone(),
9848 recovery_state: epsilon_recovery_state,
9849 },
9850 visiting,
9851 memo,
9852 expected,
9853 )
9854 .into_iter()
9855 .map(|mut outcome| {
9856 prepend_decision(&mut outcome, decision);
9857 outcome
9858 }),
9859 );
9860 }
9861 }
9862 Transition::Rule {
9863 target,
9864 rule_index,
9865 follow_state,
9866 precedence: rule_precedence,
9867 ..
9868 } => {
9869 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
9870 continue;
9871 };
9872 let child_local_int_arg =
9873 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
9874 let expected_before_child = expected.clone();
9875 let children = self.recognize_state(
9876 atn,
9877 RecognizeRequest {
9878 state_number: *target,
9879 stop_state: child_stop,
9880 index,
9881 rule_start_index: index,
9882 decision_start_index: None,
9883 init_action_rules,
9884 predicates,
9885 semantics,
9886 rule_args,
9887 member_actions,
9888 return_actions,
9889 local_int_arg: child_local_int_arg,
9890 member_values: member_values.clone(),
9891 return_values: BTreeMap::new(),
9892 rule_alt_number: 0,
9893 track_alt_numbers,
9894 consumed_eof: false,
9895 committed_decision: transition_committed,
9896 precedence: *rule_precedence,
9897 depth: depth + 1,
9898 recovery_symbols: epsilon_recovery_symbols.clone(),
9899 recovery_state: epsilon_recovery_state,
9900 },
9901 visiting,
9902 memo,
9903 expected,
9904 );
9905 let children = if children.is_empty() {
9906 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
9907 atn,
9908 rule_index: *rule_index,
9909 start_index: index,
9910 follow_state: *follow_state,
9911 stop_state,
9912 member_values: member_values.clone(),
9913 expected,
9914 })
9915 } else {
9916 children
9917 };
9918 let preserve_child_expected =
9919 self.child_expected_reaches_clean_eof(&children, expected);
9920 restore_expected(
9921 &children,
9922 index,
9923 expected,
9924 expected_before_child,
9925 preserve_child_expected,
9926 );
9927 for child in children {
9928 let child_stop_index =
9929 self.rule_stop_token_index(child.index, child.consumed_eof);
9930 let child_nodes = self
9931 .recognition_arena
9932 .fold_left_recursive_boundaries(child.nodes);
9933 let child_node = self.arena_rule_node(ArenaRuleSpec {
9934 rule_index: *rule_index,
9935 invoking_state: invoking_state_number(state_number),
9936 alt_number: child.alt_number,
9937 start_index: index,
9938 stop_index: child_stop_index,
9939 return_values: child.return_values.clone(),
9940 children: child_nodes,
9941 });
9942 outcomes.extend(
9943 self.recognize_state(
9944 atn,
9945 RecognizeRequest {
9946 state_number: *follow_state,
9947 stop_state,
9948 index: child.index,
9949 rule_start_index,
9950 decision_start_index: next_decision_start_index,
9951 init_action_rules,
9952 predicates,
9953 semantics,
9954 rule_args,
9955 member_actions,
9956 return_actions,
9957 local_int_arg,
9958 member_values: child.member_values.clone(),
9959 return_values: return_values.clone(),
9960 rule_alt_number,
9961 track_alt_numbers,
9962 consumed_eof: consumed_eof || child.consumed_eof,
9963 committed_decision: transition_committed
9964 && child.index == index,
9965 precedence,
9966 depth: depth + 1,
9967 recovery_symbols: BTreeSet::new(),
9968 recovery_state: None,
9969 },
9970 visiting,
9971 memo,
9972 expected,
9973 )
9974 .into_iter()
9975 .map(|mut outcome| {
9976 outcome.consumed_eof |= child.consumed_eof;
9977 outcome.diagnostics = self
9978 .recognition_arena
9979 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
9980 let mut decisions = child.decisions.clone();
9981 decisions.append(&mut outcome.decisions);
9982 outcome.decisions = decisions;
9983 prepend_decision(&mut outcome, decision);
9984 let mut actions = child.actions.clone();
9985 if init_action_rules.contains(rule_index) {
9986 actions.insert(
9987 0,
9988 ParserAction::new_rule_init(
9989 *rule_index,
9990 index,
9991 Some(*follow_state),
9992 ),
9993 );
9994 }
9995 actions.append(&mut outcome.actions);
9996 outcome.actions = actions;
9997 self.arena_prepend(&mut outcome.nodes, child_node);
9998 outcome
9999 }),
10000 );
10001 }
10002 }
10003 Transition::Atom { target, .. }
10004 | Transition::Range { target, .. }
10005 | Transition::Set { target, .. }
10006 | Transition::NotSet { target, .. }
10007 | Transition::Wildcard { target, .. } => {
10008 let symbol = self.token_type_at(index);
10009 if transition_data.matches(symbol, 1, atn.max_token_type()) {
10010 let next_index = self.consume_index(index, symbol);
10011 outcomes.extend(
10012 self.recognize_state(
10013 atn,
10014 RecognizeRequest {
10015 state_number: *target,
10016 stop_state,
10017 index: next_index,
10018 rule_start_index,
10019 decision_start_index: next_decision_start_index,
10020 init_action_rules,
10021 predicates,
10022 semantics,
10023 rule_args,
10024 member_actions,
10025 return_actions,
10026 local_int_arg,
10027 member_values: member_values.clone(),
10028 return_values: return_values.clone(),
10029 rule_alt_number: next_alt_number,
10030 track_alt_numbers,
10031 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
10032 committed_decision: false,
10033 precedence,
10034 depth: depth + 1,
10035 recovery_symbols: BTreeSet::new(),
10036 recovery_state: None,
10037 },
10038 visiting,
10039 memo,
10040 expected,
10041 )
10042 .into_iter()
10043 .map(|mut outcome| {
10044 prepend_decision(&mut outcome, decision);
10045 outcome.consumed_eof |= symbol == TOKEN_EOF;
10046 let token = self.arena_token_node(index, false);
10047 self.arena_prepend(&mut outcome.nodes, token);
10048 outcome
10049 }),
10050 );
10051 } else {
10052 let expected_symbols =
10053 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
10054 if expected_symbols.contains(&symbol) && !transition_committed {
10055 continue;
10056 }
10057 expected.record_transition(index, transition, atn.max_token_type());
10058 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
10059 let before_recovery = outcomes.len();
10060 let recovery_request = transition_request.clone();
10061 if transition_committed {
10062 outcomes.extend(self.consuming_failure_fallback(
10063 ConsumingFailureFallback {
10064 atn,
10065 target: *target,
10066 request: recovery_request,
10067 symbol,
10068 expected_symbols,
10069 decision_start_index: next_decision_start_index,
10070 decision,
10071 },
10072 visiting,
10073 memo,
10074 expected,
10075 ));
10076 break;
10077 }
10078 outcomes.extend(
10079 self.single_token_deletion_recovery(RecoveryRequest {
10080 atn,
10081 transition,
10082 expected_symbols: expected_symbols.clone(),
10083 target: *target,
10084 request: recovery_request.clone(),
10085 visiting,
10086 memo,
10087 expected,
10088 })
10089 .into_iter()
10090 .map(|mut outcome| {
10091 prepend_decision(&mut outcome, decision);
10092 outcome
10093 }),
10094 );
10095 if !state_is_left_recursive_rule(atn, state) {
10096 outcomes.extend(
10097 self.single_token_insertion_recovery(RecoveryRequest {
10098 atn,
10099 transition,
10100 expected_symbols: expected_symbols.clone(),
10101 target: *target,
10102 request: recovery_request.clone(),
10103 visiting,
10104 memo,
10105 expected,
10106 })
10107 .into_iter()
10108 .map(|mut outcome| {
10109 prepend_decision(&mut outcome, decision);
10110 outcome
10111 }),
10112 );
10113 }
10114 outcomes.extend(self.current_token_deletion_recovery(
10115 CurrentTokenDeletionRequest {
10116 atn,
10117 expected_symbols: expected_symbols.clone(),
10118 request: recovery_request.clone(),
10119 visiting,
10120 memo,
10121 expected,
10122 },
10123 ));
10124 if outcomes.len() == before_recovery {
10125 outcomes.extend(self.consuming_failure_fallback(
10126 ConsumingFailureFallback {
10127 atn,
10128 target: *target,
10129 request: recovery_request,
10130 symbol,
10131 expected_symbols,
10132 decision_start_index: next_decision_start_index,
10133 decision,
10134 },
10135 visiting,
10136 memo,
10137 expected,
10138 ));
10139 }
10140 }
10141 }
10142 }
10143 if self.decision_override_generation != decision_override_generation {
10144 break;
10145 }
10146 }
10147
10148 visiting.remove(&visit_key);
10149 self.record_prediction_diagnostics(atn, state, index, &outcomes);
10150 if matches!(
10151 self.prediction_mode,
10152 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
10153 ) {
10154 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
10155 }
10156 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
10157 memo.insert(key, outcomes.clone());
10158 outcomes
10159 }
10160
10161 fn recognize_epsilon_or_action_step(
10164 &mut self,
10165 atn: &Atn,
10166 request: &RecognizeRequest<'_>,
10167 step: EpsilonActionStep,
10168 scratch: RecognizeScratch<'_>,
10169 ) -> Vec<RecognizeOutcome> {
10170 let RecognizeScratch {
10171 visiting,
10172 memo,
10173 expected,
10174 } = scratch;
10175 let action = step.action_rule_index.map(|rule_index| {
10176 ParserAction::new(
10177 step.source_state,
10178 rule_index,
10179 request.rule_start_index,
10180 self.rule_stop_token_index(request.index, request.consumed_eof),
10181 )
10182 });
10183 let next_member_values = if action.is_some() {
10184 member_values_after_action(
10185 step.source_state,
10186 request.member_actions,
10187 request.semantics,
10188 &request.member_values,
10189 )
10190 } else {
10191 request.member_values.clone()
10192 };
10193 let next_return_values = action.map_or_else(
10194 || request.return_values.clone(),
10195 |action| {
10196 return_values_after_action(
10197 step.source_state,
10198 action.rule_index(),
10199 request.return_actions,
10200 request.semantics,
10201 &request.return_values,
10202 )
10203 },
10204 );
10205
10206 self.recognize_state(
10207 atn,
10208 RecognizeRequest {
10209 state_number: step.target,
10210 stop_state: request.stop_state,
10211 index: request.index,
10212 rule_start_index: request.rule_start_index,
10213 decision_start_index: step.decision_start_index,
10214 init_action_rules: request.init_action_rules,
10215 predicates: request.predicates,
10216 semantics: request.semantics,
10217 rule_args: request.rule_args,
10218 member_actions: request.member_actions,
10219 return_actions: request.return_actions,
10220 local_int_arg: request.local_int_arg,
10221 member_values: next_member_values,
10222 return_values: next_return_values,
10223 rule_alt_number: if step.left_recursive_boundary.is_some() {
10224 0
10225 } else {
10226 step.alt_number
10227 },
10228 track_alt_numbers: request.track_alt_numbers,
10229 consumed_eof: request.consumed_eof,
10230 committed_decision: request.committed_decision,
10231 precedence: request.precedence,
10232 depth: request.depth + 1,
10233 recovery_symbols: step.recovery_symbols,
10234 recovery_state: step.recovery_state,
10235 },
10236 visiting,
10237 memo,
10238 expected,
10239 )
10240 .into_iter()
10241 .map(|mut outcome| {
10242 prepend_decision(&mut outcome, step.decision);
10243 if let Some(rule_index) = step.left_recursive_boundary {
10244 let boundary = self.arena_boundary_node(rule_index, step.alt_number);
10245 self.arena_prepend(&mut outcome.nodes, boundary);
10246 }
10247 if let Some(action) = action {
10248 outcome.actions.insert(0, action);
10249 }
10250 outcome
10251 })
10252 .collect()
10253 }
10254
10255 fn token_type_at(&mut self, index: usize) -> i32 {
10260 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
10261 self.input.fill();
10262 }
10263 self.input.token_type_at_index(index)
10264 }
10265
10266 fn cached_state_expected_symbols(
10278 &mut self,
10279 atn: &Atn,
10280 state_number: usize,
10281 ) -> Rc<BTreeSet<i32>> {
10282 if let Some(cached) = self.state_expected_cache.get(&state_number) {
10283 return Rc::clone(cached);
10284 }
10285 let symbols = state_expected_symbols(atn, state_number);
10286 let entry = self.intern_recovery_symbols(symbols);
10287 self.state_expected_cache
10288 .insert(state_number, Rc::clone(&entry));
10289 entry
10290 }
10291
10292 fn cached_state_expected_token_set(
10293 &mut self,
10294 atn: &Atn,
10295 state_number: usize,
10296 ) -> Rc<TokenBitSet> {
10297 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
10298 return Rc::clone(cached);
10299 }
10300 let symbols = with_shared_atn_caches(atn, |cache| {
10304 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
10305 return Rc::clone(cached);
10306 }
10307 let symbols = Rc::new(state_expected_token_set(atn, state_number));
10308 cache
10309 .state_expected_tokens
10310 .insert(state_number, Rc::clone(&symbols));
10311 symbols
10312 });
10313 self.state_expected_token_cache
10314 .insert(state_number, Rc::clone(&symbols));
10315 symbols
10316 }
10317
10318 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
10319 if self.rule_stop_reach_cache.len() <= state_number {
10320 self.rule_stop_reach_cache
10321 .resize_with(atn.states().len().max(state_number + 1), || None);
10322 }
10323 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
10324 return reaches;
10325 }
10326 let reaches = with_shared_atn_caches(atn, |cache| {
10327 *cache
10328 .rule_stop_reach
10329 .entry(state_number)
10330 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
10331 });
10332 self.rule_stop_reach_cache[state_number] = Some(reaches);
10333 reaches
10334 }
10335
10336 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
10339 Rc::clone(&self.empty_recovery_symbols)
10340 }
10341
10342 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
10351 if set.is_empty() {
10352 return Rc::clone(&self.empty_recovery_symbols);
10353 }
10354 let candidate = Rc::new(set);
10355 match self.recovery_symbols_intern.get(&candidate) {
10356 Some(existing) => Rc::clone(existing),
10357 None => {
10358 self.recovery_symbols_intern
10359 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
10360 candidate
10361 }
10362 }
10363 }
10364
10365 fn cached_decision_lookahead(
10370 &mut self,
10371 atn: &Atn,
10372 state: AtnState<'_>,
10373 rule_stop_state: usize,
10374 ) -> Rc<DecisionLookahead> {
10375 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
10382 return Rc::clone(cached);
10383 }
10384 let entry = with_shared_atn_caches(atn, |cache| {
10385 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
10386 return Rc::clone(cached);
10387 }
10388 let mut entry = DecisionLookahead {
10389 transitions: Vec::with_capacity(state.transitions().len()),
10390 };
10391 for transition in &state.transitions() {
10392 entry.transitions.push(transition_first_set(
10393 atn,
10394 transition,
10395 rule_stop_state,
10396 &mut cache.first_set,
10397 ));
10398 }
10399 let entry = Rc::new(entry);
10400 cache
10401 .decision_lookahead
10402 .insert(state.state_number(), Rc::clone(&entry));
10403 entry
10404 });
10405 self.decision_lookahead_cache
10406 .insert(state.state_number(), Rc::clone(&entry));
10407 entry
10408 }
10409
10410 fn cached_rule_first_set(
10411 &mut self,
10412 atn: &Atn,
10413 target: usize,
10414 child_stop: usize,
10415 ) -> Rc<FirstSet> {
10416 if self.rule_first_set_cache.len() <= target {
10417 self.rule_first_set_cache
10418 .resize_with(atn.states().len().max(target + 1), || None);
10419 }
10420 if let Some(cached) = self
10421 .rule_first_set_cache
10422 .get(target)
10423 .and_then(Option::as_ref)
10424 {
10425 return Rc::clone(cached);
10426 }
10427 let first = with_shared_first_set_cache(atn, |cache| {
10428 rule_first_set(atn, target, child_stop, cache)
10429 });
10430 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
10431 first
10432 }
10433
10434 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
10435 let atn_key = SharedAtnCacheKey::for_atn(atn);
10436 if self.empty_cycle_cache_atn != Some(atn_key) {
10437 self.empty_cycle_cache.clear();
10438 self.empty_cycle_cache_atn = Some(atn_key);
10439 }
10440 if self.empty_cycle_cache.len() <= state_number {
10441 self.empty_cycle_cache
10442 .resize_with(atn.state_count().max(state_number + 1), || None);
10443 }
10444 if let Some(cached) = self.empty_cycle_cache[state_number] {
10445 return cached;
10446 }
10447 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
10448 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
10449 self.empty_cycle_cache[state_number] = Some(result);
10450 result
10451 }
10452
10453 fn empty_path_reaches_state(
10454 &mut self,
10455 atn: &Atn,
10456 state_number: usize,
10457 target_state: usize,
10458 visited: &mut FxHashSet<usize>,
10459 ) -> bool {
10460 enum Work {
10461 Visit(usize),
10462 RuleFollow {
10463 target: usize,
10464 rule_index: usize,
10465 follow_state: usize,
10466 },
10467 }
10468
10469 let mut work = vec![Work::Visit(state_number)];
10470 while let Some(item) = work.pop() {
10471 match item {
10472 Work::Visit(state_number) => {
10473 if !visited.insert(state_number) {
10474 continue;
10475 }
10476 let Some(state) = atn.state(state_number) else {
10477 continue;
10478 };
10479 let transitions = state.transitions();
10480 for transition_index in (0..transitions.len()).rev() {
10481 let transition = transitions
10482 .get(transition_index)
10483 .expect("in-bounds parser transition");
10484 let kind = transition.kind();
10485 let target = transition.target();
10486 match kind {
10487 ParserTransitionKind::Atom
10488 | ParserTransitionKind::Range
10489 | ParserTransitionKind::Set
10490 | ParserTransitionKind::NotSet
10491 | ParserTransitionKind::Wildcard => {}
10492 ParserTransitionKind::Rule => {
10493 if target == target_state {
10494 return true;
10495 }
10496 work.push(Work::RuleFollow {
10497 target,
10498 rule_index: transition.arg0() as usize,
10499 follow_state: transition.arg1() as usize,
10500 });
10501 work.push(Work::Visit(target));
10502 }
10503 ParserTransitionKind::Epsilon
10504 | ParserTransitionKind::Predicate
10505 | ParserTransitionKind::Action
10506 | ParserTransitionKind::Precedence => {
10507 if target == target_state {
10508 return true;
10509 }
10510 work.push(Work::Visit(target));
10511 }
10512 }
10513 }
10514 }
10515 Work::RuleFollow {
10516 target,
10517 rule_index,
10518 follow_state,
10519 } => {
10520 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
10521 continue;
10522 };
10523 if self.cached_rule_first_set(atn, target, child_stop).nullable {
10524 if follow_state == target_state {
10525 return true;
10526 }
10527 work.push(Work::Visit(follow_state));
10528 }
10529 }
10530 }
10531 }
10532 false
10533 }
10534
10535 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
10538 match self.clean_memo_mode {
10539 CleanMemoMode::Promote => true,
10540 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
10541 CleanMemoMode::Sparse => {
10542 self.clean_memo_sparse_samples += 1;
10543 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
10544 return false;
10545 }
10546 self.clean_memo_sparse_samples = 0;
10547 self.clean_memo_mode = CleanMemoMode::Probe;
10548 self.clean_memo_probe_samples = 0;
10549 self.clean_memo_probe_repeats = 0;
10550 self.clean_memo_probe_seen.clear();
10551 self.observe_clean_memo_probe(key)
10552 }
10553 }
10554 }
10555
10556 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
10557 self.clean_memo_probe_samples += 1;
10558 if !self.clean_memo_probe_seen.insert(key.clone()) {
10559 self.clean_memo_probe_repeats += 1;
10560 }
10561 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
10562 self.clean_memo_mode = CleanMemoMode::Promote;
10563 self.clean_memo_probe_seen.clear();
10564 return true;
10565 }
10566 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
10567 self.clean_memo_mode = CleanMemoMode::Sparse;
10568 self.clean_memo_sparse_samples = 0;
10569 self.clean_memo_probe_seen.clear();
10570 return false;
10571 }
10572 true
10573 }
10574
10575 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
10577 self.input.get(index)
10578 }
10579
10580 fn token_id_at(&self, index: usize) -> Option<TokenId> {
10582 self.input.get_id(index)
10583 }
10584
10585 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
10586 let token = self
10587 .token_id_at(index)
10588 .expect("recognized token index must exist in the token store");
10589 let node = if error {
10590 ArenaRecognizedNode::ErrorToken { token }
10591 } else {
10592 ArenaRecognizedNode::Token { token }
10593 };
10594 self.recognition_arena.push_node(node)
10595 }
10596
10597 fn arena_missing_token_node(
10598 &mut self,
10599 token_type: i32,
10600 at_index: usize,
10601 text: String,
10602 ) -> RecognizedNodeId {
10603 let extra = self
10604 .recognition_arena
10605 .push_extra(RecognitionExtra::MissingToken {
10606 token_type,
10607 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
10608 text,
10609 });
10610 self.recognition_arena
10611 .push_node(ArenaRecognizedNode::MissingToken { extra })
10612 }
10613
10614 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
10615 let ArenaRuleSpec {
10616 rule_index,
10617 invoking_state,
10618 alt_number,
10619 start_index,
10620 stop_index,
10621 return_values,
10622 children,
10623 } = spec;
10624 let return_values = (!return_values.is_empty()).then(|| {
10625 self.recognition_arena
10626 .push_extra(RecognitionExtra::ReturnValues(return_values))
10627 });
10628 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
10629 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10630 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
10631 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
10632 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
10633 stop_index: stop_index
10634 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
10635 return_values,
10636 children,
10637 })
10638 }
10639
10640 fn arena_boundary_node(&mut self, rule_index: usize, alt_number: usize) -> RecognizedNodeId {
10641 self.recognition_arena
10642 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
10643 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10644 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
10645 })
10646 }
10647
10648 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
10649 *sequence = self.recognition_arena.prepend(*sequence, node);
10650 }
10651
10652 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
10653 self.last_recognition_arena_root = root;
10654 self.last_recognition_arena_diagnostics = diagnostics;
10655 #[cfg(feature = "perf-counters")]
10656 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
10657 let stats = self.recognition_arena_stats();
10658 #[allow(clippy::print_stderr)]
10659 {
10660 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
10661 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
10662 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
10663 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
10664 eprintln!("perf recognition_links_total={}", stats.total_links);
10665 eprintln!("perf recognition_links_live={}", stats.live_links);
10666 eprintln!("perf recognition_links_dead={}", stats.dead_links);
10667 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
10668 eprintln!("perf recognition_extras_total={}", stats.total_extras);
10669 eprintln!("perf recognition_extras_live={}", stats.live_extras);
10670 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
10671 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
10672 }
10673 }
10674 }
10675
10676 fn reset_recognition_arena(&mut self) {
10677 self.recognition_arena.reset();
10678 self.last_recognition_arena_root = NodeSeqId::EMPTY;
10679 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
10680 }
10681
10682 fn current_visible_index(&mut self) -> usize {
10685 let index = self.input.index();
10686 self.input.seek(index);
10687 self.input.index()
10688 }
10689
10690 fn child_expected_reaches_clean_eof(
10693 &mut self,
10694 children: &[RecognizeOutcome],
10695 expected: &ExpectedTokens,
10696 ) -> bool {
10697 let Some(index) = expected.index else {
10698 return false;
10699 };
10700 self.token_type_at(index) == TOKEN_EOF
10701 && children
10702 .iter()
10703 .any(|child| child.diagnostics.is_empty() && child.index == index)
10704 }
10705
10706 fn previous_token_index(&self, index: usize) -> Option<usize> {
10713 self.input.previous_visible_token_index(index)
10714 }
10715
10716 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
10721 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
10722 Some(index)
10723 } else {
10724 self.previous_token_index(index)
10725 }
10726 }
10727
10728 #[must_use]
10745 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
10746 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
10747 self.rule_stop_token_index(current_index, consumed_eof)
10748 }
10749
10750 #[must_use]
10759 pub fn after_action_stop_index_for_tree(
10760 &mut self,
10761 tree: ParseTree,
10762 current_index: usize,
10763 ) -> Option<usize> {
10764 if let Some(stop) = self
10765 .node(tree)
10766 .as_rule()
10767 .and_then(crate::tree::RuleNodeView::stop_id)
10768 {
10769 return Some(stop.index());
10770 }
10771 self.after_action_stop_index(current_index)
10772 }
10773
10774 #[must_use]
10784 pub fn after_action_start_index_for_tree(
10785 &self,
10786 tree: ParseTree,
10787 fallback_index: usize,
10788 ) -> usize {
10789 if let Some(start) = self
10790 .node(tree)
10791 .as_rule()
10792 .and_then(crate::tree::RuleNodeView::start_id)
10793 {
10794 return start.index();
10795 }
10796 fallback_index
10797 }
10798
10799 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
10804 self.rule_stop_token_index(index, consumed_eof)
10805 .and_then(|token_index| self.token_id_at(token_index))
10806 }
10807
10808 fn predicate_failure_recovery(
10815 &mut self,
10816 request: PredicateFailureRecovery<'_>,
10817 ) -> RecognizeOutcome {
10818 let PredicateFailureRecovery {
10819 rule_index,
10820 index,
10821 message,
10822 member_values,
10823 return_values,
10824 rule_alt_number,
10825 } = request;
10826 let rule_name = self
10827 .rule_names()
10828 .get(rule_index)
10829 .map_or_else(|| rule_index.to_string(), Clone::clone);
10830 let diagnostic = diagnostic_for_token(
10831 self.token_at(index).as_ref(),
10832 format!("rule {rule_name} {message}"),
10833 );
10834 let mut reversed_nodes = NodeSeqId::EMPTY;
10835 let mut next_index = index;
10836 loop {
10837 let symbol = self.token_type_at(next_index);
10838 if symbol == TOKEN_EOF {
10839 break;
10840 }
10841 let error = self.arena_token_node(next_index, true);
10842 self.arena_prepend(&mut reversed_nodes, error);
10843 let after = self.consume_index(next_index, symbol);
10844 if after == next_index {
10845 break;
10846 }
10847 next_index = after;
10848 }
10849 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
10850 let diagnostics = self
10851 .recognition_arena
10852 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10853 RecognizeOutcome {
10854 index: next_index,
10855 consumed_eof: false,
10856 alt_number: rule_alt_number,
10857 member_values,
10858 return_values,
10859 diagnostics,
10860 decisions: Vec::new(),
10861 actions: Vec::new(),
10862 nodes,
10863 }
10864 }
10865
10866 fn parser_semantic_hook_result(
10869 &mut self,
10870 request: ParserSemanticHookRequest<'_>,
10871 ) -> Option<bool> {
10872 let ParserSemanticHookRequest {
10873 index,
10874 rule_index,
10875 pred_index,
10876 context,
10877 local_int_arg,
10878 member_values,
10879 } = request;
10880 let rule_name = self.rule_names().get(rule_index).cloned();
10881 self.input.seek(index);
10882 let input = &mut self.input;
10883 let semantic_hooks = &mut self.semantic_hooks;
10884 let mut ctx = ParserSemCtx {
10885 input,
10886 tree_storage: &self.tree,
10887 rule_index,
10888 coordinate_index: pred_index,
10889 rule_name,
10890 context,
10891 tree: None,
10892 local_int_arg,
10893 member_values,
10894 action: None,
10895 };
10896 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
10897 }
10898
10899 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
10904 if prior.is_empty() {
10905 return;
10906 }
10907 let mut merged = prior;
10908 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
10909 if !merged.contains(&coordinate) {
10910 merged.push(coordinate);
10911 }
10912 }
10913 self.unknown_predicate_hits = merged;
10914 }
10915
10916 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
10925 apply_unknown_predicate_policy(
10926 self.unknown_predicate_policy,
10927 rule_index,
10928 pred_index,
10929 &mut self.unknown_predicate_hits,
10930 )
10931 }
10932
10933 fn unknown_semantic_error(&self) -> Option<AntlrError> {
10936 use std::fmt::Write as _;
10937 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
10938 return None;
10939 }
10940 let mut message = String::new();
10941 for (rule_index, pred_index) in &self.unknown_predicate_hits {
10942 if !message.is_empty() {
10943 message.push_str("; ");
10944 }
10945 let _ = match self.rule_names().get(*rule_index) {
10946 Some(rule_name) => write!(
10947 message,
10948 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
10949 ),
10950 None => write!(
10951 message,
10952 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
10953 ),
10954 };
10955 }
10956 for (rule_index, source_state) in &self.unhandled_action_hits {
10957 if !message.is_empty() {
10958 message.push_str("; ");
10959 }
10960 let _ = match self.rule_names().get(*rule_index) {
10961 Some(rule_name) => write!(
10962 message,
10963 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
10964 ),
10965 None => write!(
10966 message,
10967 "unhandled semantic action: rule_index={rule_index} state={source_state}"
10968 ),
10969 };
10970 }
10971 Some(AntlrError::Unsupported(message))
10972 }
10973
10974 fn parser_semir_predicate_matches(
10982 &mut self,
10983 semantics: &ParserSemantics,
10984 predicate: &ParserSemanticPredicate,
10985 request: ParserSemanticHookRequest<'_>,
10986 ) -> bool {
10987 self.input.seek(request.index);
10988 let rule_name = self
10989 .data
10990 .rule_names()
10991 .get(request.rule_index)
10992 .map(String::as_str);
10993 let unknown_predicate_policy = self.unknown_predicate_policy;
10994 let mut ctx = ParserSemIrCtx {
10995 input: &mut self.input,
10996 tree_storage: &self.tree,
10997 semantic_hooks: &mut self.semantic_hooks,
10998 rule_index: request.rule_index,
10999 coordinate_index: request.pred_index,
11000 rule_name,
11001 context: request.context,
11002 local_int_arg: request.local_int_arg,
11003 member_values: request.member_values,
11004 invoked_predicates: &mut self.invoked_predicates,
11005 unknown_predicate_policy,
11006 unknown_predicate_hits: &mut self.unknown_predicate_hits,
11007 };
11008 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
11009 }
11010
11011 fn fast_parser_predicate_matches(
11012 &mut self,
11013 context: Option<FastPredicateContext<'_>>,
11014 transition: ParserTransition<'_>,
11015 index: usize,
11016 ) -> bool {
11017 let Some(context) = context else {
11018 return true;
11019 };
11020 let rule_index = transition.arg0() as usize;
11021 let pred_index = transition.arg1() as usize;
11022 let key = (index, rule_index, pred_index);
11023 if let Some(result) = self.fast_predicate_cache.get(&key) {
11024 return *result;
11025 }
11026 let result = self.parser_predicate_matches(PredicateEval {
11027 index,
11028 rule_index,
11029 pred_index,
11030 predicates: context.predicates,
11031 semantics: context.semantics,
11032 context: None,
11033 local_int_arg: None,
11034 member_values: context.member_values,
11035 });
11036 self.fast_predicate_cache.insert(key, result);
11037 result
11038 }
11039
11040 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
11041 let PredicateEval {
11042 index,
11043 rule_index,
11044 pred_index,
11045 predicates,
11046 semantics,
11047 context,
11048 local_int_arg,
11049 member_values,
11050 } = eval;
11051 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
11052 semantics
11053 .predicates
11054 .iter()
11055 .find(|predicate| {
11056 predicate.rule_index == rule_index && predicate.pred_index == pred_index
11057 })
11058 .map(|predicate| (semantics, predicate))
11059 }) {
11060 return self.parser_semir_predicate_matches(
11061 semantics,
11062 predicate,
11063 ParserSemanticHookRequest {
11064 index,
11065 rule_index,
11066 pred_index,
11067 context,
11068 local_int_arg,
11069 member_values,
11070 },
11071 );
11072 }
11073 let Some((_, _, predicate)) = predicates
11074 .iter()
11075 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
11076 else {
11077 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
11078 index,
11079 rule_index,
11080 pred_index,
11081 context,
11082 local_int_arg,
11083 member_values,
11084 }) {
11085 return result;
11086 }
11087 return self.unknown_predicate_result(rule_index, pred_index);
11088 };
11089 self.input.seek(index);
11090 match predicate {
11091 ParserPredicate::True => true,
11092 ParserPredicate::False => false,
11093 ParserPredicate::FalseWithMessage { .. } => false,
11094 ParserPredicate::Invoke { value } => {
11095 let key = (rule_index, pred_index);
11096 if !self.invoked_predicates.contains(&key) {
11097 self.invoked_predicates.push(key);
11098 use std::io::Write as _;
11099 let mut stdout = std::io::stdout().lock();
11100 let _ = writeln!(stdout, "eval={value}");
11101 }
11102 *value
11103 }
11104 ParserPredicate::LookaheadTextEquals { offset, text } => self
11105 .input
11106 .lt(*offset)
11107 .is_some_and(|token| Token::text(&token) == Some(*text)),
11108 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
11109 self.la(*offset) != *token_type
11110 }
11111 ParserPredicate::TokenPairAdjacent => {
11112 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
11113 return false;
11114 };
11115 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
11116 return false;
11117 };
11118 first + 1 == second
11119 }
11120 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
11121 .and_then(|context| {
11122 context
11123 .child_rules(&self.tree, self.input.token_store(), *rule_index)
11124 .next()
11125 .map(crate::tree::RuleNodeView::text)
11126 })
11127 .is_none_or(|actual| actual != *text),
11128 ParserPredicate::LocalIntEquals { value } => {
11129 local_int_arg.is_none_or(|(_, actual)| actual == *value)
11130 }
11131 ParserPredicate::LocalIntLessOrEqual { value } => {
11132 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
11133 }
11134 ParserPredicate::MemberModuloEquals {
11135 member,
11136 modulus,
11137 value,
11138 equals,
11139 } => {
11140 if *modulus == 0 {
11141 return false;
11142 }
11143 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
11144 (actual == *value) == *equals
11145 }
11146 ParserPredicate::MemberEquals {
11147 member,
11148 value,
11149 equals,
11150 } => {
11151 let actual = member_values.get(member).copied().unwrap_or_default();
11152 (actual == *value) == *equals
11153 }
11154 }
11155 }
11156
11157 fn parser_predicate_failure_message(
11159 &self,
11160 rule_index: usize,
11161 pred_index: usize,
11162 predicates: &[(usize, usize, ParserPredicate)],
11163 ) -> Option<&'static str> {
11164 predicates
11165 .iter()
11166 .find_map(|(rule, pred, predicate)| match predicate {
11167 ParserPredicate::FalseWithMessage { message }
11168 if *rule == rule_index && *pred == pred_index =>
11169 {
11170 Some(*message)
11171 }
11172 _ => None,
11173 })
11174 }
11175
11176 pub fn parser_semantic_ir_predicate_failure_message(
11179 &self,
11180 rule_index: usize,
11181 pred_index: usize,
11182 semantics: &ParserSemantics,
11183 ) -> Option<&'static str> {
11184 semantics
11185 .predicates
11186 .iter()
11187 .find(|predicate| {
11188 predicate.rule_index == rule_index && predicate.pred_index == pred_index
11189 })
11190 .and_then(|predicate| predicate.failure_message)
11191 }
11192
11193 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
11202 if symbol == TOKEN_EOF {
11203 return index;
11204 }
11205 self.input.next_visible_after(index)
11206 }
11207
11208 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
11211 let text = display_input_text(&self.input.text(start_index, error_index));
11212 diagnostic_for_token(
11213 self.token_at(error_index).as_ref(),
11214 format!("no viable alternative at input '{text}'"),
11215 )
11216 }
11217
11218 fn recovery_failure_diagnostic(
11221 &self,
11222 index: usize,
11223 decision_start_index: Option<usize>,
11224 expected_symbols: &BTreeSet<i32>,
11225 ) -> ParserDiagnostic {
11226 if expected_symbols.len() > 1 {
11227 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
11228 return self.no_viable_alternative(decision_start, index);
11229 }
11230 }
11231 diagnostic_for_token(
11232 self.token_at(index).as_ref(),
11233 format!(
11234 "mismatched input {} expecting {}",
11235 self.token_at(index)
11236 .as_ref()
11237 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
11238 self.expected_symbols_display(expected_symbols)
11239 ),
11240 )
11241 }
11242
11243 fn eof_rule_recovery_diagnostic(
11246 &self,
11247 index: usize,
11248 expected_symbols: &BTreeSet<i32>,
11249 expected: &ExpectedTokens,
11250 ) -> ParserDiagnostic {
11251 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
11252 &expected.symbols
11253 } else {
11254 expected_symbols
11255 };
11256 diagnostic_for_token(
11257 self.token_at(index).as_ref(),
11258 format!(
11259 "mismatched input {} expecting {}",
11260 self.token_at(index)
11261 .as_ref()
11262 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
11263 self.expected_symbols_display(symbols)
11264 ),
11265 )
11266 }
11267
11268 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
11274 let Some(stop) = stop else {
11275 return String::new();
11276 };
11277 let stop = if self
11278 .token_at(stop)
11279 .is_some_and(|token| token.token_type() == TOKEN_EOF)
11280 {
11281 let Some(previous) = self.previous_token_index(stop) else {
11282 return String::new();
11283 };
11284 previous
11285 } else {
11286 stop
11287 };
11288 self.input.text(start, stop)
11289 }
11290
11291 fn clear_prediction_diagnostics(&mut self) {
11294 self.prediction_diagnostics.clear();
11295 self.reported_prediction_diagnostics.clear();
11296 }
11297
11298 fn reset_per_parse_caches(&mut self) {
11322 self.rule_first_set_cache.clear();
11323 self.decision_lookahead_cache.clear();
11324 self.ll1_decision_cache.clear();
11325 self.fast_predicate_cache.clear();
11326 self.rule_stop_reach_cache.clear();
11327 self.clean_memo_mode = CleanMemoMode::Probe;
11328 self.clean_memo_probe_seen.clear();
11329 self.clean_memo_probe_samples = 0;
11330 self.clean_memo_probe_repeats = 0;
11331 self.clean_memo_sparse_samples = 0;
11332 self.recovery_symbols_intern.clear();
11333 self.state_expected_cache.clear();
11334 self.state_expected_token_cache.clear();
11335 }
11336
11337 fn record_prediction_diagnostics(
11340 &mut self,
11341 atn: &Atn,
11342 state: AtnState<'_>,
11343 start_index: usize,
11344 outcomes: &[RecognizeOutcome],
11345 ) {
11346 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
11347 return;
11348 }
11349 let Some(decision) = atn
11350 .decision_to_state()
11351 .iter()
11352 .position(|state_number| state_number == state.state_number())
11353 else {
11354 return;
11355 };
11356 let Some(rule_index) = state.rule_index() else {
11357 return;
11358 };
11359 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
11360 for outcome in outcomes
11361 .iter()
11362 .filter(|outcome| outcome.diagnostics.is_empty())
11363 {
11364 let Some(alt) = outcome.decisions.first() else {
11365 continue;
11366 };
11367 alts_by_end
11368 .entry(outcome.index)
11369 .or_default()
11370 .insert(alt + 1);
11371 }
11372 let Some((&end_index, ambig_alts)) = alts_by_end
11373 .iter()
11374 .filter(|(_, alts)| alts.len() > 1)
11375 .max_by_key(|(end, _)| *end)
11376 else {
11377 return;
11378 };
11379 let rule_name = self
11380 .rule_names()
11381 .get(rule_index)
11382 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
11383 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
11384 let input = display_input_text(&self.input.text(start_index, stop_index));
11385 let alts = ambig_alts
11386 .iter()
11387 .map(usize::to_string)
11388 .collect::<Vec<_>>()
11389 .join(", ");
11390 let key = (decision, start_index, format!("{alts}:{input}"));
11391 if !self.reported_prediction_diagnostics.insert(key) {
11392 return;
11393 }
11394 let start_diagnostic = diagnostic_for_token(
11395 self.token_at(start_index),
11396 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
11397 );
11398 let stop_diagnostic = diagnostic_for_token(
11399 self.token_at(stop_index),
11400 format!(
11401 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
11402 ),
11403 );
11404 self.prediction_diagnostics.push(start_diagnostic);
11405 self.prediction_diagnostics.push(stop_diagnostic);
11406 }
11407
11408 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
11410 expected_symbols_display(
11411 &state_expected_symbols(atn, state_number),
11412 self.vocabulary(),
11413 )
11414 }
11415
11416 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
11421 let state = usize::try_from(self.data().state()).unwrap_or(0);
11422 ExpectedTokenSet {
11423 symbols: state_expected_symbols(atn, state),
11424 }
11425 }
11426
11427 pub const fn set_bail_on_error(&mut self, bail: bool) {
11430 self.bail_on_error = bail;
11431 }
11432
11433 #[must_use]
11435 pub const fn bail_on_error(&self) -> bool {
11436 self.bail_on_error
11437 }
11438
11439 pub fn rule_invocation_stack(&self) -> Vec<String> {
11442 self.rule_context_stack
11443 .iter()
11444 .rev()
11445 .map(|frame| {
11446 self.data()
11447 .rule_names()
11448 .get(frame.rule_index)
11449 .cloned()
11450 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
11451 })
11452 .collect()
11453 }
11454
11455 pub fn active_invocation_states(&self) -> Vec<isize> {
11459 self.rule_context_stack
11460 .iter()
11461 .skip(1)
11462 .rev()
11463 .map(|frame| frame.invoking_state)
11464 .collect()
11465 }
11466
11467 pub fn token_display_at(&self, index: usize) -> Option<String> {
11469 self.token_at(index).map(|token| format!("{token}"))
11470 }
11471}
11472
11473impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
11474where
11475 S: TokenSource,
11476 H: SemanticHooks,
11477{
11478 fn parse_rule(
11479 &mut self,
11480 rule_index: usize,
11481 invoking_state: isize,
11482 precedence: i32,
11483 ) -> DirectAdaptiveParseResult<ParseTree> {
11484 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
11485 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
11486 )?;
11487 let stop_state = self
11488 .atn
11489 .rule_to_stop_state()
11490 .get(rule_index)
11491 .filter(|state| *state != usize::MAX)
11492 .ok_or(DirectAdaptiveParseControl::Fallback(
11493 DirectAdaptiveFallback::MissingAtn,
11494 ))?;
11495 let start_index = self.parser.current_visible_index();
11496 let mut context = ParserRuleContext::new(rule_index, invoking_state);
11497 if let Some(token) = self.parser.token_id_at(start_index) {
11498 self.parser.set_context_start(&mut context, token);
11499 }
11500 let mut state_number = start_state;
11501 let mut consumed_eof = false;
11502 while state_number != stop_state {
11503 self.step()?;
11504 let (transition, boundary) = self.next_transition(state_number, precedence)?;
11505 if boundary.is_some() {
11506 return Err(DirectAdaptiveParseControl::Fallback(
11507 DirectAdaptiveFallback::LeftRecursiveBoundary,
11508 ));
11509 }
11510 match transition.data() {
11511 Transition::Epsilon { target } => {
11512 state_number = target;
11513 }
11514 Transition::Precedence {
11515 target,
11516 precedence: transition_precedence,
11517 } => {
11518 if transition_precedence < precedence {
11519 return Err(DirectAdaptiveParseControl::Fallback(
11520 DirectAdaptiveFallback::Precedence,
11521 ));
11522 }
11523 state_number = target;
11524 }
11525 Transition::Rule {
11526 rule_index,
11527 follow_state,
11528 precedence: rule_precedence,
11529 ..
11530 } => {
11531 let child = self.parse_rule(
11532 rule_index,
11533 invoking_state_number(state_number),
11534 rule_precedence,
11535 )?;
11536 if self.parser.build_parse_trees {
11537 self.parser.tree.add_child(&mut context, child);
11538 }
11539 state_number = follow_state;
11540 }
11541 Transition::Atom { .. }
11542 | Transition::Range { .. }
11543 | Transition::Set { .. }
11544 | Transition::NotSet { .. }
11545 | Transition::Wildcard { .. } => {
11546 let (matched_eof, child) = self.consume_transition(transition)?;
11547 consumed_eof |= matched_eof;
11548 if let Some(child) = child {
11549 self.parser.tree.add_child(&mut context, child);
11550 }
11551 state_number = transition.target();
11552 }
11553 Transition::Predicate { .. } => {
11554 return Err(DirectAdaptiveParseControl::Fallback(
11555 DirectAdaptiveFallback::Predicate,
11556 ));
11557 }
11558 Transition::Action { .. } => {
11559 return Err(DirectAdaptiveParseControl::Fallback(
11560 DirectAdaptiveFallback::Action,
11561 ));
11562 }
11563 }
11564 }
11565
11566 let stop_index = self
11567 .parser
11568 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
11569 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
11570 self.parser.set_context_stop(&mut context, token);
11571 }
11572 Ok(self.parser.rule_node(context))
11573 }
11574
11575 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
11576 self.steps += 1;
11577 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
11578 return Err(DirectAdaptiveParseControl::Fallback(
11579 DirectAdaptiveFallback::StepLimit,
11580 ));
11581 }
11582 Ok(())
11583 }
11584
11585 fn next_transition(
11586 &mut self,
11587 state_number: usize,
11588 precedence: i32,
11589 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
11590 let state = self
11591 .atn
11592 .state(state_number)
11593 .ok_or(DirectAdaptiveParseControl::Fallback(
11594 DirectAdaptiveFallback::MissingAtn,
11595 ))?;
11596 if state.is_rule_stop() {
11597 return Err(DirectAdaptiveParseControl::Fallback(
11598 DirectAdaptiveFallback::RuleStop,
11599 ));
11600 }
11601 let transition_index =
11602 self.transition_index(state_number, state.transitions().len(), precedence)?;
11603 let transition = state.transitions().get(transition_index).ok_or(
11604 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
11605 )?;
11606 let boundary = match &transition.data() {
11607 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
11608 left_recursive_boundary(self.atn, state, *target)
11609 }
11610 _ => None,
11611 };
11612 Ok((transition, boundary))
11613 }
11614
11615 fn transition_index(
11616 &mut self,
11617 state_number: usize,
11618 transition_count: usize,
11619 precedence: i32,
11620 ) -> DirectAdaptiveParseResult<usize> {
11621 match transition_count {
11622 0 => Err(DirectAdaptiveParseControl::Fallback(
11623 DirectAdaptiveFallback::NoTransition,
11624 )),
11625 1 => Ok(0),
11626 _ => {
11627 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
11628 return Ok(alt);
11629 }
11630 let decision = self
11631 .decision_by_state
11632 .get(state_number)
11633 .and_then(|decision| *decision)
11634 .ok_or(DirectAdaptiveParseControl::Fallback(
11635 DirectAdaptiveFallback::UnknownDecision,
11636 ))?;
11637 let prediction = self
11638 .simulator
11639 .adaptive_predict_stream_info_with_precedence(
11640 decision,
11641 direct_precedence(precedence),
11642 &mut self.parser.input,
11643 )
11644 .map_err(|_| {
11645 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
11646 })?;
11647 if prediction.has_semantic_context {
11648 return Err(DirectAdaptiveParseControl::Fallback(
11649 DirectAdaptiveFallback::SemanticContext,
11650 ));
11651 }
11652 prediction
11653 .alt
11654 .checked_sub(1)
11655 .filter(|index| *index < transition_count)
11656 .ok_or(DirectAdaptiveParseControl::Fallback(
11657 DirectAdaptiveFallback::InvalidAlt,
11658 ))
11659 }
11660 }
11661 }
11662
11663 fn ll1_transition_index(
11664 &mut self,
11665 state_number: usize,
11666 transition_count: usize,
11667 ) -> DirectAdaptiveParseResult<Option<usize>> {
11668 let state = self
11669 .atn
11670 .state(state_number)
11671 .ok_or(DirectAdaptiveParseControl::Fallback(
11672 DirectAdaptiveFallback::MissingAtn,
11673 ))?;
11674 if state.precedence_rule_decision() {
11675 return Ok(None);
11676 }
11677 let Some(rule_stop) = state
11678 .rule_index()
11679 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
11680 else {
11681 return Ok(None);
11682 };
11683 let symbol = self.parser.input.la_token(1);
11684 let entry = self
11685 .parser
11686 .cached_decision_lookahead(self.atn, state, rule_stop);
11687 Ok(
11688 ll1_greedy_alt(&entry, symbol, state.non_greedy())
11689 .filter(|alt| *alt < transition_count),
11690 )
11691 }
11692
11693 fn consume_transition(
11694 &mut self,
11695 transition: ParserTransition<'_>,
11696 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
11697 let symbol = self.parser.input.la_token(1);
11698 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
11699 return Err(DirectAdaptiveParseControl::Fallback(
11700 DirectAdaptiveFallback::TokenMismatch,
11701 ));
11702 }
11703 let token = self
11704 .parser
11705 .input
11706 .lt_id(1)
11707 .ok_or(DirectAdaptiveParseControl::Fallback(
11708 DirectAdaptiveFallback::TokenMismatch,
11709 ))?;
11710 let matched_eof = symbol == TOKEN_EOF;
11711 if !matched_eof {
11712 self.parser.consume();
11713 }
11714 let child = self
11715 .parser
11716 .build_parse_trees
11717 .then(|| self.parser.terminal_tree(token));
11718 Ok((matched_eof, child))
11719 }
11720}
11721
11722fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
11725 if !state.precedence_rule_decision() {
11726 return None;
11727 }
11728 let target_state = atn.state(target)?;
11729 if target_state.kind() == AtnStateKind::LoopEnd {
11730 return None;
11731 }
11732 state.rule_index()
11733}
11734
11735fn next_alt_number(
11742 state: AtnState<'_>,
11743 transition_count: usize,
11744 transition_index: usize,
11745 current_alt_number: usize,
11746 track_alt_numbers: bool,
11747) -> usize {
11748 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
11749 return current_alt_number;
11750 }
11751 if matches!(
11752 state.kind(),
11753 AtnStateKind::Basic
11754 | AtnStateKind::BlockStart
11755 | AtnStateKind::PlusBlockStart
11756 | AtnStateKind::StarBlockStart
11757 | AtnStateKind::StarLoopEntry
11758 ) && !state.precedence_rule_decision()
11759 {
11760 return transition_index + 1;
11761 }
11762 current_alt_number
11763}
11764
11765fn invoking_state_number(state_number: usize) -> isize {
11768 isize::try_from(state_number).unwrap_or(isize::MAX)
11769}
11770
11771const fn packed_i32(value: u32) -> i32 {
11772 i32::from_le_bytes(value.to_le_bytes())
11773}
11774
11775fn direct_precedence(precedence: i32) -> usize {
11776 usize::try_from(precedence.max(0)).unwrap_or_default()
11777}
11778
11779fn token_input_display(token: &impl Token) -> String {
11780 format!("'{}'", token.text().unwrap_or("<EOF>"))
11781}
11782
11783fn display_input_text(text: &str) -> String {
11784 let mut out = String::new();
11785 for ch in text.chars() {
11786 match ch {
11787 '\n' => out.push_str("\\n"),
11788 '\r' => out.push_str("\\r"),
11789 '\t' => out.push_str("\\t"),
11790 other => out.push(other),
11791 }
11792 }
11793 out
11794}
11795
11796fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
11797 let (line, column) = token.map_or((0, 0), |token| (token.line(), token.column()));
11798 ParserDiagnostic {
11799 line,
11800 column,
11801 message,
11802 }
11803}
11804
11805fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
11806 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
11807}
11808
11809fn expected_symbols_display_iter(
11810 symbols: impl IntoIterator<Item = i32>,
11811 vocabulary: &Vocabulary,
11812) -> String {
11813 let items = symbols
11814 .into_iter()
11815 .map(|symbol| expected_symbol_display(symbol, vocabulary))
11816 .collect::<Vec<_>>();
11817 if let [single] = items.as_slice() {
11818 return single.clone();
11819 }
11820 format!("{{{}}}", items.join(", "))
11821}
11822
11823fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
11824 if symbol == TOKEN_EOF {
11825 return "<EOF>".to_owned();
11826 }
11827 vocabulary.display_name(symbol)
11828}
11829
11830fn caller_follow_token_info_for_stream<S: TokenSource>(
11831 input: &mut CommonTokenStream<S>,
11832 index: usize,
11833) -> (i32, bool, bool) {
11834 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
11837 input.fill();
11838 }
11839 let token_type = input.token_type_at_index(index);
11840 let visible_channel = input.channel();
11841 let token = input.get(index);
11842 let is_boundary = token
11843 .as_ref()
11844 .and_then(Token::text)
11845 .is_some_and(is_caller_follow_boundary_text);
11846 let is_boundary_gap = token.as_ref().is_some_and(|token| {
11847 token.channel() != visible_channel
11848 || is_caller_follow_boundary_gap_text(token.text_or_empty())
11849 });
11850 (token_type, is_boundary, is_boundary_gap)
11851}
11852
11853fn is_caller_follow_boundary_text(text: &str) -> bool {
11854 text.chars().any(|ch| ch == ';' || ch == '\n')
11855 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11856}
11857
11858fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
11859 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11860}
11861
11862fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
11866 let Some(rule_index) = state.rule_index() else {
11867 return false;
11868 };
11869 atn.rule_to_start_state()
11870 .get(rule_index)
11871 .and_then(|state_number| atn.state(state_number))
11872 .is_some_and(AtnState::left_recursive_rule)
11873}
11874
11875fn select_better_top_outcome(
11882 first: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
11883 second: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
11884 arena: &RecognitionArena,
11885) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
11886 match (first, second) {
11887 (Ok(first), Ok(second)) => {
11888 if arena.diagnostics(first.0.diagnostics).next().is_none() {
11889 Ok(first)
11890 } else {
11891 Ok(second)
11892 }
11893 }
11894 (Ok(first), Err(_)) => Ok(first),
11895 (Err(_), Ok(second)) => Ok(second),
11896 (Err(_), Err(second_expected)) => Err(second_expected),
11897 }
11898}
11899
11900fn select_best_fast_outcome(
11906 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
11907 prediction_mode: PredictionMode,
11908 caller_follow: Option<&TokenBitSet>,
11909 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
11910 arena: &RecognitionArena,
11911) -> Option<FastRecognizeOutcome> {
11912 let mut best = None;
11913 let mut best_caller_follow = None;
11914 for outcome in outcomes {
11915 if matches!(
11916 prediction_mode,
11917 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
11918 ) && outcome.diagnostics.is_empty()
11919 && let Some(follow) = caller_follow
11920 {
11921 let (token_type, is_boundary, _) = token_info_at(outcome.index);
11922 if is_boundary && follow.contains(token_type) {
11923 let replace =
11924 best_caller_follow
11925 .as_ref()
11926 .is_none_or(|existing: &FastRecognizeOutcome| {
11927 (outcome.index, outcome.consumed_eof)
11928 < (existing.index, existing.consumed_eof)
11929 });
11930 if replace {
11931 best_caller_follow = Some(outcome);
11932 }
11933 }
11934 }
11935 let Some(existing) = best else {
11936 best = Some(outcome);
11937 continue;
11938 };
11939 let outcome_position = (outcome.index, outcome.consumed_eof);
11940 let best_position = (existing.index, existing.consumed_eof);
11941 let better = match prediction_mode {
11942 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
11943 outcome_position,
11944 outcome.diagnostics,
11945 best_position,
11946 existing.diagnostics,
11947 arena,
11948 ),
11949 PredictionMode::Sll => outcome.index > existing.index,
11950 };
11951 best = Some(if better { outcome } else { existing });
11952 }
11953 let should_use_caller_follow =
11954 best_caller_follow
11955 .as_ref()
11956 .zip(best.as_ref())
11957 .is_some_and(|(candidate, selected)| {
11958 if !selected.diagnostics.is_empty() {
11959 return true;
11960 }
11961 candidate.index < selected.index
11962 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
11963 });
11964 if should_use_caller_follow {
11965 best_caller_follow
11966 } else {
11967 best
11968 }
11969}
11970
11971fn select_best_outcome(
11972 outcomes: impl Iterator<Item = RecognizeOutcome>,
11973 prediction_mode: PredictionMode,
11974 arena: &RecognitionArena,
11975) -> Option<RecognizeOutcome> {
11976 let outcomes = outcomes.collect::<Vec<_>>();
11977 let prefer_first_tie = outcomes
11978 .iter()
11979 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
11980 outcomes.into_iter().reduce(|best, outcome| {
11981 let outcome_position = (outcome.index, outcome.consumed_eof);
11982 let best_position = (best.index, best.consumed_eof);
11983 let better = match prediction_mode {
11984 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
11985 outcome_is_better(
11986 outcome_position,
11987 outcome.diagnostics,
11988 best_position,
11989 best.diagnostics,
11990 arena,
11991 ) || (!prefer_first_tie
11992 && outcome_position == best_position
11993 && arena.diagnostics_len(outcome.diagnostics)
11994 == arena.diagnostics_len(best.diagnostics)
11995 && arena.diagnostics_recovery_rank(outcome.diagnostics)
11996 == arena.diagnostics_recovery_rank(best.diagnostics)
11997 && (outcome.decisions < best.decisions
11998 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
11999 }
12000 PredictionMode::Sll => {
12001 outcome_position > best_position
12002 || (outcome_position == best_position
12003 && !prefer_first_tie
12004 && (outcome.decisions < best.decisions
12005 || (outcome.decisions == best.decisions
12006 && outcome_is_better(
12007 outcome_position,
12008 outcome.diagnostics,
12009 best_position,
12010 best.diagnostics,
12011 arena,
12012 ))))
12013 }
12014 };
12015 if better {
12016 return outcome;
12017 }
12018 best
12019 })
12020}
12021
12022fn transition_decision(
12029 atn: &Atn,
12030 state: AtnState<'_>,
12031 transition_count: usize,
12032 transition_index: usize,
12033 predicates: &[(usize, usize, ParserPredicate)],
12034) -> Option<usize> {
12035 if transition_count <= 1
12036 || state.precedence_rule_decision()
12037 || decision_reaches_unsupported_predicate(atn, state, predicates)
12038 {
12039 return None;
12040 }
12041 Some(transition_index)
12042}
12043
12044fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
12050 transition_count > 1
12051 && !matches!(
12052 state.kind(),
12053 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
12054 )
12055}
12056
12057fn record_no_viable_if_ambiguous(
12060 expected: &mut ExpectedTokens,
12061 decision_start_index: Option<usize>,
12062 index: usize,
12063) {
12064 if expected.index == Some(index) && expected.symbols.len() > 1 {
12065 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
12066 expected.record_no_viable(decision_start, index);
12067 }
12068 }
12069}
12070
12071const fn record_predicate_no_viable(
12074 expected: &mut ExpectedTokens,
12075 decision_start_index: Option<usize>,
12076 index: usize,
12077) {
12078 if let Some(decision_start) = decision_start_index {
12079 expected.record_no_viable(decision_start, index);
12080 }
12081}
12082
12083const fn no_viable_decision_start(
12085 decision_start_index: Option<usize>,
12086 index: usize,
12087) -> Option<usize> {
12088 match decision_start_index {
12089 Some(start) if index > start => Some(start),
12090 _ => None,
12091 }
12092}
12093
12094fn restore_expected(
12098 children: &[RecognizeOutcome],
12099 child_start_index: usize,
12100 expected: &mut ExpectedTokens,
12101 snapshot: ExpectedTokens,
12102 preserve_child_expected: bool,
12103) {
12104 if preserve_child_expected {
12105 return;
12106 }
12107 if children
12108 .iter()
12109 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
12110 {
12111 *expected = snapshot;
12112 }
12113}
12114
12115fn decision_reaches_unsupported_predicate(
12118 atn: &Atn,
12119 state: AtnState<'_>,
12120 predicates: &[(usize, usize, ParserPredicate)],
12121) -> bool {
12122 state.transitions().iter().any(|transition| {
12123 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
12124 })
12125}
12126
12127fn transition_reaches_unsupported_predicate(
12129 atn: &Atn,
12130 transition: ParserTransition<'_>,
12131 predicates: &[(usize, usize, ParserPredicate)],
12132 visited: &mut BTreeSet<usize>,
12133) -> bool {
12134 match &transition.data() {
12135 Transition::Predicate {
12136 rule_index,
12137 pred_index,
12138 ..
12139 } => !predicates
12140 .iter()
12141 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
12142 Transition::Epsilon { target }
12143 | Transition::Action { target, .. }
12144 | Transition::Rule { target, .. } => {
12145 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
12146 }
12147 Transition::Precedence { .. }
12148 | Transition::Atom { .. }
12149 | Transition::Range { .. }
12150 | Transition::Set { .. }
12151 | Transition::NotSet { .. }
12152 | Transition::Wildcard { .. } => false,
12153 }
12154}
12155
12156fn state_reaches_unsupported_predicate(
12158 atn: &Atn,
12159 state_number: usize,
12160 predicates: &[(usize, usize, ParserPredicate)],
12161 visited: &mut BTreeSet<usize>,
12162) -> bool {
12163 if !visited.insert(state_number) {
12164 return false;
12165 }
12166 let Some(state) = atn.state(state_number) else {
12167 return false;
12168 };
12169 state.transitions().iter().any(|transition| {
12170 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
12171 })
12172}
12173
12174fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
12176 if let Some(decision) = decision {
12177 outcome.decisions.insert(0, decision);
12178 }
12179}
12180
12181fn outcome_is_better(
12182 outcome_position: (usize, bool),
12183 outcome_diagnostics: DiagnosticSeqId,
12184 best_position: (usize, bool),
12185 best_diagnostics: DiagnosticSeqId,
12186 arena: &RecognitionArena,
12187) -> bool {
12188 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
12189 let best_len = arena.diagnostics_len(best_diagnostics);
12190 outcome_position > best_position
12191 || (outcome_position == best_position
12192 && (outcome_len < best_len
12193 || (outcome_len == best_len
12194 && arena.diagnostics_recovery_rank(outcome_diagnostics)
12195 < arena.diagnostics_recovery_rank(best_diagnostics))))
12196}
12197
12198fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
12199 if outcomes
12200 .iter()
12201 .any(|outcome| outcome.diagnostics.is_empty())
12202 {
12203 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
12204 }
12205}
12206
12207fn discard_recovered_outcomes_if_clean_path_exists(
12208 outcomes: &mut Vec<RecognizeOutcome>,
12209 arena: &RecognitionArena,
12210) {
12211 if outcomes
12212 .iter()
12213 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
12214 {
12215 return;
12216 }
12217 if outcomes
12218 .iter()
12219 .any(|outcome| outcome.diagnostics.is_empty())
12220 {
12221 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
12222 }
12223}
12224
12225fn outcome_has_rule_failure_diagnostic(
12228 outcome: &RecognizeOutcome,
12229 arena: &RecognitionArena,
12230) -> bool {
12231 arena
12232 .diagnostics(outcome.diagnostics)
12233 .any(|diagnostic| diagnostic.message.starts_with("rule "))
12234}
12235
12236fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
12250 if outcomes.len() < 2 {
12251 return;
12252 }
12253 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
12254 outcomes.retain(|outcome| {
12255 seen.insert((
12256 outcome.index,
12257 outcome.consumed_eof,
12258 arena.diagnostics_len(outcome.diagnostics),
12259 arena.diagnostics_recovery_rank(outcome.diagnostics),
12260 ))
12261 });
12262}
12263
12264const FAST_OUTCOME_INLINE_KEYS: usize = 8;
12265const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
12266const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
12267const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
12268
12269#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12270enum FastOutcomeDedupStrategy {
12271 Inline,
12272 Dense,
12273 Sparse,
12274}
12275
12276impl FastOutcomeDedupScratch {
12277 fn prepare_dense(&mut self, word_count: usize) {
12278 while let Some(word_index) = self.touched_dense_words.pop() {
12279 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
12280 }
12281 if self.dense_words.len() < word_count {
12282 self.dense_words.resize(word_count, 0);
12283 }
12284 }
12285}
12286
12287fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
12288 let first_index = outcomes.first()?.index;
12289 let (min_index, max_index) = outcomes[1..].iter().fold(
12290 (first_index, first_index),
12291 |(min_index, max_index), outcome| {
12292 (min_index.min(outcome.index), max_index.max(outcome.index))
12293 },
12294 );
12295 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
12296 let bit_count = index_span.checked_mul(2)?;
12297 let word_count =
12298 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
12299 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
12300 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
12301 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
12302 .then_some((min_index, word_count))
12303}
12304
12305#[cfg(feature = "perf-counters")]
12306fn record_clean_fast_outcome_dedup(
12307 strategy: FastOutcomeDedupStrategy,
12308 input_len: usize,
12309 output_len: usize,
12310 dense_words: usize,
12311) {
12312 let counter = match strategy {
12313 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
12314 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
12315 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
12316 };
12317 perf_counters::inc(
12318 &perf_counters::OUTCOME_DEDUPE_INPUTS,
12319 u64::try_from(input_len).unwrap_or(u64::MAX),
12320 );
12321 perf_counters::inc(
12322 &perf_counters::OUTCOME_DEDUPE_REMOVED,
12323 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
12324 );
12325 perf_counters::inc(counter, 1);
12326 perf_counters::inc(
12327 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
12328 u64::try_from(dense_words).unwrap_or(u64::MAX),
12329 );
12330}
12331
12332fn dedupe_clean_fast_outcomes(
12336 outcomes: &mut Vec<FastRecognizeOutcome>,
12337 scratch: &mut FastOutcomeDedupScratch,
12338) -> FastOutcomeDedupStrategy {
12339 #[cfg(feature = "perf-counters")]
12340 let input_len = outcomes.len();
12341 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
12342 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
12343 let mut inline_len = 0_usize;
12344 outcomes.retain(|outcome| {
12345 let key = (outcome.index, outcome.consumed_eof);
12346 if inline_keys[..inline_len].contains(&key) {
12347 return false;
12348 }
12349 inline_keys[inline_len] = key;
12350 inline_len += 1;
12351 true
12352 });
12353 #[cfg(feature = "perf-counters")]
12354 record_clean_fast_outcome_dedup(
12355 FastOutcomeDedupStrategy::Inline,
12356 input_len,
12357 outcomes.len(),
12358 0,
12359 );
12360 return FastOutcomeDedupStrategy::Inline;
12361 }
12362
12363 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
12364 scratch.prepare_dense(word_count);
12365 outcomes.retain(|outcome| {
12366 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
12367 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
12368 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
12369 let word = &mut scratch.dense_words[word_index];
12370 if *word & bit != 0 {
12371 return false;
12372 }
12373 if *word == 0 {
12374 scratch
12375 .touched_dense_words
12376 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
12377 }
12378 *word |= bit;
12379 true
12380 });
12381 #[cfg(feature = "perf-counters")]
12382 record_clean_fast_outcome_dedup(
12383 FastOutcomeDedupStrategy::Dense,
12384 input_len,
12385 outcomes.len(),
12386 word_count,
12387 );
12388 return FastOutcomeDedupStrategy::Dense;
12389 }
12390
12391 scratch.sparse_keys.clear();
12392 scratch.sparse_keys.reserve(outcomes.len());
12393 outcomes.retain(|outcome| {
12394 scratch
12395 .sparse_keys
12396 .insert((outcome.index, outcome.consumed_eof))
12397 });
12398 #[cfg(feature = "perf-counters")]
12399 record_clean_fast_outcome_dedup(
12400 FastOutcomeDedupStrategy::Sparse,
12401 input_len,
12402 outcomes.len(),
12403 0,
12404 );
12405 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
12406 scratch.sparse_keys = FxHashSet::default();
12407 }
12408 FastOutcomeDedupStrategy::Sparse
12409}
12410
12411fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
12414 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
12415 outcomes
12416 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
12417}
12418
12419fn compare_recognize_outcomes(
12420 left: &RecognizeOutcome,
12421 right: &RecognizeOutcome,
12422 arena: &RecognitionArena,
12423) -> Ordering {
12424 left.index
12425 .cmp(&right.index)
12426 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
12427 .then_with(|| left.alt_number.cmp(&right.alt_number))
12428 .then_with(|| left.member_values.cmp(&right.member_values))
12429 .then_with(|| left.return_values.cmp(&right.return_values))
12430 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
12431 .then_with(|| left.decisions.cmp(&right.decisions))
12432 .then_with(|| left.actions.cmp(&right.actions))
12433 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
12434}
12435
12436impl<S, H> Recognizer for BaseParser<S, H>
12437where
12438 S: TokenSource,
12439 H: SemanticHooks,
12440{
12441 fn data(&self) -> &RecognizerData {
12442 &self.data
12443 }
12444
12445 fn data_mut(&mut self) -> &mut RecognizerData {
12446 &mut self.data
12447 }
12448}
12449
12450impl<S, H> Parser for BaseParser<S, H>
12451where
12452 S: TokenSource,
12453 H: SemanticHooks,
12454{
12455 fn build_parse_trees(&self) -> bool {
12456 self.build_parse_trees
12457 }
12458
12459 fn set_build_parse_trees(&mut self, build: bool) {
12460 self.build_parse_trees = build;
12461 }
12462
12463 fn number_of_syntax_errors(&self) -> usize {
12464 Self::number_of_syntax_errors(self)
12465 }
12466
12467 fn report_diagnostic_errors(&self) -> bool {
12468 self.report_diagnostic_errors
12469 }
12470
12471 fn set_report_diagnostic_errors(&mut self, report: bool) {
12472 self.report_diagnostic_errors = report;
12473 }
12474
12475 fn prediction_mode(&self) -> PredictionMode {
12476 self.prediction_mode
12477 }
12478
12479 fn set_prediction_mode(&mut self, mode: PredictionMode) {
12480 self.prediction_mode = mode;
12481 }
12482}
12483
12484#[cfg(test)]
12485#[allow(clippy::disallowed_methods)] mod tests {
12487 use super::*;
12488 use crate::atn::parser::{
12489 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
12490 };
12491 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
12492 use crate::token::{HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError};
12493 use crate::token_stream::CommonTokenStream;
12494 use crate::tree::{NodeKind, ParseTreeStats};
12495 use crate::vocabulary::Vocabulary;
12496 use std::cell::RefCell;
12497 use std::mem::size_of;
12498 use std::rc::Rc;
12499 use std::sync::{Arc, Mutex};
12500
12501 #[test]
12502 fn fx_hasher_write_matches_typed_methods_for_full_words() {
12503 let value: u64 = 0x0102_0304_0506_0708;
12510 let mut typed = FxHasher::default();
12511 typed.write_u64(value);
12512 let mut bytewise = FxHasher::default();
12513 bytewise.write(&value.to_le_bytes());
12514 assert_eq!(typed.finish(), bytewise.finish());
12515 }
12516
12517 #[derive(Clone, Debug)]
12518 struct TestToken {
12519 spec: TokenSpec,
12520 id: TokenId,
12521 source_name: String,
12522 }
12523
12524 impl TestToken {
12525 fn new(token_type: i32) -> Self {
12526 Self {
12527 spec: TokenSpec::explicit(token_type, ""),
12528 id: TokenId::try_from(0).expect("zero token ID"),
12529 source_name: String::new(),
12530 }
12531 }
12532
12533 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
12534 Self {
12535 spec: TokenSpec::eof(index, index, line, column),
12536 id: TokenId::try_from(0).expect("zero token ID"),
12537 source_name: source_name.to_owned(),
12538 }
12539 }
12540
12541 fn with_text(mut self, text: impl Into<String>) -> Self {
12542 self.spec.text = Some(text.into());
12543 self
12544 }
12545
12546 const fn with_channel(mut self, channel: i32) -> Self {
12547 self.spec.channel = channel;
12548 self
12549 }
12550
12551 const fn with_span(mut self, start: usize, stop: usize) -> Self {
12552 self.spec.start = start;
12553 self.spec.stop = stop;
12554 self.spec.start_byte = start;
12555 self.spec.stop_byte = match stop.checked_add(1) {
12556 Some(end) if end >= start => end,
12557 Some(_) | None => start,
12558 };
12559 self
12560 }
12561
12562 const fn with_position(mut self, line: usize, column: usize) -> Self {
12563 self.spec.line = line;
12564 self.spec.column = column;
12565 self
12566 }
12567
12568 fn set_token_index(&mut self, index: isize) {
12569 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
12570 }
12571 }
12572
12573 impl Token for TestToken {
12574 fn token_id(&self) -> TokenId {
12575 self.id
12576 }
12577
12578 fn token_type(&self) -> i32 {
12579 self.spec.token_type
12580 }
12581
12582 fn channel(&self) -> i32 {
12583 self.spec.channel
12584 }
12585
12586 fn start(&self) -> usize {
12587 self.spec.start
12588 }
12589
12590 fn stop(&self) -> usize {
12591 self.spec.stop
12592 }
12593
12594 fn line(&self) -> usize {
12595 self.spec.line
12596 }
12597
12598 fn column(&self) -> usize {
12599 self.spec.column
12600 }
12601
12602 fn text(&self) -> Option<&str> {
12603 self.spec.text.as_deref()
12604 }
12605
12606 fn source_name(&self) -> &str {
12607 &self.source_name
12608 }
12609
12610 fn start_byte(&self) -> usize {
12611 self.spec.start_byte
12612 }
12613
12614 fn stop_byte(&self) -> usize {
12615 self.spec.stop_byte
12616 }
12617 }
12618
12619 #[derive(Debug)]
12620 struct Source {
12621 tokens: Vec<TestToken>,
12622 index: usize,
12623 }
12624
12625 impl TokenSource for Source {
12626 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
12627 let token = self
12628 .tokens
12629 .get(self.index)
12630 .cloned()
12631 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
12632 self.index += 1;
12633 sink.push(token.spec)
12634 }
12635
12636 fn line(&self) -> usize {
12637 1
12638 }
12639
12640 fn column(&self) -> usize {
12641 self.index
12642 }
12643
12644 fn source_name(&self) -> &'static str {
12645 "parser-test"
12646 }
12647 }
12648
12649 #[derive(Clone, Debug, Eq, PartialEq)]
12650 struct RecordedDiagnostic {
12651 grammar_file_name: String,
12652 line: usize,
12653 column: usize,
12654 message: String,
12655 error: Option<AntlrError>,
12656 }
12657
12658 #[derive(Clone, Debug)]
12659 struct RecordingErrorListener {
12660 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
12661 }
12662
12663 impl<R> crate::ErrorListener<R> for RecordingErrorListener
12664 where
12665 R: Recognizer + ?Sized,
12666 {
12667 fn syntax_error(
12668 &mut self,
12669 recognizer: &R,
12670 line: usize,
12671 column: usize,
12672 message: &str,
12673 error: Option<&AntlrError>,
12674 ) {
12675 self.diagnostics
12676 .lock()
12677 .expect("recorded diagnostics lock")
12678 .push(RecordedDiagnostic {
12679 grammar_file_name: recognizer.grammar_file_name().to_owned(),
12680 line,
12681 column,
12682 message: message.to_owned(),
12683 error: error.cloned(),
12684 });
12685 }
12686 }
12687
12688 #[derive(Debug)]
12689 struct ReportingSource {
12690 source: Source,
12691 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
12692 }
12693
12694 impl TokenSource for ReportingSource {
12695 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
12696 self.source.next_token(sink)
12697 }
12698
12699 fn line(&self) -> usize {
12700 self.source.line()
12701 }
12702
12703 fn column(&self) -> usize {
12704 self.source.column()
12705 }
12706
12707 fn source_name(&self) -> &str {
12708 self.source.source_name()
12709 }
12710
12711 fn report_error(&self, error: &TokenSourceError) -> bool {
12712 self.diagnostics.borrow_mut().push(error.clone());
12713 true
12714 }
12715 }
12716
12717 fn mini_parser_data() -> RecognizerData {
12718 RecognizerData::new(
12719 "Mini.g4",
12720 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
12721 )
12722 .with_rule_names(["s"])
12723 }
12724
12725 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
12726 let data = mini_parser_data();
12727 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
12728 }
12729
12730 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
12731 where
12732 H: SemanticHooks,
12733 {
12734 BaseParser::with_semantic_hooks(
12735 CommonTokenStream::new(Source { tokens, index: 0 }),
12736 mini_parser_data(),
12737 hooks,
12738 )
12739 }
12740
12741 #[test]
12742 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
12743 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
12744 parser.remove_error_listeners();
12745 let diagnostics = Arc::new(Mutex::new(Vec::new()));
12746 parser.add_error_listener(RecordingErrorListener {
12747 diagnostics: Arc::clone(&diagnostics),
12748 });
12749 let parser_diagnostics = [ParserDiagnostic {
12750 line: 1,
12751 column: 2,
12752 message: "missing 'x' at 'y'".to_owned(),
12753 }];
12754 let token_errors = [
12755 TokenSourceError::new(1, 1, "token recognition error at: '@'"),
12756 TokenSourceError::new(1, 3, "token recognition error at: '#'"),
12757 ];
12758
12759 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
12760
12761 insta::assert_debug_snapshot!(
12764 "parser_dispatches_recovery_diagnostics_through_registered_listeners",
12765 *diagnostics.lock().expect("recorded diagnostics lock")
12766 );
12767
12768 parser.remove_error_listeners();
12769 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
12770 assert_eq!(
12771 diagnostics.lock().expect("recorded diagnostics lock").len(),
12772 3
12773 );
12774 }
12775
12776 #[test]
12777 fn parser_leaves_token_errors_to_source_owned_listeners() {
12778 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
12779 let source = ReportingSource {
12780 source: Source {
12781 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
12782 index: 0,
12783 },
12784 diagnostics: Rc::clone(&source_diagnostics),
12785 };
12786 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
12787 parser.remove_error_listeners();
12788 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
12789 parser.add_error_listener(RecordingErrorListener {
12790 diagnostics: Arc::clone(&parser_diagnostics),
12791 });
12792 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
12793
12794 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
12795
12796 assert_eq!(*source_diagnostics.borrow(), [source_error]);
12797 assert!(
12798 parser_diagnostics
12799 .lock()
12800 .expect("recorded diagnostics lock")
12801 .is_empty()
12802 );
12803 }
12804
12805 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
12806 builder.finish().expect("valid packed parser ATN")
12807 }
12808
12809 fn nested_rule_chain_atn(depth: usize) -> Atn {
12810 nested_rule_graph_atn(depth, false, false)
12811 }
12812
12813 fn nested_rule_graph_atn(depth: usize, branching: bool, consuming_follows: bool) -> Atn {
12814 assert!(depth > 0);
12815 let mut atn = ParserAtnBuilder::new(2);
12816 let mut starts = Vec::with_capacity(depth);
12817 let mut stops = Vec::with_capacity(depth);
12818 let mut follows = Vec::with_capacity(depth.saturating_sub(1));
12819 for rule_index in 0..depth {
12820 starts.push(
12821 atn.add_state(AtnStateKind::RuleStart, Some(rule_index))
12822 .expect("rule start")
12823 .index(),
12824 );
12825 }
12826 for rule_index in 0..depth {
12827 stops.push(
12828 atn.add_state(AtnStateKind::RuleStop, Some(rule_index))
12829 .expect("rule stop")
12830 .index(),
12831 );
12832 }
12833 if consuming_follows {
12834 for rule_index in 0..depth - 1 {
12835 follows.push(
12836 atn.add_state(AtnStateKind::Basic, Some(rule_index))
12837 .expect("rule follow")
12838 .index(),
12839 );
12840 }
12841 }
12842 atn.set_rule_to_start_state(starts.clone())
12843 .expect("rule start states");
12844 atn.set_rule_to_stop_state(stops.clone())
12845 .expect("rule stop states");
12846 for rule_index in 0..depth - 1 {
12847 let follow_state = if consuming_follows {
12848 follows[rule_index]
12849 } else {
12850 stops[rule_index]
12851 };
12852 atn.add_transition(
12853 starts[rule_index],
12854 ParserTransitionSpec::Rule {
12855 target: starts[rule_index + 1],
12856 rule_index: rule_index + 1,
12857 follow_state,
12858 precedence: 0,
12859 },
12860 )
12861 .expect("nested rule transition");
12862 if branching {
12863 atn.add_transition(
12864 starts[rule_index],
12865 ParserTransitionSpec::Atom {
12866 target: stops[rule_index],
12867 label: 2,
12868 },
12869 )
12870 .expect("dead branch transition");
12871 }
12872 if consuming_follows {
12873 atn.add_transition(
12874 follow_state,
12875 ParserTransitionSpec::Atom {
12876 target: stops[rule_index],
12877 label: 1,
12878 },
12879 )
12880 .expect("consuming follow transition");
12881 }
12882 }
12883 let token_set = atn.add_interval_set([(1, 1)]).expect("token set");
12884 atn.add_transition(
12885 starts[depth - 1],
12886 ParserTransitionSpec::Set {
12887 target: stops[depth - 1],
12888 set: token_set,
12889 },
12890 )
12891 .expect("terminal set transition");
12892 if branching {
12893 atn.add_transition(
12894 starts[depth - 1],
12895 ParserTransitionSpec::Atom {
12896 target: stops[depth - 1],
12897 label: 2,
12898 },
12899 )
12900 .expect("dead leaf branch transition");
12901 }
12902 finish_atn(atn)
12903 }
12904
12905 fn ordinary_star_loop_atn() -> Atn {
12906 let mut atn = ParserAtnBuilder::new(2);
12907 for (state_number, kind, rule_index) in [
12908 (0, AtnStateKind::RuleStart, 0),
12909 (1, AtnStateKind::StarLoopEntry, 0),
12910 (2, AtnStateKind::Basic, 0),
12911 (3, AtnStateKind::StarLoopBack, 0),
12912 (4, AtnStateKind::LoopEnd, 0),
12913 (5, AtnStateKind::Basic, 0),
12914 (6, AtnStateKind::RuleStop, 0),
12915 (7, AtnStateKind::RuleStart, 1),
12916 (8, AtnStateKind::Basic, 1),
12917 (9, AtnStateKind::RuleStop, 1),
12918 ] {
12919 assert_eq!(
12920 atn.add_state(kind, Some(rule_index))
12921 .expect("state")
12922 .index(),
12923 state_number
12924 );
12925 }
12926 atn.set_rule_to_start_state(vec![0, 7])
12927 .expect("rule start states");
12928 atn.set_rule_to_stop_state(vec![6, 9])
12929 .expect("rule stop states");
12930 atn.add_decision_state(1).expect("decision state");
12931 atn.set_loop_back_state(4, 3).expect("loop back state");
12932 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12933 .expect("transition");
12934 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12935 .expect("transition");
12936 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
12937 .expect("transition");
12938 atn.add_transition(
12939 2,
12940 ParserTransitionSpec::Rule {
12941 target: 7,
12942 rule_index: 1,
12943 follow_state: 3,
12944 precedence: 0,
12945 },
12946 )
12947 .expect("transition");
12948 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
12949 .expect("transition");
12950 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12951 .expect("transition");
12952 atn.add_transition(
12953 5,
12954 ParserTransitionSpec::Atom {
12955 target: 6,
12956 label: TOKEN_EOF,
12957 },
12958 )
12959 .expect("transition");
12960 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
12961 .expect("transition");
12962 atn.add_transition(
12963 8,
12964 ParserTransitionSpec::Atom {
12965 target: 9,
12966 label: 1,
12967 },
12968 )
12969 .expect("transition");
12970 finish_atn(atn)
12971 }
12972
12973 fn ambiguous_ordinary_star_loop_atn() -> Atn {
12975 let mut atn = ParserAtnBuilder::new(1);
12976 for (state_number, kind) in [
12977 (0, AtnStateKind::RuleStart),
12978 (1, AtnStateKind::StarLoopEntry),
12979 (2, AtnStateKind::StarBlockStart),
12980 (3, AtnStateKind::Basic),
12981 (4, AtnStateKind::BlockEnd),
12982 (5, AtnStateKind::StarLoopBack),
12983 (6, AtnStateKind::LoopEnd),
12984 (7, AtnStateKind::Basic),
12985 (8, AtnStateKind::RuleStop),
12986 ] {
12987 assert_eq!(
12988 atn.add_state(kind, Some(0)).expect("state").index(),
12989 state_number
12990 );
12991 }
12992 atn.set_rule_to_start_state(vec![0])
12993 .expect("rule start states");
12994 atn.set_rule_to_stop_state(vec![8])
12995 .expect("rule stop states");
12996 atn.set_end_state(2, 4).expect("block end state");
12997 atn.set_loop_back_state(6, 5).expect("loop back state");
12998 atn.add_decision_state(1).expect("decision state");
12999 atn.add_decision_state(2).expect("decision state");
13000 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13001 .expect("transition");
13002 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13003 .expect("transition");
13004 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
13005 .expect("transition");
13006 atn.add_transition(
13007 2,
13008 ParserTransitionSpec::Atom {
13009 target: 4,
13010 label: 1,
13011 },
13012 )
13013 .expect("transition");
13014 atn.add_transition(
13015 2,
13016 ParserTransitionSpec::Atom {
13017 target: 3,
13018 label: 1,
13019 },
13020 )
13021 .expect("transition");
13022 atn.add_transition(
13023 3,
13024 ParserTransitionSpec::Atom {
13025 target: 4,
13026 label: 1,
13027 },
13028 )
13029 .expect("transition");
13030 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13031 .expect("transition");
13032 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
13033 .expect("transition");
13034 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13035 .expect("transition");
13036 atn.add_transition(
13037 7,
13038 ParserTransitionSpec::Atom {
13039 target: 8,
13040 label: TOKEN_EOF,
13041 },
13042 )
13043 .expect("transition");
13044 finish_atn(atn)
13045 }
13046
13047 fn ordinary_plus_loop_atn() -> Atn {
13048 let mut atn = ParserAtnBuilder::new(2);
13049 for (state_number, kind, rule_index) in [
13050 (0, AtnStateKind::RuleStart, 0),
13051 (1, AtnStateKind::Basic, 0),
13052 (2, AtnStateKind::PlusLoopBack, 0),
13053 (3, AtnStateKind::LoopEnd, 0),
13054 (4, AtnStateKind::Basic, 0),
13055 (5, AtnStateKind::RuleStop, 0),
13056 (6, AtnStateKind::RuleStart, 1),
13057 (7, AtnStateKind::Basic, 1),
13058 (8, AtnStateKind::RuleStop, 1),
13059 ] {
13060 assert_eq!(
13061 atn.add_state(kind, Some(rule_index))
13062 .expect("state")
13063 .index(),
13064 state_number
13065 );
13066 }
13067 atn.set_rule_to_start_state(vec![0, 6])
13068 .expect("rule start states");
13069 atn.set_rule_to_stop_state(vec![5, 8])
13070 .expect("rule stop states");
13071 atn.add_decision_state(2).expect("decision state");
13072 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13073 .expect("transition");
13074 atn.add_transition(
13075 1,
13076 ParserTransitionSpec::Rule {
13077 target: 6,
13078 rule_index: 1,
13079 follow_state: 2,
13080 precedence: 0,
13081 },
13082 )
13083 .expect("transition");
13084 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
13085 .expect("transition");
13086 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13087 .expect("transition");
13088 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
13089 .expect("transition");
13090 atn.add_transition(
13091 4,
13092 ParserTransitionSpec::Atom {
13093 target: 5,
13094 label: TOKEN_EOF,
13095 },
13096 )
13097 .expect("transition");
13098 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13099 .expect("transition");
13100 atn.add_transition(
13101 7,
13102 ParserTransitionSpec::Atom {
13103 target: 8,
13104 label: 1,
13105 },
13106 )
13107 .expect("transition");
13108 finish_atn(atn)
13109 }
13110
13111 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
13112 let mut tokens = (0..count)
13113 .map(|_| TestToken::new(1).with_text("x"))
13114 .collect::<Vec<_>>();
13115 tokens.push(TestToken::eof("parser-test", count, 1, count));
13116 tokens
13117 }
13118
13119 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
13120 let mut atn = ParserAtnBuilder::new(2);
13121 assert_eq!(
13122 atn.add_state(AtnStateKind::RuleStart, Some(0))
13123 .expect("state")
13124 .index(),
13125 0
13126 );
13127 assert_eq!(
13128 atn.add_state(AtnStateKind::Basic, Some(0))
13129 .expect("state")
13130 .index(),
13131 1
13132 );
13133 assert_eq!(
13134 atn.add_state(AtnStateKind::Basic, Some(0))
13135 .expect("state")
13136 .index(),
13137 2
13138 );
13139 assert_eq!(
13140 atn.add_state(AtnStateKind::RuleStart, Some(1))
13141 .expect("state")
13142 .index(),
13143 3
13144 );
13145 atn.set_left_recursive_rule(3)
13146 .expect("left-recursive rule start");
13147 assert_eq!(
13148 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
13149 .expect("state")
13150 .index(),
13151 4
13152 );
13153 atn.set_precedence_rule_decision(4)
13154 .expect("precedence decision");
13155 assert_eq!(
13156 atn.add_state(AtnStateKind::Basic, Some(1))
13157 .expect("state")
13158 .index(),
13159 5
13160 );
13161 assert_eq!(
13162 atn.add_state(AtnStateKind::Basic, Some(1))
13163 .expect("state")
13164 .index(),
13165 6
13166 );
13167 assert_eq!(
13168 atn.add_state(AtnStateKind::LoopEnd, Some(1))
13169 .expect("state")
13170 .index(),
13171 7
13172 );
13173 assert_eq!(
13174 atn.add_state(AtnStateKind::RuleStop, Some(1))
13175 .expect("state")
13176 .index(),
13177 8
13178 );
13179 assert_eq!(
13180 atn.add_state(AtnStateKind::RuleStop, Some(0))
13181 .expect("state")
13182 .index(),
13183 9
13184 );
13185 atn.set_rule_to_start_state(vec![0, 3])
13186 .expect("rule start states");
13187 atn.set_rule_to_stop_state(vec![9, 8])
13188 .expect("rule stop states");
13189 atn.add_transition(
13190 1,
13191 ParserTransitionSpec::Rule {
13192 target: 3,
13193 rule_index: 1,
13194 follow_state: 2,
13195 precedence: 0,
13196 },
13197 )
13198 .expect("transition");
13199 atn.add_transition(
13200 2,
13201 ParserTransitionSpec::Atom {
13202 target: 9,
13203 label: caller_symbol,
13204 },
13205 )
13206 .expect("transition");
13207 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13208 .expect("transition");
13209 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
13210 .expect("transition");
13211 atn.add_transition(
13212 5,
13213 ParserTransitionSpec::Precedence {
13214 target: 6,
13215 precedence: 1,
13216 },
13217 )
13218 .expect("transition");
13219 atn.add_transition(
13220 6,
13221 ParserTransitionSpec::Atom {
13222 target: 4,
13223 label: 1,
13224 },
13225 )
13226 .expect("transition");
13227 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
13228 .expect("transition");
13229 finish_atn(atn)
13230 }
13231
13232 fn labeled_left_recursive_operator_atn() -> Atn {
13233 let mut atn = ParserAtnBuilder::new(4);
13234 for (state, kind) in [
13235 (0, AtnStateKind::RuleStart),
13236 (1, AtnStateKind::BlockStart),
13237 (2, AtnStateKind::StarLoopEntry),
13238 (3, AtnStateKind::StarBlockStart),
13239 (4, AtnStateKind::Basic),
13240 (5, AtnStateKind::Basic),
13241 (6, AtnStateKind::Basic),
13242 (7, AtnStateKind::StarLoopBack),
13243 (8, AtnStateKind::LoopEnd),
13244 (9, AtnStateKind::RuleStop),
13245 ] {
13246 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13247 }
13248 atn.set_left_recursive_rule(0)
13249 .expect("left-recursive rule start");
13250 atn.set_precedence_rule_decision(2)
13251 .expect("precedence decision");
13252 atn.set_loop_back_state(8, 7).expect("loop-back state");
13253 atn.set_rule_to_start_state(vec![0])
13254 .expect("rule start states");
13255 atn.set_rule_to_stop_state(vec![9])
13256 .expect("rule stop states");
13257 for state in [1, 2, 3] {
13258 atn.add_decision_state(state).expect("decision state");
13259 }
13260 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
13261 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
13262 .expect("epsilon transition");
13263 }
13264 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3), (6, 7, 1)] {
13265 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
13266 .expect("token transition");
13267 }
13268 for (target, precedence) in [(4, 2), (5, 1)] {
13269 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
13270 .expect("operator precedence");
13271 }
13272 finish_atn(atn)
13273 }
13274
13275 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
13276 let mut parser = mini_parser(vec![
13277 TestToken::new(symbol).with_text("lookahead"),
13278 TestToken::eof("parser-test", 1, 1, 1),
13279 ]);
13280 parser.rule_context_stack = vec![
13281 RuleContextFrame {
13282 rule_index: 0,
13283 invoking_state: -1,
13284 },
13285 RuleContextFrame {
13286 rule_index: 1,
13287 invoking_state: 1,
13288 },
13289 ];
13290 parser
13291 }
13292
13293 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
13294 let mut atn = ParserAtnBuilder::new(1);
13298 for (state, kind, rule) in [
13299 (0, AtnStateKind::RuleStart, 0),
13300 (1, AtnStateKind::StarLoopEntry, 0),
13301 (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),
13308 (9, AtnStateKind::RuleStop, 0),
13309 ] {
13310 assert_eq!(
13311 atn.add_state(kind, Some(rule)).expect("state").index(),
13312 state
13313 );
13314 if state == 0 {
13315 atn.set_left_recursive_rule(state)
13316 .expect("left-recursive rule start");
13317 } else if state == 1 {
13318 atn.set_precedence_rule_decision(state)
13319 .expect("precedence decision");
13320 }
13321 }
13322 atn.set_rule_to_start_state(vec![0])
13323 .expect("rule start states");
13324 atn.set_rule_to_stop_state(vec![9])
13325 .expect("rule stop states");
13326 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13327 .expect("ops");
13328 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
13329 .expect("exit");
13330 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13331 .expect("to shift");
13332 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13333 .expect("to rel");
13334 atn.add_transition(
13335 3,
13336 ParserTransitionSpec::Precedence {
13337 target: 4,
13338 precedence: 2,
13339 },
13340 )
13341 .expect("shift prec");
13342 atn.add_transition(
13343 4,
13344 ParserTransitionSpec::Atom {
13345 target: 5,
13346 label: 1,
13347 },
13348 )
13349 .expect("shift first >");
13350 atn.add_transition(
13351 5,
13352 ParserTransitionSpec::Atom {
13353 target: 1,
13354 label: 1,
13355 },
13356 )
13357 .expect("shift second >");
13358 atn.add_transition(
13359 6,
13360 ParserTransitionSpec::Precedence {
13361 target: 7,
13362 precedence: 1,
13363 },
13364 )
13365 .expect("rel prec");
13366 atn.add_transition(
13367 7,
13368 ParserTransitionSpec::Atom {
13369 target: 1,
13370 label: 1,
13371 },
13372 )
13373 .expect("rel >");
13374 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
13375 .expect("loop end");
13376 finish_atn(atn)
13377 }
13378
13379 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
13380 let mut atn = ParserAtnBuilder::new(2);
13381 for (state, kind, rule) in [
13382 (0, AtnStateKind::RuleStart, 0),
13383 (1, AtnStateKind::StarLoopEntry, 0),
13384 (2, AtnStateKind::Basic, 0),
13385 (3, AtnStateKind::Basic, 0),
13386 (4, AtnStateKind::Basic, 0),
13387 (5, AtnStateKind::Basic, 0),
13388 (6, AtnStateKind::Basic, 0),
13389 (7, AtnStateKind::Basic, 0),
13390 (8, AtnStateKind::LoopEnd, 0),
13391 (9, AtnStateKind::RuleStop, 0),
13392 (10, AtnStateKind::RuleStart, 1),
13393 (11, AtnStateKind::Basic, 1),
13394 (12, AtnStateKind::RuleStop, 1),
13395 ] {
13396 assert_eq!(
13397 atn.add_state(kind, Some(rule)).expect("state").index(),
13398 state
13399 );
13400 if state == 0 {
13401 atn.set_left_recursive_rule(state)
13402 .expect("left-recursive rule start");
13403 } else if state == 1 {
13404 atn.set_precedence_rule_decision(state)
13405 .expect("precedence decision");
13406 }
13407 }
13408 atn.set_rule_to_start_state(vec![0, 10])
13409 .expect("rule start states");
13410 atn.set_rule_to_stop_state(vec![9, 12])
13411 .expect("rule stop states");
13412 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13413 .expect("ops");
13414 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
13415 .expect("exit");
13416 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13417 .expect("to shift");
13418 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13419 .expect("to relational");
13420 atn.add_transition(
13421 3,
13422 ParserTransitionSpec::Precedence {
13423 target: 4,
13424 precedence: 2,
13425 },
13426 )
13427 .expect("shift precedence");
13428 atn.add_transition(
13429 4,
13430 ParserTransitionSpec::Rule {
13431 target: 10,
13432 rule_index: 1,
13433 follow_state: 5,
13434 precedence: 0,
13435 },
13436 )
13437 .expect("first shift token helper");
13438 atn.add_transition(
13439 5,
13440 ParserTransitionSpec::Atom {
13441 target: 1,
13442 label: 1,
13443 },
13444 )
13445 .expect("second shift token");
13446 atn.add_transition(
13447 6,
13448 ParserTransitionSpec::Precedence {
13449 target: 7,
13450 precedence: 1,
13451 },
13452 )
13453 .expect("relational precedence");
13454 atn.add_transition(
13455 7,
13456 ParserTransitionSpec::Atom {
13457 target: 1,
13458 label: 1,
13459 },
13460 )
13461 .expect("relational token");
13462 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
13463 .expect("loop end");
13464 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
13465 .expect("helper entry");
13466 atn.add_transition(
13467 11,
13468 ParserTransitionSpec::Atom {
13469 target: 12,
13470 label: 1,
13471 },
13472 )
13473 .expect("first shift token");
13474 finish_atn(atn)
13475 }
13476
13477 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
13478 let mut atn = ParserAtnBuilder::new(1);
13479 for (state, kind) in [
13480 (0, AtnStateKind::RuleStart),
13481 (1, AtnStateKind::StarLoopEntry),
13482 (2, AtnStateKind::Basic),
13483 (3, AtnStateKind::Basic),
13484 (4, AtnStateKind::Basic),
13485 (5, AtnStateKind::Basic),
13486 (6, AtnStateKind::Basic),
13487 (7, AtnStateKind::Basic),
13488 (8, AtnStateKind::Basic),
13489 (9, AtnStateKind::LoopEnd),
13490 (10, AtnStateKind::RuleStop),
13491 ] {
13492 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13493 if state == 0 {
13494 atn.set_left_recursive_rule(state)
13495 .expect("left-recursive rule start");
13496 } else if state == 1 {
13497 atn.set_precedence_rule_decision(state)
13498 .expect("precedence decision");
13499 }
13500 }
13501 atn.set_rule_to_start_state(vec![0])
13502 .expect("rule start states");
13503 atn.set_rule_to_stop_state(vec![10])
13504 .expect("rule stop states");
13505 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13506 .expect("ops");
13507 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
13508 .expect("exit");
13509 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13510 .expect("to multi-token operator");
13511 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13512 .expect("to predicate operator");
13513 atn.add_transition(
13514 3,
13515 ParserTransitionSpec::Precedence {
13516 target: 4,
13517 precedence: 2,
13518 },
13519 )
13520 .expect("multi-token precedence");
13521 atn.add_transition(
13522 4,
13523 ParserTransitionSpec::Atom {
13524 target: 5,
13525 label: 1,
13526 },
13527 )
13528 .expect("multi-token first");
13529 atn.add_transition(
13530 5,
13531 ParserTransitionSpec::Atom {
13532 target: 1,
13533 label: 1,
13534 },
13535 )
13536 .expect("multi-token second");
13537 atn.add_transition(
13538 6,
13539 ParserTransitionSpec::Precedence {
13540 target: 7,
13541 precedence: 2,
13542 },
13543 )
13544 .expect("predicate precedence");
13545 atn.add_transition(
13546 7,
13547 ParserTransitionSpec::Predicate {
13548 target: 8,
13549 rule_index: 0,
13550 pred_index: 0,
13551 context_dependent: false,
13552 },
13553 )
13554 .expect("operator predicate");
13555 atn.add_transition(
13556 8,
13557 ParserTransitionSpec::Atom {
13558 target: 1,
13559 label: 1,
13560 },
13561 )
13562 .expect("predicate single token");
13563 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13564 .expect("loop end");
13565 finish_atn(atn)
13566 }
13567
13568 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
13569 let mut atn = ParserAtnBuilder::new(2);
13570 for (state, kind, rule) in [
13571 (0, AtnStateKind::RuleStart, 0),
13572 (1, AtnStateKind::StarLoopEntry, 0),
13573 (2, AtnStateKind::Basic, 0),
13574 (3, AtnStateKind::Basic, 0),
13575 (4, AtnStateKind::Basic, 0),
13576 (5, AtnStateKind::LoopEnd, 0),
13577 (6, AtnStateKind::RuleStop, 0),
13578 (7, AtnStateKind::RuleStart, 1),
13579 (8, AtnStateKind::RuleStop, 1),
13580 (9, AtnStateKind::Basic, 1),
13581 ] {
13582 assert_eq!(
13583 atn.add_state(kind, Some(rule)).expect("state").index(),
13584 state
13585 );
13586 if state == 0 {
13587 atn.set_left_recursive_rule(state)
13588 .expect("left-recursive rule start");
13589 } else if state == 1 {
13590 atn.set_precedence_rule_decision(state)
13591 .expect("precedence decision");
13592 }
13593 }
13594 atn.set_rule_to_start_state(vec![0, 7])
13595 .expect("rule start states");
13596 atn.set_rule_to_stop_state(vec![6, 8])
13597 .expect("rule stop states");
13598 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13599 .expect("transition");
13600 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
13601 .expect("transition");
13602 atn.add_transition(
13603 2,
13604 ParserTransitionSpec::Precedence {
13605 target: 3,
13606 precedence: 3,
13607 },
13608 )
13609 .expect("transition");
13610 atn.add_transition(
13611 3,
13612 ParserTransitionSpec::Rule {
13613 target: 7,
13614 rule_index: 1,
13615 follow_state: 4,
13616 precedence: 0,
13617 },
13618 )
13619 .expect("transition");
13620 atn.add_transition(
13621 4,
13622 ParserTransitionSpec::Atom {
13623 target: 1,
13624 label: 1,
13625 },
13626 )
13627 .expect("transition");
13628 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13629 .expect("transition");
13630 atn.add_transition(
13631 7,
13632 ParserTransitionSpec::Precedence {
13633 target: 9,
13634 precedence: 1,
13635 },
13636 )
13637 .expect("transition");
13638 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
13639 .expect("transition");
13640 finish_atn(atn)
13641 }
13642
13643 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
13644 let mut atn = ParserAtnBuilder::new(2);
13645 for (state, kind) in [
13646 (0, AtnStateKind::RuleStart),
13647 (1, AtnStateKind::StarLoopEntry),
13648 (2, AtnStateKind::Basic),
13649 (3, AtnStateKind::Basic),
13650 (4, AtnStateKind::Basic),
13651 (5, AtnStateKind::LoopEnd),
13652 (6, AtnStateKind::RuleStop),
13653 ] {
13654 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13655 if state == 0 {
13656 atn.set_left_recursive_rule(state)
13657 .expect("left-recursive rule start");
13658 } else if state == 1 {
13659 atn.set_precedence_rule_decision(state)
13660 .expect("precedence decision");
13661 }
13662 }
13663 atn.set_rule_to_start_state(vec![0])
13664 .expect("rule start states");
13665 atn.set_rule_to_stop_state(vec![6])
13666 .expect("rule stop states");
13667 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13668 .expect("transition");
13669 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
13670 .expect("transition");
13671 atn.add_transition(
13672 2,
13673 ParserTransitionSpec::Precedence {
13674 target: 3,
13675 precedence: 1,
13676 },
13677 )
13678 .expect("transition");
13679 atn.add_transition(
13680 3,
13681 ParserTransitionSpec::Predicate {
13682 target: 4,
13683 rule_index: 0,
13684 pred_index: 0,
13685 context_dependent: false,
13686 },
13687 )
13688 .expect("transition");
13689 atn.add_transition(
13690 4,
13691 ParserTransitionSpec::Atom {
13692 target: 1,
13693 label: 1,
13694 },
13695 )
13696 .expect("transition");
13697 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13698 .expect("transition");
13699 finish_atn(atn)
13700 }
13701
13702 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
13703 let mut atn = ParserAtnBuilder::new(2);
13704 for (state, kind, rule) in [
13705 (0, AtnStateKind::RuleStart, 0),
13706 (1, AtnStateKind::Basic, 0),
13707 (2, AtnStateKind::Basic, 0),
13708 (3, AtnStateKind::Basic, 0),
13709 (4, AtnStateKind::RuleStop, 0),
13710 (5, AtnStateKind::RuleStart, 1),
13711 (6, AtnStateKind::StarLoopEntry, 1),
13712 (7, AtnStateKind::Basic, 1),
13713 (8, AtnStateKind::Basic, 1),
13714 (9, AtnStateKind::LoopEnd, 1),
13715 (10, AtnStateKind::RuleStop, 1),
13716 (11, AtnStateKind::RuleStart, 2),
13717 (12, AtnStateKind::RuleStop, 2),
13718 ] {
13719 assert_eq!(
13720 atn.add_state(kind, Some(rule)).expect("state").index(),
13721 state
13722 );
13723 if state == 5 {
13724 atn.set_left_recursive_rule(state)
13725 .expect("left-recursive rule start");
13726 } else if state == 6 {
13727 atn.set_precedence_rule_decision(state)
13728 .expect("precedence decision");
13729 }
13730 }
13731 atn.set_rule_to_start_state(vec![0, 5, 11])
13732 .expect("rule start states");
13733 atn.set_rule_to_stop_state(vec![4, 10, 12])
13734 .expect("rule stop states");
13735 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13736 .expect("transition");
13737 atn.add_transition(
13738 1,
13739 ParserTransitionSpec::Rule {
13740 target: 5,
13741 rule_index: 1,
13742 follow_state: 2,
13743 precedence: 0,
13744 },
13745 )
13746 .expect("transition");
13747 atn.add_transition(
13748 2,
13749 ParserTransitionSpec::Rule {
13750 target: 11,
13751 rule_index: 2,
13752 follow_state: 3,
13753 precedence: 0,
13754 },
13755 )
13756 .expect("transition");
13757 atn.add_transition(
13758 3,
13759 ParserTransitionSpec::Atom {
13760 target: 4,
13761 label: caller_symbol,
13762 },
13763 )
13764 .expect("transition");
13765 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13766 .expect("transition");
13767 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
13768 .expect("transition");
13769 atn.add_transition(
13770 7,
13771 ParserTransitionSpec::Precedence {
13772 target: 8,
13773 precedence: 1,
13774 },
13775 )
13776 .expect("transition");
13777 atn.add_transition(
13778 8,
13779 ParserTransitionSpec::Atom {
13780 target: 6,
13781 label: 1,
13782 },
13783 )
13784 .expect("transition");
13785 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13786 .expect("transition");
13787 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
13788 .expect("transition");
13789 finish_atn(atn)
13790 }
13791
13792 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
13793 let mut atn = ParserAtnBuilder::new(2);
13794 for (state, kind, rule) in [
13795 (0, AtnStateKind::RuleStart, 0),
13796 (1, AtnStateKind::Basic, 0),
13797 (2, AtnStateKind::Basic, 0),
13798 (3, AtnStateKind::RuleStop, 0),
13799 (4, AtnStateKind::RuleStart, 1),
13800 (5, AtnStateKind::Basic, 1),
13801 (6, AtnStateKind::Basic, 1),
13802 (7, AtnStateKind::RuleStop, 1),
13803 (8, AtnStateKind::RuleStart, 2),
13804 (9, AtnStateKind::StarLoopEntry, 2),
13805 (10, AtnStateKind::Basic, 2),
13806 (11, AtnStateKind::Basic, 2),
13807 (12, AtnStateKind::LoopEnd, 2),
13808 (13, AtnStateKind::RuleStop, 2),
13809 ] {
13810 assert_eq!(
13811 atn.add_state(kind, Some(rule)).expect("state").index(),
13812 state
13813 );
13814 if state == 8 {
13815 atn.set_left_recursive_rule(state)
13816 .expect("left-recursive rule start");
13817 } else if state == 9 {
13818 atn.set_precedence_rule_decision(state)
13819 .expect("precedence decision");
13820 }
13821 }
13822 atn.set_rule_to_start_state(vec![0, 4, 8])
13823 .expect("rule start states");
13824 atn.set_rule_to_stop_state(vec![3, 7, 13])
13825 .expect("rule stop states");
13826 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13827 .expect("transition");
13828 atn.add_transition(
13829 1,
13830 ParserTransitionSpec::Rule {
13831 target: 4,
13832 rule_index: 1,
13833 follow_state: 2,
13834 precedence: 0,
13835 },
13836 )
13837 .expect("transition");
13838 atn.add_transition(
13839 2,
13840 ParserTransitionSpec::Atom {
13841 target: 3,
13842 label: caller_symbol,
13843 },
13844 )
13845 .expect("transition");
13846 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13847 .expect("transition");
13848 atn.add_transition(
13849 5,
13850 ParserTransitionSpec::Rule {
13851 target: 8,
13852 rule_index: 2,
13853 follow_state: 6,
13854 precedence: 0,
13855 },
13856 )
13857 .expect("transition");
13858 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13859 .expect("transition");
13860 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13861 .expect("transition");
13862 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
13863 .expect("transition");
13864 atn.add_transition(
13865 10,
13866 ParserTransitionSpec::Precedence {
13867 target: 11,
13868 precedence: 1,
13869 },
13870 )
13871 .expect("transition");
13872 atn.add_transition(
13873 11,
13874 ParserTransitionSpec::Atom {
13875 target: 9,
13876 label: 1,
13877 },
13878 )
13879 .expect("transition");
13880 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
13881 .expect("transition");
13882 finish_atn(atn)
13883 }
13884
13885 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
13886 let mut atn = ParserAtnBuilder::new(2);
13887 for (state, kind, rule) in [
13888 (0, AtnStateKind::RuleStart, 0),
13889 (1, AtnStateKind::Basic, 0),
13890 (2, AtnStateKind::Basic, 0),
13891 (3, AtnStateKind::RuleStop, 0),
13892 (4, AtnStateKind::RuleStart, 1),
13893 (5, AtnStateKind::StarLoopEntry, 1),
13894 (6, AtnStateKind::Basic, 1),
13895 (7, AtnStateKind::Basic, 1),
13896 (8, AtnStateKind::Basic, 1),
13897 (9, AtnStateKind::Basic, 1),
13898 (10, AtnStateKind::LoopEnd, 1),
13899 (11, AtnStateKind::RuleStop, 1),
13900 ] {
13901 assert_eq!(
13902 atn.add_state(kind, Some(rule)).expect("state").index(),
13903 state
13904 );
13905 if state == 4 {
13906 atn.set_left_recursive_rule(state)
13907 .expect("left-recursive rule start");
13908 } else if state == 5 {
13909 atn.set_precedence_rule_decision(state)
13910 .expect("precedence decision");
13911 }
13912 }
13913 atn.set_rule_to_start_state(vec![0, 4])
13914 .expect("rule start states");
13915 atn.set_rule_to_stop_state(vec![3, 11])
13916 .expect("rule stop states");
13917 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13918 .expect("transition");
13919 atn.add_transition(
13920 1,
13921 ParserTransitionSpec::Rule {
13922 target: 4,
13923 rule_index: 1,
13924 follow_state: 2,
13925 precedence: 0,
13926 },
13927 )
13928 .expect("transition");
13929 atn.add_transition(
13930 2,
13931 ParserTransitionSpec::Atom {
13932 target: 3,
13933 label: caller_symbol,
13934 },
13935 )
13936 .expect("transition");
13937 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13938 .expect("transition");
13939 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
13940 .expect("transition");
13941 atn.add_transition(
13942 6,
13943 ParserTransitionSpec::Precedence {
13944 target: 7,
13945 precedence: 1,
13946 },
13947 )
13948 .expect("transition");
13949 atn.add_transition(
13950 7,
13951 ParserTransitionSpec::Atom {
13952 target: 8,
13953 label: 1,
13954 },
13955 )
13956 .expect("transition");
13957 atn.add_transition(
13958 8,
13959 ParserTransitionSpec::Rule {
13960 target: 4,
13961 rule_index: 1,
13962 follow_state: 9,
13963 precedence: 2,
13964 },
13965 )
13966 .expect("transition");
13967 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
13968 .expect("transition");
13969 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
13970 .expect("transition");
13971 finish_atn(atn)
13972 }
13973
13974 #[test]
13975 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
13976 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
13977 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
13978
13979 let mut overlapping = parser_inside_left_recursive_callee(1);
13980 assert_eq!(
13981 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
13982 None
13983 );
13984
13985 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
13986 assert_eq!(
13987 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13988 Some(true)
13989 );
13990
13991 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
13992 assert_eq!(
13993 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13994 Some(false)
13995 );
13996
13997 assert_eq!(
13998 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13999 Some(true),
14000 "overlap results must not leak across ATNs"
14001 );
14002 }
14003
14004 #[test]
14005 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
14006 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
14007 let mut parser = mini_parser(vec![
14008 TestToken::new(1).with_text("operator"),
14009 TestToken::eof("parser-test", 1, 1, 1),
14010 ]);
14011 parser.rule_context_stack = vec![RuleContextFrame {
14012 rule_index: 0,
14013 invoking_state: -1,
14014 }];
14015
14016 assert_eq!(
14017 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14018 Some(true)
14019 );
14020 assert_eq!(
14021 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14022 Some(true),
14023 "cached operator lookahead must preserve the nullable prefix return path"
14024 );
14025 assert_eq!(
14026 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14027 Some(true),
14028 "the nullable child must use its rule-call precedence, not the caller precedence"
14029 );
14030 }
14031
14032 #[test]
14033 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
14034 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
14039 let mut parser = mini_parser(vec![
14040 TestToken::new(1).with_text(">"),
14041 TestToken::new(2).with_text("id"),
14042 TestToken::eof("parser-test", 1, 1, 1),
14043 ]);
14044 parser.rule_context_stack = vec![RuleContextFrame {
14045 rule_index: 0,
14046 invoking_state: -1,
14047 }];
14048
14049 assert_eq!(
14050 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14051 Some(true),
14052 "at low precedence relational `>` is a single-token operator"
14053 );
14054 assert_eq!(
14055 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
14056 Some(true),
14057 "relational remains single-token at its own precedence"
14058 );
14059 assert_eq!(
14060 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14061 None,
14062 "at shift precedence, bare `>` must not force enter"
14063 );
14064 }
14065
14066 #[test]
14067 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
14068 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
14069 let mut parser = mini_parser(vec![
14070 TestToken::new(1).with_text(">"),
14071 TestToken::new(2).with_text("id"),
14072 TestToken::eof("parser-test", 1, 1, 1),
14073 ]);
14074 parser.rule_context_stack = vec![RuleContextFrame {
14075 rule_index: 0,
14076 invoking_state: -1,
14077 }];
14078
14079 assert_eq!(
14080 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14081 Some(true),
14082 "the direct relational alternative remains a one-token operator"
14083 );
14084 assert_eq!(
14085 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14086 None,
14087 "a token matched in the helper rule must return to the second shift token"
14088 );
14089 }
14090
14091 #[test]
14092 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
14093 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
14094 let mut parser = mini_parser(vec![
14095 TestToken::new(1).with_text(">"),
14096 TestToken::new(2).with_text("id"),
14097 TestToken::eof("parser-test", 1, 1, 1),
14098 ]);
14099 parser.rule_context_stack = vec![RuleContextFrame {
14100 rule_index: 0,
14101 invoking_state: -1,
14102 }];
14103
14104 assert_eq!(
14105 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14106 None,
14107 "a predicate-gated single-token path must not be hidden by a multi-token path"
14108 );
14109 }
14110
14111 #[test]
14112 fn left_recursive_loop_defers_predicate_guarded_operator() {
14113 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
14114 let mut parser = mini_parser_with_hooks(
14115 vec![
14116 TestToken::new(1).with_text("operator"),
14117 TestToken::eof("parser-test", 1, 1, 1),
14118 ],
14119 RejectingPredicateHooks::default(),
14120 );
14121 parser.rule_context_stack = vec![RuleContextFrame {
14122 rule_index: 0,
14123 invoking_state: -1,
14124 }];
14125
14126 assert_eq!(
14127 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14128 None,
14129 "a false predicate must be evaluated before entering the operator alternative"
14130 );
14131 assert_eq!(
14132 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14133 None,
14134 "cached predicate-dependent lookahead must keep deferring"
14135 );
14136 }
14137
14138 #[test]
14139 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
14140 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
14141 let mut parser = parser_inside_left_recursive_callee(1);
14142
14143 assert_eq!(
14144 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
14145 None
14146 );
14147 assert_eq!(
14148 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
14149 None,
14150 "the cached overlap must preserve the nullable child return path"
14151 );
14152 }
14153
14154 #[test]
14155 fn left_recursive_loop_defers_through_nullable_parent_return() {
14156 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
14157 let mut parser = mini_parser(vec![
14158 TestToken::new(1).with_text("lookahead"),
14159 TestToken::eof("parser-test", 1, 1, 1),
14160 ]);
14161 parser.rule_context_stack = vec![
14162 RuleContextFrame {
14163 rule_index: 0,
14164 invoking_state: -1,
14165 },
14166 RuleContextFrame {
14167 rule_index: 1,
14168 invoking_state: 1,
14169 },
14170 RuleContextFrame {
14171 rule_index: 2,
14172 invoking_state: 5,
14173 },
14174 ];
14175
14176 assert_eq!(
14177 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
14178 None,
14179 "a nullable caller must unwind to its parent's consuming follow path"
14180 );
14181 assert_eq!(
14182 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
14183 None,
14184 "the caller-overlap cache must not retain a false negative"
14185 );
14186 }
14187
14188 #[test]
14189 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
14190 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
14191 let mut parser = mini_parser(vec![
14192 TestToken::new(1).with_text("lookahead"),
14193 TestToken::eof("parser-test", 1, 1, 1),
14194 ]);
14195 parser.rule_context_stack = vec![
14196 RuleContextFrame {
14197 rule_index: 0,
14198 invoking_state: -1,
14199 },
14200 RuleContextFrame {
14201 rule_index: 1,
14202 invoking_state: 1,
14203 },
14204 RuleContextFrame {
14205 rule_index: 1,
14206 invoking_state: 8,
14207 },
14208 ];
14209
14210 assert_eq!(
14211 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
14212 None,
14213 "a recursive operand return must preserve its parent caller context"
14214 );
14215 assert_eq!(
14216 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
14217 None,
14218 "the caller-overlap cache must preserve the loop-boundary return"
14219 );
14220 }
14221
14222 fn token_then_eof_atn() -> Atn {
14223 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14224 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, ]))
14240 .deserialize_parser()
14241 .expect("artificial parser ATN should deserialize")
14242 }
14243
14244 fn epsilon_cycle_atn() -> Atn {
14245 let mut atn = ParserAtnBuilder::new(1);
14246 for (state_number, kind) in [
14247 (0, AtnStateKind::RuleStart),
14248 (1, AtnStateKind::Basic),
14249 (2, AtnStateKind::RuleStop),
14250 ] {
14251 assert_eq!(
14252 atn.add_state(kind, Some(0)).expect("state").index(),
14253 state_number
14254 );
14255 }
14256 atn.set_rule_to_start_state(vec![0])
14257 .expect("rule start states");
14258 atn.set_rule_to_stop_state(vec![2])
14259 .expect("rule stop states");
14260 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14261 .expect("transition");
14262 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
14263 .expect("self-cycle transition");
14264 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14265 .expect("exit transition");
14266 finish_atn(atn)
14267 }
14268
14269 fn eof_then_action_atn() -> Atn {
14270 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14271 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, ]))
14287 .deserialize_parser()
14288 .expect("artificial parser ATN should deserialize")
14289 }
14290
14291 fn noop_action_then_token_then_eof_atn() -> Atn {
14292 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14293 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, ]))
14311 .deserialize_parser()
14312 .expect("artificial no-op action ATN should deserialize")
14313 }
14314
14315 fn two_alt_decision_atn() -> Atn {
14316 let mut atn = ParserAtnBuilder::new(2);
14317 assert_eq!(
14318 atn.add_state(AtnStateKind::RuleStart, Some(0))
14319 .expect("state")
14320 .index(),
14321 0
14322 );
14323 assert_eq!(
14324 atn.add_state(AtnStateKind::BlockStart, Some(0))
14325 .expect("state")
14326 .index(),
14327 1
14328 );
14329 assert_eq!(
14330 atn.add_state(AtnStateKind::Basic, Some(0))
14331 .expect("state")
14332 .index(),
14333 2
14334 );
14335 assert_eq!(
14336 atn.add_state(AtnStateKind::Basic, Some(0))
14337 .expect("state")
14338 .index(),
14339 3
14340 );
14341 assert_eq!(
14342 atn.add_state(AtnStateKind::BlockEnd, Some(0))
14343 .expect("state")
14344 .index(),
14345 4
14346 );
14347 assert_eq!(
14348 atn.add_state(AtnStateKind::RuleStop, Some(0))
14349 .expect("state")
14350 .index(),
14351 5
14352 );
14353 atn.set_rule_to_start_state(vec![0])
14354 .expect("rule start states");
14355 atn.set_rule_to_stop_state(vec![5])
14356 .expect("rule stop states");
14357 atn.add_decision_state(1).expect("decision state");
14358 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14359 .expect("transition");
14360 atn.add_transition(
14361 1,
14362 ParserTransitionSpec::Atom {
14363 target: 2,
14364 label: 1,
14365 },
14366 )
14367 .expect("transition");
14368 atn.add_transition(
14369 1,
14370 ParserTransitionSpec::Atom {
14371 target: 3,
14372 label: 2,
14373 },
14374 )
14375 .expect("transition");
14376 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
14377 .expect("transition");
14378 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14379 .expect("transition");
14380 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14381 .expect("transition");
14382 finish_atn(atn)
14383 }
14384
14385 fn optional_then_b_eof_atn() -> Atn {
14388 let mut atn = ParserAtnBuilder::new(3);
14389 assert_eq!(
14390 atn.add_state(AtnStateKind::RuleStart, Some(0))
14391 .expect("state")
14392 .index(),
14393 0
14394 );
14395 assert_eq!(
14396 atn.add_state(AtnStateKind::BlockStart, Some(0))
14397 .expect("state")
14398 .index(),
14399 1
14400 );
14401 assert_eq!(
14402 atn.add_state(AtnStateKind::Basic, Some(0))
14403 .expect("state")
14404 .index(),
14405 2
14406 );
14407 assert_eq!(
14408 atn.add_state(AtnStateKind::Basic, Some(0))
14409 .expect("state")
14410 .index(),
14411 3
14412 );
14413 assert_eq!(
14414 atn.add_state(AtnStateKind::Basic, Some(0))
14415 .expect("state")
14416 .index(),
14417 4
14418 );
14419 assert_eq!(
14420 atn.add_state(AtnStateKind::RuleStop, Some(0))
14421 .expect("state")
14422 .index(),
14423 5
14424 );
14425 atn.set_rule_to_start_state(vec![0])
14426 .expect("rule start states");
14427 atn.set_rule_to_stop_state(vec![5])
14428 .expect("rule stop states");
14429 atn.add_decision_state(1).expect("decision state");
14430 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14431 .expect("transition");
14432 atn.add_transition(
14434 1,
14435 ParserTransitionSpec::Atom {
14436 target: 3,
14437 label: 1,
14438 },
14439 )
14440 .expect("transition");
14441 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
14442 .expect("transition");
14443 atn.add_transition(
14445 3,
14446 ParserTransitionSpec::Atom {
14447 target: 4,
14448 label: 2,
14449 },
14450 )
14451 .expect("transition");
14452 atn.add_transition(
14453 4,
14454 ParserTransitionSpec::Atom {
14455 target: 5,
14456 label: TOKEN_EOF,
14457 },
14458 )
14459 .expect("transition");
14460 finish_atn(atn)
14461 }
14462
14463 #[test]
14464 fn sync_decision_deletes_only_a_single_token() {
14465 let atn = optional_then_b_eof_atn();
14473
14474 let mut single = mini_parser(vec![
14475 TestToken::new(3).with_text("c"),
14476 TestToken::new(2).with_text("b"),
14477 TestToken::eof("parser-test", 1, 2, 2),
14478 ]);
14479 single.rule_context_stack = vec![RuleContextFrame {
14480 rule_index: 0,
14481 invoking_state: 0,
14482 }];
14483 let children = single
14484 .sync_decision(&atn, 1, true, false)
14485 .expect("single extraneous token recovers");
14486 assert_eq!(children.len(), 1);
14487 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
14488 assert_eq!(single.number_of_syntax_errors(), 1);
14489 assert_eq!(single.la(1), 2);
14491
14492 let mut double = mini_parser(vec![
14493 TestToken::new(3).with_text("c"),
14494 TestToken::new(3).with_text("c"),
14495 TestToken::new(2).with_text("b"),
14496 TestToken::eof("parser-test", 1, 3, 3),
14497 ]);
14498 double.rule_context_stack = vec![RuleContextFrame {
14499 rule_index: 0,
14500 invoking_state: 0,
14501 }];
14502 let result = double.sync_decision(&atn, 1, true, false);
14503 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
14508 match error {
14509 AntlrError::ParserError { message, .. } => {
14510 assert!(message.starts_with("mismatched input"), "got: {message}");
14511 }
14512 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
14513 }
14514 assert_eq!(double.la(1), 3);
14515 }
14516
14517 fn star_loop_then_eof_atn() -> Atn {
14521 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14522 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,
14523 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,
14524 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,
14525 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
14526 ]))
14527 .deserialize_parser()
14528 .expect("star-loop-then-EOF ATN should deserialize")
14529 }
14530
14531 fn plus_loop_with_recovering_body_atn() -> Atn {
14537 let mut atn = ParserAtnBuilder::new(2);
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::PlusBlockStart, Some(0))
14546 .expect("state")
14547 .index(),
14548 1
14549 );
14550 assert_eq!(
14551 atn.add_state(AtnStateKind::Basic, Some(0))
14552 .expect("state")
14553 .index(),
14554 2
14555 );
14556 assert_eq!(
14557 atn.add_state(AtnStateKind::BlockEnd, Some(0))
14558 .expect("state")
14559 .index(),
14560 3
14561 );
14562 assert_eq!(
14563 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
14564 .expect("state")
14565 .index(),
14566 4
14567 );
14568 assert_eq!(
14569 atn.add_state(AtnStateKind::LoopEnd, Some(0))
14570 .expect("state")
14571 .index(),
14572 5
14573 );
14574 assert_eq!(
14575 atn.add_state(AtnStateKind::RuleStop, Some(0))
14576 .expect("state")
14577 .index(),
14578 6
14579 );
14580 assert_eq!(
14581 atn.add_state(AtnStateKind::RuleStart, Some(1))
14582 .expect("state")
14583 .index(),
14584 7
14585 );
14586 assert_eq!(
14587 atn.add_state(AtnStateKind::Basic, Some(1))
14588 .expect("state")
14589 .index(),
14590 8
14591 );
14592 assert_eq!(
14593 atn.add_state(AtnStateKind::RuleStop, Some(1))
14594 .expect("state")
14595 .index(),
14596 9
14597 );
14598 atn.set_rule_to_start_state(vec![0, 7])
14599 .expect("rule start states");
14600 atn.set_rule_to_stop_state(vec![6, 9])
14601 .expect("rule stop states");
14602 atn.set_end_state(1, 3).expect("block end state");
14603 atn.set_loop_back_state(5, 4).expect("loop back state");
14604 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14605 .expect("transition");
14606 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14607 .expect("transition");
14608 atn.add_transition(
14609 2,
14610 ParserTransitionSpec::Rule {
14611 target: 7,
14612 rule_index: 1,
14613 follow_state: 3,
14614 precedence: 0,
14615 },
14616 )
14617 .expect("transition");
14618 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14619 .expect("transition");
14620 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
14621 .expect("transition");
14622 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14623 .expect("transition");
14624 atn.add_transition(
14625 5,
14626 ParserTransitionSpec::Atom {
14627 target: 6,
14628 label: 2,
14629 },
14630 )
14631 .expect("transition");
14632 atn.add_transition(
14633 7,
14634 ParserTransitionSpec::Atom {
14635 target: 8,
14636 label: 1,
14637 },
14638 )
14639 .expect("transition");
14640 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14641 .expect("transition");
14642 finish_atn(atn)
14643 }
14644
14645 #[test]
14646 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
14647 let atn = plus_loop_with_recovering_body_atn();
14648 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14649
14650 let error = parser
14651 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
14652 .expect_err("EOF recovery should report a bounded mismatch");
14653
14654 let AntlrError::ParserError { message, .. } = error else {
14655 panic!("expected ParserError, got {error:?}");
14656 };
14657 insta::assert_snapshot!(message, @"mismatched input '<EOF>' expecting {'x', 2}");
14658 assert_eq!(parser.number_of_syntax_errors(), 1);
14659 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
14660 }
14661
14662 #[test]
14663 fn sync_decision_deletes_token_before_eof_at_loop_back() {
14664 let atn = star_loop_then_eof_atn();
14670 let mut parser = mini_parser(vec![
14671 TestToken::new(2).with_text("c"),
14672 TestToken::eof("parser-test", 1, 1, 1),
14673 ]);
14674 parser.rule_context_stack = vec![RuleContextFrame {
14675 rule_index: 0,
14676 invoking_state: 0,
14677 }];
14678 let children = parser
14679 .sync_decision(&atn, 5, true, false)
14680 .expect("single token before EOF recovers");
14681 assert_eq!(children.len(), 1);
14682 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
14683 assert_eq!(parser.number_of_syntax_errors(), 1);
14684 assert_eq!(
14685 parser.la(1),
14686 TOKEN_EOF,
14687 "EOF is left for the rule's EOF match"
14688 );
14689 }
14690
14691 #[test]
14692 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
14693 let atn = star_loop_then_eof_atn();
14698 let mut parser = mini_parser(vec![
14699 TestToken::new(2).with_text("c"),
14700 TestToken::new(2).with_text("c"),
14701 TestToken::eof("parser-test", 1, 2, 2),
14702 ]);
14703 parser.rule_context_stack = vec![RuleContextFrame {
14704 rule_index: 0,
14705 invoking_state: 0,
14706 }];
14707 let error = parser
14708 .sync_decision(&atn, 5, true, false)
14709 .expect_err("two tokens at the loop entry must not be deleted");
14710 match error {
14711 AntlrError::ParserError { message, .. } => {
14712 assert!(message.starts_with("mismatched input"), "got: {message}");
14713 }
14714 other => panic!("expected mismatched-input ParserError, got {other:?}"),
14715 }
14716 assert_eq!(
14717 parser.la(1),
14718 2,
14719 "nothing consumed; cursor still on first `c`"
14720 );
14721 }
14722
14723 #[test]
14724 fn sync_decision_consumes_until_eof_at_loop_back() {
14725 let atn = star_loop_then_eof_atn();
14731 let mut parser = mini_parser(vec![
14732 TestToken::new(2).with_text("c"),
14733 TestToken::new(2).with_text("c"),
14734 TestToken::eof("parser-test", 1, 2, 2),
14735 ]);
14736 parser.rule_context_stack = vec![RuleContextFrame {
14737 rule_index: 0,
14738 invoking_state: 0,
14739 }];
14740 let children = parser
14741 .sync_decision(&atn, 5, false, true)
14742 .expect("loop-back multi-token deletion recovers onto EOF");
14743 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
14744 assert!(
14745 children
14746 .iter()
14747 .all(|child| parser.node(*child).kind() == NodeKind::Error)
14748 );
14749 assert_eq!(parser.number_of_syntax_errors(), 1);
14750 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
14751 }
14752
14753 fn predicate_after_token_atn() -> Atn {
14754 let mut atn = ParserAtnBuilder::new(2);
14755 assert_eq!(
14756 atn.add_state(AtnStateKind::RuleStart, Some(0))
14757 .expect("state")
14758 .index(),
14759 0
14760 );
14761 assert_eq!(
14762 atn.add_state(AtnStateKind::Basic, Some(0))
14763 .expect("state")
14764 .index(),
14765 1
14766 );
14767 assert_eq!(
14768 atn.add_state(AtnStateKind::Basic, Some(0))
14769 .expect("state")
14770 .index(),
14771 2
14772 );
14773 assert_eq!(
14774 atn.add_state(AtnStateKind::Basic, Some(0))
14775 .expect("state")
14776 .index(),
14777 3
14778 );
14779 assert_eq!(
14780 atn.add_state(AtnStateKind::RuleStop, Some(0))
14781 .expect("state")
14782 .index(),
14783 4
14784 );
14785 atn.set_rule_to_start_state(vec![0])
14786 .expect("rule start states");
14787 atn.set_rule_to_stop_state(vec![4])
14788 .expect("rule stop states");
14789 atn.add_transition(
14790 0,
14791 ParserTransitionSpec::Atom {
14792 target: 1,
14793 label: 1,
14794 },
14795 )
14796 .expect("transition");
14797 atn.add_transition(
14798 1,
14799 ParserTransitionSpec::Predicate {
14800 target: 2,
14801 rule_index: 0,
14802 pred_index: 0,
14803 context_dependent: false,
14804 },
14805 )
14806 .expect("transition");
14807 atn.add_transition(
14808 2,
14809 ParserTransitionSpec::Atom {
14810 target: 3,
14811 label: 2,
14812 },
14813 )
14814 .expect("transition");
14815 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14816 .expect("transition");
14817 finish_atn(atn)
14818 }
14819
14820 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
14821 let mut atn = ParserAtnBuilder::new(1);
14822 for (state_number, kind) in [
14823 (0, AtnStateKind::RuleStart),
14824 (1, AtnStateKind::BlockStart),
14825 (2, AtnStateKind::Basic),
14826 (3, AtnStateKind::Basic),
14827 (4, AtnStateKind::Basic),
14828 (5, AtnStateKind::Basic),
14829 (6, AtnStateKind::BlockEnd),
14830 (7, AtnStateKind::RuleStop),
14831 ] {
14832 assert_eq!(
14833 atn.add_state(kind, Some(0)).expect("state").index(),
14834 state_number
14835 );
14836 }
14837 atn.set_rule_to_start_state(vec![0])
14838 .expect("rule start states");
14839 atn.set_rule_to_stop_state(vec![7])
14840 .expect("rule stop states");
14841 atn.add_decision_state(1).expect("decision state");
14842 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14843 .expect("transition");
14844 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14845 .expect("transition");
14846 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
14847 .expect("transition");
14848 atn.add_transition(
14849 2,
14850 ParserTransitionSpec::Predicate {
14851 target: 4,
14852 rule_index: 0,
14853 pred_index: pred_indexes[0],
14854 context_dependent: false,
14855 },
14856 )
14857 .expect("transition");
14858 atn.add_transition(
14859 3,
14860 ParserTransitionSpec::Predicate {
14861 target: 5,
14862 rule_index: 0,
14863 pred_index: pred_indexes[1],
14864 context_dependent: false,
14865 },
14866 )
14867 .expect("transition");
14868 atn.add_transition(
14869 4,
14870 ParserTransitionSpec::Atom {
14871 target: 6,
14872 label: 1,
14873 },
14874 )
14875 .expect("transition");
14876 atn.add_transition(
14877 5,
14878 ParserTransitionSpec::Atom {
14879 target: 6,
14880 label: 1,
14881 },
14882 )
14883 .expect("transition");
14884 atn.add_transition(
14885 6,
14886 ParserTransitionSpec::Atom {
14887 target: 7,
14888 label: TOKEN_EOF,
14889 },
14890 )
14891 .expect("transition");
14892 finish_atn(atn)
14893 }
14894
14895 fn nested_nullable_context_atn() -> Atn {
14896 let mut atn = ParserAtnBuilder::new(1);
14897 for state_number in 0..=20 {
14898 let kind = match state_number {
14899 0 | 10 | 16 => AtnStateKind::RuleStart,
14900 9 | 15 | 20 => AtnStateKind::RuleStop,
14901 _ => AtnStateKind::Basic,
14902 };
14903 let rule_index = match state_number {
14904 0..=9 => 0,
14905 10..=15 => 1,
14906 _ => 2,
14907 };
14908 assert_eq!(
14909 atn.add_state(kind, Some(rule_index))
14910 .expect("state")
14911 .index(),
14912 state_number
14913 );
14914 }
14915 atn.set_rule_to_start_state(vec![0, 10, 16])
14916 .expect("rule start states");
14917 atn.set_rule_to_stop_state(vec![9, 15, 20])
14918 .expect("rule stop states");
14919 atn.add_transition(
14920 1,
14921 ParserTransitionSpec::Rule {
14922 target: 10,
14923 rule_index: 1,
14924 follow_state: 8,
14925 precedence: 0,
14926 },
14927 )
14928 .expect("transition");
14929 atn.add_transition(
14930 8,
14931 ParserTransitionSpec::Atom {
14932 target: 9,
14933 label: 1,
14934 },
14935 )
14936 .expect("transition");
14937 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14938 .expect("transition");
14939 atn.add_transition(
14940 2,
14941 ParserTransitionSpec::Rule {
14942 target: 16,
14943 rule_index: 2,
14944 follow_state: 14,
14945 precedence: 0,
14946 },
14947 )
14948 .expect("transition");
14949 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
14950 .expect("transition");
14951 finish_atn(atn)
14952 }
14953
14954 fn generated_match_recovery_atn() -> Atn {
14955 let mut atn = ParserAtnBuilder::new(2);
14956 assert_eq!(
14957 atn.add_state(AtnStateKind::RuleStart, Some(0))
14958 .expect("state")
14959 .index(),
14960 0
14961 );
14962 assert_eq!(
14963 atn.add_state(AtnStateKind::Basic, Some(0))
14964 .expect("state")
14965 .index(),
14966 1
14967 );
14968 assert_eq!(
14969 atn.add_state(AtnStateKind::Basic, Some(0))
14970 .expect("state")
14971 .index(),
14972 2
14973 );
14974 assert_eq!(
14975 atn.add_state(AtnStateKind::RuleStop, Some(0))
14976 .expect("state")
14977 .index(),
14978 3
14979 );
14980 assert_eq!(
14981 atn.add_state(AtnStateKind::RuleStart, Some(1))
14982 .expect("state")
14983 .index(),
14984 4
14985 );
14986 assert_eq!(
14987 atn.add_state(AtnStateKind::RuleStop, Some(1))
14988 .expect("state")
14989 .index(),
14990 5
14991 );
14992 atn.set_rule_to_start_state(vec![0, 4])
14993 .expect("rule start states");
14994 atn.set_rule_to_stop_state(vec![3, 5])
14995 .expect("rule stop states");
14996 atn.add_transition(
14997 1,
14998 ParserTransitionSpec::Rule {
14999 target: 4,
15000 rule_index: 1,
15001 follow_state: 2,
15002 precedence: 0,
15003 },
15004 )
15005 .expect("transition");
15006 atn.add_transition(
15007 2,
15008 ParserTransitionSpec::Atom {
15009 target: 3,
15010 label: TOKEN_EOF,
15011 },
15012 )
15013 .expect("transition");
15014 finish_atn(atn)
15015 }
15016
15017 fn complement_set_atn() -> Atn {
15018 let mut atn = ParserAtnBuilder::new(1);
15019 assert_eq!(
15020 atn.add_state(AtnStateKind::RuleStart, Some(0))
15021 .expect("state")
15022 .index(),
15023 0
15024 );
15025 assert_eq!(
15026 atn.add_state(AtnStateKind::RuleStop, Some(0))
15027 .expect("state")
15028 .index(),
15029 1
15030 );
15031 atn.set_rule_to_start_state(vec![0])
15032 .expect("rule start states");
15033 atn.set_rule_to_stop_state(vec![1])
15034 .expect("rule stop states");
15035 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
15036 atn.add_transition(
15037 0,
15038 ParserTransitionSpec::NotSet {
15039 target: 1,
15040 set: excluded,
15041 },
15042 )
15043 .expect("transition");
15044 finish_atn(atn)
15045 }
15046
15047 fn wildcard_then_eof_atn() -> Atn {
15050 let mut atn = ParserAtnBuilder::new(1);
15051 assert_eq!(
15052 atn.add_state(AtnStateKind::RuleStart, Some(0))
15053 .expect("state")
15054 .index(),
15055 0
15056 );
15057 assert_eq!(
15058 atn.add_state(AtnStateKind::RuleStop, Some(0))
15059 .expect("state")
15060 .index(),
15061 1
15062 );
15063 assert_eq!(
15064 atn.add_state(AtnStateKind::Basic, Some(0))
15065 .expect("state")
15066 .index(),
15067 2
15068 );
15069 atn.set_rule_to_start_state(vec![0])
15070 .expect("rule start states");
15071 atn.set_rule_to_stop_state(vec![1])
15072 .expect("rule stop states");
15073 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
15074 .expect("transition");
15075 atn.add_transition(
15076 2,
15077 ParserTransitionSpec::Atom {
15078 target: 1,
15079 label: TOKEN_EOF,
15080 },
15081 )
15082 .expect("transition");
15083 finish_atn(atn)
15084 }
15085
15086 #[test]
15087 fn parser_matches_token_and_reports_mismatch() {
15088 let source = Source {
15089 tokens: vec![
15090 TestToken::new(1).with_text("x"),
15091 TestToken::eof("parser-test", 1, 1, 1),
15092 ],
15093 index: 0,
15094 };
15095 let data = RecognizerData::new(
15096 "Mini.g4",
15097 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
15098 );
15099 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
15100 let matched = parser.match_token(1).expect("token 1 should match");
15101 assert_eq!(parser.node(matched).text(), "x");
15102 assert!(parser.match_token(1).is_err());
15103 }
15104
15105 #[test]
15106 fn parser_matches_token_sets() {
15107 let mut parser = mini_parser(vec![
15108 TestToken::new(1).with_text("x"),
15109 TestToken::eof("parser-test", 1, 1, 1),
15110 ]);
15111
15112 let matched = parser
15113 .match_set(&[(1, 1), (3, 4)])
15114 .expect("token set should match");
15115 assert_eq!(parser.node(matched).text(), "x");
15116 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
15117 }
15118
15119 #[test]
15120 fn generated_rule_api_tracks_state_and_precedence() {
15121 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15122
15123 let context = parser.enter_rule(7, 2);
15124 assert_eq!(context.rule_index(), 2);
15125 assert_eq!(parser.state(), 7);
15126 assert_eq!(
15127 parser.rule_context_stack,
15128 vec![RuleContextFrame {
15129 rule_index: 2,
15130 invoking_state: 7
15131 }]
15132 );
15133
15134 let recursive = parser.enter_recursion_rule(11, 3, 4);
15135 assert_eq!(recursive.rule_index(), 3);
15136 assert!(parser.precpred(4));
15137 assert!(parser.precpred(5));
15138 assert!(!parser.precpred(3));
15139
15140 let next = parser.push_new_recursion_context(13, 3);
15141 assert_eq!(next.invoking_state(), 13);
15142 parser.unroll_recursion_context();
15143 assert_eq!(parser.precedence_stack, vec![0]);
15144 assert_eq!(
15145 parser.rule_context_stack,
15146 vec![RuleContextFrame {
15147 rule_index: 2,
15148 invoking_state: 7
15149 }]
15150 );
15151
15152 parser.exit_rule();
15153 assert!(parser.rule_context_stack.is_empty());
15154 }
15155
15156 #[test]
15157 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
15158 let mut parser = mini_parser(vec![
15159 TestToken::new(1).with_text("x"),
15160 TestToken::eof("parser-test", 1, 1, 1),
15161 ]);
15162 let matched = parser.match_token(1).expect("token should match");
15163 assert_eq!(parser.node(matched).text(), "x");
15164 parser.record_generated_syntax_error();
15165 parser.set_int_member(7, 11);
15166 parser.set_build_parse_trees(false);
15167 parser.set_report_diagnostic_errors(true);
15168 parser.set_prediction_mode(PredictionMode::Sll);
15169 parser.set_bail_on_error(true);
15170 let _context = parser.enter_recursion_rule(9, 0, 4);
15171 parser.pending_invoking_states.push(5);
15172 parser.unknown_predicate_hits.push((0, 1));
15173 parser.unhandled_action_hits.push((0, 2));
15174
15175 parser.reset();
15176
15177 assert_eq!(parser.input.index(), 0);
15178 assert_eq!(parser.la(1), 1);
15179 assert_eq!(parser.state(), -1);
15180 assert_eq!(parser.number_of_syntax_errors(), 0);
15181 assert_eq!(parser.parse_tree_storage().node_count(), 0);
15182 assert!(parser.rule_context_stack.is_empty());
15183 assert!(parser.pending_invoking_states.is_empty());
15184 assert_eq!(parser.precedence_stack, [0]);
15185 assert!(parser.unknown_predicate_hits.is_empty());
15186 assert!(parser.unhandled_action_hits.is_empty());
15187 assert_eq!(parser.int_member(7), Some(11));
15188 assert!(!parser.build_parse_trees());
15189 assert!(parser.report_diagnostic_errors());
15190 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
15191 assert!(parser.bail_on_error());
15192 }
15193
15194 #[test]
15195 fn set_token_stream_replaces_input_and_resets_parser() {
15196 let mut parser = mini_parser(vec![
15197 TestToken::new(1).with_text("old"),
15198 TestToken::eof("parser-test", 1, 1, 1),
15199 ]);
15200 parser.consume();
15201 parser.record_generated_syntax_error();
15202 let replacement = CommonTokenStream::new(Source {
15203 tokens: vec![
15204 TestToken::new(2).with_text("new"),
15205 TestToken::eof("parser-test", 1, 1, 1),
15206 ],
15207 index: 0,
15208 });
15209
15210 parser.set_token_stream(replacement);
15211
15212 assert_eq!(parser.input.index(), 0);
15213 assert_eq!(parser.la(1), 2);
15214 assert_eq!(parser.input.text_all(), "new");
15215 assert_eq!(parser.number_of_syntax_errors(), 0);
15216 }
15217
15218 #[test]
15219 fn active_invocation_states_exclude_the_root_frame() {
15220 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15221
15222 let _root = parser.enter_rule(0, 0);
15223 assert!(parser.active_invocation_states().is_empty());
15224
15225 let marker = parser.push_invoking_state(6);
15226 let _child = parser.enter_rule(2, 1);
15227 parser.discard_invoking_state(marker);
15228 assert_eq!(parser.active_invocation_states(), [6]);
15229
15230 let marker = parser.push_invoking_state(13);
15231 let _grandchild = parser.enter_rule(4, 2);
15232 parser.discard_invoking_state(marker);
15233 assert_eq!(parser.active_invocation_states(), [13, 6]);
15234
15235 parser.exit_rule();
15236 parser.exit_rule();
15237 parser.exit_rule();
15238 }
15239
15240 #[test]
15241 fn parser_predicates_support_token_adjacency() {
15242 let mut parser = mini_parser(vec![
15243 TestToken::new(1).with_text("=").with_span(0, 0),
15244 TestToken::new(1).with_text(">").with_span(1, 1),
15245 TestToken::eof("parser-test", 2, 1, 2),
15246 ]);
15247 parser.consume();
15248 parser.consume();
15249
15250 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
15251
15252 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
15253
15254 let mut parser = mini_parser(vec![
15255 TestToken::new(1).with_text("=").with_span(0, 0),
15256 TestToken::new(1)
15257 .with_text(" ")
15258 .with_channel(HIDDEN_CHANNEL)
15259 .with_span(1, 1),
15260 TestToken::new(1).with_text(">").with_span(2, 2),
15261 TestToken::eof("parser-test", 3, 1, 3),
15262 ]);
15263 parser.consume();
15264 parser.consume();
15265
15266 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
15267 }
15268
15269 #[test]
15270 fn parser_predicates_support_context_child_text_checks() {
15271 let mut parser = mini_parser(vec![
15272 TestToken::new(1).with_text("var"),
15273 TestToken::eof("parser-test", 1, 1, 1),
15274 ]);
15275 let mut context = ParserRuleContext::new(1, 0);
15276 let mut child_context = ParserRuleContext::new(2, 0);
15277 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
15278 parser.tree.add_child(&mut child_context, terminal);
15279 let child = parser.rule_node(child_context);
15280 parser.tree.add_child(&mut context, child);
15281 let predicates = [(
15282 1,
15283 0,
15284 ParserPredicate::ContextChildRuleTextNotEquals {
15285 rule_index: 2,
15286 text: "var",
15287 },
15288 )];
15289
15290 assert!(
15291 !parser.parser_semantic_predicate_matches_with_context_and_local(
15292 &predicates,
15293 1,
15294 0,
15295 &context,
15296 0,
15297 )
15298 );
15299 }
15300
15301 #[test]
15302 fn context_expected_symbols_walks_nullable_parent_contexts() {
15303 let atn = nested_nullable_context_atn();
15304 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15305 parser.rule_context_stack = vec![
15306 RuleContextFrame {
15307 rule_index: 0,
15308 invoking_state: 0,
15309 },
15310 RuleContextFrame {
15311 rule_index: 1,
15312 invoking_state: 1,
15313 },
15314 RuleContextFrame {
15315 rule_index: 2,
15316 invoking_state: 2,
15317 },
15318 ];
15319
15320 let expected = parser.context_expected_symbols(&atn);
15321
15322 assert!(expected.contains(&1));
15323 assert!(expected.contains(&TOKEN_EOF));
15324 }
15325
15326 #[test]
15327 fn prediction_context_return_states_track_rule_stack_changes() {
15328 let atn = nested_nullable_context_atn();
15329 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15330 parser.rule_context_stack = vec![
15331 RuleContextFrame {
15332 rule_index: 0,
15333 invoking_state: 0,
15334 },
15335 RuleContextFrame {
15336 rule_index: 1,
15337 invoking_state: 1,
15338 },
15339 RuleContextFrame {
15340 rule_index: 2,
15341 invoking_state: 2,
15342 },
15343 ];
15344
15345 let initial_version = parser.rule_context_version();
15346 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15347 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15348 assert_eq!(first, second);
15349 assert_eq!(parser.rule_context_version(), initial_version);
15350
15351 parser.exit_rule();
15352 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15353 assert_ne!(first, after_pop);
15354 assert_ne!(parser.rule_context_version(), initial_version);
15355 }
15356
15357 #[test]
15358 fn generated_match_token_recovers_missing_token_from_context_follow() {
15359 let atn = generated_match_recovery_atn();
15360 let data = RecognizerData::new(
15361 "Mini.g4",
15362 Vocabulary::new(
15363 [None, Some("'X'"), Some("'Y'")],
15364 [None, Some("X"), Some("Y")],
15365 [None::<&str>, None, None],
15366 ),
15367 );
15368 let mut parser = BaseParser::new(
15369 CommonTokenStream::new(Source {
15370 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
15371 index: 0,
15372 }),
15373 data,
15374 );
15375 parser.rule_context_stack = vec![
15376 RuleContextFrame {
15377 rule_index: 0,
15378 invoking_state: 0,
15379 },
15380 RuleContextFrame {
15381 rule_index: 1,
15382 invoking_state: 1,
15383 },
15384 ];
15385 assert_eq!(parser.number_of_syntax_errors(), 0);
15386
15387 let node = parser
15388 .match_token_recovering(2, 5, &atn)
15389 .expect("generated match should insert missing token");
15390
15391 assert_eq!(node.children().len(), 1);
15392 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
15393 assert_eq!(
15394 node.clone()
15395 .into_child_iter()
15396 .map(|child| parser.node(child).text())
15397 .collect::<Vec<_>>(),
15398 ["<missing 'Y'>"]
15399 );
15400 assert!(!node.consumed_eof());
15403 assert_eq!(parser.la(1), TOKEN_EOF);
15404 assert_eq!(parser.number_of_syntax_errors(), 1);
15405 assert_eq!(
15406 parser.generated_parser_diagnostics,
15407 [ParserDiagnostic {
15408 line: 1,
15409 column: 3,
15410 message: "missing 'Y' at '<EOF>'".to_owned(),
15411 }]
15412 );
15413 }
15414
15415 #[test]
15416 fn generated_match_token_counts_single_token_deletion_recovery() {
15417 let atn = generated_match_recovery_atn();
15418 let data = RecognizerData::new(
15419 "Mini.g4",
15420 Vocabulary::new(
15421 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
15422 [None, Some("X"), Some("Y"), Some("Z")],
15423 [None::<&str>, None, None, None],
15424 ),
15425 );
15426 let mut parser = BaseParser::new(
15427 CommonTokenStream::new(Source {
15428 tokens: vec![
15429 TestToken::new(3).with_text("z"),
15430 TestToken::new(2).with_text("y"),
15431 TestToken::eof("parser-test", 3, 1, 3),
15432 ],
15433 index: 0,
15434 }),
15435 data,
15436 );
15437
15438 let node = parser
15439 .match_token_recovering(2, 5, &atn)
15440 .expect("generated match should delete the extraneous token");
15441
15442 assert_eq!(node.children().len(), 2);
15443 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
15444 assert_eq!(parser.node(node.children()[0]).text(), "z");
15445 assert_eq!(parser.node(node.children()[1]).text(), "y");
15446 assert_eq!(
15447 node.into_child_iter()
15448 .map(|child| parser.node(child).text())
15449 .collect::<Vec<_>>(),
15450 ["z", "y"]
15451 );
15452 assert_eq!(parser.number_of_syntax_errors(), 1);
15453 }
15454
15455 #[test]
15456 fn generated_match_token_iterates_single_success_without_a_children_vec() {
15457 let atn = generated_match_recovery_atn();
15458 let data = RecognizerData::new(
15459 "Mini.g4",
15460 Vocabulary::new(
15461 [None, Some("'X'"), Some("'Y'")],
15462 [None, Some("X"), Some("Y")],
15463 [None::<&str>, None, None],
15464 ),
15465 );
15466 let mut parser = BaseParser::new(
15467 CommonTokenStream::new(Source {
15468 tokens: vec![
15469 TestToken::new(2).with_text("y"),
15470 TestToken::eof("parser-test", 1, 1, 1),
15471 ],
15472 index: 0,
15473 }),
15474 data,
15475 );
15476
15477 let node = parser
15478 .match_token_recovering(2, 5, &atn)
15479 .expect("generated match should consume the expected token");
15480
15481 assert_eq!(
15482 node.into_child_iter()
15483 .map(|child| parser.node(child).text())
15484 .collect::<Vec<_>>(),
15485 ["y"]
15486 );
15487 assert_eq!(parser.number_of_syntax_errors(), 0);
15488 }
15489
15490 #[test]
15491 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
15492 let atn = generated_match_recovery_atn();
15493 let data = RecognizerData::new(
15494 "Mini.g4",
15495 Vocabulary::new(
15496 [None, Some("'X'"), Some("'Y'")],
15497 [None, Some("X"), Some("Y")],
15498 [None::<&str>, None, None],
15499 ),
15500 );
15501 let mut parser = BaseParser::new(
15502 CommonTokenStream::new(Source {
15503 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
15504 index: 0,
15505 }),
15506 data,
15507 );
15508 parser.rule_context_stack = vec![
15509 RuleContextFrame {
15510 rule_index: 0,
15511 invoking_state: 0,
15512 },
15513 RuleContextFrame {
15514 rule_index: 1,
15515 invoking_state: 1,
15516 },
15517 ];
15518 let marker = parser.generated_diagnostics_checkpoint();
15519
15520 let _ = parser
15521 .match_token_recovering(2, 5, &atn)
15522 .expect("generated match should insert missing token");
15523 assert_eq!(parser.number_of_syntax_errors(), 1);
15524
15525 parser.restore_generated_diagnostics(marker);
15526
15527 assert_eq!(parser.number_of_syntax_errors(), 0);
15528 assert!(parser.generated_parser_diagnostics.is_empty());
15529 }
15530
15531 #[test]
15532 fn generated_prediction_diagnostics_use_adaptive_context() {
15533 let atn = two_alt_decision_atn();
15534 let data = RecognizerData::new(
15535 "Mini.g4",
15536 Vocabulary::new(
15537 [None, Some("'x'"), Some("'y'")],
15538 [None, Some("X"), Some("Y")],
15539 [None::<&str>, None, None],
15540 ),
15541 )
15542 .with_rule_names(["s"]);
15543 let mut parser = BaseParser::new(
15544 CommonTokenStream::new(Source {
15545 tokens: vec![
15546 TestToken::new(1)
15547 .with_text("x")
15548 .with_position(1, 0)
15549 .with_span(0, 0),
15550 TestToken::new(2)
15551 .with_text("y")
15552 .with_position(1, 2)
15553 .with_span(1, 1),
15554 TestToken::eof("parser-test", 2, 1, 3),
15555 ],
15556 index: 0,
15557 }),
15558 data,
15559 );
15560 parser.set_report_diagnostic_errors(true);
15561
15562 parser.record_generated_prediction_diagnostic(
15563 &atn,
15564 1,
15565 &ParserAtnPrediction {
15566 alt: 1,
15567 requires_full_context: true,
15568 has_semantic_context: false,
15569 diagnostic: Some(ParserAtnPredictionDiagnostic {
15570 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
15571 start_index: 0,
15572 sll_stop_index: 1,
15573 ll_stop_index: 0,
15574 conflicting_alts: vec![1, 2],
15575 exact: false,
15576 }),
15577 },
15578 );
15579 parser.record_generated_prediction_diagnostic(
15584 &atn,
15585 1,
15586 &ParserAtnPrediction {
15587 alt: 1,
15588 requires_full_context: true,
15589 has_semantic_context: false,
15590 diagnostic: Some(ParserAtnPredictionDiagnostic {
15591 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
15592 start_index: 0,
15593 sll_stop_index: 1,
15594 ll_stop_index: 1,
15595 conflicting_alts: vec![1, 2],
15596 exact: false,
15597 }),
15598 },
15599 );
15600
15601 insta::assert_debug_snapshot!(
15604 "generated_prediction_diagnostics_use_adaptive_context",
15605 parser.generated_parser_diagnostics
15606 );
15607 }
15608
15609 #[test]
15610 fn generated_match_not_set_recovers_empty_complement_at_eof() {
15611 let atn = complement_set_atn();
15612 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15613 parser.rule_context_stack = vec![RuleContextFrame {
15614 rule_index: 0,
15615 invoking_state: 0,
15616 }];
15617
15618 let node = parser
15619 .match_not_token_set_recovering(
15620 atn.token_set(0).expect("excluded token set"),
15621 1,
15622 1,
15623 1,
15624 &atn,
15625 )
15626 .expect("empty complement should recover at EOF");
15627
15628 assert_eq!(node.children().len(), 1);
15629 assert!(!node.consumed_eof());
15632 assert_eq!(parser.la(1), TOKEN_EOF);
15633 assert_eq!(
15634 parser.generated_parser_diagnostics,
15635 [ParserDiagnostic {
15636 line: 1,
15637 column: 1,
15638 message: "missing {} at '<EOF>'".to_owned(),
15639 }]
15640 );
15641 }
15642
15643 #[test]
15644 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
15645 let atn = wildcard_then_eof_atn();
15651 let data = RecognizerData::new(
15652 "Mini.g4",
15653 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
15654 );
15655 let mut parser = BaseParser::new(
15656 CommonTokenStream::new(Source {
15657 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
15658 index: 0,
15659 }),
15660 data,
15661 );
15662 parser.rule_context_stack = vec![RuleContextFrame {
15663 rule_index: 0,
15664 invoking_state: 0,
15665 }];
15666
15667 let node = parser
15668 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
15669 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
15670
15671 assert_eq!(node.children().len(), 1);
15673 assert!(!node.consumed_eof());
15674 assert!(
15675 parser
15676 .node(node.children()[0])
15677 .text()
15678 .starts_with("<missing")
15679 );
15680 assert_eq!(parser.la(1), TOKEN_EOF);
15681 assert_eq!(
15682 parser.generated_parser_diagnostics,
15683 [ParserDiagnostic {
15684 line: 1,
15685 column: 1,
15686 message: "missing 'x' at '<EOF>'".to_owned(),
15687 }]
15688 );
15689 }
15690
15691 #[test]
15692 fn generated_rule_recovery_consumes_to_parent_follow() {
15693 let atn = generated_match_recovery_atn();
15694 let data = RecognizerData::new(
15695 "Mini.g4",
15696 Vocabulary::new(
15697 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
15698 [None, Some("X"), Some("Y"), Some("Z")],
15699 [None::<&str>, None, None, None],
15700 ),
15701 );
15702 let mut parser = BaseParser::new(
15703 CommonTokenStream::new(Source {
15704 tokens: vec![
15705 TestToken::new(3).with_text("z"),
15706 TestToken::eof("parser-test", 1, 1, 1),
15707 ],
15708 index: 0,
15709 }),
15710 data,
15711 );
15712 let _parent = parser.enter_rule(0, 0);
15713 let marker = parser.push_invoking_state(1);
15714 let mut child = parser.enter_rule(4, 1);
15715 parser.discard_invoking_state(marker);
15716
15717 parser.recover_generated_rule(
15718 &mut child,
15719 &atn,
15720 AntlrError::ParserError {
15721 line: 1,
15722 column: 0,
15723 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
15724 },
15725 );
15726 let tree = parser.finish_rule(child, false);
15727
15728 assert_eq!(parser.la(1), TOKEN_EOF);
15729 assert_eq!(
15730 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
15731 "(a z)"
15732 );
15733 assert_eq!(parser.number_of_syntax_errors(), 1);
15734 assert_eq!(
15735 parser.generated_parser_diagnostics,
15736 [ParserDiagnostic {
15737 line: 1,
15738 column: 0,
15739 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
15740 }]
15741 );
15742 parser.exit_rule();
15743 }
15744
15745 #[test]
15746 fn generated_rule_recovery_forces_progress_after_repeated_error_state() {
15747 let atn = nested_nullable_context_atn();
15748 let mut parser = mini_parser(vec![
15749 TestToken::new(1).with_text("x"),
15750 TestToken::eof("parser-test", 1, 1, 1),
15751 ]);
15752 parser.rule_context_stack = vec![
15753 RuleContextFrame {
15754 rule_index: 0,
15755 invoking_state: 0,
15756 },
15757 RuleContextFrame {
15758 rule_index: 1,
15759 invoking_state: 1,
15760 },
15761 RuleContextFrame {
15762 rule_index: 2,
15763 invoking_state: 2,
15764 },
15765 ];
15766 parser.set_state(20);
15767 let mut context = ParserRuleContext::new(2, 2);
15768
15769 parser.recover_generated_rule(
15770 &mut context,
15771 &atn,
15772 AntlrError::NoViableAlternative {
15773 input: "'x'".to_owned(),
15774 },
15775 );
15776 assert_eq!(parser.input.index(), 0);
15777
15778 parser.set_state(21);
15779 parser.recover_generated_rule(
15780 &mut context,
15781 &atn,
15782 AntlrError::NoViableAlternative {
15783 input: "'x'".to_owned(),
15784 },
15785 );
15786 assert_eq!(parser.input.index(), 0);
15787 assert_eq!(
15788 parser.generated_recovery_error_states,
15789 BTreeSet::from([20, 21])
15790 );
15791
15792 parser.set_state(20);
15793 parser.recover_generated_rule(
15794 &mut context,
15795 &atn,
15796 AntlrError::NoViableAlternative {
15797 input: "'x'".to_owned(),
15798 },
15799 );
15800
15801 assert_eq!(parser.input.index(), 1);
15802 assert_eq!(parser.la(1), TOKEN_EOF);
15803 assert!(context.has_matched_child());
15804 assert_eq!(parser.generated_recovery_error_states, BTreeSet::from([20]));
15805
15806 parser.match_eof().expect("EOF should match");
15807 assert_eq!(parser.generated_recovery_error_index, None);
15808 assert!(parser.generated_recovery_error_states.is_empty());
15809 }
15810
15811 #[test]
15812 fn greedy_ll1_alt_handles_nullable_loop_exit() {
15813 let mut body_symbols = TokenBitSet::default();
15814 body_symbols.insert(1);
15815 let entry = DecisionLookahead {
15816 transitions: vec![
15817 TransitionLookSet {
15818 symbols: body_symbols,
15819 nullable: false,
15820 },
15821 TransitionLookSet {
15822 symbols: TokenBitSet::default(),
15823 nullable: true,
15824 },
15825 ],
15826 };
15827
15828 assert_eq!(ll1_unique_alt(&entry, 2), None);
15829 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
15830 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
15831 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
15832 }
15833
15834 #[test]
15835 fn ordinary_repetition_builds_tree_in_input_order() {
15836 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15837 let mut parser = mini_parser(repeated_x_tokens(3));
15838 let tree = parser
15839 .parse_atn_rule(&atn, 0)
15840 .expect("ordinary repetition should parse");
15841
15842 let root = parser
15843 .node(tree)
15844 .as_rule()
15845 .expect("entry result should be a rule");
15846 let body_rules = root.child_rules(1).collect::<Vec<_>>();
15847 assert_eq!(root.text(), "xxx<EOF>");
15848 assert_eq!(body_rules.len(), 3);
15849 assert_eq!(
15850 body_rules
15851 .iter()
15852 .map(|rule| rule.start_id().expect("body start").index())
15853 .collect::<Vec<_>>(),
15854 [0, 1, 2]
15855 );
15856 assert_eq!(
15857 body_rules
15858 .iter()
15859 .map(|rule| rule.stop_id().expect("body stop").index())
15860 .collect::<Vec<_>>(),
15861 [0, 1, 2]
15862 );
15863 assert_eq!(parser.number_of_syntax_errors(), 0);
15864 }
15865 }
15866
15867 #[test]
15868 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
15869 const DEPTH: usize = 20_000;
15870
15871 std::thread::Builder::new()
15872 .name("deferred-rule-materialization".to_owned())
15873 .stack_size(256 * 1024)
15874 .spawn(|| {
15875 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
15876 let mut root = FastDeferredNodeId::EMPTY;
15877 for depth in 0..DEPTH {
15878 root = parser
15879 .recognition_arena
15880 .deferred_rule_node(FastDeferredRule {
15881 rule_index: u32::try_from(depth).expect("depth fits in u32"),
15882 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
15883 start_index: 0,
15884 stop_index: None,
15885 deferred_children: root,
15886 children: NodeSeqId::EMPTY,
15887 });
15888 }
15889
15890 let (mut children, alt_number) =
15891 parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
15892 assert_eq!(alt_number, 0);
15893 for expected_rule in (0..DEPTH).rev() {
15894 let mut nodes = parser.recognition_arena.iter(children);
15895 let node = nodes.next().expect("nested rule node");
15896 assert!(nodes.next().is_none(), "each rule has one child");
15897 let ArenaRecognizedNode::Rule {
15898 rule_index,
15899 children: nested,
15900 ..
15901 } = parser.recognition_arena.node(node)
15902 else {
15903 panic!("expected nested rule");
15904 };
15905 assert_eq!(rule_index as usize, expected_rule);
15906 children = nested;
15907 }
15908 assert!(children.is_empty());
15909 })
15910 .expect("small-stack thread should start")
15911 .join()
15912 .expect("deferred rules should materialize without recursion");
15913 }
15914
15915 #[test]
15916 fn deferred_alternatives_preserve_left_recursive_contexts() {
15917 let mut parser = mini_parser(vec![
15918 TestToken::new(1).with_text("1"),
15919 TestToken::new(2).with_text("+"),
15920 TestToken::new(1).with_text("2"),
15921 TestToken::eof("parser-test", 3, 1, 3),
15922 ]);
15923 let base = parser.arena_token_node(0, false);
15924 let operator = parser.arena_token_node(1, false);
15925 let right = parser.arena_token_node(2, false);
15926
15927 let base = parser.recognition_arena.prepend(NodeSeqId::EMPTY, base);
15928 let base = parser.recognition_arena.deferred_fragment(base);
15929 let operator = parser.recognition_arena.prepend(NodeSeqId::EMPTY, operator);
15930 let operator = parser.recognition_arena.deferred_fragment(operator);
15931 let right = parser.recognition_arena.prepend(NodeSeqId::EMPTY, right);
15932 let right = parser.recognition_arena.deferred_fragment(right);
15933 let base_alt = parser.recognition_arena.deferred_alternative(1);
15934 let boundary = parser.recognition_arena.deferred_left_recursive_boundary(0);
15935 let operator_alt = parser.recognition_arena.deferred_alternative(6);
15936
15937 let mut deferred = FastDeferredNodeId::EMPTY;
15938 for fragment in [base_alt, base, boundary, operator_alt, operator, right] {
15939 deferred = parser
15940 .recognition_arena
15941 .concat_deferred_nodes(deferred, fragment);
15942 }
15943 let (nodes, root_alt_number) =
15944 parser.materialize_fast_deferred_nodes(deferred, NodeSeqId::EMPTY);
15945 let nodes = parser
15946 .recognition_arena
15947 .fold_left_recursive_boundaries(nodes);
15948
15949 let mut root = ParserRuleContext::new(0, -1);
15950 root.set_context_alt_number(root_alt_number);
15951 let mut cursor = nodes;
15952 while let Some(link) = parser.recognition_arena.link(cursor) {
15953 let child = parser
15954 .arena_recognized_node_tree(link.head, false, true)
15955 .expect("materialized child should become a public tree");
15956 parser.tree.add_child(&mut root, child);
15957 cursor = link.tail;
15958 }
15959 let tree = parser.rule_node(root);
15960 let contexts = parser
15961 .node(tree)
15962 .descendants()
15963 .filter_map(Node::as_rule)
15964 .map(|rule| {
15965 (
15966 rule.rule_index(),
15967 rule.alt_number(),
15968 rule.context_alt_number(),
15969 rule.text(),
15970 )
15971 })
15972 .collect::<Vec<_>>();
15973
15974 insta::assert_debug_snapshot!(
15975 "deferred_alternatives_preserve_left_recursive_contexts",
15976 contexts
15977 );
15978 }
15979
15980 #[test]
15981 fn fast_recognizer_preserves_labeled_left_recursive_operator_context() {
15982 let atn = labeled_left_recursive_operator_atn();
15983 let mut parser = mini_parser(vec![
15984 TestToken::new(1).with_text("a"),
15985 TestToken::new(3).with_text("+"),
15986 TestToken::new(1).with_text("b"),
15987 TestToken::eof("parser-test", 3, 1, 3),
15988 ]);
15989
15990 let (tree, _) = parser
15991 .parse_atn_rule_with_runtime_options(
15992 &atn,
15993 0,
15994 ParserRuntimeOptions {
15995 track_context_alt_numbers: true,
15996 ..ParserRuntimeOptions::default()
15997 },
15998 )
15999 .expect("labeled left-recursive addition should parse");
16000 let contexts = parser
16001 .node(tree)
16002 .descendants()
16003 .filter_map(Node::as_rule)
16004 .map(|rule| {
16005 let operator = rule
16006 .children()
16007 .next()
16008 .and_then(Node::as_rule)
16009 .is_some_and(|child| child.rule_index() == rule.rule_index());
16010 (operator, rule.context_alt_number(), rule.text())
16011 })
16012 .collect::<Vec<_>>();
16013
16014 insta::assert_debug_snapshot!(
16015 "fast_recognizer_preserves_labeled_left_recursive_operator_context",
16016 contexts
16017 );
16018 assert!(!parser.recognition_arena.deferred_nodes.is_empty());
16019 assert_eq!(parser.number_of_syntax_errors(), 0);
16020 }
16021
16022 #[test]
16023 fn deeply_nested_rule_calls_grow_the_stack() {
16024 const DEPTH: usize = 4_096;
16025 const STACK_SIZE: usize = 256 * 1024;
16026 let atn = nested_rule_chain_atn(DEPTH);
16027 std::thread::Builder::new()
16028 .name("nested-adaptive-set-rules".to_owned())
16029 .stack_size(STACK_SIZE)
16030 .spawn(move || {
16031 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
16032 parser.set_build_parse_trees(false);
16033 parser.fast_first_set_prefilter = false;
16036 parser
16037 .parse_atn_rule(&atn, 0)
16038 .expect("nested rule chain should grow the native stack");
16039 assert_eq!(parser.input.index(), 1);
16040 })
16041 .expect("small-stack thread should start")
16042 .join()
16043 .expect("nested rule chain should not overflow its stack");
16044 }
16045
16046 #[test]
16047 fn deeply_nested_branching_rules_grow_the_stack() {
16048 const DEPTH: usize = 4_096;
16049 const STACK_SIZE: usize = 256 * 1024;
16050 let atn = nested_rule_graph_atn(DEPTH, true, false);
16051 std::thread::Builder::new()
16052 .name("nested-branching-rules".to_owned())
16053 .stack_size(STACK_SIZE)
16054 .spawn(move || {
16055 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
16056 parser.set_build_parse_trees(false);
16057 parser
16058 .parse_atn_rule(&atn, 0)
16059 .expect("branching rule chain should grow the native stack");
16060 assert_eq!(parser.input.index(), 1);
16061 })
16062 .expect("small-stack thread should start")
16063 .join()
16064 .expect("branching rule chain should not overflow its stack");
16065 }
16066
16067 #[test]
16068 fn deeply_nested_rule_follows_grow_the_stack() {
16069 const DEPTH: usize = 4_096;
16070 const STACK_SIZE: usize = 256 * 1024;
16071 let atn = nested_rule_graph_atn(DEPTH, false, true);
16072 std::thread::Builder::new()
16073 .name("nested-rule-follows".to_owned())
16074 .stack_size(STACK_SIZE)
16075 .spawn(move || {
16076 let mut parser = mini_parser(repeated_x_tokens(DEPTH));
16077 parser.set_build_parse_trees(false);
16078 parser.fast_first_set_prefilter = false;
16079 parser
16080 .parse_atn_rule(&atn, 0)
16081 .expect("rule follow chain should grow the native stack");
16082 assert_eq!(parser.input.index(), DEPTH);
16083 })
16084 .expect("small-stack thread should start")
16085 .join()
16086 .expect("nested rule follow chain should not overflow its stack");
16087 }
16088
16089 #[test]
16090 fn deeply_nested_recovery_grows_the_stack() {
16091 const DEPTH: usize = 4_096;
16092 const STACK_SIZE: usize = 256 * 1024;
16093 let atn = nested_rule_chain_atn(DEPTH);
16094 std::thread::Builder::new()
16095 .name("nested-rule-recovery".to_owned())
16096 .stack_size(STACK_SIZE)
16097 .spawn(move || {
16098 let mut parser = mini_parser(vec![
16099 TestToken::new(2).with_text("z"),
16100 TestToken::new(1).with_text("x"),
16101 TestToken::eof("parser-test", 2, 1, 2),
16102 ]);
16103 parser.set_build_parse_trees(false);
16104 parser.fast_first_set_prefilter = false;
16105 parser
16106 .parse_atn_rule(&atn, 0)
16107 .expect("nested recovery should grow the native stack");
16108 assert_eq!(parser.input.index(), 2);
16109 assert_eq!(parser.number_of_syntax_errors(), 1);
16110 })
16111 .expect("small-stack thread should start")
16112 .join()
16113 .expect("nested rule recovery should not overflow its stack");
16114 }
16115
16116 #[test]
16117 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
16118 const REPETITIONS: usize = 64;
16119
16120 let atn = ambiguous_ordinary_star_loop_atn();
16121 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16122 let tree = parser
16123 .parse_atn_rule(&atn, 0)
16124 .expect("ambiguous ordinary repetition should parse");
16125
16126 let root = parser
16127 .node(tree)
16128 .as_rule()
16129 .expect("entry result should be a rule");
16130 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
16131 assert_eq!(parser.input.index(), REPETITIONS);
16132 assert!(
16133 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
16134 "equivalent segmentations should keep deferred storage linear"
16135 );
16136 assert_eq!(parser.number_of_syntax_errors(), 0);
16137 }
16138
16139 #[test]
16140 fn long_ordinary_repetition_does_not_consume_native_stack() {
16141 const REPETITIONS: usize = 20_000;
16142
16143 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
16144 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16145 parser.set_build_parse_trees(false);
16146 parser
16147 .parse_atn_rule(&atn, 0)
16148 .expect("long ordinary repetition should parse");
16149
16150 assert_eq!(parser.input.index(), REPETITIONS);
16151 assert_eq!(parser.number_of_syntax_errors(), 0);
16152 }
16153 }
16154
16155 #[test]
16156 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
16157 const REPETITIONS: usize = 2_000;
16158 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
16159
16160 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
16161 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16162 let tree = parser
16163 .parse_atn_rule(&atn, 0)
16164 .expect("long rule repetition should parse");
16165
16166 let root = parser
16167 .node(tree)
16168 .as_rule()
16169 .expect("entry result should be a rule");
16170 assert_eq!(root.text(), expected_text);
16171 assert_eq!(root.child_rules(1).count(), REPETITIONS);
16172 let first_body = root.child_rules(1).next().expect("first body rule");
16173 let last_body = root.child_rules(1).next_back().expect("last body rule");
16174 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
16175 assert_eq!(
16176 last_body.stop_id().expect("last body stop").index(),
16177 REPETITIONS - 1
16178 );
16179
16180 let stats = parser.recognition_arena_stats();
16181 assert_eq!(
16182 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
16183 (REPETITIONS, REPETITIONS, 0)
16184 );
16185 assert_eq!(
16186 (stats.total_links, stats.live_links, stats.dead_links),
16187 (REPETITIONS, REPETITIONS, 0)
16188 );
16189 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
16190 assert_eq!(
16191 parser.recognition_arena.deferred_nodes.len(),
16192 REPETITIONS * 2 - 1
16193 );
16194 assert_eq!(parser.number_of_syntax_errors(), 0);
16195 }
16196 }
16197
16198 #[test]
16199 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
16200 let key = |state_number| FastRecognizeKey {
16201 state_number,
16202 stop_state: 10,
16203 index: state_number,
16204 rule_start_index: 0,
16205 decision_start_index: None,
16206 precedence: 0,
16207 recovery_symbols_id: 0,
16208 recovery_state: None,
16209 };
16210
16211 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16212 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
16213 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
16214 }
16215 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
16216 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
16217
16218 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16219 let repeated = key(1);
16220 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
16221 assert!(promote.clean_memo_enabled_for_key(&repeated));
16222 }
16223 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
16224
16225 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
16226 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
16227 }
16228 assert!(sparse.clean_memo_enabled_for_key(&repeated));
16229 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
16230 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
16231 assert!(sparse.clean_memo_enabled_for_key(&repeated));
16232 }
16233 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
16234 }
16235
16236 #[test]
16237 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
16238 assert_eq!(
16239 fast_recognize_memo_capacity(0),
16240 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
16241 );
16242 assert_eq!(
16243 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
16244 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
16245 );
16246 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
16247 assert_eq!(
16248 fast_recognize_memo_capacity(usize::MAX),
16249 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
16250 );
16251 }
16252
16253 #[test]
16254 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
16255 let mut scratch = FastRecognizeTopScratch::default();
16256 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
16257 let retained_capacity = scratch.memo.capacity();
16258 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
16259 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16260
16261 let larger_capacity = retained_capacity + 1;
16262 scratch.prepare(larger_capacity);
16263 let grown_capacity = scratch.memo.capacity();
16264 assert!(grown_capacity >= larger_capacity);
16265 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16266
16267 scratch.memo.insert(
16268 FastRecognizeKey {
16269 state_number: 0,
16270 stop_state: 0,
16271 index: 0,
16272 rule_start_index: 0,
16273 decision_start_index: None,
16274 precedence: 0,
16275 recovery_symbols_id: 0,
16276 recovery_state: None,
16277 },
16278 Rc::from([FastRecognizeOutcome {
16279 index: 0,
16280 consumed_eof: false,
16281 diagnostics: DiagnosticSeqId::EMPTY,
16282 deferred_nodes: FastDeferredNodeId::EMPTY,
16283 nodes: NodeSeqId::EMPTY,
16284 }]),
16285 );
16286 scratch.release_oversized_memo();
16287 assert!(scratch.memo.is_empty());
16288 assert_eq!(scratch.memo.capacity(), grown_capacity);
16289
16290 scratch
16291 .memo
16292 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
16293 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16294
16295 scratch.release_oversized_memo();
16296 assert!(scratch.memo.is_empty());
16297 assert_eq!(scratch.memo.capacity(), 0);
16298 }
16299
16300 #[test]
16301 fn clean_empty_multi_alt_outcomes_are_memoized() {
16302 let mut atn = ParserAtnBuilder::new(2);
16303 assert_eq!(
16304 atn.add_state(AtnStateKind::RuleStart, Some(0))
16305 .expect("state")
16306 .index(),
16307 0
16308 );
16309 assert_eq!(
16310 atn.add_state(AtnStateKind::BlockStart, Some(0))
16311 .expect("state")
16312 .index(),
16313 1
16314 );
16315 assert_eq!(
16316 atn.add_state(AtnStateKind::RuleStop, Some(0))
16317 .expect("state")
16318 .index(),
16319 2
16320 );
16321 atn.set_rule_to_start_state(vec![0])
16322 .expect("rule start states");
16323 atn.set_rule_to_stop_state(vec![2])
16324 .expect("rule stop states");
16325 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16326 .expect("transition");
16327 atn.add_transition(
16328 1,
16329 ParserTransitionSpec::Atom {
16330 target: 2,
16331 label: 1,
16332 },
16333 )
16334 .expect("transition");
16335 atn.add_transition(
16336 1,
16337 ParserTransitionSpec::Atom {
16338 target: 2,
16339 label: 2,
16340 },
16341 )
16342 .expect("transition");
16343 let atn = finish_atn(atn);
16344
16345 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
16346 parser.fast_recovery_enabled = false;
16347 let mut visiting = FxHashSet::default();
16348 let mut memo = FxHashMap::default();
16349 let mut expected = ExpectedTokens::default();
16350 let outcomes = parser.recognize_state_fast(
16351 &atn,
16352 FastRecognizeRequest {
16353 state_number: 1,
16354 stop_state: 2,
16355 index: 0,
16356 rule_start_index: 0,
16357 decision_start_index: None,
16358 precedence: 0,
16359 depth: 0,
16360 recovery_symbols: parser.empty_recovery_symbols(),
16361 recovery_state: None,
16362 },
16363 FastRecognizeScratch {
16364 predicate_context: None,
16365 visiting: &mut visiting,
16366 memo: &mut memo,
16367 expected: &mut expected,
16368 native_depth: 0,
16369 },
16370 );
16371
16372 assert!(outcomes.is_empty());
16373 assert_eq!(memo.len(), 1);
16374 assert!(memo.values().next().expect("memo entry").is_empty());
16375
16376 parser.clean_memo_mode = CleanMemoMode::Sparse;
16377 visiting.clear();
16378 memo.clear();
16379 expected = ExpectedTokens::default();
16380 let sparse_outcomes = parser.recognize_state_fast(
16381 &atn,
16382 FastRecognizeRequest {
16383 state_number: 1,
16384 stop_state: 2,
16385 index: 0,
16386 rule_start_index: 0,
16387 decision_start_index: None,
16388 precedence: 0,
16389 depth: 0,
16390 recovery_symbols: parser.empty_recovery_symbols(),
16391 recovery_state: None,
16392 },
16393 FastRecognizeScratch {
16394 predicate_context: None,
16395 visiting: &mut visiting,
16396 memo: &mut memo,
16397 expected: &mut expected,
16398 native_depth: 0,
16399 },
16400 );
16401
16402 assert!(sparse_outcomes.is_empty());
16403 assert!(memo.is_empty());
16404 }
16405
16406 #[test]
16407 fn wildcard_matches_non_eof_only() {
16408 let mut parser = mini_parser(vec![
16409 TestToken::new(1).with_text("x"),
16410 TestToken::eof("parser-test", 1, 1, 1),
16411 ]);
16412 let matched = parser.match_wildcard().expect("wildcard");
16413 assert_eq!(parser.node(matched).text(), "x");
16414 assert!(parser.match_wildcard().is_err());
16415 }
16416
16417 #[test]
16418 fn add_parse_child_records_match_even_without_tree_building() {
16419 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16424 let token = TestToken::new(1).with_text("x");
16425
16426 parser.set_build_parse_trees(false);
16427 let mut ctx = ParserRuleContext::new(0, 0);
16428 assert!(!ctx.has_matched_child());
16429 let child = parser.terminal_tree(token.id);
16430 parser.add_parse_child(&mut ctx, child);
16431 assert_eq!(ctx.child_count(), 0);
16433 assert_eq!(parser.parse_tree_storage().node_count(), 0);
16434 assert!(ctx.has_matched_child());
16436
16437 parser.set_build_parse_trees(true);
16439 let mut ctx = ParserRuleContext::new(0, 0);
16440 let child = parser.terminal_tree(token.id);
16441 parser.add_parse_child(&mut ctx, child);
16442 assert_eq!(ctx.child_count(), 1);
16443 assert!(ctx.has_matched_child());
16444 }
16445
16446 #[test]
16447 fn disabled_tree_building_does_not_grow_flat_storage() {
16448 let mut parser = mini_parser(vec![
16449 TestToken::new(1).with_text("x"),
16450 TestToken::new(1).with_text("y"),
16451 TestToken::eof("parser-test", 2, 1, 2),
16452 ]);
16453 parser.set_build_parse_trees(false);
16454 let mut context = ParserRuleContext::new(0, -1);
16455
16456 for _ in 0..2 {
16457 let child = parser.match_token(1).expect("token should match");
16458 parser.add_parse_child(&mut context, child);
16459 }
16460 let current = parser.input.lt_id(1).expect("EOF token");
16461 let error = parser.error_tree(current);
16462 parser.add_parse_child(&mut context, error);
16463 let root = parser.rule_node(context);
16464
16465 assert_eq!(
16466 parser.parse_tree_storage().stats(),
16467 ParseTreeStats::default()
16468 );
16469 assert!(
16470 parser
16471 .parse_tree_storage()
16472 .node(parser.token_store(), root)
16473 .is_none(),
16474 "the no-tree sentinel must not resolve to stored data"
16475 );
16476 }
16477
16478 #[test]
16479 fn disabled_tree_building_skips_recognition_rule_node_storage() {
16480 let atn = ordinary_star_loop_atn();
16481 let mut parser = mini_parser(repeated_x_tokens(3));
16482 parser.set_build_parse_trees(false);
16483
16484 parser
16485 .parse_atn_rule(&atn, 0)
16486 .expect("ordinary repetition should parse without a tree");
16487
16488 assert_eq!(parser.input.index(), 3);
16489 assert!(parser.recognition_arena.nodes.is_empty());
16490 assert!(parser.recognition_arena.seq_links.is_empty());
16491 assert!(parser.recognition_arena.deferred_nodes.is_empty());
16492 assert!(parser.recognition_arena.deferred_rules.is_empty());
16493 assert!(!parser.fast_token_nodes_enabled);
16494 assert!(parser.fast_recognize_scratch.memo.is_empty());
16495 }
16496
16497 #[test]
16498 fn parser_interprets_simple_atn_rule() {
16499 let atn = token_then_eof_atn();
16500 let mut parser = mini_parser(vec![
16501 TestToken::new(1).with_text("x"),
16502 TestToken::eof("parser-test", 1, 1, 1),
16503 ]);
16504
16505 let tree = parser
16506 .parse_atn_rule(&atn, 0)
16507 .expect("artificial parser rule should parse");
16508 assert_eq!(parser.node(tree).text(), "x<EOF>");
16509 assert_eq!(parser.number_of_syntax_errors(), 0);
16510 assert_eq!(
16511 parser
16512 .node(tree)
16513 .first_rule_stop(0)
16514 .expect("rule should stop at EOF")
16515 .token_type(),
16516 TOKEN_EOF
16517 );
16518
16519 let mut parser = mini_parser(vec![
16520 TestToken::new(1).with_text("x"),
16521 TestToken::eof("parser-test", 1, 1, 1),
16522 ]);
16523 let (tree, actions) = parser
16524 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16525 .expect("runtime-option parser rule should parse");
16526 assert!(actions.is_empty());
16527 assert_eq!(
16528 parser
16529 .node(tree)
16530 .first_rule_stop(0)
16531 .expect("rule should stop at EOF")
16532 .token_type(),
16533 TOKEN_EOF
16534 );
16535 }
16536
16537 #[test]
16538 fn runtime_options_default_ignores_noop_action_transitions() {
16539 let atn = noop_action_then_token_then_eof_atn();
16540 let mut parser = mini_parser(vec![
16541 TestToken::new(1).with_text("x"),
16542 TestToken::eof("parser-test", 1, 1, 1),
16543 ]);
16544
16545 let (tree, actions) = parser
16546 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16547 .expect("no-op parser action should not force action replay");
16548
16549 assert_eq!(parser.node(tree).text(), "x<EOF>");
16550 assert!(
16551 actions.is_empty(),
16552 "action_index=None transitions are ANTLR metadata, not replay actions"
16553 );
16554 assert_eq!(parser.number_of_syntax_errors(), 0);
16555 }
16556
16557 #[test]
16558 fn parser_exposes_buffered_token_stream_after_parse() {
16559 let atn = token_then_eof_atn();
16560 let mut parser = mini_parser(vec![
16561 TestToken::new(1).with_text("x"),
16562 TestToken::eof("parser-test", 1, 1, 1),
16563 ]);
16564
16565 let tree = parser
16566 .parse_atn_rule(&atn, 0)
16567 .expect("artificial parser rule should parse");
16568 assert_eq!(parser.node(tree).text(), "x<EOF>");
16569
16570 let stream = parser.token_stream();
16571 let source_index_after_parse = stream.token_source().index;
16572 let buffered = stream.tokens().collect::<Vec<_>>();
16573 assert_eq!(buffered.len(), 2);
16574 assert_eq!(buffered[0].text(), Some("x"));
16575 assert_eq!(buffered[0].token_id().index(), 0);
16576 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
16577 assert_eq!(stream.token_source().index, source_index_after_parse);
16578 drop(buffered);
16579
16580 let stream = parser.into_token_stream();
16581 assert_eq!(stream.token_source().index, source_index_after_parse);
16582 assert_eq!(
16583 stream.tokens().next().expect("first token").text(),
16584 Some("x")
16585 );
16586 assert_eq!(
16587 stream.tokens().nth(1).expect("EOF token").token_type(),
16588 TOKEN_EOF
16589 );
16590 }
16591
16592 #[test]
16593 fn parsed_file_exposes_all_buffered_tokens() {
16594 let atn = token_then_eof_atn();
16595 let mut parser = mini_parser(vec![
16596 TestToken::new(99)
16597 .with_text(" comment")
16598 .with_channel(HIDDEN_CHANNEL),
16599 TestToken::new(1).with_text("x"),
16600 TestToken::eof("parser-test", 9, 1, 9),
16601 ]);
16602
16603 let tree = parser
16604 .parse_atn_rule(&atn, 0)
16605 .expect("artificial parser rule should parse");
16606 let parsed = parser.into_parsed_file(tree);
16607
16608 insta::assert_debug_snapshot!(
16611 "parsed_file_exposes_all_buffered_tokens",
16612 parsed
16613 .tokens()
16614 .iter()
16615 .map(|token| (token.token_type(), token.channel(), token.text()))
16616 .collect::<Vec<_>>()
16617 );
16618 assert_eq!(parsed.tokens().into_iter().count(), 3);
16619 }
16620
16621 #[test]
16622 fn parser_syntax_error_count_tracks_interpreted_recovery() {
16623 let atn = token_then_eof_atn();
16624 let mut parser = mini_parser(vec![
16625 TestToken::new(1).with_text("x"),
16626 TestToken::new(2).with_text("y"),
16627 TestToken::eof("parser-test", 2, 1, 2),
16628 ]);
16629
16630 let tree = parser
16631 .parse_atn_rule(&atn, 0)
16632 .expect("invalid token should recover into an error node");
16633
16634 assert_eq!(parser.number_of_syntax_errors(), 1);
16635 assert_eq!(
16636 parser
16637 .node(tree)
16638 .first_error_token()
16639 .expect("recovery should embed an error token")
16640 .text(),
16641 Some("y")
16642 );
16643 }
16644
16645 #[test]
16646 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
16647 let atn = token_then_eof_atn();
16648 let mut parser = mini_parser(vec![
16649 TestToken::new(2).with_text("y"),
16650 TestToken::eof("parser-test", 1, 1, 1),
16651 ]);
16652
16653 let error = parser
16654 .parse_atn_rule(&atn, 0)
16655 .expect_err("start-rule mismatch should remain a parser error");
16656
16657 assert_eq!(parser.number_of_syntax_errors(), 1);
16658 assert!(matches!(error, AntlrError::ParserError { .. }));
16659 }
16660
16661 #[test]
16662 fn adaptive_direct_rule_uses_simulator_decision() {
16663 let atn = two_alt_decision_atn();
16664 let mut simulator = ParserAtnSimulator::new(&atn);
16665 let mut parser = mini_parser(vec![
16666 TestToken::new(2).with_text("y"),
16667 TestToken::eof("parser-test", 1, 1, 1),
16668 ]);
16669
16670 let tree = parser
16671 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
16672 .expect("direct adaptive rule should parse");
16673
16674 assert_eq!(parser.node(tree).text(), "y");
16675 assert_eq!(parser.input.index(), 1);
16676 }
16677
16678 #[test]
16679 fn adaptive_direct_rule_restores_input_on_fallback() {
16680 let atn = predicate_after_token_atn();
16681 let mut simulator = ParserAtnSimulator::new(&atn);
16682 let mut parser = mini_parser(vec![
16683 TestToken::new(1).with_text("x"),
16684 TestToken::new(2).with_text("y"),
16685 TestToken::eof("parser-test", 2, 1, 2),
16686 ]);
16687
16688 let tree = parser
16689 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
16690 .expect("fallback recognizer should parse");
16691
16692 assert_eq!(parser.node(tree).text(), "xy");
16693 assert_eq!(parser.input.index(), 2);
16694 let stats = parser.parse_tree_storage().stats();
16695 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
16696 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
16697 assert_eq!(stats.scratch_links, 0);
16698 }
16699
16700 #[test]
16701 fn unknown_predicate_policy_defaults_to_assume_true() {
16702 let atn = predicate_after_token_atn();
16703 let mut parser = mini_parser(vec![
16704 TestToken::new(1).with_text("x"),
16705 TestToken::new(2).with_text("y"),
16706 TestToken::eof("parser-test", 2, 1, 2),
16707 ]);
16708
16709 let (tree, _) = parser
16710 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16711 .expect("unknown predicate should pass under the default policy");
16712
16713 assert_eq!(parser.node(tree).text(), "xy");
16714 assert_eq!(parser.number_of_syntax_errors(), 0);
16715 }
16716
16717 #[test]
16718 fn private_context_alt_tracking_keeps_fast_predicate_recognition() {
16719 let atn = predicate_gated_same_lookahead_atn([0, 1]);
16720 let mut parser = mini_parser(vec![
16721 TestToken::new(1).with_text("x"),
16722 TestToken::eof("parser-test", 1, 1, 1),
16723 ]);
16724
16725 let (tree, _) = parser
16726 .parse_atn_rule_with_runtime_options(
16727 &atn,
16728 0,
16729 ParserRuntimeOptions {
16730 predicates: &[
16731 (0, 0, ParserPredicate::False),
16732 (0, 1, ParserPredicate::True),
16733 ],
16734 track_context_alt_numbers: true,
16735 ..ParserRuntimeOptions::default()
16736 },
16737 )
16738 .expect("the second predicate-gated alternative should match");
16739
16740 let root = parser.node(tree).as_rule().expect("entry result is a rule");
16741 insta::assert_debug_snapshot!(
16742 "private_context_alt_tracking_keeps_fast_predicate_recognition",
16743 (root.alt_number(), root.context_alt_number(), root.text())
16744 );
16745 assert_eq!(parser.number_of_syntax_errors(), 0);
16746 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
16747 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
16748 }
16749
16750 #[test]
16751 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
16752 let atn = token_then_eof_atn();
16756 let mut parser = mini_parser(vec![
16757 TestToken::new(1).with_text("x"),
16758 TestToken::eof("parser-test", 1, 1, 1),
16759 ]);
16760
16761 parser.unknown_predicate_hits.push((7, 3));
16763
16764 parser
16766 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16767 .expect("child rule parses");
16768
16769 let error = parser
16771 .take_unknown_semantic_error()
16772 .expect("parent's recorded coordinate must survive the nested interpreted parse");
16773 let AntlrError::Unsupported(message) = error else {
16774 panic!("expected AntlrError::Unsupported, got {error:?}");
16775 };
16776 assert!(message.contains("pred_index=3"), "message: {message}");
16777 }
16778
16779 #[test]
16780 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
16781 let atn = predicate_after_token_atn();
16782 let mut parser = mini_parser(vec![
16783 TestToken::new(1).with_text("x"),
16784 TestToken::new(2).with_text("y"),
16785 TestToken::eof("parser-test", 2, 1, 2),
16786 ]);
16787
16788 let result = parser.parse_atn_rule_with_runtime_options(
16789 &atn,
16790 0,
16791 ParserRuntimeOptions {
16792 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
16793 ..ParserRuntimeOptions::default()
16794 },
16795 );
16796
16797 assert!(
16798 result.is_err(),
16799 "the only path is predicate-guarded, so assume-false must fail the parse"
16800 );
16801 }
16802
16803 #[test]
16804 fn predicate_failure_message_keeps_semantic_recovery_path() {
16805 let atn = predicate_after_token_atn();
16806 let mut parser = mini_parser(vec![
16807 TestToken::new(1).with_text("x"),
16808 TestToken::new(2).with_text("y"),
16809 TestToken::eof("parser-test", 2, 1, 2),
16810 ]);
16811
16812 let (tree, _) = parser
16813 .parse_atn_rule_with_runtime_options(
16814 &atn,
16815 0,
16816 ParserRuntimeOptions {
16817 predicates: &[(
16818 0,
16819 0,
16820 ParserPredicate::FalseWithMessage {
16821 message: "predicate rejected input",
16822 },
16823 )],
16824 ..ParserRuntimeOptions::default()
16825 },
16826 )
16827 .expect("failure-message predicates recover through the semantic interpreter");
16828
16829 assert_eq!(parser.node(tree).text(), "xy");
16830 assert_eq!(parser.number_of_syntax_errors(), 1);
16831 assert!(
16832 parser.fast_predicate_cache.is_empty(),
16833 "failure-message predicates need the semantic interpreter's recovery outcome"
16834 );
16835 }
16836
16837 #[test]
16838 fn unknown_predicate_policy_error_names_the_coordinate() {
16839 let atn = predicate_after_token_atn();
16840 let mut parser = mini_parser(vec![
16841 TestToken::new(1).with_text("x"),
16842 TestToken::new(2).with_text("y"),
16843 TestToken::eof("parser-test", 2, 1, 2),
16844 ]);
16845
16846 let error = parser
16847 .parse_atn_rule_with_runtime_options(
16848 &atn,
16849 0,
16850 ParserRuntimeOptions {
16851 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16852 ..ParserRuntimeOptions::default()
16853 },
16854 )
16855 .expect_err("evaluating an unknown predicate under Error policy must fail");
16856
16857 let AntlrError::Unsupported(message) = error else {
16858 panic!("expected AntlrError::Unsupported, got {error:?}");
16859 };
16860 assert!(
16861 message.contains("unsupported semantic predicate"),
16862 "message should name the failure class: {message}"
16863 );
16864 assert!(
16865 message.contains("pred_index=0"),
16866 "message should carry the coordinate: {message}"
16867 );
16868 }
16869
16870 #[test]
16871 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
16872 let atn = predicate_after_token_atn();
16878 let mut parser = mini_parser(vec![
16879 TestToken::new(1).with_text("x"),
16880 TestToken::new(2).with_text("y"),
16881 TestToken::eof("parser-test", 2, 1, 2),
16882 ]);
16883
16884 parser
16885 .parse_atn_rule_with_runtime_options(
16886 &atn,
16887 0,
16888 ParserRuntimeOptions {
16889 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16890 ..ParserRuntimeOptions::default()
16891 },
16892 )
16893 .expect_err("first parse fails loud under the Error policy");
16894
16895 parser.reset_unknown_semantic_hits();
16900 assert!(
16901 parser.take_unknown_semantic_error().is_none(),
16902 "reset must drop stale unknown-predicate coordinates before a reused parse"
16903 );
16904 }
16905
16906 #[derive(Debug, Default)]
16907 struct RecordingHooks {
16908 predicates: Vec<(usize, usize, usize, Option<String>)>,
16909 actions: Vec<(usize, String, Option<String>)>,
16910 action_trees: Vec<Option<String>>,
16911 }
16912
16913 impl SemanticHooks for RecordingHooks {
16914 fn sempred<S>(
16915 &mut self,
16916 ctx: &mut ParserSemCtx<'_, S>,
16917 rule_index: usize,
16918 pred_index: usize,
16919 ) -> Option<bool>
16920 where
16921 S: TokenSource,
16922 {
16923 self.predicates.push((
16924 ctx.input_index(),
16925 rule_index,
16926 pred_index,
16927 ctx.token_text(1)
16928 .and_then(|token| token.text().map(str::to_owned)),
16929 ));
16930 Some(true)
16931 }
16932
16933 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
16934 where
16935 S: TokenSource,
16936 {
16937 self.actions.push((
16938 action.source_state(),
16939 ctx.action_text(),
16940 ctx.rule_name().map(str::to_owned),
16941 ));
16942 self.action_trees.push(ctx.tree().map(Node::text));
16943 true
16944 }
16945 }
16946
16947 #[derive(Debug, Default)]
16948 struct RejectingPredicateHooks {
16949 predicates: Vec<(usize, usize, usize, Option<String>)>,
16950 }
16951
16952 impl SemanticHooks for RejectingPredicateHooks {
16953 fn sempred<S>(
16954 &mut self,
16955 ctx: &mut ParserSemCtx<'_, S>,
16956 rule_index: usize,
16957 pred_index: usize,
16958 ) -> Option<bool>
16959 where
16960 S: TokenSource,
16961 {
16962 self.predicates.push((
16963 ctx.input_index(),
16964 rule_index,
16965 pred_index,
16966 ctx.token_text(1)
16967 .and_then(|token| token.text().map(str::to_owned)),
16968 ));
16969 Some(false)
16970 }
16971 }
16972
16973 #[test]
16974 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
16975 let atn = predicate_gated_same_lookahead_atn([0, 0]);
16976 let mut parser = mini_parser_with_hooks(
16977 vec![
16978 TestToken::new(1).with_text("x"),
16979 TestToken::eof("parser-test", 1, 1, 1),
16980 ],
16981 RecordingHooks::default(),
16982 );
16983
16984 let (tree, _) = parser
16985 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16986 .expect("both alternatives share one replay-safe predicate result");
16987
16988 assert_eq!(parser.node(tree).text(), "x<EOF>");
16989 assert_eq!(
16990 parser.semantic_hooks.predicates,
16991 vec![(0, 0, 0, Some("x".to_owned()))]
16992 );
16993 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
16994 }
16995
16996 #[test]
16997 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
16998 let atn = predicate_after_token_atn();
16999 let mut parser = mini_parser_with_hooks(
17000 vec![
17001 TestToken::new(1).with_text("x"),
17002 TestToken::new(2).with_text("y"),
17003 TestToken::eof("parser-test", 2, 1, 2),
17004 ],
17005 RecordingHooks::default(),
17006 );
17007
17008 let (tree, _) = parser
17009 .parse_atn_rule_with_runtime_options(
17010 &atn,
17011 0,
17012 ParserRuntimeOptions {
17013 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17014 ..ParserRuntimeOptions::default()
17015 },
17016 )
17017 .expect("hook supplies the missing predicate result");
17018
17019 assert_eq!(parser.node(tree).text(), "xy");
17020 assert_eq!(
17021 parser.semantic_hooks.predicates,
17022 vec![(1, 0, 0, Some("y".to_owned()))]
17023 );
17024 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
17025 }
17026
17027 #[test]
17028 fn runtime_options_default_preserves_semantic_hook_predicates() {
17029 let atn = predicate_after_token_atn();
17030 let mut parser = mini_parser_with_hooks(
17031 vec![
17032 TestToken::new(1).with_text("x"),
17033 TestToken::new(2).with_text("y"),
17034 TestToken::eof("parser-test", 2, 1, 2),
17035 ],
17036 RejectingPredicateHooks::default(),
17037 );
17038
17039 let result =
17040 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
17041
17042 assert!(
17043 result.is_err(),
17044 "default runtime options must not bypass semantic hooks for predicate ATNs"
17045 );
17046 assert_eq!(
17047 parser.semantic_hooks.predicates,
17048 vec![(1, 0, 0, Some("y".to_owned()))]
17049 );
17050 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
17051 }
17052
17053 #[test]
17054 fn semantic_hook_handles_committed_parser_action() {
17055 let atn = token_then_eof_atn();
17056 let mut parser = mini_parser_with_hooks(
17057 vec![
17058 TestToken::new(1).with_text("x"),
17059 TestToken::eof("parser-test", 1, 1, 1),
17060 ],
17061 RecordingHooks::default(),
17062 );
17063 let (tree, _) = parser
17064 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17065 .expect("rule parses before action hook is tested");
17066
17067 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17068 assert_eq!(
17069 parser.semantic_hooks.actions,
17070 vec![(42, "x".to_owned(), Some("s".to_owned()))]
17071 );
17072 assert_eq!(
17073 parser.semantic_hooks.action_trees,
17074 [Some("x<EOF>".to_owned())]
17075 );
17076 }
17077
17078 #[test]
17079 fn unhandled_committed_action_fails_loud_under_error_policy() {
17080 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17084 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
17085 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
17086
17087 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17089
17090 let error = parser
17091 .take_unknown_semantic_error()
17092 .expect("an unhandled committed action under Error policy must fail loud");
17093 let AntlrError::Unsupported(message) = error else {
17094 panic!("expected AntlrError::Unsupported, got {error:?}");
17095 };
17096 assert!(
17097 message.contains("unhandled semantic action") && message.contains("state=42"),
17098 "message should name the dropped action coordinate: {message}"
17099 );
17100
17101 let mut lenient =
17103 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17104 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
17105 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17106 assert!(lenient.take_unknown_semantic_error().is_none());
17107 }
17108
17109 #[test]
17110 fn translated_predicate_is_unaffected_by_error_policy() {
17111 let atn = predicate_after_token_atn();
17112 let mut parser = mini_parser(vec![
17113 TestToken::new(1).with_text("x"),
17114 TestToken::new(2).with_text("y"),
17115 TestToken::eof("parser-test", 2, 1, 2),
17116 ]);
17117
17118 let (tree, _) = parser
17119 .parse_atn_rule_with_runtime_options(
17120 &atn,
17121 0,
17122 ParserRuntimeOptions {
17123 predicates: &[(0, 0, ParserPredicate::True)],
17124 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17125 ..ParserRuntimeOptions::default()
17126 },
17127 )
17128 .expect("a predicate covered by the table is not an unknown coordinate");
17129
17130 assert_eq!(parser.node(tree).text(), "xy");
17131 }
17132
17133 fn hook_predicate_semantics() -> ParserSemantics {
17138 let mut ir = SemIr::new();
17139 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
17140 ParserSemantics {
17141 ir,
17142 predicates: vec![ParserSemanticPredicate {
17143 rule_index: 0,
17144 pred_index: 0,
17145 expr,
17146 failure_message: None,
17147 }],
17148 actions: Vec::new(),
17149 }
17150 }
17151
17152 #[derive(Debug, Default)]
17153 struct DecliningHooks;
17154
17155 impl SemanticHooks for DecliningHooks {}
17156
17157 #[test]
17158 fn semir_hook_none_falls_through_to_assume_true() {
17159 let atn = predicate_after_token_atn();
17160 let semantics = hook_predicate_semantics();
17161 let mut parser = mini_parser_with_hooks(
17162 vec![
17163 TestToken::new(1).with_text("x"),
17164 TestToken::new(2).with_text("y"),
17165 TestToken::eof("parser-test", 2, 1, 2),
17166 ],
17167 DecliningHooks,
17168 );
17169
17170 let (tree, _) = parser
17171 .parse_atn_rule_with_runtime_options(
17172 &atn,
17173 0,
17174 ParserRuntimeOptions {
17175 semantics: Some(&semantics),
17176 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
17177 ..ParserRuntimeOptions::default()
17178 },
17179 )
17180 .expect("a declined SemIR hook must pass under assume-true");
17181
17182 assert_eq!(parser.node(tree).text(), "xy");
17183 }
17184
17185 #[test]
17186 fn semir_hook_none_falls_through_to_assume_false() {
17187 let atn = predicate_after_token_atn();
17188 let semantics = hook_predicate_semantics();
17189 let mut parser = mini_parser_with_hooks(
17190 vec![
17191 TestToken::new(1).with_text("x"),
17192 TestToken::new(2).with_text("y"),
17193 TestToken::eof("parser-test", 2, 1, 2),
17194 ],
17195 DecliningHooks,
17196 );
17197
17198 let result = parser.parse_atn_rule_with_runtime_options(
17199 &atn,
17200 0,
17201 ParserRuntimeOptions {
17202 semantics: Some(&semantics),
17203 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
17204 ..ParserRuntimeOptions::default()
17205 },
17206 );
17207
17208 assert!(
17209 result.is_err(),
17210 "a declined SemIR hook must fail the only guarded path under assume-false"
17211 );
17212 }
17213
17214 #[test]
17215 fn semir_hook_none_records_coordinate_under_error_policy() {
17216 let atn = predicate_after_token_atn();
17217 let semantics = hook_predicate_semantics();
17218 let mut parser = mini_parser_with_hooks(
17219 vec![
17220 TestToken::new(1).with_text("x"),
17221 TestToken::new(2).with_text("y"),
17222 TestToken::eof("parser-test", 2, 1, 2),
17223 ],
17224 DecliningHooks,
17225 );
17226
17227 let error = parser
17228 .parse_atn_rule_with_runtime_options(
17229 &atn,
17230 0,
17231 ParserRuntimeOptions {
17232 semantics: Some(&semantics),
17233 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17234 ..ParserRuntimeOptions::default()
17235 },
17236 )
17237 .expect_err("a declined SemIR hook under Error policy must fail the parse");
17238
17239 let AntlrError::Unsupported(message) = error else {
17240 panic!("expected AntlrError::Unsupported, got {error:?}");
17241 };
17242 assert!(
17243 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
17244 "message should name the unresolved coordinate: {message}"
17245 );
17246 }
17247
17248 #[test]
17249 fn generated_direct_predicate_honors_installed_policy() {
17250 let semantics = hook_predicate_semantics();
17256 let context = ParserRuleContext::new(0, -1);
17257
17258 let mut assume_true =
17259 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17260 assert!(
17261 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
17262 &semantics, 0, 0, &context, 0
17263 ),
17264 "default AssumeTrue accepts a declined hook"
17265 );
17266 assert!(assume_true.take_unknown_semantic_error().is_none());
17267
17268 let mut error_policy =
17269 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17270 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
17271 assert!(
17272 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
17273 &semantics, 0, 0, &context, 0
17274 ),
17275 "Error policy rejects a declined hook on the generated-direct path"
17276 );
17277 let error = error_policy
17278 .take_unknown_semantic_error()
17279 .expect("Error policy records the unresolved coordinate for the generated path");
17280 let AntlrError::Unsupported(message) = error else {
17281 panic!("expected AntlrError::Unsupported, got {error:?}");
17282 };
17283 assert!(message.contains("pred_index=0"), "message: {message}");
17284 }
17285
17286 #[test]
17287 fn parser_rule_start_skips_leading_hidden_tokens() {
17288 let atn = token_then_eof_atn();
17289 let mut parser = mini_parser(vec![
17290 TestToken::new(99)
17291 .with_text(" ")
17292 .with_channel(HIDDEN_CHANNEL),
17293 TestToken::new(1).with_text("x"),
17294 TestToken::eof("parser-test", 2, 1, 2),
17295 ]);
17296
17297 let tree = parser
17298 .parse_atn_rule(&atn, 0)
17299 .expect("artificial parser rule should parse");
17300 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
17301 panic!("rule node should be present");
17302 };
17303 assert_eq!(
17304 rule.start()
17305 .expect("rule should have a start token")
17306 .token_type(),
17307 1
17308 );
17309 }
17310
17311 #[test]
17312 fn parser_action_after_eof_stops_at_eof_token() {
17313 let atn = eof_then_action_atn();
17314 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
17315
17316 let (_, actions) = parser
17317 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17318 .expect("EOF action rule should parse");
17319
17320 assert_eq!(actions.len(), 1);
17321 assert_eq!(actions[0].stop_index(), Some(0));
17322 assert_eq!(
17323 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
17324 ""
17325 );
17326 }
17327
17328 #[test]
17329 fn after_action_stop_uses_rule_context_stop_not_cursor() {
17330 let mut id = TestToken::new(1).with_text("x");
17335 id.set_token_index(0);
17336 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
17337 eof.set_token_index(1);
17338 let mut parser = mini_parser(vec![id.clone(), eof]);
17339 parser.consume();
17341 assert_eq!(parser.la(1), TOKEN_EOF);
17342
17343 let mut ctx = ParserRuleContext::new(0, 0);
17346 parser.set_context_stop(
17347 &mut ctx,
17348 parser.token_id_at(0).expect("ID token should be buffered"),
17349 );
17350 let tree = parser.rule_node(ctx);
17351
17352 let current_index = parser.input.index();
17353 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
17355 assert_eq!(
17357 parser.after_action_stop_index_for_tree(tree, current_index),
17358 Some(0)
17359 );
17360 }
17361
17362 #[test]
17363 fn after_action_start_uses_rule_context_start_not_cursor() {
17364 let mut parser = mini_parser(vec![
17369 TestToken::new(9)
17370 .with_text(" ")
17371 .with_channel(HIDDEN_CHANNEL),
17372 TestToken::new(9)
17373 .with_text(" ")
17374 .with_channel(HIDDEN_CHANNEL),
17375 TestToken::new(1).with_text("x"),
17376 TestToken::eof("parser-test", 3, 1, 3),
17377 ]);
17378
17379 let mut ctx = ParserRuleContext::new(0, 0);
17380 parser.set_context_start(
17381 &mut ctx,
17382 parser.token_id_at(2).expect("ID token should be buffered"),
17383 );
17384 let tree = parser.rule_node(ctx);
17385
17386 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
17389
17390 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
17392 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
17393 }
17394
17395 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
17396 FastRecognizeOutcome {
17397 index,
17398 consumed_eof,
17399 diagnostics: DiagnosticSeqId::EMPTY,
17400 deferred_nodes: FastDeferredNodeId::EMPTY,
17401 nodes: NodeSeqId(marker),
17402 }
17403 }
17404
17405 #[test]
17406 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
17407 let mut outcomes = vec![
17408 clean_fast_outcome(4, false, 0),
17409 clean_fast_outcome(2, false, 1),
17410 clean_fast_outcome(4, false, 2),
17411 clean_fast_outcome(4, true, 3),
17412 clean_fast_outcome(2, false, 4),
17413 ];
17414 let mut scratch = FastOutcomeDedupScratch::default();
17415
17416 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17417
17418 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
17419 assert_eq!(
17420 outcomes
17421 .iter()
17422 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
17423 .collect::<Vec<_>>(),
17424 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
17425 );
17426 assert!(scratch.dense_words.is_empty());
17427 assert!(scratch.sparse_keys.is_empty());
17428 }
17429
17430 #[test]
17431 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
17432 let mut scratch = FastOutcomeDedupScratch::default();
17433 let mut outcomes = (100..109)
17434 .flat_map(|index| {
17435 [
17436 clean_fast_outcome(
17437 index,
17438 false,
17439 u32::try_from(index).expect("test index fits in u32"),
17440 ),
17441 clean_fast_outcome(index, false, u32::MAX),
17442 ]
17443 })
17444 .collect();
17445
17446 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17447
17448 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
17449 assert_eq!(outcomes.len(), 9);
17450 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
17451 let dense_capacity = scratch.dense_words.capacity();
17452
17453 let mut reused = (1_000..1_009)
17454 .map(|index| {
17455 clean_fast_outcome(
17456 index,
17457 false,
17458 u32::try_from(index).expect("test index fits in u32"),
17459 )
17460 })
17461 .collect();
17462 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
17463
17464 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
17465 assert_eq!(reused.len(), 9);
17466 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
17467 }
17468
17469 #[test]
17470 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
17471 let mut scratch = FastOutcomeDedupScratch::default();
17472 let sparse_indexes = [
17473 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
17474 ];
17475 let mut outcomes = sparse_indexes
17476 .into_iter()
17477 .chain([400_000])
17478 .enumerate()
17479 .map(|(marker, index)| {
17480 clean_fast_outcome(
17481 index,
17482 false,
17483 u32::try_from(marker).expect("test marker fits in u32"),
17484 )
17485 })
17486 .collect();
17487
17488 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17489
17490 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
17491 assert_eq!(outcomes.len(), sparse_indexes.len());
17492 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
17493 let sparse_capacity = scratch.sparse_keys.capacity();
17494
17495 let mut reused = sparse_indexes
17496 .into_iter()
17497 .map(|index| {
17498 clean_fast_outcome(
17499 index,
17500 false,
17501 u32::try_from(index).expect("test index fits in u32"),
17502 )
17503 })
17504 .collect();
17505 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
17506
17507 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
17508 assert_eq!(reused.len(), sparse_indexes.len());
17509 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
17510 }
17511
17512 #[test]
17513 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
17514 let mut scratch = FastOutcomeDedupScratch::default();
17515 scratch
17516 .sparse_keys
17517 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
17518 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
17519 let mut outcomes = (0..9)
17520 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
17521 .collect();
17522
17523 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17524
17525 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
17526 assert!(scratch.sparse_keys.is_empty());
17527 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
17528 }
17529
17530 #[test]
17531 fn fast_outcome_selection_respects_sll_tie_order() {
17532 let mut arena = RecognitionArena::default();
17533 let first = FastRecognizeOutcome {
17534 index: 1,
17535 consumed_eof: false,
17536 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17537 line: 1,
17538 column: 0,
17539 message: "mismatched input 'x'".to_owned(),
17540 }]),
17541 deferred_nodes: FastDeferredNodeId::EMPTY,
17542 nodes: NodeSeqId::EMPTY,
17543 };
17544 let second = FastRecognizeOutcome {
17545 index: first.index,
17546 consumed_eof: first.consumed_eof,
17547 diagnostics: DiagnosticSeqId::EMPTY,
17548 deferred_nodes: FastDeferredNodeId::EMPTY,
17549 nodes: NodeSeqId::EMPTY,
17550 };
17551
17552 let selected = select_best_fast_outcome(
17553 [first, second].into_iter(),
17554 PredictionMode::Sll,
17555 None,
17556 |_| panic!("caller-follow token probe should not run"),
17557 &arena,
17558 )
17559 .expect("one outcome should be selected");
17560 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
17561 let eof_second = FastRecognizeOutcome {
17562 index: second.index,
17563 consumed_eof: true,
17564 diagnostics: DiagnosticSeqId::EMPTY,
17565 deferred_nodes: FastDeferredNodeId::EMPTY,
17566 nodes: NodeSeqId::EMPTY,
17567 };
17568 let selected = select_best_fast_outcome(
17569 [first, eof_second].into_iter(),
17570 PredictionMode::Sll,
17571 None,
17572 |_| panic!("caller-follow token probe should not run"),
17573 &arena,
17574 )
17575 .expect("one outcome should be selected");
17576 assert!(!selected.consumed_eof);
17577 let selected = select_best_fast_outcome(
17578 [first, second].into_iter(),
17579 PredictionMode::Ll,
17580 None,
17581 |_| panic!("caller-follow token probe should not run"),
17582 &arena,
17583 )
17584 .expect("one outcome should be selected");
17585 assert!(selected.diagnostics.is_empty());
17586 }
17587
17588 #[test]
17589 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
17590 let mut arena = RecognitionArena::default();
17591 let first = FastRecognizeOutcome {
17592 index: 3,
17593 consumed_eof: false,
17594 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17595 line: 1,
17596 column: 0,
17597 message: "mismatched input 'x' expecting 'a'".to_owned(),
17598 }]),
17599 deferred_nodes: FastDeferredNodeId::EMPTY,
17600 nodes: NodeSeqId::EMPTY,
17601 };
17602 let same_rank = FastRecognizeOutcome {
17603 index: first.index,
17604 consumed_eof: first.consumed_eof,
17605 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17606 line: 1,
17607 column: 0,
17608 message: "mismatched input 'x' expecting 'b'".to_owned(),
17609 }]),
17610 deferred_nodes: FastDeferredNodeId::EMPTY,
17611 nodes: NodeSeqId::EMPTY,
17612 };
17613 let better_rank = FastRecognizeOutcome {
17614 index: first.index,
17615 consumed_eof: first.consumed_eof,
17616 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17617 line: 1,
17618 column: 0,
17619 message: "missing 'a' at 'x'".to_owned(),
17620 }]),
17621 deferred_nodes: FastDeferredNodeId::EMPTY,
17622 nodes: NodeSeqId::EMPTY,
17623 };
17624 let mut outcomes = vec![first, same_rank, better_rank];
17625
17626 dedupe_fast_outcomes(&mut outcomes, &arena);
17627
17628 assert_eq!(outcomes.len(), 2);
17629 assert_eq!(
17630 arena
17631 .diagnostics(outcomes[0].diagnostics)
17632 .next()
17633 .expect("first diagnostic")
17634 .message,
17635 "mismatched input 'x' expecting 'a'"
17636 );
17637 assert_eq!(
17638 arena
17639 .diagnostics(outcomes[1].diagnostics)
17640 .next()
17641 .expect("second diagnostic")
17642 .message,
17643 "missing 'a' at 'x'"
17644 );
17645 }
17646
17647 #[test]
17648 fn fast_outcome_selection_prefers_generated_caller_follow() {
17649 let arena = RecognitionArena::default();
17650 let earlier = FastRecognizeOutcome {
17651 index: 7,
17652 consumed_eof: false,
17653 diagnostics: DiagnosticSeqId::EMPTY,
17654 deferred_nodes: FastDeferredNodeId::EMPTY,
17655 nodes: NodeSeqId::EMPTY,
17656 };
17657 let later = FastRecognizeOutcome {
17658 index: 8,
17659 consumed_eof: false,
17660 diagnostics: DiagnosticSeqId::EMPTY,
17661 deferred_nodes: FastDeferredNodeId::EMPTY,
17662 nodes: NodeSeqId::EMPTY,
17663 };
17664 let mut follow = TokenBitSet::default();
17665 follow.insert(5);
17666
17667 let selected = select_best_fast_outcome(
17668 [later, earlier].into_iter(),
17669 PredictionMode::Ll,
17670 Some(&follow),
17671 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
17672 &arena,
17673 )
17674 .expect("one outcome should be selected");
17675 assert_eq!(selected.index, 7);
17676
17677 let selected = select_best_fast_outcome(
17678 [later, earlier].into_iter(),
17679 PredictionMode::Ll,
17680 Some(&follow),
17681 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
17682 &arena,
17683 )
17684 .expect("one outcome should be selected");
17685 assert_eq!(selected.index, 8);
17686
17687 let indented_next_statement = FastRecognizeOutcome {
17688 index: 9,
17689 consumed_eof: false,
17690 diagnostics: DiagnosticSeqId::EMPTY,
17691 deferred_nodes: FastDeferredNodeId::EMPTY,
17692 nodes: NodeSeqId::EMPTY,
17693 };
17694 let selected = select_best_fast_outcome(
17695 [indented_next_statement, earlier].into_iter(),
17696 PredictionMode::Ll,
17697 Some(&follow),
17698 |index| {
17699 let is_boundary = index == 7;
17700 let is_boundary_gap = matches!(index, 7 | 8);
17701 (
17702 if index == 7 { 5 } else { TOKEN_EOF },
17703 is_boundary,
17704 is_boundary_gap,
17705 )
17706 },
17707 &arena,
17708 )
17709 .expect("one outcome should be selected");
17710 assert_eq!(selected.index, 7);
17711
17712 let continuation = FastRecognizeOutcome {
17713 index: 10,
17714 consumed_eof: false,
17715 diagnostics: DiagnosticSeqId::EMPTY,
17716 deferred_nodes: FastDeferredNodeId::EMPTY,
17717 nodes: NodeSeqId::EMPTY,
17718 };
17719 let selected = select_best_fast_outcome(
17720 [continuation, earlier].into_iter(),
17721 PredictionMode::Ll,
17722 Some(&follow),
17723 |index| {
17724 let is_boundary = matches!(index, 7 | 9);
17725 (
17726 if index == 7 { 5 } else { TOKEN_EOF },
17727 is_boundary,
17728 is_boundary,
17729 )
17730 },
17731 &arena,
17732 )
17733 .expect("one outcome should be selected");
17734 assert_eq!(selected.index, 10);
17735
17736 let selected = select_best_fast_outcome(
17737 [earlier, later].into_iter(),
17738 PredictionMode::Sll,
17739 Some(&follow),
17740 |_| panic!("caller-follow token probe should not run in SLL mode"),
17741 &arena,
17742 )
17743 .expect("one outcome should be selected");
17744 assert_eq!(selected.index, 8);
17745 }
17746
17747 #[test]
17748 fn caller_follow_boundary_text_requires_separator_shape() {
17749 assert!(is_caller_follow_boundary_text(";"));
17750 assert!(is_caller_follow_boundary_text("\n"));
17751 assert!(is_caller_follow_boundary_text("\r\n "));
17752 assert!(is_caller_follow_boundary_text(";\n"));
17753 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
17754 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
17755 assert!(!is_caller_follow_boundary_text("identifier"));
17756 assert!(is_caller_follow_boundary_gap_text(" \t "));
17757 assert!(is_caller_follow_boundary_gap_text("\n "));
17758 assert!(is_caller_follow_boundary_gap_text(";\t"));
17759 assert!(!is_caller_follow_boundary_gap_text(
17760 "\"\"\"line1\nline2\"\"\""
17761 ));
17762 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
17763 }
17764
17765 #[test]
17766 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
17767 let mut parser = mini_parser(vec![
17768 TestToken::new(5).with_text("\n"),
17769 TestToken::new(6)
17770 .with_text("// comment\n")
17771 .with_channel(HIDDEN_CHANNEL),
17772 TestToken::new(1).with_text("x"),
17773 TestToken::eof("parser-test", 1, 2, 0),
17774 ]);
17775
17776 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
17777 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
17778 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
17779 }
17780
17781 #[test]
17782 fn caller_follow_token_info_uses_stream_visible_channel() {
17783 let source = Source {
17784 tokens: vec![
17785 TestToken::new(5).with_text("\n").with_channel(2),
17786 TestToken::new(1).with_text("x").with_channel(2),
17787 TestToken::new(6)
17788 .with_text("// comment\n")
17789 .with_channel(HIDDEN_CHANNEL),
17790 TestToken::eof("parser-test", 1, 2, 0),
17791 ],
17792 index: 0,
17793 };
17794 let data = RecognizerData::new(
17795 "Mini.g4",
17796 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17797 );
17798 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
17799
17800 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
17801 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
17802 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
17803 }
17804
17805 #[test]
17806 fn reset_per_parse_caches_clears_state_expected_token_cache() {
17807 let atn = token_then_eof_atn();
17808 let mut parser = mini_parser(Vec::new());
17809
17810 let _ = parser.cached_state_expected_token_set(&atn, 0);
17811 assert!(!parser.state_expected_token_cache.is_empty());
17812
17813 parser.reset_per_parse_caches();
17814 assert!(parser.state_expected_token_cache.is_empty());
17815 }
17816
17817 #[test]
17818 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
17819 let cyclic = epsilon_cycle_atn();
17820 let acyclic = token_then_eof_atn();
17821 let mut parser = mini_parser(Vec::new());
17822
17823 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
17824 assert_eq!(
17825 parser.empty_cycle_cache_atn,
17826 Some(SharedAtnCacheKey::for_atn(&cyclic))
17827 );
17828 assert_eq!(parser.empty_cycle_cache[1], Some(true));
17829
17830 parser.reset_per_parse_caches();
17831 assert_eq!(parser.empty_cycle_cache[1], Some(true));
17832 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
17833
17834 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
17835 assert_eq!(
17836 parser.empty_cycle_cache_atn,
17837 Some(SharedAtnCacheKey::for_atn(&acyclic))
17838 );
17839 assert_eq!(parser.empty_cycle_cache[1], Some(false));
17840 }
17841
17842 #[test]
17843 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
17844 let source = Source {
17845 tokens: vec![
17846 TestToken::new(1).with_text("x"),
17847 TestToken::eof("parser-test", 1, 1, 1),
17848 ],
17849 index: 0,
17850 };
17851 let data = RecognizerData::new(
17852 "Mini.g4",
17853 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17854 );
17855 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17856 let expected = ExpectedTokens {
17857 index: Some(0),
17858 symbols: BTreeSet::new(),
17859 no_viable: None,
17860 };
17861
17862 let (_, message) = parser.expected_error_message(0, 0, &expected);
17863
17864 assert_eq!(message, "mismatched input 'x'");
17865 }
17866
17867 #[test]
17868 fn eof_rule_stop_index_points_at_eof_token() {
17869 let source = Source {
17870 tokens: vec![
17871 TestToken::new(1).with_text("x"),
17872 TestToken::eof("parser-test", 1, 1, 1),
17873 ],
17874 index: 0,
17875 };
17876 let data = RecognizerData::new(
17877 "Mini.g4",
17878 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17879 );
17880 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17881
17882 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
17883 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
17884 }
17885
17886 #[test]
17887 fn generated_parser_action_uses_current_rule_stop_boundary() {
17888 let mut parser = mini_parser(vec![
17889 TestToken::new(1).with_text("x"),
17890 TestToken::eof("parser-test", 1, 1, 1),
17891 ]);
17892
17893 parser.match_token(1).expect("token should match");
17894 let action = parser.parser_action_at_current(7, 0, 0, false);
17895 assert_eq!(action.source_state(), 7);
17896 assert_eq!(action.rule_index(), 0);
17897 assert_eq!(action.start_index(), 0);
17898 assert_eq!(action.stop_index(), Some(0));
17899
17900 parser.match_eof().expect("EOF should match");
17901 let action = parser.parser_action_at_current(8, 0, 0, true);
17902 assert_eq!(action.stop_index(), Some(1));
17903 }
17904
17905 #[test]
17906 fn folds_left_recursive_boundary_into_rule_node() {
17907 let mut arena = RecognitionArena::default();
17908 let first = arena.push_node(ArenaRecognizedNode::Token {
17909 token: TokenId::try_from(0).expect("test token ID"),
17910 });
17911 let boundary = arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
17912 rule_index: 1,
17913 alt_number: 3,
17914 });
17915 let second = arena.push_node(ArenaRecognizedNode::Token {
17916 token: TokenId::try_from(1).expect("test token ID"),
17917 });
17918 let mut nodes = NodeSeqId::EMPTY;
17919 for node in [first, boundary, second].into_iter().rev() {
17920 nodes = arena.prepend(nodes, node);
17921 }
17922
17923 let folded = arena.fold_left_recursive_boundaries(nodes);
17924 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
17925
17926 assert_eq!(folded_nodes.len(), 2);
17927 let ArenaRecognizedNode::Rule {
17928 rule_index,
17929 invoking_state,
17930 alt_number,
17931 start_index,
17932 stop_index,
17933 children,
17934 ..
17935 } = arena.node(folded_nodes[0])
17936 else {
17937 panic!("first folded node should be a rule");
17938 };
17939 insta::assert_debug_snapshot!(
17943 "folds_left_recursive_boundary_into_rule_node",
17944 (
17945 rule_index,
17946 invoking_state,
17947 alt_number,
17948 start_index,
17949 stop_index
17950 )
17951 );
17952 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
17953 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
17954
17955 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
17956 assert_eq!(
17957 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17958 (4, 3, 1)
17959 );
17960 assert_eq!(
17961 (stats.total_links, stats.live_links, stats.dead_links),
17962 (9, 3, 6)
17963 );
17964 }
17965
17966 #[test]
17967 fn recognition_arena_reports_live_dead_and_retained_capacity() {
17968 let mut arena = RecognitionArena::default();
17969 let token = arena.push_node(ArenaRecognizedNode::Token {
17970 token: TokenId::try_from(0).expect("test token ID"),
17971 });
17972 let extra = arena.push_extra(RecognitionExtra::MissingToken {
17973 token_type: 2,
17974 at_index: 1,
17975 text: "<missing X>".to_owned(),
17976 });
17977 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
17978 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
17979 token: TokenId::try_from(1).expect("test token ID"),
17980 });
17981 let mut live = NodeSeqId::EMPTY;
17982 live = arena.prepend(live, missing);
17983 live = arena.prepend(live, token);
17984 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
17985 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17986 line: 1,
17987 column: 0,
17988 message: "missing X".to_owned(),
17989 }]);
17990 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17991 line: 1,
17992 column: 1,
17993 message: "discarded".to_owned(),
17994 }]);
17995 let deferred_children = arena.deferred_fragment(live);
17996 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
17997 rule_index: 0,
17998 invoking_state: -1,
17999 start_index: 0,
18000 stop_index: Some(1),
18001 deferred_children,
18002 children: NodeSeqId::EMPTY,
18003 });
18004
18005 let stats = arena.stats(live, live_diagnostics);
18006
18007 assert_eq!(
18008 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18009 (3, 2, 1)
18010 );
18011 assert_eq!(
18012 (stats.total_links, stats.live_links, stats.dead_links),
18013 (5, 3, 2)
18014 );
18015 assert_eq!(
18016 (stats.total_extras, stats.live_extras, stats.dead_extras),
18017 (3, 2, 1)
18018 );
18019 assert!(size_of::<SeqLink>() <= 8);
18020 assert!(size_of::<DiagnosticLink>() <= 8);
18021 assert!(size_of::<FastDeferredNode>() <= 12);
18022 assert!(size_of::<FastDeferredRule>() <= 28);
18023 assert!(size_of::<FastRecognizeOutcome>() <= 24);
18024 let capacities = (
18025 stats.node_capacity,
18026 stats.link_capacity,
18027 stats.extra_capacity,
18028 );
18029 let deferred_capacities = (
18030 arena.deferred_nodes.capacity(),
18031 arena.deferred_rules.capacity(),
18032 );
18033
18034 arena.reset();
18035 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
18036 assert_eq!(
18037 (reset.total_nodes, reset.total_links, reset.total_extras),
18038 (0, 0, 0)
18039 );
18040 assert_eq!(
18041 (
18042 reset.node_capacity,
18043 reset.link_capacity,
18044 reset.extra_capacity,
18045 ),
18046 capacities
18047 );
18048 assert!(arena.deferred_nodes.is_empty());
18049 assert!(arena.deferred_rules.is_empty());
18050 assert_eq!(
18051 (
18052 arena.deferred_nodes.capacity(),
18053 arena.deferred_rules.capacity(),
18054 ),
18055 deferred_capacities
18056 );
18057 }
18058
18059 #[test]
18060 fn parser_computes_recognition_arena_stats_on_demand() {
18061 let mut parser = mini_parser(Vec::new());
18062 let live = parser
18063 .recognition_arena
18064 .push_node(ArenaRecognizedNode::Token {
18065 token: TokenId::try_from(0).expect("test token ID"),
18066 });
18067 let discarded = parser
18068 .recognition_arena
18069 .push_node(ArenaRecognizedNode::ErrorToken {
18070 token: TokenId::try_from(1).expect("test token ID"),
18071 });
18072 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
18073 let _discarded_root = parser
18074 .recognition_arena
18075 .prepend(NodeSeqId::EMPTY, discarded);
18076 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
18077
18078 let stats = parser.recognition_arena_stats();
18079
18080 assert_eq!(
18081 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18082 (2, 1, 1)
18083 );
18084 assert_eq!(
18085 (stats.total_links, stats.live_links, stats.dead_links),
18086 (2, 1, 1)
18087 );
18088 }
18089
18090 #[test]
18091 fn recognition_arena_drops_capacity_above_retention_limit() {
18092 let mut storage = Vec::<u8>::with_capacity(4);
18093 storage.extend([1, 2, 3]);
18094
18095 reset_arena_vec(&mut storage, 3);
18096
18097 assert!(storage.is_empty());
18098 assert_eq!(storage.capacity(), 0);
18099 }
18100
18101 #[test]
18102 fn recognition_arena_concatenates_diagnostics_in_source_order() {
18103 let mut arena = RecognitionArena::default();
18104 let prefix = arena.diagnostic_sequence([
18105 ParserDiagnostic {
18106 line: 1,
18107 column: 0,
18108 message: "first".to_owned(),
18109 },
18110 ParserDiagnostic {
18111 line: 1,
18112 column: 1,
18113 message: "second".to_owned(),
18114 },
18115 ]);
18116 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
18117 line: 1,
18118 column: 2,
18119 message: "third".to_owned(),
18120 }]);
18121 let extras_before = arena.extras.len();
18122
18123 let combined = arena.concat_diagnostics(prefix, suffix);
18124 let messages = arena
18125 .diagnostics(combined)
18126 .map(|diagnostic| diagnostic.message.as_str())
18127 .collect::<Vec<_>>();
18128
18129 assert_eq!(messages, ["first", "second", "third"]);
18130 assert_eq!(arena.extras.len(), extras_before);
18131 }
18132
18133 #[test]
18134 fn outcome_ties_keep_later_non_recursive_alternative() {
18135 let arena = RecognitionArena::default();
18136 let first = RecognizeOutcome {
18137 index: 1,
18138 consumed_eof: false,
18139 alt_number: 0,
18140 member_values: BTreeMap::new(),
18141 return_values: BTreeMap::new(),
18142 diagnostics: DiagnosticSeqId::EMPTY,
18143 decisions: Vec::new(),
18144 actions: vec![ParserAction::new(1, 0, 0, None)],
18145 nodes: NodeSeqId::EMPTY,
18146 };
18147 let second = RecognizeOutcome {
18148 actions: vec![ParserAction::new(2, 0, 0, None)],
18149 ..first.clone()
18150 };
18151
18152 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18153 .expect("one outcome should be selected");
18154 assert_eq!(selected.actions[0].source_state(), 2);
18155 }
18156
18157 #[test]
18158 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
18159 let arena = RecognitionArena::default();
18160 let first = RecognizeOutcome {
18161 index: 1,
18162 consumed_eof: false,
18163 alt_number: 0,
18164 member_values: BTreeMap::new(),
18165 return_values: BTreeMap::new(),
18166 diagnostics: DiagnosticSeqId::EMPTY,
18167 decisions: Vec::new(),
18168 actions: vec![ParserAction::new(1, 0, 0, None)],
18169 nodes: NodeSeqId::EMPTY,
18170 };
18171 let second = RecognizeOutcome {
18172 actions: vec![
18173 ParserAction::new(2, 0, 0, None),
18174 ParserAction::new(3, 0, 0, None),
18175 ],
18176 ..first.clone()
18177 };
18178
18179 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
18180 .expect("one outcome should be selected");
18181 assert_eq!(selected.actions.len(), 2);
18182 }
18183
18184 #[test]
18185 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
18186 let arena = RecognitionArena::default();
18187 let first = RecognizeOutcome {
18188 index: 7,
18189 consumed_eof: false,
18190 alt_number: 0,
18191 member_values: BTreeMap::new(),
18192 return_values: BTreeMap::new(),
18193 diagnostics: DiagnosticSeqId::EMPTY,
18194 decisions: vec![1, 0],
18195 actions: vec![
18196 ParserAction::new(23, 2, 2, Some(4)),
18197 ParserAction::new(23, 2, 0, Some(6)),
18198 ],
18199 nodes: NodeSeqId::EMPTY,
18200 };
18201 let second = RecognizeOutcome {
18202 decisions: vec![0, 1],
18203 actions: vec![
18204 ParserAction::new(23, 2, 2, Some(6)),
18205 ParserAction::new(23, 2, 0, Some(6)),
18206 ],
18207 ..first.clone()
18208 };
18209
18210 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18211 .expect("one outcome should be selected");
18212 assert_eq!(selected.actions[0].stop_index(), Some(6));
18213 }
18214
18215 #[test]
18216 fn outcome_ties_keep_first_recursive_tree_shape() {
18217 let mut arena = RecognitionArena::default();
18218 let token = arena.push_node(ArenaRecognizedNode::Token {
18219 token: TokenId::try_from(0).expect("test token ID"),
18220 });
18221 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
18222 let inner = arena.push_node(ArenaRecognizedNode::Rule {
18223 rule_index: 1,
18224 invoking_state: -1,
18225 alt_number: 0,
18226 start_index: 0,
18227 stop_index: Some(0),
18228 return_values: None,
18229 children: token_children,
18230 });
18231 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
18232 let outer = arena.push_node(ArenaRecognizedNode::Rule {
18233 rule_index: 1,
18234 invoking_state: -1,
18235 alt_number: 0,
18236 start_index: 0,
18237 stop_index: Some(0),
18238 return_values: None,
18239 children: inner_children,
18240 });
18241 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
18242 let first = RecognizeOutcome {
18243 index: 1,
18244 consumed_eof: false,
18245 alt_number: 0,
18246 member_values: BTreeMap::new(),
18247 return_values: BTreeMap::new(),
18248 diagnostics: DiagnosticSeqId::EMPTY,
18249 decisions: Vec::new(),
18250 actions: vec![ParserAction::new(1, 0, 0, None)],
18251 nodes: recursive_nodes,
18252 };
18253 let second = RecognizeOutcome {
18254 index: 1,
18255 consumed_eof: false,
18256 alt_number: 0,
18257 member_values: BTreeMap::new(),
18258 return_values: BTreeMap::new(),
18259 diagnostics: DiagnosticSeqId::EMPTY,
18260 decisions: Vec::new(),
18261 actions: vec![ParserAction::new(2, 0, 0, None)],
18262 nodes: recursive_nodes,
18263 };
18264
18265 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18266 .expect("one outcome should be selected");
18267 assert_eq!(selected.actions[0].source_state(), 1);
18268 }
18269
18270 #[test]
18271 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
18272 let mut arena = RecognitionArena::default();
18273 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
18274 line: 1,
18275 column: 3,
18276 message: "missing 'Y' at '<EOF>'".to_owned(),
18277 }]);
18278 let first_alt = RecognizeOutcome {
18279 index: 2,
18280 consumed_eof: true,
18281 alt_number: 0,
18282 member_values: BTreeMap::new(),
18283 return_values: BTreeMap::new(),
18284 diagnostics: recovered_diagnostics,
18285 decisions: vec![0],
18286 actions: vec![ParserAction::new(1, 0, 0, None)],
18287 nodes: NodeSeqId::EMPTY,
18288 };
18289 let second_alt = RecognizeOutcome {
18290 diagnostics: DiagnosticSeqId::EMPTY,
18291 decisions: vec![1],
18292 actions: vec![ParserAction::new(2, 0, 0, None)],
18293 ..first_alt.clone()
18294 };
18295
18296 let selected = select_best_outcome(
18297 [second_alt, first_alt].into_iter(),
18298 PredictionMode::Sll,
18299 &arena,
18300 )
18301 .expect("one outcome should be selected");
18302 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
18303 assert_eq!(selected.decisions, [0]);
18304 }
18305}