1use std::cell::RefCell;
7use std::cmp::Ordering;
8#[allow(clippy::disallowed_types)]
9use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
10use std::hash::{BuildHasherDefault, Hash, Hasher};
11use std::rc::Rc;
12
13#[derive(Clone, Copy, Default)]
20struct FxHasher {
21 hash: u64,
22}
23
24const FX_ROT: u32 = 5;
25const FX_SEED: u64 = 0x51_7c_c1_b7_27_22_0a_95;
26
27impl Hasher for FxHasher {
28 #[inline]
36 fn write(&mut self, mut bytes: &[u8]) {
37 while bytes.len() >= 8 {
38 let (head, rest) = bytes.split_at(8);
39 let word = u64::from_le_bytes(head.try_into().expect("8-byte chunk"));
40 self.hash = (self.hash.rotate_left(FX_ROT) ^ word).wrapping_mul(FX_SEED);
41 bytes = rest;
42 }
43 for byte in bytes {
44 self.hash = (self.hash.rotate_left(FX_ROT) ^ u64::from(*byte)).wrapping_mul(FX_SEED);
45 }
46 }
47 #[inline]
48 fn write_u64(&mut self, value: u64) {
49 self.hash = (self.hash.rotate_left(FX_ROT) ^ value).wrapping_mul(FX_SEED);
50 }
51 #[inline]
52 fn write_usize(&mut self, value: usize) {
53 self.write_u64(value as u64);
54 }
55 #[inline]
56 fn write_u32(&mut self, value: u32) {
57 self.write_u64(u64::from(value));
58 }
59 #[inline]
60 fn write_i32(&mut self, value: i32) {
61 self.write_u64(u64::from(i32::cast_unsigned(value)));
62 }
63 #[inline]
64 fn finish(&self) -> u64 {
65 self.hash
66 }
67}
68
69type FxBuildHasher = BuildHasherDefault<FxHasher>;
70#[allow(clippy::disallowed_types)]
71type FxHashMap<K, V> = HashMap<K, V, FxBuildHasher>;
72#[allow(clippy::disallowed_types)]
73type FxHashSet<K> = HashSet<K, FxBuildHasher>;
74
75use crate::atn::AtnStateKind;
76use crate::atn::parser::{
77 ParserAtnPrediction, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
78};
79use crate::atn::parser_atn::{
80 ParserAtn as Atn, ParserAtnState as AtnState, ParserIntervalSet, ParserTransition,
81 ParserTransitionData as Transition, ParserTransitionKind,
82};
83#[cfg(test)]
84use crate::atn::parser_atn::{ParserAtnBuilder, ParserTransitionSpec};
85use crate::char_stream::CharStream;
86use crate::errors::AntlrError;
87use crate::int_stream::IntStream;
88use crate::lexer::{LexerCustomAction, LexerLifecycleCtx, LexerSemCtx};
89use crate::recognizer::{Recognizer, RecognizerData};
90use crate::semir::{self, AStmt, ArithOp, CmpOp, ExprId, HookId, PExpr, SemIr, StmtId};
91use crate::token::{
92 TOKEN_EOF, Token, TokenId, TokenSource, TokenSourceError, TokenSpec, TokenStore, TokenView,
93};
94use crate::token_stream::CommonTokenStream;
95use crate::tree::{
96 Node, NodeId, ParseTreeCheckpoint, ParseTreeStorage, ParsedFile, ParserRuleContext,
97};
98use crate::vocabulary::Vocabulary;
99
100type ParseTree = NodeId;
101
102const RECOGNITION_DEPTH_LIMIT: usize = 32_768;
106const FAST_RECOGNIZE_STACK_CHECK_INTERVAL: usize = 8;
109const FAST_RECOGNIZE_RED_ZONE: usize = 1024 * 1024;
110const FAST_RECOGNIZE_STACK_SIZE: usize = 4 * 1024 * 1024;
111const ADAPTIVE_DIRECT_STEP_LIMIT: usize = RECOGNITION_DEPTH_LIMIT;
115const CLEAN_MEMO_PROBE_LIMIT: usize = 4096;
119const CLEAN_MEMO_REPEAT_LIMIT: usize = 8;
120const CLEAN_MEMO_REPROBE_INTERVAL: usize = 262_144;
123const FAST_RECOGNIZE_VISITING_CAPACITY: usize = 256;
124const FAST_RECOGNIZE_MIN_MEMO_CAPACITY: usize = 256;
125const FAST_RECOGNIZE_MAX_MEMO_CAPACITY: usize = 524_288;
126const FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY: usize = 65_536;
127
128#[derive(Clone, Copy, Debug, Eq, PartialEq)]
129enum CleanMemoMode {
130 Probe,
131 Promote,
132 Sparse,
133}
134
135fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
136 intervals
137 .iter()
138 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
139}
140
141fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
142 let mut symbols = BTreeSet::new();
143 for (start, stop) in intervals {
144 symbols.extend(*start..=*stop);
145 }
146 symbols
147}
148
149fn interval_complement_symbols(
150 intervals: &[(i32, i32)],
151 min_vocabulary: i32,
152 max_vocabulary: i32,
153) -> BTreeSet<i32> {
154 (min_vocabulary..=max_vocabulary)
155 .filter(|symbol| !interval_set_contains(intervals, *symbol))
156 .collect()
157}
158
159#[cfg(feature = "perf-counters")]
160mod perf_counters {
161 use std::cell::Cell;
162 thread_local! {
163 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
164 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
165 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
166 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
167 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
168 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
169 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
170 pub(super) static OUTCOME_DEDUPE_INPUTS: Cell<u64> = const { Cell::new(0) };
171 pub(super) static OUTCOME_DEDUPE_REMOVED: Cell<u64> = const { Cell::new(0) };
172 pub(super) static OUTCOME_DEDUPE_INLINE: Cell<u64> = const { Cell::new(0) };
173 pub(super) static OUTCOME_DEDUPE_DENSE: Cell<u64> = const { Cell::new(0) };
174 pub(super) static OUTCOME_DEDUPE_SPARSE: Cell<u64> = const { Cell::new(0) };
175 pub(super) static OUTCOME_DEDUPE_DENSE_WORDS: Cell<u64> = const { Cell::new(0) };
176 }
177 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
178 c.with(|v| v.set(v.get() + n));
179 }
180 thread_local! {
181 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
182 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
183 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
184 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
185 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
186 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
187 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
188 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
189 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
190 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
191 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
192 }
193 pub(super) fn snapshot() -> [(&'static str, u64); 24] {
194 [
195 ("rfs_calls", RFS_CALLS.with(Cell::get)),
196 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
197 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
198 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
199 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
200 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
201 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
202 (
203 "outcome_dedupe_inputs",
204 OUTCOME_DEDUPE_INPUTS.with(Cell::get),
205 ),
206 (
207 "outcome_dedupe_removed",
208 OUTCOME_DEDUPE_REMOVED.with(Cell::get),
209 ),
210 (
211 "outcome_dedupe_inline",
212 OUTCOME_DEDUPE_INLINE.with(Cell::get),
213 ),
214 ("outcome_dedupe_dense", OUTCOME_DEDUPE_DENSE.with(Cell::get)),
215 (
216 "outcome_dedupe_sparse",
217 OUTCOME_DEDUPE_SPARSE.with(Cell::get),
218 ),
219 (
220 "outcome_dedupe_dense_words",
221 OUTCOME_DEDUPE_DENSE_WORDS.with(Cell::get),
222 ),
223 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
224 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
225 (
226 "atom_range_transitions",
227 ATOM_RANGE_TRANSITIONS.with(Cell::get),
228 ),
229 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
230 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
231 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
232 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
233 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
234 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
235 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
236 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
237 ]
238 }
239 pub fn reset() {
240 RFS_CALLS.with(|c| c.set(0));
241 RFS_MEMO_HITS.with(|c| c.set(0));
242 RFS_MEMO_MISSES.with(|c| c.set(0));
243 RFS_VISITING_CYCLE.with(|c| c.set(0));
244 MEMO_INSERTED.with(|c| c.set(0));
245 OUTCOMES_PUSHED.with(|c| c.set(0));
246 OUTCOMES_CLONED.with(|c| c.set(0));
247 OUTCOME_DEDUPE_INPUTS.with(|c| c.set(0));
248 OUTCOME_DEDUPE_REMOVED.with(|c| c.set(0));
249 OUTCOME_DEDUPE_INLINE.with(|c| c.set(0));
250 OUTCOME_DEDUPE_DENSE.with(|c| c.set(0));
251 OUTCOME_DEDUPE_SPARSE.with(|c| c.set(0));
252 OUTCOME_DEDUPE_DENSE_WORDS.with(|c| c.set(0));
253 EPSILON_TRANSITIONS.with(|c| c.set(0));
254 RULE_TRANSITIONS.with(|c| c.set(0));
255 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
256 SINGLE_TRANS_BODY.with(|c| c.set(0));
257 MULTI_TRANS_BODY.with(|c| c.set(0));
258 SINGLE_TRANS_RULE.with(|c| c.set(0));
259 SINGLE_TRANS_ATOM.with(|c| c.set(0));
260 SINGLE_TRANS_OTHER.with(|c| c.set(0));
261 OUTCOMES_RETURN_0.with(|c| c.set(0));
262 OUTCOMES_RETURN_1.with(|c| c.set(0));
263 OUTCOMES_RETURN_N.with(|c| c.set(0));
264 }
265 pub fn dump() {
266 for (name, value) in snapshot() {
267 #[allow(clippy::print_stderr)]
268 {
269 eprintln!("perf {name}={value}");
270 }
271 }
272 }
273}
274
275#[cfg(feature = "perf-counters")]
276pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
277const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
282#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
291pub struct ParserAction {
292 source_state: usize,
293 rule_index: usize,
294 start_index: usize,
295 stop_index: Option<usize>,
296 rule_init: bool,
297 expected_state: Option<usize>,
298}
299
300impl ParserAction {
301 pub const fn new(
303 source_state: usize,
304 rule_index: usize,
305 start_index: usize,
306 stop_index: Option<usize>,
307 ) -> Self {
308 Self {
309 source_state,
310 rule_index,
311 start_index,
312 stop_index,
313 rule_init: false,
314 expected_state: None,
315 }
316 }
317
318 pub const fn new_rule_init(
320 rule_index: usize,
321 start_index: usize,
322 expected_state: Option<usize>,
323 ) -> Self {
324 Self {
325 source_state: usize::MAX,
326 rule_index,
327 start_index,
328 stop_index: None,
329 rule_init: true,
330 expected_state,
331 }
332 }
333
334 pub const fn source_state(&self) -> usize {
336 self.source_state
337 }
338
339 pub const fn rule_index(&self) -> usize {
341 self.rule_index
342 }
343
344 pub const fn start_index(&self) -> usize {
346 self.start_index
347 }
348
349 pub const fn stop_index(&self) -> Option<usize> {
351 self.stop_index
352 }
353
354 pub const fn is_rule_init(&self) -> bool {
356 self.rule_init
357 }
358
359 pub const fn expected_state(&self) -> Option<usize> {
361 self.expected_state
362 }
363}
364
365pub struct ParserSemCtx<'a, S>
373where
374 S: TokenSource,
375{
376 input: &'a mut CommonTokenStream<S>,
377 tree_storage: &'a ParseTreeStorage,
378 rule_index: usize,
379 coordinate_index: usize,
380 rule_name: Option<String>,
381 context: Option<&'a ParserRuleContext>,
382 tree: Option<ParseTree>,
383 local_int_arg: Option<(usize, i64)>,
384 member_values: &'a BTreeMap<usize, i64>,
385 action: Option<ParserAction>,
386}
387
388impl<S> std::fmt::Debug for ParserSemCtx<'_, S>
389where
390 S: TokenSource,
391{
392 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
393 f.debug_struct("ParserSemCtx")
394 .field("rule_index", &self.rule_index)
395 .field("coordinate_index", &self.coordinate_index)
396 .field("rule_name", &self.rule_name)
397 .field("context", &self.context)
398 .field("tree", &self.tree)
399 .field("local_int_arg", &self.local_int_arg)
400 .field("member_values", &self.member_values)
401 .field("action", &self.action)
402 .finish_non_exhaustive()
403 }
404}
405
406impl<'a, S> ParserSemCtx<'a, S>
407where
408 S: TokenSource,
409{
410 #[must_use]
412 pub const fn rule_index(&self) -> usize {
413 self.rule_index
414 }
415
416 #[must_use]
418 pub fn rule_name(&self) -> Option<&str> {
419 self.rule_name.as_deref()
420 }
421
422 #[must_use]
426 pub const fn coordinate_index(&self) -> usize {
427 self.coordinate_index
428 }
429
430 #[must_use]
432 pub fn input_index(&self) -> usize {
433 self.input.index()
434 }
435
436 pub fn la(&mut self, offset: isize) -> i32 {
438 self.input.la(offset)
439 }
440
441 pub fn lt(&self, offset: isize) -> Option<TokenView<'_>> {
443 self.input.lt(offset)
444 }
445
446 pub fn token_text(&self, offset: isize) -> Option<TokenView<'_>> {
448 self.lt(offset)
449 }
450
451 pub fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
458 self.input.get(index)
459 }
460
461 #[must_use]
464 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
465 self.context
466 }
467
468 #[must_use]
470 pub const fn parse_tree_storage(&self) -> &'a ParseTreeStorage {
471 self.tree_storage
472 }
473
474 #[must_use]
476 pub const fn token_store(&self) -> &TokenStore {
477 self.input.token_store()
478 }
479
480 #[must_use]
482 pub const fn tree_id(&self) -> Option<NodeId> {
483 self.tree
484 }
485
486 #[must_use]
489 pub fn tree(&self) -> Option<Node<'_>> {
490 self.tree
491 .and_then(|id| self.tree_storage.node(self.input.token_store(), id))
492 }
493
494 #[must_use]
496 pub fn local_int_arg(&self) -> Option<i64> {
497 self.local_int_arg.map(|(_, value)| value)
498 }
499
500 #[must_use]
502 pub fn member_int(&self, member: usize) -> Option<i64> {
503 self.member_values.get(&member).copied()
504 }
505
506 #[must_use]
509 pub const fn action(&self) -> Option<ParserAction> {
510 self.action
511 }
512
513 pub fn action_text(&self) -> String {
521 let Some(action) = self.action else {
522 return String::new();
523 };
524 let Some(stop) = action.stop_index() else {
525 return String::new();
526 };
527 let stop = if self
528 .input
529 .get(stop)
530 .is_some_and(|token| token.token_type() == TOKEN_EOF)
531 {
532 let Some(previous) = self.input.previous_visible_token_index(stop) else {
533 return String::new();
534 };
535 previous
536 } else {
537 stop
538 };
539 self.input.text(action.start_index(), stop)
540 }
541}
542
543pub trait SemanticHooks {
550 const ENABLES_LEXER_LIFECYCLE: bool = true;
557
558 fn observes_parser_predicates(&self) -> bool {
563 true
564 }
565
566 fn observes_parser_decisions(&self) -> bool {
571 false
572 }
573
574 fn parser_decision_override(
580 &mut self,
581 decision: usize,
582 input_index: usize,
583 alternative_count: usize,
584 ) -> Option<usize> {
585 let _ = (decision, input_index, alternative_count);
586 None
587 }
588
589 fn sempred<S>(
590 &mut self,
591 ctx: &mut ParserSemCtx<'_, S>,
592 rule_index: usize,
593 pred_index: usize,
594 ) -> Option<bool>
595 where
596 S: TokenSource,
597 {
598 let _ = (ctx, rule_index, pred_index);
599 None
600 }
601
602 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
603 where
604 S: TokenSource,
605 {
606 let _ = (ctx, action);
607 false
608 }
609
610 fn lexer_sempred<I>(
611 &mut self,
612 ctx: &mut LexerSemCtx<'_, I>,
613 rule_index: usize,
614 pred_index: usize,
615 ) -> Option<bool>
616 where
617 I: CharStream,
618 {
619 let _ = (ctx, rule_index, pred_index);
620 None
621 }
622
623 fn lexer_action<I>(&mut self, ctx: &mut LexerSemCtx<'_, I>, action: LexerCustomAction) -> bool
633 where
634 I: CharStream,
635 {
636 let _ = (ctx, action);
637 false
638 }
639
640 fn lexer_reset<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
644 where
645 I: CharStream,
646 {
647 let _ = ctx;
648 }
649
650 fn lexer_before_token<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
656 where
657 I: CharStream,
658 {
659 let _ = ctx;
660 }
661
662 fn lexer_after_accept<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
671 where
672 I: CharStream,
673 {
674 let _ = ctx;
675 }
676
677 fn lexer_token_emitted(&mut self, token: TokenView<'_>) {
684 let _ = token;
685 }
686}
687
688#[derive(Clone, Copy, Debug, Default)]
691pub struct NoSemanticHooks;
692
693impl SemanticHooks for NoSemanticHooks {
694 const ENABLES_LEXER_LIFECYCLE: bool = false;
695
696 fn observes_parser_predicates(&self) -> bool {
697 false
698 }
699}
700
701#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
708pub enum ParserPredicate {
709 True,
710 False,
711 FalseWithMessage {
713 message: &'static str,
714 },
715 Invoke {
718 value: bool,
719 },
720 LookaheadTextEquals {
721 offset: isize,
722 text: &'static str,
723 },
724 LookaheadNotEquals {
725 offset: isize,
726 token_type: i32,
727 },
728 TokenPairAdjacent,
731 ContextChildRuleTextNotEquals {
736 rule_index: usize,
737 text: &'static str,
738 },
739 LocalIntEquals {
742 value: i64,
743 },
744 LocalIntLessOrEqual {
747 value: i64,
748 },
749 MemberModuloEquals {
751 member: usize,
752 modulus: i64,
753 value: i64,
754 equals: bool,
755 },
756 MemberEquals {
758 member: usize,
759 value: i64,
760 equals: bool,
761 },
762}
763
764impl ParserPredicate {
765 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
771 match self {
772 Self::True => ir.expr(PExpr::Bool(true)),
773 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
774 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
775 Self::LookaheadTextEquals { offset, text } => {
776 let token = ir.expr(PExpr::TokenText(offset));
777 let text = ir.intern(text);
778 let text = ir.expr(PExpr::Str(text));
779 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
780 }
781 Self::LookaheadNotEquals { offset, token_type } => {
782 let actual = ir.expr(PExpr::La(offset));
783 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
784 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
785 }
786 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
787 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
788 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
789 let expected = ir.intern(text);
790 let expected = ir.expr(PExpr::Str(expected));
791 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
792 }
793 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
794 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
795 Self::MemberModuloEquals {
796 member,
797 modulus,
798 value,
799 equals,
800 } => {
801 if modulus == 0 {
802 return ir.expr(PExpr::Bool(false));
803 }
804 let member = ir.expr(PExpr::Member(member));
805 let modulus = ir.expr(PExpr::Int(modulus));
806 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
807 let expected = ir.expr(PExpr::Int(value));
808 ir.expr(PExpr::Cmp(
809 if equals { CmpOp::Eq } else { CmpOp::Ne },
810 actual,
811 expected,
812 ))
813 }
814 Self::MemberEquals {
815 member,
816 value,
817 equals,
818 } => {
819 let actual = ir.expr(PExpr::Member(member));
820 let expected = ir.expr(PExpr::Int(value));
821 ir.expr(PExpr::Cmp(
822 if equals { CmpOp::Eq } else { CmpOp::Ne },
823 actual,
824 expected,
825 ))
826 }
827 }
828 }
829
830 #[must_use]
831 pub const fn failure_message(self) -> Option<&'static str> {
832 match self {
833 Self::FalseWithMessage { message } => Some(message),
834 Self::True
835 | Self::False
836 | Self::Invoke { .. }
837 | Self::LookaheadTextEquals { .. }
838 | Self::LookaheadNotEquals { .. }
839 | Self::TokenPairAdjacent
840 | Self::ContextChildRuleTextNotEquals { .. }
841 | Self::LocalIntEquals { .. }
842 | Self::LocalIntLessOrEqual { .. }
843 | Self::MemberModuloEquals { .. }
844 | Self::MemberEquals { .. } => None,
845 }
846 }
847}
848
849fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
850 let local = ir.expr(PExpr::LocalArg);
851 let absent = ir.expr(PExpr::IsNull(local));
852 let expected = ir.expr(PExpr::Int(value));
853 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
854 ir.expr(PExpr::Or([absent, comparison].into()))
855}
856
857#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
870pub enum UnknownSemanticPolicy {
871 #[default]
873 AssumeTrue,
874 AssumeFalse,
876 Error,
879}
880
881fn apply_unknown_predicate_policy(
890 policy: UnknownSemanticPolicy,
891 rule_index: usize,
892 pred_index: usize,
893 hits: &mut Vec<(usize, usize)>,
894) -> bool {
895 match policy {
896 UnknownSemanticPolicy::AssumeTrue => true,
897 UnknownSemanticPolicy::AssumeFalse => false,
898 UnknownSemanticPolicy::Error => {
899 let coordinate = (rule_index, pred_index);
900 if !hits.contains(&coordinate) {
901 hits.push(coordinate);
902 }
903 false
904 }
905 }
906}
907
908#[derive(Clone, Debug, Eq, PartialEq)]
912pub struct ExpectedTokenSet {
913 symbols: BTreeSet<i32>,
914}
915
916impl ExpectedTokenSet {
917 #[must_use]
919 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
920 expected_symbols_display(&self.symbols, vocabulary)
921 }
922}
923
924#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
929pub struct BailErrorStrategy;
930
931impl BailErrorStrategy {
932 #[must_use]
933 pub const fn new() -> Self {
934 Self
935 }
936}
937
938#[derive(Clone, Copy, Debug, Eq, PartialEq)]
940pub enum PredictionMode {
941 Ll,
944 Sll,
947 LlExactAmbigDetection,
949}
950
951#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
957pub struct ParserRuleArg {
958 pub source_state: usize,
960 pub rule_index: usize,
962 pub value: i64,
964 pub inherit_local: bool,
966}
967
968#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
970pub struct ParserMemberAction {
971 pub source_state: usize,
973 pub member: usize,
975 pub delta: i64,
977}
978
979#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
986pub struct ParserReturnAction {
987 pub source_state: usize,
989 pub rule_index: usize,
991 pub name: &'static str,
993 pub value: i64,
995}
996
997impl ParserMemberAction {
998 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1000 let delta = ir.expr(PExpr::Int(self.delta));
1001 ParserSemanticAction {
1002 source_state: self.source_state,
1003 rule_index: usize::MAX,
1004 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
1005 speculative: true,
1006 }
1007 }
1008}
1009
1010impl ParserReturnAction {
1011 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1013 let name = ir.intern(self.name);
1014 let value = ir.expr(PExpr::Int(self.value));
1015 ParserSemanticAction {
1016 source_state: self.source_state,
1017 rule_index: self.rule_index,
1018 stmt: ir.stmt(AStmt::SetReturn(name, value)),
1019 speculative: false,
1020 }
1021 }
1022}
1023
1024#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1026pub struct ParserSemanticPredicate {
1027 pub rule_index: usize,
1029 pub pred_index: usize,
1031 pub expr: ExprId,
1033 pub failure_message: Option<&'static str>,
1035}
1036
1037#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1039pub struct ParserSemanticAction {
1040 pub source_state: usize,
1042 pub rule_index: usize,
1044 pub stmt: StmtId,
1046 pub speculative: bool,
1048}
1049
1050#[derive(Clone, Debug, Default, Eq, PartialEq)]
1057pub struct ParserSemantics {
1058 pub ir: SemIr,
1059 pub predicates: Vec<ParserSemanticPredicate>,
1060 pub actions: Vec<ParserSemanticAction>,
1061}
1062
1063#[derive(Clone, Copy, Debug, Default)]
1065pub struct ParserRuntimeOptions<'a> {
1066 pub init_action_rules: &'a [usize],
1068 pub track_alt_numbers: bool,
1070 #[doc(hidden)]
1075 pub track_context_alt_numbers: bool,
1076 pub predicates: &'a [(usize, usize, ParserPredicate)],
1078 pub semantics: Option<&'a ParserSemantics>,
1080 pub rule_args: &'a [ParserRuleArg],
1082 pub member_actions: &'a [ParserMemberAction],
1084 pub return_actions: &'a [ParserReturnAction],
1086 pub unknown_predicate_policy: UnknownSemanticPolicy,
1089}
1090
1091pub trait Parser: Recognizer {
1092 fn build_parse_trees(&self) -> bool;
1095
1096 fn set_build_parse_trees(&mut self, build: bool);
1098
1099 fn number_of_syntax_errors(&self) -> usize {
1102 0
1103 }
1104
1105 fn report_diagnostic_errors(&self) -> bool {
1108 false
1109 }
1110
1111 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
1114
1115 fn prediction_mode(&self) -> PredictionMode {
1117 PredictionMode::Ll
1118 }
1119
1120 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
1122}
1123
1124#[derive(Debug)]
1125struct LeftRecursiveCallerOverlap {
1126 atn_key: SharedAtnCacheKey,
1127 state_number: usize,
1128 symbol: i32,
1129 context_version: usize,
1130 overlaps: bool,
1131}
1132
1133const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
1134
1135#[derive(Debug)]
1136pub struct BaseParser<S, H = NoSemanticHooks> {
1137 input: CommonTokenStream<S>,
1138 tree: ParseTreeStorage,
1139 data: RecognizerData,
1140 semantic_hooks: H,
1141 decision_override_generation: usize,
1142 build_parse_trees: bool,
1143 syntax_errors: usize,
1144 report_diagnostic_errors: bool,
1145 prediction_mode: PredictionMode,
1146 prediction_diagnostics: Vec<ParserDiagnostic>,
1147 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1148 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1149 generated_sync_expected: Option<TokenBitSet>,
1150 generated_recovery_error_index: Option<usize>,
1151 generated_recovery_error_states: BTreeSet<isize>,
1152 int_members: BTreeMap<usize, i64>,
1153 rule_context_stack: Vec<RuleContextFrame>,
1154 rule_context_version: usize,
1155 left_recursive_caller_overlap_cache:
1156 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1157 pending_invoking_states: Vec<isize>,
1158 precedence_stack: Vec<i32>,
1159 invoked_predicates: Vec<(usize, usize)>,
1163 bail_on_error: bool,
1167 unknown_predicate_policy: UnknownSemanticPolicy,
1170 unknown_predicate_hits: Vec<(usize, usize)>,
1173 unhandled_action_hits: Vec<(usize, usize)>,
1178 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1183 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1189 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1194 rule_stop_reach_cache: Vec<Option<bool>>,
1199 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1204 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1210 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1216 fast_predicate_cache: FxHashMap<(usize, usize, usize), bool>,
1220 empty_cycle_cache: Vec<Option<bool>>,
1226 empty_cycle_cache_atn: Option<SharedAtnCacheKey>,
1227 clean_memo_mode: CleanMemoMode,
1230 clean_memo_probe_seen: FxHashSet<FastRecognizeKey>,
1231 clean_memo_probe_samples: usize,
1232 clean_memo_probe_repeats: usize,
1233 clean_memo_sparse_samples: usize,
1234 fast_recognize_scratch: FastRecognizeTopScratch,
1236 fast_outcome_dedup: FastOutcomeDedupScratch,
1238 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1241 fast_first_set_prefilter: bool,
1249 fast_recovery_enabled: bool,
1253 fast_token_nodes_enabled: bool,
1258 fast_track_alt_numbers: bool,
1261 recognition_arena: RecognitionArena,
1265 last_recognition_arena_root: NodeSeqId,
1266 last_recognition_arena_diagnostics: DiagnosticSeqId,
1267}
1268
1269#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1271pub struct GeneratedDiagnosticsCheckpoint {
1272 diagnostics_len: usize,
1273 syntax_errors: usize,
1274 tree: ParseTreeCheckpoint,
1275}
1276
1277#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1280pub struct RecognitionArenaStats {
1281 pub total_nodes: usize,
1282 pub live_nodes: usize,
1283 pub dead_nodes: usize,
1284 pub node_capacity: usize,
1285 pub total_links: usize,
1286 pub live_links: usize,
1287 pub dead_links: usize,
1288 pub link_capacity: usize,
1289 pub total_extras: usize,
1290 pub live_extras: usize,
1291 pub dead_extras: usize,
1292 pub extra_capacity: usize,
1293}
1294
1295#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1296struct RuleContextFrame {
1297 rule_index: usize,
1298 invoking_state: isize,
1299}
1300
1301#[derive(Clone, Debug, Eq, PartialEq)]
1302struct RecognizeOutcome {
1303 index: usize,
1304 consumed_eof: bool,
1305 alt_number: usize,
1306 member_values: BTreeMap<usize, i64>,
1307 return_values: BTreeMap<String, i64>,
1308 diagnostics: DiagnosticSeqId,
1309 decisions: Vec<usize>,
1310 actions: Vec<ParserAction>,
1311 nodes: NodeSeqId,
1312}
1313
1314#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1315struct FastRecognizeOutcome {
1316 index: usize,
1317 consumed_eof: bool,
1318 diagnostics: DiagnosticSeqId,
1319 deferred_nodes: FastDeferredNodeId,
1320 nodes: NodeSeqId,
1324}
1325
1326#[derive(Debug, Default)]
1327struct FastRecognizeTopScratch {
1328 visiting: FxHashSet<FastRecognizeKey>,
1329 memo: FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
1330}
1331
1332impl FastRecognizeTopScratch {
1333 fn prepare(&mut self, memo_capacity: usize) {
1334 self.visiting.clear();
1335 self.visiting.reserve(FAST_RECOGNIZE_VISITING_CAPACITY);
1336 self.memo.clear();
1337 self.memo.reserve(memo_capacity);
1338 }
1339
1340 fn release_oversized_memo(&mut self) {
1341 self.memo.clear();
1342 if self.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY {
1343 self.memo = FxHashMap::default();
1344 }
1345 }
1346}
1347
1348fn fast_recognize_memo_capacity(buffered_tokens: usize) -> usize {
1349 buffered_tokens.saturating_mul(8).clamp(
1350 FAST_RECOGNIZE_MIN_MEMO_CAPACITY,
1351 FAST_RECOGNIZE_MAX_MEMO_CAPACITY,
1352 )
1353}
1354
1355#[derive(Debug, Default)]
1356struct FastOutcomeDedupScratch {
1357 dense_words: Vec<u64>,
1358 touched_dense_words: Vec<u32>,
1359 sparse_keys: FxHashSet<(usize, bool)>,
1360}
1361
1362#[repr(transparent)]
1367#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1368struct FastDeferredNodeId(u32);
1369
1370impl FastDeferredNodeId {
1371 const EMPTY: Self = Self(u32::MAX);
1372
1373 const fn is_empty(self) -> bool {
1374 self.0 == Self::EMPTY.0
1375 }
1376}
1377
1378impl Default for FastDeferredNodeId {
1379 fn default() -> Self {
1380 Self::EMPTY
1381 }
1382}
1383
1384#[repr(transparent)]
1385#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1386struct FastDeferredRuleId(u32);
1387
1388#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1390enum FastDeferredNode {
1391 Fragment(NodeSeqId),
1392 Rule(FastDeferredRuleId),
1393 Alternative(u32),
1394 LeftRecursiveBoundary {
1395 rule_index: u32,
1396 },
1397 Concat {
1398 prefix: FastDeferredNodeId,
1399 suffix: FastDeferredNodeId,
1400 },
1401}
1402
1403#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1404struct FastDeferredRule {
1405 rule_index: u32,
1406 invoking_state: i32,
1407 start_index: u32,
1408 stop_index: Option<u32>,
1409 deferred_children: FastDeferredNodeId,
1410 children: NodeSeqId,
1411}
1412
1413#[repr(transparent)]
1414#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1415struct RecognizedNodeId(u32);
1416
1417#[repr(transparent)]
1418#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1419struct NodeSeqId(u32);
1420
1421impl NodeSeqId {
1422 const EMPTY: Self = Self(u32::MAX);
1423
1424 const fn is_empty(self) -> bool {
1425 self.0 == Self::EMPTY.0
1426 }
1427}
1428
1429impl Default for NodeSeqId {
1430 fn default() -> Self {
1431 Self::EMPTY
1432 }
1433}
1434
1435#[repr(transparent)]
1436#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1437struct DiagnosticSeqId(u32);
1438
1439impl DiagnosticSeqId {
1440 const EMPTY: Self = Self(u32::MAX);
1441
1442 const fn is_empty(self) -> bool {
1443 self.0 == Self::EMPTY.0
1444 }
1445}
1446
1447impl Default for DiagnosticSeqId {
1448 fn default() -> Self {
1449 Self::EMPTY
1450 }
1451}
1452
1453#[repr(transparent)]
1454#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1455struct RecognitionExtraId(u32);
1456
1457#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1458struct SeqLink {
1459 head: RecognizedNodeId,
1460 tail: NodeSeqId,
1461}
1462
1463#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1464struct DiagnosticLink {
1465 head: RecognitionExtraId,
1466 tail: DiagnosticSeqId,
1467}
1468
1469struct ArenaRuleSpec {
1470 rule_index: usize,
1471 invoking_state: isize,
1472 alt_number: usize,
1473 start_index: usize,
1474 stop_index: Option<usize>,
1475 return_values: BTreeMap<String, i64>,
1476 children: NodeSeqId,
1477}
1478
1479#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1482enum ArenaRecognizedNode {
1483 Token {
1484 token: TokenId,
1485 },
1486 ErrorToken {
1487 token: TokenId,
1488 },
1489 MissingToken {
1490 extra: RecognitionExtraId,
1491 },
1492 Rule {
1493 rule_index: u32,
1494 invoking_state: i32,
1495 alt_number: u32,
1496 start_index: u32,
1497 stop_index: Option<u32>,
1498 return_values: Option<RecognitionExtraId>,
1499 children: NodeSeqId,
1500 },
1501 LeftRecursiveBoundary {
1505 rule_index: u32,
1506 alt_number: u32,
1507 },
1508}
1509
1510#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1511enum RecognitionExtra {
1512 MissingToken {
1513 token_type: i32,
1514 at_index: u32,
1515 text: String,
1516 },
1517 ReturnValues(BTreeMap<String, i64>),
1518 Diagnostic(ParserDiagnostic),
1519}
1520
1521#[derive(Debug, Default)]
1522struct RecognitionArena {
1523 nodes: Vec<ArenaRecognizedNode>,
1524 seq_links: Vec<SeqLink>,
1525 diagnostic_links: Vec<DiagnosticLink>,
1526 extras: Vec<RecognitionExtra>,
1527 deferred_nodes: Vec<FastDeferredNode>,
1528 deferred_rules: Vec<FastDeferredRule>,
1529}
1530
1531const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1534const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1535const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1536const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1537const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1538const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1539
1540impl RecognitionArena {
1541 fn reset(&mut self) {
1542 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1543 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1544 reset_arena_vec(
1545 &mut self.diagnostic_links,
1546 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1547 );
1548 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1549 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1550 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1551 }
1552
1553 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1554 let id = RecognizedNodeId(
1555 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1556 );
1557 self.nodes.push(node);
1558 id
1559 }
1560
1561 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1562 let id = RecognitionExtraId(
1563 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1564 );
1565 self.extras.push(extra);
1566 id
1567 }
1568
1569 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1570 let id = NodeSeqId(
1571 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1572 );
1573 self.seq_links.push(SeqLink { head, tail });
1574 id
1575 }
1576
1577 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1578 let id = FastDeferredNodeId(
1579 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
1580 );
1581 self.deferred_nodes.push(node);
1582 id
1583 }
1584
1585 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
1586 let id = FastDeferredRuleId(
1587 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
1588 );
1589 self.deferred_rules.push(rule);
1590 id
1591 }
1592
1593 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
1594 if nodes.is_empty() {
1595 FastDeferredNodeId::EMPTY
1596 } else {
1597 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
1598 }
1599 }
1600
1601 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
1602 let rule = self.push_deferred_rule(rule);
1603 self.push_deferred_node(FastDeferredNode::Rule(rule))
1604 }
1605
1606 fn deferred_alternative(&mut self, alt_number: usize) -> FastDeferredNodeId {
1607 self.push_deferred_node(FastDeferredNode::Alternative(
1608 u32::try_from(alt_number).expect("alternative number fits in u32"),
1609 ))
1610 }
1611
1612 fn deferred_left_recursive_boundary(&mut self, rule_index: usize) -> FastDeferredNodeId {
1613 self.push_deferred_node(FastDeferredNode::LeftRecursiveBoundary {
1614 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
1615 })
1616 }
1617
1618 fn concat_deferred_nodes(
1619 &mut self,
1620 prefix: FastDeferredNodeId,
1621 suffix: FastDeferredNodeId,
1622 ) -> FastDeferredNodeId {
1623 if prefix.is_empty() {
1624 return suffix;
1625 }
1626 if suffix.is_empty() {
1627 return prefix;
1628 }
1629 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
1630 }
1631
1632 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
1633 self.deferred_nodes[id.0 as usize]
1634 }
1635
1636 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
1637 self.deferred_rules[id.0 as usize]
1638 }
1639
1640 fn prepend_diagnostic(
1641 &mut self,
1642 tail: DiagnosticSeqId,
1643 diagnostic: ParserDiagnostic,
1644 ) -> DiagnosticSeqId {
1645 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
1646 self.prepend_diagnostic_id(tail, head)
1647 }
1648
1649 fn prepend_diagnostic_id(
1650 &mut self,
1651 tail: DiagnosticSeqId,
1652 head: RecognitionExtraId,
1653 ) -> DiagnosticSeqId {
1654 let id = DiagnosticSeqId(
1655 u32::try_from(self.diagnostic_links.len())
1656 .expect("diagnostic sequence arena fits in u32"),
1657 );
1658 self.diagnostic_links.push(DiagnosticLink { head, tail });
1659 id
1660 }
1661
1662 fn concat_diagnostics(
1663 &mut self,
1664 prefix: DiagnosticSeqId,
1665 mut suffix: DiagnosticSeqId,
1666 ) -> DiagnosticSeqId {
1667 if prefix.is_empty() {
1668 return suffix;
1669 }
1670 if suffix.is_empty() {
1671 return prefix;
1672 }
1673 let mut reversed = DiagnosticSeqId::EMPTY;
1674 let mut cursor = prefix;
1675 while let Some(link) = self.diagnostic_link(cursor) {
1676 reversed = self.prepend_diagnostic_id(reversed, link.head);
1677 cursor = link.tail;
1678 }
1679 while let Some(link) = self.diagnostic_link(reversed) {
1680 suffix = self.prepend_diagnostic_id(suffix, link.head);
1681 reversed = link.tail;
1682 }
1683 suffix
1684 }
1685
1686 #[cfg(test)]
1687 fn diagnostic_sequence(
1688 &mut self,
1689 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
1690 ) -> DiagnosticSeqId {
1691 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
1692 let mut sequence = DiagnosticSeqId::EMPTY;
1693 for diagnostic in diagnostics.into_iter().rev() {
1694 sequence = self.prepend_diagnostic(sequence, diagnostic);
1695 }
1696 sequence
1697 }
1698
1699 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
1700 self.nodes[id.0 as usize]
1701 }
1702
1703 fn set_boundary_alt_number(&mut self, id: RecognizedNodeId, alt_number: u32) {
1704 let ArenaRecognizedNode::LeftRecursiveBoundary {
1705 alt_number: stored, ..
1706 } = &mut self.nodes[id.0 as usize]
1707 else {
1708 unreachable!("deferred boundary must materialize as a boundary node");
1709 };
1710 *stored = alt_number;
1711 }
1712
1713 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
1714 &self.extras[id.0 as usize]
1715 }
1716
1717 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
1718 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
1719 }
1720
1721 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
1722 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
1723 }
1724
1725 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
1726 NodeSeqIter {
1727 arena: self,
1728 cursor: sequence,
1729 }
1730 }
1731
1732 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
1733 DiagnosticSeqIter {
1734 arena: self,
1735 cursor: sequence,
1736 }
1737 }
1738
1739 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
1740 self.diagnostics(sequence).count()
1741 }
1742
1743 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
1744 self.diagnostics(sequence)
1745 .filter(|diagnostic| {
1746 diagnostic.message.starts_with("mismatched input ")
1747 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
1748 })
1749 .count()
1750 }
1751
1752 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
1753 self.diagnostics(left).cmp(self.diagnostics(right))
1754 }
1755
1756 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
1757 self.iter(sequence).count()
1758 }
1759
1760 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
1761 self.iter(sequence).any(|node| match self.node(node) {
1762 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1763 ArenaRecognizedNode::Rule { children, .. } => {
1764 self.sequence_has_left_recursive_boundary(children)
1765 }
1766 ArenaRecognizedNode::Token { .. }
1767 | ArenaRecognizedNode::ErrorToken { .. }
1768 | ArenaRecognizedNode::MissingToken { .. } => false,
1769 })
1770 }
1771
1772 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
1773 self.iter(sequence).any(|node| {
1774 matches!(
1775 self.node(node),
1776 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
1777 )
1778 })
1779 }
1780
1781 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
1782 self.iter(sequence).any(|node| {
1783 matches!(
1784 self.node(node),
1785 ArenaRecognizedNode::Token { .. }
1786 | ArenaRecognizedNode::ErrorToken { .. }
1787 | ArenaRecognizedNode::MissingToken { .. }
1788 )
1789 })
1790 }
1791
1792 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
1793 match self.node(node) {
1794 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1795 Some(token.index())
1796 }
1797 ArenaRecognizedNode::MissingToken { extra } => {
1798 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1799 unreachable!("missing-token node must reference missing-token extra");
1800 };
1801 Some(*at_index as usize)
1802 }
1803 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
1804 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1805 }
1806 }
1807
1808 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
1809 match self.node(node) {
1810 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1811 Some(token.index())
1812 }
1813 ArenaRecognizedNode::MissingToken { extra } => {
1814 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1815 unreachable!("missing-token node must reference missing-token extra");
1816 };
1817 (*at_index as usize).checked_sub(1)
1818 }
1819 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
1820 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1821 }
1822 }
1823
1824 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
1825 let start = self.node_start_index(node)?;
1826 let stop = self.node_stop_index(node);
1827 Some((start, stop))
1828 }
1829
1830 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
1831 self.iter(sequence)
1832 .find_map(|node| self.node_start_index(node))
1833 }
1834
1835 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
1836 let mut stop = None;
1837 for node in self.iter(sequence) {
1838 if let Some(index) = self.node_stop_index(node) {
1839 stop = Some(index);
1840 }
1841 }
1842 stop
1843 }
1844
1845 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
1846 self.iter(sequence)
1847 .any(|node| self.node_needs_stable_tie(node))
1848 }
1849
1850 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
1851 match self.node(node) {
1852 ArenaRecognizedNode::Token { .. }
1853 | ArenaRecognizedNode::ErrorToken { .. }
1854 | ArenaRecognizedNode::MissingToken { .. } => false,
1855 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1856 ArenaRecognizedNode::Rule {
1857 rule_index,
1858 children,
1859 ..
1860 } => self.iter(children).any(|child| {
1861 matches!(
1862 self.node(child),
1863 ArenaRecognizedNode::Rule {
1864 rule_index: child_rule,
1865 ..
1866 } if child_rule == rule_index
1867 ) || self.node_needs_stable_tie(child)
1868 }),
1869 }
1870 }
1871
1872 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
1873 loop {
1874 match (self.link(left), self.link(right)) {
1875 (Some(left_link), Some(right_link)) => {
1876 let order = self.compare_nodes(left_link.head, right_link.head);
1877 if order != Ordering::Equal {
1878 return order;
1879 }
1880 left = left_link.tail;
1881 right = right_link.tail;
1882 }
1883 (None, None) => return Ordering::Equal,
1884 (None, Some(_)) => return Ordering::Less,
1885 (Some(_), None) => return Ordering::Greater,
1886 }
1887 }
1888 }
1889
1890 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
1891 let left = self.node(left);
1892 let right = self.node(right);
1893 match (left, right) {
1894 (
1895 ArenaRecognizedNode::Token { token: left },
1896 ArenaRecognizedNode::Token { token: right },
1897 )
1898 | (
1899 ArenaRecognizedNode::ErrorToken { token: left },
1900 ArenaRecognizedNode::ErrorToken { token: right },
1901 ) => left.cmp(&right),
1902 (
1903 ArenaRecognizedNode::MissingToken { extra: left },
1904 ArenaRecognizedNode::MissingToken { extra: right },
1905 ) => self.extra(left).cmp(self.extra(right)),
1906 (
1907 ArenaRecognizedNode::Rule {
1908 rule_index: left_rule,
1909 invoking_state: left_invoking,
1910 alt_number: left_alt,
1911 start_index: left_start,
1912 stop_index: left_stop,
1913 return_values: left_returns,
1914 children: left_children,
1915 },
1916 ArenaRecognizedNode::Rule {
1917 rule_index: right_rule,
1918 invoking_state: right_invoking,
1919 alt_number: right_alt,
1920 start_index: right_start,
1921 stop_index: right_stop,
1922 return_values: right_returns,
1923 children: right_children,
1924 },
1925 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
1926 .cmp(&(
1927 right_rule,
1928 right_invoking,
1929 right_alt,
1930 right_start,
1931 right_stop,
1932 ))
1933 .then_with(|| {
1934 left_returns
1935 .map(|id| self.extra(id))
1936 .cmp(&right_returns.map(|id| self.extra(id)))
1937 })
1938 .then_with(|| self.compare_sequences(left_children, right_children)),
1939 (
1940 ArenaRecognizedNode::LeftRecursiveBoundary {
1941 rule_index: left_rule,
1942 alt_number: left_alt,
1943 },
1944 ArenaRecognizedNode::LeftRecursiveBoundary {
1945 rule_index: right_rule,
1946 alt_number: right_alt,
1947 },
1948 ) => (left_rule, left_alt).cmp(&(right_rule, right_alt)),
1949 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
1950 }
1951 }
1952
1953 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1954 let mut reversed = NodeSeqId::EMPTY;
1955 while let Some(link) = self.link(sequence) {
1956 reversed = self.prepend(reversed, link.head);
1957 sequence = link.tail;
1958 }
1959 reversed
1960 }
1961
1962 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1963 if !self.sequence_has_direct_boundary(sequence) {
1964 return sequence;
1965 }
1966 let mut reversed = NodeSeqId::EMPTY;
1967 while let Some(link) = self.link(sequence) {
1968 match self.node(link.head) {
1969 ArenaRecognizedNode::LeftRecursiveBoundary {
1970 rule_index,
1971 alt_number,
1972 } => {
1973 if !reversed.is_empty() {
1974 let children = self.reverse_sequence(reversed);
1975 let start_index = self.sequence_start_index(children).unwrap_or_default();
1976 let stop_index = self.sequence_stop_index(children);
1977 let rule = self.push_node(ArenaRecognizedNode::Rule {
1978 rule_index,
1979 invoking_state: -1,
1980 alt_number,
1981 start_index: u32::try_from(start_index)
1982 .expect("left-recursive start index fits in u32"),
1983 stop_index: stop_index.map(|index| {
1984 u32::try_from(index).expect("left-recursive stop index fits in u32")
1985 }),
1986 return_values: None,
1987 children,
1988 });
1989 reversed = self.prepend(NodeSeqId::EMPTY, rule);
1990 }
1991 }
1992 _ => {
1993 reversed = self.prepend(reversed, link.head);
1994 }
1995 }
1996 sequence = link.tail;
1997 }
1998 self.reverse_sequence(reversed)
1999 }
2000
2001 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
2002 let mut live_nodes = vec![false; self.nodes.len()];
2003 let mut live_links = vec![false; self.seq_links.len()];
2004 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
2005 let mut live_extras = vec![false; self.extras.len()];
2006 let mut pending = vec![root];
2007 while let Some(mut sequence) = pending.pop() {
2008 while let Some(link) = self.link(sequence) {
2009 let link_index = sequence.0 as usize;
2010 if live_links[link_index] {
2011 break;
2012 }
2013 live_links[link_index] = true;
2014 let node_index = link.head.0 as usize;
2015 if !live_nodes[node_index] {
2016 live_nodes[node_index] = true;
2017 match self.node(link.head) {
2018 ArenaRecognizedNode::MissingToken { extra } => {
2019 live_extras[extra.0 as usize] = true;
2020 }
2021 ArenaRecognizedNode::Rule {
2022 return_values,
2023 children,
2024 ..
2025 } => {
2026 if let Some(extra) = return_values {
2027 live_extras[extra.0 as usize] = true;
2028 }
2029 pending.push(children);
2030 }
2031 ArenaRecognizedNode::Token { .. }
2032 | ArenaRecognizedNode::ErrorToken { .. }
2033 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
2034 }
2035 }
2036 sequence = link.tail;
2037 }
2038 }
2039 let mut diagnostics = diagnostics;
2040 while let Some(link) = self.diagnostic_link(diagnostics) {
2041 let link_index = diagnostics.0 as usize;
2042 if live_diagnostic_links[link_index] {
2043 break;
2044 }
2045 live_diagnostic_links[link_index] = true;
2046 live_extras[link.head.0 as usize] = true;
2047 diagnostics = link.tail;
2048 }
2049 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
2050 let live_link_count = live_links.into_iter().filter(|live| *live).count()
2051 + live_diagnostic_links
2052 .into_iter()
2053 .filter(|live| *live)
2054 .count();
2055 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
2056 let total_links = self.seq_links.len() + self.diagnostic_links.len();
2057 RecognitionArenaStats {
2058 total_nodes: self.nodes.len(),
2059 live_nodes: live_node_count,
2060 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
2061 node_capacity: self.nodes.capacity(),
2062 total_links,
2063 live_links: live_link_count,
2064 dead_links: total_links.saturating_sub(live_link_count),
2065 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
2066 total_extras: self.extras.len(),
2067 live_extras: live_extra_count,
2068 dead_extras: self.extras.len().saturating_sub(live_extra_count),
2069 extra_capacity: self.extras.capacity(),
2070 }
2071 }
2072}
2073
2074fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
2075 if storage.capacity() > max_retained_capacity {
2076 *storage = Vec::new();
2077 } else {
2078 storage.clear();
2079 }
2080}
2081
2082const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
2083 match node {
2084 ArenaRecognizedNode::Token { .. } => 0,
2085 ArenaRecognizedNode::ErrorToken { .. } => 1,
2086 ArenaRecognizedNode::MissingToken { .. } => 2,
2087 ArenaRecognizedNode::Rule { .. } => 3,
2088 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
2089 }
2090}
2091
2092struct NodeSeqIter<'a> {
2093 arena: &'a RecognitionArena,
2094 cursor: NodeSeqId,
2095}
2096
2097impl Iterator for NodeSeqIter<'_> {
2098 type Item = RecognizedNodeId;
2099
2100 fn next(&mut self) -> Option<Self::Item> {
2101 let link = self.arena.link(self.cursor)?;
2102 self.cursor = link.tail;
2103 Some(link.head)
2104 }
2105}
2106
2107struct DiagnosticSeqIter<'a> {
2108 arena: &'a RecognitionArena,
2109 cursor: DiagnosticSeqId,
2110}
2111
2112impl<'a> Iterator for DiagnosticSeqIter<'a> {
2113 type Item = &'a ParserDiagnostic;
2114
2115 fn next(&mut self) -> Option<Self::Item> {
2116 let link = self.arena.diagnostic_link(self.cursor)?;
2117 self.cursor = link.tail;
2118 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2119 unreachable!("diagnostic link must reference diagnostic extra");
2120 };
2121 Some(diagnostic)
2122 }
2123}
2124
2125#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2126struct ParserDiagnostic {
2127 line: usize,
2128 column: usize,
2129 message: String,
2130}
2131
2132#[derive(Clone, Debug, Default, Eq, PartialEq)]
2133struct ExpectedTokens {
2134 index: Option<usize>,
2135 symbols: BTreeSet<i32>,
2136 no_viable: Option<NoViableAlternative>,
2137}
2138
2139#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2140struct NoViableAlternative {
2141 start_index: usize,
2142 error_index: usize,
2143}
2144
2145impl ExpectedTokens {
2146 fn record_transition(
2149 &mut self,
2150 index: usize,
2151 transition: ParserTransition<'_>,
2152 max_token_type: i32,
2153 ) {
2154 let symbols = transition_expected_symbols(transition, max_token_type);
2155 match self.index {
2156 Some(current) if index < current => {}
2157 Some(current) if index == current => self.symbols.extend(symbols),
2158 _ => {
2159 self.index = Some(index);
2160 self.symbols = symbols;
2161 }
2162 }
2163 }
2164
2165 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2168 match self.no_viable {
2169 Some(current) if error_index < current.error_index => {}
2170 _ => {
2171 self.no_viable = Some(NoViableAlternative {
2172 start_index,
2173 error_index,
2174 });
2175 }
2176 }
2177 }
2178}
2179
2180#[derive(Clone, Debug, Default, Eq, PartialEq)]
2187struct TokenBitSet {
2188 words: Vec<u64>,
2189}
2190
2191impl TokenBitSet {
2192 fn insert(&mut self, symbol: i32) {
2193 let Some(slot) = token_bit_slot(symbol) else {
2194 return;
2195 };
2196 let word = slot / u64::BITS as usize;
2197 if word >= self.words.len() {
2198 self.words.resize(word + 1, 0);
2199 }
2200 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2201 }
2202
2203 fn extend_range(&mut self, start: i32, stop: i32) {
2204 let (start, stop) = if start <= stop {
2205 (start, stop)
2206 } else {
2207 (stop, start)
2208 };
2209 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2210 self.insert(TOKEN_EOF);
2211 }
2212 let positive_start = start.max(1);
2213 if positive_start > stop {
2214 return;
2215 }
2216 let Some(start_slot) = token_bit_slot(positive_start) else {
2217 return;
2218 };
2219 let Some(stop_slot) = token_bit_slot(stop) else {
2220 return;
2221 };
2222 self.extend_slot_range(start_slot, stop_slot);
2223 }
2224
2225 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2226 if start_slot > stop_slot {
2227 return;
2228 }
2229 let start_word = start_slot / u64::BITS as usize;
2230 let stop_word = stop_slot / u64::BITS as usize;
2231 if stop_word >= self.words.len() {
2232 self.words.resize(stop_word + 1, 0);
2233 }
2234 let start_offset = start_slot % u64::BITS as usize;
2235 let stop_offset = stop_slot % u64::BITS as usize;
2236 if start_word == stop_word {
2237 self.words[start_word] |=
2238 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2239 return;
2240 }
2241 self.words[start_word] |= !0_u64 << start_offset;
2242 for word in &mut self.words[(start_word + 1)..stop_word] {
2243 *word = !0_u64;
2244 }
2245 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2246 }
2247
2248 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2249 for symbol in symbols {
2250 self.insert(symbol);
2251 }
2252 }
2253
2254 fn extend_from(&mut self, other: &Self) {
2255 if other.words.len() > self.words.len() {
2256 self.words.resize(other.words.len(), 0);
2257 }
2258 for (left, right) in self.words.iter_mut().zip(&other.words) {
2259 *left |= *right;
2260 }
2261 }
2262
2263 fn contains(&self, symbol: i32) -> bool {
2264 let Some(slot) = token_bit_slot(symbol) else {
2265 return false;
2266 };
2267 let word = slot / u64::BITS as usize;
2268 self.words
2269 .get(word)
2270 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2271 }
2272
2273 fn is_empty(&self) -> bool {
2274 self.words.iter().all(|word| *word == 0)
2275 }
2276
2277 fn symbols(&self) -> impl Iterator<Item = i32> + '_ {
2278 self.words
2279 .iter()
2280 .copied()
2281 .enumerate()
2282 .flat_map(|(word_index, mut bits)| {
2283 std::iter::from_fn(move || {
2284 while bits != 0 {
2285 let bit = bits.trailing_zeros() as usize;
2286 bits &= bits - 1;
2287 if let Some(symbol) =
2288 token_bit_symbol(word_index * u64::BITS as usize + bit)
2289 {
2290 return Some(symbol);
2291 }
2292 }
2293 None
2294 })
2295 })
2296 }
2297
2298 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2299 target.extend(self.symbols());
2300 }
2301
2302 fn to_btree_set(&self) -> BTreeSet<i32> {
2303 let mut out = BTreeSet::new();
2304 self.extend_btree_set(&mut out);
2305 out
2306 }
2307}
2308
2309fn token_bit_slot(symbol: i32) -> Option<usize> {
2310 if symbol == TOKEN_EOF {
2311 Some(0)
2312 } else if symbol > 0 {
2313 usize::try_from(symbol).ok()
2314 } else {
2315 None
2316 }
2317}
2318
2319fn token_bit_symbol(slot: usize) -> Option<i32> {
2320 if slot == 0 {
2321 Some(TOKEN_EOF)
2322 } else {
2323 i32::try_from(slot).ok()
2324 }
2325}
2326
2327fn transition_expected_symbols(
2330 transition: ParserTransition<'_>,
2331 max_token_type: i32,
2332) -> BTreeSet<i32> {
2333 let mut symbols = BTreeSet::new();
2334 match &transition.data() {
2335 Transition::Atom { label, .. } => {
2336 symbols.insert(*label);
2337 }
2338 Transition::Range { start, stop, .. } => {
2339 symbols.extend(*start..=*stop);
2340 }
2341 Transition::Set { set, .. } => {
2342 for (start, stop) in set.ranges() {
2343 symbols.extend(start..=stop);
2344 }
2345 }
2346 Transition::NotSet { set, .. } => {
2347 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2348 }
2349 Transition::Wildcard { .. } => {
2350 symbols.extend(1..=max_token_type);
2351 }
2352 Transition::Epsilon { .. }
2353 | Transition::Rule { .. }
2354 | Transition::Predicate { .. }
2355 | Transition::Action { .. }
2356 | Transition::Precedence { .. } => {}
2357 }
2358 symbols
2359}
2360
2361fn transition_expected_token_set(
2362 transition: ParserTransition<'_>,
2363 max_token_type: i32,
2364) -> TokenBitSet {
2365 let mut symbols = TokenBitSet::default();
2366 match &transition.data() {
2367 Transition::Atom { label, .. } => {
2368 symbols.insert(*label);
2369 }
2370 Transition::Range { start, stop, .. } => {
2371 symbols.extend_range(*start, *stop);
2372 }
2373 Transition::Set { set, .. } => {
2374 for (start, stop) in set.ranges() {
2375 symbols.extend_range(start, stop);
2376 }
2377 }
2378 Transition::NotSet { set, .. } => {
2379 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2380 }
2381 Transition::Wildcard { .. } => {
2382 symbols.extend_range(1, max_token_type);
2383 }
2384 Transition::Epsilon { .. }
2385 | Transition::Rule { .. }
2386 | Transition::Predicate { .. }
2387 | Transition::Action { .. }
2388 | Transition::Precedence { .. } => {}
2389 }
2390 symbols
2391}
2392
2393fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2397 let mut symbols = BTreeSet::new();
2398 let mut stack = vec![state_number];
2399 let mut visited = BTreeSet::new();
2400 while let Some(current) = stack.pop() {
2401 if !visited.insert(current) {
2402 continue;
2403 }
2404 let Some(state) = atn.state(current) else {
2405 continue;
2406 };
2407 for transition in &state.transitions() {
2408 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2409 if transition_symbols.is_empty() {
2410 if transition.is_epsilon() {
2411 stack.push(transition.target());
2412 }
2413 } else {
2414 symbols.extend(transition_symbols);
2415 }
2416 }
2417 }
2418 symbols
2419}
2420
2421fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2422 let mut symbols = TokenBitSet::default();
2423 let mut stack = vec![state_number];
2424 let mut visited = BTreeSet::new();
2425 while let Some(current) = stack.pop() {
2426 if !visited.insert(current) {
2427 continue;
2428 }
2429 let Some(state) = atn.state(current) else {
2430 continue;
2431 };
2432 for transition in &state.transitions() {
2433 let transition_symbols =
2434 transition_expected_token_set(transition, atn.max_token_type());
2435 if transition_symbols.is_empty() {
2436 if transition.is_epsilon() {
2437 stack.push(transition.target());
2438 }
2439 } else {
2440 symbols.extend_from(&transition_symbols);
2441 }
2442 }
2443 }
2444 symbols
2445}
2446
2447fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2448 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2449 return false;
2450 };
2451 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2452 return false;
2453 };
2454 epsilon_reaches_state(atn, state_number, stop_state)
2455}
2456
2457fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2458 let mut stack = vec![start];
2459 let mut visited = BTreeSet::new();
2460 while let Some(current) = stack.pop() {
2461 if current == target {
2462 return true;
2463 }
2464 if !visited.insert(current) {
2465 continue;
2466 }
2467 let Some(state) = atn.state(current) else {
2468 continue;
2469 };
2470 stack.extend(
2471 state
2472 .transitions()
2473 .iter()
2474 .filter(|transition| transition.is_epsilon())
2475 .map(ParserTransition::target),
2476 );
2477 }
2478 false
2479}
2480
2481#[derive(Clone, Debug, Default, Eq, PartialEq)]
2488struct FirstSet {
2489 symbols: TokenBitSet,
2490 nullable: bool,
2491}
2492
2493type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2500
2501type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2508
2509#[derive(Debug, Default)]
2510struct LeftRecursiveOperatorLookahead {
2511 single_token: TokenBitSet,
2515 multi_token_prefix: TokenBitSet,
2520 predicate_dependent: TokenBitSet,
2521}
2522
2523#[derive(Default)]
2524struct SharedAtnCache {
2525 first_set: FirstSetCache,
2526 decision_lookahead: DecisionLookaheadCache,
2527 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2528 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2529 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2530 rule_stop_reach: FxHashMap<usize, bool>,
2531 observable_action_transitions: Option<bool>,
2532 predicate_transitions: Option<bool>,
2533}
2534
2535thread_local! {
2536 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2537 RefCell::new(FxHashMap::default());
2538}
2539
2540#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2551struct SharedAtnCacheKey {
2552 atn: usize,
2553 states: usize,
2554 state_count: usize,
2555 max_token_type: i32,
2556}
2557
2558impl SharedAtnCacheKey {
2559 fn for_atn(atn: &Atn) -> Self {
2560 let (states, state_count) = atn.storage_identity();
2561 Self {
2562 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2563 states,
2564 state_count,
2565 max_token_type: atn.max_token_type(),
2566 }
2567 }
2568}
2569
2570fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2571 SHARED_ATN_CACHES.with(|cell| {
2572 let key = SharedAtnCacheKey::for_atn(atn);
2573 let mut map = cell.borrow_mut();
2574 let cache = map.entry(key).or_default();
2575 f(&mut cache.first_set)
2576 })
2577}
2578
2579fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
2580 SHARED_ATN_CACHES.with(|cell| {
2581 let key = SharedAtnCacheKey::for_atn(atn);
2582 let mut map = cell.borrow_mut();
2583 let cache = map.entry(key).or_default();
2584 f(cache)
2585 })
2586}
2587
2588#[derive(Debug, Default)]
2597struct DecisionLookahead {
2598 transitions: Vec<TransitionLookSet>,
2599}
2600
2601#[derive(Clone, Debug, Default)]
2608struct TransitionLookSet {
2609 symbols: TokenBitSet,
2610 nullable: bool,
2611}
2612
2613struct FirstSetCtx<'a> {
2617 cache: &'a mut FirstSetCache,
2618 in_progress: BTreeSet<(usize, usize)>,
2619 hit_cycle: bool,
2620}
2621
2622fn rule_first_set(
2631 atn: &Atn,
2632 target: usize,
2633 rule_stop_state: usize,
2634 cache: &mut FirstSetCache,
2635) -> Rc<FirstSet> {
2636 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
2637 return Rc::clone(cached);
2638 }
2639 let mut ctx = FirstSetCtx {
2640 cache,
2641 in_progress: BTreeSet::new(),
2642 hit_cycle: false,
2643 };
2644 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
2645}
2646
2647fn rule_first_set_cached(
2648 atn: &Atn,
2649 target: usize,
2650 rule_stop_state: usize,
2651 ctx: &mut FirstSetCtx<'_>,
2652) -> Rc<FirstSet> {
2653 let key = (target, rule_stop_state);
2654 if let Some(cached) = ctx.cache.get(&key) {
2655 return Rc::clone(cached);
2656 }
2657 if !ctx.in_progress.insert(key) {
2658 return Rc::new(FirstSet::default());
2662 }
2663 let saved_hit_cycle = ctx.hit_cycle;
2664 ctx.hit_cycle = false;
2665 let mut first = FirstSet::default();
2666 let mut visited = BTreeSet::new();
2667 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
2668 ctx.in_progress.remove(&key);
2669 let entry = Rc::new(first);
2670 if !ctx.hit_cycle {
2671 ctx.cache.insert(key, Rc::clone(&entry));
2672 }
2673 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
2674 entry
2675}
2676
2677fn transition_first_set(
2681 atn: &Atn,
2682 transition: ParserTransition<'_>,
2683 rule_stop_state: usize,
2684 cache: &mut FirstSetCache,
2685) -> TransitionLookSet {
2686 match &transition.data() {
2687 Transition::Atom { label, .. } => {
2688 let mut symbols = TokenBitSet::default();
2689 symbols.insert(*label);
2690 TransitionLookSet {
2691 symbols,
2692 nullable: false,
2693 }
2694 }
2695 Transition::Range { start, stop, .. } => {
2696 let mut symbols = TokenBitSet::default();
2697 symbols.extend_range(*start, *stop);
2698 TransitionLookSet {
2699 symbols,
2700 nullable: false,
2701 }
2702 }
2703 Transition::Set { set, .. } => {
2704 let mut symbols = TokenBitSet::default();
2705 for (start, stop) in set.ranges() {
2706 symbols.extend_range(start, stop);
2707 }
2708 TransitionLookSet {
2709 symbols,
2710 nullable: false,
2711 }
2712 }
2713 Transition::NotSet { set, .. } => {
2714 let max = atn.max_token_type();
2715 let mut symbols = TokenBitSet::default();
2716 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
2717 TransitionLookSet {
2718 symbols,
2719 nullable: false,
2720 }
2721 }
2722 Transition::Wildcard { .. } => {
2723 let mut symbols = TokenBitSet::default();
2724 symbols.extend_range(1, atn.max_token_type());
2725 TransitionLookSet {
2726 symbols,
2727 nullable: false,
2728 }
2729 }
2730 Transition::Epsilon { target }
2731 | Transition::Action { target, .. }
2732 | Transition::Predicate { target, .. }
2733 | Transition::Precedence { target, .. } => {
2734 let first = rule_first_set(atn, *target, rule_stop_state, cache);
2737 TransitionLookSet {
2738 symbols: first.symbols.clone(),
2739 nullable: first.nullable,
2740 }
2741 }
2742 Transition::Rule {
2743 target,
2744 rule_index,
2745 follow_state,
2746 ..
2747 } => {
2748 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2749 return TransitionLookSet::default();
2750 };
2751 let child = rule_first_set(atn, *target, child_stop, cache);
2752 let mut symbols = child.symbols.clone();
2753 let nullable = if child.nullable {
2754 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
2755 symbols.extend_from(&follow.symbols);
2756 follow.nullable
2757 } else {
2758 false
2759 };
2760 TransitionLookSet { symbols, nullable }
2761 }
2762 }
2763}
2764
2765fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
2786 let mut chosen: Option<usize> = None;
2787 for (index, transition) in entry.transitions.iter().enumerate() {
2788 if transition.nullable {
2789 return None;
2790 }
2791 if transition.symbols.contains(symbol) {
2792 if chosen.is_some() {
2793 return None;
2794 }
2795 chosen = Some(index);
2796 }
2797 }
2798 chosen
2799}
2800
2801fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
2810 let mut matching_non_nullable_alt = None;
2811 let mut nullable_alt = None;
2812 for (index, transition) in entry.transitions.iter().enumerate() {
2813 if transition.nullable {
2814 if nullable_alt.is_some() {
2815 return None;
2816 }
2817 nullable_alt = Some(index);
2818 }
2819 if transition.symbols.contains(symbol) {
2820 if transition.nullable {
2821 continue;
2822 }
2823 if matching_non_nullable_alt.is_some() {
2824 return None;
2825 }
2826 matching_non_nullable_alt = Some(index);
2827 }
2828 }
2829 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
2830 return None;
2831 }
2832 if non_greedy {
2833 nullable_alt.or(matching_non_nullable_alt)
2834 } else {
2835 matching_non_nullable_alt.or(nullable_alt)
2836 }
2837}
2838
2839fn should_skip_via_lookahead(
2840 transition_kind: ParserTransitionKind,
2841 transition_index: usize,
2842 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
2843 index: usize,
2844 record_expected: bool,
2845 expected: &mut ExpectedTokens,
2846) -> bool {
2847 let prune_non_consuming = matches!(
2848 transition_kind,
2849 ParserTransitionKind::Epsilon
2850 | ParserTransitionKind::Action
2851 | ParserTransitionKind::Predicate
2852 | ParserTransitionKind::Rule
2853 | ParserTransitionKind::Precedence
2854 );
2855 if !prune_non_consuming {
2856 return false;
2857 }
2858 let Some((symbol, entry)) = lookahead_filter else {
2859 return false;
2860 };
2861 let Some(set) = entry.transitions.get(transition_index) else {
2862 return false;
2863 };
2864 if set.symbols.contains(*symbol) || set.nullable {
2865 return false;
2866 }
2867 if record_expected && !set.symbols.is_empty() {
2868 record_pruned_transition_expected(set, index, expected);
2869 }
2870 true
2871}
2872
2873fn should_skip_rule_via_first_set(
2874 first: &FirstSet,
2875 symbol: i32,
2876 record_expected: bool,
2877 index: usize,
2878 expected: &mut ExpectedTokens,
2879) -> bool {
2880 if first.nullable || first.symbols.contains(symbol) {
2881 return false;
2882 }
2883 if record_expected && !first.symbols.is_empty() {
2884 record_token_bit_expected(&first.symbols, index, expected);
2885 }
2886 true
2887}
2888
2889fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
2890 match expected.index {
2891 Some(current) if index < current => {}
2892 Some(current) if index == current => {
2893 symbols.extend_btree_set(&mut expected.symbols);
2894 }
2895 _ => {
2896 expected.index = Some(index);
2897 expected.symbols = symbols.to_btree_set();
2898 }
2899 }
2900}
2901
2902fn record_pruned_transition_expected(
2904 set: &TransitionLookSet,
2905 index: usize,
2906 expected: &mut ExpectedTokens,
2907) {
2908 match expected.index {
2909 Some(current) if index < current => {}
2910 Some(current) if index == current => {
2911 set.symbols.extend_btree_set(&mut expected.symbols);
2912 }
2913 _ => {
2914 expected.index = Some(index);
2915 expected.symbols = set.symbols.to_btree_set();
2916 }
2917 }
2918}
2919
2920fn rule_first_set_inner(
2921 atn: &Atn,
2922 state_number: usize,
2923 rule_stop_state: usize,
2924 ctx: &mut FirstSetCtx<'_>,
2925 visited: &mut BTreeSet<usize>,
2926 first: &mut FirstSet,
2927) {
2928 if !visited.insert(state_number) {
2929 return;
2930 }
2931 if state_number == rule_stop_state {
2932 first.nullable = true;
2933 return;
2934 }
2935 let Some(state) = atn.state(state_number) else {
2936 return;
2937 };
2938 for transition in &state.transitions() {
2939 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2940 if !transition_symbols.is_empty() {
2941 first.symbols.extend_iter(transition_symbols);
2942 continue;
2943 }
2944 match &transition.data() {
2945 Transition::Epsilon { target }
2946 | Transition::Action { target, .. }
2947 | Transition::Predicate { target, .. }
2948 | Transition::Precedence { target, .. } => {
2949 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
2950 }
2951 Transition::Rule {
2952 target,
2953 rule_index,
2954 follow_state,
2955 ..
2956 } => {
2957 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2958 continue;
2959 };
2960 let child_key = (*target, child_stop);
2961 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
2962 ctx.hit_cycle = true;
2963 }
2964 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
2965 first.symbols.extend_from(&child.symbols);
2966 if child.nullable {
2967 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
2968 }
2969 }
2970 Transition::Atom { .. }
2971 | Transition::Range { .. }
2972 | Transition::Set { .. }
2973 | Transition::NotSet { .. }
2974 | Transition::Wildcard { .. } => {}
2975 }
2976 }
2977}
2978
2979fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
2982 let mut symbols = BTreeSet::new();
2983 state_sync_symbols_inner(
2984 atn,
2985 state_number,
2986 stop_state,
2987 &mut BTreeSet::new(),
2988 &mut symbols,
2989 );
2990 symbols
2991}
2992
2993fn state_sync_symbols_inner(
2996 atn: &Atn,
2997 state_number: usize,
2998 stop_state: usize,
2999 visited: &mut BTreeSet<usize>,
3000 symbols: &mut BTreeSet<i32>,
3001) {
3002 if !visited.insert(state_number) {
3003 return;
3004 }
3005 if state_number == stop_state {
3006 symbols.insert(TOKEN_EOF);
3007 return;
3008 }
3009 let Some(state) = atn.state(state_number) else {
3010 return;
3011 };
3012 for transition in &state.transitions() {
3013 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3014 if transition_symbols.is_empty() {
3015 match &transition.data() {
3016 Transition::Rule { target, .. }
3017 | Transition::Epsilon { target }
3018 | Transition::Action { target, .. }
3019 | Transition::Predicate { target, .. }
3020 | Transition::Precedence { target, .. } => {
3021 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
3022 }
3023 Transition::Atom { .. }
3024 | Transition::Range { .. }
3025 | Transition::Set { .. }
3026 | Transition::NotSet { .. }
3027 | Transition::Wildcard { .. } => {}
3028 }
3029 } else {
3030 symbols.extend(transition_symbols);
3031 }
3032 }
3033}
3034
3035#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
3036struct OperatorSymbolReachability {
3037 single_token: bool,
3039 multi_token: bool,
3041 predicate_dependent: bool,
3043}
3044
3045impl OperatorSymbolReachability {
3046 const ADAPTIVE_FALLBACK: Self = Self {
3047 single_token: false,
3048 multi_token: false,
3049 predicate_dependent: true,
3050 };
3051
3052 const fn single_token(predicate_dependent: bool) -> Self {
3053 if predicate_dependent {
3054 Self {
3055 single_token: false,
3056 multi_token: false,
3057 predicate_dependent: true,
3058 }
3059 } else {
3060 Self {
3061 single_token: true,
3062 multi_token: false,
3063 predicate_dependent: false,
3064 }
3065 }
3066 }
3067
3068 const fn multi_token(predicate_dependent: bool) -> Self {
3069 if predicate_dependent {
3070 Self {
3071 single_token: false,
3072 multi_token: false,
3073 predicate_dependent: true,
3074 }
3075 } else {
3076 Self {
3077 single_token: false,
3078 multi_token: true,
3079 predicate_dependent: false,
3080 }
3081 }
3082 }
3083
3084 const fn union(self, other: Self) -> Self {
3085 Self {
3086 single_token: self.single_token || other.single_token,
3087 multi_token: self.multi_token || other.multi_token,
3088 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
3089 }
3090 }
3091}
3092
3093#[derive(Clone, Copy)]
3094struct OperatorReachabilityRequest {
3095 symbol: i32,
3096 precedence: i32,
3097 predicate_dependent: bool,
3098 operator_rule_index: usize,
3099}
3100
3101#[derive(Clone, Copy, Debug)]
3102struct OperatorRuleContinuation {
3103 stop_state: usize,
3104 follow_state: usize,
3105 return_precedence: i32,
3106}
3107
3108struct NullablePrecedenceCtx {
3109 cache: FxHashMap<(usize, usize, i32, bool), bool>,
3110 in_progress: BTreeSet<(usize, usize, i32, bool)>,
3111 hit_cycle: bool,
3112}
3113
3114fn state_is_nullable_with_precedence(
3115 atn: &Atn,
3116 state_number: usize,
3117 stop_state_number: usize,
3118 precedence: i32,
3119 allow_predicates: bool,
3120 ctx: &mut NullablePrecedenceCtx,
3121) -> bool {
3122 let saved_hit_cycle = ctx.hit_cycle;
3123 ctx.hit_cycle = false;
3124 let nullable = state_is_nullable_with_precedence_cached(
3125 atn,
3126 state_number,
3127 stop_state_number,
3128 precedence,
3129 allow_predicates,
3130 ctx,
3131 );
3132 ctx.hit_cycle = saved_hit_cycle;
3133 nullable
3134}
3135
3136fn state_is_nullable_with_precedence_cached(
3137 atn: &Atn,
3138 state_number: usize,
3139 stop_state_number: usize,
3140 precedence: i32,
3141 allow_predicates: bool,
3142 ctx: &mut NullablePrecedenceCtx,
3143) -> bool {
3144 if state_number == stop_state_number {
3145 return true;
3146 }
3147 let key = (
3148 state_number,
3149 stop_state_number,
3150 precedence,
3151 allow_predicates,
3152 );
3153 if let Some(cached) = ctx.cache.get(&key) {
3154 return *cached;
3155 }
3156 if !ctx.in_progress.insert(key) {
3157 ctx.hit_cycle = true;
3158 return false;
3159 }
3160 let saved_hit_cycle = ctx.hit_cycle;
3161 ctx.hit_cycle = false;
3162 let nullable = atn.state(state_number).is_some_and(|state| {
3163 state
3164 .transitions()
3165 .iter()
3166 .any(|transition| match &transition.data() {
3167 Transition::Rule {
3168 target,
3169 rule_index,
3170 follow_state,
3171 precedence: rule_precedence,
3172 } => {
3173 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3174 return false;
3175 };
3176 state_is_nullable_with_precedence_cached(
3177 atn,
3178 *target,
3179 child_stop,
3180 *rule_precedence,
3181 allow_predicates,
3182 ctx,
3183 ) && state_is_nullable_with_precedence_cached(
3184 atn,
3185 *follow_state,
3186 stop_state_number,
3187 precedence,
3188 allow_predicates,
3189 ctx,
3190 )
3191 }
3192 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3193 state_is_nullable_with_precedence_cached(
3194 atn,
3195 *target,
3196 stop_state_number,
3197 precedence,
3198 allow_predicates,
3199 ctx,
3200 )
3201 }
3202 Transition::Predicate { target, .. } if allow_predicates => {
3203 state_is_nullable_with_precedence_cached(
3204 atn,
3205 *target,
3206 stop_state_number,
3207 precedence,
3208 allow_predicates,
3209 ctx,
3210 )
3211 }
3212 Transition::Precedence {
3213 target,
3214 precedence: transition_precedence,
3215 } if *transition_precedence >= precedence => {
3216 state_is_nullable_with_precedence_cached(
3217 atn,
3218 *target,
3219 stop_state_number,
3220 precedence,
3221 allow_predicates,
3222 ctx,
3223 )
3224 }
3225 Transition::Atom { .. }
3226 | Transition::Range { .. }
3227 | Transition::Set { .. }
3228 | Transition::NotSet { .. }
3229 | Transition::Wildcard { .. }
3230 | Transition::Predicate { .. }
3231 | Transition::Precedence { .. } => false,
3232 })
3233 });
3234 ctx.in_progress.remove(&key);
3235 if !ctx.hit_cycle {
3236 ctx.cache.insert(key, nullable);
3237 }
3238 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3239 nullable
3240}
3241
3242fn state_operator_token_prefix_reachability(
3244 atn: &Atn,
3245 state_number: usize,
3246 request: OperatorReachabilityRequest,
3247 continuations: &[OperatorRuleContinuation],
3248 visited: &mut BTreeSet<(usize, i32, bool)>,
3249) -> OperatorSymbolReachability {
3250 let key = (
3251 state_number,
3252 request.precedence,
3253 request.predicate_dependent,
3254 );
3255 if !visited.insert(key) {
3256 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3260 }
3261 if let Some((continuation, remaining)) = continuations.split_last()
3262 && state_number == continuation.stop_state
3263 {
3264 let result = state_operator_token_prefix_reachability(
3265 atn,
3266 continuation.follow_state,
3267 OperatorReachabilityRequest {
3268 precedence: continuation.return_precedence,
3269 ..request
3270 },
3271 remaining,
3272 visited,
3273 );
3274 visited.remove(&key);
3275 return result;
3276 }
3277 let Some(state) = atn.state(state_number) else {
3278 visited.remove(&key);
3279 return OperatorSymbolReachability::default();
3280 };
3281 let completes_operator = match state.kind() {
3282 AtnStateKind::RuleStop => continuations.is_empty(),
3283 AtnStateKind::StarLoopBack
3284 | AtnStateKind::StarLoopEntry
3285 | AtnStateKind::PlusLoopBack
3286 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3287 _ => false,
3288 };
3289 if completes_operator {
3290 visited.remove(&key);
3291 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3292 }
3293 let mut reachability = OperatorSymbolReachability::default();
3294 for transition in &state.transitions() {
3295 let transition_reachability = match &transition.data() {
3296 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3297 OperatorSymbolReachability::single_token(request.predicate_dependent)
3298 }
3299 Transition::Rule {
3300 target,
3301 rule_index,
3302 follow_state,
3303 precedence: rule_precedence,
3304 } => {
3305 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3306 continue;
3307 };
3308 let mut nested = continuations.to_vec();
3309 nested.push(OperatorRuleContinuation {
3310 stop_state: child_stop,
3311 follow_state: *follow_state,
3312 return_precedence: request.precedence,
3313 });
3314 state_operator_token_prefix_reachability(
3315 atn,
3316 *target,
3317 OperatorReachabilityRequest {
3318 precedence: *rule_precedence,
3319 ..request
3320 },
3321 &nested,
3322 visited,
3323 )
3324 }
3325 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3326 state_operator_token_prefix_reachability(
3327 atn,
3328 *target,
3329 request,
3330 continuations,
3331 visited,
3332 )
3333 }
3334 Transition::Precedence {
3335 target,
3336 precedence: transition_precedence,
3337 } => {
3338 if *transition_precedence < request.precedence {
3339 OperatorSymbolReachability::default()
3340 } else {
3341 state_operator_token_prefix_reachability(
3342 atn,
3343 *target,
3344 request,
3345 continuations,
3346 visited,
3347 )
3348 }
3349 }
3350 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3351 atn,
3352 *target,
3353 OperatorReachabilityRequest {
3354 predicate_dependent: true,
3355 ..request
3356 },
3357 continuations,
3358 visited,
3359 ),
3360 Transition::Atom { .. }
3361 | Transition::Range { .. }
3362 | Transition::Set { .. }
3363 | Transition::NotSet { .. }
3364 | Transition::Wildcard { .. } => {
3365 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3366 }
3367 };
3368 reachability = reachability.union(transition_reachability);
3369 }
3370 visited.remove(&key);
3371 reachability
3372}
3373
3374fn state_can_reach_symbol_with_precedence(
3375 atn: &Atn,
3376 state_number: usize,
3377 request: OperatorReachabilityRequest,
3378 nullable_ctx: &mut NullablePrecedenceCtx,
3379 continuations: &mut Vec<OperatorRuleContinuation>,
3380 visited: &mut BTreeSet<(usize, i32, bool)>,
3381) -> OperatorSymbolReachability {
3382 let key = (
3383 state_number,
3384 request.precedence,
3385 request.predicate_dependent,
3386 );
3387 if !visited.insert(key) {
3388 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3389 }
3390 let Some(state) = atn.state(state_number) else {
3391 visited.remove(&key);
3392 return OperatorSymbolReachability::default();
3393 };
3394 let mut reachability = OperatorSymbolReachability::default();
3395 for transition in &state.transitions() {
3396 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3397 reachability = reachability.union(state_operator_token_prefix_reachability(
3398 atn,
3399 transition.target(),
3400 request,
3401 continuations,
3402 &mut BTreeSet::new(),
3403 ));
3404 continue;
3405 }
3406 let transition_reachability = match &transition.data() {
3407 Transition::Rule {
3408 target,
3409 rule_index,
3410 follow_state,
3411 precedence: rule_precedence,
3412 } => {
3413 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3414 continue;
3415 };
3416 continuations.push(OperatorRuleContinuation {
3417 stop_state: child_stop,
3418 follow_state: *follow_state,
3419 return_precedence: request.precedence,
3420 });
3421 let mut result = state_can_reach_symbol_with_precedence(
3422 atn,
3423 *target,
3424 OperatorReachabilityRequest {
3425 precedence: *rule_precedence,
3426 ..request
3427 },
3428 nullable_ctx,
3429 continuations,
3430 visited,
3431 );
3432 continuations.pop();
3433 if state_is_nullable_with_precedence(
3434 atn,
3435 *target,
3436 child_stop,
3437 *rule_precedence,
3438 true,
3439 nullable_ctx,
3440 ) {
3441 let child_predicate_dependent = request.predicate_dependent
3442 || !state_is_nullable_with_precedence(
3443 atn,
3444 *target,
3445 child_stop,
3446 *rule_precedence,
3447 false,
3448 nullable_ctx,
3449 );
3450 result = result.union(state_can_reach_symbol_with_precedence(
3451 atn,
3452 *follow_state,
3453 OperatorReachabilityRequest {
3454 predicate_dependent: child_predicate_dependent,
3455 ..request
3456 },
3457 nullable_ctx,
3458 continuations,
3459 visited,
3460 ));
3461 }
3462 result
3463 }
3464 Transition::Epsilon { target }
3465 | Transition::Action { target, .. }
3466 | Transition::Precedence { target, .. } => {
3467 if matches!(
3468 &transition.data(),
3469 Transition::Precedence {
3470 precedence: transition_precedence,
3471 ..
3472 } if *transition_precedence < request.precedence
3473 ) {
3474 continue;
3475 }
3476 state_can_reach_symbol_with_precedence(
3477 atn,
3478 *target,
3479 request,
3480 nullable_ctx,
3481 continuations,
3482 visited,
3483 )
3484 }
3485 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3486 atn,
3487 *target,
3488 OperatorReachabilityRequest {
3489 predicate_dependent: true,
3490 ..request
3491 },
3492 nullable_ctx,
3493 continuations,
3494 visited,
3495 ),
3496 Transition::Atom { .. }
3497 | Transition::Range { .. }
3498 | Transition::Set { .. }
3499 | Transition::NotSet { .. }
3500 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3501 };
3502 reachability = reachability.union(transition_reachability);
3503 }
3504 visited.remove(&key);
3505 reachability
3506}
3507
3508fn left_recursive_operator_lookahead(
3509 atn: &Atn,
3510 state_number: usize,
3511 precedence: i32,
3512) -> LeftRecursiveOperatorLookahead {
3513 let Some(state) = atn.state(state_number) else {
3514 return LeftRecursiveOperatorLookahead::default();
3515 };
3516 let Some(operator_rule_index) = state.rule_index() else {
3517 return LeftRecursiveOperatorLookahead::default();
3518 };
3519 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3520 let mut nullable_ctx = NullablePrecedenceCtx {
3521 cache: FxHashMap::default(),
3522 in_progress: BTreeSet::new(),
3523 hit_cycle: false,
3524 };
3525 for transition in &state.transitions() {
3526 let target = transition.target();
3527 if atn
3528 .state(target)
3529 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3530 {
3531 continue;
3532 }
3533 for symbol in 1..=atn.max_token_type() {
3534 let reachability = state_can_reach_symbol_with_precedence(
3535 atn,
3536 target,
3537 OperatorReachabilityRequest {
3538 symbol,
3539 precedence,
3540 predicate_dependent: false,
3541 operator_rule_index,
3542 },
3543 &mut nullable_ctx,
3544 &mut Vec::new(),
3545 &mut BTreeSet::new(),
3546 );
3547 if reachability.single_token {
3548 lookahead.single_token.insert(symbol);
3549 }
3550 if reachability.multi_token {
3551 lookahead.multi_token_prefix.insert(symbol);
3552 }
3553 if reachability.predicate_dependent {
3554 lookahead.predicate_dependent.insert(symbol);
3555 }
3556 }
3557 }
3558 lookahead
3559}
3560
3561#[derive(Debug, Default)]
3562struct StateBeforeStopLookahead {
3563 symbols: TokenBitSet,
3564 reaches_context_boundary: bool,
3565}
3566
3567fn state_before_stop_lookahead(
3568 atn: &Atn,
3569 state_number: usize,
3570 stop_state_number: usize,
3571) -> Rc<StateBeforeStopLookahead> {
3572 with_shared_atn_caches(atn, |cache| {
3573 let key = (state_number, stop_state_number);
3574 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
3575 return Rc::clone(cached);
3576 }
3577 let mut lookahead = StateBeforeStopLookahead::default();
3578 state_before_stop_lookahead_inner(
3579 atn,
3580 state_number,
3581 stop_state_number,
3582 &mut BTreeSet::new(),
3583 &mut cache.first_set,
3584 &mut lookahead,
3585 );
3586 let lookahead = Rc::new(lookahead);
3587 cache
3588 .state_before_stop_lookahead
3589 .insert(key, Rc::clone(&lookahead));
3590 lookahead
3591 })
3592}
3593
3594fn state_before_stop_lookahead_inner(
3595 atn: &Atn,
3596 state_number: usize,
3597 stop_state_number: usize,
3598 visited: &mut BTreeSet<usize>,
3599 first_set_cache: &mut FirstSetCache,
3600 lookahead: &mut StateBeforeStopLookahead,
3601) {
3602 if state_number == stop_state_number {
3603 lookahead.reaches_context_boundary = true;
3604 return;
3605 }
3606 if !visited.insert(state_number) {
3607 return;
3608 }
3609 let Some(state) = atn.state(state_number) else {
3610 return;
3611 };
3612 if state.kind() == AtnStateKind::RuleStop {
3613 lookahead.reaches_context_boundary = true;
3614 return;
3615 }
3616 for transition in &state.transitions() {
3617 match &transition.data() {
3618 Transition::Epsilon { target }
3619 | Transition::Action { target, .. }
3620 | Transition::Predicate { target, .. }
3621 | Transition::Precedence { target, .. } => {
3622 state_before_stop_lookahead_inner(
3623 atn,
3624 *target,
3625 stop_state_number,
3626 visited,
3627 first_set_cache,
3628 lookahead,
3629 );
3630 }
3631 Transition::Rule {
3632 target,
3633 rule_index,
3634 follow_state,
3635 ..
3636 } => {
3637 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3638 continue;
3639 };
3640 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
3641 lookahead.symbols.extend_from(&child.symbols);
3642 if child.nullable {
3643 state_before_stop_lookahead_inner(
3644 atn,
3645 *follow_state,
3646 stop_state_number,
3647 visited,
3648 first_set_cache,
3649 lookahead,
3650 );
3651 }
3652 }
3653 Transition::Atom { .. }
3654 | Transition::Range { .. }
3655 | Transition::Set { .. }
3656 | Transition::NotSet { .. }
3657 | Transition::Wildcard { .. } => {
3658 lookahead.symbols.extend_iter(transition_expected_symbols(
3659 transition,
3660 atn.max_token_type(),
3661 ));
3662 }
3663 }
3664 }
3665}
3666
3667fn caller_context_can_match_symbol_before_state(
3668 atn: &Atn,
3669 return_states: impl DoubleEndedIterator<Item = usize>,
3670 stop_state_number: usize,
3671 symbol: i32,
3672) -> bool {
3673 for return_state in return_states.rev() {
3674 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
3675 if lookahead.symbols.contains(symbol) {
3676 return true;
3677 }
3678 if !lookahead.reaches_context_boundary {
3679 return false;
3680 }
3681 }
3682 false
3683}
3684
3685fn next_recovery_context(
3689 atn: &Atn,
3690 state: AtnState<'_>,
3691 inherited: &BTreeSet<i32>,
3692 inherited_state: Option<usize>,
3693) -> (BTreeSet<i32>, Option<usize>) {
3694 let state_symbols = state_expected_symbols(atn, state.state_number());
3695 if state.transitions().len() > 1 && !state_symbols.is_empty() {
3696 let mut symbols = state_symbols;
3697 symbols.extend(inherited.iter().copied());
3698 return (symbols, Some(state.state_number()));
3699 }
3700 (inherited.clone(), inherited_state)
3701}
3702
3703fn recovery_expected_symbols(
3704 atn: &Atn,
3705 state_number: usize,
3706 inherited: &BTreeSet<i32>,
3707) -> BTreeSet<i32> {
3708 let mut symbols = state_expected_symbols(atn, state_number);
3709 symbols.extend(inherited.iter().copied());
3710 symbols
3711}
3712
3713fn fast_next_recovery_context<S, H>(
3717 parser: &mut BaseParser<S, H>,
3718 atn: &Atn,
3719 state: AtnState<'_>,
3720 inherited: &Rc<BTreeSet<i32>>,
3721 inherited_state: Option<usize>,
3722) -> (Rc<BTreeSet<i32>>, Option<usize>)
3723where
3724 S: TokenSource,
3725 H: SemanticHooks,
3726{
3727 if state.transitions().len() <= 1 {
3728 return (Rc::clone(inherited), inherited_state);
3729 }
3730 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
3731 if state_symbols.is_empty() {
3732 return (Rc::clone(inherited), inherited_state);
3733 }
3734 if inherited.is_empty() {
3735 return (state_symbols, Some(state.state_number()));
3736 }
3737 if Rc::ptr_eq(&state_symbols, inherited) {
3738 return (state_symbols, Some(state.state_number()));
3739 }
3740 let mut combined = (*state_symbols).clone();
3741 combined.extend(inherited.iter().copied());
3742 (
3743 parser.intern_recovery_symbols(combined),
3744 Some(state.state_number()),
3745 )
3746}
3747
3748fn fast_recovery_expected_symbols<S, H>(
3752 parser: &mut BaseParser<S, H>,
3753 atn: &Atn,
3754 state_number: usize,
3755 inherited: &Rc<BTreeSet<i32>>,
3756) -> Rc<BTreeSet<i32>>
3757where
3758 S: TokenSource,
3759 H: SemanticHooks,
3760{
3761 let cached = parser.cached_state_expected_symbols(atn, state_number);
3762 if inherited.is_empty() {
3763 return cached;
3764 }
3765 if cached.is_empty() {
3766 return Rc::clone(inherited);
3767 }
3768 if Rc::ptr_eq(&cached, inherited) {
3769 return cached;
3770 }
3771 let mut combined = (*cached).clone();
3772 combined.extend(inherited.iter().copied());
3773 parser.intern_recovery_symbols(combined)
3774}
3775
3776struct ParserTableSemCtx<'a> {
3777 member_values: &'a mut BTreeMap<usize, i64>,
3778 return_values: &'a mut BTreeMap<String, i64>,
3779}
3780
3781impl semir::PredContext for ParserTableSemCtx<'_> {
3782 type TokenText<'a>
3783 = &'a str
3784 where
3785 Self: 'a;
3786
3787 fn la(&mut self, _offset: isize) -> i64 {
3788 i64::from(TOKEN_EOF)
3789 }
3790
3791 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
3792 None
3793 }
3794
3795 fn token_index_adjacent(&mut self) -> bool {
3796 false
3797 }
3798
3799 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
3800 None
3801 }
3802
3803 fn member(&self, member: usize) -> Option<i64> {
3804 Some(self.member_values.get(&member).copied().unwrap_or_default())
3805 }
3806
3807 fn local_arg(&self) -> Option<i64> {
3808 None
3809 }
3810
3811 fn column(&self) -> Option<i64> {
3812 None
3813 }
3814
3815 fn token_start_column(&self) -> Option<i64> {
3816 None
3817 }
3818
3819 fn token_text_so_far(&self) -> Option<String> {
3820 None
3821 }
3822
3823 fn hook(&mut self, _hook: HookId) -> bool {
3824 false
3825 }
3826}
3827
3828impl semir::ActContext for ParserTableSemCtx<'_> {
3829 fn set_member(&mut self, member: usize, value: i64) {
3830 self.member_values.insert(member, value);
3831 }
3832
3833 fn set_return(&mut self, name: &str, value: i64) {
3834 self.return_values.insert(name.to_owned(), value);
3835 }
3836
3837 fn action_hook(&mut self, _hook: HookId) {}
3838}
3839
3840fn apply_member_actions(
3842 source_state: usize,
3843 actions: &[ParserMemberAction],
3844 semantics: Option<&ParserSemantics>,
3845 values: &mut BTreeMap<usize, i64>,
3846) {
3847 for action in actions
3848 .iter()
3849 .filter(|action| action.source_state == source_state)
3850 {
3851 *values.entry(action.member).or_default() += action.delta;
3852 }
3853 let Some(semantics) = semantics else {
3854 return;
3855 };
3856 let mut return_values = BTreeMap::new();
3857 let mut ctx = ParserTableSemCtx {
3858 member_values: values,
3859 return_values: &mut return_values,
3860 };
3861 for action in semantics
3862 .actions
3863 .iter()
3864 .filter(|action| action.source_state == source_state && action.speculative)
3865 {
3866 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3867 }
3868}
3869
3870fn member_values_after_action(
3872 source_state: usize,
3873 actions: &[ParserMemberAction],
3874 semantics: Option<&ParserSemantics>,
3875 values: &BTreeMap<usize, i64>,
3876) -> BTreeMap<usize, i64> {
3877 let mut values = values.clone();
3878 apply_member_actions(source_state, actions, semantics, &mut values);
3879 values
3880}
3881
3882fn return_values_after_action(
3884 source_state: usize,
3885 rule_index: usize,
3886 actions: &[ParserReturnAction],
3887 semantics: Option<&ParserSemantics>,
3888 values: &BTreeMap<String, i64>,
3889) -> BTreeMap<String, i64> {
3890 let mut values = values.clone();
3891 for action in actions
3892 .iter()
3893 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
3894 {
3895 values.insert(action.name.to_owned(), action.value);
3896 }
3897 if let Some(semantics) = semantics {
3898 let mut member_values = BTreeMap::new();
3899 let mut ctx = ParserTableSemCtx {
3900 member_values: &mut member_values,
3901 return_values: &mut values,
3902 };
3903 for action in semantics.actions.iter().filter(|action| {
3904 action.source_state == source_state
3905 && action.rule_index == rule_index
3906 && !action.speculative
3907 }) {
3908 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3909 }
3910 }
3911 values
3912}
3913
3914fn rule_local_int_arg(
3916 rule_args: &[ParserRuleArg],
3917 source_state: usize,
3918 rule_index: usize,
3919 local_int_arg: Option<(usize, i64)>,
3920) -> Option<(usize, i64)> {
3921 rule_args
3922 .iter()
3923 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
3924 .map(|arg| {
3925 let value = if arg.inherit_local {
3926 local_int_arg.map_or(arg.value, |(_, value)| value)
3927 } else {
3928 arg.value
3929 };
3930 (rule_index, value)
3931 })
3932}
3933
3934fn stop_outcome(
3937 index: usize,
3938 consumed_eof: bool,
3939 rule_alt_number: usize,
3940 member_values: BTreeMap<usize, i64>,
3941 return_values: BTreeMap<String, i64>,
3942) -> Vec<RecognizeOutcome> {
3943 vec![RecognizeOutcome {
3944 index,
3945 consumed_eof,
3946 alt_number: rule_alt_number,
3947 member_values,
3948 return_values,
3949 diagnostics: DiagnosticSeqId::EMPTY,
3950 decisions: Vec::new(),
3951 actions: Vec::new(),
3952 nodes: NodeSeqId::EMPTY,
3953 }]
3954}
3955
3956fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
3957 with_shared_atn_caches(atn, |cache| {
3958 *cache.observable_action_transitions.get_or_insert_with(|| {
3959 atn.states().any(|state| {
3960 state.transitions().iter().any(|transition| {
3961 matches!(
3962 &transition.data(),
3963 Transition::Action {
3964 action_index: Some(_),
3965 ..
3966 }
3967 )
3968 })
3969 })
3970 })
3971 })
3972}
3973
3974fn atn_has_predicate_transitions(atn: &Atn) -> bool {
3975 with_shared_atn_caches(atn, |cache| {
3976 *cache.predicate_transitions.get_or_insert_with(|| {
3977 atn.states().any(|state| {
3978 state
3979 .transitions()
3980 .iter()
3981 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
3982 })
3983 })
3984 })
3985}
3986
3987fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
3992 options.init_action_rules.is_empty()
3993 && !options.track_alt_numbers
3994 && options
3995 .predicates
3996 .iter()
3997 .all(|(_, _, predicate)| predicate.failure_message().is_none())
3998 && options.semantics.is_none_or(|semantics| {
3999 semantics.actions.is_empty()
4000 && semantics
4001 .predicates
4002 .iter()
4003 .all(|predicate| predicate.failure_message.is_none())
4004 })
4005 && options.rule_args.is_empty()
4006 && options.member_actions.is_empty()
4007 && options.return_actions.is_empty()
4008 && !atn_has_observable_action_transitions(atn)
4009}
4010
4011#[derive(Clone, Debug, Eq, PartialEq)]
4012struct RecognizeRequest<'a> {
4013 state_number: usize,
4014 stop_state: usize,
4015 index: usize,
4016 rule_start_index: usize,
4017 decision_start_index: Option<usize>,
4018 init_action_rules: &'a BTreeSet<usize>,
4019 predicates: &'a [(usize, usize, ParserPredicate)],
4020 semantics: Option<&'a ParserSemantics>,
4021 rule_args: &'a [ParserRuleArg],
4022 member_actions: &'a [ParserMemberAction],
4023 return_actions: &'a [ParserReturnAction],
4024 local_int_arg: Option<(usize, i64)>,
4025 member_values: BTreeMap<usize, i64>,
4026 return_values: BTreeMap<String, i64>,
4027 rule_alt_number: usize,
4028 track_alt_numbers: bool,
4029 consumed_eof: bool,
4030 committed_decision: bool,
4031 precedence: i32,
4034 depth: usize,
4035 recovery_symbols: BTreeSet<i32>,
4036 recovery_state: Option<usize>,
4037}
4038
4039#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
4040struct RecognizeKey {
4041 state_number: usize,
4042 stop_state: usize,
4043 index: usize,
4044 rule_start_index: usize,
4045 decision_start_index: Option<usize>,
4046 local_int_arg: Option<(usize, i64)>,
4047 member_values: BTreeMap<usize, i64>,
4048 return_values: BTreeMap<String, i64>,
4049 rule_alt_number: usize,
4050 track_alt_numbers: bool,
4051 consumed_eof: bool,
4052 committed_decision: bool,
4053 precedence: i32,
4054 recovery_symbols: BTreeSet<i32>,
4055 recovery_state: Option<usize>,
4056}
4057
4058#[derive(Clone, Debug, Eq, PartialEq)]
4059struct EpsilonActionStep {
4060 source_state: usize,
4061 target: usize,
4062 action_rule_index: Option<usize>,
4063 left_recursive_boundary: Option<usize>,
4064 decision: Option<usize>,
4065 decision_start_index: Option<usize>,
4066 alt_number: usize,
4067 recovery_symbols: BTreeSet<i32>,
4068 recovery_state: Option<usize>,
4069}
4070
4071struct RecognizeScratch<'a> {
4072 visiting: &'a mut BTreeSet<RecognizeKey>,
4073 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4074 expected: &'a mut ExpectedTokens,
4075}
4076
4077#[derive(Clone, Debug, Eq, PartialEq)]
4078struct FastRecognizeRequest {
4079 state_number: usize,
4080 stop_state: usize,
4081 index: usize,
4082 rule_start_index: usize,
4083 decision_start_index: Option<usize>,
4084 precedence: i32,
4085 depth: usize,
4086 recovery_symbols: Rc<BTreeSet<i32>>,
4087 recovery_state: Option<usize>,
4088}
4089
4090#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4091struct FastRecognizeTopRequest {
4092 start_state: usize,
4093 stop_state: usize,
4094 start_index: usize,
4095 precedence: i32,
4096 caller_follow_state: Option<usize>,
4097}
4098
4099#[derive(Clone, Copy, Debug)]
4100struct FastPredicateContext<'a> {
4101 predicates: &'a [(usize, usize, ParserPredicate)],
4102 semantics: Option<&'a ParserSemantics>,
4103 member_values: &'a BTreeMap<usize, i64>,
4104}
4105
4106#[derive(Clone, Copy, Debug, Default)]
4107struct AltNumberTracking {
4108 public: bool,
4109 context: bool,
4110}
4111
4112impl AltNumberTracking {
4113 const fn any(self) -> bool {
4114 self.public || self.context
4115 }
4116}
4117
4118struct FastRecognizeScratch<'a, 'b> {
4119 predicate_context: Option<FastPredicateContext<'a>>,
4120 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4121 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4122 expected: &'b mut ExpectedTokens,
4123 native_depth: usize,
4124}
4125
4126#[derive(Clone, Copy, Debug)]
4127struct FastRepetitionShape {
4128 enter_target: usize,
4129 exit_target: usize,
4130 body_stop_state: usize,
4131 enter_transition_index: usize,
4132 exit_transition_index: usize,
4133}
4134
4135#[derive(Clone, Copy, Debug)]
4136struct FastRepetitionPath {
4137 index: usize,
4138 deferred_nodes: FastDeferredNodeId,
4139 diagnostics: DiagnosticSeqId,
4140 consumed_eof: bool,
4141}
4142
4143enum FastRepetitionWork {
4144 Enter(FastRepetitionPath),
4145 Exit(FastRepetitionPath),
4146}
4147
4148struct FastRepetitionCoordinates {
4153 base_index: usize,
4154 base_state: u8,
4155 later_states: Vec<u8>,
4156}
4157
4158impl FastRepetitionCoordinates {
4159 const ENTERED: u8 = 0;
4160 const EXITED: u8 = 2;
4161
4162 const fn new(base_index: usize) -> Self {
4163 Self {
4164 base_index,
4165 base_state: 0,
4166 later_states: Vec::new(),
4167 }
4168 }
4169
4170 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4171 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4172 }
4173
4174 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4175 self.insert(path.index, path.consumed_eof, Self::EXITED)
4176 }
4177
4178 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4179 let Some(offset) = index.checked_sub(self.base_index) else {
4180 return false;
4181 };
4182 let state = if offset == 0 {
4183 &mut self.base_state
4184 } else {
4185 if self.later_states.len() < offset {
4186 self.later_states.resize(offset, 0);
4187 }
4188 &mut self.later_states[offset - 1]
4189 };
4190 let bit = 1 << (base_bit + u8::from(consumed_eof));
4191 let is_new = *state & bit == 0;
4192 *state |= bit;
4193 is_new
4194 }
4195}
4196
4197fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4198 if state.precedence_rule_decision()
4199 || !matches!(
4200 state.kind(),
4201 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4202 )
4203 || state.transitions().len() != 2
4204 {
4205 return None;
4206 }
4207 let mut enter = None;
4208 let mut exit = None;
4209 for (index, transition) in state.transitions().iter().enumerate() {
4210 if transition.kind() != ParserTransitionKind::Epsilon {
4211 return None;
4212 }
4213 let target = transition.target();
4214 if atn
4215 .state(target)
4216 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4217 {
4218 if exit.replace((index, target)).is_some() {
4219 return None;
4220 }
4221 } else if enter.replace((index, target)).is_some() {
4222 return None;
4223 }
4224 }
4225 let (enter_transition_index, enter_target) = enter?;
4226 let (exit_transition_index, exit_target) = exit?;
4227 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4228 atn.state(exit_target)?.loop_back_state()?
4229 } else {
4230 state.state_number()
4231 };
4232 Some(FastRepetitionShape {
4233 enter_target,
4234 exit_target,
4235 body_stop_state,
4236 enter_transition_index,
4237 exit_transition_index,
4238 })
4239}
4240
4241fn push_fast_repetition_work(
4242 work: &mut Vec<FastRepetitionWork>,
4243 shape: FastRepetitionShape,
4244 path: FastRepetitionPath,
4245 lookahead: Option<&DecisionLookahead>,
4246 symbol: i32,
4247) {
4248 let transition_is_viable = |transition_index: usize| {
4251 let Some(entry) = lookahead else {
4252 return true;
4253 };
4254 let Some(transition) = entry.transitions.get(transition_index) else {
4255 return true;
4256 };
4257 transition.nullable || transition.symbols.contains(symbol)
4258 };
4259 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4260 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4261 if shape.enter_transition_index < shape.exit_transition_index {
4262 if exit_is_viable {
4263 work.push(FastRepetitionWork::Exit(path));
4264 }
4265 if enter_is_viable {
4266 work.push(FastRepetitionWork::Enter(path));
4267 }
4268 } else {
4269 if enter_is_viable {
4270 work.push(FastRepetitionWork::Enter(path));
4271 }
4272 if exit_is_viable {
4273 work.push(FastRepetitionWork::Exit(path));
4274 }
4275 }
4276}
4277
4278#[derive(Clone, Debug)]
4285struct FastRecognizeKey {
4286 state_number: usize,
4287 stop_state: usize,
4288 index: usize,
4289 rule_start_index: usize,
4290 decision_start_index: Option<usize>,
4291 precedence: i32,
4292 recovery_symbols_id: usize,
4293 recovery_state: Option<usize>,
4294}
4295
4296impl PartialEq for FastRecognizeKey {
4297 fn eq(&self, other: &Self) -> bool {
4298 if self.state_number != other.state_number
4299 || self.stop_state != other.stop_state
4300 || self.index != other.index
4301 || self.rule_start_index != other.rule_start_index
4302 || self.decision_start_index != other.decision_start_index
4303 || self.precedence != other.precedence
4304 || self.recovery_state != other.recovery_state
4305 || self.recovery_symbols_id != other.recovery_symbols_id
4306 {
4307 return false;
4308 }
4309 true
4310 }
4311}
4312
4313impl Eq for FastRecognizeKey {}
4314
4315impl Hash for FastRecognizeKey {
4316 fn hash<H: Hasher>(&self, hasher: &mut H) {
4317 self.state_number.hash(hasher);
4318 self.stop_state.hash(hasher);
4319 self.index.hash(hasher);
4320 self.rule_start_index.hash(hasher);
4321 self.decision_start_index.hash(hasher);
4322 self.precedence.hash(hasher);
4323 self.recovery_state.hash(hasher);
4324 self.recovery_symbols_id.hash(hasher);
4325 }
4326}
4327
4328struct FastRecoveryRequest<'a, 'b> {
4329 atn: &'a Atn,
4330 transition: ParserTransition<'a>,
4331 expected_symbols: Rc<BTreeSet<i32>>,
4332 target: usize,
4333 request: FastRecognizeRequest,
4334 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4335 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4336 expected: &'b mut ExpectedTokens,
4337}
4338
4339struct FastCurrentTokenDeletionRequest<'a, 'b> {
4340 atn: &'a Atn,
4341 expected_symbols: Rc<BTreeSet<i32>>,
4342 request: FastRecognizeRequest,
4343 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4344 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4345 expected: &'b mut ExpectedTokens,
4346}
4347
4348#[derive(Clone, Copy)]
4349struct FastChildRuleFailureRecoveryRequest<'a> {
4350 atn: &'a Atn,
4351 rule_index: usize,
4352 start_index: usize,
4353 follow_state: usize,
4354 stop_state: usize,
4355 expected: &'a ExpectedTokens,
4356}
4357
4358struct RecoveryRequest<'a, 'b> {
4359 atn: &'a Atn,
4360 transition: ParserTransition<'a>,
4361 expected_symbols: BTreeSet<i32>,
4362 target: usize,
4363 request: RecognizeRequest<'a>,
4364 visiting: &'b mut BTreeSet<RecognizeKey>,
4365 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4366 expected: &'b mut ExpectedTokens,
4367}
4368
4369struct CurrentTokenDeletionRequest<'a, 'b> {
4370 atn: &'a Atn,
4371 expected_symbols: BTreeSet<i32>,
4372 request: RecognizeRequest<'a>,
4373 visiting: &'b mut BTreeSet<RecognizeKey>,
4374 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4375 expected: &'b mut ExpectedTokens,
4376}
4377
4378struct ConsumingFailureFallback<'a> {
4381 atn: &'a Atn,
4382 target: usize,
4383 request: RecognizeRequest<'a>,
4384 symbol: i32,
4385 expected_symbols: BTreeSet<i32>,
4386 decision_start_index: Option<usize>,
4387 decision: Option<usize>,
4388}
4389
4390struct ChildRuleFailureRecovery<'a> {
4393 atn: &'a Atn,
4394 rule_index: usize,
4395 start_index: usize,
4396 follow_state: usize,
4397 stop_state: usize,
4398 member_values: BTreeMap<usize, i64>,
4399 expected: &'a ExpectedTokens,
4400}
4401
4402#[derive(Clone, Copy, Debug)]
4404struct PredicateEval<'a> {
4405 index: usize,
4406 rule_index: usize,
4407 pred_index: usize,
4408 predicates: &'a [(usize, usize, ParserPredicate)],
4409 semantics: Option<&'a ParserSemantics>,
4410 context: Option<&'a ParserRuleContext>,
4411 local_int_arg: Option<(usize, i64)>,
4412 member_values: &'a BTreeMap<usize, i64>,
4413}
4414
4415#[derive(Clone, Copy, Debug)]
4416struct ParserSemanticHookRequest<'a> {
4417 index: usize,
4418 rule_index: usize,
4419 pred_index: usize,
4420 context: Option<&'a ParserRuleContext>,
4421 local_int_arg: Option<(usize, i64)>,
4422 member_values: &'a BTreeMap<usize, i64>,
4423}
4424
4425struct ParserSemIrCtx<'a, S, H>
4434where
4435 S: TokenSource,
4436 H: SemanticHooks,
4437{
4438 input: &'a mut CommonTokenStream<S>,
4439 tree_storage: &'a ParseTreeStorage,
4440 semantic_hooks: &'a mut H,
4441 rule_index: usize,
4442 coordinate_index: usize,
4443 rule_name: Option<&'a str>,
4444 context: Option<&'a ParserRuleContext>,
4445 local_int_arg: Option<(usize, i64)>,
4446 member_values: &'a BTreeMap<usize, i64>,
4447 invoked_predicates: &'a mut Vec<(usize, usize)>,
4448 unknown_predicate_policy: UnknownSemanticPolicy,
4452 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4453}
4454
4455impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4456where
4457 S: TokenSource,
4458 H: SemanticHooks,
4459{
4460 type TokenText<'a>
4461 = TokenView<'a>
4462 where
4463 Self: 'a;
4464
4465 fn la(&mut self, offset: isize) -> i64 {
4466 i64::from(self.input.la(offset))
4467 }
4468
4469 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4470 self.input.lt(offset)
4471 }
4472
4473 fn token_index_adjacent(&mut self) -> bool {
4474 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4475 return false;
4476 };
4477 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4478 return false;
4479 };
4480 first + 1 == second
4481 }
4482
4483 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4484 self.context.and_then(|context| {
4485 context
4486 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4487 .next()
4488 .map(crate::tree::RuleNodeView::text)
4489 })
4490 }
4491
4492 fn member(&self, member: usize) -> Option<i64> {
4493 Some(self.member_values.get(&member).copied().unwrap_or_default())
4494 }
4495
4496 fn local_arg(&self) -> Option<i64> {
4497 self.local_int_arg.map(|(_, value)| value)
4498 }
4499
4500 fn column(&self) -> Option<i64> {
4501 None
4502 }
4503
4504 fn token_start_column(&self) -> Option<i64> {
4505 None
4506 }
4507
4508 fn token_text_so_far(&self) -> Option<String> {
4509 None
4510 }
4511
4512 fn hook(&mut self, _hook: HookId) -> bool {
4513 let mut ctx = ParserSemCtx {
4514 input: &mut *self.input,
4515 tree_storage: self.tree_storage,
4516 rule_index: self.rule_index,
4517 coordinate_index: self.coordinate_index,
4518 rule_name: self.rule_name.map(str::to_owned),
4519 context: self.context,
4520 tree: None,
4521 local_int_arg: self.local_int_arg,
4522 member_values: self.member_values,
4523 action: None,
4524 };
4525 match self
4526 .semantic_hooks
4527 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4528 {
4529 Some(result) => result,
4530 None => apply_unknown_predicate_policy(
4534 self.unknown_predicate_policy,
4535 self.rule_index,
4536 self.coordinate_index,
4537 self.unknown_predicate_hits,
4538 ),
4539 }
4540 }
4541
4542 fn trace_bool(&mut self, value: bool) -> bool {
4543 let key = (self.rule_index, self.coordinate_index);
4544 if !self.invoked_predicates.contains(&key) {
4545 self.invoked_predicates.push(key);
4546 use std::io::Write as _;
4547 let mut stdout = std::io::stdout().lock();
4548 let _ = writeln!(stdout, "eval={value}");
4549 }
4550 value
4551 }
4552}
4553
4554struct PredicateFailureRecovery<'a> {
4556 rule_index: usize,
4557 index: usize,
4558 message: &'a str,
4559 member_values: BTreeMap<usize, i64>,
4560 return_values: BTreeMap<String, i64>,
4561 rule_alt_number: usize,
4562}
4563
4564#[derive(Debug)]
4565enum DirectAdaptiveParseControl {
4566 Fallback(DirectAdaptiveFallback),
4567}
4568
4569#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4570enum DirectAdaptiveFallback {
4571 Action,
4572 InvalidAlt,
4573 LeftRecursiveBoundary,
4574 MissingAtn,
4575 NoTransition,
4576 Predicate,
4577 Prediction,
4578 Precedence,
4579 RuleStop,
4580 SemanticContext,
4581 StepLimit,
4582 TokenMismatch,
4583 UnknownDecision,
4584}
4585
4586type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
4587
4588struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
4589where
4590 S: TokenSource,
4591 H: SemanticHooks,
4592{
4593 parser: &'sim mut BaseParser<S, H>,
4594 atn: &'atn Atn,
4595 simulator: &'sim mut ParserAtnSimulator<'atn>,
4596 decision_by_state: Vec<Option<usize>>,
4597 steps: usize,
4598}
4599
4600#[derive(Clone, Debug, Eq, PartialEq)]
4610pub struct GeneratedMatch {
4611 children: GeneratedMatchChildren,
4612 consumed_eof: bool,
4613}
4614
4615#[derive(Clone, Copy)]
4616enum GeneratedExpectedSymbols<'a> {
4617 Tree(&'a BTreeSet<i32>),
4618 TokenSet(ParserIntervalSet<'a>),
4619 TokenSetComplement {
4620 set: ParserIntervalSet<'a>,
4621 min_vocabulary: i32,
4622 max_vocabulary: i32,
4623 },
4624}
4625
4626impl GeneratedExpectedSymbols<'_> {
4627 fn is_empty(self) -> bool {
4628 match self {
4629 Self::Tree(symbols) => symbols.is_empty(),
4630 Self::TokenSet(set) => set.is_empty(),
4631 Self::TokenSetComplement {
4632 set,
4633 min_vocabulary,
4634 max_vocabulary,
4635 } => (min_vocabulary..=max_vocabulary).all(|symbol| set.contains(symbol)),
4636 }
4637 }
4638
4639 fn first(self) -> Option<i32> {
4640 match self {
4641 Self::Tree(symbols) => symbols.iter().next().copied(),
4642 Self::TokenSet(set) => set.ranges().next().map(|(start, _)| start),
4643 Self::TokenSetComplement {
4644 set,
4645 min_vocabulary,
4646 max_vocabulary,
4647 } => (min_vocabulary..=max_vocabulary).find(|symbol| !set.contains(*symbol)),
4648 }
4649 }
4650
4651 fn display(self, vocabulary: &Vocabulary) -> String {
4652 match self {
4653 Self::Tree(symbols) => expected_symbols_display(symbols, vocabulary),
4654 Self::TokenSet(set) => expected_symbols_display_iter(
4655 set.ranges().flat_map(|(start, stop)| start..=stop),
4656 vocabulary,
4657 ),
4658 Self::TokenSetComplement {
4659 set,
4660 min_vocabulary,
4661 max_vocabulary,
4662 } => expected_symbols_display_iter(
4663 (min_vocabulary..=max_vocabulary).filter(|symbol| !set.contains(*symbol)),
4664 vocabulary,
4665 ),
4666 }
4667 }
4668}
4669
4670#[derive(Clone, Debug, Eq, PartialEq)]
4671enum GeneratedMatchChildren {
4672 One(ParseTree),
4673 Many(Vec<ParseTree>),
4674}
4675
4676struct GeneratedMatchChildrenIntoIter {
4677 one: Option<ParseTree>,
4678 many: Option<std::vec::IntoIter<ParseTree>>,
4679}
4680
4681impl Iterator for GeneratedMatchChildrenIntoIter {
4682 type Item = ParseTree;
4683
4684 fn next(&mut self) -> Option<Self::Item> {
4685 self.one
4686 .take()
4687 .or_else(|| self.many.as_mut().and_then(Iterator::next))
4688 }
4689}
4690
4691impl GeneratedMatch {
4692 #[must_use]
4696 pub fn children(&self) -> &[ParseTree] {
4697 match &self.children {
4698 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
4699 GeneratedMatchChildren::Many(children) => children,
4700 }
4701 }
4702
4703 #[must_use]
4706 pub fn into_children(self) -> Vec<ParseTree> {
4707 match self.children {
4708 GeneratedMatchChildren::One(child) => vec![child],
4709 GeneratedMatchChildren::Many(children) => children,
4710 }
4711 }
4712
4713 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
4715 match self.children {
4716 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
4717 one: Some(child),
4718 many: None,
4719 },
4720 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
4721 one: None,
4722 many: Some(children.into_iter()),
4723 },
4724 }
4725 }
4726
4727 #[must_use]
4729 pub const fn consumed_eof(&self) -> bool {
4730 self.consumed_eof
4731 }
4732}
4733
4734impl<S> BaseParser<S, NoSemanticHooks>
4735where
4736 S: TokenSource,
4737{
4738 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
4741 Self::with_semantic_hooks(input, data, NoSemanticHooks)
4742 }
4743}
4744
4745impl<S, H> BaseParser<S, H>
4746where
4747 S: TokenSource,
4748 H: SemanticHooks,
4749{
4750 pub fn with_semantic_hooks(
4752 input: CommonTokenStream<S>,
4753 data: RecognizerData,
4754 semantic_hooks: H,
4755 ) -> Self {
4756 Self {
4757 input,
4758 tree: ParseTreeStorage::new(),
4759 data,
4760 semantic_hooks,
4761 decision_override_generation: 0,
4762 build_parse_trees: true,
4763 syntax_errors: 0,
4764 report_diagnostic_errors: false,
4765 prediction_mode: PredictionMode::Ll,
4766 prediction_diagnostics: Vec::new(),
4767 reported_prediction_diagnostics: BTreeSet::new(),
4768 generated_parser_diagnostics: Vec::new(),
4769 generated_sync_expected: None,
4770 generated_recovery_error_index: None,
4771 generated_recovery_error_states: BTreeSet::new(),
4772 int_members: BTreeMap::new(),
4773 rule_context_stack: Vec::new(),
4774 rule_context_version: 0,
4775 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
4776 pending_invoking_states: Vec::new(),
4777 precedence_stack: vec![0],
4778 invoked_predicates: Vec::new(),
4779 bail_on_error: false,
4780 unknown_predicate_policy: UnknownSemanticPolicy::default(),
4781 unknown_predicate_hits: Vec::new(),
4782 unhandled_action_hits: Vec::new(),
4783 rule_first_set_cache: Vec::new(),
4784 state_expected_cache: FxHashMap::default(),
4785 state_expected_token_cache: FxHashMap::default(),
4786 rule_stop_reach_cache: Vec::new(),
4787 recovery_symbols_intern: FxHashMap::default(),
4788 decision_lookahead_cache: FxHashMap::default(),
4789 ll1_decision_cache: FxHashMap::default(),
4790 fast_predicate_cache: FxHashMap::default(),
4791 empty_cycle_cache: Vec::new(),
4792 empty_cycle_cache_atn: None,
4793 clean_memo_mode: CleanMemoMode::Probe,
4794 clean_memo_probe_seen: FxHashSet::default(),
4795 clean_memo_probe_samples: 0,
4796 clean_memo_probe_repeats: 0,
4797 clean_memo_sparse_samples: 0,
4798 fast_recognize_scratch: FastRecognizeTopScratch::default(),
4799 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
4800 empty_recovery_symbols: Rc::new(BTreeSet::new()),
4801 fast_first_set_prefilter: true,
4802 fast_recovery_enabled: true,
4803 fast_token_nodes_enabled: true,
4804 fast_track_alt_numbers: false,
4805 recognition_arena: RecognitionArena::default(),
4806 last_recognition_arena_root: NodeSeqId::EMPTY,
4807 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
4808 }
4809 }
4810
4811 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
4812 &mut self.input
4813 }
4814
4815 pub fn reset(&mut self) {
4820 self.input.seek(0);
4821 self.tree.reset();
4822 self.data.set_state(-1);
4823 self.syntax_errors = 0;
4824 self.prediction_diagnostics.clear();
4825 self.reported_prediction_diagnostics.clear();
4826 self.generated_parser_diagnostics.clear();
4827 self.generated_sync_expected = None;
4828 self.reset_generated_recovery_state();
4829 self.rule_context_stack.clear();
4830 self.advance_rule_context_version();
4831 self.left_recursive_caller_overlap_cache = std::array::from_fn(|_| None);
4832 self.pending_invoking_states.clear();
4833 self.precedence_stack.clear();
4834 self.precedence_stack.push(0);
4835 self.invoked_predicates.clear();
4836 self.decision_override_generation = 0;
4837 self.unknown_predicate_hits.clear();
4838 self.unhandled_action_hits.clear();
4839 self.reset_per_parse_caches();
4840 self.fast_first_set_prefilter = true;
4841 self.fast_recovery_enabled = true;
4842 self.fast_token_nodes_enabled = self.build_parse_trees;
4843 self.fast_track_alt_numbers = false;
4844 self.reset_recognition_arena();
4845 }
4846
4847 pub fn set_token_stream(&mut self, input: CommonTokenStream<S>) {
4849 self.input = input;
4850 self.reset();
4851 }
4852
4853 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
4864 self.unknown_predicate_policy = policy;
4865 }
4866
4867 #[must_use]
4873 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
4874 let error = self.unknown_semantic_error();
4875 self.unknown_predicate_hits.clear();
4876 self.unhandled_action_hits.clear();
4877 error
4878 }
4879
4880 pub fn reset_unknown_semantic_hits(&mut self) {
4887 self.unknown_predicate_hits.clear();
4888 self.unhandled_action_hits.clear();
4889 }
4890
4891 #[must_use]
4893 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
4894 &self.input
4895 }
4896
4897 #[must_use]
4899 pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<S> {
4900 &mut self.input
4901 }
4902
4903 #[must_use]
4905 pub const fn token_store(&self) -> &TokenStore {
4906 self.input.token_store()
4907 }
4908
4909 #[must_use]
4911 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
4912 &self.tree
4913 }
4914
4915 #[must_use]
4917 pub fn node(&self, id: NodeId) -> Node<'_> {
4918 self.tree
4919 .node(self.input.token_store(), id)
4920 .expect("parser-produced node ID should remain valid")
4921 }
4922
4923 #[must_use]
4925 pub fn into_token_stream(self) -> CommonTokenStream<S> {
4926 self.input
4927 }
4928
4929 #[must_use]
4931 pub fn into_token_store(self) -> TokenStore {
4932 self.input.into_token_store()
4933 }
4934
4935 #[must_use]
4937 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
4938 ParsedFile::new(self.input.into_token_store(), self.tree, root)
4939 }
4940
4941 pub const fn number_of_syntax_errors(&self) -> usize {
4944 self.syntax_errors
4945 }
4946
4947 #[must_use]
4953 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
4954 self.recognition_arena.stats(
4955 self.last_recognition_arena_root,
4956 self.last_recognition_arena_diagnostics,
4957 )
4958 }
4959
4960 pub const fn record_generated_syntax_error(&mut self) {
4963 self.record_syntax_errors(1);
4964 }
4965
4966 const fn record_syntax_errors(&mut self, count: usize) {
4967 self.syntax_errors = self.syntax_errors.saturating_add(count);
4968 }
4969
4970 pub fn report_token_source_errors(&mut self) {
4973 let errors = self.input.drain_source_errors();
4974 self.dispatch_token_source_errors(&errors);
4975 }
4976
4977 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
4980 GeneratedDiagnosticsCheckpoint {
4981 diagnostics_len: self.generated_parser_diagnostics.len(),
4982 syntax_errors: self.syntax_errors,
4983 tree: self.tree.checkpoint(),
4984 }
4985 }
4986
4987 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
4989 self.generated_parser_diagnostics
4990 .truncate(marker.diagnostics_len);
4991 self.syntax_errors = marker.syntax_errors;
4992 self.generated_sync_expected = None;
4993 self.tree.rollback(marker.tree);
4994 }
4995
4996 pub fn report_generated_parser_diagnostics(&mut self) {
4998 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
4999 let token_errors = self.input.drain_source_errors();
5000 self.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
5001 }
5002
5003 fn dispatch_parser_diagnostic(&self, diagnostic: &ParserDiagnostic) {
5004 self.notify_error_listeners(
5005 diagnostic.line,
5006 diagnostic.column,
5007 &diagnostic.message,
5008 None,
5009 );
5010 }
5011
5012 fn dispatch_parser_diagnostics<'a>(
5013 &self,
5014 diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>,
5015 ) {
5016 for diagnostic in diagnostics {
5017 self.dispatch_parser_diagnostic(diagnostic);
5018 }
5019 }
5020
5021 fn dispatch_token_source_error(&self, source_error: &TokenSourceError) {
5022 if self.input.token_source().report_error(source_error) {
5023 return;
5024 }
5025 self.notify_error_listeners(
5026 source_error.line,
5027 source_error.column,
5028 &source_error.message,
5029 None,
5030 );
5031 }
5032
5033 fn dispatch_token_source_errors(&self, errors: &[TokenSourceError]) {
5034 for error in errors {
5035 self.dispatch_token_source_error(error);
5036 }
5037 }
5038
5039 fn dispatch_generated_diagnostics(
5042 &self,
5043 parser_diagnostics: &[ParserDiagnostic],
5044 token_errors: &[TokenSourceError],
5045 ) {
5046 let mut token_iter = token_errors.iter().peekable();
5052 for diagnostic in parser_diagnostics {
5053 while let Some(error) = token_iter.peek() {
5054 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
5055 self.dispatch_token_source_error(error);
5056 token_iter.next();
5057 } else {
5058 break;
5059 }
5060 }
5061 self.dispatch_parser_diagnostic(diagnostic);
5062 }
5063 for error in token_iter {
5064 self.dispatch_token_source_error(error);
5065 }
5066 }
5067
5068 pub fn record_generated_ambiguity_diagnostic(
5071 &mut self,
5072 atn: &Atn,
5073 state_number: usize,
5074 start_index: usize,
5075 stop_index: usize,
5076 alts: &[usize],
5077 ) {
5078 if !self.report_diagnostic_errors || alts.len() < 2 {
5079 return;
5080 }
5081 let Some(decision) = atn
5082 .decision_to_state()
5083 .iter()
5084 .position(|candidate| candidate == state_number)
5085 else {
5086 return;
5087 };
5088 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5089 return;
5090 };
5091 let rule_name = self
5092 .rule_names()
5093 .get(rule_index)
5094 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5095 let input = display_input_text(&self.input.text(start_index, stop_index));
5096 let alts = alts
5097 .iter()
5098 .map(usize::to_string)
5099 .collect::<Vec<_>>()
5100 .join(", ");
5101 let key = (decision, start_index, format!("{alts}:{input}"));
5102 if !self.reported_prediction_diagnostics.insert(key) {
5103 return;
5104 }
5105 let start_diagnostic = diagnostic_for_token(
5106 self.token_at(start_index),
5107 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
5108 );
5109 let stop_diagnostic = diagnostic_for_token(
5110 self.token_at(stop_index),
5111 format!(
5112 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
5113 ),
5114 );
5115 self.generated_parser_diagnostics.push(start_diagnostic);
5116 self.generated_parser_diagnostics.push(stop_diagnostic);
5117 }
5118
5119 pub fn record_generated_prediction_diagnostic(
5122 &mut self,
5123 atn: &Atn,
5124 state_number: usize,
5125 prediction: &ParserAtnPrediction,
5126 ) {
5127 let Some(diagnostic) = &prediction.diagnostic else {
5128 return;
5129 };
5130 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5131 return;
5132 }
5133 let Some(decision) = atn
5134 .decision_to_state()
5135 .iter()
5136 .position(|candidate| candidate == state_number)
5137 else {
5138 return;
5139 };
5140 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5141 return;
5142 };
5143 let rule_name = self
5144 .rule_names()
5145 .get(rule_index)
5146 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5147 let attempt_input = display_input_text(
5148 &self
5149 .input
5150 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5151 );
5152 let result_input = display_input_text(
5153 &self
5154 .input
5155 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5156 );
5157 let alts = diagnostic
5158 .conflicting_alts
5159 .iter()
5160 .map(usize::to_string)
5161 .collect::<Vec<_>>()
5162 .join(", ");
5163 let key = (
5164 decision,
5165 diagnostic.start_index,
5166 format!(
5167 "{:?}:{alts}:{attempt_input}:{result_input}",
5168 diagnostic.kind
5169 ),
5170 );
5171 if !self.reported_prediction_diagnostics.insert(key) {
5172 return;
5173 }
5174 let attempt_diagnostic = diagnostic_for_token(
5175 self.token_at(diagnostic.sll_stop_index),
5176 format!(
5177 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5178 ),
5179 );
5180 self.generated_parser_diagnostics.push(attempt_diagnostic);
5181 let message = match diagnostic.kind {
5182 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5183 if !diagnostic.exact {
5188 return;
5189 }
5190 format!(
5191 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5192 )
5193 }
5194 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5195 format!(
5196 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5197 )
5198 }
5199 };
5200 let result_diagnostic =
5201 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5202 self.generated_parser_diagnostics.push(result_diagnostic);
5203 }
5204
5205 pub fn la(&self, offset: isize) -> i32 {
5206 self.input.la_token(offset)
5207 }
5208
5209 pub fn consume(&mut self) {
5210 IntStream::consume(&mut self.input);
5211 }
5212
5213 pub fn set_int_member(&mut self, member: usize, value: i64) {
5215 self.int_members.insert(member, value);
5216 }
5217
5218 pub fn int_member(&self, member: usize) -> Option<i64> {
5220 self.int_members.get(&member).copied()
5221 }
5222
5223 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
5226 self.int_members.clone()
5227 }
5228
5229 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
5231 self.int_members = members;
5232 }
5233
5234 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5236 let value = self.int_members.entry(member).or_default();
5237 *value += delta;
5238 *value
5239 }
5240
5241 fn token_type_for_id(&self, id: TokenId) -> i32 {
5242 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5243 }
5244
5245 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5246 if self.build_parse_trees {
5247 self.tree.terminal(id)
5248 } else {
5249 NodeId::placeholder()
5250 }
5251 }
5252
5253 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5254 if self.build_parse_trees {
5255 self.tree.error(id)
5256 } else {
5257 NodeId::placeholder()
5258 }
5259 }
5260
5261 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5262 context.set_start_id(id);
5263 }
5264
5265 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5266 context.set_stop_id(id);
5267 }
5268
5269 fn insert_synthetic_token(
5270 &mut self,
5271 token_type: i32,
5272 text: String,
5273 line: usize,
5274 column: usize,
5275 ) -> Result<TokenId, AntlrError> {
5276 self.input
5277 .insert(
5278 TokenSpec::explicit(token_type, text)
5279 .with_span(usize::MAX, usize::MAX)
5280 .with_byte_span(0, 0)
5281 .with_position(line, column),
5282 )
5283 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5284 }
5285
5286 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5293 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5294 line: 0,
5295 column: 0,
5296 message: "missing current token".to_owned(),
5297 })?;
5298 let current_type = self.token_type_for_id(current);
5299 if current_type == token_type {
5300 self.reset_generated_recovery_state();
5301 self.consume();
5302 Ok(self.terminal_tree(current))
5303 } else {
5304 Err(AntlrError::MismatchedInput {
5305 expected: self.vocabulary().display_name(token_type),
5306 found: self.vocabulary().display_name(current_type),
5307 })
5308 }
5309 }
5310
5311 pub fn match_token_recovering(
5315 &mut self,
5316 token_type: i32,
5317 follow_state: usize,
5318 atn: &Atn,
5319 ) -> Result<GeneratedMatch, AntlrError> {
5320 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5321 line: 0,
5322 column: 0,
5323 message: "missing current token".to_owned(),
5324 })?;
5325 let current_type = self.token_type_for_id(current);
5326 if current_type == token_type {
5327 self.generated_sync_expected = None;
5328 self.reset_generated_recovery_state();
5329 let consumed_eof = current_type == TOKEN_EOF;
5330 self.consume();
5331 return Ok(GeneratedMatch {
5332 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5333 consumed_eof,
5334 });
5335 }
5336 let mut expected_symbols = BTreeSet::new();
5337 expected_symbols.insert(token_type);
5338 self.recover_generated_match(
5339 current,
5340 GeneratedExpectedSymbols::Tree(&expected_symbols),
5341 follow_state,
5342 atn,
5343 |symbol| symbol == token_type,
5344 )
5345 }
5346
5347 pub fn match_set_recovering(
5348 &mut self,
5349 intervals: &[(i32, i32)],
5350 follow_state: usize,
5351 atn: &Atn,
5352 ) -> Result<GeneratedMatch, AntlrError> {
5353 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5354 line: 0,
5355 column: 0,
5356 message: "missing current token".to_owned(),
5357 })?;
5358 let current_type = self.token_type_for_id(current);
5359 if interval_set_contains(intervals, current_type) {
5360 self.generated_sync_expected = None;
5361 self.reset_generated_recovery_state();
5362 let consumed_eof = current_type == TOKEN_EOF;
5363 self.consume();
5364 return Ok(GeneratedMatch {
5365 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5366 consumed_eof,
5367 });
5368 }
5369 let expected_symbols = interval_symbols(intervals);
5370 self.recover_generated_match(
5371 current,
5372 GeneratedExpectedSymbols::Tree(&expected_symbols),
5373 follow_state,
5374 atn,
5375 |symbol| interval_set_contains(intervals, symbol),
5376 )
5377 }
5378
5379 pub fn match_token_set_recovering(
5380 &mut self,
5381 set: ParserIntervalSet<'_>,
5382 follow_state: usize,
5383 atn: &Atn,
5384 ) -> Result<GeneratedMatch, AntlrError> {
5385 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5386 line: 0,
5387 column: 0,
5388 message: "missing current token".to_owned(),
5389 })?;
5390 let current_type = self.token_type_for_id(current);
5391 if set.contains(current_type) {
5392 self.generated_sync_expected = None;
5393 self.reset_generated_recovery_state();
5394 let consumed_eof = current_type == TOKEN_EOF;
5395 self.consume();
5396 return Ok(GeneratedMatch {
5397 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5398 consumed_eof,
5399 });
5400 }
5401 self.recover_generated_match(
5402 current,
5403 GeneratedExpectedSymbols::TokenSet(set),
5404 follow_state,
5405 atn,
5406 |symbol| set.contains(symbol),
5407 )
5408 }
5409
5410 pub fn match_not_set_recovering(
5411 &mut self,
5412 intervals: &[(i32, i32)],
5413 min_vocabulary: i32,
5414 max_vocabulary: i32,
5415 follow_state: usize,
5416 atn: &Atn,
5417 ) -> Result<GeneratedMatch, AntlrError> {
5418 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5419 line: 0,
5420 column: 0,
5421 message: "missing current token".to_owned(),
5422 })?;
5423 let current_type = self.token_type_for_id(current);
5424 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5425 && !interval_set_contains(intervals, current_type)
5426 {
5427 self.generated_sync_expected = None;
5428 self.reset_generated_recovery_state();
5429 let consumed_eof = current_type == TOKEN_EOF;
5430 self.consume();
5431 return Ok(GeneratedMatch {
5432 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5433 consumed_eof,
5434 });
5435 }
5436 let expected_symbols =
5437 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
5438 self.recover_generated_match(
5439 current,
5440 GeneratedExpectedSymbols::Tree(&expected_symbols),
5441 follow_state,
5442 atn,
5443 |symbol| {
5444 (min_vocabulary..=max_vocabulary).contains(&symbol)
5445 && !interval_set_contains(intervals, symbol)
5446 },
5447 )
5448 }
5449
5450 pub fn match_not_token_set_recovering(
5451 &mut self,
5452 set: ParserIntervalSet<'_>,
5453 min_vocabulary: i32,
5454 max_vocabulary: i32,
5455 follow_state: usize,
5456 atn: &Atn,
5457 ) -> Result<GeneratedMatch, AntlrError> {
5458 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5459 line: 0,
5460 column: 0,
5461 message: "missing current token".to_owned(),
5462 })?;
5463 let current_type = self.token_type_for_id(current);
5464 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
5465 {
5466 self.generated_sync_expected = None;
5467 self.reset_generated_recovery_state();
5468 let consumed_eof = current_type == TOKEN_EOF;
5469 self.consume();
5470 return Ok(GeneratedMatch {
5471 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5472 consumed_eof,
5473 });
5474 }
5475 self.recover_generated_match(
5476 current,
5477 GeneratedExpectedSymbols::TokenSetComplement {
5478 set,
5479 min_vocabulary,
5480 max_vocabulary,
5481 },
5482 follow_state,
5483 atn,
5484 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
5485 )
5486 }
5487
5488 fn recover_generated_match(
5489 &mut self,
5490 current: TokenId,
5491 expected_symbols: GeneratedExpectedSymbols<'_>,
5492 follow_state: usize,
5493 atn: &Atn,
5494 matches: impl Fn(i32) -> bool,
5495 ) -> Result<GeneratedMatch, AntlrError> {
5496 let expected_display = expected_symbols.display(self.vocabulary());
5497 let (current_type, current_line, current_column, current_display) = {
5498 let token = self
5499 .input
5500 .token_view(current)
5501 .expect("current token ID should be valid");
5502 (
5503 token.token_type(),
5504 token.line(),
5505 token.column(),
5506 token_input_display(&token),
5507 )
5508 };
5509 if self.bail_on_error {
5510 return Err(AntlrError::ParserError {
5511 line: current_line,
5512 column: current_column,
5513 message: format!("mismatched input {current_display} expecting {expected_display}"),
5514 });
5515 }
5516 if current_type != TOKEN_EOF
5517 && let Some(next) = self.input.lt_id(2)
5518 && matches(self.token_type_for_id(next))
5519 {
5520 let message =
5521 format!("extraneous input {current_display} expecting {expected_display}");
5522 self.push_generated_parser_diagnostic(ParserDiagnostic {
5523 line: current_line,
5524 column: current_column,
5525 message,
5526 });
5527 self.record_syntax_errors(1);
5528 self.generated_sync_expected = None;
5529 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
5532 self.consume();
5533 self.consume();
5534 self.reset_generated_recovery_state();
5535 return Ok(GeneratedMatch {
5536 children: GeneratedMatchChildren::Many(vec![
5537 self.error_tree(current),
5538 self.terminal_tree(next),
5539 ]),
5540 consumed_eof,
5541 });
5542 }
5543 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
5544 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
5553 && self
5554 .cached_state_expected_symbols(atn, follow_state)
5555 .contains(&TOKEN_EOF);
5556 if follow_symbols.contains(¤t_type)
5557 && (current_type != TOKEN_EOF
5558 || self.rule_context_stack.len() > 1
5559 || expected_symbols.is_empty()
5560 || follow_explicitly_expects_eof)
5561 {
5562 let message = format!("missing {expected_display} at {current_display}");
5563 self.push_generated_parser_diagnostic(ParserDiagnostic {
5564 line: current_line,
5565 column: current_column,
5566 message,
5567 });
5568 self.record_syntax_errors(1);
5569 self.generated_sync_expected = None;
5570 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
5571 let missing_display = expected_symbol_display(token_type, self.vocabulary());
5572 let token = self.insert_synthetic_token(
5573 token_type,
5574 format!("<missing {missing_display}>"),
5575 current_line,
5576 current_column,
5577 )?;
5578 return Ok(GeneratedMatch {
5583 children: GeneratedMatchChildren::One(self.error_tree(token)),
5584 consumed_eof: false,
5585 });
5586 }
5587 let mismatch_expected_display = self
5588 .generated_sync_expected
5589 .take()
5590 .map_or(expected_display, |symbols| {
5591 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
5592 });
5593 Err(AntlrError::ParserError {
5594 line: current_line,
5595 column: current_column,
5596 message: format!(
5597 "mismatched input {current_display} expecting {mismatch_expected_display}"
5598 ),
5599 })
5600 }
5601
5602 fn generated_recovery_follow_symbols(
5603 &mut self,
5604 atn: &Atn,
5605 follow_state: usize,
5606 ) -> BTreeSet<i32> {
5607 let mut follow = self
5608 .cached_state_expected_symbols(atn, follow_state)
5609 .as_ref()
5610 .clone();
5611 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
5612 follow.extend(self.context_expected_symbols(atn));
5613 }
5614 follow
5615 }
5616
5617 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
5618 self.match_token(TOKEN_EOF)
5619 }
5620
5621 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
5622 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
5623 }
5624
5625 pub fn match_not_set(
5626 &mut self,
5627 intervals: &[(i32, i32)],
5628 min_vocabulary: i32,
5629 max_vocabulary: i32,
5630 ) -> Result<ParseTree, AntlrError> {
5631 self.match_interval_condition(intervals, |symbol| {
5632 (min_vocabulary..=max_vocabulary).contains(&symbol)
5633 && !interval_set_contains(intervals, symbol)
5634 })
5635 }
5636
5637 fn match_interval_condition(
5638 &mut self,
5639 intervals: &[(i32, i32)],
5640 matches: impl FnOnce(i32) -> bool,
5641 ) -> Result<ParseTree, AntlrError> {
5642 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5643 line: 0,
5644 column: 0,
5645 message: "missing current token".to_owned(),
5646 })?;
5647 let current_type = self.token_type_for_id(current);
5648 if matches(current_type) {
5649 self.reset_generated_recovery_state();
5650 self.consume();
5651 Ok(self.terminal_tree(current))
5652 } else {
5653 Err(AntlrError::MismatchedInput {
5654 expected: self.interval_display(intervals),
5655 found: self.vocabulary().display_name(current_type),
5656 })
5657 }
5658 }
5659
5660 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
5661 let values = intervals
5662 .iter()
5663 .map(|(start, stop)| {
5664 if start == stop {
5665 self.vocabulary().display_name(*start)
5666 } else {
5667 format!(
5668 "{}..{}",
5669 self.vocabulary().display_name(*start),
5670 self.vocabulary().display_name(*stop)
5671 )
5672 }
5673 })
5674 .collect::<Vec<_>>()
5675 .join(", ");
5676 format!("{{{values}}}")
5677 }
5678
5679 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
5680 if self.build_parse_trees {
5681 self.tree.finish_rule(context)
5682 } else {
5683 NodeId::placeholder()
5684 }
5685 }
5686
5687 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
5690 self.set_state(state);
5691 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
5692 self.rule_context_stack.push(RuleContextFrame {
5693 rule_index,
5694 invoking_state,
5695 });
5696 self.advance_rule_context_version();
5697 let start_index = self.current_visible_index();
5698 let mut context = ParserRuleContext::new(rule_index, invoking_state);
5699 if let Some(token) = self.token_id_at(start_index) {
5700 self.set_context_start(&mut context, token);
5701 }
5702 context
5703 }
5704
5705 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
5712 let marker = self.pending_invoking_states.len();
5713 self.pending_invoking_states.push(invoking_state);
5714 marker
5715 }
5716
5717 pub fn discard_invoking_state(&mut self, marker: usize) {
5719 self.pending_invoking_states.truncate(marker);
5720 }
5721
5722 pub fn exit_rule(&mut self) {
5724 self.rule_context_stack.pop();
5725 self.advance_rule_context_version();
5726 }
5727
5728 pub fn prediction_context_return_states<'a>(
5731 &'a self,
5732 atn: &'a Atn,
5733 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
5734 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
5735 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
5736 return None;
5737 };
5738 let Some(Transition::Rule { follow_state, .. }) = atn
5739 .state(state_number)
5740 .and_then(|state| state.transitions().first())
5741 .map(ParserTransition::data)
5742 else {
5743 return None;
5744 };
5745 Some(follow_state)
5746 })
5747 }
5748
5749 pub const fn rule_context_version(&self) -> usize {
5754 self.rule_context_version
5755 }
5756
5757 const fn advance_rule_context_version(&mut self) {
5758 self.rule_context_version = self.rule_context_version.wrapping_add(1);
5759 }
5760
5761 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
5766 if self.build_parse_trees {
5767 self.tree.add_child(context, child);
5768 } else {
5769 context.note_matched_child();
5770 }
5771 }
5772
5773 fn release_tree_scratch_if_idle(&mut self) {
5774 if self.rule_context_stack.is_empty() {
5775 self.tree.release_scratch();
5776 }
5777 }
5778
5779 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
5781 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5782 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5783 self.set_context_stop(&mut context, token);
5784 }
5785 let node = self.rule_node(context);
5786 self.exit_rule();
5787 self.release_tree_scratch_if_idle();
5788 node
5789 }
5790
5791 pub fn recover_generated_rule(
5798 &mut self,
5799 context: &mut ParserRuleContext,
5800 atn: &Atn,
5801 error: AntlrError,
5802 ) {
5803 let diagnostic = self.generated_rule_error_diagnostic(error);
5804 self.push_generated_parser_diagnostic(diagnostic);
5805 self.generated_sync_expected = None;
5806 let error_index = self.input.index();
5807 let error_state = self.data.state();
5808 if self.generated_recovery_error_index == Some(error_index)
5813 && self.generated_recovery_error_states.contains(&error_state)
5814 && self.la(1) != TOKEN_EOF
5815 && let Some(token) = self.input.lt_id(1)
5816 {
5817 self.consume();
5818 let child = self.error_tree(token);
5819 self.add_parse_child(context, child);
5820 }
5821 let recovery_index = self.input.index();
5822 if self.generated_recovery_error_index != Some(recovery_index) {
5823 self.generated_recovery_error_index = Some(recovery_index);
5824 self.generated_recovery_error_states.clear();
5825 }
5826 self.generated_recovery_error_states.insert(error_state);
5827 let recovery_symbols = self.context_expected_symbols(atn);
5828 loop {
5829 let symbol = self.la(1);
5830 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
5831 break;
5832 }
5833 let Some(token) = self.input.lt_id(1) else {
5834 break;
5835 };
5836 self.consume();
5837 let child = self.error_tree(token);
5838 self.add_parse_child(context, child);
5839 }
5840 self.record_syntax_errors(1);
5841 }
5842
5843 fn reset_generated_recovery_state(&mut self) {
5844 if self.generated_recovery_error_index.is_some() {
5845 self.generated_recovery_error_index = None;
5846 self.generated_recovery_error_states.clear();
5847 }
5848 }
5849
5850 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
5851 if self
5852 .generated_parser_diagnostics
5853 .iter()
5854 .any(|existing| existing == &diagnostic)
5855 {
5856 return;
5857 }
5858 self.generated_parser_diagnostics.push(diagnostic);
5859 }
5860
5861 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
5862 match error {
5863 AntlrError::ParserError {
5864 line,
5865 column,
5866 message,
5867 } => ParserDiagnostic {
5868 line,
5869 column,
5870 message,
5871 },
5872 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
5873 self.input.lt(1),
5874 format!("mismatched input {found} expecting {expected}"),
5875 ),
5876 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
5877 self.input.lt(1),
5878 format!("no viable alternative at input {input}"),
5879 ),
5880 AntlrError::LexerError {
5881 line,
5882 column,
5883 message,
5884 } => ParserDiagnostic {
5885 line,
5886 column,
5887 message,
5888 },
5889 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
5890 }
5891 }
5892
5893 pub fn finish_recursion_rule(
5895 &mut self,
5896 mut context: ParserRuleContext,
5897 consumed_eof: bool,
5898 ) -> ParseTree {
5899 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5900 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5901 self.set_context_stop(&mut context, token);
5902 }
5903 let node = self.rule_node(context);
5904 self.unroll_recursion_context();
5905 self.release_tree_scratch_if_idle();
5906 node
5907 }
5908
5909 pub fn enter_recursion_rule(
5911 &mut self,
5912 state: isize,
5913 rule_index: usize,
5914 precedence: i32,
5915 ) -> ParserRuleContext {
5916 self.precedence_stack.push(precedence);
5917 self.enter_rule(state, rule_index)
5918 }
5919
5920 pub fn push_new_recursion_context(
5922 &mut self,
5923 state: isize,
5924 rule_index: usize,
5925 ) -> ParserRuleContext {
5926 self.set_state(state);
5927 ParserRuleContext::new(rule_index, state)
5928 }
5929
5930 pub fn push_new_recursion_context_with_previous(
5933 &mut self,
5934 state: isize,
5935 rule_index: usize,
5936 current: &mut ParserRuleContext,
5937 ) {
5938 self.set_state(state);
5939 if let Some(stop) = self
5940 .rule_stop_token_index(self.input.index(), false)
5941 .and_then(|index| self.token_id_at(index))
5942 {
5943 self.set_context_stop(current, stop);
5944 }
5945 let invoking_state = current.invoking_state();
5946 let start = current.start_id();
5947 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
5948 if start.is_some() {
5949 replacement.set_start_from_context(current);
5950 }
5951 let previous = std::mem::replace(current, replacement);
5952 if self.build_parse_trees {
5953 let previous = self.rule_node(previous);
5954 self.tree.add_child(current, previous);
5955 }
5956 }
5957
5958 pub fn unroll_recursion_context(&mut self) {
5960 if self.precedence_stack.len() > 1 {
5961 self.precedence_stack.pop();
5962 }
5963 self.exit_rule();
5964 }
5965
5966 pub fn left_recursive_loop_enter_prediction(
5980 &mut self,
5981 atn: &Atn,
5982 state_number: usize,
5983 precedence: i32,
5984 ) -> Option<bool> {
5985 let symbol = self.la(1);
5986 if symbol == TOKEN_EOF {
5987 return Some(false);
5988 }
5989 let operator_lookahead =
5990 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
5991 let can_single = operator_lookahead.single_token.contains(symbol);
5992 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
5993 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
5994 if !can_single && !can_multi && !can_predicate {
5995 return Some(false);
5996 }
5997 if can_predicate && !can_single {
5998 return None;
5999 }
6000 if !can_single && can_multi && precedence > 0 {
6004 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
6005 if baseline.single_token.contains(symbol) {
6006 return None;
6007 }
6008 }
6009 let atn_key = SharedAtnCacheKey::for_atn(atn);
6010 let cached_overlap = self
6011 .left_recursive_caller_overlap_cache
6012 .iter()
6013 .flatten()
6014 .find(|entry| {
6015 entry.atn_key == atn_key
6016 && entry.state_number == state_number
6017 && entry.symbol == symbol
6018 && entry.context_version == self.rule_context_version
6019 })
6020 .map(|entry| entry.overlaps);
6021 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
6022 let overlaps = caller_context_can_match_symbol_before_state(
6023 atn,
6024 self.prediction_context_return_states(atn),
6025 state_number,
6026 symbol,
6027 );
6028 if let Some(slot) = self
6029 .left_recursive_caller_overlap_cache
6030 .iter_mut()
6031 .find(|slot| slot.is_none())
6032 {
6033 *slot = Some(LeftRecursiveCallerOverlap {
6034 atn_key,
6035 state_number,
6036 symbol,
6037 context_version: self.rule_context_version,
6038 overlaps,
6039 });
6040 }
6041 overlaps
6042 });
6043 if caller_overlaps {
6044 return None;
6045 }
6046 Some(true)
6047 }
6048
6049 fn cached_left_recursive_operator_lookahead(
6050 atn: &Atn,
6051 state_number: usize,
6052 precedence: i32,
6053 ) -> Rc<LeftRecursiveOperatorLookahead> {
6054 with_shared_atn_caches(atn, |cache| {
6055 let key = (state_number, precedence);
6056 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
6057 return Rc::clone(cached);
6058 }
6059 let lookahead = Rc::new(left_recursive_operator_lookahead(
6060 atn,
6061 state_number,
6062 precedence,
6063 ));
6064 cache
6065 .left_recursive_operator_lookahead
6066 .insert(key, Rc::clone(&lookahead));
6067 lookahead
6068 })
6069 }
6070
6071 pub fn left_recursive_loop_enter_matches(
6074 &mut self,
6075 atn: &Atn,
6076 state_number: usize,
6077 precedence: i32,
6078 ) -> bool {
6079 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
6080 }
6081
6082 pub fn precpred(&self, precedence: i32) -> bool {
6084 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
6085 }
6086
6087 pub fn parser_semantic_predicate_matches(
6090 &mut self,
6091 predicates: &[(usize, usize, ParserPredicate)],
6092 rule_index: usize,
6093 pred_index: usize,
6094 ) -> bool {
6095 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
6096 }
6097
6098 pub fn parser_semantic_predicate_matches_with_local(
6101 &mut self,
6102 predicates: &[(usize, usize, ParserPredicate)],
6103 rule_index: usize,
6104 pred_index: usize,
6105 local_int_arg: i32,
6106 ) -> bool {
6107 self.parser_semantic_predicate_matches_inner(
6108 predicates,
6109 rule_index,
6110 pred_index,
6111 Some((rule_index, i64::from(local_int_arg))),
6112 )
6113 }
6114
6115 fn parser_semantic_predicate_matches_inner(
6116 &mut self,
6117 predicates: &[(usize, usize, ParserPredicate)],
6118 rule_index: usize,
6119 pred_index: usize,
6120 local_int_arg: Option<(usize, i64)>,
6121 ) -> bool {
6122 let index = self.input.index();
6123 let member_values = self.int_members.clone();
6124 self.parser_predicate_matches(PredicateEval {
6125 index,
6126 rule_index,
6127 pred_index,
6128 predicates,
6129 semantics: None,
6130 context: None,
6131 local_int_arg,
6132 member_values: &member_values,
6133 })
6134 }
6135
6136 pub fn parser_semantic_predicate_matches_with_context_and_local(
6139 &mut self,
6140 predicates: &[(usize, usize, ParserPredicate)],
6141 rule_index: usize,
6142 pred_index: usize,
6143 context: &ParserRuleContext,
6144 local_int_arg: i32,
6145 ) -> bool {
6146 let index = self.input.index();
6147 let member_values = self.int_members.clone();
6148 self.parser_predicate_matches(PredicateEval {
6149 index,
6150 rule_index,
6151 pred_index,
6152 predicates,
6153 semantics: None,
6154 context: Some(context),
6155 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6156 member_values: &member_values,
6157 })
6158 }
6159
6160 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
6163 &mut self,
6164 semantics: &ParserSemantics,
6165 rule_index: usize,
6166 pred_index: usize,
6167 context: &ParserRuleContext,
6168 local_int_arg: i32,
6169 ) -> bool {
6170 let index = self.input.index();
6171 let member_values = self.int_members.clone();
6172 self.parser_predicate_matches(PredicateEval {
6173 index,
6174 rule_index,
6175 pred_index,
6176 predicates: &[],
6177 semantics: Some(semantics),
6178 context: Some(context),
6179 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6180 member_values: &member_values,
6181 })
6182 }
6183
6184 pub fn parser_semantic_predicate_failure_message(
6187 &self,
6188 rule_index: usize,
6189 pred_index: usize,
6190 predicates: &[(usize, usize, ParserPredicate)],
6191 ) -> Option<&'static str> {
6192 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
6193 }
6194
6195 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
6197 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6198 line: 0,
6199 column: 0,
6200 message: "missing current token".to_owned(),
6201 })?;
6202 if self.token_type_for_id(current) == TOKEN_EOF {
6203 return Err(AntlrError::MismatchedInput {
6204 expected: "wildcard".to_owned(),
6205 found: self.vocabulary().display_name(TOKEN_EOF),
6206 });
6207 }
6208 self.reset_generated_recovery_state();
6209 self.consume();
6210 Ok(self.terminal_tree(current))
6211 }
6212
6213 #[allow(clippy::unnecessary_wraps)]
6217 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
6218 self.set_state(state);
6219 Ok(())
6220 }
6221
6222 pub fn sync_decision(
6230 &mut self,
6231 atn: &Atn,
6232 state_number: usize,
6233 current_context_empty: bool,
6234 loop_back: bool,
6235 ) -> Result<Vec<ParseTree>, AntlrError> {
6236 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
6237 self.generated_sync_expected = None;
6238 let Some(state) = atn.state(state_number) else {
6239 return Ok(Vec::new());
6240 };
6241 let Some(rule_index) = state.rule_index() else {
6242 return Ok(Vec::new());
6243 };
6244 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
6245 return Ok(Vec::new());
6246 };
6247 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6248 let symbol = self.la(1);
6249 let mut has_expected_symbols = false;
6250 let mut nullable = false;
6251 let mut explicit_eof_expected = false;
6259 for transition in &entry.transitions {
6260 if transition.symbols.contains(symbol) {
6261 return Ok(Vec::new());
6262 }
6263 has_expected_symbols |= !transition.symbols.is_empty();
6264 nullable |= transition.nullable;
6265 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
6266 }
6267 if nullable && self.context_expected_contains(atn, symbol) {
6272 return Ok(Vec::new());
6273 }
6274 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
6275 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
6276 return Ok(Vec::new());
6277 }
6278 let mut expected = TokenBitSet::default();
6279 for transition in &entry.transitions {
6280 expected.extend_from(&transition.symbols);
6281 }
6282 if let Some(context_expected) = context_expected {
6283 expected.extend_from(&context_expected);
6284 }
6285 let can_delete_in_place =
6286 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
6287 let loop_sync = loop_back;
6304 if symbol != TOKEN_EOF && can_delete_in_place {
6305 let mut cursor = self.input.index();
6306 let mut skipped = Vec::new();
6307 loop {
6308 let current = self.token_type_at(cursor);
6309 if current == TOKEN_EOF {
6310 break;
6311 }
6312 skipped.push(cursor);
6313 let next = self.consume_index(cursor, current);
6314 if next == cursor {
6315 break;
6316 }
6317 let next_symbol = self.token_type_at(next);
6318 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
6326 explicit_eof_expected
6327 } else {
6328 expected.contains(next_symbol)
6329 };
6330 if next_is_expected_stop {
6331 let current_token = self.input.lt(1);
6332 let expected_symbols = expected.to_btree_set();
6333 let message = format!(
6334 "extraneous input {} expecting {}",
6335 current_token
6336 .as_ref()
6337 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6338 self.expected_symbols_display(&expected_symbols)
6339 );
6340 self.push_generated_parser_diagnostic(diagnostic_for_token(
6341 current_token,
6342 message,
6343 ));
6344 self.record_syntax_errors(1);
6345 let mut children = Vec::with_capacity(skipped.len());
6346 for index in skipped {
6347 if let Some(token) = self.token_id_at(index) {
6348 self.consume();
6349 children.push(self.error_tree(token));
6350 }
6351 }
6352 if !loop_sync {
6353 self.reset_generated_recovery_state();
6354 }
6355 return Ok(children);
6356 }
6357 if !loop_sync {
6361 break;
6362 }
6363 cursor = next;
6364 }
6365 }
6366 if nullable {
6367 self.generated_sync_expected = Some(expected);
6368 return Ok(Vec::new());
6369 }
6370 let current = self.input.lt(1);
6371 let expected_symbols = expected.to_btree_set();
6372 Err(AntlrError::ParserError {
6373 line: current.as_ref().map(Token::line).unwrap_or_default(),
6374 column: current.as_ref().map(Token::column).unwrap_or_default(),
6375 message: format!(
6376 "mismatched input {} expecting {}",
6377 current
6378 .as_ref()
6379 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6380 self.expected_symbols_display(&expected_symbols)
6381 ),
6382 })
6383 }
6384
6385 pub fn ll1_decision_prediction(
6392 &mut self,
6393 atn: &Atn,
6394 state_number: usize,
6395 ) -> Option<ParserAtnPrediction> {
6396 let state = atn.state(state_number)?;
6397 if state.precedence_rule_decision() {
6398 return None;
6399 }
6400 let rule_stop = state
6401 .rule_index()
6402 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
6403 let symbol = self.la(1);
6404 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6405 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
6406 alt: alt + 1,
6407 requires_full_context: false,
6408 has_semantic_context: false,
6409 diagnostic: None,
6410 })
6411 }
6412
6413 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
6414 let mut expected = BTreeSet::new();
6415 for index in (1..self.rule_context_stack.len()).rev() {
6416 let invoking_state = self.rule_context_stack[index].invoking_state;
6417 let Ok(state_number) = usize::try_from(invoking_state) else {
6418 continue;
6419 };
6420 let Some(Transition::Rule { follow_state, .. }) = atn
6421 .state(state_number)
6422 .and_then(|state| state.transitions().first())
6423 .map(ParserTransition::data)
6424 else {
6425 continue;
6426 };
6427 let return_state = follow_state;
6428 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
6429 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
6430 return expected;
6431 }
6432 }
6433 expected.insert(TOKEN_EOF);
6434 expected
6435 }
6436
6437 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
6438 let mut expected = TokenBitSet::default();
6439 for index in (1..self.rule_context_stack.len()).rev() {
6440 let invoking_state = self.rule_context_stack[index].invoking_state;
6441 let Ok(state_number) = usize::try_from(invoking_state) else {
6442 continue;
6443 };
6444 let Some(Transition::Rule { follow_state, .. }) = atn
6445 .state(state_number)
6446 .and_then(|state| state.transitions().first())
6447 .map(ParserTransition::data)
6448 else {
6449 continue;
6450 };
6451 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
6452 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6453 return expected;
6454 }
6455 }
6456 expected.insert(TOKEN_EOF);
6457 expected
6458 }
6459
6460 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
6471 for index in (1..self.rule_context_stack.len()).rev() {
6472 let invoking_state = self.rule_context_stack[index].invoking_state;
6473 let Ok(state_number) = usize::try_from(invoking_state) else {
6474 continue;
6475 };
6476 let Some(Transition::Rule { follow_state, .. }) = atn
6477 .state(state_number)
6478 .and_then(|state| state.transitions().first())
6479 .map(ParserTransition::data)
6480 else {
6481 continue;
6482 };
6483 if self
6484 .cached_state_expected_token_set(atn, follow_state)
6485 .contains(symbol)
6486 {
6487 return true;
6488 }
6489 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6490 return false;
6491 }
6492 }
6493 symbol == TOKEN_EOF
6494 }
6495
6496 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
6498 let error_index = self.input.index();
6499 self.no_viable_alternative_error_at(start_index, error_index)
6500 }
6501
6502 pub fn no_viable_alternative_error_at(
6507 &self,
6508 start_index: usize,
6509 error_index: usize,
6510 ) -> AntlrError {
6511 let diagnostic = self.no_viable_alternative(start_index, error_index);
6512 AntlrError::ParserError {
6513 line: diagnostic.line,
6514 column: diagnostic.column,
6515 message: diagnostic.message,
6516 }
6517 }
6518
6519 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
6521 let current = self.input.lt(1);
6522 AntlrError::ParserError {
6523 line: current.as_ref().map(Token::line).unwrap_or_default(),
6524 column: current.as_ref().map(Token::column).unwrap_or_default(),
6525 message: format!("rule failed predicate: {}", message.into()),
6526 }
6527 }
6528
6529 pub fn failed_predicate_option_error(
6532 &self,
6533 rule_index: usize,
6534 message: impl Into<String>,
6535 ) -> AntlrError {
6536 let current = self.input.lt(1);
6537 let rule_name = self
6538 .rule_names()
6539 .get(rule_index)
6540 .map_or_else(|| rule_index.to_string(), Clone::clone);
6541 AntlrError::ParserError {
6542 line: current.as_ref().map(Token::line).unwrap_or_default(),
6543 column: current.as_ref().map(Token::column).unwrap_or_default(),
6544 message: format!("rule {rule_name} {}", message.into()),
6545 }
6546 }
6547
6548 pub fn parser_action_at_current(
6550 &mut self,
6551 source_state: usize,
6552 rule_index: usize,
6553 start_index: usize,
6554 consumed_eof: bool,
6555 ) -> ParserAction {
6556 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6557 ParserAction::new(source_state, rule_index, start_index, stop_index)
6558 }
6559
6560 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
6565 let rule_index = action.rule_index();
6566 let rule_name = self.rule_names().get(rule_index).cloned();
6567 let context = None;
6568 let input = &mut self.input;
6569 let semantic_hooks = &mut self.semantic_hooks;
6570 let member_values = &self.int_members;
6571 let mut ctx = ParserSemCtx {
6572 input,
6573 tree_storage: &self.tree,
6574 rule_index,
6575 coordinate_index: usize::MAX,
6576 rule_name,
6577 context,
6578 tree: Some(tree),
6579 local_int_arg: None,
6580 member_values,
6581 action: Some(action),
6582 };
6583 let handled = semantic_hooks.action(&mut ctx, action);
6584 if !handled && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error) {
6590 let coordinate = (rule_index, action.source_state());
6591 if !self.unhandled_action_hits.contains(&coordinate) {
6592 self.unhandled_action_hits.push(coordinate);
6593 }
6594 }
6595 handled
6596 }
6597
6598 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
6603 &mut self,
6604 atn: &'atn Atn,
6605 simulator: &mut ParserAtnSimulator<'atn>,
6606 rule_index: usize,
6607 ) -> Result<ParseTree, AntlrError> {
6608 let start_index = self.current_visible_index();
6609 self.clear_prediction_diagnostics();
6610 self.reset_per_parse_caches();
6611 self.reset_recognition_arena();
6612 let tree_checkpoint = self.tree.checkpoint();
6613 let mut decision_by_state = vec![None; atn.states().len()];
6614 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
6615 if let Some(slot) = decision_by_state.get_mut(state_number) {
6616 *slot = Some(decision);
6617 }
6618 }
6619
6620 let result = DirectAdaptiveParser {
6621 parser: self,
6622 atn,
6623 simulator,
6624 decision_by_state,
6625 steps: 0,
6626 }
6627 .parse_rule(rule_index, -1, 0);
6628
6629 match result {
6630 Ok(tree) => {
6631 self.report_token_source_errors();
6632 self.release_tree_scratch_if_idle();
6633 Ok(tree)
6634 }
6635 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
6636 let _ = reason;
6637 self.tree.rollback(tree_checkpoint);
6638 self.input.seek(start_index);
6639 self.parse_atn_rule(atn, rule_index)
6640 }
6641 }
6642 }
6643
6644 pub fn parse_atn_rule(
6654 &mut self,
6655 atn: &Atn,
6656 rule_index: usize,
6657 ) -> Result<ParseTree, AntlrError> {
6658 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
6659 }
6660
6661 pub fn parse_atn_rule_with_precedence(
6664 &mut self,
6665 atn: &Atn,
6666 rule_index: usize,
6667 precedence: i32,
6668 ) -> Result<ParseTree, AntlrError> {
6669 self.parse_atn_rule_with_precedence_inner(
6670 atn,
6671 rule_index,
6672 precedence,
6673 None,
6674 AltNumberTracking::default(),
6675 )
6676 }
6677
6678 fn parse_atn_rule_with_precedence_inner(
6679 &mut self,
6680 atn: &Atn,
6681 rule_index: usize,
6682 precedence: i32,
6683 predicate_context: Option<FastPredicateContext<'_>>,
6684 alt_tracking: AltNumberTracking,
6685 ) -> Result<ParseTree, AntlrError> {
6686 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
6687 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
6688 })?;
6689 let stop_state = atn
6690 .rule_to_stop_state()
6691 .get(rule_index)
6692 .filter(|state| *state != usize::MAX)
6693 .ok_or_else(|| {
6694 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
6695 })?;
6696
6697 let start_index = self.current_visible_index();
6698 self.clear_prediction_diagnostics();
6699 self.reset_per_parse_caches();
6700 self.reset_recognition_arena();
6701 let caller_follow_state = self.pending_invoking_follow_state(atn);
6702 self.fast_recovery_enabled = false;
6703 self.fast_token_nodes_enabled = false;
6704 self.fast_track_alt_numbers = alt_tracking.any();
6705 let top_request = FastRecognizeTopRequest {
6706 start_state,
6707 stop_state,
6708 start_index,
6709 precedence,
6710 caller_follow_state,
6711 };
6712 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
6713 self.fast_token_nodes_enabled = self.build_parse_trees;
6714 let needs_tree_retry = matches!(
6715 &first_pass,
6716 Ok((outcome, _, _))
6717 if self.build_parse_trees
6718 && self
6719 .recognition_arena
6720 .sequence_has_left_recursive_boundary(outcome.nodes)
6721 );
6722 let needs_retry = match &first_pass {
6723 Err(_) => true,
6736 Ok((outcome, _, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
6737 };
6738 let (outcome, _expected, alt_number) = if needs_retry {
6739 self.fast_first_set_prefilter = false;
6740 self.fast_recovery_enabled = false;
6741 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6742 let clean_selected = if needs_tree_retry {
6743 match clean_retry {
6744 ok @ Ok(_) => ok,
6745 Err(_) => first_pass,
6746 }
6747 } else {
6748 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
6749 };
6750 let selected = if clean_selected.is_err()
6751 || matches!(&clean_selected, Ok((outcome, _, _)) if !outcome.diagnostics.is_empty())
6752 {
6753 self.fast_recovery_enabled = true;
6754 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6755 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
6756 } else {
6757 clean_selected
6758 };
6759 self.fast_first_set_prefilter = true;
6760 self.fast_recovery_enabled = true;
6761 selected.map_err(|expected| {
6762 if predicate_context.is_some()
6763 && let Some(error) = self.unknown_semantic_error()
6764 {
6765 self.report_token_source_errors();
6766 return error;
6767 }
6768 let error = self.recognition_error(rule_index, start_index, &expected);
6769 self.record_syntax_errors(1);
6770 self.report_token_source_errors();
6771 error
6772 })?
6773 } else {
6774 first_pass.expect("first_pass is Ok in the no-retry branch")
6775 };
6776 if predicate_context.is_some()
6777 && let Some(error) = self.unknown_semantic_error()
6778 {
6779 self.report_token_source_errors();
6780 return Err(error);
6781 }
6782 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
6783 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
6784 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
6785 self.report_token_source_errors();
6786 let mut context = ParserRuleContext::with_child_capacity(
6787 rule_index,
6788 self.state(),
6789 if self.build_parse_trees {
6790 self.recognition_arena.sequence_len(outcome.nodes)
6791 } else {
6792 0
6793 },
6794 );
6795 if alt_tracking.public {
6796 context.set_alt_number(alt_number.max(1));
6797 }
6798 if alt_tracking.context {
6799 context.set_context_alt_number(alt_number);
6800 }
6801 if let Some(token) = self.token_id_at(start_index) {
6802 self.set_context_start(&mut context, token);
6803 }
6804 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
6805 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
6806 self.set_context_stop(&mut context, token);
6807 }
6808 let live_root = if self.build_parse_trees {
6809 self.recognition_arena
6810 .fold_left_recursive_boundaries(outcome.nodes)
6811 } else {
6812 outcome.nodes
6813 };
6814 if self.build_parse_trees {
6815 if self
6816 .recognition_arena
6817 .sequence_has_explicit_token(live_root)
6818 {
6819 let mut cursor = live_root;
6820 while let Some(link) = self.recognition_arena.link(cursor) {
6821 let child = self.arena_recognized_node_tree(
6822 link.head,
6823 alt_tracking.public,
6824 alt_tracking.context,
6825 )?;
6826 self.tree.add_child(&mut context, child);
6827 cursor = link.tail;
6828 }
6829 } else {
6830 self.add_arena_implicit_token_children(
6831 &mut context,
6832 start_index,
6833 stop_index,
6834 live_root,
6835 alt_tracking,
6836 )?;
6837 }
6838 }
6839 self.finish_recognition_arena(live_root, outcome.diagnostics);
6840 self.input.seek(outcome.index);
6841
6842 let tree = self.rule_node(context);
6843 self.release_tree_scratch_if_idle();
6844 Ok(tree)
6845 }
6846
6847 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
6848 let invoking_state = self.pending_invoking_states.last().copied()?;
6849 let state_number = usize::try_from(invoking_state).ok()?;
6850 match atn.state(state_number)?.transitions().first()?.data() {
6851 Transition::Rule { follow_state, .. } => Some(follow_state),
6852 _ => None,
6853 }
6854 }
6855
6856 #[cfg(test)]
6857 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
6858 caller_follow_token_info_for_stream(&mut self.input, index)
6859 }
6860
6861 fn fast_recognize_top(
6866 &mut self,
6867 atn: &Atn,
6868 request: FastRecognizeTopRequest,
6869 predicate_context: Option<FastPredicateContext<'_>>,
6870 ) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
6871 let FastRecognizeTopRequest {
6872 start_state,
6873 stop_state,
6874 start_index,
6875 precedence,
6876 caller_follow_state,
6877 } = request;
6878 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
6887 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
6888 recognize_scratch.prepare(memo_capacity);
6889 let mut expected = ExpectedTokens::default();
6890 let empty_recovery = self.empty_recovery_symbols();
6891 let outcomes = self.recognize_state_fast(
6892 atn,
6893 FastRecognizeRequest {
6894 state_number: start_state,
6895 stop_state,
6896 index: start_index,
6897 rule_start_index: start_index,
6898 decision_start_index: None,
6899 precedence,
6900 depth: 0,
6901 recovery_symbols: empty_recovery,
6902 recovery_state: None,
6903 },
6904 FastRecognizeScratch {
6905 predicate_context,
6906 visiting: &mut recognize_scratch.visiting,
6907 memo: &mut recognize_scratch.memo,
6908 expected: &mut expected,
6909 native_depth: 0,
6910 },
6911 );
6912 recognize_scratch.release_oversized_memo();
6913 self.fast_recognize_scratch = recognize_scratch;
6914 #[cfg(feature = "perf-counters")]
6915 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
6916 perf_counters::dump();
6917 perf_counters::reset();
6918 }
6919 let caller_follow =
6920 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
6921 let selected = {
6922 let arena = &self.recognition_arena;
6923 let input = &mut self.input;
6924 select_best_fast_outcome(
6925 outcomes.into_iter(),
6926 self.prediction_mode,
6927 caller_follow.as_deref(),
6928 |index| caller_follow_token_info_for_stream(input, index),
6929 arena,
6930 )
6931 };
6932 match selected {
6933 Some(mut outcome) => {
6934 let alt_number = if self.build_parse_trees || self.fast_track_alt_numbers {
6935 self.materialize_fast_outcome_nodes(&mut outcome)
6936 } else {
6937 0
6938 };
6939 Ok((outcome, expected, alt_number))
6940 }
6941 None => Err(expected),
6942 }
6943 }
6944
6945 fn arena_recognized_node_tree(
6947 &mut self,
6948 node_id: RecognizedNodeId,
6949 track_alt_numbers: bool,
6950 track_context_alt_numbers: bool,
6951 ) -> Result<ParseTree, AntlrError> {
6952 let node = self.recognition_arena.node(node_id);
6953 match node {
6954 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
6955 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
6956 ArenaRecognizedNode::MissingToken { extra } => {
6957 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
6958 RecognitionExtra::MissingToken {
6959 token_type,
6960 at_index,
6961 text,
6962 } => (*token_type, *at_index as usize, text.clone()),
6963 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
6964 unreachable!("missing-token node must reference missing-token extra")
6965 }
6966 };
6967 let (line, column) = self
6968 .token_at(at_index)
6969 .map_or((0, 0), |token| (token.line(), token.column()));
6970 let token = self.insert_synthetic_token(token_type, text, line, column)?;
6971 Ok(self.error_tree(token))
6972 }
6973 ArenaRecognizedNode::Rule {
6974 rule_index,
6975 invoking_state,
6976 alt_number,
6977 start_index,
6978 stop_index,
6979 return_values,
6980 children,
6981 } => {
6982 let mut context = ParserRuleContext::with_child_capacity(
6983 rule_index as usize,
6984 invoking_state as isize,
6985 self.recognition_arena.sequence_len(children),
6986 );
6987 if track_alt_numbers {
6988 context.set_alt_number((alt_number as usize).max(1));
6989 }
6990 if track_context_alt_numbers {
6991 context.set_context_alt_number(alt_number as usize);
6992 }
6993 if let Some(extra) = return_values {
6994 let RecognitionExtra::ReturnValues(values) =
6995 self.recognition_arena.extra(extra)
6996 else {
6997 unreachable!("rule node must reference return-values extra");
6998 };
6999 for (name, value) in values {
7000 context.set_int_return(name.clone(), *value);
7001 }
7002 }
7003 if let Some(token) = self.token_id_at(start_index as usize) {
7004 self.set_context_start(&mut context, token);
7005 }
7006 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7007 self.set_context_stop(&mut context, token);
7008 }
7009 let mut cursor = self
7010 .recognition_arena
7011 .fold_left_recursive_boundaries(children);
7012 while let Some(link) = self.recognition_arena.link(cursor) {
7013 let child = self.arena_recognized_node_tree(
7014 link.head,
7015 track_alt_numbers,
7016 track_context_alt_numbers,
7017 )?;
7018 self.tree.add_child(&mut context, child);
7019 cursor = link.tail;
7020 }
7021 Ok(self.rule_node(context))
7022 }
7023 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index, .. } => {
7024 Err(AntlrError::Unsupported(format!(
7025 "unfolded left-recursive boundary for rule {rule_index}"
7026 )))
7027 }
7028 }
7029 }
7030
7031 fn arena_recognized_node_tree_with_implicit_tokens(
7032 &mut self,
7033 node_id: RecognizedNodeId,
7034 alt_tracking: AltNumberTracking,
7035 ) -> Result<ParseTree, AntlrError> {
7036 let node = self.recognition_arena.node(node_id);
7037 match node {
7038 ArenaRecognizedNode::Rule {
7039 rule_index,
7040 invoking_state,
7041 alt_number,
7042 start_index,
7043 stop_index,
7044 children,
7045 ..
7046 } => {
7047 let mut context = ParserRuleContext::with_child_capacity(
7048 rule_index as usize,
7049 invoking_state as isize,
7050 self.recognition_arena.sequence_len(children),
7051 );
7052 if alt_tracking.public {
7053 context.set_alt_number((alt_number as usize).max(1));
7054 }
7055 if alt_tracking.context {
7056 context.set_context_alt_number(alt_number as usize);
7057 }
7058 if let Some(token) = self.token_id_at(start_index as usize) {
7059 self.set_context_start(&mut context, token);
7060 }
7061 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7062 self.set_context_stop(&mut context, token);
7063 }
7064 let children = self
7065 .recognition_arena
7066 .fold_left_recursive_boundaries(children);
7067 self.add_arena_implicit_token_children(
7068 &mut context,
7069 start_index as usize,
7070 stop_index.map(|index| index as usize),
7071 children,
7072 alt_tracking,
7073 )?;
7074 Ok(self.rule_node(context))
7075 }
7076 _ => {
7077 self.arena_recognized_node_tree(node_id, alt_tracking.public, alt_tracking.context)
7078 }
7079 }
7080 }
7081
7082 fn add_arena_implicit_token_children(
7083 &mut self,
7084 context: &mut ParserRuleContext,
7085 start_index: usize,
7086 stop_index: Option<usize>,
7087 mut children: NodeSeqId,
7088 alt_tracking: AltNumberTracking,
7089 ) -> Result<(), AntlrError> {
7090 let mut cursor = Some(start_index);
7091 while let Some(link) = self.recognition_arena.link(children) {
7092 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
7093 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
7094 let child =
7095 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7096 self.tree.add_child(context, child);
7097 if let Some(child_stop) = child_stop {
7098 let next = self.next_visible_after_token(child_stop);
7099 cursor = match (cursor, next) {
7100 (None, _) | (_, None) => None,
7101 (Some(current), Some(next)) => Some(current.max(next)),
7102 };
7103 }
7104 } else {
7105 let child =
7106 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7107 self.tree.add_child(context, child);
7108 }
7109 children = link.tail;
7110 }
7111 if let Some(stop) = stop_index {
7112 self.add_visible_terminals_through(context, cursor, stop)?;
7113 }
7114 Ok(())
7115 }
7116
7117 fn add_visible_terminals_before(
7118 &mut self,
7119 context: &mut ParserRuleContext,
7120 cursor: &mut Option<usize>,
7121 before: usize,
7122 ) -> Result<(), AntlrError> {
7123 let Some(stop) = before.checked_sub(1) else {
7124 return Ok(());
7125 };
7126 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
7127 *cursor = next;
7128 Ok(())
7129 }
7130
7131 fn add_visible_terminals_through(
7132 &mut self,
7133 context: &mut ParserRuleContext,
7134 mut cursor: Option<usize>,
7135 stop: usize,
7136 ) -> Result<Option<usize>, AntlrError> {
7137 while let Some(index) = cursor {
7138 if index > stop {
7139 return Ok(Some(index));
7140 }
7141 let token = self
7142 .input
7143 .get_id(index)
7144 .ok_or_else(|| AntlrError::ParserError {
7145 line: 0,
7146 column: 0,
7147 message: format!("missing token at index {index}"),
7148 })?;
7149 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
7150 let child = self.terminal_tree(token);
7151 self.tree.add_child(context, child);
7152 if is_eof {
7153 return Ok(None);
7154 }
7155 cursor = self.next_visible_after_token(index);
7156 }
7157 Ok(None)
7158 }
7159
7160 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
7161 let next = self.input.next_visible_after(index);
7162 (next != index).then_some(next)
7163 }
7164
7165 pub fn parse_atn_rule_with_actions(
7172 &mut self,
7173 atn: &Atn,
7174 rule_index: usize,
7175 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7176 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
7177 }
7178
7179 pub fn parse_atn_rule_with_action_inits(
7187 &mut self,
7188 atn: &Atn,
7189 rule_index: usize,
7190 init_action_rules: &[usize],
7191 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7192 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
7193 }
7194
7195 pub fn parse_atn_rule_with_action_options(
7201 &mut self,
7202 atn: &Atn,
7203 rule_index: usize,
7204 init_action_rules: &[usize],
7205 track_alt_numbers: bool,
7206 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7207 self.parse_atn_rule_with_runtime_options(
7208 atn,
7209 rule_index,
7210 ParserRuntimeOptions {
7211 init_action_rules,
7212 track_alt_numbers,
7213 ..ParserRuntimeOptions::default()
7214 },
7215 )
7216 }
7217
7218 pub fn parse_atn_rule_with_runtime_options(
7225 &mut self,
7226 atn: &Atn,
7227 rule_index: usize,
7228 options: ParserRuntimeOptions<'_>,
7229 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7230 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
7231 }
7232
7233 pub fn parse_atn_rule_with_runtime_options_and_precedence(
7236 &mut self,
7237 atn: &Atn,
7238 rule_index: usize,
7239 precedence: i32,
7240 options: ParserRuntimeOptions<'_>,
7241 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7242 let ParserRuntimeOptions {
7243 init_action_rules,
7244 track_alt_numbers,
7245 track_context_alt_numbers,
7246 predicates,
7247 semantics,
7248 rule_args,
7249 member_actions,
7250 return_actions,
7251 unknown_predicate_policy,
7252 } = options;
7253 let capture_alt_numbers = track_alt_numbers || track_context_alt_numbers;
7254 if init_action_rules.is_empty()
7255 && !capture_alt_numbers
7256 && predicates.is_empty()
7257 && semantics.is_none()
7258 && rule_args.is_empty()
7259 && member_actions.is_empty()
7260 && return_actions.is_empty()
7261 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
7262 && !atn_has_observable_action_transitions(atn)
7263 && !self.semantic_hooks.observes_parser_decisions()
7264 && (!self.semantic_hooks.observes_parser_predicates()
7265 || !atn_has_predicate_transitions(atn))
7266 {
7267 return self
7268 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
7269 .map(|tree| (tree, Vec::new()));
7270 }
7271 if !self.semantic_hooks.observes_parser_decisions()
7272 && can_use_fast_predicate_recognizer(atn, &options)
7273 {
7274 self.unknown_predicate_policy = unknown_predicate_policy;
7275 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7276 let member_values = self.int_members.clone();
7277 let result = self
7278 .parse_atn_rule_with_precedence_inner(
7279 atn,
7280 rule_index,
7281 precedence,
7282 Some(FastPredicateContext {
7283 predicates,
7284 semantics,
7285 member_values: &member_values,
7286 }),
7287 AltNumberTracking {
7288 public: track_alt_numbers,
7289 context: track_context_alt_numbers,
7290 },
7291 )
7292 .map(|tree| (tree, Vec::new()));
7293 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
7294 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7295 }
7296 return result;
7297 }
7298 self.unknown_predicate_policy = unknown_predicate_policy;
7299 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7306 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7307 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7308 })?;
7309 let stop_state = atn
7310 .rule_to_stop_state()
7311 .get(rule_index)
7312 .filter(|state| *state != usize::MAX)
7313 .ok_or_else(|| {
7314 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7315 })?;
7316
7317 let start_index = self.current_visible_index();
7318 self.clear_prediction_diagnostics();
7319 self.reset_per_parse_caches();
7320 self.reset_recognition_arena();
7321 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
7322 let invoking_state = self.pending_invoking_states.pop();
7323 let local_int_arg = invoking_state
7324 .and_then(|state| usize::try_from(state).ok())
7325 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
7326 let mut visiting = BTreeSet::new();
7327 let mut memo = BTreeMap::new();
7328 let mut expected = ExpectedTokens::default();
7329 let member_values = self.int_members.clone();
7330 let return_values = BTreeMap::new();
7331 let outcomes = self.recognize_state(
7332 atn,
7333 RecognizeRequest {
7334 state_number: start_state,
7335 stop_state,
7336 index: start_index,
7337 rule_start_index: start_index,
7338 decision_start_index: None,
7339 init_action_rules: &init_action_rules,
7340 predicates,
7341 semantics,
7342 rule_args,
7343 member_actions,
7344 return_actions,
7345 local_int_arg,
7346 member_values,
7347 return_values,
7348 rule_alt_number: 0,
7349 track_alt_numbers: capture_alt_numbers,
7350 consumed_eof: false,
7351 committed_decision: false,
7352 precedence,
7353 depth: 0,
7354 recovery_symbols: BTreeSet::new(),
7355 recovery_state: None,
7356 },
7357 &mut visiting,
7358 &mut memo,
7359 &mut expected,
7360 );
7361 if let Some(error) = self.unknown_semantic_error() {
7362 self.report_token_source_errors();
7363 return Err(error);
7370 }
7371 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7374 let Some(outcome) = select_best_outcome(
7375 outcomes.into_iter(),
7376 self.prediction_mode,
7377 &self.recognition_arena,
7378 ) else {
7379 let error = self.recognition_error(rule_index, start_index, &expected);
7380 self.record_syntax_errors(1);
7381 self.report_token_source_errors();
7382 return Err(error);
7383 };
7384
7385 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7386 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7387 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7388 self.report_token_source_errors();
7389 let mut actions = outcome.actions;
7390 if init_action_rules.contains(&rule_index) {
7391 actions.insert(
7392 0,
7393 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
7394 );
7395 }
7396 let mut context =
7397 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
7398 if track_alt_numbers {
7399 context.set_alt_number(outcome.alt_number.max(1));
7400 }
7401 if track_context_alt_numbers {
7402 context.set_context_alt_number(outcome.alt_number);
7403 }
7404 for (name, value) in outcome.return_values {
7405 context.set_int_return(name, value);
7406 }
7407 if let Some(token) = self.token_id_at(start_index) {
7408 self.set_context_start(&mut context, token);
7409 }
7410 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
7411 self.set_context_stop(&mut context, token);
7412 }
7413 let live_root = if self.build_parse_trees {
7414 self.recognition_arena
7415 .fold_left_recursive_boundaries(outcome.nodes)
7416 } else {
7417 outcome.nodes
7418 };
7419 if self.build_parse_trees {
7420 let mut nodes = live_root;
7421 while let Some(link) = self.recognition_arena.link(nodes) {
7422 let child = self.arena_recognized_node_tree(
7423 link.head,
7424 track_alt_numbers,
7425 track_context_alt_numbers,
7426 )?;
7427 self.tree.add_child(&mut context, child);
7428 nodes = link.tail;
7429 }
7430 }
7431 self.finish_recognition_arena(live_root, outcome.diagnostics);
7432 self.input.seek(outcome.index);
7433
7434 let tree = self.rule_node(context);
7435 self.release_tree_scratch_if_idle();
7436 Ok((tree, actions))
7437 }
7438
7439 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
7446 let mut context = ParserRuleContext::new(rule_index, self.state());
7447 while self.la(1) != TOKEN_EOF {
7448 let token_type = self.la(1);
7449 let child = self.match_token(token_type)?;
7450 if self.build_parse_trees {
7451 self.tree.add_child(&mut context, child);
7452 }
7453 }
7454 if self.build_parse_trees {
7455 let child = self.match_eof()?;
7456 self.tree.add_child(&mut context, child);
7457 }
7458 let tree = self.rule_node(context);
7459 self.release_tree_scratch_if_idle();
7460 Ok(tree)
7461 }
7462
7463 fn recognition_error(
7466 &mut self,
7467 rule_index: usize,
7468 start_index: usize,
7469 expected: &ExpectedTokens,
7470 ) -> AntlrError {
7471 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
7472 self.input.seek(index);
7473 let current = self.input.lt(1);
7474 let line = current.as_ref().map(Token::line).unwrap_or_default();
7475 let column = current.as_ref().map(Token::column).unwrap_or_default();
7476 AntlrError::ParserError {
7477 line,
7478 column,
7479 message,
7480 }
7481 }
7482
7483 fn expected_error_message(
7485 &mut self,
7486 rule_index: usize,
7487 start_index: usize,
7488 expected: &ExpectedTokens,
7489 ) -> (usize, String) {
7490 let index = expected
7491 .index
7492 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
7493 .unwrap_or_else(|| self.input.index());
7494 self.input.seek(index);
7495 let current = self.input.lt(1);
7496 let message = if expected
7497 .no_viable
7498 .as_ref()
7499 .is_some_and(|no_viable| no_viable.error_index == index)
7500 {
7501 let start = expected
7502 .no_viable
7503 .as_ref()
7504 .map_or(start_index, |no_viable| no_viable.start_index);
7505 let text = display_input_text(&self.input.text(start, index));
7506 format!("no viable alternative at input '{text}'")
7507 } else if expected.symbols.is_empty() {
7508 if expected.index.is_some() {
7509 let found = current
7510 .as_ref()
7511 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
7512 if current
7513 .as_ref()
7514 .is_some_and(|token| token.token_type() == TOKEN_EOF)
7515 {
7516 format!(
7517 "missing {} at {found}",
7518 self.expected_symbols_display(&expected.symbols)
7519 )
7520 } else {
7521 format!("mismatched input {found}")
7522 }
7523 } else {
7524 format!("no viable alternative while parsing rule {rule_index}")
7525 }
7526 } else {
7527 format!(
7528 "mismatched input {} expecting {}",
7529 current
7530 .as_ref()
7531 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7532 self.expected_symbols_display(&expected.symbols)
7533 )
7534 };
7535 (index, message)
7536 }
7537
7538 fn child_rule_failure_recovery(
7541 &mut self,
7542 rule_index: usize,
7543 start_index: usize,
7544 sync_symbols: &BTreeSet<i32>,
7545 member_values: BTreeMap<usize, i64>,
7546 expected: &ExpectedTokens,
7547 ) -> Option<RecognizeOutcome> {
7548 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7549 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7550 let mut next_index = error_index;
7551 loop {
7552 let symbol = self.token_type_at(next_index);
7553 if sync_symbols.contains(&symbol) {
7554 if next_index == error_index {
7555 return None;
7556 }
7557 break;
7558 }
7559 if symbol == TOKEN_EOF {
7560 break;
7561 }
7562 let after = self.consume_index(next_index, symbol);
7563 if after == next_index {
7564 break;
7565 }
7566 next_index = after;
7567 }
7568 let mut nodes = NodeSeqId::EMPTY;
7569 let error = self.arena_token_node(error_index, true);
7570 self.arena_prepend(&mut nodes, error);
7571 let diagnostics = self
7572 .recognition_arena
7573 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7574 Some(RecognizeOutcome {
7575 index: next_index,
7576 consumed_eof: false,
7577 alt_number: 0,
7578 member_values,
7579 return_values: BTreeMap::new(),
7580 diagnostics,
7581 decisions: Vec::new(),
7582 actions: Vec::new(),
7583 nodes,
7584 })
7585 }
7586
7587 fn child_rule_failure_recovery_outcomes(
7590 &mut self,
7591 request: ChildRuleFailureRecovery<'_>,
7592 ) -> Vec<RecognizeOutcome> {
7593 let sync_symbols =
7594 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
7595 self.child_rule_failure_recovery(
7596 request.rule_index,
7597 request.start_index,
7598 &sync_symbols,
7599 request.member_values,
7600 request.expected,
7601 )
7602 .into_iter()
7603 .collect()
7604 }
7605
7606 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
7608 expected_symbols_display(symbols, self.vocabulary())
7609 }
7610
7611 fn single_token_deletion(
7614 &mut self,
7615 transition: ParserTransition<'_>,
7616 index: usize,
7617 max_token_type: i32,
7618 expected_symbols: &BTreeSet<i32>,
7619 ) -> Option<(ParserDiagnostic, usize, i32)> {
7620 let current_symbol = self.token_type_at(index);
7621 if current_symbol == TOKEN_EOF {
7622 return None;
7623 }
7624 let next_index = self.consume_index(index, current_symbol);
7625 if next_index == index {
7626 return None;
7627 }
7628 let next_symbol = self.token_type_at(next_index);
7629 if !transition.matches(next_symbol, 1, max_token_type) {
7630 return None;
7631 }
7632 let transition_expected = transition_expected_symbols(transition, max_token_type);
7633 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7634 &transition_expected
7635 } else {
7636 expected_symbols
7637 });
7638 let current = self.token_at(index);
7639 let message = format!(
7640 "extraneous input {} expecting {expected_display}",
7641 current
7642 .as_ref()
7643 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7644 );
7645 Some((
7646 diagnostic_for_token(current, message),
7647 next_index,
7648 next_symbol,
7649 ))
7650 }
7651
7652 fn current_token_deletion(
7655 &mut self,
7656 index: usize,
7657 expected_symbols: &BTreeSet<i32>,
7658 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
7659 if expected_symbols.is_empty() {
7660 return None;
7661 }
7662 let current_symbol = self.token_type_at(index);
7663 if current_symbol == TOKEN_EOF {
7664 return None;
7665 }
7666 let current = self.token_at(index);
7667 let message = format!(
7668 "extraneous input {} expecting {}",
7669 current
7670 .as_ref()
7671 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7672 self.expected_symbols_display(expected_symbols)
7673 );
7674 let diagnostic = diagnostic_for_token(current, message);
7675 let mut skipped = Vec::new();
7676 let mut cursor = index;
7677 loop {
7678 let symbol = self.token_type_at(cursor);
7679 if symbol == TOKEN_EOF {
7680 return None;
7681 }
7682 skipped.push(cursor);
7683 let next_index = self.consume_index(cursor, symbol);
7684 if next_index == cursor {
7685 return None;
7686 }
7687 let next_symbol = self.token_type_at(next_index);
7688 if expected_symbols.contains(&next_symbol) {
7689 return Some((diagnostic, next_index, skipped));
7690 }
7691 cursor = next_index;
7692 }
7693 }
7694
7695 fn single_token_insertion(
7699 &mut self,
7700 transition: ParserTransition<'_>,
7701 index: usize,
7702 max_token_type: i32,
7703 expected_symbols: &BTreeSet<i32>,
7704 follow_symbols: &BTreeSet<i32>,
7705 ) -> Option<(ParserDiagnostic, i32, String)> {
7706 let current_symbol = self.token_type_at(index);
7707 if !follow_symbols.contains(¤t_symbol) {
7708 return None;
7709 }
7710 let transition_expected = transition_expected_symbols(transition, max_token_type);
7711 let token_type = transition_expected.iter().next().copied()?;
7712 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7713 &transition_expected
7714 } else {
7715 expected_symbols
7716 });
7717 let mut token_symbols = BTreeSet::new();
7718 token_symbols.insert(token_type);
7719 let missing_token_display = self.expected_symbols_display(&token_symbols);
7720 let current = self.token_at(index);
7721 let message = format!(
7722 "missing {expected_display} at {}",
7723 current
7724 .as_ref()
7725 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7726 );
7727 let text = format!("<missing {missing_token_display}>");
7728 Some((
7729 diagnostic_for_token(current.as_ref(), message),
7730 token_type,
7731 text,
7732 ))
7733 }
7734
7735 fn fast_single_token_deletion_recovery(
7739 &mut self,
7740 recovery: FastRecoveryRequest<'_, '_>,
7741 predicate_context: Option<FastPredicateContext<'_>>,
7742 ) -> Vec<FastRecognizeOutcome> {
7743 let FastRecoveryRequest {
7744 atn,
7745 transition,
7746 expected_symbols,
7747 target,
7748 request,
7749 visiting,
7750 memo,
7751 expected,
7752 } = recovery;
7753 let FastRecognizeRequest {
7754 stop_state,
7755 index,
7756 rule_start_index,
7757 decision_start_index,
7758 precedence,
7759 depth,
7760 ..
7761 } = request;
7762 let Some((diagnostic, next_index, next_symbol)) =
7763 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
7764 else {
7765 return Vec::new();
7766 };
7767 let after_next = self.consume_index(next_index, next_symbol);
7768 let empty_recovery = self.empty_recovery_symbols();
7769 self.recognize_state_fast(
7770 atn,
7771 FastRecognizeRequest {
7772 state_number: target,
7773 stop_state,
7774 index: after_next,
7775 rule_start_index,
7776 decision_start_index,
7777 precedence,
7778 depth: depth + 1,
7779 recovery_symbols: empty_recovery,
7780 recovery_state: None,
7781 },
7782 FastRecognizeScratch {
7783 predicate_context,
7784 visiting,
7785 memo,
7786 expected,
7787 native_depth: 0,
7788 },
7789 )
7790 .into_iter()
7791 .map(|mut outcome| {
7792 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
7793 outcome.diagnostics = self
7794 .recognition_arena
7795 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7796 if self.fast_token_nodes_enabled {
7797 let token = self.arena_token_node(next_index, false);
7798 self.defer_fast_outcome_node(&mut outcome, token);
7799 let error = self.arena_token_node(index, true);
7800 self.defer_fast_outcome_node(&mut outcome, error);
7801 }
7802 outcome
7803 })
7804 .collect()
7805 }
7806
7807 fn fast_single_token_insertion_recovery(
7811 &mut self,
7812 recovery: FastRecoveryRequest<'_, '_>,
7813 predicate_context: Option<FastPredicateContext<'_>>,
7814 ) -> Vec<FastRecognizeOutcome> {
7815 let FastRecoveryRequest {
7816 atn,
7817 transition,
7818 expected_symbols,
7819 target,
7820 request,
7821 visiting,
7822 memo,
7823 expected,
7824 } = recovery;
7825 let FastRecognizeRequest {
7826 stop_state,
7827 index,
7828 rule_start_index,
7829 decision_start_index,
7830 precedence,
7831 depth,
7832 ..
7833 } = request;
7834 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
7835 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
7836 transition,
7837 index,
7838 atn.max_token_type(),
7839 &expected_symbols,
7840 &follow_symbols,
7841 ) else {
7842 return Vec::new();
7843 };
7844 let empty_recovery = self.empty_recovery_symbols();
7845 self.recognize_state_fast(
7846 atn,
7847 FastRecognizeRequest {
7848 state_number: target,
7849 stop_state,
7850 index,
7851 rule_start_index,
7852 decision_start_index,
7853 precedence,
7854 depth: depth + 1,
7855 recovery_symbols: empty_recovery,
7856 recovery_state: None,
7857 },
7858 FastRecognizeScratch {
7859 predicate_context,
7860 visiting,
7861 memo,
7862 expected,
7863 native_depth: 0,
7864 },
7865 )
7866 .into_iter()
7867 .map(|mut outcome| {
7868 outcome.diagnostics = self
7869 .recognition_arena
7870 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7871 let missing = self.arena_missing_token_node(token_type, index, text.clone());
7872 self.defer_fast_outcome_node(&mut outcome, missing);
7873 outcome
7874 })
7875 .collect()
7876 }
7877
7878 fn fast_current_token_deletion_recovery(
7881 &mut self,
7882 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
7883 predicate_context: Option<FastPredicateContext<'_>>,
7884 ) -> Vec<FastRecognizeOutcome> {
7885 let FastCurrentTokenDeletionRequest {
7886 atn,
7887 expected_symbols,
7888 mut request,
7889 visiting,
7890 memo,
7891 expected,
7892 } = recovery;
7893 if request.index == request.rule_start_index {
7894 return Vec::new();
7895 }
7896 let Some((diagnostic, next_index, skipped)) =
7897 self.current_token_deletion(request.index, &expected_symbols)
7898 else {
7899 return Vec::new();
7900 };
7901 request.state_number = request.recovery_state.unwrap_or(request.state_number);
7902 request.index = next_index;
7903 request.depth += 1;
7904 request.recovery_state = None;
7905 self.recognize_state_fast(
7906 atn,
7907 request,
7908 FastRecognizeScratch {
7909 predicate_context,
7910 visiting,
7911 memo,
7912 expected,
7913 native_depth: 0,
7914 },
7915 )
7916 .into_iter()
7917 .map(|mut outcome| {
7918 outcome.diagnostics = self
7919 .recognition_arena
7920 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7921 for index in skipped.iter().rev() {
7922 let error = self.arena_token_node(*index, true);
7923 self.defer_fast_outcome_node(&mut outcome, error);
7924 }
7925 outcome
7926 })
7927 .collect()
7928 }
7929
7930 fn fast_child_rule_failure_recovery(
7933 &mut self,
7934 rule_index: usize,
7935 start_index: usize,
7936 sync_symbols: &BTreeSet<i32>,
7937 expected: &ExpectedTokens,
7938 ) -> Option<FastRecognizeOutcome> {
7939 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7940 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7941 let mut next_index = error_index;
7942 loop {
7943 let symbol = self.token_type_at(next_index);
7944 if sync_symbols.contains(&symbol) {
7945 if next_index == error_index {
7946 return None;
7947 }
7948 break;
7949 }
7950 if symbol == TOKEN_EOF {
7951 break;
7952 }
7953 let after = self.consume_index(next_index, symbol);
7954 if after == next_index {
7955 break;
7956 }
7957 next_index = after;
7958 }
7959 let diagnostics = self
7960 .recognition_arena
7961 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7962 let mut nodes = NodeSeqId::EMPTY;
7963 if self.fast_token_nodes_enabled {
7964 let error = self.arena_token_node(error_index, true);
7965 self.arena_prepend(&mut nodes, error);
7966 }
7967 Some(FastRecognizeOutcome {
7968 index: next_index,
7969 consumed_eof: false,
7970 diagnostics,
7971 deferred_nodes: FastDeferredNodeId::EMPTY,
7972 nodes,
7973 })
7974 }
7975
7976 fn fast_child_rule_failure_recovery_outcomes(
7979 &mut self,
7980 request: FastChildRuleFailureRecoveryRequest<'_>,
7981 ) -> Vec<FastRecognizeOutcome> {
7982 let FastChildRuleFailureRecoveryRequest {
7983 atn,
7984 rule_index,
7985 start_index,
7986 follow_state,
7987 stop_state,
7988 expected,
7989 } = request;
7990 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
7991 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
7992 .into_iter()
7993 .collect()
7994 }
7995
7996 fn defer_fast_outcome_node(
7997 &mut self,
7998 outcome: &mut FastRecognizeOutcome,
7999 node: RecognizedNodeId,
8000 ) {
8001 if outcome.deferred_nodes.is_empty() {
8002 self.arena_prepend(&mut outcome.nodes, node);
8003 return;
8004 }
8005 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
8006 let fragment = self.recognition_arena.deferred_fragment(fragment);
8007 outcome.deferred_nodes = self
8008 .recognition_arena
8009 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
8010 }
8011
8012 fn defer_fast_outcome_alternative(
8013 &mut self,
8014 outcome: &mut FastRecognizeOutcome,
8015 alt_number: usize,
8016 ) {
8017 let alternative = self.recognition_arena.deferred_alternative(alt_number);
8018 outcome.deferred_nodes = self
8019 .recognition_arena
8020 .concat_deferred_nodes(alternative, outcome.deferred_nodes);
8021 }
8022
8023 fn defer_fast_outcome_boundary(
8024 &mut self,
8025 outcome: &mut FastRecognizeOutcome,
8026 rule_index: usize,
8027 ) {
8028 let boundary = self
8029 .recognition_arena
8030 .deferred_left_recursive_boundary(rule_index);
8031 outcome.deferred_nodes = self
8032 .recognition_arena
8033 .concat_deferred_nodes(boundary, outcome.deferred_nodes);
8034 }
8035
8036 fn materialize_fast_deferred_nodes(
8037 &mut self,
8038 root: FastDeferredNodeId,
8039 initial_suffix: NodeSeqId,
8040 ) -> (NodeSeqId, usize) {
8041 if root.is_empty() {
8042 return (initial_suffix, 0);
8043 }
8044
8045 enum Frame {
8046 Visit(FastDeferredNodeId),
8047 ContinuePrefix(FastDeferredNodeId),
8048 FinishRule {
8049 rule: FastDeferredRule,
8050 parent_suffix: NodeSeqId,
8051 parent_alt_number: u32,
8052 parent_pending_boundary: Option<RecognizedNodeId>,
8053 },
8054 }
8055
8056 let mut result = initial_suffix;
8057 let mut alt_number = 0;
8061 let mut pending_boundary = None;
8062 let mut pending = Vec::with_capacity(16);
8063 pending.push(Frame::Visit(root));
8064 let mut fragment_nodes = Vec::new();
8065 while let Some(frame) = pending.pop() {
8066 match frame {
8067 Frame::Visit(deferred) => {
8068 if deferred.is_empty() {
8069 continue;
8070 }
8071
8072 match self.recognition_arena.deferred_node(deferred) {
8073 FastDeferredNode::Fragment(sequence) => {
8074 fragment_nodes.clear();
8075 fragment_nodes.extend(self.recognition_arena.iter(sequence));
8076 while let Some(node) = fragment_nodes.pop() {
8077 self.arena_prepend(&mut result, node);
8078 }
8079 }
8080 FastDeferredNode::Rule(rule) => {
8081 let rule = self.recognition_arena.deferred_rule(rule);
8082 let parent_suffix = result;
8083 let parent_alt_number = alt_number;
8084 let parent_pending_boundary = pending_boundary;
8085 result = rule.children;
8086 alt_number = 0;
8087 pending_boundary = None;
8088 pending.push(Frame::FinishRule {
8089 rule,
8090 parent_suffix,
8091 parent_alt_number,
8092 parent_pending_boundary,
8093 });
8094 pending.push(Frame::Visit(rule.deferred_children));
8095 }
8096 FastDeferredNode::Alternative(selected) => {
8097 if let Some(boundary) = pending_boundary {
8098 self.recognition_arena
8099 .set_boundary_alt_number(boundary, selected);
8100 } else {
8101 alt_number = selected;
8102 }
8103 }
8104 FastDeferredNode::LeftRecursiveBoundary { rule_index } => {
8105 let boundary = self.arena_boundary_node(rule_index as usize, 0);
8106 self.arena_prepend(&mut result, boundary);
8107 pending_boundary = Some(boundary);
8108 }
8109 FastDeferredNode::Concat {
8110 prefix,
8111 suffix: deferred_suffix,
8112 } => {
8113 pending.push(Frame::ContinuePrefix(prefix));
8114 pending.push(Frame::Visit(deferred_suffix));
8115 }
8116 }
8117 }
8118 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
8119 Frame::FinishRule {
8120 rule,
8121 parent_suffix,
8122 parent_alt_number,
8123 parent_pending_boundary,
8124 } => {
8125 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
8126 rule_index: rule.rule_index,
8127 invoking_state: rule.invoking_state,
8128 alt_number,
8129 start_index: rule.start_index,
8130 stop_index: rule.stop_index,
8131 return_values: None,
8132 children: result,
8133 });
8134 result = parent_suffix;
8135 self.arena_prepend(&mut result, node);
8136 alt_number = parent_alt_number;
8137 pending_boundary = parent_pending_boundary;
8138 }
8139 }
8140 }
8141 (result, alt_number as usize)
8142 }
8143
8144 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) -> usize {
8145 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
8146 let (nodes, alt_number) =
8147 self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
8148 outcome.nodes = nodes;
8149 alt_number
8150 }
8151
8152 fn recognize_repetition_fast(
8155 &mut self,
8156 atn: &Atn,
8157 request: &FastRecognizeRequest,
8158 shape: FastRepetitionShape,
8159 scratch: FastRecognizeScratch<'_, '_>,
8160 ) -> Vec<FastRecognizeOutcome> {
8161 let FastRecognizeScratch {
8162 predicate_context,
8163 visiting,
8164 memo,
8165 expected,
8166 native_depth,
8167 } = scratch;
8168 let lookahead = if self.fast_first_set_prefilter {
8169 atn.state(request.state_number).and_then(|state| {
8170 state
8171 .rule_index()
8172 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8173 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
8174 })
8175 } else {
8176 None
8177 };
8178 let (enter_alt_number, exit_alt_number) = if self.fast_track_alt_numbers {
8179 let state = atn
8180 .state(request.state_number)
8181 .expect("repetition request state must exist");
8182 (
8183 next_alt_number(state, 2, shape.enter_transition_index, 0, true),
8184 next_alt_number(state, 2, shape.exit_transition_index, 0, true),
8185 )
8186 } else {
8187 (0, 0)
8188 };
8189 let mut work = Vec::with_capacity(2);
8190 push_fast_repetition_work(
8191 &mut work,
8192 shape,
8193 FastRepetitionPath {
8194 index: request.index,
8195 deferred_nodes: FastDeferredNodeId::EMPTY,
8196 diagnostics: DiagnosticSeqId::EMPTY,
8197 consumed_eof: false,
8198 },
8199 lookahead.as_deref(),
8200 self.token_type_at(request.index),
8201 );
8202 let mut coordinates = FastRepetitionCoordinates::new(request.index);
8203 let mut outcomes = Vec::new();
8204 while let Some(item) = work.pop() {
8205 match item {
8206 FastRepetitionWork::Enter(path) => {
8207 if !coordinates.insert_entered(path) {
8208 continue;
8209 }
8210 let path_nodes = if enter_alt_number == 0 {
8211 path.deferred_nodes
8212 } else {
8213 let alternative = self
8214 .recognition_arena
8215 .deferred_alternative(enter_alt_number);
8216 self.recognition_arena
8217 .concat_deferred_nodes(path.deferred_nodes, alternative)
8218 };
8219 let body_outcomes = self.recognize_state_fast(
8220 atn,
8221 FastRecognizeRequest {
8222 state_number: shape.enter_target,
8223 stop_state: shape.body_stop_state,
8224 index: path.index,
8225 rule_start_index: request.rule_start_index,
8226 decision_start_index: request.decision_start_index,
8227 precedence: request.precedence,
8228 depth: request.depth.saturating_add(1),
8229 recovery_symbols: Rc::clone(&request.recovery_symbols),
8230 recovery_state: request.recovery_state,
8231 },
8232 FastRecognizeScratch {
8233 predicate_context,
8234 visiting: &mut *visiting,
8235 memo: &mut *memo,
8236 expected: &mut *expected,
8237 native_depth: native_depth + 1,
8238 },
8239 );
8240 for body in body_outcomes.into_iter().rev() {
8241 if body.index <= path.index {
8245 continue;
8246 }
8247 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
8248 let body_nodes = self
8249 .recognition_arena
8250 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
8251 let deferred_nodes = self
8252 .recognition_arena
8253 .concat_deferred_nodes(path_nodes, body_nodes);
8254 let next_path = FastRepetitionPath {
8255 index: body.index,
8256 deferred_nodes,
8257 diagnostics: self
8258 .recognition_arena
8259 .concat_diagnostics(path.diagnostics, body.diagnostics),
8260 consumed_eof: path.consumed_eof || body.consumed_eof,
8261 };
8262 let symbol = self.token_type_at(next_path.index);
8263 push_fast_repetition_work(
8264 &mut work,
8265 shape,
8266 next_path,
8267 lookahead.as_deref(),
8268 symbol,
8269 );
8270 }
8271 }
8272 FastRepetitionWork::Exit(path) => {
8273 if !coordinates.insert_exited(path) {
8274 continue;
8275 }
8276 let path_nodes = if exit_alt_number == 0 {
8277 path.deferred_nodes
8278 } else {
8279 let alternative =
8280 self.recognition_arena.deferred_alternative(exit_alt_number);
8281 self.recognition_arena
8282 .concat_deferred_nodes(path.deferred_nodes, alternative)
8283 };
8284 let suffixes = self.recognize_state_fast(
8285 atn,
8286 FastRecognizeRequest {
8287 state_number: shape.exit_target,
8288 stop_state: request.stop_state,
8289 index: path.index,
8290 rule_start_index: request.rule_start_index,
8291 decision_start_index: request.decision_start_index,
8292 precedence: request.precedence,
8293 depth: request.depth.saturating_add(1),
8294 recovery_symbols: Rc::clone(&request.recovery_symbols),
8295 recovery_state: request.recovery_state,
8296 },
8297 FastRecognizeScratch {
8298 predicate_context,
8299 visiting: &mut *visiting,
8300 memo: &mut *memo,
8301 expected: &mut *expected,
8302 native_depth: native_depth + 1,
8303 },
8304 );
8305 for mut outcome in suffixes {
8306 outcome.deferred_nodes = self
8307 .recognition_arena
8308 .concat_deferred_nodes(path_nodes, outcome.deferred_nodes);
8309 outcome.diagnostics = self
8310 .recognition_arena
8311 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
8312 outcome.consumed_eof |= path.consumed_eof;
8313 outcomes.push(outcome);
8314 }
8315 }
8316 }
8317 }
8318 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8319 outcomes
8320 }
8321
8322 fn recognize_state_fast(
8325 &mut self,
8326 atn: &Atn,
8327 request: FastRecognizeRequest,
8328 scratch: FastRecognizeScratch<'_, '_>,
8329 ) -> Vec<FastRecognizeOutcome> {
8330 if scratch.native_depth != 0 && scratch.native_depth < FAST_RECOGNIZE_STACK_CHECK_INTERVAL {
8331 return self.recognize_state_fast_inner(atn, request, scratch);
8332 }
8333 self.recognize_state_fast_checked(atn, request, scratch)
8334 }
8335
8336 #[inline(never)]
8337 fn recognize_state_fast_checked(
8338 &mut self,
8339 atn: &Atn,
8340 request: FastRecognizeRequest,
8341 mut scratch: FastRecognizeScratch<'_, '_>,
8342 ) -> Vec<FastRecognizeOutcome> {
8343 scratch.native_depth = 1;
8344 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, || {
8345 self.recognize_state_fast_inner(atn, request, scratch)
8346 })
8347 }
8348
8349 #[allow(clippy::too_many_lines)]
8350 fn recognize_state_fast_inner(
8351 &mut self,
8352 atn: &Atn,
8353 request: FastRecognizeRequest,
8354 scratch: FastRecognizeScratch<'_, '_>,
8355 ) -> Vec<FastRecognizeOutcome> {
8356 #[cfg(feature = "perf-counters")]
8357 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
8358 let FastRecognizeScratch {
8359 predicate_context,
8360 visiting,
8361 memo,
8362 expected,
8363 native_depth,
8364 } = scratch;
8365 let FastRecognizeRequest {
8366 mut state_number,
8367 stop_state,
8368 mut index,
8369 rule_start_index,
8370 decision_start_index,
8371 precedence,
8372 mut depth,
8373 recovery_symbols,
8374 recovery_state,
8375 } = request;
8376 let max_token_type = atn.max_token_type();
8377 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
8396 let mut inline_consumed_eof = false;
8397 loop {
8398 if depth > RECOGNITION_DEPTH_LIMIT {
8399 return Vec::new();
8400 }
8401 if state_number == stop_state {
8402 let mut nodes = NodeSeqId::EMPTY;
8403 if self.fast_token_nodes_enabled {
8404 for token_index in inline_consumed_tokens.iter().rev() {
8405 let token = self.arena_token_node(*token_index, false);
8406 self.arena_prepend(&mut nodes, token);
8407 }
8408 }
8409 return vec![FastRecognizeOutcome {
8410 index,
8411 consumed_eof: inline_consumed_eof,
8412 diagnostics: DiagnosticSeqId::EMPTY,
8413 deferred_nodes: FastDeferredNodeId::EMPTY,
8414 nodes,
8415 }];
8416 }
8417 let Some(state) = atn.state(state_number) else {
8418 return Vec::new();
8419 };
8420 let transitions = state.transitions();
8421 if transitions.len() == 1 && !state.precedence_rule_decision() {
8422 let transition = transitions
8423 .first()
8424 .expect("single transition checked above");
8425 let transition_kind = transition.kind();
8426 let target = transition.target();
8427 match transition_kind {
8428 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
8429 if left_recursive_boundary(atn, state, target).is_none() =>
8430 {
8431 #[cfg(feature = "perf-counters")]
8432 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8433 state_number = target;
8434 depth += 1;
8435 continue;
8436 }
8437 ParserTransitionKind::Predicate
8438 if left_recursive_boundary(atn, state, target).is_none() =>
8439 {
8440 #[cfg(feature = "perf-counters")]
8441 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8442 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
8443 {
8444 record_predicate_no_viable(expected, decision_start_index, index);
8445 return Vec::new();
8446 }
8447 state_number = target;
8448 depth += 1;
8449 continue;
8450 }
8451 ParserTransitionKind::Precedence
8452 if packed_i32(transition.arg0()) >= precedence
8453 && left_recursive_boundary(atn, state, target).is_none() =>
8454 {
8455 #[cfg(feature = "perf-counters")]
8456 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8457 state_number = target;
8458 depth += 1;
8459 continue;
8460 }
8461 ParserTransitionKind::Atom
8471 | ParserTransitionKind::Range
8472 | ParserTransitionKind::Set
8473 | ParserTransitionKind::NotSet
8474 | ParserTransitionKind::Wildcard
8475 if !self.fast_recovery_enabled =>
8476 {
8477 let symbol = self.token_type_at(index);
8478 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
8479 #[cfg(feature = "perf-counters")]
8480 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
8481 if self.fast_token_nodes_enabled {
8482 inline_consumed_tokens.push(index);
8483 }
8484 inline_consumed_eof |= symbol == TOKEN_EOF;
8485 index = self.consume_index(index, symbol);
8486 state_number = target;
8487 depth += 1;
8488 continue;
8489 }
8490 }
8493 _ => {}
8494 }
8495 }
8496 break;
8497 }
8498 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
8502 let Some(state) = atn.state(state_number) else {
8503 return Vec::new();
8504 };
8505 let transitions = state.transitions();
8506 let transition_count = transitions.len();
8507 if !self.fast_recovery_enabled
8508 && let Some(shape) = fast_repetition_shape(atn, state)
8509 {
8510 let mut outcomes = self.recognize_repetition_fast(
8511 atn,
8512 &FastRecognizeRequest {
8513 state_number,
8514 stop_state,
8515 index,
8516 rule_start_index,
8517 decision_start_index,
8518 precedence,
8519 depth,
8520 recovery_symbols: Rc::clone(&recovery_symbols),
8521 recovery_state,
8522 },
8523 shape,
8524 FastRecognizeScratch {
8525 predicate_context,
8526 visiting: &mut *visiting,
8527 memo: &mut *memo,
8528 expected: &mut *expected,
8529 native_depth: native_depth + 1,
8530 },
8531 );
8532 if inline_pending {
8533 for outcome in &mut outcomes {
8534 outcome.consumed_eof |= inline_consumed_eof;
8535 if self.fast_token_nodes_enabled {
8536 for token_index in inline_consumed_tokens.iter().rev() {
8537 let token = self.arena_token_node(*token_index, false);
8538 self.defer_fast_outcome_node(outcome, token);
8539 }
8540 }
8541 }
8542 }
8543 return outcomes;
8544 }
8545 let key = if self.fast_recovery_enabled {
8555 FastRecognizeKey {
8556 state_number,
8557 stop_state,
8558 index,
8559 rule_start_index,
8560 decision_start_index,
8561 precedence,
8562 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
8563 recovery_state,
8564 }
8565 } else {
8566 FastRecognizeKey {
8567 state_number,
8568 stop_state,
8569 index,
8570 rule_start_index: 0,
8571 decision_start_index: None,
8572 precedence,
8573 recovery_symbols_id: 0,
8574 recovery_state: None,
8575 }
8576 };
8577 let memo_lookup_enabled = self.fast_recovery_enabled
8582 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
8583 if memo_lookup_enabled {
8584 if let Some(outcomes) = memo.get(&key) {
8585 #[cfg(feature = "perf-counters")]
8586 {
8587 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
8588 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
8589 }
8590 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
8594 let inline_eof = inline_consumed_eof;
8595 let inline_tokens = &inline_consumed_tokens;
8596 return outcomes
8597 .iter()
8598 .copied()
8599 .map(|mut outcome| {
8600 if inline_eof {
8601 outcome.consumed_eof = true;
8602 }
8603 if self.fast_token_nodes_enabled {
8604 for token_index in inline_tokens.iter().rev() {
8605 let token = self.arena_token_node(*token_index, false);
8606 self.defer_fast_outcome_node(&mut outcome, token);
8607 }
8608 }
8609 outcome
8610 })
8611 .collect();
8612 }
8613 return outcomes.to_vec();
8614 }
8615 #[cfg(feature = "perf-counters")]
8616 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
8617 }
8618
8619 let needs_cycle_guard = if self.fast_recovery_enabled {
8624 transitions.iter().any(ParserTransition::is_epsilon)
8625 } else {
8626 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
8627 };
8628 #[cfg(feature = "perf-counters")]
8629 if needs_cycle_guard {
8630 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
8631 } else {
8632 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
8633 match state
8634 .transitions()
8635 .first()
8636 .expect("single-transition path requires one transition")
8637 .data()
8638 {
8639 Transition::Rule { .. } => {
8640 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
8641 }
8642 Transition::Atom { .. }
8643 | Transition::Range { .. }
8644 | Transition::Set { .. }
8645 | Transition::NotSet { .. }
8646 | Transition::Wildcard { .. } => {
8647 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
8648 }
8649 _ => {
8650 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
8651 }
8652 }
8653 }
8654 let has_inserted_cycle_guard = if needs_cycle_guard {
8655 if !visiting.insert(key.clone()) {
8656 #[cfg(feature = "perf-counters")]
8657 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
8658 return Vec::new();
8659 }
8660 true
8661 } else {
8662 false
8663 };
8664 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
8665 Some(index)
8666 } else {
8667 decision_start_index
8668 };
8669 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
8670 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
8671 } else {
8672 (Rc::clone(&recovery_symbols), recovery_state)
8673 };
8674
8675 let lookahead_filter = if transition_count > 1
8694 && self.fast_first_set_prefilter
8695 && !state.precedence_rule_decision()
8696 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
8697 {
8698 state
8699 .rule_index()
8700 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8701 .map(|rule_stop| {
8702 let symbol = self.token_type_at(index);
8703 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
8704 (symbol, entry)
8705 })
8706 } else {
8707 None
8708 };
8709 let ll1_only_alt: Option<usize> = if transition_count > 1
8718 && let Some((symbol, entry)) = lookahead_filter.as_ref()
8719 {
8720 let key = (state.state_number(), *symbol);
8721 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
8722 cached
8723 } else {
8724 let result = ll1_unique_alt(entry, *symbol);
8725 self.ll1_decision_cache.insert(key, result);
8726 result
8727 }
8728 } else {
8729 None
8730 };
8731 let lookahead_filter = lookahead_filter.as_ref();
8732 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
8738 for (transition_index, transition) in transitions.iter().enumerate() {
8739 if let Some(alt) = ll1_only_alt {
8740 if alt != transition_index {
8742 continue;
8743 }
8744 }
8745 let transition_kind = transition.kind();
8746 if ll1_only_alt.is_none()
8747 && should_skip_via_lookahead(
8748 transition_kind,
8749 transition_index,
8750 lookahead_filter,
8751 index,
8752 self.fast_recovery_enabled,
8753 expected,
8754 )
8755 {
8756 continue;
8757 }
8758 let target = transition.target();
8759 let outcomes_before_transition = outcomes.len();
8760 let left_recursive_boundary = match transition_kind {
8761 ParserTransitionKind::Epsilon
8762 | ParserTransitionKind::Action
8763 | ParserTransitionKind::Predicate
8764 | ParserTransitionKind::Precedence => left_recursive_boundary(atn, state, target),
8765 ParserTransitionKind::Atom
8766 | ParserTransitionKind::Range
8767 | ParserTransitionKind::Set
8768 | ParserTransitionKind::NotSet
8769 | ParserTransitionKind::Wildcard
8770 | ParserTransitionKind::Rule => None,
8771 };
8772 match transition_kind {
8773 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
8774 #[cfg(feature = "perf-counters")]
8775 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8776 outcomes.extend(self.recognize_state_fast(
8777 atn,
8778 FastRecognizeRequest {
8779 state_number: target,
8780 stop_state,
8781 index,
8782 rule_start_index,
8783 decision_start_index: next_decision_start_index,
8784 precedence,
8785 depth: depth + 1,
8786 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8787 recovery_state: epsilon_recovery_state,
8788 },
8789 FastRecognizeScratch {
8790 predicate_context,
8791 visiting,
8792 memo,
8793 expected,
8794 native_depth: native_depth + 1,
8795 },
8796 ));
8797 }
8798 ParserTransitionKind::Predicate => {
8799 #[cfg(feature = "perf-counters")]
8800 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8801 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
8802 outcomes.extend(self.recognize_state_fast(
8803 atn,
8804 FastRecognizeRequest {
8805 state_number: target,
8806 stop_state,
8807 index,
8808 rule_start_index,
8809 decision_start_index: next_decision_start_index,
8810 precedence,
8811 depth: depth + 1,
8812 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8813 recovery_state: epsilon_recovery_state,
8814 },
8815 FastRecognizeScratch {
8816 predicate_context,
8817 visiting,
8818 memo,
8819 expected,
8820 native_depth: native_depth + 1,
8821 },
8822 ));
8823 } else {
8824 record_predicate_no_viable(expected, next_decision_start_index, index);
8825 }
8826 }
8827 ParserTransitionKind::Precedence => {
8828 let transition_precedence = packed_i32(transition.arg0());
8829 if transition_precedence >= precedence {
8830 outcomes.extend(self.recognize_state_fast(
8831 atn,
8832 FastRecognizeRequest {
8833 state_number: target,
8834 stop_state,
8835 index,
8836 rule_start_index,
8837 decision_start_index: next_decision_start_index,
8838 precedence,
8839 depth: depth + 1,
8840 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8841 recovery_state: epsilon_recovery_state,
8842 },
8843 FastRecognizeScratch {
8844 predicate_context,
8845 visiting,
8846 memo,
8847 expected,
8848 native_depth: native_depth + 1,
8849 },
8850 ));
8851 }
8852 }
8853 ParserTransitionKind::Rule => {
8854 let rule_index = transition.arg0() as usize;
8855 let follow_state = transition.arg1() as usize;
8856 let rule_precedence = packed_i32(transition.arg2());
8857 #[cfg(feature = "perf-counters")]
8858 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
8859 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
8860 continue;
8861 };
8862 let symbol = self.token_type_at(index);
8874 if self.fast_first_set_prefilter {
8875 let first = self.cached_rule_first_set(atn, target, child_stop);
8888 if should_skip_rule_via_first_set(
8889 &first,
8890 symbol,
8891 self.fast_recovery_enabled,
8892 index,
8893 expected,
8894 ) {
8895 continue;
8896 }
8897 }
8898 let expected_before_child =
8899 self.fast_recovery_enabled.then(|| expected.clone());
8900 let mut children = self.recognize_state_fast(
8901 atn,
8902 FastRecognizeRequest {
8903 state_number: target,
8904 stop_state: child_stop,
8905 index,
8906 rule_start_index: index,
8907 decision_start_index: None,
8908 precedence: rule_precedence,
8909 depth: depth + 1,
8910 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8911 recovery_state: epsilon_recovery_state,
8912 },
8913 FastRecognizeScratch {
8914 predicate_context,
8915 visiting,
8916 memo,
8917 expected,
8918 native_depth: native_depth + 1,
8919 },
8920 );
8921 if children.is_empty() && self.fast_recovery_enabled {
8922 children = self.fast_child_rule_failure_recovery_outcomes(
8923 FastChildRuleFailureRecoveryRequest {
8924 atn,
8925 rule_index,
8926 start_index: index,
8927 follow_state,
8928 stop_state,
8929 expected,
8930 },
8931 );
8932 }
8933 if let Some(expected_before_child) = expected_before_child {
8934 if children
8935 .iter()
8936 .any(|child| child.diagnostics.is_empty() && child.index > index)
8937 {
8938 *expected = expected_before_child;
8939 }
8940 }
8941 for child in children {
8942 let child_index = child.index;
8943 let child_consumed_eof = child.consumed_eof;
8944 let child_diagnostics = child.diagnostics;
8945 let empty_recovery = self.empty_recovery_symbols();
8946 let follow_outcomes = self.recognize_state_fast(
8947 atn,
8948 FastRecognizeRequest {
8949 state_number: follow_state,
8950 stop_state,
8951 index: child_index,
8952 rule_start_index,
8953 decision_start_index: next_decision_start_index,
8954 precedence,
8955 depth: depth + 1,
8956 recovery_symbols: empty_recovery,
8957 recovery_state: None,
8958 },
8959 FastRecognizeScratch {
8960 predicate_context,
8961 visiting,
8962 memo,
8963 expected,
8964 native_depth: native_depth + 1,
8965 },
8966 );
8967 if follow_outcomes.is_empty() {
8968 continue;
8969 }
8970 let child_stop_index =
8971 self.rule_stop_token_index(child_index, child_consumed_eof);
8972 let child_node = self.build_parse_trees.then(|| {
8973 self.recognition_arena.deferred_rule_node(FastDeferredRule {
8974 rule_index: u32::try_from(rule_index)
8975 .expect("rule index fits in u32"),
8976 invoking_state: i32::try_from(invoking_state_number(state_number))
8977 .expect("invoking state fits in i32"),
8978 start_index: u32::try_from(index)
8979 .expect("rule start index fits in u32"),
8980 stop_index: child_stop_index.map(|stop_index| {
8981 u32::try_from(stop_index).expect("rule stop index fits in u32")
8982 }),
8983 deferred_children: child.deferred_nodes,
8984 children: child.nodes,
8985 })
8986 });
8987 let child_diags_empty = child_diagnostics.is_empty();
8988 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
8989 outcome.consumed_eof |= child_consumed_eof;
8990 if !child_diags_empty {
8993 outcome.diagnostics = self
8994 .recognition_arena
8995 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
8996 }
8997 if let Some(child_node) = child_node {
8998 outcome.deferred_nodes = self
8999 .recognition_arena
9000 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
9001 }
9002 outcome
9003 }));
9004 }
9005 }
9006 ParserTransitionKind::Atom
9007 | ParserTransitionKind::Range
9008 | ParserTransitionKind::Set
9009 | ParserTransitionKind::NotSet
9010 | ParserTransitionKind::Wildcard => {
9011 #[cfg(feature = "perf-counters")]
9012 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9013 let symbol = self.token_type_at(index);
9014 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9015 let next_index = self.consume_index(index, symbol);
9016 let empty_recovery = self.empty_recovery_symbols();
9017 outcomes.extend(
9018 self.recognize_state_fast(
9019 atn,
9020 FastRecognizeRequest {
9021 state_number: target,
9022 stop_state,
9023 index: next_index,
9024 rule_start_index,
9025 decision_start_index: next_decision_start_index,
9026 precedence,
9027 depth: depth + 1,
9028 recovery_symbols: empty_recovery,
9029 recovery_state: None,
9030 },
9031 FastRecognizeScratch {
9032 predicate_context,
9033 visiting,
9034 memo,
9035 expected,
9036 native_depth: native_depth + 1,
9037 },
9038 )
9039 .into_iter()
9040 .map(|mut outcome| {
9041 outcome.consumed_eof |= symbol == TOKEN_EOF;
9042 if self.fast_token_nodes_enabled {
9043 let token = self.arena_token_node(index, false);
9044 self.defer_fast_outcome_node(&mut outcome, token);
9045 }
9046 outcome
9047 }),
9048 );
9049 } else {
9050 if !self.fast_recovery_enabled {
9051 continue;
9059 }
9060 let expected_symbols = fast_recovery_expected_symbols(
9061 self,
9062 atn,
9063 state.state_number(),
9064 &recovery_symbols,
9065 );
9066 if expected_symbols.contains(&symbol) {
9067 continue;
9068 }
9069 {
9070 expected.record_transition(index, transition, max_token_type);
9071 record_no_viable_if_ambiguous(
9072 expected,
9073 next_decision_start_index,
9074 index,
9075 );
9076 outcomes.extend(self.fast_single_token_deletion_recovery(
9077 FastRecoveryRequest {
9078 atn,
9079 transition,
9080 expected_symbols: Rc::clone(&expected_symbols),
9081 target,
9082 request: FastRecognizeRequest {
9083 state_number,
9084 stop_state,
9085 index,
9086 rule_start_index,
9087 decision_start_index,
9088 precedence,
9089 depth,
9090 recovery_symbols: Rc::clone(&recovery_symbols),
9091 recovery_state,
9092 },
9093 visiting,
9094 memo,
9095 expected,
9096 },
9097 predicate_context,
9098 ));
9099 if !state_is_left_recursive_rule(atn, state) {
9100 outcomes.extend(self.fast_single_token_insertion_recovery(
9101 FastRecoveryRequest {
9102 atn,
9103 transition,
9104 expected_symbols: Rc::clone(&expected_symbols),
9105 target,
9106 request: FastRecognizeRequest {
9107 state_number,
9108 stop_state,
9109 index,
9110 rule_start_index,
9111 decision_start_index,
9112 precedence,
9113 depth,
9114 recovery_symbols: Rc::clone(&recovery_symbols),
9115 recovery_state,
9116 },
9117 visiting,
9118 memo,
9119 expected,
9120 },
9121 predicate_context,
9122 ));
9123 }
9124 outcomes.extend(self.fast_current_token_deletion_recovery(
9125 FastCurrentTokenDeletionRequest {
9126 atn,
9127 expected_symbols,
9128 request: FastRecognizeRequest {
9129 state_number,
9130 stop_state,
9131 index,
9132 rule_start_index,
9133 decision_start_index,
9134 precedence,
9135 depth,
9136 recovery_symbols: Rc::clone(&recovery_symbols),
9137 recovery_state,
9138 },
9139 visiting,
9140 memo,
9141 expected,
9142 },
9143 predicate_context,
9144 ));
9145 }
9146 }
9147 }
9148 }
9149 let alt_number = next_alt_number(
9150 state,
9151 transition_count,
9152 transition_index,
9153 0,
9154 self.fast_track_alt_numbers,
9155 );
9156 if alt_number != 0 || left_recursive_boundary.is_some() {
9157 for outcome in &mut outcomes[outcomes_before_transition..] {
9158 if alt_number != 0 {
9159 self.defer_fast_outcome_alternative(outcome, alt_number);
9160 }
9161 if let Some(rule_index) = left_recursive_boundary {
9162 self.defer_fast_outcome_boundary(outcome, rule_index);
9163 }
9164 }
9165 }
9166 }
9167
9168 if has_inserted_cycle_guard {
9169 visiting.remove(&key);
9170 }
9171 if matches!(
9172 self.prediction_mode,
9173 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9174 ) && self.fast_recovery_enabled
9175 {
9176 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
9180 }
9181 if self.fast_recovery_enabled {
9182 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
9183 } else {
9184 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
9185 }
9186 let should_memoize = self.fast_recovery_enabled
9196 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
9197 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
9201 if inline_consumed_eof {
9202 outcome.consumed_eof = true;
9203 }
9204 if !inline_consumed_tokens.is_empty() {
9205 for token_index in inline_consumed_tokens.iter().rev() {
9206 let token = self.arena_token_node(*token_index, false);
9207 self.defer_fast_outcome_node(&mut outcome, token);
9208 }
9209 }
9210 outcome
9211 };
9212 if should_memoize {
9213 #[cfg(feature = "perf-counters")]
9214 {
9215 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
9216 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
9217 match outcomes.len() {
9218 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
9219 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
9220 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
9221 }
9222 }
9223 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
9228 memo.insert(key, Rc::clone(&stored));
9229 if inline_pending {
9230 return stored
9231 .iter()
9232 .copied()
9233 .map(&mut apply_inline_pending)
9234 .collect();
9235 }
9236 return stored.to_vec();
9237 }
9238 #[cfg(feature = "perf-counters")]
9239 match outcomes.len() {
9240 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
9241 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
9242 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
9243 }
9244 if inline_pending {
9245 return outcomes.into_iter().map(apply_inline_pending).collect();
9246 }
9247 outcomes
9248 }
9249
9250 fn single_token_deletion_recovery(
9253 &mut self,
9254 recovery: RecoveryRequest<'_, '_>,
9255 ) -> Vec<RecognizeOutcome> {
9256 let RecoveryRequest {
9257 atn,
9258 transition,
9259 expected_symbols,
9260 target,
9261 request,
9262 visiting,
9263 memo,
9264 expected,
9265 } = recovery;
9266 let RecognizeRequest {
9267 stop_state,
9268 index,
9269 rule_start_index,
9270 decision_start_index,
9271 init_action_rules,
9272 predicates,
9273 semantics,
9274 rule_args,
9275 member_actions,
9276 return_actions,
9277 local_int_arg,
9278 member_values,
9279 return_values,
9280 rule_alt_number,
9281 track_alt_numbers,
9282 consumed_eof,
9283 precedence,
9284 depth,
9285 ..
9286 } = request;
9287 let Some((diagnostic, next_index, next_symbol)) =
9288 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
9289 else {
9290 return Vec::new();
9291 };
9292 let after_next = self.consume_index(next_index, next_symbol);
9293 self.recognize_state(
9294 atn,
9295 RecognizeRequest {
9296 state_number: target,
9297 stop_state,
9298 index: after_next,
9299 rule_start_index,
9300 decision_start_index,
9301 init_action_rules,
9302 predicates,
9303 semantics,
9304 rule_args,
9305 member_actions,
9306 return_actions,
9307 local_int_arg,
9308 member_values,
9309 return_values,
9310 rule_alt_number,
9311 track_alt_numbers,
9312 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
9313 committed_decision: false,
9314 precedence,
9315 depth: depth + 1,
9316 recovery_symbols: BTreeSet::new(),
9317 recovery_state: None,
9318 },
9319 visiting,
9320 memo,
9321 expected,
9322 )
9323 .into_iter()
9324 .map(|mut outcome| {
9325 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
9326 outcome.diagnostics = self
9327 .recognition_arena
9328 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9329 let token = self.arena_token_node(next_index, false);
9330 self.arena_prepend(&mut outcome.nodes, token);
9331 let error = self.arena_token_node(index, true);
9332 self.arena_prepend(&mut outcome.nodes, error);
9333 outcome
9334 })
9335 .collect()
9336 }
9337
9338 fn current_token_deletion_recovery(
9341 &mut self,
9342 recovery: CurrentTokenDeletionRequest<'_, '_>,
9343 ) -> Vec<RecognizeOutcome> {
9344 let CurrentTokenDeletionRequest {
9345 atn,
9346 expected_symbols,
9347 mut request,
9348 visiting,
9349 memo,
9350 expected,
9351 } = recovery;
9352 let error_index = request.index;
9353 if error_index == request.rule_start_index {
9354 return Vec::new();
9355 }
9356 let Some((diagnostic, next_index, skipped)) =
9357 self.current_token_deletion(error_index, &expected_symbols)
9358 else {
9359 return Vec::new();
9360 };
9361 request.state_number = request.recovery_state.unwrap_or(request.state_number);
9362 request.index = next_index;
9363 request.committed_decision = false;
9364 request.depth += 1;
9365 request.recovery_state = None;
9366 self.recognize_state(atn, request, visiting, memo, expected)
9367 .into_iter()
9368 .map(|mut outcome| {
9369 outcome.diagnostics = self
9370 .recognition_arena
9371 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9372 for index in skipped.iter().rev() {
9373 let error = self.arena_token_node(*index, true);
9374 self.arena_prepend(&mut outcome.nodes, error);
9375 }
9376 outcome
9377 })
9378 .collect()
9379 }
9380
9381 fn consuming_failure_fallback(
9384 &mut self,
9385 fallback: ConsumingFailureFallback<'_>,
9386 visiting: &mut BTreeSet<RecognizeKey>,
9387 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9388 expected: &mut ExpectedTokens,
9389 ) -> Vec<RecognizeOutcome> {
9390 if fallback.expected_symbols.is_empty() {
9391 return Vec::new();
9392 }
9393 if fallback.symbol == TOKEN_EOF {
9394 return self.eof_consuming_failure_fallback(fallback, expected);
9395 }
9396 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
9397 }
9398
9399 fn non_eof_consuming_failure_fallback(
9402 &mut self,
9403 fallback: ConsumingFailureFallback<'_>,
9404 visiting: &mut BTreeSet<RecognizeKey>,
9405 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9406 expected: &mut ExpectedTokens,
9407 ) -> Vec<RecognizeOutcome> {
9408 let ConsumingFailureFallback {
9409 atn,
9410 target,
9411 request,
9412 symbol,
9413 expected_symbols,
9414 decision_start_index,
9415 decision,
9416 } = fallback;
9417 let error_index = request.index;
9418 let diagnostic =
9419 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
9420 let next_index = self.consume_index(error_index, symbol);
9421 self.recognize_state(
9422 atn,
9423 RecognizeRequest {
9424 state_number: target,
9425 stop_state: request.stop_state,
9426 index: next_index,
9427 rule_start_index: request.rule_start_index,
9428 decision_start_index,
9429 init_action_rules: request.init_action_rules,
9430 predicates: request.predicates,
9431 semantics: request.semantics,
9432 rule_args: request.rule_args,
9433 member_actions: request.member_actions,
9434 return_actions: request.return_actions,
9435 local_int_arg: request.local_int_arg,
9436 member_values: request.member_values,
9437 return_values: request.return_values,
9438 rule_alt_number: request.rule_alt_number,
9439 track_alt_numbers: request.track_alt_numbers,
9440 consumed_eof: request.consumed_eof,
9441 committed_decision: false,
9442 precedence: request.precedence,
9443 depth: request.depth + 1,
9444 recovery_symbols: BTreeSet::new(),
9445 recovery_state: None,
9446 },
9447 visiting,
9448 memo,
9449 expected,
9450 )
9451 .into_iter()
9452 .map(|mut outcome| {
9453 prepend_decision(&mut outcome, decision);
9454 outcome.diagnostics = self
9455 .recognition_arena
9456 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9457 let error = self.arena_token_node(error_index, true);
9458 self.arena_prepend(&mut outcome.nodes, error);
9459 outcome
9460 })
9461 .collect()
9462 }
9463
9464 fn eof_consuming_failure_fallback(
9467 &mut self,
9468 fallback: ConsumingFailureFallback<'_>,
9469 expected: &ExpectedTokens,
9470 ) -> Vec<RecognizeOutcome> {
9471 let request = fallback.request;
9472 if request.index == request.rule_start_index {
9473 return Vec::new();
9474 }
9475 let diagnostic =
9476 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
9477 let diagnostics = self
9478 .recognition_arena
9479 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
9480 vec![RecognizeOutcome {
9481 index: request.index,
9482 consumed_eof: request.consumed_eof,
9483 alt_number: request.rule_alt_number,
9484 member_values: request.member_values,
9485 return_values: request.return_values,
9486 diagnostics,
9487 decisions: Vec::new(),
9488 actions: Vec::new(),
9489 nodes: NodeSeqId::EMPTY,
9490 }]
9491 }
9492
9493 fn single_token_insertion_recovery(
9496 &mut self,
9497 recovery: RecoveryRequest<'_, '_>,
9498 ) -> Vec<RecognizeOutcome> {
9499 let RecoveryRequest {
9500 atn,
9501 transition,
9502 expected_symbols,
9503 target,
9504 request,
9505 visiting,
9506 memo,
9507 expected,
9508 } = recovery;
9509 let RecognizeRequest {
9510 stop_state,
9511 index,
9512 rule_start_index,
9513 decision_start_index,
9514 init_action_rules,
9515 predicates,
9516 semantics,
9517 rule_args,
9518 member_actions,
9519 return_actions,
9520 local_int_arg,
9521 member_values,
9522 return_values,
9523 rule_alt_number,
9524 track_alt_numbers,
9525 consumed_eof,
9526 precedence,
9527 depth,
9528 ..
9529 } = request;
9530 let follow_symbols = state_expected_symbols(atn, transition.target());
9531 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
9532 transition,
9533 index,
9534 atn.max_token_type(),
9535 &expected_symbols,
9536 &follow_symbols,
9537 ) else {
9538 return Vec::new();
9539 };
9540 self.recognize_state(
9541 atn,
9542 RecognizeRequest {
9543 state_number: target,
9544 stop_state,
9545 index,
9546 rule_start_index,
9547 decision_start_index,
9548 init_action_rules,
9549 predicates,
9550 semantics,
9551 rule_args,
9552 member_actions,
9553 return_actions,
9554 local_int_arg,
9555 member_values,
9556 return_values,
9557 rule_alt_number,
9558 track_alt_numbers,
9559 consumed_eof,
9560 committed_decision: false,
9561 precedence,
9562 depth: depth + 1,
9563 recovery_symbols: BTreeSet::new(),
9564 recovery_state: None,
9565 },
9566 visiting,
9567 memo,
9568 expected,
9569 )
9570 .into_iter()
9571 .map(|mut outcome| {
9572 outcome.diagnostics = self
9573 .recognition_arena
9574 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9575 let missing = self.arena_missing_token_node(token_type, index, text.clone());
9576 self.arena_prepend(&mut outcome.nodes, missing);
9577 outcome
9578 })
9579 .collect()
9580 }
9581
9582 #[allow(clippy::too_many_lines)]
9585 fn recognize_state(
9586 &mut self,
9587 atn: &Atn,
9588 request: RecognizeRequest<'_>,
9589 visiting: &mut BTreeSet<RecognizeKey>,
9590 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9591 expected: &mut ExpectedTokens,
9592 ) -> Vec<RecognizeOutcome> {
9593 let request_template = request.clone();
9594 let RecognizeRequest {
9595 state_number,
9596 stop_state,
9597 index,
9598 rule_start_index,
9599 decision_start_index,
9600 init_action_rules,
9601 predicates,
9602 semantics,
9603 rule_args,
9604 member_actions,
9605 return_actions,
9606 local_int_arg,
9607 member_values,
9608 return_values,
9609 rule_alt_number,
9610 track_alt_numbers,
9611 consumed_eof,
9612 committed_decision,
9613 precedence,
9614 depth,
9615 recovery_symbols,
9616 recovery_state,
9617 } = request;
9618 if depth > RECOGNITION_DEPTH_LIMIT {
9619 return Vec::new();
9620 }
9621 if state_number == stop_state {
9622 return stop_outcome(
9623 index,
9624 consumed_eof,
9625 rule_alt_number,
9626 member_values,
9627 return_values,
9628 );
9629 }
9630 let key = RecognizeKey {
9631 state_number,
9632 stop_state,
9633 index,
9634 rule_start_index,
9635 decision_start_index,
9636 local_int_arg,
9637 member_values: member_values.clone(),
9638 return_values: return_values.clone(),
9639 rule_alt_number,
9640 track_alt_numbers,
9641 consumed_eof,
9642 committed_decision,
9643 precedence,
9644 recovery_symbols: recovery_symbols.clone(),
9645 recovery_state,
9646 };
9647 if let Some(outcomes) = memo.get(&key) {
9648 return outcomes.clone();
9649 }
9650
9651 let visit_key = key.clone();
9652 if !visiting.insert(visit_key.clone()) {
9653 return Vec::new();
9654 }
9655
9656 let Some(state) = atn.state(state_number) else {
9657 visiting.remove(&visit_key);
9658 return Vec::new();
9659 };
9660 let decision_override_generation = self.decision_override_generation;
9661 let transitions = state.transitions();
9662 let transition_count = transitions.len();
9663 let overridden_transition = if transition_count > 1
9664 && self.semantic_hooks.observes_parser_decisions()
9665 {
9666 atn.decision_to_state()
9667 .iter()
9668 .position(|candidate| candidate == state_number)
9669 .and_then(|decision| {
9670 self.semantic_hooks
9671 .parser_decision_override(decision, index, transition_count)
9672 })
9673 .and_then(|alternative| alternative.checked_sub(1))
9674 .filter(|alternative| *alternative < transition_count)
9675 } else {
9676 None
9677 };
9678 if overridden_transition.is_some() {
9679 self.decision_override_generation = self.decision_override_generation.wrapping_add(1);
9680 }
9681 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9682 Some(index)
9683 } else {
9684 decision_start_index
9685 };
9686 let (epsilon_recovery_symbols, epsilon_recovery_state) =
9687 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
9688 let mut outcomes = Vec::new();
9689 for (transition_index, transition) in transitions.iter().enumerate() {
9690 if overridden_transition.is_some_and(|forced| forced != transition_index) {
9691 continue;
9692 }
9693 let transition_committed =
9694 committed_decision || overridden_transition == Some(transition_index);
9695 let mut transition_request = request_template.clone();
9696 transition_request.committed_decision = transition_committed;
9697 let decision =
9698 transition_decision(atn, state, transition_count, transition_index, predicates);
9699 let next_alt_number = next_alt_number(
9700 state,
9701 transition_count,
9702 transition_index,
9703 rule_alt_number,
9704 track_alt_numbers,
9705 );
9706 let transition_data = transition.data();
9707 match &transition_data {
9708 Transition::Epsilon { target } | Transition::Action { target, .. } => {
9709 let action_rule_index = match &transition_data {
9710 Transition::Action { rule_index, .. } => Some(*rule_index),
9711 _ => None,
9712 };
9713 outcomes.extend(self.recognize_epsilon_or_action_step(
9714 atn,
9715 &transition_request,
9716 EpsilonActionStep {
9717 source_state: state_number,
9718 target: *target,
9719 action_rule_index,
9720 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
9721 decision,
9722 decision_start_index: next_decision_start_index,
9723 alt_number: next_alt_number,
9724 recovery_symbols: epsilon_recovery_symbols.clone(),
9725 recovery_state: epsilon_recovery_state,
9726 },
9727 RecognizeScratch {
9728 visiting,
9729 memo,
9730 expected,
9731 },
9732 ));
9733 }
9734 Transition::Predicate {
9735 target,
9736 rule_index,
9737 pred_index,
9738 ..
9739 } => {
9740 let predicate = PredicateEval {
9741 index,
9742 rule_index: *rule_index,
9743 pred_index: *pred_index,
9744 predicates,
9745 semantics,
9746 context: None,
9747 local_int_arg,
9748 member_values: &member_values,
9749 };
9750 if self.parser_predicate_matches(predicate) {
9751 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
9752 outcomes.extend(
9753 self.recognize_state(
9754 atn,
9755 RecognizeRequest {
9756 state_number: *target,
9757 stop_state,
9758 index,
9759 rule_start_index,
9760 decision_start_index: next_decision_start_index,
9761 init_action_rules,
9762 predicates,
9763 semantics,
9764 rule_args,
9765 member_actions,
9766 return_actions,
9767 local_int_arg,
9768 member_values: member_values.clone(),
9769 return_values: return_values.clone(),
9770 rule_alt_number: next_alt_number,
9771 track_alt_numbers,
9772 consumed_eof,
9773 committed_decision: transition_committed,
9774 precedence,
9775 depth: depth + 1,
9776 recovery_symbols: epsilon_recovery_symbols.clone(),
9777 recovery_state: epsilon_recovery_state,
9778 },
9779 visiting,
9780 memo,
9781 expected,
9782 )
9783 .into_iter()
9784 .map(|mut outcome| {
9785 prepend_decision(&mut outcome, decision);
9786 if let Some(rule_index) = left_recursive_boundary {
9787 let boundary =
9788 self.arena_boundary_node(rule_index, next_alt_number);
9789 self.arena_prepend(&mut outcome.nodes, boundary);
9790 }
9791 outcome
9792 }),
9793 );
9794 } else if let Some(message) = semantics
9795 .and_then(|semantics| {
9796 self.parser_semantic_ir_predicate_failure_message(
9797 *rule_index,
9798 *pred_index,
9799 semantics,
9800 )
9801 })
9802 .or_else(|| {
9803 self.parser_predicate_failure_message(
9804 *rule_index,
9805 *pred_index,
9806 predicates,
9807 )
9808 })
9809 {
9810 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
9811 rule_index: *rule_index,
9812 index,
9813 message,
9814 member_values: member_values.clone(),
9815 return_values: return_values.clone(),
9816 rule_alt_number,
9817 }));
9818 } else {
9819 record_predicate_no_viable(expected, next_decision_start_index, index);
9820 }
9821 }
9822 Transition::Precedence {
9823 target,
9824 precedence: transition_precedence,
9825 } => {
9826 if *transition_precedence >= precedence {
9827 outcomes.extend(
9828 self.recognize_state(
9829 atn,
9830 RecognizeRequest {
9831 state_number: *target,
9832 stop_state,
9833 index,
9834 rule_start_index,
9835 decision_start_index: next_decision_start_index,
9836 init_action_rules,
9837 predicates,
9838 semantics,
9839 rule_args,
9840 member_actions,
9841 return_actions,
9842 local_int_arg,
9843 member_values: member_values.clone(),
9844 return_values: return_values.clone(),
9845 rule_alt_number: next_alt_number,
9846 track_alt_numbers,
9847 consumed_eof,
9848 committed_decision: transition_committed,
9849 precedence,
9850 depth: depth + 1,
9851 recovery_symbols: epsilon_recovery_symbols.clone(),
9852 recovery_state: epsilon_recovery_state,
9853 },
9854 visiting,
9855 memo,
9856 expected,
9857 )
9858 .into_iter()
9859 .map(|mut outcome| {
9860 prepend_decision(&mut outcome, decision);
9861 outcome
9862 }),
9863 );
9864 }
9865 }
9866 Transition::Rule {
9867 target,
9868 rule_index,
9869 follow_state,
9870 precedence: rule_precedence,
9871 ..
9872 } => {
9873 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
9874 continue;
9875 };
9876 let child_local_int_arg =
9877 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
9878 let expected_before_child = expected.clone();
9879 let children = self.recognize_state(
9880 atn,
9881 RecognizeRequest {
9882 state_number: *target,
9883 stop_state: child_stop,
9884 index,
9885 rule_start_index: index,
9886 decision_start_index: None,
9887 init_action_rules,
9888 predicates,
9889 semantics,
9890 rule_args,
9891 member_actions,
9892 return_actions,
9893 local_int_arg: child_local_int_arg,
9894 member_values: member_values.clone(),
9895 return_values: BTreeMap::new(),
9896 rule_alt_number: 0,
9897 track_alt_numbers,
9898 consumed_eof: false,
9899 committed_decision: transition_committed,
9900 precedence: *rule_precedence,
9901 depth: depth + 1,
9902 recovery_symbols: epsilon_recovery_symbols.clone(),
9903 recovery_state: epsilon_recovery_state,
9904 },
9905 visiting,
9906 memo,
9907 expected,
9908 );
9909 let children = if children.is_empty() {
9910 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
9911 atn,
9912 rule_index: *rule_index,
9913 start_index: index,
9914 follow_state: *follow_state,
9915 stop_state,
9916 member_values: member_values.clone(),
9917 expected,
9918 })
9919 } else {
9920 children
9921 };
9922 let preserve_child_expected =
9923 self.child_expected_reaches_clean_eof(&children, expected);
9924 restore_expected(
9925 &children,
9926 index,
9927 expected,
9928 expected_before_child,
9929 preserve_child_expected,
9930 );
9931 for child in children {
9932 let child_stop_index =
9933 self.rule_stop_token_index(child.index, child.consumed_eof);
9934 let child_nodes = self
9935 .recognition_arena
9936 .fold_left_recursive_boundaries(child.nodes);
9937 let child_node = self.arena_rule_node(ArenaRuleSpec {
9938 rule_index: *rule_index,
9939 invoking_state: invoking_state_number(state_number),
9940 alt_number: child.alt_number,
9941 start_index: index,
9942 stop_index: child_stop_index,
9943 return_values: child.return_values.clone(),
9944 children: child_nodes,
9945 });
9946 outcomes.extend(
9947 self.recognize_state(
9948 atn,
9949 RecognizeRequest {
9950 state_number: *follow_state,
9951 stop_state,
9952 index: child.index,
9953 rule_start_index,
9954 decision_start_index: next_decision_start_index,
9955 init_action_rules,
9956 predicates,
9957 semantics,
9958 rule_args,
9959 member_actions,
9960 return_actions,
9961 local_int_arg,
9962 member_values: child.member_values.clone(),
9963 return_values: return_values.clone(),
9964 rule_alt_number,
9965 track_alt_numbers,
9966 consumed_eof: consumed_eof || child.consumed_eof,
9967 committed_decision: transition_committed
9968 && child.index == index,
9969 precedence,
9970 depth: depth + 1,
9971 recovery_symbols: BTreeSet::new(),
9972 recovery_state: None,
9973 },
9974 visiting,
9975 memo,
9976 expected,
9977 )
9978 .into_iter()
9979 .map(|mut outcome| {
9980 outcome.consumed_eof |= child.consumed_eof;
9981 outcome.diagnostics = self
9982 .recognition_arena
9983 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
9984 let mut decisions = child.decisions.clone();
9985 decisions.append(&mut outcome.decisions);
9986 outcome.decisions = decisions;
9987 prepend_decision(&mut outcome, decision);
9988 let mut actions = child.actions.clone();
9989 if init_action_rules.contains(rule_index) {
9990 actions.insert(
9991 0,
9992 ParserAction::new_rule_init(
9993 *rule_index,
9994 index,
9995 Some(*follow_state),
9996 ),
9997 );
9998 }
9999 actions.append(&mut outcome.actions);
10000 outcome.actions = actions;
10001 self.arena_prepend(&mut outcome.nodes, child_node);
10002 outcome
10003 }),
10004 );
10005 }
10006 }
10007 Transition::Atom { target, .. }
10008 | Transition::Range { target, .. }
10009 | Transition::Set { target, .. }
10010 | Transition::NotSet { target, .. }
10011 | Transition::Wildcard { target, .. } => {
10012 let symbol = self.token_type_at(index);
10013 if transition_data.matches(symbol, 1, atn.max_token_type()) {
10014 let next_index = self.consume_index(index, symbol);
10015 outcomes.extend(
10016 self.recognize_state(
10017 atn,
10018 RecognizeRequest {
10019 state_number: *target,
10020 stop_state,
10021 index: next_index,
10022 rule_start_index,
10023 decision_start_index: next_decision_start_index,
10024 init_action_rules,
10025 predicates,
10026 semantics,
10027 rule_args,
10028 member_actions,
10029 return_actions,
10030 local_int_arg,
10031 member_values: member_values.clone(),
10032 return_values: return_values.clone(),
10033 rule_alt_number: next_alt_number,
10034 track_alt_numbers,
10035 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
10036 committed_decision: false,
10037 precedence,
10038 depth: depth + 1,
10039 recovery_symbols: BTreeSet::new(),
10040 recovery_state: None,
10041 },
10042 visiting,
10043 memo,
10044 expected,
10045 )
10046 .into_iter()
10047 .map(|mut outcome| {
10048 prepend_decision(&mut outcome, decision);
10049 outcome.consumed_eof |= symbol == TOKEN_EOF;
10050 let token = self.arena_token_node(index, false);
10051 self.arena_prepend(&mut outcome.nodes, token);
10052 outcome
10053 }),
10054 );
10055 } else {
10056 let expected_symbols =
10057 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
10058 if expected_symbols.contains(&symbol) && !transition_committed {
10059 continue;
10060 }
10061 expected.record_transition(index, transition, atn.max_token_type());
10062 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
10063 let before_recovery = outcomes.len();
10064 let recovery_request = transition_request.clone();
10065 if transition_committed {
10066 outcomes.extend(self.consuming_failure_fallback(
10067 ConsumingFailureFallback {
10068 atn,
10069 target: *target,
10070 request: recovery_request,
10071 symbol,
10072 expected_symbols,
10073 decision_start_index: next_decision_start_index,
10074 decision,
10075 },
10076 visiting,
10077 memo,
10078 expected,
10079 ));
10080 break;
10081 }
10082 outcomes.extend(
10083 self.single_token_deletion_recovery(RecoveryRequest {
10084 atn,
10085 transition,
10086 expected_symbols: expected_symbols.clone(),
10087 target: *target,
10088 request: recovery_request.clone(),
10089 visiting,
10090 memo,
10091 expected,
10092 })
10093 .into_iter()
10094 .map(|mut outcome| {
10095 prepend_decision(&mut outcome, decision);
10096 outcome
10097 }),
10098 );
10099 if !state_is_left_recursive_rule(atn, state) {
10100 outcomes.extend(
10101 self.single_token_insertion_recovery(RecoveryRequest {
10102 atn,
10103 transition,
10104 expected_symbols: expected_symbols.clone(),
10105 target: *target,
10106 request: recovery_request.clone(),
10107 visiting,
10108 memo,
10109 expected,
10110 })
10111 .into_iter()
10112 .map(|mut outcome| {
10113 prepend_decision(&mut outcome, decision);
10114 outcome
10115 }),
10116 );
10117 }
10118 outcomes.extend(self.current_token_deletion_recovery(
10119 CurrentTokenDeletionRequest {
10120 atn,
10121 expected_symbols: expected_symbols.clone(),
10122 request: recovery_request.clone(),
10123 visiting,
10124 memo,
10125 expected,
10126 },
10127 ));
10128 if outcomes.len() == before_recovery {
10129 outcomes.extend(self.consuming_failure_fallback(
10130 ConsumingFailureFallback {
10131 atn,
10132 target: *target,
10133 request: recovery_request,
10134 symbol,
10135 expected_symbols,
10136 decision_start_index: next_decision_start_index,
10137 decision,
10138 },
10139 visiting,
10140 memo,
10141 expected,
10142 ));
10143 }
10144 }
10145 }
10146 }
10147 if self.decision_override_generation != decision_override_generation {
10148 break;
10149 }
10150 }
10151
10152 visiting.remove(&visit_key);
10153 self.record_prediction_diagnostics(atn, state, index, &outcomes);
10154 if matches!(
10155 self.prediction_mode,
10156 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
10157 ) {
10158 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
10159 }
10160 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
10161 memo.insert(key, outcomes.clone());
10162 outcomes
10163 }
10164
10165 fn recognize_epsilon_or_action_step(
10168 &mut self,
10169 atn: &Atn,
10170 request: &RecognizeRequest<'_>,
10171 step: EpsilonActionStep,
10172 scratch: RecognizeScratch<'_>,
10173 ) -> Vec<RecognizeOutcome> {
10174 let RecognizeScratch {
10175 visiting,
10176 memo,
10177 expected,
10178 } = scratch;
10179 let action = step.action_rule_index.map(|rule_index| {
10180 ParserAction::new(
10181 step.source_state,
10182 rule_index,
10183 request.rule_start_index,
10184 self.rule_stop_token_index(request.index, request.consumed_eof),
10185 )
10186 });
10187 let next_member_values = if action.is_some() {
10188 member_values_after_action(
10189 step.source_state,
10190 request.member_actions,
10191 request.semantics,
10192 &request.member_values,
10193 )
10194 } else {
10195 request.member_values.clone()
10196 };
10197 let next_return_values = action.map_or_else(
10198 || request.return_values.clone(),
10199 |action| {
10200 return_values_after_action(
10201 step.source_state,
10202 action.rule_index(),
10203 request.return_actions,
10204 request.semantics,
10205 &request.return_values,
10206 )
10207 },
10208 );
10209
10210 self.recognize_state(
10211 atn,
10212 RecognizeRequest {
10213 state_number: step.target,
10214 stop_state: request.stop_state,
10215 index: request.index,
10216 rule_start_index: request.rule_start_index,
10217 decision_start_index: step.decision_start_index,
10218 init_action_rules: request.init_action_rules,
10219 predicates: request.predicates,
10220 semantics: request.semantics,
10221 rule_args: request.rule_args,
10222 member_actions: request.member_actions,
10223 return_actions: request.return_actions,
10224 local_int_arg: request.local_int_arg,
10225 member_values: next_member_values,
10226 return_values: next_return_values,
10227 rule_alt_number: if step.left_recursive_boundary.is_some() {
10228 0
10229 } else {
10230 step.alt_number
10231 },
10232 track_alt_numbers: request.track_alt_numbers,
10233 consumed_eof: request.consumed_eof,
10234 committed_decision: request.committed_decision,
10235 precedence: request.precedence,
10236 depth: request.depth + 1,
10237 recovery_symbols: step.recovery_symbols,
10238 recovery_state: step.recovery_state,
10239 },
10240 visiting,
10241 memo,
10242 expected,
10243 )
10244 .into_iter()
10245 .map(|mut outcome| {
10246 prepend_decision(&mut outcome, step.decision);
10247 if let Some(rule_index) = step.left_recursive_boundary {
10248 let boundary = self.arena_boundary_node(rule_index, step.alt_number);
10249 self.arena_prepend(&mut outcome.nodes, boundary);
10250 }
10251 if let Some(action) = action {
10252 outcome.actions.insert(0, action);
10253 }
10254 outcome
10255 })
10256 .collect()
10257 }
10258
10259 fn token_type_at(&mut self, index: usize) -> i32 {
10264 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
10265 self.input.fill();
10266 }
10267 self.input.token_type_at_index(index)
10268 }
10269
10270 fn cached_state_expected_symbols(
10282 &mut self,
10283 atn: &Atn,
10284 state_number: usize,
10285 ) -> Rc<BTreeSet<i32>> {
10286 if let Some(cached) = self.state_expected_cache.get(&state_number) {
10287 return Rc::clone(cached);
10288 }
10289 let symbols = state_expected_symbols(atn, state_number);
10290 let entry = self.intern_recovery_symbols(symbols);
10291 self.state_expected_cache
10292 .insert(state_number, Rc::clone(&entry));
10293 entry
10294 }
10295
10296 fn cached_state_expected_token_set(
10297 &mut self,
10298 atn: &Atn,
10299 state_number: usize,
10300 ) -> Rc<TokenBitSet> {
10301 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
10302 return Rc::clone(cached);
10303 }
10304 let symbols = with_shared_atn_caches(atn, |cache| {
10308 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
10309 return Rc::clone(cached);
10310 }
10311 let symbols = Rc::new(state_expected_token_set(atn, state_number));
10312 cache
10313 .state_expected_tokens
10314 .insert(state_number, Rc::clone(&symbols));
10315 symbols
10316 });
10317 self.state_expected_token_cache
10318 .insert(state_number, Rc::clone(&symbols));
10319 symbols
10320 }
10321
10322 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
10323 if self.rule_stop_reach_cache.len() <= state_number {
10324 self.rule_stop_reach_cache
10325 .resize_with(atn.states().len().max(state_number + 1), || None);
10326 }
10327 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
10328 return reaches;
10329 }
10330 let reaches = with_shared_atn_caches(atn, |cache| {
10331 *cache
10332 .rule_stop_reach
10333 .entry(state_number)
10334 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
10335 });
10336 self.rule_stop_reach_cache[state_number] = Some(reaches);
10337 reaches
10338 }
10339
10340 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
10343 Rc::clone(&self.empty_recovery_symbols)
10344 }
10345
10346 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
10355 if set.is_empty() {
10356 return Rc::clone(&self.empty_recovery_symbols);
10357 }
10358 let candidate = Rc::new(set);
10359 match self.recovery_symbols_intern.get(&candidate) {
10360 Some(existing) => Rc::clone(existing),
10361 None => {
10362 self.recovery_symbols_intern
10363 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
10364 candidate
10365 }
10366 }
10367 }
10368
10369 fn cached_decision_lookahead(
10374 &mut self,
10375 atn: &Atn,
10376 state: AtnState<'_>,
10377 rule_stop_state: usize,
10378 ) -> Rc<DecisionLookahead> {
10379 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
10386 return Rc::clone(cached);
10387 }
10388 let entry = with_shared_atn_caches(atn, |cache| {
10389 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
10390 return Rc::clone(cached);
10391 }
10392 let mut entry = DecisionLookahead {
10393 transitions: Vec::with_capacity(state.transitions().len()),
10394 };
10395 for transition in &state.transitions() {
10396 entry.transitions.push(transition_first_set(
10397 atn,
10398 transition,
10399 rule_stop_state,
10400 &mut cache.first_set,
10401 ));
10402 }
10403 let entry = Rc::new(entry);
10404 cache
10405 .decision_lookahead
10406 .insert(state.state_number(), Rc::clone(&entry));
10407 entry
10408 });
10409 self.decision_lookahead_cache
10410 .insert(state.state_number(), Rc::clone(&entry));
10411 entry
10412 }
10413
10414 fn cached_rule_first_set(
10415 &mut self,
10416 atn: &Atn,
10417 target: usize,
10418 child_stop: usize,
10419 ) -> Rc<FirstSet> {
10420 if self.rule_first_set_cache.len() <= target {
10421 self.rule_first_set_cache
10422 .resize_with(atn.states().len().max(target + 1), || None);
10423 }
10424 if let Some(cached) = self
10425 .rule_first_set_cache
10426 .get(target)
10427 .and_then(Option::as_ref)
10428 {
10429 return Rc::clone(cached);
10430 }
10431 let first = with_shared_first_set_cache(atn, |cache| {
10432 rule_first_set(atn, target, child_stop, cache)
10433 });
10434 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
10435 first
10436 }
10437
10438 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
10439 let atn_key = SharedAtnCacheKey::for_atn(atn);
10440 if self.empty_cycle_cache_atn != Some(atn_key) {
10441 self.empty_cycle_cache.clear();
10442 self.empty_cycle_cache_atn = Some(atn_key);
10443 }
10444 if self.empty_cycle_cache.len() <= state_number {
10445 self.empty_cycle_cache
10446 .resize_with(atn.state_count().max(state_number + 1), || None);
10447 }
10448 if let Some(cached) = self.empty_cycle_cache[state_number] {
10449 return cached;
10450 }
10451 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
10452 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
10453 self.empty_cycle_cache[state_number] = Some(result);
10454 result
10455 }
10456
10457 fn empty_path_reaches_state(
10458 &mut self,
10459 atn: &Atn,
10460 state_number: usize,
10461 target_state: usize,
10462 visited: &mut FxHashSet<usize>,
10463 ) -> bool {
10464 enum Work {
10465 Visit(usize),
10466 RuleFollow {
10467 target: usize,
10468 rule_index: usize,
10469 follow_state: usize,
10470 },
10471 }
10472
10473 let mut work = vec![Work::Visit(state_number)];
10474 while let Some(item) = work.pop() {
10475 match item {
10476 Work::Visit(state_number) => {
10477 if !visited.insert(state_number) {
10478 continue;
10479 }
10480 let Some(state) = atn.state(state_number) else {
10481 continue;
10482 };
10483 let transitions = state.transitions();
10484 for transition_index in (0..transitions.len()).rev() {
10485 let transition = transitions
10486 .get(transition_index)
10487 .expect("in-bounds parser transition");
10488 let kind = transition.kind();
10489 let target = transition.target();
10490 match kind {
10491 ParserTransitionKind::Atom
10492 | ParserTransitionKind::Range
10493 | ParserTransitionKind::Set
10494 | ParserTransitionKind::NotSet
10495 | ParserTransitionKind::Wildcard => {}
10496 ParserTransitionKind::Rule => {
10497 if target == target_state {
10498 return true;
10499 }
10500 work.push(Work::RuleFollow {
10501 target,
10502 rule_index: transition.arg0() as usize,
10503 follow_state: transition.arg1() as usize,
10504 });
10505 work.push(Work::Visit(target));
10506 }
10507 ParserTransitionKind::Epsilon
10508 | ParserTransitionKind::Predicate
10509 | ParserTransitionKind::Action
10510 | ParserTransitionKind::Precedence => {
10511 if target == target_state {
10512 return true;
10513 }
10514 work.push(Work::Visit(target));
10515 }
10516 }
10517 }
10518 }
10519 Work::RuleFollow {
10520 target,
10521 rule_index,
10522 follow_state,
10523 } => {
10524 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
10525 continue;
10526 };
10527 if self.cached_rule_first_set(atn, target, child_stop).nullable {
10528 if follow_state == target_state {
10529 return true;
10530 }
10531 work.push(Work::Visit(follow_state));
10532 }
10533 }
10534 }
10535 }
10536 false
10537 }
10538
10539 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
10542 match self.clean_memo_mode {
10543 CleanMemoMode::Promote => true,
10544 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
10545 CleanMemoMode::Sparse => {
10546 self.clean_memo_sparse_samples += 1;
10547 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
10548 return false;
10549 }
10550 self.clean_memo_sparse_samples = 0;
10551 self.clean_memo_mode = CleanMemoMode::Probe;
10552 self.clean_memo_probe_samples = 0;
10553 self.clean_memo_probe_repeats = 0;
10554 self.clean_memo_probe_seen.clear();
10555 self.observe_clean_memo_probe(key)
10556 }
10557 }
10558 }
10559
10560 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
10561 self.clean_memo_probe_samples += 1;
10562 if !self.clean_memo_probe_seen.insert(key.clone()) {
10563 self.clean_memo_probe_repeats += 1;
10564 }
10565 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
10566 self.clean_memo_mode = CleanMemoMode::Promote;
10567 self.clean_memo_probe_seen.clear();
10568 return true;
10569 }
10570 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
10571 self.clean_memo_mode = CleanMemoMode::Sparse;
10572 self.clean_memo_sparse_samples = 0;
10573 self.clean_memo_probe_seen.clear();
10574 return false;
10575 }
10576 true
10577 }
10578
10579 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
10581 self.input.get(index)
10582 }
10583
10584 fn token_id_at(&self, index: usize) -> Option<TokenId> {
10586 self.input.get_id(index)
10587 }
10588
10589 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
10590 let token = self
10591 .token_id_at(index)
10592 .expect("recognized token index must exist in the token store");
10593 let node = if error {
10594 ArenaRecognizedNode::ErrorToken { token }
10595 } else {
10596 ArenaRecognizedNode::Token { token }
10597 };
10598 self.recognition_arena.push_node(node)
10599 }
10600
10601 fn arena_missing_token_node(
10602 &mut self,
10603 token_type: i32,
10604 at_index: usize,
10605 text: String,
10606 ) -> RecognizedNodeId {
10607 let extra = self
10608 .recognition_arena
10609 .push_extra(RecognitionExtra::MissingToken {
10610 token_type,
10611 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
10612 text,
10613 });
10614 self.recognition_arena
10615 .push_node(ArenaRecognizedNode::MissingToken { extra })
10616 }
10617
10618 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
10619 let ArenaRuleSpec {
10620 rule_index,
10621 invoking_state,
10622 alt_number,
10623 start_index,
10624 stop_index,
10625 return_values,
10626 children,
10627 } = spec;
10628 let return_values = (!return_values.is_empty()).then(|| {
10629 self.recognition_arena
10630 .push_extra(RecognitionExtra::ReturnValues(return_values))
10631 });
10632 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
10633 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10634 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
10635 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
10636 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
10637 stop_index: stop_index
10638 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
10639 return_values,
10640 children,
10641 })
10642 }
10643
10644 fn arena_boundary_node(&mut self, rule_index: usize, alt_number: usize) -> RecognizedNodeId {
10645 self.recognition_arena
10646 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
10647 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10648 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
10649 })
10650 }
10651
10652 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
10653 *sequence = self.recognition_arena.prepend(*sequence, node);
10654 }
10655
10656 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
10657 self.last_recognition_arena_root = root;
10658 self.last_recognition_arena_diagnostics = diagnostics;
10659 #[cfg(feature = "perf-counters")]
10660 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
10661 let stats = self.recognition_arena_stats();
10662 #[allow(clippy::print_stderr)]
10663 {
10664 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
10665 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
10666 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
10667 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
10668 eprintln!("perf recognition_links_total={}", stats.total_links);
10669 eprintln!("perf recognition_links_live={}", stats.live_links);
10670 eprintln!("perf recognition_links_dead={}", stats.dead_links);
10671 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
10672 eprintln!("perf recognition_extras_total={}", stats.total_extras);
10673 eprintln!("perf recognition_extras_live={}", stats.live_extras);
10674 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
10675 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
10676 }
10677 }
10678 }
10679
10680 fn reset_recognition_arena(&mut self) {
10681 self.recognition_arena.reset();
10682 self.last_recognition_arena_root = NodeSeqId::EMPTY;
10683 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
10684 }
10685
10686 fn current_visible_index(&mut self) -> usize {
10689 let index = self.input.index();
10690 self.input.seek(index);
10691 self.input.index()
10692 }
10693
10694 fn child_expected_reaches_clean_eof(
10697 &mut self,
10698 children: &[RecognizeOutcome],
10699 expected: &ExpectedTokens,
10700 ) -> bool {
10701 let Some(index) = expected.index else {
10702 return false;
10703 };
10704 self.token_type_at(index) == TOKEN_EOF
10705 && children
10706 .iter()
10707 .any(|child| child.diagnostics.is_empty() && child.index == index)
10708 }
10709
10710 fn previous_token_index(&self, index: usize) -> Option<usize> {
10717 self.input.previous_visible_token_index(index)
10718 }
10719
10720 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
10725 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
10726 Some(index)
10727 } else {
10728 self.previous_token_index(index)
10729 }
10730 }
10731
10732 #[must_use]
10749 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
10750 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
10751 self.rule_stop_token_index(current_index, consumed_eof)
10752 }
10753
10754 #[must_use]
10763 pub fn after_action_stop_index_for_tree(
10764 &mut self,
10765 tree: ParseTree,
10766 current_index: usize,
10767 ) -> Option<usize> {
10768 if let Some(stop) = self
10769 .node(tree)
10770 .as_rule()
10771 .and_then(crate::tree::RuleNodeView::stop_id)
10772 {
10773 return Some(stop.index());
10774 }
10775 self.after_action_stop_index(current_index)
10776 }
10777
10778 #[must_use]
10788 pub fn after_action_start_index_for_tree(
10789 &self,
10790 tree: ParseTree,
10791 fallback_index: usize,
10792 ) -> usize {
10793 if let Some(start) = self
10794 .node(tree)
10795 .as_rule()
10796 .and_then(crate::tree::RuleNodeView::start_id)
10797 {
10798 return start.index();
10799 }
10800 fallback_index
10801 }
10802
10803 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
10808 self.rule_stop_token_index(index, consumed_eof)
10809 .and_then(|token_index| self.token_id_at(token_index))
10810 }
10811
10812 fn predicate_failure_recovery(
10819 &mut self,
10820 request: PredicateFailureRecovery<'_>,
10821 ) -> RecognizeOutcome {
10822 let PredicateFailureRecovery {
10823 rule_index,
10824 index,
10825 message,
10826 member_values,
10827 return_values,
10828 rule_alt_number,
10829 } = request;
10830 let rule_name = self
10831 .rule_names()
10832 .get(rule_index)
10833 .map_or_else(|| rule_index.to_string(), Clone::clone);
10834 let diagnostic = diagnostic_for_token(
10835 self.token_at(index).as_ref(),
10836 format!("rule {rule_name} {message}"),
10837 );
10838 let mut reversed_nodes = NodeSeqId::EMPTY;
10839 let mut next_index = index;
10840 loop {
10841 let symbol = self.token_type_at(next_index);
10842 if symbol == TOKEN_EOF {
10843 break;
10844 }
10845 let error = self.arena_token_node(next_index, true);
10846 self.arena_prepend(&mut reversed_nodes, error);
10847 let after = self.consume_index(next_index, symbol);
10848 if after == next_index {
10849 break;
10850 }
10851 next_index = after;
10852 }
10853 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
10854 let diagnostics = self
10855 .recognition_arena
10856 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10857 RecognizeOutcome {
10858 index: next_index,
10859 consumed_eof: false,
10860 alt_number: rule_alt_number,
10861 member_values,
10862 return_values,
10863 diagnostics,
10864 decisions: Vec::new(),
10865 actions: Vec::new(),
10866 nodes,
10867 }
10868 }
10869
10870 fn parser_semantic_hook_result(
10873 &mut self,
10874 request: ParserSemanticHookRequest<'_>,
10875 ) -> Option<bool> {
10876 let ParserSemanticHookRequest {
10877 index,
10878 rule_index,
10879 pred_index,
10880 context,
10881 local_int_arg,
10882 member_values,
10883 } = request;
10884 let rule_name = self.rule_names().get(rule_index).cloned();
10885 self.input.seek(index);
10886 let input = &mut self.input;
10887 let semantic_hooks = &mut self.semantic_hooks;
10888 let mut ctx = ParserSemCtx {
10889 input,
10890 tree_storage: &self.tree,
10891 rule_index,
10892 coordinate_index: pred_index,
10893 rule_name,
10894 context,
10895 tree: None,
10896 local_int_arg,
10897 member_values,
10898 action: None,
10899 };
10900 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
10901 }
10902
10903 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
10908 if prior.is_empty() {
10909 return;
10910 }
10911 let mut merged = prior;
10912 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
10913 if !merged.contains(&coordinate) {
10914 merged.push(coordinate);
10915 }
10916 }
10917 self.unknown_predicate_hits = merged;
10918 }
10919
10920 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
10929 apply_unknown_predicate_policy(
10930 self.unknown_predicate_policy,
10931 rule_index,
10932 pred_index,
10933 &mut self.unknown_predicate_hits,
10934 )
10935 }
10936
10937 fn unknown_semantic_error(&self) -> Option<AntlrError> {
10940 use std::fmt::Write as _;
10941 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
10942 return None;
10943 }
10944 let mut message = String::new();
10945 for (rule_index, pred_index) in &self.unknown_predicate_hits {
10946 if !message.is_empty() {
10947 message.push_str("; ");
10948 }
10949 let _ = match self.rule_names().get(*rule_index) {
10950 Some(rule_name) => write!(
10951 message,
10952 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
10953 ),
10954 None => write!(
10955 message,
10956 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
10957 ),
10958 };
10959 }
10960 for (rule_index, source_state) in &self.unhandled_action_hits {
10961 if !message.is_empty() {
10962 message.push_str("; ");
10963 }
10964 let _ = match self.rule_names().get(*rule_index) {
10965 Some(rule_name) => write!(
10966 message,
10967 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
10968 ),
10969 None => write!(
10970 message,
10971 "unhandled semantic action: rule_index={rule_index} state={source_state}"
10972 ),
10973 };
10974 }
10975 Some(AntlrError::Unsupported(message))
10976 }
10977
10978 fn parser_semir_predicate_matches(
10986 &mut self,
10987 semantics: &ParserSemantics,
10988 predicate: &ParserSemanticPredicate,
10989 request: ParserSemanticHookRequest<'_>,
10990 ) -> bool {
10991 self.input.seek(request.index);
10992 let rule_name = self
10993 .data
10994 .rule_names()
10995 .get(request.rule_index)
10996 .map(String::as_str);
10997 let unknown_predicate_policy = self.unknown_predicate_policy;
10998 let mut ctx = ParserSemIrCtx {
10999 input: &mut self.input,
11000 tree_storage: &self.tree,
11001 semantic_hooks: &mut self.semantic_hooks,
11002 rule_index: request.rule_index,
11003 coordinate_index: request.pred_index,
11004 rule_name,
11005 context: request.context,
11006 local_int_arg: request.local_int_arg,
11007 member_values: request.member_values,
11008 invoked_predicates: &mut self.invoked_predicates,
11009 unknown_predicate_policy,
11010 unknown_predicate_hits: &mut self.unknown_predicate_hits,
11011 };
11012 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
11013 }
11014
11015 fn fast_parser_predicate_matches(
11016 &mut self,
11017 context: Option<FastPredicateContext<'_>>,
11018 transition: ParserTransition<'_>,
11019 index: usize,
11020 ) -> bool {
11021 let Some(context) = context else {
11022 return true;
11023 };
11024 let rule_index = transition.arg0() as usize;
11025 let pred_index = transition.arg1() as usize;
11026 let key = (index, rule_index, pred_index);
11027 if let Some(result) = self.fast_predicate_cache.get(&key) {
11028 return *result;
11029 }
11030 let result = self.parser_predicate_matches(PredicateEval {
11031 index,
11032 rule_index,
11033 pred_index,
11034 predicates: context.predicates,
11035 semantics: context.semantics,
11036 context: None,
11037 local_int_arg: None,
11038 member_values: context.member_values,
11039 });
11040 self.fast_predicate_cache.insert(key, result);
11041 result
11042 }
11043
11044 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
11045 let PredicateEval {
11046 index,
11047 rule_index,
11048 pred_index,
11049 predicates,
11050 semantics,
11051 context,
11052 local_int_arg,
11053 member_values,
11054 } = eval;
11055 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
11056 semantics
11057 .predicates
11058 .iter()
11059 .find(|predicate| {
11060 predicate.rule_index == rule_index && predicate.pred_index == pred_index
11061 })
11062 .map(|predicate| (semantics, predicate))
11063 }) {
11064 return self.parser_semir_predicate_matches(
11065 semantics,
11066 predicate,
11067 ParserSemanticHookRequest {
11068 index,
11069 rule_index,
11070 pred_index,
11071 context,
11072 local_int_arg,
11073 member_values,
11074 },
11075 );
11076 }
11077 let Some((_, _, predicate)) = predicates
11078 .iter()
11079 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
11080 else {
11081 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
11082 index,
11083 rule_index,
11084 pred_index,
11085 context,
11086 local_int_arg,
11087 member_values,
11088 }) {
11089 return result;
11090 }
11091 return self.unknown_predicate_result(rule_index, pred_index);
11092 };
11093 self.input.seek(index);
11094 match predicate {
11095 ParserPredicate::True => true,
11096 ParserPredicate::False => false,
11097 ParserPredicate::FalseWithMessage { .. } => false,
11098 ParserPredicate::Invoke { value } => {
11099 let key = (rule_index, pred_index);
11100 if !self.invoked_predicates.contains(&key) {
11101 self.invoked_predicates.push(key);
11102 use std::io::Write as _;
11103 let mut stdout = std::io::stdout().lock();
11104 let _ = writeln!(stdout, "eval={value}");
11105 }
11106 *value
11107 }
11108 ParserPredicate::LookaheadTextEquals { offset, text } => self
11109 .input
11110 .lt(*offset)
11111 .is_some_and(|token| Token::text(&token) == Some(*text)),
11112 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
11113 self.la(*offset) != *token_type
11114 }
11115 ParserPredicate::TokenPairAdjacent => {
11116 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
11117 return false;
11118 };
11119 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
11120 return false;
11121 };
11122 first + 1 == second
11123 }
11124 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
11125 .and_then(|context| {
11126 context
11127 .child_rules(&self.tree, self.input.token_store(), *rule_index)
11128 .next()
11129 .map(crate::tree::RuleNodeView::text)
11130 })
11131 .is_none_or(|actual| actual != *text),
11132 ParserPredicate::LocalIntEquals { value } => {
11133 local_int_arg.is_none_or(|(_, actual)| actual == *value)
11134 }
11135 ParserPredicate::LocalIntLessOrEqual { value } => {
11136 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
11137 }
11138 ParserPredicate::MemberModuloEquals {
11139 member,
11140 modulus,
11141 value,
11142 equals,
11143 } => {
11144 if *modulus == 0 {
11145 return false;
11146 }
11147 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
11148 (actual == *value) == *equals
11149 }
11150 ParserPredicate::MemberEquals {
11151 member,
11152 value,
11153 equals,
11154 } => {
11155 let actual = member_values.get(member).copied().unwrap_or_default();
11156 (actual == *value) == *equals
11157 }
11158 }
11159 }
11160
11161 fn parser_predicate_failure_message(
11163 &self,
11164 rule_index: usize,
11165 pred_index: usize,
11166 predicates: &[(usize, usize, ParserPredicate)],
11167 ) -> Option<&'static str> {
11168 predicates
11169 .iter()
11170 .find_map(|(rule, pred, predicate)| match predicate {
11171 ParserPredicate::FalseWithMessage { message }
11172 if *rule == rule_index && *pred == pred_index =>
11173 {
11174 Some(*message)
11175 }
11176 _ => None,
11177 })
11178 }
11179
11180 pub fn parser_semantic_ir_predicate_failure_message(
11183 &self,
11184 rule_index: usize,
11185 pred_index: usize,
11186 semantics: &ParserSemantics,
11187 ) -> Option<&'static str> {
11188 semantics
11189 .predicates
11190 .iter()
11191 .find(|predicate| {
11192 predicate.rule_index == rule_index && predicate.pred_index == pred_index
11193 })
11194 .and_then(|predicate| predicate.failure_message)
11195 }
11196
11197 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
11206 if symbol == TOKEN_EOF {
11207 return index;
11208 }
11209 self.input.next_visible_after(index)
11210 }
11211
11212 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
11215 let text = display_input_text(&self.input.text(start_index, error_index));
11216 diagnostic_for_token(
11217 self.token_at(error_index).as_ref(),
11218 format!("no viable alternative at input '{text}'"),
11219 )
11220 }
11221
11222 fn recovery_failure_diagnostic(
11225 &self,
11226 index: usize,
11227 decision_start_index: Option<usize>,
11228 expected_symbols: &BTreeSet<i32>,
11229 ) -> ParserDiagnostic {
11230 if expected_symbols.len() > 1 {
11231 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
11232 return self.no_viable_alternative(decision_start, index);
11233 }
11234 }
11235 diagnostic_for_token(
11236 self.token_at(index).as_ref(),
11237 format!(
11238 "mismatched input {} expecting {}",
11239 self.token_at(index)
11240 .as_ref()
11241 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
11242 self.expected_symbols_display(expected_symbols)
11243 ),
11244 )
11245 }
11246
11247 fn eof_rule_recovery_diagnostic(
11250 &self,
11251 index: usize,
11252 expected_symbols: &BTreeSet<i32>,
11253 expected: &ExpectedTokens,
11254 ) -> ParserDiagnostic {
11255 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
11256 &expected.symbols
11257 } else {
11258 expected_symbols
11259 };
11260 diagnostic_for_token(
11261 self.token_at(index).as_ref(),
11262 format!(
11263 "mismatched input {} expecting {}",
11264 self.token_at(index)
11265 .as_ref()
11266 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
11267 self.expected_symbols_display(symbols)
11268 ),
11269 )
11270 }
11271
11272 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
11278 let Some(stop) = stop else {
11279 return String::new();
11280 };
11281 let stop = if self
11282 .token_at(stop)
11283 .is_some_and(|token| token.token_type() == TOKEN_EOF)
11284 {
11285 let Some(previous) = self.previous_token_index(stop) else {
11286 return String::new();
11287 };
11288 previous
11289 } else {
11290 stop
11291 };
11292 self.input.text(start, stop)
11293 }
11294
11295 fn clear_prediction_diagnostics(&mut self) {
11298 self.prediction_diagnostics.clear();
11299 self.reported_prediction_diagnostics.clear();
11300 }
11301
11302 fn reset_per_parse_caches(&mut self) {
11326 self.rule_first_set_cache.clear();
11327 self.decision_lookahead_cache.clear();
11328 self.ll1_decision_cache.clear();
11329 self.fast_predicate_cache.clear();
11330 self.rule_stop_reach_cache.clear();
11331 self.clean_memo_mode = CleanMemoMode::Probe;
11332 self.clean_memo_probe_seen.clear();
11333 self.clean_memo_probe_samples = 0;
11334 self.clean_memo_probe_repeats = 0;
11335 self.clean_memo_sparse_samples = 0;
11336 self.recovery_symbols_intern.clear();
11337 self.state_expected_cache.clear();
11338 self.state_expected_token_cache.clear();
11339 }
11340
11341 fn record_prediction_diagnostics(
11344 &mut self,
11345 atn: &Atn,
11346 state: AtnState<'_>,
11347 start_index: usize,
11348 outcomes: &[RecognizeOutcome],
11349 ) {
11350 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
11351 return;
11352 }
11353 let Some(decision) = atn
11354 .decision_to_state()
11355 .iter()
11356 .position(|state_number| state_number == state.state_number())
11357 else {
11358 return;
11359 };
11360 let Some(rule_index) = state.rule_index() else {
11361 return;
11362 };
11363 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
11364 for outcome in outcomes
11365 .iter()
11366 .filter(|outcome| outcome.diagnostics.is_empty())
11367 {
11368 let Some(alt) = outcome.decisions.first() else {
11369 continue;
11370 };
11371 alts_by_end
11372 .entry(outcome.index)
11373 .or_default()
11374 .insert(alt + 1);
11375 }
11376 let Some((&end_index, ambig_alts)) = alts_by_end
11377 .iter()
11378 .filter(|(_, alts)| alts.len() > 1)
11379 .max_by_key(|(end, _)| *end)
11380 else {
11381 return;
11382 };
11383 let rule_name = self
11384 .rule_names()
11385 .get(rule_index)
11386 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
11387 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
11388 let input = display_input_text(&self.input.text(start_index, stop_index));
11389 let alts = ambig_alts
11390 .iter()
11391 .map(usize::to_string)
11392 .collect::<Vec<_>>()
11393 .join(", ");
11394 let key = (decision, start_index, format!("{alts}:{input}"));
11395 if !self.reported_prediction_diagnostics.insert(key) {
11396 return;
11397 }
11398 let start_diagnostic = diagnostic_for_token(
11399 self.token_at(start_index),
11400 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
11401 );
11402 let stop_diagnostic = diagnostic_for_token(
11403 self.token_at(stop_index),
11404 format!(
11405 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
11406 ),
11407 );
11408 self.prediction_diagnostics.push(start_diagnostic);
11409 self.prediction_diagnostics.push(stop_diagnostic);
11410 }
11411
11412 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
11414 expected_symbols_display(
11415 &state_expected_symbols(atn, state_number),
11416 self.vocabulary(),
11417 )
11418 }
11419
11420 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
11425 let state = usize::try_from(self.data().state()).unwrap_or(0);
11426 ExpectedTokenSet {
11427 symbols: state_expected_symbols(atn, state),
11428 }
11429 }
11430
11431 pub const fn set_bail_on_error(&mut self, bail: bool) {
11434 self.bail_on_error = bail;
11435 }
11436
11437 #[must_use]
11439 pub const fn bail_on_error(&self) -> bool {
11440 self.bail_on_error
11441 }
11442
11443 pub fn rule_invocation_stack(&self) -> Vec<String> {
11446 self.rule_context_stack
11447 .iter()
11448 .rev()
11449 .map(|frame| {
11450 self.data()
11451 .rule_names()
11452 .get(frame.rule_index)
11453 .cloned()
11454 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
11455 })
11456 .collect()
11457 }
11458
11459 pub fn active_invocation_states(&self) -> Vec<isize> {
11463 self.rule_context_stack
11464 .iter()
11465 .skip(1)
11466 .rev()
11467 .map(|frame| frame.invoking_state)
11468 .collect()
11469 }
11470
11471 pub fn token_display_at(&self, index: usize) -> Option<String> {
11473 self.token_at(index).map(|token| format!("{token}"))
11474 }
11475}
11476
11477impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
11478where
11479 S: TokenSource,
11480 H: SemanticHooks,
11481{
11482 fn parse_rule(
11483 &mut self,
11484 rule_index: usize,
11485 invoking_state: isize,
11486 precedence: i32,
11487 ) -> DirectAdaptiveParseResult<ParseTree> {
11488 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
11489 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
11490 )?;
11491 let stop_state = self
11492 .atn
11493 .rule_to_stop_state()
11494 .get(rule_index)
11495 .filter(|state| *state != usize::MAX)
11496 .ok_or(DirectAdaptiveParseControl::Fallback(
11497 DirectAdaptiveFallback::MissingAtn,
11498 ))?;
11499 let start_index = self.parser.current_visible_index();
11500 let mut context = ParserRuleContext::new(rule_index, invoking_state);
11501 if let Some(token) = self.parser.token_id_at(start_index) {
11502 self.parser.set_context_start(&mut context, token);
11503 }
11504 let mut state_number = start_state;
11505 let mut consumed_eof = false;
11506 while state_number != stop_state {
11507 self.step()?;
11508 let (transition, boundary) = self.next_transition(state_number, precedence)?;
11509 if boundary.is_some() {
11510 return Err(DirectAdaptiveParseControl::Fallback(
11511 DirectAdaptiveFallback::LeftRecursiveBoundary,
11512 ));
11513 }
11514 match transition.data() {
11515 Transition::Epsilon { target } => {
11516 state_number = target;
11517 }
11518 Transition::Precedence {
11519 target,
11520 precedence: transition_precedence,
11521 } => {
11522 if transition_precedence < precedence {
11523 return Err(DirectAdaptiveParseControl::Fallback(
11524 DirectAdaptiveFallback::Precedence,
11525 ));
11526 }
11527 state_number = target;
11528 }
11529 Transition::Rule {
11530 rule_index,
11531 follow_state,
11532 precedence: rule_precedence,
11533 ..
11534 } => {
11535 let child = self.parse_rule(
11536 rule_index,
11537 invoking_state_number(state_number),
11538 rule_precedence,
11539 )?;
11540 if self.parser.build_parse_trees {
11541 self.parser.tree.add_child(&mut context, child);
11542 }
11543 state_number = follow_state;
11544 }
11545 Transition::Atom { .. }
11546 | Transition::Range { .. }
11547 | Transition::Set { .. }
11548 | Transition::NotSet { .. }
11549 | Transition::Wildcard { .. } => {
11550 let (matched_eof, child) = self.consume_transition(transition)?;
11551 consumed_eof |= matched_eof;
11552 if let Some(child) = child {
11553 self.parser.tree.add_child(&mut context, child);
11554 }
11555 state_number = transition.target();
11556 }
11557 Transition::Predicate { .. } => {
11558 return Err(DirectAdaptiveParseControl::Fallback(
11559 DirectAdaptiveFallback::Predicate,
11560 ));
11561 }
11562 Transition::Action { .. } => {
11563 return Err(DirectAdaptiveParseControl::Fallback(
11564 DirectAdaptiveFallback::Action,
11565 ));
11566 }
11567 }
11568 }
11569
11570 let stop_index = self
11571 .parser
11572 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
11573 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
11574 self.parser.set_context_stop(&mut context, token);
11575 }
11576 Ok(self.parser.rule_node(context))
11577 }
11578
11579 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
11580 self.steps += 1;
11581 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
11582 return Err(DirectAdaptiveParseControl::Fallback(
11583 DirectAdaptiveFallback::StepLimit,
11584 ));
11585 }
11586 Ok(())
11587 }
11588
11589 fn next_transition(
11590 &mut self,
11591 state_number: usize,
11592 precedence: i32,
11593 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
11594 let state = self
11595 .atn
11596 .state(state_number)
11597 .ok_or(DirectAdaptiveParseControl::Fallback(
11598 DirectAdaptiveFallback::MissingAtn,
11599 ))?;
11600 if state.is_rule_stop() {
11601 return Err(DirectAdaptiveParseControl::Fallback(
11602 DirectAdaptiveFallback::RuleStop,
11603 ));
11604 }
11605 let transition_index =
11606 self.transition_index(state_number, state.transitions().len(), precedence)?;
11607 let transition = state.transitions().get(transition_index).ok_or(
11608 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
11609 )?;
11610 let boundary = match &transition.data() {
11611 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
11612 left_recursive_boundary(self.atn, state, *target)
11613 }
11614 _ => None,
11615 };
11616 Ok((transition, boundary))
11617 }
11618
11619 fn transition_index(
11620 &mut self,
11621 state_number: usize,
11622 transition_count: usize,
11623 precedence: i32,
11624 ) -> DirectAdaptiveParseResult<usize> {
11625 match transition_count {
11626 0 => Err(DirectAdaptiveParseControl::Fallback(
11627 DirectAdaptiveFallback::NoTransition,
11628 )),
11629 1 => Ok(0),
11630 _ => {
11631 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
11632 return Ok(alt);
11633 }
11634 let decision = self
11635 .decision_by_state
11636 .get(state_number)
11637 .and_then(|decision| *decision)
11638 .ok_or(DirectAdaptiveParseControl::Fallback(
11639 DirectAdaptiveFallback::UnknownDecision,
11640 ))?;
11641 let prediction = self
11642 .simulator
11643 .adaptive_predict_stream_info_with_precedence(
11644 decision,
11645 direct_precedence(precedence),
11646 &mut self.parser.input,
11647 )
11648 .map_err(|_| {
11649 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
11650 })?;
11651 if prediction.has_semantic_context {
11652 return Err(DirectAdaptiveParseControl::Fallback(
11653 DirectAdaptiveFallback::SemanticContext,
11654 ));
11655 }
11656 prediction
11657 .alt
11658 .checked_sub(1)
11659 .filter(|index| *index < transition_count)
11660 .ok_or(DirectAdaptiveParseControl::Fallback(
11661 DirectAdaptiveFallback::InvalidAlt,
11662 ))
11663 }
11664 }
11665 }
11666
11667 fn ll1_transition_index(
11668 &mut self,
11669 state_number: usize,
11670 transition_count: usize,
11671 ) -> DirectAdaptiveParseResult<Option<usize>> {
11672 let state = self
11673 .atn
11674 .state(state_number)
11675 .ok_or(DirectAdaptiveParseControl::Fallback(
11676 DirectAdaptiveFallback::MissingAtn,
11677 ))?;
11678 if state.precedence_rule_decision() {
11679 return Ok(None);
11680 }
11681 let Some(rule_stop) = state
11682 .rule_index()
11683 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
11684 else {
11685 return Ok(None);
11686 };
11687 let symbol = self.parser.input.la_token(1);
11688 let entry = self
11689 .parser
11690 .cached_decision_lookahead(self.atn, state, rule_stop);
11691 Ok(
11692 ll1_greedy_alt(&entry, symbol, state.non_greedy())
11693 .filter(|alt| *alt < transition_count),
11694 )
11695 }
11696
11697 fn consume_transition(
11698 &mut self,
11699 transition: ParserTransition<'_>,
11700 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
11701 let symbol = self.parser.input.la_token(1);
11702 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
11703 return Err(DirectAdaptiveParseControl::Fallback(
11704 DirectAdaptiveFallback::TokenMismatch,
11705 ));
11706 }
11707 let token = self
11708 .parser
11709 .input
11710 .lt_id(1)
11711 .ok_or(DirectAdaptiveParseControl::Fallback(
11712 DirectAdaptiveFallback::TokenMismatch,
11713 ))?;
11714 let matched_eof = symbol == TOKEN_EOF;
11715 if !matched_eof {
11716 self.parser.consume();
11717 }
11718 let child = self
11719 .parser
11720 .build_parse_trees
11721 .then(|| self.parser.terminal_tree(token));
11722 Ok((matched_eof, child))
11723 }
11724}
11725
11726fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
11729 if !state.precedence_rule_decision() {
11730 return None;
11731 }
11732 let target_state = atn.state(target)?;
11733 if target_state.kind() == AtnStateKind::LoopEnd {
11734 return None;
11735 }
11736 state.rule_index()
11737}
11738
11739fn next_alt_number(
11746 state: AtnState<'_>,
11747 transition_count: usize,
11748 transition_index: usize,
11749 current_alt_number: usize,
11750 track_alt_numbers: bool,
11751) -> usize {
11752 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
11753 return current_alt_number;
11754 }
11755 if matches!(
11756 state.kind(),
11757 AtnStateKind::Basic
11758 | AtnStateKind::BlockStart
11759 | AtnStateKind::PlusBlockStart
11760 | AtnStateKind::StarBlockStart
11761 | AtnStateKind::StarLoopEntry
11762 ) && !state.precedence_rule_decision()
11763 {
11764 return transition_index + 1;
11765 }
11766 current_alt_number
11767}
11768
11769fn invoking_state_number(state_number: usize) -> isize {
11772 isize::try_from(state_number).unwrap_or(isize::MAX)
11773}
11774
11775const fn packed_i32(value: u32) -> i32 {
11776 i32::from_le_bytes(value.to_le_bytes())
11777}
11778
11779fn direct_precedence(precedence: i32) -> usize {
11780 usize::try_from(precedence.max(0)).unwrap_or_default()
11781}
11782
11783fn token_input_display(token: &impl Token) -> String {
11784 format!("'{}'", token.text().unwrap_or("<EOF>"))
11785}
11786
11787fn display_input_text(text: &str) -> String {
11788 let mut out = String::new();
11789 for ch in text.chars() {
11790 match ch {
11791 '\n' => out.push_str("\\n"),
11792 '\r' => out.push_str("\\r"),
11793 '\t' => out.push_str("\\t"),
11794 other => out.push(other),
11795 }
11796 }
11797 out
11798}
11799
11800fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
11801 let (line, column) = token.map_or((0, 0), |token| (token.line(), token.column()));
11802 ParserDiagnostic {
11803 line,
11804 column,
11805 message,
11806 }
11807}
11808
11809fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
11810 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
11811}
11812
11813fn expected_symbols_display_iter(
11814 symbols: impl IntoIterator<Item = i32>,
11815 vocabulary: &Vocabulary,
11816) -> String {
11817 let items = symbols
11818 .into_iter()
11819 .map(|symbol| expected_symbol_display(symbol, vocabulary))
11820 .collect::<Vec<_>>();
11821 if let [single] = items.as_slice() {
11822 return single.clone();
11823 }
11824 format!("{{{}}}", items.join(", "))
11825}
11826
11827fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
11828 if symbol == TOKEN_EOF {
11829 return "<EOF>".to_owned();
11830 }
11831 vocabulary.display_name(symbol)
11832}
11833
11834fn caller_follow_token_info_for_stream<S: TokenSource>(
11835 input: &mut CommonTokenStream<S>,
11836 index: usize,
11837) -> (i32, bool, bool) {
11838 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
11841 input.fill();
11842 }
11843 let token_type = input.token_type_at_index(index);
11844 let visible_channel = input.channel();
11845 let token = input.get(index);
11846 let is_boundary = token
11847 .as_ref()
11848 .and_then(Token::text)
11849 .is_some_and(is_caller_follow_boundary_text);
11850 let is_boundary_gap = token.as_ref().is_some_and(|token| {
11851 token.channel() != visible_channel
11852 || is_caller_follow_boundary_gap_text(token.text_or_empty())
11853 });
11854 (token_type, is_boundary, is_boundary_gap)
11855}
11856
11857fn is_caller_follow_boundary_text(text: &str) -> bool {
11858 text.chars().any(|ch| ch == ';' || ch == '\n')
11859 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11860}
11861
11862fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
11863 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11864}
11865
11866fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
11870 let Some(rule_index) = state.rule_index() else {
11871 return false;
11872 };
11873 atn.rule_to_start_state()
11874 .get(rule_index)
11875 .and_then(|state_number| atn.state(state_number))
11876 .is_some_and(AtnState::left_recursive_rule)
11877}
11878
11879fn select_better_top_outcome(
11886 first: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
11887 second: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
11888 arena: &RecognitionArena,
11889) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
11890 match (first, second) {
11891 (Ok(first), Ok(second)) => {
11892 if arena.diagnostics(first.0.diagnostics).next().is_none() {
11893 Ok(first)
11894 } else {
11895 Ok(second)
11896 }
11897 }
11898 (Ok(first), Err(_)) => Ok(first),
11899 (Err(_), Ok(second)) => Ok(second),
11900 (Err(_), Err(second_expected)) => Err(second_expected),
11901 }
11902}
11903
11904fn select_best_fast_outcome(
11910 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
11911 prediction_mode: PredictionMode,
11912 caller_follow: Option<&TokenBitSet>,
11913 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
11914 arena: &RecognitionArena,
11915) -> Option<FastRecognizeOutcome> {
11916 let mut best = None;
11917 let mut best_caller_follow = None;
11918 for outcome in outcomes {
11919 if matches!(
11920 prediction_mode,
11921 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
11922 ) && outcome.diagnostics.is_empty()
11923 && let Some(follow) = caller_follow
11924 {
11925 let (token_type, is_boundary, _) = token_info_at(outcome.index);
11926 if is_boundary && follow.contains(token_type) {
11927 let replace =
11928 best_caller_follow
11929 .as_ref()
11930 .is_none_or(|existing: &FastRecognizeOutcome| {
11931 (outcome.index, outcome.consumed_eof)
11932 < (existing.index, existing.consumed_eof)
11933 });
11934 if replace {
11935 best_caller_follow = Some(outcome);
11936 }
11937 }
11938 }
11939 let Some(existing) = best else {
11940 best = Some(outcome);
11941 continue;
11942 };
11943 let outcome_position = (outcome.index, outcome.consumed_eof);
11944 let best_position = (existing.index, existing.consumed_eof);
11945 let better = match prediction_mode {
11946 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
11947 outcome_position,
11948 outcome.diagnostics,
11949 best_position,
11950 existing.diagnostics,
11951 arena,
11952 ),
11953 PredictionMode::Sll => outcome.index > existing.index,
11954 };
11955 best = Some(if better { outcome } else { existing });
11956 }
11957 let should_use_caller_follow =
11958 best_caller_follow
11959 .as_ref()
11960 .zip(best.as_ref())
11961 .is_some_and(|(candidate, selected)| {
11962 if !selected.diagnostics.is_empty() {
11963 return true;
11964 }
11965 candidate.index < selected.index
11966 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
11967 });
11968 if should_use_caller_follow {
11969 best_caller_follow
11970 } else {
11971 best
11972 }
11973}
11974
11975fn select_best_outcome(
11976 outcomes: impl Iterator<Item = RecognizeOutcome>,
11977 prediction_mode: PredictionMode,
11978 arena: &RecognitionArena,
11979) -> Option<RecognizeOutcome> {
11980 let outcomes = outcomes.collect::<Vec<_>>();
11981 let prefer_first_tie = outcomes
11982 .iter()
11983 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
11984 outcomes.into_iter().reduce(|best, outcome| {
11985 let outcome_position = (outcome.index, outcome.consumed_eof);
11986 let best_position = (best.index, best.consumed_eof);
11987 let better = match prediction_mode {
11988 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
11989 outcome_is_better(
11990 outcome_position,
11991 outcome.diagnostics,
11992 best_position,
11993 best.diagnostics,
11994 arena,
11995 ) || (outcome_position == best_position
11996 && arena.diagnostics_len(outcome.diagnostics)
11997 == arena.diagnostics_len(best.diagnostics)
11998 && arena.diagnostics_recovery_rank(outcome.diagnostics)
11999 == arena.diagnostics_recovery_rank(best.diagnostics)
12000 && (outcome.decisions < best.decisions
12001 || (!prefer_first_tie
12002 && outcome.decisions == best.decisions
12003 && outcome.actions > best.actions)))
12004 }
12005 PredictionMode::Sll => {
12006 outcome_position > best_position
12007 || (outcome_position == best_position
12008 && !prefer_first_tie
12009 && (outcome.decisions < best.decisions
12010 || (outcome.decisions == best.decisions
12011 && outcome_is_better(
12012 outcome_position,
12013 outcome.diagnostics,
12014 best_position,
12015 best.diagnostics,
12016 arena,
12017 ))))
12018 }
12019 };
12020 if better {
12021 return outcome;
12022 }
12023 best
12024 })
12025}
12026
12027fn transition_decision(
12034 atn: &Atn,
12035 state: AtnState<'_>,
12036 transition_count: usize,
12037 transition_index: usize,
12038 predicates: &[(usize, usize, ParserPredicate)],
12039) -> Option<usize> {
12040 if transition_count <= 1 || decision_reaches_unsupported_predicate(atn, state, predicates) {
12041 return None;
12042 }
12043 Some(transition_index)
12044}
12045
12046fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
12052 transition_count > 1
12053 && !matches!(
12054 state.kind(),
12055 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
12056 )
12057}
12058
12059fn record_no_viable_if_ambiguous(
12062 expected: &mut ExpectedTokens,
12063 decision_start_index: Option<usize>,
12064 index: usize,
12065) {
12066 if expected.index == Some(index) && expected.symbols.len() > 1 {
12067 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
12068 expected.record_no_viable(decision_start, index);
12069 }
12070 }
12071}
12072
12073const fn record_predicate_no_viable(
12076 expected: &mut ExpectedTokens,
12077 decision_start_index: Option<usize>,
12078 index: usize,
12079) {
12080 if let Some(decision_start) = decision_start_index {
12081 expected.record_no_viable(decision_start, index);
12082 }
12083}
12084
12085const fn no_viable_decision_start(
12087 decision_start_index: Option<usize>,
12088 index: usize,
12089) -> Option<usize> {
12090 match decision_start_index {
12091 Some(start) if index > start => Some(start),
12092 _ => None,
12093 }
12094}
12095
12096fn restore_expected(
12100 children: &[RecognizeOutcome],
12101 child_start_index: usize,
12102 expected: &mut ExpectedTokens,
12103 snapshot: ExpectedTokens,
12104 preserve_child_expected: bool,
12105) {
12106 if preserve_child_expected {
12107 return;
12108 }
12109 if children
12110 .iter()
12111 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
12112 {
12113 *expected = snapshot;
12114 }
12115}
12116
12117fn decision_reaches_unsupported_predicate(
12120 atn: &Atn,
12121 state: AtnState<'_>,
12122 predicates: &[(usize, usize, ParserPredicate)],
12123) -> bool {
12124 state.transitions().iter().any(|transition| {
12125 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
12126 })
12127}
12128
12129fn transition_reaches_unsupported_predicate(
12131 atn: &Atn,
12132 transition: ParserTransition<'_>,
12133 predicates: &[(usize, usize, ParserPredicate)],
12134 visited: &mut BTreeSet<usize>,
12135) -> bool {
12136 match &transition.data() {
12137 Transition::Predicate {
12138 rule_index,
12139 pred_index,
12140 ..
12141 } => !predicates
12142 .iter()
12143 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
12144 Transition::Epsilon { target }
12145 | Transition::Action { target, .. }
12146 | Transition::Rule { target, .. } => {
12147 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
12148 }
12149 Transition::Precedence { .. }
12150 | Transition::Atom { .. }
12151 | Transition::Range { .. }
12152 | Transition::Set { .. }
12153 | Transition::NotSet { .. }
12154 | Transition::Wildcard { .. } => false,
12155 }
12156}
12157
12158fn state_reaches_unsupported_predicate(
12160 atn: &Atn,
12161 state_number: usize,
12162 predicates: &[(usize, usize, ParserPredicate)],
12163 visited: &mut BTreeSet<usize>,
12164) -> bool {
12165 if !visited.insert(state_number) {
12166 return false;
12167 }
12168 let Some(state) = atn.state(state_number) else {
12169 return false;
12170 };
12171 state.transitions().iter().any(|transition| {
12172 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
12173 })
12174}
12175
12176fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
12178 if let Some(decision) = decision {
12179 outcome.decisions.insert(0, decision);
12180 }
12181}
12182
12183fn outcome_is_better(
12184 outcome_position: (usize, bool),
12185 outcome_diagnostics: DiagnosticSeqId,
12186 best_position: (usize, bool),
12187 best_diagnostics: DiagnosticSeqId,
12188 arena: &RecognitionArena,
12189) -> bool {
12190 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
12191 let best_len = arena.diagnostics_len(best_diagnostics);
12192 outcome_position > best_position
12193 || (outcome_position == best_position
12194 && (outcome_len < best_len
12195 || (outcome_len == best_len
12196 && arena.diagnostics_recovery_rank(outcome_diagnostics)
12197 < arena.diagnostics_recovery_rank(best_diagnostics))))
12198}
12199
12200fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
12201 if outcomes
12202 .iter()
12203 .any(|outcome| outcome.diagnostics.is_empty())
12204 {
12205 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
12206 }
12207}
12208
12209fn discard_recovered_outcomes_if_clean_path_exists(
12210 outcomes: &mut Vec<RecognizeOutcome>,
12211 arena: &RecognitionArena,
12212) {
12213 if outcomes
12214 .iter()
12215 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
12216 {
12217 return;
12218 }
12219 if outcomes
12220 .iter()
12221 .any(|outcome| outcome.diagnostics.is_empty())
12222 {
12223 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
12224 }
12225}
12226
12227fn outcome_has_rule_failure_diagnostic(
12230 outcome: &RecognizeOutcome,
12231 arena: &RecognitionArena,
12232) -> bool {
12233 arena
12234 .diagnostics(outcome.diagnostics)
12235 .any(|diagnostic| diagnostic.message.starts_with("rule "))
12236}
12237
12238fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
12252 if outcomes.len() < 2 {
12253 return;
12254 }
12255 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
12256 outcomes.retain(|outcome| {
12257 seen.insert((
12258 outcome.index,
12259 outcome.consumed_eof,
12260 arena.diagnostics_len(outcome.diagnostics),
12261 arena.diagnostics_recovery_rank(outcome.diagnostics),
12262 ))
12263 });
12264}
12265
12266const FAST_OUTCOME_INLINE_KEYS: usize = 8;
12267const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
12268const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
12269const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
12270
12271#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12272enum FastOutcomeDedupStrategy {
12273 Inline,
12274 Dense,
12275 Sparse,
12276}
12277
12278impl FastOutcomeDedupScratch {
12279 fn prepare_dense(&mut self, word_count: usize) {
12280 while let Some(word_index) = self.touched_dense_words.pop() {
12281 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
12282 }
12283 if self.dense_words.len() < word_count {
12284 self.dense_words.resize(word_count, 0);
12285 }
12286 }
12287}
12288
12289fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
12290 let first_index = outcomes.first()?.index;
12291 let (min_index, max_index) = outcomes[1..].iter().fold(
12292 (first_index, first_index),
12293 |(min_index, max_index), outcome| {
12294 (min_index.min(outcome.index), max_index.max(outcome.index))
12295 },
12296 );
12297 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
12298 let bit_count = index_span.checked_mul(2)?;
12299 let word_count =
12300 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
12301 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
12302 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
12303 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
12304 .then_some((min_index, word_count))
12305}
12306
12307#[cfg(feature = "perf-counters")]
12308fn record_clean_fast_outcome_dedup(
12309 strategy: FastOutcomeDedupStrategy,
12310 input_len: usize,
12311 output_len: usize,
12312 dense_words: usize,
12313) {
12314 let counter = match strategy {
12315 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
12316 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
12317 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
12318 };
12319 perf_counters::inc(
12320 &perf_counters::OUTCOME_DEDUPE_INPUTS,
12321 u64::try_from(input_len).unwrap_or(u64::MAX),
12322 );
12323 perf_counters::inc(
12324 &perf_counters::OUTCOME_DEDUPE_REMOVED,
12325 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
12326 );
12327 perf_counters::inc(counter, 1);
12328 perf_counters::inc(
12329 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
12330 u64::try_from(dense_words).unwrap_or(u64::MAX),
12331 );
12332}
12333
12334fn dedupe_clean_fast_outcomes(
12338 outcomes: &mut Vec<FastRecognizeOutcome>,
12339 scratch: &mut FastOutcomeDedupScratch,
12340) -> FastOutcomeDedupStrategy {
12341 #[cfg(feature = "perf-counters")]
12342 let input_len = outcomes.len();
12343 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
12344 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
12345 let mut inline_len = 0_usize;
12346 outcomes.retain(|outcome| {
12347 let key = (outcome.index, outcome.consumed_eof);
12348 if inline_keys[..inline_len].contains(&key) {
12349 return false;
12350 }
12351 inline_keys[inline_len] = key;
12352 inline_len += 1;
12353 true
12354 });
12355 #[cfg(feature = "perf-counters")]
12356 record_clean_fast_outcome_dedup(
12357 FastOutcomeDedupStrategy::Inline,
12358 input_len,
12359 outcomes.len(),
12360 0,
12361 );
12362 return FastOutcomeDedupStrategy::Inline;
12363 }
12364
12365 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
12366 scratch.prepare_dense(word_count);
12367 outcomes.retain(|outcome| {
12368 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
12369 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
12370 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
12371 let word = &mut scratch.dense_words[word_index];
12372 if *word & bit != 0 {
12373 return false;
12374 }
12375 if *word == 0 {
12376 scratch
12377 .touched_dense_words
12378 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
12379 }
12380 *word |= bit;
12381 true
12382 });
12383 #[cfg(feature = "perf-counters")]
12384 record_clean_fast_outcome_dedup(
12385 FastOutcomeDedupStrategy::Dense,
12386 input_len,
12387 outcomes.len(),
12388 word_count,
12389 );
12390 return FastOutcomeDedupStrategy::Dense;
12391 }
12392
12393 scratch.sparse_keys.clear();
12394 scratch.sparse_keys.reserve(outcomes.len());
12395 outcomes.retain(|outcome| {
12396 scratch
12397 .sparse_keys
12398 .insert((outcome.index, outcome.consumed_eof))
12399 });
12400 #[cfg(feature = "perf-counters")]
12401 record_clean_fast_outcome_dedup(
12402 FastOutcomeDedupStrategy::Sparse,
12403 input_len,
12404 outcomes.len(),
12405 0,
12406 );
12407 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
12408 scratch.sparse_keys = FxHashSet::default();
12409 }
12410 FastOutcomeDedupStrategy::Sparse
12411}
12412
12413fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
12416 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
12417 outcomes
12418 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
12419}
12420
12421fn compare_recognize_outcomes(
12422 left: &RecognizeOutcome,
12423 right: &RecognizeOutcome,
12424 arena: &RecognitionArena,
12425) -> Ordering {
12426 left.index
12427 .cmp(&right.index)
12428 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
12429 .then_with(|| left.alt_number.cmp(&right.alt_number))
12430 .then_with(|| left.member_values.cmp(&right.member_values))
12431 .then_with(|| left.return_values.cmp(&right.return_values))
12432 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
12433 .then_with(|| left.decisions.cmp(&right.decisions))
12434 .then_with(|| left.actions.cmp(&right.actions))
12435 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
12436}
12437
12438impl<S, H> Recognizer for BaseParser<S, H>
12439where
12440 S: TokenSource,
12441 H: SemanticHooks,
12442{
12443 fn data(&self) -> &RecognizerData {
12444 &self.data
12445 }
12446
12447 fn data_mut(&mut self) -> &mut RecognizerData {
12448 &mut self.data
12449 }
12450}
12451
12452impl<S, H> Parser for BaseParser<S, H>
12453where
12454 S: TokenSource,
12455 H: SemanticHooks,
12456{
12457 fn build_parse_trees(&self) -> bool {
12458 self.build_parse_trees
12459 }
12460
12461 fn set_build_parse_trees(&mut self, build: bool) {
12462 self.build_parse_trees = build;
12463 }
12464
12465 fn number_of_syntax_errors(&self) -> usize {
12466 Self::number_of_syntax_errors(self)
12467 }
12468
12469 fn report_diagnostic_errors(&self) -> bool {
12470 self.report_diagnostic_errors
12471 }
12472
12473 fn set_report_diagnostic_errors(&mut self, report: bool) {
12474 self.report_diagnostic_errors = report;
12475 }
12476
12477 fn prediction_mode(&self) -> PredictionMode {
12478 self.prediction_mode
12479 }
12480
12481 fn set_prediction_mode(&mut self, mode: PredictionMode) {
12482 self.prediction_mode = mode;
12483 }
12484}
12485
12486#[cfg(test)]
12487#[allow(clippy::disallowed_methods)] mod tests {
12489 use super::*;
12490 use crate::atn::parser::{
12491 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
12492 };
12493 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
12494 use crate::token::{HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError};
12495 use crate::token_stream::CommonTokenStream;
12496 use crate::tree::{NodeKind, ParseTreeStats};
12497 use crate::vocabulary::Vocabulary;
12498 use std::cell::RefCell;
12499 use std::mem::size_of;
12500 use std::rc::Rc;
12501 use std::sync::{Arc, Mutex};
12502
12503 #[test]
12504 fn fx_hasher_write_matches_typed_methods_for_full_words() {
12505 let value: u64 = 0x0102_0304_0506_0708;
12512 let mut typed = FxHasher::default();
12513 typed.write_u64(value);
12514 let mut bytewise = FxHasher::default();
12515 bytewise.write(&value.to_le_bytes());
12516 assert_eq!(typed.finish(), bytewise.finish());
12517 }
12518
12519 #[derive(Clone, Debug)]
12520 struct TestToken {
12521 spec: TokenSpec,
12522 id: TokenId,
12523 source_name: String,
12524 }
12525
12526 impl TestToken {
12527 fn new(token_type: i32) -> Self {
12528 Self {
12529 spec: TokenSpec::explicit(token_type, ""),
12530 id: TokenId::try_from(0).expect("zero token ID"),
12531 source_name: String::new(),
12532 }
12533 }
12534
12535 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
12536 Self {
12537 spec: TokenSpec::eof(index, index, line, column),
12538 id: TokenId::try_from(0).expect("zero token ID"),
12539 source_name: source_name.to_owned(),
12540 }
12541 }
12542
12543 fn with_text(mut self, text: impl Into<String>) -> Self {
12544 self.spec.text = Some(text.into());
12545 self
12546 }
12547
12548 const fn with_channel(mut self, channel: i32) -> Self {
12549 self.spec.channel = channel;
12550 self
12551 }
12552
12553 const fn with_span(mut self, start: usize, stop: usize) -> Self {
12554 self.spec.start = start;
12555 self.spec.stop = stop;
12556 self.spec.start_byte = start;
12557 self.spec.stop_byte = match stop.checked_add(1) {
12558 Some(end) if end >= start => end,
12559 Some(_) | None => start,
12560 };
12561 self
12562 }
12563
12564 const fn with_position(mut self, line: usize, column: usize) -> Self {
12565 self.spec.line = line;
12566 self.spec.column = column;
12567 self
12568 }
12569
12570 fn set_token_index(&mut self, index: isize) {
12571 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
12572 }
12573 }
12574
12575 impl Token for TestToken {
12576 fn token_id(&self) -> TokenId {
12577 self.id
12578 }
12579
12580 fn token_type(&self) -> i32 {
12581 self.spec.token_type
12582 }
12583
12584 fn channel(&self) -> i32 {
12585 self.spec.channel
12586 }
12587
12588 fn start(&self) -> usize {
12589 self.spec.start
12590 }
12591
12592 fn stop(&self) -> usize {
12593 self.spec.stop
12594 }
12595
12596 fn line(&self) -> usize {
12597 self.spec.line
12598 }
12599
12600 fn column(&self) -> usize {
12601 self.spec.column
12602 }
12603
12604 fn text(&self) -> Option<&str> {
12605 self.spec.text.as_deref()
12606 }
12607
12608 fn source_name(&self) -> &str {
12609 &self.source_name
12610 }
12611
12612 fn start_byte(&self) -> usize {
12613 self.spec.start_byte
12614 }
12615
12616 fn stop_byte(&self) -> usize {
12617 self.spec.stop_byte
12618 }
12619 }
12620
12621 #[derive(Debug)]
12622 struct Source {
12623 tokens: Vec<TestToken>,
12624 index: usize,
12625 }
12626
12627 impl TokenSource for Source {
12628 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
12629 let token = self
12630 .tokens
12631 .get(self.index)
12632 .cloned()
12633 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
12634 self.index += 1;
12635 sink.push(token.spec)
12636 }
12637
12638 fn line(&self) -> usize {
12639 1
12640 }
12641
12642 fn column(&self) -> usize {
12643 self.index
12644 }
12645
12646 fn source_name(&self) -> &'static str {
12647 "parser-test"
12648 }
12649 }
12650
12651 #[derive(Clone, Debug, Eq, PartialEq)]
12652 struct RecordedDiagnostic {
12653 grammar_file_name: String,
12654 line: usize,
12655 column: usize,
12656 message: String,
12657 error: Option<AntlrError>,
12658 }
12659
12660 #[derive(Clone, Debug)]
12661 struct RecordingErrorListener {
12662 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
12663 }
12664
12665 impl<R> crate::ErrorListener<R> for RecordingErrorListener
12666 where
12667 R: Recognizer + ?Sized,
12668 {
12669 fn syntax_error(
12670 &mut self,
12671 recognizer: &R,
12672 line: usize,
12673 column: usize,
12674 message: &str,
12675 error: Option<&AntlrError>,
12676 ) {
12677 self.diagnostics
12678 .lock()
12679 .expect("recorded diagnostics lock")
12680 .push(RecordedDiagnostic {
12681 grammar_file_name: recognizer.grammar_file_name().to_owned(),
12682 line,
12683 column,
12684 message: message.to_owned(),
12685 error: error.cloned(),
12686 });
12687 }
12688 }
12689
12690 #[derive(Debug)]
12691 struct ReportingSource {
12692 source: Source,
12693 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
12694 }
12695
12696 impl TokenSource for ReportingSource {
12697 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
12698 self.source.next_token(sink)
12699 }
12700
12701 fn line(&self) -> usize {
12702 self.source.line()
12703 }
12704
12705 fn column(&self) -> usize {
12706 self.source.column()
12707 }
12708
12709 fn source_name(&self) -> &str {
12710 self.source.source_name()
12711 }
12712
12713 fn report_error(&self, error: &TokenSourceError) -> bool {
12714 self.diagnostics.borrow_mut().push(error.clone());
12715 true
12716 }
12717 }
12718
12719 fn mini_parser_data() -> RecognizerData {
12720 RecognizerData::new(
12721 "Mini.g4",
12722 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
12723 )
12724 .with_rule_names(["s"])
12725 }
12726
12727 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
12728 let data = mini_parser_data();
12729 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
12730 }
12731
12732 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
12733 where
12734 H: SemanticHooks,
12735 {
12736 BaseParser::with_semantic_hooks(
12737 CommonTokenStream::new(Source { tokens, index: 0 }),
12738 mini_parser_data(),
12739 hooks,
12740 )
12741 }
12742
12743 #[test]
12744 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
12745 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
12746 parser.remove_error_listeners();
12747 let diagnostics = Arc::new(Mutex::new(Vec::new()));
12748 parser.add_error_listener(RecordingErrorListener {
12749 diagnostics: Arc::clone(&diagnostics),
12750 });
12751 let parser_diagnostics = [ParserDiagnostic {
12752 line: 1,
12753 column: 2,
12754 message: "missing 'x' at 'y'".to_owned(),
12755 }];
12756 let token_errors = [
12757 TokenSourceError::new(1, 1, "token recognition error at: '@'"),
12758 TokenSourceError::new(1, 3, "token recognition error at: '#'"),
12759 ];
12760
12761 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
12762
12763 insta::assert_debug_snapshot!(
12766 "parser_dispatches_recovery_diagnostics_through_registered_listeners",
12767 *diagnostics.lock().expect("recorded diagnostics lock")
12768 );
12769
12770 parser.remove_error_listeners();
12771 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
12772 assert_eq!(
12773 diagnostics.lock().expect("recorded diagnostics lock").len(),
12774 3
12775 );
12776 }
12777
12778 #[test]
12779 fn parser_leaves_token_errors_to_source_owned_listeners() {
12780 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
12781 let source = ReportingSource {
12782 source: Source {
12783 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
12784 index: 0,
12785 },
12786 diagnostics: Rc::clone(&source_diagnostics),
12787 };
12788 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
12789 parser.remove_error_listeners();
12790 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
12791 parser.add_error_listener(RecordingErrorListener {
12792 diagnostics: Arc::clone(&parser_diagnostics),
12793 });
12794 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
12795
12796 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
12797
12798 assert_eq!(*source_diagnostics.borrow(), [source_error]);
12799 assert!(
12800 parser_diagnostics
12801 .lock()
12802 .expect("recorded diagnostics lock")
12803 .is_empty()
12804 );
12805 }
12806
12807 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
12808 builder.finish().expect("valid packed parser ATN")
12809 }
12810
12811 fn nested_rule_chain_atn(depth: usize) -> Atn {
12812 nested_rule_graph_atn(depth, false, false)
12813 }
12814
12815 fn nested_rule_graph_atn(depth: usize, branching: bool, consuming_follows: bool) -> Atn {
12816 assert!(depth > 0);
12817 let mut atn = ParserAtnBuilder::new(2);
12818 let mut starts = Vec::with_capacity(depth);
12819 let mut stops = Vec::with_capacity(depth);
12820 let mut follows = Vec::with_capacity(depth.saturating_sub(1));
12821 for rule_index in 0..depth {
12822 starts.push(
12823 atn.add_state(AtnStateKind::RuleStart, Some(rule_index))
12824 .expect("rule start")
12825 .index(),
12826 );
12827 }
12828 for rule_index in 0..depth {
12829 stops.push(
12830 atn.add_state(AtnStateKind::RuleStop, Some(rule_index))
12831 .expect("rule stop")
12832 .index(),
12833 );
12834 }
12835 if consuming_follows {
12836 for rule_index in 0..depth - 1 {
12837 follows.push(
12838 atn.add_state(AtnStateKind::Basic, Some(rule_index))
12839 .expect("rule follow")
12840 .index(),
12841 );
12842 }
12843 }
12844 atn.set_rule_to_start_state(starts.clone())
12845 .expect("rule start states");
12846 atn.set_rule_to_stop_state(stops.clone())
12847 .expect("rule stop states");
12848 for rule_index in 0..depth - 1 {
12849 let follow_state = if consuming_follows {
12850 follows[rule_index]
12851 } else {
12852 stops[rule_index]
12853 };
12854 atn.add_transition(
12855 starts[rule_index],
12856 ParserTransitionSpec::Rule {
12857 target: starts[rule_index + 1],
12858 rule_index: rule_index + 1,
12859 follow_state,
12860 precedence: 0,
12861 },
12862 )
12863 .expect("nested rule transition");
12864 if branching {
12865 atn.add_transition(
12866 starts[rule_index],
12867 ParserTransitionSpec::Atom {
12868 target: stops[rule_index],
12869 label: 2,
12870 },
12871 )
12872 .expect("dead branch transition");
12873 }
12874 if consuming_follows {
12875 atn.add_transition(
12876 follow_state,
12877 ParserTransitionSpec::Atom {
12878 target: stops[rule_index],
12879 label: 1,
12880 },
12881 )
12882 .expect("consuming follow transition");
12883 }
12884 }
12885 let token_set = atn.add_interval_set([(1, 1)]).expect("token set");
12886 atn.add_transition(
12887 starts[depth - 1],
12888 ParserTransitionSpec::Set {
12889 target: stops[depth - 1],
12890 set: token_set,
12891 },
12892 )
12893 .expect("terminal set transition");
12894 if branching {
12895 atn.add_transition(
12896 starts[depth - 1],
12897 ParserTransitionSpec::Atom {
12898 target: stops[depth - 1],
12899 label: 2,
12900 },
12901 )
12902 .expect("dead leaf branch transition");
12903 }
12904 finish_atn(atn)
12905 }
12906
12907 fn ordinary_star_loop_atn() -> Atn {
12908 let mut atn = ParserAtnBuilder::new(2);
12909 for (state_number, kind, rule_index) in [
12910 (0, AtnStateKind::RuleStart, 0),
12911 (1, AtnStateKind::StarLoopEntry, 0),
12912 (2, AtnStateKind::Basic, 0),
12913 (3, AtnStateKind::StarLoopBack, 0),
12914 (4, AtnStateKind::LoopEnd, 0),
12915 (5, AtnStateKind::Basic, 0),
12916 (6, AtnStateKind::RuleStop, 0),
12917 (7, AtnStateKind::RuleStart, 1),
12918 (8, AtnStateKind::Basic, 1),
12919 (9, AtnStateKind::RuleStop, 1),
12920 ] {
12921 assert_eq!(
12922 atn.add_state(kind, Some(rule_index))
12923 .expect("state")
12924 .index(),
12925 state_number
12926 );
12927 }
12928 atn.set_rule_to_start_state(vec![0, 7])
12929 .expect("rule start states");
12930 atn.set_rule_to_stop_state(vec![6, 9])
12931 .expect("rule stop states");
12932 atn.add_decision_state(1).expect("decision state");
12933 atn.set_loop_back_state(4, 3).expect("loop back state");
12934 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12935 .expect("transition");
12936 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12937 .expect("transition");
12938 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
12939 .expect("transition");
12940 atn.add_transition(
12941 2,
12942 ParserTransitionSpec::Rule {
12943 target: 7,
12944 rule_index: 1,
12945 follow_state: 3,
12946 precedence: 0,
12947 },
12948 )
12949 .expect("transition");
12950 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
12951 .expect("transition");
12952 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12953 .expect("transition");
12954 atn.add_transition(
12955 5,
12956 ParserTransitionSpec::Atom {
12957 target: 6,
12958 label: TOKEN_EOF,
12959 },
12960 )
12961 .expect("transition");
12962 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
12963 .expect("transition");
12964 atn.add_transition(
12965 8,
12966 ParserTransitionSpec::Atom {
12967 target: 9,
12968 label: 1,
12969 },
12970 )
12971 .expect("transition");
12972 finish_atn(atn)
12973 }
12974
12975 fn ambiguous_ordinary_star_loop_atn() -> Atn {
12977 let mut atn = ParserAtnBuilder::new(1);
12978 for (state_number, kind) in [
12979 (0, AtnStateKind::RuleStart),
12980 (1, AtnStateKind::StarLoopEntry),
12981 (2, AtnStateKind::StarBlockStart),
12982 (3, AtnStateKind::Basic),
12983 (4, AtnStateKind::BlockEnd),
12984 (5, AtnStateKind::StarLoopBack),
12985 (6, AtnStateKind::LoopEnd),
12986 (7, AtnStateKind::Basic),
12987 (8, AtnStateKind::RuleStop),
12988 ] {
12989 assert_eq!(
12990 atn.add_state(kind, Some(0)).expect("state").index(),
12991 state_number
12992 );
12993 }
12994 atn.set_rule_to_start_state(vec![0])
12995 .expect("rule start states");
12996 atn.set_rule_to_stop_state(vec![8])
12997 .expect("rule stop states");
12998 atn.set_end_state(2, 4).expect("block end state");
12999 atn.set_loop_back_state(6, 5).expect("loop back state");
13000 atn.add_decision_state(1).expect("decision state");
13001 atn.add_decision_state(2).expect("decision state");
13002 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13003 .expect("transition");
13004 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13005 .expect("transition");
13006 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
13007 .expect("transition");
13008 atn.add_transition(
13009 2,
13010 ParserTransitionSpec::Atom {
13011 target: 4,
13012 label: 1,
13013 },
13014 )
13015 .expect("transition");
13016 atn.add_transition(
13017 2,
13018 ParserTransitionSpec::Atom {
13019 target: 3,
13020 label: 1,
13021 },
13022 )
13023 .expect("transition");
13024 atn.add_transition(
13025 3,
13026 ParserTransitionSpec::Atom {
13027 target: 4,
13028 label: 1,
13029 },
13030 )
13031 .expect("transition");
13032 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13033 .expect("transition");
13034 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
13035 .expect("transition");
13036 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13037 .expect("transition");
13038 atn.add_transition(
13039 7,
13040 ParserTransitionSpec::Atom {
13041 target: 8,
13042 label: TOKEN_EOF,
13043 },
13044 )
13045 .expect("transition");
13046 finish_atn(atn)
13047 }
13048
13049 fn ordinary_plus_loop_atn() -> Atn {
13050 let mut atn = ParserAtnBuilder::new(2);
13051 for (state_number, kind, rule_index) in [
13052 (0, AtnStateKind::RuleStart, 0),
13053 (1, AtnStateKind::Basic, 0),
13054 (2, AtnStateKind::PlusLoopBack, 0),
13055 (3, AtnStateKind::LoopEnd, 0),
13056 (4, AtnStateKind::Basic, 0),
13057 (5, AtnStateKind::RuleStop, 0),
13058 (6, AtnStateKind::RuleStart, 1),
13059 (7, AtnStateKind::Basic, 1),
13060 (8, AtnStateKind::RuleStop, 1),
13061 ] {
13062 assert_eq!(
13063 atn.add_state(kind, Some(rule_index))
13064 .expect("state")
13065 .index(),
13066 state_number
13067 );
13068 }
13069 atn.set_rule_to_start_state(vec![0, 6])
13070 .expect("rule start states");
13071 atn.set_rule_to_stop_state(vec![5, 8])
13072 .expect("rule stop states");
13073 atn.add_decision_state(2).expect("decision state");
13074 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13075 .expect("transition");
13076 atn.add_transition(
13077 1,
13078 ParserTransitionSpec::Rule {
13079 target: 6,
13080 rule_index: 1,
13081 follow_state: 2,
13082 precedence: 0,
13083 },
13084 )
13085 .expect("transition");
13086 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
13087 .expect("transition");
13088 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13089 .expect("transition");
13090 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
13091 .expect("transition");
13092 atn.add_transition(
13093 4,
13094 ParserTransitionSpec::Atom {
13095 target: 5,
13096 label: TOKEN_EOF,
13097 },
13098 )
13099 .expect("transition");
13100 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13101 .expect("transition");
13102 atn.add_transition(
13103 7,
13104 ParserTransitionSpec::Atom {
13105 target: 8,
13106 label: 1,
13107 },
13108 )
13109 .expect("transition");
13110 finish_atn(atn)
13111 }
13112
13113 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
13114 let mut tokens = (0..count)
13115 .map(|_| TestToken::new(1).with_text("x"))
13116 .collect::<Vec<_>>();
13117 tokens.push(TestToken::eof("parser-test", count, 1, count));
13118 tokens
13119 }
13120
13121 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
13122 let mut atn = ParserAtnBuilder::new(2);
13123 assert_eq!(
13124 atn.add_state(AtnStateKind::RuleStart, Some(0))
13125 .expect("state")
13126 .index(),
13127 0
13128 );
13129 assert_eq!(
13130 atn.add_state(AtnStateKind::Basic, Some(0))
13131 .expect("state")
13132 .index(),
13133 1
13134 );
13135 assert_eq!(
13136 atn.add_state(AtnStateKind::Basic, Some(0))
13137 .expect("state")
13138 .index(),
13139 2
13140 );
13141 assert_eq!(
13142 atn.add_state(AtnStateKind::RuleStart, Some(1))
13143 .expect("state")
13144 .index(),
13145 3
13146 );
13147 atn.set_left_recursive_rule(3)
13148 .expect("left-recursive rule start");
13149 assert_eq!(
13150 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
13151 .expect("state")
13152 .index(),
13153 4
13154 );
13155 atn.set_precedence_rule_decision(4)
13156 .expect("precedence decision");
13157 assert_eq!(
13158 atn.add_state(AtnStateKind::Basic, Some(1))
13159 .expect("state")
13160 .index(),
13161 5
13162 );
13163 assert_eq!(
13164 atn.add_state(AtnStateKind::Basic, Some(1))
13165 .expect("state")
13166 .index(),
13167 6
13168 );
13169 assert_eq!(
13170 atn.add_state(AtnStateKind::LoopEnd, Some(1))
13171 .expect("state")
13172 .index(),
13173 7
13174 );
13175 assert_eq!(
13176 atn.add_state(AtnStateKind::RuleStop, Some(1))
13177 .expect("state")
13178 .index(),
13179 8
13180 );
13181 assert_eq!(
13182 atn.add_state(AtnStateKind::RuleStop, Some(0))
13183 .expect("state")
13184 .index(),
13185 9
13186 );
13187 atn.set_rule_to_start_state(vec![0, 3])
13188 .expect("rule start states");
13189 atn.set_rule_to_stop_state(vec![9, 8])
13190 .expect("rule stop states");
13191 atn.add_transition(
13192 1,
13193 ParserTransitionSpec::Rule {
13194 target: 3,
13195 rule_index: 1,
13196 follow_state: 2,
13197 precedence: 0,
13198 },
13199 )
13200 .expect("transition");
13201 atn.add_transition(
13202 2,
13203 ParserTransitionSpec::Atom {
13204 target: 9,
13205 label: caller_symbol,
13206 },
13207 )
13208 .expect("transition");
13209 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13210 .expect("transition");
13211 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
13212 .expect("transition");
13213 atn.add_transition(
13214 5,
13215 ParserTransitionSpec::Precedence {
13216 target: 6,
13217 precedence: 1,
13218 },
13219 )
13220 .expect("transition");
13221 atn.add_transition(
13222 6,
13223 ParserTransitionSpec::Atom {
13224 target: 4,
13225 label: 1,
13226 },
13227 )
13228 .expect("transition");
13229 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
13230 .expect("transition");
13231 finish_atn(atn)
13232 }
13233
13234 fn labeled_left_recursive_operator_atn() -> Atn {
13235 let mut atn = ParserAtnBuilder::new(4);
13236 for (state, kind) in [
13237 (0, AtnStateKind::RuleStart),
13238 (1, AtnStateKind::BlockStart),
13239 (2, AtnStateKind::StarLoopEntry),
13240 (3, AtnStateKind::StarBlockStart),
13241 (4, AtnStateKind::Basic),
13242 (5, AtnStateKind::Basic),
13243 (6, AtnStateKind::Basic),
13244 (7, AtnStateKind::StarLoopBack),
13245 (8, AtnStateKind::LoopEnd),
13246 (9, AtnStateKind::RuleStop),
13247 ] {
13248 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13249 }
13250 atn.set_left_recursive_rule(0)
13251 .expect("left-recursive rule start");
13252 atn.set_precedence_rule_decision(2)
13253 .expect("precedence decision");
13254 atn.set_loop_back_state(8, 7).expect("loop-back state");
13255 atn.set_rule_to_start_state(vec![0])
13256 .expect("rule start states");
13257 atn.set_rule_to_stop_state(vec![9])
13258 .expect("rule stop states");
13259 for state in [1, 2, 3] {
13260 atn.add_decision_state(state).expect("decision state");
13261 }
13262 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
13263 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
13264 .expect("epsilon transition");
13265 }
13266 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3), (6, 7, 1)] {
13267 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
13268 .expect("token transition");
13269 }
13270 for (target, precedence) in [(4, 2), (5, 1)] {
13271 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
13272 .expect("operator precedence");
13273 }
13274 finish_atn(atn)
13275 }
13276
13277 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
13278 let mut parser = mini_parser(vec![
13279 TestToken::new(symbol).with_text("lookahead"),
13280 TestToken::eof("parser-test", 1, 1, 1),
13281 ]);
13282 parser.rule_context_stack = vec![
13283 RuleContextFrame {
13284 rule_index: 0,
13285 invoking_state: -1,
13286 },
13287 RuleContextFrame {
13288 rule_index: 1,
13289 invoking_state: 1,
13290 },
13291 ];
13292 parser
13293 }
13294
13295 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
13296 let mut atn = ParserAtnBuilder::new(1);
13300 for (state, kind, rule) in [
13301 (0, AtnStateKind::RuleStart, 0),
13302 (1, AtnStateKind::StarLoopEntry, 0),
13303 (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),
13310 (9, AtnStateKind::RuleStop, 0),
13311 ] {
13312 assert_eq!(
13313 atn.add_state(kind, Some(rule)).expect("state").index(),
13314 state
13315 );
13316 if state == 0 {
13317 atn.set_left_recursive_rule(state)
13318 .expect("left-recursive rule start");
13319 } else if state == 1 {
13320 atn.set_precedence_rule_decision(state)
13321 .expect("precedence decision");
13322 }
13323 }
13324 atn.set_rule_to_start_state(vec![0])
13325 .expect("rule start states");
13326 atn.set_rule_to_stop_state(vec![9])
13327 .expect("rule stop states");
13328 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13329 .expect("ops");
13330 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
13331 .expect("exit");
13332 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13333 .expect("to shift");
13334 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13335 .expect("to rel");
13336 atn.add_transition(
13337 3,
13338 ParserTransitionSpec::Precedence {
13339 target: 4,
13340 precedence: 2,
13341 },
13342 )
13343 .expect("shift prec");
13344 atn.add_transition(
13345 4,
13346 ParserTransitionSpec::Atom {
13347 target: 5,
13348 label: 1,
13349 },
13350 )
13351 .expect("shift first >");
13352 atn.add_transition(
13353 5,
13354 ParserTransitionSpec::Atom {
13355 target: 1,
13356 label: 1,
13357 },
13358 )
13359 .expect("shift second >");
13360 atn.add_transition(
13361 6,
13362 ParserTransitionSpec::Precedence {
13363 target: 7,
13364 precedence: 1,
13365 },
13366 )
13367 .expect("rel prec");
13368 atn.add_transition(
13369 7,
13370 ParserTransitionSpec::Atom {
13371 target: 1,
13372 label: 1,
13373 },
13374 )
13375 .expect("rel >");
13376 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
13377 .expect("loop end");
13378 finish_atn(atn)
13379 }
13380
13381 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
13382 let mut atn = ParserAtnBuilder::new(2);
13383 for (state, kind, rule) in [
13384 (0, AtnStateKind::RuleStart, 0),
13385 (1, AtnStateKind::StarLoopEntry, 0),
13386 (2, AtnStateKind::Basic, 0),
13387 (3, AtnStateKind::Basic, 0),
13388 (4, AtnStateKind::Basic, 0),
13389 (5, AtnStateKind::Basic, 0),
13390 (6, AtnStateKind::Basic, 0),
13391 (7, AtnStateKind::Basic, 0),
13392 (8, AtnStateKind::LoopEnd, 0),
13393 (9, AtnStateKind::RuleStop, 0),
13394 (10, AtnStateKind::RuleStart, 1),
13395 (11, AtnStateKind::Basic, 1),
13396 (12, AtnStateKind::RuleStop, 1),
13397 ] {
13398 assert_eq!(
13399 atn.add_state(kind, Some(rule)).expect("state").index(),
13400 state
13401 );
13402 if state == 0 {
13403 atn.set_left_recursive_rule(state)
13404 .expect("left-recursive rule start");
13405 } else if state == 1 {
13406 atn.set_precedence_rule_decision(state)
13407 .expect("precedence decision");
13408 }
13409 }
13410 atn.set_rule_to_start_state(vec![0, 10])
13411 .expect("rule start states");
13412 atn.set_rule_to_stop_state(vec![9, 12])
13413 .expect("rule stop states");
13414 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13415 .expect("ops");
13416 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
13417 .expect("exit");
13418 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13419 .expect("to shift");
13420 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13421 .expect("to relational");
13422 atn.add_transition(
13423 3,
13424 ParserTransitionSpec::Precedence {
13425 target: 4,
13426 precedence: 2,
13427 },
13428 )
13429 .expect("shift precedence");
13430 atn.add_transition(
13431 4,
13432 ParserTransitionSpec::Rule {
13433 target: 10,
13434 rule_index: 1,
13435 follow_state: 5,
13436 precedence: 0,
13437 },
13438 )
13439 .expect("first shift token helper");
13440 atn.add_transition(
13441 5,
13442 ParserTransitionSpec::Atom {
13443 target: 1,
13444 label: 1,
13445 },
13446 )
13447 .expect("second shift token");
13448 atn.add_transition(
13449 6,
13450 ParserTransitionSpec::Precedence {
13451 target: 7,
13452 precedence: 1,
13453 },
13454 )
13455 .expect("relational precedence");
13456 atn.add_transition(
13457 7,
13458 ParserTransitionSpec::Atom {
13459 target: 1,
13460 label: 1,
13461 },
13462 )
13463 .expect("relational token");
13464 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
13465 .expect("loop end");
13466 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
13467 .expect("helper entry");
13468 atn.add_transition(
13469 11,
13470 ParserTransitionSpec::Atom {
13471 target: 12,
13472 label: 1,
13473 },
13474 )
13475 .expect("first shift token");
13476 finish_atn(atn)
13477 }
13478
13479 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
13480 let mut atn = ParserAtnBuilder::new(1);
13481 for (state, kind) in [
13482 (0, AtnStateKind::RuleStart),
13483 (1, AtnStateKind::StarLoopEntry),
13484 (2, AtnStateKind::Basic),
13485 (3, AtnStateKind::Basic),
13486 (4, AtnStateKind::Basic),
13487 (5, AtnStateKind::Basic),
13488 (6, AtnStateKind::Basic),
13489 (7, AtnStateKind::Basic),
13490 (8, AtnStateKind::Basic),
13491 (9, AtnStateKind::LoopEnd),
13492 (10, AtnStateKind::RuleStop),
13493 ] {
13494 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13495 if state == 0 {
13496 atn.set_left_recursive_rule(state)
13497 .expect("left-recursive rule start");
13498 } else if state == 1 {
13499 atn.set_precedence_rule_decision(state)
13500 .expect("precedence decision");
13501 }
13502 }
13503 atn.set_rule_to_start_state(vec![0])
13504 .expect("rule start states");
13505 atn.set_rule_to_stop_state(vec![10])
13506 .expect("rule stop states");
13507 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13508 .expect("ops");
13509 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
13510 .expect("exit");
13511 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13512 .expect("to multi-token operator");
13513 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13514 .expect("to predicate operator");
13515 atn.add_transition(
13516 3,
13517 ParserTransitionSpec::Precedence {
13518 target: 4,
13519 precedence: 2,
13520 },
13521 )
13522 .expect("multi-token precedence");
13523 atn.add_transition(
13524 4,
13525 ParserTransitionSpec::Atom {
13526 target: 5,
13527 label: 1,
13528 },
13529 )
13530 .expect("multi-token first");
13531 atn.add_transition(
13532 5,
13533 ParserTransitionSpec::Atom {
13534 target: 1,
13535 label: 1,
13536 },
13537 )
13538 .expect("multi-token second");
13539 atn.add_transition(
13540 6,
13541 ParserTransitionSpec::Precedence {
13542 target: 7,
13543 precedence: 2,
13544 },
13545 )
13546 .expect("predicate precedence");
13547 atn.add_transition(
13548 7,
13549 ParserTransitionSpec::Predicate {
13550 target: 8,
13551 rule_index: 0,
13552 pred_index: 0,
13553 context_dependent: false,
13554 },
13555 )
13556 .expect("operator predicate");
13557 atn.add_transition(
13558 8,
13559 ParserTransitionSpec::Atom {
13560 target: 1,
13561 label: 1,
13562 },
13563 )
13564 .expect("predicate single token");
13565 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13566 .expect("loop end");
13567 finish_atn(atn)
13568 }
13569
13570 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
13571 let mut atn = ParserAtnBuilder::new(2);
13572 for (state, kind, rule) in [
13573 (0, AtnStateKind::RuleStart, 0),
13574 (1, AtnStateKind::StarLoopEntry, 0),
13575 (2, AtnStateKind::Basic, 0),
13576 (3, AtnStateKind::Basic, 0),
13577 (4, AtnStateKind::Basic, 0),
13578 (5, AtnStateKind::LoopEnd, 0),
13579 (6, AtnStateKind::RuleStop, 0),
13580 (7, AtnStateKind::RuleStart, 1),
13581 (8, AtnStateKind::RuleStop, 1),
13582 (9, AtnStateKind::Basic, 1),
13583 ] {
13584 assert_eq!(
13585 atn.add_state(kind, Some(rule)).expect("state").index(),
13586 state
13587 );
13588 if state == 0 {
13589 atn.set_left_recursive_rule(state)
13590 .expect("left-recursive rule start");
13591 } else if state == 1 {
13592 atn.set_precedence_rule_decision(state)
13593 .expect("precedence decision");
13594 }
13595 }
13596 atn.set_rule_to_start_state(vec![0, 7])
13597 .expect("rule start states");
13598 atn.set_rule_to_stop_state(vec![6, 8])
13599 .expect("rule stop states");
13600 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13601 .expect("transition");
13602 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
13603 .expect("transition");
13604 atn.add_transition(
13605 2,
13606 ParserTransitionSpec::Precedence {
13607 target: 3,
13608 precedence: 3,
13609 },
13610 )
13611 .expect("transition");
13612 atn.add_transition(
13613 3,
13614 ParserTransitionSpec::Rule {
13615 target: 7,
13616 rule_index: 1,
13617 follow_state: 4,
13618 precedence: 0,
13619 },
13620 )
13621 .expect("transition");
13622 atn.add_transition(
13623 4,
13624 ParserTransitionSpec::Atom {
13625 target: 1,
13626 label: 1,
13627 },
13628 )
13629 .expect("transition");
13630 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13631 .expect("transition");
13632 atn.add_transition(
13633 7,
13634 ParserTransitionSpec::Precedence {
13635 target: 9,
13636 precedence: 1,
13637 },
13638 )
13639 .expect("transition");
13640 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
13641 .expect("transition");
13642 finish_atn(atn)
13643 }
13644
13645 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
13646 let mut atn = ParserAtnBuilder::new(2);
13647 for (state, kind) in [
13648 (0, AtnStateKind::RuleStart),
13649 (1, AtnStateKind::StarLoopEntry),
13650 (2, AtnStateKind::Basic),
13651 (3, AtnStateKind::Basic),
13652 (4, AtnStateKind::Basic),
13653 (5, AtnStateKind::LoopEnd),
13654 (6, AtnStateKind::RuleStop),
13655 ] {
13656 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13657 if state == 0 {
13658 atn.set_left_recursive_rule(state)
13659 .expect("left-recursive rule start");
13660 } else if state == 1 {
13661 atn.set_precedence_rule_decision(state)
13662 .expect("precedence decision");
13663 }
13664 }
13665 atn.set_rule_to_start_state(vec![0])
13666 .expect("rule start states");
13667 atn.set_rule_to_stop_state(vec![6])
13668 .expect("rule stop states");
13669 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13670 .expect("transition");
13671 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
13672 .expect("transition");
13673 atn.add_transition(
13674 2,
13675 ParserTransitionSpec::Precedence {
13676 target: 3,
13677 precedence: 1,
13678 },
13679 )
13680 .expect("transition");
13681 atn.add_transition(
13682 3,
13683 ParserTransitionSpec::Predicate {
13684 target: 4,
13685 rule_index: 0,
13686 pred_index: 0,
13687 context_dependent: false,
13688 },
13689 )
13690 .expect("transition");
13691 atn.add_transition(
13692 4,
13693 ParserTransitionSpec::Atom {
13694 target: 1,
13695 label: 1,
13696 },
13697 )
13698 .expect("transition");
13699 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13700 .expect("transition");
13701 finish_atn(atn)
13702 }
13703
13704 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
13705 let mut atn = ParserAtnBuilder::new(2);
13706 for (state, kind, rule) in [
13707 (0, AtnStateKind::RuleStart, 0),
13708 (1, AtnStateKind::Basic, 0),
13709 (2, AtnStateKind::Basic, 0),
13710 (3, AtnStateKind::Basic, 0),
13711 (4, AtnStateKind::RuleStop, 0),
13712 (5, AtnStateKind::RuleStart, 1),
13713 (6, AtnStateKind::StarLoopEntry, 1),
13714 (7, AtnStateKind::Basic, 1),
13715 (8, AtnStateKind::Basic, 1),
13716 (9, AtnStateKind::LoopEnd, 1),
13717 (10, AtnStateKind::RuleStop, 1),
13718 (11, AtnStateKind::RuleStart, 2),
13719 (12, AtnStateKind::RuleStop, 2),
13720 ] {
13721 assert_eq!(
13722 atn.add_state(kind, Some(rule)).expect("state").index(),
13723 state
13724 );
13725 if state == 5 {
13726 atn.set_left_recursive_rule(state)
13727 .expect("left-recursive rule start");
13728 } else if state == 6 {
13729 atn.set_precedence_rule_decision(state)
13730 .expect("precedence decision");
13731 }
13732 }
13733 atn.set_rule_to_start_state(vec![0, 5, 11])
13734 .expect("rule start states");
13735 atn.set_rule_to_stop_state(vec![4, 10, 12])
13736 .expect("rule stop states");
13737 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13738 .expect("transition");
13739 atn.add_transition(
13740 1,
13741 ParserTransitionSpec::Rule {
13742 target: 5,
13743 rule_index: 1,
13744 follow_state: 2,
13745 precedence: 0,
13746 },
13747 )
13748 .expect("transition");
13749 atn.add_transition(
13750 2,
13751 ParserTransitionSpec::Rule {
13752 target: 11,
13753 rule_index: 2,
13754 follow_state: 3,
13755 precedence: 0,
13756 },
13757 )
13758 .expect("transition");
13759 atn.add_transition(
13760 3,
13761 ParserTransitionSpec::Atom {
13762 target: 4,
13763 label: caller_symbol,
13764 },
13765 )
13766 .expect("transition");
13767 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13768 .expect("transition");
13769 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
13770 .expect("transition");
13771 atn.add_transition(
13772 7,
13773 ParserTransitionSpec::Precedence {
13774 target: 8,
13775 precedence: 1,
13776 },
13777 )
13778 .expect("transition");
13779 atn.add_transition(
13780 8,
13781 ParserTransitionSpec::Atom {
13782 target: 6,
13783 label: 1,
13784 },
13785 )
13786 .expect("transition");
13787 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13788 .expect("transition");
13789 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
13790 .expect("transition");
13791 finish_atn(atn)
13792 }
13793
13794 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
13795 let mut atn = ParserAtnBuilder::new(2);
13796 for (state, kind, rule) in [
13797 (0, AtnStateKind::RuleStart, 0),
13798 (1, AtnStateKind::Basic, 0),
13799 (2, AtnStateKind::Basic, 0),
13800 (3, AtnStateKind::RuleStop, 0),
13801 (4, AtnStateKind::RuleStart, 1),
13802 (5, AtnStateKind::Basic, 1),
13803 (6, AtnStateKind::Basic, 1),
13804 (7, AtnStateKind::RuleStop, 1),
13805 (8, AtnStateKind::RuleStart, 2),
13806 (9, AtnStateKind::StarLoopEntry, 2),
13807 (10, AtnStateKind::Basic, 2),
13808 (11, AtnStateKind::Basic, 2),
13809 (12, AtnStateKind::LoopEnd, 2),
13810 (13, AtnStateKind::RuleStop, 2),
13811 ] {
13812 assert_eq!(
13813 atn.add_state(kind, Some(rule)).expect("state").index(),
13814 state
13815 );
13816 if state == 8 {
13817 atn.set_left_recursive_rule(state)
13818 .expect("left-recursive rule start");
13819 } else if state == 9 {
13820 atn.set_precedence_rule_decision(state)
13821 .expect("precedence decision");
13822 }
13823 }
13824 atn.set_rule_to_start_state(vec![0, 4, 8])
13825 .expect("rule start states");
13826 atn.set_rule_to_stop_state(vec![3, 7, 13])
13827 .expect("rule stop states");
13828 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13829 .expect("transition");
13830 atn.add_transition(
13831 1,
13832 ParserTransitionSpec::Rule {
13833 target: 4,
13834 rule_index: 1,
13835 follow_state: 2,
13836 precedence: 0,
13837 },
13838 )
13839 .expect("transition");
13840 atn.add_transition(
13841 2,
13842 ParserTransitionSpec::Atom {
13843 target: 3,
13844 label: caller_symbol,
13845 },
13846 )
13847 .expect("transition");
13848 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13849 .expect("transition");
13850 atn.add_transition(
13851 5,
13852 ParserTransitionSpec::Rule {
13853 target: 8,
13854 rule_index: 2,
13855 follow_state: 6,
13856 precedence: 0,
13857 },
13858 )
13859 .expect("transition");
13860 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13861 .expect("transition");
13862 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13863 .expect("transition");
13864 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
13865 .expect("transition");
13866 atn.add_transition(
13867 10,
13868 ParserTransitionSpec::Precedence {
13869 target: 11,
13870 precedence: 1,
13871 },
13872 )
13873 .expect("transition");
13874 atn.add_transition(
13875 11,
13876 ParserTransitionSpec::Atom {
13877 target: 9,
13878 label: 1,
13879 },
13880 )
13881 .expect("transition");
13882 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
13883 .expect("transition");
13884 finish_atn(atn)
13885 }
13886
13887 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
13888 let mut atn = ParserAtnBuilder::new(2);
13889 for (state, kind, rule) in [
13890 (0, AtnStateKind::RuleStart, 0),
13891 (1, AtnStateKind::Basic, 0),
13892 (2, AtnStateKind::Basic, 0),
13893 (3, AtnStateKind::RuleStop, 0),
13894 (4, AtnStateKind::RuleStart, 1),
13895 (5, AtnStateKind::StarLoopEntry, 1),
13896 (6, AtnStateKind::Basic, 1),
13897 (7, AtnStateKind::Basic, 1),
13898 (8, AtnStateKind::Basic, 1),
13899 (9, AtnStateKind::Basic, 1),
13900 (10, AtnStateKind::LoopEnd, 1),
13901 (11, AtnStateKind::RuleStop, 1),
13902 ] {
13903 assert_eq!(
13904 atn.add_state(kind, Some(rule)).expect("state").index(),
13905 state
13906 );
13907 if state == 4 {
13908 atn.set_left_recursive_rule(state)
13909 .expect("left-recursive rule start");
13910 } else if state == 5 {
13911 atn.set_precedence_rule_decision(state)
13912 .expect("precedence decision");
13913 }
13914 }
13915 atn.set_rule_to_start_state(vec![0, 4])
13916 .expect("rule start states");
13917 atn.set_rule_to_stop_state(vec![3, 11])
13918 .expect("rule stop states");
13919 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13920 .expect("transition");
13921 atn.add_transition(
13922 1,
13923 ParserTransitionSpec::Rule {
13924 target: 4,
13925 rule_index: 1,
13926 follow_state: 2,
13927 precedence: 0,
13928 },
13929 )
13930 .expect("transition");
13931 atn.add_transition(
13932 2,
13933 ParserTransitionSpec::Atom {
13934 target: 3,
13935 label: caller_symbol,
13936 },
13937 )
13938 .expect("transition");
13939 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13940 .expect("transition");
13941 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
13942 .expect("transition");
13943 atn.add_transition(
13944 6,
13945 ParserTransitionSpec::Precedence {
13946 target: 7,
13947 precedence: 1,
13948 },
13949 )
13950 .expect("transition");
13951 atn.add_transition(
13952 7,
13953 ParserTransitionSpec::Atom {
13954 target: 8,
13955 label: 1,
13956 },
13957 )
13958 .expect("transition");
13959 atn.add_transition(
13960 8,
13961 ParserTransitionSpec::Rule {
13962 target: 4,
13963 rule_index: 1,
13964 follow_state: 9,
13965 precedence: 2,
13966 },
13967 )
13968 .expect("transition");
13969 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
13970 .expect("transition");
13971 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
13972 .expect("transition");
13973 finish_atn(atn)
13974 }
13975
13976 #[test]
13977 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
13978 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
13979 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
13980
13981 let mut overlapping = parser_inside_left_recursive_callee(1);
13982 assert_eq!(
13983 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
13984 None
13985 );
13986
13987 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
13988 assert_eq!(
13989 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13990 Some(true)
13991 );
13992
13993 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
13994 assert_eq!(
13995 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13996 Some(false)
13997 );
13998
13999 assert_eq!(
14000 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
14001 Some(true),
14002 "overlap results must not leak across ATNs"
14003 );
14004 }
14005
14006 #[test]
14007 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
14008 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
14009 let mut parser = mini_parser(vec![
14010 TestToken::new(1).with_text("operator"),
14011 TestToken::eof("parser-test", 1, 1, 1),
14012 ]);
14013 parser.rule_context_stack = vec![RuleContextFrame {
14014 rule_index: 0,
14015 invoking_state: -1,
14016 }];
14017
14018 assert_eq!(
14019 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14020 Some(true)
14021 );
14022 assert_eq!(
14023 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14024 Some(true),
14025 "cached operator lookahead must preserve the nullable prefix return path"
14026 );
14027 assert_eq!(
14028 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14029 Some(true),
14030 "the nullable child must use its rule-call precedence, not the caller precedence"
14031 );
14032 }
14033
14034 #[test]
14035 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
14036 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
14041 let mut parser = mini_parser(vec![
14042 TestToken::new(1).with_text(">"),
14043 TestToken::new(2).with_text("id"),
14044 TestToken::eof("parser-test", 1, 1, 1),
14045 ]);
14046 parser.rule_context_stack = vec![RuleContextFrame {
14047 rule_index: 0,
14048 invoking_state: -1,
14049 }];
14050
14051 assert_eq!(
14052 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14053 Some(true),
14054 "at low precedence relational `>` is a single-token operator"
14055 );
14056 assert_eq!(
14057 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
14058 Some(true),
14059 "relational remains single-token at its own precedence"
14060 );
14061 assert_eq!(
14062 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14063 None,
14064 "at shift precedence, bare `>` must not force enter"
14065 );
14066 }
14067
14068 #[test]
14069 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
14070 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
14071 let mut parser = mini_parser(vec![
14072 TestToken::new(1).with_text(">"),
14073 TestToken::new(2).with_text("id"),
14074 TestToken::eof("parser-test", 1, 1, 1),
14075 ]);
14076 parser.rule_context_stack = vec![RuleContextFrame {
14077 rule_index: 0,
14078 invoking_state: -1,
14079 }];
14080
14081 assert_eq!(
14082 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14083 Some(true),
14084 "the direct relational alternative remains a one-token operator"
14085 );
14086 assert_eq!(
14087 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14088 None,
14089 "a token matched in the helper rule must return to the second shift token"
14090 );
14091 }
14092
14093 #[test]
14094 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
14095 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
14096 let mut parser = mini_parser(vec![
14097 TestToken::new(1).with_text(">"),
14098 TestToken::new(2).with_text("id"),
14099 TestToken::eof("parser-test", 1, 1, 1),
14100 ]);
14101 parser.rule_context_stack = vec![RuleContextFrame {
14102 rule_index: 0,
14103 invoking_state: -1,
14104 }];
14105
14106 assert_eq!(
14107 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14108 None,
14109 "a predicate-gated single-token path must not be hidden by a multi-token path"
14110 );
14111 }
14112
14113 #[test]
14114 fn left_recursive_loop_defers_predicate_guarded_operator() {
14115 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
14116 let mut parser = mini_parser_with_hooks(
14117 vec![
14118 TestToken::new(1).with_text("operator"),
14119 TestToken::eof("parser-test", 1, 1, 1),
14120 ],
14121 RejectingPredicateHooks::default(),
14122 );
14123 parser.rule_context_stack = vec![RuleContextFrame {
14124 rule_index: 0,
14125 invoking_state: -1,
14126 }];
14127
14128 assert_eq!(
14129 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14130 None,
14131 "a false predicate must be evaluated before entering the operator alternative"
14132 );
14133 assert_eq!(
14134 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14135 None,
14136 "cached predicate-dependent lookahead must keep deferring"
14137 );
14138 }
14139
14140 #[test]
14141 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
14142 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
14143 let mut parser = parser_inside_left_recursive_callee(1);
14144
14145 assert_eq!(
14146 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
14147 None
14148 );
14149 assert_eq!(
14150 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
14151 None,
14152 "the cached overlap must preserve the nullable child return path"
14153 );
14154 }
14155
14156 #[test]
14157 fn left_recursive_loop_defers_through_nullable_parent_return() {
14158 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
14159 let mut parser = mini_parser(vec![
14160 TestToken::new(1).with_text("lookahead"),
14161 TestToken::eof("parser-test", 1, 1, 1),
14162 ]);
14163 parser.rule_context_stack = vec![
14164 RuleContextFrame {
14165 rule_index: 0,
14166 invoking_state: -1,
14167 },
14168 RuleContextFrame {
14169 rule_index: 1,
14170 invoking_state: 1,
14171 },
14172 RuleContextFrame {
14173 rule_index: 2,
14174 invoking_state: 5,
14175 },
14176 ];
14177
14178 assert_eq!(
14179 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
14180 None,
14181 "a nullable caller must unwind to its parent's consuming follow path"
14182 );
14183 assert_eq!(
14184 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
14185 None,
14186 "the caller-overlap cache must not retain a false negative"
14187 );
14188 }
14189
14190 #[test]
14191 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
14192 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
14193 let mut parser = mini_parser(vec![
14194 TestToken::new(1).with_text("lookahead"),
14195 TestToken::eof("parser-test", 1, 1, 1),
14196 ]);
14197 parser.rule_context_stack = vec![
14198 RuleContextFrame {
14199 rule_index: 0,
14200 invoking_state: -1,
14201 },
14202 RuleContextFrame {
14203 rule_index: 1,
14204 invoking_state: 1,
14205 },
14206 RuleContextFrame {
14207 rule_index: 1,
14208 invoking_state: 8,
14209 },
14210 ];
14211
14212 assert_eq!(
14213 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
14214 None,
14215 "a recursive operand return must preserve its parent caller context"
14216 );
14217 assert_eq!(
14218 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
14219 None,
14220 "the caller-overlap cache must preserve the loop-boundary return"
14221 );
14222 }
14223
14224 fn token_then_eof_atn() -> Atn {
14225 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14226 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, ]))
14242 .deserialize_parser()
14243 .expect("artificial parser ATN should deserialize")
14244 }
14245
14246 fn epsilon_cycle_atn() -> Atn {
14247 let mut atn = ParserAtnBuilder::new(1);
14248 for (state_number, kind) in [
14249 (0, AtnStateKind::RuleStart),
14250 (1, AtnStateKind::Basic),
14251 (2, AtnStateKind::RuleStop),
14252 ] {
14253 assert_eq!(
14254 atn.add_state(kind, Some(0)).expect("state").index(),
14255 state_number
14256 );
14257 }
14258 atn.set_rule_to_start_state(vec![0])
14259 .expect("rule start states");
14260 atn.set_rule_to_stop_state(vec![2])
14261 .expect("rule stop states");
14262 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14263 .expect("transition");
14264 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
14265 .expect("self-cycle transition");
14266 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14267 .expect("exit transition");
14268 finish_atn(atn)
14269 }
14270
14271 fn eof_then_action_atn() -> Atn {
14272 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14273 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, ]))
14289 .deserialize_parser()
14290 .expect("artificial parser ATN should deserialize")
14291 }
14292
14293 fn noop_action_then_token_then_eof_atn() -> Atn {
14294 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14295 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, ]))
14313 .deserialize_parser()
14314 .expect("artificial no-op action ATN should deserialize")
14315 }
14316
14317 fn two_alt_decision_atn() -> Atn {
14318 let mut atn = ParserAtnBuilder::new(2);
14319 assert_eq!(
14320 atn.add_state(AtnStateKind::RuleStart, Some(0))
14321 .expect("state")
14322 .index(),
14323 0
14324 );
14325 assert_eq!(
14326 atn.add_state(AtnStateKind::BlockStart, Some(0))
14327 .expect("state")
14328 .index(),
14329 1
14330 );
14331 assert_eq!(
14332 atn.add_state(AtnStateKind::Basic, Some(0))
14333 .expect("state")
14334 .index(),
14335 2
14336 );
14337 assert_eq!(
14338 atn.add_state(AtnStateKind::Basic, Some(0))
14339 .expect("state")
14340 .index(),
14341 3
14342 );
14343 assert_eq!(
14344 atn.add_state(AtnStateKind::BlockEnd, Some(0))
14345 .expect("state")
14346 .index(),
14347 4
14348 );
14349 assert_eq!(
14350 atn.add_state(AtnStateKind::RuleStop, Some(0))
14351 .expect("state")
14352 .index(),
14353 5
14354 );
14355 atn.set_rule_to_start_state(vec![0])
14356 .expect("rule start states");
14357 atn.set_rule_to_stop_state(vec![5])
14358 .expect("rule stop states");
14359 atn.add_decision_state(1).expect("decision state");
14360 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14361 .expect("transition");
14362 atn.add_transition(
14363 1,
14364 ParserTransitionSpec::Atom {
14365 target: 2,
14366 label: 1,
14367 },
14368 )
14369 .expect("transition");
14370 atn.add_transition(
14371 1,
14372 ParserTransitionSpec::Atom {
14373 target: 3,
14374 label: 2,
14375 },
14376 )
14377 .expect("transition");
14378 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
14379 .expect("transition");
14380 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14381 .expect("transition");
14382 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14383 .expect("transition");
14384 finish_atn(atn)
14385 }
14386
14387 fn optional_then_b_eof_atn() -> Atn {
14390 let mut atn = ParserAtnBuilder::new(3);
14391 assert_eq!(
14392 atn.add_state(AtnStateKind::RuleStart, Some(0))
14393 .expect("state")
14394 .index(),
14395 0
14396 );
14397 assert_eq!(
14398 atn.add_state(AtnStateKind::BlockStart, Some(0))
14399 .expect("state")
14400 .index(),
14401 1
14402 );
14403 assert_eq!(
14404 atn.add_state(AtnStateKind::Basic, Some(0))
14405 .expect("state")
14406 .index(),
14407 2
14408 );
14409 assert_eq!(
14410 atn.add_state(AtnStateKind::Basic, Some(0))
14411 .expect("state")
14412 .index(),
14413 3
14414 );
14415 assert_eq!(
14416 atn.add_state(AtnStateKind::Basic, Some(0))
14417 .expect("state")
14418 .index(),
14419 4
14420 );
14421 assert_eq!(
14422 atn.add_state(AtnStateKind::RuleStop, Some(0))
14423 .expect("state")
14424 .index(),
14425 5
14426 );
14427 atn.set_rule_to_start_state(vec![0])
14428 .expect("rule start states");
14429 atn.set_rule_to_stop_state(vec![5])
14430 .expect("rule stop states");
14431 atn.add_decision_state(1).expect("decision state");
14432 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14433 .expect("transition");
14434 atn.add_transition(
14436 1,
14437 ParserTransitionSpec::Atom {
14438 target: 3,
14439 label: 1,
14440 },
14441 )
14442 .expect("transition");
14443 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
14444 .expect("transition");
14445 atn.add_transition(
14447 3,
14448 ParserTransitionSpec::Atom {
14449 target: 4,
14450 label: 2,
14451 },
14452 )
14453 .expect("transition");
14454 atn.add_transition(
14455 4,
14456 ParserTransitionSpec::Atom {
14457 target: 5,
14458 label: TOKEN_EOF,
14459 },
14460 )
14461 .expect("transition");
14462 finish_atn(atn)
14463 }
14464
14465 #[test]
14466 fn sync_decision_deletes_only_a_single_token() {
14467 let atn = optional_then_b_eof_atn();
14475
14476 let mut single = mini_parser(vec![
14477 TestToken::new(3).with_text("c"),
14478 TestToken::new(2).with_text("b"),
14479 TestToken::eof("parser-test", 1, 2, 2),
14480 ]);
14481 single.rule_context_stack = vec![RuleContextFrame {
14482 rule_index: 0,
14483 invoking_state: 0,
14484 }];
14485 let children = single
14486 .sync_decision(&atn, 1, true, false)
14487 .expect("single extraneous token recovers");
14488 assert_eq!(children.len(), 1);
14489 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
14490 assert_eq!(single.number_of_syntax_errors(), 1);
14491 assert_eq!(single.la(1), 2);
14493
14494 let mut double = mini_parser(vec![
14495 TestToken::new(3).with_text("c"),
14496 TestToken::new(3).with_text("c"),
14497 TestToken::new(2).with_text("b"),
14498 TestToken::eof("parser-test", 1, 3, 3),
14499 ]);
14500 double.rule_context_stack = vec![RuleContextFrame {
14501 rule_index: 0,
14502 invoking_state: 0,
14503 }];
14504 let result = double.sync_decision(&atn, 1, true, false);
14505 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
14510 match error {
14511 AntlrError::ParserError { message, .. } => {
14512 assert!(message.starts_with("mismatched input"), "got: {message}");
14513 }
14514 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
14515 }
14516 assert_eq!(double.la(1), 3);
14517 }
14518
14519 fn star_loop_then_eof_atn() -> Atn {
14523 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14524 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,
14525 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,
14526 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,
14527 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
14528 ]))
14529 .deserialize_parser()
14530 .expect("star-loop-then-EOF ATN should deserialize")
14531 }
14532
14533 fn plus_loop_with_recovering_body_atn() -> Atn {
14539 let mut atn = ParserAtnBuilder::new(2);
14540 assert_eq!(
14541 atn.add_state(AtnStateKind::RuleStart, Some(0))
14542 .expect("state")
14543 .index(),
14544 0
14545 );
14546 assert_eq!(
14547 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
14548 .expect("state")
14549 .index(),
14550 1
14551 );
14552 assert_eq!(
14553 atn.add_state(AtnStateKind::Basic, Some(0))
14554 .expect("state")
14555 .index(),
14556 2
14557 );
14558 assert_eq!(
14559 atn.add_state(AtnStateKind::BlockEnd, Some(0))
14560 .expect("state")
14561 .index(),
14562 3
14563 );
14564 assert_eq!(
14565 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
14566 .expect("state")
14567 .index(),
14568 4
14569 );
14570 assert_eq!(
14571 atn.add_state(AtnStateKind::LoopEnd, Some(0))
14572 .expect("state")
14573 .index(),
14574 5
14575 );
14576 assert_eq!(
14577 atn.add_state(AtnStateKind::RuleStop, Some(0))
14578 .expect("state")
14579 .index(),
14580 6
14581 );
14582 assert_eq!(
14583 atn.add_state(AtnStateKind::RuleStart, Some(1))
14584 .expect("state")
14585 .index(),
14586 7
14587 );
14588 assert_eq!(
14589 atn.add_state(AtnStateKind::Basic, Some(1))
14590 .expect("state")
14591 .index(),
14592 8
14593 );
14594 assert_eq!(
14595 atn.add_state(AtnStateKind::RuleStop, Some(1))
14596 .expect("state")
14597 .index(),
14598 9
14599 );
14600 atn.set_rule_to_start_state(vec![0, 7])
14601 .expect("rule start states");
14602 atn.set_rule_to_stop_state(vec![6, 9])
14603 .expect("rule stop states");
14604 atn.set_end_state(1, 3).expect("block end state");
14605 atn.set_loop_back_state(5, 4).expect("loop back state");
14606 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14607 .expect("transition");
14608 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14609 .expect("transition");
14610 atn.add_transition(
14611 2,
14612 ParserTransitionSpec::Rule {
14613 target: 7,
14614 rule_index: 1,
14615 follow_state: 3,
14616 precedence: 0,
14617 },
14618 )
14619 .expect("transition");
14620 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14621 .expect("transition");
14622 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
14623 .expect("transition");
14624 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14625 .expect("transition");
14626 atn.add_transition(
14627 5,
14628 ParserTransitionSpec::Atom {
14629 target: 6,
14630 label: 2,
14631 },
14632 )
14633 .expect("transition");
14634 atn.add_transition(
14635 7,
14636 ParserTransitionSpec::Atom {
14637 target: 8,
14638 label: 1,
14639 },
14640 )
14641 .expect("transition");
14642 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14643 .expect("transition");
14644 finish_atn(atn)
14645 }
14646
14647 #[test]
14648 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
14649 let atn = plus_loop_with_recovering_body_atn();
14650 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14651
14652 let error = parser
14653 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
14654 .expect_err("EOF recovery should report a bounded mismatch");
14655
14656 let AntlrError::ParserError { message, .. } = error else {
14657 panic!("expected ParserError, got {error:?}");
14658 };
14659 insta::assert_snapshot!(message, @"mismatched input '<EOF>' expecting {'x', 2}");
14660 assert_eq!(parser.number_of_syntax_errors(), 1);
14661 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
14662 }
14663
14664 #[test]
14665 fn sync_decision_deletes_token_before_eof_at_loop_back() {
14666 let atn = star_loop_then_eof_atn();
14672 let mut parser = mini_parser(vec![
14673 TestToken::new(2).with_text("c"),
14674 TestToken::eof("parser-test", 1, 1, 1),
14675 ]);
14676 parser.rule_context_stack = vec![RuleContextFrame {
14677 rule_index: 0,
14678 invoking_state: 0,
14679 }];
14680 let children = parser
14681 .sync_decision(&atn, 5, true, false)
14682 .expect("single token before EOF recovers");
14683 assert_eq!(children.len(), 1);
14684 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
14685 assert_eq!(parser.number_of_syntax_errors(), 1);
14686 assert_eq!(
14687 parser.la(1),
14688 TOKEN_EOF,
14689 "EOF is left for the rule's EOF match"
14690 );
14691 }
14692
14693 #[test]
14694 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
14695 let atn = star_loop_then_eof_atn();
14700 let mut parser = mini_parser(vec![
14701 TestToken::new(2).with_text("c"),
14702 TestToken::new(2).with_text("c"),
14703 TestToken::eof("parser-test", 1, 2, 2),
14704 ]);
14705 parser.rule_context_stack = vec![RuleContextFrame {
14706 rule_index: 0,
14707 invoking_state: 0,
14708 }];
14709 let error = parser
14710 .sync_decision(&atn, 5, true, false)
14711 .expect_err("two tokens at the loop entry must not be deleted");
14712 match error {
14713 AntlrError::ParserError { message, .. } => {
14714 assert!(message.starts_with("mismatched input"), "got: {message}");
14715 }
14716 other => panic!("expected mismatched-input ParserError, got {other:?}"),
14717 }
14718 assert_eq!(
14719 parser.la(1),
14720 2,
14721 "nothing consumed; cursor still on first `c`"
14722 );
14723 }
14724
14725 #[test]
14726 fn sync_decision_consumes_until_eof_at_loop_back() {
14727 let atn = star_loop_then_eof_atn();
14733 let mut parser = mini_parser(vec![
14734 TestToken::new(2).with_text("c"),
14735 TestToken::new(2).with_text("c"),
14736 TestToken::eof("parser-test", 1, 2, 2),
14737 ]);
14738 parser.rule_context_stack = vec![RuleContextFrame {
14739 rule_index: 0,
14740 invoking_state: 0,
14741 }];
14742 let children = parser
14743 .sync_decision(&atn, 5, false, true)
14744 .expect("loop-back multi-token deletion recovers onto EOF");
14745 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
14746 assert!(
14747 children
14748 .iter()
14749 .all(|child| parser.node(*child).kind() == NodeKind::Error)
14750 );
14751 assert_eq!(parser.number_of_syntax_errors(), 1);
14752 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
14753 }
14754
14755 fn predicate_after_token_atn() -> Atn {
14756 let mut atn = ParserAtnBuilder::new(2);
14757 assert_eq!(
14758 atn.add_state(AtnStateKind::RuleStart, Some(0))
14759 .expect("state")
14760 .index(),
14761 0
14762 );
14763 assert_eq!(
14764 atn.add_state(AtnStateKind::Basic, Some(0))
14765 .expect("state")
14766 .index(),
14767 1
14768 );
14769 assert_eq!(
14770 atn.add_state(AtnStateKind::Basic, Some(0))
14771 .expect("state")
14772 .index(),
14773 2
14774 );
14775 assert_eq!(
14776 atn.add_state(AtnStateKind::Basic, Some(0))
14777 .expect("state")
14778 .index(),
14779 3
14780 );
14781 assert_eq!(
14782 atn.add_state(AtnStateKind::RuleStop, Some(0))
14783 .expect("state")
14784 .index(),
14785 4
14786 );
14787 atn.set_rule_to_start_state(vec![0])
14788 .expect("rule start states");
14789 atn.set_rule_to_stop_state(vec![4])
14790 .expect("rule stop states");
14791 atn.add_transition(
14792 0,
14793 ParserTransitionSpec::Atom {
14794 target: 1,
14795 label: 1,
14796 },
14797 )
14798 .expect("transition");
14799 atn.add_transition(
14800 1,
14801 ParserTransitionSpec::Predicate {
14802 target: 2,
14803 rule_index: 0,
14804 pred_index: 0,
14805 context_dependent: false,
14806 },
14807 )
14808 .expect("transition");
14809 atn.add_transition(
14810 2,
14811 ParserTransitionSpec::Atom {
14812 target: 3,
14813 label: 2,
14814 },
14815 )
14816 .expect("transition");
14817 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14818 .expect("transition");
14819 finish_atn(atn)
14820 }
14821
14822 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
14823 let mut atn = ParserAtnBuilder::new(1);
14824 for (state_number, kind) in [
14825 (0, AtnStateKind::RuleStart),
14826 (1, AtnStateKind::BlockStart),
14827 (2, AtnStateKind::Basic),
14828 (3, AtnStateKind::Basic),
14829 (4, AtnStateKind::Basic),
14830 (5, AtnStateKind::Basic),
14831 (6, AtnStateKind::BlockEnd),
14832 (7, AtnStateKind::RuleStop),
14833 ] {
14834 assert_eq!(
14835 atn.add_state(kind, Some(0)).expect("state").index(),
14836 state_number
14837 );
14838 }
14839 atn.set_rule_to_start_state(vec![0])
14840 .expect("rule start states");
14841 atn.set_rule_to_stop_state(vec![7])
14842 .expect("rule stop states");
14843 atn.add_decision_state(1).expect("decision state");
14844 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14845 .expect("transition");
14846 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14847 .expect("transition");
14848 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
14849 .expect("transition");
14850 atn.add_transition(
14851 2,
14852 ParserTransitionSpec::Predicate {
14853 target: 4,
14854 rule_index: 0,
14855 pred_index: pred_indexes[0],
14856 context_dependent: false,
14857 },
14858 )
14859 .expect("transition");
14860 atn.add_transition(
14861 3,
14862 ParserTransitionSpec::Predicate {
14863 target: 5,
14864 rule_index: 0,
14865 pred_index: pred_indexes[1],
14866 context_dependent: false,
14867 },
14868 )
14869 .expect("transition");
14870 atn.add_transition(
14871 4,
14872 ParserTransitionSpec::Atom {
14873 target: 6,
14874 label: 1,
14875 },
14876 )
14877 .expect("transition");
14878 atn.add_transition(
14879 5,
14880 ParserTransitionSpec::Atom {
14881 target: 6,
14882 label: 1,
14883 },
14884 )
14885 .expect("transition");
14886 atn.add_transition(
14887 6,
14888 ParserTransitionSpec::Atom {
14889 target: 7,
14890 label: TOKEN_EOF,
14891 },
14892 )
14893 .expect("transition");
14894 finish_atn(atn)
14895 }
14896
14897 fn nested_nullable_context_atn() -> Atn {
14898 let mut atn = ParserAtnBuilder::new(1);
14899 for state_number in 0..=20 {
14900 let kind = match state_number {
14901 0 | 10 | 16 => AtnStateKind::RuleStart,
14902 9 | 15 | 20 => AtnStateKind::RuleStop,
14903 _ => AtnStateKind::Basic,
14904 };
14905 let rule_index = match state_number {
14906 0..=9 => 0,
14907 10..=15 => 1,
14908 _ => 2,
14909 };
14910 assert_eq!(
14911 atn.add_state(kind, Some(rule_index))
14912 .expect("state")
14913 .index(),
14914 state_number
14915 );
14916 }
14917 atn.set_rule_to_start_state(vec![0, 10, 16])
14918 .expect("rule start states");
14919 atn.set_rule_to_stop_state(vec![9, 15, 20])
14920 .expect("rule stop states");
14921 atn.add_transition(
14922 1,
14923 ParserTransitionSpec::Rule {
14924 target: 10,
14925 rule_index: 1,
14926 follow_state: 8,
14927 precedence: 0,
14928 },
14929 )
14930 .expect("transition");
14931 atn.add_transition(
14932 8,
14933 ParserTransitionSpec::Atom {
14934 target: 9,
14935 label: 1,
14936 },
14937 )
14938 .expect("transition");
14939 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14940 .expect("transition");
14941 atn.add_transition(
14942 2,
14943 ParserTransitionSpec::Rule {
14944 target: 16,
14945 rule_index: 2,
14946 follow_state: 14,
14947 precedence: 0,
14948 },
14949 )
14950 .expect("transition");
14951 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
14952 .expect("transition");
14953 finish_atn(atn)
14954 }
14955
14956 fn generated_match_recovery_atn() -> Atn {
14957 let mut atn = ParserAtnBuilder::new(2);
14958 assert_eq!(
14959 atn.add_state(AtnStateKind::RuleStart, Some(0))
14960 .expect("state")
14961 .index(),
14962 0
14963 );
14964 assert_eq!(
14965 atn.add_state(AtnStateKind::Basic, Some(0))
14966 .expect("state")
14967 .index(),
14968 1
14969 );
14970 assert_eq!(
14971 atn.add_state(AtnStateKind::Basic, Some(0))
14972 .expect("state")
14973 .index(),
14974 2
14975 );
14976 assert_eq!(
14977 atn.add_state(AtnStateKind::RuleStop, Some(0))
14978 .expect("state")
14979 .index(),
14980 3
14981 );
14982 assert_eq!(
14983 atn.add_state(AtnStateKind::RuleStart, Some(1))
14984 .expect("state")
14985 .index(),
14986 4
14987 );
14988 assert_eq!(
14989 atn.add_state(AtnStateKind::RuleStop, Some(1))
14990 .expect("state")
14991 .index(),
14992 5
14993 );
14994 atn.set_rule_to_start_state(vec![0, 4])
14995 .expect("rule start states");
14996 atn.set_rule_to_stop_state(vec![3, 5])
14997 .expect("rule stop states");
14998 atn.add_transition(
14999 1,
15000 ParserTransitionSpec::Rule {
15001 target: 4,
15002 rule_index: 1,
15003 follow_state: 2,
15004 precedence: 0,
15005 },
15006 )
15007 .expect("transition");
15008 atn.add_transition(
15009 2,
15010 ParserTransitionSpec::Atom {
15011 target: 3,
15012 label: TOKEN_EOF,
15013 },
15014 )
15015 .expect("transition");
15016 finish_atn(atn)
15017 }
15018
15019 fn complement_set_atn() -> Atn {
15020 let mut atn = ParserAtnBuilder::new(1);
15021 assert_eq!(
15022 atn.add_state(AtnStateKind::RuleStart, Some(0))
15023 .expect("state")
15024 .index(),
15025 0
15026 );
15027 assert_eq!(
15028 atn.add_state(AtnStateKind::RuleStop, Some(0))
15029 .expect("state")
15030 .index(),
15031 1
15032 );
15033 atn.set_rule_to_start_state(vec![0])
15034 .expect("rule start states");
15035 atn.set_rule_to_stop_state(vec![1])
15036 .expect("rule stop states");
15037 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
15038 atn.add_transition(
15039 0,
15040 ParserTransitionSpec::NotSet {
15041 target: 1,
15042 set: excluded,
15043 },
15044 )
15045 .expect("transition");
15046 finish_atn(atn)
15047 }
15048
15049 fn wildcard_then_eof_atn() -> Atn {
15052 let mut atn = ParserAtnBuilder::new(1);
15053 assert_eq!(
15054 atn.add_state(AtnStateKind::RuleStart, Some(0))
15055 .expect("state")
15056 .index(),
15057 0
15058 );
15059 assert_eq!(
15060 atn.add_state(AtnStateKind::RuleStop, Some(0))
15061 .expect("state")
15062 .index(),
15063 1
15064 );
15065 assert_eq!(
15066 atn.add_state(AtnStateKind::Basic, Some(0))
15067 .expect("state")
15068 .index(),
15069 2
15070 );
15071 atn.set_rule_to_start_state(vec![0])
15072 .expect("rule start states");
15073 atn.set_rule_to_stop_state(vec![1])
15074 .expect("rule stop states");
15075 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
15076 .expect("transition");
15077 atn.add_transition(
15078 2,
15079 ParserTransitionSpec::Atom {
15080 target: 1,
15081 label: TOKEN_EOF,
15082 },
15083 )
15084 .expect("transition");
15085 finish_atn(atn)
15086 }
15087
15088 #[test]
15089 fn parser_matches_token_and_reports_mismatch() {
15090 let source = Source {
15091 tokens: vec![
15092 TestToken::new(1).with_text("x"),
15093 TestToken::eof("parser-test", 1, 1, 1),
15094 ],
15095 index: 0,
15096 };
15097 let data = RecognizerData::new(
15098 "Mini.g4",
15099 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
15100 );
15101 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
15102 let matched = parser.match_token(1).expect("token 1 should match");
15103 assert_eq!(parser.node(matched).text(), "x");
15104 assert!(parser.match_token(1).is_err());
15105 }
15106
15107 #[test]
15108 fn parser_matches_token_sets() {
15109 let mut parser = mini_parser(vec![
15110 TestToken::new(1).with_text("x"),
15111 TestToken::eof("parser-test", 1, 1, 1),
15112 ]);
15113
15114 let matched = parser
15115 .match_set(&[(1, 1), (3, 4)])
15116 .expect("token set should match");
15117 assert_eq!(parser.node(matched).text(), "x");
15118 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
15119 }
15120
15121 #[test]
15122 fn generated_rule_api_tracks_state_and_precedence() {
15123 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15124
15125 let context = parser.enter_rule(7, 2);
15126 assert_eq!(context.rule_index(), 2);
15127 assert_eq!(parser.state(), 7);
15128 assert_eq!(
15129 parser.rule_context_stack,
15130 vec![RuleContextFrame {
15131 rule_index: 2,
15132 invoking_state: 7
15133 }]
15134 );
15135
15136 let recursive = parser.enter_recursion_rule(11, 3, 4);
15137 assert_eq!(recursive.rule_index(), 3);
15138 assert!(parser.precpred(4));
15139 assert!(parser.precpred(5));
15140 assert!(!parser.precpred(3));
15141
15142 let next = parser.push_new_recursion_context(13, 3);
15143 assert_eq!(next.invoking_state(), 13);
15144 parser.unroll_recursion_context();
15145 assert_eq!(parser.precedence_stack, vec![0]);
15146 assert_eq!(
15147 parser.rule_context_stack,
15148 vec![RuleContextFrame {
15149 rule_index: 2,
15150 invoking_state: 7
15151 }]
15152 );
15153
15154 parser.exit_rule();
15155 assert!(parser.rule_context_stack.is_empty());
15156 }
15157
15158 #[test]
15159 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
15160 let mut parser = mini_parser(vec![
15161 TestToken::new(1).with_text("x"),
15162 TestToken::eof("parser-test", 1, 1, 1),
15163 ]);
15164 let matched = parser.match_token(1).expect("token should match");
15165 assert_eq!(parser.node(matched).text(), "x");
15166 parser.record_generated_syntax_error();
15167 parser.set_int_member(7, 11);
15168 parser.set_build_parse_trees(false);
15169 parser.set_report_diagnostic_errors(true);
15170 parser.set_prediction_mode(PredictionMode::Sll);
15171 parser.set_bail_on_error(true);
15172 let _context = parser.enter_recursion_rule(9, 0, 4);
15173 parser.pending_invoking_states.push(5);
15174 parser.unknown_predicate_hits.push((0, 1));
15175 parser.unhandled_action_hits.push((0, 2));
15176
15177 parser.reset();
15178
15179 assert_eq!(parser.input.index(), 0);
15180 assert_eq!(parser.la(1), 1);
15181 assert_eq!(parser.state(), -1);
15182 assert_eq!(parser.number_of_syntax_errors(), 0);
15183 assert_eq!(parser.parse_tree_storage().node_count(), 0);
15184 assert!(parser.rule_context_stack.is_empty());
15185 assert!(parser.pending_invoking_states.is_empty());
15186 assert_eq!(parser.precedence_stack, [0]);
15187 assert!(parser.unknown_predicate_hits.is_empty());
15188 assert!(parser.unhandled_action_hits.is_empty());
15189 assert_eq!(parser.int_member(7), Some(11));
15190 assert!(!parser.build_parse_trees());
15191 assert!(parser.report_diagnostic_errors());
15192 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
15193 assert!(parser.bail_on_error());
15194 }
15195
15196 #[test]
15197 fn set_token_stream_replaces_input_and_resets_parser() {
15198 let mut parser = mini_parser(vec![
15199 TestToken::new(1).with_text("old"),
15200 TestToken::eof("parser-test", 1, 1, 1),
15201 ]);
15202 parser.consume();
15203 parser.record_generated_syntax_error();
15204 let replacement = CommonTokenStream::new(Source {
15205 tokens: vec![
15206 TestToken::new(2).with_text("new"),
15207 TestToken::eof("parser-test", 1, 1, 1),
15208 ],
15209 index: 0,
15210 });
15211
15212 parser.set_token_stream(replacement);
15213
15214 assert_eq!(parser.input.index(), 0);
15215 assert_eq!(parser.la(1), 2);
15216 assert_eq!(parser.input.text_all(), "new");
15217 assert_eq!(parser.number_of_syntax_errors(), 0);
15218 }
15219
15220 #[test]
15221 fn active_invocation_states_exclude_the_root_frame() {
15222 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15223
15224 let _root = parser.enter_rule(0, 0);
15225 assert!(parser.active_invocation_states().is_empty());
15226
15227 let marker = parser.push_invoking_state(6);
15228 let _child = parser.enter_rule(2, 1);
15229 parser.discard_invoking_state(marker);
15230 assert_eq!(parser.active_invocation_states(), [6]);
15231
15232 let marker = parser.push_invoking_state(13);
15233 let _grandchild = parser.enter_rule(4, 2);
15234 parser.discard_invoking_state(marker);
15235 assert_eq!(parser.active_invocation_states(), [13, 6]);
15236
15237 parser.exit_rule();
15238 parser.exit_rule();
15239 parser.exit_rule();
15240 }
15241
15242 #[test]
15243 fn parser_predicates_support_token_adjacency() {
15244 let mut parser = mini_parser(vec![
15245 TestToken::new(1).with_text("=").with_span(0, 0),
15246 TestToken::new(1).with_text(">").with_span(1, 1),
15247 TestToken::eof("parser-test", 2, 1, 2),
15248 ]);
15249 parser.consume();
15250 parser.consume();
15251
15252 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
15253
15254 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
15255
15256 let mut parser = mini_parser(vec![
15257 TestToken::new(1).with_text("=").with_span(0, 0),
15258 TestToken::new(1)
15259 .with_text(" ")
15260 .with_channel(HIDDEN_CHANNEL)
15261 .with_span(1, 1),
15262 TestToken::new(1).with_text(">").with_span(2, 2),
15263 TestToken::eof("parser-test", 3, 1, 3),
15264 ]);
15265 parser.consume();
15266 parser.consume();
15267
15268 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
15269 }
15270
15271 #[test]
15272 fn parser_predicates_support_context_child_text_checks() {
15273 let mut parser = mini_parser(vec![
15274 TestToken::new(1).with_text("var"),
15275 TestToken::eof("parser-test", 1, 1, 1),
15276 ]);
15277 let mut context = ParserRuleContext::new(1, 0);
15278 let mut child_context = ParserRuleContext::new(2, 0);
15279 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
15280 parser.tree.add_child(&mut child_context, terminal);
15281 let child = parser.rule_node(child_context);
15282 parser.tree.add_child(&mut context, child);
15283 let predicates = [(
15284 1,
15285 0,
15286 ParserPredicate::ContextChildRuleTextNotEquals {
15287 rule_index: 2,
15288 text: "var",
15289 },
15290 )];
15291
15292 assert!(
15293 !parser.parser_semantic_predicate_matches_with_context_and_local(
15294 &predicates,
15295 1,
15296 0,
15297 &context,
15298 0,
15299 )
15300 );
15301 }
15302
15303 #[test]
15304 fn context_expected_symbols_walks_nullable_parent_contexts() {
15305 let atn = nested_nullable_context_atn();
15306 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15307 parser.rule_context_stack = vec![
15308 RuleContextFrame {
15309 rule_index: 0,
15310 invoking_state: 0,
15311 },
15312 RuleContextFrame {
15313 rule_index: 1,
15314 invoking_state: 1,
15315 },
15316 RuleContextFrame {
15317 rule_index: 2,
15318 invoking_state: 2,
15319 },
15320 ];
15321
15322 let expected = parser.context_expected_symbols(&atn);
15323
15324 assert!(expected.contains(&1));
15325 assert!(expected.contains(&TOKEN_EOF));
15326 }
15327
15328 #[test]
15329 fn prediction_context_return_states_track_rule_stack_changes() {
15330 let atn = nested_nullable_context_atn();
15331 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15332 parser.rule_context_stack = vec![
15333 RuleContextFrame {
15334 rule_index: 0,
15335 invoking_state: 0,
15336 },
15337 RuleContextFrame {
15338 rule_index: 1,
15339 invoking_state: 1,
15340 },
15341 RuleContextFrame {
15342 rule_index: 2,
15343 invoking_state: 2,
15344 },
15345 ];
15346
15347 let initial_version = parser.rule_context_version();
15348 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15349 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15350 assert_eq!(first, second);
15351 assert_eq!(parser.rule_context_version(), initial_version);
15352
15353 parser.exit_rule();
15354 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15355 assert_ne!(first, after_pop);
15356 assert_ne!(parser.rule_context_version(), initial_version);
15357 }
15358
15359 #[test]
15360 fn generated_match_token_recovers_missing_token_from_context_follow() {
15361 let atn = generated_match_recovery_atn();
15362 let data = RecognizerData::new(
15363 "Mini.g4",
15364 Vocabulary::new(
15365 [None, Some("'X'"), Some("'Y'")],
15366 [None, Some("X"), Some("Y")],
15367 [None::<&str>, None, None],
15368 ),
15369 );
15370 let mut parser = BaseParser::new(
15371 CommonTokenStream::new(Source {
15372 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
15373 index: 0,
15374 }),
15375 data,
15376 );
15377 parser.rule_context_stack = vec![
15378 RuleContextFrame {
15379 rule_index: 0,
15380 invoking_state: 0,
15381 },
15382 RuleContextFrame {
15383 rule_index: 1,
15384 invoking_state: 1,
15385 },
15386 ];
15387 assert_eq!(parser.number_of_syntax_errors(), 0);
15388
15389 let node = parser
15390 .match_token_recovering(2, 5, &atn)
15391 .expect("generated match should insert missing token");
15392
15393 assert_eq!(node.children().len(), 1);
15394 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
15395 assert_eq!(
15396 node.clone()
15397 .into_child_iter()
15398 .map(|child| parser.node(child).text())
15399 .collect::<Vec<_>>(),
15400 ["<missing 'Y'>"]
15401 );
15402 assert!(!node.consumed_eof());
15405 assert_eq!(parser.la(1), TOKEN_EOF);
15406 assert_eq!(parser.number_of_syntax_errors(), 1);
15407 assert_eq!(
15408 parser.generated_parser_diagnostics,
15409 [ParserDiagnostic {
15410 line: 1,
15411 column: 3,
15412 message: "missing 'Y' at '<EOF>'".to_owned(),
15413 }]
15414 );
15415 }
15416
15417 #[test]
15418 fn generated_match_token_counts_single_token_deletion_recovery() {
15419 let atn = generated_match_recovery_atn();
15420 let data = RecognizerData::new(
15421 "Mini.g4",
15422 Vocabulary::new(
15423 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
15424 [None, Some("X"), Some("Y"), Some("Z")],
15425 [None::<&str>, None, None, None],
15426 ),
15427 );
15428 let mut parser = BaseParser::new(
15429 CommonTokenStream::new(Source {
15430 tokens: vec![
15431 TestToken::new(3).with_text("z"),
15432 TestToken::new(2).with_text("y"),
15433 TestToken::eof("parser-test", 3, 1, 3),
15434 ],
15435 index: 0,
15436 }),
15437 data,
15438 );
15439
15440 let node = parser
15441 .match_token_recovering(2, 5, &atn)
15442 .expect("generated match should delete the extraneous token");
15443
15444 assert_eq!(node.children().len(), 2);
15445 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
15446 assert_eq!(parser.node(node.children()[0]).text(), "z");
15447 assert_eq!(parser.node(node.children()[1]).text(), "y");
15448 assert_eq!(
15449 node.into_child_iter()
15450 .map(|child| parser.node(child).text())
15451 .collect::<Vec<_>>(),
15452 ["z", "y"]
15453 );
15454 assert_eq!(parser.number_of_syntax_errors(), 1);
15455 }
15456
15457 #[test]
15458 fn generated_match_token_iterates_single_success_without_a_children_vec() {
15459 let atn = generated_match_recovery_atn();
15460 let data = RecognizerData::new(
15461 "Mini.g4",
15462 Vocabulary::new(
15463 [None, Some("'X'"), Some("'Y'")],
15464 [None, Some("X"), Some("Y")],
15465 [None::<&str>, None, None],
15466 ),
15467 );
15468 let mut parser = BaseParser::new(
15469 CommonTokenStream::new(Source {
15470 tokens: vec![
15471 TestToken::new(2).with_text("y"),
15472 TestToken::eof("parser-test", 1, 1, 1),
15473 ],
15474 index: 0,
15475 }),
15476 data,
15477 );
15478
15479 let node = parser
15480 .match_token_recovering(2, 5, &atn)
15481 .expect("generated match should consume the expected token");
15482
15483 assert_eq!(
15484 node.into_child_iter()
15485 .map(|child| parser.node(child).text())
15486 .collect::<Vec<_>>(),
15487 ["y"]
15488 );
15489 assert_eq!(parser.number_of_syntax_errors(), 0);
15490 }
15491
15492 #[test]
15493 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
15494 let atn = generated_match_recovery_atn();
15495 let data = RecognizerData::new(
15496 "Mini.g4",
15497 Vocabulary::new(
15498 [None, Some("'X'"), Some("'Y'")],
15499 [None, Some("X"), Some("Y")],
15500 [None::<&str>, None, None],
15501 ),
15502 );
15503 let mut parser = BaseParser::new(
15504 CommonTokenStream::new(Source {
15505 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
15506 index: 0,
15507 }),
15508 data,
15509 );
15510 parser.rule_context_stack = vec![
15511 RuleContextFrame {
15512 rule_index: 0,
15513 invoking_state: 0,
15514 },
15515 RuleContextFrame {
15516 rule_index: 1,
15517 invoking_state: 1,
15518 },
15519 ];
15520 let marker = parser.generated_diagnostics_checkpoint();
15521
15522 let _ = parser
15523 .match_token_recovering(2, 5, &atn)
15524 .expect("generated match should insert missing token");
15525 assert_eq!(parser.number_of_syntax_errors(), 1);
15526
15527 parser.restore_generated_diagnostics(marker);
15528
15529 assert_eq!(parser.number_of_syntax_errors(), 0);
15530 assert!(parser.generated_parser_diagnostics.is_empty());
15531 }
15532
15533 #[test]
15534 fn generated_prediction_diagnostics_use_adaptive_context() {
15535 let atn = two_alt_decision_atn();
15536 let data = RecognizerData::new(
15537 "Mini.g4",
15538 Vocabulary::new(
15539 [None, Some("'x'"), Some("'y'")],
15540 [None, Some("X"), Some("Y")],
15541 [None::<&str>, None, None],
15542 ),
15543 )
15544 .with_rule_names(["s"]);
15545 let mut parser = BaseParser::new(
15546 CommonTokenStream::new(Source {
15547 tokens: vec![
15548 TestToken::new(1)
15549 .with_text("x")
15550 .with_position(1, 0)
15551 .with_span(0, 0),
15552 TestToken::new(2)
15553 .with_text("y")
15554 .with_position(1, 2)
15555 .with_span(1, 1),
15556 TestToken::eof("parser-test", 2, 1, 3),
15557 ],
15558 index: 0,
15559 }),
15560 data,
15561 );
15562 parser.set_report_diagnostic_errors(true);
15563
15564 parser.record_generated_prediction_diagnostic(
15565 &atn,
15566 1,
15567 &ParserAtnPrediction {
15568 alt: 1,
15569 requires_full_context: true,
15570 has_semantic_context: false,
15571 diagnostic: Some(ParserAtnPredictionDiagnostic {
15572 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
15573 start_index: 0,
15574 sll_stop_index: 1,
15575 ll_stop_index: 0,
15576 conflicting_alts: vec![1, 2],
15577 exact: false,
15578 }),
15579 },
15580 );
15581 parser.record_generated_prediction_diagnostic(
15586 &atn,
15587 1,
15588 &ParserAtnPrediction {
15589 alt: 1,
15590 requires_full_context: true,
15591 has_semantic_context: false,
15592 diagnostic: Some(ParserAtnPredictionDiagnostic {
15593 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
15594 start_index: 0,
15595 sll_stop_index: 1,
15596 ll_stop_index: 1,
15597 conflicting_alts: vec![1, 2],
15598 exact: false,
15599 }),
15600 },
15601 );
15602
15603 insta::assert_debug_snapshot!(
15606 "generated_prediction_diagnostics_use_adaptive_context",
15607 parser.generated_parser_diagnostics
15608 );
15609 }
15610
15611 #[test]
15612 fn generated_match_not_set_recovers_empty_complement_at_eof() {
15613 let atn = complement_set_atn();
15614 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15615 parser.rule_context_stack = vec![RuleContextFrame {
15616 rule_index: 0,
15617 invoking_state: 0,
15618 }];
15619
15620 let node = parser
15621 .match_not_token_set_recovering(
15622 atn.token_set(0).expect("excluded token set"),
15623 1,
15624 1,
15625 1,
15626 &atn,
15627 )
15628 .expect("empty complement should recover at EOF");
15629
15630 assert_eq!(node.children().len(), 1);
15631 assert!(!node.consumed_eof());
15634 assert_eq!(parser.la(1), TOKEN_EOF);
15635 assert_eq!(
15636 parser.generated_parser_diagnostics,
15637 [ParserDiagnostic {
15638 line: 1,
15639 column: 1,
15640 message: "missing {} at '<EOF>'".to_owned(),
15641 }]
15642 );
15643 }
15644
15645 #[test]
15646 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
15647 let atn = wildcard_then_eof_atn();
15653 let data = RecognizerData::new(
15654 "Mini.g4",
15655 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
15656 );
15657 let mut parser = BaseParser::new(
15658 CommonTokenStream::new(Source {
15659 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
15660 index: 0,
15661 }),
15662 data,
15663 );
15664 parser.rule_context_stack = vec![RuleContextFrame {
15665 rule_index: 0,
15666 invoking_state: 0,
15667 }];
15668
15669 let node = parser
15670 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
15671 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
15672
15673 assert_eq!(node.children().len(), 1);
15675 assert!(!node.consumed_eof());
15676 assert!(
15677 parser
15678 .node(node.children()[0])
15679 .text()
15680 .starts_with("<missing")
15681 );
15682 assert_eq!(parser.la(1), TOKEN_EOF);
15683 assert_eq!(
15684 parser.generated_parser_diagnostics,
15685 [ParserDiagnostic {
15686 line: 1,
15687 column: 1,
15688 message: "missing 'x' at '<EOF>'".to_owned(),
15689 }]
15690 );
15691 }
15692
15693 #[test]
15694 fn generated_rule_recovery_consumes_to_parent_follow() {
15695 let atn = generated_match_recovery_atn();
15696 let data = RecognizerData::new(
15697 "Mini.g4",
15698 Vocabulary::new(
15699 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
15700 [None, Some("X"), Some("Y"), Some("Z")],
15701 [None::<&str>, None, None, None],
15702 ),
15703 );
15704 let mut parser = BaseParser::new(
15705 CommonTokenStream::new(Source {
15706 tokens: vec![
15707 TestToken::new(3).with_text("z"),
15708 TestToken::eof("parser-test", 1, 1, 1),
15709 ],
15710 index: 0,
15711 }),
15712 data,
15713 );
15714 let _parent = parser.enter_rule(0, 0);
15715 let marker = parser.push_invoking_state(1);
15716 let mut child = parser.enter_rule(4, 1);
15717 parser.discard_invoking_state(marker);
15718
15719 parser.recover_generated_rule(
15720 &mut child,
15721 &atn,
15722 AntlrError::ParserError {
15723 line: 1,
15724 column: 0,
15725 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
15726 },
15727 );
15728 let tree = parser.finish_rule(child, false);
15729
15730 assert_eq!(parser.la(1), TOKEN_EOF);
15731 assert_eq!(
15732 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
15733 "(a z)"
15734 );
15735 assert_eq!(parser.number_of_syntax_errors(), 1);
15736 assert_eq!(
15737 parser.generated_parser_diagnostics,
15738 [ParserDiagnostic {
15739 line: 1,
15740 column: 0,
15741 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
15742 }]
15743 );
15744 parser.exit_rule();
15745 }
15746
15747 #[test]
15748 fn generated_rule_recovery_forces_progress_after_repeated_error_state() {
15749 let atn = nested_nullable_context_atn();
15750 let mut parser = mini_parser(vec![
15751 TestToken::new(1).with_text("x"),
15752 TestToken::eof("parser-test", 1, 1, 1),
15753 ]);
15754 parser.rule_context_stack = vec![
15755 RuleContextFrame {
15756 rule_index: 0,
15757 invoking_state: 0,
15758 },
15759 RuleContextFrame {
15760 rule_index: 1,
15761 invoking_state: 1,
15762 },
15763 RuleContextFrame {
15764 rule_index: 2,
15765 invoking_state: 2,
15766 },
15767 ];
15768 parser.set_state(20);
15769 let mut context = ParserRuleContext::new(2, 2);
15770
15771 parser.recover_generated_rule(
15772 &mut context,
15773 &atn,
15774 AntlrError::NoViableAlternative {
15775 input: "'x'".to_owned(),
15776 },
15777 );
15778 assert_eq!(parser.input.index(), 0);
15779
15780 parser.set_state(21);
15781 parser.recover_generated_rule(
15782 &mut context,
15783 &atn,
15784 AntlrError::NoViableAlternative {
15785 input: "'x'".to_owned(),
15786 },
15787 );
15788 assert_eq!(parser.input.index(), 0);
15789 assert_eq!(
15790 parser.generated_recovery_error_states,
15791 BTreeSet::from([20, 21])
15792 );
15793
15794 parser.set_state(20);
15795 parser.recover_generated_rule(
15796 &mut context,
15797 &atn,
15798 AntlrError::NoViableAlternative {
15799 input: "'x'".to_owned(),
15800 },
15801 );
15802
15803 assert_eq!(parser.input.index(), 1);
15804 assert_eq!(parser.la(1), TOKEN_EOF);
15805 assert!(context.has_matched_child());
15806 assert_eq!(parser.generated_recovery_error_states, BTreeSet::from([20]));
15807
15808 parser.match_eof().expect("EOF should match");
15809 assert_eq!(parser.generated_recovery_error_index, None);
15810 assert!(parser.generated_recovery_error_states.is_empty());
15811 }
15812
15813 #[test]
15814 fn greedy_ll1_alt_handles_nullable_loop_exit() {
15815 let mut body_symbols = TokenBitSet::default();
15816 body_symbols.insert(1);
15817 let entry = DecisionLookahead {
15818 transitions: vec![
15819 TransitionLookSet {
15820 symbols: body_symbols,
15821 nullable: false,
15822 },
15823 TransitionLookSet {
15824 symbols: TokenBitSet::default(),
15825 nullable: true,
15826 },
15827 ],
15828 };
15829
15830 assert_eq!(ll1_unique_alt(&entry, 2), None);
15831 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
15832 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
15833 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
15834 }
15835
15836 #[test]
15837 fn ordinary_repetition_builds_tree_in_input_order() {
15838 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15839 let mut parser = mini_parser(repeated_x_tokens(3));
15840 let tree = parser
15841 .parse_atn_rule(&atn, 0)
15842 .expect("ordinary repetition should parse");
15843
15844 let root = parser
15845 .node(tree)
15846 .as_rule()
15847 .expect("entry result should be a rule");
15848 let body_rules = root.child_rules(1).collect::<Vec<_>>();
15849 assert_eq!(root.text(), "xxx<EOF>");
15850 assert_eq!(body_rules.len(), 3);
15851 assert_eq!(
15852 body_rules
15853 .iter()
15854 .map(|rule| rule.start_id().expect("body start").index())
15855 .collect::<Vec<_>>(),
15856 [0, 1, 2]
15857 );
15858 assert_eq!(
15859 body_rules
15860 .iter()
15861 .map(|rule| rule.stop_id().expect("body stop").index())
15862 .collect::<Vec<_>>(),
15863 [0, 1, 2]
15864 );
15865 assert_eq!(parser.number_of_syntax_errors(), 0);
15866 }
15867 }
15868
15869 #[test]
15870 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
15871 const DEPTH: usize = 20_000;
15872
15873 std::thread::Builder::new()
15874 .name("deferred-rule-materialization".to_owned())
15875 .stack_size(256 * 1024)
15876 .spawn(|| {
15877 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
15878 let mut root = FastDeferredNodeId::EMPTY;
15879 for depth in 0..DEPTH {
15880 root = parser
15881 .recognition_arena
15882 .deferred_rule_node(FastDeferredRule {
15883 rule_index: u32::try_from(depth).expect("depth fits in u32"),
15884 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
15885 start_index: 0,
15886 stop_index: None,
15887 deferred_children: root,
15888 children: NodeSeqId::EMPTY,
15889 });
15890 }
15891
15892 let (mut children, alt_number) =
15893 parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
15894 assert_eq!(alt_number, 0);
15895 for expected_rule in (0..DEPTH).rev() {
15896 let mut nodes = parser.recognition_arena.iter(children);
15897 let node = nodes.next().expect("nested rule node");
15898 assert!(nodes.next().is_none(), "each rule has one child");
15899 let ArenaRecognizedNode::Rule {
15900 rule_index,
15901 children: nested,
15902 ..
15903 } = parser.recognition_arena.node(node)
15904 else {
15905 panic!("expected nested rule");
15906 };
15907 assert_eq!(rule_index as usize, expected_rule);
15908 children = nested;
15909 }
15910 assert!(children.is_empty());
15911 })
15912 .expect("small-stack thread should start")
15913 .join()
15914 .expect("deferred rules should materialize without recursion");
15915 }
15916
15917 #[test]
15918 fn deferred_alternatives_preserve_left_recursive_contexts() {
15919 let mut parser = mini_parser(vec![
15920 TestToken::new(1).with_text("1"),
15921 TestToken::new(2).with_text("+"),
15922 TestToken::new(1).with_text("2"),
15923 TestToken::eof("parser-test", 3, 1, 3),
15924 ]);
15925 let base = parser.arena_token_node(0, false);
15926 let operator = parser.arena_token_node(1, false);
15927 let right = parser.arena_token_node(2, false);
15928
15929 let base = parser.recognition_arena.prepend(NodeSeqId::EMPTY, base);
15930 let base = parser.recognition_arena.deferred_fragment(base);
15931 let operator = parser.recognition_arena.prepend(NodeSeqId::EMPTY, operator);
15932 let operator = parser.recognition_arena.deferred_fragment(operator);
15933 let right = parser.recognition_arena.prepend(NodeSeqId::EMPTY, right);
15934 let right = parser.recognition_arena.deferred_fragment(right);
15935 let base_alt = parser.recognition_arena.deferred_alternative(1);
15936 let boundary = parser.recognition_arena.deferred_left_recursive_boundary(0);
15937 let operator_alt = parser.recognition_arena.deferred_alternative(6);
15938
15939 let mut deferred = FastDeferredNodeId::EMPTY;
15940 for fragment in [base_alt, base, boundary, operator_alt, operator, right] {
15941 deferred = parser
15942 .recognition_arena
15943 .concat_deferred_nodes(deferred, fragment);
15944 }
15945 let (nodes, root_alt_number) =
15946 parser.materialize_fast_deferred_nodes(deferred, NodeSeqId::EMPTY);
15947 let nodes = parser
15948 .recognition_arena
15949 .fold_left_recursive_boundaries(nodes);
15950
15951 let mut root = ParserRuleContext::new(0, -1);
15952 root.set_context_alt_number(root_alt_number);
15953 let mut cursor = nodes;
15954 while let Some(link) = parser.recognition_arena.link(cursor) {
15955 let child = parser
15956 .arena_recognized_node_tree(link.head, false, true)
15957 .expect("materialized child should become a public tree");
15958 parser.tree.add_child(&mut root, child);
15959 cursor = link.tail;
15960 }
15961 let tree = parser.rule_node(root);
15962 let contexts = parser
15963 .node(tree)
15964 .descendants()
15965 .filter_map(Node::as_rule)
15966 .map(|rule| {
15967 (
15968 rule.rule_index(),
15969 rule.alt_number(),
15970 rule.context_alt_number(),
15971 rule.text(),
15972 )
15973 })
15974 .collect::<Vec<_>>();
15975
15976 insta::assert_debug_snapshot!(
15977 "deferred_alternatives_preserve_left_recursive_contexts",
15978 contexts
15979 );
15980 }
15981
15982 #[test]
15983 fn fast_recognizer_preserves_labeled_left_recursive_operator_context() {
15984 let atn = labeled_left_recursive_operator_atn();
15985 let mut parser = mini_parser(vec![
15986 TestToken::new(1).with_text("a"),
15987 TestToken::new(3).with_text("+"),
15988 TestToken::new(1).with_text("b"),
15989 TestToken::eof("parser-test", 3, 1, 3),
15990 ]);
15991
15992 let (tree, _) = parser
15993 .parse_atn_rule_with_runtime_options(
15994 &atn,
15995 0,
15996 ParserRuntimeOptions {
15997 track_context_alt_numbers: true,
15998 ..ParserRuntimeOptions::default()
15999 },
16000 )
16001 .expect("labeled left-recursive addition should parse");
16002 let contexts = parser
16003 .node(tree)
16004 .descendants()
16005 .filter_map(Node::as_rule)
16006 .map(|rule| {
16007 let operator = rule
16008 .children()
16009 .next()
16010 .and_then(Node::as_rule)
16011 .is_some_and(|child| child.rule_index() == rule.rule_index());
16012 (operator, rule.context_alt_number(), rule.text())
16013 })
16014 .collect::<Vec<_>>();
16015
16016 insta::assert_debug_snapshot!(
16017 "fast_recognizer_preserves_labeled_left_recursive_operator_context",
16018 contexts
16019 );
16020 assert!(!parser.recognition_arena.deferred_nodes.is_empty());
16021 assert_eq!(parser.number_of_syntax_errors(), 0);
16022 }
16023
16024 #[test]
16025 fn deeply_nested_rule_calls_grow_the_stack() {
16026 const DEPTH: usize = 4_096;
16027 const STACK_SIZE: usize = 256 * 1024;
16028 let atn = nested_rule_chain_atn(DEPTH);
16029 std::thread::Builder::new()
16030 .name("nested-adaptive-set-rules".to_owned())
16031 .stack_size(STACK_SIZE)
16032 .spawn(move || {
16033 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
16034 parser.set_build_parse_trees(false);
16035 parser.fast_first_set_prefilter = false;
16038 parser
16039 .parse_atn_rule(&atn, 0)
16040 .expect("nested rule chain should grow the native stack");
16041 assert_eq!(parser.input.index(), 1);
16042 })
16043 .expect("small-stack thread should start")
16044 .join()
16045 .expect("nested rule chain should not overflow its stack");
16046 }
16047
16048 #[test]
16049 fn deeply_nested_branching_rules_grow_the_stack() {
16050 const DEPTH: usize = 4_096;
16051 const STACK_SIZE: usize = 256 * 1024;
16052 let atn = nested_rule_graph_atn(DEPTH, true, false);
16053 std::thread::Builder::new()
16054 .name("nested-branching-rules".to_owned())
16055 .stack_size(STACK_SIZE)
16056 .spawn(move || {
16057 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
16058 parser.set_build_parse_trees(false);
16059 parser
16060 .parse_atn_rule(&atn, 0)
16061 .expect("branching rule chain should grow the native stack");
16062 assert_eq!(parser.input.index(), 1);
16063 })
16064 .expect("small-stack thread should start")
16065 .join()
16066 .expect("branching rule chain should not overflow its stack");
16067 }
16068
16069 #[test]
16070 fn deeply_nested_rule_follows_grow_the_stack() {
16071 const DEPTH: usize = 4_096;
16072 const STACK_SIZE: usize = 256 * 1024;
16073 let atn = nested_rule_graph_atn(DEPTH, false, true);
16074 std::thread::Builder::new()
16075 .name("nested-rule-follows".to_owned())
16076 .stack_size(STACK_SIZE)
16077 .spawn(move || {
16078 let mut parser = mini_parser(repeated_x_tokens(DEPTH));
16079 parser.set_build_parse_trees(false);
16080 parser.fast_first_set_prefilter = false;
16081 parser
16082 .parse_atn_rule(&atn, 0)
16083 .expect("rule follow chain should grow the native stack");
16084 assert_eq!(parser.input.index(), DEPTH);
16085 })
16086 .expect("small-stack thread should start")
16087 .join()
16088 .expect("nested rule follow chain should not overflow its stack");
16089 }
16090
16091 #[test]
16092 fn deeply_nested_recovery_grows_the_stack() {
16093 const DEPTH: usize = 4_096;
16094 const STACK_SIZE: usize = 256 * 1024;
16095 let atn = nested_rule_chain_atn(DEPTH);
16096 std::thread::Builder::new()
16097 .name("nested-rule-recovery".to_owned())
16098 .stack_size(STACK_SIZE)
16099 .spawn(move || {
16100 let mut parser = mini_parser(vec![
16101 TestToken::new(2).with_text("z"),
16102 TestToken::new(1).with_text("x"),
16103 TestToken::eof("parser-test", 2, 1, 2),
16104 ]);
16105 parser.set_build_parse_trees(false);
16106 parser.fast_first_set_prefilter = false;
16107 parser
16108 .parse_atn_rule(&atn, 0)
16109 .expect("nested recovery should grow the native stack");
16110 assert_eq!(parser.input.index(), 2);
16111 assert_eq!(parser.number_of_syntax_errors(), 1);
16112 })
16113 .expect("small-stack thread should start")
16114 .join()
16115 .expect("nested rule recovery should not overflow its stack");
16116 }
16117
16118 #[test]
16119 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
16120 const REPETITIONS: usize = 64;
16121
16122 let atn = ambiguous_ordinary_star_loop_atn();
16123 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16124 let tree = parser
16125 .parse_atn_rule(&atn, 0)
16126 .expect("ambiguous ordinary repetition should parse");
16127
16128 let root = parser
16129 .node(tree)
16130 .as_rule()
16131 .expect("entry result should be a rule");
16132 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
16133 assert_eq!(parser.input.index(), REPETITIONS);
16134 assert!(
16135 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
16136 "equivalent segmentations should keep deferred storage linear"
16137 );
16138 assert_eq!(parser.number_of_syntax_errors(), 0);
16139 }
16140
16141 #[test]
16142 fn long_ordinary_repetition_does_not_consume_native_stack() {
16143 const REPETITIONS: usize = 20_000;
16144
16145 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
16146 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16147 parser.set_build_parse_trees(false);
16148 parser
16149 .parse_atn_rule(&atn, 0)
16150 .expect("long ordinary repetition should parse");
16151
16152 assert_eq!(parser.input.index(), REPETITIONS);
16153 assert_eq!(parser.number_of_syntax_errors(), 0);
16154 }
16155 }
16156
16157 #[test]
16158 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
16159 const REPETITIONS: usize = 2_000;
16160 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
16161
16162 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
16163 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16164 let tree = parser
16165 .parse_atn_rule(&atn, 0)
16166 .expect("long rule repetition should parse");
16167
16168 let root = parser
16169 .node(tree)
16170 .as_rule()
16171 .expect("entry result should be a rule");
16172 assert_eq!(root.text(), expected_text);
16173 assert_eq!(root.child_rules(1).count(), REPETITIONS);
16174 let first_body = root.child_rules(1).next().expect("first body rule");
16175 let last_body = root.child_rules(1).next_back().expect("last body rule");
16176 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
16177 assert_eq!(
16178 last_body.stop_id().expect("last body stop").index(),
16179 REPETITIONS - 1
16180 );
16181
16182 let stats = parser.recognition_arena_stats();
16183 assert_eq!(
16184 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
16185 (REPETITIONS, REPETITIONS, 0)
16186 );
16187 assert_eq!(
16188 (stats.total_links, stats.live_links, stats.dead_links),
16189 (REPETITIONS, REPETITIONS, 0)
16190 );
16191 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
16192 assert_eq!(
16193 parser.recognition_arena.deferred_nodes.len(),
16194 REPETITIONS * 2 - 1
16195 );
16196 assert_eq!(parser.number_of_syntax_errors(), 0);
16197 }
16198 }
16199
16200 #[test]
16201 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
16202 let key = |state_number| FastRecognizeKey {
16203 state_number,
16204 stop_state: 10,
16205 index: state_number,
16206 rule_start_index: 0,
16207 decision_start_index: None,
16208 precedence: 0,
16209 recovery_symbols_id: 0,
16210 recovery_state: None,
16211 };
16212
16213 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16214 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
16215 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
16216 }
16217 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
16218 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
16219
16220 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16221 let repeated = key(1);
16222 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
16223 assert!(promote.clean_memo_enabled_for_key(&repeated));
16224 }
16225 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
16226
16227 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
16228 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
16229 }
16230 assert!(sparse.clean_memo_enabled_for_key(&repeated));
16231 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
16232 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
16233 assert!(sparse.clean_memo_enabled_for_key(&repeated));
16234 }
16235 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
16236 }
16237
16238 #[test]
16239 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
16240 assert_eq!(
16241 fast_recognize_memo_capacity(0),
16242 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
16243 );
16244 assert_eq!(
16245 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
16246 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
16247 );
16248 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
16249 assert_eq!(
16250 fast_recognize_memo_capacity(usize::MAX),
16251 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
16252 );
16253 }
16254
16255 #[test]
16256 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
16257 let mut scratch = FastRecognizeTopScratch::default();
16258 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
16259 let retained_capacity = scratch.memo.capacity();
16260 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
16261 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16262
16263 let larger_capacity = retained_capacity + 1;
16264 scratch.prepare(larger_capacity);
16265 let grown_capacity = scratch.memo.capacity();
16266 assert!(grown_capacity >= larger_capacity);
16267 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16268
16269 scratch.memo.insert(
16270 FastRecognizeKey {
16271 state_number: 0,
16272 stop_state: 0,
16273 index: 0,
16274 rule_start_index: 0,
16275 decision_start_index: None,
16276 precedence: 0,
16277 recovery_symbols_id: 0,
16278 recovery_state: None,
16279 },
16280 Rc::from([FastRecognizeOutcome {
16281 index: 0,
16282 consumed_eof: false,
16283 diagnostics: DiagnosticSeqId::EMPTY,
16284 deferred_nodes: FastDeferredNodeId::EMPTY,
16285 nodes: NodeSeqId::EMPTY,
16286 }]),
16287 );
16288 scratch.release_oversized_memo();
16289 assert!(scratch.memo.is_empty());
16290 assert_eq!(scratch.memo.capacity(), grown_capacity);
16291
16292 scratch
16293 .memo
16294 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
16295 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16296
16297 scratch.release_oversized_memo();
16298 assert!(scratch.memo.is_empty());
16299 assert_eq!(scratch.memo.capacity(), 0);
16300 }
16301
16302 #[test]
16303 fn clean_empty_multi_alt_outcomes_are_memoized() {
16304 let mut atn = ParserAtnBuilder::new(2);
16305 assert_eq!(
16306 atn.add_state(AtnStateKind::RuleStart, Some(0))
16307 .expect("state")
16308 .index(),
16309 0
16310 );
16311 assert_eq!(
16312 atn.add_state(AtnStateKind::BlockStart, Some(0))
16313 .expect("state")
16314 .index(),
16315 1
16316 );
16317 assert_eq!(
16318 atn.add_state(AtnStateKind::RuleStop, Some(0))
16319 .expect("state")
16320 .index(),
16321 2
16322 );
16323 atn.set_rule_to_start_state(vec![0])
16324 .expect("rule start states");
16325 atn.set_rule_to_stop_state(vec![2])
16326 .expect("rule stop states");
16327 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16328 .expect("transition");
16329 atn.add_transition(
16330 1,
16331 ParserTransitionSpec::Atom {
16332 target: 2,
16333 label: 1,
16334 },
16335 )
16336 .expect("transition");
16337 atn.add_transition(
16338 1,
16339 ParserTransitionSpec::Atom {
16340 target: 2,
16341 label: 2,
16342 },
16343 )
16344 .expect("transition");
16345 let atn = finish_atn(atn);
16346
16347 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
16348 parser.fast_recovery_enabled = false;
16349 let mut visiting = FxHashSet::default();
16350 let mut memo = FxHashMap::default();
16351 let mut expected = ExpectedTokens::default();
16352 let outcomes = parser.recognize_state_fast(
16353 &atn,
16354 FastRecognizeRequest {
16355 state_number: 1,
16356 stop_state: 2,
16357 index: 0,
16358 rule_start_index: 0,
16359 decision_start_index: None,
16360 precedence: 0,
16361 depth: 0,
16362 recovery_symbols: parser.empty_recovery_symbols(),
16363 recovery_state: None,
16364 },
16365 FastRecognizeScratch {
16366 predicate_context: None,
16367 visiting: &mut visiting,
16368 memo: &mut memo,
16369 expected: &mut expected,
16370 native_depth: 0,
16371 },
16372 );
16373
16374 assert!(outcomes.is_empty());
16375 assert_eq!(memo.len(), 1);
16376 assert!(memo.values().next().expect("memo entry").is_empty());
16377
16378 parser.clean_memo_mode = CleanMemoMode::Sparse;
16379 visiting.clear();
16380 memo.clear();
16381 expected = ExpectedTokens::default();
16382 let sparse_outcomes = parser.recognize_state_fast(
16383 &atn,
16384 FastRecognizeRequest {
16385 state_number: 1,
16386 stop_state: 2,
16387 index: 0,
16388 rule_start_index: 0,
16389 decision_start_index: None,
16390 precedence: 0,
16391 depth: 0,
16392 recovery_symbols: parser.empty_recovery_symbols(),
16393 recovery_state: None,
16394 },
16395 FastRecognizeScratch {
16396 predicate_context: None,
16397 visiting: &mut visiting,
16398 memo: &mut memo,
16399 expected: &mut expected,
16400 native_depth: 0,
16401 },
16402 );
16403
16404 assert!(sparse_outcomes.is_empty());
16405 assert!(memo.is_empty());
16406 }
16407
16408 #[test]
16409 fn wildcard_matches_non_eof_only() {
16410 let mut parser = mini_parser(vec![
16411 TestToken::new(1).with_text("x"),
16412 TestToken::eof("parser-test", 1, 1, 1),
16413 ]);
16414 let matched = parser.match_wildcard().expect("wildcard");
16415 assert_eq!(parser.node(matched).text(), "x");
16416 assert!(parser.match_wildcard().is_err());
16417 }
16418
16419 #[test]
16420 fn add_parse_child_records_match_even_without_tree_building() {
16421 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16426 let token = TestToken::new(1).with_text("x");
16427
16428 parser.set_build_parse_trees(false);
16429 let mut ctx = ParserRuleContext::new(0, 0);
16430 assert!(!ctx.has_matched_child());
16431 let child = parser.terminal_tree(token.id);
16432 parser.add_parse_child(&mut ctx, child);
16433 assert_eq!(ctx.child_count(), 0);
16435 assert_eq!(parser.parse_tree_storage().node_count(), 0);
16436 assert!(ctx.has_matched_child());
16438
16439 parser.set_build_parse_trees(true);
16441 let mut ctx = ParserRuleContext::new(0, 0);
16442 let child = parser.terminal_tree(token.id);
16443 parser.add_parse_child(&mut ctx, child);
16444 assert_eq!(ctx.child_count(), 1);
16445 assert!(ctx.has_matched_child());
16446 }
16447
16448 #[test]
16449 fn disabled_tree_building_does_not_grow_flat_storage() {
16450 let mut parser = mini_parser(vec![
16451 TestToken::new(1).with_text("x"),
16452 TestToken::new(1).with_text("y"),
16453 TestToken::eof("parser-test", 2, 1, 2),
16454 ]);
16455 parser.set_build_parse_trees(false);
16456 let mut context = ParserRuleContext::new(0, -1);
16457
16458 for _ in 0..2 {
16459 let child = parser.match_token(1).expect("token should match");
16460 parser.add_parse_child(&mut context, child);
16461 }
16462 let current = parser.input.lt_id(1).expect("EOF token");
16463 let error = parser.error_tree(current);
16464 parser.add_parse_child(&mut context, error);
16465 let root = parser.rule_node(context);
16466
16467 assert_eq!(
16468 parser.parse_tree_storage().stats(),
16469 ParseTreeStats::default()
16470 );
16471 assert!(
16472 parser
16473 .parse_tree_storage()
16474 .node(parser.token_store(), root)
16475 .is_none(),
16476 "the no-tree sentinel must not resolve to stored data"
16477 );
16478 }
16479
16480 #[test]
16481 fn disabled_tree_building_skips_recognition_rule_node_storage() {
16482 let atn = ordinary_star_loop_atn();
16483 let mut parser = mini_parser(repeated_x_tokens(3));
16484 parser.set_build_parse_trees(false);
16485
16486 parser
16487 .parse_atn_rule(&atn, 0)
16488 .expect("ordinary repetition should parse without a tree");
16489
16490 assert_eq!(parser.input.index(), 3);
16491 assert!(parser.recognition_arena.nodes.is_empty());
16492 assert!(parser.recognition_arena.seq_links.is_empty());
16493 assert!(parser.recognition_arena.deferred_nodes.is_empty());
16494 assert!(parser.recognition_arena.deferred_rules.is_empty());
16495 assert!(!parser.fast_token_nodes_enabled);
16496 assert!(parser.fast_recognize_scratch.memo.is_empty());
16497 }
16498
16499 #[test]
16500 fn parser_interprets_simple_atn_rule() {
16501 let atn = token_then_eof_atn();
16502 let mut parser = mini_parser(vec![
16503 TestToken::new(1).with_text("x"),
16504 TestToken::eof("parser-test", 1, 1, 1),
16505 ]);
16506
16507 let tree = parser
16508 .parse_atn_rule(&atn, 0)
16509 .expect("artificial parser rule should parse");
16510 assert_eq!(parser.node(tree).text(), "x<EOF>");
16511 assert_eq!(parser.number_of_syntax_errors(), 0);
16512 assert_eq!(
16513 parser
16514 .node(tree)
16515 .first_rule_stop(0)
16516 .expect("rule should stop at EOF")
16517 .token_type(),
16518 TOKEN_EOF
16519 );
16520
16521 let mut parser = mini_parser(vec![
16522 TestToken::new(1).with_text("x"),
16523 TestToken::eof("parser-test", 1, 1, 1),
16524 ]);
16525 let (tree, actions) = parser
16526 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16527 .expect("runtime-option parser rule should parse");
16528 assert!(actions.is_empty());
16529 assert_eq!(
16530 parser
16531 .node(tree)
16532 .first_rule_stop(0)
16533 .expect("rule should stop at EOF")
16534 .token_type(),
16535 TOKEN_EOF
16536 );
16537 }
16538
16539 #[test]
16540 fn runtime_options_default_ignores_noop_action_transitions() {
16541 let atn = noop_action_then_token_then_eof_atn();
16542 let mut parser = mini_parser(vec![
16543 TestToken::new(1).with_text("x"),
16544 TestToken::eof("parser-test", 1, 1, 1),
16545 ]);
16546
16547 let (tree, actions) = parser
16548 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16549 .expect("no-op parser action should not force action replay");
16550
16551 assert_eq!(parser.node(tree).text(), "x<EOF>");
16552 assert!(
16553 actions.is_empty(),
16554 "action_index=None transitions are ANTLR metadata, not replay actions"
16555 );
16556 assert_eq!(parser.number_of_syntax_errors(), 0);
16557 }
16558
16559 #[test]
16560 fn parser_exposes_buffered_token_stream_after_parse() {
16561 let atn = token_then_eof_atn();
16562 let mut parser = mini_parser(vec![
16563 TestToken::new(1).with_text("x"),
16564 TestToken::eof("parser-test", 1, 1, 1),
16565 ]);
16566
16567 let tree = parser
16568 .parse_atn_rule(&atn, 0)
16569 .expect("artificial parser rule should parse");
16570 assert_eq!(parser.node(tree).text(), "x<EOF>");
16571
16572 let stream = parser.token_stream();
16573 let source_index_after_parse = stream.token_source().index;
16574 let buffered = stream.tokens().collect::<Vec<_>>();
16575 assert_eq!(buffered.len(), 2);
16576 assert_eq!(buffered[0].text(), Some("x"));
16577 assert_eq!(buffered[0].token_id().index(), 0);
16578 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
16579 assert_eq!(stream.token_source().index, source_index_after_parse);
16580 drop(buffered);
16581
16582 let stream = parser.into_token_stream();
16583 assert_eq!(stream.token_source().index, source_index_after_parse);
16584 assert_eq!(
16585 stream.tokens().next().expect("first token").text(),
16586 Some("x")
16587 );
16588 assert_eq!(
16589 stream.tokens().nth(1).expect("EOF token").token_type(),
16590 TOKEN_EOF
16591 );
16592 }
16593
16594 #[test]
16595 fn parsed_file_exposes_all_buffered_tokens() {
16596 let atn = token_then_eof_atn();
16597 let mut parser = mini_parser(vec![
16598 TestToken::new(99)
16599 .with_text(" comment")
16600 .with_channel(HIDDEN_CHANNEL),
16601 TestToken::new(1).with_text("x"),
16602 TestToken::eof("parser-test", 9, 1, 9),
16603 ]);
16604
16605 let tree = parser
16606 .parse_atn_rule(&atn, 0)
16607 .expect("artificial parser rule should parse");
16608 let parsed = parser.into_parsed_file(tree);
16609
16610 insta::assert_debug_snapshot!(
16613 "parsed_file_exposes_all_buffered_tokens",
16614 parsed
16615 .tokens()
16616 .iter()
16617 .map(|token| (token.token_type(), token.channel(), token.text()))
16618 .collect::<Vec<_>>()
16619 );
16620 assert_eq!(parsed.tokens().into_iter().count(), 3);
16621 }
16622
16623 #[test]
16624 fn parser_syntax_error_count_tracks_interpreted_recovery() {
16625 let atn = token_then_eof_atn();
16626 let mut parser = mini_parser(vec![
16627 TestToken::new(1).with_text("x"),
16628 TestToken::new(2).with_text("y"),
16629 TestToken::eof("parser-test", 2, 1, 2),
16630 ]);
16631
16632 let tree = parser
16633 .parse_atn_rule(&atn, 0)
16634 .expect("invalid token should recover into an error node");
16635
16636 assert_eq!(parser.number_of_syntax_errors(), 1);
16637 assert_eq!(
16638 parser
16639 .node(tree)
16640 .first_error_token()
16641 .expect("recovery should embed an error token")
16642 .text(),
16643 Some("y")
16644 );
16645 }
16646
16647 #[test]
16648 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
16649 let atn = token_then_eof_atn();
16650 let mut parser = mini_parser(vec![
16651 TestToken::new(2).with_text("y"),
16652 TestToken::eof("parser-test", 1, 1, 1),
16653 ]);
16654
16655 let error = parser
16656 .parse_atn_rule(&atn, 0)
16657 .expect_err("start-rule mismatch should remain a parser error");
16658
16659 assert_eq!(parser.number_of_syntax_errors(), 1);
16660 assert!(matches!(error, AntlrError::ParserError { .. }));
16661 }
16662
16663 #[test]
16664 fn adaptive_direct_rule_uses_simulator_decision() {
16665 let atn = two_alt_decision_atn();
16666 let mut simulator = ParserAtnSimulator::new(&atn);
16667 let mut parser = mini_parser(vec![
16668 TestToken::new(2).with_text("y"),
16669 TestToken::eof("parser-test", 1, 1, 1),
16670 ]);
16671
16672 let tree = parser
16673 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
16674 .expect("direct adaptive rule should parse");
16675
16676 assert_eq!(parser.node(tree).text(), "y");
16677 assert_eq!(parser.input.index(), 1);
16678 }
16679
16680 #[test]
16681 fn adaptive_direct_rule_restores_input_on_fallback() {
16682 let atn = predicate_after_token_atn();
16683 let mut simulator = ParserAtnSimulator::new(&atn);
16684 let mut parser = mini_parser(vec![
16685 TestToken::new(1).with_text("x"),
16686 TestToken::new(2).with_text("y"),
16687 TestToken::eof("parser-test", 2, 1, 2),
16688 ]);
16689
16690 let tree = parser
16691 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
16692 .expect("fallback recognizer should parse");
16693
16694 assert_eq!(parser.node(tree).text(), "xy");
16695 assert_eq!(parser.input.index(), 2);
16696 let stats = parser.parse_tree_storage().stats();
16697 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
16698 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
16699 assert_eq!(stats.scratch_links, 0);
16700 }
16701
16702 #[test]
16703 fn unknown_predicate_policy_defaults_to_assume_true() {
16704 let atn = predicate_after_token_atn();
16705 let mut parser = mini_parser(vec![
16706 TestToken::new(1).with_text("x"),
16707 TestToken::new(2).with_text("y"),
16708 TestToken::eof("parser-test", 2, 1, 2),
16709 ]);
16710
16711 let (tree, _) = parser
16712 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16713 .expect("unknown predicate should pass under the default policy");
16714
16715 assert_eq!(parser.node(tree).text(), "xy");
16716 assert_eq!(parser.number_of_syntax_errors(), 0);
16717 }
16718
16719 #[test]
16720 fn private_context_alt_tracking_keeps_fast_predicate_recognition() {
16721 let atn = predicate_gated_same_lookahead_atn([0, 1]);
16722 let mut parser = mini_parser(vec![
16723 TestToken::new(1).with_text("x"),
16724 TestToken::eof("parser-test", 1, 1, 1),
16725 ]);
16726
16727 let (tree, _) = parser
16728 .parse_atn_rule_with_runtime_options(
16729 &atn,
16730 0,
16731 ParserRuntimeOptions {
16732 predicates: &[
16733 (0, 0, ParserPredicate::False),
16734 (0, 1, ParserPredicate::True),
16735 ],
16736 track_context_alt_numbers: true,
16737 ..ParserRuntimeOptions::default()
16738 },
16739 )
16740 .expect("the second predicate-gated alternative should match");
16741
16742 let root = parser.node(tree).as_rule().expect("entry result is a rule");
16743 insta::assert_debug_snapshot!(
16744 "private_context_alt_tracking_keeps_fast_predicate_recognition",
16745 (root.alt_number(), root.context_alt_number(), root.text())
16746 );
16747 assert_eq!(parser.number_of_syntax_errors(), 0);
16748 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
16749 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
16750 }
16751
16752 #[test]
16753 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
16754 let atn = token_then_eof_atn();
16758 let mut parser = mini_parser(vec![
16759 TestToken::new(1).with_text("x"),
16760 TestToken::eof("parser-test", 1, 1, 1),
16761 ]);
16762
16763 parser.unknown_predicate_hits.push((7, 3));
16765
16766 parser
16768 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16769 .expect("child rule parses");
16770
16771 let error = parser
16773 .take_unknown_semantic_error()
16774 .expect("parent's recorded coordinate must survive the nested interpreted parse");
16775 let AntlrError::Unsupported(message) = error else {
16776 panic!("expected AntlrError::Unsupported, got {error:?}");
16777 };
16778 assert!(message.contains("pred_index=3"), "message: {message}");
16779 }
16780
16781 #[test]
16782 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
16783 let atn = predicate_after_token_atn();
16784 let mut parser = mini_parser(vec![
16785 TestToken::new(1).with_text("x"),
16786 TestToken::new(2).with_text("y"),
16787 TestToken::eof("parser-test", 2, 1, 2),
16788 ]);
16789
16790 let result = parser.parse_atn_rule_with_runtime_options(
16791 &atn,
16792 0,
16793 ParserRuntimeOptions {
16794 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
16795 ..ParserRuntimeOptions::default()
16796 },
16797 );
16798
16799 assert!(
16800 result.is_err(),
16801 "the only path is predicate-guarded, so assume-false must fail the parse"
16802 );
16803 }
16804
16805 #[test]
16806 fn predicate_failure_message_keeps_semantic_recovery_path() {
16807 let atn = predicate_after_token_atn();
16808 let mut parser = mini_parser(vec![
16809 TestToken::new(1).with_text("x"),
16810 TestToken::new(2).with_text("y"),
16811 TestToken::eof("parser-test", 2, 1, 2),
16812 ]);
16813
16814 let (tree, _) = parser
16815 .parse_atn_rule_with_runtime_options(
16816 &atn,
16817 0,
16818 ParserRuntimeOptions {
16819 predicates: &[(
16820 0,
16821 0,
16822 ParserPredicate::FalseWithMessage {
16823 message: "predicate rejected input",
16824 },
16825 )],
16826 ..ParserRuntimeOptions::default()
16827 },
16828 )
16829 .expect("failure-message predicates recover through the semantic interpreter");
16830
16831 assert_eq!(parser.node(tree).text(), "xy");
16832 assert_eq!(parser.number_of_syntax_errors(), 1);
16833 assert!(
16834 parser.fast_predicate_cache.is_empty(),
16835 "failure-message predicates need the semantic interpreter's recovery outcome"
16836 );
16837 }
16838
16839 #[test]
16840 fn unknown_predicate_policy_error_names_the_coordinate() {
16841 let atn = predicate_after_token_atn();
16842 let mut parser = mini_parser(vec![
16843 TestToken::new(1).with_text("x"),
16844 TestToken::new(2).with_text("y"),
16845 TestToken::eof("parser-test", 2, 1, 2),
16846 ]);
16847
16848 let error = parser
16849 .parse_atn_rule_with_runtime_options(
16850 &atn,
16851 0,
16852 ParserRuntimeOptions {
16853 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16854 ..ParserRuntimeOptions::default()
16855 },
16856 )
16857 .expect_err("evaluating an unknown predicate under Error policy must fail");
16858
16859 let AntlrError::Unsupported(message) = error else {
16860 panic!("expected AntlrError::Unsupported, got {error:?}");
16861 };
16862 assert!(
16863 message.contains("unsupported semantic predicate"),
16864 "message should name the failure class: {message}"
16865 );
16866 assert!(
16867 message.contains("pred_index=0"),
16868 "message should carry the coordinate: {message}"
16869 );
16870 }
16871
16872 #[test]
16873 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
16874 let atn = predicate_after_token_atn();
16880 let mut parser = mini_parser(vec![
16881 TestToken::new(1).with_text("x"),
16882 TestToken::new(2).with_text("y"),
16883 TestToken::eof("parser-test", 2, 1, 2),
16884 ]);
16885
16886 parser
16887 .parse_atn_rule_with_runtime_options(
16888 &atn,
16889 0,
16890 ParserRuntimeOptions {
16891 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16892 ..ParserRuntimeOptions::default()
16893 },
16894 )
16895 .expect_err("first parse fails loud under the Error policy");
16896
16897 parser.reset_unknown_semantic_hits();
16902 assert!(
16903 parser.take_unknown_semantic_error().is_none(),
16904 "reset must drop stale unknown-predicate coordinates before a reused parse"
16905 );
16906 }
16907
16908 #[derive(Debug, Default)]
16909 struct RecordingHooks {
16910 predicates: Vec<(usize, usize, usize, Option<String>)>,
16911 actions: Vec<(usize, String, Option<String>)>,
16912 action_trees: Vec<Option<String>>,
16913 }
16914
16915 impl SemanticHooks for RecordingHooks {
16916 fn sempred<S>(
16917 &mut self,
16918 ctx: &mut ParserSemCtx<'_, S>,
16919 rule_index: usize,
16920 pred_index: usize,
16921 ) -> Option<bool>
16922 where
16923 S: TokenSource,
16924 {
16925 self.predicates.push((
16926 ctx.input_index(),
16927 rule_index,
16928 pred_index,
16929 ctx.token_text(1)
16930 .and_then(|token| token.text().map(str::to_owned)),
16931 ));
16932 Some(true)
16933 }
16934
16935 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
16936 where
16937 S: TokenSource,
16938 {
16939 self.actions.push((
16940 action.source_state(),
16941 ctx.action_text(),
16942 ctx.rule_name().map(str::to_owned),
16943 ));
16944 self.action_trees.push(ctx.tree().map(Node::text));
16945 true
16946 }
16947 }
16948
16949 #[derive(Debug, Default)]
16950 struct RejectingPredicateHooks {
16951 predicates: Vec<(usize, usize, usize, Option<String>)>,
16952 }
16953
16954 impl SemanticHooks for RejectingPredicateHooks {
16955 fn sempred<S>(
16956 &mut self,
16957 ctx: &mut ParserSemCtx<'_, S>,
16958 rule_index: usize,
16959 pred_index: usize,
16960 ) -> Option<bool>
16961 where
16962 S: TokenSource,
16963 {
16964 self.predicates.push((
16965 ctx.input_index(),
16966 rule_index,
16967 pred_index,
16968 ctx.token_text(1)
16969 .and_then(|token| token.text().map(str::to_owned)),
16970 ));
16971 Some(false)
16972 }
16973 }
16974
16975 #[test]
16976 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
16977 let atn = predicate_gated_same_lookahead_atn([0, 0]);
16978 let mut parser = mini_parser_with_hooks(
16979 vec![
16980 TestToken::new(1).with_text("x"),
16981 TestToken::eof("parser-test", 1, 1, 1),
16982 ],
16983 RecordingHooks::default(),
16984 );
16985
16986 let (tree, _) = parser
16987 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16988 .expect("both alternatives share one replay-safe predicate result");
16989
16990 assert_eq!(parser.node(tree).text(), "x<EOF>");
16991 assert_eq!(
16992 parser.semantic_hooks.predicates,
16993 vec![(0, 0, 0, Some("x".to_owned()))]
16994 );
16995 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
16996 }
16997
16998 #[test]
16999 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
17000 let atn = predicate_after_token_atn();
17001 let mut parser = mini_parser_with_hooks(
17002 vec![
17003 TestToken::new(1).with_text("x"),
17004 TestToken::new(2).with_text("y"),
17005 TestToken::eof("parser-test", 2, 1, 2),
17006 ],
17007 RecordingHooks::default(),
17008 );
17009
17010 let (tree, _) = parser
17011 .parse_atn_rule_with_runtime_options(
17012 &atn,
17013 0,
17014 ParserRuntimeOptions {
17015 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17016 ..ParserRuntimeOptions::default()
17017 },
17018 )
17019 .expect("hook supplies the missing predicate result");
17020
17021 assert_eq!(parser.node(tree).text(), "xy");
17022 assert_eq!(
17023 parser.semantic_hooks.predicates,
17024 vec![(1, 0, 0, Some("y".to_owned()))]
17025 );
17026 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
17027 }
17028
17029 #[test]
17030 fn runtime_options_default_preserves_semantic_hook_predicates() {
17031 let atn = predicate_after_token_atn();
17032 let mut parser = mini_parser_with_hooks(
17033 vec![
17034 TestToken::new(1).with_text("x"),
17035 TestToken::new(2).with_text("y"),
17036 TestToken::eof("parser-test", 2, 1, 2),
17037 ],
17038 RejectingPredicateHooks::default(),
17039 );
17040
17041 let result =
17042 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
17043
17044 assert!(
17045 result.is_err(),
17046 "default runtime options must not bypass semantic hooks for predicate ATNs"
17047 );
17048 assert_eq!(
17049 parser.semantic_hooks.predicates,
17050 vec![(1, 0, 0, Some("y".to_owned()))]
17051 );
17052 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
17053 }
17054
17055 #[test]
17056 fn semantic_hook_handles_committed_parser_action() {
17057 let atn = token_then_eof_atn();
17058 let mut parser = mini_parser_with_hooks(
17059 vec![
17060 TestToken::new(1).with_text("x"),
17061 TestToken::eof("parser-test", 1, 1, 1),
17062 ],
17063 RecordingHooks::default(),
17064 );
17065 let (tree, _) = parser
17066 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17067 .expect("rule parses before action hook is tested");
17068
17069 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17070 assert_eq!(
17071 parser.semantic_hooks.actions,
17072 vec![(42, "x".to_owned(), Some("s".to_owned()))]
17073 );
17074 assert_eq!(
17075 parser.semantic_hooks.action_trees,
17076 [Some("x<EOF>".to_owned())]
17077 );
17078 }
17079
17080 #[test]
17081 fn unhandled_committed_action_fails_loud_under_error_policy() {
17082 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17086 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
17087 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
17088
17089 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17091
17092 let error = parser
17093 .take_unknown_semantic_error()
17094 .expect("an unhandled committed action under Error policy must fail loud");
17095 let AntlrError::Unsupported(message) = error else {
17096 panic!("expected AntlrError::Unsupported, got {error:?}");
17097 };
17098 assert!(
17099 message.contains("unhandled semantic action") && message.contains("state=42"),
17100 "message should name the dropped action coordinate: {message}"
17101 );
17102
17103 let mut lenient =
17105 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17106 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
17107 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17108 assert!(lenient.take_unknown_semantic_error().is_none());
17109 }
17110
17111 #[test]
17112 fn translated_predicate_is_unaffected_by_error_policy() {
17113 let atn = predicate_after_token_atn();
17114 let mut parser = mini_parser(vec![
17115 TestToken::new(1).with_text("x"),
17116 TestToken::new(2).with_text("y"),
17117 TestToken::eof("parser-test", 2, 1, 2),
17118 ]);
17119
17120 let (tree, _) = parser
17121 .parse_atn_rule_with_runtime_options(
17122 &atn,
17123 0,
17124 ParserRuntimeOptions {
17125 predicates: &[(0, 0, ParserPredicate::True)],
17126 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17127 ..ParserRuntimeOptions::default()
17128 },
17129 )
17130 .expect("a predicate covered by the table is not an unknown coordinate");
17131
17132 assert_eq!(parser.node(tree).text(), "xy");
17133 }
17134
17135 fn hook_predicate_semantics() -> ParserSemantics {
17140 let mut ir = SemIr::new();
17141 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
17142 ParserSemantics {
17143 ir,
17144 predicates: vec![ParserSemanticPredicate {
17145 rule_index: 0,
17146 pred_index: 0,
17147 expr,
17148 failure_message: None,
17149 }],
17150 actions: Vec::new(),
17151 }
17152 }
17153
17154 #[derive(Debug, Default)]
17155 struct DecliningHooks;
17156
17157 impl SemanticHooks for DecliningHooks {}
17158
17159 #[test]
17160 fn semir_hook_none_falls_through_to_assume_true() {
17161 let atn = predicate_after_token_atn();
17162 let semantics = hook_predicate_semantics();
17163 let mut parser = mini_parser_with_hooks(
17164 vec![
17165 TestToken::new(1).with_text("x"),
17166 TestToken::new(2).with_text("y"),
17167 TestToken::eof("parser-test", 2, 1, 2),
17168 ],
17169 DecliningHooks,
17170 );
17171
17172 let (tree, _) = parser
17173 .parse_atn_rule_with_runtime_options(
17174 &atn,
17175 0,
17176 ParserRuntimeOptions {
17177 semantics: Some(&semantics),
17178 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
17179 ..ParserRuntimeOptions::default()
17180 },
17181 )
17182 .expect("a declined SemIR hook must pass under assume-true");
17183
17184 assert_eq!(parser.node(tree).text(), "xy");
17185 }
17186
17187 #[test]
17188 fn semir_hook_none_falls_through_to_assume_false() {
17189 let atn = predicate_after_token_atn();
17190 let semantics = hook_predicate_semantics();
17191 let mut parser = mini_parser_with_hooks(
17192 vec![
17193 TestToken::new(1).with_text("x"),
17194 TestToken::new(2).with_text("y"),
17195 TestToken::eof("parser-test", 2, 1, 2),
17196 ],
17197 DecliningHooks,
17198 );
17199
17200 let result = parser.parse_atn_rule_with_runtime_options(
17201 &atn,
17202 0,
17203 ParserRuntimeOptions {
17204 semantics: Some(&semantics),
17205 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
17206 ..ParserRuntimeOptions::default()
17207 },
17208 );
17209
17210 assert!(
17211 result.is_err(),
17212 "a declined SemIR hook must fail the only guarded path under assume-false"
17213 );
17214 }
17215
17216 #[test]
17217 fn semir_hook_none_records_coordinate_under_error_policy() {
17218 let atn = predicate_after_token_atn();
17219 let semantics = hook_predicate_semantics();
17220 let mut parser = mini_parser_with_hooks(
17221 vec![
17222 TestToken::new(1).with_text("x"),
17223 TestToken::new(2).with_text("y"),
17224 TestToken::eof("parser-test", 2, 1, 2),
17225 ],
17226 DecliningHooks,
17227 );
17228
17229 let error = parser
17230 .parse_atn_rule_with_runtime_options(
17231 &atn,
17232 0,
17233 ParserRuntimeOptions {
17234 semantics: Some(&semantics),
17235 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17236 ..ParserRuntimeOptions::default()
17237 },
17238 )
17239 .expect_err("a declined SemIR hook under Error policy must fail the parse");
17240
17241 let AntlrError::Unsupported(message) = error else {
17242 panic!("expected AntlrError::Unsupported, got {error:?}");
17243 };
17244 assert!(
17245 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
17246 "message should name the unresolved coordinate: {message}"
17247 );
17248 }
17249
17250 #[test]
17251 fn generated_direct_predicate_honors_installed_policy() {
17252 let semantics = hook_predicate_semantics();
17258 let context = ParserRuleContext::new(0, -1);
17259
17260 let mut assume_true =
17261 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17262 assert!(
17263 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
17264 &semantics, 0, 0, &context, 0
17265 ),
17266 "default AssumeTrue accepts a declined hook"
17267 );
17268 assert!(assume_true.take_unknown_semantic_error().is_none());
17269
17270 let mut error_policy =
17271 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17272 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
17273 assert!(
17274 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
17275 &semantics, 0, 0, &context, 0
17276 ),
17277 "Error policy rejects a declined hook on the generated-direct path"
17278 );
17279 let error = error_policy
17280 .take_unknown_semantic_error()
17281 .expect("Error policy records the unresolved coordinate for the generated path");
17282 let AntlrError::Unsupported(message) = error else {
17283 panic!("expected AntlrError::Unsupported, got {error:?}");
17284 };
17285 assert!(message.contains("pred_index=0"), "message: {message}");
17286 }
17287
17288 #[test]
17289 fn parser_rule_start_skips_leading_hidden_tokens() {
17290 let atn = token_then_eof_atn();
17291 let mut parser = mini_parser(vec![
17292 TestToken::new(99)
17293 .with_text(" ")
17294 .with_channel(HIDDEN_CHANNEL),
17295 TestToken::new(1).with_text("x"),
17296 TestToken::eof("parser-test", 2, 1, 2),
17297 ]);
17298
17299 let tree = parser
17300 .parse_atn_rule(&atn, 0)
17301 .expect("artificial parser rule should parse");
17302 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
17303 panic!("rule node should be present");
17304 };
17305 assert_eq!(
17306 rule.start()
17307 .expect("rule should have a start token")
17308 .token_type(),
17309 1
17310 );
17311 }
17312
17313 #[test]
17314 fn parser_action_after_eof_stops_at_eof_token() {
17315 let atn = eof_then_action_atn();
17316 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
17317
17318 let (_, actions) = parser
17319 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17320 .expect("EOF action rule should parse");
17321
17322 assert_eq!(actions.len(), 1);
17323 assert_eq!(actions[0].stop_index(), Some(0));
17324 assert_eq!(
17325 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
17326 ""
17327 );
17328 }
17329
17330 #[test]
17331 fn after_action_stop_uses_rule_context_stop_not_cursor() {
17332 let mut id = TestToken::new(1).with_text("x");
17337 id.set_token_index(0);
17338 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
17339 eof.set_token_index(1);
17340 let mut parser = mini_parser(vec![id.clone(), eof]);
17341 parser.consume();
17343 assert_eq!(parser.la(1), TOKEN_EOF);
17344
17345 let mut ctx = ParserRuleContext::new(0, 0);
17348 parser.set_context_stop(
17349 &mut ctx,
17350 parser.token_id_at(0).expect("ID token should be buffered"),
17351 );
17352 let tree = parser.rule_node(ctx);
17353
17354 let current_index = parser.input.index();
17355 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
17357 assert_eq!(
17359 parser.after_action_stop_index_for_tree(tree, current_index),
17360 Some(0)
17361 );
17362 }
17363
17364 #[test]
17365 fn after_action_start_uses_rule_context_start_not_cursor() {
17366 let mut parser = mini_parser(vec![
17371 TestToken::new(9)
17372 .with_text(" ")
17373 .with_channel(HIDDEN_CHANNEL),
17374 TestToken::new(9)
17375 .with_text(" ")
17376 .with_channel(HIDDEN_CHANNEL),
17377 TestToken::new(1).with_text("x"),
17378 TestToken::eof("parser-test", 3, 1, 3),
17379 ]);
17380
17381 let mut ctx = ParserRuleContext::new(0, 0);
17382 parser.set_context_start(
17383 &mut ctx,
17384 parser.token_id_at(2).expect("ID token should be buffered"),
17385 );
17386 let tree = parser.rule_node(ctx);
17387
17388 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
17391
17392 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
17394 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
17395 }
17396
17397 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
17398 FastRecognizeOutcome {
17399 index,
17400 consumed_eof,
17401 diagnostics: DiagnosticSeqId::EMPTY,
17402 deferred_nodes: FastDeferredNodeId::EMPTY,
17403 nodes: NodeSeqId(marker),
17404 }
17405 }
17406
17407 #[test]
17408 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
17409 let mut outcomes = vec![
17410 clean_fast_outcome(4, false, 0),
17411 clean_fast_outcome(2, false, 1),
17412 clean_fast_outcome(4, false, 2),
17413 clean_fast_outcome(4, true, 3),
17414 clean_fast_outcome(2, false, 4),
17415 ];
17416 let mut scratch = FastOutcomeDedupScratch::default();
17417
17418 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17419
17420 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
17421 assert_eq!(
17422 outcomes
17423 .iter()
17424 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
17425 .collect::<Vec<_>>(),
17426 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
17427 );
17428 assert!(scratch.dense_words.is_empty());
17429 assert!(scratch.sparse_keys.is_empty());
17430 }
17431
17432 #[test]
17433 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
17434 let mut scratch = FastOutcomeDedupScratch::default();
17435 let mut outcomes = (100..109)
17436 .flat_map(|index| {
17437 [
17438 clean_fast_outcome(
17439 index,
17440 false,
17441 u32::try_from(index).expect("test index fits in u32"),
17442 ),
17443 clean_fast_outcome(index, false, u32::MAX),
17444 ]
17445 })
17446 .collect();
17447
17448 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17449
17450 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
17451 assert_eq!(outcomes.len(), 9);
17452 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
17453 let dense_capacity = scratch.dense_words.capacity();
17454
17455 let mut reused = (1_000..1_009)
17456 .map(|index| {
17457 clean_fast_outcome(
17458 index,
17459 false,
17460 u32::try_from(index).expect("test index fits in u32"),
17461 )
17462 })
17463 .collect();
17464 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
17465
17466 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
17467 assert_eq!(reused.len(), 9);
17468 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
17469 }
17470
17471 #[test]
17472 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
17473 let mut scratch = FastOutcomeDedupScratch::default();
17474 let sparse_indexes = [
17475 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
17476 ];
17477 let mut outcomes = sparse_indexes
17478 .into_iter()
17479 .chain([400_000])
17480 .enumerate()
17481 .map(|(marker, index)| {
17482 clean_fast_outcome(
17483 index,
17484 false,
17485 u32::try_from(marker).expect("test marker fits in u32"),
17486 )
17487 })
17488 .collect();
17489
17490 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17491
17492 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
17493 assert_eq!(outcomes.len(), sparse_indexes.len());
17494 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
17495 let sparse_capacity = scratch.sparse_keys.capacity();
17496
17497 let mut reused = sparse_indexes
17498 .into_iter()
17499 .map(|index| {
17500 clean_fast_outcome(
17501 index,
17502 false,
17503 u32::try_from(index).expect("test index fits in u32"),
17504 )
17505 })
17506 .collect();
17507 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
17508
17509 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
17510 assert_eq!(reused.len(), sparse_indexes.len());
17511 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
17512 }
17513
17514 #[test]
17515 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
17516 let mut scratch = FastOutcomeDedupScratch::default();
17517 scratch
17518 .sparse_keys
17519 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
17520 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
17521 let mut outcomes = (0..9)
17522 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
17523 .collect();
17524
17525 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17526
17527 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
17528 assert!(scratch.sparse_keys.is_empty());
17529 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
17530 }
17531
17532 #[test]
17533 fn fast_outcome_selection_respects_sll_tie_order() {
17534 let mut arena = RecognitionArena::default();
17535 let first = FastRecognizeOutcome {
17536 index: 1,
17537 consumed_eof: false,
17538 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17539 line: 1,
17540 column: 0,
17541 message: "mismatched input 'x'".to_owned(),
17542 }]),
17543 deferred_nodes: FastDeferredNodeId::EMPTY,
17544 nodes: NodeSeqId::EMPTY,
17545 };
17546 let second = FastRecognizeOutcome {
17547 index: first.index,
17548 consumed_eof: first.consumed_eof,
17549 diagnostics: DiagnosticSeqId::EMPTY,
17550 deferred_nodes: FastDeferredNodeId::EMPTY,
17551 nodes: NodeSeqId::EMPTY,
17552 };
17553
17554 let selected = select_best_fast_outcome(
17555 [first, second].into_iter(),
17556 PredictionMode::Sll,
17557 None,
17558 |_| panic!("caller-follow token probe should not run"),
17559 &arena,
17560 )
17561 .expect("one outcome should be selected");
17562 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
17563 let eof_second = FastRecognizeOutcome {
17564 index: second.index,
17565 consumed_eof: true,
17566 diagnostics: DiagnosticSeqId::EMPTY,
17567 deferred_nodes: FastDeferredNodeId::EMPTY,
17568 nodes: NodeSeqId::EMPTY,
17569 };
17570 let selected = select_best_fast_outcome(
17571 [first, eof_second].into_iter(),
17572 PredictionMode::Sll,
17573 None,
17574 |_| panic!("caller-follow token probe should not run"),
17575 &arena,
17576 )
17577 .expect("one outcome should be selected");
17578 assert!(!selected.consumed_eof);
17579 let selected = select_best_fast_outcome(
17580 [first, second].into_iter(),
17581 PredictionMode::Ll,
17582 None,
17583 |_| panic!("caller-follow token probe should not run"),
17584 &arena,
17585 )
17586 .expect("one outcome should be selected");
17587 assert!(selected.diagnostics.is_empty());
17588 }
17589
17590 #[test]
17591 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
17592 let mut arena = RecognitionArena::default();
17593 let first = FastRecognizeOutcome {
17594 index: 3,
17595 consumed_eof: false,
17596 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17597 line: 1,
17598 column: 0,
17599 message: "mismatched input 'x' expecting 'a'".to_owned(),
17600 }]),
17601 deferred_nodes: FastDeferredNodeId::EMPTY,
17602 nodes: NodeSeqId::EMPTY,
17603 };
17604 let same_rank = FastRecognizeOutcome {
17605 index: first.index,
17606 consumed_eof: first.consumed_eof,
17607 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17608 line: 1,
17609 column: 0,
17610 message: "mismatched input 'x' expecting 'b'".to_owned(),
17611 }]),
17612 deferred_nodes: FastDeferredNodeId::EMPTY,
17613 nodes: NodeSeqId::EMPTY,
17614 };
17615 let better_rank = FastRecognizeOutcome {
17616 index: first.index,
17617 consumed_eof: first.consumed_eof,
17618 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17619 line: 1,
17620 column: 0,
17621 message: "missing 'a' at 'x'".to_owned(),
17622 }]),
17623 deferred_nodes: FastDeferredNodeId::EMPTY,
17624 nodes: NodeSeqId::EMPTY,
17625 };
17626 let mut outcomes = vec![first, same_rank, better_rank];
17627
17628 dedupe_fast_outcomes(&mut outcomes, &arena);
17629
17630 assert_eq!(outcomes.len(), 2);
17631 assert_eq!(
17632 arena
17633 .diagnostics(outcomes[0].diagnostics)
17634 .next()
17635 .expect("first diagnostic")
17636 .message,
17637 "mismatched input 'x' expecting 'a'"
17638 );
17639 assert_eq!(
17640 arena
17641 .diagnostics(outcomes[1].diagnostics)
17642 .next()
17643 .expect("second diagnostic")
17644 .message,
17645 "missing 'a' at 'x'"
17646 );
17647 }
17648
17649 #[test]
17650 fn fast_outcome_selection_prefers_generated_caller_follow() {
17651 let arena = RecognitionArena::default();
17652 let earlier = FastRecognizeOutcome {
17653 index: 7,
17654 consumed_eof: false,
17655 diagnostics: DiagnosticSeqId::EMPTY,
17656 deferred_nodes: FastDeferredNodeId::EMPTY,
17657 nodes: NodeSeqId::EMPTY,
17658 };
17659 let later = FastRecognizeOutcome {
17660 index: 8,
17661 consumed_eof: false,
17662 diagnostics: DiagnosticSeqId::EMPTY,
17663 deferred_nodes: FastDeferredNodeId::EMPTY,
17664 nodes: NodeSeqId::EMPTY,
17665 };
17666 let mut follow = TokenBitSet::default();
17667 follow.insert(5);
17668
17669 let selected = select_best_fast_outcome(
17670 [later, earlier].into_iter(),
17671 PredictionMode::Ll,
17672 Some(&follow),
17673 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
17674 &arena,
17675 )
17676 .expect("one outcome should be selected");
17677 assert_eq!(selected.index, 7);
17678
17679 let selected = select_best_fast_outcome(
17680 [later, earlier].into_iter(),
17681 PredictionMode::Ll,
17682 Some(&follow),
17683 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
17684 &arena,
17685 )
17686 .expect("one outcome should be selected");
17687 assert_eq!(selected.index, 8);
17688
17689 let indented_next_statement = FastRecognizeOutcome {
17690 index: 9,
17691 consumed_eof: false,
17692 diagnostics: DiagnosticSeqId::EMPTY,
17693 deferred_nodes: FastDeferredNodeId::EMPTY,
17694 nodes: NodeSeqId::EMPTY,
17695 };
17696 let selected = select_best_fast_outcome(
17697 [indented_next_statement, earlier].into_iter(),
17698 PredictionMode::Ll,
17699 Some(&follow),
17700 |index| {
17701 let is_boundary = index == 7;
17702 let is_boundary_gap = matches!(index, 7 | 8);
17703 (
17704 if index == 7 { 5 } else { TOKEN_EOF },
17705 is_boundary,
17706 is_boundary_gap,
17707 )
17708 },
17709 &arena,
17710 )
17711 .expect("one outcome should be selected");
17712 assert_eq!(selected.index, 7);
17713
17714 let continuation = FastRecognizeOutcome {
17715 index: 10,
17716 consumed_eof: false,
17717 diagnostics: DiagnosticSeqId::EMPTY,
17718 deferred_nodes: FastDeferredNodeId::EMPTY,
17719 nodes: NodeSeqId::EMPTY,
17720 };
17721 let selected = select_best_fast_outcome(
17722 [continuation, earlier].into_iter(),
17723 PredictionMode::Ll,
17724 Some(&follow),
17725 |index| {
17726 let is_boundary = matches!(index, 7 | 9);
17727 (
17728 if index == 7 { 5 } else { TOKEN_EOF },
17729 is_boundary,
17730 is_boundary,
17731 )
17732 },
17733 &arena,
17734 )
17735 .expect("one outcome should be selected");
17736 assert_eq!(selected.index, 10);
17737
17738 let selected = select_best_fast_outcome(
17739 [earlier, later].into_iter(),
17740 PredictionMode::Sll,
17741 Some(&follow),
17742 |_| panic!("caller-follow token probe should not run in SLL mode"),
17743 &arena,
17744 )
17745 .expect("one outcome should be selected");
17746 assert_eq!(selected.index, 8);
17747 }
17748
17749 #[test]
17750 fn caller_follow_boundary_text_requires_separator_shape() {
17751 assert!(is_caller_follow_boundary_text(";"));
17752 assert!(is_caller_follow_boundary_text("\n"));
17753 assert!(is_caller_follow_boundary_text("\r\n "));
17754 assert!(is_caller_follow_boundary_text(";\n"));
17755 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
17756 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
17757 assert!(!is_caller_follow_boundary_text("identifier"));
17758 assert!(is_caller_follow_boundary_gap_text(" \t "));
17759 assert!(is_caller_follow_boundary_gap_text("\n "));
17760 assert!(is_caller_follow_boundary_gap_text(";\t"));
17761 assert!(!is_caller_follow_boundary_gap_text(
17762 "\"\"\"line1\nline2\"\"\""
17763 ));
17764 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
17765 }
17766
17767 #[test]
17768 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
17769 let mut parser = mini_parser(vec![
17770 TestToken::new(5).with_text("\n"),
17771 TestToken::new(6)
17772 .with_text("// comment\n")
17773 .with_channel(HIDDEN_CHANNEL),
17774 TestToken::new(1).with_text("x"),
17775 TestToken::eof("parser-test", 1, 2, 0),
17776 ]);
17777
17778 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
17779 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
17780 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
17781 }
17782
17783 #[test]
17784 fn caller_follow_token_info_uses_stream_visible_channel() {
17785 let source = Source {
17786 tokens: vec![
17787 TestToken::new(5).with_text("\n").with_channel(2),
17788 TestToken::new(1).with_text("x").with_channel(2),
17789 TestToken::new(6)
17790 .with_text("// comment\n")
17791 .with_channel(HIDDEN_CHANNEL),
17792 TestToken::eof("parser-test", 1, 2, 0),
17793 ],
17794 index: 0,
17795 };
17796 let data = RecognizerData::new(
17797 "Mini.g4",
17798 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17799 );
17800 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
17801
17802 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
17803 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
17804 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
17805 }
17806
17807 #[test]
17808 fn reset_per_parse_caches_clears_state_expected_token_cache() {
17809 let atn = token_then_eof_atn();
17810 let mut parser = mini_parser(Vec::new());
17811
17812 let _ = parser.cached_state_expected_token_set(&atn, 0);
17813 assert!(!parser.state_expected_token_cache.is_empty());
17814
17815 parser.reset_per_parse_caches();
17816 assert!(parser.state_expected_token_cache.is_empty());
17817 }
17818
17819 #[test]
17820 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
17821 let cyclic = epsilon_cycle_atn();
17822 let acyclic = token_then_eof_atn();
17823 let mut parser = mini_parser(Vec::new());
17824
17825 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
17826 assert_eq!(
17827 parser.empty_cycle_cache_atn,
17828 Some(SharedAtnCacheKey::for_atn(&cyclic))
17829 );
17830 assert_eq!(parser.empty_cycle_cache[1], Some(true));
17831
17832 parser.reset_per_parse_caches();
17833 assert_eq!(parser.empty_cycle_cache[1], Some(true));
17834 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
17835
17836 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
17837 assert_eq!(
17838 parser.empty_cycle_cache_atn,
17839 Some(SharedAtnCacheKey::for_atn(&acyclic))
17840 );
17841 assert_eq!(parser.empty_cycle_cache[1], Some(false));
17842 }
17843
17844 #[test]
17845 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
17846 let source = Source {
17847 tokens: vec![
17848 TestToken::new(1).with_text("x"),
17849 TestToken::eof("parser-test", 1, 1, 1),
17850 ],
17851 index: 0,
17852 };
17853 let data = RecognizerData::new(
17854 "Mini.g4",
17855 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17856 );
17857 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17858 let expected = ExpectedTokens {
17859 index: Some(0),
17860 symbols: BTreeSet::new(),
17861 no_viable: None,
17862 };
17863
17864 let (_, message) = parser.expected_error_message(0, 0, &expected);
17865
17866 assert_eq!(message, "mismatched input 'x'");
17867 }
17868
17869 #[test]
17870 fn eof_rule_stop_index_points_at_eof_token() {
17871 let source = Source {
17872 tokens: vec![
17873 TestToken::new(1).with_text("x"),
17874 TestToken::eof("parser-test", 1, 1, 1),
17875 ],
17876 index: 0,
17877 };
17878 let data = RecognizerData::new(
17879 "Mini.g4",
17880 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17881 );
17882 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17883
17884 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
17885 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
17886 }
17887
17888 #[test]
17889 fn generated_parser_action_uses_current_rule_stop_boundary() {
17890 let mut parser = mini_parser(vec![
17891 TestToken::new(1).with_text("x"),
17892 TestToken::eof("parser-test", 1, 1, 1),
17893 ]);
17894
17895 parser.match_token(1).expect("token should match");
17896 let action = parser.parser_action_at_current(7, 0, 0, false);
17897 assert_eq!(action.source_state(), 7);
17898 assert_eq!(action.rule_index(), 0);
17899 assert_eq!(action.start_index(), 0);
17900 assert_eq!(action.stop_index(), Some(0));
17901
17902 parser.match_eof().expect("EOF should match");
17903 let action = parser.parser_action_at_current(8, 0, 0, true);
17904 assert_eq!(action.stop_index(), Some(1));
17905 }
17906
17907 #[test]
17908 fn folds_left_recursive_boundary_into_rule_node() {
17909 let mut arena = RecognitionArena::default();
17910 let first = arena.push_node(ArenaRecognizedNode::Token {
17911 token: TokenId::try_from(0).expect("test token ID"),
17912 });
17913 let boundary = arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
17914 rule_index: 1,
17915 alt_number: 3,
17916 });
17917 let second = arena.push_node(ArenaRecognizedNode::Token {
17918 token: TokenId::try_from(1).expect("test token ID"),
17919 });
17920 let mut nodes = NodeSeqId::EMPTY;
17921 for node in [first, boundary, second].into_iter().rev() {
17922 nodes = arena.prepend(nodes, node);
17923 }
17924
17925 let folded = arena.fold_left_recursive_boundaries(nodes);
17926 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
17927
17928 assert_eq!(folded_nodes.len(), 2);
17929 let ArenaRecognizedNode::Rule {
17930 rule_index,
17931 invoking_state,
17932 alt_number,
17933 start_index,
17934 stop_index,
17935 children,
17936 ..
17937 } = arena.node(folded_nodes[0])
17938 else {
17939 panic!("first folded node should be a rule");
17940 };
17941 insta::assert_debug_snapshot!(
17945 "folds_left_recursive_boundary_into_rule_node",
17946 (
17947 rule_index,
17948 invoking_state,
17949 alt_number,
17950 start_index,
17951 stop_index
17952 )
17953 );
17954 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
17955 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
17956
17957 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
17958 assert_eq!(
17959 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17960 (4, 3, 1)
17961 );
17962 assert_eq!(
17963 (stats.total_links, stats.live_links, stats.dead_links),
17964 (9, 3, 6)
17965 );
17966 }
17967
17968 #[test]
17969 fn recognition_arena_reports_live_dead_and_retained_capacity() {
17970 let mut arena = RecognitionArena::default();
17971 let token = arena.push_node(ArenaRecognizedNode::Token {
17972 token: TokenId::try_from(0).expect("test token ID"),
17973 });
17974 let extra = arena.push_extra(RecognitionExtra::MissingToken {
17975 token_type: 2,
17976 at_index: 1,
17977 text: "<missing X>".to_owned(),
17978 });
17979 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
17980 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
17981 token: TokenId::try_from(1).expect("test token ID"),
17982 });
17983 let mut live = NodeSeqId::EMPTY;
17984 live = arena.prepend(live, missing);
17985 live = arena.prepend(live, token);
17986 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
17987 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17988 line: 1,
17989 column: 0,
17990 message: "missing X".to_owned(),
17991 }]);
17992 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17993 line: 1,
17994 column: 1,
17995 message: "discarded".to_owned(),
17996 }]);
17997 let deferred_children = arena.deferred_fragment(live);
17998 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
17999 rule_index: 0,
18000 invoking_state: -1,
18001 start_index: 0,
18002 stop_index: Some(1),
18003 deferred_children,
18004 children: NodeSeqId::EMPTY,
18005 });
18006
18007 let stats = arena.stats(live, live_diagnostics);
18008
18009 assert_eq!(
18010 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18011 (3, 2, 1)
18012 );
18013 assert_eq!(
18014 (stats.total_links, stats.live_links, stats.dead_links),
18015 (5, 3, 2)
18016 );
18017 assert_eq!(
18018 (stats.total_extras, stats.live_extras, stats.dead_extras),
18019 (3, 2, 1)
18020 );
18021 assert!(size_of::<SeqLink>() <= 8);
18022 assert!(size_of::<DiagnosticLink>() <= 8);
18023 assert!(size_of::<FastDeferredNode>() <= 12);
18024 assert!(size_of::<FastDeferredRule>() <= 28);
18025 assert!(size_of::<FastRecognizeOutcome>() <= 24);
18026 let capacities = (
18027 stats.node_capacity,
18028 stats.link_capacity,
18029 stats.extra_capacity,
18030 );
18031 let deferred_capacities = (
18032 arena.deferred_nodes.capacity(),
18033 arena.deferred_rules.capacity(),
18034 );
18035
18036 arena.reset();
18037 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
18038 assert_eq!(
18039 (reset.total_nodes, reset.total_links, reset.total_extras),
18040 (0, 0, 0)
18041 );
18042 assert_eq!(
18043 (
18044 reset.node_capacity,
18045 reset.link_capacity,
18046 reset.extra_capacity,
18047 ),
18048 capacities
18049 );
18050 assert!(arena.deferred_nodes.is_empty());
18051 assert!(arena.deferred_rules.is_empty());
18052 assert_eq!(
18053 (
18054 arena.deferred_nodes.capacity(),
18055 arena.deferred_rules.capacity(),
18056 ),
18057 deferred_capacities
18058 );
18059 }
18060
18061 #[test]
18062 fn parser_computes_recognition_arena_stats_on_demand() {
18063 let mut parser = mini_parser(Vec::new());
18064 let live = parser
18065 .recognition_arena
18066 .push_node(ArenaRecognizedNode::Token {
18067 token: TokenId::try_from(0).expect("test token ID"),
18068 });
18069 let discarded = parser
18070 .recognition_arena
18071 .push_node(ArenaRecognizedNode::ErrorToken {
18072 token: TokenId::try_from(1).expect("test token ID"),
18073 });
18074 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
18075 let _discarded_root = parser
18076 .recognition_arena
18077 .prepend(NodeSeqId::EMPTY, discarded);
18078 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
18079
18080 let stats = parser.recognition_arena_stats();
18081
18082 assert_eq!(
18083 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18084 (2, 1, 1)
18085 );
18086 assert_eq!(
18087 (stats.total_links, stats.live_links, stats.dead_links),
18088 (2, 1, 1)
18089 );
18090 }
18091
18092 #[test]
18093 fn recognition_arena_drops_capacity_above_retention_limit() {
18094 let mut storage = Vec::<u8>::with_capacity(4);
18095 storage.extend([1, 2, 3]);
18096
18097 reset_arena_vec(&mut storage, 3);
18098
18099 assert!(storage.is_empty());
18100 assert_eq!(storage.capacity(), 0);
18101 }
18102
18103 #[test]
18104 fn recognition_arena_concatenates_diagnostics_in_source_order() {
18105 let mut arena = RecognitionArena::default();
18106 let prefix = arena.diagnostic_sequence([
18107 ParserDiagnostic {
18108 line: 1,
18109 column: 0,
18110 message: "first".to_owned(),
18111 },
18112 ParserDiagnostic {
18113 line: 1,
18114 column: 1,
18115 message: "second".to_owned(),
18116 },
18117 ]);
18118 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
18119 line: 1,
18120 column: 2,
18121 message: "third".to_owned(),
18122 }]);
18123 let extras_before = arena.extras.len();
18124
18125 let combined = arena.concat_diagnostics(prefix, suffix);
18126 let messages = arena
18127 .diagnostics(combined)
18128 .map(|diagnostic| diagnostic.message.as_str())
18129 .collect::<Vec<_>>();
18130
18131 assert_eq!(messages, ["first", "second", "third"]);
18132 assert_eq!(arena.extras.len(), extras_before);
18133 }
18134
18135 #[test]
18136 fn outcome_ties_keep_later_non_recursive_alternative() {
18137 let arena = RecognitionArena::default();
18138 let first = RecognizeOutcome {
18139 index: 1,
18140 consumed_eof: false,
18141 alt_number: 0,
18142 member_values: BTreeMap::new(),
18143 return_values: BTreeMap::new(),
18144 diagnostics: DiagnosticSeqId::EMPTY,
18145 decisions: Vec::new(),
18146 actions: vec![ParserAction::new(1, 0, 0, None)],
18147 nodes: NodeSeqId::EMPTY,
18148 };
18149 let second = RecognizeOutcome {
18150 actions: vec![ParserAction::new(2, 0, 0, None)],
18151 ..first.clone()
18152 };
18153
18154 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18155 .expect("one outcome should be selected");
18156 assert_eq!(selected.actions[0].source_state(), 2);
18157 }
18158
18159 #[test]
18160 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
18161 let arena = RecognitionArena::default();
18162 let first = RecognizeOutcome {
18163 index: 1,
18164 consumed_eof: false,
18165 alt_number: 0,
18166 member_values: BTreeMap::new(),
18167 return_values: BTreeMap::new(),
18168 diagnostics: DiagnosticSeqId::EMPTY,
18169 decisions: Vec::new(),
18170 actions: vec![ParserAction::new(1, 0, 0, None)],
18171 nodes: NodeSeqId::EMPTY,
18172 };
18173 let second = RecognizeOutcome {
18174 actions: vec![
18175 ParserAction::new(2, 0, 0, None),
18176 ParserAction::new(3, 0, 0, None),
18177 ],
18178 ..first.clone()
18179 };
18180
18181 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
18182 .expect("one outcome should be selected");
18183 assert_eq!(selected.actions.len(), 2);
18184 }
18185
18186 #[test]
18187 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
18188 let arena = RecognitionArena::default();
18189 let first = RecognizeOutcome {
18190 index: 7,
18191 consumed_eof: false,
18192 alt_number: 0,
18193 member_values: BTreeMap::new(),
18194 return_values: BTreeMap::new(),
18195 diagnostics: DiagnosticSeqId::EMPTY,
18196 decisions: vec![1, 0],
18197 actions: vec![
18198 ParserAction::new(23, 2, 2, Some(4)),
18199 ParserAction::new(23, 2, 0, Some(6)),
18200 ],
18201 nodes: NodeSeqId::EMPTY,
18202 };
18203 let second = RecognizeOutcome {
18204 decisions: vec![0, 1],
18205 actions: vec![
18206 ParserAction::new(23, 2, 2, Some(6)),
18207 ParserAction::new(23, 2, 0, Some(6)),
18208 ],
18209 ..first.clone()
18210 };
18211
18212 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18213 .expect("one outcome should be selected");
18214 assert_eq!(selected.actions[0].stop_index(), Some(6));
18215 }
18216
18217 #[test]
18218 fn outcome_ties_keep_first_recursive_tree_shape() {
18219 let mut arena = RecognitionArena::default();
18220 let token = arena.push_node(ArenaRecognizedNode::Token {
18221 token: TokenId::try_from(0).expect("test token ID"),
18222 });
18223 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
18224 let inner = arena.push_node(ArenaRecognizedNode::Rule {
18225 rule_index: 1,
18226 invoking_state: -1,
18227 alt_number: 0,
18228 start_index: 0,
18229 stop_index: Some(0),
18230 return_values: None,
18231 children: token_children,
18232 });
18233 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
18234 let outer = arena.push_node(ArenaRecognizedNode::Rule {
18235 rule_index: 1,
18236 invoking_state: -1,
18237 alt_number: 0,
18238 start_index: 0,
18239 stop_index: Some(0),
18240 return_values: None,
18241 children: inner_children,
18242 });
18243 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
18244 let first = RecognizeOutcome {
18245 index: 1,
18246 consumed_eof: false,
18247 alt_number: 0,
18248 member_values: BTreeMap::new(),
18249 return_values: BTreeMap::new(),
18250 diagnostics: DiagnosticSeqId::EMPTY,
18251 decisions: Vec::new(),
18252 actions: vec![ParserAction::new(1, 0, 0, None)],
18253 nodes: recursive_nodes,
18254 };
18255 let second = RecognizeOutcome {
18256 index: 1,
18257 consumed_eof: false,
18258 alt_number: 0,
18259 member_values: BTreeMap::new(),
18260 return_values: BTreeMap::new(),
18261 diagnostics: DiagnosticSeqId::EMPTY,
18262 decisions: Vec::new(),
18263 actions: vec![ParserAction::new(2, 0, 0, None)],
18264 nodes: recursive_nodes,
18265 };
18266
18267 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18268 .expect("one outcome should be selected");
18269 assert_eq!(selected.actions[0].source_state(), 1);
18270 }
18271
18272 #[test]
18273 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
18274 let mut arena = RecognitionArena::default();
18275 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
18276 line: 1,
18277 column: 3,
18278 message: "missing 'Y' at '<EOF>'".to_owned(),
18279 }]);
18280 let first_alt = RecognizeOutcome {
18281 index: 2,
18282 consumed_eof: true,
18283 alt_number: 0,
18284 member_values: BTreeMap::new(),
18285 return_values: BTreeMap::new(),
18286 diagnostics: recovered_diagnostics,
18287 decisions: vec![0],
18288 actions: vec![ParserAction::new(1, 0, 0, None)],
18289 nodes: NodeSeqId::EMPTY,
18290 };
18291 let second_alt = RecognizeOutcome {
18292 diagnostics: DiagnosticSeqId::EMPTY,
18293 decisions: vec![1],
18294 actions: vec![ParserAction::new(2, 0, 0, None)],
18295 ..first_alt.clone()
18296 };
18297
18298 let selected = select_best_outcome(
18299 [second_alt, first_alt].into_iter(),
18300 PredictionMode::Sll,
18301 &arena,
18302 )
18303 .expect("one outcome should be selected");
18304 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
18305 assert_eq!(selected.decisions, [0]);
18306 }
18307}