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 recognition_arena: RecognitionArena,
1262 last_recognition_arena_root: NodeSeqId,
1263 last_recognition_arena_diagnostics: DiagnosticSeqId,
1264}
1265
1266#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1268pub struct GeneratedDiagnosticsCheckpoint {
1269 diagnostics_len: usize,
1270 syntax_errors: usize,
1271 tree: ParseTreeCheckpoint,
1272}
1273
1274#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1277pub struct RecognitionArenaStats {
1278 pub total_nodes: usize,
1279 pub live_nodes: usize,
1280 pub dead_nodes: usize,
1281 pub node_capacity: usize,
1282 pub total_links: usize,
1283 pub live_links: usize,
1284 pub dead_links: usize,
1285 pub link_capacity: usize,
1286 pub total_extras: usize,
1287 pub live_extras: usize,
1288 pub dead_extras: usize,
1289 pub extra_capacity: usize,
1290}
1291
1292#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1293struct RuleContextFrame {
1294 rule_index: usize,
1295 invoking_state: isize,
1296}
1297
1298#[derive(Clone, Debug, Eq, PartialEq)]
1299struct RecognizeOutcome {
1300 index: usize,
1301 consumed_eof: bool,
1302 alt_number: usize,
1303 member_values: BTreeMap<usize, i64>,
1304 return_values: BTreeMap<String, i64>,
1305 diagnostics: DiagnosticSeqId,
1306 decisions: Vec<usize>,
1307 actions: Vec<ParserAction>,
1308 nodes: NodeSeqId,
1309}
1310
1311#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1312struct FastRecognizeOutcome {
1313 index: usize,
1314 consumed_eof: bool,
1315 diagnostics: DiagnosticSeqId,
1316 deferred_nodes: FastDeferredNodeId,
1317 nodes: NodeSeqId,
1321}
1322
1323#[derive(Debug, Default)]
1324struct FastRecognizeTopScratch {
1325 visiting: FxHashSet<FastRecognizeKey>,
1326 memo: FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
1327}
1328
1329impl FastRecognizeTopScratch {
1330 fn prepare(&mut self, memo_capacity: usize) {
1331 self.visiting.clear();
1332 self.visiting.reserve(FAST_RECOGNIZE_VISITING_CAPACITY);
1333 self.memo.clear();
1334 self.memo.reserve(memo_capacity);
1335 }
1336
1337 fn release_oversized_memo(&mut self) {
1338 self.memo.clear();
1339 if self.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY {
1340 self.memo = FxHashMap::default();
1341 }
1342 }
1343}
1344
1345fn fast_recognize_memo_capacity(buffered_tokens: usize) -> usize {
1346 buffered_tokens.saturating_mul(8).clamp(
1347 FAST_RECOGNIZE_MIN_MEMO_CAPACITY,
1348 FAST_RECOGNIZE_MAX_MEMO_CAPACITY,
1349 )
1350}
1351
1352#[derive(Debug, Default)]
1353struct FastOutcomeDedupScratch {
1354 dense_words: Vec<u64>,
1355 touched_dense_words: Vec<u32>,
1356 sparse_keys: FxHashSet<(usize, bool)>,
1357}
1358
1359#[repr(transparent)]
1364#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1365struct FastDeferredNodeId(u32);
1366
1367impl FastDeferredNodeId {
1368 const EMPTY: Self = Self(u32::MAX);
1369
1370 const fn is_empty(self) -> bool {
1371 self.0 == Self::EMPTY.0
1372 }
1373}
1374
1375impl Default for FastDeferredNodeId {
1376 fn default() -> Self {
1377 Self::EMPTY
1378 }
1379}
1380
1381#[repr(transparent)]
1382#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1383struct FastDeferredRuleId(u32);
1384
1385#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1387enum FastDeferredNode {
1388 Fragment(NodeSeqId),
1389 Rule(FastDeferredRuleId),
1390 Concat {
1391 prefix: FastDeferredNodeId,
1392 suffix: FastDeferredNodeId,
1393 },
1394}
1395
1396#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1397struct FastDeferredRule {
1398 rule_index: u32,
1399 invoking_state: i32,
1400 start_index: u32,
1401 stop_index: Option<u32>,
1402 deferred_children: FastDeferredNodeId,
1403 children: NodeSeqId,
1404}
1405
1406#[repr(transparent)]
1407#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1408struct RecognizedNodeId(u32);
1409
1410#[repr(transparent)]
1411#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1412struct NodeSeqId(u32);
1413
1414impl NodeSeqId {
1415 const EMPTY: Self = Self(u32::MAX);
1416
1417 const fn is_empty(self) -> bool {
1418 self.0 == Self::EMPTY.0
1419 }
1420}
1421
1422impl Default for NodeSeqId {
1423 fn default() -> Self {
1424 Self::EMPTY
1425 }
1426}
1427
1428#[repr(transparent)]
1429#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1430struct DiagnosticSeqId(u32);
1431
1432impl DiagnosticSeqId {
1433 const EMPTY: Self = Self(u32::MAX);
1434
1435 const fn is_empty(self) -> bool {
1436 self.0 == Self::EMPTY.0
1437 }
1438}
1439
1440impl Default for DiagnosticSeqId {
1441 fn default() -> Self {
1442 Self::EMPTY
1443 }
1444}
1445
1446#[repr(transparent)]
1447#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1448struct RecognitionExtraId(u32);
1449
1450#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1451struct SeqLink {
1452 head: RecognizedNodeId,
1453 tail: NodeSeqId,
1454}
1455
1456#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1457struct DiagnosticLink {
1458 head: RecognitionExtraId,
1459 tail: DiagnosticSeqId,
1460}
1461
1462struct ArenaRuleSpec {
1463 rule_index: usize,
1464 invoking_state: isize,
1465 alt_number: usize,
1466 start_index: usize,
1467 stop_index: Option<usize>,
1468 return_values: BTreeMap<String, i64>,
1469 children: NodeSeqId,
1470}
1471
1472#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1475enum ArenaRecognizedNode {
1476 Token {
1477 token: TokenId,
1478 },
1479 ErrorToken {
1480 token: TokenId,
1481 },
1482 MissingToken {
1483 extra: RecognitionExtraId,
1484 },
1485 Rule {
1486 rule_index: u32,
1487 invoking_state: i32,
1488 alt_number: u32,
1489 start_index: u32,
1490 stop_index: Option<u32>,
1491 return_values: Option<RecognitionExtraId>,
1492 children: NodeSeqId,
1493 },
1494 LeftRecursiveBoundary {
1498 rule_index: u32,
1499 alt_number: u32,
1500 },
1501}
1502
1503#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1504enum RecognitionExtra {
1505 MissingToken {
1506 token_type: i32,
1507 at_index: u32,
1508 text: String,
1509 },
1510 ReturnValues(BTreeMap<String, i64>),
1511 Diagnostic(ParserDiagnostic),
1512}
1513
1514#[derive(Debug, Default)]
1515struct RecognitionArena {
1516 nodes: Vec<ArenaRecognizedNode>,
1517 seq_links: Vec<SeqLink>,
1518 diagnostic_links: Vec<DiagnosticLink>,
1519 extras: Vec<RecognitionExtra>,
1520 deferred_nodes: Vec<FastDeferredNode>,
1521 deferred_rules: Vec<FastDeferredRule>,
1522}
1523
1524const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1527const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1528const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1529const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1530const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1531const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1532
1533impl RecognitionArena {
1534 fn reset(&mut self) {
1535 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1536 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1537 reset_arena_vec(
1538 &mut self.diagnostic_links,
1539 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1540 );
1541 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1542 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1543 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1544 }
1545
1546 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1547 let id = RecognizedNodeId(
1548 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1549 );
1550 self.nodes.push(node);
1551 id
1552 }
1553
1554 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1555 let id = RecognitionExtraId(
1556 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1557 );
1558 self.extras.push(extra);
1559 id
1560 }
1561
1562 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1563 let id = NodeSeqId(
1564 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1565 );
1566 self.seq_links.push(SeqLink { head, tail });
1567 id
1568 }
1569
1570 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1571 let id = FastDeferredNodeId(
1572 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
1573 );
1574 self.deferred_nodes.push(node);
1575 id
1576 }
1577
1578 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
1579 let id = FastDeferredRuleId(
1580 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
1581 );
1582 self.deferred_rules.push(rule);
1583 id
1584 }
1585
1586 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
1587 if nodes.is_empty() {
1588 FastDeferredNodeId::EMPTY
1589 } else {
1590 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
1591 }
1592 }
1593
1594 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
1595 let rule = self.push_deferred_rule(rule);
1596 self.push_deferred_node(FastDeferredNode::Rule(rule))
1597 }
1598
1599 fn concat_deferred_nodes(
1600 &mut self,
1601 prefix: FastDeferredNodeId,
1602 suffix: FastDeferredNodeId,
1603 ) -> FastDeferredNodeId {
1604 if prefix.is_empty() {
1605 return suffix;
1606 }
1607 if suffix.is_empty() {
1608 return prefix;
1609 }
1610 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
1611 }
1612
1613 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
1614 self.deferred_nodes[id.0 as usize]
1615 }
1616
1617 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
1618 self.deferred_rules[id.0 as usize]
1619 }
1620
1621 fn prepend_diagnostic(
1622 &mut self,
1623 tail: DiagnosticSeqId,
1624 diagnostic: ParserDiagnostic,
1625 ) -> DiagnosticSeqId {
1626 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
1627 self.prepend_diagnostic_id(tail, head)
1628 }
1629
1630 fn prepend_diagnostic_id(
1631 &mut self,
1632 tail: DiagnosticSeqId,
1633 head: RecognitionExtraId,
1634 ) -> DiagnosticSeqId {
1635 let id = DiagnosticSeqId(
1636 u32::try_from(self.diagnostic_links.len())
1637 .expect("diagnostic sequence arena fits in u32"),
1638 );
1639 self.diagnostic_links.push(DiagnosticLink { head, tail });
1640 id
1641 }
1642
1643 fn concat_diagnostics(
1644 &mut self,
1645 prefix: DiagnosticSeqId,
1646 mut suffix: DiagnosticSeqId,
1647 ) -> DiagnosticSeqId {
1648 if prefix.is_empty() {
1649 return suffix;
1650 }
1651 if suffix.is_empty() {
1652 return prefix;
1653 }
1654 let mut reversed = DiagnosticSeqId::EMPTY;
1655 let mut cursor = prefix;
1656 while let Some(link) = self.diagnostic_link(cursor) {
1657 reversed = self.prepend_diagnostic_id(reversed, link.head);
1658 cursor = link.tail;
1659 }
1660 while let Some(link) = self.diagnostic_link(reversed) {
1661 suffix = self.prepend_diagnostic_id(suffix, link.head);
1662 reversed = link.tail;
1663 }
1664 suffix
1665 }
1666
1667 #[cfg(test)]
1668 fn diagnostic_sequence(
1669 &mut self,
1670 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
1671 ) -> DiagnosticSeqId {
1672 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
1673 let mut sequence = DiagnosticSeqId::EMPTY;
1674 for diagnostic in diagnostics.into_iter().rev() {
1675 sequence = self.prepend_diagnostic(sequence, diagnostic);
1676 }
1677 sequence
1678 }
1679
1680 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
1681 self.nodes[id.0 as usize]
1682 }
1683
1684 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
1685 &self.extras[id.0 as usize]
1686 }
1687
1688 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
1689 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
1690 }
1691
1692 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
1693 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
1694 }
1695
1696 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
1697 NodeSeqIter {
1698 arena: self,
1699 cursor: sequence,
1700 }
1701 }
1702
1703 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
1704 DiagnosticSeqIter {
1705 arena: self,
1706 cursor: sequence,
1707 }
1708 }
1709
1710 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
1711 self.diagnostics(sequence).count()
1712 }
1713
1714 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
1715 self.diagnostics(sequence)
1716 .filter(|diagnostic| {
1717 diagnostic.message.starts_with("mismatched input ")
1718 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
1719 })
1720 .count()
1721 }
1722
1723 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
1724 self.diagnostics(left).cmp(self.diagnostics(right))
1725 }
1726
1727 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
1728 self.iter(sequence).count()
1729 }
1730
1731 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
1732 self.iter(sequence).any(|node| match self.node(node) {
1733 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1734 ArenaRecognizedNode::Rule { children, .. } => {
1735 self.sequence_has_left_recursive_boundary(children)
1736 }
1737 ArenaRecognizedNode::Token { .. }
1738 | ArenaRecognizedNode::ErrorToken { .. }
1739 | ArenaRecognizedNode::MissingToken { .. } => false,
1740 })
1741 }
1742
1743 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
1744 self.iter(sequence).any(|node| {
1745 matches!(
1746 self.node(node),
1747 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
1748 )
1749 })
1750 }
1751
1752 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
1753 self.iter(sequence).any(|node| {
1754 matches!(
1755 self.node(node),
1756 ArenaRecognizedNode::Token { .. }
1757 | ArenaRecognizedNode::ErrorToken { .. }
1758 | ArenaRecognizedNode::MissingToken { .. }
1759 )
1760 })
1761 }
1762
1763 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
1764 match self.node(node) {
1765 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1766 Some(token.index())
1767 }
1768 ArenaRecognizedNode::MissingToken { extra } => {
1769 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1770 unreachable!("missing-token node must reference missing-token extra");
1771 };
1772 Some(*at_index as usize)
1773 }
1774 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
1775 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1776 }
1777 }
1778
1779 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
1780 match self.node(node) {
1781 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1782 Some(token.index())
1783 }
1784 ArenaRecognizedNode::MissingToken { extra } => {
1785 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1786 unreachable!("missing-token node must reference missing-token extra");
1787 };
1788 (*at_index as usize).checked_sub(1)
1789 }
1790 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
1791 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1792 }
1793 }
1794
1795 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
1796 let start = self.node_start_index(node)?;
1797 let stop = self.node_stop_index(node);
1798 Some((start, stop))
1799 }
1800
1801 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
1802 self.iter(sequence)
1803 .find_map(|node| self.node_start_index(node))
1804 }
1805
1806 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
1807 let mut stop = None;
1808 for node in self.iter(sequence) {
1809 if let Some(index) = self.node_stop_index(node) {
1810 stop = Some(index);
1811 }
1812 }
1813 stop
1814 }
1815
1816 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
1817 self.iter(sequence)
1818 .any(|node| self.node_needs_stable_tie(node))
1819 }
1820
1821 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
1822 match self.node(node) {
1823 ArenaRecognizedNode::Token { .. }
1824 | ArenaRecognizedNode::ErrorToken { .. }
1825 | ArenaRecognizedNode::MissingToken { .. } => false,
1826 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1827 ArenaRecognizedNode::Rule {
1828 rule_index,
1829 children,
1830 ..
1831 } => self.iter(children).any(|child| {
1832 matches!(
1833 self.node(child),
1834 ArenaRecognizedNode::Rule {
1835 rule_index: child_rule,
1836 ..
1837 } if child_rule == rule_index
1838 ) || self.node_needs_stable_tie(child)
1839 }),
1840 }
1841 }
1842
1843 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
1844 loop {
1845 match (self.link(left), self.link(right)) {
1846 (Some(left_link), Some(right_link)) => {
1847 let order = self.compare_nodes(left_link.head, right_link.head);
1848 if order != Ordering::Equal {
1849 return order;
1850 }
1851 left = left_link.tail;
1852 right = right_link.tail;
1853 }
1854 (None, None) => return Ordering::Equal,
1855 (None, Some(_)) => return Ordering::Less,
1856 (Some(_), None) => return Ordering::Greater,
1857 }
1858 }
1859 }
1860
1861 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
1862 let left = self.node(left);
1863 let right = self.node(right);
1864 match (left, right) {
1865 (
1866 ArenaRecognizedNode::Token { token: left },
1867 ArenaRecognizedNode::Token { token: right },
1868 )
1869 | (
1870 ArenaRecognizedNode::ErrorToken { token: left },
1871 ArenaRecognizedNode::ErrorToken { token: right },
1872 ) => left.cmp(&right),
1873 (
1874 ArenaRecognizedNode::MissingToken { extra: left },
1875 ArenaRecognizedNode::MissingToken { extra: right },
1876 ) => self.extra(left).cmp(self.extra(right)),
1877 (
1878 ArenaRecognizedNode::Rule {
1879 rule_index: left_rule,
1880 invoking_state: left_invoking,
1881 alt_number: left_alt,
1882 start_index: left_start,
1883 stop_index: left_stop,
1884 return_values: left_returns,
1885 children: left_children,
1886 },
1887 ArenaRecognizedNode::Rule {
1888 rule_index: right_rule,
1889 invoking_state: right_invoking,
1890 alt_number: right_alt,
1891 start_index: right_start,
1892 stop_index: right_stop,
1893 return_values: right_returns,
1894 children: right_children,
1895 },
1896 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
1897 .cmp(&(
1898 right_rule,
1899 right_invoking,
1900 right_alt,
1901 right_start,
1902 right_stop,
1903 ))
1904 .then_with(|| {
1905 left_returns
1906 .map(|id| self.extra(id))
1907 .cmp(&right_returns.map(|id| self.extra(id)))
1908 })
1909 .then_with(|| self.compare_sequences(left_children, right_children)),
1910 (
1911 ArenaRecognizedNode::LeftRecursiveBoundary {
1912 rule_index: left_rule,
1913 alt_number: left_alt,
1914 },
1915 ArenaRecognizedNode::LeftRecursiveBoundary {
1916 rule_index: right_rule,
1917 alt_number: right_alt,
1918 },
1919 ) => (left_rule, left_alt).cmp(&(right_rule, right_alt)),
1920 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
1921 }
1922 }
1923
1924 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1925 let mut reversed = NodeSeqId::EMPTY;
1926 while let Some(link) = self.link(sequence) {
1927 reversed = self.prepend(reversed, link.head);
1928 sequence = link.tail;
1929 }
1930 reversed
1931 }
1932
1933 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1934 if !self.sequence_has_direct_boundary(sequence) {
1935 return sequence;
1936 }
1937 let mut reversed = NodeSeqId::EMPTY;
1938 while let Some(link) = self.link(sequence) {
1939 match self.node(link.head) {
1940 ArenaRecognizedNode::LeftRecursiveBoundary {
1941 rule_index,
1942 alt_number,
1943 } => {
1944 if !reversed.is_empty() {
1945 let children = self.reverse_sequence(reversed);
1946 let start_index = self.sequence_start_index(children).unwrap_or_default();
1947 let stop_index = self.sequence_stop_index(children);
1948 let rule = self.push_node(ArenaRecognizedNode::Rule {
1949 rule_index,
1950 invoking_state: -1,
1951 alt_number,
1952 start_index: u32::try_from(start_index)
1953 .expect("left-recursive start index fits in u32"),
1954 stop_index: stop_index.map(|index| {
1955 u32::try_from(index).expect("left-recursive stop index fits in u32")
1956 }),
1957 return_values: None,
1958 children,
1959 });
1960 reversed = self.prepend(NodeSeqId::EMPTY, rule);
1961 }
1962 }
1963 _ => {
1964 reversed = self.prepend(reversed, link.head);
1965 }
1966 }
1967 sequence = link.tail;
1968 }
1969 self.reverse_sequence(reversed)
1970 }
1971
1972 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
1973 let mut live_nodes = vec![false; self.nodes.len()];
1974 let mut live_links = vec![false; self.seq_links.len()];
1975 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
1976 let mut live_extras = vec![false; self.extras.len()];
1977 let mut pending = vec![root];
1978 while let Some(mut sequence) = pending.pop() {
1979 while let Some(link) = self.link(sequence) {
1980 let link_index = sequence.0 as usize;
1981 if live_links[link_index] {
1982 break;
1983 }
1984 live_links[link_index] = true;
1985 let node_index = link.head.0 as usize;
1986 if !live_nodes[node_index] {
1987 live_nodes[node_index] = true;
1988 match self.node(link.head) {
1989 ArenaRecognizedNode::MissingToken { extra } => {
1990 live_extras[extra.0 as usize] = true;
1991 }
1992 ArenaRecognizedNode::Rule {
1993 return_values,
1994 children,
1995 ..
1996 } => {
1997 if let Some(extra) = return_values {
1998 live_extras[extra.0 as usize] = true;
1999 }
2000 pending.push(children);
2001 }
2002 ArenaRecognizedNode::Token { .. }
2003 | ArenaRecognizedNode::ErrorToken { .. }
2004 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
2005 }
2006 }
2007 sequence = link.tail;
2008 }
2009 }
2010 let mut diagnostics = diagnostics;
2011 while let Some(link) = self.diagnostic_link(diagnostics) {
2012 let link_index = diagnostics.0 as usize;
2013 if live_diagnostic_links[link_index] {
2014 break;
2015 }
2016 live_diagnostic_links[link_index] = true;
2017 live_extras[link.head.0 as usize] = true;
2018 diagnostics = link.tail;
2019 }
2020 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
2021 let live_link_count = live_links.into_iter().filter(|live| *live).count()
2022 + live_diagnostic_links
2023 .into_iter()
2024 .filter(|live| *live)
2025 .count();
2026 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
2027 let total_links = self.seq_links.len() + self.diagnostic_links.len();
2028 RecognitionArenaStats {
2029 total_nodes: self.nodes.len(),
2030 live_nodes: live_node_count,
2031 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
2032 node_capacity: self.nodes.capacity(),
2033 total_links,
2034 live_links: live_link_count,
2035 dead_links: total_links.saturating_sub(live_link_count),
2036 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
2037 total_extras: self.extras.len(),
2038 live_extras: live_extra_count,
2039 dead_extras: self.extras.len().saturating_sub(live_extra_count),
2040 extra_capacity: self.extras.capacity(),
2041 }
2042 }
2043}
2044
2045fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
2046 if storage.capacity() > max_retained_capacity {
2047 *storage = Vec::new();
2048 } else {
2049 storage.clear();
2050 }
2051}
2052
2053const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
2054 match node {
2055 ArenaRecognizedNode::Token { .. } => 0,
2056 ArenaRecognizedNode::ErrorToken { .. } => 1,
2057 ArenaRecognizedNode::MissingToken { .. } => 2,
2058 ArenaRecognizedNode::Rule { .. } => 3,
2059 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
2060 }
2061}
2062
2063struct NodeSeqIter<'a> {
2064 arena: &'a RecognitionArena,
2065 cursor: NodeSeqId,
2066}
2067
2068impl Iterator for NodeSeqIter<'_> {
2069 type Item = RecognizedNodeId;
2070
2071 fn next(&mut self) -> Option<Self::Item> {
2072 let link = self.arena.link(self.cursor)?;
2073 self.cursor = link.tail;
2074 Some(link.head)
2075 }
2076}
2077
2078struct DiagnosticSeqIter<'a> {
2079 arena: &'a RecognitionArena,
2080 cursor: DiagnosticSeqId,
2081}
2082
2083impl<'a> Iterator for DiagnosticSeqIter<'a> {
2084 type Item = &'a ParserDiagnostic;
2085
2086 fn next(&mut self) -> Option<Self::Item> {
2087 let link = self.arena.diagnostic_link(self.cursor)?;
2088 self.cursor = link.tail;
2089 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2090 unreachable!("diagnostic link must reference diagnostic extra");
2091 };
2092 Some(diagnostic)
2093 }
2094}
2095
2096#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2097struct ParserDiagnostic {
2098 line: usize,
2099 column: usize,
2100 message: String,
2101}
2102
2103#[derive(Clone, Debug, Default, Eq, PartialEq)]
2104struct ExpectedTokens {
2105 index: Option<usize>,
2106 symbols: BTreeSet<i32>,
2107 no_viable: Option<NoViableAlternative>,
2108}
2109
2110#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2111struct NoViableAlternative {
2112 start_index: usize,
2113 error_index: usize,
2114}
2115
2116impl ExpectedTokens {
2117 fn record_transition(
2120 &mut self,
2121 index: usize,
2122 transition: ParserTransition<'_>,
2123 max_token_type: i32,
2124 ) {
2125 let symbols = transition_expected_symbols(transition, max_token_type);
2126 match self.index {
2127 Some(current) if index < current => {}
2128 Some(current) if index == current => self.symbols.extend(symbols),
2129 _ => {
2130 self.index = Some(index);
2131 self.symbols = symbols;
2132 }
2133 }
2134 }
2135
2136 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2139 match self.no_viable {
2140 Some(current) if error_index < current.error_index => {}
2141 _ => {
2142 self.no_viable = Some(NoViableAlternative {
2143 start_index,
2144 error_index,
2145 });
2146 }
2147 }
2148 }
2149}
2150
2151#[derive(Clone, Debug, Default, Eq, PartialEq)]
2158struct TokenBitSet {
2159 words: Vec<u64>,
2160}
2161
2162impl TokenBitSet {
2163 fn insert(&mut self, symbol: i32) {
2164 let Some(slot) = token_bit_slot(symbol) else {
2165 return;
2166 };
2167 let word = slot / u64::BITS as usize;
2168 if word >= self.words.len() {
2169 self.words.resize(word + 1, 0);
2170 }
2171 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2172 }
2173
2174 fn extend_range(&mut self, start: i32, stop: i32) {
2175 let (start, stop) = if start <= stop {
2176 (start, stop)
2177 } else {
2178 (stop, start)
2179 };
2180 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2181 self.insert(TOKEN_EOF);
2182 }
2183 let positive_start = start.max(1);
2184 if positive_start > stop {
2185 return;
2186 }
2187 let Some(start_slot) = token_bit_slot(positive_start) else {
2188 return;
2189 };
2190 let Some(stop_slot) = token_bit_slot(stop) else {
2191 return;
2192 };
2193 self.extend_slot_range(start_slot, stop_slot);
2194 }
2195
2196 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2197 if start_slot > stop_slot {
2198 return;
2199 }
2200 let start_word = start_slot / u64::BITS as usize;
2201 let stop_word = stop_slot / u64::BITS as usize;
2202 if stop_word >= self.words.len() {
2203 self.words.resize(stop_word + 1, 0);
2204 }
2205 let start_offset = start_slot % u64::BITS as usize;
2206 let stop_offset = stop_slot % u64::BITS as usize;
2207 if start_word == stop_word {
2208 self.words[start_word] |=
2209 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2210 return;
2211 }
2212 self.words[start_word] |= !0_u64 << start_offset;
2213 for word in &mut self.words[(start_word + 1)..stop_word] {
2214 *word = !0_u64;
2215 }
2216 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2217 }
2218
2219 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2220 for symbol in symbols {
2221 self.insert(symbol);
2222 }
2223 }
2224
2225 fn extend_from(&mut self, other: &Self) {
2226 if other.words.len() > self.words.len() {
2227 self.words.resize(other.words.len(), 0);
2228 }
2229 for (left, right) in self.words.iter_mut().zip(&other.words) {
2230 *left |= *right;
2231 }
2232 }
2233
2234 fn contains(&self, symbol: i32) -> bool {
2235 let Some(slot) = token_bit_slot(symbol) else {
2236 return false;
2237 };
2238 let word = slot / u64::BITS as usize;
2239 self.words
2240 .get(word)
2241 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2242 }
2243
2244 fn is_empty(&self) -> bool {
2245 self.words.iter().all(|word| *word == 0)
2246 }
2247
2248 fn symbols(&self) -> impl Iterator<Item = i32> + '_ {
2249 self.words
2250 .iter()
2251 .copied()
2252 .enumerate()
2253 .flat_map(|(word_index, mut bits)| {
2254 std::iter::from_fn(move || {
2255 while bits != 0 {
2256 let bit = bits.trailing_zeros() as usize;
2257 bits &= bits - 1;
2258 if let Some(symbol) =
2259 token_bit_symbol(word_index * u64::BITS as usize + bit)
2260 {
2261 return Some(symbol);
2262 }
2263 }
2264 None
2265 })
2266 })
2267 }
2268
2269 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2270 target.extend(self.symbols());
2271 }
2272
2273 fn to_btree_set(&self) -> BTreeSet<i32> {
2274 let mut out = BTreeSet::new();
2275 self.extend_btree_set(&mut out);
2276 out
2277 }
2278}
2279
2280fn token_bit_slot(symbol: i32) -> Option<usize> {
2281 if symbol == TOKEN_EOF {
2282 Some(0)
2283 } else if symbol > 0 {
2284 usize::try_from(symbol).ok()
2285 } else {
2286 None
2287 }
2288}
2289
2290fn token_bit_symbol(slot: usize) -> Option<i32> {
2291 if slot == 0 {
2292 Some(TOKEN_EOF)
2293 } else {
2294 i32::try_from(slot).ok()
2295 }
2296}
2297
2298fn transition_expected_symbols(
2301 transition: ParserTransition<'_>,
2302 max_token_type: i32,
2303) -> BTreeSet<i32> {
2304 let mut symbols = BTreeSet::new();
2305 match &transition.data() {
2306 Transition::Atom { label, .. } => {
2307 symbols.insert(*label);
2308 }
2309 Transition::Range { start, stop, .. } => {
2310 symbols.extend(*start..=*stop);
2311 }
2312 Transition::Set { set, .. } => {
2313 for (start, stop) in set.ranges() {
2314 symbols.extend(start..=stop);
2315 }
2316 }
2317 Transition::NotSet { set, .. } => {
2318 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2319 }
2320 Transition::Wildcard { .. } => {
2321 symbols.extend(1..=max_token_type);
2322 }
2323 Transition::Epsilon { .. }
2324 | Transition::Rule { .. }
2325 | Transition::Predicate { .. }
2326 | Transition::Action { .. }
2327 | Transition::Precedence { .. } => {}
2328 }
2329 symbols
2330}
2331
2332fn transition_expected_token_set(
2333 transition: ParserTransition<'_>,
2334 max_token_type: i32,
2335) -> TokenBitSet {
2336 let mut symbols = TokenBitSet::default();
2337 match &transition.data() {
2338 Transition::Atom { label, .. } => {
2339 symbols.insert(*label);
2340 }
2341 Transition::Range { start, stop, .. } => {
2342 symbols.extend_range(*start, *stop);
2343 }
2344 Transition::Set { set, .. } => {
2345 for (start, stop) in set.ranges() {
2346 symbols.extend_range(start, stop);
2347 }
2348 }
2349 Transition::NotSet { set, .. } => {
2350 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2351 }
2352 Transition::Wildcard { .. } => {
2353 symbols.extend_range(1, max_token_type);
2354 }
2355 Transition::Epsilon { .. }
2356 | Transition::Rule { .. }
2357 | Transition::Predicate { .. }
2358 | Transition::Action { .. }
2359 | Transition::Precedence { .. } => {}
2360 }
2361 symbols
2362}
2363
2364fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2368 let mut symbols = BTreeSet::new();
2369 let mut stack = vec![state_number];
2370 let mut visited = BTreeSet::new();
2371 while let Some(current) = stack.pop() {
2372 if !visited.insert(current) {
2373 continue;
2374 }
2375 let Some(state) = atn.state(current) else {
2376 continue;
2377 };
2378 for transition in &state.transitions() {
2379 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2380 if transition_symbols.is_empty() {
2381 if transition.is_epsilon() {
2382 stack.push(transition.target());
2383 }
2384 } else {
2385 symbols.extend(transition_symbols);
2386 }
2387 }
2388 }
2389 symbols
2390}
2391
2392fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2393 let mut symbols = TokenBitSet::default();
2394 let mut stack = vec![state_number];
2395 let mut visited = BTreeSet::new();
2396 while let Some(current) = stack.pop() {
2397 if !visited.insert(current) {
2398 continue;
2399 }
2400 let Some(state) = atn.state(current) else {
2401 continue;
2402 };
2403 for transition in &state.transitions() {
2404 let transition_symbols =
2405 transition_expected_token_set(transition, atn.max_token_type());
2406 if transition_symbols.is_empty() {
2407 if transition.is_epsilon() {
2408 stack.push(transition.target());
2409 }
2410 } else {
2411 symbols.extend_from(&transition_symbols);
2412 }
2413 }
2414 }
2415 symbols
2416}
2417
2418fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2419 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2420 return false;
2421 };
2422 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2423 return false;
2424 };
2425 epsilon_reaches_state(atn, state_number, stop_state)
2426}
2427
2428fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2429 let mut stack = vec![start];
2430 let mut visited = BTreeSet::new();
2431 while let Some(current) = stack.pop() {
2432 if current == target {
2433 return true;
2434 }
2435 if !visited.insert(current) {
2436 continue;
2437 }
2438 let Some(state) = atn.state(current) else {
2439 continue;
2440 };
2441 stack.extend(
2442 state
2443 .transitions()
2444 .iter()
2445 .filter(|transition| transition.is_epsilon())
2446 .map(ParserTransition::target),
2447 );
2448 }
2449 false
2450}
2451
2452#[derive(Clone, Debug, Default, Eq, PartialEq)]
2459struct FirstSet {
2460 symbols: TokenBitSet,
2461 nullable: bool,
2462}
2463
2464type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2471
2472type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2479
2480#[derive(Debug, Default)]
2481struct LeftRecursiveOperatorLookahead {
2482 single_token: TokenBitSet,
2486 multi_token_prefix: TokenBitSet,
2491 predicate_dependent: TokenBitSet,
2492}
2493
2494#[derive(Default)]
2495struct SharedAtnCache {
2496 first_set: FirstSetCache,
2497 decision_lookahead: DecisionLookaheadCache,
2498 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2499 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2500 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2501 rule_stop_reach: FxHashMap<usize, bool>,
2502 observable_action_transitions: Option<bool>,
2503 predicate_transitions: Option<bool>,
2504}
2505
2506thread_local! {
2507 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2508 RefCell::new(FxHashMap::default());
2509}
2510
2511#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2522struct SharedAtnCacheKey {
2523 atn: usize,
2524 states: usize,
2525 state_count: usize,
2526 max_token_type: i32,
2527}
2528
2529impl SharedAtnCacheKey {
2530 fn for_atn(atn: &Atn) -> Self {
2531 let (states, state_count) = atn.storage_identity();
2532 Self {
2533 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2534 states,
2535 state_count,
2536 max_token_type: atn.max_token_type(),
2537 }
2538 }
2539}
2540
2541fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2542 SHARED_ATN_CACHES.with(|cell| {
2543 let key = SharedAtnCacheKey::for_atn(atn);
2544 let mut map = cell.borrow_mut();
2545 let cache = map.entry(key).or_default();
2546 f(&mut cache.first_set)
2547 })
2548}
2549
2550fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
2551 SHARED_ATN_CACHES.with(|cell| {
2552 let key = SharedAtnCacheKey::for_atn(atn);
2553 let mut map = cell.borrow_mut();
2554 let cache = map.entry(key).or_default();
2555 f(cache)
2556 })
2557}
2558
2559#[derive(Debug, Default)]
2568struct DecisionLookahead {
2569 transitions: Vec<TransitionLookSet>,
2570}
2571
2572#[derive(Clone, Debug, Default)]
2579struct TransitionLookSet {
2580 symbols: TokenBitSet,
2581 nullable: bool,
2582}
2583
2584struct FirstSetCtx<'a> {
2588 cache: &'a mut FirstSetCache,
2589 in_progress: BTreeSet<(usize, usize)>,
2590 hit_cycle: bool,
2591}
2592
2593fn rule_first_set(
2602 atn: &Atn,
2603 target: usize,
2604 rule_stop_state: usize,
2605 cache: &mut FirstSetCache,
2606) -> Rc<FirstSet> {
2607 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
2608 return Rc::clone(cached);
2609 }
2610 let mut ctx = FirstSetCtx {
2611 cache,
2612 in_progress: BTreeSet::new(),
2613 hit_cycle: false,
2614 };
2615 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
2616}
2617
2618fn rule_first_set_cached(
2619 atn: &Atn,
2620 target: usize,
2621 rule_stop_state: usize,
2622 ctx: &mut FirstSetCtx<'_>,
2623) -> Rc<FirstSet> {
2624 let key = (target, rule_stop_state);
2625 if let Some(cached) = ctx.cache.get(&key) {
2626 return Rc::clone(cached);
2627 }
2628 if !ctx.in_progress.insert(key) {
2629 return Rc::new(FirstSet::default());
2633 }
2634 let saved_hit_cycle = ctx.hit_cycle;
2635 ctx.hit_cycle = false;
2636 let mut first = FirstSet::default();
2637 let mut visited = BTreeSet::new();
2638 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
2639 ctx.in_progress.remove(&key);
2640 let entry = Rc::new(first);
2641 if !ctx.hit_cycle {
2642 ctx.cache.insert(key, Rc::clone(&entry));
2643 }
2644 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
2645 entry
2646}
2647
2648fn transition_first_set(
2652 atn: &Atn,
2653 transition: ParserTransition<'_>,
2654 rule_stop_state: usize,
2655 cache: &mut FirstSetCache,
2656) -> TransitionLookSet {
2657 match &transition.data() {
2658 Transition::Atom { label, .. } => {
2659 let mut symbols = TokenBitSet::default();
2660 symbols.insert(*label);
2661 TransitionLookSet {
2662 symbols,
2663 nullable: false,
2664 }
2665 }
2666 Transition::Range { start, stop, .. } => {
2667 let mut symbols = TokenBitSet::default();
2668 symbols.extend_range(*start, *stop);
2669 TransitionLookSet {
2670 symbols,
2671 nullable: false,
2672 }
2673 }
2674 Transition::Set { set, .. } => {
2675 let mut symbols = TokenBitSet::default();
2676 for (start, stop) in set.ranges() {
2677 symbols.extend_range(start, stop);
2678 }
2679 TransitionLookSet {
2680 symbols,
2681 nullable: false,
2682 }
2683 }
2684 Transition::NotSet { set, .. } => {
2685 let max = atn.max_token_type();
2686 let mut symbols = TokenBitSet::default();
2687 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
2688 TransitionLookSet {
2689 symbols,
2690 nullable: false,
2691 }
2692 }
2693 Transition::Wildcard { .. } => {
2694 let mut symbols = TokenBitSet::default();
2695 symbols.extend_range(1, atn.max_token_type());
2696 TransitionLookSet {
2697 symbols,
2698 nullable: false,
2699 }
2700 }
2701 Transition::Epsilon { target }
2702 | Transition::Action { target, .. }
2703 | Transition::Predicate { target, .. }
2704 | Transition::Precedence { target, .. } => {
2705 let first = rule_first_set(atn, *target, rule_stop_state, cache);
2708 TransitionLookSet {
2709 symbols: first.symbols.clone(),
2710 nullable: first.nullable,
2711 }
2712 }
2713 Transition::Rule {
2714 target,
2715 rule_index,
2716 follow_state,
2717 ..
2718 } => {
2719 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2720 return TransitionLookSet::default();
2721 };
2722 let child = rule_first_set(atn, *target, child_stop, cache);
2723 let mut symbols = child.symbols.clone();
2724 let nullable = if child.nullable {
2725 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
2726 symbols.extend_from(&follow.symbols);
2727 follow.nullable
2728 } else {
2729 false
2730 };
2731 TransitionLookSet { symbols, nullable }
2732 }
2733 }
2734}
2735
2736fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
2757 let mut chosen: Option<usize> = None;
2758 for (index, transition) in entry.transitions.iter().enumerate() {
2759 if transition.nullable {
2760 return None;
2761 }
2762 if transition.symbols.contains(symbol) {
2763 if chosen.is_some() {
2764 return None;
2765 }
2766 chosen = Some(index);
2767 }
2768 }
2769 chosen
2770}
2771
2772fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
2781 let mut matching_non_nullable_alt = None;
2782 let mut nullable_alt = None;
2783 for (index, transition) in entry.transitions.iter().enumerate() {
2784 if transition.nullable {
2785 if nullable_alt.is_some() {
2786 return None;
2787 }
2788 nullable_alt = Some(index);
2789 }
2790 if transition.symbols.contains(symbol) {
2791 if transition.nullable {
2792 continue;
2793 }
2794 if matching_non_nullable_alt.is_some() {
2795 return None;
2796 }
2797 matching_non_nullable_alt = Some(index);
2798 }
2799 }
2800 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
2801 return None;
2802 }
2803 if non_greedy {
2804 nullable_alt.or(matching_non_nullable_alt)
2805 } else {
2806 matching_non_nullable_alt.or(nullable_alt)
2807 }
2808}
2809
2810fn should_skip_via_lookahead(
2811 transition_kind: ParserTransitionKind,
2812 transition_index: usize,
2813 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
2814 index: usize,
2815 record_expected: bool,
2816 expected: &mut ExpectedTokens,
2817) -> bool {
2818 let prune_non_consuming = matches!(
2819 transition_kind,
2820 ParserTransitionKind::Epsilon
2821 | ParserTransitionKind::Action
2822 | ParserTransitionKind::Predicate
2823 | ParserTransitionKind::Rule
2824 | ParserTransitionKind::Precedence
2825 );
2826 if !prune_non_consuming {
2827 return false;
2828 }
2829 let Some((symbol, entry)) = lookahead_filter else {
2830 return false;
2831 };
2832 let Some(set) = entry.transitions.get(transition_index) else {
2833 return false;
2834 };
2835 if set.symbols.contains(*symbol) || set.nullable {
2836 return false;
2837 }
2838 if record_expected && !set.symbols.is_empty() {
2839 record_pruned_transition_expected(set, index, expected);
2840 }
2841 true
2842}
2843
2844fn should_skip_rule_via_first_set(
2845 first: &FirstSet,
2846 symbol: i32,
2847 record_expected: bool,
2848 index: usize,
2849 expected: &mut ExpectedTokens,
2850) -> bool {
2851 if first.nullable || first.symbols.contains(symbol) {
2852 return false;
2853 }
2854 if record_expected && !first.symbols.is_empty() {
2855 record_token_bit_expected(&first.symbols, index, expected);
2856 }
2857 true
2858}
2859
2860fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
2861 match expected.index {
2862 Some(current) if index < current => {}
2863 Some(current) if index == current => {
2864 symbols.extend_btree_set(&mut expected.symbols);
2865 }
2866 _ => {
2867 expected.index = Some(index);
2868 expected.symbols = symbols.to_btree_set();
2869 }
2870 }
2871}
2872
2873fn record_pruned_transition_expected(
2875 set: &TransitionLookSet,
2876 index: usize,
2877 expected: &mut ExpectedTokens,
2878) {
2879 match expected.index {
2880 Some(current) if index < current => {}
2881 Some(current) if index == current => {
2882 set.symbols.extend_btree_set(&mut expected.symbols);
2883 }
2884 _ => {
2885 expected.index = Some(index);
2886 expected.symbols = set.symbols.to_btree_set();
2887 }
2888 }
2889}
2890
2891fn rule_first_set_inner(
2892 atn: &Atn,
2893 state_number: usize,
2894 rule_stop_state: usize,
2895 ctx: &mut FirstSetCtx<'_>,
2896 visited: &mut BTreeSet<usize>,
2897 first: &mut FirstSet,
2898) {
2899 if !visited.insert(state_number) {
2900 return;
2901 }
2902 if state_number == rule_stop_state {
2903 first.nullable = true;
2904 return;
2905 }
2906 let Some(state) = atn.state(state_number) else {
2907 return;
2908 };
2909 for transition in &state.transitions() {
2910 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2911 if !transition_symbols.is_empty() {
2912 first.symbols.extend_iter(transition_symbols);
2913 continue;
2914 }
2915 match &transition.data() {
2916 Transition::Epsilon { target }
2917 | Transition::Action { target, .. }
2918 | Transition::Predicate { target, .. }
2919 | Transition::Precedence { target, .. } => {
2920 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
2921 }
2922 Transition::Rule {
2923 target,
2924 rule_index,
2925 follow_state,
2926 ..
2927 } => {
2928 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2929 continue;
2930 };
2931 let child_key = (*target, child_stop);
2932 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
2933 ctx.hit_cycle = true;
2934 }
2935 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
2936 first.symbols.extend_from(&child.symbols);
2937 if child.nullable {
2938 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
2939 }
2940 }
2941 Transition::Atom { .. }
2942 | Transition::Range { .. }
2943 | Transition::Set { .. }
2944 | Transition::NotSet { .. }
2945 | Transition::Wildcard { .. } => {}
2946 }
2947 }
2948}
2949
2950fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
2953 let mut symbols = BTreeSet::new();
2954 state_sync_symbols_inner(
2955 atn,
2956 state_number,
2957 stop_state,
2958 &mut BTreeSet::new(),
2959 &mut symbols,
2960 );
2961 symbols
2962}
2963
2964fn state_sync_symbols_inner(
2967 atn: &Atn,
2968 state_number: usize,
2969 stop_state: usize,
2970 visited: &mut BTreeSet<usize>,
2971 symbols: &mut BTreeSet<i32>,
2972) {
2973 if !visited.insert(state_number) {
2974 return;
2975 }
2976 if state_number == stop_state {
2977 symbols.insert(TOKEN_EOF);
2978 return;
2979 }
2980 let Some(state) = atn.state(state_number) else {
2981 return;
2982 };
2983 for transition in &state.transitions() {
2984 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2985 if transition_symbols.is_empty() {
2986 match &transition.data() {
2987 Transition::Rule { target, .. }
2988 | Transition::Epsilon { target }
2989 | Transition::Action { target, .. }
2990 | Transition::Predicate { target, .. }
2991 | Transition::Precedence { target, .. } => {
2992 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
2993 }
2994 Transition::Atom { .. }
2995 | Transition::Range { .. }
2996 | Transition::Set { .. }
2997 | Transition::NotSet { .. }
2998 | Transition::Wildcard { .. } => {}
2999 }
3000 } else {
3001 symbols.extend(transition_symbols);
3002 }
3003 }
3004}
3005
3006#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
3007struct OperatorSymbolReachability {
3008 single_token: bool,
3010 multi_token: bool,
3012 predicate_dependent: bool,
3014}
3015
3016impl OperatorSymbolReachability {
3017 const ADAPTIVE_FALLBACK: Self = Self {
3018 single_token: false,
3019 multi_token: false,
3020 predicate_dependent: true,
3021 };
3022
3023 const fn single_token(predicate_dependent: bool) -> Self {
3024 if predicate_dependent {
3025 Self {
3026 single_token: false,
3027 multi_token: false,
3028 predicate_dependent: true,
3029 }
3030 } else {
3031 Self {
3032 single_token: true,
3033 multi_token: false,
3034 predicate_dependent: false,
3035 }
3036 }
3037 }
3038
3039 const fn multi_token(predicate_dependent: bool) -> Self {
3040 if predicate_dependent {
3041 Self {
3042 single_token: false,
3043 multi_token: false,
3044 predicate_dependent: true,
3045 }
3046 } else {
3047 Self {
3048 single_token: false,
3049 multi_token: true,
3050 predicate_dependent: false,
3051 }
3052 }
3053 }
3054
3055 const fn union(self, other: Self) -> Self {
3056 Self {
3057 single_token: self.single_token || other.single_token,
3058 multi_token: self.multi_token || other.multi_token,
3059 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
3060 }
3061 }
3062}
3063
3064#[derive(Clone, Copy)]
3065struct OperatorReachabilityRequest {
3066 symbol: i32,
3067 precedence: i32,
3068 predicate_dependent: bool,
3069 operator_rule_index: usize,
3070}
3071
3072#[derive(Clone, Copy, Debug)]
3073struct OperatorRuleContinuation {
3074 stop_state: usize,
3075 follow_state: usize,
3076 return_precedence: i32,
3077}
3078
3079struct NullablePrecedenceCtx {
3080 cache: FxHashMap<(usize, usize, i32, bool), bool>,
3081 in_progress: BTreeSet<(usize, usize, i32, bool)>,
3082 hit_cycle: bool,
3083}
3084
3085fn state_is_nullable_with_precedence(
3086 atn: &Atn,
3087 state_number: usize,
3088 stop_state_number: usize,
3089 precedence: i32,
3090 allow_predicates: bool,
3091 ctx: &mut NullablePrecedenceCtx,
3092) -> bool {
3093 let saved_hit_cycle = ctx.hit_cycle;
3094 ctx.hit_cycle = false;
3095 let nullable = state_is_nullable_with_precedence_cached(
3096 atn,
3097 state_number,
3098 stop_state_number,
3099 precedence,
3100 allow_predicates,
3101 ctx,
3102 );
3103 ctx.hit_cycle = saved_hit_cycle;
3104 nullable
3105}
3106
3107fn state_is_nullable_with_precedence_cached(
3108 atn: &Atn,
3109 state_number: usize,
3110 stop_state_number: usize,
3111 precedence: i32,
3112 allow_predicates: bool,
3113 ctx: &mut NullablePrecedenceCtx,
3114) -> bool {
3115 if state_number == stop_state_number {
3116 return true;
3117 }
3118 let key = (
3119 state_number,
3120 stop_state_number,
3121 precedence,
3122 allow_predicates,
3123 );
3124 if let Some(cached) = ctx.cache.get(&key) {
3125 return *cached;
3126 }
3127 if !ctx.in_progress.insert(key) {
3128 ctx.hit_cycle = true;
3129 return false;
3130 }
3131 let saved_hit_cycle = ctx.hit_cycle;
3132 ctx.hit_cycle = false;
3133 let nullable = atn.state(state_number).is_some_and(|state| {
3134 state
3135 .transitions()
3136 .iter()
3137 .any(|transition| match &transition.data() {
3138 Transition::Rule {
3139 target,
3140 rule_index,
3141 follow_state,
3142 precedence: rule_precedence,
3143 } => {
3144 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3145 return false;
3146 };
3147 state_is_nullable_with_precedence_cached(
3148 atn,
3149 *target,
3150 child_stop,
3151 *rule_precedence,
3152 allow_predicates,
3153 ctx,
3154 ) && state_is_nullable_with_precedence_cached(
3155 atn,
3156 *follow_state,
3157 stop_state_number,
3158 precedence,
3159 allow_predicates,
3160 ctx,
3161 )
3162 }
3163 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3164 state_is_nullable_with_precedence_cached(
3165 atn,
3166 *target,
3167 stop_state_number,
3168 precedence,
3169 allow_predicates,
3170 ctx,
3171 )
3172 }
3173 Transition::Predicate { target, .. } if allow_predicates => {
3174 state_is_nullable_with_precedence_cached(
3175 atn,
3176 *target,
3177 stop_state_number,
3178 precedence,
3179 allow_predicates,
3180 ctx,
3181 )
3182 }
3183 Transition::Precedence {
3184 target,
3185 precedence: transition_precedence,
3186 } if *transition_precedence >= precedence => {
3187 state_is_nullable_with_precedence_cached(
3188 atn,
3189 *target,
3190 stop_state_number,
3191 precedence,
3192 allow_predicates,
3193 ctx,
3194 )
3195 }
3196 Transition::Atom { .. }
3197 | Transition::Range { .. }
3198 | Transition::Set { .. }
3199 | Transition::NotSet { .. }
3200 | Transition::Wildcard { .. }
3201 | Transition::Predicate { .. }
3202 | Transition::Precedence { .. } => false,
3203 })
3204 });
3205 ctx.in_progress.remove(&key);
3206 if !ctx.hit_cycle {
3207 ctx.cache.insert(key, nullable);
3208 }
3209 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3210 nullable
3211}
3212
3213fn state_operator_token_prefix_reachability(
3215 atn: &Atn,
3216 state_number: usize,
3217 request: OperatorReachabilityRequest,
3218 continuations: &[OperatorRuleContinuation],
3219 visited: &mut BTreeSet<(usize, i32, bool)>,
3220) -> OperatorSymbolReachability {
3221 let key = (
3222 state_number,
3223 request.precedence,
3224 request.predicate_dependent,
3225 );
3226 if !visited.insert(key) {
3227 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3231 }
3232 if let Some((continuation, remaining)) = continuations.split_last()
3233 && state_number == continuation.stop_state
3234 {
3235 let result = state_operator_token_prefix_reachability(
3236 atn,
3237 continuation.follow_state,
3238 OperatorReachabilityRequest {
3239 precedence: continuation.return_precedence,
3240 ..request
3241 },
3242 remaining,
3243 visited,
3244 );
3245 visited.remove(&key);
3246 return result;
3247 }
3248 let Some(state) = atn.state(state_number) else {
3249 visited.remove(&key);
3250 return OperatorSymbolReachability::default();
3251 };
3252 let completes_operator = match state.kind() {
3253 AtnStateKind::RuleStop => continuations.is_empty(),
3254 AtnStateKind::StarLoopBack
3255 | AtnStateKind::StarLoopEntry
3256 | AtnStateKind::PlusLoopBack
3257 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3258 _ => false,
3259 };
3260 if completes_operator {
3261 visited.remove(&key);
3262 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3263 }
3264 let mut reachability = OperatorSymbolReachability::default();
3265 for transition in &state.transitions() {
3266 let transition_reachability = match &transition.data() {
3267 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3268 OperatorSymbolReachability::single_token(request.predicate_dependent)
3269 }
3270 Transition::Rule {
3271 target,
3272 rule_index,
3273 follow_state,
3274 precedence: rule_precedence,
3275 } => {
3276 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3277 continue;
3278 };
3279 let mut nested = continuations.to_vec();
3280 nested.push(OperatorRuleContinuation {
3281 stop_state: child_stop,
3282 follow_state: *follow_state,
3283 return_precedence: request.precedence,
3284 });
3285 state_operator_token_prefix_reachability(
3286 atn,
3287 *target,
3288 OperatorReachabilityRequest {
3289 precedence: *rule_precedence,
3290 ..request
3291 },
3292 &nested,
3293 visited,
3294 )
3295 }
3296 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3297 state_operator_token_prefix_reachability(
3298 atn,
3299 *target,
3300 request,
3301 continuations,
3302 visited,
3303 )
3304 }
3305 Transition::Precedence {
3306 target,
3307 precedence: transition_precedence,
3308 } => {
3309 if *transition_precedence < request.precedence {
3310 OperatorSymbolReachability::default()
3311 } else {
3312 state_operator_token_prefix_reachability(
3313 atn,
3314 *target,
3315 request,
3316 continuations,
3317 visited,
3318 )
3319 }
3320 }
3321 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3322 atn,
3323 *target,
3324 OperatorReachabilityRequest {
3325 predicate_dependent: true,
3326 ..request
3327 },
3328 continuations,
3329 visited,
3330 ),
3331 Transition::Atom { .. }
3332 | Transition::Range { .. }
3333 | Transition::Set { .. }
3334 | Transition::NotSet { .. }
3335 | Transition::Wildcard { .. } => {
3336 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3337 }
3338 };
3339 reachability = reachability.union(transition_reachability);
3340 }
3341 visited.remove(&key);
3342 reachability
3343}
3344
3345fn state_can_reach_symbol_with_precedence(
3346 atn: &Atn,
3347 state_number: usize,
3348 request: OperatorReachabilityRequest,
3349 nullable_ctx: &mut NullablePrecedenceCtx,
3350 continuations: &mut Vec<OperatorRuleContinuation>,
3351 visited: &mut BTreeSet<(usize, i32, bool)>,
3352) -> OperatorSymbolReachability {
3353 let key = (
3354 state_number,
3355 request.precedence,
3356 request.predicate_dependent,
3357 );
3358 if !visited.insert(key) {
3359 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3360 }
3361 let Some(state) = atn.state(state_number) else {
3362 visited.remove(&key);
3363 return OperatorSymbolReachability::default();
3364 };
3365 let mut reachability = OperatorSymbolReachability::default();
3366 for transition in &state.transitions() {
3367 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3368 reachability = reachability.union(state_operator_token_prefix_reachability(
3369 atn,
3370 transition.target(),
3371 request,
3372 continuations,
3373 &mut BTreeSet::new(),
3374 ));
3375 continue;
3376 }
3377 let transition_reachability = match &transition.data() {
3378 Transition::Rule {
3379 target,
3380 rule_index,
3381 follow_state,
3382 precedence: rule_precedence,
3383 } => {
3384 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3385 continue;
3386 };
3387 continuations.push(OperatorRuleContinuation {
3388 stop_state: child_stop,
3389 follow_state: *follow_state,
3390 return_precedence: request.precedence,
3391 });
3392 let mut result = state_can_reach_symbol_with_precedence(
3393 atn,
3394 *target,
3395 OperatorReachabilityRequest {
3396 precedence: *rule_precedence,
3397 ..request
3398 },
3399 nullable_ctx,
3400 continuations,
3401 visited,
3402 );
3403 continuations.pop();
3404 if state_is_nullable_with_precedence(
3405 atn,
3406 *target,
3407 child_stop,
3408 *rule_precedence,
3409 true,
3410 nullable_ctx,
3411 ) {
3412 let child_predicate_dependent = request.predicate_dependent
3413 || !state_is_nullable_with_precedence(
3414 atn,
3415 *target,
3416 child_stop,
3417 *rule_precedence,
3418 false,
3419 nullable_ctx,
3420 );
3421 result = result.union(state_can_reach_symbol_with_precedence(
3422 atn,
3423 *follow_state,
3424 OperatorReachabilityRequest {
3425 predicate_dependent: child_predicate_dependent,
3426 ..request
3427 },
3428 nullable_ctx,
3429 continuations,
3430 visited,
3431 ));
3432 }
3433 result
3434 }
3435 Transition::Epsilon { target }
3436 | Transition::Action { target, .. }
3437 | Transition::Precedence { target, .. } => {
3438 if matches!(
3439 &transition.data(),
3440 Transition::Precedence {
3441 precedence: transition_precedence,
3442 ..
3443 } if *transition_precedence < request.precedence
3444 ) {
3445 continue;
3446 }
3447 state_can_reach_symbol_with_precedence(
3448 atn,
3449 *target,
3450 request,
3451 nullable_ctx,
3452 continuations,
3453 visited,
3454 )
3455 }
3456 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3457 atn,
3458 *target,
3459 OperatorReachabilityRequest {
3460 predicate_dependent: true,
3461 ..request
3462 },
3463 nullable_ctx,
3464 continuations,
3465 visited,
3466 ),
3467 Transition::Atom { .. }
3468 | Transition::Range { .. }
3469 | Transition::Set { .. }
3470 | Transition::NotSet { .. }
3471 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3472 };
3473 reachability = reachability.union(transition_reachability);
3474 }
3475 visited.remove(&key);
3476 reachability
3477}
3478
3479fn left_recursive_operator_lookahead(
3480 atn: &Atn,
3481 state_number: usize,
3482 precedence: i32,
3483) -> LeftRecursiveOperatorLookahead {
3484 let Some(state) = atn.state(state_number) else {
3485 return LeftRecursiveOperatorLookahead::default();
3486 };
3487 let Some(operator_rule_index) = state.rule_index() else {
3488 return LeftRecursiveOperatorLookahead::default();
3489 };
3490 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3491 let mut nullable_ctx = NullablePrecedenceCtx {
3492 cache: FxHashMap::default(),
3493 in_progress: BTreeSet::new(),
3494 hit_cycle: false,
3495 };
3496 for transition in &state.transitions() {
3497 let target = transition.target();
3498 if atn
3499 .state(target)
3500 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3501 {
3502 continue;
3503 }
3504 for symbol in 1..=atn.max_token_type() {
3505 let reachability = state_can_reach_symbol_with_precedence(
3506 atn,
3507 target,
3508 OperatorReachabilityRequest {
3509 symbol,
3510 precedence,
3511 predicate_dependent: false,
3512 operator_rule_index,
3513 },
3514 &mut nullable_ctx,
3515 &mut Vec::new(),
3516 &mut BTreeSet::new(),
3517 );
3518 if reachability.single_token {
3519 lookahead.single_token.insert(symbol);
3520 }
3521 if reachability.multi_token {
3522 lookahead.multi_token_prefix.insert(symbol);
3523 }
3524 if reachability.predicate_dependent {
3525 lookahead.predicate_dependent.insert(symbol);
3526 }
3527 }
3528 }
3529 lookahead
3530}
3531
3532#[derive(Debug, Default)]
3533struct StateBeforeStopLookahead {
3534 symbols: TokenBitSet,
3535 reaches_context_boundary: bool,
3536}
3537
3538fn state_before_stop_lookahead(
3539 atn: &Atn,
3540 state_number: usize,
3541 stop_state_number: usize,
3542) -> Rc<StateBeforeStopLookahead> {
3543 with_shared_atn_caches(atn, |cache| {
3544 let key = (state_number, stop_state_number);
3545 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
3546 return Rc::clone(cached);
3547 }
3548 let mut lookahead = StateBeforeStopLookahead::default();
3549 state_before_stop_lookahead_inner(
3550 atn,
3551 state_number,
3552 stop_state_number,
3553 &mut BTreeSet::new(),
3554 &mut cache.first_set,
3555 &mut lookahead,
3556 );
3557 let lookahead = Rc::new(lookahead);
3558 cache
3559 .state_before_stop_lookahead
3560 .insert(key, Rc::clone(&lookahead));
3561 lookahead
3562 })
3563}
3564
3565fn state_before_stop_lookahead_inner(
3566 atn: &Atn,
3567 state_number: usize,
3568 stop_state_number: usize,
3569 visited: &mut BTreeSet<usize>,
3570 first_set_cache: &mut FirstSetCache,
3571 lookahead: &mut StateBeforeStopLookahead,
3572) {
3573 if state_number == stop_state_number {
3574 lookahead.reaches_context_boundary = true;
3575 return;
3576 }
3577 if !visited.insert(state_number) {
3578 return;
3579 }
3580 let Some(state) = atn.state(state_number) else {
3581 return;
3582 };
3583 if state.kind() == AtnStateKind::RuleStop {
3584 lookahead.reaches_context_boundary = true;
3585 return;
3586 }
3587 for transition in &state.transitions() {
3588 match &transition.data() {
3589 Transition::Epsilon { target }
3590 | Transition::Action { target, .. }
3591 | Transition::Predicate { target, .. }
3592 | Transition::Precedence { target, .. } => {
3593 state_before_stop_lookahead_inner(
3594 atn,
3595 *target,
3596 stop_state_number,
3597 visited,
3598 first_set_cache,
3599 lookahead,
3600 );
3601 }
3602 Transition::Rule {
3603 target,
3604 rule_index,
3605 follow_state,
3606 ..
3607 } => {
3608 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3609 continue;
3610 };
3611 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
3612 lookahead.symbols.extend_from(&child.symbols);
3613 if child.nullable {
3614 state_before_stop_lookahead_inner(
3615 atn,
3616 *follow_state,
3617 stop_state_number,
3618 visited,
3619 first_set_cache,
3620 lookahead,
3621 );
3622 }
3623 }
3624 Transition::Atom { .. }
3625 | Transition::Range { .. }
3626 | Transition::Set { .. }
3627 | Transition::NotSet { .. }
3628 | Transition::Wildcard { .. } => {
3629 lookahead.symbols.extend_iter(transition_expected_symbols(
3630 transition,
3631 atn.max_token_type(),
3632 ));
3633 }
3634 }
3635 }
3636}
3637
3638fn caller_context_can_match_symbol_before_state(
3639 atn: &Atn,
3640 return_states: impl DoubleEndedIterator<Item = usize>,
3641 stop_state_number: usize,
3642 symbol: i32,
3643) -> bool {
3644 for return_state in return_states.rev() {
3645 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
3646 if lookahead.symbols.contains(symbol) {
3647 return true;
3648 }
3649 if !lookahead.reaches_context_boundary {
3650 return false;
3651 }
3652 }
3653 false
3654}
3655
3656fn next_recovery_context(
3660 atn: &Atn,
3661 state: AtnState<'_>,
3662 inherited: &BTreeSet<i32>,
3663 inherited_state: Option<usize>,
3664) -> (BTreeSet<i32>, Option<usize>) {
3665 let state_symbols = state_expected_symbols(atn, state.state_number());
3666 if state.transitions().len() > 1 && !state_symbols.is_empty() {
3667 let mut symbols = state_symbols;
3668 symbols.extend(inherited.iter().copied());
3669 return (symbols, Some(state.state_number()));
3670 }
3671 (inherited.clone(), inherited_state)
3672}
3673
3674fn recovery_expected_symbols(
3675 atn: &Atn,
3676 state_number: usize,
3677 inherited: &BTreeSet<i32>,
3678) -> BTreeSet<i32> {
3679 let mut symbols = state_expected_symbols(atn, state_number);
3680 symbols.extend(inherited.iter().copied());
3681 symbols
3682}
3683
3684fn fast_next_recovery_context<S, H>(
3688 parser: &mut BaseParser<S, H>,
3689 atn: &Atn,
3690 state: AtnState<'_>,
3691 inherited: &Rc<BTreeSet<i32>>,
3692 inherited_state: Option<usize>,
3693) -> (Rc<BTreeSet<i32>>, Option<usize>)
3694where
3695 S: TokenSource,
3696 H: SemanticHooks,
3697{
3698 if state.transitions().len() <= 1 {
3699 return (Rc::clone(inherited), inherited_state);
3700 }
3701 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
3702 if state_symbols.is_empty() {
3703 return (Rc::clone(inherited), inherited_state);
3704 }
3705 if inherited.is_empty() {
3706 return (state_symbols, Some(state.state_number()));
3707 }
3708 if Rc::ptr_eq(&state_symbols, inherited) {
3709 return (state_symbols, Some(state.state_number()));
3710 }
3711 let mut combined = (*state_symbols).clone();
3712 combined.extend(inherited.iter().copied());
3713 (
3714 parser.intern_recovery_symbols(combined),
3715 Some(state.state_number()),
3716 )
3717}
3718
3719fn fast_recovery_expected_symbols<S, H>(
3723 parser: &mut BaseParser<S, H>,
3724 atn: &Atn,
3725 state_number: usize,
3726 inherited: &Rc<BTreeSet<i32>>,
3727) -> Rc<BTreeSet<i32>>
3728where
3729 S: TokenSource,
3730 H: SemanticHooks,
3731{
3732 let cached = parser.cached_state_expected_symbols(atn, state_number);
3733 if inherited.is_empty() {
3734 return cached;
3735 }
3736 if cached.is_empty() {
3737 return Rc::clone(inherited);
3738 }
3739 if Rc::ptr_eq(&cached, inherited) {
3740 return cached;
3741 }
3742 let mut combined = (*cached).clone();
3743 combined.extend(inherited.iter().copied());
3744 parser.intern_recovery_symbols(combined)
3745}
3746
3747struct ParserTableSemCtx<'a> {
3748 member_values: &'a mut BTreeMap<usize, i64>,
3749 return_values: &'a mut BTreeMap<String, i64>,
3750}
3751
3752impl semir::PredContext for ParserTableSemCtx<'_> {
3753 type TokenText<'a>
3754 = &'a str
3755 where
3756 Self: 'a;
3757
3758 fn la(&mut self, _offset: isize) -> i64 {
3759 i64::from(TOKEN_EOF)
3760 }
3761
3762 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
3763 None
3764 }
3765
3766 fn token_index_adjacent(&mut self) -> bool {
3767 false
3768 }
3769
3770 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
3771 None
3772 }
3773
3774 fn member(&self, member: usize) -> Option<i64> {
3775 Some(self.member_values.get(&member).copied().unwrap_or_default())
3776 }
3777
3778 fn local_arg(&self) -> Option<i64> {
3779 None
3780 }
3781
3782 fn column(&self) -> Option<i64> {
3783 None
3784 }
3785
3786 fn token_start_column(&self) -> Option<i64> {
3787 None
3788 }
3789
3790 fn token_text_so_far(&self) -> Option<String> {
3791 None
3792 }
3793
3794 fn hook(&mut self, _hook: HookId) -> bool {
3795 false
3796 }
3797}
3798
3799impl semir::ActContext for ParserTableSemCtx<'_> {
3800 fn set_member(&mut self, member: usize, value: i64) {
3801 self.member_values.insert(member, value);
3802 }
3803
3804 fn set_return(&mut self, name: &str, value: i64) {
3805 self.return_values.insert(name.to_owned(), value);
3806 }
3807
3808 fn action_hook(&mut self, _hook: HookId) {}
3809}
3810
3811fn apply_member_actions(
3813 source_state: usize,
3814 actions: &[ParserMemberAction],
3815 semantics: Option<&ParserSemantics>,
3816 values: &mut BTreeMap<usize, i64>,
3817) {
3818 for action in actions
3819 .iter()
3820 .filter(|action| action.source_state == source_state)
3821 {
3822 *values.entry(action.member).or_default() += action.delta;
3823 }
3824 let Some(semantics) = semantics else {
3825 return;
3826 };
3827 let mut return_values = BTreeMap::new();
3828 let mut ctx = ParserTableSemCtx {
3829 member_values: values,
3830 return_values: &mut return_values,
3831 };
3832 for action in semantics
3833 .actions
3834 .iter()
3835 .filter(|action| action.source_state == source_state && action.speculative)
3836 {
3837 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3838 }
3839}
3840
3841fn member_values_after_action(
3843 source_state: usize,
3844 actions: &[ParserMemberAction],
3845 semantics: Option<&ParserSemantics>,
3846 values: &BTreeMap<usize, i64>,
3847) -> BTreeMap<usize, i64> {
3848 let mut values = values.clone();
3849 apply_member_actions(source_state, actions, semantics, &mut values);
3850 values
3851}
3852
3853fn return_values_after_action(
3855 source_state: usize,
3856 rule_index: usize,
3857 actions: &[ParserReturnAction],
3858 semantics: Option<&ParserSemantics>,
3859 values: &BTreeMap<String, i64>,
3860) -> BTreeMap<String, i64> {
3861 let mut values = values.clone();
3862 for action in actions
3863 .iter()
3864 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
3865 {
3866 values.insert(action.name.to_owned(), action.value);
3867 }
3868 if let Some(semantics) = semantics {
3869 let mut member_values = BTreeMap::new();
3870 let mut ctx = ParserTableSemCtx {
3871 member_values: &mut member_values,
3872 return_values: &mut values,
3873 };
3874 for action in semantics.actions.iter().filter(|action| {
3875 action.source_state == source_state
3876 && action.rule_index == rule_index
3877 && !action.speculative
3878 }) {
3879 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3880 }
3881 }
3882 values
3883}
3884
3885fn rule_local_int_arg(
3887 rule_args: &[ParserRuleArg],
3888 source_state: usize,
3889 rule_index: usize,
3890 local_int_arg: Option<(usize, i64)>,
3891) -> Option<(usize, i64)> {
3892 rule_args
3893 .iter()
3894 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
3895 .map(|arg| {
3896 let value = if arg.inherit_local {
3897 local_int_arg.map_or(arg.value, |(_, value)| value)
3898 } else {
3899 arg.value
3900 };
3901 (rule_index, value)
3902 })
3903}
3904
3905fn stop_outcome(
3908 index: usize,
3909 consumed_eof: bool,
3910 rule_alt_number: usize,
3911 member_values: BTreeMap<usize, i64>,
3912 return_values: BTreeMap<String, i64>,
3913) -> Vec<RecognizeOutcome> {
3914 vec![RecognizeOutcome {
3915 index,
3916 consumed_eof,
3917 alt_number: rule_alt_number,
3918 member_values,
3919 return_values,
3920 diagnostics: DiagnosticSeqId::EMPTY,
3921 decisions: Vec::new(),
3922 actions: Vec::new(),
3923 nodes: NodeSeqId::EMPTY,
3924 }]
3925}
3926
3927fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
3928 with_shared_atn_caches(atn, |cache| {
3929 *cache.observable_action_transitions.get_or_insert_with(|| {
3930 atn.states().any(|state| {
3931 state.transitions().iter().any(|transition| {
3932 matches!(
3933 &transition.data(),
3934 Transition::Action {
3935 action_index: Some(_),
3936 ..
3937 }
3938 )
3939 })
3940 })
3941 })
3942 })
3943}
3944
3945fn atn_has_predicate_transitions(atn: &Atn) -> bool {
3946 with_shared_atn_caches(atn, |cache| {
3947 *cache.predicate_transitions.get_or_insert_with(|| {
3948 atn.states().any(|state| {
3949 state
3950 .transitions()
3951 .iter()
3952 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
3953 })
3954 })
3955 })
3956}
3957
3958fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
3963 options.init_action_rules.is_empty()
3964 && !options.track_alt_numbers
3965 && !options.track_context_alt_numbers
3966 && options
3967 .predicates
3968 .iter()
3969 .all(|(_, _, predicate)| predicate.failure_message().is_none())
3970 && options.semantics.is_none_or(|semantics| {
3971 semantics.actions.is_empty()
3972 && semantics
3973 .predicates
3974 .iter()
3975 .all(|predicate| predicate.failure_message.is_none())
3976 })
3977 && options.rule_args.is_empty()
3978 && options.member_actions.is_empty()
3979 && options.return_actions.is_empty()
3980 && !atn_has_observable_action_transitions(atn)
3981}
3982
3983#[derive(Clone, Debug, Eq, PartialEq)]
3984struct RecognizeRequest<'a> {
3985 state_number: usize,
3986 stop_state: usize,
3987 index: usize,
3988 rule_start_index: usize,
3989 decision_start_index: Option<usize>,
3990 init_action_rules: &'a BTreeSet<usize>,
3991 predicates: &'a [(usize, usize, ParserPredicate)],
3992 semantics: Option<&'a ParserSemantics>,
3993 rule_args: &'a [ParserRuleArg],
3994 member_actions: &'a [ParserMemberAction],
3995 return_actions: &'a [ParserReturnAction],
3996 local_int_arg: Option<(usize, i64)>,
3997 member_values: BTreeMap<usize, i64>,
3998 return_values: BTreeMap<String, i64>,
3999 rule_alt_number: usize,
4000 track_alt_numbers: bool,
4001 consumed_eof: bool,
4002 committed_decision: bool,
4003 precedence: i32,
4006 depth: usize,
4007 recovery_symbols: BTreeSet<i32>,
4008 recovery_state: Option<usize>,
4009}
4010
4011#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
4012struct RecognizeKey {
4013 state_number: usize,
4014 stop_state: usize,
4015 index: usize,
4016 rule_start_index: usize,
4017 decision_start_index: Option<usize>,
4018 local_int_arg: Option<(usize, i64)>,
4019 member_values: BTreeMap<usize, i64>,
4020 return_values: BTreeMap<String, i64>,
4021 rule_alt_number: usize,
4022 track_alt_numbers: bool,
4023 consumed_eof: bool,
4024 committed_decision: bool,
4025 precedence: i32,
4026 recovery_symbols: BTreeSet<i32>,
4027 recovery_state: Option<usize>,
4028}
4029
4030#[derive(Clone, Debug, Eq, PartialEq)]
4031struct EpsilonActionStep {
4032 source_state: usize,
4033 target: usize,
4034 action_rule_index: Option<usize>,
4035 left_recursive_boundary: Option<usize>,
4036 decision: Option<usize>,
4037 decision_start_index: Option<usize>,
4038 alt_number: usize,
4039 recovery_symbols: BTreeSet<i32>,
4040 recovery_state: Option<usize>,
4041}
4042
4043struct RecognizeScratch<'a> {
4044 visiting: &'a mut BTreeSet<RecognizeKey>,
4045 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4046 expected: &'a mut ExpectedTokens,
4047}
4048
4049#[derive(Clone, Debug, Eq, PartialEq)]
4050struct FastRecognizeRequest {
4051 state_number: usize,
4052 stop_state: usize,
4053 index: usize,
4054 rule_start_index: usize,
4055 decision_start_index: Option<usize>,
4056 precedence: i32,
4057 depth: usize,
4058 recovery_symbols: Rc<BTreeSet<i32>>,
4059 recovery_state: Option<usize>,
4060}
4061
4062#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4063struct FastRecognizeTopRequest {
4064 start_state: usize,
4065 stop_state: usize,
4066 start_index: usize,
4067 precedence: i32,
4068 caller_follow_state: Option<usize>,
4069}
4070
4071#[derive(Clone, Copy, Debug)]
4072struct FastPredicateContext<'a> {
4073 predicates: &'a [(usize, usize, ParserPredicate)],
4074 semantics: Option<&'a ParserSemantics>,
4075 member_values: &'a BTreeMap<usize, i64>,
4076}
4077
4078struct FastRecognizeScratch<'a, 'b> {
4079 predicate_context: Option<FastPredicateContext<'a>>,
4080 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4081 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4082 expected: &'b mut ExpectedTokens,
4083 native_depth: usize,
4084}
4085
4086#[derive(Clone, Copy, Debug)]
4087struct FastRepetitionShape {
4088 enter_target: usize,
4089 exit_target: usize,
4090 body_stop_state: usize,
4091 enter_transition_index: usize,
4092 exit_transition_index: usize,
4093}
4094
4095#[derive(Clone, Copy, Debug)]
4096struct FastRepetitionPath {
4097 index: usize,
4098 deferred_nodes: FastDeferredNodeId,
4099 diagnostics: DiagnosticSeqId,
4100 consumed_eof: bool,
4101}
4102
4103enum FastRepetitionWork {
4104 Enter(FastRepetitionPath),
4105 Exit(FastRepetitionPath),
4106}
4107
4108struct FastRepetitionCoordinates {
4113 base_index: usize,
4114 base_state: u8,
4115 later_states: Vec<u8>,
4116}
4117
4118impl FastRepetitionCoordinates {
4119 const ENTERED: u8 = 0;
4120 const EXITED: u8 = 2;
4121
4122 const fn new(base_index: usize) -> Self {
4123 Self {
4124 base_index,
4125 base_state: 0,
4126 later_states: Vec::new(),
4127 }
4128 }
4129
4130 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4131 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4132 }
4133
4134 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4135 self.insert(path.index, path.consumed_eof, Self::EXITED)
4136 }
4137
4138 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4139 let Some(offset) = index.checked_sub(self.base_index) else {
4140 return false;
4141 };
4142 let state = if offset == 0 {
4143 &mut self.base_state
4144 } else {
4145 if self.later_states.len() < offset {
4146 self.later_states.resize(offset, 0);
4147 }
4148 &mut self.later_states[offset - 1]
4149 };
4150 let bit = 1 << (base_bit + u8::from(consumed_eof));
4151 let is_new = *state & bit == 0;
4152 *state |= bit;
4153 is_new
4154 }
4155}
4156
4157fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4158 if state.precedence_rule_decision()
4159 || !matches!(
4160 state.kind(),
4161 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4162 )
4163 || state.transitions().len() != 2
4164 {
4165 return None;
4166 }
4167 let mut enter = None;
4168 let mut exit = None;
4169 for (index, transition) in state.transitions().iter().enumerate() {
4170 if transition.kind() != ParserTransitionKind::Epsilon {
4171 return None;
4172 }
4173 let target = transition.target();
4174 if atn
4175 .state(target)
4176 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4177 {
4178 if exit.replace((index, target)).is_some() {
4179 return None;
4180 }
4181 } else if enter.replace((index, target)).is_some() {
4182 return None;
4183 }
4184 }
4185 let (enter_transition_index, enter_target) = enter?;
4186 let (exit_transition_index, exit_target) = exit?;
4187 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4188 atn.state(exit_target)?.loop_back_state()?
4189 } else {
4190 state.state_number()
4191 };
4192 Some(FastRepetitionShape {
4193 enter_target,
4194 exit_target,
4195 body_stop_state,
4196 enter_transition_index,
4197 exit_transition_index,
4198 })
4199}
4200
4201fn push_fast_repetition_work(
4202 work: &mut Vec<FastRepetitionWork>,
4203 shape: FastRepetitionShape,
4204 path: FastRepetitionPath,
4205 lookahead: Option<&DecisionLookahead>,
4206 symbol: i32,
4207) {
4208 let transition_is_viable = |transition_index: usize| {
4211 let Some(entry) = lookahead else {
4212 return true;
4213 };
4214 let Some(transition) = entry.transitions.get(transition_index) else {
4215 return true;
4216 };
4217 transition.nullable || transition.symbols.contains(symbol)
4218 };
4219 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4220 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4221 if shape.enter_transition_index < shape.exit_transition_index {
4222 if exit_is_viable {
4223 work.push(FastRepetitionWork::Exit(path));
4224 }
4225 if enter_is_viable {
4226 work.push(FastRepetitionWork::Enter(path));
4227 }
4228 } else {
4229 if enter_is_viable {
4230 work.push(FastRepetitionWork::Enter(path));
4231 }
4232 if exit_is_viable {
4233 work.push(FastRepetitionWork::Exit(path));
4234 }
4235 }
4236}
4237
4238#[derive(Clone, Debug)]
4245struct FastRecognizeKey {
4246 state_number: usize,
4247 stop_state: usize,
4248 index: usize,
4249 rule_start_index: usize,
4250 decision_start_index: Option<usize>,
4251 precedence: i32,
4252 recovery_symbols_id: usize,
4253 recovery_state: Option<usize>,
4254}
4255
4256impl PartialEq for FastRecognizeKey {
4257 fn eq(&self, other: &Self) -> bool {
4258 if self.state_number != other.state_number
4259 || self.stop_state != other.stop_state
4260 || self.index != other.index
4261 || self.rule_start_index != other.rule_start_index
4262 || self.decision_start_index != other.decision_start_index
4263 || self.precedence != other.precedence
4264 || self.recovery_state != other.recovery_state
4265 || self.recovery_symbols_id != other.recovery_symbols_id
4266 {
4267 return false;
4268 }
4269 true
4270 }
4271}
4272
4273impl Eq for FastRecognizeKey {}
4274
4275impl Hash for FastRecognizeKey {
4276 fn hash<H: Hasher>(&self, hasher: &mut H) {
4277 self.state_number.hash(hasher);
4278 self.stop_state.hash(hasher);
4279 self.index.hash(hasher);
4280 self.rule_start_index.hash(hasher);
4281 self.decision_start_index.hash(hasher);
4282 self.precedence.hash(hasher);
4283 self.recovery_state.hash(hasher);
4284 self.recovery_symbols_id.hash(hasher);
4285 }
4286}
4287
4288struct FastRecoveryRequest<'a, 'b> {
4289 atn: &'a Atn,
4290 transition: ParserTransition<'a>,
4291 expected_symbols: Rc<BTreeSet<i32>>,
4292 target: usize,
4293 request: FastRecognizeRequest,
4294 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4295 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4296 expected: &'b mut ExpectedTokens,
4297}
4298
4299struct FastCurrentTokenDeletionRequest<'a, 'b> {
4300 atn: &'a Atn,
4301 expected_symbols: Rc<BTreeSet<i32>>,
4302 request: FastRecognizeRequest,
4303 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4304 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4305 expected: &'b mut ExpectedTokens,
4306}
4307
4308#[derive(Clone, Copy)]
4309struct FastChildRuleFailureRecoveryRequest<'a> {
4310 atn: &'a Atn,
4311 rule_index: usize,
4312 start_index: usize,
4313 follow_state: usize,
4314 stop_state: usize,
4315 expected: &'a ExpectedTokens,
4316}
4317
4318struct RecoveryRequest<'a, 'b> {
4319 atn: &'a Atn,
4320 transition: ParserTransition<'a>,
4321 expected_symbols: BTreeSet<i32>,
4322 target: usize,
4323 request: RecognizeRequest<'a>,
4324 visiting: &'b mut BTreeSet<RecognizeKey>,
4325 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4326 expected: &'b mut ExpectedTokens,
4327}
4328
4329struct CurrentTokenDeletionRequest<'a, 'b> {
4330 atn: &'a Atn,
4331 expected_symbols: BTreeSet<i32>,
4332 request: RecognizeRequest<'a>,
4333 visiting: &'b mut BTreeSet<RecognizeKey>,
4334 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4335 expected: &'b mut ExpectedTokens,
4336}
4337
4338struct ConsumingFailureFallback<'a> {
4341 atn: &'a Atn,
4342 target: usize,
4343 request: RecognizeRequest<'a>,
4344 symbol: i32,
4345 expected_symbols: BTreeSet<i32>,
4346 decision_start_index: Option<usize>,
4347 decision: Option<usize>,
4348}
4349
4350struct ChildRuleFailureRecovery<'a> {
4353 atn: &'a Atn,
4354 rule_index: usize,
4355 start_index: usize,
4356 follow_state: usize,
4357 stop_state: usize,
4358 member_values: BTreeMap<usize, i64>,
4359 expected: &'a ExpectedTokens,
4360}
4361
4362#[derive(Clone, Copy, Debug)]
4364struct PredicateEval<'a> {
4365 index: usize,
4366 rule_index: usize,
4367 pred_index: usize,
4368 predicates: &'a [(usize, usize, ParserPredicate)],
4369 semantics: Option<&'a ParserSemantics>,
4370 context: Option<&'a ParserRuleContext>,
4371 local_int_arg: Option<(usize, i64)>,
4372 member_values: &'a BTreeMap<usize, i64>,
4373}
4374
4375#[derive(Clone, Copy, Debug)]
4376struct ParserSemanticHookRequest<'a> {
4377 index: usize,
4378 rule_index: usize,
4379 pred_index: usize,
4380 context: Option<&'a ParserRuleContext>,
4381 local_int_arg: Option<(usize, i64)>,
4382 member_values: &'a BTreeMap<usize, i64>,
4383}
4384
4385struct ParserSemIrCtx<'a, S, H>
4394where
4395 S: TokenSource,
4396 H: SemanticHooks,
4397{
4398 input: &'a mut CommonTokenStream<S>,
4399 tree_storage: &'a ParseTreeStorage,
4400 semantic_hooks: &'a mut H,
4401 rule_index: usize,
4402 coordinate_index: usize,
4403 rule_name: Option<&'a str>,
4404 context: Option<&'a ParserRuleContext>,
4405 local_int_arg: Option<(usize, i64)>,
4406 member_values: &'a BTreeMap<usize, i64>,
4407 invoked_predicates: &'a mut Vec<(usize, usize)>,
4408 unknown_predicate_policy: UnknownSemanticPolicy,
4412 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4413}
4414
4415impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4416where
4417 S: TokenSource,
4418 H: SemanticHooks,
4419{
4420 type TokenText<'a>
4421 = TokenView<'a>
4422 where
4423 Self: 'a;
4424
4425 fn la(&mut self, offset: isize) -> i64 {
4426 i64::from(self.input.la(offset))
4427 }
4428
4429 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4430 self.input.lt(offset)
4431 }
4432
4433 fn token_index_adjacent(&mut self) -> bool {
4434 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4435 return false;
4436 };
4437 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4438 return false;
4439 };
4440 first + 1 == second
4441 }
4442
4443 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4444 self.context.and_then(|context| {
4445 context
4446 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4447 .next()
4448 .map(crate::tree::RuleNodeView::text)
4449 })
4450 }
4451
4452 fn member(&self, member: usize) -> Option<i64> {
4453 Some(self.member_values.get(&member).copied().unwrap_or_default())
4454 }
4455
4456 fn local_arg(&self) -> Option<i64> {
4457 self.local_int_arg.map(|(_, value)| value)
4458 }
4459
4460 fn column(&self) -> Option<i64> {
4461 None
4462 }
4463
4464 fn token_start_column(&self) -> Option<i64> {
4465 None
4466 }
4467
4468 fn token_text_so_far(&self) -> Option<String> {
4469 None
4470 }
4471
4472 fn hook(&mut self, _hook: HookId) -> bool {
4473 let mut ctx = ParserSemCtx {
4474 input: &mut *self.input,
4475 tree_storage: self.tree_storage,
4476 rule_index: self.rule_index,
4477 coordinate_index: self.coordinate_index,
4478 rule_name: self.rule_name.map(str::to_owned),
4479 context: self.context,
4480 tree: None,
4481 local_int_arg: self.local_int_arg,
4482 member_values: self.member_values,
4483 action: None,
4484 };
4485 match self
4486 .semantic_hooks
4487 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4488 {
4489 Some(result) => result,
4490 None => apply_unknown_predicate_policy(
4494 self.unknown_predicate_policy,
4495 self.rule_index,
4496 self.coordinate_index,
4497 self.unknown_predicate_hits,
4498 ),
4499 }
4500 }
4501
4502 fn trace_bool(&mut self, value: bool) -> bool {
4503 let key = (self.rule_index, self.coordinate_index);
4504 if !self.invoked_predicates.contains(&key) {
4505 self.invoked_predicates.push(key);
4506 use std::io::Write as _;
4507 let mut stdout = std::io::stdout().lock();
4508 let _ = writeln!(stdout, "eval={value}");
4509 }
4510 value
4511 }
4512}
4513
4514struct PredicateFailureRecovery<'a> {
4516 rule_index: usize,
4517 index: usize,
4518 message: &'a str,
4519 member_values: BTreeMap<usize, i64>,
4520 return_values: BTreeMap<String, i64>,
4521 rule_alt_number: usize,
4522}
4523
4524#[derive(Debug)]
4525enum DirectAdaptiveParseControl {
4526 Fallback(DirectAdaptiveFallback),
4527}
4528
4529#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4530enum DirectAdaptiveFallback {
4531 Action,
4532 InvalidAlt,
4533 LeftRecursiveBoundary,
4534 MissingAtn,
4535 NoTransition,
4536 Predicate,
4537 Prediction,
4538 Precedence,
4539 RuleStop,
4540 SemanticContext,
4541 StepLimit,
4542 TokenMismatch,
4543 UnknownDecision,
4544}
4545
4546type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
4547
4548struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
4549where
4550 S: TokenSource,
4551 H: SemanticHooks,
4552{
4553 parser: &'sim mut BaseParser<S, H>,
4554 atn: &'atn Atn,
4555 simulator: &'sim mut ParserAtnSimulator<'atn>,
4556 decision_by_state: Vec<Option<usize>>,
4557 steps: usize,
4558}
4559
4560#[derive(Clone, Debug, Eq, PartialEq)]
4570pub struct GeneratedMatch {
4571 children: GeneratedMatchChildren,
4572 consumed_eof: bool,
4573}
4574
4575#[derive(Clone, Copy)]
4576enum GeneratedExpectedSymbols<'a> {
4577 Tree(&'a BTreeSet<i32>),
4578 TokenSet(ParserIntervalSet<'a>),
4579 TokenSetComplement {
4580 set: ParserIntervalSet<'a>,
4581 min_vocabulary: i32,
4582 max_vocabulary: i32,
4583 },
4584}
4585
4586impl GeneratedExpectedSymbols<'_> {
4587 fn is_empty(self) -> bool {
4588 match self {
4589 Self::Tree(symbols) => symbols.is_empty(),
4590 Self::TokenSet(set) => set.is_empty(),
4591 Self::TokenSetComplement {
4592 set,
4593 min_vocabulary,
4594 max_vocabulary,
4595 } => (min_vocabulary..=max_vocabulary).all(|symbol| set.contains(symbol)),
4596 }
4597 }
4598
4599 fn first(self) -> Option<i32> {
4600 match self {
4601 Self::Tree(symbols) => symbols.iter().next().copied(),
4602 Self::TokenSet(set) => set.ranges().next().map(|(start, _)| start),
4603 Self::TokenSetComplement {
4604 set,
4605 min_vocabulary,
4606 max_vocabulary,
4607 } => (min_vocabulary..=max_vocabulary).find(|symbol| !set.contains(*symbol)),
4608 }
4609 }
4610
4611 fn display(self, vocabulary: &Vocabulary) -> String {
4612 match self {
4613 Self::Tree(symbols) => expected_symbols_display(symbols, vocabulary),
4614 Self::TokenSet(set) => expected_symbols_display_iter(
4615 set.ranges().flat_map(|(start, stop)| start..=stop),
4616 vocabulary,
4617 ),
4618 Self::TokenSetComplement {
4619 set,
4620 min_vocabulary,
4621 max_vocabulary,
4622 } => expected_symbols_display_iter(
4623 (min_vocabulary..=max_vocabulary).filter(|symbol| !set.contains(*symbol)),
4624 vocabulary,
4625 ),
4626 }
4627 }
4628}
4629
4630#[derive(Clone, Debug, Eq, PartialEq)]
4631enum GeneratedMatchChildren {
4632 One(ParseTree),
4633 Many(Vec<ParseTree>),
4634}
4635
4636struct GeneratedMatchChildrenIntoIter {
4637 one: Option<ParseTree>,
4638 many: Option<std::vec::IntoIter<ParseTree>>,
4639}
4640
4641impl Iterator for GeneratedMatchChildrenIntoIter {
4642 type Item = ParseTree;
4643
4644 fn next(&mut self) -> Option<Self::Item> {
4645 self.one
4646 .take()
4647 .or_else(|| self.many.as_mut().and_then(Iterator::next))
4648 }
4649}
4650
4651impl GeneratedMatch {
4652 #[must_use]
4656 pub fn children(&self) -> &[ParseTree] {
4657 match &self.children {
4658 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
4659 GeneratedMatchChildren::Many(children) => children,
4660 }
4661 }
4662
4663 #[must_use]
4666 pub fn into_children(self) -> Vec<ParseTree> {
4667 match self.children {
4668 GeneratedMatchChildren::One(child) => vec![child],
4669 GeneratedMatchChildren::Many(children) => children,
4670 }
4671 }
4672
4673 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
4675 match self.children {
4676 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
4677 one: Some(child),
4678 many: None,
4679 },
4680 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
4681 one: None,
4682 many: Some(children.into_iter()),
4683 },
4684 }
4685 }
4686
4687 #[must_use]
4689 pub const fn consumed_eof(&self) -> bool {
4690 self.consumed_eof
4691 }
4692}
4693
4694impl<S> BaseParser<S, NoSemanticHooks>
4695where
4696 S: TokenSource,
4697{
4698 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
4701 Self::with_semantic_hooks(input, data, NoSemanticHooks)
4702 }
4703}
4704
4705impl<S, H> BaseParser<S, H>
4706where
4707 S: TokenSource,
4708 H: SemanticHooks,
4709{
4710 pub fn with_semantic_hooks(
4712 input: CommonTokenStream<S>,
4713 data: RecognizerData,
4714 semantic_hooks: H,
4715 ) -> Self {
4716 Self {
4717 input,
4718 tree: ParseTreeStorage::new(),
4719 data,
4720 semantic_hooks,
4721 decision_override_generation: 0,
4722 build_parse_trees: true,
4723 syntax_errors: 0,
4724 report_diagnostic_errors: false,
4725 prediction_mode: PredictionMode::Ll,
4726 prediction_diagnostics: Vec::new(),
4727 reported_prediction_diagnostics: BTreeSet::new(),
4728 generated_parser_diagnostics: Vec::new(),
4729 generated_sync_expected: None,
4730 generated_recovery_error_index: None,
4731 generated_recovery_error_states: BTreeSet::new(),
4732 int_members: BTreeMap::new(),
4733 rule_context_stack: Vec::new(),
4734 rule_context_version: 0,
4735 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
4736 pending_invoking_states: Vec::new(),
4737 precedence_stack: vec![0],
4738 invoked_predicates: Vec::new(),
4739 bail_on_error: false,
4740 unknown_predicate_policy: UnknownSemanticPolicy::default(),
4741 unknown_predicate_hits: Vec::new(),
4742 unhandled_action_hits: Vec::new(),
4743 rule_first_set_cache: Vec::new(),
4744 state_expected_cache: FxHashMap::default(),
4745 state_expected_token_cache: FxHashMap::default(),
4746 rule_stop_reach_cache: Vec::new(),
4747 recovery_symbols_intern: FxHashMap::default(),
4748 decision_lookahead_cache: FxHashMap::default(),
4749 ll1_decision_cache: FxHashMap::default(),
4750 fast_predicate_cache: FxHashMap::default(),
4751 empty_cycle_cache: Vec::new(),
4752 empty_cycle_cache_atn: None,
4753 clean_memo_mode: CleanMemoMode::Probe,
4754 clean_memo_probe_seen: FxHashSet::default(),
4755 clean_memo_probe_samples: 0,
4756 clean_memo_probe_repeats: 0,
4757 clean_memo_sparse_samples: 0,
4758 fast_recognize_scratch: FastRecognizeTopScratch::default(),
4759 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
4760 empty_recovery_symbols: Rc::new(BTreeSet::new()),
4761 fast_first_set_prefilter: true,
4762 fast_recovery_enabled: true,
4763 fast_token_nodes_enabled: true,
4764 recognition_arena: RecognitionArena::default(),
4765 last_recognition_arena_root: NodeSeqId::EMPTY,
4766 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
4767 }
4768 }
4769
4770 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
4771 &mut self.input
4772 }
4773
4774 pub fn reset(&mut self) {
4779 self.input.seek(0);
4780 self.tree.reset();
4781 self.data.set_state(-1);
4782 self.syntax_errors = 0;
4783 self.prediction_diagnostics.clear();
4784 self.reported_prediction_diagnostics.clear();
4785 self.generated_parser_diagnostics.clear();
4786 self.generated_sync_expected = None;
4787 self.reset_generated_recovery_state();
4788 self.rule_context_stack.clear();
4789 self.advance_rule_context_version();
4790 self.left_recursive_caller_overlap_cache = std::array::from_fn(|_| None);
4791 self.pending_invoking_states.clear();
4792 self.precedence_stack.clear();
4793 self.precedence_stack.push(0);
4794 self.invoked_predicates.clear();
4795 self.decision_override_generation = 0;
4796 self.unknown_predicate_hits.clear();
4797 self.unhandled_action_hits.clear();
4798 self.reset_per_parse_caches();
4799 self.fast_first_set_prefilter = true;
4800 self.fast_recovery_enabled = true;
4801 self.fast_token_nodes_enabled = self.build_parse_trees;
4802 self.reset_recognition_arena();
4803 }
4804
4805 pub fn set_token_stream(&mut self, input: CommonTokenStream<S>) {
4807 self.input = input;
4808 self.reset();
4809 }
4810
4811 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
4822 self.unknown_predicate_policy = policy;
4823 }
4824
4825 #[must_use]
4831 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
4832 let error = self.unknown_semantic_error();
4833 self.unknown_predicate_hits.clear();
4834 self.unhandled_action_hits.clear();
4835 error
4836 }
4837
4838 pub fn reset_unknown_semantic_hits(&mut self) {
4845 self.unknown_predicate_hits.clear();
4846 self.unhandled_action_hits.clear();
4847 }
4848
4849 #[must_use]
4851 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
4852 &self.input
4853 }
4854
4855 #[must_use]
4857 pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<S> {
4858 &mut self.input
4859 }
4860
4861 #[must_use]
4863 pub const fn token_store(&self) -> &TokenStore {
4864 self.input.token_store()
4865 }
4866
4867 #[must_use]
4869 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
4870 &self.tree
4871 }
4872
4873 #[must_use]
4875 pub fn node(&self, id: NodeId) -> Node<'_> {
4876 self.tree
4877 .node(self.input.token_store(), id)
4878 .expect("parser-produced node ID should remain valid")
4879 }
4880
4881 #[must_use]
4883 pub fn into_token_stream(self) -> CommonTokenStream<S> {
4884 self.input
4885 }
4886
4887 #[must_use]
4889 pub fn into_token_store(self) -> TokenStore {
4890 self.input.into_token_store()
4891 }
4892
4893 #[must_use]
4895 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
4896 ParsedFile::new(self.input.into_token_store(), self.tree, root)
4897 }
4898
4899 pub const fn number_of_syntax_errors(&self) -> usize {
4902 self.syntax_errors
4903 }
4904
4905 #[must_use]
4911 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
4912 self.recognition_arena.stats(
4913 self.last_recognition_arena_root,
4914 self.last_recognition_arena_diagnostics,
4915 )
4916 }
4917
4918 pub const fn record_generated_syntax_error(&mut self) {
4921 self.record_syntax_errors(1);
4922 }
4923
4924 const fn record_syntax_errors(&mut self, count: usize) {
4925 self.syntax_errors = self.syntax_errors.saturating_add(count);
4926 }
4927
4928 pub fn report_token_source_errors(&mut self) {
4931 let errors = self.input.drain_source_errors();
4932 self.dispatch_token_source_errors(&errors);
4933 }
4934
4935 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
4938 GeneratedDiagnosticsCheckpoint {
4939 diagnostics_len: self.generated_parser_diagnostics.len(),
4940 syntax_errors: self.syntax_errors,
4941 tree: self.tree.checkpoint(),
4942 }
4943 }
4944
4945 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
4947 self.generated_parser_diagnostics
4948 .truncate(marker.diagnostics_len);
4949 self.syntax_errors = marker.syntax_errors;
4950 self.generated_sync_expected = None;
4951 self.tree.rollback(marker.tree);
4952 }
4953
4954 pub fn report_generated_parser_diagnostics(&mut self) {
4956 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
4957 let token_errors = self.input.drain_source_errors();
4958 self.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
4959 }
4960
4961 fn dispatch_parser_diagnostic(&self, diagnostic: &ParserDiagnostic) {
4962 self.notify_error_listeners(
4963 diagnostic.line,
4964 diagnostic.column,
4965 &diagnostic.message,
4966 None,
4967 );
4968 }
4969
4970 fn dispatch_parser_diagnostics<'a>(
4971 &self,
4972 diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>,
4973 ) {
4974 for diagnostic in diagnostics {
4975 self.dispatch_parser_diagnostic(diagnostic);
4976 }
4977 }
4978
4979 fn dispatch_token_source_error(&self, source_error: &TokenSourceError) {
4980 if self.input.token_source().report_error(source_error) {
4981 return;
4982 }
4983 self.notify_error_listeners(
4984 source_error.line,
4985 source_error.column,
4986 &source_error.message,
4987 None,
4988 );
4989 }
4990
4991 fn dispatch_token_source_errors(&self, errors: &[TokenSourceError]) {
4992 for error in errors {
4993 self.dispatch_token_source_error(error);
4994 }
4995 }
4996
4997 fn dispatch_generated_diagnostics(
5000 &self,
5001 parser_diagnostics: &[ParserDiagnostic],
5002 token_errors: &[TokenSourceError],
5003 ) {
5004 let mut token_iter = token_errors.iter().peekable();
5010 for diagnostic in parser_diagnostics {
5011 while let Some(error) = token_iter.peek() {
5012 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
5013 self.dispatch_token_source_error(error);
5014 token_iter.next();
5015 } else {
5016 break;
5017 }
5018 }
5019 self.dispatch_parser_diagnostic(diagnostic);
5020 }
5021 for error in token_iter {
5022 self.dispatch_token_source_error(error);
5023 }
5024 }
5025
5026 pub fn record_generated_ambiguity_diagnostic(
5029 &mut self,
5030 atn: &Atn,
5031 state_number: usize,
5032 start_index: usize,
5033 stop_index: usize,
5034 alts: &[usize],
5035 ) {
5036 if !self.report_diagnostic_errors || alts.len() < 2 {
5037 return;
5038 }
5039 let Some(decision) = atn
5040 .decision_to_state()
5041 .iter()
5042 .position(|candidate| candidate == state_number)
5043 else {
5044 return;
5045 };
5046 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5047 return;
5048 };
5049 let rule_name = self
5050 .rule_names()
5051 .get(rule_index)
5052 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5053 let input = display_input_text(&self.input.text(start_index, stop_index));
5054 let alts = alts
5055 .iter()
5056 .map(usize::to_string)
5057 .collect::<Vec<_>>()
5058 .join(", ");
5059 let key = (decision, start_index, format!("{alts}:{input}"));
5060 if !self.reported_prediction_diagnostics.insert(key) {
5061 return;
5062 }
5063 let start_diagnostic = diagnostic_for_token(
5064 self.token_at(start_index),
5065 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
5066 );
5067 let stop_diagnostic = diagnostic_for_token(
5068 self.token_at(stop_index),
5069 format!(
5070 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
5071 ),
5072 );
5073 self.generated_parser_diagnostics.push(start_diagnostic);
5074 self.generated_parser_diagnostics.push(stop_diagnostic);
5075 }
5076
5077 pub fn record_generated_prediction_diagnostic(
5080 &mut self,
5081 atn: &Atn,
5082 state_number: usize,
5083 prediction: &ParserAtnPrediction,
5084 ) {
5085 let Some(diagnostic) = &prediction.diagnostic else {
5086 return;
5087 };
5088 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5089 return;
5090 }
5091 let Some(decision) = atn
5092 .decision_to_state()
5093 .iter()
5094 .position(|candidate| candidate == state_number)
5095 else {
5096 return;
5097 };
5098 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5099 return;
5100 };
5101 let rule_name = self
5102 .rule_names()
5103 .get(rule_index)
5104 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5105 let attempt_input = display_input_text(
5106 &self
5107 .input
5108 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5109 );
5110 let result_input = display_input_text(
5111 &self
5112 .input
5113 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5114 );
5115 let alts = diagnostic
5116 .conflicting_alts
5117 .iter()
5118 .map(usize::to_string)
5119 .collect::<Vec<_>>()
5120 .join(", ");
5121 let key = (
5122 decision,
5123 diagnostic.start_index,
5124 format!(
5125 "{:?}:{alts}:{attempt_input}:{result_input}",
5126 diagnostic.kind
5127 ),
5128 );
5129 if !self.reported_prediction_diagnostics.insert(key) {
5130 return;
5131 }
5132 let attempt_diagnostic = diagnostic_for_token(
5133 self.token_at(diagnostic.sll_stop_index),
5134 format!(
5135 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5136 ),
5137 );
5138 self.generated_parser_diagnostics.push(attempt_diagnostic);
5139 let message = match diagnostic.kind {
5140 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5141 if !diagnostic.exact {
5146 return;
5147 }
5148 format!(
5149 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5150 )
5151 }
5152 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5153 format!(
5154 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5155 )
5156 }
5157 };
5158 let result_diagnostic =
5159 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5160 self.generated_parser_diagnostics.push(result_diagnostic);
5161 }
5162
5163 pub fn la(&self, offset: isize) -> i32 {
5164 self.input.la_token(offset)
5165 }
5166
5167 pub fn consume(&mut self) {
5168 IntStream::consume(&mut self.input);
5169 }
5170
5171 pub fn set_int_member(&mut self, member: usize, value: i64) {
5173 self.int_members.insert(member, value);
5174 }
5175
5176 pub fn int_member(&self, member: usize) -> Option<i64> {
5178 self.int_members.get(&member).copied()
5179 }
5180
5181 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
5184 self.int_members.clone()
5185 }
5186
5187 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
5189 self.int_members = members;
5190 }
5191
5192 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5194 let value = self.int_members.entry(member).or_default();
5195 *value += delta;
5196 *value
5197 }
5198
5199 fn token_type_for_id(&self, id: TokenId) -> i32 {
5200 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5201 }
5202
5203 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5204 if self.build_parse_trees {
5205 self.tree.terminal(id)
5206 } else {
5207 NodeId::placeholder()
5208 }
5209 }
5210
5211 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5212 if self.build_parse_trees {
5213 self.tree.error(id)
5214 } else {
5215 NodeId::placeholder()
5216 }
5217 }
5218
5219 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5220 context.set_start_id(id);
5221 }
5222
5223 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5224 context.set_stop_id(id);
5225 }
5226
5227 fn insert_synthetic_token(
5228 &mut self,
5229 token_type: i32,
5230 text: String,
5231 line: usize,
5232 column: usize,
5233 ) -> Result<TokenId, AntlrError> {
5234 self.input
5235 .insert(
5236 TokenSpec::explicit(token_type, text)
5237 .with_span(usize::MAX, usize::MAX)
5238 .with_byte_span(0, 0)
5239 .with_position(line, column),
5240 )
5241 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5242 }
5243
5244 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5251 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5252 line: 0,
5253 column: 0,
5254 message: "missing current token".to_owned(),
5255 })?;
5256 let current_type = self.token_type_for_id(current);
5257 if current_type == token_type {
5258 self.reset_generated_recovery_state();
5259 self.consume();
5260 Ok(self.terminal_tree(current))
5261 } else {
5262 Err(AntlrError::MismatchedInput {
5263 expected: self.vocabulary().display_name(token_type),
5264 found: self.vocabulary().display_name(current_type),
5265 })
5266 }
5267 }
5268
5269 pub fn match_token_recovering(
5273 &mut self,
5274 token_type: i32,
5275 follow_state: usize,
5276 atn: &Atn,
5277 ) -> Result<GeneratedMatch, AntlrError> {
5278 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5279 line: 0,
5280 column: 0,
5281 message: "missing current token".to_owned(),
5282 })?;
5283 let current_type = self.token_type_for_id(current);
5284 if current_type == token_type {
5285 self.generated_sync_expected = None;
5286 self.reset_generated_recovery_state();
5287 let consumed_eof = current_type == TOKEN_EOF;
5288 self.consume();
5289 return Ok(GeneratedMatch {
5290 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5291 consumed_eof,
5292 });
5293 }
5294 let mut expected_symbols = BTreeSet::new();
5295 expected_symbols.insert(token_type);
5296 self.recover_generated_match(
5297 current,
5298 GeneratedExpectedSymbols::Tree(&expected_symbols),
5299 follow_state,
5300 atn,
5301 |symbol| symbol == token_type,
5302 )
5303 }
5304
5305 pub fn match_set_recovering(
5306 &mut self,
5307 intervals: &[(i32, i32)],
5308 follow_state: usize,
5309 atn: &Atn,
5310 ) -> Result<GeneratedMatch, AntlrError> {
5311 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5312 line: 0,
5313 column: 0,
5314 message: "missing current token".to_owned(),
5315 })?;
5316 let current_type = self.token_type_for_id(current);
5317 if interval_set_contains(intervals, current_type) {
5318 self.generated_sync_expected = None;
5319 self.reset_generated_recovery_state();
5320 let consumed_eof = current_type == TOKEN_EOF;
5321 self.consume();
5322 return Ok(GeneratedMatch {
5323 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5324 consumed_eof,
5325 });
5326 }
5327 let expected_symbols = interval_symbols(intervals);
5328 self.recover_generated_match(
5329 current,
5330 GeneratedExpectedSymbols::Tree(&expected_symbols),
5331 follow_state,
5332 atn,
5333 |symbol| interval_set_contains(intervals, symbol),
5334 )
5335 }
5336
5337 pub fn match_token_set_recovering(
5338 &mut self,
5339 set: ParserIntervalSet<'_>,
5340 follow_state: usize,
5341 atn: &Atn,
5342 ) -> Result<GeneratedMatch, AntlrError> {
5343 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5344 line: 0,
5345 column: 0,
5346 message: "missing current token".to_owned(),
5347 })?;
5348 let current_type = self.token_type_for_id(current);
5349 if set.contains(current_type) {
5350 self.generated_sync_expected = None;
5351 self.reset_generated_recovery_state();
5352 let consumed_eof = current_type == TOKEN_EOF;
5353 self.consume();
5354 return Ok(GeneratedMatch {
5355 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5356 consumed_eof,
5357 });
5358 }
5359 self.recover_generated_match(
5360 current,
5361 GeneratedExpectedSymbols::TokenSet(set),
5362 follow_state,
5363 atn,
5364 |symbol| set.contains(symbol),
5365 )
5366 }
5367
5368 pub fn match_not_set_recovering(
5369 &mut self,
5370 intervals: &[(i32, i32)],
5371 min_vocabulary: i32,
5372 max_vocabulary: i32,
5373 follow_state: usize,
5374 atn: &Atn,
5375 ) -> Result<GeneratedMatch, AntlrError> {
5376 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5377 line: 0,
5378 column: 0,
5379 message: "missing current token".to_owned(),
5380 })?;
5381 let current_type = self.token_type_for_id(current);
5382 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5383 && !interval_set_contains(intervals, current_type)
5384 {
5385 self.generated_sync_expected = None;
5386 self.reset_generated_recovery_state();
5387 let consumed_eof = current_type == TOKEN_EOF;
5388 self.consume();
5389 return Ok(GeneratedMatch {
5390 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5391 consumed_eof,
5392 });
5393 }
5394 let expected_symbols =
5395 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
5396 self.recover_generated_match(
5397 current,
5398 GeneratedExpectedSymbols::Tree(&expected_symbols),
5399 follow_state,
5400 atn,
5401 |symbol| {
5402 (min_vocabulary..=max_vocabulary).contains(&symbol)
5403 && !interval_set_contains(intervals, symbol)
5404 },
5405 )
5406 }
5407
5408 pub fn match_not_token_set_recovering(
5409 &mut self,
5410 set: ParserIntervalSet<'_>,
5411 min_vocabulary: i32,
5412 max_vocabulary: i32,
5413 follow_state: usize,
5414 atn: &Atn,
5415 ) -> Result<GeneratedMatch, AntlrError> {
5416 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5417 line: 0,
5418 column: 0,
5419 message: "missing current token".to_owned(),
5420 })?;
5421 let current_type = self.token_type_for_id(current);
5422 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
5423 {
5424 self.generated_sync_expected = None;
5425 self.reset_generated_recovery_state();
5426 let consumed_eof = current_type == TOKEN_EOF;
5427 self.consume();
5428 return Ok(GeneratedMatch {
5429 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5430 consumed_eof,
5431 });
5432 }
5433 self.recover_generated_match(
5434 current,
5435 GeneratedExpectedSymbols::TokenSetComplement {
5436 set,
5437 min_vocabulary,
5438 max_vocabulary,
5439 },
5440 follow_state,
5441 atn,
5442 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
5443 )
5444 }
5445
5446 fn recover_generated_match(
5447 &mut self,
5448 current: TokenId,
5449 expected_symbols: GeneratedExpectedSymbols<'_>,
5450 follow_state: usize,
5451 atn: &Atn,
5452 matches: impl Fn(i32) -> bool,
5453 ) -> Result<GeneratedMatch, AntlrError> {
5454 let expected_display = expected_symbols.display(self.vocabulary());
5455 let (current_type, current_line, current_column, current_display) = {
5456 let token = self
5457 .input
5458 .token_view(current)
5459 .expect("current token ID should be valid");
5460 (
5461 token.token_type(),
5462 token.line(),
5463 token.column(),
5464 token_input_display(&token),
5465 )
5466 };
5467 if self.bail_on_error {
5468 return Err(AntlrError::ParserError {
5469 line: current_line,
5470 column: current_column,
5471 message: format!("mismatched input {current_display} expecting {expected_display}"),
5472 });
5473 }
5474 if current_type != TOKEN_EOF
5475 && let Some(next) = self.input.lt_id(2)
5476 && matches(self.token_type_for_id(next))
5477 {
5478 let message =
5479 format!("extraneous input {current_display} expecting {expected_display}");
5480 self.push_generated_parser_diagnostic(ParserDiagnostic {
5481 line: current_line,
5482 column: current_column,
5483 message,
5484 });
5485 self.record_syntax_errors(1);
5486 self.generated_sync_expected = None;
5487 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
5490 self.consume();
5491 self.consume();
5492 self.reset_generated_recovery_state();
5493 return Ok(GeneratedMatch {
5494 children: GeneratedMatchChildren::Many(vec![
5495 self.error_tree(current),
5496 self.terminal_tree(next),
5497 ]),
5498 consumed_eof,
5499 });
5500 }
5501 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
5502 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
5511 && self
5512 .cached_state_expected_symbols(atn, follow_state)
5513 .contains(&TOKEN_EOF);
5514 if follow_symbols.contains(¤t_type)
5515 && (current_type != TOKEN_EOF
5516 || self.rule_context_stack.len() > 1
5517 || expected_symbols.is_empty()
5518 || follow_explicitly_expects_eof)
5519 {
5520 let message = format!("missing {expected_display} at {current_display}");
5521 self.push_generated_parser_diagnostic(ParserDiagnostic {
5522 line: current_line,
5523 column: current_column,
5524 message,
5525 });
5526 self.record_syntax_errors(1);
5527 self.generated_sync_expected = None;
5528 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
5529 let missing_display = expected_symbol_display(token_type, self.vocabulary());
5530 let token = self.insert_synthetic_token(
5531 token_type,
5532 format!("<missing {missing_display}>"),
5533 current_line,
5534 current_column,
5535 )?;
5536 return Ok(GeneratedMatch {
5541 children: GeneratedMatchChildren::One(self.error_tree(token)),
5542 consumed_eof: false,
5543 });
5544 }
5545 let mismatch_expected_display = self
5546 .generated_sync_expected
5547 .take()
5548 .map_or(expected_display, |symbols| {
5549 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
5550 });
5551 Err(AntlrError::ParserError {
5552 line: current_line,
5553 column: current_column,
5554 message: format!(
5555 "mismatched input {current_display} expecting {mismatch_expected_display}"
5556 ),
5557 })
5558 }
5559
5560 fn generated_recovery_follow_symbols(
5561 &mut self,
5562 atn: &Atn,
5563 follow_state: usize,
5564 ) -> BTreeSet<i32> {
5565 let mut follow = self
5566 .cached_state_expected_symbols(atn, follow_state)
5567 .as_ref()
5568 .clone();
5569 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
5570 follow.extend(self.context_expected_symbols(atn));
5571 }
5572 follow
5573 }
5574
5575 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
5576 self.match_token(TOKEN_EOF)
5577 }
5578
5579 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
5580 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
5581 }
5582
5583 pub fn match_not_set(
5584 &mut self,
5585 intervals: &[(i32, i32)],
5586 min_vocabulary: i32,
5587 max_vocabulary: i32,
5588 ) -> Result<ParseTree, AntlrError> {
5589 self.match_interval_condition(intervals, |symbol| {
5590 (min_vocabulary..=max_vocabulary).contains(&symbol)
5591 && !interval_set_contains(intervals, symbol)
5592 })
5593 }
5594
5595 fn match_interval_condition(
5596 &mut self,
5597 intervals: &[(i32, i32)],
5598 matches: impl FnOnce(i32) -> bool,
5599 ) -> Result<ParseTree, AntlrError> {
5600 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5601 line: 0,
5602 column: 0,
5603 message: "missing current token".to_owned(),
5604 })?;
5605 let current_type = self.token_type_for_id(current);
5606 if matches(current_type) {
5607 self.reset_generated_recovery_state();
5608 self.consume();
5609 Ok(self.terminal_tree(current))
5610 } else {
5611 Err(AntlrError::MismatchedInput {
5612 expected: self.interval_display(intervals),
5613 found: self.vocabulary().display_name(current_type),
5614 })
5615 }
5616 }
5617
5618 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
5619 let values = intervals
5620 .iter()
5621 .map(|(start, stop)| {
5622 if start == stop {
5623 self.vocabulary().display_name(*start)
5624 } else {
5625 format!(
5626 "{}..{}",
5627 self.vocabulary().display_name(*start),
5628 self.vocabulary().display_name(*stop)
5629 )
5630 }
5631 })
5632 .collect::<Vec<_>>()
5633 .join(", ");
5634 format!("{{{values}}}")
5635 }
5636
5637 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
5638 if self.build_parse_trees {
5639 self.tree.finish_rule(context)
5640 } else {
5641 NodeId::placeholder()
5642 }
5643 }
5644
5645 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
5648 self.set_state(state);
5649 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
5650 self.rule_context_stack.push(RuleContextFrame {
5651 rule_index,
5652 invoking_state,
5653 });
5654 self.advance_rule_context_version();
5655 let start_index = self.current_visible_index();
5656 let mut context = ParserRuleContext::new(rule_index, invoking_state);
5657 if let Some(token) = self.token_id_at(start_index) {
5658 self.set_context_start(&mut context, token);
5659 }
5660 context
5661 }
5662
5663 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
5670 let marker = self.pending_invoking_states.len();
5671 self.pending_invoking_states.push(invoking_state);
5672 marker
5673 }
5674
5675 pub fn discard_invoking_state(&mut self, marker: usize) {
5677 self.pending_invoking_states.truncate(marker);
5678 }
5679
5680 pub fn exit_rule(&mut self) {
5682 self.rule_context_stack.pop();
5683 self.advance_rule_context_version();
5684 }
5685
5686 pub fn prediction_context_return_states<'a>(
5689 &'a self,
5690 atn: &'a Atn,
5691 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
5692 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
5693 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
5694 return None;
5695 };
5696 let Some(Transition::Rule { follow_state, .. }) = atn
5697 .state(state_number)
5698 .and_then(|state| state.transitions().first())
5699 .map(ParserTransition::data)
5700 else {
5701 return None;
5702 };
5703 Some(follow_state)
5704 })
5705 }
5706
5707 pub const fn rule_context_version(&self) -> usize {
5712 self.rule_context_version
5713 }
5714
5715 const fn advance_rule_context_version(&mut self) {
5716 self.rule_context_version = self.rule_context_version.wrapping_add(1);
5717 }
5718
5719 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
5724 if self.build_parse_trees {
5725 self.tree.add_child(context, child);
5726 } else {
5727 context.note_matched_child();
5728 }
5729 }
5730
5731 fn release_tree_scratch_if_idle(&mut self) {
5732 if self.rule_context_stack.is_empty() {
5733 self.tree.release_scratch();
5734 }
5735 }
5736
5737 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
5739 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5740 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5741 self.set_context_stop(&mut context, token);
5742 }
5743 let node = self.rule_node(context);
5744 self.exit_rule();
5745 self.release_tree_scratch_if_idle();
5746 node
5747 }
5748
5749 pub fn recover_generated_rule(
5756 &mut self,
5757 context: &mut ParserRuleContext,
5758 atn: &Atn,
5759 error: AntlrError,
5760 ) {
5761 let diagnostic = self.generated_rule_error_diagnostic(error);
5762 self.push_generated_parser_diagnostic(diagnostic);
5763 self.generated_sync_expected = None;
5764 let error_index = self.input.index();
5765 let error_state = self.data.state();
5766 if self.generated_recovery_error_index == Some(error_index)
5771 && self.generated_recovery_error_states.contains(&error_state)
5772 && self.la(1) != TOKEN_EOF
5773 && let Some(token) = self.input.lt_id(1)
5774 {
5775 self.consume();
5776 let child = self.error_tree(token);
5777 self.add_parse_child(context, child);
5778 }
5779 let recovery_index = self.input.index();
5780 if self.generated_recovery_error_index != Some(recovery_index) {
5781 self.generated_recovery_error_index = Some(recovery_index);
5782 self.generated_recovery_error_states.clear();
5783 }
5784 self.generated_recovery_error_states.insert(error_state);
5785 let recovery_symbols = self.context_expected_symbols(atn);
5786 loop {
5787 let symbol = self.la(1);
5788 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
5789 break;
5790 }
5791 let Some(token) = self.input.lt_id(1) else {
5792 break;
5793 };
5794 self.consume();
5795 let child = self.error_tree(token);
5796 self.add_parse_child(context, child);
5797 }
5798 self.record_syntax_errors(1);
5799 }
5800
5801 fn reset_generated_recovery_state(&mut self) {
5802 if self.generated_recovery_error_index.is_some() {
5803 self.generated_recovery_error_index = None;
5804 self.generated_recovery_error_states.clear();
5805 }
5806 }
5807
5808 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
5809 if self
5810 .generated_parser_diagnostics
5811 .iter()
5812 .any(|existing| existing == &diagnostic)
5813 {
5814 return;
5815 }
5816 self.generated_parser_diagnostics.push(diagnostic);
5817 }
5818
5819 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
5820 match error {
5821 AntlrError::ParserError {
5822 line,
5823 column,
5824 message,
5825 } => ParserDiagnostic {
5826 line,
5827 column,
5828 message,
5829 },
5830 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
5831 self.input.lt(1),
5832 format!("mismatched input {found} expecting {expected}"),
5833 ),
5834 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
5835 self.input.lt(1),
5836 format!("no viable alternative at input {input}"),
5837 ),
5838 AntlrError::LexerError {
5839 line,
5840 column,
5841 message,
5842 } => ParserDiagnostic {
5843 line,
5844 column,
5845 message,
5846 },
5847 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
5848 }
5849 }
5850
5851 pub fn finish_recursion_rule(
5853 &mut self,
5854 mut context: ParserRuleContext,
5855 consumed_eof: bool,
5856 ) -> ParseTree {
5857 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5858 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5859 self.set_context_stop(&mut context, token);
5860 }
5861 let node = self.rule_node(context);
5862 self.unroll_recursion_context();
5863 self.release_tree_scratch_if_idle();
5864 node
5865 }
5866
5867 pub fn enter_recursion_rule(
5869 &mut self,
5870 state: isize,
5871 rule_index: usize,
5872 precedence: i32,
5873 ) -> ParserRuleContext {
5874 self.precedence_stack.push(precedence);
5875 self.enter_rule(state, rule_index)
5876 }
5877
5878 pub fn push_new_recursion_context(
5880 &mut self,
5881 state: isize,
5882 rule_index: usize,
5883 ) -> ParserRuleContext {
5884 self.set_state(state);
5885 ParserRuleContext::new(rule_index, state)
5886 }
5887
5888 pub fn push_new_recursion_context_with_previous(
5891 &mut self,
5892 state: isize,
5893 rule_index: usize,
5894 current: &mut ParserRuleContext,
5895 ) {
5896 self.set_state(state);
5897 if let Some(stop) = self
5898 .rule_stop_token_index(self.input.index(), false)
5899 .and_then(|index| self.token_id_at(index))
5900 {
5901 self.set_context_stop(current, stop);
5902 }
5903 let invoking_state = current.invoking_state();
5904 let start = current.start_id();
5905 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
5906 if start.is_some() {
5907 replacement.set_start_from_context(current);
5908 }
5909 let previous = std::mem::replace(current, replacement);
5910 if self.build_parse_trees {
5911 let previous = self.rule_node(previous);
5912 self.tree.add_child(current, previous);
5913 }
5914 }
5915
5916 pub fn unroll_recursion_context(&mut self) {
5918 if self.precedence_stack.len() > 1 {
5919 self.precedence_stack.pop();
5920 }
5921 self.exit_rule();
5922 }
5923
5924 pub fn left_recursive_loop_enter_prediction(
5938 &mut self,
5939 atn: &Atn,
5940 state_number: usize,
5941 precedence: i32,
5942 ) -> Option<bool> {
5943 let symbol = self.la(1);
5944 if symbol == TOKEN_EOF {
5945 return Some(false);
5946 }
5947 let operator_lookahead =
5948 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
5949 let can_single = operator_lookahead.single_token.contains(symbol);
5950 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
5951 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
5952 if !can_single && !can_multi && !can_predicate {
5953 return Some(false);
5954 }
5955 if can_predicate && !can_single {
5956 return None;
5957 }
5958 if !can_single && can_multi && precedence > 0 {
5962 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
5963 if baseline.single_token.contains(symbol) {
5964 return None;
5965 }
5966 }
5967 let atn_key = SharedAtnCacheKey::for_atn(atn);
5968 let cached_overlap = self
5969 .left_recursive_caller_overlap_cache
5970 .iter()
5971 .flatten()
5972 .find(|entry| {
5973 entry.atn_key == atn_key
5974 && entry.state_number == state_number
5975 && entry.symbol == symbol
5976 && entry.context_version == self.rule_context_version
5977 })
5978 .map(|entry| entry.overlaps);
5979 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
5980 let overlaps = caller_context_can_match_symbol_before_state(
5981 atn,
5982 self.prediction_context_return_states(atn),
5983 state_number,
5984 symbol,
5985 );
5986 if let Some(slot) = self
5987 .left_recursive_caller_overlap_cache
5988 .iter_mut()
5989 .find(|slot| slot.is_none())
5990 {
5991 *slot = Some(LeftRecursiveCallerOverlap {
5992 atn_key,
5993 state_number,
5994 symbol,
5995 context_version: self.rule_context_version,
5996 overlaps,
5997 });
5998 }
5999 overlaps
6000 });
6001 if caller_overlaps {
6002 return None;
6003 }
6004 Some(true)
6005 }
6006
6007 fn cached_left_recursive_operator_lookahead(
6008 atn: &Atn,
6009 state_number: usize,
6010 precedence: i32,
6011 ) -> Rc<LeftRecursiveOperatorLookahead> {
6012 with_shared_atn_caches(atn, |cache| {
6013 let key = (state_number, precedence);
6014 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
6015 return Rc::clone(cached);
6016 }
6017 let lookahead = Rc::new(left_recursive_operator_lookahead(
6018 atn,
6019 state_number,
6020 precedence,
6021 ));
6022 cache
6023 .left_recursive_operator_lookahead
6024 .insert(key, Rc::clone(&lookahead));
6025 lookahead
6026 })
6027 }
6028
6029 pub fn left_recursive_loop_enter_matches(
6032 &mut self,
6033 atn: &Atn,
6034 state_number: usize,
6035 precedence: i32,
6036 ) -> bool {
6037 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
6038 }
6039
6040 pub fn precpred(&self, precedence: i32) -> bool {
6042 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
6043 }
6044
6045 pub fn parser_semantic_predicate_matches(
6048 &mut self,
6049 predicates: &[(usize, usize, ParserPredicate)],
6050 rule_index: usize,
6051 pred_index: usize,
6052 ) -> bool {
6053 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
6054 }
6055
6056 pub fn parser_semantic_predicate_matches_with_local(
6059 &mut self,
6060 predicates: &[(usize, usize, ParserPredicate)],
6061 rule_index: usize,
6062 pred_index: usize,
6063 local_int_arg: i32,
6064 ) -> bool {
6065 self.parser_semantic_predicate_matches_inner(
6066 predicates,
6067 rule_index,
6068 pred_index,
6069 Some((rule_index, i64::from(local_int_arg))),
6070 )
6071 }
6072
6073 fn parser_semantic_predicate_matches_inner(
6074 &mut self,
6075 predicates: &[(usize, usize, ParserPredicate)],
6076 rule_index: usize,
6077 pred_index: usize,
6078 local_int_arg: Option<(usize, i64)>,
6079 ) -> bool {
6080 let index = self.input.index();
6081 let member_values = self.int_members.clone();
6082 self.parser_predicate_matches(PredicateEval {
6083 index,
6084 rule_index,
6085 pred_index,
6086 predicates,
6087 semantics: None,
6088 context: None,
6089 local_int_arg,
6090 member_values: &member_values,
6091 })
6092 }
6093
6094 pub fn parser_semantic_predicate_matches_with_context_and_local(
6097 &mut self,
6098 predicates: &[(usize, usize, ParserPredicate)],
6099 rule_index: usize,
6100 pred_index: usize,
6101 context: &ParserRuleContext,
6102 local_int_arg: i32,
6103 ) -> bool {
6104 let index = self.input.index();
6105 let member_values = self.int_members.clone();
6106 self.parser_predicate_matches(PredicateEval {
6107 index,
6108 rule_index,
6109 pred_index,
6110 predicates,
6111 semantics: None,
6112 context: Some(context),
6113 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6114 member_values: &member_values,
6115 })
6116 }
6117
6118 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
6121 &mut self,
6122 semantics: &ParserSemantics,
6123 rule_index: usize,
6124 pred_index: usize,
6125 context: &ParserRuleContext,
6126 local_int_arg: i32,
6127 ) -> bool {
6128 let index = self.input.index();
6129 let member_values = self.int_members.clone();
6130 self.parser_predicate_matches(PredicateEval {
6131 index,
6132 rule_index,
6133 pred_index,
6134 predicates: &[],
6135 semantics: Some(semantics),
6136 context: Some(context),
6137 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6138 member_values: &member_values,
6139 })
6140 }
6141
6142 pub fn parser_semantic_predicate_failure_message(
6145 &self,
6146 rule_index: usize,
6147 pred_index: usize,
6148 predicates: &[(usize, usize, ParserPredicate)],
6149 ) -> Option<&'static str> {
6150 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
6151 }
6152
6153 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
6155 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6156 line: 0,
6157 column: 0,
6158 message: "missing current token".to_owned(),
6159 })?;
6160 if self.token_type_for_id(current) == TOKEN_EOF {
6161 return Err(AntlrError::MismatchedInput {
6162 expected: "wildcard".to_owned(),
6163 found: self.vocabulary().display_name(TOKEN_EOF),
6164 });
6165 }
6166 self.reset_generated_recovery_state();
6167 self.consume();
6168 Ok(self.terminal_tree(current))
6169 }
6170
6171 #[allow(clippy::unnecessary_wraps)]
6175 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
6176 self.set_state(state);
6177 Ok(())
6178 }
6179
6180 pub fn sync_decision(
6188 &mut self,
6189 atn: &Atn,
6190 state_number: usize,
6191 current_context_empty: bool,
6192 loop_back: bool,
6193 ) -> Result<Vec<ParseTree>, AntlrError> {
6194 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
6195 self.generated_sync_expected = None;
6196 let Some(state) = atn.state(state_number) else {
6197 return Ok(Vec::new());
6198 };
6199 let Some(rule_index) = state.rule_index() else {
6200 return Ok(Vec::new());
6201 };
6202 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
6203 return Ok(Vec::new());
6204 };
6205 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6206 let symbol = self.la(1);
6207 let mut has_expected_symbols = false;
6208 let mut nullable = false;
6209 let mut explicit_eof_expected = false;
6217 for transition in &entry.transitions {
6218 if transition.symbols.contains(symbol) {
6219 return Ok(Vec::new());
6220 }
6221 has_expected_symbols |= !transition.symbols.is_empty();
6222 nullable |= transition.nullable;
6223 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
6224 }
6225 if nullable && self.context_expected_contains(atn, symbol) {
6230 return Ok(Vec::new());
6231 }
6232 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
6233 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
6234 return Ok(Vec::new());
6235 }
6236 let mut expected = TokenBitSet::default();
6237 for transition in &entry.transitions {
6238 expected.extend_from(&transition.symbols);
6239 }
6240 if let Some(context_expected) = context_expected {
6241 expected.extend_from(&context_expected);
6242 }
6243 let can_delete_in_place =
6244 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
6245 let loop_sync = loop_back;
6262 if symbol != TOKEN_EOF && can_delete_in_place {
6263 let mut cursor = self.input.index();
6264 let mut skipped = Vec::new();
6265 loop {
6266 let current = self.token_type_at(cursor);
6267 if current == TOKEN_EOF {
6268 break;
6269 }
6270 skipped.push(cursor);
6271 let next = self.consume_index(cursor, current);
6272 if next == cursor {
6273 break;
6274 }
6275 let next_symbol = self.token_type_at(next);
6276 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
6284 explicit_eof_expected
6285 } else {
6286 expected.contains(next_symbol)
6287 };
6288 if next_is_expected_stop {
6289 let current_token = self.input.lt(1);
6290 let expected_symbols = expected.to_btree_set();
6291 let message = format!(
6292 "extraneous input {} expecting {}",
6293 current_token
6294 .as_ref()
6295 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6296 self.expected_symbols_display(&expected_symbols)
6297 );
6298 self.push_generated_parser_diagnostic(diagnostic_for_token(
6299 current_token,
6300 message,
6301 ));
6302 self.record_syntax_errors(1);
6303 let mut children = Vec::with_capacity(skipped.len());
6304 for index in skipped {
6305 if let Some(token) = self.token_id_at(index) {
6306 self.consume();
6307 children.push(self.error_tree(token));
6308 }
6309 }
6310 if !loop_sync {
6311 self.reset_generated_recovery_state();
6312 }
6313 return Ok(children);
6314 }
6315 if !loop_sync {
6319 break;
6320 }
6321 cursor = next;
6322 }
6323 }
6324 if nullable {
6325 self.generated_sync_expected = Some(expected);
6326 return Ok(Vec::new());
6327 }
6328 let current = self.input.lt(1);
6329 let expected_symbols = expected.to_btree_set();
6330 Err(AntlrError::ParserError {
6331 line: current.as_ref().map(Token::line).unwrap_or_default(),
6332 column: current.as_ref().map(Token::column).unwrap_or_default(),
6333 message: format!(
6334 "mismatched input {} expecting {}",
6335 current
6336 .as_ref()
6337 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6338 self.expected_symbols_display(&expected_symbols)
6339 ),
6340 })
6341 }
6342
6343 pub fn ll1_decision_prediction(
6350 &mut self,
6351 atn: &Atn,
6352 state_number: usize,
6353 ) -> Option<ParserAtnPrediction> {
6354 let state = atn.state(state_number)?;
6355 if state.precedence_rule_decision() {
6356 return None;
6357 }
6358 let rule_stop = state
6359 .rule_index()
6360 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
6361 let symbol = self.la(1);
6362 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6363 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
6364 alt: alt + 1,
6365 requires_full_context: false,
6366 has_semantic_context: false,
6367 diagnostic: None,
6368 })
6369 }
6370
6371 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
6372 let mut expected = BTreeSet::new();
6373 for index in (1..self.rule_context_stack.len()).rev() {
6374 let invoking_state = self.rule_context_stack[index].invoking_state;
6375 let Ok(state_number) = usize::try_from(invoking_state) else {
6376 continue;
6377 };
6378 let Some(Transition::Rule { follow_state, .. }) = atn
6379 .state(state_number)
6380 .and_then(|state| state.transitions().first())
6381 .map(ParserTransition::data)
6382 else {
6383 continue;
6384 };
6385 let return_state = follow_state;
6386 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
6387 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
6388 return expected;
6389 }
6390 }
6391 expected.insert(TOKEN_EOF);
6392 expected
6393 }
6394
6395 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
6396 let mut expected = TokenBitSet::default();
6397 for index in (1..self.rule_context_stack.len()).rev() {
6398 let invoking_state = self.rule_context_stack[index].invoking_state;
6399 let Ok(state_number) = usize::try_from(invoking_state) else {
6400 continue;
6401 };
6402 let Some(Transition::Rule { follow_state, .. }) = atn
6403 .state(state_number)
6404 .and_then(|state| state.transitions().first())
6405 .map(ParserTransition::data)
6406 else {
6407 continue;
6408 };
6409 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
6410 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6411 return expected;
6412 }
6413 }
6414 expected.insert(TOKEN_EOF);
6415 expected
6416 }
6417
6418 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
6429 for index in (1..self.rule_context_stack.len()).rev() {
6430 let invoking_state = self.rule_context_stack[index].invoking_state;
6431 let Ok(state_number) = usize::try_from(invoking_state) else {
6432 continue;
6433 };
6434 let Some(Transition::Rule { follow_state, .. }) = atn
6435 .state(state_number)
6436 .and_then(|state| state.transitions().first())
6437 .map(ParserTransition::data)
6438 else {
6439 continue;
6440 };
6441 if self
6442 .cached_state_expected_token_set(atn, follow_state)
6443 .contains(symbol)
6444 {
6445 return true;
6446 }
6447 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6448 return false;
6449 }
6450 }
6451 symbol == TOKEN_EOF
6452 }
6453
6454 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
6456 let error_index = self.input.index();
6457 self.no_viable_alternative_error_at(start_index, error_index)
6458 }
6459
6460 pub fn no_viable_alternative_error_at(
6465 &self,
6466 start_index: usize,
6467 error_index: usize,
6468 ) -> AntlrError {
6469 let diagnostic = self.no_viable_alternative(start_index, error_index);
6470 AntlrError::ParserError {
6471 line: diagnostic.line,
6472 column: diagnostic.column,
6473 message: diagnostic.message,
6474 }
6475 }
6476
6477 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
6479 let current = self.input.lt(1);
6480 AntlrError::ParserError {
6481 line: current.as_ref().map(Token::line).unwrap_or_default(),
6482 column: current.as_ref().map(Token::column).unwrap_or_default(),
6483 message: format!("rule failed predicate: {}", message.into()),
6484 }
6485 }
6486
6487 pub fn failed_predicate_option_error(
6490 &self,
6491 rule_index: usize,
6492 message: impl Into<String>,
6493 ) -> AntlrError {
6494 let current = self.input.lt(1);
6495 let rule_name = self
6496 .rule_names()
6497 .get(rule_index)
6498 .map_or_else(|| rule_index.to_string(), Clone::clone);
6499 AntlrError::ParserError {
6500 line: current.as_ref().map(Token::line).unwrap_or_default(),
6501 column: current.as_ref().map(Token::column).unwrap_or_default(),
6502 message: format!("rule {rule_name} {}", message.into()),
6503 }
6504 }
6505
6506 pub fn parser_action_at_current(
6508 &mut self,
6509 source_state: usize,
6510 rule_index: usize,
6511 start_index: usize,
6512 consumed_eof: bool,
6513 ) -> ParserAction {
6514 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6515 ParserAction::new(source_state, rule_index, start_index, stop_index)
6516 }
6517
6518 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
6523 let rule_index = action.rule_index();
6524 let rule_name = self.rule_names().get(rule_index).cloned();
6525 let context = None;
6526 let input = &mut self.input;
6527 let semantic_hooks = &mut self.semantic_hooks;
6528 let member_values = &self.int_members;
6529 let mut ctx = ParserSemCtx {
6530 input,
6531 tree_storage: &self.tree,
6532 rule_index,
6533 coordinate_index: usize::MAX,
6534 rule_name,
6535 context,
6536 tree: Some(tree),
6537 local_int_arg: None,
6538 member_values,
6539 action: Some(action),
6540 };
6541 let handled = semantic_hooks.action(&mut ctx, action);
6542 if !handled && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error) {
6548 let coordinate = (rule_index, action.source_state());
6549 if !self.unhandled_action_hits.contains(&coordinate) {
6550 self.unhandled_action_hits.push(coordinate);
6551 }
6552 }
6553 handled
6554 }
6555
6556 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
6561 &mut self,
6562 atn: &'atn Atn,
6563 simulator: &mut ParserAtnSimulator<'atn>,
6564 rule_index: usize,
6565 ) -> Result<ParseTree, AntlrError> {
6566 let start_index = self.current_visible_index();
6567 self.clear_prediction_diagnostics();
6568 self.reset_per_parse_caches();
6569 self.reset_recognition_arena();
6570 let tree_checkpoint = self.tree.checkpoint();
6571 let mut decision_by_state = vec![None; atn.states().len()];
6572 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
6573 if let Some(slot) = decision_by_state.get_mut(state_number) {
6574 *slot = Some(decision);
6575 }
6576 }
6577
6578 let result = DirectAdaptiveParser {
6579 parser: self,
6580 atn,
6581 simulator,
6582 decision_by_state,
6583 steps: 0,
6584 }
6585 .parse_rule(rule_index, -1, 0);
6586
6587 match result {
6588 Ok(tree) => {
6589 self.report_token_source_errors();
6590 self.release_tree_scratch_if_idle();
6591 Ok(tree)
6592 }
6593 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
6594 let _ = reason;
6595 self.tree.rollback(tree_checkpoint);
6596 self.input.seek(start_index);
6597 self.parse_atn_rule(atn, rule_index)
6598 }
6599 }
6600 }
6601
6602 pub fn parse_atn_rule(
6612 &mut self,
6613 atn: &Atn,
6614 rule_index: usize,
6615 ) -> Result<ParseTree, AntlrError> {
6616 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
6617 }
6618
6619 pub fn parse_atn_rule_with_precedence(
6622 &mut self,
6623 atn: &Atn,
6624 rule_index: usize,
6625 precedence: i32,
6626 ) -> Result<ParseTree, AntlrError> {
6627 self.parse_atn_rule_with_precedence_inner(atn, rule_index, precedence, None)
6628 }
6629
6630 fn parse_atn_rule_with_precedence_inner(
6631 &mut self,
6632 atn: &Atn,
6633 rule_index: usize,
6634 precedence: i32,
6635 predicate_context: Option<FastPredicateContext<'_>>,
6636 ) -> Result<ParseTree, AntlrError> {
6637 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
6638 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
6639 })?;
6640 let stop_state = atn
6641 .rule_to_stop_state()
6642 .get(rule_index)
6643 .filter(|state| *state != usize::MAX)
6644 .ok_or_else(|| {
6645 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
6646 })?;
6647
6648 let start_index = self.current_visible_index();
6649 self.clear_prediction_diagnostics();
6650 self.reset_per_parse_caches();
6651 self.reset_recognition_arena();
6652 let caller_follow_state = self.pending_invoking_follow_state(atn);
6653 self.fast_recovery_enabled = false;
6654 self.fast_token_nodes_enabled = false;
6655 let top_request = FastRecognizeTopRequest {
6656 start_state,
6657 stop_state,
6658 start_index,
6659 precedence,
6660 caller_follow_state,
6661 };
6662 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
6663 self.fast_token_nodes_enabled = self.build_parse_trees;
6664 let needs_tree_retry = matches!(
6665 &first_pass,
6666 Ok((outcome, _))
6667 if self.build_parse_trees
6668 && self
6669 .recognition_arena
6670 .sequence_has_left_recursive_boundary(outcome.nodes)
6671 );
6672 let needs_retry = match &first_pass {
6673 Err(_) => true,
6686 Ok((outcome, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
6687 };
6688 let (outcome, _expected) = if needs_retry {
6689 self.fast_first_set_prefilter = false;
6690 self.fast_recovery_enabled = false;
6691 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6692 let clean_selected = if needs_tree_retry {
6693 match clean_retry {
6694 ok @ Ok(_) => ok,
6695 Err(_) => first_pass,
6696 }
6697 } else {
6698 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
6699 };
6700 let selected = if clean_selected.is_err()
6701 || matches!(&clean_selected, Ok((outcome, _)) if !outcome.diagnostics.is_empty())
6702 {
6703 self.fast_recovery_enabled = true;
6704 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6705 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
6706 } else {
6707 clean_selected
6708 };
6709 self.fast_first_set_prefilter = true;
6710 self.fast_recovery_enabled = true;
6711 selected.map_err(|expected| {
6712 if predicate_context.is_some()
6713 && let Some(error) = self.unknown_semantic_error()
6714 {
6715 self.report_token_source_errors();
6716 return error;
6717 }
6718 let error = self.recognition_error(rule_index, start_index, &expected);
6719 self.record_syntax_errors(1);
6720 self.report_token_source_errors();
6721 error
6722 })?
6723 } else {
6724 first_pass.expect("first_pass is Ok in the no-retry branch")
6725 };
6726 if predicate_context.is_some()
6727 && let Some(error) = self.unknown_semantic_error()
6728 {
6729 self.report_token_source_errors();
6730 return Err(error);
6731 }
6732 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
6733 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
6734 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
6735 self.report_token_source_errors();
6736 let mut context = ParserRuleContext::with_child_capacity(
6737 rule_index,
6738 self.state(),
6739 if self.build_parse_trees {
6740 self.recognition_arena.sequence_len(outcome.nodes)
6741 } else {
6742 0
6743 },
6744 );
6745 if let Some(token) = self.token_id_at(start_index) {
6746 self.set_context_start(&mut context, token);
6747 }
6748 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
6749 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
6750 self.set_context_stop(&mut context, token);
6751 }
6752 let live_root = if self.build_parse_trees {
6753 self.recognition_arena
6754 .fold_left_recursive_boundaries(outcome.nodes)
6755 } else {
6756 outcome.nodes
6757 };
6758 if self.build_parse_trees {
6759 if self
6760 .recognition_arena
6761 .sequence_has_explicit_token(live_root)
6762 {
6763 let mut cursor = live_root;
6764 while let Some(link) = self.recognition_arena.link(cursor) {
6765 let child = self.arena_recognized_node_tree(link.head, false, false)?;
6766 self.tree.add_child(&mut context, child);
6767 cursor = link.tail;
6768 }
6769 } else {
6770 self.add_arena_implicit_token_children(
6771 &mut context,
6772 start_index,
6773 stop_index,
6774 live_root,
6775 )?;
6776 }
6777 }
6778 self.finish_recognition_arena(live_root, outcome.diagnostics);
6779 self.input.seek(outcome.index);
6780
6781 let tree = self.rule_node(context);
6782 self.release_tree_scratch_if_idle();
6783 Ok(tree)
6784 }
6785
6786 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
6787 let invoking_state = self.pending_invoking_states.last().copied()?;
6788 let state_number = usize::try_from(invoking_state).ok()?;
6789 match atn.state(state_number)?.transitions().first()?.data() {
6790 Transition::Rule { follow_state, .. } => Some(follow_state),
6791 _ => None,
6792 }
6793 }
6794
6795 #[cfg(test)]
6796 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
6797 caller_follow_token_info_for_stream(&mut self.input, index)
6798 }
6799
6800 fn fast_recognize_top(
6805 &mut self,
6806 atn: &Atn,
6807 request: FastRecognizeTopRequest,
6808 predicate_context: Option<FastPredicateContext<'_>>,
6809 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
6810 let FastRecognizeTopRequest {
6811 start_state,
6812 stop_state,
6813 start_index,
6814 precedence,
6815 caller_follow_state,
6816 } = request;
6817 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
6826 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
6827 recognize_scratch.prepare(memo_capacity);
6828 let mut expected = ExpectedTokens::default();
6829 let empty_recovery = self.empty_recovery_symbols();
6830 let outcomes = self.recognize_state_fast(
6831 atn,
6832 FastRecognizeRequest {
6833 state_number: start_state,
6834 stop_state,
6835 index: start_index,
6836 rule_start_index: start_index,
6837 decision_start_index: None,
6838 precedence,
6839 depth: 0,
6840 recovery_symbols: empty_recovery,
6841 recovery_state: None,
6842 },
6843 FastRecognizeScratch {
6844 predicate_context,
6845 visiting: &mut recognize_scratch.visiting,
6846 memo: &mut recognize_scratch.memo,
6847 expected: &mut expected,
6848 native_depth: 0,
6849 },
6850 );
6851 recognize_scratch.release_oversized_memo();
6852 self.fast_recognize_scratch = recognize_scratch;
6853 #[cfg(feature = "perf-counters")]
6854 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
6855 perf_counters::dump();
6856 perf_counters::reset();
6857 }
6858 let caller_follow =
6859 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
6860 let selected = {
6861 let arena = &self.recognition_arena;
6862 let input = &mut self.input;
6863 select_best_fast_outcome(
6864 outcomes.into_iter(),
6865 self.prediction_mode,
6866 caller_follow.as_deref(),
6867 |index| caller_follow_token_info_for_stream(input, index),
6868 arena,
6869 )
6870 };
6871 match selected {
6872 Some(mut outcome) => {
6873 if self.build_parse_trees {
6874 self.materialize_fast_outcome_nodes(&mut outcome);
6875 }
6876 Ok((outcome, expected))
6877 }
6878 None => Err(expected),
6879 }
6880 }
6881
6882 fn arena_recognized_node_tree(
6884 &mut self,
6885 node_id: RecognizedNodeId,
6886 track_alt_numbers: bool,
6887 track_context_alt_numbers: bool,
6888 ) -> Result<ParseTree, AntlrError> {
6889 let node = self.recognition_arena.node(node_id);
6890 match node {
6891 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
6892 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
6893 ArenaRecognizedNode::MissingToken { extra } => {
6894 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
6895 RecognitionExtra::MissingToken {
6896 token_type,
6897 at_index,
6898 text,
6899 } => (*token_type, *at_index as usize, text.clone()),
6900 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
6901 unreachable!("missing-token node must reference missing-token extra")
6902 }
6903 };
6904 let (line, column) = self
6905 .token_at(at_index)
6906 .map_or((0, 0), |token| (token.line(), token.column()));
6907 let token = self.insert_synthetic_token(token_type, text, line, column)?;
6908 Ok(self.error_tree(token))
6909 }
6910 ArenaRecognizedNode::Rule {
6911 rule_index,
6912 invoking_state,
6913 alt_number,
6914 start_index,
6915 stop_index,
6916 return_values,
6917 children,
6918 } => {
6919 let mut context = ParserRuleContext::with_child_capacity(
6920 rule_index as usize,
6921 invoking_state as isize,
6922 self.recognition_arena.sequence_len(children),
6923 );
6924 if track_alt_numbers {
6925 context.set_alt_number(alt_number as usize);
6926 }
6927 if track_context_alt_numbers {
6928 context.set_context_alt_number(alt_number as usize);
6929 }
6930 if let Some(extra) = return_values {
6931 let RecognitionExtra::ReturnValues(values) =
6932 self.recognition_arena.extra(extra)
6933 else {
6934 unreachable!("rule node must reference return-values extra");
6935 };
6936 for (name, value) in values {
6937 context.set_int_return(name.clone(), *value);
6938 }
6939 }
6940 if let Some(token) = self.token_id_at(start_index as usize) {
6941 self.set_context_start(&mut context, token);
6942 }
6943 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
6944 self.set_context_stop(&mut context, token);
6945 }
6946 let mut cursor = self
6947 .recognition_arena
6948 .fold_left_recursive_boundaries(children);
6949 while let Some(link) = self.recognition_arena.link(cursor) {
6950 let child = self.arena_recognized_node_tree(
6951 link.head,
6952 track_alt_numbers,
6953 track_context_alt_numbers,
6954 )?;
6955 self.tree.add_child(&mut context, child);
6956 cursor = link.tail;
6957 }
6958 Ok(self.rule_node(context))
6959 }
6960 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index, .. } => {
6961 Err(AntlrError::Unsupported(format!(
6962 "unfolded left-recursive boundary for rule {rule_index}"
6963 )))
6964 }
6965 }
6966 }
6967
6968 fn arena_recognized_node_tree_with_implicit_tokens(
6969 &mut self,
6970 node_id: RecognizedNodeId,
6971 ) -> Result<ParseTree, AntlrError> {
6972 let node = self.recognition_arena.node(node_id);
6973 match node {
6974 ArenaRecognizedNode::Rule {
6975 rule_index,
6976 invoking_state,
6977 start_index,
6978 stop_index,
6979 children,
6980 ..
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 let Some(token) = self.token_id_at(start_index as usize) {
6988 self.set_context_start(&mut context, token);
6989 }
6990 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
6991 self.set_context_stop(&mut context, token);
6992 }
6993 let children = self
6994 .recognition_arena
6995 .fold_left_recursive_boundaries(children);
6996 self.add_arena_implicit_token_children(
6997 &mut context,
6998 start_index as usize,
6999 stop_index.map(|index| index as usize),
7000 children,
7001 )?;
7002 Ok(self.rule_node(context))
7003 }
7004 _ => self.arena_recognized_node_tree(node_id, false, false),
7005 }
7006 }
7007
7008 fn add_arena_implicit_token_children(
7009 &mut self,
7010 context: &mut ParserRuleContext,
7011 start_index: usize,
7012 stop_index: Option<usize>,
7013 mut children: NodeSeqId,
7014 ) -> Result<(), AntlrError> {
7015 let mut cursor = Some(start_index);
7016 while let Some(link) = self.recognition_arena.link(children) {
7017 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
7018 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
7019 let child = self.arena_recognized_node_tree_with_implicit_tokens(link.head)?;
7020 self.tree.add_child(context, child);
7021 if let Some(child_stop) = child_stop {
7022 cursor = self.next_visible_after_token(child_stop);
7023 }
7024 } else {
7025 let child = self.arena_recognized_node_tree_with_implicit_tokens(link.head)?;
7026 self.tree.add_child(context, child);
7027 }
7028 children = link.tail;
7029 }
7030 if let Some(stop) = stop_index {
7031 self.add_visible_terminals_through(context, cursor, stop)?;
7032 }
7033 Ok(())
7034 }
7035
7036 fn add_visible_terminals_before(
7037 &mut self,
7038 context: &mut ParserRuleContext,
7039 cursor: &mut Option<usize>,
7040 before: usize,
7041 ) -> Result<(), AntlrError> {
7042 let Some(stop) = before.checked_sub(1) else {
7043 return Ok(());
7044 };
7045 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
7046 *cursor = next;
7047 Ok(())
7048 }
7049
7050 fn add_visible_terminals_through(
7051 &mut self,
7052 context: &mut ParserRuleContext,
7053 mut cursor: Option<usize>,
7054 stop: usize,
7055 ) -> Result<Option<usize>, AntlrError> {
7056 while let Some(index) = cursor {
7057 if index > stop {
7058 return Ok(Some(index));
7059 }
7060 let token = self
7061 .input
7062 .get_id(index)
7063 .ok_or_else(|| AntlrError::ParserError {
7064 line: 0,
7065 column: 0,
7066 message: format!("missing token at index {index}"),
7067 })?;
7068 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
7069 let child = self.terminal_tree(token);
7070 self.tree.add_child(context, child);
7071 if is_eof {
7072 return Ok(None);
7073 }
7074 cursor = self.next_visible_after_token(index);
7075 }
7076 Ok(None)
7077 }
7078
7079 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
7080 let next = self.input.next_visible_after(index);
7081 (next != index).then_some(next)
7082 }
7083
7084 pub fn parse_atn_rule_with_actions(
7091 &mut self,
7092 atn: &Atn,
7093 rule_index: usize,
7094 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7095 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
7096 }
7097
7098 pub fn parse_atn_rule_with_action_inits(
7106 &mut self,
7107 atn: &Atn,
7108 rule_index: usize,
7109 init_action_rules: &[usize],
7110 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7111 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
7112 }
7113
7114 pub fn parse_atn_rule_with_action_options(
7120 &mut self,
7121 atn: &Atn,
7122 rule_index: usize,
7123 init_action_rules: &[usize],
7124 track_alt_numbers: bool,
7125 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7126 self.parse_atn_rule_with_runtime_options(
7127 atn,
7128 rule_index,
7129 ParserRuntimeOptions {
7130 init_action_rules,
7131 track_alt_numbers,
7132 ..ParserRuntimeOptions::default()
7133 },
7134 )
7135 }
7136
7137 pub fn parse_atn_rule_with_runtime_options(
7144 &mut self,
7145 atn: &Atn,
7146 rule_index: usize,
7147 options: ParserRuntimeOptions<'_>,
7148 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7149 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
7150 }
7151
7152 pub fn parse_atn_rule_with_runtime_options_and_precedence(
7155 &mut self,
7156 atn: &Atn,
7157 rule_index: usize,
7158 precedence: i32,
7159 options: ParserRuntimeOptions<'_>,
7160 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7161 let ParserRuntimeOptions {
7162 init_action_rules,
7163 track_alt_numbers,
7164 track_context_alt_numbers,
7165 predicates,
7166 semantics,
7167 rule_args,
7168 member_actions,
7169 return_actions,
7170 unknown_predicate_policy,
7171 } = options;
7172 let capture_alt_numbers = track_alt_numbers || track_context_alt_numbers;
7173 if init_action_rules.is_empty()
7174 && !capture_alt_numbers
7175 && predicates.is_empty()
7176 && semantics.is_none()
7177 && rule_args.is_empty()
7178 && member_actions.is_empty()
7179 && return_actions.is_empty()
7180 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
7181 && !atn_has_observable_action_transitions(atn)
7182 && !self.semantic_hooks.observes_parser_decisions()
7183 && (!self.semantic_hooks.observes_parser_predicates()
7184 || !atn_has_predicate_transitions(atn))
7185 {
7186 return self
7187 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
7188 .map(|tree| (tree, Vec::new()));
7189 }
7190 if !self.semantic_hooks.observes_parser_decisions()
7191 && can_use_fast_predicate_recognizer(atn, &options)
7192 {
7193 self.unknown_predicate_policy = unknown_predicate_policy;
7194 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7195 let member_values = self.int_members.clone();
7196 let result = self
7197 .parse_atn_rule_with_precedence_inner(
7198 atn,
7199 rule_index,
7200 precedence,
7201 Some(FastPredicateContext {
7202 predicates,
7203 semantics,
7204 member_values: &member_values,
7205 }),
7206 )
7207 .map(|tree| (tree, Vec::new()));
7208 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
7209 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7210 }
7211 return result;
7212 }
7213 self.unknown_predicate_policy = unknown_predicate_policy;
7214 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7221 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7222 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7223 })?;
7224 let stop_state = atn
7225 .rule_to_stop_state()
7226 .get(rule_index)
7227 .filter(|state| *state != usize::MAX)
7228 .ok_or_else(|| {
7229 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7230 })?;
7231
7232 let start_index = self.current_visible_index();
7233 self.clear_prediction_diagnostics();
7234 self.reset_per_parse_caches();
7235 self.reset_recognition_arena();
7236 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
7237 let invoking_state = self.pending_invoking_states.pop();
7238 let local_int_arg = invoking_state
7239 .and_then(|state| usize::try_from(state).ok())
7240 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
7241 let mut visiting = BTreeSet::new();
7242 let mut memo = BTreeMap::new();
7243 let mut expected = ExpectedTokens::default();
7244 let member_values = self.int_members.clone();
7245 let return_values = BTreeMap::new();
7246 let outcomes = self.recognize_state(
7247 atn,
7248 RecognizeRequest {
7249 state_number: start_state,
7250 stop_state,
7251 index: start_index,
7252 rule_start_index: start_index,
7253 decision_start_index: None,
7254 init_action_rules: &init_action_rules,
7255 predicates,
7256 semantics,
7257 rule_args,
7258 member_actions,
7259 return_actions,
7260 local_int_arg,
7261 member_values,
7262 return_values,
7263 rule_alt_number: 0,
7264 track_alt_numbers: capture_alt_numbers,
7265 consumed_eof: false,
7266 committed_decision: false,
7267 precedence,
7268 depth: 0,
7269 recovery_symbols: BTreeSet::new(),
7270 recovery_state: None,
7271 },
7272 &mut visiting,
7273 &mut memo,
7274 &mut expected,
7275 );
7276 if let Some(error) = self.unknown_semantic_error() {
7277 self.report_token_source_errors();
7278 return Err(error);
7285 }
7286 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7289 let Some(outcome) = select_best_outcome(
7290 outcomes.into_iter(),
7291 self.prediction_mode,
7292 &self.recognition_arena,
7293 ) else {
7294 let error = self.recognition_error(rule_index, start_index, &expected);
7295 self.record_syntax_errors(1);
7296 self.report_token_source_errors();
7297 return Err(error);
7298 };
7299
7300 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7301 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7302 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7303 self.report_token_source_errors();
7304 let mut actions = outcome.actions;
7305 if init_action_rules.contains(&rule_index) {
7306 actions.insert(
7307 0,
7308 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
7309 );
7310 }
7311 let mut context =
7312 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
7313 if track_alt_numbers {
7314 context.set_alt_number(outcome.alt_number);
7315 }
7316 if track_context_alt_numbers {
7317 context.set_context_alt_number(outcome.alt_number);
7318 }
7319 for (name, value) in outcome.return_values {
7320 context.set_int_return(name, value);
7321 }
7322 if let Some(token) = self.token_id_at(start_index) {
7323 self.set_context_start(&mut context, token);
7324 }
7325 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
7326 self.set_context_stop(&mut context, token);
7327 }
7328 let live_root = if self.build_parse_trees {
7329 self.recognition_arena
7330 .fold_left_recursive_boundaries(outcome.nodes)
7331 } else {
7332 outcome.nodes
7333 };
7334 if self.build_parse_trees {
7335 let mut nodes = live_root;
7336 while let Some(link) = self.recognition_arena.link(nodes) {
7337 let child = self.arena_recognized_node_tree(
7338 link.head,
7339 track_alt_numbers,
7340 track_context_alt_numbers,
7341 )?;
7342 self.tree.add_child(&mut context, child);
7343 nodes = link.tail;
7344 }
7345 }
7346 self.finish_recognition_arena(live_root, outcome.diagnostics);
7347 self.input.seek(outcome.index);
7348
7349 let tree = self.rule_node(context);
7350 self.release_tree_scratch_if_idle();
7351 Ok((tree, actions))
7352 }
7353
7354 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
7361 let mut context = ParserRuleContext::new(rule_index, self.state());
7362 while self.la(1) != TOKEN_EOF {
7363 let token_type = self.la(1);
7364 let child = self.match_token(token_type)?;
7365 if self.build_parse_trees {
7366 self.tree.add_child(&mut context, child);
7367 }
7368 }
7369 if self.build_parse_trees {
7370 let child = self.match_eof()?;
7371 self.tree.add_child(&mut context, child);
7372 }
7373 let tree = self.rule_node(context);
7374 self.release_tree_scratch_if_idle();
7375 Ok(tree)
7376 }
7377
7378 fn recognition_error(
7381 &mut self,
7382 rule_index: usize,
7383 start_index: usize,
7384 expected: &ExpectedTokens,
7385 ) -> AntlrError {
7386 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
7387 self.input.seek(index);
7388 let current = self.input.lt(1);
7389 let line = current.as_ref().map(Token::line).unwrap_or_default();
7390 let column = current.as_ref().map(Token::column).unwrap_or_default();
7391 AntlrError::ParserError {
7392 line,
7393 column,
7394 message,
7395 }
7396 }
7397
7398 fn expected_error_message(
7400 &mut self,
7401 rule_index: usize,
7402 start_index: usize,
7403 expected: &ExpectedTokens,
7404 ) -> (usize, String) {
7405 let index = expected
7406 .index
7407 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
7408 .unwrap_or_else(|| self.input.index());
7409 self.input.seek(index);
7410 let current = self.input.lt(1);
7411 let message = if expected
7412 .no_viable
7413 .as_ref()
7414 .is_some_and(|no_viable| no_viable.error_index == index)
7415 {
7416 let start = expected
7417 .no_viable
7418 .as_ref()
7419 .map_or(start_index, |no_viable| no_viable.start_index);
7420 let text = display_input_text(&self.input.text(start, index));
7421 format!("no viable alternative at input '{text}'")
7422 } else if expected.symbols.is_empty() {
7423 if expected.index.is_some() {
7424 let found = current
7425 .as_ref()
7426 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
7427 if current
7428 .as_ref()
7429 .is_some_and(|token| token.token_type() == TOKEN_EOF)
7430 {
7431 format!(
7432 "missing {} at {found}",
7433 self.expected_symbols_display(&expected.symbols)
7434 )
7435 } else {
7436 format!("mismatched input {found}")
7437 }
7438 } else {
7439 format!("no viable alternative while parsing rule {rule_index}")
7440 }
7441 } else {
7442 format!(
7443 "mismatched input {} expecting {}",
7444 current
7445 .as_ref()
7446 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7447 self.expected_symbols_display(&expected.symbols)
7448 )
7449 };
7450 (index, message)
7451 }
7452
7453 fn child_rule_failure_recovery(
7456 &mut self,
7457 rule_index: usize,
7458 start_index: usize,
7459 sync_symbols: &BTreeSet<i32>,
7460 member_values: BTreeMap<usize, i64>,
7461 expected: &ExpectedTokens,
7462 ) -> Option<RecognizeOutcome> {
7463 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7464 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7465 let mut next_index = error_index;
7466 loop {
7467 let symbol = self.token_type_at(next_index);
7468 if sync_symbols.contains(&symbol) {
7469 if next_index == error_index {
7470 return None;
7471 }
7472 break;
7473 }
7474 if symbol == TOKEN_EOF {
7475 break;
7476 }
7477 let after = self.consume_index(next_index, symbol);
7478 if after == next_index {
7479 break;
7480 }
7481 next_index = after;
7482 }
7483 let mut nodes = NodeSeqId::EMPTY;
7484 let error = self.arena_token_node(error_index, true);
7485 self.arena_prepend(&mut nodes, error);
7486 let diagnostics = self
7487 .recognition_arena
7488 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7489 Some(RecognizeOutcome {
7490 index: next_index,
7491 consumed_eof: false,
7492 alt_number: 0,
7493 member_values,
7494 return_values: BTreeMap::new(),
7495 diagnostics,
7496 decisions: Vec::new(),
7497 actions: Vec::new(),
7498 nodes,
7499 })
7500 }
7501
7502 fn child_rule_failure_recovery_outcomes(
7505 &mut self,
7506 request: ChildRuleFailureRecovery<'_>,
7507 ) -> Vec<RecognizeOutcome> {
7508 let sync_symbols =
7509 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
7510 self.child_rule_failure_recovery(
7511 request.rule_index,
7512 request.start_index,
7513 &sync_symbols,
7514 request.member_values,
7515 request.expected,
7516 )
7517 .into_iter()
7518 .collect()
7519 }
7520
7521 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
7523 expected_symbols_display(symbols, self.vocabulary())
7524 }
7525
7526 fn single_token_deletion(
7529 &mut self,
7530 transition: ParserTransition<'_>,
7531 index: usize,
7532 max_token_type: i32,
7533 expected_symbols: &BTreeSet<i32>,
7534 ) -> Option<(ParserDiagnostic, usize, i32)> {
7535 let current_symbol = self.token_type_at(index);
7536 if current_symbol == TOKEN_EOF {
7537 return None;
7538 }
7539 let next_index = self.consume_index(index, current_symbol);
7540 if next_index == index {
7541 return None;
7542 }
7543 let next_symbol = self.token_type_at(next_index);
7544 if !transition.matches(next_symbol, 1, max_token_type) {
7545 return None;
7546 }
7547 let transition_expected = transition_expected_symbols(transition, max_token_type);
7548 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7549 &transition_expected
7550 } else {
7551 expected_symbols
7552 });
7553 let current = self.token_at(index);
7554 let message = format!(
7555 "extraneous input {} expecting {expected_display}",
7556 current
7557 .as_ref()
7558 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7559 );
7560 Some((
7561 diagnostic_for_token(current, message),
7562 next_index,
7563 next_symbol,
7564 ))
7565 }
7566
7567 fn current_token_deletion(
7570 &mut self,
7571 index: usize,
7572 expected_symbols: &BTreeSet<i32>,
7573 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
7574 if expected_symbols.is_empty() {
7575 return None;
7576 }
7577 let current_symbol = self.token_type_at(index);
7578 if current_symbol == TOKEN_EOF {
7579 return None;
7580 }
7581 let current = self.token_at(index);
7582 let message = format!(
7583 "extraneous input {} expecting {}",
7584 current
7585 .as_ref()
7586 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7587 self.expected_symbols_display(expected_symbols)
7588 );
7589 let diagnostic = diagnostic_for_token(current, message);
7590 let mut skipped = Vec::new();
7591 let mut cursor = index;
7592 loop {
7593 let symbol = self.token_type_at(cursor);
7594 if symbol == TOKEN_EOF {
7595 return None;
7596 }
7597 skipped.push(cursor);
7598 let next_index = self.consume_index(cursor, symbol);
7599 if next_index == cursor {
7600 return None;
7601 }
7602 let next_symbol = self.token_type_at(next_index);
7603 if expected_symbols.contains(&next_symbol) {
7604 return Some((diagnostic, next_index, skipped));
7605 }
7606 cursor = next_index;
7607 }
7608 }
7609
7610 fn single_token_insertion(
7614 &mut self,
7615 transition: ParserTransition<'_>,
7616 index: usize,
7617 max_token_type: i32,
7618 expected_symbols: &BTreeSet<i32>,
7619 follow_symbols: &BTreeSet<i32>,
7620 ) -> Option<(ParserDiagnostic, i32, String)> {
7621 let current_symbol = self.token_type_at(index);
7622 if !follow_symbols.contains(¤t_symbol) {
7623 return None;
7624 }
7625 let transition_expected = transition_expected_symbols(transition, max_token_type);
7626 let token_type = transition_expected.iter().next().copied()?;
7627 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7628 &transition_expected
7629 } else {
7630 expected_symbols
7631 });
7632 let mut token_symbols = BTreeSet::new();
7633 token_symbols.insert(token_type);
7634 let missing_token_display = self.expected_symbols_display(&token_symbols);
7635 let current = self.token_at(index);
7636 let message = format!(
7637 "missing {expected_display} at {}",
7638 current
7639 .as_ref()
7640 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7641 );
7642 let text = format!("<missing {missing_token_display}>");
7643 Some((
7644 diagnostic_for_token(current.as_ref(), message),
7645 token_type,
7646 text,
7647 ))
7648 }
7649
7650 fn fast_single_token_deletion_recovery(
7654 &mut self,
7655 recovery: FastRecoveryRequest<'_, '_>,
7656 predicate_context: Option<FastPredicateContext<'_>>,
7657 ) -> Vec<FastRecognizeOutcome> {
7658 let FastRecoveryRequest {
7659 atn,
7660 transition,
7661 expected_symbols,
7662 target,
7663 request,
7664 visiting,
7665 memo,
7666 expected,
7667 } = recovery;
7668 let FastRecognizeRequest {
7669 stop_state,
7670 index,
7671 rule_start_index,
7672 decision_start_index,
7673 precedence,
7674 depth,
7675 ..
7676 } = request;
7677 let Some((diagnostic, next_index, next_symbol)) =
7678 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
7679 else {
7680 return Vec::new();
7681 };
7682 let after_next = self.consume_index(next_index, next_symbol);
7683 let empty_recovery = self.empty_recovery_symbols();
7684 self.recognize_state_fast(
7685 atn,
7686 FastRecognizeRequest {
7687 state_number: target,
7688 stop_state,
7689 index: after_next,
7690 rule_start_index,
7691 decision_start_index,
7692 precedence,
7693 depth: depth + 1,
7694 recovery_symbols: empty_recovery,
7695 recovery_state: None,
7696 },
7697 FastRecognizeScratch {
7698 predicate_context,
7699 visiting,
7700 memo,
7701 expected,
7702 native_depth: 0,
7703 },
7704 )
7705 .into_iter()
7706 .map(|mut outcome| {
7707 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
7708 outcome.diagnostics = self
7709 .recognition_arena
7710 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7711 if self.fast_token_nodes_enabled {
7712 let token = self.arena_token_node(next_index, false);
7713 self.defer_fast_outcome_node(&mut outcome, token);
7714 let error = self.arena_token_node(index, true);
7715 self.defer_fast_outcome_node(&mut outcome, error);
7716 }
7717 outcome
7718 })
7719 .collect()
7720 }
7721
7722 fn fast_single_token_insertion_recovery(
7726 &mut self,
7727 recovery: FastRecoveryRequest<'_, '_>,
7728 predicate_context: Option<FastPredicateContext<'_>>,
7729 ) -> Vec<FastRecognizeOutcome> {
7730 let FastRecoveryRequest {
7731 atn,
7732 transition,
7733 expected_symbols,
7734 target,
7735 request,
7736 visiting,
7737 memo,
7738 expected,
7739 } = recovery;
7740 let FastRecognizeRequest {
7741 stop_state,
7742 index,
7743 rule_start_index,
7744 decision_start_index,
7745 precedence,
7746 depth,
7747 ..
7748 } = request;
7749 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
7750 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
7751 transition,
7752 index,
7753 atn.max_token_type(),
7754 &expected_symbols,
7755 &follow_symbols,
7756 ) else {
7757 return Vec::new();
7758 };
7759 let empty_recovery = self.empty_recovery_symbols();
7760 self.recognize_state_fast(
7761 atn,
7762 FastRecognizeRequest {
7763 state_number: target,
7764 stop_state,
7765 index,
7766 rule_start_index,
7767 decision_start_index,
7768 precedence,
7769 depth: depth + 1,
7770 recovery_symbols: empty_recovery,
7771 recovery_state: None,
7772 },
7773 FastRecognizeScratch {
7774 predicate_context,
7775 visiting,
7776 memo,
7777 expected,
7778 native_depth: 0,
7779 },
7780 )
7781 .into_iter()
7782 .map(|mut outcome| {
7783 outcome.diagnostics = self
7784 .recognition_arena
7785 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7786 let missing = self.arena_missing_token_node(token_type, index, text.clone());
7787 self.defer_fast_outcome_node(&mut outcome, missing);
7788 outcome
7789 })
7790 .collect()
7791 }
7792
7793 fn fast_current_token_deletion_recovery(
7796 &mut self,
7797 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
7798 predicate_context: Option<FastPredicateContext<'_>>,
7799 ) -> Vec<FastRecognizeOutcome> {
7800 let FastCurrentTokenDeletionRequest {
7801 atn,
7802 expected_symbols,
7803 mut request,
7804 visiting,
7805 memo,
7806 expected,
7807 } = recovery;
7808 if request.index == request.rule_start_index {
7809 return Vec::new();
7810 }
7811 let Some((diagnostic, next_index, skipped)) =
7812 self.current_token_deletion(request.index, &expected_symbols)
7813 else {
7814 return Vec::new();
7815 };
7816 request.state_number = request.recovery_state.unwrap_or(request.state_number);
7817 request.index = next_index;
7818 request.depth += 1;
7819 request.recovery_state = None;
7820 self.recognize_state_fast(
7821 atn,
7822 request,
7823 FastRecognizeScratch {
7824 predicate_context,
7825 visiting,
7826 memo,
7827 expected,
7828 native_depth: 0,
7829 },
7830 )
7831 .into_iter()
7832 .map(|mut outcome| {
7833 outcome.diagnostics = self
7834 .recognition_arena
7835 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7836 for index in skipped.iter().rev() {
7837 let error = self.arena_token_node(*index, true);
7838 self.defer_fast_outcome_node(&mut outcome, error);
7839 }
7840 outcome
7841 })
7842 .collect()
7843 }
7844
7845 fn fast_child_rule_failure_recovery(
7848 &mut self,
7849 rule_index: usize,
7850 start_index: usize,
7851 sync_symbols: &BTreeSet<i32>,
7852 expected: &ExpectedTokens,
7853 ) -> Option<FastRecognizeOutcome> {
7854 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7855 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7856 let mut next_index = error_index;
7857 loop {
7858 let symbol = self.token_type_at(next_index);
7859 if sync_symbols.contains(&symbol) {
7860 if next_index == error_index {
7861 return None;
7862 }
7863 break;
7864 }
7865 if symbol == TOKEN_EOF {
7866 break;
7867 }
7868 let after = self.consume_index(next_index, symbol);
7869 if after == next_index {
7870 break;
7871 }
7872 next_index = after;
7873 }
7874 let diagnostics = self
7875 .recognition_arena
7876 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7877 let mut nodes = NodeSeqId::EMPTY;
7878 if self.fast_token_nodes_enabled {
7879 let error = self.arena_token_node(error_index, true);
7880 self.arena_prepend(&mut nodes, error);
7881 }
7882 Some(FastRecognizeOutcome {
7883 index: next_index,
7884 consumed_eof: false,
7885 diagnostics,
7886 deferred_nodes: FastDeferredNodeId::EMPTY,
7887 nodes,
7888 })
7889 }
7890
7891 fn fast_child_rule_failure_recovery_outcomes(
7894 &mut self,
7895 request: FastChildRuleFailureRecoveryRequest<'_>,
7896 ) -> Vec<FastRecognizeOutcome> {
7897 let FastChildRuleFailureRecoveryRequest {
7898 atn,
7899 rule_index,
7900 start_index,
7901 follow_state,
7902 stop_state,
7903 expected,
7904 } = request;
7905 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
7906 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
7907 .into_iter()
7908 .collect()
7909 }
7910
7911 fn defer_fast_outcome_node(
7912 &mut self,
7913 outcome: &mut FastRecognizeOutcome,
7914 node: RecognizedNodeId,
7915 ) {
7916 if outcome.deferred_nodes.is_empty() {
7917 self.arena_prepend(&mut outcome.nodes, node);
7918 return;
7919 }
7920 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
7921 let fragment = self.recognition_arena.deferred_fragment(fragment);
7922 outcome.deferred_nodes = self
7923 .recognition_arena
7924 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
7925 }
7926
7927 fn materialize_fast_deferred_nodes(
7928 &mut self,
7929 root: FastDeferredNodeId,
7930 initial_suffix: NodeSeqId,
7931 ) -> NodeSeqId {
7932 if root.is_empty() {
7933 return initial_suffix;
7934 }
7935
7936 enum Frame {
7937 Visit(FastDeferredNodeId),
7938 ContinuePrefix(FastDeferredNodeId),
7939 FinishRule {
7940 rule: FastDeferredRule,
7941 parent_suffix: NodeSeqId,
7942 },
7943 }
7944
7945 let mut result = initial_suffix;
7946 let mut pending = Vec::with_capacity(16);
7947 pending.push(Frame::Visit(root));
7948 let mut fragment_nodes = Vec::new();
7949 while let Some(frame) = pending.pop() {
7950 match frame {
7951 Frame::Visit(deferred) => {
7952 if deferred.is_empty() {
7953 continue;
7954 }
7955
7956 match self.recognition_arena.deferred_node(deferred) {
7957 FastDeferredNode::Fragment(sequence) => {
7958 fragment_nodes.clear();
7959 fragment_nodes.extend(self.recognition_arena.iter(sequence));
7960 while let Some(node) = fragment_nodes.pop() {
7961 self.arena_prepend(&mut result, node);
7962 }
7963 }
7964 FastDeferredNode::Rule(rule) => {
7965 let rule = self.recognition_arena.deferred_rule(rule);
7966 let parent_suffix = result;
7967 result = rule.children;
7968 pending.push(Frame::FinishRule {
7969 rule,
7970 parent_suffix,
7971 });
7972 pending.push(Frame::Visit(rule.deferred_children));
7973 }
7974 FastDeferredNode::Concat {
7975 prefix,
7976 suffix: deferred_suffix,
7977 } => {
7978 pending.push(Frame::ContinuePrefix(prefix));
7979 pending.push(Frame::Visit(deferred_suffix));
7980 }
7981 }
7982 }
7983 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
7984 Frame::FinishRule {
7985 rule,
7986 parent_suffix,
7987 } => {
7988 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
7989 rule_index: rule.rule_index,
7990 invoking_state: rule.invoking_state,
7991 alt_number: 0,
7992 start_index: rule.start_index,
7993 stop_index: rule.stop_index,
7994 return_values: None,
7995 children: result,
7996 });
7997 result = parent_suffix;
7998 self.arena_prepend(&mut result, node);
7999 }
8000 }
8001 }
8002 result
8003 }
8004
8005 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) {
8006 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
8007 outcome.nodes = self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
8008 }
8009
8010 fn recognize_repetition_fast(
8013 &mut self,
8014 atn: &Atn,
8015 request: &FastRecognizeRequest,
8016 shape: FastRepetitionShape,
8017 scratch: FastRecognizeScratch<'_, '_>,
8018 ) -> Vec<FastRecognizeOutcome> {
8019 let FastRecognizeScratch {
8020 predicate_context,
8021 visiting,
8022 memo,
8023 expected,
8024 native_depth,
8025 } = scratch;
8026 let lookahead = if self.fast_first_set_prefilter {
8027 atn.state(request.state_number).and_then(|state| {
8028 state
8029 .rule_index()
8030 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8031 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
8032 })
8033 } else {
8034 None
8035 };
8036 let mut work = Vec::with_capacity(2);
8037 push_fast_repetition_work(
8038 &mut work,
8039 shape,
8040 FastRepetitionPath {
8041 index: request.index,
8042 deferred_nodes: FastDeferredNodeId::EMPTY,
8043 diagnostics: DiagnosticSeqId::EMPTY,
8044 consumed_eof: false,
8045 },
8046 lookahead.as_deref(),
8047 self.token_type_at(request.index),
8048 );
8049 let mut coordinates = FastRepetitionCoordinates::new(request.index);
8050 let mut outcomes = Vec::new();
8051 while let Some(item) = work.pop() {
8052 match item {
8053 FastRepetitionWork::Enter(path) => {
8054 if !coordinates.insert_entered(path) {
8055 continue;
8056 }
8057 let body_outcomes = self.recognize_state_fast(
8058 atn,
8059 FastRecognizeRequest {
8060 state_number: shape.enter_target,
8061 stop_state: shape.body_stop_state,
8062 index: path.index,
8063 rule_start_index: request.rule_start_index,
8064 decision_start_index: request.decision_start_index,
8065 precedence: request.precedence,
8066 depth: request.depth.saturating_add(1),
8067 recovery_symbols: Rc::clone(&request.recovery_symbols),
8068 recovery_state: request.recovery_state,
8069 },
8070 FastRecognizeScratch {
8071 predicate_context,
8072 visiting: &mut *visiting,
8073 memo: &mut *memo,
8074 expected: &mut *expected,
8075 native_depth: native_depth + 1,
8076 },
8077 );
8078 for body in body_outcomes.into_iter().rev() {
8079 if body.index <= path.index {
8083 continue;
8084 }
8085 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
8086 let body_nodes = self
8087 .recognition_arena
8088 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
8089 let deferred_nodes = self
8090 .recognition_arena
8091 .concat_deferred_nodes(path.deferred_nodes, body_nodes);
8092 let next_path = FastRepetitionPath {
8093 index: body.index,
8094 deferred_nodes,
8095 diagnostics: self
8096 .recognition_arena
8097 .concat_diagnostics(path.diagnostics, body.diagnostics),
8098 consumed_eof: path.consumed_eof || body.consumed_eof,
8099 };
8100 let symbol = self.token_type_at(next_path.index);
8101 push_fast_repetition_work(
8102 &mut work,
8103 shape,
8104 next_path,
8105 lookahead.as_deref(),
8106 symbol,
8107 );
8108 }
8109 }
8110 FastRepetitionWork::Exit(path) => {
8111 if !coordinates.insert_exited(path) {
8112 continue;
8113 }
8114 let suffixes = self.recognize_state_fast(
8115 atn,
8116 FastRecognizeRequest {
8117 state_number: shape.exit_target,
8118 stop_state: request.stop_state,
8119 index: path.index,
8120 rule_start_index: request.rule_start_index,
8121 decision_start_index: request.decision_start_index,
8122 precedence: request.precedence,
8123 depth: request.depth.saturating_add(1),
8124 recovery_symbols: Rc::clone(&request.recovery_symbols),
8125 recovery_state: request.recovery_state,
8126 },
8127 FastRecognizeScratch {
8128 predicate_context,
8129 visiting: &mut *visiting,
8130 memo: &mut *memo,
8131 expected: &mut *expected,
8132 native_depth: native_depth + 1,
8133 },
8134 );
8135 for mut outcome in suffixes {
8136 outcome.deferred_nodes = self
8137 .recognition_arena
8138 .concat_deferred_nodes(path.deferred_nodes, outcome.deferred_nodes);
8139 outcome.diagnostics = self
8140 .recognition_arena
8141 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
8142 outcome.consumed_eof |= path.consumed_eof;
8143 outcomes.push(outcome);
8144 }
8145 }
8146 }
8147 }
8148 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8149 outcomes
8150 }
8151
8152 fn recognize_state_fast(
8155 &mut self,
8156 atn: &Atn,
8157 request: FastRecognizeRequest,
8158 scratch: FastRecognizeScratch<'_, '_>,
8159 ) -> Vec<FastRecognizeOutcome> {
8160 if scratch.native_depth != 0 && scratch.native_depth < FAST_RECOGNIZE_STACK_CHECK_INTERVAL {
8161 return self.recognize_state_fast_inner(atn, request, scratch);
8162 }
8163 self.recognize_state_fast_checked(atn, request, scratch)
8164 }
8165
8166 #[inline(never)]
8167 fn recognize_state_fast_checked(
8168 &mut self,
8169 atn: &Atn,
8170 request: FastRecognizeRequest,
8171 mut scratch: FastRecognizeScratch<'_, '_>,
8172 ) -> Vec<FastRecognizeOutcome> {
8173 scratch.native_depth = 1;
8174 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, || {
8175 self.recognize_state_fast_inner(atn, request, scratch)
8176 })
8177 }
8178
8179 #[allow(clippy::too_many_lines)]
8180 fn recognize_state_fast_inner(
8181 &mut self,
8182 atn: &Atn,
8183 request: FastRecognizeRequest,
8184 scratch: FastRecognizeScratch<'_, '_>,
8185 ) -> Vec<FastRecognizeOutcome> {
8186 #[cfg(feature = "perf-counters")]
8187 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
8188 let FastRecognizeScratch {
8189 predicate_context,
8190 visiting,
8191 memo,
8192 expected,
8193 native_depth,
8194 } = scratch;
8195 let FastRecognizeRequest {
8196 mut state_number,
8197 stop_state,
8198 mut index,
8199 rule_start_index,
8200 decision_start_index,
8201 precedence,
8202 mut depth,
8203 recovery_symbols,
8204 recovery_state,
8205 } = request;
8206 let max_token_type = atn.max_token_type();
8207 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
8226 let mut inline_consumed_eof = false;
8227 loop {
8228 if depth > RECOGNITION_DEPTH_LIMIT {
8229 return Vec::new();
8230 }
8231 if state_number == stop_state {
8232 let mut nodes = NodeSeqId::EMPTY;
8233 if self.fast_token_nodes_enabled {
8234 for token_index in inline_consumed_tokens.iter().rev() {
8235 let token = self.arena_token_node(*token_index, false);
8236 self.arena_prepend(&mut nodes, token);
8237 }
8238 }
8239 return vec![FastRecognizeOutcome {
8240 index,
8241 consumed_eof: inline_consumed_eof,
8242 diagnostics: DiagnosticSeqId::EMPTY,
8243 deferred_nodes: FastDeferredNodeId::EMPTY,
8244 nodes,
8245 }];
8246 }
8247 let Some(state) = atn.state(state_number) else {
8248 return Vec::new();
8249 };
8250 let transitions = state.transitions();
8251 if transitions.len() == 1 && !state.precedence_rule_decision() {
8252 let transition = transitions
8253 .first()
8254 .expect("single transition checked above");
8255 let transition_kind = transition.kind();
8256 let target = transition.target();
8257 match transition_kind {
8258 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
8259 if left_recursive_boundary(atn, state, target).is_none() =>
8260 {
8261 #[cfg(feature = "perf-counters")]
8262 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8263 state_number = target;
8264 depth += 1;
8265 continue;
8266 }
8267 ParserTransitionKind::Predicate
8268 if left_recursive_boundary(atn, state, target).is_none() =>
8269 {
8270 #[cfg(feature = "perf-counters")]
8271 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8272 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
8273 {
8274 record_predicate_no_viable(expected, decision_start_index, index);
8275 return Vec::new();
8276 }
8277 state_number = target;
8278 depth += 1;
8279 continue;
8280 }
8281 ParserTransitionKind::Precedence
8282 if packed_i32(transition.arg0()) >= precedence
8283 && left_recursive_boundary(atn, state, target).is_none() =>
8284 {
8285 #[cfg(feature = "perf-counters")]
8286 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8287 state_number = target;
8288 depth += 1;
8289 continue;
8290 }
8291 ParserTransitionKind::Atom
8301 | ParserTransitionKind::Range
8302 | ParserTransitionKind::Set
8303 | ParserTransitionKind::NotSet
8304 | ParserTransitionKind::Wildcard
8305 if !self.fast_recovery_enabled =>
8306 {
8307 let symbol = self.token_type_at(index);
8308 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
8309 #[cfg(feature = "perf-counters")]
8310 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
8311 if self.fast_token_nodes_enabled {
8312 inline_consumed_tokens.push(index);
8313 }
8314 inline_consumed_eof |= symbol == TOKEN_EOF;
8315 index = self.consume_index(index, symbol);
8316 state_number = target;
8317 depth += 1;
8318 continue;
8319 }
8320 }
8323 _ => {}
8324 }
8325 }
8326 break;
8327 }
8328 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
8332 let Some(state) = atn.state(state_number) else {
8333 return Vec::new();
8334 };
8335 let transitions = state.transitions();
8336 let transition_count = transitions.len();
8337 if !self.fast_recovery_enabled
8338 && let Some(shape) = fast_repetition_shape(atn, state)
8339 {
8340 let mut outcomes = self.recognize_repetition_fast(
8341 atn,
8342 &FastRecognizeRequest {
8343 state_number,
8344 stop_state,
8345 index,
8346 rule_start_index,
8347 decision_start_index,
8348 precedence,
8349 depth,
8350 recovery_symbols: Rc::clone(&recovery_symbols),
8351 recovery_state,
8352 },
8353 shape,
8354 FastRecognizeScratch {
8355 predicate_context,
8356 visiting: &mut *visiting,
8357 memo: &mut *memo,
8358 expected: &mut *expected,
8359 native_depth: native_depth + 1,
8360 },
8361 );
8362 if inline_pending {
8363 for outcome in &mut outcomes {
8364 outcome.consumed_eof |= inline_consumed_eof;
8365 if self.fast_token_nodes_enabled {
8366 for token_index in inline_consumed_tokens.iter().rev() {
8367 let token = self.arena_token_node(*token_index, false);
8368 self.defer_fast_outcome_node(outcome, token);
8369 }
8370 }
8371 }
8372 }
8373 return outcomes;
8374 }
8375 let key = if self.fast_recovery_enabled {
8385 FastRecognizeKey {
8386 state_number,
8387 stop_state,
8388 index,
8389 rule_start_index,
8390 decision_start_index,
8391 precedence,
8392 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
8393 recovery_state,
8394 }
8395 } else {
8396 FastRecognizeKey {
8397 state_number,
8398 stop_state,
8399 index,
8400 rule_start_index: 0,
8401 decision_start_index: None,
8402 precedence,
8403 recovery_symbols_id: 0,
8404 recovery_state: None,
8405 }
8406 };
8407 let memo_lookup_enabled = self.fast_recovery_enabled
8412 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
8413 if memo_lookup_enabled {
8414 if let Some(outcomes) = memo.get(&key) {
8415 #[cfg(feature = "perf-counters")]
8416 {
8417 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
8418 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
8419 }
8420 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
8424 let inline_eof = inline_consumed_eof;
8425 let inline_tokens = &inline_consumed_tokens;
8426 return outcomes
8427 .iter()
8428 .copied()
8429 .map(|mut outcome| {
8430 if inline_eof {
8431 outcome.consumed_eof = true;
8432 }
8433 if self.fast_token_nodes_enabled {
8434 for token_index in inline_tokens.iter().rev() {
8435 let token = self.arena_token_node(*token_index, false);
8436 self.defer_fast_outcome_node(&mut outcome, token);
8437 }
8438 }
8439 outcome
8440 })
8441 .collect();
8442 }
8443 return outcomes.to_vec();
8444 }
8445 #[cfg(feature = "perf-counters")]
8446 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
8447 }
8448
8449 let needs_cycle_guard = if self.fast_recovery_enabled {
8454 transitions.iter().any(ParserTransition::is_epsilon)
8455 } else {
8456 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
8457 };
8458 #[cfg(feature = "perf-counters")]
8459 if needs_cycle_guard {
8460 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
8461 } else {
8462 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
8463 match state
8464 .transitions()
8465 .first()
8466 .expect("single-transition path requires one transition")
8467 .data()
8468 {
8469 Transition::Rule { .. } => {
8470 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
8471 }
8472 Transition::Atom { .. }
8473 | Transition::Range { .. }
8474 | Transition::Set { .. }
8475 | Transition::NotSet { .. }
8476 | Transition::Wildcard { .. } => {
8477 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
8478 }
8479 _ => {
8480 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
8481 }
8482 }
8483 }
8484 let has_inserted_cycle_guard = if needs_cycle_guard {
8485 if !visiting.insert(key.clone()) {
8486 #[cfg(feature = "perf-counters")]
8487 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
8488 return Vec::new();
8489 }
8490 true
8491 } else {
8492 false
8493 };
8494 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
8495 Some(index)
8496 } else {
8497 decision_start_index
8498 };
8499 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
8500 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
8501 } else {
8502 (Rc::clone(&recovery_symbols), recovery_state)
8503 };
8504
8505 let lookahead_filter = if transition_count > 1
8524 && self.fast_first_set_prefilter
8525 && !state.precedence_rule_decision()
8526 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
8527 {
8528 state
8529 .rule_index()
8530 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8531 .map(|rule_stop| {
8532 let symbol = self.token_type_at(index);
8533 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
8534 (symbol, entry)
8535 })
8536 } else {
8537 None
8538 };
8539 let ll1_only_alt: Option<usize> = if transition_count > 1
8548 && let Some((symbol, entry)) = lookahead_filter.as_ref()
8549 {
8550 let key = (state.state_number(), *symbol);
8551 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
8552 cached
8553 } else {
8554 let result = ll1_unique_alt(entry, *symbol);
8555 self.ll1_decision_cache.insert(key, result);
8556 result
8557 }
8558 } else {
8559 None
8560 };
8561 let lookahead_filter = lookahead_filter.as_ref();
8562 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
8568 for (transition_index, transition) in transitions.iter().enumerate() {
8569 if let Some(alt) = ll1_only_alt {
8570 if alt != transition_index {
8572 continue;
8573 }
8574 }
8575 let transition_kind = transition.kind();
8576 if ll1_only_alt.is_none()
8577 && should_skip_via_lookahead(
8578 transition_kind,
8579 transition_index,
8580 lookahead_filter,
8581 index,
8582 self.fast_recovery_enabled,
8583 expected,
8584 )
8585 {
8586 continue;
8587 }
8588 let target = transition.target();
8589 match transition_kind {
8590 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
8591 #[cfg(feature = "perf-counters")]
8592 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8593 let boundary = left_recursive_boundary(atn, state, target);
8594 outcomes.extend(
8595 self.recognize_state_fast(
8596 atn,
8597 FastRecognizeRequest {
8598 state_number: target,
8599 stop_state,
8600 index,
8601 rule_start_index,
8602 decision_start_index: next_decision_start_index,
8603 precedence,
8604 depth: depth + 1,
8605 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8606 recovery_state: epsilon_recovery_state,
8607 },
8608 FastRecognizeScratch {
8609 predicate_context,
8610 visiting,
8611 memo,
8612 expected,
8613 native_depth: native_depth + 1,
8614 },
8615 )
8616 .into_iter()
8617 .map(|mut outcome| {
8618 if let Some(rule_index) = boundary {
8619 let boundary = self.arena_boundary_node(rule_index, 0);
8620 self.defer_fast_outcome_node(&mut outcome, boundary);
8621 }
8622 outcome
8623 }),
8624 );
8625 }
8626 ParserTransitionKind::Predicate => {
8627 #[cfg(feature = "perf-counters")]
8628 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8629 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
8630 let boundary = left_recursive_boundary(atn, state, target);
8631 outcomes.extend(
8632 self.recognize_state_fast(
8633 atn,
8634 FastRecognizeRequest {
8635 state_number: target,
8636 stop_state,
8637 index,
8638 rule_start_index,
8639 decision_start_index: next_decision_start_index,
8640 precedence,
8641 depth: depth + 1,
8642 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8643 recovery_state: epsilon_recovery_state,
8644 },
8645 FastRecognizeScratch {
8646 predicate_context,
8647 visiting,
8648 memo,
8649 expected,
8650 native_depth: native_depth + 1,
8651 },
8652 )
8653 .into_iter()
8654 .map(|mut outcome| {
8655 if let Some(rule_index) = boundary {
8656 let boundary = self.arena_boundary_node(rule_index, 0);
8657 self.defer_fast_outcome_node(&mut outcome, boundary);
8658 }
8659 outcome
8660 }),
8661 );
8662 } else {
8663 record_predicate_no_viable(expected, next_decision_start_index, index);
8664 }
8665 }
8666 ParserTransitionKind::Precedence => {
8667 let transition_precedence = packed_i32(transition.arg0());
8668 if transition_precedence >= precedence {
8669 let boundary = left_recursive_boundary(atn, state, target);
8670 outcomes.extend(
8671 self.recognize_state_fast(
8672 atn,
8673 FastRecognizeRequest {
8674 state_number: target,
8675 stop_state,
8676 index,
8677 rule_start_index,
8678 decision_start_index: next_decision_start_index,
8679 precedence,
8680 depth: depth + 1,
8681 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8682 recovery_state: epsilon_recovery_state,
8683 },
8684 FastRecognizeScratch {
8685 predicate_context,
8686 visiting,
8687 memo,
8688 expected,
8689 native_depth: native_depth + 1,
8690 },
8691 )
8692 .into_iter()
8693 .map(|mut outcome| {
8694 if let Some(rule_index) = boundary {
8695 let boundary = self.arena_boundary_node(rule_index, 0);
8696 self.defer_fast_outcome_node(&mut outcome, boundary);
8697 }
8698 outcome
8699 }),
8700 );
8701 }
8702 }
8703 ParserTransitionKind::Rule => {
8704 let rule_index = transition.arg0() as usize;
8705 let follow_state = transition.arg1() as usize;
8706 let rule_precedence = packed_i32(transition.arg2());
8707 #[cfg(feature = "perf-counters")]
8708 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
8709 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
8710 continue;
8711 };
8712 let symbol = self.token_type_at(index);
8724 if self.fast_first_set_prefilter {
8725 let first = self.cached_rule_first_set(atn, target, child_stop);
8738 if should_skip_rule_via_first_set(
8739 &first,
8740 symbol,
8741 self.fast_recovery_enabled,
8742 index,
8743 expected,
8744 ) {
8745 continue;
8746 }
8747 }
8748 let expected_before_child =
8749 self.fast_recovery_enabled.then(|| expected.clone());
8750 let mut children = self.recognize_state_fast(
8751 atn,
8752 FastRecognizeRequest {
8753 state_number: target,
8754 stop_state: child_stop,
8755 index,
8756 rule_start_index: index,
8757 decision_start_index: None,
8758 precedence: rule_precedence,
8759 depth: depth + 1,
8760 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8761 recovery_state: epsilon_recovery_state,
8762 },
8763 FastRecognizeScratch {
8764 predicate_context,
8765 visiting,
8766 memo,
8767 expected,
8768 native_depth: native_depth + 1,
8769 },
8770 );
8771 if children.is_empty() && self.fast_recovery_enabled {
8772 children = self.fast_child_rule_failure_recovery_outcomes(
8773 FastChildRuleFailureRecoveryRequest {
8774 atn,
8775 rule_index,
8776 start_index: index,
8777 follow_state,
8778 stop_state,
8779 expected,
8780 },
8781 );
8782 }
8783 if let Some(expected_before_child) = expected_before_child {
8784 if children
8785 .iter()
8786 .any(|child| child.diagnostics.is_empty() && child.index > index)
8787 {
8788 *expected = expected_before_child;
8789 }
8790 }
8791 for child in children {
8792 let child_index = child.index;
8793 let child_consumed_eof = child.consumed_eof;
8794 let child_diagnostics = child.diagnostics;
8795 let empty_recovery = self.empty_recovery_symbols();
8796 let follow_outcomes = self.recognize_state_fast(
8797 atn,
8798 FastRecognizeRequest {
8799 state_number: follow_state,
8800 stop_state,
8801 index: child_index,
8802 rule_start_index,
8803 decision_start_index: next_decision_start_index,
8804 precedence,
8805 depth: depth + 1,
8806 recovery_symbols: empty_recovery,
8807 recovery_state: None,
8808 },
8809 FastRecognizeScratch {
8810 predicate_context,
8811 visiting,
8812 memo,
8813 expected,
8814 native_depth: native_depth + 1,
8815 },
8816 );
8817 if follow_outcomes.is_empty() {
8818 continue;
8819 }
8820 let child_stop_index =
8821 self.rule_stop_token_index(child_index, child_consumed_eof);
8822 let child_node = self.build_parse_trees.then(|| {
8823 self.recognition_arena.deferred_rule_node(FastDeferredRule {
8824 rule_index: u32::try_from(rule_index)
8825 .expect("rule index fits in u32"),
8826 invoking_state: i32::try_from(invoking_state_number(state_number))
8827 .expect("invoking state fits in i32"),
8828 start_index: u32::try_from(index)
8829 .expect("rule start index fits in u32"),
8830 stop_index: child_stop_index.map(|stop_index| {
8831 u32::try_from(stop_index).expect("rule stop index fits in u32")
8832 }),
8833 deferred_children: child.deferred_nodes,
8834 children: child.nodes,
8835 })
8836 });
8837 let child_diags_empty = child_diagnostics.is_empty();
8838 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
8839 outcome.consumed_eof |= child_consumed_eof;
8840 if !child_diags_empty {
8843 outcome.diagnostics = self
8844 .recognition_arena
8845 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
8846 }
8847 if let Some(child_node) = child_node {
8848 outcome.deferred_nodes = self
8849 .recognition_arena
8850 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
8851 }
8852 outcome
8853 }));
8854 }
8855 }
8856 ParserTransitionKind::Atom
8857 | ParserTransitionKind::Range
8858 | ParserTransitionKind::Set
8859 | ParserTransitionKind::NotSet
8860 | ParserTransitionKind::Wildcard => {
8861 #[cfg(feature = "perf-counters")]
8862 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
8863 let symbol = self.token_type_at(index);
8864 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
8865 let next_index = self.consume_index(index, symbol);
8866 let empty_recovery = self.empty_recovery_symbols();
8867 outcomes.extend(
8868 self.recognize_state_fast(
8869 atn,
8870 FastRecognizeRequest {
8871 state_number: target,
8872 stop_state,
8873 index: next_index,
8874 rule_start_index,
8875 decision_start_index: next_decision_start_index,
8876 precedence,
8877 depth: depth + 1,
8878 recovery_symbols: empty_recovery,
8879 recovery_state: None,
8880 },
8881 FastRecognizeScratch {
8882 predicate_context,
8883 visiting,
8884 memo,
8885 expected,
8886 native_depth: native_depth + 1,
8887 },
8888 )
8889 .into_iter()
8890 .map(|mut outcome| {
8891 outcome.consumed_eof |= symbol == TOKEN_EOF;
8892 if self.fast_token_nodes_enabled {
8893 let token = self.arena_token_node(index, false);
8894 self.defer_fast_outcome_node(&mut outcome, token);
8895 }
8896 outcome
8897 }),
8898 );
8899 } else {
8900 if !self.fast_recovery_enabled {
8901 continue;
8909 }
8910 let expected_symbols = fast_recovery_expected_symbols(
8911 self,
8912 atn,
8913 state.state_number(),
8914 &recovery_symbols,
8915 );
8916 if expected_symbols.contains(&symbol) {
8917 continue;
8918 }
8919 {
8920 expected.record_transition(index, transition, max_token_type);
8921 record_no_viable_if_ambiguous(
8922 expected,
8923 next_decision_start_index,
8924 index,
8925 );
8926 outcomes.extend(self.fast_single_token_deletion_recovery(
8927 FastRecoveryRequest {
8928 atn,
8929 transition,
8930 expected_symbols: Rc::clone(&expected_symbols),
8931 target,
8932 request: FastRecognizeRequest {
8933 state_number,
8934 stop_state,
8935 index,
8936 rule_start_index,
8937 decision_start_index,
8938 precedence,
8939 depth,
8940 recovery_symbols: Rc::clone(&recovery_symbols),
8941 recovery_state,
8942 },
8943 visiting,
8944 memo,
8945 expected,
8946 },
8947 predicate_context,
8948 ));
8949 if !state_is_left_recursive_rule(atn, state) {
8950 outcomes.extend(self.fast_single_token_insertion_recovery(
8951 FastRecoveryRequest {
8952 atn,
8953 transition,
8954 expected_symbols: Rc::clone(&expected_symbols),
8955 target,
8956 request: FastRecognizeRequest {
8957 state_number,
8958 stop_state,
8959 index,
8960 rule_start_index,
8961 decision_start_index,
8962 precedence,
8963 depth,
8964 recovery_symbols: Rc::clone(&recovery_symbols),
8965 recovery_state,
8966 },
8967 visiting,
8968 memo,
8969 expected,
8970 },
8971 predicate_context,
8972 ));
8973 }
8974 outcomes.extend(self.fast_current_token_deletion_recovery(
8975 FastCurrentTokenDeletionRequest {
8976 atn,
8977 expected_symbols,
8978 request: FastRecognizeRequest {
8979 state_number,
8980 stop_state,
8981 index,
8982 rule_start_index,
8983 decision_start_index,
8984 precedence,
8985 depth,
8986 recovery_symbols: Rc::clone(&recovery_symbols),
8987 recovery_state,
8988 },
8989 visiting,
8990 memo,
8991 expected,
8992 },
8993 predicate_context,
8994 ));
8995 }
8996 }
8997 }
8998 }
8999 }
9000
9001 if has_inserted_cycle_guard {
9002 visiting.remove(&key);
9003 }
9004 if matches!(
9005 self.prediction_mode,
9006 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9007 ) && self.fast_recovery_enabled
9008 {
9009 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
9013 }
9014 if self.fast_recovery_enabled {
9015 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
9016 } else {
9017 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
9018 }
9019 let should_memoize = self.fast_recovery_enabled
9029 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
9030 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
9034 if inline_consumed_eof {
9035 outcome.consumed_eof = true;
9036 }
9037 if !inline_consumed_tokens.is_empty() {
9038 for token_index in inline_consumed_tokens.iter().rev() {
9039 let token = self.arena_token_node(*token_index, false);
9040 self.defer_fast_outcome_node(&mut outcome, token);
9041 }
9042 }
9043 outcome
9044 };
9045 if should_memoize {
9046 #[cfg(feature = "perf-counters")]
9047 {
9048 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
9049 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
9050 match outcomes.len() {
9051 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
9052 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
9053 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
9054 }
9055 }
9056 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
9061 memo.insert(key, Rc::clone(&stored));
9062 if inline_pending {
9063 return stored
9064 .iter()
9065 .copied()
9066 .map(&mut apply_inline_pending)
9067 .collect();
9068 }
9069 return stored.to_vec();
9070 }
9071 #[cfg(feature = "perf-counters")]
9072 match outcomes.len() {
9073 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
9074 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
9075 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
9076 }
9077 if inline_pending {
9078 return outcomes.into_iter().map(apply_inline_pending).collect();
9079 }
9080 outcomes
9081 }
9082
9083 fn single_token_deletion_recovery(
9086 &mut self,
9087 recovery: RecoveryRequest<'_, '_>,
9088 ) -> Vec<RecognizeOutcome> {
9089 let RecoveryRequest {
9090 atn,
9091 transition,
9092 expected_symbols,
9093 target,
9094 request,
9095 visiting,
9096 memo,
9097 expected,
9098 } = recovery;
9099 let RecognizeRequest {
9100 stop_state,
9101 index,
9102 rule_start_index,
9103 decision_start_index,
9104 init_action_rules,
9105 predicates,
9106 semantics,
9107 rule_args,
9108 member_actions,
9109 return_actions,
9110 local_int_arg,
9111 member_values,
9112 return_values,
9113 rule_alt_number,
9114 track_alt_numbers,
9115 consumed_eof,
9116 precedence,
9117 depth,
9118 ..
9119 } = request;
9120 let Some((diagnostic, next_index, next_symbol)) =
9121 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
9122 else {
9123 return Vec::new();
9124 };
9125 let after_next = self.consume_index(next_index, next_symbol);
9126 self.recognize_state(
9127 atn,
9128 RecognizeRequest {
9129 state_number: target,
9130 stop_state,
9131 index: after_next,
9132 rule_start_index,
9133 decision_start_index,
9134 init_action_rules,
9135 predicates,
9136 semantics,
9137 rule_args,
9138 member_actions,
9139 return_actions,
9140 local_int_arg,
9141 member_values,
9142 return_values,
9143 rule_alt_number,
9144 track_alt_numbers,
9145 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
9146 committed_decision: false,
9147 precedence,
9148 depth: depth + 1,
9149 recovery_symbols: BTreeSet::new(),
9150 recovery_state: None,
9151 },
9152 visiting,
9153 memo,
9154 expected,
9155 )
9156 .into_iter()
9157 .map(|mut outcome| {
9158 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
9159 outcome.diagnostics = self
9160 .recognition_arena
9161 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9162 let token = self.arena_token_node(next_index, false);
9163 self.arena_prepend(&mut outcome.nodes, token);
9164 let error = self.arena_token_node(index, true);
9165 self.arena_prepend(&mut outcome.nodes, error);
9166 outcome
9167 })
9168 .collect()
9169 }
9170
9171 fn current_token_deletion_recovery(
9174 &mut self,
9175 recovery: CurrentTokenDeletionRequest<'_, '_>,
9176 ) -> Vec<RecognizeOutcome> {
9177 let CurrentTokenDeletionRequest {
9178 atn,
9179 expected_symbols,
9180 mut request,
9181 visiting,
9182 memo,
9183 expected,
9184 } = recovery;
9185 let error_index = request.index;
9186 if error_index == request.rule_start_index {
9187 return Vec::new();
9188 }
9189 let Some((diagnostic, next_index, skipped)) =
9190 self.current_token_deletion(error_index, &expected_symbols)
9191 else {
9192 return Vec::new();
9193 };
9194 request.state_number = request.recovery_state.unwrap_or(request.state_number);
9195 request.index = next_index;
9196 request.committed_decision = false;
9197 request.depth += 1;
9198 request.recovery_state = None;
9199 self.recognize_state(atn, request, visiting, memo, expected)
9200 .into_iter()
9201 .map(|mut outcome| {
9202 outcome.diagnostics = self
9203 .recognition_arena
9204 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9205 for index in skipped.iter().rev() {
9206 let error = self.arena_token_node(*index, true);
9207 self.arena_prepend(&mut outcome.nodes, error);
9208 }
9209 outcome
9210 })
9211 .collect()
9212 }
9213
9214 fn consuming_failure_fallback(
9217 &mut self,
9218 fallback: ConsumingFailureFallback<'_>,
9219 visiting: &mut BTreeSet<RecognizeKey>,
9220 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9221 expected: &mut ExpectedTokens,
9222 ) -> Vec<RecognizeOutcome> {
9223 if fallback.expected_symbols.is_empty() {
9224 return Vec::new();
9225 }
9226 if fallback.symbol == TOKEN_EOF {
9227 return self.eof_consuming_failure_fallback(fallback, expected);
9228 }
9229 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
9230 }
9231
9232 fn non_eof_consuming_failure_fallback(
9235 &mut self,
9236 fallback: ConsumingFailureFallback<'_>,
9237 visiting: &mut BTreeSet<RecognizeKey>,
9238 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9239 expected: &mut ExpectedTokens,
9240 ) -> Vec<RecognizeOutcome> {
9241 let ConsumingFailureFallback {
9242 atn,
9243 target,
9244 request,
9245 symbol,
9246 expected_symbols,
9247 decision_start_index,
9248 decision,
9249 } = fallback;
9250 let error_index = request.index;
9251 let diagnostic =
9252 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
9253 let next_index = self.consume_index(error_index, symbol);
9254 self.recognize_state(
9255 atn,
9256 RecognizeRequest {
9257 state_number: target,
9258 stop_state: request.stop_state,
9259 index: next_index,
9260 rule_start_index: request.rule_start_index,
9261 decision_start_index,
9262 init_action_rules: request.init_action_rules,
9263 predicates: request.predicates,
9264 semantics: request.semantics,
9265 rule_args: request.rule_args,
9266 member_actions: request.member_actions,
9267 return_actions: request.return_actions,
9268 local_int_arg: request.local_int_arg,
9269 member_values: request.member_values,
9270 return_values: request.return_values,
9271 rule_alt_number: request.rule_alt_number,
9272 track_alt_numbers: request.track_alt_numbers,
9273 consumed_eof: request.consumed_eof,
9274 committed_decision: false,
9275 precedence: request.precedence,
9276 depth: request.depth + 1,
9277 recovery_symbols: BTreeSet::new(),
9278 recovery_state: None,
9279 },
9280 visiting,
9281 memo,
9282 expected,
9283 )
9284 .into_iter()
9285 .map(|mut outcome| {
9286 prepend_decision(&mut outcome, decision);
9287 outcome.diagnostics = self
9288 .recognition_arena
9289 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9290 let error = self.arena_token_node(error_index, true);
9291 self.arena_prepend(&mut outcome.nodes, error);
9292 outcome
9293 })
9294 .collect()
9295 }
9296
9297 fn eof_consuming_failure_fallback(
9300 &mut self,
9301 fallback: ConsumingFailureFallback<'_>,
9302 expected: &ExpectedTokens,
9303 ) -> Vec<RecognizeOutcome> {
9304 let request = fallback.request;
9305 if request.index == request.rule_start_index {
9306 return Vec::new();
9307 }
9308 let diagnostic =
9309 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
9310 let diagnostics = self
9311 .recognition_arena
9312 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
9313 vec![RecognizeOutcome {
9314 index: request.index,
9315 consumed_eof: request.consumed_eof,
9316 alt_number: request.rule_alt_number,
9317 member_values: request.member_values,
9318 return_values: request.return_values,
9319 diagnostics,
9320 decisions: Vec::new(),
9321 actions: Vec::new(),
9322 nodes: NodeSeqId::EMPTY,
9323 }]
9324 }
9325
9326 fn single_token_insertion_recovery(
9329 &mut self,
9330 recovery: RecoveryRequest<'_, '_>,
9331 ) -> Vec<RecognizeOutcome> {
9332 let RecoveryRequest {
9333 atn,
9334 transition,
9335 expected_symbols,
9336 target,
9337 request,
9338 visiting,
9339 memo,
9340 expected,
9341 } = recovery;
9342 let RecognizeRequest {
9343 stop_state,
9344 index,
9345 rule_start_index,
9346 decision_start_index,
9347 init_action_rules,
9348 predicates,
9349 semantics,
9350 rule_args,
9351 member_actions,
9352 return_actions,
9353 local_int_arg,
9354 member_values,
9355 return_values,
9356 rule_alt_number,
9357 track_alt_numbers,
9358 consumed_eof,
9359 precedence,
9360 depth,
9361 ..
9362 } = request;
9363 let follow_symbols = state_expected_symbols(atn, transition.target());
9364 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
9365 transition,
9366 index,
9367 atn.max_token_type(),
9368 &expected_symbols,
9369 &follow_symbols,
9370 ) else {
9371 return Vec::new();
9372 };
9373 self.recognize_state(
9374 atn,
9375 RecognizeRequest {
9376 state_number: target,
9377 stop_state,
9378 index,
9379 rule_start_index,
9380 decision_start_index,
9381 init_action_rules,
9382 predicates,
9383 semantics,
9384 rule_args,
9385 member_actions,
9386 return_actions,
9387 local_int_arg,
9388 member_values,
9389 return_values,
9390 rule_alt_number,
9391 track_alt_numbers,
9392 consumed_eof,
9393 committed_decision: false,
9394 precedence,
9395 depth: depth + 1,
9396 recovery_symbols: BTreeSet::new(),
9397 recovery_state: None,
9398 },
9399 visiting,
9400 memo,
9401 expected,
9402 )
9403 .into_iter()
9404 .map(|mut outcome| {
9405 outcome.diagnostics = self
9406 .recognition_arena
9407 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9408 let missing = self.arena_missing_token_node(token_type, index, text.clone());
9409 self.arena_prepend(&mut outcome.nodes, missing);
9410 outcome
9411 })
9412 .collect()
9413 }
9414
9415 #[allow(clippy::too_many_lines)]
9418 fn recognize_state(
9419 &mut self,
9420 atn: &Atn,
9421 request: RecognizeRequest<'_>,
9422 visiting: &mut BTreeSet<RecognizeKey>,
9423 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9424 expected: &mut ExpectedTokens,
9425 ) -> Vec<RecognizeOutcome> {
9426 let request_template = request.clone();
9427 let RecognizeRequest {
9428 state_number,
9429 stop_state,
9430 index,
9431 rule_start_index,
9432 decision_start_index,
9433 init_action_rules,
9434 predicates,
9435 semantics,
9436 rule_args,
9437 member_actions,
9438 return_actions,
9439 local_int_arg,
9440 member_values,
9441 return_values,
9442 rule_alt_number,
9443 track_alt_numbers,
9444 consumed_eof,
9445 committed_decision,
9446 precedence,
9447 depth,
9448 recovery_symbols,
9449 recovery_state,
9450 } = request;
9451 if depth > RECOGNITION_DEPTH_LIMIT {
9452 return Vec::new();
9453 }
9454 if state_number == stop_state {
9455 return stop_outcome(
9456 index,
9457 consumed_eof,
9458 rule_alt_number,
9459 member_values,
9460 return_values,
9461 );
9462 }
9463 let key = RecognizeKey {
9464 state_number,
9465 stop_state,
9466 index,
9467 rule_start_index,
9468 decision_start_index,
9469 local_int_arg,
9470 member_values: member_values.clone(),
9471 return_values: return_values.clone(),
9472 rule_alt_number,
9473 track_alt_numbers,
9474 consumed_eof,
9475 committed_decision,
9476 precedence,
9477 recovery_symbols: recovery_symbols.clone(),
9478 recovery_state,
9479 };
9480 if let Some(outcomes) = memo.get(&key) {
9481 return outcomes.clone();
9482 }
9483
9484 let visit_key = key.clone();
9485 if !visiting.insert(visit_key.clone()) {
9486 return Vec::new();
9487 }
9488
9489 let Some(state) = atn.state(state_number) else {
9490 visiting.remove(&visit_key);
9491 return Vec::new();
9492 };
9493 let decision_override_generation = self.decision_override_generation;
9494 let transitions = state.transitions();
9495 let transition_count = transitions.len();
9496 let overridden_transition = if transition_count > 1
9497 && self.semantic_hooks.observes_parser_decisions()
9498 {
9499 atn.decision_to_state()
9500 .iter()
9501 .position(|candidate| candidate == state_number)
9502 .and_then(|decision| {
9503 self.semantic_hooks
9504 .parser_decision_override(decision, index, transition_count)
9505 })
9506 .and_then(|alternative| alternative.checked_sub(1))
9507 .filter(|alternative| *alternative < transition_count)
9508 } else {
9509 None
9510 };
9511 if overridden_transition.is_some() {
9512 self.decision_override_generation = self.decision_override_generation.wrapping_add(1);
9513 }
9514 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9515 Some(index)
9516 } else {
9517 decision_start_index
9518 };
9519 let (epsilon_recovery_symbols, epsilon_recovery_state) =
9520 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
9521 let mut outcomes = Vec::new();
9522 for (transition_index, transition) in transitions.iter().enumerate() {
9523 if overridden_transition.is_some_and(|forced| forced != transition_index) {
9524 continue;
9525 }
9526 let transition_committed =
9527 committed_decision || overridden_transition == Some(transition_index);
9528 let mut transition_request = request_template.clone();
9529 transition_request.committed_decision = transition_committed;
9530 let decision =
9531 transition_decision(atn, state, transition_count, transition_index, predicates);
9532 let next_alt_number = next_alt_number(
9533 state,
9534 transition_count,
9535 transition_index,
9536 rule_alt_number,
9537 track_alt_numbers,
9538 );
9539 let transition_data = transition.data();
9540 match &transition_data {
9541 Transition::Epsilon { target } | Transition::Action { target, .. } => {
9542 let action_rule_index = match &transition_data {
9543 Transition::Action { rule_index, .. } => Some(*rule_index),
9544 _ => None,
9545 };
9546 outcomes.extend(self.recognize_epsilon_or_action_step(
9547 atn,
9548 &transition_request,
9549 EpsilonActionStep {
9550 source_state: state_number,
9551 target: *target,
9552 action_rule_index,
9553 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
9554 decision,
9555 decision_start_index: next_decision_start_index,
9556 alt_number: next_alt_number,
9557 recovery_symbols: epsilon_recovery_symbols.clone(),
9558 recovery_state: epsilon_recovery_state,
9559 },
9560 RecognizeScratch {
9561 visiting,
9562 memo,
9563 expected,
9564 },
9565 ));
9566 }
9567 Transition::Predicate {
9568 target,
9569 rule_index,
9570 pred_index,
9571 ..
9572 } => {
9573 let predicate = PredicateEval {
9574 index,
9575 rule_index: *rule_index,
9576 pred_index: *pred_index,
9577 predicates,
9578 semantics,
9579 context: None,
9580 local_int_arg,
9581 member_values: &member_values,
9582 };
9583 if self.parser_predicate_matches(predicate) {
9584 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
9585 outcomes.extend(
9586 self.recognize_state(
9587 atn,
9588 RecognizeRequest {
9589 state_number: *target,
9590 stop_state,
9591 index,
9592 rule_start_index,
9593 decision_start_index: next_decision_start_index,
9594 init_action_rules,
9595 predicates,
9596 semantics,
9597 rule_args,
9598 member_actions,
9599 return_actions,
9600 local_int_arg,
9601 member_values: member_values.clone(),
9602 return_values: return_values.clone(),
9603 rule_alt_number: next_alt_number,
9604 track_alt_numbers,
9605 consumed_eof,
9606 committed_decision: transition_committed,
9607 precedence,
9608 depth: depth + 1,
9609 recovery_symbols: epsilon_recovery_symbols.clone(),
9610 recovery_state: epsilon_recovery_state,
9611 },
9612 visiting,
9613 memo,
9614 expected,
9615 )
9616 .into_iter()
9617 .map(|mut outcome| {
9618 prepend_decision(&mut outcome, decision);
9619 if let Some(rule_index) = left_recursive_boundary {
9620 let boundary =
9621 self.arena_boundary_node(rule_index, next_alt_number);
9622 self.arena_prepend(&mut outcome.nodes, boundary);
9623 }
9624 outcome
9625 }),
9626 );
9627 } else if let Some(message) = semantics
9628 .and_then(|semantics| {
9629 self.parser_semantic_ir_predicate_failure_message(
9630 *rule_index,
9631 *pred_index,
9632 semantics,
9633 )
9634 })
9635 .or_else(|| {
9636 self.parser_predicate_failure_message(
9637 *rule_index,
9638 *pred_index,
9639 predicates,
9640 )
9641 })
9642 {
9643 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
9644 rule_index: *rule_index,
9645 index,
9646 message,
9647 member_values: member_values.clone(),
9648 return_values: return_values.clone(),
9649 rule_alt_number,
9650 }));
9651 } else {
9652 record_predicate_no_viable(expected, next_decision_start_index, index);
9653 }
9654 }
9655 Transition::Precedence {
9656 target,
9657 precedence: transition_precedence,
9658 } => {
9659 if *transition_precedence >= precedence {
9660 outcomes.extend(
9661 self.recognize_state(
9662 atn,
9663 RecognizeRequest {
9664 state_number: *target,
9665 stop_state,
9666 index,
9667 rule_start_index,
9668 decision_start_index: next_decision_start_index,
9669 init_action_rules,
9670 predicates,
9671 semantics,
9672 rule_args,
9673 member_actions,
9674 return_actions,
9675 local_int_arg,
9676 member_values: member_values.clone(),
9677 return_values: return_values.clone(),
9678 rule_alt_number: next_alt_number,
9679 track_alt_numbers,
9680 consumed_eof,
9681 committed_decision: transition_committed,
9682 precedence,
9683 depth: depth + 1,
9684 recovery_symbols: epsilon_recovery_symbols.clone(),
9685 recovery_state: epsilon_recovery_state,
9686 },
9687 visiting,
9688 memo,
9689 expected,
9690 )
9691 .into_iter()
9692 .map(|mut outcome| {
9693 prepend_decision(&mut outcome, decision);
9694 outcome
9695 }),
9696 );
9697 }
9698 }
9699 Transition::Rule {
9700 target,
9701 rule_index,
9702 follow_state,
9703 precedence: rule_precedence,
9704 ..
9705 } => {
9706 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
9707 continue;
9708 };
9709 let child_local_int_arg =
9710 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
9711 let expected_before_child = expected.clone();
9712 let children = self.recognize_state(
9713 atn,
9714 RecognizeRequest {
9715 state_number: *target,
9716 stop_state: child_stop,
9717 index,
9718 rule_start_index: index,
9719 decision_start_index: None,
9720 init_action_rules,
9721 predicates,
9722 semantics,
9723 rule_args,
9724 member_actions,
9725 return_actions,
9726 local_int_arg: child_local_int_arg,
9727 member_values: member_values.clone(),
9728 return_values: BTreeMap::new(),
9729 rule_alt_number: 0,
9730 track_alt_numbers,
9731 consumed_eof: false,
9732 committed_decision: transition_committed,
9733 precedence: *rule_precedence,
9734 depth: depth + 1,
9735 recovery_symbols: epsilon_recovery_symbols.clone(),
9736 recovery_state: epsilon_recovery_state,
9737 },
9738 visiting,
9739 memo,
9740 expected,
9741 );
9742 let children = if children.is_empty() {
9743 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
9744 atn,
9745 rule_index: *rule_index,
9746 start_index: index,
9747 follow_state: *follow_state,
9748 stop_state,
9749 member_values: member_values.clone(),
9750 expected,
9751 })
9752 } else {
9753 children
9754 };
9755 let preserve_child_expected =
9756 self.child_expected_reaches_clean_eof(&children, expected);
9757 restore_expected(
9758 &children,
9759 index,
9760 expected,
9761 expected_before_child,
9762 preserve_child_expected,
9763 );
9764 for child in children {
9765 let child_stop_index =
9766 self.rule_stop_token_index(child.index, child.consumed_eof);
9767 let child_nodes = self
9768 .recognition_arena
9769 .fold_left_recursive_boundaries(child.nodes);
9770 let child_node = self.arena_rule_node(ArenaRuleSpec {
9771 rule_index: *rule_index,
9772 invoking_state: invoking_state_number(state_number),
9773 alt_number: child.alt_number,
9774 start_index: index,
9775 stop_index: child_stop_index,
9776 return_values: child.return_values.clone(),
9777 children: child_nodes,
9778 });
9779 outcomes.extend(
9780 self.recognize_state(
9781 atn,
9782 RecognizeRequest {
9783 state_number: *follow_state,
9784 stop_state,
9785 index: child.index,
9786 rule_start_index,
9787 decision_start_index: next_decision_start_index,
9788 init_action_rules,
9789 predicates,
9790 semantics,
9791 rule_args,
9792 member_actions,
9793 return_actions,
9794 local_int_arg,
9795 member_values: child.member_values.clone(),
9796 return_values: return_values.clone(),
9797 rule_alt_number,
9798 track_alt_numbers,
9799 consumed_eof: consumed_eof || child.consumed_eof,
9800 committed_decision: transition_committed
9801 && child.index == index,
9802 precedence,
9803 depth: depth + 1,
9804 recovery_symbols: BTreeSet::new(),
9805 recovery_state: None,
9806 },
9807 visiting,
9808 memo,
9809 expected,
9810 )
9811 .into_iter()
9812 .map(|mut outcome| {
9813 outcome.consumed_eof |= child.consumed_eof;
9814 outcome.diagnostics = self
9815 .recognition_arena
9816 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
9817 let mut decisions = child.decisions.clone();
9818 decisions.append(&mut outcome.decisions);
9819 outcome.decisions = decisions;
9820 prepend_decision(&mut outcome, decision);
9821 let mut actions = child.actions.clone();
9822 if init_action_rules.contains(rule_index) {
9823 actions.insert(
9824 0,
9825 ParserAction::new_rule_init(
9826 *rule_index,
9827 index,
9828 Some(*follow_state),
9829 ),
9830 );
9831 }
9832 actions.append(&mut outcome.actions);
9833 outcome.actions = actions;
9834 self.arena_prepend(&mut outcome.nodes, child_node);
9835 outcome
9836 }),
9837 );
9838 }
9839 }
9840 Transition::Atom { target, .. }
9841 | Transition::Range { target, .. }
9842 | Transition::Set { target, .. }
9843 | Transition::NotSet { target, .. }
9844 | Transition::Wildcard { target, .. } => {
9845 let symbol = self.token_type_at(index);
9846 if transition_data.matches(symbol, 1, atn.max_token_type()) {
9847 let next_index = self.consume_index(index, symbol);
9848 outcomes.extend(
9849 self.recognize_state(
9850 atn,
9851 RecognizeRequest {
9852 state_number: *target,
9853 stop_state,
9854 index: next_index,
9855 rule_start_index,
9856 decision_start_index: next_decision_start_index,
9857 init_action_rules,
9858 predicates,
9859 semantics,
9860 rule_args,
9861 member_actions,
9862 return_actions,
9863 local_int_arg,
9864 member_values: member_values.clone(),
9865 return_values: return_values.clone(),
9866 rule_alt_number: next_alt_number,
9867 track_alt_numbers,
9868 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
9869 committed_decision: false,
9870 precedence,
9871 depth: depth + 1,
9872 recovery_symbols: BTreeSet::new(),
9873 recovery_state: None,
9874 },
9875 visiting,
9876 memo,
9877 expected,
9878 )
9879 .into_iter()
9880 .map(|mut outcome| {
9881 prepend_decision(&mut outcome, decision);
9882 outcome.consumed_eof |= symbol == TOKEN_EOF;
9883 let token = self.arena_token_node(index, false);
9884 self.arena_prepend(&mut outcome.nodes, token);
9885 outcome
9886 }),
9887 );
9888 } else {
9889 let expected_symbols =
9890 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
9891 if expected_symbols.contains(&symbol) && !transition_committed {
9892 continue;
9893 }
9894 expected.record_transition(index, transition, atn.max_token_type());
9895 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
9896 let before_recovery = outcomes.len();
9897 let recovery_request = transition_request.clone();
9898 if transition_committed {
9899 outcomes.extend(self.consuming_failure_fallback(
9900 ConsumingFailureFallback {
9901 atn,
9902 target: *target,
9903 request: recovery_request,
9904 symbol,
9905 expected_symbols,
9906 decision_start_index: next_decision_start_index,
9907 decision,
9908 },
9909 visiting,
9910 memo,
9911 expected,
9912 ));
9913 break;
9914 }
9915 outcomes.extend(
9916 self.single_token_deletion_recovery(RecoveryRequest {
9917 atn,
9918 transition,
9919 expected_symbols: expected_symbols.clone(),
9920 target: *target,
9921 request: recovery_request.clone(),
9922 visiting,
9923 memo,
9924 expected,
9925 })
9926 .into_iter()
9927 .map(|mut outcome| {
9928 prepend_decision(&mut outcome, decision);
9929 outcome
9930 }),
9931 );
9932 if !state_is_left_recursive_rule(atn, state) {
9933 outcomes.extend(
9934 self.single_token_insertion_recovery(RecoveryRequest {
9935 atn,
9936 transition,
9937 expected_symbols: expected_symbols.clone(),
9938 target: *target,
9939 request: recovery_request.clone(),
9940 visiting,
9941 memo,
9942 expected,
9943 })
9944 .into_iter()
9945 .map(|mut outcome| {
9946 prepend_decision(&mut outcome, decision);
9947 outcome
9948 }),
9949 );
9950 }
9951 outcomes.extend(self.current_token_deletion_recovery(
9952 CurrentTokenDeletionRequest {
9953 atn,
9954 expected_symbols: expected_symbols.clone(),
9955 request: recovery_request.clone(),
9956 visiting,
9957 memo,
9958 expected,
9959 },
9960 ));
9961 if outcomes.len() == before_recovery {
9962 outcomes.extend(self.consuming_failure_fallback(
9963 ConsumingFailureFallback {
9964 atn,
9965 target: *target,
9966 request: recovery_request,
9967 symbol,
9968 expected_symbols,
9969 decision_start_index: next_decision_start_index,
9970 decision,
9971 },
9972 visiting,
9973 memo,
9974 expected,
9975 ));
9976 }
9977 }
9978 }
9979 }
9980 if self.decision_override_generation != decision_override_generation {
9981 break;
9982 }
9983 }
9984
9985 visiting.remove(&visit_key);
9986 self.record_prediction_diagnostics(atn, state, index, &outcomes);
9987 if matches!(
9988 self.prediction_mode,
9989 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9990 ) {
9991 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
9992 }
9993 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
9994 memo.insert(key, outcomes.clone());
9995 outcomes
9996 }
9997
9998 fn recognize_epsilon_or_action_step(
10001 &mut self,
10002 atn: &Atn,
10003 request: &RecognizeRequest<'_>,
10004 step: EpsilonActionStep,
10005 scratch: RecognizeScratch<'_>,
10006 ) -> Vec<RecognizeOutcome> {
10007 let RecognizeScratch {
10008 visiting,
10009 memo,
10010 expected,
10011 } = scratch;
10012 let action = step.action_rule_index.map(|rule_index| {
10013 ParserAction::new(
10014 step.source_state,
10015 rule_index,
10016 request.rule_start_index,
10017 self.rule_stop_token_index(request.index, request.consumed_eof),
10018 )
10019 });
10020 let next_member_values = if action.is_some() {
10021 member_values_after_action(
10022 step.source_state,
10023 request.member_actions,
10024 request.semantics,
10025 &request.member_values,
10026 )
10027 } else {
10028 request.member_values.clone()
10029 };
10030 let next_return_values = action.map_or_else(
10031 || request.return_values.clone(),
10032 |action| {
10033 return_values_after_action(
10034 step.source_state,
10035 action.rule_index(),
10036 request.return_actions,
10037 request.semantics,
10038 &request.return_values,
10039 )
10040 },
10041 );
10042
10043 self.recognize_state(
10044 atn,
10045 RecognizeRequest {
10046 state_number: step.target,
10047 stop_state: request.stop_state,
10048 index: request.index,
10049 rule_start_index: request.rule_start_index,
10050 decision_start_index: step.decision_start_index,
10051 init_action_rules: request.init_action_rules,
10052 predicates: request.predicates,
10053 semantics: request.semantics,
10054 rule_args: request.rule_args,
10055 member_actions: request.member_actions,
10056 return_actions: request.return_actions,
10057 local_int_arg: request.local_int_arg,
10058 member_values: next_member_values,
10059 return_values: next_return_values,
10060 rule_alt_number: if step.left_recursive_boundary.is_some() {
10061 0
10062 } else {
10063 step.alt_number
10064 },
10065 track_alt_numbers: request.track_alt_numbers,
10066 consumed_eof: request.consumed_eof,
10067 committed_decision: request.committed_decision,
10068 precedence: request.precedence,
10069 depth: request.depth + 1,
10070 recovery_symbols: step.recovery_symbols,
10071 recovery_state: step.recovery_state,
10072 },
10073 visiting,
10074 memo,
10075 expected,
10076 )
10077 .into_iter()
10078 .map(|mut outcome| {
10079 prepend_decision(&mut outcome, step.decision);
10080 if let Some(rule_index) = step.left_recursive_boundary {
10081 let boundary = self.arena_boundary_node(rule_index, step.alt_number);
10082 self.arena_prepend(&mut outcome.nodes, boundary);
10083 }
10084 if let Some(action) = action {
10085 outcome.actions.insert(0, action);
10086 }
10087 outcome
10088 })
10089 .collect()
10090 }
10091
10092 fn token_type_at(&mut self, index: usize) -> i32 {
10097 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
10098 self.input.fill();
10099 }
10100 self.input.token_type_at_index(index)
10101 }
10102
10103 fn cached_state_expected_symbols(
10115 &mut self,
10116 atn: &Atn,
10117 state_number: usize,
10118 ) -> Rc<BTreeSet<i32>> {
10119 if let Some(cached) = self.state_expected_cache.get(&state_number) {
10120 return Rc::clone(cached);
10121 }
10122 let symbols = state_expected_symbols(atn, state_number);
10123 let entry = self.intern_recovery_symbols(symbols);
10124 self.state_expected_cache
10125 .insert(state_number, Rc::clone(&entry));
10126 entry
10127 }
10128
10129 fn cached_state_expected_token_set(
10130 &mut self,
10131 atn: &Atn,
10132 state_number: usize,
10133 ) -> Rc<TokenBitSet> {
10134 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
10135 return Rc::clone(cached);
10136 }
10137 let symbols = with_shared_atn_caches(atn, |cache| {
10141 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
10142 return Rc::clone(cached);
10143 }
10144 let symbols = Rc::new(state_expected_token_set(atn, state_number));
10145 cache
10146 .state_expected_tokens
10147 .insert(state_number, Rc::clone(&symbols));
10148 symbols
10149 });
10150 self.state_expected_token_cache
10151 .insert(state_number, Rc::clone(&symbols));
10152 symbols
10153 }
10154
10155 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
10156 if self.rule_stop_reach_cache.len() <= state_number {
10157 self.rule_stop_reach_cache
10158 .resize_with(atn.states().len().max(state_number + 1), || None);
10159 }
10160 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
10161 return reaches;
10162 }
10163 let reaches = with_shared_atn_caches(atn, |cache| {
10164 *cache
10165 .rule_stop_reach
10166 .entry(state_number)
10167 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
10168 });
10169 self.rule_stop_reach_cache[state_number] = Some(reaches);
10170 reaches
10171 }
10172
10173 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
10176 Rc::clone(&self.empty_recovery_symbols)
10177 }
10178
10179 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
10188 if set.is_empty() {
10189 return Rc::clone(&self.empty_recovery_symbols);
10190 }
10191 let candidate = Rc::new(set);
10192 match self.recovery_symbols_intern.get(&candidate) {
10193 Some(existing) => Rc::clone(existing),
10194 None => {
10195 self.recovery_symbols_intern
10196 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
10197 candidate
10198 }
10199 }
10200 }
10201
10202 fn cached_decision_lookahead(
10207 &mut self,
10208 atn: &Atn,
10209 state: AtnState<'_>,
10210 rule_stop_state: usize,
10211 ) -> Rc<DecisionLookahead> {
10212 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
10219 return Rc::clone(cached);
10220 }
10221 let entry = with_shared_atn_caches(atn, |cache| {
10222 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
10223 return Rc::clone(cached);
10224 }
10225 let mut entry = DecisionLookahead {
10226 transitions: Vec::with_capacity(state.transitions().len()),
10227 };
10228 for transition in &state.transitions() {
10229 entry.transitions.push(transition_first_set(
10230 atn,
10231 transition,
10232 rule_stop_state,
10233 &mut cache.first_set,
10234 ));
10235 }
10236 let entry = Rc::new(entry);
10237 cache
10238 .decision_lookahead
10239 .insert(state.state_number(), Rc::clone(&entry));
10240 entry
10241 });
10242 self.decision_lookahead_cache
10243 .insert(state.state_number(), Rc::clone(&entry));
10244 entry
10245 }
10246
10247 fn cached_rule_first_set(
10248 &mut self,
10249 atn: &Atn,
10250 target: usize,
10251 child_stop: usize,
10252 ) -> Rc<FirstSet> {
10253 if self.rule_first_set_cache.len() <= target {
10254 self.rule_first_set_cache
10255 .resize_with(atn.states().len().max(target + 1), || None);
10256 }
10257 if let Some(cached) = self
10258 .rule_first_set_cache
10259 .get(target)
10260 .and_then(Option::as_ref)
10261 {
10262 return Rc::clone(cached);
10263 }
10264 let first = with_shared_first_set_cache(atn, |cache| {
10265 rule_first_set(atn, target, child_stop, cache)
10266 });
10267 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
10268 first
10269 }
10270
10271 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
10272 let atn_key = SharedAtnCacheKey::for_atn(atn);
10273 if self.empty_cycle_cache_atn != Some(atn_key) {
10274 self.empty_cycle_cache.clear();
10275 self.empty_cycle_cache_atn = Some(atn_key);
10276 }
10277 if self.empty_cycle_cache.len() <= state_number {
10278 self.empty_cycle_cache
10279 .resize_with(atn.state_count().max(state_number + 1), || None);
10280 }
10281 if let Some(cached) = self.empty_cycle_cache[state_number] {
10282 return cached;
10283 }
10284 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
10285 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
10286 self.empty_cycle_cache[state_number] = Some(result);
10287 result
10288 }
10289
10290 fn empty_path_reaches_state(
10291 &mut self,
10292 atn: &Atn,
10293 state_number: usize,
10294 target_state: usize,
10295 visited: &mut FxHashSet<usize>,
10296 ) -> bool {
10297 enum Work {
10298 Visit(usize),
10299 RuleFollow {
10300 target: usize,
10301 rule_index: usize,
10302 follow_state: usize,
10303 },
10304 }
10305
10306 let mut work = vec![Work::Visit(state_number)];
10307 while let Some(item) = work.pop() {
10308 match item {
10309 Work::Visit(state_number) => {
10310 if !visited.insert(state_number) {
10311 continue;
10312 }
10313 let Some(state) = atn.state(state_number) else {
10314 continue;
10315 };
10316 let transitions = state.transitions();
10317 for transition_index in (0..transitions.len()).rev() {
10318 let transition = transitions
10319 .get(transition_index)
10320 .expect("in-bounds parser transition");
10321 let kind = transition.kind();
10322 let target = transition.target();
10323 match kind {
10324 ParserTransitionKind::Atom
10325 | ParserTransitionKind::Range
10326 | ParserTransitionKind::Set
10327 | ParserTransitionKind::NotSet
10328 | ParserTransitionKind::Wildcard => {}
10329 ParserTransitionKind::Rule => {
10330 if target == target_state {
10331 return true;
10332 }
10333 work.push(Work::RuleFollow {
10334 target,
10335 rule_index: transition.arg0() as usize,
10336 follow_state: transition.arg1() as usize,
10337 });
10338 work.push(Work::Visit(target));
10339 }
10340 ParserTransitionKind::Epsilon
10341 | ParserTransitionKind::Predicate
10342 | ParserTransitionKind::Action
10343 | ParserTransitionKind::Precedence => {
10344 if target == target_state {
10345 return true;
10346 }
10347 work.push(Work::Visit(target));
10348 }
10349 }
10350 }
10351 }
10352 Work::RuleFollow {
10353 target,
10354 rule_index,
10355 follow_state,
10356 } => {
10357 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
10358 continue;
10359 };
10360 if self.cached_rule_first_set(atn, target, child_stop).nullable {
10361 if follow_state == target_state {
10362 return true;
10363 }
10364 work.push(Work::Visit(follow_state));
10365 }
10366 }
10367 }
10368 }
10369 false
10370 }
10371
10372 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
10375 match self.clean_memo_mode {
10376 CleanMemoMode::Promote => true,
10377 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
10378 CleanMemoMode::Sparse => {
10379 self.clean_memo_sparse_samples += 1;
10380 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
10381 return false;
10382 }
10383 self.clean_memo_sparse_samples = 0;
10384 self.clean_memo_mode = CleanMemoMode::Probe;
10385 self.clean_memo_probe_samples = 0;
10386 self.clean_memo_probe_repeats = 0;
10387 self.clean_memo_probe_seen.clear();
10388 self.observe_clean_memo_probe(key)
10389 }
10390 }
10391 }
10392
10393 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
10394 self.clean_memo_probe_samples += 1;
10395 if !self.clean_memo_probe_seen.insert(key.clone()) {
10396 self.clean_memo_probe_repeats += 1;
10397 }
10398 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
10399 self.clean_memo_mode = CleanMemoMode::Promote;
10400 self.clean_memo_probe_seen.clear();
10401 return true;
10402 }
10403 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
10404 self.clean_memo_mode = CleanMemoMode::Sparse;
10405 self.clean_memo_sparse_samples = 0;
10406 self.clean_memo_probe_seen.clear();
10407 return false;
10408 }
10409 true
10410 }
10411
10412 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
10414 self.input.get(index)
10415 }
10416
10417 fn token_id_at(&self, index: usize) -> Option<TokenId> {
10419 self.input.get_id(index)
10420 }
10421
10422 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
10423 let token = self
10424 .token_id_at(index)
10425 .expect("recognized token index must exist in the token store");
10426 let node = if error {
10427 ArenaRecognizedNode::ErrorToken { token }
10428 } else {
10429 ArenaRecognizedNode::Token { token }
10430 };
10431 self.recognition_arena.push_node(node)
10432 }
10433
10434 fn arena_missing_token_node(
10435 &mut self,
10436 token_type: i32,
10437 at_index: usize,
10438 text: String,
10439 ) -> RecognizedNodeId {
10440 let extra = self
10441 .recognition_arena
10442 .push_extra(RecognitionExtra::MissingToken {
10443 token_type,
10444 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
10445 text,
10446 });
10447 self.recognition_arena
10448 .push_node(ArenaRecognizedNode::MissingToken { extra })
10449 }
10450
10451 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
10452 let ArenaRuleSpec {
10453 rule_index,
10454 invoking_state,
10455 alt_number,
10456 start_index,
10457 stop_index,
10458 return_values,
10459 children,
10460 } = spec;
10461 let return_values = (!return_values.is_empty()).then(|| {
10462 self.recognition_arena
10463 .push_extra(RecognitionExtra::ReturnValues(return_values))
10464 });
10465 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
10466 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10467 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
10468 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
10469 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
10470 stop_index: stop_index
10471 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
10472 return_values,
10473 children,
10474 })
10475 }
10476
10477 fn arena_boundary_node(&mut self, rule_index: usize, alt_number: usize) -> RecognizedNodeId {
10478 self.recognition_arena
10479 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
10480 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10481 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
10482 })
10483 }
10484
10485 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
10486 *sequence = self.recognition_arena.prepend(*sequence, node);
10487 }
10488
10489 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
10490 self.last_recognition_arena_root = root;
10491 self.last_recognition_arena_diagnostics = diagnostics;
10492 #[cfg(feature = "perf-counters")]
10493 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
10494 let stats = self.recognition_arena_stats();
10495 #[allow(clippy::print_stderr)]
10496 {
10497 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
10498 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
10499 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
10500 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
10501 eprintln!("perf recognition_links_total={}", stats.total_links);
10502 eprintln!("perf recognition_links_live={}", stats.live_links);
10503 eprintln!("perf recognition_links_dead={}", stats.dead_links);
10504 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
10505 eprintln!("perf recognition_extras_total={}", stats.total_extras);
10506 eprintln!("perf recognition_extras_live={}", stats.live_extras);
10507 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
10508 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
10509 }
10510 }
10511 }
10512
10513 fn reset_recognition_arena(&mut self) {
10514 self.recognition_arena.reset();
10515 self.last_recognition_arena_root = NodeSeqId::EMPTY;
10516 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
10517 }
10518
10519 fn current_visible_index(&mut self) -> usize {
10522 let index = self.input.index();
10523 self.input.seek(index);
10524 self.input.index()
10525 }
10526
10527 fn child_expected_reaches_clean_eof(
10530 &mut self,
10531 children: &[RecognizeOutcome],
10532 expected: &ExpectedTokens,
10533 ) -> bool {
10534 let Some(index) = expected.index else {
10535 return false;
10536 };
10537 self.token_type_at(index) == TOKEN_EOF
10538 && children
10539 .iter()
10540 .any(|child| child.diagnostics.is_empty() && child.index == index)
10541 }
10542
10543 fn previous_token_index(&self, index: usize) -> Option<usize> {
10550 self.input.previous_visible_token_index(index)
10551 }
10552
10553 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
10558 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
10559 Some(index)
10560 } else {
10561 self.previous_token_index(index)
10562 }
10563 }
10564
10565 #[must_use]
10582 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
10583 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
10584 self.rule_stop_token_index(current_index, consumed_eof)
10585 }
10586
10587 #[must_use]
10596 pub fn after_action_stop_index_for_tree(
10597 &mut self,
10598 tree: ParseTree,
10599 current_index: usize,
10600 ) -> Option<usize> {
10601 if let Some(stop) = self
10602 .node(tree)
10603 .as_rule()
10604 .and_then(crate::tree::RuleNodeView::stop_id)
10605 {
10606 return Some(stop.index());
10607 }
10608 self.after_action_stop_index(current_index)
10609 }
10610
10611 #[must_use]
10621 pub fn after_action_start_index_for_tree(
10622 &self,
10623 tree: ParseTree,
10624 fallback_index: usize,
10625 ) -> usize {
10626 if let Some(start) = self
10627 .node(tree)
10628 .as_rule()
10629 .and_then(crate::tree::RuleNodeView::start_id)
10630 {
10631 return start.index();
10632 }
10633 fallback_index
10634 }
10635
10636 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
10641 self.rule_stop_token_index(index, consumed_eof)
10642 .and_then(|token_index| self.token_id_at(token_index))
10643 }
10644
10645 fn predicate_failure_recovery(
10652 &mut self,
10653 request: PredicateFailureRecovery<'_>,
10654 ) -> RecognizeOutcome {
10655 let PredicateFailureRecovery {
10656 rule_index,
10657 index,
10658 message,
10659 member_values,
10660 return_values,
10661 rule_alt_number,
10662 } = request;
10663 let rule_name = self
10664 .rule_names()
10665 .get(rule_index)
10666 .map_or_else(|| rule_index.to_string(), Clone::clone);
10667 let diagnostic = diagnostic_for_token(
10668 self.token_at(index).as_ref(),
10669 format!("rule {rule_name} {message}"),
10670 );
10671 let mut reversed_nodes = NodeSeqId::EMPTY;
10672 let mut next_index = index;
10673 loop {
10674 let symbol = self.token_type_at(next_index);
10675 if symbol == TOKEN_EOF {
10676 break;
10677 }
10678 let error = self.arena_token_node(next_index, true);
10679 self.arena_prepend(&mut reversed_nodes, error);
10680 let after = self.consume_index(next_index, symbol);
10681 if after == next_index {
10682 break;
10683 }
10684 next_index = after;
10685 }
10686 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
10687 let diagnostics = self
10688 .recognition_arena
10689 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10690 RecognizeOutcome {
10691 index: next_index,
10692 consumed_eof: false,
10693 alt_number: rule_alt_number,
10694 member_values,
10695 return_values,
10696 diagnostics,
10697 decisions: Vec::new(),
10698 actions: Vec::new(),
10699 nodes,
10700 }
10701 }
10702
10703 fn parser_semantic_hook_result(
10706 &mut self,
10707 request: ParserSemanticHookRequest<'_>,
10708 ) -> Option<bool> {
10709 let ParserSemanticHookRequest {
10710 index,
10711 rule_index,
10712 pred_index,
10713 context,
10714 local_int_arg,
10715 member_values,
10716 } = request;
10717 let rule_name = self.rule_names().get(rule_index).cloned();
10718 self.input.seek(index);
10719 let input = &mut self.input;
10720 let semantic_hooks = &mut self.semantic_hooks;
10721 let mut ctx = ParserSemCtx {
10722 input,
10723 tree_storage: &self.tree,
10724 rule_index,
10725 coordinate_index: pred_index,
10726 rule_name,
10727 context,
10728 tree: None,
10729 local_int_arg,
10730 member_values,
10731 action: None,
10732 };
10733 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
10734 }
10735
10736 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
10741 if prior.is_empty() {
10742 return;
10743 }
10744 let mut merged = prior;
10745 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
10746 if !merged.contains(&coordinate) {
10747 merged.push(coordinate);
10748 }
10749 }
10750 self.unknown_predicate_hits = merged;
10751 }
10752
10753 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
10762 apply_unknown_predicate_policy(
10763 self.unknown_predicate_policy,
10764 rule_index,
10765 pred_index,
10766 &mut self.unknown_predicate_hits,
10767 )
10768 }
10769
10770 fn unknown_semantic_error(&self) -> Option<AntlrError> {
10773 use std::fmt::Write as _;
10774 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
10775 return None;
10776 }
10777 let mut message = String::new();
10778 for (rule_index, pred_index) in &self.unknown_predicate_hits {
10779 if !message.is_empty() {
10780 message.push_str("; ");
10781 }
10782 let _ = match self.rule_names().get(*rule_index) {
10783 Some(rule_name) => write!(
10784 message,
10785 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
10786 ),
10787 None => write!(
10788 message,
10789 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
10790 ),
10791 };
10792 }
10793 for (rule_index, source_state) in &self.unhandled_action_hits {
10794 if !message.is_empty() {
10795 message.push_str("; ");
10796 }
10797 let _ = match self.rule_names().get(*rule_index) {
10798 Some(rule_name) => write!(
10799 message,
10800 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
10801 ),
10802 None => write!(
10803 message,
10804 "unhandled semantic action: rule_index={rule_index} state={source_state}"
10805 ),
10806 };
10807 }
10808 Some(AntlrError::Unsupported(message))
10809 }
10810
10811 fn parser_semir_predicate_matches(
10819 &mut self,
10820 semantics: &ParserSemantics,
10821 predicate: &ParserSemanticPredicate,
10822 request: ParserSemanticHookRequest<'_>,
10823 ) -> bool {
10824 self.input.seek(request.index);
10825 let rule_name = self
10826 .data
10827 .rule_names()
10828 .get(request.rule_index)
10829 .map(String::as_str);
10830 let unknown_predicate_policy = self.unknown_predicate_policy;
10831 let mut ctx = ParserSemIrCtx {
10832 input: &mut self.input,
10833 tree_storage: &self.tree,
10834 semantic_hooks: &mut self.semantic_hooks,
10835 rule_index: request.rule_index,
10836 coordinate_index: request.pred_index,
10837 rule_name,
10838 context: request.context,
10839 local_int_arg: request.local_int_arg,
10840 member_values: request.member_values,
10841 invoked_predicates: &mut self.invoked_predicates,
10842 unknown_predicate_policy,
10843 unknown_predicate_hits: &mut self.unknown_predicate_hits,
10844 };
10845 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
10846 }
10847
10848 fn fast_parser_predicate_matches(
10849 &mut self,
10850 context: Option<FastPredicateContext<'_>>,
10851 transition: ParserTransition<'_>,
10852 index: usize,
10853 ) -> bool {
10854 let Some(context) = context else {
10855 return true;
10856 };
10857 let rule_index = transition.arg0() as usize;
10858 let pred_index = transition.arg1() as usize;
10859 let key = (index, rule_index, pred_index);
10860 if let Some(result) = self.fast_predicate_cache.get(&key) {
10861 return *result;
10862 }
10863 let result = self.parser_predicate_matches(PredicateEval {
10864 index,
10865 rule_index,
10866 pred_index,
10867 predicates: context.predicates,
10868 semantics: context.semantics,
10869 context: None,
10870 local_int_arg: None,
10871 member_values: context.member_values,
10872 });
10873 self.fast_predicate_cache.insert(key, result);
10874 result
10875 }
10876
10877 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
10878 let PredicateEval {
10879 index,
10880 rule_index,
10881 pred_index,
10882 predicates,
10883 semantics,
10884 context,
10885 local_int_arg,
10886 member_values,
10887 } = eval;
10888 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
10889 semantics
10890 .predicates
10891 .iter()
10892 .find(|predicate| {
10893 predicate.rule_index == rule_index && predicate.pred_index == pred_index
10894 })
10895 .map(|predicate| (semantics, predicate))
10896 }) {
10897 return self.parser_semir_predicate_matches(
10898 semantics,
10899 predicate,
10900 ParserSemanticHookRequest {
10901 index,
10902 rule_index,
10903 pred_index,
10904 context,
10905 local_int_arg,
10906 member_values,
10907 },
10908 );
10909 }
10910 let Some((_, _, predicate)) = predicates
10911 .iter()
10912 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
10913 else {
10914 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
10915 index,
10916 rule_index,
10917 pred_index,
10918 context,
10919 local_int_arg,
10920 member_values,
10921 }) {
10922 return result;
10923 }
10924 return self.unknown_predicate_result(rule_index, pred_index);
10925 };
10926 self.input.seek(index);
10927 match predicate {
10928 ParserPredicate::True => true,
10929 ParserPredicate::False => false,
10930 ParserPredicate::FalseWithMessage { .. } => false,
10931 ParserPredicate::Invoke { value } => {
10932 let key = (rule_index, pred_index);
10933 if !self.invoked_predicates.contains(&key) {
10934 self.invoked_predicates.push(key);
10935 use std::io::Write as _;
10936 let mut stdout = std::io::stdout().lock();
10937 let _ = writeln!(stdout, "eval={value}");
10938 }
10939 *value
10940 }
10941 ParserPredicate::LookaheadTextEquals { offset, text } => self
10942 .input
10943 .lt(*offset)
10944 .is_some_and(|token| Token::text(&token) == Some(*text)),
10945 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
10946 self.la(*offset) != *token_type
10947 }
10948 ParserPredicate::TokenPairAdjacent => {
10949 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
10950 return false;
10951 };
10952 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
10953 return false;
10954 };
10955 first + 1 == second
10956 }
10957 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
10958 .and_then(|context| {
10959 context
10960 .child_rules(&self.tree, self.input.token_store(), *rule_index)
10961 .next()
10962 .map(crate::tree::RuleNodeView::text)
10963 })
10964 .is_none_or(|actual| actual != *text),
10965 ParserPredicate::LocalIntEquals { value } => {
10966 local_int_arg.is_none_or(|(_, actual)| actual == *value)
10967 }
10968 ParserPredicate::LocalIntLessOrEqual { value } => {
10969 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
10970 }
10971 ParserPredicate::MemberModuloEquals {
10972 member,
10973 modulus,
10974 value,
10975 equals,
10976 } => {
10977 if *modulus == 0 {
10978 return false;
10979 }
10980 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
10981 (actual == *value) == *equals
10982 }
10983 ParserPredicate::MemberEquals {
10984 member,
10985 value,
10986 equals,
10987 } => {
10988 let actual = member_values.get(member).copied().unwrap_or_default();
10989 (actual == *value) == *equals
10990 }
10991 }
10992 }
10993
10994 fn parser_predicate_failure_message(
10996 &self,
10997 rule_index: usize,
10998 pred_index: usize,
10999 predicates: &[(usize, usize, ParserPredicate)],
11000 ) -> Option<&'static str> {
11001 predicates
11002 .iter()
11003 .find_map(|(rule, pred, predicate)| match predicate {
11004 ParserPredicate::FalseWithMessage { message }
11005 if *rule == rule_index && *pred == pred_index =>
11006 {
11007 Some(*message)
11008 }
11009 _ => None,
11010 })
11011 }
11012
11013 pub fn parser_semantic_ir_predicate_failure_message(
11016 &self,
11017 rule_index: usize,
11018 pred_index: usize,
11019 semantics: &ParserSemantics,
11020 ) -> Option<&'static str> {
11021 semantics
11022 .predicates
11023 .iter()
11024 .find(|predicate| {
11025 predicate.rule_index == rule_index && predicate.pred_index == pred_index
11026 })
11027 .and_then(|predicate| predicate.failure_message)
11028 }
11029
11030 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
11039 if symbol == TOKEN_EOF {
11040 return index;
11041 }
11042 self.input.next_visible_after(index)
11043 }
11044
11045 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
11048 let text = display_input_text(&self.input.text(start_index, error_index));
11049 diagnostic_for_token(
11050 self.token_at(error_index).as_ref(),
11051 format!("no viable alternative at input '{text}'"),
11052 )
11053 }
11054
11055 fn recovery_failure_diagnostic(
11058 &self,
11059 index: usize,
11060 decision_start_index: Option<usize>,
11061 expected_symbols: &BTreeSet<i32>,
11062 ) -> ParserDiagnostic {
11063 if expected_symbols.len() > 1 {
11064 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
11065 return self.no_viable_alternative(decision_start, index);
11066 }
11067 }
11068 diagnostic_for_token(
11069 self.token_at(index).as_ref(),
11070 format!(
11071 "mismatched input {} expecting {}",
11072 self.token_at(index)
11073 .as_ref()
11074 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
11075 self.expected_symbols_display(expected_symbols)
11076 ),
11077 )
11078 }
11079
11080 fn eof_rule_recovery_diagnostic(
11083 &self,
11084 index: usize,
11085 expected_symbols: &BTreeSet<i32>,
11086 expected: &ExpectedTokens,
11087 ) -> ParserDiagnostic {
11088 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
11089 &expected.symbols
11090 } else {
11091 expected_symbols
11092 };
11093 diagnostic_for_token(
11094 self.token_at(index).as_ref(),
11095 format!(
11096 "mismatched input {} expecting {}",
11097 self.token_at(index)
11098 .as_ref()
11099 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
11100 self.expected_symbols_display(symbols)
11101 ),
11102 )
11103 }
11104
11105 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
11111 let Some(stop) = stop else {
11112 return String::new();
11113 };
11114 let stop = if self
11115 .token_at(stop)
11116 .is_some_and(|token| token.token_type() == TOKEN_EOF)
11117 {
11118 let Some(previous) = self.previous_token_index(stop) else {
11119 return String::new();
11120 };
11121 previous
11122 } else {
11123 stop
11124 };
11125 self.input.text(start, stop)
11126 }
11127
11128 fn clear_prediction_diagnostics(&mut self) {
11131 self.prediction_diagnostics.clear();
11132 self.reported_prediction_diagnostics.clear();
11133 }
11134
11135 fn reset_per_parse_caches(&mut self) {
11159 self.rule_first_set_cache.clear();
11160 self.decision_lookahead_cache.clear();
11161 self.ll1_decision_cache.clear();
11162 self.fast_predicate_cache.clear();
11163 self.rule_stop_reach_cache.clear();
11164 self.clean_memo_mode = CleanMemoMode::Probe;
11165 self.clean_memo_probe_seen.clear();
11166 self.clean_memo_probe_samples = 0;
11167 self.clean_memo_probe_repeats = 0;
11168 self.clean_memo_sparse_samples = 0;
11169 self.recovery_symbols_intern.clear();
11170 self.state_expected_cache.clear();
11171 self.state_expected_token_cache.clear();
11172 }
11173
11174 fn record_prediction_diagnostics(
11177 &mut self,
11178 atn: &Atn,
11179 state: AtnState<'_>,
11180 start_index: usize,
11181 outcomes: &[RecognizeOutcome],
11182 ) {
11183 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
11184 return;
11185 }
11186 let Some(decision) = atn
11187 .decision_to_state()
11188 .iter()
11189 .position(|state_number| state_number == state.state_number())
11190 else {
11191 return;
11192 };
11193 let Some(rule_index) = state.rule_index() else {
11194 return;
11195 };
11196 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
11197 for outcome in outcomes
11198 .iter()
11199 .filter(|outcome| outcome.diagnostics.is_empty())
11200 {
11201 let Some(alt) = outcome.decisions.first() else {
11202 continue;
11203 };
11204 alts_by_end
11205 .entry(outcome.index)
11206 .or_default()
11207 .insert(alt + 1);
11208 }
11209 let Some((&end_index, ambig_alts)) = alts_by_end
11210 .iter()
11211 .filter(|(_, alts)| alts.len() > 1)
11212 .max_by_key(|(end, _)| *end)
11213 else {
11214 return;
11215 };
11216 let rule_name = self
11217 .rule_names()
11218 .get(rule_index)
11219 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
11220 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
11221 let input = display_input_text(&self.input.text(start_index, stop_index));
11222 let alts = ambig_alts
11223 .iter()
11224 .map(usize::to_string)
11225 .collect::<Vec<_>>()
11226 .join(", ");
11227 let key = (decision, start_index, format!("{alts}:{input}"));
11228 if !self.reported_prediction_diagnostics.insert(key) {
11229 return;
11230 }
11231 let start_diagnostic = diagnostic_for_token(
11232 self.token_at(start_index),
11233 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
11234 );
11235 let stop_diagnostic = diagnostic_for_token(
11236 self.token_at(stop_index),
11237 format!(
11238 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
11239 ),
11240 );
11241 self.prediction_diagnostics.push(start_diagnostic);
11242 self.prediction_diagnostics.push(stop_diagnostic);
11243 }
11244
11245 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
11247 expected_symbols_display(
11248 &state_expected_symbols(atn, state_number),
11249 self.vocabulary(),
11250 )
11251 }
11252
11253 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
11258 let state = usize::try_from(self.data().state()).unwrap_or(0);
11259 ExpectedTokenSet {
11260 symbols: state_expected_symbols(atn, state),
11261 }
11262 }
11263
11264 pub const fn set_bail_on_error(&mut self, bail: bool) {
11267 self.bail_on_error = bail;
11268 }
11269
11270 #[must_use]
11272 pub const fn bail_on_error(&self) -> bool {
11273 self.bail_on_error
11274 }
11275
11276 pub fn rule_invocation_stack(&self) -> Vec<String> {
11279 self.rule_context_stack
11280 .iter()
11281 .rev()
11282 .map(|frame| {
11283 self.data()
11284 .rule_names()
11285 .get(frame.rule_index)
11286 .cloned()
11287 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
11288 })
11289 .collect()
11290 }
11291
11292 pub fn active_invocation_states(&self) -> Vec<isize> {
11296 self.rule_context_stack
11297 .iter()
11298 .skip(1)
11299 .rev()
11300 .map(|frame| frame.invoking_state)
11301 .collect()
11302 }
11303
11304 pub fn token_display_at(&self, index: usize) -> Option<String> {
11306 self.token_at(index).map(|token| format!("{token}"))
11307 }
11308}
11309
11310impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
11311where
11312 S: TokenSource,
11313 H: SemanticHooks,
11314{
11315 fn parse_rule(
11316 &mut self,
11317 rule_index: usize,
11318 invoking_state: isize,
11319 precedence: i32,
11320 ) -> DirectAdaptiveParseResult<ParseTree> {
11321 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
11322 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
11323 )?;
11324 let stop_state = self
11325 .atn
11326 .rule_to_stop_state()
11327 .get(rule_index)
11328 .filter(|state| *state != usize::MAX)
11329 .ok_or(DirectAdaptiveParseControl::Fallback(
11330 DirectAdaptiveFallback::MissingAtn,
11331 ))?;
11332 let start_index = self.parser.current_visible_index();
11333 let mut context = ParserRuleContext::new(rule_index, invoking_state);
11334 if let Some(token) = self.parser.token_id_at(start_index) {
11335 self.parser.set_context_start(&mut context, token);
11336 }
11337 let mut state_number = start_state;
11338 let mut consumed_eof = false;
11339 while state_number != stop_state {
11340 self.step()?;
11341 let (transition, boundary) = self.next_transition(state_number, precedence)?;
11342 if boundary.is_some() {
11343 return Err(DirectAdaptiveParseControl::Fallback(
11344 DirectAdaptiveFallback::LeftRecursiveBoundary,
11345 ));
11346 }
11347 match transition.data() {
11348 Transition::Epsilon { target } => {
11349 state_number = target;
11350 }
11351 Transition::Precedence {
11352 target,
11353 precedence: transition_precedence,
11354 } => {
11355 if transition_precedence < precedence {
11356 return Err(DirectAdaptiveParseControl::Fallback(
11357 DirectAdaptiveFallback::Precedence,
11358 ));
11359 }
11360 state_number = target;
11361 }
11362 Transition::Rule {
11363 rule_index,
11364 follow_state,
11365 precedence: rule_precedence,
11366 ..
11367 } => {
11368 let child = self.parse_rule(
11369 rule_index,
11370 invoking_state_number(state_number),
11371 rule_precedence,
11372 )?;
11373 if self.parser.build_parse_trees {
11374 self.parser.tree.add_child(&mut context, child);
11375 }
11376 state_number = follow_state;
11377 }
11378 Transition::Atom { .. }
11379 | Transition::Range { .. }
11380 | Transition::Set { .. }
11381 | Transition::NotSet { .. }
11382 | Transition::Wildcard { .. } => {
11383 let (matched_eof, child) = self.consume_transition(transition)?;
11384 consumed_eof |= matched_eof;
11385 if let Some(child) = child {
11386 self.parser.tree.add_child(&mut context, child);
11387 }
11388 state_number = transition.target();
11389 }
11390 Transition::Predicate { .. } => {
11391 return Err(DirectAdaptiveParseControl::Fallback(
11392 DirectAdaptiveFallback::Predicate,
11393 ));
11394 }
11395 Transition::Action { .. } => {
11396 return Err(DirectAdaptiveParseControl::Fallback(
11397 DirectAdaptiveFallback::Action,
11398 ));
11399 }
11400 }
11401 }
11402
11403 let stop_index = self
11404 .parser
11405 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
11406 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
11407 self.parser.set_context_stop(&mut context, token);
11408 }
11409 Ok(self.parser.rule_node(context))
11410 }
11411
11412 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
11413 self.steps += 1;
11414 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
11415 return Err(DirectAdaptiveParseControl::Fallback(
11416 DirectAdaptiveFallback::StepLimit,
11417 ));
11418 }
11419 Ok(())
11420 }
11421
11422 fn next_transition(
11423 &mut self,
11424 state_number: usize,
11425 precedence: i32,
11426 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
11427 let state = self
11428 .atn
11429 .state(state_number)
11430 .ok_or(DirectAdaptiveParseControl::Fallback(
11431 DirectAdaptiveFallback::MissingAtn,
11432 ))?;
11433 if state.is_rule_stop() {
11434 return Err(DirectAdaptiveParseControl::Fallback(
11435 DirectAdaptiveFallback::RuleStop,
11436 ));
11437 }
11438 let transition_index =
11439 self.transition_index(state_number, state.transitions().len(), precedence)?;
11440 let transition = state.transitions().get(transition_index).ok_or(
11441 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
11442 )?;
11443 let boundary = match &transition.data() {
11444 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
11445 left_recursive_boundary(self.atn, state, *target)
11446 }
11447 _ => None,
11448 };
11449 Ok((transition, boundary))
11450 }
11451
11452 fn transition_index(
11453 &mut self,
11454 state_number: usize,
11455 transition_count: usize,
11456 precedence: i32,
11457 ) -> DirectAdaptiveParseResult<usize> {
11458 match transition_count {
11459 0 => Err(DirectAdaptiveParseControl::Fallback(
11460 DirectAdaptiveFallback::NoTransition,
11461 )),
11462 1 => Ok(0),
11463 _ => {
11464 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
11465 return Ok(alt);
11466 }
11467 let decision = self
11468 .decision_by_state
11469 .get(state_number)
11470 .and_then(|decision| *decision)
11471 .ok_or(DirectAdaptiveParseControl::Fallback(
11472 DirectAdaptiveFallback::UnknownDecision,
11473 ))?;
11474 let prediction = self
11475 .simulator
11476 .adaptive_predict_stream_info_with_precedence(
11477 decision,
11478 direct_precedence(precedence),
11479 &mut self.parser.input,
11480 )
11481 .map_err(|_| {
11482 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
11483 })?;
11484 if prediction.has_semantic_context {
11485 return Err(DirectAdaptiveParseControl::Fallback(
11486 DirectAdaptiveFallback::SemanticContext,
11487 ));
11488 }
11489 prediction
11490 .alt
11491 .checked_sub(1)
11492 .filter(|index| *index < transition_count)
11493 .ok_or(DirectAdaptiveParseControl::Fallback(
11494 DirectAdaptiveFallback::InvalidAlt,
11495 ))
11496 }
11497 }
11498 }
11499
11500 fn ll1_transition_index(
11501 &mut self,
11502 state_number: usize,
11503 transition_count: usize,
11504 ) -> DirectAdaptiveParseResult<Option<usize>> {
11505 let state = self
11506 .atn
11507 .state(state_number)
11508 .ok_or(DirectAdaptiveParseControl::Fallback(
11509 DirectAdaptiveFallback::MissingAtn,
11510 ))?;
11511 if state.precedence_rule_decision() {
11512 return Ok(None);
11513 }
11514 let Some(rule_stop) = state
11515 .rule_index()
11516 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
11517 else {
11518 return Ok(None);
11519 };
11520 let symbol = self.parser.input.la_token(1);
11521 let entry = self
11522 .parser
11523 .cached_decision_lookahead(self.atn, state, rule_stop);
11524 Ok(
11525 ll1_greedy_alt(&entry, symbol, state.non_greedy())
11526 .filter(|alt| *alt < transition_count),
11527 )
11528 }
11529
11530 fn consume_transition(
11531 &mut self,
11532 transition: ParserTransition<'_>,
11533 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
11534 let symbol = self.parser.input.la_token(1);
11535 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
11536 return Err(DirectAdaptiveParseControl::Fallback(
11537 DirectAdaptiveFallback::TokenMismatch,
11538 ));
11539 }
11540 let token = self
11541 .parser
11542 .input
11543 .lt_id(1)
11544 .ok_or(DirectAdaptiveParseControl::Fallback(
11545 DirectAdaptiveFallback::TokenMismatch,
11546 ))?;
11547 let matched_eof = symbol == TOKEN_EOF;
11548 if !matched_eof {
11549 self.parser.consume();
11550 }
11551 let child = self
11552 .parser
11553 .build_parse_trees
11554 .then(|| self.parser.terminal_tree(token));
11555 Ok((matched_eof, child))
11556 }
11557}
11558
11559fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
11562 if !state.precedence_rule_decision() {
11563 return None;
11564 }
11565 let target_state = atn.state(target)?;
11566 if target_state.kind() == AtnStateKind::LoopEnd {
11567 return None;
11568 }
11569 state.rule_index()
11570}
11571
11572fn next_alt_number(
11579 state: AtnState<'_>,
11580 transition_count: usize,
11581 transition_index: usize,
11582 current_alt_number: usize,
11583 track_alt_numbers: bool,
11584) -> usize {
11585 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
11586 return current_alt_number;
11587 }
11588 if matches!(
11589 state.kind(),
11590 AtnStateKind::Basic
11591 | AtnStateKind::BlockStart
11592 | AtnStateKind::PlusBlockStart
11593 | AtnStateKind::StarBlockStart
11594 | AtnStateKind::StarLoopEntry
11595 ) && !state.precedence_rule_decision()
11596 {
11597 return transition_index + 1;
11598 }
11599 current_alt_number
11600}
11601
11602fn invoking_state_number(state_number: usize) -> isize {
11605 isize::try_from(state_number).unwrap_or(isize::MAX)
11606}
11607
11608const fn packed_i32(value: u32) -> i32 {
11609 i32::from_le_bytes(value.to_le_bytes())
11610}
11611
11612fn direct_precedence(precedence: i32) -> usize {
11613 usize::try_from(precedence.max(0)).unwrap_or_default()
11614}
11615
11616fn token_input_display(token: &impl Token) -> String {
11617 format!("'{}'", token.text().unwrap_or("<EOF>"))
11618}
11619
11620fn display_input_text(text: &str) -> String {
11621 let mut out = String::new();
11622 for ch in text.chars() {
11623 match ch {
11624 '\n' => out.push_str("\\n"),
11625 '\r' => out.push_str("\\r"),
11626 '\t' => out.push_str("\\t"),
11627 other => out.push(other),
11628 }
11629 }
11630 out
11631}
11632
11633fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
11634 let (line, column) = token.map_or((0, 0), |token| (token.line(), token.column()));
11635 ParserDiagnostic {
11636 line,
11637 column,
11638 message,
11639 }
11640}
11641
11642fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
11643 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
11644}
11645
11646fn expected_symbols_display_iter(
11647 symbols: impl IntoIterator<Item = i32>,
11648 vocabulary: &Vocabulary,
11649) -> String {
11650 let items = symbols
11651 .into_iter()
11652 .map(|symbol| expected_symbol_display(symbol, vocabulary))
11653 .collect::<Vec<_>>();
11654 if let [single] = items.as_slice() {
11655 return single.clone();
11656 }
11657 format!("{{{}}}", items.join(", "))
11658}
11659
11660fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
11661 if symbol == TOKEN_EOF {
11662 return "<EOF>".to_owned();
11663 }
11664 vocabulary.display_name(symbol)
11665}
11666
11667fn caller_follow_token_info_for_stream<S: TokenSource>(
11668 input: &mut CommonTokenStream<S>,
11669 index: usize,
11670) -> (i32, bool, bool) {
11671 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
11674 input.fill();
11675 }
11676 let token_type = input.token_type_at_index(index);
11677 let visible_channel = input.channel();
11678 let token = input.get(index);
11679 let is_boundary = token
11680 .as_ref()
11681 .and_then(Token::text)
11682 .is_some_and(is_caller_follow_boundary_text);
11683 let is_boundary_gap = token.as_ref().is_some_and(|token| {
11684 token.channel() != visible_channel
11685 || is_caller_follow_boundary_gap_text(token.text_or_empty())
11686 });
11687 (token_type, is_boundary, is_boundary_gap)
11688}
11689
11690fn is_caller_follow_boundary_text(text: &str) -> bool {
11691 text.chars().any(|ch| ch == ';' || ch == '\n')
11692 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11693}
11694
11695fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
11696 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11697}
11698
11699fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
11703 let Some(rule_index) = state.rule_index() else {
11704 return false;
11705 };
11706 atn.rule_to_start_state()
11707 .get(rule_index)
11708 .and_then(|state_number| atn.state(state_number))
11709 .is_some_and(AtnState::left_recursive_rule)
11710}
11711
11712fn select_better_top_outcome(
11719 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
11720 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
11721 arena: &RecognitionArena,
11722) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
11723 match (first, second) {
11724 (Ok(first), Ok(second)) => {
11725 if arena.diagnostics(first.0.diagnostics).next().is_none() {
11726 Ok(first)
11727 } else {
11728 Ok(second)
11729 }
11730 }
11731 (Ok(first), Err(_)) => Ok(first),
11732 (Err(_), Ok(second)) => Ok(second),
11733 (Err(_), Err(second_expected)) => Err(second_expected),
11734 }
11735}
11736
11737fn select_best_fast_outcome(
11743 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
11744 prediction_mode: PredictionMode,
11745 caller_follow: Option<&TokenBitSet>,
11746 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
11747 arena: &RecognitionArena,
11748) -> Option<FastRecognizeOutcome> {
11749 let mut best = None;
11750 let mut best_caller_follow = None;
11751 for outcome in outcomes {
11752 if matches!(
11753 prediction_mode,
11754 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
11755 ) && outcome.diagnostics.is_empty()
11756 && let Some(follow) = caller_follow
11757 {
11758 let (token_type, is_boundary, _) = token_info_at(outcome.index);
11759 if is_boundary && follow.contains(token_type) {
11760 let replace =
11761 best_caller_follow
11762 .as_ref()
11763 .is_none_or(|existing: &FastRecognizeOutcome| {
11764 (outcome.index, outcome.consumed_eof)
11765 < (existing.index, existing.consumed_eof)
11766 });
11767 if replace {
11768 best_caller_follow = Some(outcome);
11769 }
11770 }
11771 }
11772 let Some(existing) = best else {
11773 best = Some(outcome);
11774 continue;
11775 };
11776 let outcome_position = (outcome.index, outcome.consumed_eof);
11777 let best_position = (existing.index, existing.consumed_eof);
11778 let better = match prediction_mode {
11779 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
11780 outcome_position,
11781 outcome.diagnostics,
11782 best_position,
11783 existing.diagnostics,
11784 arena,
11785 ),
11786 PredictionMode::Sll => outcome.index > existing.index,
11787 };
11788 best = Some(if better { outcome } else { existing });
11789 }
11790 let should_use_caller_follow =
11791 best_caller_follow
11792 .as_ref()
11793 .zip(best.as_ref())
11794 .is_some_and(|(candidate, selected)| {
11795 if !selected.diagnostics.is_empty() {
11796 return true;
11797 }
11798 candidate.index < selected.index
11799 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
11800 });
11801 if should_use_caller_follow {
11802 best_caller_follow
11803 } else {
11804 best
11805 }
11806}
11807
11808fn select_best_outcome(
11809 outcomes: impl Iterator<Item = RecognizeOutcome>,
11810 prediction_mode: PredictionMode,
11811 arena: &RecognitionArena,
11812) -> Option<RecognizeOutcome> {
11813 let outcomes = outcomes.collect::<Vec<_>>();
11814 let prefer_first_tie = outcomes
11815 .iter()
11816 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
11817 outcomes.into_iter().reduce(|best, outcome| {
11818 let outcome_position = (outcome.index, outcome.consumed_eof);
11819 let best_position = (best.index, best.consumed_eof);
11820 let better = match prediction_mode {
11821 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
11822 outcome_is_better(
11823 outcome_position,
11824 outcome.diagnostics,
11825 best_position,
11826 best.diagnostics,
11827 arena,
11828 ) || (!prefer_first_tie
11829 && outcome_position == best_position
11830 && arena.diagnostics_len(outcome.diagnostics)
11831 == arena.diagnostics_len(best.diagnostics)
11832 && arena.diagnostics_recovery_rank(outcome.diagnostics)
11833 == arena.diagnostics_recovery_rank(best.diagnostics)
11834 && (outcome.decisions < best.decisions
11835 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
11836 }
11837 PredictionMode::Sll => {
11838 outcome_position > best_position
11839 || (outcome_position == best_position
11840 && !prefer_first_tie
11841 && (outcome.decisions < best.decisions
11842 || (outcome.decisions == best.decisions
11843 && outcome_is_better(
11844 outcome_position,
11845 outcome.diagnostics,
11846 best_position,
11847 best.diagnostics,
11848 arena,
11849 ))))
11850 }
11851 };
11852 if better {
11853 return outcome;
11854 }
11855 best
11856 })
11857}
11858
11859fn transition_decision(
11866 atn: &Atn,
11867 state: AtnState<'_>,
11868 transition_count: usize,
11869 transition_index: usize,
11870 predicates: &[(usize, usize, ParserPredicate)],
11871) -> Option<usize> {
11872 if transition_count <= 1
11873 || state.precedence_rule_decision()
11874 || decision_reaches_unsupported_predicate(atn, state, predicates)
11875 {
11876 return None;
11877 }
11878 Some(transition_index)
11879}
11880
11881fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
11887 transition_count > 1
11888 && !matches!(
11889 state.kind(),
11890 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
11891 )
11892}
11893
11894fn record_no_viable_if_ambiguous(
11897 expected: &mut ExpectedTokens,
11898 decision_start_index: Option<usize>,
11899 index: usize,
11900) {
11901 if expected.index == Some(index) && expected.symbols.len() > 1 {
11902 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
11903 expected.record_no_viable(decision_start, index);
11904 }
11905 }
11906}
11907
11908const fn record_predicate_no_viable(
11911 expected: &mut ExpectedTokens,
11912 decision_start_index: Option<usize>,
11913 index: usize,
11914) {
11915 if let Some(decision_start) = decision_start_index {
11916 expected.record_no_viable(decision_start, index);
11917 }
11918}
11919
11920const fn no_viable_decision_start(
11922 decision_start_index: Option<usize>,
11923 index: usize,
11924) -> Option<usize> {
11925 match decision_start_index {
11926 Some(start) if index > start => Some(start),
11927 _ => None,
11928 }
11929}
11930
11931fn restore_expected(
11935 children: &[RecognizeOutcome],
11936 child_start_index: usize,
11937 expected: &mut ExpectedTokens,
11938 snapshot: ExpectedTokens,
11939 preserve_child_expected: bool,
11940) {
11941 if preserve_child_expected {
11942 return;
11943 }
11944 if children
11945 .iter()
11946 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
11947 {
11948 *expected = snapshot;
11949 }
11950}
11951
11952fn decision_reaches_unsupported_predicate(
11955 atn: &Atn,
11956 state: AtnState<'_>,
11957 predicates: &[(usize, usize, ParserPredicate)],
11958) -> bool {
11959 state.transitions().iter().any(|transition| {
11960 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
11961 })
11962}
11963
11964fn transition_reaches_unsupported_predicate(
11966 atn: &Atn,
11967 transition: ParserTransition<'_>,
11968 predicates: &[(usize, usize, ParserPredicate)],
11969 visited: &mut BTreeSet<usize>,
11970) -> bool {
11971 match &transition.data() {
11972 Transition::Predicate {
11973 rule_index,
11974 pred_index,
11975 ..
11976 } => !predicates
11977 .iter()
11978 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
11979 Transition::Epsilon { target }
11980 | Transition::Action { target, .. }
11981 | Transition::Rule { target, .. } => {
11982 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
11983 }
11984 Transition::Precedence { .. }
11985 | Transition::Atom { .. }
11986 | Transition::Range { .. }
11987 | Transition::Set { .. }
11988 | Transition::NotSet { .. }
11989 | Transition::Wildcard { .. } => false,
11990 }
11991}
11992
11993fn state_reaches_unsupported_predicate(
11995 atn: &Atn,
11996 state_number: usize,
11997 predicates: &[(usize, usize, ParserPredicate)],
11998 visited: &mut BTreeSet<usize>,
11999) -> bool {
12000 if !visited.insert(state_number) {
12001 return false;
12002 }
12003 let Some(state) = atn.state(state_number) else {
12004 return false;
12005 };
12006 state.transitions().iter().any(|transition| {
12007 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
12008 })
12009}
12010
12011fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
12013 if let Some(decision) = decision {
12014 outcome.decisions.insert(0, decision);
12015 }
12016}
12017
12018fn outcome_is_better(
12019 outcome_position: (usize, bool),
12020 outcome_diagnostics: DiagnosticSeqId,
12021 best_position: (usize, bool),
12022 best_diagnostics: DiagnosticSeqId,
12023 arena: &RecognitionArena,
12024) -> bool {
12025 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
12026 let best_len = arena.diagnostics_len(best_diagnostics);
12027 outcome_position > best_position
12028 || (outcome_position == best_position
12029 && (outcome_len < best_len
12030 || (outcome_len == best_len
12031 && arena.diagnostics_recovery_rank(outcome_diagnostics)
12032 < arena.diagnostics_recovery_rank(best_diagnostics))))
12033}
12034
12035fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
12036 if outcomes
12037 .iter()
12038 .any(|outcome| outcome.diagnostics.is_empty())
12039 {
12040 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
12041 }
12042}
12043
12044fn discard_recovered_outcomes_if_clean_path_exists(
12045 outcomes: &mut Vec<RecognizeOutcome>,
12046 arena: &RecognitionArena,
12047) {
12048 if outcomes
12049 .iter()
12050 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
12051 {
12052 return;
12053 }
12054 if outcomes
12055 .iter()
12056 .any(|outcome| outcome.diagnostics.is_empty())
12057 {
12058 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
12059 }
12060}
12061
12062fn outcome_has_rule_failure_diagnostic(
12065 outcome: &RecognizeOutcome,
12066 arena: &RecognitionArena,
12067) -> bool {
12068 arena
12069 .diagnostics(outcome.diagnostics)
12070 .any(|diagnostic| diagnostic.message.starts_with("rule "))
12071}
12072
12073fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
12087 if outcomes.len() < 2 {
12088 return;
12089 }
12090 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
12091 outcomes.retain(|outcome| {
12092 seen.insert((
12093 outcome.index,
12094 outcome.consumed_eof,
12095 arena.diagnostics_len(outcome.diagnostics),
12096 arena.diagnostics_recovery_rank(outcome.diagnostics),
12097 ))
12098 });
12099}
12100
12101const FAST_OUTCOME_INLINE_KEYS: usize = 8;
12102const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
12103const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
12104const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
12105
12106#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12107enum FastOutcomeDedupStrategy {
12108 Inline,
12109 Dense,
12110 Sparse,
12111}
12112
12113impl FastOutcomeDedupScratch {
12114 fn prepare_dense(&mut self, word_count: usize) {
12115 while let Some(word_index) = self.touched_dense_words.pop() {
12116 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
12117 }
12118 if self.dense_words.len() < word_count {
12119 self.dense_words.resize(word_count, 0);
12120 }
12121 }
12122}
12123
12124fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
12125 let first_index = outcomes.first()?.index;
12126 let (min_index, max_index) = outcomes[1..].iter().fold(
12127 (first_index, first_index),
12128 |(min_index, max_index), outcome| {
12129 (min_index.min(outcome.index), max_index.max(outcome.index))
12130 },
12131 );
12132 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
12133 let bit_count = index_span.checked_mul(2)?;
12134 let word_count =
12135 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
12136 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
12137 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
12138 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
12139 .then_some((min_index, word_count))
12140}
12141
12142#[cfg(feature = "perf-counters")]
12143fn record_clean_fast_outcome_dedup(
12144 strategy: FastOutcomeDedupStrategy,
12145 input_len: usize,
12146 output_len: usize,
12147 dense_words: usize,
12148) {
12149 let counter = match strategy {
12150 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
12151 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
12152 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
12153 };
12154 perf_counters::inc(
12155 &perf_counters::OUTCOME_DEDUPE_INPUTS,
12156 u64::try_from(input_len).unwrap_or(u64::MAX),
12157 );
12158 perf_counters::inc(
12159 &perf_counters::OUTCOME_DEDUPE_REMOVED,
12160 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
12161 );
12162 perf_counters::inc(counter, 1);
12163 perf_counters::inc(
12164 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
12165 u64::try_from(dense_words).unwrap_or(u64::MAX),
12166 );
12167}
12168
12169fn dedupe_clean_fast_outcomes(
12173 outcomes: &mut Vec<FastRecognizeOutcome>,
12174 scratch: &mut FastOutcomeDedupScratch,
12175) -> FastOutcomeDedupStrategy {
12176 #[cfg(feature = "perf-counters")]
12177 let input_len = outcomes.len();
12178 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
12179 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
12180 let mut inline_len = 0_usize;
12181 outcomes.retain(|outcome| {
12182 let key = (outcome.index, outcome.consumed_eof);
12183 if inline_keys[..inline_len].contains(&key) {
12184 return false;
12185 }
12186 inline_keys[inline_len] = key;
12187 inline_len += 1;
12188 true
12189 });
12190 #[cfg(feature = "perf-counters")]
12191 record_clean_fast_outcome_dedup(
12192 FastOutcomeDedupStrategy::Inline,
12193 input_len,
12194 outcomes.len(),
12195 0,
12196 );
12197 return FastOutcomeDedupStrategy::Inline;
12198 }
12199
12200 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
12201 scratch.prepare_dense(word_count);
12202 outcomes.retain(|outcome| {
12203 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
12204 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
12205 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
12206 let word = &mut scratch.dense_words[word_index];
12207 if *word & bit != 0 {
12208 return false;
12209 }
12210 if *word == 0 {
12211 scratch
12212 .touched_dense_words
12213 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
12214 }
12215 *word |= bit;
12216 true
12217 });
12218 #[cfg(feature = "perf-counters")]
12219 record_clean_fast_outcome_dedup(
12220 FastOutcomeDedupStrategy::Dense,
12221 input_len,
12222 outcomes.len(),
12223 word_count,
12224 );
12225 return FastOutcomeDedupStrategy::Dense;
12226 }
12227
12228 scratch.sparse_keys.clear();
12229 scratch.sparse_keys.reserve(outcomes.len());
12230 outcomes.retain(|outcome| {
12231 scratch
12232 .sparse_keys
12233 .insert((outcome.index, outcome.consumed_eof))
12234 });
12235 #[cfg(feature = "perf-counters")]
12236 record_clean_fast_outcome_dedup(
12237 FastOutcomeDedupStrategy::Sparse,
12238 input_len,
12239 outcomes.len(),
12240 0,
12241 );
12242 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
12243 scratch.sparse_keys = FxHashSet::default();
12244 }
12245 FastOutcomeDedupStrategy::Sparse
12246}
12247
12248fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
12251 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
12252 outcomes
12253 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
12254}
12255
12256fn compare_recognize_outcomes(
12257 left: &RecognizeOutcome,
12258 right: &RecognizeOutcome,
12259 arena: &RecognitionArena,
12260) -> Ordering {
12261 left.index
12262 .cmp(&right.index)
12263 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
12264 .then_with(|| left.alt_number.cmp(&right.alt_number))
12265 .then_with(|| left.member_values.cmp(&right.member_values))
12266 .then_with(|| left.return_values.cmp(&right.return_values))
12267 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
12268 .then_with(|| left.decisions.cmp(&right.decisions))
12269 .then_with(|| left.actions.cmp(&right.actions))
12270 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
12271}
12272
12273impl<S, H> Recognizer for BaseParser<S, H>
12274where
12275 S: TokenSource,
12276 H: SemanticHooks,
12277{
12278 fn data(&self) -> &RecognizerData {
12279 &self.data
12280 }
12281
12282 fn data_mut(&mut self) -> &mut RecognizerData {
12283 &mut self.data
12284 }
12285}
12286
12287impl<S, H> Parser for BaseParser<S, H>
12288where
12289 S: TokenSource,
12290 H: SemanticHooks,
12291{
12292 fn build_parse_trees(&self) -> bool {
12293 self.build_parse_trees
12294 }
12295
12296 fn set_build_parse_trees(&mut self, build: bool) {
12297 self.build_parse_trees = build;
12298 }
12299
12300 fn number_of_syntax_errors(&self) -> usize {
12301 Self::number_of_syntax_errors(self)
12302 }
12303
12304 fn report_diagnostic_errors(&self) -> bool {
12305 self.report_diagnostic_errors
12306 }
12307
12308 fn set_report_diagnostic_errors(&mut self, report: bool) {
12309 self.report_diagnostic_errors = report;
12310 }
12311
12312 fn prediction_mode(&self) -> PredictionMode {
12313 self.prediction_mode
12314 }
12315
12316 fn set_prediction_mode(&mut self, mode: PredictionMode) {
12317 self.prediction_mode = mode;
12318 }
12319}
12320
12321#[cfg(test)]
12322mod tests {
12323 use super::*;
12324 use crate::atn::parser::{
12325 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
12326 };
12327 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
12328 use crate::token::{
12329 DEFAULT_CHANNEL, HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError,
12330 };
12331 use crate::token_stream::CommonTokenStream;
12332 use crate::tree::{NodeKind, ParseTreeStats};
12333 use crate::vocabulary::Vocabulary;
12334 use std::cell::RefCell;
12335 use std::mem::size_of;
12336 use std::rc::Rc;
12337 use std::sync::{Arc, Mutex};
12338
12339 #[test]
12340 fn fx_hasher_write_matches_typed_methods_for_full_words() {
12341 let value: u64 = 0x0102_0304_0506_0708;
12348 let mut typed = FxHasher::default();
12349 typed.write_u64(value);
12350 let mut bytewise = FxHasher::default();
12351 bytewise.write(&value.to_le_bytes());
12352 assert_eq!(typed.finish(), bytewise.finish());
12353 }
12354
12355 #[derive(Clone, Debug)]
12356 struct TestToken {
12357 spec: TokenSpec,
12358 id: TokenId,
12359 source_name: String,
12360 }
12361
12362 impl TestToken {
12363 fn new(token_type: i32) -> Self {
12364 Self {
12365 spec: TokenSpec::explicit(token_type, ""),
12366 id: TokenId::try_from(0).expect("zero token ID"),
12367 source_name: String::new(),
12368 }
12369 }
12370
12371 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
12372 Self {
12373 spec: TokenSpec::eof(index, index, line, column),
12374 id: TokenId::try_from(0).expect("zero token ID"),
12375 source_name: source_name.to_owned(),
12376 }
12377 }
12378
12379 fn with_text(mut self, text: impl Into<String>) -> Self {
12380 self.spec.text = Some(text.into());
12381 self
12382 }
12383
12384 const fn with_channel(mut self, channel: i32) -> Self {
12385 self.spec.channel = channel;
12386 self
12387 }
12388
12389 const fn with_span(mut self, start: usize, stop: usize) -> Self {
12390 self.spec.start = start;
12391 self.spec.stop = stop;
12392 self.spec.start_byte = start;
12393 self.spec.stop_byte = match stop.checked_add(1) {
12394 Some(end) if end >= start => end,
12395 Some(_) | None => start,
12396 };
12397 self
12398 }
12399
12400 const fn with_position(mut self, line: usize, column: usize) -> Self {
12401 self.spec.line = line;
12402 self.spec.column = column;
12403 self
12404 }
12405
12406 fn set_token_index(&mut self, index: isize) {
12407 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
12408 }
12409 }
12410
12411 impl Token for TestToken {
12412 fn token_id(&self) -> TokenId {
12413 self.id
12414 }
12415
12416 fn token_type(&self) -> i32 {
12417 self.spec.token_type
12418 }
12419
12420 fn channel(&self) -> i32 {
12421 self.spec.channel
12422 }
12423
12424 fn start(&self) -> usize {
12425 self.spec.start
12426 }
12427
12428 fn stop(&self) -> usize {
12429 self.spec.stop
12430 }
12431
12432 fn line(&self) -> usize {
12433 self.spec.line
12434 }
12435
12436 fn column(&self) -> usize {
12437 self.spec.column
12438 }
12439
12440 fn text(&self) -> Option<&str> {
12441 self.spec.text.as_deref()
12442 }
12443
12444 fn source_name(&self) -> &str {
12445 &self.source_name
12446 }
12447
12448 fn start_byte(&self) -> usize {
12449 self.spec.start_byte
12450 }
12451
12452 fn stop_byte(&self) -> usize {
12453 self.spec.stop_byte
12454 }
12455 }
12456
12457 #[derive(Debug)]
12458 struct Source {
12459 tokens: Vec<TestToken>,
12460 index: usize,
12461 }
12462
12463 impl TokenSource for Source {
12464 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
12465 let token = self
12466 .tokens
12467 .get(self.index)
12468 .cloned()
12469 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
12470 self.index += 1;
12471 sink.push(token.spec)
12472 }
12473
12474 fn line(&self) -> usize {
12475 1
12476 }
12477
12478 fn column(&self) -> usize {
12479 self.index
12480 }
12481
12482 fn source_name(&self) -> &'static str {
12483 "parser-test"
12484 }
12485 }
12486
12487 #[derive(Clone, Debug, Eq, PartialEq)]
12488 struct RecordedDiagnostic {
12489 grammar_file_name: String,
12490 line: usize,
12491 column: usize,
12492 message: String,
12493 error: Option<AntlrError>,
12494 }
12495
12496 #[derive(Clone, Debug)]
12497 struct RecordingErrorListener {
12498 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
12499 }
12500
12501 impl<R> crate::ErrorListener<R> for RecordingErrorListener
12502 where
12503 R: Recognizer + ?Sized,
12504 {
12505 fn syntax_error(
12506 &mut self,
12507 recognizer: &R,
12508 line: usize,
12509 column: usize,
12510 message: &str,
12511 error: Option<&AntlrError>,
12512 ) {
12513 self.diagnostics
12514 .lock()
12515 .expect("recorded diagnostics lock")
12516 .push(RecordedDiagnostic {
12517 grammar_file_name: recognizer.grammar_file_name().to_owned(),
12518 line,
12519 column,
12520 message: message.to_owned(),
12521 error: error.cloned(),
12522 });
12523 }
12524 }
12525
12526 #[derive(Debug)]
12527 struct ReportingSource {
12528 source: Source,
12529 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
12530 }
12531
12532 impl TokenSource for ReportingSource {
12533 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
12534 self.source.next_token(sink)
12535 }
12536
12537 fn line(&self) -> usize {
12538 self.source.line()
12539 }
12540
12541 fn column(&self) -> usize {
12542 self.source.column()
12543 }
12544
12545 fn source_name(&self) -> &str {
12546 self.source.source_name()
12547 }
12548
12549 fn report_error(&self, error: &TokenSourceError) -> bool {
12550 self.diagnostics.borrow_mut().push(error.clone());
12551 true
12552 }
12553 }
12554
12555 fn mini_parser_data() -> RecognizerData {
12556 RecognizerData::new(
12557 "Mini.g4",
12558 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
12559 )
12560 .with_rule_names(["s"])
12561 }
12562
12563 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
12564 let data = mini_parser_data();
12565 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
12566 }
12567
12568 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
12569 where
12570 H: SemanticHooks,
12571 {
12572 BaseParser::with_semantic_hooks(
12573 CommonTokenStream::new(Source { tokens, index: 0 }),
12574 mini_parser_data(),
12575 hooks,
12576 )
12577 }
12578
12579 #[test]
12580 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
12581 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
12582 parser.remove_error_listeners();
12583 let diagnostics = Arc::new(Mutex::new(Vec::new()));
12584 parser.add_error_listener(RecordingErrorListener {
12585 diagnostics: Arc::clone(&diagnostics),
12586 });
12587 let parser_diagnostics = [ParserDiagnostic {
12588 line: 1,
12589 column: 2,
12590 message: "missing 'x' at 'y'".to_owned(),
12591 }];
12592 let token_errors = [
12593 TokenSourceError::new(1, 1, "token recognition error at: '@'"),
12594 TokenSourceError::new(1, 3, "token recognition error at: '#'"),
12595 ];
12596
12597 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
12598
12599 assert_eq!(
12600 *diagnostics.lock().expect("recorded diagnostics lock"),
12601 [
12602 RecordedDiagnostic {
12603 grammar_file_name: "Mini.g4".to_owned(),
12604 line: 1,
12605 column: 1,
12606 message: "token recognition error at: '@'".to_owned(),
12607 error: None,
12608 },
12609 RecordedDiagnostic {
12610 grammar_file_name: "Mini.g4".to_owned(),
12611 line: 1,
12612 column: 2,
12613 message: "missing 'x' at 'y'".to_owned(),
12614 error: None,
12615 },
12616 RecordedDiagnostic {
12617 grammar_file_name: "Mini.g4".to_owned(),
12618 line: 1,
12619 column: 3,
12620 message: "token recognition error at: '#'".to_owned(),
12621 error: None,
12622 },
12623 ]
12624 );
12625
12626 parser.remove_error_listeners();
12627 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
12628 assert_eq!(
12629 diagnostics.lock().expect("recorded diagnostics lock").len(),
12630 3
12631 );
12632 }
12633
12634 #[test]
12635 fn parser_leaves_token_errors_to_source_owned_listeners() {
12636 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
12637 let source = ReportingSource {
12638 source: Source {
12639 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
12640 index: 0,
12641 },
12642 diagnostics: Rc::clone(&source_diagnostics),
12643 };
12644 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
12645 parser.remove_error_listeners();
12646 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
12647 parser.add_error_listener(RecordingErrorListener {
12648 diagnostics: Arc::clone(&parser_diagnostics),
12649 });
12650 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
12651
12652 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
12653
12654 assert_eq!(*source_diagnostics.borrow(), [source_error]);
12655 assert!(
12656 parser_diagnostics
12657 .lock()
12658 .expect("recorded diagnostics lock")
12659 .is_empty()
12660 );
12661 }
12662
12663 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
12664 builder.finish().expect("valid packed parser ATN")
12665 }
12666
12667 fn nested_rule_chain_atn(depth: usize) -> Atn {
12668 nested_rule_graph_atn(depth, false, false)
12669 }
12670
12671 fn nested_rule_graph_atn(depth: usize, branching: bool, consuming_follows: bool) -> Atn {
12672 assert!(depth > 0);
12673 let mut atn = ParserAtnBuilder::new(2);
12674 let mut starts = Vec::with_capacity(depth);
12675 let mut stops = Vec::with_capacity(depth);
12676 let mut follows = Vec::with_capacity(depth.saturating_sub(1));
12677 for rule_index in 0..depth {
12678 starts.push(
12679 atn.add_state(AtnStateKind::RuleStart, Some(rule_index))
12680 .expect("rule start")
12681 .index(),
12682 );
12683 }
12684 for rule_index in 0..depth {
12685 stops.push(
12686 atn.add_state(AtnStateKind::RuleStop, Some(rule_index))
12687 .expect("rule stop")
12688 .index(),
12689 );
12690 }
12691 if consuming_follows {
12692 for rule_index in 0..depth - 1 {
12693 follows.push(
12694 atn.add_state(AtnStateKind::Basic, Some(rule_index))
12695 .expect("rule follow")
12696 .index(),
12697 );
12698 }
12699 }
12700 atn.set_rule_to_start_state(starts.clone())
12701 .expect("rule start states");
12702 atn.set_rule_to_stop_state(stops.clone())
12703 .expect("rule stop states");
12704 for rule_index in 0..depth - 1 {
12705 let follow_state = if consuming_follows {
12706 follows[rule_index]
12707 } else {
12708 stops[rule_index]
12709 };
12710 atn.add_transition(
12711 starts[rule_index],
12712 ParserTransitionSpec::Rule {
12713 target: starts[rule_index + 1],
12714 rule_index: rule_index + 1,
12715 follow_state,
12716 precedence: 0,
12717 },
12718 )
12719 .expect("nested rule transition");
12720 if branching {
12721 atn.add_transition(
12722 starts[rule_index],
12723 ParserTransitionSpec::Atom {
12724 target: stops[rule_index],
12725 label: 2,
12726 },
12727 )
12728 .expect("dead branch transition");
12729 }
12730 if consuming_follows {
12731 atn.add_transition(
12732 follow_state,
12733 ParserTransitionSpec::Atom {
12734 target: stops[rule_index],
12735 label: 1,
12736 },
12737 )
12738 .expect("consuming follow transition");
12739 }
12740 }
12741 let token_set = atn.add_interval_set([(1, 1)]).expect("token set");
12742 atn.add_transition(
12743 starts[depth - 1],
12744 ParserTransitionSpec::Set {
12745 target: stops[depth - 1],
12746 set: token_set,
12747 },
12748 )
12749 .expect("terminal set transition");
12750 if branching {
12751 atn.add_transition(
12752 starts[depth - 1],
12753 ParserTransitionSpec::Atom {
12754 target: stops[depth - 1],
12755 label: 2,
12756 },
12757 )
12758 .expect("dead leaf branch transition");
12759 }
12760 finish_atn(atn)
12761 }
12762
12763 fn ordinary_star_loop_atn() -> Atn {
12764 let mut atn = ParserAtnBuilder::new(2);
12765 for (state_number, kind, rule_index) in [
12766 (0, AtnStateKind::RuleStart, 0),
12767 (1, AtnStateKind::StarLoopEntry, 0),
12768 (2, AtnStateKind::Basic, 0),
12769 (3, AtnStateKind::StarLoopBack, 0),
12770 (4, AtnStateKind::LoopEnd, 0),
12771 (5, AtnStateKind::Basic, 0),
12772 (6, AtnStateKind::RuleStop, 0),
12773 (7, AtnStateKind::RuleStart, 1),
12774 (8, AtnStateKind::Basic, 1),
12775 (9, AtnStateKind::RuleStop, 1),
12776 ] {
12777 assert_eq!(
12778 atn.add_state(kind, Some(rule_index))
12779 .expect("state")
12780 .index(),
12781 state_number
12782 );
12783 }
12784 atn.set_rule_to_start_state(vec![0, 7])
12785 .expect("rule start states");
12786 atn.set_rule_to_stop_state(vec![6, 9])
12787 .expect("rule stop states");
12788 atn.add_decision_state(1).expect("decision state");
12789 atn.set_loop_back_state(4, 3).expect("loop back state");
12790 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12791 .expect("transition");
12792 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12793 .expect("transition");
12794 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
12795 .expect("transition");
12796 atn.add_transition(
12797 2,
12798 ParserTransitionSpec::Rule {
12799 target: 7,
12800 rule_index: 1,
12801 follow_state: 3,
12802 precedence: 0,
12803 },
12804 )
12805 .expect("transition");
12806 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
12807 .expect("transition");
12808 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12809 .expect("transition");
12810 atn.add_transition(
12811 5,
12812 ParserTransitionSpec::Atom {
12813 target: 6,
12814 label: TOKEN_EOF,
12815 },
12816 )
12817 .expect("transition");
12818 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
12819 .expect("transition");
12820 atn.add_transition(
12821 8,
12822 ParserTransitionSpec::Atom {
12823 target: 9,
12824 label: 1,
12825 },
12826 )
12827 .expect("transition");
12828 finish_atn(atn)
12829 }
12830
12831 fn ambiguous_ordinary_star_loop_atn() -> Atn {
12833 let mut atn = ParserAtnBuilder::new(1);
12834 for (state_number, kind) in [
12835 (0, AtnStateKind::RuleStart),
12836 (1, AtnStateKind::StarLoopEntry),
12837 (2, AtnStateKind::StarBlockStart),
12838 (3, AtnStateKind::Basic),
12839 (4, AtnStateKind::BlockEnd),
12840 (5, AtnStateKind::StarLoopBack),
12841 (6, AtnStateKind::LoopEnd),
12842 (7, AtnStateKind::Basic),
12843 (8, AtnStateKind::RuleStop),
12844 ] {
12845 assert_eq!(
12846 atn.add_state(kind, Some(0)).expect("state").index(),
12847 state_number
12848 );
12849 }
12850 atn.set_rule_to_start_state(vec![0])
12851 .expect("rule start states");
12852 atn.set_rule_to_stop_state(vec![8])
12853 .expect("rule stop states");
12854 atn.set_end_state(2, 4).expect("block end state");
12855 atn.set_loop_back_state(6, 5).expect("loop back state");
12856 atn.add_decision_state(1).expect("decision state");
12857 atn.add_decision_state(2).expect("decision state");
12858 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12859 .expect("transition");
12860 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12861 .expect("transition");
12862 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
12863 .expect("transition");
12864 atn.add_transition(
12865 2,
12866 ParserTransitionSpec::Atom {
12867 target: 4,
12868 label: 1,
12869 },
12870 )
12871 .expect("transition");
12872 atn.add_transition(
12873 2,
12874 ParserTransitionSpec::Atom {
12875 target: 3,
12876 label: 1,
12877 },
12878 )
12879 .expect("transition");
12880 atn.add_transition(
12881 3,
12882 ParserTransitionSpec::Atom {
12883 target: 4,
12884 label: 1,
12885 },
12886 )
12887 .expect("transition");
12888 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12889 .expect("transition");
12890 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
12891 .expect("transition");
12892 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12893 .expect("transition");
12894 atn.add_transition(
12895 7,
12896 ParserTransitionSpec::Atom {
12897 target: 8,
12898 label: TOKEN_EOF,
12899 },
12900 )
12901 .expect("transition");
12902 finish_atn(atn)
12903 }
12904
12905 fn ordinary_plus_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::Basic, 0),
12910 (2, AtnStateKind::PlusLoopBack, 0),
12911 (3, AtnStateKind::LoopEnd, 0),
12912 (4, AtnStateKind::Basic, 0),
12913 (5, AtnStateKind::RuleStop, 0),
12914 (6, AtnStateKind::RuleStart, 1),
12915 (7, AtnStateKind::Basic, 1),
12916 (8, AtnStateKind::RuleStop, 1),
12917 ] {
12918 assert_eq!(
12919 atn.add_state(kind, Some(rule_index))
12920 .expect("state")
12921 .index(),
12922 state_number
12923 );
12924 }
12925 atn.set_rule_to_start_state(vec![0, 6])
12926 .expect("rule start states");
12927 atn.set_rule_to_stop_state(vec![5, 8])
12928 .expect("rule stop states");
12929 atn.add_decision_state(2).expect("decision state");
12930 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12931 .expect("transition");
12932 atn.add_transition(
12933 1,
12934 ParserTransitionSpec::Rule {
12935 target: 6,
12936 rule_index: 1,
12937 follow_state: 2,
12938 precedence: 0,
12939 },
12940 )
12941 .expect("transition");
12942 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
12943 .expect("transition");
12944 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12945 .expect("transition");
12946 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
12947 .expect("transition");
12948 atn.add_transition(
12949 4,
12950 ParserTransitionSpec::Atom {
12951 target: 5,
12952 label: TOKEN_EOF,
12953 },
12954 )
12955 .expect("transition");
12956 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12957 .expect("transition");
12958 atn.add_transition(
12959 7,
12960 ParserTransitionSpec::Atom {
12961 target: 8,
12962 label: 1,
12963 },
12964 )
12965 .expect("transition");
12966 finish_atn(atn)
12967 }
12968
12969 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
12970 let mut tokens = (0..count)
12971 .map(|_| TestToken::new(1).with_text("x"))
12972 .collect::<Vec<_>>();
12973 tokens.push(TestToken::eof("parser-test", count, 1, count));
12974 tokens
12975 }
12976
12977 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
12978 let mut atn = ParserAtnBuilder::new(2);
12979 assert_eq!(
12980 atn.add_state(AtnStateKind::RuleStart, Some(0))
12981 .expect("state")
12982 .index(),
12983 0
12984 );
12985 assert_eq!(
12986 atn.add_state(AtnStateKind::Basic, Some(0))
12987 .expect("state")
12988 .index(),
12989 1
12990 );
12991 assert_eq!(
12992 atn.add_state(AtnStateKind::Basic, Some(0))
12993 .expect("state")
12994 .index(),
12995 2
12996 );
12997 assert_eq!(
12998 atn.add_state(AtnStateKind::RuleStart, Some(1))
12999 .expect("state")
13000 .index(),
13001 3
13002 );
13003 atn.set_left_recursive_rule(3)
13004 .expect("left-recursive rule start");
13005 assert_eq!(
13006 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
13007 .expect("state")
13008 .index(),
13009 4
13010 );
13011 atn.set_precedence_rule_decision(4)
13012 .expect("precedence decision");
13013 assert_eq!(
13014 atn.add_state(AtnStateKind::Basic, Some(1))
13015 .expect("state")
13016 .index(),
13017 5
13018 );
13019 assert_eq!(
13020 atn.add_state(AtnStateKind::Basic, Some(1))
13021 .expect("state")
13022 .index(),
13023 6
13024 );
13025 assert_eq!(
13026 atn.add_state(AtnStateKind::LoopEnd, Some(1))
13027 .expect("state")
13028 .index(),
13029 7
13030 );
13031 assert_eq!(
13032 atn.add_state(AtnStateKind::RuleStop, Some(1))
13033 .expect("state")
13034 .index(),
13035 8
13036 );
13037 assert_eq!(
13038 atn.add_state(AtnStateKind::RuleStop, Some(0))
13039 .expect("state")
13040 .index(),
13041 9
13042 );
13043 atn.set_rule_to_start_state(vec![0, 3])
13044 .expect("rule start states");
13045 atn.set_rule_to_stop_state(vec![9, 8])
13046 .expect("rule stop states");
13047 atn.add_transition(
13048 1,
13049 ParserTransitionSpec::Rule {
13050 target: 3,
13051 rule_index: 1,
13052 follow_state: 2,
13053 precedence: 0,
13054 },
13055 )
13056 .expect("transition");
13057 atn.add_transition(
13058 2,
13059 ParserTransitionSpec::Atom {
13060 target: 9,
13061 label: caller_symbol,
13062 },
13063 )
13064 .expect("transition");
13065 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13066 .expect("transition");
13067 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
13068 .expect("transition");
13069 atn.add_transition(
13070 5,
13071 ParserTransitionSpec::Precedence {
13072 target: 6,
13073 precedence: 1,
13074 },
13075 )
13076 .expect("transition");
13077 atn.add_transition(
13078 6,
13079 ParserTransitionSpec::Atom {
13080 target: 4,
13081 label: 1,
13082 },
13083 )
13084 .expect("transition");
13085 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
13086 .expect("transition");
13087 finish_atn(atn)
13088 }
13089
13090 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
13091 let mut parser = mini_parser(vec![
13092 TestToken::new(symbol).with_text("lookahead"),
13093 TestToken::eof("parser-test", 1, 1, 1),
13094 ]);
13095 parser.rule_context_stack = vec![
13096 RuleContextFrame {
13097 rule_index: 0,
13098 invoking_state: -1,
13099 },
13100 RuleContextFrame {
13101 rule_index: 1,
13102 invoking_state: 1,
13103 },
13104 ];
13105 parser
13106 }
13107
13108 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
13109 let mut atn = ParserAtnBuilder::new(1);
13113 for (state, kind, rule) in [
13114 (0, AtnStateKind::RuleStart, 0),
13115 (1, AtnStateKind::StarLoopEntry, 0),
13116 (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),
13123 (9, AtnStateKind::RuleStop, 0),
13124 ] {
13125 assert_eq!(
13126 atn.add_state(kind, Some(rule)).expect("state").index(),
13127 state
13128 );
13129 if state == 0 {
13130 atn.set_left_recursive_rule(state)
13131 .expect("left-recursive rule start");
13132 } else if state == 1 {
13133 atn.set_precedence_rule_decision(state)
13134 .expect("precedence decision");
13135 }
13136 }
13137 atn.set_rule_to_start_state(vec![0])
13138 .expect("rule start states");
13139 atn.set_rule_to_stop_state(vec![9])
13140 .expect("rule stop states");
13141 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13142 .expect("ops");
13143 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
13144 .expect("exit");
13145 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13146 .expect("to shift");
13147 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13148 .expect("to rel");
13149 atn.add_transition(
13150 3,
13151 ParserTransitionSpec::Precedence {
13152 target: 4,
13153 precedence: 2,
13154 },
13155 )
13156 .expect("shift prec");
13157 atn.add_transition(
13158 4,
13159 ParserTransitionSpec::Atom {
13160 target: 5,
13161 label: 1,
13162 },
13163 )
13164 .expect("shift first >");
13165 atn.add_transition(
13166 5,
13167 ParserTransitionSpec::Atom {
13168 target: 1,
13169 label: 1,
13170 },
13171 )
13172 .expect("shift second >");
13173 atn.add_transition(
13174 6,
13175 ParserTransitionSpec::Precedence {
13176 target: 7,
13177 precedence: 1,
13178 },
13179 )
13180 .expect("rel prec");
13181 atn.add_transition(
13182 7,
13183 ParserTransitionSpec::Atom {
13184 target: 1,
13185 label: 1,
13186 },
13187 )
13188 .expect("rel >");
13189 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
13190 .expect("loop end");
13191 finish_atn(atn)
13192 }
13193
13194 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
13195 let mut atn = ParserAtnBuilder::new(2);
13196 for (state, kind, rule) in [
13197 (0, AtnStateKind::RuleStart, 0),
13198 (1, AtnStateKind::StarLoopEntry, 0),
13199 (2, AtnStateKind::Basic, 0),
13200 (3, AtnStateKind::Basic, 0),
13201 (4, AtnStateKind::Basic, 0),
13202 (5, AtnStateKind::Basic, 0),
13203 (6, AtnStateKind::Basic, 0),
13204 (7, AtnStateKind::Basic, 0),
13205 (8, AtnStateKind::LoopEnd, 0),
13206 (9, AtnStateKind::RuleStop, 0),
13207 (10, AtnStateKind::RuleStart, 1),
13208 (11, AtnStateKind::Basic, 1),
13209 (12, AtnStateKind::RuleStop, 1),
13210 ] {
13211 assert_eq!(
13212 atn.add_state(kind, Some(rule)).expect("state").index(),
13213 state
13214 );
13215 if state == 0 {
13216 atn.set_left_recursive_rule(state)
13217 .expect("left-recursive rule start");
13218 } else if state == 1 {
13219 atn.set_precedence_rule_decision(state)
13220 .expect("precedence decision");
13221 }
13222 }
13223 atn.set_rule_to_start_state(vec![0, 10])
13224 .expect("rule start states");
13225 atn.set_rule_to_stop_state(vec![9, 12])
13226 .expect("rule stop states");
13227 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13228 .expect("ops");
13229 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
13230 .expect("exit");
13231 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13232 .expect("to shift");
13233 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13234 .expect("to relational");
13235 atn.add_transition(
13236 3,
13237 ParserTransitionSpec::Precedence {
13238 target: 4,
13239 precedence: 2,
13240 },
13241 )
13242 .expect("shift precedence");
13243 atn.add_transition(
13244 4,
13245 ParserTransitionSpec::Rule {
13246 target: 10,
13247 rule_index: 1,
13248 follow_state: 5,
13249 precedence: 0,
13250 },
13251 )
13252 .expect("first shift token helper");
13253 atn.add_transition(
13254 5,
13255 ParserTransitionSpec::Atom {
13256 target: 1,
13257 label: 1,
13258 },
13259 )
13260 .expect("second shift token");
13261 atn.add_transition(
13262 6,
13263 ParserTransitionSpec::Precedence {
13264 target: 7,
13265 precedence: 1,
13266 },
13267 )
13268 .expect("relational precedence");
13269 atn.add_transition(
13270 7,
13271 ParserTransitionSpec::Atom {
13272 target: 1,
13273 label: 1,
13274 },
13275 )
13276 .expect("relational token");
13277 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
13278 .expect("loop end");
13279 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
13280 .expect("helper entry");
13281 atn.add_transition(
13282 11,
13283 ParserTransitionSpec::Atom {
13284 target: 12,
13285 label: 1,
13286 },
13287 )
13288 .expect("first shift token");
13289 finish_atn(atn)
13290 }
13291
13292 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
13293 let mut atn = ParserAtnBuilder::new(1);
13294 for (state, kind) in [
13295 (0, AtnStateKind::RuleStart),
13296 (1, AtnStateKind::StarLoopEntry),
13297 (2, AtnStateKind::Basic),
13298 (3, AtnStateKind::Basic),
13299 (4, AtnStateKind::Basic),
13300 (5, AtnStateKind::Basic),
13301 (6, AtnStateKind::Basic),
13302 (7, AtnStateKind::Basic),
13303 (8, AtnStateKind::Basic),
13304 (9, AtnStateKind::LoopEnd),
13305 (10, AtnStateKind::RuleStop),
13306 ] {
13307 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13308 if state == 0 {
13309 atn.set_left_recursive_rule(state)
13310 .expect("left-recursive rule start");
13311 } else if state == 1 {
13312 atn.set_precedence_rule_decision(state)
13313 .expect("precedence decision");
13314 }
13315 }
13316 atn.set_rule_to_start_state(vec![0])
13317 .expect("rule start states");
13318 atn.set_rule_to_stop_state(vec![10])
13319 .expect("rule stop states");
13320 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13321 .expect("ops");
13322 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
13323 .expect("exit");
13324 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13325 .expect("to multi-token operator");
13326 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13327 .expect("to predicate operator");
13328 atn.add_transition(
13329 3,
13330 ParserTransitionSpec::Precedence {
13331 target: 4,
13332 precedence: 2,
13333 },
13334 )
13335 .expect("multi-token precedence");
13336 atn.add_transition(
13337 4,
13338 ParserTransitionSpec::Atom {
13339 target: 5,
13340 label: 1,
13341 },
13342 )
13343 .expect("multi-token first");
13344 atn.add_transition(
13345 5,
13346 ParserTransitionSpec::Atom {
13347 target: 1,
13348 label: 1,
13349 },
13350 )
13351 .expect("multi-token second");
13352 atn.add_transition(
13353 6,
13354 ParserTransitionSpec::Precedence {
13355 target: 7,
13356 precedence: 2,
13357 },
13358 )
13359 .expect("predicate precedence");
13360 atn.add_transition(
13361 7,
13362 ParserTransitionSpec::Predicate {
13363 target: 8,
13364 rule_index: 0,
13365 pred_index: 0,
13366 context_dependent: false,
13367 },
13368 )
13369 .expect("operator predicate");
13370 atn.add_transition(
13371 8,
13372 ParserTransitionSpec::Atom {
13373 target: 1,
13374 label: 1,
13375 },
13376 )
13377 .expect("predicate single token");
13378 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13379 .expect("loop end");
13380 finish_atn(atn)
13381 }
13382
13383 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
13384 let mut atn = ParserAtnBuilder::new(2);
13385 for (state, kind, rule) in [
13386 (0, AtnStateKind::RuleStart, 0),
13387 (1, AtnStateKind::StarLoopEntry, 0),
13388 (2, AtnStateKind::Basic, 0),
13389 (3, AtnStateKind::Basic, 0),
13390 (4, AtnStateKind::Basic, 0),
13391 (5, AtnStateKind::LoopEnd, 0),
13392 (6, AtnStateKind::RuleStop, 0),
13393 (7, AtnStateKind::RuleStart, 1),
13394 (8, AtnStateKind::RuleStop, 1),
13395 (9, AtnStateKind::Basic, 1),
13396 ] {
13397 assert_eq!(
13398 atn.add_state(kind, Some(rule)).expect("state").index(),
13399 state
13400 );
13401 if state == 0 {
13402 atn.set_left_recursive_rule(state)
13403 .expect("left-recursive rule start");
13404 } else if state == 1 {
13405 atn.set_precedence_rule_decision(state)
13406 .expect("precedence decision");
13407 }
13408 }
13409 atn.set_rule_to_start_state(vec![0, 7])
13410 .expect("rule start states");
13411 atn.set_rule_to_stop_state(vec![6, 8])
13412 .expect("rule stop states");
13413 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13414 .expect("transition");
13415 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
13416 .expect("transition");
13417 atn.add_transition(
13418 2,
13419 ParserTransitionSpec::Precedence {
13420 target: 3,
13421 precedence: 3,
13422 },
13423 )
13424 .expect("transition");
13425 atn.add_transition(
13426 3,
13427 ParserTransitionSpec::Rule {
13428 target: 7,
13429 rule_index: 1,
13430 follow_state: 4,
13431 precedence: 0,
13432 },
13433 )
13434 .expect("transition");
13435 atn.add_transition(
13436 4,
13437 ParserTransitionSpec::Atom {
13438 target: 1,
13439 label: 1,
13440 },
13441 )
13442 .expect("transition");
13443 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13444 .expect("transition");
13445 atn.add_transition(
13446 7,
13447 ParserTransitionSpec::Precedence {
13448 target: 9,
13449 precedence: 1,
13450 },
13451 )
13452 .expect("transition");
13453 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
13454 .expect("transition");
13455 finish_atn(atn)
13456 }
13457
13458 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
13459 let mut atn = ParserAtnBuilder::new(2);
13460 for (state, kind) in [
13461 (0, AtnStateKind::RuleStart),
13462 (1, AtnStateKind::StarLoopEntry),
13463 (2, AtnStateKind::Basic),
13464 (3, AtnStateKind::Basic),
13465 (4, AtnStateKind::Basic),
13466 (5, AtnStateKind::LoopEnd),
13467 (6, AtnStateKind::RuleStop),
13468 ] {
13469 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13470 if state == 0 {
13471 atn.set_left_recursive_rule(state)
13472 .expect("left-recursive rule start");
13473 } else if state == 1 {
13474 atn.set_precedence_rule_decision(state)
13475 .expect("precedence decision");
13476 }
13477 }
13478 atn.set_rule_to_start_state(vec![0])
13479 .expect("rule start states");
13480 atn.set_rule_to_stop_state(vec![6])
13481 .expect("rule stop states");
13482 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13483 .expect("transition");
13484 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
13485 .expect("transition");
13486 atn.add_transition(
13487 2,
13488 ParserTransitionSpec::Precedence {
13489 target: 3,
13490 precedence: 1,
13491 },
13492 )
13493 .expect("transition");
13494 atn.add_transition(
13495 3,
13496 ParserTransitionSpec::Predicate {
13497 target: 4,
13498 rule_index: 0,
13499 pred_index: 0,
13500 context_dependent: false,
13501 },
13502 )
13503 .expect("transition");
13504 atn.add_transition(
13505 4,
13506 ParserTransitionSpec::Atom {
13507 target: 1,
13508 label: 1,
13509 },
13510 )
13511 .expect("transition");
13512 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13513 .expect("transition");
13514 finish_atn(atn)
13515 }
13516
13517 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
13518 let mut atn = ParserAtnBuilder::new(2);
13519 for (state, kind, rule) in [
13520 (0, AtnStateKind::RuleStart, 0),
13521 (1, AtnStateKind::Basic, 0),
13522 (2, AtnStateKind::Basic, 0),
13523 (3, AtnStateKind::Basic, 0),
13524 (4, AtnStateKind::RuleStop, 0),
13525 (5, AtnStateKind::RuleStart, 1),
13526 (6, AtnStateKind::StarLoopEntry, 1),
13527 (7, AtnStateKind::Basic, 1),
13528 (8, AtnStateKind::Basic, 1),
13529 (9, AtnStateKind::LoopEnd, 1),
13530 (10, AtnStateKind::RuleStop, 1),
13531 (11, AtnStateKind::RuleStart, 2),
13532 (12, AtnStateKind::RuleStop, 2),
13533 ] {
13534 assert_eq!(
13535 atn.add_state(kind, Some(rule)).expect("state").index(),
13536 state
13537 );
13538 if state == 5 {
13539 atn.set_left_recursive_rule(state)
13540 .expect("left-recursive rule start");
13541 } else if state == 6 {
13542 atn.set_precedence_rule_decision(state)
13543 .expect("precedence decision");
13544 }
13545 }
13546 atn.set_rule_to_start_state(vec![0, 5, 11])
13547 .expect("rule start states");
13548 atn.set_rule_to_stop_state(vec![4, 10, 12])
13549 .expect("rule stop states");
13550 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13551 .expect("transition");
13552 atn.add_transition(
13553 1,
13554 ParserTransitionSpec::Rule {
13555 target: 5,
13556 rule_index: 1,
13557 follow_state: 2,
13558 precedence: 0,
13559 },
13560 )
13561 .expect("transition");
13562 atn.add_transition(
13563 2,
13564 ParserTransitionSpec::Rule {
13565 target: 11,
13566 rule_index: 2,
13567 follow_state: 3,
13568 precedence: 0,
13569 },
13570 )
13571 .expect("transition");
13572 atn.add_transition(
13573 3,
13574 ParserTransitionSpec::Atom {
13575 target: 4,
13576 label: caller_symbol,
13577 },
13578 )
13579 .expect("transition");
13580 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13581 .expect("transition");
13582 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
13583 .expect("transition");
13584 atn.add_transition(
13585 7,
13586 ParserTransitionSpec::Precedence {
13587 target: 8,
13588 precedence: 1,
13589 },
13590 )
13591 .expect("transition");
13592 atn.add_transition(
13593 8,
13594 ParserTransitionSpec::Atom {
13595 target: 6,
13596 label: 1,
13597 },
13598 )
13599 .expect("transition");
13600 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13601 .expect("transition");
13602 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
13603 .expect("transition");
13604 finish_atn(atn)
13605 }
13606
13607 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
13608 let mut atn = ParserAtnBuilder::new(2);
13609 for (state, kind, rule) in [
13610 (0, AtnStateKind::RuleStart, 0),
13611 (1, AtnStateKind::Basic, 0),
13612 (2, AtnStateKind::Basic, 0),
13613 (3, AtnStateKind::RuleStop, 0),
13614 (4, AtnStateKind::RuleStart, 1),
13615 (5, AtnStateKind::Basic, 1),
13616 (6, AtnStateKind::Basic, 1),
13617 (7, AtnStateKind::RuleStop, 1),
13618 (8, AtnStateKind::RuleStart, 2),
13619 (9, AtnStateKind::StarLoopEntry, 2),
13620 (10, AtnStateKind::Basic, 2),
13621 (11, AtnStateKind::Basic, 2),
13622 (12, AtnStateKind::LoopEnd, 2),
13623 (13, AtnStateKind::RuleStop, 2),
13624 ] {
13625 assert_eq!(
13626 atn.add_state(kind, Some(rule)).expect("state").index(),
13627 state
13628 );
13629 if state == 8 {
13630 atn.set_left_recursive_rule(state)
13631 .expect("left-recursive rule start");
13632 } else if state == 9 {
13633 atn.set_precedence_rule_decision(state)
13634 .expect("precedence decision");
13635 }
13636 }
13637 atn.set_rule_to_start_state(vec![0, 4, 8])
13638 .expect("rule start states");
13639 atn.set_rule_to_stop_state(vec![3, 7, 13])
13640 .expect("rule stop states");
13641 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13642 .expect("transition");
13643 atn.add_transition(
13644 1,
13645 ParserTransitionSpec::Rule {
13646 target: 4,
13647 rule_index: 1,
13648 follow_state: 2,
13649 precedence: 0,
13650 },
13651 )
13652 .expect("transition");
13653 atn.add_transition(
13654 2,
13655 ParserTransitionSpec::Atom {
13656 target: 3,
13657 label: caller_symbol,
13658 },
13659 )
13660 .expect("transition");
13661 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13662 .expect("transition");
13663 atn.add_transition(
13664 5,
13665 ParserTransitionSpec::Rule {
13666 target: 8,
13667 rule_index: 2,
13668 follow_state: 6,
13669 precedence: 0,
13670 },
13671 )
13672 .expect("transition");
13673 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13674 .expect("transition");
13675 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13676 .expect("transition");
13677 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
13678 .expect("transition");
13679 atn.add_transition(
13680 10,
13681 ParserTransitionSpec::Precedence {
13682 target: 11,
13683 precedence: 1,
13684 },
13685 )
13686 .expect("transition");
13687 atn.add_transition(
13688 11,
13689 ParserTransitionSpec::Atom {
13690 target: 9,
13691 label: 1,
13692 },
13693 )
13694 .expect("transition");
13695 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
13696 .expect("transition");
13697 finish_atn(atn)
13698 }
13699
13700 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
13701 let mut atn = ParserAtnBuilder::new(2);
13702 for (state, kind, rule) in [
13703 (0, AtnStateKind::RuleStart, 0),
13704 (1, AtnStateKind::Basic, 0),
13705 (2, AtnStateKind::Basic, 0),
13706 (3, AtnStateKind::RuleStop, 0),
13707 (4, AtnStateKind::RuleStart, 1),
13708 (5, AtnStateKind::StarLoopEntry, 1),
13709 (6, AtnStateKind::Basic, 1),
13710 (7, AtnStateKind::Basic, 1),
13711 (8, AtnStateKind::Basic, 1),
13712 (9, AtnStateKind::Basic, 1),
13713 (10, AtnStateKind::LoopEnd, 1),
13714 (11, AtnStateKind::RuleStop, 1),
13715 ] {
13716 assert_eq!(
13717 atn.add_state(kind, Some(rule)).expect("state").index(),
13718 state
13719 );
13720 if state == 4 {
13721 atn.set_left_recursive_rule(state)
13722 .expect("left-recursive rule start");
13723 } else if state == 5 {
13724 atn.set_precedence_rule_decision(state)
13725 .expect("precedence decision");
13726 }
13727 }
13728 atn.set_rule_to_start_state(vec![0, 4])
13729 .expect("rule start states");
13730 atn.set_rule_to_stop_state(vec![3, 11])
13731 .expect("rule stop states");
13732 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13733 .expect("transition");
13734 atn.add_transition(
13735 1,
13736 ParserTransitionSpec::Rule {
13737 target: 4,
13738 rule_index: 1,
13739 follow_state: 2,
13740 precedence: 0,
13741 },
13742 )
13743 .expect("transition");
13744 atn.add_transition(
13745 2,
13746 ParserTransitionSpec::Atom {
13747 target: 3,
13748 label: caller_symbol,
13749 },
13750 )
13751 .expect("transition");
13752 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13753 .expect("transition");
13754 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
13755 .expect("transition");
13756 atn.add_transition(
13757 6,
13758 ParserTransitionSpec::Precedence {
13759 target: 7,
13760 precedence: 1,
13761 },
13762 )
13763 .expect("transition");
13764 atn.add_transition(
13765 7,
13766 ParserTransitionSpec::Atom {
13767 target: 8,
13768 label: 1,
13769 },
13770 )
13771 .expect("transition");
13772 atn.add_transition(
13773 8,
13774 ParserTransitionSpec::Rule {
13775 target: 4,
13776 rule_index: 1,
13777 follow_state: 9,
13778 precedence: 2,
13779 },
13780 )
13781 .expect("transition");
13782 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
13783 .expect("transition");
13784 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
13785 .expect("transition");
13786 finish_atn(atn)
13787 }
13788
13789 #[test]
13790 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
13791 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
13792 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
13793
13794 let mut overlapping = parser_inside_left_recursive_callee(1);
13795 assert_eq!(
13796 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
13797 None
13798 );
13799
13800 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
13801 assert_eq!(
13802 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13803 Some(true)
13804 );
13805
13806 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
13807 assert_eq!(
13808 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13809 Some(false)
13810 );
13811
13812 assert_eq!(
13813 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13814 Some(true),
13815 "overlap results must not leak across ATNs"
13816 );
13817 }
13818
13819 #[test]
13820 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
13821 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
13822 let mut parser = mini_parser(vec![
13823 TestToken::new(1).with_text("operator"),
13824 TestToken::eof("parser-test", 1, 1, 1),
13825 ]);
13826 parser.rule_context_stack = vec![RuleContextFrame {
13827 rule_index: 0,
13828 invoking_state: -1,
13829 }];
13830
13831 assert_eq!(
13832 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13833 Some(true)
13834 );
13835 assert_eq!(
13836 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13837 Some(true),
13838 "cached operator lookahead must preserve the nullable prefix return path"
13839 );
13840 assert_eq!(
13841 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13842 Some(true),
13843 "the nullable child must use its rule-call precedence, not the caller precedence"
13844 );
13845 }
13846
13847 #[test]
13848 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
13849 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
13854 let mut parser = mini_parser(vec![
13855 TestToken::new(1).with_text(">"),
13856 TestToken::new(2).with_text("id"),
13857 TestToken::eof("parser-test", 1, 1, 1),
13858 ]);
13859 parser.rule_context_stack = vec![RuleContextFrame {
13860 rule_index: 0,
13861 invoking_state: -1,
13862 }];
13863
13864 assert_eq!(
13865 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13866 Some(true),
13867 "at low precedence relational `>` is a single-token operator"
13868 );
13869 assert_eq!(
13870 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
13871 Some(true),
13872 "relational remains single-token at its own precedence"
13873 );
13874 assert_eq!(
13875 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13876 None,
13877 "at shift precedence, bare `>` must not force enter"
13878 );
13879 }
13880
13881 #[test]
13882 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
13883 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
13884 let mut parser = mini_parser(vec![
13885 TestToken::new(1).with_text(">"),
13886 TestToken::new(2).with_text("id"),
13887 TestToken::eof("parser-test", 1, 1, 1),
13888 ]);
13889 parser.rule_context_stack = vec![RuleContextFrame {
13890 rule_index: 0,
13891 invoking_state: -1,
13892 }];
13893
13894 assert_eq!(
13895 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13896 Some(true),
13897 "the direct relational alternative remains a one-token operator"
13898 );
13899 assert_eq!(
13900 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13901 None,
13902 "a token matched in the helper rule must return to the second shift token"
13903 );
13904 }
13905
13906 #[test]
13907 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
13908 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
13909 let mut parser = mini_parser(vec![
13910 TestToken::new(1).with_text(">"),
13911 TestToken::new(2).with_text("id"),
13912 TestToken::eof("parser-test", 1, 1, 1),
13913 ]);
13914 parser.rule_context_stack = vec![RuleContextFrame {
13915 rule_index: 0,
13916 invoking_state: -1,
13917 }];
13918
13919 assert_eq!(
13920 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13921 None,
13922 "a predicate-gated single-token path must not be hidden by a multi-token path"
13923 );
13924 }
13925
13926 #[test]
13927 fn left_recursive_loop_defers_predicate_guarded_operator() {
13928 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
13929 let mut parser = mini_parser_with_hooks(
13930 vec![
13931 TestToken::new(1).with_text("operator"),
13932 TestToken::eof("parser-test", 1, 1, 1),
13933 ],
13934 RejectingPredicateHooks::default(),
13935 );
13936 parser.rule_context_stack = vec![RuleContextFrame {
13937 rule_index: 0,
13938 invoking_state: -1,
13939 }];
13940
13941 assert_eq!(
13942 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13943 None,
13944 "a false predicate must be evaluated before entering the operator alternative"
13945 );
13946 assert_eq!(
13947 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13948 None,
13949 "cached predicate-dependent lookahead must keep deferring"
13950 );
13951 }
13952
13953 #[test]
13954 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
13955 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
13956 let mut parser = parser_inside_left_recursive_callee(1);
13957
13958 assert_eq!(
13959 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
13960 None
13961 );
13962 assert_eq!(
13963 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
13964 None,
13965 "the cached overlap must preserve the nullable child return path"
13966 );
13967 }
13968
13969 #[test]
13970 fn left_recursive_loop_defers_through_nullable_parent_return() {
13971 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
13972 let mut parser = mini_parser(vec![
13973 TestToken::new(1).with_text("lookahead"),
13974 TestToken::eof("parser-test", 1, 1, 1),
13975 ]);
13976 parser.rule_context_stack = vec![
13977 RuleContextFrame {
13978 rule_index: 0,
13979 invoking_state: -1,
13980 },
13981 RuleContextFrame {
13982 rule_index: 1,
13983 invoking_state: 1,
13984 },
13985 RuleContextFrame {
13986 rule_index: 2,
13987 invoking_state: 5,
13988 },
13989 ];
13990
13991 assert_eq!(
13992 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
13993 None,
13994 "a nullable caller must unwind to its parent's consuming follow path"
13995 );
13996 assert_eq!(
13997 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
13998 None,
13999 "the caller-overlap cache must not retain a false negative"
14000 );
14001 }
14002
14003 #[test]
14004 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
14005 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
14006 let mut parser = mini_parser(vec![
14007 TestToken::new(1).with_text("lookahead"),
14008 TestToken::eof("parser-test", 1, 1, 1),
14009 ]);
14010 parser.rule_context_stack = vec![
14011 RuleContextFrame {
14012 rule_index: 0,
14013 invoking_state: -1,
14014 },
14015 RuleContextFrame {
14016 rule_index: 1,
14017 invoking_state: 1,
14018 },
14019 RuleContextFrame {
14020 rule_index: 1,
14021 invoking_state: 8,
14022 },
14023 ];
14024
14025 assert_eq!(
14026 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
14027 None,
14028 "a recursive operand return must preserve its parent caller context"
14029 );
14030 assert_eq!(
14031 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
14032 None,
14033 "the caller-overlap cache must preserve the loop-boundary return"
14034 );
14035 }
14036
14037 fn token_then_eof_atn() -> Atn {
14038 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14039 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, ]))
14055 .deserialize_parser()
14056 .expect("artificial parser ATN should deserialize")
14057 }
14058
14059 fn epsilon_cycle_atn() -> Atn {
14060 let mut atn = ParserAtnBuilder::new(1);
14061 for (state_number, kind) in [
14062 (0, AtnStateKind::RuleStart),
14063 (1, AtnStateKind::Basic),
14064 (2, AtnStateKind::RuleStop),
14065 ] {
14066 assert_eq!(
14067 atn.add_state(kind, Some(0)).expect("state").index(),
14068 state_number
14069 );
14070 }
14071 atn.set_rule_to_start_state(vec![0])
14072 .expect("rule start states");
14073 atn.set_rule_to_stop_state(vec![2])
14074 .expect("rule stop states");
14075 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14076 .expect("transition");
14077 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
14078 .expect("self-cycle transition");
14079 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14080 .expect("exit transition");
14081 finish_atn(atn)
14082 }
14083
14084 fn eof_then_action_atn() -> Atn {
14085 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14086 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, ]))
14102 .deserialize_parser()
14103 .expect("artificial parser ATN should deserialize")
14104 }
14105
14106 fn noop_action_then_token_then_eof_atn() -> Atn {
14107 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14108 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, ]))
14126 .deserialize_parser()
14127 .expect("artificial no-op action ATN should deserialize")
14128 }
14129
14130 fn two_alt_decision_atn() -> Atn {
14131 let mut atn = ParserAtnBuilder::new(2);
14132 assert_eq!(
14133 atn.add_state(AtnStateKind::RuleStart, Some(0))
14134 .expect("state")
14135 .index(),
14136 0
14137 );
14138 assert_eq!(
14139 atn.add_state(AtnStateKind::BlockStart, Some(0))
14140 .expect("state")
14141 .index(),
14142 1
14143 );
14144 assert_eq!(
14145 atn.add_state(AtnStateKind::Basic, Some(0))
14146 .expect("state")
14147 .index(),
14148 2
14149 );
14150 assert_eq!(
14151 atn.add_state(AtnStateKind::Basic, Some(0))
14152 .expect("state")
14153 .index(),
14154 3
14155 );
14156 assert_eq!(
14157 atn.add_state(AtnStateKind::BlockEnd, Some(0))
14158 .expect("state")
14159 .index(),
14160 4
14161 );
14162 assert_eq!(
14163 atn.add_state(AtnStateKind::RuleStop, Some(0))
14164 .expect("state")
14165 .index(),
14166 5
14167 );
14168 atn.set_rule_to_start_state(vec![0])
14169 .expect("rule start states");
14170 atn.set_rule_to_stop_state(vec![5])
14171 .expect("rule stop states");
14172 atn.add_decision_state(1).expect("decision state");
14173 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14174 .expect("transition");
14175 atn.add_transition(
14176 1,
14177 ParserTransitionSpec::Atom {
14178 target: 2,
14179 label: 1,
14180 },
14181 )
14182 .expect("transition");
14183 atn.add_transition(
14184 1,
14185 ParserTransitionSpec::Atom {
14186 target: 3,
14187 label: 2,
14188 },
14189 )
14190 .expect("transition");
14191 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
14192 .expect("transition");
14193 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14194 .expect("transition");
14195 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14196 .expect("transition");
14197 finish_atn(atn)
14198 }
14199
14200 fn optional_then_b_eof_atn() -> Atn {
14203 let mut atn = ParserAtnBuilder::new(3);
14204 assert_eq!(
14205 atn.add_state(AtnStateKind::RuleStart, Some(0))
14206 .expect("state")
14207 .index(),
14208 0
14209 );
14210 assert_eq!(
14211 atn.add_state(AtnStateKind::BlockStart, Some(0))
14212 .expect("state")
14213 .index(),
14214 1
14215 );
14216 assert_eq!(
14217 atn.add_state(AtnStateKind::Basic, Some(0))
14218 .expect("state")
14219 .index(),
14220 2
14221 );
14222 assert_eq!(
14223 atn.add_state(AtnStateKind::Basic, Some(0))
14224 .expect("state")
14225 .index(),
14226 3
14227 );
14228 assert_eq!(
14229 atn.add_state(AtnStateKind::Basic, Some(0))
14230 .expect("state")
14231 .index(),
14232 4
14233 );
14234 assert_eq!(
14235 atn.add_state(AtnStateKind::RuleStop, Some(0))
14236 .expect("state")
14237 .index(),
14238 5
14239 );
14240 atn.set_rule_to_start_state(vec![0])
14241 .expect("rule start states");
14242 atn.set_rule_to_stop_state(vec![5])
14243 .expect("rule stop states");
14244 atn.add_decision_state(1).expect("decision state");
14245 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14246 .expect("transition");
14247 atn.add_transition(
14249 1,
14250 ParserTransitionSpec::Atom {
14251 target: 3,
14252 label: 1,
14253 },
14254 )
14255 .expect("transition");
14256 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
14257 .expect("transition");
14258 atn.add_transition(
14260 3,
14261 ParserTransitionSpec::Atom {
14262 target: 4,
14263 label: 2,
14264 },
14265 )
14266 .expect("transition");
14267 atn.add_transition(
14268 4,
14269 ParserTransitionSpec::Atom {
14270 target: 5,
14271 label: TOKEN_EOF,
14272 },
14273 )
14274 .expect("transition");
14275 finish_atn(atn)
14276 }
14277
14278 #[test]
14279 fn sync_decision_deletes_only_a_single_token() {
14280 let atn = optional_then_b_eof_atn();
14288
14289 let mut single = mini_parser(vec![
14290 TestToken::new(3).with_text("c"),
14291 TestToken::new(2).with_text("b"),
14292 TestToken::eof("parser-test", 1, 2, 2),
14293 ]);
14294 single.rule_context_stack = vec![RuleContextFrame {
14295 rule_index: 0,
14296 invoking_state: 0,
14297 }];
14298 let children = single
14299 .sync_decision(&atn, 1, true, false)
14300 .expect("single extraneous token recovers");
14301 assert_eq!(children.len(), 1);
14302 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
14303 assert_eq!(single.number_of_syntax_errors(), 1);
14304 assert_eq!(single.la(1), 2);
14306
14307 let mut double = mini_parser(vec![
14308 TestToken::new(3).with_text("c"),
14309 TestToken::new(3).with_text("c"),
14310 TestToken::new(2).with_text("b"),
14311 TestToken::eof("parser-test", 1, 3, 3),
14312 ]);
14313 double.rule_context_stack = vec![RuleContextFrame {
14314 rule_index: 0,
14315 invoking_state: 0,
14316 }];
14317 let result = double.sync_decision(&atn, 1, true, false);
14318 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
14323 match error {
14324 AntlrError::ParserError { message, .. } => {
14325 assert!(message.starts_with("mismatched input"), "got: {message}");
14326 }
14327 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
14328 }
14329 assert_eq!(double.la(1), 3);
14330 }
14331
14332 fn star_loop_then_eof_atn() -> Atn {
14336 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14337 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,
14338 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,
14339 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,
14340 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
14341 ]))
14342 .deserialize_parser()
14343 .expect("star-loop-then-EOF ATN should deserialize")
14344 }
14345
14346 fn plus_loop_with_recovering_body_atn() -> Atn {
14352 let mut atn = ParserAtnBuilder::new(2);
14353 assert_eq!(
14354 atn.add_state(AtnStateKind::RuleStart, Some(0))
14355 .expect("state")
14356 .index(),
14357 0
14358 );
14359 assert_eq!(
14360 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
14361 .expect("state")
14362 .index(),
14363 1
14364 );
14365 assert_eq!(
14366 atn.add_state(AtnStateKind::Basic, Some(0))
14367 .expect("state")
14368 .index(),
14369 2
14370 );
14371 assert_eq!(
14372 atn.add_state(AtnStateKind::BlockEnd, Some(0))
14373 .expect("state")
14374 .index(),
14375 3
14376 );
14377 assert_eq!(
14378 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
14379 .expect("state")
14380 .index(),
14381 4
14382 );
14383 assert_eq!(
14384 atn.add_state(AtnStateKind::LoopEnd, Some(0))
14385 .expect("state")
14386 .index(),
14387 5
14388 );
14389 assert_eq!(
14390 atn.add_state(AtnStateKind::RuleStop, Some(0))
14391 .expect("state")
14392 .index(),
14393 6
14394 );
14395 assert_eq!(
14396 atn.add_state(AtnStateKind::RuleStart, Some(1))
14397 .expect("state")
14398 .index(),
14399 7
14400 );
14401 assert_eq!(
14402 atn.add_state(AtnStateKind::Basic, Some(1))
14403 .expect("state")
14404 .index(),
14405 8
14406 );
14407 assert_eq!(
14408 atn.add_state(AtnStateKind::RuleStop, Some(1))
14409 .expect("state")
14410 .index(),
14411 9
14412 );
14413 atn.set_rule_to_start_state(vec![0, 7])
14414 .expect("rule start states");
14415 atn.set_rule_to_stop_state(vec![6, 9])
14416 .expect("rule stop states");
14417 atn.set_end_state(1, 3).expect("block end state");
14418 atn.set_loop_back_state(5, 4).expect("loop back state");
14419 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14420 .expect("transition");
14421 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14422 .expect("transition");
14423 atn.add_transition(
14424 2,
14425 ParserTransitionSpec::Rule {
14426 target: 7,
14427 rule_index: 1,
14428 follow_state: 3,
14429 precedence: 0,
14430 },
14431 )
14432 .expect("transition");
14433 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14434 .expect("transition");
14435 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
14436 .expect("transition");
14437 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14438 .expect("transition");
14439 atn.add_transition(
14440 5,
14441 ParserTransitionSpec::Atom {
14442 target: 6,
14443 label: 2,
14444 },
14445 )
14446 .expect("transition");
14447 atn.add_transition(
14448 7,
14449 ParserTransitionSpec::Atom {
14450 target: 8,
14451 label: 1,
14452 },
14453 )
14454 .expect("transition");
14455 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14456 .expect("transition");
14457 finish_atn(atn)
14458 }
14459
14460 #[test]
14461 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
14462 let atn = plus_loop_with_recovering_body_atn();
14463 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14464
14465 let error = parser
14466 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
14467 .expect_err("EOF recovery should report a bounded mismatch");
14468
14469 let AntlrError::ParserError { message, .. } = error else {
14470 panic!("expected ParserError, got {error:?}");
14471 };
14472 assert_eq!(message, "mismatched input '<EOF>' expecting {'x', 2}");
14473 assert_eq!(parser.number_of_syntax_errors(), 1);
14474 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
14475 }
14476
14477 #[test]
14478 fn sync_decision_deletes_token_before_eof_at_loop_back() {
14479 let atn = star_loop_then_eof_atn();
14485 let mut parser = mini_parser(vec![
14486 TestToken::new(2).with_text("c"),
14487 TestToken::eof("parser-test", 1, 1, 1),
14488 ]);
14489 parser.rule_context_stack = vec![RuleContextFrame {
14490 rule_index: 0,
14491 invoking_state: 0,
14492 }];
14493 let children = parser
14494 .sync_decision(&atn, 5, true, false)
14495 .expect("single token before EOF recovers");
14496 assert_eq!(children.len(), 1);
14497 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
14498 assert_eq!(parser.number_of_syntax_errors(), 1);
14499 assert_eq!(
14500 parser.la(1),
14501 TOKEN_EOF,
14502 "EOF is left for the rule's EOF match"
14503 );
14504 }
14505
14506 #[test]
14507 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
14508 let atn = star_loop_then_eof_atn();
14513 let mut parser = mini_parser(vec![
14514 TestToken::new(2).with_text("c"),
14515 TestToken::new(2).with_text("c"),
14516 TestToken::eof("parser-test", 1, 2, 2),
14517 ]);
14518 parser.rule_context_stack = vec![RuleContextFrame {
14519 rule_index: 0,
14520 invoking_state: 0,
14521 }];
14522 let error = parser
14523 .sync_decision(&atn, 5, true, false)
14524 .expect_err("two tokens at the loop entry must not be deleted");
14525 match error {
14526 AntlrError::ParserError { message, .. } => {
14527 assert!(message.starts_with("mismatched input"), "got: {message}");
14528 }
14529 other => panic!("expected mismatched-input ParserError, got {other:?}"),
14530 }
14531 assert_eq!(
14532 parser.la(1),
14533 2,
14534 "nothing consumed; cursor still on first `c`"
14535 );
14536 }
14537
14538 #[test]
14539 fn sync_decision_consumes_until_eof_at_loop_back() {
14540 let atn = star_loop_then_eof_atn();
14546 let mut parser = mini_parser(vec![
14547 TestToken::new(2).with_text("c"),
14548 TestToken::new(2).with_text("c"),
14549 TestToken::eof("parser-test", 1, 2, 2),
14550 ]);
14551 parser.rule_context_stack = vec![RuleContextFrame {
14552 rule_index: 0,
14553 invoking_state: 0,
14554 }];
14555 let children = parser
14556 .sync_decision(&atn, 5, false, true)
14557 .expect("loop-back multi-token deletion recovers onto EOF");
14558 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
14559 assert!(
14560 children
14561 .iter()
14562 .all(|child| parser.node(*child).kind() == NodeKind::Error)
14563 );
14564 assert_eq!(parser.number_of_syntax_errors(), 1);
14565 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
14566 }
14567
14568 fn predicate_after_token_atn() -> Atn {
14569 let mut atn = ParserAtnBuilder::new(2);
14570 assert_eq!(
14571 atn.add_state(AtnStateKind::RuleStart, Some(0))
14572 .expect("state")
14573 .index(),
14574 0
14575 );
14576 assert_eq!(
14577 atn.add_state(AtnStateKind::Basic, Some(0))
14578 .expect("state")
14579 .index(),
14580 1
14581 );
14582 assert_eq!(
14583 atn.add_state(AtnStateKind::Basic, Some(0))
14584 .expect("state")
14585 .index(),
14586 2
14587 );
14588 assert_eq!(
14589 atn.add_state(AtnStateKind::Basic, Some(0))
14590 .expect("state")
14591 .index(),
14592 3
14593 );
14594 assert_eq!(
14595 atn.add_state(AtnStateKind::RuleStop, Some(0))
14596 .expect("state")
14597 .index(),
14598 4
14599 );
14600 atn.set_rule_to_start_state(vec![0])
14601 .expect("rule start states");
14602 atn.set_rule_to_stop_state(vec![4])
14603 .expect("rule stop states");
14604 atn.add_transition(
14605 0,
14606 ParserTransitionSpec::Atom {
14607 target: 1,
14608 label: 1,
14609 },
14610 )
14611 .expect("transition");
14612 atn.add_transition(
14613 1,
14614 ParserTransitionSpec::Predicate {
14615 target: 2,
14616 rule_index: 0,
14617 pred_index: 0,
14618 context_dependent: false,
14619 },
14620 )
14621 .expect("transition");
14622 atn.add_transition(
14623 2,
14624 ParserTransitionSpec::Atom {
14625 target: 3,
14626 label: 2,
14627 },
14628 )
14629 .expect("transition");
14630 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14631 .expect("transition");
14632 finish_atn(atn)
14633 }
14634
14635 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
14636 let mut atn = ParserAtnBuilder::new(1);
14637 for (state_number, kind) in [
14638 (0, AtnStateKind::RuleStart),
14639 (1, AtnStateKind::BlockStart),
14640 (2, AtnStateKind::Basic),
14641 (3, AtnStateKind::Basic),
14642 (4, AtnStateKind::Basic),
14643 (5, AtnStateKind::Basic),
14644 (6, AtnStateKind::BlockEnd),
14645 (7, AtnStateKind::RuleStop),
14646 ] {
14647 assert_eq!(
14648 atn.add_state(kind, Some(0)).expect("state").index(),
14649 state_number
14650 );
14651 }
14652 atn.set_rule_to_start_state(vec![0])
14653 .expect("rule start states");
14654 atn.set_rule_to_stop_state(vec![7])
14655 .expect("rule stop states");
14656 atn.add_decision_state(1).expect("decision state");
14657 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14658 .expect("transition");
14659 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14660 .expect("transition");
14661 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
14662 .expect("transition");
14663 atn.add_transition(
14664 2,
14665 ParserTransitionSpec::Predicate {
14666 target: 4,
14667 rule_index: 0,
14668 pred_index: pred_indexes[0],
14669 context_dependent: false,
14670 },
14671 )
14672 .expect("transition");
14673 atn.add_transition(
14674 3,
14675 ParserTransitionSpec::Predicate {
14676 target: 5,
14677 rule_index: 0,
14678 pred_index: pred_indexes[1],
14679 context_dependent: false,
14680 },
14681 )
14682 .expect("transition");
14683 atn.add_transition(
14684 4,
14685 ParserTransitionSpec::Atom {
14686 target: 6,
14687 label: 1,
14688 },
14689 )
14690 .expect("transition");
14691 atn.add_transition(
14692 5,
14693 ParserTransitionSpec::Atom {
14694 target: 6,
14695 label: 1,
14696 },
14697 )
14698 .expect("transition");
14699 atn.add_transition(
14700 6,
14701 ParserTransitionSpec::Atom {
14702 target: 7,
14703 label: TOKEN_EOF,
14704 },
14705 )
14706 .expect("transition");
14707 finish_atn(atn)
14708 }
14709
14710 fn nested_nullable_context_atn() -> Atn {
14711 let mut atn = ParserAtnBuilder::new(1);
14712 for state_number in 0..=20 {
14713 let kind = match state_number {
14714 0 | 10 | 16 => AtnStateKind::RuleStart,
14715 9 | 15 | 20 => AtnStateKind::RuleStop,
14716 _ => AtnStateKind::Basic,
14717 };
14718 let rule_index = match state_number {
14719 0..=9 => 0,
14720 10..=15 => 1,
14721 _ => 2,
14722 };
14723 assert_eq!(
14724 atn.add_state(kind, Some(rule_index))
14725 .expect("state")
14726 .index(),
14727 state_number
14728 );
14729 }
14730 atn.set_rule_to_start_state(vec![0, 10, 16])
14731 .expect("rule start states");
14732 atn.set_rule_to_stop_state(vec![9, 15, 20])
14733 .expect("rule stop states");
14734 atn.add_transition(
14735 1,
14736 ParserTransitionSpec::Rule {
14737 target: 10,
14738 rule_index: 1,
14739 follow_state: 8,
14740 precedence: 0,
14741 },
14742 )
14743 .expect("transition");
14744 atn.add_transition(
14745 8,
14746 ParserTransitionSpec::Atom {
14747 target: 9,
14748 label: 1,
14749 },
14750 )
14751 .expect("transition");
14752 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14753 .expect("transition");
14754 atn.add_transition(
14755 2,
14756 ParserTransitionSpec::Rule {
14757 target: 16,
14758 rule_index: 2,
14759 follow_state: 14,
14760 precedence: 0,
14761 },
14762 )
14763 .expect("transition");
14764 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
14765 .expect("transition");
14766 finish_atn(atn)
14767 }
14768
14769 fn generated_match_recovery_atn() -> Atn {
14770 let mut atn = ParserAtnBuilder::new(2);
14771 assert_eq!(
14772 atn.add_state(AtnStateKind::RuleStart, Some(0))
14773 .expect("state")
14774 .index(),
14775 0
14776 );
14777 assert_eq!(
14778 atn.add_state(AtnStateKind::Basic, Some(0))
14779 .expect("state")
14780 .index(),
14781 1
14782 );
14783 assert_eq!(
14784 atn.add_state(AtnStateKind::Basic, Some(0))
14785 .expect("state")
14786 .index(),
14787 2
14788 );
14789 assert_eq!(
14790 atn.add_state(AtnStateKind::RuleStop, Some(0))
14791 .expect("state")
14792 .index(),
14793 3
14794 );
14795 assert_eq!(
14796 atn.add_state(AtnStateKind::RuleStart, Some(1))
14797 .expect("state")
14798 .index(),
14799 4
14800 );
14801 assert_eq!(
14802 atn.add_state(AtnStateKind::RuleStop, Some(1))
14803 .expect("state")
14804 .index(),
14805 5
14806 );
14807 atn.set_rule_to_start_state(vec![0, 4])
14808 .expect("rule start states");
14809 atn.set_rule_to_stop_state(vec![3, 5])
14810 .expect("rule stop states");
14811 atn.add_transition(
14812 1,
14813 ParserTransitionSpec::Rule {
14814 target: 4,
14815 rule_index: 1,
14816 follow_state: 2,
14817 precedence: 0,
14818 },
14819 )
14820 .expect("transition");
14821 atn.add_transition(
14822 2,
14823 ParserTransitionSpec::Atom {
14824 target: 3,
14825 label: TOKEN_EOF,
14826 },
14827 )
14828 .expect("transition");
14829 finish_atn(atn)
14830 }
14831
14832 fn complement_set_atn() -> Atn {
14833 let mut atn = ParserAtnBuilder::new(1);
14834 assert_eq!(
14835 atn.add_state(AtnStateKind::RuleStart, Some(0))
14836 .expect("state")
14837 .index(),
14838 0
14839 );
14840 assert_eq!(
14841 atn.add_state(AtnStateKind::RuleStop, Some(0))
14842 .expect("state")
14843 .index(),
14844 1
14845 );
14846 atn.set_rule_to_start_state(vec![0])
14847 .expect("rule start states");
14848 atn.set_rule_to_stop_state(vec![1])
14849 .expect("rule stop states");
14850 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
14851 atn.add_transition(
14852 0,
14853 ParserTransitionSpec::NotSet {
14854 target: 1,
14855 set: excluded,
14856 },
14857 )
14858 .expect("transition");
14859 finish_atn(atn)
14860 }
14861
14862 fn wildcard_then_eof_atn() -> Atn {
14865 let mut atn = ParserAtnBuilder::new(1);
14866 assert_eq!(
14867 atn.add_state(AtnStateKind::RuleStart, Some(0))
14868 .expect("state")
14869 .index(),
14870 0
14871 );
14872 assert_eq!(
14873 atn.add_state(AtnStateKind::RuleStop, Some(0))
14874 .expect("state")
14875 .index(),
14876 1
14877 );
14878 assert_eq!(
14879 atn.add_state(AtnStateKind::Basic, Some(0))
14880 .expect("state")
14881 .index(),
14882 2
14883 );
14884 atn.set_rule_to_start_state(vec![0])
14885 .expect("rule start states");
14886 atn.set_rule_to_stop_state(vec![1])
14887 .expect("rule stop states");
14888 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
14889 .expect("transition");
14890 atn.add_transition(
14891 2,
14892 ParserTransitionSpec::Atom {
14893 target: 1,
14894 label: TOKEN_EOF,
14895 },
14896 )
14897 .expect("transition");
14898 finish_atn(atn)
14899 }
14900
14901 #[test]
14902 fn parser_matches_token_and_reports_mismatch() {
14903 let source = Source {
14904 tokens: vec![
14905 TestToken::new(1).with_text("x"),
14906 TestToken::eof("parser-test", 1, 1, 1),
14907 ],
14908 index: 0,
14909 };
14910 let data = RecognizerData::new(
14911 "Mini.g4",
14912 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
14913 );
14914 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
14915 let matched = parser.match_token(1).expect("token 1 should match");
14916 assert_eq!(parser.node(matched).text(), "x");
14917 assert!(parser.match_token(1).is_err());
14918 }
14919
14920 #[test]
14921 fn parser_matches_token_sets() {
14922 let mut parser = mini_parser(vec![
14923 TestToken::new(1).with_text("x"),
14924 TestToken::eof("parser-test", 1, 1, 1),
14925 ]);
14926
14927 let matched = parser
14928 .match_set(&[(1, 1), (3, 4)])
14929 .expect("token set should match");
14930 assert_eq!(parser.node(matched).text(), "x");
14931 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
14932 }
14933
14934 #[test]
14935 fn generated_rule_api_tracks_state_and_precedence() {
14936 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14937
14938 let context = parser.enter_rule(7, 2);
14939 assert_eq!(context.rule_index(), 2);
14940 assert_eq!(parser.state(), 7);
14941 assert_eq!(
14942 parser.rule_context_stack,
14943 vec![RuleContextFrame {
14944 rule_index: 2,
14945 invoking_state: 7
14946 }]
14947 );
14948
14949 let recursive = parser.enter_recursion_rule(11, 3, 4);
14950 assert_eq!(recursive.rule_index(), 3);
14951 assert!(parser.precpred(4));
14952 assert!(parser.precpred(5));
14953 assert!(!parser.precpred(3));
14954
14955 let next = parser.push_new_recursion_context(13, 3);
14956 assert_eq!(next.invoking_state(), 13);
14957 parser.unroll_recursion_context();
14958 assert_eq!(parser.precedence_stack, vec![0]);
14959 assert_eq!(
14960 parser.rule_context_stack,
14961 vec![RuleContextFrame {
14962 rule_index: 2,
14963 invoking_state: 7
14964 }]
14965 );
14966
14967 parser.exit_rule();
14968 assert!(parser.rule_context_stack.is_empty());
14969 }
14970
14971 #[test]
14972 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
14973 let mut parser = mini_parser(vec![
14974 TestToken::new(1).with_text("x"),
14975 TestToken::eof("parser-test", 1, 1, 1),
14976 ]);
14977 let matched = parser.match_token(1).expect("token should match");
14978 assert_eq!(parser.node(matched).text(), "x");
14979 parser.record_generated_syntax_error();
14980 parser.set_int_member(7, 11);
14981 parser.set_build_parse_trees(false);
14982 parser.set_report_diagnostic_errors(true);
14983 parser.set_prediction_mode(PredictionMode::Sll);
14984 parser.set_bail_on_error(true);
14985 let _context = parser.enter_recursion_rule(9, 0, 4);
14986 parser.pending_invoking_states.push(5);
14987 parser.unknown_predicate_hits.push((0, 1));
14988 parser.unhandled_action_hits.push((0, 2));
14989
14990 parser.reset();
14991
14992 assert_eq!(parser.input.index(), 0);
14993 assert_eq!(parser.la(1), 1);
14994 assert_eq!(parser.state(), -1);
14995 assert_eq!(parser.number_of_syntax_errors(), 0);
14996 assert_eq!(parser.parse_tree_storage().node_count(), 0);
14997 assert!(parser.rule_context_stack.is_empty());
14998 assert!(parser.pending_invoking_states.is_empty());
14999 assert_eq!(parser.precedence_stack, [0]);
15000 assert!(parser.unknown_predicate_hits.is_empty());
15001 assert!(parser.unhandled_action_hits.is_empty());
15002 assert_eq!(parser.int_member(7), Some(11));
15003 assert!(!parser.build_parse_trees());
15004 assert!(parser.report_diagnostic_errors());
15005 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
15006 assert!(parser.bail_on_error());
15007 }
15008
15009 #[test]
15010 fn set_token_stream_replaces_input_and_resets_parser() {
15011 let mut parser = mini_parser(vec![
15012 TestToken::new(1).with_text("old"),
15013 TestToken::eof("parser-test", 1, 1, 1),
15014 ]);
15015 parser.consume();
15016 parser.record_generated_syntax_error();
15017 let replacement = CommonTokenStream::new(Source {
15018 tokens: vec![
15019 TestToken::new(2).with_text("new"),
15020 TestToken::eof("parser-test", 1, 1, 1),
15021 ],
15022 index: 0,
15023 });
15024
15025 parser.set_token_stream(replacement);
15026
15027 assert_eq!(parser.input.index(), 0);
15028 assert_eq!(parser.la(1), 2);
15029 assert_eq!(parser.input.text_all(), "new");
15030 assert_eq!(parser.number_of_syntax_errors(), 0);
15031 }
15032
15033 #[test]
15034 fn active_invocation_states_exclude_the_root_frame() {
15035 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15036
15037 let _root = parser.enter_rule(0, 0);
15038 assert!(parser.active_invocation_states().is_empty());
15039
15040 let marker = parser.push_invoking_state(6);
15041 let _child = parser.enter_rule(2, 1);
15042 parser.discard_invoking_state(marker);
15043 assert_eq!(parser.active_invocation_states(), [6]);
15044
15045 let marker = parser.push_invoking_state(13);
15046 let _grandchild = parser.enter_rule(4, 2);
15047 parser.discard_invoking_state(marker);
15048 assert_eq!(parser.active_invocation_states(), [13, 6]);
15049
15050 parser.exit_rule();
15051 parser.exit_rule();
15052 parser.exit_rule();
15053 }
15054
15055 #[test]
15056 fn parser_predicates_support_token_adjacency() {
15057 let mut parser = mini_parser(vec![
15058 TestToken::new(1).with_text("=").with_span(0, 0),
15059 TestToken::new(1).with_text(">").with_span(1, 1),
15060 TestToken::eof("parser-test", 2, 1, 2),
15061 ]);
15062 parser.consume();
15063 parser.consume();
15064
15065 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
15066
15067 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
15068
15069 let mut parser = mini_parser(vec![
15070 TestToken::new(1).with_text("=").with_span(0, 0),
15071 TestToken::new(1)
15072 .with_text(" ")
15073 .with_channel(HIDDEN_CHANNEL)
15074 .with_span(1, 1),
15075 TestToken::new(1).with_text(">").with_span(2, 2),
15076 TestToken::eof("parser-test", 3, 1, 3),
15077 ]);
15078 parser.consume();
15079 parser.consume();
15080
15081 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
15082 }
15083
15084 #[test]
15085 fn parser_predicates_support_context_child_text_checks() {
15086 let mut parser = mini_parser(vec![
15087 TestToken::new(1).with_text("var"),
15088 TestToken::eof("parser-test", 1, 1, 1),
15089 ]);
15090 let mut context = ParserRuleContext::new(1, 0);
15091 let mut child_context = ParserRuleContext::new(2, 0);
15092 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
15093 parser.tree.add_child(&mut child_context, terminal);
15094 let child = parser.rule_node(child_context);
15095 parser.tree.add_child(&mut context, child);
15096 let predicates = [(
15097 1,
15098 0,
15099 ParserPredicate::ContextChildRuleTextNotEquals {
15100 rule_index: 2,
15101 text: "var",
15102 },
15103 )];
15104
15105 assert!(
15106 !parser.parser_semantic_predicate_matches_with_context_and_local(
15107 &predicates,
15108 1,
15109 0,
15110 &context,
15111 0,
15112 )
15113 );
15114 }
15115
15116 #[test]
15117 fn context_expected_symbols_walks_nullable_parent_contexts() {
15118 let atn = nested_nullable_context_atn();
15119 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15120 parser.rule_context_stack = vec![
15121 RuleContextFrame {
15122 rule_index: 0,
15123 invoking_state: 0,
15124 },
15125 RuleContextFrame {
15126 rule_index: 1,
15127 invoking_state: 1,
15128 },
15129 RuleContextFrame {
15130 rule_index: 2,
15131 invoking_state: 2,
15132 },
15133 ];
15134
15135 let expected = parser.context_expected_symbols(&atn);
15136
15137 assert!(expected.contains(&1));
15138 assert!(expected.contains(&TOKEN_EOF));
15139 }
15140
15141 #[test]
15142 fn prediction_context_return_states_track_rule_stack_changes() {
15143 let atn = nested_nullable_context_atn();
15144 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15145 parser.rule_context_stack = vec![
15146 RuleContextFrame {
15147 rule_index: 0,
15148 invoking_state: 0,
15149 },
15150 RuleContextFrame {
15151 rule_index: 1,
15152 invoking_state: 1,
15153 },
15154 RuleContextFrame {
15155 rule_index: 2,
15156 invoking_state: 2,
15157 },
15158 ];
15159
15160 let initial_version = parser.rule_context_version();
15161 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15162 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15163 assert_eq!(first, second);
15164 assert_eq!(parser.rule_context_version(), initial_version);
15165
15166 parser.exit_rule();
15167 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15168 assert_ne!(first, after_pop);
15169 assert_ne!(parser.rule_context_version(), initial_version);
15170 }
15171
15172 #[test]
15173 fn generated_match_token_recovers_missing_token_from_context_follow() {
15174 let atn = generated_match_recovery_atn();
15175 let data = RecognizerData::new(
15176 "Mini.g4",
15177 Vocabulary::new(
15178 [None, Some("'X'"), Some("'Y'")],
15179 [None, Some("X"), Some("Y")],
15180 [None::<&str>, None, None],
15181 ),
15182 );
15183 let mut parser = BaseParser::new(
15184 CommonTokenStream::new(Source {
15185 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
15186 index: 0,
15187 }),
15188 data,
15189 );
15190 parser.rule_context_stack = vec![
15191 RuleContextFrame {
15192 rule_index: 0,
15193 invoking_state: 0,
15194 },
15195 RuleContextFrame {
15196 rule_index: 1,
15197 invoking_state: 1,
15198 },
15199 ];
15200 assert_eq!(parser.number_of_syntax_errors(), 0);
15201
15202 let node = parser
15203 .match_token_recovering(2, 5, &atn)
15204 .expect("generated match should insert missing token");
15205
15206 assert_eq!(node.children().len(), 1);
15207 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
15208 assert_eq!(
15209 node.clone()
15210 .into_child_iter()
15211 .map(|child| parser.node(child).text())
15212 .collect::<Vec<_>>(),
15213 ["<missing 'Y'>"]
15214 );
15215 assert!(!node.consumed_eof());
15218 assert_eq!(parser.la(1), TOKEN_EOF);
15219 assert_eq!(parser.number_of_syntax_errors(), 1);
15220 assert_eq!(
15221 parser.generated_parser_diagnostics,
15222 [ParserDiagnostic {
15223 line: 1,
15224 column: 3,
15225 message: "missing 'Y' at '<EOF>'".to_owned(),
15226 }]
15227 );
15228 }
15229
15230 #[test]
15231 fn generated_match_token_counts_single_token_deletion_recovery() {
15232 let atn = generated_match_recovery_atn();
15233 let data = RecognizerData::new(
15234 "Mini.g4",
15235 Vocabulary::new(
15236 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
15237 [None, Some("X"), Some("Y"), Some("Z")],
15238 [None::<&str>, None, None, None],
15239 ),
15240 );
15241 let mut parser = BaseParser::new(
15242 CommonTokenStream::new(Source {
15243 tokens: vec![
15244 TestToken::new(3).with_text("z"),
15245 TestToken::new(2).with_text("y"),
15246 TestToken::eof("parser-test", 3, 1, 3),
15247 ],
15248 index: 0,
15249 }),
15250 data,
15251 );
15252
15253 let node = parser
15254 .match_token_recovering(2, 5, &atn)
15255 .expect("generated match should delete the extraneous token");
15256
15257 assert_eq!(node.children().len(), 2);
15258 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
15259 assert_eq!(parser.node(node.children()[0]).text(), "z");
15260 assert_eq!(parser.node(node.children()[1]).text(), "y");
15261 assert_eq!(
15262 node.into_child_iter()
15263 .map(|child| parser.node(child).text())
15264 .collect::<Vec<_>>(),
15265 ["z", "y"]
15266 );
15267 assert_eq!(parser.number_of_syntax_errors(), 1);
15268 }
15269
15270 #[test]
15271 fn generated_match_token_iterates_single_success_without_a_children_vec() {
15272 let atn = generated_match_recovery_atn();
15273 let data = RecognizerData::new(
15274 "Mini.g4",
15275 Vocabulary::new(
15276 [None, Some("'X'"), Some("'Y'")],
15277 [None, Some("X"), Some("Y")],
15278 [None::<&str>, None, None],
15279 ),
15280 );
15281 let mut parser = BaseParser::new(
15282 CommonTokenStream::new(Source {
15283 tokens: vec![
15284 TestToken::new(2).with_text("y"),
15285 TestToken::eof("parser-test", 1, 1, 1),
15286 ],
15287 index: 0,
15288 }),
15289 data,
15290 );
15291
15292 let node = parser
15293 .match_token_recovering(2, 5, &atn)
15294 .expect("generated match should consume the expected token");
15295
15296 assert_eq!(
15297 node.into_child_iter()
15298 .map(|child| parser.node(child).text())
15299 .collect::<Vec<_>>(),
15300 ["y"]
15301 );
15302 assert_eq!(parser.number_of_syntax_errors(), 0);
15303 }
15304
15305 #[test]
15306 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
15307 let atn = generated_match_recovery_atn();
15308 let data = RecognizerData::new(
15309 "Mini.g4",
15310 Vocabulary::new(
15311 [None, Some("'X'"), Some("'Y'")],
15312 [None, Some("X"), Some("Y")],
15313 [None::<&str>, None, None],
15314 ),
15315 );
15316 let mut parser = BaseParser::new(
15317 CommonTokenStream::new(Source {
15318 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
15319 index: 0,
15320 }),
15321 data,
15322 );
15323 parser.rule_context_stack = vec![
15324 RuleContextFrame {
15325 rule_index: 0,
15326 invoking_state: 0,
15327 },
15328 RuleContextFrame {
15329 rule_index: 1,
15330 invoking_state: 1,
15331 },
15332 ];
15333 let marker = parser.generated_diagnostics_checkpoint();
15334
15335 let _ = parser
15336 .match_token_recovering(2, 5, &atn)
15337 .expect("generated match should insert missing token");
15338 assert_eq!(parser.number_of_syntax_errors(), 1);
15339
15340 parser.restore_generated_diagnostics(marker);
15341
15342 assert_eq!(parser.number_of_syntax_errors(), 0);
15343 assert!(parser.generated_parser_diagnostics.is_empty());
15344 }
15345
15346 #[test]
15347 fn generated_prediction_diagnostics_use_adaptive_context() {
15348 let atn = two_alt_decision_atn();
15349 let data = RecognizerData::new(
15350 "Mini.g4",
15351 Vocabulary::new(
15352 [None, Some("'x'"), Some("'y'")],
15353 [None, Some("X"), Some("Y")],
15354 [None::<&str>, None, None],
15355 ),
15356 )
15357 .with_rule_names(["s"]);
15358 let mut parser = BaseParser::new(
15359 CommonTokenStream::new(Source {
15360 tokens: vec![
15361 TestToken::new(1)
15362 .with_text("x")
15363 .with_position(1, 0)
15364 .with_span(0, 0),
15365 TestToken::new(2)
15366 .with_text("y")
15367 .with_position(1, 2)
15368 .with_span(1, 1),
15369 TestToken::eof("parser-test", 2, 1, 3),
15370 ],
15371 index: 0,
15372 }),
15373 data,
15374 );
15375 parser.set_report_diagnostic_errors(true);
15376
15377 parser.record_generated_prediction_diagnostic(
15378 &atn,
15379 1,
15380 &ParserAtnPrediction {
15381 alt: 1,
15382 requires_full_context: true,
15383 has_semantic_context: false,
15384 diagnostic: Some(ParserAtnPredictionDiagnostic {
15385 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
15386 start_index: 0,
15387 sll_stop_index: 1,
15388 ll_stop_index: 0,
15389 conflicting_alts: vec![1, 2],
15390 exact: false,
15391 }),
15392 },
15393 );
15394 parser.record_generated_prediction_diagnostic(
15399 &atn,
15400 1,
15401 &ParserAtnPrediction {
15402 alt: 1,
15403 requires_full_context: true,
15404 has_semantic_context: false,
15405 diagnostic: Some(ParserAtnPredictionDiagnostic {
15406 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
15407 start_index: 0,
15408 sll_stop_index: 1,
15409 ll_stop_index: 1,
15410 conflicting_alts: vec![1, 2],
15411 exact: false,
15412 }),
15413 },
15414 );
15415
15416 assert_eq!(
15417 parser.generated_parser_diagnostics,
15418 [
15419 ParserDiagnostic {
15420 line: 1,
15421 column: 2,
15422 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
15423 },
15424 ParserDiagnostic {
15425 line: 1,
15426 column: 0,
15427 message: "reportContextSensitivity d=0 (s), input='x'".to_owned(),
15428 },
15429 ParserDiagnostic {
15430 line: 1,
15431 column: 2,
15432 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
15433 },
15434 ]
15435 );
15436 }
15437
15438 #[test]
15439 fn generated_match_not_set_recovers_empty_complement_at_eof() {
15440 let atn = complement_set_atn();
15441 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15442 parser.rule_context_stack = vec![RuleContextFrame {
15443 rule_index: 0,
15444 invoking_state: 0,
15445 }];
15446
15447 let node = parser
15448 .match_not_token_set_recovering(
15449 atn.token_set(0).expect("excluded token set"),
15450 1,
15451 1,
15452 1,
15453 &atn,
15454 )
15455 .expect("empty complement should recover at EOF");
15456
15457 assert_eq!(node.children().len(), 1);
15458 assert!(!node.consumed_eof());
15461 assert_eq!(parser.la(1), TOKEN_EOF);
15462 assert_eq!(
15463 parser.generated_parser_diagnostics,
15464 [ParserDiagnostic {
15465 line: 1,
15466 column: 1,
15467 message: "missing {} at '<EOF>'".to_owned(),
15468 }]
15469 );
15470 }
15471
15472 #[test]
15473 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
15474 let atn = wildcard_then_eof_atn();
15480 let data = RecognizerData::new(
15481 "Mini.g4",
15482 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
15483 );
15484 let mut parser = BaseParser::new(
15485 CommonTokenStream::new(Source {
15486 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
15487 index: 0,
15488 }),
15489 data,
15490 );
15491 parser.rule_context_stack = vec![RuleContextFrame {
15492 rule_index: 0,
15493 invoking_state: 0,
15494 }];
15495
15496 let node = parser
15497 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
15498 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
15499
15500 assert_eq!(node.children().len(), 1);
15502 assert!(!node.consumed_eof());
15503 assert!(
15504 parser
15505 .node(node.children()[0])
15506 .text()
15507 .starts_with("<missing")
15508 );
15509 assert_eq!(parser.la(1), TOKEN_EOF);
15510 assert_eq!(
15511 parser.generated_parser_diagnostics,
15512 [ParserDiagnostic {
15513 line: 1,
15514 column: 1,
15515 message: "missing 'x' at '<EOF>'".to_owned(),
15516 }]
15517 );
15518 }
15519
15520 #[test]
15521 fn generated_rule_recovery_consumes_to_parent_follow() {
15522 let atn = generated_match_recovery_atn();
15523 let data = RecognizerData::new(
15524 "Mini.g4",
15525 Vocabulary::new(
15526 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
15527 [None, Some("X"), Some("Y"), Some("Z")],
15528 [None::<&str>, None, None, None],
15529 ),
15530 );
15531 let mut parser = BaseParser::new(
15532 CommonTokenStream::new(Source {
15533 tokens: vec![
15534 TestToken::new(3).with_text("z"),
15535 TestToken::eof("parser-test", 1, 1, 1),
15536 ],
15537 index: 0,
15538 }),
15539 data,
15540 );
15541 let _parent = parser.enter_rule(0, 0);
15542 let marker = parser.push_invoking_state(1);
15543 let mut child = parser.enter_rule(4, 1);
15544 parser.discard_invoking_state(marker);
15545
15546 parser.recover_generated_rule(
15547 &mut child,
15548 &atn,
15549 AntlrError::ParserError {
15550 line: 1,
15551 column: 0,
15552 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
15553 },
15554 );
15555 let tree = parser.finish_rule(child, false);
15556
15557 assert_eq!(parser.la(1), TOKEN_EOF);
15558 assert_eq!(
15559 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
15560 "(a z)"
15561 );
15562 assert_eq!(parser.number_of_syntax_errors(), 1);
15563 assert_eq!(
15564 parser.generated_parser_diagnostics,
15565 [ParserDiagnostic {
15566 line: 1,
15567 column: 0,
15568 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
15569 }]
15570 );
15571 parser.exit_rule();
15572 }
15573
15574 #[test]
15575 fn generated_rule_recovery_forces_progress_after_repeated_error_state() {
15576 let atn = nested_nullable_context_atn();
15577 let mut parser = mini_parser(vec![
15578 TestToken::new(1).with_text("x"),
15579 TestToken::eof("parser-test", 1, 1, 1),
15580 ]);
15581 parser.rule_context_stack = vec![
15582 RuleContextFrame {
15583 rule_index: 0,
15584 invoking_state: 0,
15585 },
15586 RuleContextFrame {
15587 rule_index: 1,
15588 invoking_state: 1,
15589 },
15590 RuleContextFrame {
15591 rule_index: 2,
15592 invoking_state: 2,
15593 },
15594 ];
15595 parser.set_state(20);
15596 let mut context = ParserRuleContext::new(2, 2);
15597
15598 parser.recover_generated_rule(
15599 &mut context,
15600 &atn,
15601 AntlrError::NoViableAlternative {
15602 input: "'x'".to_owned(),
15603 },
15604 );
15605 assert_eq!(parser.input.index(), 0);
15606
15607 parser.set_state(21);
15608 parser.recover_generated_rule(
15609 &mut context,
15610 &atn,
15611 AntlrError::NoViableAlternative {
15612 input: "'x'".to_owned(),
15613 },
15614 );
15615 assert_eq!(parser.input.index(), 0);
15616 assert_eq!(
15617 parser.generated_recovery_error_states,
15618 BTreeSet::from([20, 21])
15619 );
15620
15621 parser.set_state(20);
15622 parser.recover_generated_rule(
15623 &mut context,
15624 &atn,
15625 AntlrError::NoViableAlternative {
15626 input: "'x'".to_owned(),
15627 },
15628 );
15629
15630 assert_eq!(parser.input.index(), 1);
15631 assert_eq!(parser.la(1), TOKEN_EOF);
15632 assert!(context.has_matched_child());
15633 assert_eq!(parser.generated_recovery_error_states, BTreeSet::from([20]));
15634
15635 parser.match_eof().expect("EOF should match");
15636 assert_eq!(parser.generated_recovery_error_index, None);
15637 assert!(parser.generated_recovery_error_states.is_empty());
15638 }
15639
15640 #[test]
15641 fn greedy_ll1_alt_handles_nullable_loop_exit() {
15642 let mut body_symbols = TokenBitSet::default();
15643 body_symbols.insert(1);
15644 let entry = DecisionLookahead {
15645 transitions: vec![
15646 TransitionLookSet {
15647 symbols: body_symbols,
15648 nullable: false,
15649 },
15650 TransitionLookSet {
15651 symbols: TokenBitSet::default(),
15652 nullable: true,
15653 },
15654 ],
15655 };
15656
15657 assert_eq!(ll1_unique_alt(&entry, 2), None);
15658 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
15659 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
15660 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
15661 }
15662
15663 #[test]
15664 fn ordinary_repetition_builds_tree_in_input_order() {
15665 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15666 let mut parser = mini_parser(repeated_x_tokens(3));
15667 let tree = parser
15668 .parse_atn_rule(&atn, 0)
15669 .expect("ordinary repetition should parse");
15670
15671 let root = parser
15672 .node(tree)
15673 .as_rule()
15674 .expect("entry result should be a rule");
15675 let body_rules = root.child_rules(1).collect::<Vec<_>>();
15676 assert_eq!(root.text(), "xxx<EOF>");
15677 assert_eq!(body_rules.len(), 3);
15678 assert_eq!(
15679 body_rules
15680 .iter()
15681 .map(|rule| rule.start_id().expect("body start").index())
15682 .collect::<Vec<_>>(),
15683 [0, 1, 2]
15684 );
15685 assert_eq!(
15686 body_rules
15687 .iter()
15688 .map(|rule| rule.stop_id().expect("body stop").index())
15689 .collect::<Vec<_>>(),
15690 [0, 1, 2]
15691 );
15692 assert_eq!(parser.number_of_syntax_errors(), 0);
15693 }
15694 }
15695
15696 #[test]
15697 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
15698 const DEPTH: usize = 20_000;
15699
15700 std::thread::Builder::new()
15701 .name("deferred-rule-materialization".to_owned())
15702 .stack_size(256 * 1024)
15703 .spawn(|| {
15704 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
15705 let mut root = FastDeferredNodeId::EMPTY;
15706 for depth in 0..DEPTH {
15707 root = parser
15708 .recognition_arena
15709 .deferred_rule_node(FastDeferredRule {
15710 rule_index: u32::try_from(depth).expect("depth fits in u32"),
15711 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
15712 start_index: 0,
15713 stop_index: None,
15714 deferred_children: root,
15715 children: NodeSeqId::EMPTY,
15716 });
15717 }
15718
15719 let mut children = parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
15720 for expected_rule in (0..DEPTH).rev() {
15721 let mut nodes = parser.recognition_arena.iter(children);
15722 let node = nodes.next().expect("nested rule node");
15723 assert!(nodes.next().is_none(), "each rule has one child");
15724 let ArenaRecognizedNode::Rule {
15725 rule_index,
15726 children: nested,
15727 ..
15728 } = parser.recognition_arena.node(node)
15729 else {
15730 panic!("expected nested rule");
15731 };
15732 assert_eq!(rule_index as usize, expected_rule);
15733 children = nested;
15734 }
15735 assert!(children.is_empty());
15736 })
15737 .expect("small-stack thread should start")
15738 .join()
15739 .expect("deferred rules should materialize without recursion");
15740 }
15741
15742 #[test]
15743 fn deeply_nested_rule_calls_grow_the_stack() {
15744 const DEPTH: usize = 4_096;
15745 const STACK_SIZE: usize = 256 * 1024;
15746 let atn = nested_rule_chain_atn(DEPTH);
15747 std::thread::Builder::new()
15748 .name("nested-adaptive-set-rules".to_owned())
15749 .stack_size(STACK_SIZE)
15750 .spawn(move || {
15751 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
15752 parser.set_build_parse_trees(false);
15753 parser.fast_first_set_prefilter = false;
15756 parser
15757 .parse_atn_rule(&atn, 0)
15758 .expect("nested rule chain should grow the native stack");
15759 assert_eq!(parser.input.index(), 1);
15760 })
15761 .expect("small-stack thread should start")
15762 .join()
15763 .expect("nested rule chain should not overflow its stack");
15764 }
15765
15766 #[test]
15767 fn deeply_nested_branching_rules_grow_the_stack() {
15768 const DEPTH: usize = 4_096;
15769 const STACK_SIZE: usize = 256 * 1024;
15770 let atn = nested_rule_graph_atn(DEPTH, true, false);
15771 std::thread::Builder::new()
15772 .name("nested-branching-rules".to_owned())
15773 .stack_size(STACK_SIZE)
15774 .spawn(move || {
15775 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
15776 parser.set_build_parse_trees(false);
15777 parser
15778 .parse_atn_rule(&atn, 0)
15779 .expect("branching rule chain should grow the native stack");
15780 assert_eq!(parser.input.index(), 1);
15781 })
15782 .expect("small-stack thread should start")
15783 .join()
15784 .expect("branching rule chain should not overflow its stack");
15785 }
15786
15787 #[test]
15788 fn deeply_nested_rule_follows_grow_the_stack() {
15789 const DEPTH: usize = 4_096;
15790 const STACK_SIZE: usize = 256 * 1024;
15791 let atn = nested_rule_graph_atn(DEPTH, false, true);
15792 std::thread::Builder::new()
15793 .name("nested-rule-follows".to_owned())
15794 .stack_size(STACK_SIZE)
15795 .spawn(move || {
15796 let mut parser = mini_parser(repeated_x_tokens(DEPTH));
15797 parser.set_build_parse_trees(false);
15798 parser.fast_first_set_prefilter = false;
15799 parser
15800 .parse_atn_rule(&atn, 0)
15801 .expect("rule follow chain should grow the native stack");
15802 assert_eq!(parser.input.index(), DEPTH);
15803 })
15804 .expect("small-stack thread should start")
15805 .join()
15806 .expect("nested rule follow chain should not overflow its stack");
15807 }
15808
15809 #[test]
15810 fn deeply_nested_recovery_grows_the_stack() {
15811 const DEPTH: usize = 4_096;
15812 const STACK_SIZE: usize = 256 * 1024;
15813 let atn = nested_rule_chain_atn(DEPTH);
15814 std::thread::Builder::new()
15815 .name("nested-rule-recovery".to_owned())
15816 .stack_size(STACK_SIZE)
15817 .spawn(move || {
15818 let mut parser = mini_parser(vec![
15819 TestToken::new(2).with_text("z"),
15820 TestToken::new(1).with_text("x"),
15821 TestToken::eof("parser-test", 2, 1, 2),
15822 ]);
15823 parser.set_build_parse_trees(false);
15824 parser.fast_first_set_prefilter = false;
15825 parser
15826 .parse_atn_rule(&atn, 0)
15827 .expect("nested recovery should grow the native stack");
15828 assert_eq!(parser.input.index(), 2);
15829 assert_eq!(parser.number_of_syntax_errors(), 1);
15830 })
15831 .expect("small-stack thread should start")
15832 .join()
15833 .expect("nested rule recovery should not overflow its stack");
15834 }
15835
15836 #[test]
15837 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
15838 const REPETITIONS: usize = 64;
15839
15840 let atn = ambiguous_ordinary_star_loop_atn();
15841 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15842 let tree = parser
15843 .parse_atn_rule(&atn, 0)
15844 .expect("ambiguous ordinary repetition should parse");
15845
15846 let root = parser
15847 .node(tree)
15848 .as_rule()
15849 .expect("entry result should be a rule");
15850 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
15851 assert_eq!(parser.input.index(), REPETITIONS);
15852 assert!(
15853 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
15854 "equivalent segmentations should keep deferred storage linear"
15855 );
15856 assert_eq!(parser.number_of_syntax_errors(), 0);
15857 }
15858
15859 #[test]
15860 fn long_ordinary_repetition_does_not_consume_native_stack() {
15861 const REPETITIONS: usize = 20_000;
15862
15863 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15864 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15865 parser.set_build_parse_trees(false);
15866 parser
15867 .parse_atn_rule(&atn, 0)
15868 .expect("long ordinary repetition should parse");
15869
15870 assert_eq!(parser.input.index(), REPETITIONS);
15871 assert_eq!(parser.number_of_syntax_errors(), 0);
15872 }
15873 }
15874
15875 #[test]
15876 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
15877 const REPETITIONS: usize = 2_000;
15878 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
15879
15880 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15881 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15882 let tree = parser
15883 .parse_atn_rule(&atn, 0)
15884 .expect("long rule repetition should parse");
15885
15886 let root = parser
15887 .node(tree)
15888 .as_rule()
15889 .expect("entry result should be a rule");
15890 assert_eq!(root.text(), expected_text);
15891 assert_eq!(root.child_rules(1).count(), REPETITIONS);
15892 let first_body = root.child_rules(1).next().expect("first body rule");
15893 let last_body = root.child_rules(1).next_back().expect("last body rule");
15894 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
15895 assert_eq!(
15896 last_body.stop_id().expect("last body stop").index(),
15897 REPETITIONS - 1
15898 );
15899
15900 let stats = parser.recognition_arena_stats();
15901 assert_eq!(
15902 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
15903 (REPETITIONS, REPETITIONS, 0)
15904 );
15905 assert_eq!(
15906 (stats.total_links, stats.live_links, stats.dead_links),
15907 (REPETITIONS, REPETITIONS, 0)
15908 );
15909 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
15910 assert_eq!(
15911 parser.recognition_arena.deferred_nodes.len(),
15912 REPETITIONS * 2 - 1
15913 );
15914 assert_eq!(parser.number_of_syntax_errors(), 0);
15915 }
15916 }
15917
15918 #[test]
15919 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
15920 let key = |state_number| FastRecognizeKey {
15921 state_number,
15922 stop_state: 10,
15923 index: state_number,
15924 rule_start_index: 0,
15925 decision_start_index: None,
15926 precedence: 0,
15927 recovery_symbols_id: 0,
15928 recovery_state: None,
15929 };
15930
15931 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15932 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
15933 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
15934 }
15935 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
15936 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
15937
15938 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15939 let repeated = key(1);
15940 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
15941 assert!(promote.clean_memo_enabled_for_key(&repeated));
15942 }
15943 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
15944
15945 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
15946 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
15947 }
15948 assert!(sparse.clean_memo_enabled_for_key(&repeated));
15949 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
15950 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
15951 assert!(sparse.clean_memo_enabled_for_key(&repeated));
15952 }
15953 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
15954 }
15955
15956 #[test]
15957 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
15958 assert_eq!(
15959 fast_recognize_memo_capacity(0),
15960 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
15961 );
15962 assert_eq!(
15963 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
15964 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
15965 );
15966 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
15967 assert_eq!(
15968 fast_recognize_memo_capacity(usize::MAX),
15969 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
15970 );
15971 }
15972
15973 #[test]
15974 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
15975 let mut scratch = FastRecognizeTopScratch::default();
15976 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
15977 let retained_capacity = scratch.memo.capacity();
15978 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
15979 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15980
15981 let larger_capacity = retained_capacity + 1;
15982 scratch.prepare(larger_capacity);
15983 let grown_capacity = scratch.memo.capacity();
15984 assert!(grown_capacity >= larger_capacity);
15985 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15986
15987 scratch.memo.insert(
15988 FastRecognizeKey {
15989 state_number: 0,
15990 stop_state: 0,
15991 index: 0,
15992 rule_start_index: 0,
15993 decision_start_index: None,
15994 precedence: 0,
15995 recovery_symbols_id: 0,
15996 recovery_state: None,
15997 },
15998 Rc::from([FastRecognizeOutcome {
15999 index: 0,
16000 consumed_eof: false,
16001 diagnostics: DiagnosticSeqId::EMPTY,
16002 deferred_nodes: FastDeferredNodeId::EMPTY,
16003 nodes: NodeSeqId::EMPTY,
16004 }]),
16005 );
16006 scratch.release_oversized_memo();
16007 assert!(scratch.memo.is_empty());
16008 assert_eq!(scratch.memo.capacity(), grown_capacity);
16009
16010 scratch
16011 .memo
16012 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
16013 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16014
16015 scratch.release_oversized_memo();
16016 assert!(scratch.memo.is_empty());
16017 assert_eq!(scratch.memo.capacity(), 0);
16018 }
16019
16020 #[test]
16021 fn clean_empty_multi_alt_outcomes_are_memoized() {
16022 let mut atn = ParserAtnBuilder::new(2);
16023 assert_eq!(
16024 atn.add_state(AtnStateKind::RuleStart, Some(0))
16025 .expect("state")
16026 .index(),
16027 0
16028 );
16029 assert_eq!(
16030 atn.add_state(AtnStateKind::BlockStart, Some(0))
16031 .expect("state")
16032 .index(),
16033 1
16034 );
16035 assert_eq!(
16036 atn.add_state(AtnStateKind::RuleStop, Some(0))
16037 .expect("state")
16038 .index(),
16039 2
16040 );
16041 atn.set_rule_to_start_state(vec![0])
16042 .expect("rule start states");
16043 atn.set_rule_to_stop_state(vec![2])
16044 .expect("rule stop states");
16045 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16046 .expect("transition");
16047 atn.add_transition(
16048 1,
16049 ParserTransitionSpec::Atom {
16050 target: 2,
16051 label: 1,
16052 },
16053 )
16054 .expect("transition");
16055 atn.add_transition(
16056 1,
16057 ParserTransitionSpec::Atom {
16058 target: 2,
16059 label: 2,
16060 },
16061 )
16062 .expect("transition");
16063 let atn = finish_atn(atn);
16064
16065 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
16066 parser.fast_recovery_enabled = false;
16067 let mut visiting = FxHashSet::default();
16068 let mut memo = FxHashMap::default();
16069 let mut expected = ExpectedTokens::default();
16070 let outcomes = parser.recognize_state_fast(
16071 &atn,
16072 FastRecognizeRequest {
16073 state_number: 1,
16074 stop_state: 2,
16075 index: 0,
16076 rule_start_index: 0,
16077 decision_start_index: None,
16078 precedence: 0,
16079 depth: 0,
16080 recovery_symbols: parser.empty_recovery_symbols(),
16081 recovery_state: None,
16082 },
16083 FastRecognizeScratch {
16084 predicate_context: None,
16085 visiting: &mut visiting,
16086 memo: &mut memo,
16087 expected: &mut expected,
16088 native_depth: 0,
16089 },
16090 );
16091
16092 assert!(outcomes.is_empty());
16093 assert_eq!(memo.len(), 1);
16094 assert!(memo.values().next().expect("memo entry").is_empty());
16095
16096 parser.clean_memo_mode = CleanMemoMode::Sparse;
16097 visiting.clear();
16098 memo.clear();
16099 expected = ExpectedTokens::default();
16100 let sparse_outcomes = parser.recognize_state_fast(
16101 &atn,
16102 FastRecognizeRequest {
16103 state_number: 1,
16104 stop_state: 2,
16105 index: 0,
16106 rule_start_index: 0,
16107 decision_start_index: None,
16108 precedence: 0,
16109 depth: 0,
16110 recovery_symbols: parser.empty_recovery_symbols(),
16111 recovery_state: None,
16112 },
16113 FastRecognizeScratch {
16114 predicate_context: None,
16115 visiting: &mut visiting,
16116 memo: &mut memo,
16117 expected: &mut expected,
16118 native_depth: 0,
16119 },
16120 );
16121
16122 assert!(sparse_outcomes.is_empty());
16123 assert!(memo.is_empty());
16124 }
16125
16126 #[test]
16127 fn wildcard_matches_non_eof_only() {
16128 let mut parser = mini_parser(vec![
16129 TestToken::new(1).with_text("x"),
16130 TestToken::eof("parser-test", 1, 1, 1),
16131 ]);
16132 let matched = parser.match_wildcard().expect("wildcard");
16133 assert_eq!(parser.node(matched).text(), "x");
16134 assert!(parser.match_wildcard().is_err());
16135 }
16136
16137 #[test]
16138 fn add_parse_child_records_match_even_without_tree_building() {
16139 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16144 let token = TestToken::new(1).with_text("x");
16145
16146 parser.set_build_parse_trees(false);
16147 let mut ctx = ParserRuleContext::new(0, 0);
16148 assert!(!ctx.has_matched_child());
16149 let child = parser.terminal_tree(token.id);
16150 parser.add_parse_child(&mut ctx, child);
16151 assert_eq!(ctx.child_count(), 0);
16153 assert_eq!(parser.parse_tree_storage().node_count(), 0);
16154 assert!(ctx.has_matched_child());
16156
16157 parser.set_build_parse_trees(true);
16159 let mut ctx = ParserRuleContext::new(0, 0);
16160 let child = parser.terminal_tree(token.id);
16161 parser.add_parse_child(&mut ctx, child);
16162 assert_eq!(ctx.child_count(), 1);
16163 assert!(ctx.has_matched_child());
16164 }
16165
16166 #[test]
16167 fn disabled_tree_building_does_not_grow_flat_storage() {
16168 let mut parser = mini_parser(vec![
16169 TestToken::new(1).with_text("x"),
16170 TestToken::new(1).with_text("y"),
16171 TestToken::eof("parser-test", 2, 1, 2),
16172 ]);
16173 parser.set_build_parse_trees(false);
16174 let mut context = ParserRuleContext::new(0, -1);
16175
16176 for _ in 0..2 {
16177 let child = parser.match_token(1).expect("token should match");
16178 parser.add_parse_child(&mut context, child);
16179 }
16180 let current = parser.input.lt_id(1).expect("EOF token");
16181 let error = parser.error_tree(current);
16182 parser.add_parse_child(&mut context, error);
16183 let root = parser.rule_node(context);
16184
16185 assert_eq!(
16186 parser.parse_tree_storage().stats(),
16187 ParseTreeStats::default()
16188 );
16189 assert!(
16190 parser
16191 .parse_tree_storage()
16192 .node(parser.token_store(), root)
16193 .is_none(),
16194 "the no-tree sentinel must not resolve to stored data"
16195 );
16196 }
16197
16198 #[test]
16199 fn disabled_tree_building_skips_recognition_rule_node_storage() {
16200 let atn = ordinary_star_loop_atn();
16201 let mut parser = mini_parser(repeated_x_tokens(3));
16202 parser.set_build_parse_trees(false);
16203
16204 parser
16205 .parse_atn_rule(&atn, 0)
16206 .expect("ordinary repetition should parse without a tree");
16207
16208 assert_eq!(parser.input.index(), 3);
16209 assert!(parser.recognition_arena.nodes.is_empty());
16210 assert!(parser.recognition_arena.seq_links.is_empty());
16211 assert!(parser.recognition_arena.deferred_nodes.is_empty());
16212 assert!(parser.recognition_arena.deferred_rules.is_empty());
16213 assert!(!parser.fast_token_nodes_enabled);
16214 assert!(parser.fast_recognize_scratch.memo.is_empty());
16215 }
16216
16217 #[test]
16218 fn parser_interprets_simple_atn_rule() {
16219 let atn = token_then_eof_atn();
16220 let mut parser = mini_parser(vec![
16221 TestToken::new(1).with_text("x"),
16222 TestToken::eof("parser-test", 1, 1, 1),
16223 ]);
16224
16225 let tree = parser
16226 .parse_atn_rule(&atn, 0)
16227 .expect("artificial parser rule should parse");
16228 assert_eq!(parser.node(tree).text(), "x<EOF>");
16229 assert_eq!(parser.number_of_syntax_errors(), 0);
16230 assert_eq!(
16231 parser
16232 .node(tree)
16233 .first_rule_stop(0)
16234 .expect("rule should stop at EOF")
16235 .token_type(),
16236 TOKEN_EOF
16237 );
16238
16239 let mut parser = mini_parser(vec![
16240 TestToken::new(1).with_text("x"),
16241 TestToken::eof("parser-test", 1, 1, 1),
16242 ]);
16243 let (tree, actions) = parser
16244 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16245 .expect("runtime-option parser rule should parse");
16246 assert!(actions.is_empty());
16247 assert_eq!(
16248 parser
16249 .node(tree)
16250 .first_rule_stop(0)
16251 .expect("rule should stop at EOF")
16252 .token_type(),
16253 TOKEN_EOF
16254 );
16255 }
16256
16257 #[test]
16258 fn runtime_options_default_ignores_noop_action_transitions() {
16259 let atn = noop_action_then_token_then_eof_atn();
16260 let mut parser = mini_parser(vec![
16261 TestToken::new(1).with_text("x"),
16262 TestToken::eof("parser-test", 1, 1, 1),
16263 ]);
16264
16265 let (tree, actions) = parser
16266 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16267 .expect("no-op parser action should not force action replay");
16268
16269 assert_eq!(parser.node(tree).text(), "x<EOF>");
16270 assert!(
16271 actions.is_empty(),
16272 "action_index=None transitions are ANTLR metadata, not replay actions"
16273 );
16274 assert_eq!(parser.number_of_syntax_errors(), 0);
16275 }
16276
16277 #[test]
16278 fn parser_exposes_buffered_token_stream_after_parse() {
16279 let atn = token_then_eof_atn();
16280 let mut parser = mini_parser(vec![
16281 TestToken::new(1).with_text("x"),
16282 TestToken::eof("parser-test", 1, 1, 1),
16283 ]);
16284
16285 let tree = parser
16286 .parse_atn_rule(&atn, 0)
16287 .expect("artificial parser rule should parse");
16288 assert_eq!(parser.node(tree).text(), "x<EOF>");
16289
16290 let stream = parser.token_stream();
16291 let source_index_after_parse = stream.token_source().index;
16292 let buffered = stream.tokens().collect::<Vec<_>>();
16293 assert_eq!(buffered.len(), 2);
16294 assert_eq!(buffered[0].text(), Some("x"));
16295 assert_eq!(buffered[0].token_id().index(), 0);
16296 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
16297 assert_eq!(stream.token_source().index, source_index_after_parse);
16298 drop(buffered);
16299
16300 let stream = parser.into_token_stream();
16301 assert_eq!(stream.token_source().index, source_index_after_parse);
16302 assert_eq!(
16303 stream.tokens().next().expect("first token").text(),
16304 Some("x")
16305 );
16306 assert_eq!(
16307 stream.tokens().nth(1).expect("EOF token").token_type(),
16308 TOKEN_EOF
16309 );
16310 }
16311
16312 #[test]
16313 fn parsed_file_exposes_all_buffered_tokens() {
16314 let atn = token_then_eof_atn();
16315 let mut parser = mini_parser(vec![
16316 TestToken::new(99)
16317 .with_text(" comment")
16318 .with_channel(HIDDEN_CHANNEL),
16319 TestToken::new(1).with_text("x"),
16320 TestToken::eof("parser-test", 9, 1, 9),
16321 ]);
16322
16323 let tree = parser
16324 .parse_atn_rule(&atn, 0)
16325 .expect("artificial parser rule should parse");
16326 let parsed = parser.into_parsed_file(tree);
16327
16328 assert_eq!(
16329 parsed
16330 .tokens()
16331 .iter()
16332 .map(|token| (token.token_type(), token.channel(), token.text()))
16333 .collect::<Vec<_>>(),
16334 [
16335 (99, HIDDEN_CHANNEL, Some(" comment")),
16336 (1, DEFAULT_CHANNEL, Some("x")),
16337 (TOKEN_EOF, DEFAULT_CHANNEL, Some("<EOF>")),
16338 ]
16339 );
16340 assert_eq!(parsed.tokens().into_iter().count(), 3);
16341 }
16342
16343 #[test]
16344 fn parser_syntax_error_count_tracks_interpreted_recovery() {
16345 let atn = token_then_eof_atn();
16346 let mut parser = mini_parser(vec![
16347 TestToken::new(1).with_text("x"),
16348 TestToken::new(2).with_text("y"),
16349 TestToken::eof("parser-test", 2, 1, 2),
16350 ]);
16351
16352 let tree = parser
16353 .parse_atn_rule(&atn, 0)
16354 .expect("invalid token should recover into an error node");
16355
16356 assert_eq!(parser.number_of_syntax_errors(), 1);
16357 assert_eq!(
16358 parser
16359 .node(tree)
16360 .first_error_token()
16361 .expect("recovery should embed an error token")
16362 .text(),
16363 Some("y")
16364 );
16365 }
16366
16367 #[test]
16368 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
16369 let atn = token_then_eof_atn();
16370 let mut parser = mini_parser(vec![
16371 TestToken::new(2).with_text("y"),
16372 TestToken::eof("parser-test", 1, 1, 1),
16373 ]);
16374
16375 let error = parser
16376 .parse_atn_rule(&atn, 0)
16377 .expect_err("start-rule mismatch should remain a parser error");
16378
16379 assert_eq!(parser.number_of_syntax_errors(), 1);
16380 assert!(matches!(error, AntlrError::ParserError { .. }));
16381 }
16382
16383 #[test]
16384 fn adaptive_direct_rule_uses_simulator_decision() {
16385 let atn = two_alt_decision_atn();
16386 let mut simulator = ParserAtnSimulator::new(&atn);
16387 let mut parser = mini_parser(vec![
16388 TestToken::new(2).with_text("y"),
16389 TestToken::eof("parser-test", 1, 1, 1),
16390 ]);
16391
16392 let tree = parser
16393 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
16394 .expect("direct adaptive rule should parse");
16395
16396 assert_eq!(parser.node(tree).text(), "y");
16397 assert_eq!(parser.input.index(), 1);
16398 }
16399
16400 #[test]
16401 fn adaptive_direct_rule_restores_input_on_fallback() {
16402 let atn = predicate_after_token_atn();
16403 let mut simulator = ParserAtnSimulator::new(&atn);
16404 let mut parser = mini_parser(vec![
16405 TestToken::new(1).with_text("x"),
16406 TestToken::new(2).with_text("y"),
16407 TestToken::eof("parser-test", 2, 1, 2),
16408 ]);
16409
16410 let tree = parser
16411 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
16412 .expect("fallback recognizer should parse");
16413
16414 assert_eq!(parser.node(tree).text(), "xy");
16415 assert_eq!(parser.input.index(), 2);
16416 let stats = parser.parse_tree_storage().stats();
16417 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
16418 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
16419 assert_eq!(stats.scratch_links, 0);
16420 }
16421
16422 #[test]
16423 fn unknown_predicate_policy_defaults_to_assume_true() {
16424 let atn = predicate_after_token_atn();
16425 let mut parser = mini_parser(vec![
16426 TestToken::new(1).with_text("x"),
16427 TestToken::new(2).with_text("y"),
16428 TestToken::eof("parser-test", 2, 1, 2),
16429 ]);
16430
16431 let (tree, _) = parser
16432 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16433 .expect("unknown predicate should pass under the default policy");
16434
16435 assert_eq!(parser.node(tree).text(), "xy");
16436 assert_eq!(parser.number_of_syntax_errors(), 0);
16437 }
16438
16439 #[test]
16440 fn predicate_gated_same_lookahead_uses_viable_alternative() {
16441 let atn = predicate_gated_same_lookahead_atn([0, 1]);
16442 let mut parser = mini_parser(vec![
16443 TestToken::new(1).with_text("x"),
16444 TestToken::eof("parser-test", 1, 1, 1),
16445 ]);
16446
16447 let (tree, _) = parser
16448 .parse_atn_rule_with_runtime_options(
16449 &atn,
16450 0,
16451 ParserRuntimeOptions {
16452 predicates: &[
16453 (0, 0, ParserPredicate::False),
16454 (0, 1, ParserPredicate::True),
16455 ],
16456 ..ParserRuntimeOptions::default()
16457 },
16458 )
16459 .expect("the second predicate-gated alternative should match");
16460
16461 assert_eq!(parser.node(tree).text(), "x<EOF>");
16462 assert_eq!(parser.number_of_syntax_errors(), 0);
16463 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
16464 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
16465 }
16466
16467 #[test]
16468 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
16469 let atn = token_then_eof_atn();
16473 let mut parser = mini_parser(vec![
16474 TestToken::new(1).with_text("x"),
16475 TestToken::eof("parser-test", 1, 1, 1),
16476 ]);
16477
16478 parser.unknown_predicate_hits.push((7, 3));
16480
16481 parser
16483 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16484 .expect("child rule parses");
16485
16486 let error = parser
16488 .take_unknown_semantic_error()
16489 .expect("parent's recorded coordinate must survive the nested interpreted parse");
16490 let AntlrError::Unsupported(message) = error else {
16491 panic!("expected AntlrError::Unsupported, got {error:?}");
16492 };
16493 assert!(message.contains("pred_index=3"), "message: {message}");
16494 }
16495
16496 #[test]
16497 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
16498 let atn = predicate_after_token_atn();
16499 let mut parser = mini_parser(vec![
16500 TestToken::new(1).with_text("x"),
16501 TestToken::new(2).with_text("y"),
16502 TestToken::eof("parser-test", 2, 1, 2),
16503 ]);
16504
16505 let result = parser.parse_atn_rule_with_runtime_options(
16506 &atn,
16507 0,
16508 ParserRuntimeOptions {
16509 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
16510 ..ParserRuntimeOptions::default()
16511 },
16512 );
16513
16514 assert!(
16515 result.is_err(),
16516 "the only path is predicate-guarded, so assume-false must fail the parse"
16517 );
16518 }
16519
16520 #[test]
16521 fn predicate_failure_message_keeps_semantic_recovery_path() {
16522 let atn = predicate_after_token_atn();
16523 let mut parser = mini_parser(vec![
16524 TestToken::new(1).with_text("x"),
16525 TestToken::new(2).with_text("y"),
16526 TestToken::eof("parser-test", 2, 1, 2),
16527 ]);
16528
16529 let (tree, _) = parser
16530 .parse_atn_rule_with_runtime_options(
16531 &atn,
16532 0,
16533 ParserRuntimeOptions {
16534 predicates: &[(
16535 0,
16536 0,
16537 ParserPredicate::FalseWithMessage {
16538 message: "predicate rejected input",
16539 },
16540 )],
16541 ..ParserRuntimeOptions::default()
16542 },
16543 )
16544 .expect("failure-message predicates recover through the semantic interpreter");
16545
16546 assert_eq!(parser.node(tree).text(), "xy");
16547 assert_eq!(parser.number_of_syntax_errors(), 1);
16548 assert!(
16549 parser.fast_predicate_cache.is_empty(),
16550 "failure-message predicates need the semantic interpreter's recovery outcome"
16551 );
16552 }
16553
16554 #[test]
16555 fn unknown_predicate_policy_error_names_the_coordinate() {
16556 let atn = predicate_after_token_atn();
16557 let mut parser = mini_parser(vec![
16558 TestToken::new(1).with_text("x"),
16559 TestToken::new(2).with_text("y"),
16560 TestToken::eof("parser-test", 2, 1, 2),
16561 ]);
16562
16563 let error = parser
16564 .parse_atn_rule_with_runtime_options(
16565 &atn,
16566 0,
16567 ParserRuntimeOptions {
16568 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16569 ..ParserRuntimeOptions::default()
16570 },
16571 )
16572 .expect_err("evaluating an unknown predicate under Error policy must fail");
16573
16574 let AntlrError::Unsupported(message) = error else {
16575 panic!("expected AntlrError::Unsupported, got {error:?}");
16576 };
16577 assert!(
16578 message.contains("unsupported semantic predicate"),
16579 "message should name the failure class: {message}"
16580 );
16581 assert!(
16582 message.contains("pred_index=0"),
16583 "message should carry the coordinate: {message}"
16584 );
16585 }
16586
16587 #[test]
16588 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
16589 let atn = predicate_after_token_atn();
16595 let mut parser = mini_parser(vec![
16596 TestToken::new(1).with_text("x"),
16597 TestToken::new(2).with_text("y"),
16598 TestToken::eof("parser-test", 2, 1, 2),
16599 ]);
16600
16601 parser
16602 .parse_atn_rule_with_runtime_options(
16603 &atn,
16604 0,
16605 ParserRuntimeOptions {
16606 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16607 ..ParserRuntimeOptions::default()
16608 },
16609 )
16610 .expect_err("first parse fails loud under the Error policy");
16611
16612 parser.reset_unknown_semantic_hits();
16617 assert!(
16618 parser.take_unknown_semantic_error().is_none(),
16619 "reset must drop stale unknown-predicate coordinates before a reused parse"
16620 );
16621 }
16622
16623 #[derive(Debug, Default)]
16624 struct RecordingHooks {
16625 predicates: Vec<(usize, usize, usize, Option<String>)>,
16626 actions: Vec<(usize, String, Option<String>)>,
16627 action_trees: Vec<Option<String>>,
16628 }
16629
16630 impl SemanticHooks for RecordingHooks {
16631 fn sempred<S>(
16632 &mut self,
16633 ctx: &mut ParserSemCtx<'_, S>,
16634 rule_index: usize,
16635 pred_index: usize,
16636 ) -> Option<bool>
16637 where
16638 S: TokenSource,
16639 {
16640 self.predicates.push((
16641 ctx.input_index(),
16642 rule_index,
16643 pred_index,
16644 ctx.token_text(1)
16645 .and_then(|token| token.text().map(str::to_owned)),
16646 ));
16647 Some(true)
16648 }
16649
16650 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
16651 where
16652 S: TokenSource,
16653 {
16654 self.actions.push((
16655 action.source_state(),
16656 ctx.action_text(),
16657 ctx.rule_name().map(str::to_owned),
16658 ));
16659 self.action_trees.push(ctx.tree().map(Node::text));
16660 true
16661 }
16662 }
16663
16664 #[derive(Debug, Default)]
16665 struct RejectingPredicateHooks {
16666 predicates: Vec<(usize, usize, usize, Option<String>)>,
16667 }
16668
16669 impl SemanticHooks for RejectingPredicateHooks {
16670 fn sempred<S>(
16671 &mut self,
16672 ctx: &mut ParserSemCtx<'_, S>,
16673 rule_index: usize,
16674 pred_index: usize,
16675 ) -> Option<bool>
16676 where
16677 S: TokenSource,
16678 {
16679 self.predicates.push((
16680 ctx.input_index(),
16681 rule_index,
16682 pred_index,
16683 ctx.token_text(1)
16684 .and_then(|token| token.text().map(str::to_owned)),
16685 ));
16686 Some(false)
16687 }
16688 }
16689
16690 #[test]
16691 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
16692 let atn = predicate_gated_same_lookahead_atn([0, 0]);
16693 let mut parser = mini_parser_with_hooks(
16694 vec![
16695 TestToken::new(1).with_text("x"),
16696 TestToken::eof("parser-test", 1, 1, 1),
16697 ],
16698 RecordingHooks::default(),
16699 );
16700
16701 let (tree, _) = parser
16702 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16703 .expect("both alternatives share one replay-safe predicate result");
16704
16705 assert_eq!(parser.node(tree).text(), "x<EOF>");
16706 assert_eq!(
16707 parser.semantic_hooks.predicates,
16708 vec![(0, 0, 0, Some("x".to_owned()))]
16709 );
16710 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
16711 }
16712
16713 #[test]
16714 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
16715 let atn = predicate_after_token_atn();
16716 let mut parser = mini_parser_with_hooks(
16717 vec![
16718 TestToken::new(1).with_text("x"),
16719 TestToken::new(2).with_text("y"),
16720 TestToken::eof("parser-test", 2, 1, 2),
16721 ],
16722 RecordingHooks::default(),
16723 );
16724
16725 let (tree, _) = parser
16726 .parse_atn_rule_with_runtime_options(
16727 &atn,
16728 0,
16729 ParserRuntimeOptions {
16730 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16731 ..ParserRuntimeOptions::default()
16732 },
16733 )
16734 .expect("hook supplies the missing predicate result");
16735
16736 assert_eq!(parser.node(tree).text(), "xy");
16737 assert_eq!(
16738 parser.semantic_hooks.predicates,
16739 vec![(1, 0, 0, Some("y".to_owned()))]
16740 );
16741 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
16742 }
16743
16744 #[test]
16745 fn runtime_options_default_preserves_semantic_hook_predicates() {
16746 let atn = predicate_after_token_atn();
16747 let mut parser = mini_parser_with_hooks(
16748 vec![
16749 TestToken::new(1).with_text("x"),
16750 TestToken::new(2).with_text("y"),
16751 TestToken::eof("parser-test", 2, 1, 2),
16752 ],
16753 RejectingPredicateHooks::default(),
16754 );
16755
16756 let result =
16757 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
16758
16759 assert!(
16760 result.is_err(),
16761 "default runtime options must not bypass semantic hooks for predicate ATNs"
16762 );
16763 assert_eq!(
16764 parser.semantic_hooks.predicates,
16765 vec![(1, 0, 0, Some("y".to_owned()))]
16766 );
16767 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
16768 }
16769
16770 #[test]
16771 fn semantic_hook_handles_committed_parser_action() {
16772 let atn = token_then_eof_atn();
16773 let mut parser = mini_parser_with_hooks(
16774 vec![
16775 TestToken::new(1).with_text("x"),
16776 TestToken::eof("parser-test", 1, 1, 1),
16777 ],
16778 RecordingHooks::default(),
16779 );
16780 let (tree, _) = parser
16781 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16782 .expect("rule parses before action hook is tested");
16783
16784 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
16785 assert_eq!(
16786 parser.semantic_hooks.actions,
16787 vec![(42, "x".to_owned(), Some("s".to_owned()))]
16788 );
16789 assert_eq!(
16790 parser.semantic_hooks.action_trees,
16791 [Some("x<EOF>".to_owned())]
16792 );
16793 }
16794
16795 #[test]
16796 fn unhandled_committed_action_fails_loud_under_error_policy() {
16797 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16801 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
16802 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
16803
16804 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
16806
16807 let error = parser
16808 .take_unknown_semantic_error()
16809 .expect("an unhandled committed action under Error policy must fail loud");
16810 let AntlrError::Unsupported(message) = error else {
16811 panic!("expected AntlrError::Unsupported, got {error:?}");
16812 };
16813 assert!(
16814 message.contains("unhandled semantic action") && message.contains("state=42"),
16815 "message should name the dropped action coordinate: {message}"
16816 );
16817
16818 let mut lenient =
16820 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16821 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
16822 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
16823 assert!(lenient.take_unknown_semantic_error().is_none());
16824 }
16825
16826 #[test]
16827 fn translated_predicate_is_unaffected_by_error_policy() {
16828 let atn = predicate_after_token_atn();
16829 let mut parser = mini_parser(vec![
16830 TestToken::new(1).with_text("x"),
16831 TestToken::new(2).with_text("y"),
16832 TestToken::eof("parser-test", 2, 1, 2),
16833 ]);
16834
16835 let (tree, _) = parser
16836 .parse_atn_rule_with_runtime_options(
16837 &atn,
16838 0,
16839 ParserRuntimeOptions {
16840 predicates: &[(0, 0, ParserPredicate::True)],
16841 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16842 ..ParserRuntimeOptions::default()
16843 },
16844 )
16845 .expect("a predicate covered by the table is not an unknown coordinate");
16846
16847 assert_eq!(parser.node(tree).text(), "xy");
16848 }
16849
16850 fn hook_predicate_semantics() -> ParserSemantics {
16855 let mut ir = SemIr::new();
16856 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
16857 ParserSemantics {
16858 ir,
16859 predicates: vec![ParserSemanticPredicate {
16860 rule_index: 0,
16861 pred_index: 0,
16862 expr,
16863 failure_message: None,
16864 }],
16865 actions: Vec::new(),
16866 }
16867 }
16868
16869 #[derive(Debug, Default)]
16870 struct DecliningHooks;
16871
16872 impl SemanticHooks for DecliningHooks {}
16873
16874 #[test]
16875 fn semir_hook_none_falls_through_to_assume_true() {
16876 let atn = predicate_after_token_atn();
16877 let semantics = hook_predicate_semantics();
16878 let mut parser = mini_parser_with_hooks(
16879 vec![
16880 TestToken::new(1).with_text("x"),
16881 TestToken::new(2).with_text("y"),
16882 TestToken::eof("parser-test", 2, 1, 2),
16883 ],
16884 DecliningHooks,
16885 );
16886
16887 let (tree, _) = parser
16888 .parse_atn_rule_with_runtime_options(
16889 &atn,
16890 0,
16891 ParserRuntimeOptions {
16892 semantics: Some(&semantics),
16893 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
16894 ..ParserRuntimeOptions::default()
16895 },
16896 )
16897 .expect("a declined SemIR hook must pass under assume-true");
16898
16899 assert_eq!(parser.node(tree).text(), "xy");
16900 }
16901
16902 #[test]
16903 fn semir_hook_none_falls_through_to_assume_false() {
16904 let atn = predicate_after_token_atn();
16905 let semantics = hook_predicate_semantics();
16906 let mut parser = mini_parser_with_hooks(
16907 vec![
16908 TestToken::new(1).with_text("x"),
16909 TestToken::new(2).with_text("y"),
16910 TestToken::eof("parser-test", 2, 1, 2),
16911 ],
16912 DecliningHooks,
16913 );
16914
16915 let result = parser.parse_atn_rule_with_runtime_options(
16916 &atn,
16917 0,
16918 ParserRuntimeOptions {
16919 semantics: Some(&semantics),
16920 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
16921 ..ParserRuntimeOptions::default()
16922 },
16923 );
16924
16925 assert!(
16926 result.is_err(),
16927 "a declined SemIR hook must fail the only guarded path under assume-false"
16928 );
16929 }
16930
16931 #[test]
16932 fn semir_hook_none_records_coordinate_under_error_policy() {
16933 let atn = predicate_after_token_atn();
16934 let semantics = hook_predicate_semantics();
16935 let mut parser = mini_parser_with_hooks(
16936 vec![
16937 TestToken::new(1).with_text("x"),
16938 TestToken::new(2).with_text("y"),
16939 TestToken::eof("parser-test", 2, 1, 2),
16940 ],
16941 DecliningHooks,
16942 );
16943
16944 let error = parser
16945 .parse_atn_rule_with_runtime_options(
16946 &atn,
16947 0,
16948 ParserRuntimeOptions {
16949 semantics: Some(&semantics),
16950 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16951 ..ParserRuntimeOptions::default()
16952 },
16953 )
16954 .expect_err("a declined SemIR hook under Error policy must fail the parse");
16955
16956 let AntlrError::Unsupported(message) = error else {
16957 panic!("expected AntlrError::Unsupported, got {error:?}");
16958 };
16959 assert!(
16960 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
16961 "message should name the unresolved coordinate: {message}"
16962 );
16963 }
16964
16965 #[test]
16966 fn generated_direct_predicate_honors_installed_policy() {
16967 let semantics = hook_predicate_semantics();
16973 let context = ParserRuleContext::new(0, -1);
16974
16975 let mut assume_true =
16976 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16977 assert!(
16978 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
16979 &semantics, 0, 0, &context, 0
16980 ),
16981 "default AssumeTrue accepts a declined hook"
16982 );
16983 assert!(assume_true.take_unknown_semantic_error().is_none());
16984
16985 let mut error_policy =
16986 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16987 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
16988 assert!(
16989 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
16990 &semantics, 0, 0, &context, 0
16991 ),
16992 "Error policy rejects a declined hook on the generated-direct path"
16993 );
16994 let error = error_policy
16995 .take_unknown_semantic_error()
16996 .expect("Error policy records the unresolved coordinate for the generated path");
16997 let AntlrError::Unsupported(message) = error else {
16998 panic!("expected AntlrError::Unsupported, got {error:?}");
16999 };
17000 assert!(message.contains("pred_index=0"), "message: {message}");
17001 }
17002
17003 #[test]
17004 fn parser_rule_start_skips_leading_hidden_tokens() {
17005 let atn = token_then_eof_atn();
17006 let mut parser = mini_parser(vec![
17007 TestToken::new(99)
17008 .with_text(" ")
17009 .with_channel(HIDDEN_CHANNEL),
17010 TestToken::new(1).with_text("x"),
17011 TestToken::eof("parser-test", 2, 1, 2),
17012 ]);
17013
17014 let tree = parser
17015 .parse_atn_rule(&atn, 0)
17016 .expect("artificial parser rule should parse");
17017 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
17018 panic!("rule node should be present");
17019 };
17020 assert_eq!(
17021 rule.start()
17022 .expect("rule should have a start token")
17023 .token_type(),
17024 1
17025 );
17026 }
17027
17028 #[test]
17029 fn parser_action_after_eof_stops_at_eof_token() {
17030 let atn = eof_then_action_atn();
17031 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
17032
17033 let (_, actions) = parser
17034 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17035 .expect("EOF action rule should parse");
17036
17037 assert_eq!(actions.len(), 1);
17038 assert_eq!(actions[0].stop_index(), Some(0));
17039 assert_eq!(
17040 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
17041 ""
17042 );
17043 }
17044
17045 #[test]
17046 fn after_action_stop_uses_rule_context_stop_not_cursor() {
17047 let mut id = TestToken::new(1).with_text("x");
17052 id.set_token_index(0);
17053 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
17054 eof.set_token_index(1);
17055 let mut parser = mini_parser(vec![id.clone(), eof]);
17056 parser.consume();
17058 assert_eq!(parser.la(1), TOKEN_EOF);
17059
17060 let mut ctx = ParserRuleContext::new(0, 0);
17063 parser.set_context_stop(
17064 &mut ctx,
17065 parser.token_id_at(0).expect("ID token should be buffered"),
17066 );
17067 let tree = parser.rule_node(ctx);
17068
17069 let current_index = parser.input.index();
17070 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
17072 assert_eq!(
17074 parser.after_action_stop_index_for_tree(tree, current_index),
17075 Some(0)
17076 );
17077 }
17078
17079 #[test]
17080 fn after_action_start_uses_rule_context_start_not_cursor() {
17081 let mut parser = mini_parser(vec![
17086 TestToken::new(9)
17087 .with_text(" ")
17088 .with_channel(HIDDEN_CHANNEL),
17089 TestToken::new(9)
17090 .with_text(" ")
17091 .with_channel(HIDDEN_CHANNEL),
17092 TestToken::new(1).with_text("x"),
17093 TestToken::eof("parser-test", 3, 1, 3),
17094 ]);
17095
17096 let mut ctx = ParserRuleContext::new(0, 0);
17097 parser.set_context_start(
17098 &mut ctx,
17099 parser.token_id_at(2).expect("ID token should be buffered"),
17100 );
17101 let tree = parser.rule_node(ctx);
17102
17103 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
17106
17107 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
17109 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
17110 }
17111
17112 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
17113 FastRecognizeOutcome {
17114 index,
17115 consumed_eof,
17116 diagnostics: DiagnosticSeqId::EMPTY,
17117 deferred_nodes: FastDeferredNodeId::EMPTY,
17118 nodes: NodeSeqId(marker),
17119 }
17120 }
17121
17122 #[test]
17123 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
17124 let mut outcomes = vec![
17125 clean_fast_outcome(4, false, 0),
17126 clean_fast_outcome(2, false, 1),
17127 clean_fast_outcome(4, false, 2),
17128 clean_fast_outcome(4, true, 3),
17129 clean_fast_outcome(2, false, 4),
17130 ];
17131 let mut scratch = FastOutcomeDedupScratch::default();
17132
17133 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17134
17135 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
17136 assert_eq!(
17137 outcomes
17138 .iter()
17139 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
17140 .collect::<Vec<_>>(),
17141 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
17142 );
17143 assert!(scratch.dense_words.is_empty());
17144 assert!(scratch.sparse_keys.is_empty());
17145 }
17146
17147 #[test]
17148 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
17149 let mut scratch = FastOutcomeDedupScratch::default();
17150 let mut outcomes = (100..109)
17151 .flat_map(|index| {
17152 [
17153 clean_fast_outcome(
17154 index,
17155 false,
17156 u32::try_from(index).expect("test index fits in u32"),
17157 ),
17158 clean_fast_outcome(index, false, u32::MAX),
17159 ]
17160 })
17161 .collect();
17162
17163 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17164
17165 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
17166 assert_eq!(outcomes.len(), 9);
17167 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
17168 let dense_capacity = scratch.dense_words.capacity();
17169
17170 let mut reused = (1_000..1_009)
17171 .map(|index| {
17172 clean_fast_outcome(
17173 index,
17174 false,
17175 u32::try_from(index).expect("test index fits in u32"),
17176 )
17177 })
17178 .collect();
17179 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
17180
17181 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
17182 assert_eq!(reused.len(), 9);
17183 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
17184 }
17185
17186 #[test]
17187 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
17188 let mut scratch = FastOutcomeDedupScratch::default();
17189 let sparse_indexes = [
17190 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
17191 ];
17192 let mut outcomes = sparse_indexes
17193 .into_iter()
17194 .chain([400_000])
17195 .enumerate()
17196 .map(|(marker, index)| {
17197 clean_fast_outcome(
17198 index,
17199 false,
17200 u32::try_from(marker).expect("test marker fits in u32"),
17201 )
17202 })
17203 .collect();
17204
17205 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17206
17207 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
17208 assert_eq!(outcomes.len(), sparse_indexes.len());
17209 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
17210 let sparse_capacity = scratch.sparse_keys.capacity();
17211
17212 let mut reused = sparse_indexes
17213 .into_iter()
17214 .map(|index| {
17215 clean_fast_outcome(
17216 index,
17217 false,
17218 u32::try_from(index).expect("test index fits in u32"),
17219 )
17220 })
17221 .collect();
17222 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
17223
17224 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
17225 assert_eq!(reused.len(), sparse_indexes.len());
17226 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
17227 }
17228
17229 #[test]
17230 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
17231 let mut scratch = FastOutcomeDedupScratch::default();
17232 scratch
17233 .sparse_keys
17234 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
17235 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
17236 let mut outcomes = (0..9)
17237 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
17238 .collect();
17239
17240 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17241
17242 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
17243 assert!(scratch.sparse_keys.is_empty());
17244 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
17245 }
17246
17247 #[test]
17248 fn fast_outcome_selection_respects_sll_tie_order() {
17249 let mut arena = RecognitionArena::default();
17250 let first = FastRecognizeOutcome {
17251 index: 1,
17252 consumed_eof: false,
17253 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17254 line: 1,
17255 column: 0,
17256 message: "mismatched input 'x'".to_owned(),
17257 }]),
17258 deferred_nodes: FastDeferredNodeId::EMPTY,
17259 nodes: NodeSeqId::EMPTY,
17260 };
17261 let second = FastRecognizeOutcome {
17262 index: first.index,
17263 consumed_eof: first.consumed_eof,
17264 diagnostics: DiagnosticSeqId::EMPTY,
17265 deferred_nodes: FastDeferredNodeId::EMPTY,
17266 nodes: NodeSeqId::EMPTY,
17267 };
17268
17269 let selected = select_best_fast_outcome(
17270 [first, second].into_iter(),
17271 PredictionMode::Sll,
17272 None,
17273 |_| panic!("caller-follow token probe should not run"),
17274 &arena,
17275 )
17276 .expect("one outcome should be selected");
17277 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
17278 let eof_second = FastRecognizeOutcome {
17279 index: second.index,
17280 consumed_eof: true,
17281 diagnostics: DiagnosticSeqId::EMPTY,
17282 deferred_nodes: FastDeferredNodeId::EMPTY,
17283 nodes: NodeSeqId::EMPTY,
17284 };
17285 let selected = select_best_fast_outcome(
17286 [first, eof_second].into_iter(),
17287 PredictionMode::Sll,
17288 None,
17289 |_| panic!("caller-follow token probe should not run"),
17290 &arena,
17291 )
17292 .expect("one outcome should be selected");
17293 assert!(!selected.consumed_eof);
17294 let selected = select_best_fast_outcome(
17295 [first, second].into_iter(),
17296 PredictionMode::Ll,
17297 None,
17298 |_| panic!("caller-follow token probe should not run"),
17299 &arena,
17300 )
17301 .expect("one outcome should be selected");
17302 assert!(selected.diagnostics.is_empty());
17303 }
17304
17305 #[test]
17306 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
17307 let mut arena = RecognitionArena::default();
17308 let first = FastRecognizeOutcome {
17309 index: 3,
17310 consumed_eof: false,
17311 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17312 line: 1,
17313 column: 0,
17314 message: "mismatched input 'x' expecting 'a'".to_owned(),
17315 }]),
17316 deferred_nodes: FastDeferredNodeId::EMPTY,
17317 nodes: NodeSeqId::EMPTY,
17318 };
17319 let same_rank = FastRecognizeOutcome {
17320 index: first.index,
17321 consumed_eof: first.consumed_eof,
17322 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17323 line: 1,
17324 column: 0,
17325 message: "mismatched input 'x' expecting 'b'".to_owned(),
17326 }]),
17327 deferred_nodes: FastDeferredNodeId::EMPTY,
17328 nodes: NodeSeqId::EMPTY,
17329 };
17330 let better_rank = FastRecognizeOutcome {
17331 index: first.index,
17332 consumed_eof: first.consumed_eof,
17333 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17334 line: 1,
17335 column: 0,
17336 message: "missing 'a' at 'x'".to_owned(),
17337 }]),
17338 deferred_nodes: FastDeferredNodeId::EMPTY,
17339 nodes: NodeSeqId::EMPTY,
17340 };
17341 let mut outcomes = vec![first, same_rank, better_rank];
17342
17343 dedupe_fast_outcomes(&mut outcomes, &arena);
17344
17345 assert_eq!(outcomes.len(), 2);
17346 assert_eq!(
17347 arena
17348 .diagnostics(outcomes[0].diagnostics)
17349 .next()
17350 .expect("first diagnostic")
17351 .message,
17352 "mismatched input 'x' expecting 'a'"
17353 );
17354 assert_eq!(
17355 arena
17356 .diagnostics(outcomes[1].diagnostics)
17357 .next()
17358 .expect("second diagnostic")
17359 .message,
17360 "missing 'a' at 'x'"
17361 );
17362 }
17363
17364 #[test]
17365 fn fast_outcome_selection_prefers_generated_caller_follow() {
17366 let arena = RecognitionArena::default();
17367 let earlier = FastRecognizeOutcome {
17368 index: 7,
17369 consumed_eof: false,
17370 diagnostics: DiagnosticSeqId::EMPTY,
17371 deferred_nodes: FastDeferredNodeId::EMPTY,
17372 nodes: NodeSeqId::EMPTY,
17373 };
17374 let later = FastRecognizeOutcome {
17375 index: 8,
17376 consumed_eof: false,
17377 diagnostics: DiagnosticSeqId::EMPTY,
17378 deferred_nodes: FastDeferredNodeId::EMPTY,
17379 nodes: NodeSeqId::EMPTY,
17380 };
17381 let mut follow = TokenBitSet::default();
17382 follow.insert(5);
17383
17384 let selected = select_best_fast_outcome(
17385 [later, earlier].into_iter(),
17386 PredictionMode::Ll,
17387 Some(&follow),
17388 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
17389 &arena,
17390 )
17391 .expect("one outcome should be selected");
17392 assert_eq!(selected.index, 7);
17393
17394 let selected = select_best_fast_outcome(
17395 [later, earlier].into_iter(),
17396 PredictionMode::Ll,
17397 Some(&follow),
17398 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
17399 &arena,
17400 )
17401 .expect("one outcome should be selected");
17402 assert_eq!(selected.index, 8);
17403
17404 let indented_next_statement = FastRecognizeOutcome {
17405 index: 9,
17406 consumed_eof: false,
17407 diagnostics: DiagnosticSeqId::EMPTY,
17408 deferred_nodes: FastDeferredNodeId::EMPTY,
17409 nodes: NodeSeqId::EMPTY,
17410 };
17411 let selected = select_best_fast_outcome(
17412 [indented_next_statement, earlier].into_iter(),
17413 PredictionMode::Ll,
17414 Some(&follow),
17415 |index| {
17416 let is_boundary = index == 7;
17417 let is_boundary_gap = matches!(index, 7 | 8);
17418 (
17419 if index == 7 { 5 } else { TOKEN_EOF },
17420 is_boundary,
17421 is_boundary_gap,
17422 )
17423 },
17424 &arena,
17425 )
17426 .expect("one outcome should be selected");
17427 assert_eq!(selected.index, 7);
17428
17429 let continuation = FastRecognizeOutcome {
17430 index: 10,
17431 consumed_eof: false,
17432 diagnostics: DiagnosticSeqId::EMPTY,
17433 deferred_nodes: FastDeferredNodeId::EMPTY,
17434 nodes: NodeSeqId::EMPTY,
17435 };
17436 let selected = select_best_fast_outcome(
17437 [continuation, earlier].into_iter(),
17438 PredictionMode::Ll,
17439 Some(&follow),
17440 |index| {
17441 let is_boundary = matches!(index, 7 | 9);
17442 (
17443 if index == 7 { 5 } else { TOKEN_EOF },
17444 is_boundary,
17445 is_boundary,
17446 )
17447 },
17448 &arena,
17449 )
17450 .expect("one outcome should be selected");
17451 assert_eq!(selected.index, 10);
17452
17453 let selected = select_best_fast_outcome(
17454 [earlier, later].into_iter(),
17455 PredictionMode::Sll,
17456 Some(&follow),
17457 |_| panic!("caller-follow token probe should not run in SLL mode"),
17458 &arena,
17459 )
17460 .expect("one outcome should be selected");
17461 assert_eq!(selected.index, 8);
17462 }
17463
17464 #[test]
17465 fn caller_follow_boundary_text_requires_separator_shape() {
17466 assert!(is_caller_follow_boundary_text(";"));
17467 assert!(is_caller_follow_boundary_text("\n"));
17468 assert!(is_caller_follow_boundary_text("\r\n "));
17469 assert!(is_caller_follow_boundary_text(";\n"));
17470 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
17471 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
17472 assert!(!is_caller_follow_boundary_text("identifier"));
17473 assert!(is_caller_follow_boundary_gap_text(" \t "));
17474 assert!(is_caller_follow_boundary_gap_text("\n "));
17475 assert!(is_caller_follow_boundary_gap_text(";\t"));
17476 assert!(!is_caller_follow_boundary_gap_text(
17477 "\"\"\"line1\nline2\"\"\""
17478 ));
17479 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
17480 }
17481
17482 #[test]
17483 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
17484 let mut parser = mini_parser(vec![
17485 TestToken::new(5).with_text("\n"),
17486 TestToken::new(6)
17487 .with_text("// comment\n")
17488 .with_channel(HIDDEN_CHANNEL),
17489 TestToken::new(1).with_text("x"),
17490 TestToken::eof("parser-test", 1, 2, 0),
17491 ]);
17492
17493 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
17494 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
17495 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
17496 }
17497
17498 #[test]
17499 fn caller_follow_token_info_uses_stream_visible_channel() {
17500 let source = Source {
17501 tokens: vec![
17502 TestToken::new(5).with_text("\n").with_channel(2),
17503 TestToken::new(1).with_text("x").with_channel(2),
17504 TestToken::new(6)
17505 .with_text("// comment\n")
17506 .with_channel(HIDDEN_CHANNEL),
17507 TestToken::eof("parser-test", 1, 2, 0),
17508 ],
17509 index: 0,
17510 };
17511 let data = RecognizerData::new(
17512 "Mini.g4",
17513 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17514 );
17515 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
17516
17517 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
17518 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
17519 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
17520 }
17521
17522 #[test]
17523 fn reset_per_parse_caches_clears_state_expected_token_cache() {
17524 let atn = token_then_eof_atn();
17525 let mut parser = mini_parser(Vec::new());
17526
17527 let _ = parser.cached_state_expected_token_set(&atn, 0);
17528 assert!(!parser.state_expected_token_cache.is_empty());
17529
17530 parser.reset_per_parse_caches();
17531 assert!(parser.state_expected_token_cache.is_empty());
17532 }
17533
17534 #[test]
17535 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
17536 let cyclic = epsilon_cycle_atn();
17537 let acyclic = token_then_eof_atn();
17538 let mut parser = mini_parser(Vec::new());
17539
17540 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
17541 assert_eq!(
17542 parser.empty_cycle_cache_atn,
17543 Some(SharedAtnCacheKey::for_atn(&cyclic))
17544 );
17545 assert_eq!(parser.empty_cycle_cache[1], Some(true));
17546
17547 parser.reset_per_parse_caches();
17548 assert_eq!(parser.empty_cycle_cache[1], Some(true));
17549 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
17550
17551 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
17552 assert_eq!(
17553 parser.empty_cycle_cache_atn,
17554 Some(SharedAtnCacheKey::for_atn(&acyclic))
17555 );
17556 assert_eq!(parser.empty_cycle_cache[1], Some(false));
17557 }
17558
17559 #[test]
17560 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
17561 let source = Source {
17562 tokens: vec![
17563 TestToken::new(1).with_text("x"),
17564 TestToken::eof("parser-test", 1, 1, 1),
17565 ],
17566 index: 0,
17567 };
17568 let data = RecognizerData::new(
17569 "Mini.g4",
17570 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17571 );
17572 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17573 let expected = ExpectedTokens {
17574 index: Some(0),
17575 symbols: BTreeSet::new(),
17576 no_viable: None,
17577 };
17578
17579 let (_, message) = parser.expected_error_message(0, 0, &expected);
17580
17581 assert_eq!(message, "mismatched input 'x'");
17582 }
17583
17584 #[test]
17585 fn eof_rule_stop_index_points_at_eof_token() {
17586 let source = Source {
17587 tokens: vec![
17588 TestToken::new(1).with_text("x"),
17589 TestToken::eof("parser-test", 1, 1, 1),
17590 ],
17591 index: 0,
17592 };
17593 let data = RecognizerData::new(
17594 "Mini.g4",
17595 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17596 );
17597 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17598
17599 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
17600 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
17601 }
17602
17603 #[test]
17604 fn generated_parser_action_uses_current_rule_stop_boundary() {
17605 let mut parser = mini_parser(vec![
17606 TestToken::new(1).with_text("x"),
17607 TestToken::eof("parser-test", 1, 1, 1),
17608 ]);
17609
17610 parser.match_token(1).expect("token should match");
17611 let action = parser.parser_action_at_current(7, 0, 0, false);
17612 assert_eq!(action.source_state(), 7);
17613 assert_eq!(action.rule_index(), 0);
17614 assert_eq!(action.start_index(), 0);
17615 assert_eq!(action.stop_index(), Some(0));
17616
17617 parser.match_eof().expect("EOF should match");
17618 let action = parser.parser_action_at_current(8, 0, 0, true);
17619 assert_eq!(action.stop_index(), Some(1));
17620 }
17621
17622 #[test]
17623 fn folds_left_recursive_boundary_into_rule_node() {
17624 let mut arena = RecognitionArena::default();
17625 let first = arena.push_node(ArenaRecognizedNode::Token {
17626 token: TokenId::try_from(0).expect("test token ID"),
17627 });
17628 let boundary = arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
17629 rule_index: 1,
17630 alt_number: 3,
17631 });
17632 let second = arena.push_node(ArenaRecognizedNode::Token {
17633 token: TokenId::try_from(1).expect("test token ID"),
17634 });
17635 let mut nodes = NodeSeqId::EMPTY;
17636 for node in [first, boundary, second].into_iter().rev() {
17637 nodes = arena.prepend(nodes, node);
17638 }
17639
17640 let folded = arena.fold_left_recursive_boundaries(nodes);
17641 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
17642
17643 assert_eq!(folded_nodes.len(), 2);
17644 let ArenaRecognizedNode::Rule {
17645 rule_index,
17646 invoking_state,
17647 alt_number,
17648 start_index,
17649 stop_index,
17650 children,
17651 ..
17652 } = arena.node(folded_nodes[0])
17653 else {
17654 panic!("first folded node should be a rule");
17655 };
17656 assert_eq!(rule_index, 1);
17657 assert_eq!(invoking_state, -1);
17658 assert_eq!(alt_number, 3);
17659 assert_eq!(start_index, 0);
17660 assert_eq!(stop_index, Some(0));
17661 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
17662 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
17663
17664 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
17665 assert_eq!(
17666 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17667 (4, 3, 1)
17668 );
17669 assert_eq!(
17670 (stats.total_links, stats.live_links, stats.dead_links),
17671 (9, 3, 6)
17672 );
17673 }
17674
17675 #[test]
17676 fn recognition_arena_reports_live_dead_and_retained_capacity() {
17677 let mut arena = RecognitionArena::default();
17678 let token = arena.push_node(ArenaRecognizedNode::Token {
17679 token: TokenId::try_from(0).expect("test token ID"),
17680 });
17681 let extra = arena.push_extra(RecognitionExtra::MissingToken {
17682 token_type: 2,
17683 at_index: 1,
17684 text: "<missing X>".to_owned(),
17685 });
17686 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
17687 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
17688 token: TokenId::try_from(1).expect("test token ID"),
17689 });
17690 let mut live = NodeSeqId::EMPTY;
17691 live = arena.prepend(live, missing);
17692 live = arena.prepend(live, token);
17693 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
17694 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17695 line: 1,
17696 column: 0,
17697 message: "missing X".to_owned(),
17698 }]);
17699 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17700 line: 1,
17701 column: 1,
17702 message: "discarded".to_owned(),
17703 }]);
17704 let deferred_children = arena.deferred_fragment(live);
17705 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
17706 rule_index: 0,
17707 invoking_state: -1,
17708 start_index: 0,
17709 stop_index: Some(1),
17710 deferred_children,
17711 children: NodeSeqId::EMPTY,
17712 });
17713
17714 let stats = arena.stats(live, live_diagnostics);
17715
17716 assert_eq!(
17717 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17718 (3, 2, 1)
17719 );
17720 assert_eq!(
17721 (stats.total_links, stats.live_links, stats.dead_links),
17722 (5, 3, 2)
17723 );
17724 assert_eq!(
17725 (stats.total_extras, stats.live_extras, stats.dead_extras),
17726 (3, 2, 1)
17727 );
17728 assert!(size_of::<SeqLink>() <= 8);
17729 assert!(size_of::<DiagnosticLink>() <= 8);
17730 assert!(size_of::<FastDeferredNode>() <= 12);
17731 assert!(size_of::<FastDeferredRule>() <= 28);
17732 assert!(size_of::<FastRecognizeOutcome>() <= 24);
17733 let capacities = (
17734 stats.node_capacity,
17735 stats.link_capacity,
17736 stats.extra_capacity,
17737 );
17738 let deferred_capacities = (
17739 arena.deferred_nodes.capacity(),
17740 arena.deferred_rules.capacity(),
17741 );
17742
17743 arena.reset();
17744 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
17745 assert_eq!(
17746 (reset.total_nodes, reset.total_links, reset.total_extras),
17747 (0, 0, 0)
17748 );
17749 assert_eq!(
17750 (
17751 reset.node_capacity,
17752 reset.link_capacity,
17753 reset.extra_capacity,
17754 ),
17755 capacities
17756 );
17757 assert!(arena.deferred_nodes.is_empty());
17758 assert!(arena.deferred_rules.is_empty());
17759 assert_eq!(
17760 (
17761 arena.deferred_nodes.capacity(),
17762 arena.deferred_rules.capacity(),
17763 ),
17764 deferred_capacities
17765 );
17766 }
17767
17768 #[test]
17769 fn parser_computes_recognition_arena_stats_on_demand() {
17770 let mut parser = mini_parser(Vec::new());
17771 let live = parser
17772 .recognition_arena
17773 .push_node(ArenaRecognizedNode::Token {
17774 token: TokenId::try_from(0).expect("test token ID"),
17775 });
17776 let discarded = parser
17777 .recognition_arena
17778 .push_node(ArenaRecognizedNode::ErrorToken {
17779 token: TokenId::try_from(1).expect("test token ID"),
17780 });
17781 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
17782 let _discarded_root = parser
17783 .recognition_arena
17784 .prepend(NodeSeqId::EMPTY, discarded);
17785 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
17786
17787 let stats = parser.recognition_arena_stats();
17788
17789 assert_eq!(
17790 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17791 (2, 1, 1)
17792 );
17793 assert_eq!(
17794 (stats.total_links, stats.live_links, stats.dead_links),
17795 (2, 1, 1)
17796 );
17797 }
17798
17799 #[test]
17800 fn recognition_arena_drops_capacity_above_retention_limit() {
17801 let mut storage = Vec::<u8>::with_capacity(4);
17802 storage.extend([1, 2, 3]);
17803
17804 reset_arena_vec(&mut storage, 3);
17805
17806 assert!(storage.is_empty());
17807 assert_eq!(storage.capacity(), 0);
17808 }
17809
17810 #[test]
17811 fn recognition_arena_concatenates_diagnostics_in_source_order() {
17812 let mut arena = RecognitionArena::default();
17813 let prefix = arena.diagnostic_sequence([
17814 ParserDiagnostic {
17815 line: 1,
17816 column: 0,
17817 message: "first".to_owned(),
17818 },
17819 ParserDiagnostic {
17820 line: 1,
17821 column: 1,
17822 message: "second".to_owned(),
17823 },
17824 ]);
17825 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
17826 line: 1,
17827 column: 2,
17828 message: "third".to_owned(),
17829 }]);
17830 let extras_before = arena.extras.len();
17831
17832 let combined = arena.concat_diagnostics(prefix, suffix);
17833 let messages = arena
17834 .diagnostics(combined)
17835 .map(|diagnostic| diagnostic.message.as_str())
17836 .collect::<Vec<_>>();
17837
17838 assert_eq!(messages, ["first", "second", "third"]);
17839 assert_eq!(arena.extras.len(), extras_before);
17840 }
17841
17842 #[test]
17843 fn outcome_ties_keep_later_non_recursive_alternative() {
17844 let arena = RecognitionArena::default();
17845 let first = RecognizeOutcome {
17846 index: 1,
17847 consumed_eof: false,
17848 alt_number: 0,
17849 member_values: BTreeMap::new(),
17850 return_values: BTreeMap::new(),
17851 diagnostics: DiagnosticSeqId::EMPTY,
17852 decisions: Vec::new(),
17853 actions: vec![ParserAction::new(1, 0, 0, None)],
17854 nodes: NodeSeqId::EMPTY,
17855 };
17856 let second = RecognizeOutcome {
17857 actions: vec![ParserAction::new(2, 0, 0, None)],
17858 ..first.clone()
17859 };
17860
17861 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17862 .expect("one outcome should be selected");
17863 assert_eq!(selected.actions[0].source_state(), 2);
17864 }
17865
17866 #[test]
17867 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
17868 let arena = RecognitionArena::default();
17869 let first = RecognizeOutcome {
17870 index: 1,
17871 consumed_eof: false,
17872 alt_number: 0,
17873 member_values: BTreeMap::new(),
17874 return_values: BTreeMap::new(),
17875 diagnostics: DiagnosticSeqId::EMPTY,
17876 decisions: Vec::new(),
17877 actions: vec![ParserAction::new(1, 0, 0, None)],
17878 nodes: NodeSeqId::EMPTY,
17879 };
17880 let second = RecognizeOutcome {
17881 actions: vec![
17882 ParserAction::new(2, 0, 0, None),
17883 ParserAction::new(3, 0, 0, None),
17884 ],
17885 ..first.clone()
17886 };
17887
17888 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
17889 .expect("one outcome should be selected");
17890 assert_eq!(selected.actions.len(), 2);
17891 }
17892
17893 #[test]
17894 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
17895 let arena = RecognitionArena::default();
17896 let first = RecognizeOutcome {
17897 index: 7,
17898 consumed_eof: false,
17899 alt_number: 0,
17900 member_values: BTreeMap::new(),
17901 return_values: BTreeMap::new(),
17902 diagnostics: DiagnosticSeqId::EMPTY,
17903 decisions: vec![1, 0],
17904 actions: vec![
17905 ParserAction::new(23, 2, 2, Some(4)),
17906 ParserAction::new(23, 2, 0, Some(6)),
17907 ],
17908 nodes: NodeSeqId::EMPTY,
17909 };
17910 let second = RecognizeOutcome {
17911 decisions: vec![0, 1],
17912 actions: vec![
17913 ParserAction::new(23, 2, 2, Some(6)),
17914 ParserAction::new(23, 2, 0, Some(6)),
17915 ],
17916 ..first.clone()
17917 };
17918
17919 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17920 .expect("one outcome should be selected");
17921 assert_eq!(selected.actions[0].stop_index(), Some(6));
17922 }
17923
17924 #[test]
17925 fn outcome_ties_keep_first_recursive_tree_shape() {
17926 let mut arena = RecognitionArena::default();
17927 let token = arena.push_node(ArenaRecognizedNode::Token {
17928 token: TokenId::try_from(0).expect("test token ID"),
17929 });
17930 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
17931 let inner = arena.push_node(ArenaRecognizedNode::Rule {
17932 rule_index: 1,
17933 invoking_state: -1,
17934 alt_number: 0,
17935 start_index: 0,
17936 stop_index: Some(0),
17937 return_values: None,
17938 children: token_children,
17939 });
17940 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
17941 let outer = arena.push_node(ArenaRecognizedNode::Rule {
17942 rule_index: 1,
17943 invoking_state: -1,
17944 alt_number: 0,
17945 start_index: 0,
17946 stop_index: Some(0),
17947 return_values: None,
17948 children: inner_children,
17949 });
17950 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
17951 let first = RecognizeOutcome {
17952 index: 1,
17953 consumed_eof: false,
17954 alt_number: 0,
17955 member_values: BTreeMap::new(),
17956 return_values: BTreeMap::new(),
17957 diagnostics: DiagnosticSeqId::EMPTY,
17958 decisions: Vec::new(),
17959 actions: vec![ParserAction::new(1, 0, 0, None)],
17960 nodes: recursive_nodes,
17961 };
17962 let second = RecognizeOutcome {
17963 index: 1,
17964 consumed_eof: false,
17965 alt_number: 0,
17966 member_values: BTreeMap::new(),
17967 return_values: BTreeMap::new(),
17968 diagnostics: DiagnosticSeqId::EMPTY,
17969 decisions: Vec::new(),
17970 actions: vec![ParserAction::new(2, 0, 0, None)],
17971 nodes: recursive_nodes,
17972 };
17973
17974 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17975 .expect("one outcome should be selected");
17976 assert_eq!(selected.actions[0].source_state(), 1);
17977 }
17978
17979 #[test]
17980 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
17981 let mut arena = RecognitionArena::default();
17982 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17983 line: 1,
17984 column: 3,
17985 message: "missing 'Y' at '<EOF>'".to_owned(),
17986 }]);
17987 let first_alt = RecognizeOutcome {
17988 index: 2,
17989 consumed_eof: true,
17990 alt_number: 0,
17991 member_values: BTreeMap::new(),
17992 return_values: BTreeMap::new(),
17993 diagnostics: recovered_diagnostics,
17994 decisions: vec![0],
17995 actions: vec![ParserAction::new(1, 0, 0, None)],
17996 nodes: NodeSeqId::EMPTY,
17997 };
17998 let second_alt = RecognizeOutcome {
17999 diagnostics: DiagnosticSeqId::EMPTY,
18000 decisions: vec![1],
18001 actions: vec![ParserAction::new(2, 0, 0, None)],
18002 ..first_alt.clone()
18003 };
18004
18005 let selected = select_best_outcome(
18006 [second_alt, first_alt].into_iter(),
18007 PredictionMode::Sll,
18008 &arena,
18009 )
18010 .expect("one outcome should be selected");
18011 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
18012 assert_eq!(selected.decisions, [0]);
18013 }
18014}