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 sempred<S>(
567 &mut self,
568 ctx: &mut ParserSemCtx<'_, S>,
569 rule_index: usize,
570 pred_index: usize,
571 ) -> Option<bool>
572 where
573 S: TokenSource,
574 {
575 let _ = (ctx, rule_index, pred_index);
576 None
577 }
578
579 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
580 where
581 S: TokenSource,
582 {
583 let _ = (ctx, action);
584 false
585 }
586
587 fn lexer_sempred<I>(
588 &mut self,
589 ctx: &mut LexerSemCtx<'_, I>,
590 rule_index: usize,
591 pred_index: usize,
592 ) -> Option<bool>
593 where
594 I: CharStream,
595 {
596 let _ = (ctx, rule_index, pred_index);
597 None
598 }
599
600 fn lexer_action<I>(&mut self, ctx: &mut LexerSemCtx<'_, I>, action: LexerCustomAction) -> bool
610 where
611 I: CharStream,
612 {
613 let _ = (ctx, action);
614 false
615 }
616
617 fn lexer_reset<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
621 where
622 I: CharStream,
623 {
624 let _ = ctx;
625 }
626
627 fn lexer_before_token<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
633 where
634 I: CharStream,
635 {
636 let _ = ctx;
637 }
638
639 fn lexer_after_accept<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
648 where
649 I: CharStream,
650 {
651 let _ = ctx;
652 }
653
654 fn lexer_token_emitted(&mut self, token: TokenView<'_>) {
661 let _ = token;
662 }
663}
664
665#[derive(Clone, Copy, Debug, Default)]
668pub struct NoSemanticHooks;
669
670impl SemanticHooks for NoSemanticHooks {
671 const ENABLES_LEXER_LIFECYCLE: bool = false;
672
673 fn observes_parser_predicates(&self) -> bool {
674 false
675 }
676}
677
678#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
685pub enum ParserPredicate {
686 True,
687 False,
688 FalseWithMessage {
690 message: &'static str,
691 },
692 Invoke {
695 value: bool,
696 },
697 LookaheadTextEquals {
698 offset: isize,
699 text: &'static str,
700 },
701 LookaheadNotEquals {
702 offset: isize,
703 token_type: i32,
704 },
705 TokenPairAdjacent,
708 ContextChildRuleTextNotEquals {
713 rule_index: usize,
714 text: &'static str,
715 },
716 LocalIntEquals {
719 value: i64,
720 },
721 LocalIntLessOrEqual {
724 value: i64,
725 },
726 MemberModuloEquals {
728 member: usize,
729 modulus: i64,
730 value: i64,
731 equals: bool,
732 },
733 MemberEquals {
735 member: usize,
736 value: i64,
737 equals: bool,
738 },
739}
740
741impl ParserPredicate {
742 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
748 match self {
749 Self::True => ir.expr(PExpr::Bool(true)),
750 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
751 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
752 Self::LookaheadTextEquals { offset, text } => {
753 let token = ir.expr(PExpr::TokenText(offset));
754 let text = ir.intern(text);
755 let text = ir.expr(PExpr::Str(text));
756 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
757 }
758 Self::LookaheadNotEquals { offset, token_type } => {
759 let actual = ir.expr(PExpr::La(offset));
760 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
761 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
762 }
763 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
764 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
765 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
766 let expected = ir.intern(text);
767 let expected = ir.expr(PExpr::Str(expected));
768 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
769 }
770 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
771 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
772 Self::MemberModuloEquals {
773 member,
774 modulus,
775 value,
776 equals,
777 } => {
778 if modulus == 0 {
779 return ir.expr(PExpr::Bool(false));
780 }
781 let member = ir.expr(PExpr::Member(member));
782 let modulus = ir.expr(PExpr::Int(modulus));
783 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
784 let expected = ir.expr(PExpr::Int(value));
785 ir.expr(PExpr::Cmp(
786 if equals { CmpOp::Eq } else { CmpOp::Ne },
787 actual,
788 expected,
789 ))
790 }
791 Self::MemberEquals {
792 member,
793 value,
794 equals,
795 } => {
796 let actual = ir.expr(PExpr::Member(member));
797 let expected = ir.expr(PExpr::Int(value));
798 ir.expr(PExpr::Cmp(
799 if equals { CmpOp::Eq } else { CmpOp::Ne },
800 actual,
801 expected,
802 ))
803 }
804 }
805 }
806
807 #[must_use]
808 pub const fn failure_message(self) -> Option<&'static str> {
809 match self {
810 Self::FalseWithMessage { message } => Some(message),
811 Self::True
812 | Self::False
813 | Self::Invoke { .. }
814 | Self::LookaheadTextEquals { .. }
815 | Self::LookaheadNotEquals { .. }
816 | Self::TokenPairAdjacent
817 | Self::ContextChildRuleTextNotEquals { .. }
818 | Self::LocalIntEquals { .. }
819 | Self::LocalIntLessOrEqual { .. }
820 | Self::MemberModuloEquals { .. }
821 | Self::MemberEquals { .. } => None,
822 }
823 }
824}
825
826fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
827 let local = ir.expr(PExpr::LocalArg);
828 let absent = ir.expr(PExpr::IsNull(local));
829 let expected = ir.expr(PExpr::Int(value));
830 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
831 ir.expr(PExpr::Or([absent, comparison].into()))
832}
833
834#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
847pub enum UnknownSemanticPolicy {
848 #[default]
850 AssumeTrue,
851 AssumeFalse,
853 Error,
856}
857
858fn apply_unknown_predicate_policy(
867 policy: UnknownSemanticPolicy,
868 rule_index: usize,
869 pred_index: usize,
870 hits: &mut Vec<(usize, usize)>,
871) -> bool {
872 match policy {
873 UnknownSemanticPolicy::AssumeTrue => true,
874 UnknownSemanticPolicy::AssumeFalse => false,
875 UnknownSemanticPolicy::Error => {
876 let coordinate = (rule_index, pred_index);
877 if !hits.contains(&coordinate) {
878 hits.push(coordinate);
879 }
880 false
881 }
882 }
883}
884
885#[derive(Clone, Debug, Eq, PartialEq)]
889pub struct ExpectedTokenSet {
890 symbols: BTreeSet<i32>,
891}
892
893impl ExpectedTokenSet {
894 #[must_use]
896 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
897 expected_symbols_display(&self.symbols, vocabulary)
898 }
899}
900
901#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
906pub struct BailErrorStrategy;
907
908impl BailErrorStrategy {
909 #[must_use]
910 pub const fn new() -> Self {
911 Self
912 }
913}
914
915#[derive(Clone, Copy, Debug, Eq, PartialEq)]
917pub enum PredictionMode {
918 Ll,
921 Sll,
924 LlExactAmbigDetection,
926}
927
928#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
934pub struct ParserRuleArg {
935 pub source_state: usize,
937 pub rule_index: usize,
939 pub value: i64,
941 pub inherit_local: bool,
943}
944
945#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
947pub struct ParserMemberAction {
948 pub source_state: usize,
950 pub member: usize,
952 pub delta: i64,
954}
955
956#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
963pub struct ParserReturnAction {
964 pub source_state: usize,
966 pub rule_index: usize,
968 pub name: &'static str,
970 pub value: i64,
972}
973
974impl ParserMemberAction {
975 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
977 let delta = ir.expr(PExpr::Int(self.delta));
978 ParserSemanticAction {
979 source_state: self.source_state,
980 rule_index: usize::MAX,
981 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
982 speculative: true,
983 }
984 }
985}
986
987impl ParserReturnAction {
988 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
990 let name = ir.intern(self.name);
991 let value = ir.expr(PExpr::Int(self.value));
992 ParserSemanticAction {
993 source_state: self.source_state,
994 rule_index: self.rule_index,
995 stmt: ir.stmt(AStmt::SetReturn(name, value)),
996 speculative: false,
997 }
998 }
999}
1000
1001#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1003pub struct ParserSemanticPredicate {
1004 pub rule_index: usize,
1006 pub pred_index: usize,
1008 pub expr: ExprId,
1010 pub failure_message: Option<&'static str>,
1012}
1013
1014#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1016pub struct ParserSemanticAction {
1017 pub source_state: usize,
1019 pub rule_index: usize,
1021 pub stmt: StmtId,
1023 pub speculative: bool,
1025}
1026
1027#[derive(Clone, Debug, Default, Eq, PartialEq)]
1034pub struct ParserSemantics {
1035 pub ir: SemIr,
1036 pub predicates: Vec<ParserSemanticPredicate>,
1037 pub actions: Vec<ParserSemanticAction>,
1038}
1039
1040#[derive(Clone, Copy, Debug, Default)]
1042pub struct ParserRuntimeOptions<'a> {
1043 pub init_action_rules: &'a [usize],
1045 pub track_alt_numbers: bool,
1047 pub predicates: &'a [(usize, usize, ParserPredicate)],
1049 pub semantics: Option<&'a ParserSemantics>,
1051 pub rule_args: &'a [ParserRuleArg],
1053 pub member_actions: &'a [ParserMemberAction],
1055 pub return_actions: &'a [ParserReturnAction],
1057 pub unknown_predicate_policy: UnknownSemanticPolicy,
1060}
1061
1062pub trait Parser: Recognizer {
1063 fn build_parse_trees(&self) -> bool;
1066
1067 fn set_build_parse_trees(&mut self, build: bool);
1069
1070 fn number_of_syntax_errors(&self) -> usize {
1073 0
1074 }
1075
1076 fn report_diagnostic_errors(&self) -> bool {
1079 false
1080 }
1081
1082 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
1085
1086 fn prediction_mode(&self) -> PredictionMode {
1088 PredictionMode::Ll
1089 }
1090
1091 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
1093}
1094
1095#[derive(Debug)]
1096struct LeftRecursiveCallerOverlap {
1097 atn_key: SharedAtnCacheKey,
1098 state_number: usize,
1099 symbol: i32,
1100 context_version: usize,
1101 overlaps: bool,
1102}
1103
1104const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
1105
1106#[derive(Debug)]
1107pub struct BaseParser<S, H = NoSemanticHooks> {
1108 input: CommonTokenStream<S>,
1109 tree: ParseTreeStorage,
1110 data: RecognizerData,
1111 semantic_hooks: H,
1112 build_parse_trees: bool,
1113 syntax_errors: usize,
1114 report_diagnostic_errors: bool,
1115 prediction_mode: PredictionMode,
1116 prediction_diagnostics: Vec<ParserDiagnostic>,
1117 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1118 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1119 generated_sync_expected: Option<TokenBitSet>,
1120 int_members: BTreeMap<usize, i64>,
1121 rule_context_stack: Vec<RuleContextFrame>,
1122 rule_context_version: usize,
1123 left_recursive_caller_overlap_cache:
1124 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1125 pending_invoking_states: Vec<isize>,
1126 precedence_stack: Vec<i32>,
1127 invoked_predicates: Vec<(usize, usize)>,
1131 bail_on_error: bool,
1135 unknown_predicate_policy: UnknownSemanticPolicy,
1138 unknown_predicate_hits: Vec<(usize, usize)>,
1141 unhandled_action_hits: Vec<(usize, usize)>,
1146 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1151 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1157 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1162 rule_stop_reach_cache: Vec<Option<bool>>,
1167 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1172 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1178 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1184 fast_predicate_cache: FxHashMap<(usize, usize, usize), bool>,
1188 empty_cycle_cache: Vec<Option<bool>>,
1194 empty_cycle_cache_atn: Option<SharedAtnCacheKey>,
1195 clean_memo_mode: CleanMemoMode,
1198 clean_memo_probe_seen: FxHashSet<FastRecognizeKey>,
1199 clean_memo_probe_samples: usize,
1200 clean_memo_probe_repeats: usize,
1201 clean_memo_sparse_samples: usize,
1202 fast_recognize_scratch: FastRecognizeTopScratch,
1204 fast_outcome_dedup: FastOutcomeDedupScratch,
1206 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1209 fast_first_set_prefilter: bool,
1217 fast_recovery_enabled: bool,
1221 fast_token_nodes_enabled: bool,
1226 recognition_arena: RecognitionArena,
1230 last_recognition_arena_root: NodeSeqId,
1231 last_recognition_arena_diagnostics: DiagnosticSeqId,
1232}
1233
1234#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1236pub struct GeneratedDiagnosticsCheckpoint {
1237 diagnostics_len: usize,
1238 syntax_errors: usize,
1239 tree: ParseTreeCheckpoint,
1240}
1241
1242#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1245pub struct RecognitionArenaStats {
1246 pub total_nodes: usize,
1247 pub live_nodes: usize,
1248 pub dead_nodes: usize,
1249 pub node_capacity: usize,
1250 pub total_links: usize,
1251 pub live_links: usize,
1252 pub dead_links: usize,
1253 pub link_capacity: usize,
1254 pub total_extras: usize,
1255 pub live_extras: usize,
1256 pub dead_extras: usize,
1257 pub extra_capacity: usize,
1258}
1259
1260#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1261struct RuleContextFrame {
1262 rule_index: usize,
1263 invoking_state: isize,
1264}
1265
1266#[derive(Clone, Debug, Eq, PartialEq)]
1267struct RecognizeOutcome {
1268 index: usize,
1269 consumed_eof: bool,
1270 alt_number: usize,
1271 member_values: BTreeMap<usize, i64>,
1272 return_values: BTreeMap<String, i64>,
1273 diagnostics: DiagnosticSeqId,
1274 decisions: Vec<usize>,
1275 actions: Vec<ParserAction>,
1276 nodes: NodeSeqId,
1277}
1278
1279#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1280struct FastRecognizeOutcome {
1281 index: usize,
1282 consumed_eof: bool,
1283 diagnostics: DiagnosticSeqId,
1284 deferred_nodes: FastDeferredNodeId,
1285 nodes: NodeSeqId,
1289}
1290
1291#[derive(Debug, Default)]
1292struct FastRecognizeTopScratch {
1293 visiting: FxHashSet<FastRecognizeKey>,
1294 memo: FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
1295}
1296
1297impl FastRecognizeTopScratch {
1298 fn prepare(&mut self, memo_capacity: usize) {
1299 self.visiting.clear();
1300 self.visiting.reserve(FAST_RECOGNIZE_VISITING_CAPACITY);
1301 self.memo.clear();
1302 self.memo.reserve(memo_capacity);
1303 }
1304
1305 fn release_oversized_memo(&mut self) {
1306 self.memo.clear();
1307 if self.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY {
1308 self.memo = FxHashMap::default();
1309 }
1310 }
1311}
1312
1313fn fast_recognize_memo_capacity(buffered_tokens: usize) -> usize {
1314 buffered_tokens.saturating_mul(8).clamp(
1315 FAST_RECOGNIZE_MIN_MEMO_CAPACITY,
1316 FAST_RECOGNIZE_MAX_MEMO_CAPACITY,
1317 )
1318}
1319
1320#[derive(Debug, Default)]
1321struct FastOutcomeDedupScratch {
1322 dense_words: Vec<u64>,
1323 touched_dense_words: Vec<u32>,
1324 sparse_keys: FxHashSet<(usize, bool)>,
1325}
1326
1327#[repr(transparent)]
1332#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1333struct FastDeferredNodeId(u32);
1334
1335impl FastDeferredNodeId {
1336 const EMPTY: Self = Self(u32::MAX);
1337
1338 const fn is_empty(self) -> bool {
1339 self.0 == Self::EMPTY.0
1340 }
1341}
1342
1343impl Default for FastDeferredNodeId {
1344 fn default() -> Self {
1345 Self::EMPTY
1346 }
1347}
1348
1349#[repr(transparent)]
1350#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1351struct FastDeferredRuleId(u32);
1352
1353#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1355enum FastDeferredNode {
1356 Fragment(NodeSeqId),
1357 Rule(FastDeferredRuleId),
1358 Concat {
1359 prefix: FastDeferredNodeId,
1360 suffix: FastDeferredNodeId,
1361 },
1362}
1363
1364#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1365struct FastDeferredRule {
1366 rule_index: u32,
1367 invoking_state: i32,
1368 start_index: u32,
1369 stop_index: Option<u32>,
1370 deferred_children: FastDeferredNodeId,
1371 children: NodeSeqId,
1372}
1373
1374#[repr(transparent)]
1375#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1376struct RecognizedNodeId(u32);
1377
1378#[repr(transparent)]
1379#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1380struct NodeSeqId(u32);
1381
1382impl NodeSeqId {
1383 const EMPTY: Self = Self(u32::MAX);
1384
1385 const fn is_empty(self) -> bool {
1386 self.0 == Self::EMPTY.0
1387 }
1388}
1389
1390impl Default for NodeSeqId {
1391 fn default() -> Self {
1392 Self::EMPTY
1393 }
1394}
1395
1396#[repr(transparent)]
1397#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1398struct DiagnosticSeqId(u32);
1399
1400impl DiagnosticSeqId {
1401 const EMPTY: Self = Self(u32::MAX);
1402
1403 const fn is_empty(self) -> bool {
1404 self.0 == Self::EMPTY.0
1405 }
1406}
1407
1408impl Default for DiagnosticSeqId {
1409 fn default() -> Self {
1410 Self::EMPTY
1411 }
1412}
1413
1414#[repr(transparent)]
1415#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1416struct RecognitionExtraId(u32);
1417
1418#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1419struct SeqLink {
1420 head: RecognizedNodeId,
1421 tail: NodeSeqId,
1422}
1423
1424#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1425struct DiagnosticLink {
1426 head: RecognitionExtraId,
1427 tail: DiagnosticSeqId,
1428}
1429
1430struct ArenaRuleSpec {
1431 rule_index: usize,
1432 invoking_state: isize,
1433 alt_number: usize,
1434 start_index: usize,
1435 stop_index: Option<usize>,
1436 return_values: BTreeMap<String, i64>,
1437 children: NodeSeqId,
1438}
1439
1440#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1443enum ArenaRecognizedNode {
1444 Token {
1445 token: TokenId,
1446 },
1447 ErrorToken {
1448 token: TokenId,
1449 },
1450 MissingToken {
1451 extra: RecognitionExtraId,
1452 },
1453 Rule {
1454 rule_index: u32,
1455 invoking_state: i32,
1456 alt_number: u32,
1457 start_index: u32,
1458 stop_index: Option<u32>,
1459 return_values: Option<RecognitionExtraId>,
1460 children: NodeSeqId,
1461 },
1462 LeftRecursiveBoundary {
1466 rule_index: u32,
1467 },
1468}
1469
1470#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1471enum RecognitionExtra {
1472 MissingToken {
1473 token_type: i32,
1474 at_index: u32,
1475 text: String,
1476 },
1477 ReturnValues(BTreeMap<String, i64>),
1478 Diagnostic(ParserDiagnostic),
1479}
1480
1481#[derive(Debug, Default)]
1482struct RecognitionArena {
1483 nodes: Vec<ArenaRecognizedNode>,
1484 seq_links: Vec<SeqLink>,
1485 diagnostic_links: Vec<DiagnosticLink>,
1486 extras: Vec<RecognitionExtra>,
1487 deferred_nodes: Vec<FastDeferredNode>,
1488 deferred_rules: Vec<FastDeferredRule>,
1489}
1490
1491const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1494const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1495const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1496const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1497const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1498const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1499
1500impl RecognitionArena {
1501 fn reset(&mut self) {
1502 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1503 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1504 reset_arena_vec(
1505 &mut self.diagnostic_links,
1506 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1507 );
1508 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1509 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1510 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1511 }
1512
1513 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1514 let id = RecognizedNodeId(
1515 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1516 );
1517 self.nodes.push(node);
1518 id
1519 }
1520
1521 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1522 let id = RecognitionExtraId(
1523 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1524 );
1525 self.extras.push(extra);
1526 id
1527 }
1528
1529 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1530 let id = NodeSeqId(
1531 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1532 );
1533 self.seq_links.push(SeqLink { head, tail });
1534 id
1535 }
1536
1537 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1538 let id = FastDeferredNodeId(
1539 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
1540 );
1541 self.deferred_nodes.push(node);
1542 id
1543 }
1544
1545 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
1546 let id = FastDeferredRuleId(
1547 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
1548 );
1549 self.deferred_rules.push(rule);
1550 id
1551 }
1552
1553 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
1554 if nodes.is_empty() {
1555 FastDeferredNodeId::EMPTY
1556 } else {
1557 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
1558 }
1559 }
1560
1561 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
1562 let rule = self.push_deferred_rule(rule);
1563 self.push_deferred_node(FastDeferredNode::Rule(rule))
1564 }
1565
1566 fn concat_deferred_nodes(
1567 &mut self,
1568 prefix: FastDeferredNodeId,
1569 suffix: FastDeferredNodeId,
1570 ) -> FastDeferredNodeId {
1571 if prefix.is_empty() {
1572 return suffix;
1573 }
1574 if suffix.is_empty() {
1575 return prefix;
1576 }
1577 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
1578 }
1579
1580 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
1581 self.deferred_nodes[id.0 as usize]
1582 }
1583
1584 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
1585 self.deferred_rules[id.0 as usize]
1586 }
1587
1588 fn prepend_diagnostic(
1589 &mut self,
1590 tail: DiagnosticSeqId,
1591 diagnostic: ParserDiagnostic,
1592 ) -> DiagnosticSeqId {
1593 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
1594 self.prepend_diagnostic_id(tail, head)
1595 }
1596
1597 fn prepend_diagnostic_id(
1598 &mut self,
1599 tail: DiagnosticSeqId,
1600 head: RecognitionExtraId,
1601 ) -> DiagnosticSeqId {
1602 let id = DiagnosticSeqId(
1603 u32::try_from(self.diagnostic_links.len())
1604 .expect("diagnostic sequence arena fits in u32"),
1605 );
1606 self.diagnostic_links.push(DiagnosticLink { head, tail });
1607 id
1608 }
1609
1610 fn concat_diagnostics(
1611 &mut self,
1612 prefix: DiagnosticSeqId,
1613 mut suffix: DiagnosticSeqId,
1614 ) -> DiagnosticSeqId {
1615 if prefix.is_empty() {
1616 return suffix;
1617 }
1618 if suffix.is_empty() {
1619 return prefix;
1620 }
1621 let mut reversed = DiagnosticSeqId::EMPTY;
1622 let mut cursor = prefix;
1623 while let Some(link) = self.diagnostic_link(cursor) {
1624 reversed = self.prepend_diagnostic_id(reversed, link.head);
1625 cursor = link.tail;
1626 }
1627 while let Some(link) = self.diagnostic_link(reversed) {
1628 suffix = self.prepend_diagnostic_id(suffix, link.head);
1629 reversed = link.tail;
1630 }
1631 suffix
1632 }
1633
1634 #[cfg(test)]
1635 fn diagnostic_sequence(
1636 &mut self,
1637 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
1638 ) -> DiagnosticSeqId {
1639 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
1640 let mut sequence = DiagnosticSeqId::EMPTY;
1641 for diagnostic in diagnostics.into_iter().rev() {
1642 sequence = self.prepend_diagnostic(sequence, diagnostic);
1643 }
1644 sequence
1645 }
1646
1647 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
1648 self.nodes[id.0 as usize]
1649 }
1650
1651 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
1652 &self.extras[id.0 as usize]
1653 }
1654
1655 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
1656 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
1657 }
1658
1659 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
1660 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
1661 }
1662
1663 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
1664 NodeSeqIter {
1665 arena: self,
1666 cursor: sequence,
1667 }
1668 }
1669
1670 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
1671 DiagnosticSeqIter {
1672 arena: self,
1673 cursor: sequence,
1674 }
1675 }
1676
1677 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
1678 self.diagnostics(sequence).count()
1679 }
1680
1681 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
1682 self.diagnostics(sequence)
1683 .filter(|diagnostic| {
1684 diagnostic.message.starts_with("mismatched input ")
1685 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
1686 })
1687 .count()
1688 }
1689
1690 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
1691 self.diagnostics(left).cmp(self.diagnostics(right))
1692 }
1693
1694 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
1695 self.iter(sequence).count()
1696 }
1697
1698 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
1699 self.iter(sequence).any(|node| match self.node(node) {
1700 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1701 ArenaRecognizedNode::Rule { children, .. } => {
1702 self.sequence_has_left_recursive_boundary(children)
1703 }
1704 ArenaRecognizedNode::Token { .. }
1705 | ArenaRecognizedNode::ErrorToken { .. }
1706 | ArenaRecognizedNode::MissingToken { .. } => false,
1707 })
1708 }
1709
1710 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
1711 self.iter(sequence).any(|node| {
1712 matches!(
1713 self.node(node),
1714 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
1715 )
1716 })
1717 }
1718
1719 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
1720 self.iter(sequence).any(|node| {
1721 matches!(
1722 self.node(node),
1723 ArenaRecognizedNode::Token { .. }
1724 | ArenaRecognizedNode::ErrorToken { .. }
1725 | ArenaRecognizedNode::MissingToken { .. }
1726 )
1727 })
1728 }
1729
1730 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
1731 match self.node(node) {
1732 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1733 Some(token.index())
1734 }
1735 ArenaRecognizedNode::MissingToken { extra } => {
1736 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1737 unreachable!("missing-token node must reference missing-token extra");
1738 };
1739 Some(*at_index as usize)
1740 }
1741 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
1742 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1743 }
1744 }
1745
1746 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
1747 match self.node(node) {
1748 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1749 Some(token.index())
1750 }
1751 ArenaRecognizedNode::MissingToken { extra } => {
1752 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1753 unreachable!("missing-token node must reference missing-token extra");
1754 };
1755 (*at_index as usize).checked_sub(1)
1756 }
1757 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
1758 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1759 }
1760 }
1761
1762 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
1763 let start = self.node_start_index(node)?;
1764 let stop = self.node_stop_index(node);
1765 Some((start, stop))
1766 }
1767
1768 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
1769 self.iter(sequence)
1770 .find_map(|node| self.node_start_index(node))
1771 }
1772
1773 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
1774 let mut stop = None;
1775 for node in self.iter(sequence) {
1776 if let Some(index) = self.node_stop_index(node) {
1777 stop = Some(index);
1778 }
1779 }
1780 stop
1781 }
1782
1783 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
1784 self.iter(sequence)
1785 .any(|node| self.node_needs_stable_tie(node))
1786 }
1787
1788 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
1789 match self.node(node) {
1790 ArenaRecognizedNode::Token { .. }
1791 | ArenaRecognizedNode::ErrorToken { .. }
1792 | ArenaRecognizedNode::MissingToken { .. } => false,
1793 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1794 ArenaRecognizedNode::Rule {
1795 rule_index,
1796 children,
1797 ..
1798 } => self.iter(children).any(|child| {
1799 matches!(
1800 self.node(child),
1801 ArenaRecognizedNode::Rule {
1802 rule_index: child_rule,
1803 ..
1804 } if child_rule == rule_index
1805 ) || self.node_needs_stable_tie(child)
1806 }),
1807 }
1808 }
1809
1810 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
1811 loop {
1812 match (self.link(left), self.link(right)) {
1813 (Some(left_link), Some(right_link)) => {
1814 let order = self.compare_nodes(left_link.head, right_link.head);
1815 if order != Ordering::Equal {
1816 return order;
1817 }
1818 left = left_link.tail;
1819 right = right_link.tail;
1820 }
1821 (None, None) => return Ordering::Equal,
1822 (None, Some(_)) => return Ordering::Less,
1823 (Some(_), None) => return Ordering::Greater,
1824 }
1825 }
1826 }
1827
1828 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
1829 let left = self.node(left);
1830 let right = self.node(right);
1831 match (left, right) {
1832 (
1833 ArenaRecognizedNode::Token { token: left },
1834 ArenaRecognizedNode::Token { token: right },
1835 )
1836 | (
1837 ArenaRecognizedNode::ErrorToken { token: left },
1838 ArenaRecognizedNode::ErrorToken { token: right },
1839 ) => left.cmp(&right),
1840 (
1841 ArenaRecognizedNode::MissingToken { extra: left },
1842 ArenaRecognizedNode::MissingToken { extra: right },
1843 ) => self.extra(left).cmp(self.extra(right)),
1844 (
1845 ArenaRecognizedNode::Rule {
1846 rule_index: left_rule,
1847 invoking_state: left_invoking,
1848 alt_number: left_alt,
1849 start_index: left_start,
1850 stop_index: left_stop,
1851 return_values: left_returns,
1852 children: left_children,
1853 },
1854 ArenaRecognizedNode::Rule {
1855 rule_index: right_rule,
1856 invoking_state: right_invoking,
1857 alt_number: right_alt,
1858 start_index: right_start,
1859 stop_index: right_stop,
1860 return_values: right_returns,
1861 children: right_children,
1862 },
1863 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
1864 .cmp(&(
1865 right_rule,
1866 right_invoking,
1867 right_alt,
1868 right_start,
1869 right_stop,
1870 ))
1871 .then_with(|| {
1872 left_returns
1873 .map(|id| self.extra(id))
1874 .cmp(&right_returns.map(|id| self.extra(id)))
1875 })
1876 .then_with(|| self.compare_sequences(left_children, right_children)),
1877 (
1878 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: left },
1879 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: right },
1880 ) => left.cmp(&right),
1881 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
1882 }
1883 }
1884
1885 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1886 let mut reversed = NodeSeqId::EMPTY;
1887 while let Some(link) = self.link(sequence) {
1888 reversed = self.prepend(reversed, link.head);
1889 sequence = link.tail;
1890 }
1891 reversed
1892 }
1893
1894 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
1895 if !self.sequence_has_direct_boundary(sequence) {
1896 return sequence;
1897 }
1898 let mut reversed = NodeSeqId::EMPTY;
1899 while let Some(link) = self.link(sequence) {
1900 match self.node(link.head) {
1901 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index } => {
1902 if !reversed.is_empty() {
1903 let children = self.reverse_sequence(reversed);
1904 let start_index = self.sequence_start_index(children).unwrap_or_default();
1905 let stop_index = self.sequence_stop_index(children);
1906 let rule = self.push_node(ArenaRecognizedNode::Rule {
1907 rule_index,
1908 invoking_state: -1,
1909 alt_number: 0,
1910 start_index: u32::try_from(start_index)
1911 .expect("left-recursive start index fits in u32"),
1912 stop_index: stop_index.map(|index| {
1913 u32::try_from(index).expect("left-recursive stop index fits in u32")
1914 }),
1915 return_values: None,
1916 children,
1917 });
1918 reversed = self.prepend(NodeSeqId::EMPTY, rule);
1919 }
1920 }
1921 _ => {
1922 reversed = self.prepend(reversed, link.head);
1923 }
1924 }
1925 sequence = link.tail;
1926 }
1927 self.reverse_sequence(reversed)
1928 }
1929
1930 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
1931 let mut live_nodes = vec![false; self.nodes.len()];
1932 let mut live_links = vec![false; self.seq_links.len()];
1933 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
1934 let mut live_extras = vec![false; self.extras.len()];
1935 let mut pending = vec![root];
1936 while let Some(mut sequence) = pending.pop() {
1937 while let Some(link) = self.link(sequence) {
1938 let link_index = sequence.0 as usize;
1939 if live_links[link_index] {
1940 break;
1941 }
1942 live_links[link_index] = true;
1943 let node_index = link.head.0 as usize;
1944 if !live_nodes[node_index] {
1945 live_nodes[node_index] = true;
1946 match self.node(link.head) {
1947 ArenaRecognizedNode::MissingToken { extra } => {
1948 live_extras[extra.0 as usize] = true;
1949 }
1950 ArenaRecognizedNode::Rule {
1951 return_values,
1952 children,
1953 ..
1954 } => {
1955 if let Some(extra) = return_values {
1956 live_extras[extra.0 as usize] = true;
1957 }
1958 pending.push(children);
1959 }
1960 ArenaRecognizedNode::Token { .. }
1961 | ArenaRecognizedNode::ErrorToken { .. }
1962 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
1963 }
1964 }
1965 sequence = link.tail;
1966 }
1967 }
1968 let mut diagnostics = diagnostics;
1969 while let Some(link) = self.diagnostic_link(diagnostics) {
1970 let link_index = diagnostics.0 as usize;
1971 if live_diagnostic_links[link_index] {
1972 break;
1973 }
1974 live_diagnostic_links[link_index] = true;
1975 live_extras[link.head.0 as usize] = true;
1976 diagnostics = link.tail;
1977 }
1978 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
1979 let live_link_count = live_links.into_iter().filter(|live| *live).count()
1980 + live_diagnostic_links
1981 .into_iter()
1982 .filter(|live| *live)
1983 .count();
1984 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
1985 let total_links = self.seq_links.len() + self.diagnostic_links.len();
1986 RecognitionArenaStats {
1987 total_nodes: self.nodes.len(),
1988 live_nodes: live_node_count,
1989 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
1990 node_capacity: self.nodes.capacity(),
1991 total_links,
1992 live_links: live_link_count,
1993 dead_links: total_links.saturating_sub(live_link_count),
1994 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
1995 total_extras: self.extras.len(),
1996 live_extras: live_extra_count,
1997 dead_extras: self.extras.len().saturating_sub(live_extra_count),
1998 extra_capacity: self.extras.capacity(),
1999 }
2000 }
2001}
2002
2003fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
2004 if storage.capacity() > max_retained_capacity {
2005 *storage = Vec::new();
2006 } else {
2007 storage.clear();
2008 }
2009}
2010
2011const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
2012 match node {
2013 ArenaRecognizedNode::Token { .. } => 0,
2014 ArenaRecognizedNode::ErrorToken { .. } => 1,
2015 ArenaRecognizedNode::MissingToken { .. } => 2,
2016 ArenaRecognizedNode::Rule { .. } => 3,
2017 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
2018 }
2019}
2020
2021struct NodeSeqIter<'a> {
2022 arena: &'a RecognitionArena,
2023 cursor: NodeSeqId,
2024}
2025
2026impl Iterator for NodeSeqIter<'_> {
2027 type Item = RecognizedNodeId;
2028
2029 fn next(&mut self) -> Option<Self::Item> {
2030 let link = self.arena.link(self.cursor)?;
2031 self.cursor = link.tail;
2032 Some(link.head)
2033 }
2034}
2035
2036struct DiagnosticSeqIter<'a> {
2037 arena: &'a RecognitionArena,
2038 cursor: DiagnosticSeqId,
2039}
2040
2041impl<'a> Iterator for DiagnosticSeqIter<'a> {
2042 type Item = &'a ParserDiagnostic;
2043
2044 fn next(&mut self) -> Option<Self::Item> {
2045 let link = self.arena.diagnostic_link(self.cursor)?;
2046 self.cursor = link.tail;
2047 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2048 unreachable!("diagnostic link must reference diagnostic extra");
2049 };
2050 Some(diagnostic)
2051 }
2052}
2053
2054#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2055struct ParserDiagnostic {
2056 line: usize,
2057 column: usize,
2058 message: String,
2059}
2060
2061#[derive(Clone, Debug, Default, Eq, PartialEq)]
2062struct ExpectedTokens {
2063 index: Option<usize>,
2064 symbols: BTreeSet<i32>,
2065 no_viable: Option<NoViableAlternative>,
2066}
2067
2068#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2069struct NoViableAlternative {
2070 start_index: usize,
2071 error_index: usize,
2072}
2073
2074impl ExpectedTokens {
2075 fn record_transition(
2078 &mut self,
2079 index: usize,
2080 transition: ParserTransition<'_>,
2081 max_token_type: i32,
2082 ) {
2083 let symbols = transition_expected_symbols(transition, max_token_type);
2084 match self.index {
2085 Some(current) if index < current => {}
2086 Some(current) if index == current => self.symbols.extend(symbols),
2087 _ => {
2088 self.index = Some(index);
2089 self.symbols = symbols;
2090 }
2091 }
2092 }
2093
2094 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2097 match self.no_viable {
2098 Some(current) if error_index < current.error_index => {}
2099 _ => {
2100 self.no_viable = Some(NoViableAlternative {
2101 start_index,
2102 error_index,
2103 });
2104 }
2105 }
2106 }
2107}
2108
2109#[derive(Clone, Debug, Default, Eq, PartialEq)]
2116struct TokenBitSet {
2117 words: Vec<u64>,
2118}
2119
2120impl TokenBitSet {
2121 fn insert(&mut self, symbol: i32) {
2122 let Some(slot) = token_bit_slot(symbol) else {
2123 return;
2124 };
2125 let word = slot / u64::BITS as usize;
2126 if word >= self.words.len() {
2127 self.words.resize(word + 1, 0);
2128 }
2129 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2130 }
2131
2132 fn extend_range(&mut self, start: i32, stop: i32) {
2133 let (start, stop) = if start <= stop {
2134 (start, stop)
2135 } else {
2136 (stop, start)
2137 };
2138 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2139 self.insert(TOKEN_EOF);
2140 }
2141 let positive_start = start.max(1);
2142 if positive_start > stop {
2143 return;
2144 }
2145 let Some(start_slot) = token_bit_slot(positive_start) else {
2146 return;
2147 };
2148 let Some(stop_slot) = token_bit_slot(stop) else {
2149 return;
2150 };
2151 self.extend_slot_range(start_slot, stop_slot);
2152 }
2153
2154 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2155 if start_slot > stop_slot {
2156 return;
2157 }
2158 let start_word = start_slot / u64::BITS as usize;
2159 let stop_word = stop_slot / u64::BITS as usize;
2160 if stop_word >= self.words.len() {
2161 self.words.resize(stop_word + 1, 0);
2162 }
2163 let start_offset = start_slot % u64::BITS as usize;
2164 let stop_offset = stop_slot % u64::BITS as usize;
2165 if start_word == stop_word {
2166 self.words[start_word] |=
2167 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2168 return;
2169 }
2170 self.words[start_word] |= !0_u64 << start_offset;
2171 for word in &mut self.words[(start_word + 1)..stop_word] {
2172 *word = !0_u64;
2173 }
2174 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2175 }
2176
2177 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2178 for symbol in symbols {
2179 self.insert(symbol);
2180 }
2181 }
2182
2183 fn extend_from(&mut self, other: &Self) {
2184 if other.words.len() > self.words.len() {
2185 self.words.resize(other.words.len(), 0);
2186 }
2187 for (left, right) in self.words.iter_mut().zip(&other.words) {
2188 *left |= *right;
2189 }
2190 }
2191
2192 fn contains(&self, symbol: i32) -> bool {
2193 let Some(slot) = token_bit_slot(symbol) else {
2194 return false;
2195 };
2196 let word = slot / u64::BITS as usize;
2197 self.words
2198 .get(word)
2199 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2200 }
2201
2202 fn is_empty(&self) -> bool {
2203 self.words.iter().all(|word| *word == 0)
2204 }
2205
2206 fn symbols(&self) -> impl Iterator<Item = i32> + '_ {
2207 self.words
2208 .iter()
2209 .copied()
2210 .enumerate()
2211 .flat_map(|(word_index, mut bits)| {
2212 std::iter::from_fn(move || {
2213 while bits != 0 {
2214 let bit = bits.trailing_zeros() as usize;
2215 bits &= bits - 1;
2216 if let Some(symbol) =
2217 token_bit_symbol(word_index * u64::BITS as usize + bit)
2218 {
2219 return Some(symbol);
2220 }
2221 }
2222 None
2223 })
2224 })
2225 }
2226
2227 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2228 target.extend(self.symbols());
2229 }
2230
2231 fn to_btree_set(&self) -> BTreeSet<i32> {
2232 let mut out = BTreeSet::new();
2233 self.extend_btree_set(&mut out);
2234 out
2235 }
2236}
2237
2238fn token_bit_slot(symbol: i32) -> Option<usize> {
2239 if symbol == TOKEN_EOF {
2240 Some(0)
2241 } else if symbol > 0 {
2242 usize::try_from(symbol).ok()
2243 } else {
2244 None
2245 }
2246}
2247
2248fn token_bit_symbol(slot: usize) -> Option<i32> {
2249 if slot == 0 {
2250 Some(TOKEN_EOF)
2251 } else {
2252 i32::try_from(slot).ok()
2253 }
2254}
2255
2256fn transition_expected_symbols(
2259 transition: ParserTransition<'_>,
2260 max_token_type: i32,
2261) -> BTreeSet<i32> {
2262 let mut symbols = BTreeSet::new();
2263 match &transition.data() {
2264 Transition::Atom { label, .. } => {
2265 symbols.insert(*label);
2266 }
2267 Transition::Range { start, stop, .. } => {
2268 symbols.extend(*start..=*stop);
2269 }
2270 Transition::Set { set, .. } => {
2271 for (start, stop) in set.ranges() {
2272 symbols.extend(start..=stop);
2273 }
2274 }
2275 Transition::NotSet { set, .. } => {
2276 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2277 }
2278 Transition::Wildcard { .. } => {
2279 symbols.extend(1..=max_token_type);
2280 }
2281 Transition::Epsilon { .. }
2282 | Transition::Rule { .. }
2283 | Transition::Predicate { .. }
2284 | Transition::Action { .. }
2285 | Transition::Precedence { .. } => {}
2286 }
2287 symbols
2288}
2289
2290fn transition_expected_token_set(
2291 transition: ParserTransition<'_>,
2292 max_token_type: i32,
2293) -> TokenBitSet {
2294 let mut symbols = TokenBitSet::default();
2295 match &transition.data() {
2296 Transition::Atom { label, .. } => {
2297 symbols.insert(*label);
2298 }
2299 Transition::Range { start, stop, .. } => {
2300 symbols.extend_range(*start, *stop);
2301 }
2302 Transition::Set { set, .. } => {
2303 for (start, stop) in set.ranges() {
2304 symbols.extend_range(start, stop);
2305 }
2306 }
2307 Transition::NotSet { set, .. } => {
2308 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2309 }
2310 Transition::Wildcard { .. } => {
2311 symbols.extend_range(1, max_token_type);
2312 }
2313 Transition::Epsilon { .. }
2314 | Transition::Rule { .. }
2315 | Transition::Predicate { .. }
2316 | Transition::Action { .. }
2317 | Transition::Precedence { .. } => {}
2318 }
2319 symbols
2320}
2321
2322fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2326 let mut symbols = BTreeSet::new();
2327 let mut stack = vec![state_number];
2328 let mut visited = BTreeSet::new();
2329 while let Some(current) = stack.pop() {
2330 if !visited.insert(current) {
2331 continue;
2332 }
2333 let Some(state) = atn.state(current) else {
2334 continue;
2335 };
2336 for transition in &state.transitions() {
2337 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2338 if transition_symbols.is_empty() {
2339 if transition.is_epsilon() {
2340 stack.push(transition.target());
2341 }
2342 } else {
2343 symbols.extend(transition_symbols);
2344 }
2345 }
2346 }
2347 symbols
2348}
2349
2350fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2351 let mut symbols = TokenBitSet::default();
2352 let mut stack = vec![state_number];
2353 let mut visited = BTreeSet::new();
2354 while let Some(current) = stack.pop() {
2355 if !visited.insert(current) {
2356 continue;
2357 }
2358 let Some(state) = atn.state(current) else {
2359 continue;
2360 };
2361 for transition in &state.transitions() {
2362 let transition_symbols =
2363 transition_expected_token_set(transition, atn.max_token_type());
2364 if transition_symbols.is_empty() {
2365 if transition.is_epsilon() {
2366 stack.push(transition.target());
2367 }
2368 } else {
2369 symbols.extend_from(&transition_symbols);
2370 }
2371 }
2372 }
2373 symbols
2374}
2375
2376fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2377 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2378 return false;
2379 };
2380 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2381 return false;
2382 };
2383 epsilon_reaches_state(atn, state_number, stop_state)
2384}
2385
2386fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2387 let mut stack = vec![start];
2388 let mut visited = BTreeSet::new();
2389 while let Some(current) = stack.pop() {
2390 if current == target {
2391 return true;
2392 }
2393 if !visited.insert(current) {
2394 continue;
2395 }
2396 let Some(state) = atn.state(current) else {
2397 continue;
2398 };
2399 stack.extend(
2400 state
2401 .transitions()
2402 .iter()
2403 .filter(|transition| transition.is_epsilon())
2404 .map(ParserTransition::target),
2405 );
2406 }
2407 false
2408}
2409
2410#[derive(Clone, Debug, Default, Eq, PartialEq)]
2417struct FirstSet {
2418 symbols: TokenBitSet,
2419 nullable: bool,
2420}
2421
2422type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2429
2430type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2437
2438#[derive(Debug, Default)]
2439struct LeftRecursiveOperatorLookahead {
2440 single_token: TokenBitSet,
2444 multi_token_prefix: TokenBitSet,
2449 predicate_dependent: TokenBitSet,
2450}
2451
2452#[derive(Default)]
2453struct SharedAtnCache {
2454 first_set: FirstSetCache,
2455 decision_lookahead: DecisionLookaheadCache,
2456 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2457 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2458 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2459 rule_stop_reach: FxHashMap<usize, bool>,
2460 observable_action_transitions: Option<bool>,
2461 predicate_transitions: Option<bool>,
2462}
2463
2464thread_local! {
2465 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2466 RefCell::new(FxHashMap::default());
2467}
2468
2469#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2480struct SharedAtnCacheKey {
2481 atn: usize,
2482 states: usize,
2483 state_count: usize,
2484 max_token_type: i32,
2485}
2486
2487impl SharedAtnCacheKey {
2488 fn for_atn(atn: &Atn) -> Self {
2489 let (states, state_count) = atn.storage_identity();
2490 Self {
2491 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2492 states,
2493 state_count,
2494 max_token_type: atn.max_token_type(),
2495 }
2496 }
2497}
2498
2499fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2500 SHARED_ATN_CACHES.with(|cell| {
2501 let key = SharedAtnCacheKey::for_atn(atn);
2502 let mut map = cell.borrow_mut();
2503 let cache = map.entry(key).or_default();
2504 f(&mut cache.first_set)
2505 })
2506}
2507
2508fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
2509 SHARED_ATN_CACHES.with(|cell| {
2510 let key = SharedAtnCacheKey::for_atn(atn);
2511 let mut map = cell.borrow_mut();
2512 let cache = map.entry(key).or_default();
2513 f(cache)
2514 })
2515}
2516
2517#[derive(Debug, Default)]
2526struct DecisionLookahead {
2527 transitions: Vec<TransitionLookSet>,
2528}
2529
2530#[derive(Clone, Debug, Default)]
2537struct TransitionLookSet {
2538 symbols: TokenBitSet,
2539 nullable: bool,
2540}
2541
2542struct FirstSetCtx<'a> {
2546 cache: &'a mut FirstSetCache,
2547 in_progress: BTreeSet<(usize, usize)>,
2548 hit_cycle: bool,
2549}
2550
2551fn rule_first_set(
2560 atn: &Atn,
2561 target: usize,
2562 rule_stop_state: usize,
2563 cache: &mut FirstSetCache,
2564) -> Rc<FirstSet> {
2565 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
2566 return Rc::clone(cached);
2567 }
2568 let mut ctx = FirstSetCtx {
2569 cache,
2570 in_progress: BTreeSet::new(),
2571 hit_cycle: false,
2572 };
2573 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
2574}
2575
2576fn rule_first_set_cached(
2577 atn: &Atn,
2578 target: usize,
2579 rule_stop_state: usize,
2580 ctx: &mut FirstSetCtx<'_>,
2581) -> Rc<FirstSet> {
2582 let key = (target, rule_stop_state);
2583 if let Some(cached) = ctx.cache.get(&key) {
2584 return Rc::clone(cached);
2585 }
2586 if !ctx.in_progress.insert(key) {
2587 return Rc::new(FirstSet::default());
2591 }
2592 let saved_hit_cycle = ctx.hit_cycle;
2593 ctx.hit_cycle = false;
2594 let mut first = FirstSet::default();
2595 let mut visited = BTreeSet::new();
2596 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
2597 ctx.in_progress.remove(&key);
2598 let entry = Rc::new(first);
2599 if !ctx.hit_cycle {
2600 ctx.cache.insert(key, Rc::clone(&entry));
2601 }
2602 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
2603 entry
2604}
2605
2606fn transition_first_set(
2610 atn: &Atn,
2611 transition: ParserTransition<'_>,
2612 rule_stop_state: usize,
2613 cache: &mut FirstSetCache,
2614) -> TransitionLookSet {
2615 match &transition.data() {
2616 Transition::Atom { label, .. } => {
2617 let mut symbols = TokenBitSet::default();
2618 symbols.insert(*label);
2619 TransitionLookSet {
2620 symbols,
2621 nullable: false,
2622 }
2623 }
2624 Transition::Range { start, stop, .. } => {
2625 let mut symbols = TokenBitSet::default();
2626 symbols.extend_range(*start, *stop);
2627 TransitionLookSet {
2628 symbols,
2629 nullable: false,
2630 }
2631 }
2632 Transition::Set { set, .. } => {
2633 let mut symbols = TokenBitSet::default();
2634 for (start, stop) in set.ranges() {
2635 symbols.extend_range(start, stop);
2636 }
2637 TransitionLookSet {
2638 symbols,
2639 nullable: false,
2640 }
2641 }
2642 Transition::NotSet { set, .. } => {
2643 let max = atn.max_token_type();
2644 let mut symbols = TokenBitSet::default();
2645 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
2646 TransitionLookSet {
2647 symbols,
2648 nullable: false,
2649 }
2650 }
2651 Transition::Wildcard { .. } => {
2652 let mut symbols = TokenBitSet::default();
2653 symbols.extend_range(1, atn.max_token_type());
2654 TransitionLookSet {
2655 symbols,
2656 nullable: false,
2657 }
2658 }
2659 Transition::Epsilon { target }
2660 | Transition::Action { target, .. }
2661 | Transition::Predicate { target, .. }
2662 | Transition::Precedence { target, .. } => {
2663 let first = rule_first_set(atn, *target, rule_stop_state, cache);
2666 TransitionLookSet {
2667 symbols: first.symbols.clone(),
2668 nullable: first.nullable,
2669 }
2670 }
2671 Transition::Rule {
2672 target,
2673 rule_index,
2674 follow_state,
2675 ..
2676 } => {
2677 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2678 return TransitionLookSet::default();
2679 };
2680 let child = rule_first_set(atn, *target, child_stop, cache);
2681 let mut symbols = child.symbols.clone();
2682 let nullable = if child.nullable {
2683 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
2684 symbols.extend_from(&follow.symbols);
2685 follow.nullable
2686 } else {
2687 false
2688 };
2689 TransitionLookSet { symbols, nullable }
2690 }
2691 }
2692}
2693
2694fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
2715 let mut chosen: Option<usize> = None;
2716 for (index, transition) in entry.transitions.iter().enumerate() {
2717 if transition.nullable {
2718 return None;
2719 }
2720 if transition.symbols.contains(symbol) {
2721 if chosen.is_some() {
2722 return None;
2723 }
2724 chosen = Some(index);
2725 }
2726 }
2727 chosen
2728}
2729
2730fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
2739 let mut matching_non_nullable_alt = None;
2740 let mut nullable_alt = None;
2741 for (index, transition) in entry.transitions.iter().enumerate() {
2742 if transition.nullable {
2743 if nullable_alt.is_some() {
2744 return None;
2745 }
2746 nullable_alt = Some(index);
2747 }
2748 if transition.symbols.contains(symbol) {
2749 if transition.nullable {
2750 continue;
2751 }
2752 if matching_non_nullable_alt.is_some() {
2753 return None;
2754 }
2755 matching_non_nullable_alt = Some(index);
2756 }
2757 }
2758 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
2759 return None;
2760 }
2761 if non_greedy {
2762 nullable_alt.or(matching_non_nullable_alt)
2763 } else {
2764 matching_non_nullable_alt.or(nullable_alt)
2765 }
2766}
2767
2768fn should_skip_via_lookahead(
2769 transition_kind: ParserTransitionKind,
2770 transition_index: usize,
2771 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
2772 index: usize,
2773 record_expected: bool,
2774 expected: &mut ExpectedTokens,
2775) -> bool {
2776 let prune_non_consuming = matches!(
2777 transition_kind,
2778 ParserTransitionKind::Epsilon
2779 | ParserTransitionKind::Action
2780 | ParserTransitionKind::Predicate
2781 | ParserTransitionKind::Rule
2782 | ParserTransitionKind::Precedence
2783 );
2784 if !prune_non_consuming {
2785 return false;
2786 }
2787 let Some((symbol, entry)) = lookahead_filter else {
2788 return false;
2789 };
2790 let Some(set) = entry.transitions.get(transition_index) else {
2791 return false;
2792 };
2793 if set.symbols.contains(*symbol) || set.nullable {
2794 return false;
2795 }
2796 if record_expected && !set.symbols.is_empty() {
2797 record_pruned_transition_expected(set, index, expected);
2798 }
2799 true
2800}
2801
2802fn should_skip_rule_via_first_set(
2803 first: &FirstSet,
2804 symbol: i32,
2805 record_expected: bool,
2806 index: usize,
2807 expected: &mut ExpectedTokens,
2808) -> bool {
2809 if first.nullable || first.symbols.contains(symbol) {
2810 return false;
2811 }
2812 if record_expected && !first.symbols.is_empty() {
2813 record_token_bit_expected(&first.symbols, index, expected);
2814 }
2815 true
2816}
2817
2818fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
2819 match expected.index {
2820 Some(current) if index < current => {}
2821 Some(current) if index == current => {
2822 symbols.extend_btree_set(&mut expected.symbols);
2823 }
2824 _ => {
2825 expected.index = Some(index);
2826 expected.symbols = symbols.to_btree_set();
2827 }
2828 }
2829}
2830
2831fn record_pruned_transition_expected(
2833 set: &TransitionLookSet,
2834 index: usize,
2835 expected: &mut ExpectedTokens,
2836) {
2837 match expected.index {
2838 Some(current) if index < current => {}
2839 Some(current) if index == current => {
2840 set.symbols.extend_btree_set(&mut expected.symbols);
2841 }
2842 _ => {
2843 expected.index = Some(index);
2844 expected.symbols = set.symbols.to_btree_set();
2845 }
2846 }
2847}
2848
2849fn rule_first_set_inner(
2850 atn: &Atn,
2851 state_number: usize,
2852 rule_stop_state: usize,
2853 ctx: &mut FirstSetCtx<'_>,
2854 visited: &mut BTreeSet<usize>,
2855 first: &mut FirstSet,
2856) {
2857 if !visited.insert(state_number) {
2858 return;
2859 }
2860 if state_number == rule_stop_state {
2861 first.nullable = true;
2862 return;
2863 }
2864 let Some(state) = atn.state(state_number) else {
2865 return;
2866 };
2867 for transition in &state.transitions() {
2868 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2869 if !transition_symbols.is_empty() {
2870 first.symbols.extend_iter(transition_symbols);
2871 continue;
2872 }
2873 match &transition.data() {
2874 Transition::Epsilon { target }
2875 | Transition::Action { target, .. }
2876 | Transition::Predicate { target, .. }
2877 | Transition::Precedence { target, .. } => {
2878 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
2879 }
2880 Transition::Rule {
2881 target,
2882 rule_index,
2883 follow_state,
2884 ..
2885 } => {
2886 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2887 continue;
2888 };
2889 let child_key = (*target, child_stop);
2890 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
2891 ctx.hit_cycle = true;
2892 }
2893 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
2894 first.symbols.extend_from(&child.symbols);
2895 if child.nullable {
2896 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
2897 }
2898 }
2899 Transition::Atom { .. }
2900 | Transition::Range { .. }
2901 | Transition::Set { .. }
2902 | Transition::NotSet { .. }
2903 | Transition::Wildcard { .. } => {}
2904 }
2905 }
2906}
2907
2908fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
2911 let mut symbols = BTreeSet::new();
2912 state_sync_symbols_inner(
2913 atn,
2914 state_number,
2915 stop_state,
2916 &mut BTreeSet::new(),
2917 &mut symbols,
2918 );
2919 symbols
2920}
2921
2922fn state_sync_symbols_inner(
2925 atn: &Atn,
2926 state_number: usize,
2927 stop_state: usize,
2928 visited: &mut BTreeSet<usize>,
2929 symbols: &mut BTreeSet<i32>,
2930) {
2931 if !visited.insert(state_number) {
2932 return;
2933 }
2934 if state_number == stop_state {
2935 symbols.insert(TOKEN_EOF);
2936 return;
2937 }
2938 let Some(state) = atn.state(state_number) else {
2939 return;
2940 };
2941 for transition in &state.transitions() {
2942 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2943 if transition_symbols.is_empty() {
2944 match &transition.data() {
2945 Transition::Rule { target, .. }
2946 | Transition::Epsilon { target }
2947 | Transition::Action { target, .. }
2948 | Transition::Predicate { target, .. }
2949 | Transition::Precedence { target, .. } => {
2950 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
2951 }
2952 Transition::Atom { .. }
2953 | Transition::Range { .. }
2954 | Transition::Set { .. }
2955 | Transition::NotSet { .. }
2956 | Transition::Wildcard { .. } => {}
2957 }
2958 } else {
2959 symbols.extend(transition_symbols);
2960 }
2961 }
2962}
2963
2964#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
2965struct OperatorSymbolReachability {
2966 single_token: bool,
2968 multi_token: bool,
2970 predicate_dependent: bool,
2972}
2973
2974impl OperatorSymbolReachability {
2975 const ADAPTIVE_FALLBACK: Self = Self {
2976 single_token: false,
2977 multi_token: false,
2978 predicate_dependent: true,
2979 };
2980
2981 const fn single_token(predicate_dependent: bool) -> Self {
2982 if predicate_dependent {
2983 Self {
2984 single_token: false,
2985 multi_token: false,
2986 predicate_dependent: true,
2987 }
2988 } else {
2989 Self {
2990 single_token: true,
2991 multi_token: false,
2992 predicate_dependent: false,
2993 }
2994 }
2995 }
2996
2997 const fn multi_token(predicate_dependent: bool) -> Self {
2998 if predicate_dependent {
2999 Self {
3000 single_token: false,
3001 multi_token: false,
3002 predicate_dependent: true,
3003 }
3004 } else {
3005 Self {
3006 single_token: false,
3007 multi_token: true,
3008 predicate_dependent: false,
3009 }
3010 }
3011 }
3012
3013 const fn union(self, other: Self) -> Self {
3014 Self {
3015 single_token: self.single_token || other.single_token,
3016 multi_token: self.multi_token || other.multi_token,
3017 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
3018 }
3019 }
3020}
3021
3022#[derive(Clone, Copy)]
3023struct OperatorReachabilityRequest {
3024 symbol: i32,
3025 precedence: i32,
3026 predicate_dependent: bool,
3027 operator_rule_index: usize,
3028}
3029
3030#[derive(Clone, Copy, Debug)]
3031struct OperatorRuleContinuation {
3032 stop_state: usize,
3033 follow_state: usize,
3034 return_precedence: i32,
3035}
3036
3037struct NullablePrecedenceCtx {
3038 cache: FxHashMap<(usize, usize, i32, bool), bool>,
3039 in_progress: BTreeSet<(usize, usize, i32, bool)>,
3040 hit_cycle: bool,
3041}
3042
3043fn state_is_nullable_with_precedence(
3044 atn: &Atn,
3045 state_number: usize,
3046 stop_state_number: usize,
3047 precedence: i32,
3048 allow_predicates: bool,
3049 ctx: &mut NullablePrecedenceCtx,
3050) -> bool {
3051 let saved_hit_cycle = ctx.hit_cycle;
3052 ctx.hit_cycle = false;
3053 let nullable = state_is_nullable_with_precedence_cached(
3054 atn,
3055 state_number,
3056 stop_state_number,
3057 precedence,
3058 allow_predicates,
3059 ctx,
3060 );
3061 ctx.hit_cycle = saved_hit_cycle;
3062 nullable
3063}
3064
3065fn state_is_nullable_with_precedence_cached(
3066 atn: &Atn,
3067 state_number: usize,
3068 stop_state_number: usize,
3069 precedence: i32,
3070 allow_predicates: bool,
3071 ctx: &mut NullablePrecedenceCtx,
3072) -> bool {
3073 if state_number == stop_state_number {
3074 return true;
3075 }
3076 let key = (
3077 state_number,
3078 stop_state_number,
3079 precedence,
3080 allow_predicates,
3081 );
3082 if let Some(cached) = ctx.cache.get(&key) {
3083 return *cached;
3084 }
3085 if !ctx.in_progress.insert(key) {
3086 ctx.hit_cycle = true;
3087 return false;
3088 }
3089 let saved_hit_cycle = ctx.hit_cycle;
3090 ctx.hit_cycle = false;
3091 let nullable = atn.state(state_number).is_some_and(|state| {
3092 state
3093 .transitions()
3094 .iter()
3095 .any(|transition| match &transition.data() {
3096 Transition::Rule {
3097 target,
3098 rule_index,
3099 follow_state,
3100 precedence: rule_precedence,
3101 } => {
3102 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3103 return false;
3104 };
3105 state_is_nullable_with_precedence_cached(
3106 atn,
3107 *target,
3108 child_stop,
3109 *rule_precedence,
3110 allow_predicates,
3111 ctx,
3112 ) && state_is_nullable_with_precedence_cached(
3113 atn,
3114 *follow_state,
3115 stop_state_number,
3116 precedence,
3117 allow_predicates,
3118 ctx,
3119 )
3120 }
3121 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3122 state_is_nullable_with_precedence_cached(
3123 atn,
3124 *target,
3125 stop_state_number,
3126 precedence,
3127 allow_predicates,
3128 ctx,
3129 )
3130 }
3131 Transition::Predicate { target, .. } if allow_predicates => {
3132 state_is_nullable_with_precedence_cached(
3133 atn,
3134 *target,
3135 stop_state_number,
3136 precedence,
3137 allow_predicates,
3138 ctx,
3139 )
3140 }
3141 Transition::Precedence {
3142 target,
3143 precedence: transition_precedence,
3144 } if *transition_precedence >= precedence => {
3145 state_is_nullable_with_precedence_cached(
3146 atn,
3147 *target,
3148 stop_state_number,
3149 precedence,
3150 allow_predicates,
3151 ctx,
3152 )
3153 }
3154 Transition::Atom { .. }
3155 | Transition::Range { .. }
3156 | Transition::Set { .. }
3157 | Transition::NotSet { .. }
3158 | Transition::Wildcard { .. }
3159 | Transition::Predicate { .. }
3160 | Transition::Precedence { .. } => false,
3161 })
3162 });
3163 ctx.in_progress.remove(&key);
3164 if !ctx.hit_cycle {
3165 ctx.cache.insert(key, nullable);
3166 }
3167 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3168 nullable
3169}
3170
3171fn state_operator_token_prefix_reachability(
3173 atn: &Atn,
3174 state_number: usize,
3175 request: OperatorReachabilityRequest,
3176 continuations: &[OperatorRuleContinuation],
3177 visited: &mut BTreeSet<(usize, i32, bool)>,
3178) -> OperatorSymbolReachability {
3179 let key = (
3180 state_number,
3181 request.precedence,
3182 request.predicate_dependent,
3183 );
3184 if !visited.insert(key) {
3185 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3189 }
3190 if let Some((continuation, remaining)) = continuations.split_last()
3191 && state_number == continuation.stop_state
3192 {
3193 let result = state_operator_token_prefix_reachability(
3194 atn,
3195 continuation.follow_state,
3196 OperatorReachabilityRequest {
3197 precedence: continuation.return_precedence,
3198 ..request
3199 },
3200 remaining,
3201 visited,
3202 );
3203 visited.remove(&key);
3204 return result;
3205 }
3206 let Some(state) = atn.state(state_number) else {
3207 visited.remove(&key);
3208 return OperatorSymbolReachability::default();
3209 };
3210 let completes_operator = match state.kind() {
3211 AtnStateKind::RuleStop => continuations.is_empty(),
3212 AtnStateKind::StarLoopBack
3213 | AtnStateKind::StarLoopEntry
3214 | AtnStateKind::PlusLoopBack
3215 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3216 _ => false,
3217 };
3218 if completes_operator {
3219 visited.remove(&key);
3220 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3221 }
3222 let mut reachability = OperatorSymbolReachability::default();
3223 for transition in &state.transitions() {
3224 let transition_reachability = match &transition.data() {
3225 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3226 OperatorSymbolReachability::single_token(request.predicate_dependent)
3227 }
3228 Transition::Rule {
3229 target,
3230 rule_index,
3231 follow_state,
3232 precedence: rule_precedence,
3233 } => {
3234 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3235 continue;
3236 };
3237 let mut nested = continuations.to_vec();
3238 nested.push(OperatorRuleContinuation {
3239 stop_state: child_stop,
3240 follow_state: *follow_state,
3241 return_precedence: request.precedence,
3242 });
3243 state_operator_token_prefix_reachability(
3244 atn,
3245 *target,
3246 OperatorReachabilityRequest {
3247 precedence: *rule_precedence,
3248 ..request
3249 },
3250 &nested,
3251 visited,
3252 )
3253 }
3254 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3255 state_operator_token_prefix_reachability(
3256 atn,
3257 *target,
3258 request,
3259 continuations,
3260 visited,
3261 )
3262 }
3263 Transition::Precedence {
3264 target,
3265 precedence: transition_precedence,
3266 } => {
3267 if *transition_precedence < request.precedence {
3268 OperatorSymbolReachability::default()
3269 } else {
3270 state_operator_token_prefix_reachability(
3271 atn,
3272 *target,
3273 request,
3274 continuations,
3275 visited,
3276 )
3277 }
3278 }
3279 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3280 atn,
3281 *target,
3282 OperatorReachabilityRequest {
3283 predicate_dependent: true,
3284 ..request
3285 },
3286 continuations,
3287 visited,
3288 ),
3289 Transition::Atom { .. }
3290 | Transition::Range { .. }
3291 | Transition::Set { .. }
3292 | Transition::NotSet { .. }
3293 | Transition::Wildcard { .. } => {
3294 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3295 }
3296 };
3297 reachability = reachability.union(transition_reachability);
3298 }
3299 visited.remove(&key);
3300 reachability
3301}
3302
3303fn state_can_reach_symbol_with_precedence(
3304 atn: &Atn,
3305 state_number: usize,
3306 request: OperatorReachabilityRequest,
3307 nullable_ctx: &mut NullablePrecedenceCtx,
3308 continuations: &mut Vec<OperatorRuleContinuation>,
3309 visited: &mut BTreeSet<(usize, i32, bool)>,
3310) -> OperatorSymbolReachability {
3311 let key = (
3312 state_number,
3313 request.precedence,
3314 request.predicate_dependent,
3315 );
3316 if !visited.insert(key) {
3317 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3318 }
3319 let Some(state) = atn.state(state_number) else {
3320 visited.remove(&key);
3321 return OperatorSymbolReachability::default();
3322 };
3323 let mut reachability = OperatorSymbolReachability::default();
3324 for transition in &state.transitions() {
3325 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3326 reachability = reachability.union(state_operator_token_prefix_reachability(
3327 atn,
3328 transition.target(),
3329 request,
3330 continuations,
3331 &mut BTreeSet::new(),
3332 ));
3333 continue;
3334 }
3335 let transition_reachability = match &transition.data() {
3336 Transition::Rule {
3337 target,
3338 rule_index,
3339 follow_state,
3340 precedence: rule_precedence,
3341 } => {
3342 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3343 continue;
3344 };
3345 continuations.push(OperatorRuleContinuation {
3346 stop_state: child_stop,
3347 follow_state: *follow_state,
3348 return_precedence: request.precedence,
3349 });
3350 let mut result = state_can_reach_symbol_with_precedence(
3351 atn,
3352 *target,
3353 OperatorReachabilityRequest {
3354 precedence: *rule_precedence,
3355 ..request
3356 },
3357 nullable_ctx,
3358 continuations,
3359 visited,
3360 );
3361 continuations.pop();
3362 if state_is_nullable_with_precedence(
3363 atn,
3364 *target,
3365 child_stop,
3366 *rule_precedence,
3367 true,
3368 nullable_ctx,
3369 ) {
3370 let child_predicate_dependent = request.predicate_dependent
3371 || !state_is_nullable_with_precedence(
3372 atn,
3373 *target,
3374 child_stop,
3375 *rule_precedence,
3376 false,
3377 nullable_ctx,
3378 );
3379 result = result.union(state_can_reach_symbol_with_precedence(
3380 atn,
3381 *follow_state,
3382 OperatorReachabilityRequest {
3383 predicate_dependent: child_predicate_dependent,
3384 ..request
3385 },
3386 nullable_ctx,
3387 continuations,
3388 visited,
3389 ));
3390 }
3391 result
3392 }
3393 Transition::Epsilon { target }
3394 | Transition::Action { target, .. }
3395 | Transition::Precedence { target, .. } => {
3396 if matches!(
3397 &transition.data(),
3398 Transition::Precedence {
3399 precedence: transition_precedence,
3400 ..
3401 } if *transition_precedence < request.precedence
3402 ) {
3403 continue;
3404 }
3405 state_can_reach_symbol_with_precedence(
3406 atn,
3407 *target,
3408 request,
3409 nullable_ctx,
3410 continuations,
3411 visited,
3412 )
3413 }
3414 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3415 atn,
3416 *target,
3417 OperatorReachabilityRequest {
3418 predicate_dependent: true,
3419 ..request
3420 },
3421 nullable_ctx,
3422 continuations,
3423 visited,
3424 ),
3425 Transition::Atom { .. }
3426 | Transition::Range { .. }
3427 | Transition::Set { .. }
3428 | Transition::NotSet { .. }
3429 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3430 };
3431 reachability = reachability.union(transition_reachability);
3432 }
3433 visited.remove(&key);
3434 reachability
3435}
3436
3437fn left_recursive_operator_lookahead(
3438 atn: &Atn,
3439 state_number: usize,
3440 precedence: i32,
3441) -> LeftRecursiveOperatorLookahead {
3442 let Some(state) = atn.state(state_number) else {
3443 return LeftRecursiveOperatorLookahead::default();
3444 };
3445 let Some(operator_rule_index) = state.rule_index() else {
3446 return LeftRecursiveOperatorLookahead::default();
3447 };
3448 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3449 let mut nullable_ctx = NullablePrecedenceCtx {
3450 cache: FxHashMap::default(),
3451 in_progress: BTreeSet::new(),
3452 hit_cycle: false,
3453 };
3454 for transition in &state.transitions() {
3455 let target = transition.target();
3456 if atn
3457 .state(target)
3458 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3459 {
3460 continue;
3461 }
3462 for symbol in 1..=atn.max_token_type() {
3463 let reachability = state_can_reach_symbol_with_precedence(
3464 atn,
3465 target,
3466 OperatorReachabilityRequest {
3467 symbol,
3468 precedence,
3469 predicate_dependent: false,
3470 operator_rule_index,
3471 },
3472 &mut nullable_ctx,
3473 &mut Vec::new(),
3474 &mut BTreeSet::new(),
3475 );
3476 if reachability.single_token {
3477 lookahead.single_token.insert(symbol);
3478 }
3479 if reachability.multi_token {
3480 lookahead.multi_token_prefix.insert(symbol);
3481 }
3482 if reachability.predicate_dependent {
3483 lookahead.predicate_dependent.insert(symbol);
3484 }
3485 }
3486 }
3487 lookahead
3488}
3489
3490#[derive(Debug, Default)]
3491struct StateBeforeStopLookahead {
3492 symbols: TokenBitSet,
3493 reaches_context_boundary: bool,
3494}
3495
3496fn state_before_stop_lookahead(
3497 atn: &Atn,
3498 state_number: usize,
3499 stop_state_number: usize,
3500) -> Rc<StateBeforeStopLookahead> {
3501 with_shared_atn_caches(atn, |cache| {
3502 let key = (state_number, stop_state_number);
3503 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
3504 return Rc::clone(cached);
3505 }
3506 let mut lookahead = StateBeforeStopLookahead::default();
3507 state_before_stop_lookahead_inner(
3508 atn,
3509 state_number,
3510 stop_state_number,
3511 &mut BTreeSet::new(),
3512 &mut cache.first_set,
3513 &mut lookahead,
3514 );
3515 let lookahead = Rc::new(lookahead);
3516 cache
3517 .state_before_stop_lookahead
3518 .insert(key, Rc::clone(&lookahead));
3519 lookahead
3520 })
3521}
3522
3523fn state_before_stop_lookahead_inner(
3524 atn: &Atn,
3525 state_number: usize,
3526 stop_state_number: usize,
3527 visited: &mut BTreeSet<usize>,
3528 first_set_cache: &mut FirstSetCache,
3529 lookahead: &mut StateBeforeStopLookahead,
3530) {
3531 if state_number == stop_state_number {
3532 lookahead.reaches_context_boundary = true;
3533 return;
3534 }
3535 if !visited.insert(state_number) {
3536 return;
3537 }
3538 let Some(state) = atn.state(state_number) else {
3539 return;
3540 };
3541 if state.kind() == AtnStateKind::RuleStop {
3542 lookahead.reaches_context_boundary = true;
3543 return;
3544 }
3545 for transition in &state.transitions() {
3546 match &transition.data() {
3547 Transition::Epsilon { target }
3548 | Transition::Action { target, .. }
3549 | Transition::Predicate { target, .. }
3550 | Transition::Precedence { target, .. } => {
3551 state_before_stop_lookahead_inner(
3552 atn,
3553 *target,
3554 stop_state_number,
3555 visited,
3556 first_set_cache,
3557 lookahead,
3558 );
3559 }
3560 Transition::Rule {
3561 target,
3562 rule_index,
3563 follow_state,
3564 ..
3565 } => {
3566 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3567 continue;
3568 };
3569 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
3570 lookahead.symbols.extend_from(&child.symbols);
3571 if child.nullable {
3572 state_before_stop_lookahead_inner(
3573 atn,
3574 *follow_state,
3575 stop_state_number,
3576 visited,
3577 first_set_cache,
3578 lookahead,
3579 );
3580 }
3581 }
3582 Transition::Atom { .. }
3583 | Transition::Range { .. }
3584 | Transition::Set { .. }
3585 | Transition::NotSet { .. }
3586 | Transition::Wildcard { .. } => {
3587 lookahead.symbols.extend_iter(transition_expected_symbols(
3588 transition,
3589 atn.max_token_type(),
3590 ));
3591 }
3592 }
3593 }
3594}
3595
3596fn caller_context_can_match_symbol_before_state(
3597 atn: &Atn,
3598 return_states: impl DoubleEndedIterator<Item = usize>,
3599 stop_state_number: usize,
3600 symbol: i32,
3601) -> bool {
3602 for return_state in return_states.rev() {
3603 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
3604 if lookahead.symbols.contains(symbol) {
3605 return true;
3606 }
3607 if !lookahead.reaches_context_boundary {
3608 return false;
3609 }
3610 }
3611 false
3612}
3613
3614fn next_recovery_context(
3618 atn: &Atn,
3619 state: AtnState<'_>,
3620 inherited: &BTreeSet<i32>,
3621 inherited_state: Option<usize>,
3622) -> (BTreeSet<i32>, Option<usize>) {
3623 let state_symbols = state_expected_symbols(atn, state.state_number());
3624 if state.transitions().len() > 1 && !state_symbols.is_empty() {
3625 let mut symbols = state_symbols;
3626 symbols.extend(inherited.iter().copied());
3627 return (symbols, Some(state.state_number()));
3628 }
3629 (inherited.clone(), inherited_state)
3630}
3631
3632fn recovery_expected_symbols(
3633 atn: &Atn,
3634 state_number: usize,
3635 inherited: &BTreeSet<i32>,
3636) -> BTreeSet<i32> {
3637 let mut symbols = state_expected_symbols(atn, state_number);
3638 symbols.extend(inherited.iter().copied());
3639 symbols
3640}
3641
3642fn fast_next_recovery_context<S, H>(
3646 parser: &mut BaseParser<S, H>,
3647 atn: &Atn,
3648 state: AtnState<'_>,
3649 inherited: &Rc<BTreeSet<i32>>,
3650 inherited_state: Option<usize>,
3651) -> (Rc<BTreeSet<i32>>, Option<usize>)
3652where
3653 S: TokenSource,
3654 H: SemanticHooks,
3655{
3656 if state.transitions().len() <= 1 {
3657 return (Rc::clone(inherited), inherited_state);
3658 }
3659 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
3660 if state_symbols.is_empty() {
3661 return (Rc::clone(inherited), inherited_state);
3662 }
3663 if inherited.is_empty() {
3664 return (state_symbols, Some(state.state_number()));
3665 }
3666 if Rc::ptr_eq(&state_symbols, inherited) {
3667 return (state_symbols, Some(state.state_number()));
3668 }
3669 let mut combined = (*state_symbols).clone();
3670 combined.extend(inherited.iter().copied());
3671 (
3672 parser.intern_recovery_symbols(combined),
3673 Some(state.state_number()),
3674 )
3675}
3676
3677fn fast_recovery_expected_symbols<S, H>(
3681 parser: &mut BaseParser<S, H>,
3682 atn: &Atn,
3683 state_number: usize,
3684 inherited: &Rc<BTreeSet<i32>>,
3685) -> Rc<BTreeSet<i32>>
3686where
3687 S: TokenSource,
3688 H: SemanticHooks,
3689{
3690 let cached = parser.cached_state_expected_symbols(atn, state_number);
3691 if inherited.is_empty() {
3692 return cached;
3693 }
3694 if cached.is_empty() {
3695 return Rc::clone(inherited);
3696 }
3697 if Rc::ptr_eq(&cached, inherited) {
3698 return cached;
3699 }
3700 let mut combined = (*cached).clone();
3701 combined.extend(inherited.iter().copied());
3702 parser.intern_recovery_symbols(combined)
3703}
3704
3705struct ParserTableSemCtx<'a> {
3706 member_values: &'a mut BTreeMap<usize, i64>,
3707 return_values: &'a mut BTreeMap<String, i64>,
3708}
3709
3710impl semir::PredContext for ParserTableSemCtx<'_> {
3711 type TokenText<'a>
3712 = &'a str
3713 where
3714 Self: 'a;
3715
3716 fn la(&mut self, _offset: isize) -> i64 {
3717 i64::from(TOKEN_EOF)
3718 }
3719
3720 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
3721 None
3722 }
3723
3724 fn token_index_adjacent(&mut self) -> bool {
3725 false
3726 }
3727
3728 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
3729 None
3730 }
3731
3732 fn member(&self, member: usize) -> Option<i64> {
3733 Some(self.member_values.get(&member).copied().unwrap_or_default())
3734 }
3735
3736 fn local_arg(&self) -> Option<i64> {
3737 None
3738 }
3739
3740 fn column(&self) -> Option<i64> {
3741 None
3742 }
3743
3744 fn token_start_column(&self) -> Option<i64> {
3745 None
3746 }
3747
3748 fn token_text_so_far(&self) -> Option<String> {
3749 None
3750 }
3751
3752 fn hook(&mut self, _hook: HookId) -> bool {
3753 false
3754 }
3755}
3756
3757impl semir::ActContext for ParserTableSemCtx<'_> {
3758 fn set_member(&mut self, member: usize, value: i64) {
3759 self.member_values.insert(member, value);
3760 }
3761
3762 fn set_return(&mut self, name: &str, value: i64) {
3763 self.return_values.insert(name.to_owned(), value);
3764 }
3765
3766 fn action_hook(&mut self, _hook: HookId) {}
3767}
3768
3769fn apply_member_actions(
3771 source_state: usize,
3772 actions: &[ParserMemberAction],
3773 semantics: Option<&ParserSemantics>,
3774 values: &mut BTreeMap<usize, i64>,
3775) {
3776 for action in actions
3777 .iter()
3778 .filter(|action| action.source_state == source_state)
3779 {
3780 *values.entry(action.member).or_default() += action.delta;
3781 }
3782 let Some(semantics) = semantics else {
3783 return;
3784 };
3785 let mut return_values = BTreeMap::new();
3786 let mut ctx = ParserTableSemCtx {
3787 member_values: values,
3788 return_values: &mut return_values,
3789 };
3790 for action in semantics
3791 .actions
3792 .iter()
3793 .filter(|action| action.source_state == source_state && action.speculative)
3794 {
3795 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3796 }
3797}
3798
3799fn member_values_after_action(
3801 source_state: usize,
3802 actions: &[ParserMemberAction],
3803 semantics: Option<&ParserSemantics>,
3804 values: &BTreeMap<usize, i64>,
3805) -> BTreeMap<usize, i64> {
3806 let mut values = values.clone();
3807 apply_member_actions(source_state, actions, semantics, &mut values);
3808 values
3809}
3810
3811fn return_values_after_action(
3813 source_state: usize,
3814 rule_index: usize,
3815 actions: &[ParserReturnAction],
3816 semantics: Option<&ParserSemantics>,
3817 values: &BTreeMap<String, i64>,
3818) -> BTreeMap<String, i64> {
3819 let mut values = values.clone();
3820 for action in actions
3821 .iter()
3822 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
3823 {
3824 values.insert(action.name.to_owned(), action.value);
3825 }
3826 if let Some(semantics) = semantics {
3827 let mut member_values = BTreeMap::new();
3828 let mut ctx = ParserTableSemCtx {
3829 member_values: &mut member_values,
3830 return_values: &mut values,
3831 };
3832 for action in semantics.actions.iter().filter(|action| {
3833 action.source_state == source_state
3834 && action.rule_index == rule_index
3835 && !action.speculative
3836 }) {
3837 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
3838 }
3839 }
3840 values
3841}
3842
3843fn rule_local_int_arg(
3845 rule_args: &[ParserRuleArg],
3846 source_state: usize,
3847 rule_index: usize,
3848 local_int_arg: Option<(usize, i64)>,
3849) -> Option<(usize, i64)> {
3850 rule_args
3851 .iter()
3852 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
3853 .map(|arg| {
3854 let value = if arg.inherit_local {
3855 local_int_arg.map_or(arg.value, |(_, value)| value)
3856 } else {
3857 arg.value
3858 };
3859 (rule_index, value)
3860 })
3861}
3862
3863fn stop_outcome(
3866 index: usize,
3867 consumed_eof: bool,
3868 rule_alt_number: usize,
3869 member_values: BTreeMap<usize, i64>,
3870 return_values: BTreeMap<String, i64>,
3871) -> Vec<RecognizeOutcome> {
3872 vec![RecognizeOutcome {
3873 index,
3874 consumed_eof,
3875 alt_number: rule_alt_number,
3876 member_values,
3877 return_values,
3878 diagnostics: DiagnosticSeqId::EMPTY,
3879 decisions: Vec::new(),
3880 actions: Vec::new(),
3881 nodes: NodeSeqId::EMPTY,
3882 }]
3883}
3884
3885fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
3886 with_shared_atn_caches(atn, |cache| {
3887 *cache.observable_action_transitions.get_or_insert_with(|| {
3888 atn.states().any(|state| {
3889 state.transitions().iter().any(|transition| {
3890 matches!(
3891 &transition.data(),
3892 Transition::Action {
3893 action_index: Some(_),
3894 ..
3895 }
3896 )
3897 })
3898 })
3899 })
3900 })
3901}
3902
3903fn atn_has_predicate_transitions(atn: &Atn) -> bool {
3904 with_shared_atn_caches(atn, |cache| {
3905 *cache.predicate_transitions.get_or_insert_with(|| {
3906 atn.states().any(|state| {
3907 state
3908 .transitions()
3909 .iter()
3910 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
3911 })
3912 })
3913 })
3914}
3915
3916fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
3921 options.init_action_rules.is_empty()
3922 && !options.track_alt_numbers
3923 && options
3924 .predicates
3925 .iter()
3926 .all(|(_, _, predicate)| predicate.failure_message().is_none())
3927 && options.semantics.is_none_or(|semantics| {
3928 semantics.actions.is_empty()
3929 && semantics
3930 .predicates
3931 .iter()
3932 .all(|predicate| predicate.failure_message.is_none())
3933 })
3934 && options.rule_args.is_empty()
3935 && options.member_actions.is_empty()
3936 && options.return_actions.is_empty()
3937 && !atn_has_observable_action_transitions(atn)
3938}
3939
3940#[derive(Clone, Debug, Eq, PartialEq)]
3941struct RecognizeRequest<'a> {
3942 state_number: usize,
3943 stop_state: usize,
3944 index: usize,
3945 rule_start_index: usize,
3946 decision_start_index: Option<usize>,
3947 init_action_rules: &'a BTreeSet<usize>,
3948 predicates: &'a [(usize, usize, ParserPredicate)],
3949 semantics: Option<&'a ParserSemantics>,
3950 rule_args: &'a [ParserRuleArg],
3951 member_actions: &'a [ParserMemberAction],
3952 return_actions: &'a [ParserReturnAction],
3953 local_int_arg: Option<(usize, i64)>,
3954 member_values: BTreeMap<usize, i64>,
3955 return_values: BTreeMap<String, i64>,
3956 rule_alt_number: usize,
3957 track_alt_numbers: bool,
3958 consumed_eof: bool,
3959 precedence: i32,
3962 depth: usize,
3963 recovery_symbols: BTreeSet<i32>,
3964 recovery_state: Option<usize>,
3965}
3966
3967#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
3968struct RecognizeKey {
3969 state_number: usize,
3970 stop_state: usize,
3971 index: usize,
3972 rule_start_index: usize,
3973 decision_start_index: Option<usize>,
3974 local_int_arg: Option<(usize, i64)>,
3975 member_values: BTreeMap<usize, i64>,
3976 return_values: BTreeMap<String, i64>,
3977 rule_alt_number: usize,
3978 track_alt_numbers: bool,
3979 consumed_eof: bool,
3980 precedence: i32,
3981 recovery_symbols: BTreeSet<i32>,
3982 recovery_state: Option<usize>,
3983}
3984
3985#[derive(Clone, Debug, Eq, PartialEq)]
3986struct EpsilonActionStep {
3987 source_state: usize,
3988 target: usize,
3989 action_rule_index: Option<usize>,
3990 left_recursive_boundary: Option<usize>,
3991 decision: Option<usize>,
3992 decision_start_index: Option<usize>,
3993 alt_number: usize,
3994 recovery_symbols: BTreeSet<i32>,
3995 recovery_state: Option<usize>,
3996}
3997
3998struct RecognizeScratch<'a> {
3999 visiting: &'a mut BTreeSet<RecognizeKey>,
4000 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4001 expected: &'a mut ExpectedTokens,
4002}
4003
4004#[derive(Clone, Debug, Eq, PartialEq)]
4005struct FastRecognizeRequest {
4006 state_number: usize,
4007 stop_state: usize,
4008 index: usize,
4009 rule_start_index: usize,
4010 decision_start_index: Option<usize>,
4011 precedence: i32,
4012 depth: usize,
4013 recovery_symbols: Rc<BTreeSet<i32>>,
4014 recovery_state: Option<usize>,
4015}
4016
4017#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4018struct FastRecognizeTopRequest {
4019 start_state: usize,
4020 stop_state: usize,
4021 start_index: usize,
4022 precedence: i32,
4023 caller_follow_state: Option<usize>,
4024}
4025
4026#[derive(Clone, Copy, Debug)]
4027struct FastPredicateContext<'a> {
4028 predicates: &'a [(usize, usize, ParserPredicate)],
4029 semantics: Option<&'a ParserSemantics>,
4030 member_values: &'a BTreeMap<usize, i64>,
4031}
4032
4033struct FastRecognizeScratch<'a, 'b> {
4034 predicate_context: Option<FastPredicateContext<'a>>,
4035 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4036 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4037 expected: &'b mut ExpectedTokens,
4038 native_depth: usize,
4039}
4040
4041#[derive(Clone, Copy, Debug)]
4042struct FastRepetitionShape {
4043 enter_target: usize,
4044 exit_target: usize,
4045 body_stop_state: usize,
4046 enter_transition_index: usize,
4047 exit_transition_index: usize,
4048}
4049
4050#[derive(Clone, Copy, Debug)]
4051struct FastRepetitionPath {
4052 index: usize,
4053 deferred_nodes: FastDeferredNodeId,
4054 diagnostics: DiagnosticSeqId,
4055 consumed_eof: bool,
4056}
4057
4058enum FastRepetitionWork {
4059 Enter(FastRepetitionPath),
4060 Exit(FastRepetitionPath),
4061}
4062
4063struct FastRepetitionCoordinates {
4068 base_index: usize,
4069 base_state: u8,
4070 later_states: Vec<u8>,
4071}
4072
4073impl FastRepetitionCoordinates {
4074 const ENTERED: u8 = 0;
4075 const EXITED: u8 = 2;
4076
4077 const fn new(base_index: usize) -> Self {
4078 Self {
4079 base_index,
4080 base_state: 0,
4081 later_states: Vec::new(),
4082 }
4083 }
4084
4085 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4086 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4087 }
4088
4089 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4090 self.insert(path.index, path.consumed_eof, Self::EXITED)
4091 }
4092
4093 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4094 let Some(offset) = index.checked_sub(self.base_index) else {
4095 return false;
4096 };
4097 let state = if offset == 0 {
4098 &mut self.base_state
4099 } else {
4100 if self.later_states.len() < offset {
4101 self.later_states.resize(offset, 0);
4102 }
4103 &mut self.later_states[offset - 1]
4104 };
4105 let bit = 1 << (base_bit + u8::from(consumed_eof));
4106 let is_new = *state & bit == 0;
4107 *state |= bit;
4108 is_new
4109 }
4110}
4111
4112fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4113 if state.precedence_rule_decision()
4114 || !matches!(
4115 state.kind(),
4116 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4117 )
4118 || state.transitions().len() != 2
4119 {
4120 return None;
4121 }
4122 let mut enter = None;
4123 let mut exit = None;
4124 for (index, transition) in state.transitions().iter().enumerate() {
4125 if transition.kind() != ParserTransitionKind::Epsilon {
4126 return None;
4127 }
4128 let target = transition.target();
4129 if atn
4130 .state(target)
4131 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4132 {
4133 if exit.replace((index, target)).is_some() {
4134 return None;
4135 }
4136 } else if enter.replace((index, target)).is_some() {
4137 return None;
4138 }
4139 }
4140 let (enter_transition_index, enter_target) = enter?;
4141 let (exit_transition_index, exit_target) = exit?;
4142 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4143 atn.state(exit_target)?.loop_back_state()?
4144 } else {
4145 state.state_number()
4146 };
4147 Some(FastRepetitionShape {
4148 enter_target,
4149 exit_target,
4150 body_stop_state,
4151 enter_transition_index,
4152 exit_transition_index,
4153 })
4154}
4155
4156fn push_fast_repetition_work(
4157 work: &mut Vec<FastRepetitionWork>,
4158 shape: FastRepetitionShape,
4159 path: FastRepetitionPath,
4160 lookahead: Option<&DecisionLookahead>,
4161 symbol: i32,
4162) {
4163 let transition_is_viable = |transition_index: usize| {
4166 let Some(entry) = lookahead else {
4167 return true;
4168 };
4169 let Some(transition) = entry.transitions.get(transition_index) else {
4170 return true;
4171 };
4172 transition.nullable || transition.symbols.contains(symbol)
4173 };
4174 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4175 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4176 if shape.enter_transition_index < shape.exit_transition_index {
4177 if exit_is_viable {
4178 work.push(FastRepetitionWork::Exit(path));
4179 }
4180 if enter_is_viable {
4181 work.push(FastRepetitionWork::Enter(path));
4182 }
4183 } else {
4184 if enter_is_viable {
4185 work.push(FastRepetitionWork::Enter(path));
4186 }
4187 if exit_is_viable {
4188 work.push(FastRepetitionWork::Exit(path));
4189 }
4190 }
4191}
4192
4193#[derive(Clone, Debug)]
4200struct FastRecognizeKey {
4201 state_number: usize,
4202 stop_state: usize,
4203 index: usize,
4204 rule_start_index: usize,
4205 decision_start_index: Option<usize>,
4206 precedence: i32,
4207 recovery_symbols_id: usize,
4208 recovery_state: Option<usize>,
4209}
4210
4211impl PartialEq for FastRecognizeKey {
4212 fn eq(&self, other: &Self) -> bool {
4213 if self.state_number != other.state_number
4214 || self.stop_state != other.stop_state
4215 || self.index != other.index
4216 || self.rule_start_index != other.rule_start_index
4217 || self.decision_start_index != other.decision_start_index
4218 || self.precedence != other.precedence
4219 || self.recovery_state != other.recovery_state
4220 || self.recovery_symbols_id != other.recovery_symbols_id
4221 {
4222 return false;
4223 }
4224 true
4225 }
4226}
4227
4228impl Eq for FastRecognizeKey {}
4229
4230impl Hash for FastRecognizeKey {
4231 fn hash<H: Hasher>(&self, hasher: &mut H) {
4232 self.state_number.hash(hasher);
4233 self.stop_state.hash(hasher);
4234 self.index.hash(hasher);
4235 self.rule_start_index.hash(hasher);
4236 self.decision_start_index.hash(hasher);
4237 self.precedence.hash(hasher);
4238 self.recovery_state.hash(hasher);
4239 self.recovery_symbols_id.hash(hasher);
4240 }
4241}
4242
4243struct FastRecoveryRequest<'a, 'b> {
4244 atn: &'a Atn,
4245 transition: ParserTransition<'a>,
4246 expected_symbols: Rc<BTreeSet<i32>>,
4247 target: usize,
4248 request: FastRecognizeRequest,
4249 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4250 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4251 expected: &'b mut ExpectedTokens,
4252}
4253
4254struct FastCurrentTokenDeletionRequest<'a, 'b> {
4255 atn: &'a Atn,
4256 expected_symbols: Rc<BTreeSet<i32>>,
4257 request: FastRecognizeRequest,
4258 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4259 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4260 expected: &'b mut ExpectedTokens,
4261}
4262
4263#[derive(Clone, Copy)]
4264struct FastChildRuleFailureRecoveryRequest<'a> {
4265 atn: &'a Atn,
4266 rule_index: usize,
4267 start_index: usize,
4268 follow_state: usize,
4269 stop_state: usize,
4270 expected: &'a ExpectedTokens,
4271}
4272
4273struct RecoveryRequest<'a, 'b> {
4274 atn: &'a Atn,
4275 transition: ParserTransition<'a>,
4276 expected_symbols: BTreeSet<i32>,
4277 target: usize,
4278 request: RecognizeRequest<'a>,
4279 visiting: &'b mut BTreeSet<RecognizeKey>,
4280 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4281 expected: &'b mut ExpectedTokens,
4282}
4283
4284struct CurrentTokenDeletionRequest<'a, 'b> {
4285 atn: &'a Atn,
4286 expected_symbols: BTreeSet<i32>,
4287 request: RecognizeRequest<'a>,
4288 visiting: &'b mut BTreeSet<RecognizeKey>,
4289 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4290 expected: &'b mut ExpectedTokens,
4291}
4292
4293struct ConsumingFailureFallback<'a> {
4296 atn: &'a Atn,
4297 target: usize,
4298 request: RecognizeRequest<'a>,
4299 symbol: i32,
4300 expected_symbols: BTreeSet<i32>,
4301 decision_start_index: Option<usize>,
4302 decision: Option<usize>,
4303}
4304
4305struct ChildRuleFailureRecovery<'a> {
4308 atn: &'a Atn,
4309 rule_index: usize,
4310 start_index: usize,
4311 follow_state: usize,
4312 stop_state: usize,
4313 member_values: BTreeMap<usize, i64>,
4314 expected: &'a ExpectedTokens,
4315}
4316
4317#[derive(Clone, Copy, Debug)]
4319struct PredicateEval<'a> {
4320 index: usize,
4321 rule_index: usize,
4322 pred_index: usize,
4323 predicates: &'a [(usize, usize, ParserPredicate)],
4324 semantics: Option<&'a ParserSemantics>,
4325 context: Option<&'a ParserRuleContext>,
4326 local_int_arg: Option<(usize, i64)>,
4327 member_values: &'a BTreeMap<usize, i64>,
4328}
4329
4330#[derive(Clone, Copy, Debug)]
4331struct ParserSemanticHookRequest<'a> {
4332 index: usize,
4333 rule_index: usize,
4334 pred_index: usize,
4335 context: Option<&'a ParserRuleContext>,
4336 local_int_arg: Option<(usize, i64)>,
4337 member_values: &'a BTreeMap<usize, i64>,
4338}
4339
4340struct ParserSemIrCtx<'a, S, H>
4349where
4350 S: TokenSource,
4351 H: SemanticHooks,
4352{
4353 input: &'a mut CommonTokenStream<S>,
4354 tree_storage: &'a ParseTreeStorage,
4355 semantic_hooks: &'a mut H,
4356 rule_index: usize,
4357 coordinate_index: usize,
4358 rule_name: Option<&'a str>,
4359 context: Option<&'a ParserRuleContext>,
4360 local_int_arg: Option<(usize, i64)>,
4361 member_values: &'a BTreeMap<usize, i64>,
4362 invoked_predicates: &'a mut Vec<(usize, usize)>,
4363 unknown_predicate_policy: UnknownSemanticPolicy,
4367 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4368}
4369
4370impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4371where
4372 S: TokenSource,
4373 H: SemanticHooks,
4374{
4375 type TokenText<'a>
4376 = TokenView<'a>
4377 where
4378 Self: 'a;
4379
4380 fn la(&mut self, offset: isize) -> i64 {
4381 i64::from(self.input.la(offset))
4382 }
4383
4384 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4385 self.input.lt(offset)
4386 }
4387
4388 fn token_index_adjacent(&mut self) -> bool {
4389 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4390 return false;
4391 };
4392 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4393 return false;
4394 };
4395 first + 1 == second
4396 }
4397
4398 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4399 self.context.and_then(|context| {
4400 context
4401 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4402 .next()
4403 .map(crate::tree::RuleNodeView::text)
4404 })
4405 }
4406
4407 fn member(&self, member: usize) -> Option<i64> {
4408 Some(self.member_values.get(&member).copied().unwrap_or_default())
4409 }
4410
4411 fn local_arg(&self) -> Option<i64> {
4412 self.local_int_arg.map(|(_, value)| value)
4413 }
4414
4415 fn column(&self) -> Option<i64> {
4416 None
4417 }
4418
4419 fn token_start_column(&self) -> Option<i64> {
4420 None
4421 }
4422
4423 fn token_text_so_far(&self) -> Option<String> {
4424 None
4425 }
4426
4427 fn hook(&mut self, _hook: HookId) -> bool {
4428 let mut ctx = ParserSemCtx {
4429 input: &mut *self.input,
4430 tree_storage: self.tree_storage,
4431 rule_index: self.rule_index,
4432 coordinate_index: self.coordinate_index,
4433 rule_name: self.rule_name.map(str::to_owned),
4434 context: self.context,
4435 tree: None,
4436 local_int_arg: self.local_int_arg,
4437 member_values: self.member_values,
4438 action: None,
4439 };
4440 match self
4441 .semantic_hooks
4442 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4443 {
4444 Some(result) => result,
4445 None => apply_unknown_predicate_policy(
4449 self.unknown_predicate_policy,
4450 self.rule_index,
4451 self.coordinate_index,
4452 self.unknown_predicate_hits,
4453 ),
4454 }
4455 }
4456
4457 fn trace_bool(&mut self, value: bool) -> bool {
4458 let key = (self.rule_index, self.coordinate_index);
4459 if !self.invoked_predicates.contains(&key) {
4460 self.invoked_predicates.push(key);
4461 use std::io::Write as _;
4462 let mut stdout = std::io::stdout().lock();
4463 let _ = writeln!(stdout, "eval={value}");
4464 }
4465 value
4466 }
4467}
4468
4469struct PredicateFailureRecovery<'a> {
4471 rule_index: usize,
4472 index: usize,
4473 message: &'a str,
4474 member_values: BTreeMap<usize, i64>,
4475 return_values: BTreeMap<String, i64>,
4476 rule_alt_number: usize,
4477}
4478
4479#[derive(Debug)]
4480enum DirectAdaptiveParseControl {
4481 Fallback(DirectAdaptiveFallback),
4482}
4483
4484#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4485enum DirectAdaptiveFallback {
4486 Action,
4487 InvalidAlt,
4488 LeftRecursiveBoundary,
4489 MissingAtn,
4490 NoTransition,
4491 Predicate,
4492 Prediction,
4493 Precedence,
4494 RuleStop,
4495 SemanticContext,
4496 StepLimit,
4497 TokenMismatch,
4498 UnknownDecision,
4499}
4500
4501type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
4502
4503struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
4504where
4505 S: TokenSource,
4506 H: SemanticHooks,
4507{
4508 parser: &'sim mut BaseParser<S, H>,
4509 atn: &'atn Atn,
4510 simulator: &'sim mut ParserAtnSimulator<'atn>,
4511 decision_by_state: Vec<Option<usize>>,
4512 steps: usize,
4513}
4514
4515#[derive(Clone, Debug, Eq, PartialEq)]
4525pub struct GeneratedMatch {
4526 children: GeneratedMatchChildren,
4527 consumed_eof: bool,
4528}
4529
4530#[derive(Clone, Copy)]
4531enum GeneratedExpectedSymbols<'a> {
4532 Tree(&'a BTreeSet<i32>),
4533 TokenSet(ParserIntervalSet<'a>),
4534 TokenSetComplement {
4535 set: ParserIntervalSet<'a>,
4536 min_vocabulary: i32,
4537 max_vocabulary: i32,
4538 },
4539}
4540
4541impl GeneratedExpectedSymbols<'_> {
4542 fn is_empty(self) -> bool {
4543 match self {
4544 Self::Tree(symbols) => symbols.is_empty(),
4545 Self::TokenSet(set) => set.is_empty(),
4546 Self::TokenSetComplement {
4547 set,
4548 min_vocabulary,
4549 max_vocabulary,
4550 } => (min_vocabulary..=max_vocabulary).all(|symbol| set.contains(symbol)),
4551 }
4552 }
4553
4554 fn first(self) -> Option<i32> {
4555 match self {
4556 Self::Tree(symbols) => symbols.iter().next().copied(),
4557 Self::TokenSet(set) => set.ranges().next().map(|(start, _)| start),
4558 Self::TokenSetComplement {
4559 set,
4560 min_vocabulary,
4561 max_vocabulary,
4562 } => (min_vocabulary..=max_vocabulary).find(|symbol| !set.contains(*symbol)),
4563 }
4564 }
4565
4566 fn display(self, vocabulary: &Vocabulary) -> String {
4567 match self {
4568 Self::Tree(symbols) => expected_symbols_display(symbols, vocabulary),
4569 Self::TokenSet(set) => expected_symbols_display_iter(
4570 set.ranges().flat_map(|(start, stop)| start..=stop),
4571 vocabulary,
4572 ),
4573 Self::TokenSetComplement {
4574 set,
4575 min_vocabulary,
4576 max_vocabulary,
4577 } => expected_symbols_display_iter(
4578 (min_vocabulary..=max_vocabulary).filter(|symbol| !set.contains(*symbol)),
4579 vocabulary,
4580 ),
4581 }
4582 }
4583}
4584
4585#[derive(Clone, Debug, Eq, PartialEq)]
4586enum GeneratedMatchChildren {
4587 One(ParseTree),
4588 Many(Vec<ParseTree>),
4589}
4590
4591struct GeneratedMatchChildrenIntoIter {
4592 one: Option<ParseTree>,
4593 many: Option<std::vec::IntoIter<ParseTree>>,
4594}
4595
4596impl Iterator for GeneratedMatchChildrenIntoIter {
4597 type Item = ParseTree;
4598
4599 fn next(&mut self) -> Option<Self::Item> {
4600 self.one
4601 .take()
4602 .or_else(|| self.many.as_mut().and_then(Iterator::next))
4603 }
4604}
4605
4606impl GeneratedMatch {
4607 #[must_use]
4611 pub fn children(&self) -> &[ParseTree] {
4612 match &self.children {
4613 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
4614 GeneratedMatchChildren::Many(children) => children,
4615 }
4616 }
4617
4618 #[must_use]
4621 pub fn into_children(self) -> Vec<ParseTree> {
4622 match self.children {
4623 GeneratedMatchChildren::One(child) => vec![child],
4624 GeneratedMatchChildren::Many(children) => children,
4625 }
4626 }
4627
4628 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
4630 match self.children {
4631 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
4632 one: Some(child),
4633 many: None,
4634 },
4635 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
4636 one: None,
4637 many: Some(children.into_iter()),
4638 },
4639 }
4640 }
4641
4642 #[must_use]
4644 pub const fn consumed_eof(&self) -> bool {
4645 self.consumed_eof
4646 }
4647}
4648
4649impl<S> BaseParser<S, NoSemanticHooks>
4650where
4651 S: TokenSource,
4652{
4653 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
4656 Self::with_semantic_hooks(input, data, NoSemanticHooks)
4657 }
4658}
4659
4660impl<S, H> BaseParser<S, H>
4661where
4662 S: TokenSource,
4663 H: SemanticHooks,
4664{
4665 pub fn with_semantic_hooks(
4667 input: CommonTokenStream<S>,
4668 data: RecognizerData,
4669 semantic_hooks: H,
4670 ) -> Self {
4671 Self {
4672 input,
4673 tree: ParseTreeStorage::new(),
4674 data,
4675 semantic_hooks,
4676 build_parse_trees: true,
4677 syntax_errors: 0,
4678 report_diagnostic_errors: false,
4679 prediction_mode: PredictionMode::Ll,
4680 prediction_diagnostics: Vec::new(),
4681 reported_prediction_diagnostics: BTreeSet::new(),
4682 generated_parser_diagnostics: Vec::new(),
4683 generated_sync_expected: None,
4684 int_members: BTreeMap::new(),
4685 rule_context_stack: Vec::new(),
4686 rule_context_version: 0,
4687 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
4688 pending_invoking_states: Vec::new(),
4689 precedence_stack: vec![0],
4690 invoked_predicates: Vec::new(),
4691 bail_on_error: false,
4692 unknown_predicate_policy: UnknownSemanticPolicy::default(),
4693 unknown_predicate_hits: Vec::new(),
4694 unhandled_action_hits: Vec::new(),
4695 rule_first_set_cache: Vec::new(),
4696 state_expected_cache: FxHashMap::default(),
4697 state_expected_token_cache: FxHashMap::default(),
4698 rule_stop_reach_cache: Vec::new(),
4699 recovery_symbols_intern: FxHashMap::default(),
4700 decision_lookahead_cache: FxHashMap::default(),
4701 ll1_decision_cache: FxHashMap::default(),
4702 fast_predicate_cache: FxHashMap::default(),
4703 empty_cycle_cache: Vec::new(),
4704 empty_cycle_cache_atn: None,
4705 clean_memo_mode: CleanMemoMode::Probe,
4706 clean_memo_probe_seen: FxHashSet::default(),
4707 clean_memo_probe_samples: 0,
4708 clean_memo_probe_repeats: 0,
4709 clean_memo_sparse_samples: 0,
4710 fast_recognize_scratch: FastRecognizeTopScratch::default(),
4711 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
4712 empty_recovery_symbols: Rc::new(BTreeSet::new()),
4713 fast_first_set_prefilter: true,
4714 fast_recovery_enabled: true,
4715 fast_token_nodes_enabled: true,
4716 recognition_arena: RecognitionArena::default(),
4717 last_recognition_arena_root: NodeSeqId::EMPTY,
4718 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
4719 }
4720 }
4721
4722 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
4723 &mut self.input
4724 }
4725
4726 pub fn reset(&mut self) {
4731 self.input.seek(0);
4732 self.tree.reset();
4733 self.data.set_state(-1);
4734 self.syntax_errors = 0;
4735 self.prediction_diagnostics.clear();
4736 self.reported_prediction_diagnostics.clear();
4737 self.generated_parser_diagnostics.clear();
4738 self.generated_sync_expected = None;
4739 self.rule_context_stack.clear();
4740 self.advance_rule_context_version();
4741 self.left_recursive_caller_overlap_cache = std::array::from_fn(|_| None);
4742 self.pending_invoking_states.clear();
4743 self.precedence_stack.clear();
4744 self.precedence_stack.push(0);
4745 self.invoked_predicates.clear();
4746 self.unknown_predicate_hits.clear();
4747 self.unhandled_action_hits.clear();
4748 self.reset_per_parse_caches();
4749 self.fast_first_set_prefilter = true;
4750 self.fast_recovery_enabled = true;
4751 self.fast_token_nodes_enabled = self.build_parse_trees;
4752 self.reset_recognition_arena();
4753 }
4754
4755 pub fn set_token_stream(&mut self, input: CommonTokenStream<S>) {
4757 self.input = input;
4758 self.reset();
4759 }
4760
4761 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
4772 self.unknown_predicate_policy = policy;
4773 }
4774
4775 #[must_use]
4781 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
4782 let error = self.unknown_semantic_error();
4783 self.unknown_predicate_hits.clear();
4784 self.unhandled_action_hits.clear();
4785 error
4786 }
4787
4788 pub fn reset_unknown_semantic_hits(&mut self) {
4795 self.unknown_predicate_hits.clear();
4796 self.unhandled_action_hits.clear();
4797 }
4798
4799 #[must_use]
4801 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
4802 &self.input
4803 }
4804
4805 #[must_use]
4807 pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<S> {
4808 &mut self.input
4809 }
4810
4811 #[must_use]
4813 pub const fn token_store(&self) -> &TokenStore {
4814 self.input.token_store()
4815 }
4816
4817 #[must_use]
4819 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
4820 &self.tree
4821 }
4822
4823 #[must_use]
4825 pub fn node(&self, id: NodeId) -> Node<'_> {
4826 self.tree
4827 .node(self.input.token_store(), id)
4828 .expect("parser-produced node ID should remain valid")
4829 }
4830
4831 #[must_use]
4833 pub fn into_token_stream(self) -> CommonTokenStream<S> {
4834 self.input
4835 }
4836
4837 #[must_use]
4839 pub fn into_token_store(self) -> TokenStore {
4840 self.input.into_token_store()
4841 }
4842
4843 #[must_use]
4845 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
4846 ParsedFile::new(self.input.into_token_store(), self.tree, root)
4847 }
4848
4849 pub const fn number_of_syntax_errors(&self) -> usize {
4852 self.syntax_errors
4853 }
4854
4855 #[must_use]
4861 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
4862 self.recognition_arena.stats(
4863 self.last_recognition_arena_root,
4864 self.last_recognition_arena_diagnostics,
4865 )
4866 }
4867
4868 pub const fn record_generated_syntax_error(&mut self) {
4871 self.record_syntax_errors(1);
4872 }
4873
4874 const fn record_syntax_errors(&mut self, count: usize) {
4875 self.syntax_errors = self.syntax_errors.saturating_add(count);
4876 }
4877
4878 pub fn report_token_source_errors(&mut self) {
4881 let errors = self.input.drain_source_errors();
4882 self.dispatch_token_source_errors(&errors);
4883 }
4884
4885 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
4888 GeneratedDiagnosticsCheckpoint {
4889 diagnostics_len: self.generated_parser_diagnostics.len(),
4890 syntax_errors: self.syntax_errors,
4891 tree: self.tree.checkpoint(),
4892 }
4893 }
4894
4895 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
4897 self.generated_parser_diagnostics
4898 .truncate(marker.diagnostics_len);
4899 self.syntax_errors = marker.syntax_errors;
4900 self.generated_sync_expected = None;
4901 self.tree.rollback(marker.tree);
4902 }
4903
4904 pub fn report_generated_parser_diagnostics(&mut self) {
4906 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
4907 let token_errors = self.input.drain_source_errors();
4908 self.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
4909 }
4910
4911 fn dispatch_parser_diagnostic(&self, diagnostic: &ParserDiagnostic) {
4912 self.notify_error_listeners(
4913 diagnostic.line,
4914 diagnostic.column,
4915 &diagnostic.message,
4916 None,
4917 );
4918 }
4919
4920 fn dispatch_parser_diagnostics<'a>(
4921 &self,
4922 diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>,
4923 ) {
4924 for diagnostic in diagnostics {
4925 self.dispatch_parser_diagnostic(diagnostic);
4926 }
4927 }
4928
4929 fn dispatch_token_source_error(&self, source_error: &TokenSourceError) {
4930 if self.input.token_source().report_error(source_error) {
4931 return;
4932 }
4933 self.notify_error_listeners(
4934 source_error.line,
4935 source_error.column,
4936 &source_error.message,
4937 None,
4938 );
4939 }
4940
4941 fn dispatch_token_source_errors(&self, errors: &[TokenSourceError]) {
4942 for error in errors {
4943 self.dispatch_token_source_error(error);
4944 }
4945 }
4946
4947 fn dispatch_generated_diagnostics(
4950 &self,
4951 parser_diagnostics: &[ParserDiagnostic],
4952 token_errors: &[TokenSourceError],
4953 ) {
4954 let mut token_iter = token_errors.iter().peekable();
4960 for diagnostic in parser_diagnostics {
4961 while let Some(error) = token_iter.peek() {
4962 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
4963 self.dispatch_token_source_error(error);
4964 token_iter.next();
4965 } else {
4966 break;
4967 }
4968 }
4969 self.dispatch_parser_diagnostic(diagnostic);
4970 }
4971 for error in token_iter {
4972 self.dispatch_token_source_error(error);
4973 }
4974 }
4975
4976 pub fn record_generated_ambiguity_diagnostic(
4979 &mut self,
4980 atn: &Atn,
4981 state_number: usize,
4982 start_index: usize,
4983 stop_index: usize,
4984 alts: &[usize],
4985 ) {
4986 if !self.report_diagnostic_errors || alts.len() < 2 {
4987 return;
4988 }
4989 let Some(decision) = atn
4990 .decision_to_state()
4991 .iter()
4992 .position(|candidate| candidate == state_number)
4993 else {
4994 return;
4995 };
4996 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
4997 return;
4998 };
4999 let rule_name = self
5000 .rule_names()
5001 .get(rule_index)
5002 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5003 let input = display_input_text(&self.input.text(start_index, stop_index));
5004 let alts = alts
5005 .iter()
5006 .map(usize::to_string)
5007 .collect::<Vec<_>>()
5008 .join(", ");
5009 let key = (decision, start_index, format!("{alts}:{input}"));
5010 if !self.reported_prediction_diagnostics.insert(key) {
5011 return;
5012 }
5013 let start_diagnostic = diagnostic_for_token(
5014 self.token_at(start_index),
5015 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
5016 );
5017 let stop_diagnostic = diagnostic_for_token(
5018 self.token_at(stop_index),
5019 format!(
5020 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
5021 ),
5022 );
5023 self.generated_parser_diagnostics.push(start_diagnostic);
5024 self.generated_parser_diagnostics.push(stop_diagnostic);
5025 }
5026
5027 pub fn record_generated_prediction_diagnostic(
5030 &mut self,
5031 atn: &Atn,
5032 state_number: usize,
5033 prediction: &ParserAtnPrediction,
5034 ) {
5035 let Some(diagnostic) = &prediction.diagnostic else {
5036 return;
5037 };
5038 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5039 return;
5040 }
5041 let Some(decision) = atn
5042 .decision_to_state()
5043 .iter()
5044 .position(|candidate| candidate == state_number)
5045 else {
5046 return;
5047 };
5048 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5049 return;
5050 };
5051 let rule_name = self
5052 .rule_names()
5053 .get(rule_index)
5054 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5055 let attempt_input = display_input_text(
5056 &self
5057 .input
5058 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5059 );
5060 let result_input = display_input_text(
5061 &self
5062 .input
5063 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5064 );
5065 let alts = diagnostic
5066 .conflicting_alts
5067 .iter()
5068 .map(usize::to_string)
5069 .collect::<Vec<_>>()
5070 .join(", ");
5071 let key = (
5072 decision,
5073 diagnostic.start_index,
5074 format!(
5075 "{:?}:{alts}:{attempt_input}:{result_input}",
5076 diagnostic.kind
5077 ),
5078 );
5079 if !self.reported_prediction_diagnostics.insert(key) {
5080 return;
5081 }
5082 let attempt_diagnostic = diagnostic_for_token(
5083 self.token_at(diagnostic.sll_stop_index),
5084 format!(
5085 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5086 ),
5087 );
5088 self.generated_parser_diagnostics.push(attempt_diagnostic);
5089 let message = match diagnostic.kind {
5090 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5091 if !diagnostic.exact {
5096 return;
5097 }
5098 format!(
5099 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5100 )
5101 }
5102 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5103 format!(
5104 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5105 )
5106 }
5107 };
5108 let result_diagnostic =
5109 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5110 self.generated_parser_diagnostics.push(result_diagnostic);
5111 }
5112
5113 pub fn la(&self, offset: isize) -> i32 {
5114 self.input.la_token(offset)
5115 }
5116
5117 pub fn consume(&mut self) {
5118 IntStream::consume(&mut self.input);
5119 }
5120
5121 pub fn set_int_member(&mut self, member: usize, value: i64) {
5123 self.int_members.insert(member, value);
5124 }
5125
5126 pub fn int_member(&self, member: usize) -> Option<i64> {
5128 self.int_members.get(&member).copied()
5129 }
5130
5131 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
5134 self.int_members.clone()
5135 }
5136
5137 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
5139 self.int_members = members;
5140 }
5141
5142 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5144 let value = self.int_members.entry(member).or_default();
5145 *value += delta;
5146 *value
5147 }
5148
5149 fn token_type_for_id(&self, id: TokenId) -> i32 {
5150 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5151 }
5152
5153 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5154 if self.build_parse_trees {
5155 self.tree.terminal(id)
5156 } else {
5157 NodeId::placeholder()
5158 }
5159 }
5160
5161 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5162 if self.build_parse_trees {
5163 self.tree.error(id)
5164 } else {
5165 NodeId::placeholder()
5166 }
5167 }
5168
5169 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5170 context.set_start_id(id);
5171 }
5172
5173 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5174 context.set_stop_id(id);
5175 }
5176
5177 fn insert_synthetic_token(
5178 &mut self,
5179 token_type: i32,
5180 text: String,
5181 line: usize,
5182 column: usize,
5183 ) -> Result<TokenId, AntlrError> {
5184 self.input
5185 .insert(
5186 TokenSpec::explicit(token_type, text)
5187 .with_span(usize::MAX, usize::MAX)
5188 .with_byte_span(0, 0)
5189 .with_position(line, column),
5190 )
5191 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5192 }
5193
5194 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5201 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5202 line: 0,
5203 column: 0,
5204 message: "missing current token".to_owned(),
5205 })?;
5206 let current_type = self.token_type_for_id(current);
5207 if current_type == token_type {
5208 self.consume();
5209 Ok(self.terminal_tree(current))
5210 } else {
5211 Err(AntlrError::MismatchedInput {
5212 expected: self.vocabulary().display_name(token_type),
5213 found: self.vocabulary().display_name(current_type),
5214 })
5215 }
5216 }
5217
5218 pub fn match_token_recovering(
5222 &mut self,
5223 token_type: i32,
5224 follow_state: usize,
5225 atn: &Atn,
5226 ) -> Result<GeneratedMatch, AntlrError> {
5227 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5228 line: 0,
5229 column: 0,
5230 message: "missing current token".to_owned(),
5231 })?;
5232 let current_type = self.token_type_for_id(current);
5233 if current_type == token_type {
5234 self.generated_sync_expected = None;
5235 let consumed_eof = current_type == TOKEN_EOF;
5236 self.consume();
5237 return Ok(GeneratedMatch {
5238 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5239 consumed_eof,
5240 });
5241 }
5242 let mut expected_symbols = BTreeSet::new();
5243 expected_symbols.insert(token_type);
5244 self.recover_generated_match(
5245 current,
5246 GeneratedExpectedSymbols::Tree(&expected_symbols),
5247 follow_state,
5248 atn,
5249 |symbol| symbol == token_type,
5250 )
5251 }
5252
5253 pub fn match_set_recovering(
5254 &mut self,
5255 intervals: &[(i32, i32)],
5256 follow_state: usize,
5257 atn: &Atn,
5258 ) -> Result<GeneratedMatch, AntlrError> {
5259 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5260 line: 0,
5261 column: 0,
5262 message: "missing current token".to_owned(),
5263 })?;
5264 let current_type = self.token_type_for_id(current);
5265 if interval_set_contains(intervals, current_type) {
5266 self.generated_sync_expected = None;
5267 let consumed_eof = current_type == TOKEN_EOF;
5268 self.consume();
5269 return Ok(GeneratedMatch {
5270 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5271 consumed_eof,
5272 });
5273 }
5274 let expected_symbols = interval_symbols(intervals);
5275 self.recover_generated_match(
5276 current,
5277 GeneratedExpectedSymbols::Tree(&expected_symbols),
5278 follow_state,
5279 atn,
5280 |symbol| interval_set_contains(intervals, symbol),
5281 )
5282 }
5283
5284 pub fn match_token_set_recovering(
5285 &mut self,
5286 set: ParserIntervalSet<'_>,
5287 follow_state: usize,
5288 atn: &Atn,
5289 ) -> Result<GeneratedMatch, AntlrError> {
5290 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5291 line: 0,
5292 column: 0,
5293 message: "missing current token".to_owned(),
5294 })?;
5295 let current_type = self.token_type_for_id(current);
5296 if set.contains(current_type) {
5297 self.generated_sync_expected = None;
5298 let consumed_eof = current_type == TOKEN_EOF;
5299 self.consume();
5300 return Ok(GeneratedMatch {
5301 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5302 consumed_eof,
5303 });
5304 }
5305 self.recover_generated_match(
5306 current,
5307 GeneratedExpectedSymbols::TokenSet(set),
5308 follow_state,
5309 atn,
5310 |symbol| set.contains(symbol),
5311 )
5312 }
5313
5314 pub fn match_not_set_recovering(
5315 &mut self,
5316 intervals: &[(i32, i32)],
5317 min_vocabulary: i32,
5318 max_vocabulary: i32,
5319 follow_state: usize,
5320 atn: &Atn,
5321 ) -> Result<GeneratedMatch, AntlrError> {
5322 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5323 line: 0,
5324 column: 0,
5325 message: "missing current token".to_owned(),
5326 })?;
5327 let current_type = self.token_type_for_id(current);
5328 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5329 && !interval_set_contains(intervals, current_type)
5330 {
5331 self.generated_sync_expected = None;
5332 let consumed_eof = current_type == TOKEN_EOF;
5333 self.consume();
5334 return Ok(GeneratedMatch {
5335 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5336 consumed_eof,
5337 });
5338 }
5339 let expected_symbols =
5340 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
5341 self.recover_generated_match(
5342 current,
5343 GeneratedExpectedSymbols::Tree(&expected_symbols),
5344 follow_state,
5345 atn,
5346 |symbol| {
5347 (min_vocabulary..=max_vocabulary).contains(&symbol)
5348 && !interval_set_contains(intervals, symbol)
5349 },
5350 )
5351 }
5352
5353 pub fn match_not_token_set_recovering(
5354 &mut self,
5355 set: ParserIntervalSet<'_>,
5356 min_vocabulary: i32,
5357 max_vocabulary: i32,
5358 follow_state: usize,
5359 atn: &Atn,
5360 ) -> Result<GeneratedMatch, AntlrError> {
5361 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5362 line: 0,
5363 column: 0,
5364 message: "missing current token".to_owned(),
5365 })?;
5366 let current_type = self.token_type_for_id(current);
5367 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
5368 {
5369 self.generated_sync_expected = None;
5370 let consumed_eof = current_type == TOKEN_EOF;
5371 self.consume();
5372 return Ok(GeneratedMatch {
5373 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5374 consumed_eof,
5375 });
5376 }
5377 self.recover_generated_match(
5378 current,
5379 GeneratedExpectedSymbols::TokenSetComplement {
5380 set,
5381 min_vocabulary,
5382 max_vocabulary,
5383 },
5384 follow_state,
5385 atn,
5386 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
5387 )
5388 }
5389
5390 fn recover_generated_match(
5391 &mut self,
5392 current: TokenId,
5393 expected_symbols: GeneratedExpectedSymbols<'_>,
5394 follow_state: usize,
5395 atn: &Atn,
5396 matches: impl Fn(i32) -> bool,
5397 ) -> Result<GeneratedMatch, AntlrError> {
5398 let expected_display = expected_symbols.display(self.vocabulary());
5399 let (current_type, current_line, current_column, current_display) = {
5400 let token = self
5401 .input
5402 .token_view(current)
5403 .expect("current token ID should be valid");
5404 (
5405 token.token_type(),
5406 token.line(),
5407 token.column(),
5408 token_input_display(&token),
5409 )
5410 };
5411 if self.bail_on_error {
5412 return Err(AntlrError::ParserError {
5413 line: current_line,
5414 column: current_column,
5415 message: format!("mismatched input {current_display} expecting {expected_display}"),
5416 });
5417 }
5418 if current_type != TOKEN_EOF
5419 && let Some(next) = self.input.lt_id(2)
5420 && matches(self.token_type_for_id(next))
5421 {
5422 let message =
5423 format!("extraneous input {current_display} expecting {expected_display}");
5424 self.push_generated_parser_diagnostic(ParserDiagnostic {
5425 line: current_line,
5426 column: current_column,
5427 message,
5428 });
5429 self.record_syntax_errors(1);
5430 self.generated_sync_expected = None;
5431 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
5434 self.consume();
5435 self.consume();
5436 return Ok(GeneratedMatch {
5437 children: GeneratedMatchChildren::Many(vec![
5438 self.error_tree(current),
5439 self.terminal_tree(next),
5440 ]),
5441 consumed_eof,
5442 });
5443 }
5444 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
5445 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
5454 && self
5455 .cached_state_expected_symbols(atn, follow_state)
5456 .contains(&TOKEN_EOF);
5457 if follow_symbols.contains(¤t_type)
5458 && (current_type != TOKEN_EOF
5459 || self.rule_context_stack.len() > 1
5460 || expected_symbols.is_empty()
5461 || follow_explicitly_expects_eof)
5462 {
5463 let message = format!("missing {expected_display} at {current_display}");
5464 self.push_generated_parser_diagnostic(ParserDiagnostic {
5465 line: current_line,
5466 column: current_column,
5467 message,
5468 });
5469 self.record_syntax_errors(1);
5470 self.generated_sync_expected = None;
5471 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
5472 let missing_display = expected_symbol_display(token_type, self.vocabulary());
5473 let token = self.insert_synthetic_token(
5474 token_type,
5475 format!("<missing {missing_display}>"),
5476 current_line,
5477 current_column,
5478 )?;
5479 return Ok(GeneratedMatch {
5484 children: GeneratedMatchChildren::One(self.error_tree(token)),
5485 consumed_eof: false,
5486 });
5487 }
5488 let mismatch_expected_display = self
5489 .generated_sync_expected
5490 .take()
5491 .map_or(expected_display, |symbols| {
5492 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
5493 });
5494 Err(AntlrError::ParserError {
5495 line: current_line,
5496 column: current_column,
5497 message: format!(
5498 "mismatched input {current_display} expecting {mismatch_expected_display}"
5499 ),
5500 })
5501 }
5502
5503 fn generated_recovery_follow_symbols(
5504 &mut self,
5505 atn: &Atn,
5506 follow_state: usize,
5507 ) -> BTreeSet<i32> {
5508 let mut follow = self
5509 .cached_state_expected_symbols(atn, follow_state)
5510 .as_ref()
5511 .clone();
5512 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
5513 follow.extend(self.context_expected_symbols(atn));
5514 }
5515 follow
5516 }
5517
5518 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
5519 self.match_token(TOKEN_EOF)
5520 }
5521
5522 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
5523 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
5524 }
5525
5526 pub fn match_not_set(
5527 &mut self,
5528 intervals: &[(i32, i32)],
5529 min_vocabulary: i32,
5530 max_vocabulary: i32,
5531 ) -> Result<ParseTree, AntlrError> {
5532 self.match_interval_condition(intervals, |symbol| {
5533 (min_vocabulary..=max_vocabulary).contains(&symbol)
5534 && !interval_set_contains(intervals, symbol)
5535 })
5536 }
5537
5538 fn match_interval_condition(
5539 &mut self,
5540 intervals: &[(i32, i32)],
5541 matches: impl FnOnce(i32) -> bool,
5542 ) -> Result<ParseTree, AntlrError> {
5543 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5544 line: 0,
5545 column: 0,
5546 message: "missing current token".to_owned(),
5547 })?;
5548 let current_type = self.token_type_for_id(current);
5549 if matches(current_type) {
5550 self.consume();
5551 Ok(self.terminal_tree(current))
5552 } else {
5553 Err(AntlrError::MismatchedInput {
5554 expected: self.interval_display(intervals),
5555 found: self.vocabulary().display_name(current_type),
5556 })
5557 }
5558 }
5559
5560 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
5561 let values = intervals
5562 .iter()
5563 .map(|(start, stop)| {
5564 if start == stop {
5565 self.vocabulary().display_name(*start)
5566 } else {
5567 format!(
5568 "{}..{}",
5569 self.vocabulary().display_name(*start),
5570 self.vocabulary().display_name(*stop)
5571 )
5572 }
5573 })
5574 .collect::<Vec<_>>()
5575 .join(", ");
5576 format!("{{{values}}}")
5577 }
5578
5579 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
5580 if self.build_parse_trees {
5581 self.tree.finish_rule(context)
5582 } else {
5583 NodeId::placeholder()
5584 }
5585 }
5586
5587 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
5590 self.set_state(state);
5591 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
5592 self.rule_context_stack.push(RuleContextFrame {
5593 rule_index,
5594 invoking_state,
5595 });
5596 self.advance_rule_context_version();
5597 let start_index = self.current_visible_index();
5598 let mut context = ParserRuleContext::new(rule_index, invoking_state);
5599 if let Some(token) = self.token_id_at(start_index) {
5600 self.set_context_start(&mut context, token);
5601 }
5602 context
5603 }
5604
5605 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
5612 let marker = self.pending_invoking_states.len();
5613 self.pending_invoking_states.push(invoking_state);
5614 marker
5615 }
5616
5617 pub fn discard_invoking_state(&mut self, marker: usize) {
5619 self.pending_invoking_states.truncate(marker);
5620 }
5621
5622 pub fn exit_rule(&mut self) {
5624 self.rule_context_stack.pop();
5625 self.advance_rule_context_version();
5626 }
5627
5628 pub fn prediction_context_return_states<'a>(
5631 &'a self,
5632 atn: &'a Atn,
5633 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
5634 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
5635 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
5636 return None;
5637 };
5638 let Some(Transition::Rule { follow_state, .. }) = atn
5639 .state(state_number)
5640 .and_then(|state| state.transitions().first())
5641 .map(ParserTransition::data)
5642 else {
5643 return None;
5644 };
5645 Some(follow_state)
5646 })
5647 }
5648
5649 pub const fn rule_context_version(&self) -> usize {
5654 self.rule_context_version
5655 }
5656
5657 const fn advance_rule_context_version(&mut self) {
5658 self.rule_context_version = self.rule_context_version.wrapping_add(1);
5659 }
5660
5661 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
5666 if self.build_parse_trees {
5667 self.tree.add_child(context, child);
5668 } else {
5669 context.note_matched_child();
5670 }
5671 }
5672
5673 fn release_tree_scratch_if_idle(&mut self) {
5674 if self.rule_context_stack.is_empty() {
5675 self.tree.release_scratch();
5676 }
5677 }
5678
5679 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
5681 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5682 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5683 self.set_context_stop(&mut context, token);
5684 }
5685 let node = self.rule_node(context);
5686 self.exit_rule();
5687 self.release_tree_scratch_if_idle();
5688 node
5689 }
5690
5691 pub fn recover_generated_rule(
5698 &mut self,
5699 context: &mut ParserRuleContext,
5700 atn: &Atn,
5701 error: AntlrError,
5702 ) {
5703 let diagnostic = self.generated_rule_error_diagnostic(error);
5704 self.push_generated_parser_diagnostic(diagnostic);
5705 self.generated_sync_expected = None;
5706 let recovery_symbols = self.context_expected_symbols(atn);
5707 loop {
5708 let symbol = self.la(1);
5709 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
5710 break;
5711 }
5712 let Some(token) = self.input.lt_id(1) else {
5713 break;
5714 };
5715 self.consume();
5716 let child = self.error_tree(token);
5717 self.add_parse_child(context, child);
5718 }
5719 self.record_syntax_errors(1);
5720 }
5721
5722 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
5723 if self
5724 .generated_parser_diagnostics
5725 .iter()
5726 .any(|existing| existing == &diagnostic)
5727 {
5728 return;
5729 }
5730 self.generated_parser_diagnostics.push(diagnostic);
5731 }
5732
5733 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
5734 match error {
5735 AntlrError::ParserError {
5736 line,
5737 column,
5738 message,
5739 } => ParserDiagnostic {
5740 line,
5741 column,
5742 message,
5743 },
5744 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
5745 self.input.lt(1),
5746 format!("mismatched input {found} expecting {expected}"),
5747 ),
5748 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
5749 self.input.lt(1),
5750 format!("no viable alternative at input {input}"),
5751 ),
5752 AntlrError::LexerError {
5753 line,
5754 column,
5755 message,
5756 } => ParserDiagnostic {
5757 line,
5758 column,
5759 message,
5760 },
5761 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
5762 }
5763 }
5764
5765 pub fn finish_recursion_rule(
5767 &mut self,
5768 mut context: ParserRuleContext,
5769 consumed_eof: bool,
5770 ) -> ParseTree {
5771 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
5772 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
5773 self.set_context_stop(&mut context, token);
5774 }
5775 let node = self.rule_node(context);
5776 self.unroll_recursion_context();
5777 self.release_tree_scratch_if_idle();
5778 node
5779 }
5780
5781 pub fn enter_recursion_rule(
5783 &mut self,
5784 state: isize,
5785 rule_index: usize,
5786 precedence: i32,
5787 ) -> ParserRuleContext {
5788 self.precedence_stack.push(precedence);
5789 self.enter_rule(state, rule_index)
5790 }
5791
5792 pub fn push_new_recursion_context(
5794 &mut self,
5795 state: isize,
5796 rule_index: usize,
5797 ) -> ParserRuleContext {
5798 self.set_state(state);
5799 ParserRuleContext::new(rule_index, state)
5800 }
5801
5802 pub fn push_new_recursion_context_with_previous(
5805 &mut self,
5806 state: isize,
5807 rule_index: usize,
5808 current: &mut ParserRuleContext,
5809 ) {
5810 self.set_state(state);
5811 if let Some(stop) = self
5812 .rule_stop_token_index(self.input.index(), false)
5813 .and_then(|index| self.token_id_at(index))
5814 {
5815 self.set_context_stop(current, stop);
5816 }
5817 let invoking_state = current.invoking_state();
5818 let start = current.start_id();
5819 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
5820 if start.is_some() {
5821 replacement.set_start_from_context(current);
5822 }
5823 let previous = std::mem::replace(current, replacement);
5824 if self.build_parse_trees {
5825 let previous = self.rule_node(previous);
5826 self.tree.add_child(current, previous);
5827 }
5828 }
5829
5830 pub fn unroll_recursion_context(&mut self) {
5832 if self.precedence_stack.len() > 1 {
5833 self.precedence_stack.pop();
5834 }
5835 self.exit_rule();
5836 }
5837
5838 pub fn left_recursive_loop_enter_prediction(
5852 &mut self,
5853 atn: &Atn,
5854 state_number: usize,
5855 precedence: i32,
5856 ) -> Option<bool> {
5857 let symbol = self.la(1);
5858 if symbol == TOKEN_EOF {
5859 return Some(false);
5860 }
5861 let operator_lookahead =
5862 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
5863 let can_single = operator_lookahead.single_token.contains(symbol);
5864 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
5865 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
5866 if !can_single && !can_multi && !can_predicate {
5867 return Some(false);
5868 }
5869 if can_predicate && !can_single {
5870 return None;
5871 }
5872 if !can_single && can_multi && precedence > 0 {
5876 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
5877 if baseline.single_token.contains(symbol) {
5878 return None;
5879 }
5880 }
5881 let atn_key = SharedAtnCacheKey::for_atn(atn);
5882 let cached_overlap = self
5883 .left_recursive_caller_overlap_cache
5884 .iter()
5885 .flatten()
5886 .find(|entry| {
5887 entry.atn_key == atn_key
5888 && entry.state_number == state_number
5889 && entry.symbol == symbol
5890 && entry.context_version == self.rule_context_version
5891 })
5892 .map(|entry| entry.overlaps);
5893 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
5894 let overlaps = caller_context_can_match_symbol_before_state(
5895 atn,
5896 self.prediction_context_return_states(atn),
5897 state_number,
5898 symbol,
5899 );
5900 if let Some(slot) = self
5901 .left_recursive_caller_overlap_cache
5902 .iter_mut()
5903 .find(|slot| slot.is_none())
5904 {
5905 *slot = Some(LeftRecursiveCallerOverlap {
5906 atn_key,
5907 state_number,
5908 symbol,
5909 context_version: self.rule_context_version,
5910 overlaps,
5911 });
5912 }
5913 overlaps
5914 });
5915 if caller_overlaps {
5916 return None;
5917 }
5918 Some(true)
5919 }
5920
5921 fn cached_left_recursive_operator_lookahead(
5922 atn: &Atn,
5923 state_number: usize,
5924 precedence: i32,
5925 ) -> Rc<LeftRecursiveOperatorLookahead> {
5926 with_shared_atn_caches(atn, |cache| {
5927 let key = (state_number, precedence);
5928 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
5929 return Rc::clone(cached);
5930 }
5931 let lookahead = Rc::new(left_recursive_operator_lookahead(
5932 atn,
5933 state_number,
5934 precedence,
5935 ));
5936 cache
5937 .left_recursive_operator_lookahead
5938 .insert(key, Rc::clone(&lookahead));
5939 lookahead
5940 })
5941 }
5942
5943 pub fn left_recursive_loop_enter_matches(
5946 &mut self,
5947 atn: &Atn,
5948 state_number: usize,
5949 precedence: i32,
5950 ) -> bool {
5951 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
5952 }
5953
5954 pub fn precpred(&self, precedence: i32) -> bool {
5956 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
5957 }
5958
5959 pub fn parser_semantic_predicate_matches(
5962 &mut self,
5963 predicates: &[(usize, usize, ParserPredicate)],
5964 rule_index: usize,
5965 pred_index: usize,
5966 ) -> bool {
5967 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
5968 }
5969
5970 pub fn parser_semantic_predicate_matches_with_local(
5973 &mut self,
5974 predicates: &[(usize, usize, ParserPredicate)],
5975 rule_index: usize,
5976 pred_index: usize,
5977 local_int_arg: i32,
5978 ) -> bool {
5979 self.parser_semantic_predicate_matches_inner(
5980 predicates,
5981 rule_index,
5982 pred_index,
5983 Some((rule_index, i64::from(local_int_arg))),
5984 )
5985 }
5986
5987 fn parser_semantic_predicate_matches_inner(
5988 &mut self,
5989 predicates: &[(usize, usize, ParserPredicate)],
5990 rule_index: usize,
5991 pred_index: usize,
5992 local_int_arg: Option<(usize, i64)>,
5993 ) -> bool {
5994 let index = self.input.index();
5995 let member_values = self.int_members.clone();
5996 self.parser_predicate_matches(PredicateEval {
5997 index,
5998 rule_index,
5999 pred_index,
6000 predicates,
6001 semantics: None,
6002 context: None,
6003 local_int_arg,
6004 member_values: &member_values,
6005 })
6006 }
6007
6008 pub fn parser_semantic_predicate_matches_with_context_and_local(
6011 &mut self,
6012 predicates: &[(usize, usize, ParserPredicate)],
6013 rule_index: usize,
6014 pred_index: usize,
6015 context: &ParserRuleContext,
6016 local_int_arg: i32,
6017 ) -> bool {
6018 let index = self.input.index();
6019 let member_values = self.int_members.clone();
6020 self.parser_predicate_matches(PredicateEval {
6021 index,
6022 rule_index,
6023 pred_index,
6024 predicates,
6025 semantics: None,
6026 context: Some(context),
6027 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6028 member_values: &member_values,
6029 })
6030 }
6031
6032 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
6035 &mut self,
6036 semantics: &ParserSemantics,
6037 rule_index: usize,
6038 pred_index: usize,
6039 context: &ParserRuleContext,
6040 local_int_arg: i32,
6041 ) -> bool {
6042 let index = self.input.index();
6043 let member_values = self.int_members.clone();
6044 self.parser_predicate_matches(PredicateEval {
6045 index,
6046 rule_index,
6047 pred_index,
6048 predicates: &[],
6049 semantics: Some(semantics),
6050 context: Some(context),
6051 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6052 member_values: &member_values,
6053 })
6054 }
6055
6056 pub fn parser_semantic_predicate_failure_message(
6059 &self,
6060 rule_index: usize,
6061 pred_index: usize,
6062 predicates: &[(usize, usize, ParserPredicate)],
6063 ) -> Option<&'static str> {
6064 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
6065 }
6066
6067 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
6069 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6070 line: 0,
6071 column: 0,
6072 message: "missing current token".to_owned(),
6073 })?;
6074 if self.token_type_for_id(current) == TOKEN_EOF {
6075 return Err(AntlrError::MismatchedInput {
6076 expected: "wildcard".to_owned(),
6077 found: self.vocabulary().display_name(TOKEN_EOF),
6078 });
6079 }
6080 self.consume();
6081 Ok(self.terminal_tree(current))
6082 }
6083
6084 #[allow(clippy::unnecessary_wraps)]
6088 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
6089 self.set_state(state);
6090 Ok(())
6091 }
6092
6093 pub fn sync_decision(
6101 &mut self,
6102 atn: &Atn,
6103 state_number: usize,
6104 current_context_empty: bool,
6105 loop_back: bool,
6106 ) -> Result<Vec<ParseTree>, AntlrError> {
6107 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
6108 self.generated_sync_expected = None;
6109 let Some(state) = atn.state(state_number) else {
6110 return Ok(Vec::new());
6111 };
6112 let Some(rule_index) = state.rule_index() else {
6113 return Ok(Vec::new());
6114 };
6115 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
6116 return Ok(Vec::new());
6117 };
6118 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6119 let symbol = self.la(1);
6120 let mut has_expected_symbols = false;
6121 let mut nullable = false;
6122 let mut explicit_eof_expected = false;
6130 for transition in &entry.transitions {
6131 if transition.symbols.contains(symbol) {
6132 return Ok(Vec::new());
6133 }
6134 has_expected_symbols |= !transition.symbols.is_empty();
6135 nullable |= transition.nullable;
6136 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
6137 }
6138 if nullable && self.context_expected_contains(atn, symbol) {
6143 return Ok(Vec::new());
6144 }
6145 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
6146 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
6147 return Ok(Vec::new());
6148 }
6149 let mut expected = TokenBitSet::default();
6150 for transition in &entry.transitions {
6151 expected.extend_from(&transition.symbols);
6152 }
6153 if let Some(context_expected) = context_expected {
6154 expected.extend_from(&context_expected);
6155 }
6156 let can_delete_in_place =
6157 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
6158 let loop_sync = loop_back;
6175 if symbol != TOKEN_EOF && can_delete_in_place {
6176 let mut cursor = self.input.index();
6177 let mut skipped = Vec::new();
6178 loop {
6179 let current = self.token_type_at(cursor);
6180 if current == TOKEN_EOF {
6181 break;
6182 }
6183 skipped.push(cursor);
6184 let next = self.consume_index(cursor, current);
6185 if next == cursor {
6186 break;
6187 }
6188 let next_symbol = self.token_type_at(next);
6189 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
6197 explicit_eof_expected
6198 } else {
6199 expected.contains(next_symbol)
6200 };
6201 if next_is_expected_stop {
6202 let current_token = self.input.lt(1);
6203 let expected_symbols = expected.to_btree_set();
6204 let message = format!(
6205 "extraneous input {} expecting {}",
6206 current_token
6207 .as_ref()
6208 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6209 self.expected_symbols_display(&expected_symbols)
6210 );
6211 self.push_generated_parser_diagnostic(diagnostic_for_token(
6212 current_token,
6213 message,
6214 ));
6215 self.record_syntax_errors(1);
6216 let mut children = Vec::with_capacity(skipped.len());
6217 for index in skipped {
6218 if let Some(token) = self.token_id_at(index) {
6219 self.consume();
6220 children.push(self.error_tree(token));
6221 }
6222 }
6223 return Ok(children);
6224 }
6225 if !loop_sync {
6229 break;
6230 }
6231 cursor = next;
6232 }
6233 }
6234 if nullable {
6235 self.generated_sync_expected = Some(expected);
6236 return Ok(Vec::new());
6237 }
6238 let current = self.input.lt(1);
6239 let expected_symbols = expected.to_btree_set();
6240 Err(AntlrError::ParserError {
6241 line: current.as_ref().map(Token::line).unwrap_or_default(),
6242 column: current.as_ref().map(Token::column).unwrap_or_default(),
6243 message: format!(
6244 "mismatched input {} expecting {}",
6245 current
6246 .as_ref()
6247 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6248 self.expected_symbols_display(&expected_symbols)
6249 ),
6250 })
6251 }
6252
6253 pub fn ll1_decision_prediction(
6260 &mut self,
6261 atn: &Atn,
6262 state_number: usize,
6263 ) -> Option<ParserAtnPrediction> {
6264 let state = atn.state(state_number)?;
6265 if state.precedence_rule_decision() {
6266 return None;
6267 }
6268 let rule_stop = state
6269 .rule_index()
6270 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
6271 let symbol = self.la(1);
6272 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6273 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
6274 alt: alt + 1,
6275 requires_full_context: false,
6276 has_semantic_context: false,
6277 diagnostic: None,
6278 })
6279 }
6280
6281 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
6282 let mut expected = BTreeSet::new();
6283 for index in (1..self.rule_context_stack.len()).rev() {
6284 let invoking_state = self.rule_context_stack[index].invoking_state;
6285 let Ok(state_number) = usize::try_from(invoking_state) else {
6286 continue;
6287 };
6288 let Some(Transition::Rule { follow_state, .. }) = atn
6289 .state(state_number)
6290 .and_then(|state| state.transitions().first())
6291 .map(ParserTransition::data)
6292 else {
6293 continue;
6294 };
6295 let return_state = follow_state;
6296 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
6297 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
6298 return expected;
6299 }
6300 }
6301 expected.insert(TOKEN_EOF);
6302 expected
6303 }
6304
6305 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
6306 let mut expected = TokenBitSet::default();
6307 for index in (1..self.rule_context_stack.len()).rev() {
6308 let invoking_state = self.rule_context_stack[index].invoking_state;
6309 let Ok(state_number) = usize::try_from(invoking_state) else {
6310 continue;
6311 };
6312 let Some(Transition::Rule { follow_state, .. }) = atn
6313 .state(state_number)
6314 .and_then(|state| state.transitions().first())
6315 .map(ParserTransition::data)
6316 else {
6317 continue;
6318 };
6319 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
6320 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6321 return expected;
6322 }
6323 }
6324 expected.insert(TOKEN_EOF);
6325 expected
6326 }
6327
6328 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
6339 for index in (1..self.rule_context_stack.len()).rev() {
6340 let invoking_state = self.rule_context_stack[index].invoking_state;
6341 let Ok(state_number) = usize::try_from(invoking_state) else {
6342 continue;
6343 };
6344 let Some(Transition::Rule { follow_state, .. }) = atn
6345 .state(state_number)
6346 .and_then(|state| state.transitions().first())
6347 .map(ParserTransition::data)
6348 else {
6349 continue;
6350 };
6351 if self
6352 .cached_state_expected_token_set(atn, follow_state)
6353 .contains(symbol)
6354 {
6355 return true;
6356 }
6357 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6358 return false;
6359 }
6360 }
6361 symbol == TOKEN_EOF
6362 }
6363
6364 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
6366 let error_index = self.input.index();
6367 self.no_viable_alternative_error_at(start_index, error_index)
6368 }
6369
6370 pub fn no_viable_alternative_error_at(
6375 &self,
6376 start_index: usize,
6377 error_index: usize,
6378 ) -> AntlrError {
6379 let diagnostic = self.no_viable_alternative(start_index, error_index);
6380 AntlrError::ParserError {
6381 line: diagnostic.line,
6382 column: diagnostic.column,
6383 message: diagnostic.message,
6384 }
6385 }
6386
6387 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
6389 let current = self.input.lt(1);
6390 AntlrError::ParserError {
6391 line: current.as_ref().map(Token::line).unwrap_or_default(),
6392 column: current.as_ref().map(Token::column).unwrap_or_default(),
6393 message: format!("rule failed predicate: {}", message.into()),
6394 }
6395 }
6396
6397 pub fn failed_predicate_option_error(
6400 &self,
6401 rule_index: usize,
6402 message: impl Into<String>,
6403 ) -> AntlrError {
6404 let current = self.input.lt(1);
6405 let rule_name = self
6406 .rule_names()
6407 .get(rule_index)
6408 .map_or_else(|| rule_index.to_string(), Clone::clone);
6409 AntlrError::ParserError {
6410 line: current.as_ref().map(Token::line).unwrap_or_default(),
6411 column: current.as_ref().map(Token::column).unwrap_or_default(),
6412 message: format!("rule {rule_name} {}", message.into()),
6413 }
6414 }
6415
6416 pub fn parser_action_at_current(
6418 &mut self,
6419 source_state: usize,
6420 rule_index: usize,
6421 start_index: usize,
6422 consumed_eof: bool,
6423 ) -> ParserAction {
6424 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6425 ParserAction::new(source_state, rule_index, start_index, stop_index)
6426 }
6427
6428 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
6433 let rule_index = action.rule_index();
6434 let rule_name = self.rule_names().get(rule_index).cloned();
6435 let context = None;
6436 let input = &mut self.input;
6437 let semantic_hooks = &mut self.semantic_hooks;
6438 let member_values = &self.int_members;
6439 let mut ctx = ParserSemCtx {
6440 input,
6441 tree_storage: &self.tree,
6442 rule_index,
6443 coordinate_index: usize::MAX,
6444 rule_name,
6445 context,
6446 tree: Some(tree),
6447 local_int_arg: None,
6448 member_values,
6449 action: Some(action),
6450 };
6451 let handled = semantic_hooks.action(&mut ctx, action);
6452 if !handled && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error) {
6458 let coordinate = (rule_index, action.source_state());
6459 if !self.unhandled_action_hits.contains(&coordinate) {
6460 self.unhandled_action_hits.push(coordinate);
6461 }
6462 }
6463 handled
6464 }
6465
6466 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
6471 &mut self,
6472 atn: &'atn Atn,
6473 simulator: &mut ParserAtnSimulator<'atn>,
6474 rule_index: usize,
6475 ) -> Result<ParseTree, AntlrError> {
6476 let start_index = self.current_visible_index();
6477 self.clear_prediction_diagnostics();
6478 self.reset_per_parse_caches();
6479 self.reset_recognition_arena();
6480 let tree_checkpoint = self.tree.checkpoint();
6481 let mut decision_by_state = vec![None; atn.states().len()];
6482 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
6483 if let Some(slot) = decision_by_state.get_mut(state_number) {
6484 *slot = Some(decision);
6485 }
6486 }
6487
6488 let result = DirectAdaptiveParser {
6489 parser: self,
6490 atn,
6491 simulator,
6492 decision_by_state,
6493 steps: 0,
6494 }
6495 .parse_rule(rule_index, -1, 0);
6496
6497 match result {
6498 Ok(tree) => {
6499 self.report_token_source_errors();
6500 self.release_tree_scratch_if_idle();
6501 Ok(tree)
6502 }
6503 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
6504 let _ = reason;
6505 self.tree.rollback(tree_checkpoint);
6506 self.input.seek(start_index);
6507 self.parse_atn_rule(atn, rule_index)
6508 }
6509 }
6510 }
6511
6512 pub fn parse_atn_rule(
6522 &mut self,
6523 atn: &Atn,
6524 rule_index: usize,
6525 ) -> Result<ParseTree, AntlrError> {
6526 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
6527 }
6528
6529 pub fn parse_atn_rule_with_precedence(
6532 &mut self,
6533 atn: &Atn,
6534 rule_index: usize,
6535 precedence: i32,
6536 ) -> Result<ParseTree, AntlrError> {
6537 self.parse_atn_rule_with_precedence_inner(atn, rule_index, precedence, None)
6538 }
6539
6540 fn parse_atn_rule_with_precedence_inner(
6541 &mut self,
6542 atn: &Atn,
6543 rule_index: usize,
6544 precedence: i32,
6545 predicate_context: Option<FastPredicateContext<'_>>,
6546 ) -> Result<ParseTree, AntlrError> {
6547 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
6548 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
6549 })?;
6550 let stop_state = atn
6551 .rule_to_stop_state()
6552 .get(rule_index)
6553 .filter(|state| *state != usize::MAX)
6554 .ok_or_else(|| {
6555 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
6556 })?;
6557
6558 let start_index = self.current_visible_index();
6559 self.clear_prediction_diagnostics();
6560 self.reset_per_parse_caches();
6561 self.reset_recognition_arena();
6562 let caller_follow_state = self.pending_invoking_follow_state(atn);
6563 self.fast_recovery_enabled = false;
6564 self.fast_token_nodes_enabled = false;
6565 let top_request = FastRecognizeTopRequest {
6566 start_state,
6567 stop_state,
6568 start_index,
6569 precedence,
6570 caller_follow_state,
6571 };
6572 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
6573 self.fast_token_nodes_enabled = self.build_parse_trees;
6574 let needs_tree_retry = matches!(
6575 &first_pass,
6576 Ok((outcome, _))
6577 if self.build_parse_trees
6578 && self
6579 .recognition_arena
6580 .sequence_has_left_recursive_boundary(outcome.nodes)
6581 );
6582 let needs_retry = match &first_pass {
6583 Err(_) => true,
6596 Ok((outcome, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
6597 };
6598 let (outcome, _expected) = if needs_retry {
6599 self.fast_first_set_prefilter = false;
6600 self.fast_recovery_enabled = false;
6601 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6602 let clean_selected = if needs_tree_retry {
6603 match clean_retry {
6604 ok @ Ok(_) => ok,
6605 Err(_) => first_pass,
6606 }
6607 } else {
6608 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
6609 };
6610 let selected = if clean_selected.is_err()
6611 || matches!(&clean_selected, Ok((outcome, _)) if !outcome.diagnostics.is_empty())
6612 {
6613 self.fast_recovery_enabled = true;
6614 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
6615 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
6616 } else {
6617 clean_selected
6618 };
6619 self.fast_first_set_prefilter = true;
6620 self.fast_recovery_enabled = true;
6621 selected.map_err(|expected| {
6622 if predicate_context.is_some()
6623 && let Some(error) = self.unknown_semantic_error()
6624 {
6625 self.report_token_source_errors();
6626 return error;
6627 }
6628 let error = self.recognition_error(rule_index, start_index, &expected);
6629 self.record_syntax_errors(1);
6630 self.report_token_source_errors();
6631 error
6632 })?
6633 } else {
6634 first_pass.expect("first_pass is Ok in the no-retry branch")
6635 };
6636 if predicate_context.is_some()
6637 && let Some(error) = self.unknown_semantic_error()
6638 {
6639 self.report_token_source_errors();
6640 return Err(error);
6641 }
6642 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
6643 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
6644 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
6645 self.report_token_source_errors();
6646 let mut context = ParserRuleContext::with_child_capacity(
6647 rule_index,
6648 self.state(),
6649 if self.build_parse_trees {
6650 self.recognition_arena.sequence_len(outcome.nodes)
6651 } else {
6652 0
6653 },
6654 );
6655 if let Some(token) = self.token_id_at(start_index) {
6656 self.set_context_start(&mut context, token);
6657 }
6658 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
6659 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
6660 self.set_context_stop(&mut context, token);
6661 }
6662 let live_root = if self.build_parse_trees {
6663 self.recognition_arena
6664 .fold_left_recursive_boundaries(outcome.nodes)
6665 } else {
6666 outcome.nodes
6667 };
6668 if self.build_parse_trees {
6669 if self
6670 .recognition_arena
6671 .sequence_has_explicit_token(live_root)
6672 {
6673 let mut cursor = live_root;
6674 while let Some(link) = self.recognition_arena.link(cursor) {
6675 let child = self.arena_recognized_node_tree(link.head, false)?;
6676 self.tree.add_child(&mut context, child);
6677 cursor = link.tail;
6678 }
6679 } else {
6680 self.add_arena_implicit_token_children(
6681 &mut context,
6682 start_index,
6683 stop_index,
6684 live_root,
6685 )?;
6686 }
6687 }
6688 self.finish_recognition_arena(live_root, outcome.diagnostics);
6689 self.input.seek(outcome.index);
6690
6691 let tree = self.rule_node(context);
6692 self.release_tree_scratch_if_idle();
6693 Ok(tree)
6694 }
6695
6696 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
6697 let invoking_state = self.pending_invoking_states.last().copied()?;
6698 let state_number = usize::try_from(invoking_state).ok()?;
6699 match atn.state(state_number)?.transitions().first()?.data() {
6700 Transition::Rule { follow_state, .. } => Some(follow_state),
6701 _ => None,
6702 }
6703 }
6704
6705 #[cfg(test)]
6706 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
6707 caller_follow_token_info_for_stream(&mut self.input, index)
6708 }
6709
6710 fn fast_recognize_top(
6715 &mut self,
6716 atn: &Atn,
6717 request: FastRecognizeTopRequest,
6718 predicate_context: Option<FastPredicateContext<'_>>,
6719 ) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
6720 let FastRecognizeTopRequest {
6721 start_state,
6722 stop_state,
6723 start_index,
6724 precedence,
6725 caller_follow_state,
6726 } = request;
6727 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
6736 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
6737 recognize_scratch.prepare(memo_capacity);
6738 let mut expected = ExpectedTokens::default();
6739 let empty_recovery = self.empty_recovery_symbols();
6740 let outcomes = self.recognize_state_fast(
6741 atn,
6742 FastRecognizeRequest {
6743 state_number: start_state,
6744 stop_state,
6745 index: start_index,
6746 rule_start_index: start_index,
6747 decision_start_index: None,
6748 precedence,
6749 depth: 0,
6750 recovery_symbols: empty_recovery,
6751 recovery_state: None,
6752 },
6753 FastRecognizeScratch {
6754 predicate_context,
6755 visiting: &mut recognize_scratch.visiting,
6756 memo: &mut recognize_scratch.memo,
6757 expected: &mut expected,
6758 native_depth: 0,
6759 },
6760 );
6761 recognize_scratch.release_oversized_memo();
6762 self.fast_recognize_scratch = recognize_scratch;
6763 #[cfg(feature = "perf-counters")]
6764 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
6765 perf_counters::dump();
6766 perf_counters::reset();
6767 }
6768 let caller_follow =
6769 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
6770 let selected = {
6771 let arena = &self.recognition_arena;
6772 let input = &mut self.input;
6773 select_best_fast_outcome(
6774 outcomes.into_iter(),
6775 self.prediction_mode,
6776 caller_follow.as_deref(),
6777 |index| caller_follow_token_info_for_stream(input, index),
6778 arena,
6779 )
6780 };
6781 match selected {
6782 Some(mut outcome) => {
6783 if self.build_parse_trees {
6784 self.materialize_fast_outcome_nodes(&mut outcome);
6785 }
6786 Ok((outcome, expected))
6787 }
6788 None => Err(expected),
6789 }
6790 }
6791
6792 fn arena_recognized_node_tree(
6794 &mut self,
6795 node_id: RecognizedNodeId,
6796 track_alt_numbers: bool,
6797 ) -> Result<ParseTree, AntlrError> {
6798 let node = self.recognition_arena.node(node_id);
6799 match node {
6800 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
6801 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
6802 ArenaRecognizedNode::MissingToken { extra } => {
6803 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
6804 RecognitionExtra::MissingToken {
6805 token_type,
6806 at_index,
6807 text,
6808 } => (*token_type, *at_index as usize, text.clone()),
6809 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
6810 unreachable!("missing-token node must reference missing-token extra")
6811 }
6812 };
6813 let (line, column) = self
6814 .token_at(at_index)
6815 .map_or((0, 0), |token| (token.line(), token.column()));
6816 let token = self.insert_synthetic_token(token_type, text, line, column)?;
6817 Ok(self.error_tree(token))
6818 }
6819 ArenaRecognizedNode::Rule {
6820 rule_index,
6821 invoking_state,
6822 alt_number,
6823 start_index,
6824 stop_index,
6825 return_values,
6826 children,
6827 } => {
6828 let mut context = ParserRuleContext::with_child_capacity(
6829 rule_index as usize,
6830 invoking_state as isize,
6831 self.recognition_arena.sequence_len(children),
6832 );
6833 if track_alt_numbers {
6834 context.set_alt_number(alt_number as usize);
6835 }
6836 if let Some(extra) = return_values {
6837 let RecognitionExtra::ReturnValues(values) =
6838 self.recognition_arena.extra(extra)
6839 else {
6840 unreachable!("rule node must reference return-values extra");
6841 };
6842 for (name, value) in values {
6843 context.set_int_return(name.clone(), *value);
6844 }
6845 }
6846 if let Some(token) = self.token_id_at(start_index as usize) {
6847 self.set_context_start(&mut context, token);
6848 }
6849 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
6850 self.set_context_stop(&mut context, token);
6851 }
6852 let mut cursor = self
6853 .recognition_arena
6854 .fold_left_recursive_boundaries(children);
6855 while let Some(link) = self.recognition_arena.link(cursor) {
6856 let child = self.arena_recognized_node_tree(link.head, track_alt_numbers)?;
6857 self.tree.add_child(&mut context, child);
6858 cursor = link.tail;
6859 }
6860 Ok(self.rule_node(context))
6861 }
6862 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index } => {
6863 Err(AntlrError::Unsupported(format!(
6864 "unfolded left-recursive boundary for rule {rule_index}"
6865 )))
6866 }
6867 }
6868 }
6869
6870 fn arena_recognized_node_tree_with_implicit_tokens(
6871 &mut self,
6872 node_id: RecognizedNodeId,
6873 ) -> Result<ParseTree, AntlrError> {
6874 let node = self.recognition_arena.node(node_id);
6875 match node {
6876 ArenaRecognizedNode::Rule {
6877 rule_index,
6878 invoking_state,
6879 start_index,
6880 stop_index,
6881 children,
6882 ..
6883 } => {
6884 let mut context = ParserRuleContext::with_child_capacity(
6885 rule_index as usize,
6886 invoking_state as isize,
6887 self.recognition_arena.sequence_len(children),
6888 );
6889 if let Some(token) = self.token_id_at(start_index as usize) {
6890 self.set_context_start(&mut context, token);
6891 }
6892 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
6893 self.set_context_stop(&mut context, token);
6894 }
6895 let children = self
6896 .recognition_arena
6897 .fold_left_recursive_boundaries(children);
6898 self.add_arena_implicit_token_children(
6899 &mut context,
6900 start_index as usize,
6901 stop_index.map(|index| index as usize),
6902 children,
6903 )?;
6904 Ok(self.rule_node(context))
6905 }
6906 _ => self.arena_recognized_node_tree(node_id, false),
6907 }
6908 }
6909
6910 fn add_arena_implicit_token_children(
6911 &mut self,
6912 context: &mut ParserRuleContext,
6913 start_index: usize,
6914 stop_index: Option<usize>,
6915 mut children: NodeSeqId,
6916 ) -> Result<(), AntlrError> {
6917 let mut cursor = Some(start_index);
6918 while let Some(link) = self.recognition_arena.link(children) {
6919 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
6920 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
6921 let child = self.arena_recognized_node_tree_with_implicit_tokens(link.head)?;
6922 self.tree.add_child(context, child);
6923 if let Some(child_stop) = child_stop {
6924 cursor = self.next_visible_after_token(child_stop);
6925 }
6926 } else {
6927 let child = self.arena_recognized_node_tree_with_implicit_tokens(link.head)?;
6928 self.tree.add_child(context, child);
6929 }
6930 children = link.tail;
6931 }
6932 if let Some(stop) = stop_index {
6933 self.add_visible_terminals_through(context, cursor, stop)?;
6934 }
6935 Ok(())
6936 }
6937
6938 fn add_visible_terminals_before(
6939 &mut self,
6940 context: &mut ParserRuleContext,
6941 cursor: &mut Option<usize>,
6942 before: usize,
6943 ) -> Result<(), AntlrError> {
6944 let Some(stop) = before.checked_sub(1) else {
6945 return Ok(());
6946 };
6947 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
6948 *cursor = next;
6949 Ok(())
6950 }
6951
6952 fn add_visible_terminals_through(
6953 &mut self,
6954 context: &mut ParserRuleContext,
6955 mut cursor: Option<usize>,
6956 stop: usize,
6957 ) -> Result<Option<usize>, AntlrError> {
6958 while let Some(index) = cursor {
6959 if index > stop {
6960 return Ok(Some(index));
6961 }
6962 let token = self
6963 .input
6964 .get_id(index)
6965 .ok_or_else(|| AntlrError::ParserError {
6966 line: 0,
6967 column: 0,
6968 message: format!("missing token at index {index}"),
6969 })?;
6970 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
6971 let child = self.terminal_tree(token);
6972 self.tree.add_child(context, child);
6973 if is_eof {
6974 return Ok(None);
6975 }
6976 cursor = self.next_visible_after_token(index);
6977 }
6978 Ok(None)
6979 }
6980
6981 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
6982 let next = self.input.next_visible_after(index);
6983 (next != index).then_some(next)
6984 }
6985
6986 pub fn parse_atn_rule_with_actions(
6993 &mut self,
6994 atn: &Atn,
6995 rule_index: usize,
6996 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
6997 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
6998 }
6999
7000 pub fn parse_atn_rule_with_action_inits(
7008 &mut self,
7009 atn: &Atn,
7010 rule_index: usize,
7011 init_action_rules: &[usize],
7012 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7013 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
7014 }
7015
7016 pub fn parse_atn_rule_with_action_options(
7022 &mut self,
7023 atn: &Atn,
7024 rule_index: usize,
7025 init_action_rules: &[usize],
7026 track_alt_numbers: bool,
7027 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7028 self.parse_atn_rule_with_runtime_options(
7029 atn,
7030 rule_index,
7031 ParserRuntimeOptions {
7032 init_action_rules,
7033 track_alt_numbers,
7034 ..ParserRuntimeOptions::default()
7035 },
7036 )
7037 }
7038
7039 pub fn parse_atn_rule_with_runtime_options(
7046 &mut self,
7047 atn: &Atn,
7048 rule_index: usize,
7049 options: ParserRuntimeOptions<'_>,
7050 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7051 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
7052 }
7053
7054 pub fn parse_atn_rule_with_runtime_options_and_precedence(
7057 &mut self,
7058 atn: &Atn,
7059 rule_index: usize,
7060 precedence: i32,
7061 options: ParserRuntimeOptions<'_>,
7062 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7063 let ParserRuntimeOptions {
7064 init_action_rules,
7065 track_alt_numbers,
7066 predicates,
7067 semantics,
7068 rule_args,
7069 member_actions,
7070 return_actions,
7071 unknown_predicate_policy,
7072 } = options;
7073 if init_action_rules.is_empty()
7074 && !track_alt_numbers
7075 && predicates.is_empty()
7076 && semantics.is_none()
7077 && rule_args.is_empty()
7078 && member_actions.is_empty()
7079 && return_actions.is_empty()
7080 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
7081 && !atn_has_observable_action_transitions(atn)
7082 && (!self.semantic_hooks.observes_parser_predicates()
7083 || !atn_has_predicate_transitions(atn))
7084 {
7085 return self
7086 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
7087 .map(|tree| (tree, Vec::new()));
7088 }
7089 if can_use_fast_predicate_recognizer(atn, &options) {
7090 self.unknown_predicate_policy = unknown_predicate_policy;
7091 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7092 let member_values = self.int_members.clone();
7093 let result = self
7094 .parse_atn_rule_with_precedence_inner(
7095 atn,
7096 rule_index,
7097 precedence,
7098 Some(FastPredicateContext {
7099 predicates,
7100 semantics,
7101 member_values: &member_values,
7102 }),
7103 )
7104 .map(|tree| (tree, Vec::new()));
7105 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
7106 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7107 }
7108 return result;
7109 }
7110 self.unknown_predicate_policy = unknown_predicate_policy;
7111 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7118 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7119 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7120 })?;
7121 let stop_state = atn
7122 .rule_to_stop_state()
7123 .get(rule_index)
7124 .filter(|state| *state != usize::MAX)
7125 .ok_or_else(|| {
7126 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7127 })?;
7128
7129 let start_index = self.current_visible_index();
7130 self.clear_prediction_diagnostics();
7131 self.reset_per_parse_caches();
7132 self.reset_recognition_arena();
7133 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
7134 let invoking_state = self.pending_invoking_states.pop();
7135 let local_int_arg = invoking_state
7136 .and_then(|state| usize::try_from(state).ok())
7137 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
7138 let mut visiting = BTreeSet::new();
7139 let mut memo = BTreeMap::new();
7140 let mut expected = ExpectedTokens::default();
7141 let member_values = self.int_members.clone();
7142 let return_values = BTreeMap::new();
7143 let outcomes = self.recognize_state(
7144 atn,
7145 RecognizeRequest {
7146 state_number: start_state,
7147 stop_state,
7148 index: start_index,
7149 rule_start_index: start_index,
7150 decision_start_index: None,
7151 init_action_rules: &init_action_rules,
7152 predicates,
7153 semantics,
7154 rule_args,
7155 member_actions,
7156 return_actions,
7157 local_int_arg,
7158 member_values,
7159 return_values,
7160 rule_alt_number: 0,
7161 track_alt_numbers,
7162 consumed_eof: false,
7163 precedence,
7164 depth: 0,
7165 recovery_symbols: BTreeSet::new(),
7166 recovery_state: None,
7167 },
7168 &mut visiting,
7169 &mut memo,
7170 &mut expected,
7171 );
7172 if let Some(error) = self.unknown_semantic_error() {
7173 self.report_token_source_errors();
7174 return Err(error);
7181 }
7182 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7185 let Some(outcome) = select_best_outcome(
7186 outcomes.into_iter(),
7187 self.prediction_mode,
7188 &self.recognition_arena,
7189 ) else {
7190 let error = self.recognition_error(rule_index, start_index, &expected);
7191 self.record_syntax_errors(1);
7192 self.report_token_source_errors();
7193 return Err(error);
7194 };
7195
7196 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7197 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7198 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7199 self.report_token_source_errors();
7200 let mut actions = outcome.actions;
7201 if init_action_rules.contains(&rule_index) {
7202 actions.insert(
7203 0,
7204 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
7205 );
7206 }
7207 let mut context =
7208 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
7209 if track_alt_numbers {
7210 context.set_alt_number(outcome.alt_number);
7211 }
7212 for (name, value) in outcome.return_values {
7213 context.set_int_return(name, value);
7214 }
7215 if let Some(token) = self.token_id_at(start_index) {
7216 self.set_context_start(&mut context, token);
7217 }
7218 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
7219 self.set_context_stop(&mut context, token);
7220 }
7221 let live_root = if self.build_parse_trees {
7222 self.recognition_arena
7223 .fold_left_recursive_boundaries(outcome.nodes)
7224 } else {
7225 outcome.nodes
7226 };
7227 if self.build_parse_trees {
7228 let mut nodes = live_root;
7229 while let Some(link) = self.recognition_arena.link(nodes) {
7230 let child = self.arena_recognized_node_tree(link.head, track_alt_numbers)?;
7231 self.tree.add_child(&mut context, child);
7232 nodes = link.tail;
7233 }
7234 }
7235 self.finish_recognition_arena(live_root, outcome.diagnostics);
7236 self.input.seek(outcome.index);
7237
7238 let tree = self.rule_node(context);
7239 self.release_tree_scratch_if_idle();
7240 Ok((tree, actions))
7241 }
7242
7243 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
7250 let mut context = ParserRuleContext::new(rule_index, self.state());
7251 while self.la(1) != TOKEN_EOF {
7252 let token_type = self.la(1);
7253 let child = self.match_token(token_type)?;
7254 if self.build_parse_trees {
7255 self.tree.add_child(&mut context, child);
7256 }
7257 }
7258 if self.build_parse_trees {
7259 let child = self.match_eof()?;
7260 self.tree.add_child(&mut context, child);
7261 }
7262 let tree = self.rule_node(context);
7263 self.release_tree_scratch_if_idle();
7264 Ok(tree)
7265 }
7266
7267 fn recognition_error(
7270 &mut self,
7271 rule_index: usize,
7272 start_index: usize,
7273 expected: &ExpectedTokens,
7274 ) -> AntlrError {
7275 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
7276 self.input.seek(index);
7277 let current = self.input.lt(1);
7278 let line = current.as_ref().map(Token::line).unwrap_or_default();
7279 let column = current.as_ref().map(Token::column).unwrap_or_default();
7280 AntlrError::ParserError {
7281 line,
7282 column,
7283 message,
7284 }
7285 }
7286
7287 fn expected_error_message(
7289 &mut self,
7290 rule_index: usize,
7291 start_index: usize,
7292 expected: &ExpectedTokens,
7293 ) -> (usize, String) {
7294 let index = expected
7295 .index
7296 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
7297 .unwrap_or_else(|| self.input.index());
7298 self.input.seek(index);
7299 let current = self.input.lt(1);
7300 let message = if expected
7301 .no_viable
7302 .as_ref()
7303 .is_some_and(|no_viable| no_viable.error_index == index)
7304 {
7305 let start = expected
7306 .no_viable
7307 .as_ref()
7308 .map_or(start_index, |no_viable| no_viable.start_index);
7309 let text = display_input_text(&self.input.text(start, index));
7310 format!("no viable alternative at input '{text}'")
7311 } else if expected.symbols.is_empty() {
7312 if expected.index.is_some() {
7313 let found = current
7314 .as_ref()
7315 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
7316 if current
7317 .as_ref()
7318 .is_some_and(|token| token.token_type() == TOKEN_EOF)
7319 {
7320 format!(
7321 "missing {} at {found}",
7322 self.expected_symbols_display(&expected.symbols)
7323 )
7324 } else {
7325 format!("mismatched input {found}")
7326 }
7327 } else {
7328 format!("no viable alternative while parsing rule {rule_index}")
7329 }
7330 } else {
7331 format!(
7332 "mismatched input {} expecting {}",
7333 current
7334 .as_ref()
7335 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7336 self.expected_symbols_display(&expected.symbols)
7337 )
7338 };
7339 (index, message)
7340 }
7341
7342 fn child_rule_failure_recovery(
7345 &mut self,
7346 rule_index: usize,
7347 start_index: usize,
7348 sync_symbols: &BTreeSet<i32>,
7349 member_values: BTreeMap<usize, i64>,
7350 expected: &ExpectedTokens,
7351 ) -> Option<RecognizeOutcome> {
7352 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7353 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7354 let mut next_index = error_index;
7355 loop {
7356 let symbol = self.token_type_at(next_index);
7357 if sync_symbols.contains(&symbol) {
7358 if next_index == error_index {
7359 return None;
7360 }
7361 break;
7362 }
7363 if symbol == TOKEN_EOF {
7364 break;
7365 }
7366 let after = self.consume_index(next_index, symbol);
7367 if after == next_index {
7368 break;
7369 }
7370 next_index = after;
7371 }
7372 let mut nodes = NodeSeqId::EMPTY;
7373 let error = self.arena_token_node(error_index, true);
7374 self.arena_prepend(&mut nodes, error);
7375 let diagnostics = self
7376 .recognition_arena
7377 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7378 Some(RecognizeOutcome {
7379 index: next_index,
7380 consumed_eof: false,
7381 alt_number: 0,
7382 member_values,
7383 return_values: BTreeMap::new(),
7384 diagnostics,
7385 decisions: Vec::new(),
7386 actions: Vec::new(),
7387 nodes,
7388 })
7389 }
7390
7391 fn child_rule_failure_recovery_outcomes(
7394 &mut self,
7395 request: ChildRuleFailureRecovery<'_>,
7396 ) -> Vec<RecognizeOutcome> {
7397 let sync_symbols =
7398 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
7399 self.child_rule_failure_recovery(
7400 request.rule_index,
7401 request.start_index,
7402 &sync_symbols,
7403 request.member_values,
7404 request.expected,
7405 )
7406 .into_iter()
7407 .collect()
7408 }
7409
7410 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
7412 expected_symbols_display(symbols, self.vocabulary())
7413 }
7414
7415 fn single_token_deletion(
7418 &mut self,
7419 transition: ParserTransition<'_>,
7420 index: usize,
7421 max_token_type: i32,
7422 expected_symbols: &BTreeSet<i32>,
7423 ) -> Option<(ParserDiagnostic, usize, i32)> {
7424 let current_symbol = self.token_type_at(index);
7425 if current_symbol == TOKEN_EOF {
7426 return None;
7427 }
7428 let next_index = self.consume_index(index, current_symbol);
7429 if next_index == index {
7430 return None;
7431 }
7432 let next_symbol = self.token_type_at(next_index);
7433 if !transition.matches(next_symbol, 1, max_token_type) {
7434 return None;
7435 }
7436 let transition_expected = transition_expected_symbols(transition, max_token_type);
7437 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7438 &transition_expected
7439 } else {
7440 expected_symbols
7441 });
7442 let current = self.token_at(index);
7443 let message = format!(
7444 "extraneous input {} expecting {expected_display}",
7445 current
7446 .as_ref()
7447 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7448 );
7449 Some((
7450 diagnostic_for_token(current, message),
7451 next_index,
7452 next_symbol,
7453 ))
7454 }
7455
7456 fn current_token_deletion(
7459 &mut self,
7460 index: usize,
7461 expected_symbols: &BTreeSet<i32>,
7462 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
7463 if expected_symbols.is_empty() {
7464 return None;
7465 }
7466 let current_symbol = self.token_type_at(index);
7467 if current_symbol == TOKEN_EOF {
7468 return None;
7469 }
7470 let current = self.token_at(index);
7471 let message = format!(
7472 "extraneous input {} expecting {}",
7473 current
7474 .as_ref()
7475 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7476 self.expected_symbols_display(expected_symbols)
7477 );
7478 let diagnostic = diagnostic_for_token(current, message);
7479 let mut skipped = Vec::new();
7480 let mut cursor = index;
7481 loop {
7482 let symbol = self.token_type_at(cursor);
7483 if symbol == TOKEN_EOF {
7484 return None;
7485 }
7486 skipped.push(cursor);
7487 let next_index = self.consume_index(cursor, symbol);
7488 if next_index == cursor {
7489 return None;
7490 }
7491 let next_symbol = self.token_type_at(next_index);
7492 if expected_symbols.contains(&next_symbol) {
7493 return Some((diagnostic, next_index, skipped));
7494 }
7495 cursor = next_index;
7496 }
7497 }
7498
7499 fn single_token_insertion(
7503 &mut self,
7504 transition: ParserTransition<'_>,
7505 index: usize,
7506 max_token_type: i32,
7507 expected_symbols: &BTreeSet<i32>,
7508 follow_symbols: &BTreeSet<i32>,
7509 ) -> Option<(ParserDiagnostic, i32, String)> {
7510 let current_symbol = self.token_type_at(index);
7511 if !follow_symbols.contains(¤t_symbol) {
7512 return None;
7513 }
7514 let transition_expected = transition_expected_symbols(transition, max_token_type);
7515 let token_type = transition_expected.iter().next().copied()?;
7516 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
7517 &transition_expected
7518 } else {
7519 expected_symbols
7520 });
7521 let mut token_symbols = BTreeSet::new();
7522 token_symbols.insert(token_type);
7523 let missing_token_display = self.expected_symbols_display(&token_symbols);
7524 let current = self.token_at(index);
7525 let message = format!(
7526 "missing {expected_display} at {}",
7527 current
7528 .as_ref()
7529 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
7530 );
7531 let text = format!("<missing {missing_token_display}>");
7532 Some((
7533 diagnostic_for_token(current.as_ref(), message),
7534 token_type,
7535 text,
7536 ))
7537 }
7538
7539 fn fast_single_token_deletion_recovery(
7543 &mut self,
7544 recovery: FastRecoveryRequest<'_, '_>,
7545 predicate_context: Option<FastPredicateContext<'_>>,
7546 ) -> Vec<FastRecognizeOutcome> {
7547 let FastRecoveryRequest {
7548 atn,
7549 transition,
7550 expected_symbols,
7551 target,
7552 request,
7553 visiting,
7554 memo,
7555 expected,
7556 } = recovery;
7557 let FastRecognizeRequest {
7558 stop_state,
7559 index,
7560 rule_start_index,
7561 decision_start_index,
7562 precedence,
7563 depth,
7564 ..
7565 } = request;
7566 let Some((diagnostic, next_index, next_symbol)) =
7567 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
7568 else {
7569 return Vec::new();
7570 };
7571 let after_next = self.consume_index(next_index, next_symbol);
7572 let empty_recovery = self.empty_recovery_symbols();
7573 self.recognize_state_fast(
7574 atn,
7575 FastRecognizeRequest {
7576 state_number: target,
7577 stop_state,
7578 index: after_next,
7579 rule_start_index,
7580 decision_start_index,
7581 precedence,
7582 depth: depth + 1,
7583 recovery_symbols: empty_recovery,
7584 recovery_state: None,
7585 },
7586 FastRecognizeScratch {
7587 predicate_context,
7588 visiting,
7589 memo,
7590 expected,
7591 native_depth: 0,
7592 },
7593 )
7594 .into_iter()
7595 .map(|mut outcome| {
7596 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
7597 outcome.diagnostics = self
7598 .recognition_arena
7599 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7600 if self.fast_token_nodes_enabled {
7601 let token = self.arena_token_node(next_index, false);
7602 self.defer_fast_outcome_node(&mut outcome, token);
7603 let error = self.arena_token_node(index, true);
7604 self.defer_fast_outcome_node(&mut outcome, error);
7605 }
7606 outcome
7607 })
7608 .collect()
7609 }
7610
7611 fn fast_single_token_insertion_recovery(
7615 &mut self,
7616 recovery: FastRecoveryRequest<'_, '_>,
7617 predicate_context: Option<FastPredicateContext<'_>>,
7618 ) -> Vec<FastRecognizeOutcome> {
7619 let FastRecoveryRequest {
7620 atn,
7621 transition,
7622 expected_symbols,
7623 target,
7624 request,
7625 visiting,
7626 memo,
7627 expected,
7628 } = recovery;
7629 let FastRecognizeRequest {
7630 stop_state,
7631 index,
7632 rule_start_index,
7633 decision_start_index,
7634 precedence,
7635 depth,
7636 ..
7637 } = request;
7638 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
7639 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
7640 transition,
7641 index,
7642 atn.max_token_type(),
7643 &expected_symbols,
7644 &follow_symbols,
7645 ) else {
7646 return Vec::new();
7647 };
7648 let empty_recovery = self.empty_recovery_symbols();
7649 self.recognize_state_fast(
7650 atn,
7651 FastRecognizeRequest {
7652 state_number: target,
7653 stop_state,
7654 index,
7655 rule_start_index,
7656 decision_start_index,
7657 precedence,
7658 depth: depth + 1,
7659 recovery_symbols: empty_recovery,
7660 recovery_state: None,
7661 },
7662 FastRecognizeScratch {
7663 predicate_context,
7664 visiting,
7665 memo,
7666 expected,
7667 native_depth: 0,
7668 },
7669 )
7670 .into_iter()
7671 .map(|mut outcome| {
7672 outcome.diagnostics = self
7673 .recognition_arena
7674 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7675 let missing = self.arena_missing_token_node(token_type, index, text.clone());
7676 self.defer_fast_outcome_node(&mut outcome, missing);
7677 outcome
7678 })
7679 .collect()
7680 }
7681
7682 fn fast_current_token_deletion_recovery(
7685 &mut self,
7686 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
7687 predicate_context: Option<FastPredicateContext<'_>>,
7688 ) -> Vec<FastRecognizeOutcome> {
7689 let FastCurrentTokenDeletionRequest {
7690 atn,
7691 expected_symbols,
7692 mut request,
7693 visiting,
7694 memo,
7695 expected,
7696 } = recovery;
7697 if request.index == request.rule_start_index {
7698 return Vec::new();
7699 }
7700 let Some((diagnostic, next_index, skipped)) =
7701 self.current_token_deletion(request.index, &expected_symbols)
7702 else {
7703 return Vec::new();
7704 };
7705 request.state_number = request.recovery_state.unwrap_or(request.state_number);
7706 request.index = next_index;
7707 request.depth += 1;
7708 request.recovery_state = None;
7709 self.recognize_state_fast(
7710 atn,
7711 request,
7712 FastRecognizeScratch {
7713 predicate_context,
7714 visiting,
7715 memo,
7716 expected,
7717 native_depth: 0,
7718 },
7719 )
7720 .into_iter()
7721 .map(|mut outcome| {
7722 outcome.diagnostics = self
7723 .recognition_arena
7724 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
7725 for index in skipped.iter().rev() {
7726 let error = self.arena_token_node(*index, true);
7727 self.defer_fast_outcome_node(&mut outcome, error);
7728 }
7729 outcome
7730 })
7731 .collect()
7732 }
7733
7734 fn fast_child_rule_failure_recovery(
7737 &mut self,
7738 rule_index: usize,
7739 start_index: usize,
7740 sync_symbols: &BTreeSet<i32>,
7741 expected: &ExpectedTokens,
7742 ) -> Option<FastRecognizeOutcome> {
7743 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7744 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7745 let mut next_index = error_index;
7746 loop {
7747 let symbol = self.token_type_at(next_index);
7748 if sync_symbols.contains(&symbol) {
7749 if next_index == error_index {
7750 return None;
7751 }
7752 break;
7753 }
7754 if symbol == TOKEN_EOF {
7755 break;
7756 }
7757 let after = self.consume_index(next_index, symbol);
7758 if after == next_index {
7759 break;
7760 }
7761 next_index = after;
7762 }
7763 let diagnostics = self
7764 .recognition_arena
7765 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
7766 let mut nodes = NodeSeqId::EMPTY;
7767 if self.fast_token_nodes_enabled {
7768 let error = self.arena_token_node(error_index, true);
7769 self.arena_prepend(&mut nodes, error);
7770 }
7771 Some(FastRecognizeOutcome {
7772 index: next_index,
7773 consumed_eof: false,
7774 diagnostics,
7775 deferred_nodes: FastDeferredNodeId::EMPTY,
7776 nodes,
7777 })
7778 }
7779
7780 fn fast_child_rule_failure_recovery_outcomes(
7783 &mut self,
7784 request: FastChildRuleFailureRecoveryRequest<'_>,
7785 ) -> Vec<FastRecognizeOutcome> {
7786 let FastChildRuleFailureRecoveryRequest {
7787 atn,
7788 rule_index,
7789 start_index,
7790 follow_state,
7791 stop_state,
7792 expected,
7793 } = request;
7794 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
7795 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
7796 .into_iter()
7797 .collect()
7798 }
7799
7800 fn defer_fast_outcome_node(
7801 &mut self,
7802 outcome: &mut FastRecognizeOutcome,
7803 node: RecognizedNodeId,
7804 ) {
7805 if outcome.deferred_nodes.is_empty() {
7806 self.arena_prepend(&mut outcome.nodes, node);
7807 return;
7808 }
7809 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
7810 let fragment = self.recognition_arena.deferred_fragment(fragment);
7811 outcome.deferred_nodes = self
7812 .recognition_arena
7813 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
7814 }
7815
7816 fn materialize_fast_deferred_nodes(
7817 &mut self,
7818 root: FastDeferredNodeId,
7819 initial_suffix: NodeSeqId,
7820 ) -> NodeSeqId {
7821 if root.is_empty() {
7822 return initial_suffix;
7823 }
7824
7825 enum Frame {
7826 Visit(FastDeferredNodeId),
7827 ContinuePrefix(FastDeferredNodeId),
7828 FinishRule {
7829 rule: FastDeferredRule,
7830 parent_suffix: NodeSeqId,
7831 },
7832 }
7833
7834 let mut result = initial_suffix;
7835 let mut pending = Vec::with_capacity(16);
7836 pending.push(Frame::Visit(root));
7837 let mut fragment_nodes = Vec::new();
7838 while let Some(frame) = pending.pop() {
7839 match frame {
7840 Frame::Visit(deferred) => {
7841 if deferred.is_empty() {
7842 continue;
7843 }
7844
7845 match self.recognition_arena.deferred_node(deferred) {
7846 FastDeferredNode::Fragment(sequence) => {
7847 fragment_nodes.clear();
7848 fragment_nodes.extend(self.recognition_arena.iter(sequence));
7849 while let Some(node) = fragment_nodes.pop() {
7850 self.arena_prepend(&mut result, node);
7851 }
7852 }
7853 FastDeferredNode::Rule(rule) => {
7854 let rule = self.recognition_arena.deferred_rule(rule);
7855 let parent_suffix = result;
7856 result = rule.children;
7857 pending.push(Frame::FinishRule {
7858 rule,
7859 parent_suffix,
7860 });
7861 pending.push(Frame::Visit(rule.deferred_children));
7862 }
7863 FastDeferredNode::Concat {
7864 prefix,
7865 suffix: deferred_suffix,
7866 } => {
7867 pending.push(Frame::ContinuePrefix(prefix));
7868 pending.push(Frame::Visit(deferred_suffix));
7869 }
7870 }
7871 }
7872 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
7873 Frame::FinishRule {
7874 rule,
7875 parent_suffix,
7876 } => {
7877 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
7878 rule_index: rule.rule_index,
7879 invoking_state: rule.invoking_state,
7880 alt_number: 0,
7881 start_index: rule.start_index,
7882 stop_index: rule.stop_index,
7883 return_values: None,
7884 children: result,
7885 });
7886 result = parent_suffix;
7887 self.arena_prepend(&mut result, node);
7888 }
7889 }
7890 }
7891 result
7892 }
7893
7894 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) {
7895 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
7896 outcome.nodes = self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
7897 }
7898
7899 fn recognize_repetition_fast(
7902 &mut self,
7903 atn: &Atn,
7904 request: &FastRecognizeRequest,
7905 shape: FastRepetitionShape,
7906 scratch: FastRecognizeScratch<'_, '_>,
7907 ) -> Vec<FastRecognizeOutcome> {
7908 let FastRecognizeScratch {
7909 predicate_context,
7910 visiting,
7911 memo,
7912 expected,
7913 native_depth,
7914 } = scratch;
7915 let lookahead = if self.fast_first_set_prefilter {
7916 atn.state(request.state_number).and_then(|state| {
7917 state
7918 .rule_index()
7919 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
7920 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
7921 })
7922 } else {
7923 None
7924 };
7925 let mut work = Vec::with_capacity(2);
7926 push_fast_repetition_work(
7927 &mut work,
7928 shape,
7929 FastRepetitionPath {
7930 index: request.index,
7931 deferred_nodes: FastDeferredNodeId::EMPTY,
7932 diagnostics: DiagnosticSeqId::EMPTY,
7933 consumed_eof: false,
7934 },
7935 lookahead.as_deref(),
7936 self.token_type_at(request.index),
7937 );
7938 let mut coordinates = FastRepetitionCoordinates::new(request.index);
7939 let mut outcomes = Vec::new();
7940 while let Some(item) = work.pop() {
7941 match item {
7942 FastRepetitionWork::Enter(path) => {
7943 if !coordinates.insert_entered(path) {
7944 continue;
7945 }
7946 let body_outcomes = self.recognize_state_fast(
7947 atn,
7948 FastRecognizeRequest {
7949 state_number: shape.enter_target,
7950 stop_state: shape.body_stop_state,
7951 index: path.index,
7952 rule_start_index: request.rule_start_index,
7953 decision_start_index: request.decision_start_index,
7954 precedence: request.precedence,
7955 depth: request.depth.saturating_add(1),
7956 recovery_symbols: Rc::clone(&request.recovery_symbols),
7957 recovery_state: request.recovery_state,
7958 },
7959 FastRecognizeScratch {
7960 predicate_context,
7961 visiting: &mut *visiting,
7962 memo: &mut *memo,
7963 expected: &mut *expected,
7964 native_depth: native_depth + 1,
7965 },
7966 );
7967 for body in body_outcomes.into_iter().rev() {
7968 if body.index <= path.index {
7972 continue;
7973 }
7974 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
7975 let body_nodes = self
7976 .recognition_arena
7977 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
7978 let deferred_nodes = self
7979 .recognition_arena
7980 .concat_deferred_nodes(path.deferred_nodes, body_nodes);
7981 let next_path = FastRepetitionPath {
7982 index: body.index,
7983 deferred_nodes,
7984 diagnostics: self
7985 .recognition_arena
7986 .concat_diagnostics(path.diagnostics, body.diagnostics),
7987 consumed_eof: path.consumed_eof || body.consumed_eof,
7988 };
7989 let symbol = self.token_type_at(next_path.index);
7990 push_fast_repetition_work(
7991 &mut work,
7992 shape,
7993 next_path,
7994 lookahead.as_deref(),
7995 symbol,
7996 );
7997 }
7998 }
7999 FastRepetitionWork::Exit(path) => {
8000 if !coordinates.insert_exited(path) {
8001 continue;
8002 }
8003 let suffixes = self.recognize_state_fast(
8004 atn,
8005 FastRecognizeRequest {
8006 state_number: shape.exit_target,
8007 stop_state: request.stop_state,
8008 index: path.index,
8009 rule_start_index: request.rule_start_index,
8010 decision_start_index: request.decision_start_index,
8011 precedence: request.precedence,
8012 depth: request.depth.saturating_add(1),
8013 recovery_symbols: Rc::clone(&request.recovery_symbols),
8014 recovery_state: request.recovery_state,
8015 },
8016 FastRecognizeScratch {
8017 predicate_context,
8018 visiting: &mut *visiting,
8019 memo: &mut *memo,
8020 expected: &mut *expected,
8021 native_depth: native_depth + 1,
8022 },
8023 );
8024 for mut outcome in suffixes {
8025 outcome.deferred_nodes = self
8026 .recognition_arena
8027 .concat_deferred_nodes(path.deferred_nodes, outcome.deferred_nodes);
8028 outcome.diagnostics = self
8029 .recognition_arena
8030 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
8031 outcome.consumed_eof |= path.consumed_eof;
8032 outcomes.push(outcome);
8033 }
8034 }
8035 }
8036 }
8037 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8038 outcomes
8039 }
8040
8041 fn recognize_state_fast(
8044 &mut self,
8045 atn: &Atn,
8046 request: FastRecognizeRequest,
8047 scratch: FastRecognizeScratch<'_, '_>,
8048 ) -> Vec<FastRecognizeOutcome> {
8049 if scratch.native_depth != 0 && scratch.native_depth < FAST_RECOGNIZE_STACK_CHECK_INTERVAL {
8050 return self.recognize_state_fast_inner(atn, request, scratch);
8051 }
8052 self.recognize_state_fast_checked(atn, request, scratch)
8053 }
8054
8055 #[inline(never)]
8056 fn recognize_state_fast_checked(
8057 &mut self,
8058 atn: &Atn,
8059 request: FastRecognizeRequest,
8060 mut scratch: FastRecognizeScratch<'_, '_>,
8061 ) -> Vec<FastRecognizeOutcome> {
8062 scratch.native_depth = 1;
8063 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, || {
8064 self.recognize_state_fast_inner(atn, request, scratch)
8065 })
8066 }
8067
8068 #[allow(clippy::too_many_lines)]
8069 fn recognize_state_fast_inner(
8070 &mut self,
8071 atn: &Atn,
8072 request: FastRecognizeRequest,
8073 scratch: FastRecognizeScratch<'_, '_>,
8074 ) -> Vec<FastRecognizeOutcome> {
8075 #[cfg(feature = "perf-counters")]
8076 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
8077 let FastRecognizeScratch {
8078 predicate_context,
8079 visiting,
8080 memo,
8081 expected,
8082 native_depth,
8083 } = scratch;
8084 let FastRecognizeRequest {
8085 mut state_number,
8086 stop_state,
8087 mut index,
8088 rule_start_index,
8089 decision_start_index,
8090 precedence,
8091 mut depth,
8092 recovery_symbols,
8093 recovery_state,
8094 } = request;
8095 let max_token_type = atn.max_token_type();
8096 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
8115 let mut inline_consumed_eof = false;
8116 loop {
8117 if depth > RECOGNITION_DEPTH_LIMIT {
8118 return Vec::new();
8119 }
8120 if state_number == stop_state {
8121 let mut nodes = NodeSeqId::EMPTY;
8122 if self.fast_token_nodes_enabled {
8123 for token_index in inline_consumed_tokens.iter().rev() {
8124 let token = self.arena_token_node(*token_index, false);
8125 self.arena_prepend(&mut nodes, token);
8126 }
8127 }
8128 return vec![FastRecognizeOutcome {
8129 index,
8130 consumed_eof: inline_consumed_eof,
8131 diagnostics: DiagnosticSeqId::EMPTY,
8132 deferred_nodes: FastDeferredNodeId::EMPTY,
8133 nodes,
8134 }];
8135 }
8136 let Some(state) = atn.state(state_number) else {
8137 return Vec::new();
8138 };
8139 let transitions = state.transitions();
8140 if transitions.len() == 1 && !state.precedence_rule_decision() {
8141 let transition = transitions
8142 .first()
8143 .expect("single transition checked above");
8144 let transition_kind = transition.kind();
8145 let target = transition.target();
8146 match transition_kind {
8147 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
8148 if left_recursive_boundary(atn, state, target).is_none() =>
8149 {
8150 #[cfg(feature = "perf-counters")]
8151 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8152 state_number = target;
8153 depth += 1;
8154 continue;
8155 }
8156 ParserTransitionKind::Predicate
8157 if left_recursive_boundary(atn, state, target).is_none() =>
8158 {
8159 #[cfg(feature = "perf-counters")]
8160 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8161 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
8162 {
8163 record_predicate_no_viable(expected, decision_start_index, index);
8164 return Vec::new();
8165 }
8166 state_number = target;
8167 depth += 1;
8168 continue;
8169 }
8170 ParserTransitionKind::Precedence
8171 if packed_i32(transition.arg0()) >= precedence
8172 && left_recursive_boundary(atn, state, target).is_none() =>
8173 {
8174 #[cfg(feature = "perf-counters")]
8175 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8176 state_number = target;
8177 depth += 1;
8178 continue;
8179 }
8180 ParserTransitionKind::Atom
8190 | ParserTransitionKind::Range
8191 | ParserTransitionKind::Set
8192 | ParserTransitionKind::NotSet
8193 | ParserTransitionKind::Wildcard
8194 if !self.fast_recovery_enabled =>
8195 {
8196 let symbol = self.token_type_at(index);
8197 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
8198 #[cfg(feature = "perf-counters")]
8199 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
8200 if self.fast_token_nodes_enabled {
8201 inline_consumed_tokens.push(index);
8202 }
8203 inline_consumed_eof |= symbol == TOKEN_EOF;
8204 index = self.consume_index(index, symbol);
8205 state_number = target;
8206 depth += 1;
8207 continue;
8208 }
8209 }
8212 _ => {}
8213 }
8214 }
8215 break;
8216 }
8217 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
8221 let Some(state) = atn.state(state_number) else {
8222 return Vec::new();
8223 };
8224 let transitions = state.transitions();
8225 let transition_count = transitions.len();
8226 if !self.fast_recovery_enabled
8227 && let Some(shape) = fast_repetition_shape(atn, state)
8228 {
8229 let mut outcomes = self.recognize_repetition_fast(
8230 atn,
8231 &FastRecognizeRequest {
8232 state_number,
8233 stop_state,
8234 index,
8235 rule_start_index,
8236 decision_start_index,
8237 precedence,
8238 depth,
8239 recovery_symbols: Rc::clone(&recovery_symbols),
8240 recovery_state,
8241 },
8242 shape,
8243 FastRecognizeScratch {
8244 predicate_context,
8245 visiting: &mut *visiting,
8246 memo: &mut *memo,
8247 expected: &mut *expected,
8248 native_depth: native_depth + 1,
8249 },
8250 );
8251 if inline_pending {
8252 for outcome in &mut outcomes {
8253 outcome.consumed_eof |= inline_consumed_eof;
8254 if self.fast_token_nodes_enabled {
8255 for token_index in inline_consumed_tokens.iter().rev() {
8256 let token = self.arena_token_node(*token_index, false);
8257 self.defer_fast_outcome_node(outcome, token);
8258 }
8259 }
8260 }
8261 }
8262 return outcomes;
8263 }
8264 let key = if self.fast_recovery_enabled {
8274 FastRecognizeKey {
8275 state_number,
8276 stop_state,
8277 index,
8278 rule_start_index,
8279 decision_start_index,
8280 precedence,
8281 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
8282 recovery_state,
8283 }
8284 } else {
8285 FastRecognizeKey {
8286 state_number,
8287 stop_state,
8288 index,
8289 rule_start_index: 0,
8290 decision_start_index: None,
8291 precedence,
8292 recovery_symbols_id: 0,
8293 recovery_state: None,
8294 }
8295 };
8296 let memo_lookup_enabled = self.fast_recovery_enabled
8301 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
8302 if memo_lookup_enabled {
8303 if let Some(outcomes) = memo.get(&key) {
8304 #[cfg(feature = "perf-counters")]
8305 {
8306 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
8307 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
8308 }
8309 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
8313 let inline_eof = inline_consumed_eof;
8314 let inline_tokens = &inline_consumed_tokens;
8315 return outcomes
8316 .iter()
8317 .copied()
8318 .map(|mut outcome| {
8319 if inline_eof {
8320 outcome.consumed_eof = true;
8321 }
8322 if self.fast_token_nodes_enabled {
8323 for token_index in inline_tokens.iter().rev() {
8324 let token = self.arena_token_node(*token_index, false);
8325 self.defer_fast_outcome_node(&mut outcome, token);
8326 }
8327 }
8328 outcome
8329 })
8330 .collect();
8331 }
8332 return outcomes.to_vec();
8333 }
8334 #[cfg(feature = "perf-counters")]
8335 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
8336 }
8337
8338 let needs_cycle_guard = if self.fast_recovery_enabled {
8343 transitions.iter().any(ParserTransition::is_epsilon)
8344 } else {
8345 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
8346 };
8347 #[cfg(feature = "perf-counters")]
8348 if needs_cycle_guard {
8349 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
8350 } else {
8351 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
8352 match state
8353 .transitions()
8354 .first()
8355 .expect("single-transition path requires one transition")
8356 .data()
8357 {
8358 Transition::Rule { .. } => {
8359 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
8360 }
8361 Transition::Atom { .. }
8362 | Transition::Range { .. }
8363 | Transition::Set { .. }
8364 | Transition::NotSet { .. }
8365 | Transition::Wildcard { .. } => {
8366 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
8367 }
8368 _ => {
8369 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
8370 }
8371 }
8372 }
8373 let has_inserted_cycle_guard = if needs_cycle_guard {
8374 if !visiting.insert(key.clone()) {
8375 #[cfg(feature = "perf-counters")]
8376 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
8377 return Vec::new();
8378 }
8379 true
8380 } else {
8381 false
8382 };
8383 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
8384 Some(index)
8385 } else {
8386 decision_start_index
8387 };
8388 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
8389 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
8390 } else {
8391 (Rc::clone(&recovery_symbols), recovery_state)
8392 };
8393
8394 let lookahead_filter = if transition_count > 1
8413 && self.fast_first_set_prefilter
8414 && !state.precedence_rule_decision()
8415 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
8416 {
8417 state
8418 .rule_index()
8419 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8420 .map(|rule_stop| {
8421 let symbol = self.token_type_at(index);
8422 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
8423 (symbol, entry)
8424 })
8425 } else {
8426 None
8427 };
8428 let ll1_only_alt: Option<usize> = if transition_count > 1
8437 && let Some((symbol, entry)) = lookahead_filter.as_ref()
8438 {
8439 let key = (state.state_number(), *symbol);
8440 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
8441 cached
8442 } else {
8443 let result = ll1_unique_alt(entry, *symbol);
8444 self.ll1_decision_cache.insert(key, result);
8445 result
8446 }
8447 } else {
8448 None
8449 };
8450 let lookahead_filter = lookahead_filter.as_ref();
8451 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
8457 for (transition_index, transition) in transitions.iter().enumerate() {
8458 if let Some(alt) = ll1_only_alt {
8459 if alt != transition_index {
8461 continue;
8462 }
8463 }
8464 let transition_kind = transition.kind();
8465 if ll1_only_alt.is_none()
8466 && should_skip_via_lookahead(
8467 transition_kind,
8468 transition_index,
8469 lookahead_filter,
8470 index,
8471 self.fast_recovery_enabled,
8472 expected,
8473 )
8474 {
8475 continue;
8476 }
8477 let target = transition.target();
8478 match transition_kind {
8479 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
8480 #[cfg(feature = "perf-counters")]
8481 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8482 let boundary = left_recursive_boundary(atn, state, target);
8483 outcomes.extend(
8484 self.recognize_state_fast(
8485 atn,
8486 FastRecognizeRequest {
8487 state_number: target,
8488 stop_state,
8489 index,
8490 rule_start_index,
8491 decision_start_index: next_decision_start_index,
8492 precedence,
8493 depth: depth + 1,
8494 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8495 recovery_state: epsilon_recovery_state,
8496 },
8497 FastRecognizeScratch {
8498 predicate_context,
8499 visiting,
8500 memo,
8501 expected,
8502 native_depth: native_depth + 1,
8503 },
8504 )
8505 .into_iter()
8506 .map(|mut outcome| {
8507 if let Some(rule_index) = boundary {
8508 let boundary = self.arena_boundary_node(rule_index);
8509 self.defer_fast_outcome_node(&mut outcome, boundary);
8510 }
8511 outcome
8512 }),
8513 );
8514 }
8515 ParserTransitionKind::Predicate => {
8516 #[cfg(feature = "perf-counters")]
8517 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8518 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
8519 let boundary = left_recursive_boundary(atn, state, target);
8520 outcomes.extend(
8521 self.recognize_state_fast(
8522 atn,
8523 FastRecognizeRequest {
8524 state_number: target,
8525 stop_state,
8526 index,
8527 rule_start_index,
8528 decision_start_index: next_decision_start_index,
8529 precedence,
8530 depth: depth + 1,
8531 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8532 recovery_state: epsilon_recovery_state,
8533 },
8534 FastRecognizeScratch {
8535 predicate_context,
8536 visiting,
8537 memo,
8538 expected,
8539 native_depth: native_depth + 1,
8540 },
8541 )
8542 .into_iter()
8543 .map(|mut outcome| {
8544 if let Some(rule_index) = boundary {
8545 let boundary = self.arena_boundary_node(rule_index);
8546 self.defer_fast_outcome_node(&mut outcome, boundary);
8547 }
8548 outcome
8549 }),
8550 );
8551 } else {
8552 record_predicate_no_viable(expected, next_decision_start_index, index);
8553 }
8554 }
8555 ParserTransitionKind::Precedence => {
8556 let transition_precedence = packed_i32(transition.arg0());
8557 if transition_precedence >= precedence {
8558 let boundary = left_recursive_boundary(atn, state, target);
8559 outcomes.extend(
8560 self.recognize_state_fast(
8561 atn,
8562 FastRecognizeRequest {
8563 state_number: target,
8564 stop_state,
8565 index,
8566 rule_start_index,
8567 decision_start_index: next_decision_start_index,
8568 precedence,
8569 depth: depth + 1,
8570 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8571 recovery_state: epsilon_recovery_state,
8572 },
8573 FastRecognizeScratch {
8574 predicate_context,
8575 visiting,
8576 memo,
8577 expected,
8578 native_depth: native_depth + 1,
8579 },
8580 )
8581 .into_iter()
8582 .map(|mut outcome| {
8583 if let Some(rule_index) = boundary {
8584 let boundary = self.arena_boundary_node(rule_index);
8585 self.defer_fast_outcome_node(&mut outcome, boundary);
8586 }
8587 outcome
8588 }),
8589 );
8590 }
8591 }
8592 ParserTransitionKind::Rule => {
8593 let rule_index = transition.arg0() as usize;
8594 let follow_state = transition.arg1() as usize;
8595 let rule_precedence = packed_i32(transition.arg2());
8596 #[cfg(feature = "perf-counters")]
8597 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
8598 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
8599 continue;
8600 };
8601 let symbol = self.token_type_at(index);
8613 if self.fast_first_set_prefilter {
8614 let first = self.cached_rule_first_set(atn, target, child_stop);
8627 if should_skip_rule_via_first_set(
8628 &first,
8629 symbol,
8630 self.fast_recovery_enabled,
8631 index,
8632 expected,
8633 ) {
8634 continue;
8635 }
8636 }
8637 let expected_before_child =
8638 self.fast_recovery_enabled.then(|| expected.clone());
8639 let mut children = self.recognize_state_fast(
8640 atn,
8641 FastRecognizeRequest {
8642 state_number: target,
8643 stop_state: child_stop,
8644 index,
8645 rule_start_index: index,
8646 decision_start_index: None,
8647 precedence: rule_precedence,
8648 depth: depth + 1,
8649 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
8650 recovery_state: epsilon_recovery_state,
8651 },
8652 FastRecognizeScratch {
8653 predicate_context,
8654 visiting,
8655 memo,
8656 expected,
8657 native_depth: native_depth + 1,
8658 },
8659 );
8660 if children.is_empty() && self.fast_recovery_enabled {
8661 children = self.fast_child_rule_failure_recovery_outcomes(
8662 FastChildRuleFailureRecoveryRequest {
8663 atn,
8664 rule_index,
8665 start_index: index,
8666 follow_state,
8667 stop_state,
8668 expected,
8669 },
8670 );
8671 }
8672 if let Some(expected_before_child) = expected_before_child {
8673 if children
8674 .iter()
8675 .any(|child| child.diagnostics.is_empty() && child.index > index)
8676 {
8677 *expected = expected_before_child;
8678 }
8679 }
8680 for child in children {
8681 let child_index = child.index;
8682 let child_consumed_eof = child.consumed_eof;
8683 let child_diagnostics = child.diagnostics;
8684 let empty_recovery = self.empty_recovery_symbols();
8685 let follow_outcomes = self.recognize_state_fast(
8686 atn,
8687 FastRecognizeRequest {
8688 state_number: follow_state,
8689 stop_state,
8690 index: child_index,
8691 rule_start_index,
8692 decision_start_index: next_decision_start_index,
8693 precedence,
8694 depth: depth + 1,
8695 recovery_symbols: empty_recovery,
8696 recovery_state: None,
8697 },
8698 FastRecognizeScratch {
8699 predicate_context,
8700 visiting,
8701 memo,
8702 expected,
8703 native_depth: native_depth + 1,
8704 },
8705 );
8706 if follow_outcomes.is_empty() {
8707 continue;
8708 }
8709 let child_stop_index =
8710 self.rule_stop_token_index(child_index, child_consumed_eof);
8711 let child_node = self.build_parse_trees.then(|| {
8712 self.recognition_arena.deferred_rule_node(FastDeferredRule {
8713 rule_index: u32::try_from(rule_index)
8714 .expect("rule index fits in u32"),
8715 invoking_state: i32::try_from(invoking_state_number(state_number))
8716 .expect("invoking state fits in i32"),
8717 start_index: u32::try_from(index)
8718 .expect("rule start index fits in u32"),
8719 stop_index: child_stop_index.map(|stop_index| {
8720 u32::try_from(stop_index).expect("rule stop index fits in u32")
8721 }),
8722 deferred_children: child.deferred_nodes,
8723 children: child.nodes,
8724 })
8725 });
8726 let child_diags_empty = child_diagnostics.is_empty();
8727 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
8728 outcome.consumed_eof |= child_consumed_eof;
8729 if !child_diags_empty {
8732 outcome.diagnostics = self
8733 .recognition_arena
8734 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
8735 }
8736 if let Some(child_node) = child_node {
8737 outcome.deferred_nodes = self
8738 .recognition_arena
8739 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
8740 }
8741 outcome
8742 }));
8743 }
8744 }
8745 ParserTransitionKind::Atom
8746 | ParserTransitionKind::Range
8747 | ParserTransitionKind::Set
8748 | ParserTransitionKind::NotSet
8749 | ParserTransitionKind::Wildcard => {
8750 #[cfg(feature = "perf-counters")]
8751 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
8752 let symbol = self.token_type_at(index);
8753 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
8754 let next_index = self.consume_index(index, symbol);
8755 let empty_recovery = self.empty_recovery_symbols();
8756 outcomes.extend(
8757 self.recognize_state_fast(
8758 atn,
8759 FastRecognizeRequest {
8760 state_number: target,
8761 stop_state,
8762 index: next_index,
8763 rule_start_index,
8764 decision_start_index: next_decision_start_index,
8765 precedence,
8766 depth: depth + 1,
8767 recovery_symbols: empty_recovery,
8768 recovery_state: None,
8769 },
8770 FastRecognizeScratch {
8771 predicate_context,
8772 visiting,
8773 memo,
8774 expected,
8775 native_depth: native_depth + 1,
8776 },
8777 )
8778 .into_iter()
8779 .map(|mut outcome| {
8780 outcome.consumed_eof |= symbol == TOKEN_EOF;
8781 if self.fast_token_nodes_enabled {
8782 let token = self.arena_token_node(index, false);
8783 self.defer_fast_outcome_node(&mut outcome, token);
8784 }
8785 outcome
8786 }),
8787 );
8788 } else {
8789 if !self.fast_recovery_enabled {
8790 continue;
8798 }
8799 let expected_symbols = fast_recovery_expected_symbols(
8800 self,
8801 atn,
8802 state.state_number(),
8803 &recovery_symbols,
8804 );
8805 if expected_symbols.contains(&symbol) {
8806 continue;
8807 }
8808 {
8809 expected.record_transition(index, transition, max_token_type);
8810 record_no_viable_if_ambiguous(
8811 expected,
8812 next_decision_start_index,
8813 index,
8814 );
8815 outcomes.extend(self.fast_single_token_deletion_recovery(
8816 FastRecoveryRequest {
8817 atn,
8818 transition,
8819 expected_symbols: Rc::clone(&expected_symbols),
8820 target,
8821 request: FastRecognizeRequest {
8822 state_number,
8823 stop_state,
8824 index,
8825 rule_start_index,
8826 decision_start_index,
8827 precedence,
8828 depth,
8829 recovery_symbols: Rc::clone(&recovery_symbols),
8830 recovery_state,
8831 },
8832 visiting,
8833 memo,
8834 expected,
8835 },
8836 predicate_context,
8837 ));
8838 if !state_is_left_recursive_rule(atn, state) {
8839 outcomes.extend(self.fast_single_token_insertion_recovery(
8840 FastRecoveryRequest {
8841 atn,
8842 transition,
8843 expected_symbols: Rc::clone(&expected_symbols),
8844 target,
8845 request: FastRecognizeRequest {
8846 state_number,
8847 stop_state,
8848 index,
8849 rule_start_index,
8850 decision_start_index,
8851 precedence,
8852 depth,
8853 recovery_symbols: Rc::clone(&recovery_symbols),
8854 recovery_state,
8855 },
8856 visiting,
8857 memo,
8858 expected,
8859 },
8860 predicate_context,
8861 ));
8862 }
8863 outcomes.extend(self.fast_current_token_deletion_recovery(
8864 FastCurrentTokenDeletionRequest {
8865 atn,
8866 expected_symbols,
8867 request: FastRecognizeRequest {
8868 state_number,
8869 stop_state,
8870 index,
8871 rule_start_index,
8872 decision_start_index,
8873 precedence,
8874 depth,
8875 recovery_symbols: Rc::clone(&recovery_symbols),
8876 recovery_state,
8877 },
8878 visiting,
8879 memo,
8880 expected,
8881 },
8882 predicate_context,
8883 ));
8884 }
8885 }
8886 }
8887 }
8888 }
8889
8890 if has_inserted_cycle_guard {
8891 visiting.remove(&key);
8892 }
8893 if matches!(
8894 self.prediction_mode,
8895 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
8896 ) && self.fast_recovery_enabled
8897 {
8898 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
8902 }
8903 if self.fast_recovery_enabled {
8904 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
8905 } else {
8906 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8907 }
8908 let should_memoize = self.fast_recovery_enabled
8918 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
8919 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
8923 if inline_consumed_eof {
8924 outcome.consumed_eof = true;
8925 }
8926 if !inline_consumed_tokens.is_empty() {
8927 for token_index in inline_consumed_tokens.iter().rev() {
8928 let token = self.arena_token_node(*token_index, false);
8929 self.defer_fast_outcome_node(&mut outcome, token);
8930 }
8931 }
8932 outcome
8933 };
8934 if should_memoize {
8935 #[cfg(feature = "perf-counters")]
8936 {
8937 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
8938 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
8939 match outcomes.len() {
8940 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
8941 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
8942 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
8943 }
8944 }
8945 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
8950 memo.insert(key, Rc::clone(&stored));
8951 if inline_pending {
8952 return stored
8953 .iter()
8954 .copied()
8955 .map(&mut apply_inline_pending)
8956 .collect();
8957 }
8958 return stored.to_vec();
8959 }
8960 #[cfg(feature = "perf-counters")]
8961 match outcomes.len() {
8962 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
8963 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
8964 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
8965 }
8966 if inline_pending {
8967 return outcomes.into_iter().map(apply_inline_pending).collect();
8968 }
8969 outcomes
8970 }
8971
8972 fn single_token_deletion_recovery(
8975 &mut self,
8976 recovery: RecoveryRequest<'_, '_>,
8977 ) -> Vec<RecognizeOutcome> {
8978 let RecoveryRequest {
8979 atn,
8980 transition,
8981 expected_symbols,
8982 target,
8983 request,
8984 visiting,
8985 memo,
8986 expected,
8987 } = recovery;
8988 let RecognizeRequest {
8989 stop_state,
8990 index,
8991 rule_start_index,
8992 decision_start_index,
8993 init_action_rules,
8994 predicates,
8995 semantics,
8996 rule_args,
8997 member_actions,
8998 return_actions,
8999 local_int_arg,
9000 member_values,
9001 return_values,
9002 rule_alt_number,
9003 track_alt_numbers,
9004 consumed_eof,
9005 precedence,
9006 depth,
9007 ..
9008 } = request;
9009 let Some((diagnostic, next_index, next_symbol)) =
9010 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
9011 else {
9012 return Vec::new();
9013 };
9014 let after_next = self.consume_index(next_index, next_symbol);
9015 self.recognize_state(
9016 atn,
9017 RecognizeRequest {
9018 state_number: target,
9019 stop_state,
9020 index: after_next,
9021 rule_start_index,
9022 decision_start_index,
9023 init_action_rules,
9024 predicates,
9025 semantics,
9026 rule_args,
9027 member_actions,
9028 return_actions,
9029 local_int_arg,
9030 member_values,
9031 return_values,
9032 rule_alt_number,
9033 track_alt_numbers,
9034 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
9035 precedence,
9036 depth: depth + 1,
9037 recovery_symbols: BTreeSet::new(),
9038 recovery_state: None,
9039 },
9040 visiting,
9041 memo,
9042 expected,
9043 )
9044 .into_iter()
9045 .map(|mut outcome| {
9046 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
9047 outcome.diagnostics = self
9048 .recognition_arena
9049 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9050 let token = self.arena_token_node(next_index, false);
9051 self.arena_prepend(&mut outcome.nodes, token);
9052 let error = self.arena_token_node(index, true);
9053 self.arena_prepend(&mut outcome.nodes, error);
9054 outcome
9055 })
9056 .collect()
9057 }
9058
9059 fn current_token_deletion_recovery(
9062 &mut self,
9063 recovery: CurrentTokenDeletionRequest<'_, '_>,
9064 ) -> Vec<RecognizeOutcome> {
9065 let CurrentTokenDeletionRequest {
9066 atn,
9067 expected_symbols,
9068 mut request,
9069 visiting,
9070 memo,
9071 expected,
9072 } = recovery;
9073 let error_index = request.index;
9074 if error_index == request.rule_start_index {
9075 return Vec::new();
9076 }
9077 let Some((diagnostic, next_index, skipped)) =
9078 self.current_token_deletion(error_index, &expected_symbols)
9079 else {
9080 return Vec::new();
9081 };
9082 request.state_number = request.recovery_state.unwrap_or(request.state_number);
9083 request.index = next_index;
9084 request.depth += 1;
9085 request.recovery_state = None;
9086 self.recognize_state(atn, request, visiting, memo, expected)
9087 .into_iter()
9088 .map(|mut outcome| {
9089 outcome.diagnostics = self
9090 .recognition_arena
9091 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9092 for index in skipped.iter().rev() {
9093 let error = self.arena_token_node(*index, true);
9094 self.arena_prepend(&mut outcome.nodes, error);
9095 }
9096 outcome
9097 })
9098 .collect()
9099 }
9100
9101 fn consuming_failure_fallback(
9104 &mut self,
9105 fallback: ConsumingFailureFallback<'_>,
9106 visiting: &mut BTreeSet<RecognizeKey>,
9107 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9108 expected: &mut ExpectedTokens,
9109 ) -> Vec<RecognizeOutcome> {
9110 if fallback.expected_symbols.is_empty() {
9111 return Vec::new();
9112 }
9113 if fallback.symbol == TOKEN_EOF {
9114 return self.eof_consuming_failure_fallback(fallback, expected);
9115 }
9116 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
9117 }
9118
9119 fn non_eof_consuming_failure_fallback(
9122 &mut self,
9123 fallback: ConsumingFailureFallback<'_>,
9124 visiting: &mut BTreeSet<RecognizeKey>,
9125 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9126 expected: &mut ExpectedTokens,
9127 ) -> Vec<RecognizeOutcome> {
9128 let ConsumingFailureFallback {
9129 atn,
9130 target,
9131 request,
9132 symbol,
9133 expected_symbols,
9134 decision_start_index,
9135 decision,
9136 } = fallback;
9137 let error_index = request.index;
9138 let diagnostic =
9139 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
9140 let next_index = self.consume_index(error_index, symbol);
9141 self.recognize_state(
9142 atn,
9143 RecognizeRequest {
9144 state_number: target,
9145 stop_state: request.stop_state,
9146 index: next_index,
9147 rule_start_index: request.rule_start_index,
9148 decision_start_index,
9149 init_action_rules: request.init_action_rules,
9150 predicates: request.predicates,
9151 semantics: request.semantics,
9152 rule_args: request.rule_args,
9153 member_actions: request.member_actions,
9154 return_actions: request.return_actions,
9155 local_int_arg: request.local_int_arg,
9156 member_values: request.member_values,
9157 return_values: request.return_values,
9158 rule_alt_number: request.rule_alt_number,
9159 track_alt_numbers: request.track_alt_numbers,
9160 consumed_eof: request.consumed_eof,
9161 precedence: request.precedence,
9162 depth: request.depth + 1,
9163 recovery_symbols: BTreeSet::new(),
9164 recovery_state: None,
9165 },
9166 visiting,
9167 memo,
9168 expected,
9169 )
9170 .into_iter()
9171 .map(|mut outcome| {
9172 prepend_decision(&mut outcome, decision);
9173 outcome.diagnostics = self
9174 .recognition_arena
9175 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9176 let error = self.arena_token_node(error_index, true);
9177 self.arena_prepend(&mut outcome.nodes, error);
9178 outcome
9179 })
9180 .collect()
9181 }
9182
9183 fn eof_consuming_failure_fallback(
9186 &mut self,
9187 fallback: ConsumingFailureFallback<'_>,
9188 expected: &ExpectedTokens,
9189 ) -> Vec<RecognizeOutcome> {
9190 let request = fallback.request;
9191 if request.index == request.rule_start_index {
9192 return Vec::new();
9193 }
9194 let diagnostic =
9195 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
9196 let diagnostics = self
9197 .recognition_arena
9198 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
9199 vec![RecognizeOutcome {
9200 index: request.index,
9201 consumed_eof: request.consumed_eof,
9202 alt_number: request.rule_alt_number,
9203 member_values: request.member_values,
9204 return_values: request.return_values,
9205 diagnostics,
9206 decisions: Vec::new(),
9207 actions: Vec::new(),
9208 nodes: NodeSeqId::EMPTY,
9209 }]
9210 }
9211
9212 fn single_token_insertion_recovery(
9215 &mut self,
9216 recovery: RecoveryRequest<'_, '_>,
9217 ) -> Vec<RecognizeOutcome> {
9218 let RecoveryRequest {
9219 atn,
9220 transition,
9221 expected_symbols,
9222 target,
9223 request,
9224 visiting,
9225 memo,
9226 expected,
9227 } = recovery;
9228 let RecognizeRequest {
9229 stop_state,
9230 index,
9231 rule_start_index,
9232 decision_start_index,
9233 init_action_rules,
9234 predicates,
9235 semantics,
9236 rule_args,
9237 member_actions,
9238 return_actions,
9239 local_int_arg,
9240 member_values,
9241 return_values,
9242 rule_alt_number,
9243 track_alt_numbers,
9244 consumed_eof,
9245 precedence,
9246 depth,
9247 ..
9248 } = request;
9249 let follow_symbols = state_expected_symbols(atn, transition.target());
9250 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
9251 transition,
9252 index,
9253 atn.max_token_type(),
9254 &expected_symbols,
9255 &follow_symbols,
9256 ) else {
9257 return Vec::new();
9258 };
9259 self.recognize_state(
9260 atn,
9261 RecognizeRequest {
9262 state_number: target,
9263 stop_state,
9264 index,
9265 rule_start_index,
9266 decision_start_index,
9267 init_action_rules,
9268 predicates,
9269 semantics,
9270 rule_args,
9271 member_actions,
9272 return_actions,
9273 local_int_arg,
9274 member_values,
9275 return_values,
9276 rule_alt_number,
9277 track_alt_numbers,
9278 consumed_eof,
9279 precedence,
9280 depth: depth + 1,
9281 recovery_symbols: BTreeSet::new(),
9282 recovery_state: None,
9283 },
9284 visiting,
9285 memo,
9286 expected,
9287 )
9288 .into_iter()
9289 .map(|mut outcome| {
9290 outcome.diagnostics = self
9291 .recognition_arena
9292 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9293 let missing = self.arena_missing_token_node(token_type, index, text.clone());
9294 self.arena_prepend(&mut outcome.nodes, missing);
9295 outcome
9296 })
9297 .collect()
9298 }
9299
9300 #[allow(clippy::too_many_lines)]
9303 fn recognize_state(
9304 &mut self,
9305 atn: &Atn,
9306 request: RecognizeRequest<'_>,
9307 visiting: &mut BTreeSet<RecognizeKey>,
9308 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9309 expected: &mut ExpectedTokens,
9310 ) -> Vec<RecognizeOutcome> {
9311 let request_template = request.clone();
9312 let RecognizeRequest {
9313 state_number,
9314 stop_state,
9315 index,
9316 rule_start_index,
9317 decision_start_index,
9318 init_action_rules,
9319 predicates,
9320 semantics,
9321 rule_args,
9322 member_actions,
9323 return_actions,
9324 local_int_arg,
9325 member_values,
9326 return_values,
9327 rule_alt_number,
9328 track_alt_numbers,
9329 consumed_eof,
9330 precedence,
9331 depth,
9332 recovery_symbols,
9333 recovery_state,
9334 } = request;
9335 if depth > RECOGNITION_DEPTH_LIMIT {
9336 return Vec::new();
9337 }
9338 if state_number == stop_state {
9339 return stop_outcome(
9340 index,
9341 consumed_eof,
9342 rule_alt_number,
9343 member_values,
9344 return_values,
9345 );
9346 }
9347 let key = RecognizeKey {
9348 state_number,
9349 stop_state,
9350 index,
9351 rule_start_index,
9352 decision_start_index,
9353 local_int_arg,
9354 member_values: member_values.clone(),
9355 return_values: return_values.clone(),
9356 rule_alt_number,
9357 track_alt_numbers,
9358 consumed_eof,
9359 precedence,
9360 recovery_symbols: recovery_symbols.clone(),
9361 recovery_state,
9362 };
9363 if let Some(outcomes) = memo.get(&key) {
9364 return outcomes.clone();
9365 }
9366
9367 let visit_key = key.clone();
9368 if !visiting.insert(visit_key.clone()) {
9369 return Vec::new();
9370 }
9371
9372 let Some(state) = atn.state(state_number) else {
9373 visiting.remove(&visit_key);
9374 return Vec::new();
9375 };
9376 let transitions = state.transitions();
9377 let transition_count = transitions.len();
9378 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9379 Some(index)
9380 } else {
9381 decision_start_index
9382 };
9383 let (epsilon_recovery_symbols, epsilon_recovery_state) =
9384 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
9385 let mut outcomes = Vec::new();
9386 for (transition_index, transition) in transitions.iter().enumerate() {
9387 let decision =
9388 transition_decision(atn, state, transition_count, transition_index, predicates);
9389 let next_alt_number = next_alt_number(
9390 state,
9391 transition_count,
9392 transition_index,
9393 rule_alt_number,
9394 track_alt_numbers,
9395 );
9396 let transition_data = transition.data();
9397 match &transition_data {
9398 Transition::Epsilon { target } | Transition::Action { target, .. } => {
9399 let action_rule_index = match &transition_data {
9400 Transition::Action { rule_index, .. } => Some(*rule_index),
9401 _ => None,
9402 };
9403 outcomes.extend(self.recognize_epsilon_or_action_step(
9404 atn,
9405 &request_template,
9406 EpsilonActionStep {
9407 source_state: state_number,
9408 target: *target,
9409 action_rule_index,
9410 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
9411 decision,
9412 decision_start_index: next_decision_start_index,
9413 alt_number: next_alt_number,
9414 recovery_symbols: epsilon_recovery_symbols.clone(),
9415 recovery_state: epsilon_recovery_state,
9416 },
9417 RecognizeScratch {
9418 visiting,
9419 memo,
9420 expected,
9421 },
9422 ));
9423 }
9424 Transition::Predicate {
9425 target,
9426 rule_index,
9427 pred_index,
9428 ..
9429 } => {
9430 let predicate = PredicateEval {
9431 index,
9432 rule_index: *rule_index,
9433 pred_index: *pred_index,
9434 predicates,
9435 semantics,
9436 context: None,
9437 local_int_arg,
9438 member_values: &member_values,
9439 };
9440 if self.parser_predicate_matches(predicate) {
9441 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
9442 outcomes.extend(
9443 self.recognize_state(
9444 atn,
9445 RecognizeRequest {
9446 state_number: *target,
9447 stop_state,
9448 index,
9449 rule_start_index,
9450 decision_start_index: next_decision_start_index,
9451 init_action_rules,
9452 predicates,
9453 semantics,
9454 rule_args,
9455 member_actions,
9456 return_actions,
9457 local_int_arg,
9458 member_values: member_values.clone(),
9459 return_values: return_values.clone(),
9460 rule_alt_number: next_alt_number,
9461 track_alt_numbers,
9462 consumed_eof,
9463 precedence,
9464 depth: depth + 1,
9465 recovery_symbols: epsilon_recovery_symbols.clone(),
9466 recovery_state: epsilon_recovery_state,
9467 },
9468 visiting,
9469 memo,
9470 expected,
9471 )
9472 .into_iter()
9473 .map(|mut outcome| {
9474 prepend_decision(&mut outcome, decision);
9475 if let Some(rule_index) = left_recursive_boundary {
9476 let boundary = self.arena_boundary_node(rule_index);
9477 self.arena_prepend(&mut outcome.nodes, boundary);
9478 }
9479 outcome
9480 }),
9481 );
9482 } else if let Some(message) = semantics
9483 .and_then(|semantics| {
9484 self.parser_semantic_ir_predicate_failure_message(
9485 *rule_index,
9486 *pred_index,
9487 semantics,
9488 )
9489 })
9490 .or_else(|| {
9491 self.parser_predicate_failure_message(
9492 *rule_index,
9493 *pred_index,
9494 predicates,
9495 )
9496 })
9497 {
9498 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
9499 rule_index: *rule_index,
9500 index,
9501 message,
9502 member_values: member_values.clone(),
9503 return_values: return_values.clone(),
9504 rule_alt_number,
9505 }));
9506 } else {
9507 record_predicate_no_viable(expected, next_decision_start_index, index);
9508 }
9509 }
9510 Transition::Precedence {
9511 target,
9512 precedence: transition_precedence,
9513 } => {
9514 if *transition_precedence >= precedence {
9515 outcomes.extend(
9516 self.recognize_state(
9517 atn,
9518 RecognizeRequest {
9519 state_number: *target,
9520 stop_state,
9521 index,
9522 rule_start_index,
9523 decision_start_index: next_decision_start_index,
9524 init_action_rules,
9525 predicates,
9526 semantics,
9527 rule_args,
9528 member_actions,
9529 return_actions,
9530 local_int_arg,
9531 member_values: member_values.clone(),
9532 return_values: return_values.clone(),
9533 rule_alt_number: next_alt_number,
9534 track_alt_numbers,
9535 consumed_eof,
9536 precedence,
9537 depth: depth + 1,
9538 recovery_symbols: epsilon_recovery_symbols.clone(),
9539 recovery_state: epsilon_recovery_state,
9540 },
9541 visiting,
9542 memo,
9543 expected,
9544 )
9545 .into_iter()
9546 .map(|mut outcome| {
9547 prepend_decision(&mut outcome, decision);
9548 outcome
9549 }),
9550 );
9551 }
9552 }
9553 Transition::Rule {
9554 target,
9555 rule_index,
9556 follow_state,
9557 precedence: rule_precedence,
9558 ..
9559 } => {
9560 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
9561 continue;
9562 };
9563 let child_local_int_arg =
9564 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
9565 let expected_before_child = expected.clone();
9566 let children = self.recognize_state(
9567 atn,
9568 RecognizeRequest {
9569 state_number: *target,
9570 stop_state: child_stop,
9571 index,
9572 rule_start_index: index,
9573 decision_start_index: None,
9574 init_action_rules,
9575 predicates,
9576 semantics,
9577 rule_args,
9578 member_actions,
9579 return_actions,
9580 local_int_arg: child_local_int_arg,
9581 member_values: member_values.clone(),
9582 return_values: BTreeMap::new(),
9583 rule_alt_number: 0,
9584 track_alt_numbers,
9585 consumed_eof: false,
9586 precedence: *rule_precedence,
9587 depth: depth + 1,
9588 recovery_symbols: epsilon_recovery_symbols.clone(),
9589 recovery_state: epsilon_recovery_state,
9590 },
9591 visiting,
9592 memo,
9593 expected,
9594 );
9595 let children = if children.is_empty() {
9596 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
9597 atn,
9598 rule_index: *rule_index,
9599 start_index: index,
9600 follow_state: *follow_state,
9601 stop_state,
9602 member_values: member_values.clone(),
9603 expected,
9604 })
9605 } else {
9606 children
9607 };
9608 let preserve_child_expected =
9609 self.child_expected_reaches_clean_eof(&children, expected);
9610 restore_expected(
9611 &children,
9612 index,
9613 expected,
9614 expected_before_child,
9615 preserve_child_expected,
9616 );
9617 for child in children {
9618 let child_stop_index =
9619 self.rule_stop_token_index(child.index, child.consumed_eof);
9620 let child_nodes = self
9621 .recognition_arena
9622 .fold_left_recursive_boundaries(child.nodes);
9623 let child_node = self.arena_rule_node(ArenaRuleSpec {
9624 rule_index: *rule_index,
9625 invoking_state: invoking_state_number(state_number),
9626 alt_number: child.alt_number,
9627 start_index: index,
9628 stop_index: child_stop_index,
9629 return_values: child.return_values.clone(),
9630 children: child_nodes,
9631 });
9632 outcomes.extend(
9633 self.recognize_state(
9634 atn,
9635 RecognizeRequest {
9636 state_number: *follow_state,
9637 stop_state,
9638 index: child.index,
9639 rule_start_index,
9640 decision_start_index: next_decision_start_index,
9641 init_action_rules,
9642 predicates,
9643 semantics,
9644 rule_args,
9645 member_actions,
9646 return_actions,
9647 local_int_arg,
9648 member_values: child.member_values.clone(),
9649 return_values: return_values.clone(),
9650 rule_alt_number,
9651 track_alt_numbers,
9652 consumed_eof: consumed_eof || child.consumed_eof,
9653 precedence,
9654 depth: depth + 1,
9655 recovery_symbols: BTreeSet::new(),
9656 recovery_state: None,
9657 },
9658 visiting,
9659 memo,
9660 expected,
9661 )
9662 .into_iter()
9663 .map(|mut outcome| {
9664 outcome.consumed_eof |= child.consumed_eof;
9665 outcome.diagnostics = self
9666 .recognition_arena
9667 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
9668 let mut decisions = child.decisions.clone();
9669 decisions.append(&mut outcome.decisions);
9670 outcome.decisions = decisions;
9671 prepend_decision(&mut outcome, decision);
9672 let mut actions = child.actions.clone();
9673 if init_action_rules.contains(rule_index) {
9674 actions.insert(
9675 0,
9676 ParserAction::new_rule_init(
9677 *rule_index,
9678 index,
9679 Some(*follow_state),
9680 ),
9681 );
9682 }
9683 actions.append(&mut outcome.actions);
9684 outcome.actions = actions;
9685 self.arena_prepend(&mut outcome.nodes, child_node);
9686 outcome
9687 }),
9688 );
9689 }
9690 }
9691 Transition::Atom { target, .. }
9692 | Transition::Range { target, .. }
9693 | Transition::Set { target, .. }
9694 | Transition::NotSet { target, .. }
9695 | Transition::Wildcard { target, .. } => {
9696 let symbol = self.token_type_at(index);
9697 if transition_data.matches(symbol, 1, atn.max_token_type()) {
9698 let next_index = self.consume_index(index, symbol);
9699 outcomes.extend(
9700 self.recognize_state(
9701 atn,
9702 RecognizeRequest {
9703 state_number: *target,
9704 stop_state,
9705 index: next_index,
9706 rule_start_index,
9707 decision_start_index: next_decision_start_index,
9708 init_action_rules,
9709 predicates,
9710 semantics,
9711 rule_args,
9712 member_actions,
9713 return_actions,
9714 local_int_arg,
9715 member_values: member_values.clone(),
9716 return_values: return_values.clone(),
9717 rule_alt_number: next_alt_number,
9718 track_alt_numbers,
9719 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
9720 precedence,
9721 depth: depth + 1,
9722 recovery_symbols: BTreeSet::new(),
9723 recovery_state: None,
9724 },
9725 visiting,
9726 memo,
9727 expected,
9728 )
9729 .into_iter()
9730 .map(|mut outcome| {
9731 prepend_decision(&mut outcome, decision);
9732 outcome.consumed_eof |= symbol == TOKEN_EOF;
9733 let token = self.arena_token_node(index, false);
9734 self.arena_prepend(&mut outcome.nodes, token);
9735 outcome
9736 }),
9737 );
9738 } else {
9739 let expected_symbols =
9740 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
9741 if expected_symbols.contains(&symbol) {
9742 continue;
9743 }
9744 expected.record_transition(index, transition, atn.max_token_type());
9745 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
9746 let before_recovery = outcomes.len();
9747 let recovery_request = request_template.clone();
9748 outcomes.extend(
9749 self.single_token_deletion_recovery(RecoveryRequest {
9750 atn,
9751 transition,
9752 expected_symbols: expected_symbols.clone(),
9753 target: *target,
9754 request: recovery_request.clone(),
9755 visiting,
9756 memo,
9757 expected,
9758 })
9759 .into_iter()
9760 .map(|mut outcome| {
9761 prepend_decision(&mut outcome, decision);
9762 outcome
9763 }),
9764 );
9765 if !state_is_left_recursive_rule(atn, state) {
9766 outcomes.extend(
9767 self.single_token_insertion_recovery(RecoveryRequest {
9768 atn,
9769 transition,
9770 expected_symbols: expected_symbols.clone(),
9771 target: *target,
9772 request: recovery_request.clone(),
9773 visiting,
9774 memo,
9775 expected,
9776 })
9777 .into_iter()
9778 .map(|mut outcome| {
9779 prepend_decision(&mut outcome, decision);
9780 outcome
9781 }),
9782 );
9783 }
9784 outcomes.extend(self.current_token_deletion_recovery(
9785 CurrentTokenDeletionRequest {
9786 atn,
9787 expected_symbols: expected_symbols.clone(),
9788 request: recovery_request.clone(),
9789 visiting,
9790 memo,
9791 expected,
9792 },
9793 ));
9794 if outcomes.len() == before_recovery {
9795 outcomes.extend(self.consuming_failure_fallback(
9796 ConsumingFailureFallback {
9797 atn,
9798 target: *target,
9799 request: recovery_request,
9800 symbol,
9801 expected_symbols,
9802 decision_start_index: next_decision_start_index,
9803 decision,
9804 },
9805 visiting,
9806 memo,
9807 expected,
9808 ));
9809 }
9810 }
9811 }
9812 }
9813 }
9814
9815 visiting.remove(&visit_key);
9816 self.record_prediction_diagnostics(atn, state, index, &outcomes);
9817 if matches!(
9818 self.prediction_mode,
9819 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9820 ) {
9821 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
9822 }
9823 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
9824 memo.insert(key, outcomes.clone());
9825 outcomes
9826 }
9827
9828 fn recognize_epsilon_or_action_step(
9831 &mut self,
9832 atn: &Atn,
9833 request: &RecognizeRequest<'_>,
9834 step: EpsilonActionStep,
9835 scratch: RecognizeScratch<'_>,
9836 ) -> Vec<RecognizeOutcome> {
9837 let RecognizeScratch {
9838 visiting,
9839 memo,
9840 expected,
9841 } = scratch;
9842 let action = step.action_rule_index.map(|rule_index| {
9843 ParserAction::new(
9844 step.source_state,
9845 rule_index,
9846 request.rule_start_index,
9847 self.rule_stop_token_index(request.index, request.consumed_eof),
9848 )
9849 });
9850 let next_member_values = if action.is_some() {
9851 member_values_after_action(
9852 step.source_state,
9853 request.member_actions,
9854 request.semantics,
9855 &request.member_values,
9856 )
9857 } else {
9858 request.member_values.clone()
9859 };
9860 let next_return_values = action.map_or_else(
9861 || request.return_values.clone(),
9862 |action| {
9863 return_values_after_action(
9864 step.source_state,
9865 action.rule_index(),
9866 request.return_actions,
9867 request.semantics,
9868 &request.return_values,
9869 )
9870 },
9871 );
9872
9873 self.recognize_state(
9874 atn,
9875 RecognizeRequest {
9876 state_number: step.target,
9877 stop_state: request.stop_state,
9878 index: request.index,
9879 rule_start_index: request.rule_start_index,
9880 decision_start_index: step.decision_start_index,
9881 init_action_rules: request.init_action_rules,
9882 predicates: request.predicates,
9883 semantics: request.semantics,
9884 rule_args: request.rule_args,
9885 member_actions: request.member_actions,
9886 return_actions: request.return_actions,
9887 local_int_arg: request.local_int_arg,
9888 member_values: next_member_values,
9889 return_values: next_return_values,
9890 rule_alt_number: step.alt_number,
9891 track_alt_numbers: request.track_alt_numbers,
9892 consumed_eof: request.consumed_eof,
9893 precedence: request.precedence,
9894 depth: request.depth + 1,
9895 recovery_symbols: step.recovery_symbols,
9896 recovery_state: step.recovery_state,
9897 },
9898 visiting,
9899 memo,
9900 expected,
9901 )
9902 .into_iter()
9903 .map(|mut outcome| {
9904 prepend_decision(&mut outcome, step.decision);
9905 if let Some(rule_index) = step.left_recursive_boundary {
9906 let boundary = self.arena_boundary_node(rule_index);
9907 self.arena_prepend(&mut outcome.nodes, boundary);
9908 }
9909 if let Some(action) = action {
9910 outcome.actions.insert(0, action);
9911 }
9912 outcome
9913 })
9914 .collect()
9915 }
9916
9917 fn token_type_at(&mut self, index: usize) -> i32 {
9922 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
9923 self.input.fill();
9924 }
9925 self.input.token_type_at_index(index)
9926 }
9927
9928 fn cached_state_expected_symbols(
9940 &mut self,
9941 atn: &Atn,
9942 state_number: usize,
9943 ) -> Rc<BTreeSet<i32>> {
9944 if let Some(cached) = self.state_expected_cache.get(&state_number) {
9945 return Rc::clone(cached);
9946 }
9947 let symbols = state_expected_symbols(atn, state_number);
9948 let entry = self.intern_recovery_symbols(symbols);
9949 self.state_expected_cache
9950 .insert(state_number, Rc::clone(&entry));
9951 entry
9952 }
9953
9954 fn cached_state_expected_token_set(
9955 &mut self,
9956 atn: &Atn,
9957 state_number: usize,
9958 ) -> Rc<TokenBitSet> {
9959 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
9960 return Rc::clone(cached);
9961 }
9962 let symbols = with_shared_atn_caches(atn, |cache| {
9966 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
9967 return Rc::clone(cached);
9968 }
9969 let symbols = Rc::new(state_expected_token_set(atn, state_number));
9970 cache
9971 .state_expected_tokens
9972 .insert(state_number, Rc::clone(&symbols));
9973 symbols
9974 });
9975 self.state_expected_token_cache
9976 .insert(state_number, Rc::clone(&symbols));
9977 symbols
9978 }
9979
9980 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
9981 if self.rule_stop_reach_cache.len() <= state_number {
9982 self.rule_stop_reach_cache
9983 .resize_with(atn.states().len().max(state_number + 1), || None);
9984 }
9985 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
9986 return reaches;
9987 }
9988 let reaches = with_shared_atn_caches(atn, |cache| {
9989 *cache
9990 .rule_stop_reach
9991 .entry(state_number)
9992 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
9993 });
9994 self.rule_stop_reach_cache[state_number] = Some(reaches);
9995 reaches
9996 }
9997
9998 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
10001 Rc::clone(&self.empty_recovery_symbols)
10002 }
10003
10004 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
10013 if set.is_empty() {
10014 return Rc::clone(&self.empty_recovery_symbols);
10015 }
10016 let candidate = Rc::new(set);
10017 match self.recovery_symbols_intern.get(&candidate) {
10018 Some(existing) => Rc::clone(existing),
10019 None => {
10020 self.recovery_symbols_intern
10021 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
10022 candidate
10023 }
10024 }
10025 }
10026
10027 fn cached_decision_lookahead(
10032 &mut self,
10033 atn: &Atn,
10034 state: AtnState<'_>,
10035 rule_stop_state: usize,
10036 ) -> Rc<DecisionLookahead> {
10037 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
10044 return Rc::clone(cached);
10045 }
10046 let entry = with_shared_atn_caches(atn, |cache| {
10047 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
10048 return Rc::clone(cached);
10049 }
10050 let mut entry = DecisionLookahead {
10051 transitions: Vec::with_capacity(state.transitions().len()),
10052 };
10053 for transition in &state.transitions() {
10054 entry.transitions.push(transition_first_set(
10055 atn,
10056 transition,
10057 rule_stop_state,
10058 &mut cache.first_set,
10059 ));
10060 }
10061 let entry = Rc::new(entry);
10062 cache
10063 .decision_lookahead
10064 .insert(state.state_number(), Rc::clone(&entry));
10065 entry
10066 });
10067 self.decision_lookahead_cache
10068 .insert(state.state_number(), Rc::clone(&entry));
10069 entry
10070 }
10071
10072 fn cached_rule_first_set(
10073 &mut self,
10074 atn: &Atn,
10075 target: usize,
10076 child_stop: usize,
10077 ) -> Rc<FirstSet> {
10078 if self.rule_first_set_cache.len() <= target {
10079 self.rule_first_set_cache
10080 .resize_with(atn.states().len().max(target + 1), || None);
10081 }
10082 if let Some(cached) = self
10083 .rule_first_set_cache
10084 .get(target)
10085 .and_then(Option::as_ref)
10086 {
10087 return Rc::clone(cached);
10088 }
10089 let first = with_shared_first_set_cache(atn, |cache| {
10090 rule_first_set(atn, target, child_stop, cache)
10091 });
10092 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
10093 first
10094 }
10095
10096 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
10097 let atn_key = SharedAtnCacheKey::for_atn(atn);
10098 if self.empty_cycle_cache_atn != Some(atn_key) {
10099 self.empty_cycle_cache.clear();
10100 self.empty_cycle_cache_atn = Some(atn_key);
10101 }
10102 if self.empty_cycle_cache.len() <= state_number {
10103 self.empty_cycle_cache
10104 .resize_with(atn.state_count().max(state_number + 1), || None);
10105 }
10106 if let Some(cached) = self.empty_cycle_cache[state_number] {
10107 return cached;
10108 }
10109 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
10110 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
10111 self.empty_cycle_cache[state_number] = Some(result);
10112 result
10113 }
10114
10115 fn empty_path_reaches_state(
10116 &mut self,
10117 atn: &Atn,
10118 state_number: usize,
10119 target_state: usize,
10120 visited: &mut FxHashSet<usize>,
10121 ) -> bool {
10122 enum Work {
10123 Visit(usize),
10124 RuleFollow {
10125 target: usize,
10126 rule_index: usize,
10127 follow_state: usize,
10128 },
10129 }
10130
10131 let mut work = vec![Work::Visit(state_number)];
10132 while let Some(item) = work.pop() {
10133 match item {
10134 Work::Visit(state_number) => {
10135 if !visited.insert(state_number) {
10136 continue;
10137 }
10138 let Some(state) = atn.state(state_number) else {
10139 continue;
10140 };
10141 let transitions = state.transitions();
10142 for transition_index in (0..transitions.len()).rev() {
10143 let transition = transitions
10144 .get(transition_index)
10145 .expect("in-bounds parser transition");
10146 let kind = transition.kind();
10147 let target = transition.target();
10148 match kind {
10149 ParserTransitionKind::Atom
10150 | ParserTransitionKind::Range
10151 | ParserTransitionKind::Set
10152 | ParserTransitionKind::NotSet
10153 | ParserTransitionKind::Wildcard => {}
10154 ParserTransitionKind::Rule => {
10155 if target == target_state {
10156 return true;
10157 }
10158 work.push(Work::RuleFollow {
10159 target,
10160 rule_index: transition.arg0() as usize,
10161 follow_state: transition.arg1() as usize,
10162 });
10163 work.push(Work::Visit(target));
10164 }
10165 ParserTransitionKind::Epsilon
10166 | ParserTransitionKind::Predicate
10167 | ParserTransitionKind::Action
10168 | ParserTransitionKind::Precedence => {
10169 if target == target_state {
10170 return true;
10171 }
10172 work.push(Work::Visit(target));
10173 }
10174 }
10175 }
10176 }
10177 Work::RuleFollow {
10178 target,
10179 rule_index,
10180 follow_state,
10181 } => {
10182 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
10183 continue;
10184 };
10185 if self.cached_rule_first_set(atn, target, child_stop).nullable {
10186 if follow_state == target_state {
10187 return true;
10188 }
10189 work.push(Work::Visit(follow_state));
10190 }
10191 }
10192 }
10193 }
10194 false
10195 }
10196
10197 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
10200 match self.clean_memo_mode {
10201 CleanMemoMode::Promote => true,
10202 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
10203 CleanMemoMode::Sparse => {
10204 self.clean_memo_sparse_samples += 1;
10205 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
10206 return false;
10207 }
10208 self.clean_memo_sparse_samples = 0;
10209 self.clean_memo_mode = CleanMemoMode::Probe;
10210 self.clean_memo_probe_samples = 0;
10211 self.clean_memo_probe_repeats = 0;
10212 self.clean_memo_probe_seen.clear();
10213 self.observe_clean_memo_probe(key)
10214 }
10215 }
10216 }
10217
10218 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
10219 self.clean_memo_probe_samples += 1;
10220 if !self.clean_memo_probe_seen.insert(key.clone()) {
10221 self.clean_memo_probe_repeats += 1;
10222 }
10223 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
10224 self.clean_memo_mode = CleanMemoMode::Promote;
10225 self.clean_memo_probe_seen.clear();
10226 return true;
10227 }
10228 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
10229 self.clean_memo_mode = CleanMemoMode::Sparse;
10230 self.clean_memo_sparse_samples = 0;
10231 self.clean_memo_probe_seen.clear();
10232 return false;
10233 }
10234 true
10235 }
10236
10237 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
10239 self.input.get(index)
10240 }
10241
10242 fn token_id_at(&self, index: usize) -> Option<TokenId> {
10244 self.input.get_id(index)
10245 }
10246
10247 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
10248 let token = self
10249 .token_id_at(index)
10250 .expect("recognized token index must exist in the token store");
10251 let node = if error {
10252 ArenaRecognizedNode::ErrorToken { token }
10253 } else {
10254 ArenaRecognizedNode::Token { token }
10255 };
10256 self.recognition_arena.push_node(node)
10257 }
10258
10259 fn arena_missing_token_node(
10260 &mut self,
10261 token_type: i32,
10262 at_index: usize,
10263 text: String,
10264 ) -> RecognizedNodeId {
10265 let extra = self
10266 .recognition_arena
10267 .push_extra(RecognitionExtra::MissingToken {
10268 token_type,
10269 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
10270 text,
10271 });
10272 self.recognition_arena
10273 .push_node(ArenaRecognizedNode::MissingToken { extra })
10274 }
10275
10276 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
10277 let ArenaRuleSpec {
10278 rule_index,
10279 invoking_state,
10280 alt_number,
10281 start_index,
10282 stop_index,
10283 return_values,
10284 children,
10285 } = spec;
10286 let return_values = (!return_values.is_empty()).then(|| {
10287 self.recognition_arena
10288 .push_extra(RecognitionExtra::ReturnValues(return_values))
10289 });
10290 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
10291 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10292 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
10293 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
10294 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
10295 stop_index: stop_index
10296 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
10297 return_values,
10298 children,
10299 })
10300 }
10301
10302 fn arena_boundary_node(&mut self, rule_index: usize) -> RecognizedNodeId {
10303 self.recognition_arena
10304 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
10305 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
10306 })
10307 }
10308
10309 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
10310 *sequence = self.recognition_arena.prepend(*sequence, node);
10311 }
10312
10313 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
10314 self.last_recognition_arena_root = root;
10315 self.last_recognition_arena_diagnostics = diagnostics;
10316 #[cfg(feature = "perf-counters")]
10317 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
10318 let stats = self.recognition_arena_stats();
10319 #[allow(clippy::print_stderr)]
10320 {
10321 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
10322 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
10323 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
10324 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
10325 eprintln!("perf recognition_links_total={}", stats.total_links);
10326 eprintln!("perf recognition_links_live={}", stats.live_links);
10327 eprintln!("perf recognition_links_dead={}", stats.dead_links);
10328 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
10329 eprintln!("perf recognition_extras_total={}", stats.total_extras);
10330 eprintln!("perf recognition_extras_live={}", stats.live_extras);
10331 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
10332 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
10333 }
10334 }
10335 }
10336
10337 fn reset_recognition_arena(&mut self) {
10338 self.recognition_arena.reset();
10339 self.last_recognition_arena_root = NodeSeqId::EMPTY;
10340 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
10341 }
10342
10343 fn current_visible_index(&mut self) -> usize {
10346 let index = self.input.index();
10347 self.input.seek(index);
10348 self.input.index()
10349 }
10350
10351 fn child_expected_reaches_clean_eof(
10354 &mut self,
10355 children: &[RecognizeOutcome],
10356 expected: &ExpectedTokens,
10357 ) -> bool {
10358 let Some(index) = expected.index else {
10359 return false;
10360 };
10361 self.token_type_at(index) == TOKEN_EOF
10362 && children
10363 .iter()
10364 .any(|child| child.diagnostics.is_empty() && child.index == index)
10365 }
10366
10367 fn previous_token_index(&self, index: usize) -> Option<usize> {
10374 self.input.previous_visible_token_index(index)
10375 }
10376
10377 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
10382 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
10383 Some(index)
10384 } else {
10385 self.previous_token_index(index)
10386 }
10387 }
10388
10389 #[must_use]
10406 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
10407 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
10408 self.rule_stop_token_index(current_index, consumed_eof)
10409 }
10410
10411 #[must_use]
10420 pub fn after_action_stop_index_for_tree(
10421 &mut self,
10422 tree: ParseTree,
10423 current_index: usize,
10424 ) -> Option<usize> {
10425 if let Some(stop) = self
10426 .node(tree)
10427 .as_rule()
10428 .and_then(crate::tree::RuleNodeView::stop_id)
10429 {
10430 return Some(stop.index());
10431 }
10432 self.after_action_stop_index(current_index)
10433 }
10434
10435 #[must_use]
10445 pub fn after_action_start_index_for_tree(
10446 &self,
10447 tree: ParseTree,
10448 fallback_index: usize,
10449 ) -> usize {
10450 if let Some(start) = self
10451 .node(tree)
10452 .as_rule()
10453 .and_then(crate::tree::RuleNodeView::start_id)
10454 {
10455 return start.index();
10456 }
10457 fallback_index
10458 }
10459
10460 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
10465 self.rule_stop_token_index(index, consumed_eof)
10466 .and_then(|token_index| self.token_id_at(token_index))
10467 }
10468
10469 fn predicate_failure_recovery(
10476 &mut self,
10477 request: PredicateFailureRecovery<'_>,
10478 ) -> RecognizeOutcome {
10479 let PredicateFailureRecovery {
10480 rule_index,
10481 index,
10482 message,
10483 member_values,
10484 return_values,
10485 rule_alt_number,
10486 } = request;
10487 let rule_name = self
10488 .rule_names()
10489 .get(rule_index)
10490 .map_or_else(|| rule_index.to_string(), Clone::clone);
10491 let diagnostic = diagnostic_for_token(
10492 self.token_at(index).as_ref(),
10493 format!("rule {rule_name} {message}"),
10494 );
10495 let mut reversed_nodes = NodeSeqId::EMPTY;
10496 let mut next_index = index;
10497 loop {
10498 let symbol = self.token_type_at(next_index);
10499 if symbol == TOKEN_EOF {
10500 break;
10501 }
10502 let error = self.arena_token_node(next_index, true);
10503 self.arena_prepend(&mut reversed_nodes, error);
10504 let after = self.consume_index(next_index, symbol);
10505 if after == next_index {
10506 break;
10507 }
10508 next_index = after;
10509 }
10510 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
10511 let diagnostics = self
10512 .recognition_arena
10513 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10514 RecognizeOutcome {
10515 index: next_index,
10516 consumed_eof: false,
10517 alt_number: rule_alt_number,
10518 member_values,
10519 return_values,
10520 diagnostics,
10521 decisions: Vec::new(),
10522 actions: Vec::new(),
10523 nodes,
10524 }
10525 }
10526
10527 fn parser_semantic_hook_result(
10530 &mut self,
10531 request: ParserSemanticHookRequest<'_>,
10532 ) -> Option<bool> {
10533 let ParserSemanticHookRequest {
10534 index,
10535 rule_index,
10536 pred_index,
10537 context,
10538 local_int_arg,
10539 member_values,
10540 } = request;
10541 let rule_name = self.rule_names().get(rule_index).cloned();
10542 self.input.seek(index);
10543 let input = &mut self.input;
10544 let semantic_hooks = &mut self.semantic_hooks;
10545 let mut ctx = ParserSemCtx {
10546 input,
10547 tree_storage: &self.tree,
10548 rule_index,
10549 coordinate_index: pred_index,
10550 rule_name,
10551 context,
10552 tree: None,
10553 local_int_arg,
10554 member_values,
10555 action: None,
10556 };
10557 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
10558 }
10559
10560 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
10565 if prior.is_empty() {
10566 return;
10567 }
10568 let mut merged = prior;
10569 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
10570 if !merged.contains(&coordinate) {
10571 merged.push(coordinate);
10572 }
10573 }
10574 self.unknown_predicate_hits = merged;
10575 }
10576
10577 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
10586 apply_unknown_predicate_policy(
10587 self.unknown_predicate_policy,
10588 rule_index,
10589 pred_index,
10590 &mut self.unknown_predicate_hits,
10591 )
10592 }
10593
10594 fn unknown_semantic_error(&self) -> Option<AntlrError> {
10597 use std::fmt::Write as _;
10598 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
10599 return None;
10600 }
10601 let mut message = String::new();
10602 for (rule_index, pred_index) in &self.unknown_predicate_hits {
10603 if !message.is_empty() {
10604 message.push_str("; ");
10605 }
10606 let _ = match self.rule_names().get(*rule_index) {
10607 Some(rule_name) => write!(
10608 message,
10609 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
10610 ),
10611 None => write!(
10612 message,
10613 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
10614 ),
10615 };
10616 }
10617 for (rule_index, source_state) in &self.unhandled_action_hits {
10618 if !message.is_empty() {
10619 message.push_str("; ");
10620 }
10621 let _ = match self.rule_names().get(*rule_index) {
10622 Some(rule_name) => write!(
10623 message,
10624 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
10625 ),
10626 None => write!(
10627 message,
10628 "unhandled semantic action: rule_index={rule_index} state={source_state}"
10629 ),
10630 };
10631 }
10632 Some(AntlrError::Unsupported(message))
10633 }
10634
10635 fn parser_semir_predicate_matches(
10643 &mut self,
10644 semantics: &ParserSemantics,
10645 predicate: &ParserSemanticPredicate,
10646 request: ParserSemanticHookRequest<'_>,
10647 ) -> bool {
10648 self.input.seek(request.index);
10649 let rule_name = self
10650 .data
10651 .rule_names()
10652 .get(request.rule_index)
10653 .map(String::as_str);
10654 let unknown_predicate_policy = self.unknown_predicate_policy;
10655 let mut ctx = ParserSemIrCtx {
10656 input: &mut self.input,
10657 tree_storage: &self.tree,
10658 semantic_hooks: &mut self.semantic_hooks,
10659 rule_index: request.rule_index,
10660 coordinate_index: request.pred_index,
10661 rule_name,
10662 context: request.context,
10663 local_int_arg: request.local_int_arg,
10664 member_values: request.member_values,
10665 invoked_predicates: &mut self.invoked_predicates,
10666 unknown_predicate_policy,
10667 unknown_predicate_hits: &mut self.unknown_predicate_hits,
10668 };
10669 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
10670 }
10671
10672 fn fast_parser_predicate_matches(
10673 &mut self,
10674 context: Option<FastPredicateContext<'_>>,
10675 transition: ParserTransition<'_>,
10676 index: usize,
10677 ) -> bool {
10678 let Some(context) = context else {
10679 return true;
10680 };
10681 let rule_index = transition.arg0() as usize;
10682 let pred_index = transition.arg1() as usize;
10683 let key = (index, rule_index, pred_index);
10684 if let Some(result) = self.fast_predicate_cache.get(&key) {
10685 return *result;
10686 }
10687 let result = self.parser_predicate_matches(PredicateEval {
10688 index,
10689 rule_index,
10690 pred_index,
10691 predicates: context.predicates,
10692 semantics: context.semantics,
10693 context: None,
10694 local_int_arg: None,
10695 member_values: context.member_values,
10696 });
10697 self.fast_predicate_cache.insert(key, result);
10698 result
10699 }
10700
10701 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
10702 let PredicateEval {
10703 index,
10704 rule_index,
10705 pred_index,
10706 predicates,
10707 semantics,
10708 context,
10709 local_int_arg,
10710 member_values,
10711 } = eval;
10712 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
10713 semantics
10714 .predicates
10715 .iter()
10716 .find(|predicate| {
10717 predicate.rule_index == rule_index && predicate.pred_index == pred_index
10718 })
10719 .map(|predicate| (semantics, predicate))
10720 }) {
10721 return self.parser_semir_predicate_matches(
10722 semantics,
10723 predicate,
10724 ParserSemanticHookRequest {
10725 index,
10726 rule_index,
10727 pred_index,
10728 context,
10729 local_int_arg,
10730 member_values,
10731 },
10732 );
10733 }
10734 let Some((_, _, predicate)) = predicates
10735 .iter()
10736 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
10737 else {
10738 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
10739 index,
10740 rule_index,
10741 pred_index,
10742 context,
10743 local_int_arg,
10744 member_values,
10745 }) {
10746 return result;
10747 }
10748 return self.unknown_predicate_result(rule_index, pred_index);
10749 };
10750 self.input.seek(index);
10751 match predicate {
10752 ParserPredicate::True => true,
10753 ParserPredicate::False => false,
10754 ParserPredicate::FalseWithMessage { .. } => false,
10755 ParserPredicate::Invoke { value } => {
10756 let key = (rule_index, pred_index);
10757 if !self.invoked_predicates.contains(&key) {
10758 self.invoked_predicates.push(key);
10759 use std::io::Write as _;
10760 let mut stdout = std::io::stdout().lock();
10761 let _ = writeln!(stdout, "eval={value}");
10762 }
10763 *value
10764 }
10765 ParserPredicate::LookaheadTextEquals { offset, text } => self
10766 .input
10767 .lt(*offset)
10768 .is_some_and(|token| Token::text(&token) == Some(*text)),
10769 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
10770 self.la(*offset) != *token_type
10771 }
10772 ParserPredicate::TokenPairAdjacent => {
10773 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
10774 return false;
10775 };
10776 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
10777 return false;
10778 };
10779 first + 1 == second
10780 }
10781 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
10782 .and_then(|context| {
10783 context
10784 .child_rules(&self.tree, self.input.token_store(), *rule_index)
10785 .next()
10786 .map(crate::tree::RuleNodeView::text)
10787 })
10788 .is_none_or(|actual| actual != *text),
10789 ParserPredicate::LocalIntEquals { value } => {
10790 local_int_arg.is_none_or(|(_, actual)| actual == *value)
10791 }
10792 ParserPredicate::LocalIntLessOrEqual { value } => {
10793 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
10794 }
10795 ParserPredicate::MemberModuloEquals {
10796 member,
10797 modulus,
10798 value,
10799 equals,
10800 } => {
10801 if *modulus == 0 {
10802 return false;
10803 }
10804 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
10805 (actual == *value) == *equals
10806 }
10807 ParserPredicate::MemberEquals {
10808 member,
10809 value,
10810 equals,
10811 } => {
10812 let actual = member_values.get(member).copied().unwrap_or_default();
10813 (actual == *value) == *equals
10814 }
10815 }
10816 }
10817
10818 fn parser_predicate_failure_message(
10820 &self,
10821 rule_index: usize,
10822 pred_index: usize,
10823 predicates: &[(usize, usize, ParserPredicate)],
10824 ) -> Option<&'static str> {
10825 predicates
10826 .iter()
10827 .find_map(|(rule, pred, predicate)| match predicate {
10828 ParserPredicate::FalseWithMessage { message }
10829 if *rule == rule_index && *pred == pred_index =>
10830 {
10831 Some(*message)
10832 }
10833 _ => None,
10834 })
10835 }
10836
10837 pub fn parser_semantic_ir_predicate_failure_message(
10840 &self,
10841 rule_index: usize,
10842 pred_index: usize,
10843 semantics: &ParserSemantics,
10844 ) -> Option<&'static str> {
10845 semantics
10846 .predicates
10847 .iter()
10848 .find(|predicate| {
10849 predicate.rule_index == rule_index && predicate.pred_index == pred_index
10850 })
10851 .and_then(|predicate| predicate.failure_message)
10852 }
10853
10854 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
10863 if symbol == TOKEN_EOF {
10864 return index;
10865 }
10866 self.input.next_visible_after(index)
10867 }
10868
10869 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
10872 let text = display_input_text(&self.input.text(start_index, error_index));
10873 diagnostic_for_token(
10874 self.token_at(error_index).as_ref(),
10875 format!("no viable alternative at input '{text}'"),
10876 )
10877 }
10878
10879 fn recovery_failure_diagnostic(
10882 &self,
10883 index: usize,
10884 decision_start_index: Option<usize>,
10885 expected_symbols: &BTreeSet<i32>,
10886 ) -> ParserDiagnostic {
10887 if expected_symbols.len() > 1 {
10888 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
10889 return self.no_viable_alternative(decision_start, index);
10890 }
10891 }
10892 diagnostic_for_token(
10893 self.token_at(index).as_ref(),
10894 format!(
10895 "mismatched input {} expecting {}",
10896 self.token_at(index)
10897 .as_ref()
10898 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
10899 self.expected_symbols_display(expected_symbols)
10900 ),
10901 )
10902 }
10903
10904 fn eof_rule_recovery_diagnostic(
10907 &self,
10908 index: usize,
10909 expected_symbols: &BTreeSet<i32>,
10910 expected: &ExpectedTokens,
10911 ) -> ParserDiagnostic {
10912 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
10913 &expected.symbols
10914 } else {
10915 expected_symbols
10916 };
10917 diagnostic_for_token(
10918 self.token_at(index).as_ref(),
10919 format!(
10920 "mismatched input {} expecting {}",
10921 self.token_at(index)
10922 .as_ref()
10923 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
10924 self.expected_symbols_display(symbols)
10925 ),
10926 )
10927 }
10928
10929 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
10935 let Some(stop) = stop else {
10936 return String::new();
10937 };
10938 let stop = if self
10939 .token_at(stop)
10940 .is_some_and(|token| token.token_type() == TOKEN_EOF)
10941 {
10942 let Some(previous) = self.previous_token_index(stop) else {
10943 return String::new();
10944 };
10945 previous
10946 } else {
10947 stop
10948 };
10949 self.input.text(start, stop)
10950 }
10951
10952 fn clear_prediction_diagnostics(&mut self) {
10955 self.prediction_diagnostics.clear();
10956 self.reported_prediction_diagnostics.clear();
10957 }
10958
10959 fn reset_per_parse_caches(&mut self) {
10983 self.rule_first_set_cache.clear();
10984 self.decision_lookahead_cache.clear();
10985 self.ll1_decision_cache.clear();
10986 self.fast_predicate_cache.clear();
10987 self.rule_stop_reach_cache.clear();
10988 self.clean_memo_mode = CleanMemoMode::Probe;
10989 self.clean_memo_probe_seen.clear();
10990 self.clean_memo_probe_samples = 0;
10991 self.clean_memo_probe_repeats = 0;
10992 self.clean_memo_sparse_samples = 0;
10993 self.recovery_symbols_intern.clear();
10994 self.state_expected_cache.clear();
10995 self.state_expected_token_cache.clear();
10996 }
10997
10998 fn record_prediction_diagnostics(
11001 &mut self,
11002 atn: &Atn,
11003 state: AtnState<'_>,
11004 start_index: usize,
11005 outcomes: &[RecognizeOutcome],
11006 ) {
11007 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
11008 return;
11009 }
11010 let Some(decision) = atn
11011 .decision_to_state()
11012 .iter()
11013 .position(|state_number| state_number == state.state_number())
11014 else {
11015 return;
11016 };
11017 let Some(rule_index) = state.rule_index() else {
11018 return;
11019 };
11020 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
11021 for outcome in outcomes
11022 .iter()
11023 .filter(|outcome| outcome.diagnostics.is_empty())
11024 {
11025 let Some(alt) = outcome.decisions.first() else {
11026 continue;
11027 };
11028 alts_by_end
11029 .entry(outcome.index)
11030 .or_default()
11031 .insert(alt + 1);
11032 }
11033 let Some((&end_index, ambig_alts)) = alts_by_end
11034 .iter()
11035 .filter(|(_, alts)| alts.len() > 1)
11036 .max_by_key(|(end, _)| *end)
11037 else {
11038 return;
11039 };
11040 let rule_name = self
11041 .rule_names()
11042 .get(rule_index)
11043 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
11044 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
11045 let input = display_input_text(&self.input.text(start_index, stop_index));
11046 let alts = ambig_alts
11047 .iter()
11048 .map(usize::to_string)
11049 .collect::<Vec<_>>()
11050 .join(", ");
11051 let key = (decision, start_index, format!("{alts}:{input}"));
11052 if !self.reported_prediction_diagnostics.insert(key) {
11053 return;
11054 }
11055 let start_diagnostic = diagnostic_for_token(
11056 self.token_at(start_index),
11057 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
11058 );
11059 let stop_diagnostic = diagnostic_for_token(
11060 self.token_at(stop_index),
11061 format!(
11062 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
11063 ),
11064 );
11065 self.prediction_diagnostics.push(start_diagnostic);
11066 self.prediction_diagnostics.push(stop_diagnostic);
11067 }
11068
11069 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
11071 expected_symbols_display(
11072 &state_expected_symbols(atn, state_number),
11073 self.vocabulary(),
11074 )
11075 }
11076
11077 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
11082 let state = usize::try_from(self.data().state()).unwrap_or(0);
11083 ExpectedTokenSet {
11084 symbols: state_expected_symbols(atn, state),
11085 }
11086 }
11087
11088 pub const fn set_bail_on_error(&mut self, bail: bool) {
11091 self.bail_on_error = bail;
11092 }
11093
11094 #[must_use]
11096 pub const fn bail_on_error(&self) -> bool {
11097 self.bail_on_error
11098 }
11099
11100 pub fn rule_invocation_stack(&self) -> Vec<String> {
11103 self.rule_context_stack
11104 .iter()
11105 .rev()
11106 .map(|frame| {
11107 self.data()
11108 .rule_names()
11109 .get(frame.rule_index)
11110 .cloned()
11111 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
11112 })
11113 .collect()
11114 }
11115
11116 pub fn active_invocation_states(&self) -> Vec<isize> {
11120 self.rule_context_stack
11121 .iter()
11122 .skip(1)
11123 .rev()
11124 .map(|frame| frame.invoking_state)
11125 .collect()
11126 }
11127
11128 pub fn token_display_at(&self, index: usize) -> Option<String> {
11130 self.token_at(index).map(|token| format!("{token}"))
11131 }
11132}
11133
11134impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
11135where
11136 S: TokenSource,
11137 H: SemanticHooks,
11138{
11139 fn parse_rule(
11140 &mut self,
11141 rule_index: usize,
11142 invoking_state: isize,
11143 precedence: i32,
11144 ) -> DirectAdaptiveParseResult<ParseTree> {
11145 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
11146 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
11147 )?;
11148 let stop_state = self
11149 .atn
11150 .rule_to_stop_state()
11151 .get(rule_index)
11152 .filter(|state| *state != usize::MAX)
11153 .ok_or(DirectAdaptiveParseControl::Fallback(
11154 DirectAdaptiveFallback::MissingAtn,
11155 ))?;
11156 let start_index = self.parser.current_visible_index();
11157 let mut context = ParserRuleContext::new(rule_index, invoking_state);
11158 if let Some(token) = self.parser.token_id_at(start_index) {
11159 self.parser.set_context_start(&mut context, token);
11160 }
11161 let mut state_number = start_state;
11162 let mut consumed_eof = false;
11163 while state_number != stop_state {
11164 self.step()?;
11165 let (transition, boundary) = self.next_transition(state_number, precedence)?;
11166 if boundary.is_some() {
11167 return Err(DirectAdaptiveParseControl::Fallback(
11168 DirectAdaptiveFallback::LeftRecursiveBoundary,
11169 ));
11170 }
11171 match transition.data() {
11172 Transition::Epsilon { target } => {
11173 state_number = target;
11174 }
11175 Transition::Precedence {
11176 target,
11177 precedence: transition_precedence,
11178 } => {
11179 if transition_precedence < precedence {
11180 return Err(DirectAdaptiveParseControl::Fallback(
11181 DirectAdaptiveFallback::Precedence,
11182 ));
11183 }
11184 state_number = target;
11185 }
11186 Transition::Rule {
11187 rule_index,
11188 follow_state,
11189 precedence: rule_precedence,
11190 ..
11191 } => {
11192 let child = self.parse_rule(
11193 rule_index,
11194 invoking_state_number(state_number),
11195 rule_precedence,
11196 )?;
11197 if self.parser.build_parse_trees {
11198 self.parser.tree.add_child(&mut context, child);
11199 }
11200 state_number = follow_state;
11201 }
11202 Transition::Atom { .. }
11203 | Transition::Range { .. }
11204 | Transition::Set { .. }
11205 | Transition::NotSet { .. }
11206 | Transition::Wildcard { .. } => {
11207 let (matched_eof, child) = self.consume_transition(transition)?;
11208 consumed_eof |= matched_eof;
11209 if let Some(child) = child {
11210 self.parser.tree.add_child(&mut context, child);
11211 }
11212 state_number = transition.target();
11213 }
11214 Transition::Predicate { .. } => {
11215 return Err(DirectAdaptiveParseControl::Fallback(
11216 DirectAdaptiveFallback::Predicate,
11217 ));
11218 }
11219 Transition::Action { .. } => {
11220 return Err(DirectAdaptiveParseControl::Fallback(
11221 DirectAdaptiveFallback::Action,
11222 ));
11223 }
11224 }
11225 }
11226
11227 let stop_index = self
11228 .parser
11229 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
11230 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
11231 self.parser.set_context_stop(&mut context, token);
11232 }
11233 Ok(self.parser.rule_node(context))
11234 }
11235
11236 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
11237 self.steps += 1;
11238 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
11239 return Err(DirectAdaptiveParseControl::Fallback(
11240 DirectAdaptiveFallback::StepLimit,
11241 ));
11242 }
11243 Ok(())
11244 }
11245
11246 fn next_transition(
11247 &mut self,
11248 state_number: usize,
11249 precedence: i32,
11250 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
11251 let state = self
11252 .atn
11253 .state(state_number)
11254 .ok_or(DirectAdaptiveParseControl::Fallback(
11255 DirectAdaptiveFallback::MissingAtn,
11256 ))?;
11257 if state.is_rule_stop() {
11258 return Err(DirectAdaptiveParseControl::Fallback(
11259 DirectAdaptiveFallback::RuleStop,
11260 ));
11261 }
11262 let transition_index =
11263 self.transition_index(state_number, state.transitions().len(), precedence)?;
11264 let transition = state.transitions().get(transition_index).ok_or(
11265 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
11266 )?;
11267 let boundary = match &transition.data() {
11268 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
11269 left_recursive_boundary(self.atn, state, *target)
11270 }
11271 _ => None,
11272 };
11273 Ok((transition, boundary))
11274 }
11275
11276 fn transition_index(
11277 &mut self,
11278 state_number: usize,
11279 transition_count: usize,
11280 precedence: i32,
11281 ) -> DirectAdaptiveParseResult<usize> {
11282 match transition_count {
11283 0 => Err(DirectAdaptiveParseControl::Fallback(
11284 DirectAdaptiveFallback::NoTransition,
11285 )),
11286 1 => Ok(0),
11287 _ => {
11288 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
11289 return Ok(alt);
11290 }
11291 let decision = self
11292 .decision_by_state
11293 .get(state_number)
11294 .and_then(|decision| *decision)
11295 .ok_or(DirectAdaptiveParseControl::Fallback(
11296 DirectAdaptiveFallback::UnknownDecision,
11297 ))?;
11298 let prediction = self
11299 .simulator
11300 .adaptive_predict_stream_info_with_precedence(
11301 decision,
11302 direct_precedence(precedence),
11303 &mut self.parser.input,
11304 )
11305 .map_err(|_| {
11306 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
11307 })?;
11308 if prediction.has_semantic_context {
11309 return Err(DirectAdaptiveParseControl::Fallback(
11310 DirectAdaptiveFallback::SemanticContext,
11311 ));
11312 }
11313 prediction
11314 .alt
11315 .checked_sub(1)
11316 .filter(|index| *index < transition_count)
11317 .ok_or(DirectAdaptiveParseControl::Fallback(
11318 DirectAdaptiveFallback::InvalidAlt,
11319 ))
11320 }
11321 }
11322 }
11323
11324 fn ll1_transition_index(
11325 &mut self,
11326 state_number: usize,
11327 transition_count: usize,
11328 ) -> DirectAdaptiveParseResult<Option<usize>> {
11329 let state = self
11330 .atn
11331 .state(state_number)
11332 .ok_or(DirectAdaptiveParseControl::Fallback(
11333 DirectAdaptiveFallback::MissingAtn,
11334 ))?;
11335 if state.precedence_rule_decision() {
11336 return Ok(None);
11337 }
11338 let Some(rule_stop) = state
11339 .rule_index()
11340 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
11341 else {
11342 return Ok(None);
11343 };
11344 let symbol = self.parser.input.la_token(1);
11345 let entry = self
11346 .parser
11347 .cached_decision_lookahead(self.atn, state, rule_stop);
11348 Ok(
11349 ll1_greedy_alt(&entry, symbol, state.non_greedy())
11350 .filter(|alt| *alt < transition_count),
11351 )
11352 }
11353
11354 fn consume_transition(
11355 &mut self,
11356 transition: ParserTransition<'_>,
11357 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
11358 let symbol = self.parser.input.la_token(1);
11359 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
11360 return Err(DirectAdaptiveParseControl::Fallback(
11361 DirectAdaptiveFallback::TokenMismatch,
11362 ));
11363 }
11364 let token = self
11365 .parser
11366 .input
11367 .lt_id(1)
11368 .ok_or(DirectAdaptiveParseControl::Fallback(
11369 DirectAdaptiveFallback::TokenMismatch,
11370 ))?;
11371 let matched_eof = symbol == TOKEN_EOF;
11372 if !matched_eof {
11373 self.parser.consume();
11374 }
11375 let child = self
11376 .parser
11377 .build_parse_trees
11378 .then(|| self.parser.terminal_tree(token));
11379 Ok((matched_eof, child))
11380 }
11381}
11382
11383fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
11386 if !state.precedence_rule_decision() {
11387 return None;
11388 }
11389 let target_state = atn.state(target)?;
11390 if target_state.kind() == AtnStateKind::LoopEnd {
11391 return None;
11392 }
11393 state.rule_index()
11394}
11395
11396fn next_alt_number(
11403 state: AtnState<'_>,
11404 transition_count: usize,
11405 transition_index: usize,
11406 current_alt_number: usize,
11407 track_alt_numbers: bool,
11408) -> usize {
11409 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
11410 return current_alt_number;
11411 }
11412 if matches!(
11413 state.kind(),
11414 AtnStateKind::Basic
11415 | AtnStateKind::BlockStart
11416 | AtnStateKind::PlusBlockStart
11417 | AtnStateKind::StarBlockStart
11418 | AtnStateKind::StarLoopEntry
11419 ) && !state.precedence_rule_decision()
11420 {
11421 return transition_index + 1;
11422 }
11423 current_alt_number
11424}
11425
11426fn invoking_state_number(state_number: usize) -> isize {
11429 isize::try_from(state_number).unwrap_or(isize::MAX)
11430}
11431
11432const fn packed_i32(value: u32) -> i32 {
11433 i32::from_le_bytes(value.to_le_bytes())
11434}
11435
11436fn direct_precedence(precedence: i32) -> usize {
11437 usize::try_from(precedence.max(0)).unwrap_or_default()
11438}
11439
11440fn token_input_display(token: &impl Token) -> String {
11441 format!("'{}'", token.text().unwrap_or("<EOF>"))
11442}
11443
11444fn display_input_text(text: &str) -> String {
11445 let mut out = String::new();
11446 for ch in text.chars() {
11447 match ch {
11448 '\n' => out.push_str("\\n"),
11449 '\r' => out.push_str("\\r"),
11450 '\t' => out.push_str("\\t"),
11451 other => out.push(other),
11452 }
11453 }
11454 out
11455}
11456
11457fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
11458 let (line, column) = token.map_or((0, 0), |token| (token.line(), token.column()));
11459 ParserDiagnostic {
11460 line,
11461 column,
11462 message,
11463 }
11464}
11465
11466fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
11467 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
11468}
11469
11470fn expected_symbols_display_iter(
11471 symbols: impl IntoIterator<Item = i32>,
11472 vocabulary: &Vocabulary,
11473) -> String {
11474 let items = symbols
11475 .into_iter()
11476 .map(|symbol| expected_symbol_display(symbol, vocabulary))
11477 .collect::<Vec<_>>();
11478 if let [single] = items.as_slice() {
11479 return single.clone();
11480 }
11481 format!("{{{}}}", items.join(", "))
11482}
11483
11484fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
11485 if symbol == TOKEN_EOF {
11486 return "<EOF>".to_owned();
11487 }
11488 vocabulary.display_name(symbol)
11489}
11490
11491fn caller_follow_token_info_for_stream<S: TokenSource>(
11492 input: &mut CommonTokenStream<S>,
11493 index: usize,
11494) -> (i32, bool, bool) {
11495 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
11498 input.fill();
11499 }
11500 let token_type = input.token_type_at_index(index);
11501 let visible_channel = input.channel();
11502 let token = input.get(index);
11503 let is_boundary = token
11504 .as_ref()
11505 .and_then(Token::text)
11506 .is_some_and(is_caller_follow_boundary_text);
11507 let is_boundary_gap = token.as_ref().is_some_and(|token| {
11508 token.channel() != visible_channel || is_caller_follow_boundary_gap_text(token.text())
11509 });
11510 (token_type, is_boundary, is_boundary_gap)
11511}
11512
11513fn is_caller_follow_boundary_text(text: &str) -> bool {
11514 text.chars().any(|ch| ch == ';' || ch == '\n')
11515 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11516}
11517
11518fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
11519 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
11520}
11521
11522fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
11526 let Some(rule_index) = state.rule_index() else {
11527 return false;
11528 };
11529 atn.rule_to_start_state()
11530 .get(rule_index)
11531 .and_then(|state_number| atn.state(state_number))
11532 .is_some_and(AtnState::left_recursive_rule)
11533}
11534
11535fn select_better_top_outcome(
11542 first: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
11543 second: Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens>,
11544 arena: &RecognitionArena,
11545) -> Result<(FastRecognizeOutcome, ExpectedTokens), ExpectedTokens> {
11546 match (first, second) {
11547 (Ok(first), Ok(second)) => {
11548 if arena.diagnostics(first.0.diagnostics).next().is_none() {
11549 Ok(first)
11550 } else {
11551 Ok(second)
11552 }
11553 }
11554 (Ok(first), Err(_)) => Ok(first),
11555 (Err(_), Ok(second)) => Ok(second),
11556 (Err(_), Err(second_expected)) => Err(second_expected),
11557 }
11558}
11559
11560fn select_best_fast_outcome(
11566 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
11567 prediction_mode: PredictionMode,
11568 caller_follow: Option<&TokenBitSet>,
11569 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
11570 arena: &RecognitionArena,
11571) -> Option<FastRecognizeOutcome> {
11572 let mut best = None;
11573 let mut best_caller_follow = None;
11574 for outcome in outcomes {
11575 if matches!(
11576 prediction_mode,
11577 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
11578 ) && outcome.diagnostics.is_empty()
11579 && let Some(follow) = caller_follow
11580 {
11581 let (token_type, is_boundary, _) = token_info_at(outcome.index);
11582 if is_boundary && follow.contains(token_type) {
11583 let replace =
11584 best_caller_follow
11585 .as_ref()
11586 .is_none_or(|existing: &FastRecognizeOutcome| {
11587 (outcome.index, outcome.consumed_eof)
11588 < (existing.index, existing.consumed_eof)
11589 });
11590 if replace {
11591 best_caller_follow = Some(outcome);
11592 }
11593 }
11594 }
11595 let Some(existing) = best else {
11596 best = Some(outcome);
11597 continue;
11598 };
11599 let outcome_position = (outcome.index, outcome.consumed_eof);
11600 let best_position = (existing.index, existing.consumed_eof);
11601 let better = match prediction_mode {
11602 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
11603 outcome_position,
11604 outcome.diagnostics,
11605 best_position,
11606 existing.diagnostics,
11607 arena,
11608 ),
11609 PredictionMode::Sll => outcome.index > existing.index,
11610 };
11611 best = Some(if better { outcome } else { existing });
11612 }
11613 let should_use_caller_follow =
11614 best_caller_follow
11615 .as_ref()
11616 .zip(best.as_ref())
11617 .is_some_and(|(candidate, selected)| {
11618 if !selected.diagnostics.is_empty() {
11619 return true;
11620 }
11621 candidate.index < selected.index
11622 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
11623 });
11624 if should_use_caller_follow {
11625 best_caller_follow
11626 } else {
11627 best
11628 }
11629}
11630
11631fn select_best_outcome(
11632 outcomes: impl Iterator<Item = RecognizeOutcome>,
11633 prediction_mode: PredictionMode,
11634 arena: &RecognitionArena,
11635) -> Option<RecognizeOutcome> {
11636 let outcomes = outcomes.collect::<Vec<_>>();
11637 let prefer_first_tie = outcomes
11638 .iter()
11639 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
11640 outcomes.into_iter().reduce(|best, outcome| {
11641 let outcome_position = (outcome.index, outcome.consumed_eof);
11642 let best_position = (best.index, best.consumed_eof);
11643 let better = match prediction_mode {
11644 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
11645 outcome_is_better(
11646 outcome_position,
11647 outcome.diagnostics,
11648 best_position,
11649 best.diagnostics,
11650 arena,
11651 ) || (!prefer_first_tie
11652 && outcome_position == best_position
11653 && arena.diagnostics_len(outcome.diagnostics)
11654 == arena.diagnostics_len(best.diagnostics)
11655 && arena.diagnostics_recovery_rank(outcome.diagnostics)
11656 == arena.diagnostics_recovery_rank(best.diagnostics)
11657 && (outcome.decisions < best.decisions
11658 || (outcome.decisions == best.decisions && outcome.actions > best.actions)))
11659 }
11660 PredictionMode::Sll => {
11661 outcome_position > best_position
11662 || (outcome_position == best_position
11663 && !prefer_first_tie
11664 && (outcome.decisions < best.decisions
11665 || (outcome.decisions == best.decisions
11666 && outcome_is_better(
11667 outcome_position,
11668 outcome.diagnostics,
11669 best_position,
11670 best.diagnostics,
11671 arena,
11672 ))))
11673 }
11674 };
11675 if better {
11676 return outcome;
11677 }
11678 best
11679 })
11680}
11681
11682fn transition_decision(
11689 atn: &Atn,
11690 state: AtnState<'_>,
11691 transition_count: usize,
11692 transition_index: usize,
11693 predicates: &[(usize, usize, ParserPredicate)],
11694) -> Option<usize> {
11695 if transition_count <= 1
11696 || state.precedence_rule_decision()
11697 || decision_reaches_unsupported_predicate(atn, state, predicates)
11698 {
11699 return None;
11700 }
11701 Some(transition_index)
11702}
11703
11704fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
11710 transition_count > 1
11711 && !matches!(
11712 state.kind(),
11713 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
11714 )
11715}
11716
11717fn record_no_viable_if_ambiguous(
11720 expected: &mut ExpectedTokens,
11721 decision_start_index: Option<usize>,
11722 index: usize,
11723) {
11724 if expected.index == Some(index) && expected.symbols.len() > 1 {
11725 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
11726 expected.record_no_viable(decision_start, index);
11727 }
11728 }
11729}
11730
11731const fn record_predicate_no_viable(
11734 expected: &mut ExpectedTokens,
11735 decision_start_index: Option<usize>,
11736 index: usize,
11737) {
11738 if let Some(decision_start) = decision_start_index {
11739 expected.record_no_viable(decision_start, index);
11740 }
11741}
11742
11743const fn no_viable_decision_start(
11745 decision_start_index: Option<usize>,
11746 index: usize,
11747) -> Option<usize> {
11748 match decision_start_index {
11749 Some(start) if index > start => Some(start),
11750 _ => None,
11751 }
11752}
11753
11754fn restore_expected(
11758 children: &[RecognizeOutcome],
11759 child_start_index: usize,
11760 expected: &mut ExpectedTokens,
11761 snapshot: ExpectedTokens,
11762 preserve_child_expected: bool,
11763) {
11764 if preserve_child_expected {
11765 return;
11766 }
11767 if children
11768 .iter()
11769 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
11770 {
11771 *expected = snapshot;
11772 }
11773}
11774
11775fn decision_reaches_unsupported_predicate(
11778 atn: &Atn,
11779 state: AtnState<'_>,
11780 predicates: &[(usize, usize, ParserPredicate)],
11781) -> bool {
11782 state.transitions().iter().any(|transition| {
11783 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
11784 })
11785}
11786
11787fn transition_reaches_unsupported_predicate(
11789 atn: &Atn,
11790 transition: ParserTransition<'_>,
11791 predicates: &[(usize, usize, ParserPredicate)],
11792 visited: &mut BTreeSet<usize>,
11793) -> bool {
11794 match &transition.data() {
11795 Transition::Predicate {
11796 rule_index,
11797 pred_index,
11798 ..
11799 } => !predicates
11800 .iter()
11801 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
11802 Transition::Epsilon { target }
11803 | Transition::Action { target, .. }
11804 | Transition::Rule { target, .. } => {
11805 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
11806 }
11807 Transition::Precedence { .. }
11808 | Transition::Atom { .. }
11809 | Transition::Range { .. }
11810 | Transition::Set { .. }
11811 | Transition::NotSet { .. }
11812 | Transition::Wildcard { .. } => false,
11813 }
11814}
11815
11816fn state_reaches_unsupported_predicate(
11818 atn: &Atn,
11819 state_number: usize,
11820 predicates: &[(usize, usize, ParserPredicate)],
11821 visited: &mut BTreeSet<usize>,
11822) -> bool {
11823 if !visited.insert(state_number) {
11824 return false;
11825 }
11826 let Some(state) = atn.state(state_number) else {
11827 return false;
11828 };
11829 state.transitions().iter().any(|transition| {
11830 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
11831 })
11832}
11833
11834fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
11836 if let Some(decision) = decision {
11837 outcome.decisions.insert(0, decision);
11838 }
11839}
11840
11841fn outcome_is_better(
11842 outcome_position: (usize, bool),
11843 outcome_diagnostics: DiagnosticSeqId,
11844 best_position: (usize, bool),
11845 best_diagnostics: DiagnosticSeqId,
11846 arena: &RecognitionArena,
11847) -> bool {
11848 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
11849 let best_len = arena.diagnostics_len(best_diagnostics);
11850 outcome_position > best_position
11851 || (outcome_position == best_position
11852 && (outcome_len < best_len
11853 || (outcome_len == best_len
11854 && arena.diagnostics_recovery_rank(outcome_diagnostics)
11855 < arena.diagnostics_recovery_rank(best_diagnostics))))
11856}
11857
11858fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
11859 if outcomes
11860 .iter()
11861 .any(|outcome| outcome.diagnostics.is_empty())
11862 {
11863 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
11864 }
11865}
11866
11867fn discard_recovered_outcomes_if_clean_path_exists(
11868 outcomes: &mut Vec<RecognizeOutcome>,
11869 arena: &RecognitionArena,
11870) {
11871 if outcomes
11872 .iter()
11873 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
11874 {
11875 return;
11876 }
11877 if outcomes
11878 .iter()
11879 .any(|outcome| outcome.diagnostics.is_empty())
11880 {
11881 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
11882 }
11883}
11884
11885fn outcome_has_rule_failure_diagnostic(
11888 outcome: &RecognizeOutcome,
11889 arena: &RecognitionArena,
11890) -> bool {
11891 arena
11892 .diagnostics(outcome.diagnostics)
11893 .any(|diagnostic| diagnostic.message.starts_with("rule "))
11894}
11895
11896fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
11910 if outcomes.len() < 2 {
11911 return;
11912 }
11913 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
11914 outcomes.retain(|outcome| {
11915 seen.insert((
11916 outcome.index,
11917 outcome.consumed_eof,
11918 arena.diagnostics_len(outcome.diagnostics),
11919 arena.diagnostics_recovery_rank(outcome.diagnostics),
11920 ))
11921 });
11922}
11923
11924const FAST_OUTCOME_INLINE_KEYS: usize = 8;
11925const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
11926const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
11927const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
11928
11929#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11930enum FastOutcomeDedupStrategy {
11931 Inline,
11932 Dense,
11933 Sparse,
11934}
11935
11936impl FastOutcomeDedupScratch {
11937 fn prepare_dense(&mut self, word_count: usize) {
11938 while let Some(word_index) = self.touched_dense_words.pop() {
11939 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
11940 }
11941 if self.dense_words.len() < word_count {
11942 self.dense_words.resize(word_count, 0);
11943 }
11944 }
11945}
11946
11947fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
11948 let first_index = outcomes.first()?.index;
11949 let (min_index, max_index) = outcomes[1..].iter().fold(
11950 (first_index, first_index),
11951 |(min_index, max_index), outcome| {
11952 (min_index.min(outcome.index), max_index.max(outcome.index))
11953 },
11954 );
11955 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
11956 let bit_count = index_span.checked_mul(2)?;
11957 let word_count =
11958 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
11959 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
11960 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
11961 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
11962 .then_some((min_index, word_count))
11963}
11964
11965#[cfg(feature = "perf-counters")]
11966fn record_clean_fast_outcome_dedup(
11967 strategy: FastOutcomeDedupStrategy,
11968 input_len: usize,
11969 output_len: usize,
11970 dense_words: usize,
11971) {
11972 let counter = match strategy {
11973 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
11974 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
11975 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
11976 };
11977 perf_counters::inc(
11978 &perf_counters::OUTCOME_DEDUPE_INPUTS,
11979 u64::try_from(input_len).unwrap_or(u64::MAX),
11980 );
11981 perf_counters::inc(
11982 &perf_counters::OUTCOME_DEDUPE_REMOVED,
11983 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
11984 );
11985 perf_counters::inc(counter, 1);
11986 perf_counters::inc(
11987 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
11988 u64::try_from(dense_words).unwrap_or(u64::MAX),
11989 );
11990}
11991
11992fn dedupe_clean_fast_outcomes(
11996 outcomes: &mut Vec<FastRecognizeOutcome>,
11997 scratch: &mut FastOutcomeDedupScratch,
11998) -> FastOutcomeDedupStrategy {
11999 #[cfg(feature = "perf-counters")]
12000 let input_len = outcomes.len();
12001 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
12002 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
12003 let mut inline_len = 0_usize;
12004 outcomes.retain(|outcome| {
12005 let key = (outcome.index, outcome.consumed_eof);
12006 if inline_keys[..inline_len].contains(&key) {
12007 return false;
12008 }
12009 inline_keys[inline_len] = key;
12010 inline_len += 1;
12011 true
12012 });
12013 #[cfg(feature = "perf-counters")]
12014 record_clean_fast_outcome_dedup(
12015 FastOutcomeDedupStrategy::Inline,
12016 input_len,
12017 outcomes.len(),
12018 0,
12019 );
12020 return FastOutcomeDedupStrategy::Inline;
12021 }
12022
12023 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
12024 scratch.prepare_dense(word_count);
12025 outcomes.retain(|outcome| {
12026 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
12027 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
12028 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
12029 let word = &mut scratch.dense_words[word_index];
12030 if *word & bit != 0 {
12031 return false;
12032 }
12033 if *word == 0 {
12034 scratch
12035 .touched_dense_words
12036 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
12037 }
12038 *word |= bit;
12039 true
12040 });
12041 #[cfg(feature = "perf-counters")]
12042 record_clean_fast_outcome_dedup(
12043 FastOutcomeDedupStrategy::Dense,
12044 input_len,
12045 outcomes.len(),
12046 word_count,
12047 );
12048 return FastOutcomeDedupStrategy::Dense;
12049 }
12050
12051 scratch.sparse_keys.clear();
12052 scratch.sparse_keys.reserve(outcomes.len());
12053 outcomes.retain(|outcome| {
12054 scratch
12055 .sparse_keys
12056 .insert((outcome.index, outcome.consumed_eof))
12057 });
12058 #[cfg(feature = "perf-counters")]
12059 record_clean_fast_outcome_dedup(
12060 FastOutcomeDedupStrategy::Sparse,
12061 input_len,
12062 outcomes.len(),
12063 0,
12064 );
12065 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
12066 scratch.sparse_keys = FxHashSet::default();
12067 }
12068 FastOutcomeDedupStrategy::Sparse
12069}
12070
12071fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
12074 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
12075 outcomes
12076 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
12077}
12078
12079fn compare_recognize_outcomes(
12080 left: &RecognizeOutcome,
12081 right: &RecognizeOutcome,
12082 arena: &RecognitionArena,
12083) -> Ordering {
12084 left.index
12085 .cmp(&right.index)
12086 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
12087 .then_with(|| left.alt_number.cmp(&right.alt_number))
12088 .then_with(|| left.member_values.cmp(&right.member_values))
12089 .then_with(|| left.return_values.cmp(&right.return_values))
12090 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
12091 .then_with(|| left.decisions.cmp(&right.decisions))
12092 .then_with(|| left.actions.cmp(&right.actions))
12093 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
12094}
12095
12096impl<S, H> Recognizer for BaseParser<S, H>
12097where
12098 S: TokenSource,
12099 H: SemanticHooks,
12100{
12101 fn data(&self) -> &RecognizerData {
12102 &self.data
12103 }
12104
12105 fn data_mut(&mut self) -> &mut RecognizerData {
12106 &mut self.data
12107 }
12108}
12109
12110impl<S, H> Parser for BaseParser<S, H>
12111where
12112 S: TokenSource,
12113 H: SemanticHooks,
12114{
12115 fn build_parse_trees(&self) -> bool {
12116 self.build_parse_trees
12117 }
12118
12119 fn set_build_parse_trees(&mut self, build: bool) {
12120 self.build_parse_trees = build;
12121 }
12122
12123 fn number_of_syntax_errors(&self) -> usize {
12124 Self::number_of_syntax_errors(self)
12125 }
12126
12127 fn report_diagnostic_errors(&self) -> bool {
12128 self.report_diagnostic_errors
12129 }
12130
12131 fn set_report_diagnostic_errors(&mut self, report: bool) {
12132 self.report_diagnostic_errors = report;
12133 }
12134
12135 fn prediction_mode(&self) -> PredictionMode {
12136 self.prediction_mode
12137 }
12138
12139 fn set_prediction_mode(&mut self, mode: PredictionMode) {
12140 self.prediction_mode = mode;
12141 }
12142}
12143
12144#[cfg(test)]
12145mod tests {
12146 use super::*;
12147 use crate::atn::parser::{
12148 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
12149 };
12150 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
12151 use crate::token::{HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError};
12152 use crate::token_stream::CommonTokenStream;
12153 use crate::tree::{NodeKind, ParseTreeStats};
12154 use crate::vocabulary::Vocabulary;
12155 use std::cell::RefCell;
12156 use std::mem::size_of;
12157 use std::rc::Rc;
12158 use std::sync::{Arc, Mutex};
12159
12160 #[test]
12161 fn fx_hasher_write_matches_typed_methods_for_full_words() {
12162 let value: u64 = 0x0102_0304_0506_0708;
12169 let mut typed = FxHasher::default();
12170 typed.write_u64(value);
12171 let mut bytewise = FxHasher::default();
12172 bytewise.write(&value.to_le_bytes());
12173 assert_eq!(typed.finish(), bytewise.finish());
12174 }
12175
12176 #[derive(Clone, Debug)]
12177 struct TestToken {
12178 spec: TokenSpec,
12179 id: TokenId,
12180 source_name: String,
12181 }
12182
12183 impl TestToken {
12184 fn new(token_type: i32) -> Self {
12185 Self {
12186 spec: TokenSpec::explicit(token_type, ""),
12187 id: TokenId::try_from(0).expect("zero token ID"),
12188 source_name: String::new(),
12189 }
12190 }
12191
12192 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
12193 Self {
12194 spec: TokenSpec::eof(index, index, line, column),
12195 id: TokenId::try_from(0).expect("zero token ID"),
12196 source_name: source_name.to_owned(),
12197 }
12198 }
12199
12200 fn with_text(mut self, text: impl Into<String>) -> Self {
12201 self.spec.text = Some(text.into());
12202 self
12203 }
12204
12205 const fn with_channel(mut self, channel: i32) -> Self {
12206 self.spec.channel = channel;
12207 self
12208 }
12209
12210 const fn with_span(mut self, start: usize, stop: usize) -> Self {
12211 self.spec.start = start;
12212 self.spec.stop = stop;
12213 self.spec.start_byte = start;
12214 self.spec.stop_byte = match stop.checked_add(1) {
12215 Some(end) if end >= start => end,
12216 Some(_) | None => start,
12217 };
12218 self
12219 }
12220
12221 const fn with_position(mut self, line: usize, column: usize) -> Self {
12222 self.spec.line = line;
12223 self.spec.column = column;
12224 self
12225 }
12226
12227 fn set_token_index(&mut self, index: isize) {
12228 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
12229 }
12230 }
12231
12232 impl Token for TestToken {
12233 fn token_id(&self) -> TokenId {
12234 self.id
12235 }
12236
12237 fn token_type(&self) -> i32 {
12238 self.spec.token_type
12239 }
12240
12241 fn channel(&self) -> i32 {
12242 self.spec.channel
12243 }
12244
12245 fn start(&self) -> usize {
12246 self.spec.start
12247 }
12248
12249 fn stop(&self) -> usize {
12250 self.spec.stop
12251 }
12252
12253 fn line(&self) -> usize {
12254 self.spec.line
12255 }
12256
12257 fn column(&self) -> usize {
12258 self.spec.column
12259 }
12260
12261 fn text(&self) -> Option<&str> {
12262 self.spec.text.as_deref()
12263 }
12264
12265 fn source_name(&self) -> &str {
12266 &self.source_name
12267 }
12268
12269 fn start_byte(&self) -> usize {
12270 self.spec.start_byte
12271 }
12272
12273 fn stop_byte(&self) -> usize {
12274 self.spec.stop_byte
12275 }
12276 }
12277
12278 #[derive(Debug)]
12279 struct Source {
12280 tokens: Vec<TestToken>,
12281 index: usize,
12282 }
12283
12284 impl TokenSource for Source {
12285 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
12286 let token = self
12287 .tokens
12288 .get(self.index)
12289 .cloned()
12290 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
12291 self.index += 1;
12292 sink.push(token.spec)
12293 }
12294
12295 fn line(&self) -> usize {
12296 1
12297 }
12298
12299 fn column(&self) -> usize {
12300 self.index
12301 }
12302
12303 fn source_name(&self) -> &'static str {
12304 "parser-test"
12305 }
12306 }
12307
12308 #[derive(Clone, Debug, Eq, PartialEq)]
12309 struct RecordedDiagnostic {
12310 grammar_file_name: String,
12311 line: usize,
12312 column: usize,
12313 message: String,
12314 error: Option<AntlrError>,
12315 }
12316
12317 #[derive(Clone, Debug)]
12318 struct RecordingErrorListener {
12319 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
12320 }
12321
12322 impl<R> crate::ErrorListener<R> for RecordingErrorListener
12323 where
12324 R: Recognizer + ?Sized,
12325 {
12326 fn syntax_error(
12327 &mut self,
12328 recognizer: &R,
12329 line: usize,
12330 column: usize,
12331 message: &str,
12332 error: Option<&AntlrError>,
12333 ) {
12334 self.diagnostics
12335 .lock()
12336 .expect("recorded diagnostics lock")
12337 .push(RecordedDiagnostic {
12338 grammar_file_name: recognizer.grammar_file_name().to_owned(),
12339 line,
12340 column,
12341 message: message.to_owned(),
12342 error: error.cloned(),
12343 });
12344 }
12345 }
12346
12347 #[derive(Debug)]
12348 struct ReportingSource {
12349 source: Source,
12350 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
12351 }
12352
12353 impl TokenSource for ReportingSource {
12354 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
12355 self.source.next_token(sink)
12356 }
12357
12358 fn line(&self) -> usize {
12359 self.source.line()
12360 }
12361
12362 fn column(&self) -> usize {
12363 self.source.column()
12364 }
12365
12366 fn source_name(&self) -> &str {
12367 self.source.source_name()
12368 }
12369
12370 fn report_error(&self, error: &TokenSourceError) -> bool {
12371 self.diagnostics.borrow_mut().push(error.clone());
12372 true
12373 }
12374 }
12375
12376 fn mini_parser_data() -> RecognizerData {
12377 RecognizerData::new(
12378 "Mini.g4",
12379 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
12380 )
12381 .with_rule_names(["s"])
12382 }
12383
12384 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
12385 let data = mini_parser_data();
12386 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
12387 }
12388
12389 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
12390 where
12391 H: SemanticHooks,
12392 {
12393 BaseParser::with_semantic_hooks(
12394 CommonTokenStream::new(Source { tokens, index: 0 }),
12395 mini_parser_data(),
12396 hooks,
12397 )
12398 }
12399
12400 #[test]
12401 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
12402 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
12403 parser.remove_error_listeners();
12404 let diagnostics = Arc::new(Mutex::new(Vec::new()));
12405 parser.add_error_listener(RecordingErrorListener {
12406 diagnostics: Arc::clone(&diagnostics),
12407 });
12408 let parser_diagnostics = [ParserDiagnostic {
12409 line: 1,
12410 column: 2,
12411 message: "missing 'x' at 'y'".to_owned(),
12412 }];
12413 let token_errors = [
12414 TokenSourceError::new(1, 1, "token recognition error at: '@'"),
12415 TokenSourceError::new(1, 3, "token recognition error at: '#'"),
12416 ];
12417
12418 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
12419
12420 assert_eq!(
12421 *diagnostics.lock().expect("recorded diagnostics lock"),
12422 [
12423 RecordedDiagnostic {
12424 grammar_file_name: "Mini.g4".to_owned(),
12425 line: 1,
12426 column: 1,
12427 message: "token recognition error at: '@'".to_owned(),
12428 error: None,
12429 },
12430 RecordedDiagnostic {
12431 grammar_file_name: "Mini.g4".to_owned(),
12432 line: 1,
12433 column: 2,
12434 message: "missing 'x' at 'y'".to_owned(),
12435 error: None,
12436 },
12437 RecordedDiagnostic {
12438 grammar_file_name: "Mini.g4".to_owned(),
12439 line: 1,
12440 column: 3,
12441 message: "token recognition error at: '#'".to_owned(),
12442 error: None,
12443 },
12444 ]
12445 );
12446
12447 parser.remove_error_listeners();
12448 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
12449 assert_eq!(
12450 diagnostics.lock().expect("recorded diagnostics lock").len(),
12451 3
12452 );
12453 }
12454
12455 #[test]
12456 fn parser_leaves_token_errors_to_source_owned_listeners() {
12457 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
12458 let source = ReportingSource {
12459 source: Source {
12460 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
12461 index: 0,
12462 },
12463 diagnostics: Rc::clone(&source_diagnostics),
12464 };
12465 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
12466 parser.remove_error_listeners();
12467 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
12468 parser.add_error_listener(RecordingErrorListener {
12469 diagnostics: Arc::clone(&parser_diagnostics),
12470 });
12471 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
12472
12473 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
12474
12475 assert_eq!(*source_diagnostics.borrow(), [source_error]);
12476 assert!(
12477 parser_diagnostics
12478 .lock()
12479 .expect("recorded diagnostics lock")
12480 .is_empty()
12481 );
12482 }
12483
12484 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
12485 builder.finish().expect("valid packed parser ATN")
12486 }
12487
12488 fn nested_rule_chain_atn(depth: usize) -> Atn {
12489 nested_rule_graph_atn(depth, false, false)
12490 }
12491
12492 fn nested_rule_graph_atn(depth: usize, branching: bool, consuming_follows: bool) -> Atn {
12493 assert!(depth > 0);
12494 let mut atn = ParserAtnBuilder::new(2);
12495 let mut starts = Vec::with_capacity(depth);
12496 let mut stops = Vec::with_capacity(depth);
12497 let mut follows = Vec::with_capacity(depth.saturating_sub(1));
12498 for rule_index in 0..depth {
12499 starts.push(
12500 atn.add_state(AtnStateKind::RuleStart, Some(rule_index))
12501 .expect("rule start")
12502 .index(),
12503 );
12504 }
12505 for rule_index in 0..depth {
12506 stops.push(
12507 atn.add_state(AtnStateKind::RuleStop, Some(rule_index))
12508 .expect("rule stop")
12509 .index(),
12510 );
12511 }
12512 if consuming_follows {
12513 for rule_index in 0..depth - 1 {
12514 follows.push(
12515 atn.add_state(AtnStateKind::Basic, Some(rule_index))
12516 .expect("rule follow")
12517 .index(),
12518 );
12519 }
12520 }
12521 atn.set_rule_to_start_state(starts.clone())
12522 .expect("rule start states");
12523 atn.set_rule_to_stop_state(stops.clone())
12524 .expect("rule stop states");
12525 for rule_index in 0..depth - 1 {
12526 let follow_state = if consuming_follows {
12527 follows[rule_index]
12528 } else {
12529 stops[rule_index]
12530 };
12531 atn.add_transition(
12532 starts[rule_index],
12533 ParserTransitionSpec::Rule {
12534 target: starts[rule_index + 1],
12535 rule_index: rule_index + 1,
12536 follow_state,
12537 precedence: 0,
12538 },
12539 )
12540 .expect("nested rule transition");
12541 if branching {
12542 atn.add_transition(
12543 starts[rule_index],
12544 ParserTransitionSpec::Atom {
12545 target: stops[rule_index],
12546 label: 2,
12547 },
12548 )
12549 .expect("dead branch transition");
12550 }
12551 if consuming_follows {
12552 atn.add_transition(
12553 follow_state,
12554 ParserTransitionSpec::Atom {
12555 target: stops[rule_index],
12556 label: 1,
12557 },
12558 )
12559 .expect("consuming follow transition");
12560 }
12561 }
12562 let token_set = atn.add_interval_set([(1, 1)]).expect("token set");
12563 atn.add_transition(
12564 starts[depth - 1],
12565 ParserTransitionSpec::Set {
12566 target: stops[depth - 1],
12567 set: token_set,
12568 },
12569 )
12570 .expect("terminal set transition");
12571 if branching {
12572 atn.add_transition(
12573 starts[depth - 1],
12574 ParserTransitionSpec::Atom {
12575 target: stops[depth - 1],
12576 label: 2,
12577 },
12578 )
12579 .expect("dead leaf branch transition");
12580 }
12581 finish_atn(atn)
12582 }
12583
12584 fn ordinary_star_loop_atn() -> Atn {
12585 let mut atn = ParserAtnBuilder::new(2);
12586 for (state_number, kind, rule_index) in [
12587 (0, AtnStateKind::RuleStart, 0),
12588 (1, AtnStateKind::StarLoopEntry, 0),
12589 (2, AtnStateKind::Basic, 0),
12590 (3, AtnStateKind::StarLoopBack, 0),
12591 (4, AtnStateKind::LoopEnd, 0),
12592 (5, AtnStateKind::Basic, 0),
12593 (6, AtnStateKind::RuleStop, 0),
12594 (7, AtnStateKind::RuleStart, 1),
12595 (8, AtnStateKind::Basic, 1),
12596 (9, AtnStateKind::RuleStop, 1),
12597 ] {
12598 assert_eq!(
12599 atn.add_state(kind, Some(rule_index))
12600 .expect("state")
12601 .index(),
12602 state_number
12603 );
12604 }
12605 atn.set_rule_to_start_state(vec![0, 7])
12606 .expect("rule start states");
12607 atn.set_rule_to_stop_state(vec![6, 9])
12608 .expect("rule stop states");
12609 atn.add_decision_state(1).expect("decision state");
12610 atn.set_loop_back_state(4, 3).expect("loop back state");
12611 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12612 .expect("transition");
12613 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12614 .expect("transition");
12615 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
12616 .expect("transition");
12617 atn.add_transition(
12618 2,
12619 ParserTransitionSpec::Rule {
12620 target: 7,
12621 rule_index: 1,
12622 follow_state: 3,
12623 precedence: 0,
12624 },
12625 )
12626 .expect("transition");
12627 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
12628 .expect("transition");
12629 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12630 .expect("transition");
12631 atn.add_transition(
12632 5,
12633 ParserTransitionSpec::Atom {
12634 target: 6,
12635 label: TOKEN_EOF,
12636 },
12637 )
12638 .expect("transition");
12639 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
12640 .expect("transition");
12641 atn.add_transition(
12642 8,
12643 ParserTransitionSpec::Atom {
12644 target: 9,
12645 label: 1,
12646 },
12647 )
12648 .expect("transition");
12649 finish_atn(atn)
12650 }
12651
12652 fn ambiguous_ordinary_star_loop_atn() -> Atn {
12654 let mut atn = ParserAtnBuilder::new(1);
12655 for (state_number, kind) in [
12656 (0, AtnStateKind::RuleStart),
12657 (1, AtnStateKind::StarLoopEntry),
12658 (2, AtnStateKind::StarBlockStart),
12659 (3, AtnStateKind::Basic),
12660 (4, AtnStateKind::BlockEnd),
12661 (5, AtnStateKind::StarLoopBack),
12662 (6, AtnStateKind::LoopEnd),
12663 (7, AtnStateKind::Basic),
12664 (8, AtnStateKind::RuleStop),
12665 ] {
12666 assert_eq!(
12667 atn.add_state(kind, Some(0)).expect("state").index(),
12668 state_number
12669 );
12670 }
12671 atn.set_rule_to_start_state(vec![0])
12672 .expect("rule start states");
12673 atn.set_rule_to_stop_state(vec![8])
12674 .expect("rule stop states");
12675 atn.set_end_state(2, 4).expect("block end state");
12676 atn.set_loop_back_state(6, 5).expect("loop back state");
12677 atn.add_decision_state(1).expect("decision state");
12678 atn.add_decision_state(2).expect("decision state");
12679 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12680 .expect("transition");
12681 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12682 .expect("transition");
12683 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
12684 .expect("transition");
12685 atn.add_transition(
12686 2,
12687 ParserTransitionSpec::Atom {
12688 target: 4,
12689 label: 1,
12690 },
12691 )
12692 .expect("transition");
12693 atn.add_transition(
12694 2,
12695 ParserTransitionSpec::Atom {
12696 target: 3,
12697 label: 1,
12698 },
12699 )
12700 .expect("transition");
12701 atn.add_transition(
12702 3,
12703 ParserTransitionSpec::Atom {
12704 target: 4,
12705 label: 1,
12706 },
12707 )
12708 .expect("transition");
12709 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12710 .expect("transition");
12711 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
12712 .expect("transition");
12713 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12714 .expect("transition");
12715 atn.add_transition(
12716 7,
12717 ParserTransitionSpec::Atom {
12718 target: 8,
12719 label: TOKEN_EOF,
12720 },
12721 )
12722 .expect("transition");
12723 finish_atn(atn)
12724 }
12725
12726 fn ordinary_plus_loop_atn() -> Atn {
12727 let mut atn = ParserAtnBuilder::new(2);
12728 for (state_number, kind, rule_index) in [
12729 (0, AtnStateKind::RuleStart, 0),
12730 (1, AtnStateKind::Basic, 0),
12731 (2, AtnStateKind::PlusLoopBack, 0),
12732 (3, AtnStateKind::LoopEnd, 0),
12733 (4, AtnStateKind::Basic, 0),
12734 (5, AtnStateKind::RuleStop, 0),
12735 (6, AtnStateKind::RuleStart, 1),
12736 (7, AtnStateKind::Basic, 1),
12737 (8, AtnStateKind::RuleStop, 1),
12738 ] {
12739 assert_eq!(
12740 atn.add_state(kind, Some(rule_index))
12741 .expect("state")
12742 .index(),
12743 state_number
12744 );
12745 }
12746 atn.set_rule_to_start_state(vec![0, 6])
12747 .expect("rule start states");
12748 atn.set_rule_to_stop_state(vec![5, 8])
12749 .expect("rule stop states");
12750 atn.add_decision_state(2).expect("decision state");
12751 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
12752 .expect("transition");
12753 atn.add_transition(
12754 1,
12755 ParserTransitionSpec::Rule {
12756 target: 6,
12757 rule_index: 1,
12758 follow_state: 2,
12759 precedence: 0,
12760 },
12761 )
12762 .expect("transition");
12763 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
12764 .expect("transition");
12765 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12766 .expect("transition");
12767 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
12768 .expect("transition");
12769 atn.add_transition(
12770 4,
12771 ParserTransitionSpec::Atom {
12772 target: 5,
12773 label: TOKEN_EOF,
12774 },
12775 )
12776 .expect("transition");
12777 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
12778 .expect("transition");
12779 atn.add_transition(
12780 7,
12781 ParserTransitionSpec::Atom {
12782 target: 8,
12783 label: 1,
12784 },
12785 )
12786 .expect("transition");
12787 finish_atn(atn)
12788 }
12789
12790 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
12791 let mut tokens = (0..count)
12792 .map(|_| TestToken::new(1).with_text("x"))
12793 .collect::<Vec<_>>();
12794 tokens.push(TestToken::eof("parser-test", count, 1, count));
12795 tokens
12796 }
12797
12798 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
12799 let mut atn = ParserAtnBuilder::new(2);
12800 assert_eq!(
12801 atn.add_state(AtnStateKind::RuleStart, Some(0))
12802 .expect("state")
12803 .index(),
12804 0
12805 );
12806 assert_eq!(
12807 atn.add_state(AtnStateKind::Basic, Some(0))
12808 .expect("state")
12809 .index(),
12810 1
12811 );
12812 assert_eq!(
12813 atn.add_state(AtnStateKind::Basic, Some(0))
12814 .expect("state")
12815 .index(),
12816 2
12817 );
12818 assert_eq!(
12819 atn.add_state(AtnStateKind::RuleStart, Some(1))
12820 .expect("state")
12821 .index(),
12822 3
12823 );
12824 atn.set_left_recursive_rule(3)
12825 .expect("left-recursive rule start");
12826 assert_eq!(
12827 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
12828 .expect("state")
12829 .index(),
12830 4
12831 );
12832 atn.set_precedence_rule_decision(4)
12833 .expect("precedence decision");
12834 assert_eq!(
12835 atn.add_state(AtnStateKind::Basic, Some(1))
12836 .expect("state")
12837 .index(),
12838 5
12839 );
12840 assert_eq!(
12841 atn.add_state(AtnStateKind::Basic, Some(1))
12842 .expect("state")
12843 .index(),
12844 6
12845 );
12846 assert_eq!(
12847 atn.add_state(AtnStateKind::LoopEnd, Some(1))
12848 .expect("state")
12849 .index(),
12850 7
12851 );
12852 assert_eq!(
12853 atn.add_state(AtnStateKind::RuleStop, Some(1))
12854 .expect("state")
12855 .index(),
12856 8
12857 );
12858 assert_eq!(
12859 atn.add_state(AtnStateKind::RuleStop, Some(0))
12860 .expect("state")
12861 .index(),
12862 9
12863 );
12864 atn.set_rule_to_start_state(vec![0, 3])
12865 .expect("rule start states");
12866 atn.set_rule_to_stop_state(vec![9, 8])
12867 .expect("rule stop states");
12868 atn.add_transition(
12869 1,
12870 ParserTransitionSpec::Rule {
12871 target: 3,
12872 rule_index: 1,
12873 follow_state: 2,
12874 precedence: 0,
12875 },
12876 )
12877 .expect("transition");
12878 atn.add_transition(
12879 2,
12880 ParserTransitionSpec::Atom {
12881 target: 9,
12882 label: caller_symbol,
12883 },
12884 )
12885 .expect("transition");
12886 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
12887 .expect("transition");
12888 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
12889 .expect("transition");
12890 atn.add_transition(
12891 5,
12892 ParserTransitionSpec::Precedence {
12893 target: 6,
12894 precedence: 1,
12895 },
12896 )
12897 .expect("transition");
12898 atn.add_transition(
12899 6,
12900 ParserTransitionSpec::Atom {
12901 target: 4,
12902 label: 1,
12903 },
12904 )
12905 .expect("transition");
12906 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
12907 .expect("transition");
12908 finish_atn(atn)
12909 }
12910
12911 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
12912 let mut parser = mini_parser(vec![
12913 TestToken::new(symbol).with_text("lookahead"),
12914 TestToken::eof("parser-test", 1, 1, 1),
12915 ]);
12916 parser.rule_context_stack = vec![
12917 RuleContextFrame {
12918 rule_index: 0,
12919 invoking_state: -1,
12920 },
12921 RuleContextFrame {
12922 rule_index: 1,
12923 invoking_state: 1,
12924 },
12925 ];
12926 parser
12927 }
12928
12929 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
12930 let mut atn = ParserAtnBuilder::new(1);
12934 for (state, kind, rule) in [
12935 (0, AtnStateKind::RuleStart, 0),
12936 (1, AtnStateKind::StarLoopEntry, 0),
12937 (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),
12944 (9, AtnStateKind::RuleStop, 0),
12945 ] {
12946 assert_eq!(
12947 atn.add_state(kind, Some(rule)).expect("state").index(),
12948 state
12949 );
12950 if state == 0 {
12951 atn.set_left_recursive_rule(state)
12952 .expect("left-recursive rule start");
12953 } else if state == 1 {
12954 atn.set_precedence_rule_decision(state)
12955 .expect("precedence decision");
12956 }
12957 }
12958 atn.set_rule_to_start_state(vec![0])
12959 .expect("rule start states");
12960 atn.set_rule_to_stop_state(vec![9])
12961 .expect("rule stop states");
12962 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
12963 .expect("ops");
12964 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
12965 .expect("exit");
12966 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
12967 .expect("to shift");
12968 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
12969 .expect("to rel");
12970 atn.add_transition(
12971 3,
12972 ParserTransitionSpec::Precedence {
12973 target: 4,
12974 precedence: 2,
12975 },
12976 )
12977 .expect("shift prec");
12978 atn.add_transition(
12979 4,
12980 ParserTransitionSpec::Atom {
12981 target: 5,
12982 label: 1,
12983 },
12984 )
12985 .expect("shift first >");
12986 atn.add_transition(
12987 5,
12988 ParserTransitionSpec::Atom {
12989 target: 1,
12990 label: 1,
12991 },
12992 )
12993 .expect("shift second >");
12994 atn.add_transition(
12995 6,
12996 ParserTransitionSpec::Precedence {
12997 target: 7,
12998 precedence: 1,
12999 },
13000 )
13001 .expect("rel prec");
13002 atn.add_transition(
13003 7,
13004 ParserTransitionSpec::Atom {
13005 target: 1,
13006 label: 1,
13007 },
13008 )
13009 .expect("rel >");
13010 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
13011 .expect("loop end");
13012 finish_atn(atn)
13013 }
13014
13015 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
13016 let mut atn = ParserAtnBuilder::new(2);
13017 for (state, kind, rule) in [
13018 (0, AtnStateKind::RuleStart, 0),
13019 (1, AtnStateKind::StarLoopEntry, 0),
13020 (2, AtnStateKind::Basic, 0),
13021 (3, AtnStateKind::Basic, 0),
13022 (4, AtnStateKind::Basic, 0),
13023 (5, AtnStateKind::Basic, 0),
13024 (6, AtnStateKind::Basic, 0),
13025 (7, AtnStateKind::Basic, 0),
13026 (8, AtnStateKind::LoopEnd, 0),
13027 (9, AtnStateKind::RuleStop, 0),
13028 (10, AtnStateKind::RuleStart, 1),
13029 (11, AtnStateKind::Basic, 1),
13030 (12, AtnStateKind::RuleStop, 1),
13031 ] {
13032 assert_eq!(
13033 atn.add_state(kind, Some(rule)).expect("state").index(),
13034 state
13035 );
13036 if state == 0 {
13037 atn.set_left_recursive_rule(state)
13038 .expect("left-recursive rule start");
13039 } else if state == 1 {
13040 atn.set_precedence_rule_decision(state)
13041 .expect("precedence decision");
13042 }
13043 }
13044 atn.set_rule_to_start_state(vec![0, 10])
13045 .expect("rule start states");
13046 atn.set_rule_to_stop_state(vec![9, 12])
13047 .expect("rule stop states");
13048 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13049 .expect("ops");
13050 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
13051 .expect("exit");
13052 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13053 .expect("to shift");
13054 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13055 .expect("to relational");
13056 atn.add_transition(
13057 3,
13058 ParserTransitionSpec::Precedence {
13059 target: 4,
13060 precedence: 2,
13061 },
13062 )
13063 .expect("shift precedence");
13064 atn.add_transition(
13065 4,
13066 ParserTransitionSpec::Rule {
13067 target: 10,
13068 rule_index: 1,
13069 follow_state: 5,
13070 precedence: 0,
13071 },
13072 )
13073 .expect("first shift token helper");
13074 atn.add_transition(
13075 5,
13076 ParserTransitionSpec::Atom {
13077 target: 1,
13078 label: 1,
13079 },
13080 )
13081 .expect("second shift token");
13082 atn.add_transition(
13083 6,
13084 ParserTransitionSpec::Precedence {
13085 target: 7,
13086 precedence: 1,
13087 },
13088 )
13089 .expect("relational precedence");
13090 atn.add_transition(
13091 7,
13092 ParserTransitionSpec::Atom {
13093 target: 1,
13094 label: 1,
13095 },
13096 )
13097 .expect("relational token");
13098 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
13099 .expect("loop end");
13100 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
13101 .expect("helper entry");
13102 atn.add_transition(
13103 11,
13104 ParserTransitionSpec::Atom {
13105 target: 12,
13106 label: 1,
13107 },
13108 )
13109 .expect("first shift token");
13110 finish_atn(atn)
13111 }
13112
13113 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
13114 let mut atn = ParserAtnBuilder::new(1);
13115 for (state, kind) in [
13116 (0, AtnStateKind::RuleStart),
13117 (1, AtnStateKind::StarLoopEntry),
13118 (2, AtnStateKind::Basic),
13119 (3, AtnStateKind::Basic),
13120 (4, AtnStateKind::Basic),
13121 (5, AtnStateKind::Basic),
13122 (6, AtnStateKind::Basic),
13123 (7, AtnStateKind::Basic),
13124 (8, AtnStateKind::Basic),
13125 (9, AtnStateKind::LoopEnd),
13126 (10, AtnStateKind::RuleStop),
13127 ] {
13128 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13129 if state == 0 {
13130 atn.set_left_recursive_rule(state)
13131 .expect("left-recursive rule start");
13132 } else if state == 1 {
13133 atn.set_precedence_rule_decision(state)
13134 .expect("precedence decision");
13135 }
13136 }
13137 atn.set_rule_to_start_state(vec![0])
13138 .expect("rule start states");
13139 atn.set_rule_to_stop_state(vec![10])
13140 .expect("rule stop states");
13141 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13142 .expect("ops");
13143 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
13144 .expect("exit");
13145 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13146 .expect("to multi-token operator");
13147 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13148 .expect("to predicate operator");
13149 atn.add_transition(
13150 3,
13151 ParserTransitionSpec::Precedence {
13152 target: 4,
13153 precedence: 2,
13154 },
13155 )
13156 .expect("multi-token precedence");
13157 atn.add_transition(
13158 4,
13159 ParserTransitionSpec::Atom {
13160 target: 5,
13161 label: 1,
13162 },
13163 )
13164 .expect("multi-token first");
13165 atn.add_transition(
13166 5,
13167 ParserTransitionSpec::Atom {
13168 target: 1,
13169 label: 1,
13170 },
13171 )
13172 .expect("multi-token second");
13173 atn.add_transition(
13174 6,
13175 ParserTransitionSpec::Precedence {
13176 target: 7,
13177 precedence: 2,
13178 },
13179 )
13180 .expect("predicate precedence");
13181 atn.add_transition(
13182 7,
13183 ParserTransitionSpec::Predicate {
13184 target: 8,
13185 rule_index: 0,
13186 pred_index: 0,
13187 context_dependent: false,
13188 },
13189 )
13190 .expect("operator predicate");
13191 atn.add_transition(
13192 8,
13193 ParserTransitionSpec::Atom {
13194 target: 1,
13195 label: 1,
13196 },
13197 )
13198 .expect("predicate single token");
13199 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13200 .expect("loop end");
13201 finish_atn(atn)
13202 }
13203
13204 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
13205 let mut atn = ParserAtnBuilder::new(2);
13206 for (state, kind, rule) in [
13207 (0, AtnStateKind::RuleStart, 0),
13208 (1, AtnStateKind::StarLoopEntry, 0),
13209 (2, AtnStateKind::Basic, 0),
13210 (3, AtnStateKind::Basic, 0),
13211 (4, AtnStateKind::Basic, 0),
13212 (5, AtnStateKind::LoopEnd, 0),
13213 (6, AtnStateKind::RuleStop, 0),
13214 (7, AtnStateKind::RuleStart, 1),
13215 (8, AtnStateKind::RuleStop, 1),
13216 (9, AtnStateKind::Basic, 1),
13217 ] {
13218 assert_eq!(
13219 atn.add_state(kind, Some(rule)).expect("state").index(),
13220 state
13221 );
13222 if state == 0 {
13223 atn.set_left_recursive_rule(state)
13224 .expect("left-recursive rule start");
13225 } else if state == 1 {
13226 atn.set_precedence_rule_decision(state)
13227 .expect("precedence decision");
13228 }
13229 }
13230 atn.set_rule_to_start_state(vec![0, 7])
13231 .expect("rule start states");
13232 atn.set_rule_to_stop_state(vec![6, 8])
13233 .expect("rule stop states");
13234 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13235 .expect("transition");
13236 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
13237 .expect("transition");
13238 atn.add_transition(
13239 2,
13240 ParserTransitionSpec::Precedence {
13241 target: 3,
13242 precedence: 3,
13243 },
13244 )
13245 .expect("transition");
13246 atn.add_transition(
13247 3,
13248 ParserTransitionSpec::Rule {
13249 target: 7,
13250 rule_index: 1,
13251 follow_state: 4,
13252 precedence: 0,
13253 },
13254 )
13255 .expect("transition");
13256 atn.add_transition(
13257 4,
13258 ParserTransitionSpec::Atom {
13259 target: 1,
13260 label: 1,
13261 },
13262 )
13263 .expect("transition");
13264 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13265 .expect("transition");
13266 atn.add_transition(
13267 7,
13268 ParserTransitionSpec::Precedence {
13269 target: 9,
13270 precedence: 1,
13271 },
13272 )
13273 .expect("transition");
13274 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
13275 .expect("transition");
13276 finish_atn(atn)
13277 }
13278
13279 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
13280 let mut atn = ParserAtnBuilder::new(2);
13281 for (state, kind) in [
13282 (0, AtnStateKind::RuleStart),
13283 (1, AtnStateKind::StarLoopEntry),
13284 (2, AtnStateKind::Basic),
13285 (3, AtnStateKind::Basic),
13286 (4, AtnStateKind::Basic),
13287 (5, AtnStateKind::LoopEnd),
13288 (6, AtnStateKind::RuleStop),
13289 ] {
13290 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13291 if state == 0 {
13292 atn.set_left_recursive_rule(state)
13293 .expect("left-recursive rule start");
13294 } else if state == 1 {
13295 atn.set_precedence_rule_decision(state)
13296 .expect("precedence decision");
13297 }
13298 }
13299 atn.set_rule_to_start_state(vec![0])
13300 .expect("rule start states");
13301 atn.set_rule_to_stop_state(vec![6])
13302 .expect("rule stop states");
13303 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13304 .expect("transition");
13305 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
13306 .expect("transition");
13307 atn.add_transition(
13308 2,
13309 ParserTransitionSpec::Precedence {
13310 target: 3,
13311 precedence: 1,
13312 },
13313 )
13314 .expect("transition");
13315 atn.add_transition(
13316 3,
13317 ParserTransitionSpec::Predicate {
13318 target: 4,
13319 rule_index: 0,
13320 pred_index: 0,
13321 context_dependent: false,
13322 },
13323 )
13324 .expect("transition");
13325 atn.add_transition(
13326 4,
13327 ParserTransitionSpec::Atom {
13328 target: 1,
13329 label: 1,
13330 },
13331 )
13332 .expect("transition");
13333 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13334 .expect("transition");
13335 finish_atn(atn)
13336 }
13337
13338 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
13339 let mut atn = ParserAtnBuilder::new(2);
13340 for (state, kind, rule) in [
13341 (0, AtnStateKind::RuleStart, 0),
13342 (1, AtnStateKind::Basic, 0),
13343 (2, AtnStateKind::Basic, 0),
13344 (3, AtnStateKind::Basic, 0),
13345 (4, AtnStateKind::RuleStop, 0),
13346 (5, AtnStateKind::RuleStart, 1),
13347 (6, AtnStateKind::StarLoopEntry, 1),
13348 (7, AtnStateKind::Basic, 1),
13349 (8, AtnStateKind::Basic, 1),
13350 (9, AtnStateKind::LoopEnd, 1),
13351 (10, AtnStateKind::RuleStop, 1),
13352 (11, AtnStateKind::RuleStart, 2),
13353 (12, AtnStateKind::RuleStop, 2),
13354 ] {
13355 assert_eq!(
13356 atn.add_state(kind, Some(rule)).expect("state").index(),
13357 state
13358 );
13359 if state == 5 {
13360 atn.set_left_recursive_rule(state)
13361 .expect("left-recursive rule start");
13362 } else if state == 6 {
13363 atn.set_precedence_rule_decision(state)
13364 .expect("precedence decision");
13365 }
13366 }
13367 atn.set_rule_to_start_state(vec![0, 5, 11])
13368 .expect("rule start states");
13369 atn.set_rule_to_stop_state(vec![4, 10, 12])
13370 .expect("rule stop states");
13371 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13372 .expect("transition");
13373 atn.add_transition(
13374 1,
13375 ParserTransitionSpec::Rule {
13376 target: 5,
13377 rule_index: 1,
13378 follow_state: 2,
13379 precedence: 0,
13380 },
13381 )
13382 .expect("transition");
13383 atn.add_transition(
13384 2,
13385 ParserTransitionSpec::Rule {
13386 target: 11,
13387 rule_index: 2,
13388 follow_state: 3,
13389 precedence: 0,
13390 },
13391 )
13392 .expect("transition");
13393 atn.add_transition(
13394 3,
13395 ParserTransitionSpec::Atom {
13396 target: 4,
13397 label: caller_symbol,
13398 },
13399 )
13400 .expect("transition");
13401 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13402 .expect("transition");
13403 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
13404 .expect("transition");
13405 atn.add_transition(
13406 7,
13407 ParserTransitionSpec::Precedence {
13408 target: 8,
13409 precedence: 1,
13410 },
13411 )
13412 .expect("transition");
13413 atn.add_transition(
13414 8,
13415 ParserTransitionSpec::Atom {
13416 target: 6,
13417 label: 1,
13418 },
13419 )
13420 .expect("transition");
13421 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13422 .expect("transition");
13423 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
13424 .expect("transition");
13425 finish_atn(atn)
13426 }
13427
13428 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
13429 let mut atn = ParserAtnBuilder::new(2);
13430 for (state, kind, rule) in [
13431 (0, AtnStateKind::RuleStart, 0),
13432 (1, AtnStateKind::Basic, 0),
13433 (2, AtnStateKind::Basic, 0),
13434 (3, AtnStateKind::RuleStop, 0),
13435 (4, AtnStateKind::RuleStart, 1),
13436 (5, AtnStateKind::Basic, 1),
13437 (6, AtnStateKind::Basic, 1),
13438 (7, AtnStateKind::RuleStop, 1),
13439 (8, AtnStateKind::RuleStart, 2),
13440 (9, AtnStateKind::StarLoopEntry, 2),
13441 (10, AtnStateKind::Basic, 2),
13442 (11, AtnStateKind::Basic, 2),
13443 (12, AtnStateKind::LoopEnd, 2),
13444 (13, AtnStateKind::RuleStop, 2),
13445 ] {
13446 assert_eq!(
13447 atn.add_state(kind, Some(rule)).expect("state").index(),
13448 state
13449 );
13450 if state == 8 {
13451 atn.set_left_recursive_rule(state)
13452 .expect("left-recursive rule start");
13453 } else if state == 9 {
13454 atn.set_precedence_rule_decision(state)
13455 .expect("precedence decision");
13456 }
13457 }
13458 atn.set_rule_to_start_state(vec![0, 4, 8])
13459 .expect("rule start states");
13460 atn.set_rule_to_stop_state(vec![3, 7, 13])
13461 .expect("rule stop states");
13462 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13463 .expect("transition");
13464 atn.add_transition(
13465 1,
13466 ParserTransitionSpec::Rule {
13467 target: 4,
13468 rule_index: 1,
13469 follow_state: 2,
13470 precedence: 0,
13471 },
13472 )
13473 .expect("transition");
13474 atn.add_transition(
13475 2,
13476 ParserTransitionSpec::Atom {
13477 target: 3,
13478 label: caller_symbol,
13479 },
13480 )
13481 .expect("transition");
13482 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13483 .expect("transition");
13484 atn.add_transition(
13485 5,
13486 ParserTransitionSpec::Rule {
13487 target: 8,
13488 rule_index: 2,
13489 follow_state: 6,
13490 precedence: 0,
13491 },
13492 )
13493 .expect("transition");
13494 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13495 .expect("transition");
13496 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
13497 .expect("transition");
13498 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
13499 .expect("transition");
13500 atn.add_transition(
13501 10,
13502 ParserTransitionSpec::Precedence {
13503 target: 11,
13504 precedence: 1,
13505 },
13506 )
13507 .expect("transition");
13508 atn.add_transition(
13509 11,
13510 ParserTransitionSpec::Atom {
13511 target: 9,
13512 label: 1,
13513 },
13514 )
13515 .expect("transition");
13516 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
13517 .expect("transition");
13518 finish_atn(atn)
13519 }
13520
13521 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
13522 let mut atn = ParserAtnBuilder::new(2);
13523 for (state, kind, rule) in [
13524 (0, AtnStateKind::RuleStart, 0),
13525 (1, AtnStateKind::Basic, 0),
13526 (2, AtnStateKind::Basic, 0),
13527 (3, AtnStateKind::RuleStop, 0),
13528 (4, AtnStateKind::RuleStart, 1),
13529 (5, AtnStateKind::StarLoopEntry, 1),
13530 (6, AtnStateKind::Basic, 1),
13531 (7, AtnStateKind::Basic, 1),
13532 (8, AtnStateKind::Basic, 1),
13533 (9, AtnStateKind::Basic, 1),
13534 (10, AtnStateKind::LoopEnd, 1),
13535 (11, AtnStateKind::RuleStop, 1),
13536 ] {
13537 assert_eq!(
13538 atn.add_state(kind, Some(rule)).expect("state").index(),
13539 state
13540 );
13541 if state == 4 {
13542 atn.set_left_recursive_rule(state)
13543 .expect("left-recursive rule start");
13544 } else if state == 5 {
13545 atn.set_precedence_rule_decision(state)
13546 .expect("precedence decision");
13547 }
13548 }
13549 atn.set_rule_to_start_state(vec![0, 4])
13550 .expect("rule start states");
13551 atn.set_rule_to_stop_state(vec![3, 11])
13552 .expect("rule stop states");
13553 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13554 .expect("transition");
13555 atn.add_transition(
13556 1,
13557 ParserTransitionSpec::Rule {
13558 target: 4,
13559 rule_index: 1,
13560 follow_state: 2,
13561 precedence: 0,
13562 },
13563 )
13564 .expect("transition");
13565 atn.add_transition(
13566 2,
13567 ParserTransitionSpec::Atom {
13568 target: 3,
13569 label: caller_symbol,
13570 },
13571 )
13572 .expect("transition");
13573 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
13574 .expect("transition");
13575 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
13576 .expect("transition");
13577 atn.add_transition(
13578 6,
13579 ParserTransitionSpec::Precedence {
13580 target: 7,
13581 precedence: 1,
13582 },
13583 )
13584 .expect("transition");
13585 atn.add_transition(
13586 7,
13587 ParserTransitionSpec::Atom {
13588 target: 8,
13589 label: 1,
13590 },
13591 )
13592 .expect("transition");
13593 atn.add_transition(
13594 8,
13595 ParserTransitionSpec::Rule {
13596 target: 4,
13597 rule_index: 1,
13598 follow_state: 9,
13599 precedence: 2,
13600 },
13601 )
13602 .expect("transition");
13603 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
13604 .expect("transition");
13605 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
13606 .expect("transition");
13607 finish_atn(atn)
13608 }
13609
13610 #[test]
13611 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
13612 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
13613 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
13614
13615 let mut overlapping = parser_inside_left_recursive_callee(1);
13616 assert_eq!(
13617 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
13618 None
13619 );
13620
13621 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
13622 assert_eq!(
13623 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13624 Some(true)
13625 );
13626
13627 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
13628 assert_eq!(
13629 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13630 Some(false)
13631 );
13632
13633 assert_eq!(
13634 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
13635 Some(true),
13636 "overlap results must not leak across ATNs"
13637 );
13638 }
13639
13640 #[test]
13641 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
13642 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
13643 let mut parser = mini_parser(vec![
13644 TestToken::new(1).with_text("operator"),
13645 TestToken::eof("parser-test", 1, 1, 1),
13646 ]);
13647 parser.rule_context_stack = vec![RuleContextFrame {
13648 rule_index: 0,
13649 invoking_state: -1,
13650 }];
13651
13652 assert_eq!(
13653 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13654 Some(true)
13655 );
13656 assert_eq!(
13657 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13658 Some(true),
13659 "cached operator lookahead must preserve the nullable prefix return path"
13660 );
13661 assert_eq!(
13662 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13663 Some(true),
13664 "the nullable child must use its rule-call precedence, not the caller precedence"
13665 );
13666 }
13667
13668 #[test]
13669 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
13670 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
13675 let mut parser = mini_parser(vec![
13676 TestToken::new(1).with_text(">"),
13677 TestToken::new(2).with_text("id"),
13678 TestToken::eof("parser-test", 1, 1, 1),
13679 ]);
13680 parser.rule_context_stack = vec![RuleContextFrame {
13681 rule_index: 0,
13682 invoking_state: -1,
13683 }];
13684
13685 assert_eq!(
13686 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13687 Some(true),
13688 "at low precedence relational `>` is a single-token operator"
13689 );
13690 assert_eq!(
13691 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
13692 Some(true),
13693 "relational remains single-token at its own precedence"
13694 );
13695 assert_eq!(
13696 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13697 None,
13698 "at shift precedence, bare `>` must not force enter"
13699 );
13700 }
13701
13702 #[test]
13703 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
13704 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
13705 let mut parser = mini_parser(vec![
13706 TestToken::new(1).with_text(">"),
13707 TestToken::new(2).with_text("id"),
13708 TestToken::eof("parser-test", 1, 1, 1),
13709 ]);
13710 parser.rule_context_stack = vec![RuleContextFrame {
13711 rule_index: 0,
13712 invoking_state: -1,
13713 }];
13714
13715 assert_eq!(
13716 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13717 Some(true),
13718 "the direct relational alternative remains a one-token operator"
13719 );
13720 assert_eq!(
13721 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13722 None,
13723 "a token matched in the helper rule must return to the second shift token"
13724 );
13725 }
13726
13727 #[test]
13728 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
13729 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
13730 let mut parser = mini_parser(vec![
13731 TestToken::new(1).with_text(">"),
13732 TestToken::new(2).with_text("id"),
13733 TestToken::eof("parser-test", 1, 1, 1),
13734 ]);
13735 parser.rule_context_stack = vec![RuleContextFrame {
13736 rule_index: 0,
13737 invoking_state: -1,
13738 }];
13739
13740 assert_eq!(
13741 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
13742 None,
13743 "a predicate-gated single-token path must not be hidden by a multi-token path"
13744 );
13745 }
13746
13747 #[test]
13748 fn left_recursive_loop_defers_predicate_guarded_operator() {
13749 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
13750 let mut parser = mini_parser_with_hooks(
13751 vec![
13752 TestToken::new(1).with_text("operator"),
13753 TestToken::eof("parser-test", 1, 1, 1),
13754 ],
13755 RejectingPredicateHooks::default(),
13756 );
13757 parser.rule_context_stack = vec![RuleContextFrame {
13758 rule_index: 0,
13759 invoking_state: -1,
13760 }];
13761
13762 assert_eq!(
13763 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13764 None,
13765 "a false predicate must be evaluated before entering the operator alternative"
13766 );
13767 assert_eq!(
13768 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
13769 None,
13770 "cached predicate-dependent lookahead must keep deferring"
13771 );
13772 }
13773
13774 #[test]
13775 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
13776 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
13777 let mut parser = parser_inside_left_recursive_callee(1);
13778
13779 assert_eq!(
13780 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
13781 None
13782 );
13783 assert_eq!(
13784 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
13785 None,
13786 "the cached overlap must preserve the nullable child return path"
13787 );
13788 }
13789
13790 #[test]
13791 fn left_recursive_loop_defers_through_nullable_parent_return() {
13792 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
13793 let mut parser = mini_parser(vec![
13794 TestToken::new(1).with_text("lookahead"),
13795 TestToken::eof("parser-test", 1, 1, 1),
13796 ]);
13797 parser.rule_context_stack = vec![
13798 RuleContextFrame {
13799 rule_index: 0,
13800 invoking_state: -1,
13801 },
13802 RuleContextFrame {
13803 rule_index: 1,
13804 invoking_state: 1,
13805 },
13806 RuleContextFrame {
13807 rule_index: 2,
13808 invoking_state: 5,
13809 },
13810 ];
13811
13812 assert_eq!(
13813 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
13814 None,
13815 "a nullable caller must unwind to its parent's consuming follow path"
13816 );
13817 assert_eq!(
13818 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
13819 None,
13820 "the caller-overlap cache must not retain a false negative"
13821 );
13822 }
13823
13824 #[test]
13825 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
13826 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
13827 let mut parser = mini_parser(vec![
13828 TestToken::new(1).with_text("lookahead"),
13829 TestToken::eof("parser-test", 1, 1, 1),
13830 ]);
13831 parser.rule_context_stack = vec![
13832 RuleContextFrame {
13833 rule_index: 0,
13834 invoking_state: -1,
13835 },
13836 RuleContextFrame {
13837 rule_index: 1,
13838 invoking_state: 1,
13839 },
13840 RuleContextFrame {
13841 rule_index: 1,
13842 invoking_state: 8,
13843 },
13844 ];
13845
13846 assert_eq!(
13847 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
13848 None,
13849 "a recursive operand return must preserve its parent caller context"
13850 );
13851 assert_eq!(
13852 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
13853 None,
13854 "the caller-overlap cache must preserve the loop-boundary return"
13855 );
13856 }
13857
13858 fn token_then_eof_atn() -> Atn {
13859 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13860 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, ]))
13876 .deserialize_parser()
13877 .expect("artificial parser ATN should deserialize")
13878 }
13879
13880 fn epsilon_cycle_atn() -> Atn {
13881 let mut atn = ParserAtnBuilder::new(1);
13882 for (state_number, kind) in [
13883 (0, AtnStateKind::RuleStart),
13884 (1, AtnStateKind::Basic),
13885 (2, AtnStateKind::RuleStop),
13886 ] {
13887 assert_eq!(
13888 atn.add_state(kind, Some(0)).expect("state").index(),
13889 state_number
13890 );
13891 }
13892 atn.set_rule_to_start_state(vec![0])
13893 .expect("rule start states");
13894 atn.set_rule_to_stop_state(vec![2])
13895 .expect("rule stop states");
13896 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13897 .expect("transition");
13898 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
13899 .expect("self-cycle transition");
13900 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13901 .expect("exit transition");
13902 finish_atn(atn)
13903 }
13904
13905 fn eof_then_action_atn() -> Atn {
13906 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13907 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, ]))
13923 .deserialize_parser()
13924 .expect("artificial parser ATN should deserialize")
13925 }
13926
13927 fn noop_action_then_token_then_eof_atn() -> Atn {
13928 AtnDeserializer::new(&SerializedAtn::from_i32(&[
13929 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, ]))
13947 .deserialize_parser()
13948 .expect("artificial no-op action ATN should deserialize")
13949 }
13950
13951 fn two_alt_decision_atn() -> Atn {
13952 let mut atn = ParserAtnBuilder::new(2);
13953 assert_eq!(
13954 atn.add_state(AtnStateKind::RuleStart, Some(0))
13955 .expect("state")
13956 .index(),
13957 0
13958 );
13959 assert_eq!(
13960 atn.add_state(AtnStateKind::BlockStart, Some(0))
13961 .expect("state")
13962 .index(),
13963 1
13964 );
13965 assert_eq!(
13966 atn.add_state(AtnStateKind::Basic, Some(0))
13967 .expect("state")
13968 .index(),
13969 2
13970 );
13971 assert_eq!(
13972 atn.add_state(AtnStateKind::Basic, Some(0))
13973 .expect("state")
13974 .index(),
13975 3
13976 );
13977 assert_eq!(
13978 atn.add_state(AtnStateKind::BlockEnd, Some(0))
13979 .expect("state")
13980 .index(),
13981 4
13982 );
13983 assert_eq!(
13984 atn.add_state(AtnStateKind::RuleStop, Some(0))
13985 .expect("state")
13986 .index(),
13987 5
13988 );
13989 atn.set_rule_to_start_state(vec![0])
13990 .expect("rule start states");
13991 atn.set_rule_to_stop_state(vec![5])
13992 .expect("rule stop states");
13993 atn.add_decision_state(1).expect("decision state");
13994 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13995 .expect("transition");
13996 atn.add_transition(
13997 1,
13998 ParserTransitionSpec::Atom {
13999 target: 2,
14000 label: 1,
14001 },
14002 )
14003 .expect("transition");
14004 atn.add_transition(
14005 1,
14006 ParserTransitionSpec::Atom {
14007 target: 3,
14008 label: 2,
14009 },
14010 )
14011 .expect("transition");
14012 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
14013 .expect("transition");
14014 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14015 .expect("transition");
14016 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14017 .expect("transition");
14018 finish_atn(atn)
14019 }
14020
14021 fn optional_then_b_eof_atn() -> Atn {
14024 let mut atn = ParserAtnBuilder::new(3);
14025 assert_eq!(
14026 atn.add_state(AtnStateKind::RuleStart, Some(0))
14027 .expect("state")
14028 .index(),
14029 0
14030 );
14031 assert_eq!(
14032 atn.add_state(AtnStateKind::BlockStart, Some(0))
14033 .expect("state")
14034 .index(),
14035 1
14036 );
14037 assert_eq!(
14038 atn.add_state(AtnStateKind::Basic, Some(0))
14039 .expect("state")
14040 .index(),
14041 2
14042 );
14043 assert_eq!(
14044 atn.add_state(AtnStateKind::Basic, Some(0))
14045 .expect("state")
14046 .index(),
14047 3
14048 );
14049 assert_eq!(
14050 atn.add_state(AtnStateKind::Basic, Some(0))
14051 .expect("state")
14052 .index(),
14053 4
14054 );
14055 assert_eq!(
14056 atn.add_state(AtnStateKind::RuleStop, Some(0))
14057 .expect("state")
14058 .index(),
14059 5
14060 );
14061 atn.set_rule_to_start_state(vec![0])
14062 .expect("rule start states");
14063 atn.set_rule_to_stop_state(vec![5])
14064 .expect("rule stop states");
14065 atn.add_decision_state(1).expect("decision state");
14066 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14067 .expect("transition");
14068 atn.add_transition(
14070 1,
14071 ParserTransitionSpec::Atom {
14072 target: 3,
14073 label: 1,
14074 },
14075 )
14076 .expect("transition");
14077 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
14078 .expect("transition");
14079 atn.add_transition(
14081 3,
14082 ParserTransitionSpec::Atom {
14083 target: 4,
14084 label: 2,
14085 },
14086 )
14087 .expect("transition");
14088 atn.add_transition(
14089 4,
14090 ParserTransitionSpec::Atom {
14091 target: 5,
14092 label: TOKEN_EOF,
14093 },
14094 )
14095 .expect("transition");
14096 finish_atn(atn)
14097 }
14098
14099 #[test]
14100 fn sync_decision_deletes_only_a_single_token() {
14101 let atn = optional_then_b_eof_atn();
14109
14110 let mut single = mini_parser(vec![
14111 TestToken::new(3).with_text("c"),
14112 TestToken::new(2).with_text("b"),
14113 TestToken::eof("parser-test", 1, 2, 2),
14114 ]);
14115 single.rule_context_stack = vec![RuleContextFrame {
14116 rule_index: 0,
14117 invoking_state: 0,
14118 }];
14119 let children = single
14120 .sync_decision(&atn, 1, true, false)
14121 .expect("single extraneous token recovers");
14122 assert_eq!(children.len(), 1);
14123 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
14124 assert_eq!(single.number_of_syntax_errors(), 1);
14125 assert_eq!(single.la(1), 2);
14127
14128 let mut double = mini_parser(vec![
14129 TestToken::new(3).with_text("c"),
14130 TestToken::new(3).with_text("c"),
14131 TestToken::new(2).with_text("b"),
14132 TestToken::eof("parser-test", 1, 3, 3),
14133 ]);
14134 double.rule_context_stack = vec![RuleContextFrame {
14135 rule_index: 0,
14136 invoking_state: 0,
14137 }];
14138 let result = double.sync_decision(&atn, 1, true, false);
14139 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
14144 match error {
14145 AntlrError::ParserError { message, .. } => {
14146 assert!(message.starts_with("mismatched input"), "got: {message}");
14147 }
14148 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
14149 }
14150 assert_eq!(double.la(1), 3);
14151 }
14152
14153 fn star_loop_then_eof_atn() -> Atn {
14157 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14158 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,
14159 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,
14160 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,
14161 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
14162 ]))
14163 .deserialize_parser()
14164 .expect("star-loop-then-EOF ATN should deserialize")
14165 }
14166
14167 fn plus_loop_with_recovering_body_atn() -> Atn {
14173 let mut atn = ParserAtnBuilder::new(2);
14174 assert_eq!(
14175 atn.add_state(AtnStateKind::RuleStart, Some(0))
14176 .expect("state")
14177 .index(),
14178 0
14179 );
14180 assert_eq!(
14181 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
14182 .expect("state")
14183 .index(),
14184 1
14185 );
14186 assert_eq!(
14187 atn.add_state(AtnStateKind::Basic, Some(0))
14188 .expect("state")
14189 .index(),
14190 2
14191 );
14192 assert_eq!(
14193 atn.add_state(AtnStateKind::BlockEnd, Some(0))
14194 .expect("state")
14195 .index(),
14196 3
14197 );
14198 assert_eq!(
14199 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
14200 .expect("state")
14201 .index(),
14202 4
14203 );
14204 assert_eq!(
14205 atn.add_state(AtnStateKind::LoopEnd, Some(0))
14206 .expect("state")
14207 .index(),
14208 5
14209 );
14210 assert_eq!(
14211 atn.add_state(AtnStateKind::RuleStop, Some(0))
14212 .expect("state")
14213 .index(),
14214 6
14215 );
14216 assert_eq!(
14217 atn.add_state(AtnStateKind::RuleStart, Some(1))
14218 .expect("state")
14219 .index(),
14220 7
14221 );
14222 assert_eq!(
14223 atn.add_state(AtnStateKind::Basic, Some(1))
14224 .expect("state")
14225 .index(),
14226 8
14227 );
14228 assert_eq!(
14229 atn.add_state(AtnStateKind::RuleStop, Some(1))
14230 .expect("state")
14231 .index(),
14232 9
14233 );
14234 atn.set_rule_to_start_state(vec![0, 7])
14235 .expect("rule start states");
14236 atn.set_rule_to_stop_state(vec![6, 9])
14237 .expect("rule stop states");
14238 atn.set_end_state(1, 3).expect("block end state");
14239 atn.set_loop_back_state(5, 4).expect("loop back state");
14240 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14241 .expect("transition");
14242 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14243 .expect("transition");
14244 atn.add_transition(
14245 2,
14246 ParserTransitionSpec::Rule {
14247 target: 7,
14248 rule_index: 1,
14249 follow_state: 3,
14250 precedence: 0,
14251 },
14252 )
14253 .expect("transition");
14254 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14255 .expect("transition");
14256 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
14257 .expect("transition");
14258 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14259 .expect("transition");
14260 atn.add_transition(
14261 5,
14262 ParserTransitionSpec::Atom {
14263 target: 6,
14264 label: 2,
14265 },
14266 )
14267 .expect("transition");
14268 atn.add_transition(
14269 7,
14270 ParserTransitionSpec::Atom {
14271 target: 8,
14272 label: 1,
14273 },
14274 )
14275 .expect("transition");
14276 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14277 .expect("transition");
14278 finish_atn(atn)
14279 }
14280
14281 #[test]
14282 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
14283 let atn = plus_loop_with_recovering_body_atn();
14284 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14285
14286 let error = parser
14287 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
14288 .expect_err("EOF recovery should report a bounded mismatch");
14289
14290 let AntlrError::ParserError { message, .. } = error else {
14291 panic!("expected ParserError, got {error:?}");
14292 };
14293 assert_eq!(message, "mismatched input '<EOF>' expecting {'x', 2}");
14294 assert_eq!(parser.number_of_syntax_errors(), 1);
14295 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
14296 }
14297
14298 #[test]
14299 fn sync_decision_deletes_token_before_eof_at_loop_back() {
14300 let atn = star_loop_then_eof_atn();
14306 let mut parser = mini_parser(vec![
14307 TestToken::new(2).with_text("c"),
14308 TestToken::eof("parser-test", 1, 1, 1),
14309 ]);
14310 parser.rule_context_stack = vec![RuleContextFrame {
14311 rule_index: 0,
14312 invoking_state: 0,
14313 }];
14314 let children = parser
14315 .sync_decision(&atn, 5, true, false)
14316 .expect("single token before EOF recovers");
14317 assert_eq!(children.len(), 1);
14318 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
14319 assert_eq!(parser.number_of_syntax_errors(), 1);
14320 assert_eq!(
14321 parser.la(1),
14322 TOKEN_EOF,
14323 "EOF is left for the rule's EOF match"
14324 );
14325 }
14326
14327 #[test]
14328 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
14329 let atn = star_loop_then_eof_atn();
14334 let mut parser = mini_parser(vec![
14335 TestToken::new(2).with_text("c"),
14336 TestToken::new(2).with_text("c"),
14337 TestToken::eof("parser-test", 1, 2, 2),
14338 ]);
14339 parser.rule_context_stack = vec![RuleContextFrame {
14340 rule_index: 0,
14341 invoking_state: 0,
14342 }];
14343 let error = parser
14344 .sync_decision(&atn, 5, true, false)
14345 .expect_err("two tokens at the loop entry must not be deleted");
14346 match error {
14347 AntlrError::ParserError { message, .. } => {
14348 assert!(message.starts_with("mismatched input"), "got: {message}");
14349 }
14350 other => panic!("expected mismatched-input ParserError, got {other:?}"),
14351 }
14352 assert_eq!(
14353 parser.la(1),
14354 2,
14355 "nothing consumed; cursor still on first `c`"
14356 );
14357 }
14358
14359 #[test]
14360 fn sync_decision_consumes_until_eof_at_loop_back() {
14361 let atn = star_loop_then_eof_atn();
14367 let mut parser = mini_parser(vec![
14368 TestToken::new(2).with_text("c"),
14369 TestToken::new(2).with_text("c"),
14370 TestToken::eof("parser-test", 1, 2, 2),
14371 ]);
14372 parser.rule_context_stack = vec![RuleContextFrame {
14373 rule_index: 0,
14374 invoking_state: 0,
14375 }];
14376 let children = parser
14377 .sync_decision(&atn, 5, false, true)
14378 .expect("loop-back multi-token deletion recovers onto EOF");
14379 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
14380 assert!(
14381 children
14382 .iter()
14383 .all(|child| parser.node(*child).kind() == NodeKind::Error)
14384 );
14385 assert_eq!(parser.number_of_syntax_errors(), 1);
14386 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
14387 }
14388
14389 fn predicate_after_token_atn() -> Atn {
14390 let mut atn = ParserAtnBuilder::new(2);
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::Basic, 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::RuleStop, Some(0))
14417 .expect("state")
14418 .index(),
14419 4
14420 );
14421 atn.set_rule_to_start_state(vec![0])
14422 .expect("rule start states");
14423 atn.set_rule_to_stop_state(vec![4])
14424 .expect("rule stop states");
14425 atn.add_transition(
14426 0,
14427 ParserTransitionSpec::Atom {
14428 target: 1,
14429 label: 1,
14430 },
14431 )
14432 .expect("transition");
14433 atn.add_transition(
14434 1,
14435 ParserTransitionSpec::Predicate {
14436 target: 2,
14437 rule_index: 0,
14438 pred_index: 0,
14439 context_dependent: false,
14440 },
14441 )
14442 .expect("transition");
14443 atn.add_transition(
14444 2,
14445 ParserTransitionSpec::Atom {
14446 target: 3,
14447 label: 2,
14448 },
14449 )
14450 .expect("transition");
14451 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14452 .expect("transition");
14453 finish_atn(atn)
14454 }
14455
14456 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
14457 let mut atn = ParserAtnBuilder::new(1);
14458 for (state_number, kind) in [
14459 (0, AtnStateKind::RuleStart),
14460 (1, AtnStateKind::BlockStart),
14461 (2, AtnStateKind::Basic),
14462 (3, AtnStateKind::Basic),
14463 (4, AtnStateKind::Basic),
14464 (5, AtnStateKind::Basic),
14465 (6, AtnStateKind::BlockEnd),
14466 (7, AtnStateKind::RuleStop),
14467 ] {
14468 assert_eq!(
14469 atn.add_state(kind, Some(0)).expect("state").index(),
14470 state_number
14471 );
14472 }
14473 atn.set_rule_to_start_state(vec![0])
14474 .expect("rule start states");
14475 atn.set_rule_to_stop_state(vec![7])
14476 .expect("rule stop states");
14477 atn.add_decision_state(1).expect("decision state");
14478 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14479 .expect("transition");
14480 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14481 .expect("transition");
14482 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
14483 .expect("transition");
14484 atn.add_transition(
14485 2,
14486 ParserTransitionSpec::Predicate {
14487 target: 4,
14488 rule_index: 0,
14489 pred_index: pred_indexes[0],
14490 context_dependent: false,
14491 },
14492 )
14493 .expect("transition");
14494 atn.add_transition(
14495 3,
14496 ParserTransitionSpec::Predicate {
14497 target: 5,
14498 rule_index: 0,
14499 pred_index: pred_indexes[1],
14500 context_dependent: false,
14501 },
14502 )
14503 .expect("transition");
14504 atn.add_transition(
14505 4,
14506 ParserTransitionSpec::Atom {
14507 target: 6,
14508 label: 1,
14509 },
14510 )
14511 .expect("transition");
14512 atn.add_transition(
14513 5,
14514 ParserTransitionSpec::Atom {
14515 target: 6,
14516 label: 1,
14517 },
14518 )
14519 .expect("transition");
14520 atn.add_transition(
14521 6,
14522 ParserTransitionSpec::Atom {
14523 target: 7,
14524 label: TOKEN_EOF,
14525 },
14526 )
14527 .expect("transition");
14528 finish_atn(atn)
14529 }
14530
14531 fn nested_nullable_context_atn() -> Atn {
14532 let mut atn = ParserAtnBuilder::new(1);
14533 for state_number in 0..=20 {
14534 let kind = match state_number {
14535 0 | 10 | 16 => AtnStateKind::RuleStart,
14536 9 | 15 | 20 => AtnStateKind::RuleStop,
14537 _ => AtnStateKind::Basic,
14538 };
14539 let rule_index = match state_number {
14540 0..=9 => 0,
14541 10..=15 => 1,
14542 _ => 2,
14543 };
14544 assert_eq!(
14545 atn.add_state(kind, Some(rule_index))
14546 .expect("state")
14547 .index(),
14548 state_number
14549 );
14550 }
14551 atn.set_rule_to_start_state(vec![0, 10, 16])
14552 .expect("rule start states");
14553 atn.set_rule_to_stop_state(vec![9, 15, 20])
14554 .expect("rule stop states");
14555 atn.add_transition(
14556 1,
14557 ParserTransitionSpec::Rule {
14558 target: 10,
14559 rule_index: 1,
14560 follow_state: 8,
14561 precedence: 0,
14562 },
14563 )
14564 .expect("transition");
14565 atn.add_transition(
14566 8,
14567 ParserTransitionSpec::Atom {
14568 target: 9,
14569 label: 1,
14570 },
14571 )
14572 .expect("transition");
14573 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14574 .expect("transition");
14575 atn.add_transition(
14576 2,
14577 ParserTransitionSpec::Rule {
14578 target: 16,
14579 rule_index: 2,
14580 follow_state: 14,
14581 precedence: 0,
14582 },
14583 )
14584 .expect("transition");
14585 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
14586 .expect("transition");
14587 finish_atn(atn)
14588 }
14589
14590 fn generated_match_recovery_atn() -> Atn {
14591 let mut atn = ParserAtnBuilder::new(2);
14592 assert_eq!(
14593 atn.add_state(AtnStateKind::RuleStart, Some(0))
14594 .expect("state")
14595 .index(),
14596 0
14597 );
14598 assert_eq!(
14599 atn.add_state(AtnStateKind::Basic, Some(0))
14600 .expect("state")
14601 .index(),
14602 1
14603 );
14604 assert_eq!(
14605 atn.add_state(AtnStateKind::Basic, Some(0))
14606 .expect("state")
14607 .index(),
14608 2
14609 );
14610 assert_eq!(
14611 atn.add_state(AtnStateKind::RuleStop, Some(0))
14612 .expect("state")
14613 .index(),
14614 3
14615 );
14616 assert_eq!(
14617 atn.add_state(AtnStateKind::RuleStart, Some(1))
14618 .expect("state")
14619 .index(),
14620 4
14621 );
14622 assert_eq!(
14623 atn.add_state(AtnStateKind::RuleStop, Some(1))
14624 .expect("state")
14625 .index(),
14626 5
14627 );
14628 atn.set_rule_to_start_state(vec![0, 4])
14629 .expect("rule start states");
14630 atn.set_rule_to_stop_state(vec![3, 5])
14631 .expect("rule stop states");
14632 atn.add_transition(
14633 1,
14634 ParserTransitionSpec::Rule {
14635 target: 4,
14636 rule_index: 1,
14637 follow_state: 2,
14638 precedence: 0,
14639 },
14640 )
14641 .expect("transition");
14642 atn.add_transition(
14643 2,
14644 ParserTransitionSpec::Atom {
14645 target: 3,
14646 label: TOKEN_EOF,
14647 },
14648 )
14649 .expect("transition");
14650 finish_atn(atn)
14651 }
14652
14653 fn complement_set_atn() -> Atn {
14654 let mut atn = ParserAtnBuilder::new(1);
14655 assert_eq!(
14656 atn.add_state(AtnStateKind::RuleStart, Some(0))
14657 .expect("state")
14658 .index(),
14659 0
14660 );
14661 assert_eq!(
14662 atn.add_state(AtnStateKind::RuleStop, Some(0))
14663 .expect("state")
14664 .index(),
14665 1
14666 );
14667 atn.set_rule_to_start_state(vec![0])
14668 .expect("rule start states");
14669 atn.set_rule_to_stop_state(vec![1])
14670 .expect("rule stop states");
14671 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
14672 atn.add_transition(
14673 0,
14674 ParserTransitionSpec::NotSet {
14675 target: 1,
14676 set: excluded,
14677 },
14678 )
14679 .expect("transition");
14680 finish_atn(atn)
14681 }
14682
14683 fn wildcard_then_eof_atn() -> Atn {
14686 let mut atn = ParserAtnBuilder::new(1);
14687 assert_eq!(
14688 atn.add_state(AtnStateKind::RuleStart, Some(0))
14689 .expect("state")
14690 .index(),
14691 0
14692 );
14693 assert_eq!(
14694 atn.add_state(AtnStateKind::RuleStop, Some(0))
14695 .expect("state")
14696 .index(),
14697 1
14698 );
14699 assert_eq!(
14700 atn.add_state(AtnStateKind::Basic, Some(0))
14701 .expect("state")
14702 .index(),
14703 2
14704 );
14705 atn.set_rule_to_start_state(vec![0])
14706 .expect("rule start states");
14707 atn.set_rule_to_stop_state(vec![1])
14708 .expect("rule stop states");
14709 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
14710 .expect("transition");
14711 atn.add_transition(
14712 2,
14713 ParserTransitionSpec::Atom {
14714 target: 1,
14715 label: TOKEN_EOF,
14716 },
14717 )
14718 .expect("transition");
14719 finish_atn(atn)
14720 }
14721
14722 #[test]
14723 fn parser_matches_token_and_reports_mismatch() {
14724 let source = Source {
14725 tokens: vec![
14726 TestToken::new(1).with_text("x"),
14727 TestToken::eof("parser-test", 1, 1, 1),
14728 ],
14729 index: 0,
14730 };
14731 let data = RecognizerData::new(
14732 "Mini.g4",
14733 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
14734 );
14735 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
14736 let matched = parser.match_token(1).expect("token 1 should match");
14737 assert_eq!(parser.node(matched).text(), "x");
14738 assert!(parser.match_token(1).is_err());
14739 }
14740
14741 #[test]
14742 fn parser_matches_token_sets() {
14743 let mut parser = mini_parser(vec![
14744 TestToken::new(1).with_text("x"),
14745 TestToken::eof("parser-test", 1, 1, 1),
14746 ]);
14747
14748 let matched = parser
14749 .match_set(&[(1, 1), (3, 4)])
14750 .expect("token set should match");
14751 assert_eq!(parser.node(matched).text(), "x");
14752 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
14753 }
14754
14755 #[test]
14756 fn generated_rule_api_tracks_state_and_precedence() {
14757 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14758
14759 let context = parser.enter_rule(7, 2);
14760 assert_eq!(context.rule_index(), 2);
14761 assert_eq!(parser.state(), 7);
14762 assert_eq!(
14763 parser.rule_context_stack,
14764 vec![RuleContextFrame {
14765 rule_index: 2,
14766 invoking_state: 7
14767 }]
14768 );
14769
14770 let recursive = parser.enter_recursion_rule(11, 3, 4);
14771 assert_eq!(recursive.rule_index(), 3);
14772 assert!(parser.precpred(4));
14773 assert!(parser.precpred(5));
14774 assert!(!parser.precpred(3));
14775
14776 let next = parser.push_new_recursion_context(13, 3);
14777 assert_eq!(next.invoking_state(), 13);
14778 parser.unroll_recursion_context();
14779 assert_eq!(parser.precedence_stack, vec![0]);
14780 assert_eq!(
14781 parser.rule_context_stack,
14782 vec![RuleContextFrame {
14783 rule_index: 2,
14784 invoking_state: 7
14785 }]
14786 );
14787
14788 parser.exit_rule();
14789 assert!(parser.rule_context_stack.is_empty());
14790 }
14791
14792 #[test]
14793 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
14794 let mut parser = mini_parser(vec![
14795 TestToken::new(1).with_text("x"),
14796 TestToken::eof("parser-test", 1, 1, 1),
14797 ]);
14798 let matched = parser.match_token(1).expect("token should match");
14799 assert_eq!(parser.node(matched).text(), "x");
14800 parser.record_generated_syntax_error();
14801 parser.set_int_member(7, 11);
14802 parser.set_build_parse_trees(false);
14803 parser.set_report_diagnostic_errors(true);
14804 parser.set_prediction_mode(PredictionMode::Sll);
14805 parser.set_bail_on_error(true);
14806 let _context = parser.enter_recursion_rule(9, 0, 4);
14807 parser.pending_invoking_states.push(5);
14808 parser.unknown_predicate_hits.push((0, 1));
14809 parser.unhandled_action_hits.push((0, 2));
14810
14811 parser.reset();
14812
14813 assert_eq!(parser.input.index(), 0);
14814 assert_eq!(parser.la(1), 1);
14815 assert_eq!(parser.state(), -1);
14816 assert_eq!(parser.number_of_syntax_errors(), 0);
14817 assert_eq!(parser.parse_tree_storage().node_count(), 0);
14818 assert!(parser.rule_context_stack.is_empty());
14819 assert!(parser.pending_invoking_states.is_empty());
14820 assert_eq!(parser.precedence_stack, [0]);
14821 assert!(parser.unknown_predicate_hits.is_empty());
14822 assert!(parser.unhandled_action_hits.is_empty());
14823 assert_eq!(parser.int_member(7), Some(11));
14824 assert!(!parser.build_parse_trees());
14825 assert!(parser.report_diagnostic_errors());
14826 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
14827 assert!(parser.bail_on_error());
14828 }
14829
14830 #[test]
14831 fn set_token_stream_replaces_input_and_resets_parser() {
14832 let mut parser = mini_parser(vec![
14833 TestToken::new(1).with_text("old"),
14834 TestToken::eof("parser-test", 1, 1, 1),
14835 ]);
14836 parser.consume();
14837 parser.record_generated_syntax_error();
14838 let replacement = CommonTokenStream::new(Source {
14839 tokens: vec![
14840 TestToken::new(2).with_text("new"),
14841 TestToken::eof("parser-test", 1, 1, 1),
14842 ],
14843 index: 0,
14844 });
14845
14846 parser.set_token_stream(replacement);
14847
14848 assert_eq!(parser.input.index(), 0);
14849 assert_eq!(parser.la(1), 2);
14850 assert_eq!(parser.input.text_all(), "new");
14851 assert_eq!(parser.number_of_syntax_errors(), 0);
14852 }
14853
14854 #[test]
14855 fn active_invocation_states_exclude_the_root_frame() {
14856 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14857
14858 let _root = parser.enter_rule(0, 0);
14859 assert!(parser.active_invocation_states().is_empty());
14860
14861 let marker = parser.push_invoking_state(6);
14862 let _child = parser.enter_rule(2, 1);
14863 parser.discard_invoking_state(marker);
14864 assert_eq!(parser.active_invocation_states(), [6]);
14865
14866 let marker = parser.push_invoking_state(13);
14867 let _grandchild = parser.enter_rule(4, 2);
14868 parser.discard_invoking_state(marker);
14869 assert_eq!(parser.active_invocation_states(), [13, 6]);
14870
14871 parser.exit_rule();
14872 parser.exit_rule();
14873 parser.exit_rule();
14874 }
14875
14876 #[test]
14877 fn parser_predicates_support_token_adjacency() {
14878 let mut parser = mini_parser(vec![
14879 TestToken::new(1).with_text("=").with_span(0, 0),
14880 TestToken::new(1).with_text(">").with_span(1, 1),
14881 TestToken::eof("parser-test", 2, 1, 2),
14882 ]);
14883 parser.consume();
14884 parser.consume();
14885
14886 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
14887
14888 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
14889
14890 let mut parser = mini_parser(vec![
14891 TestToken::new(1).with_text("=").with_span(0, 0),
14892 TestToken::new(1)
14893 .with_text(" ")
14894 .with_channel(HIDDEN_CHANNEL)
14895 .with_span(1, 1),
14896 TestToken::new(1).with_text(">").with_span(2, 2),
14897 TestToken::eof("parser-test", 3, 1, 3),
14898 ]);
14899 parser.consume();
14900 parser.consume();
14901
14902 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
14903 }
14904
14905 #[test]
14906 fn parser_predicates_support_context_child_text_checks() {
14907 let mut parser = mini_parser(vec![
14908 TestToken::new(1).with_text("var"),
14909 TestToken::eof("parser-test", 1, 1, 1),
14910 ]);
14911 let mut context = ParserRuleContext::new(1, 0);
14912 let mut child_context = ParserRuleContext::new(2, 0);
14913 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
14914 parser.tree.add_child(&mut child_context, terminal);
14915 let child = parser.rule_node(child_context);
14916 parser.tree.add_child(&mut context, child);
14917 let predicates = [(
14918 1,
14919 0,
14920 ParserPredicate::ContextChildRuleTextNotEquals {
14921 rule_index: 2,
14922 text: "var",
14923 },
14924 )];
14925
14926 assert!(
14927 !parser.parser_semantic_predicate_matches_with_context_and_local(
14928 &predicates,
14929 1,
14930 0,
14931 &context,
14932 0,
14933 )
14934 );
14935 }
14936
14937 #[test]
14938 fn context_expected_symbols_walks_nullable_parent_contexts() {
14939 let atn = nested_nullable_context_atn();
14940 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14941 parser.rule_context_stack = vec![
14942 RuleContextFrame {
14943 rule_index: 0,
14944 invoking_state: 0,
14945 },
14946 RuleContextFrame {
14947 rule_index: 1,
14948 invoking_state: 1,
14949 },
14950 RuleContextFrame {
14951 rule_index: 2,
14952 invoking_state: 2,
14953 },
14954 ];
14955
14956 let expected = parser.context_expected_symbols(&atn);
14957
14958 assert!(expected.contains(&1));
14959 assert!(expected.contains(&TOKEN_EOF));
14960 }
14961
14962 #[test]
14963 fn prediction_context_return_states_track_rule_stack_changes() {
14964 let atn = nested_nullable_context_atn();
14965 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
14966 parser.rule_context_stack = vec![
14967 RuleContextFrame {
14968 rule_index: 0,
14969 invoking_state: 0,
14970 },
14971 RuleContextFrame {
14972 rule_index: 1,
14973 invoking_state: 1,
14974 },
14975 RuleContextFrame {
14976 rule_index: 2,
14977 invoking_state: 2,
14978 },
14979 ];
14980
14981 let initial_version = parser.rule_context_version();
14982 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14983 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14984 assert_eq!(first, second);
14985 assert_eq!(parser.rule_context_version(), initial_version);
14986
14987 parser.exit_rule();
14988 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
14989 assert_ne!(first, after_pop);
14990 assert_ne!(parser.rule_context_version(), initial_version);
14991 }
14992
14993 #[test]
14994 fn generated_match_token_recovers_missing_token_from_context_follow() {
14995 let atn = generated_match_recovery_atn();
14996 let data = RecognizerData::new(
14997 "Mini.g4",
14998 Vocabulary::new(
14999 [None, Some("'X'"), Some("'Y'")],
15000 [None, Some("X"), Some("Y")],
15001 [None::<&str>, None, None],
15002 ),
15003 );
15004 let mut parser = BaseParser::new(
15005 CommonTokenStream::new(Source {
15006 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
15007 index: 0,
15008 }),
15009 data,
15010 );
15011 parser.rule_context_stack = vec![
15012 RuleContextFrame {
15013 rule_index: 0,
15014 invoking_state: 0,
15015 },
15016 RuleContextFrame {
15017 rule_index: 1,
15018 invoking_state: 1,
15019 },
15020 ];
15021 assert_eq!(parser.number_of_syntax_errors(), 0);
15022
15023 let node = parser
15024 .match_token_recovering(2, 5, &atn)
15025 .expect("generated match should insert missing token");
15026
15027 assert_eq!(node.children().len(), 1);
15028 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
15029 assert_eq!(
15030 node.clone()
15031 .into_child_iter()
15032 .map(|child| parser.node(child).text())
15033 .collect::<Vec<_>>(),
15034 ["<missing 'Y'>"]
15035 );
15036 assert!(!node.consumed_eof());
15039 assert_eq!(parser.la(1), TOKEN_EOF);
15040 assert_eq!(parser.number_of_syntax_errors(), 1);
15041 assert_eq!(
15042 parser.generated_parser_diagnostics,
15043 [ParserDiagnostic {
15044 line: 1,
15045 column: 3,
15046 message: "missing 'Y' at '<EOF>'".to_owned(),
15047 }]
15048 );
15049 }
15050
15051 #[test]
15052 fn generated_match_token_counts_single_token_deletion_recovery() {
15053 let atn = generated_match_recovery_atn();
15054 let data = RecognizerData::new(
15055 "Mini.g4",
15056 Vocabulary::new(
15057 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
15058 [None, Some("X"), Some("Y"), Some("Z")],
15059 [None::<&str>, None, None, None],
15060 ),
15061 );
15062 let mut parser = BaseParser::new(
15063 CommonTokenStream::new(Source {
15064 tokens: vec![
15065 TestToken::new(3).with_text("z"),
15066 TestToken::new(2).with_text("y"),
15067 TestToken::eof("parser-test", 3, 1, 3),
15068 ],
15069 index: 0,
15070 }),
15071 data,
15072 );
15073
15074 let node = parser
15075 .match_token_recovering(2, 5, &atn)
15076 .expect("generated match should delete the extraneous token");
15077
15078 assert_eq!(node.children().len(), 2);
15079 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
15080 assert_eq!(parser.node(node.children()[0]).text(), "z");
15081 assert_eq!(parser.node(node.children()[1]).text(), "y");
15082 assert_eq!(
15083 node.into_child_iter()
15084 .map(|child| parser.node(child).text())
15085 .collect::<Vec<_>>(),
15086 ["z", "y"]
15087 );
15088 assert_eq!(parser.number_of_syntax_errors(), 1);
15089 }
15090
15091 #[test]
15092 fn generated_match_token_iterates_single_success_without_a_children_vec() {
15093 let atn = generated_match_recovery_atn();
15094 let data = RecognizerData::new(
15095 "Mini.g4",
15096 Vocabulary::new(
15097 [None, Some("'X'"), Some("'Y'")],
15098 [None, Some("X"), Some("Y")],
15099 [None::<&str>, None, None],
15100 ),
15101 );
15102 let mut parser = BaseParser::new(
15103 CommonTokenStream::new(Source {
15104 tokens: vec![
15105 TestToken::new(2).with_text("y"),
15106 TestToken::eof("parser-test", 1, 1, 1),
15107 ],
15108 index: 0,
15109 }),
15110 data,
15111 );
15112
15113 let node = parser
15114 .match_token_recovering(2, 5, &atn)
15115 .expect("generated match should consume the expected token");
15116
15117 assert_eq!(
15118 node.into_child_iter()
15119 .map(|child| parser.node(child).text())
15120 .collect::<Vec<_>>(),
15121 ["y"]
15122 );
15123 assert_eq!(parser.number_of_syntax_errors(), 0);
15124 }
15125
15126 #[test]
15127 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
15128 let atn = generated_match_recovery_atn();
15129 let data = RecognizerData::new(
15130 "Mini.g4",
15131 Vocabulary::new(
15132 [None, Some("'X'"), Some("'Y'")],
15133 [None, Some("X"), Some("Y")],
15134 [None::<&str>, None, None],
15135 ),
15136 );
15137 let mut parser = BaseParser::new(
15138 CommonTokenStream::new(Source {
15139 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
15140 index: 0,
15141 }),
15142 data,
15143 );
15144 parser.rule_context_stack = vec![
15145 RuleContextFrame {
15146 rule_index: 0,
15147 invoking_state: 0,
15148 },
15149 RuleContextFrame {
15150 rule_index: 1,
15151 invoking_state: 1,
15152 },
15153 ];
15154 let marker = parser.generated_diagnostics_checkpoint();
15155
15156 let _ = parser
15157 .match_token_recovering(2, 5, &atn)
15158 .expect("generated match should insert missing token");
15159 assert_eq!(parser.number_of_syntax_errors(), 1);
15160
15161 parser.restore_generated_diagnostics(marker);
15162
15163 assert_eq!(parser.number_of_syntax_errors(), 0);
15164 assert!(parser.generated_parser_diagnostics.is_empty());
15165 }
15166
15167 #[test]
15168 fn generated_prediction_diagnostics_use_adaptive_context() {
15169 let atn = two_alt_decision_atn();
15170 let data = RecognizerData::new(
15171 "Mini.g4",
15172 Vocabulary::new(
15173 [None, Some("'x'"), Some("'y'")],
15174 [None, Some("X"), Some("Y")],
15175 [None::<&str>, None, None],
15176 ),
15177 )
15178 .with_rule_names(["s"]);
15179 let mut parser = BaseParser::new(
15180 CommonTokenStream::new(Source {
15181 tokens: vec![
15182 TestToken::new(1)
15183 .with_text("x")
15184 .with_position(1, 0)
15185 .with_span(0, 0),
15186 TestToken::new(2)
15187 .with_text("y")
15188 .with_position(1, 2)
15189 .with_span(1, 1),
15190 TestToken::eof("parser-test", 2, 1, 3),
15191 ],
15192 index: 0,
15193 }),
15194 data,
15195 );
15196 parser.set_report_diagnostic_errors(true);
15197
15198 parser.record_generated_prediction_diagnostic(
15199 &atn,
15200 1,
15201 &ParserAtnPrediction {
15202 alt: 1,
15203 requires_full_context: true,
15204 has_semantic_context: false,
15205 diagnostic: Some(ParserAtnPredictionDiagnostic {
15206 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
15207 start_index: 0,
15208 sll_stop_index: 1,
15209 ll_stop_index: 0,
15210 conflicting_alts: vec![1, 2],
15211 exact: false,
15212 }),
15213 },
15214 );
15215 parser.record_generated_prediction_diagnostic(
15220 &atn,
15221 1,
15222 &ParserAtnPrediction {
15223 alt: 1,
15224 requires_full_context: true,
15225 has_semantic_context: false,
15226 diagnostic: Some(ParserAtnPredictionDiagnostic {
15227 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
15228 start_index: 0,
15229 sll_stop_index: 1,
15230 ll_stop_index: 1,
15231 conflicting_alts: vec![1, 2],
15232 exact: false,
15233 }),
15234 },
15235 );
15236
15237 assert_eq!(
15238 parser.generated_parser_diagnostics,
15239 [
15240 ParserDiagnostic {
15241 line: 1,
15242 column: 2,
15243 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
15244 },
15245 ParserDiagnostic {
15246 line: 1,
15247 column: 0,
15248 message: "reportContextSensitivity d=0 (s), input='x'".to_owned(),
15249 },
15250 ParserDiagnostic {
15251 line: 1,
15252 column: 2,
15253 message: "reportAttemptingFullContext d=0 (s), input='xy'".to_owned(),
15254 },
15255 ]
15256 );
15257 }
15258
15259 #[test]
15260 fn generated_match_not_set_recovers_empty_complement_at_eof() {
15261 let atn = complement_set_atn();
15262 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15263 parser.rule_context_stack = vec![RuleContextFrame {
15264 rule_index: 0,
15265 invoking_state: 0,
15266 }];
15267
15268 let node = parser
15269 .match_not_token_set_recovering(
15270 atn.token_set(0).expect("excluded token set"),
15271 1,
15272 1,
15273 1,
15274 &atn,
15275 )
15276 .expect("empty complement should recover at EOF");
15277
15278 assert_eq!(node.children().len(), 1);
15279 assert!(!node.consumed_eof());
15282 assert_eq!(parser.la(1), TOKEN_EOF);
15283 assert_eq!(
15284 parser.generated_parser_diagnostics,
15285 [ParserDiagnostic {
15286 line: 1,
15287 column: 1,
15288 message: "missing {} at '<EOF>'".to_owned(),
15289 }]
15290 );
15291 }
15292
15293 #[test]
15294 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
15295 let atn = wildcard_then_eof_atn();
15301 let data = RecognizerData::new(
15302 "Mini.g4",
15303 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
15304 );
15305 let mut parser = BaseParser::new(
15306 CommonTokenStream::new(Source {
15307 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
15308 index: 0,
15309 }),
15310 data,
15311 );
15312 parser.rule_context_stack = vec![RuleContextFrame {
15313 rule_index: 0,
15314 invoking_state: 0,
15315 }];
15316
15317 let node = parser
15318 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
15319 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
15320
15321 assert_eq!(node.children().len(), 1);
15323 assert!(!node.consumed_eof());
15324 assert!(
15325 parser
15326 .node(node.children()[0])
15327 .text()
15328 .starts_with("<missing")
15329 );
15330 assert_eq!(parser.la(1), TOKEN_EOF);
15331 assert_eq!(
15332 parser.generated_parser_diagnostics,
15333 [ParserDiagnostic {
15334 line: 1,
15335 column: 1,
15336 message: "missing 'x' at '<EOF>'".to_owned(),
15337 }]
15338 );
15339 }
15340
15341 #[test]
15342 fn generated_rule_recovery_consumes_to_parent_follow() {
15343 let atn = generated_match_recovery_atn();
15344 let data = RecognizerData::new(
15345 "Mini.g4",
15346 Vocabulary::new(
15347 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
15348 [None, Some("X"), Some("Y"), Some("Z")],
15349 [None::<&str>, None, None, None],
15350 ),
15351 );
15352 let mut parser = BaseParser::new(
15353 CommonTokenStream::new(Source {
15354 tokens: vec![
15355 TestToken::new(3).with_text("z"),
15356 TestToken::eof("parser-test", 1, 1, 1),
15357 ],
15358 index: 0,
15359 }),
15360 data,
15361 );
15362 let _parent = parser.enter_rule(0, 0);
15363 let marker = parser.push_invoking_state(1);
15364 let mut child = parser.enter_rule(4, 1);
15365 parser.discard_invoking_state(marker);
15366
15367 parser.recover_generated_rule(
15368 &mut child,
15369 &atn,
15370 AntlrError::ParserError {
15371 line: 1,
15372 column: 0,
15373 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
15374 },
15375 );
15376 let tree = parser.finish_rule(child, false);
15377
15378 assert_eq!(parser.la(1), TOKEN_EOF);
15379 assert_eq!(
15380 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
15381 "(a z)"
15382 );
15383 assert_eq!(parser.number_of_syntax_errors(), 1);
15384 assert_eq!(
15385 parser.generated_parser_diagnostics,
15386 [ParserDiagnostic {
15387 line: 1,
15388 column: 0,
15389 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
15390 }]
15391 );
15392 parser.exit_rule();
15393 }
15394
15395 #[test]
15396 fn greedy_ll1_alt_handles_nullable_loop_exit() {
15397 let mut body_symbols = TokenBitSet::default();
15398 body_symbols.insert(1);
15399 let entry = DecisionLookahead {
15400 transitions: vec![
15401 TransitionLookSet {
15402 symbols: body_symbols,
15403 nullable: false,
15404 },
15405 TransitionLookSet {
15406 symbols: TokenBitSet::default(),
15407 nullable: true,
15408 },
15409 ],
15410 };
15411
15412 assert_eq!(ll1_unique_alt(&entry, 2), None);
15413 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
15414 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
15415 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
15416 }
15417
15418 #[test]
15419 fn ordinary_repetition_builds_tree_in_input_order() {
15420 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15421 let mut parser = mini_parser(repeated_x_tokens(3));
15422 let tree = parser
15423 .parse_atn_rule(&atn, 0)
15424 .expect("ordinary repetition should parse");
15425
15426 let root = parser
15427 .node(tree)
15428 .as_rule()
15429 .expect("entry result should be a rule");
15430 let body_rules = root.child_rules(1).collect::<Vec<_>>();
15431 assert_eq!(root.text(), "xxx<EOF>");
15432 assert_eq!(body_rules.len(), 3);
15433 assert_eq!(
15434 body_rules
15435 .iter()
15436 .map(|rule| rule.start_id().expect("body start").index())
15437 .collect::<Vec<_>>(),
15438 [0, 1, 2]
15439 );
15440 assert_eq!(
15441 body_rules
15442 .iter()
15443 .map(|rule| rule.stop_id().expect("body stop").index())
15444 .collect::<Vec<_>>(),
15445 [0, 1, 2]
15446 );
15447 assert_eq!(parser.number_of_syntax_errors(), 0);
15448 }
15449 }
15450
15451 #[test]
15452 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
15453 const DEPTH: usize = 20_000;
15454
15455 std::thread::Builder::new()
15456 .name("deferred-rule-materialization".to_owned())
15457 .stack_size(256 * 1024)
15458 .spawn(|| {
15459 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
15460 let mut root = FastDeferredNodeId::EMPTY;
15461 for depth in 0..DEPTH {
15462 root = parser
15463 .recognition_arena
15464 .deferred_rule_node(FastDeferredRule {
15465 rule_index: u32::try_from(depth).expect("depth fits in u32"),
15466 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
15467 start_index: 0,
15468 stop_index: None,
15469 deferred_children: root,
15470 children: NodeSeqId::EMPTY,
15471 });
15472 }
15473
15474 let mut children = parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
15475 for expected_rule in (0..DEPTH).rev() {
15476 let mut nodes = parser.recognition_arena.iter(children);
15477 let node = nodes.next().expect("nested rule node");
15478 assert!(nodes.next().is_none(), "each rule has one child");
15479 let ArenaRecognizedNode::Rule {
15480 rule_index,
15481 children: nested,
15482 ..
15483 } = parser.recognition_arena.node(node)
15484 else {
15485 panic!("expected nested rule");
15486 };
15487 assert_eq!(rule_index as usize, expected_rule);
15488 children = nested;
15489 }
15490 assert!(children.is_empty());
15491 })
15492 .expect("small-stack thread should start")
15493 .join()
15494 .expect("deferred rules should materialize without recursion");
15495 }
15496
15497 #[test]
15498 fn deeply_nested_rule_calls_grow_the_stack() {
15499 const DEPTH: usize = 4_096;
15500 const STACK_SIZE: usize = 256 * 1024;
15501 let atn = nested_rule_chain_atn(DEPTH);
15502 std::thread::Builder::new()
15503 .name("nested-adaptive-set-rules".to_owned())
15504 .stack_size(STACK_SIZE)
15505 .spawn(move || {
15506 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
15507 parser.set_build_parse_trees(false);
15508 parser.fast_first_set_prefilter = false;
15511 parser
15512 .parse_atn_rule(&atn, 0)
15513 .expect("nested rule chain should grow the native stack");
15514 assert_eq!(parser.input.index(), 1);
15515 })
15516 .expect("small-stack thread should start")
15517 .join()
15518 .expect("nested rule chain should not overflow its stack");
15519 }
15520
15521 #[test]
15522 fn deeply_nested_branching_rules_grow_the_stack() {
15523 const DEPTH: usize = 4_096;
15524 const STACK_SIZE: usize = 256 * 1024;
15525 let atn = nested_rule_graph_atn(DEPTH, true, false);
15526 std::thread::Builder::new()
15527 .name("nested-branching-rules".to_owned())
15528 .stack_size(STACK_SIZE)
15529 .spawn(move || {
15530 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
15531 parser.set_build_parse_trees(false);
15532 parser
15533 .parse_atn_rule(&atn, 0)
15534 .expect("branching rule chain should grow the native stack");
15535 assert_eq!(parser.input.index(), 1);
15536 })
15537 .expect("small-stack thread should start")
15538 .join()
15539 .expect("branching rule chain should not overflow its stack");
15540 }
15541
15542 #[test]
15543 fn deeply_nested_rule_follows_grow_the_stack() {
15544 const DEPTH: usize = 4_096;
15545 const STACK_SIZE: usize = 256 * 1024;
15546 let atn = nested_rule_graph_atn(DEPTH, false, true);
15547 std::thread::Builder::new()
15548 .name("nested-rule-follows".to_owned())
15549 .stack_size(STACK_SIZE)
15550 .spawn(move || {
15551 let mut parser = mini_parser(repeated_x_tokens(DEPTH));
15552 parser.set_build_parse_trees(false);
15553 parser.fast_first_set_prefilter = false;
15554 parser
15555 .parse_atn_rule(&atn, 0)
15556 .expect("rule follow chain should grow the native stack");
15557 assert_eq!(parser.input.index(), DEPTH);
15558 })
15559 .expect("small-stack thread should start")
15560 .join()
15561 .expect("nested rule follow chain should not overflow its stack");
15562 }
15563
15564 #[test]
15565 fn deeply_nested_recovery_grows_the_stack() {
15566 const DEPTH: usize = 4_096;
15567 const STACK_SIZE: usize = 256 * 1024;
15568 let atn = nested_rule_chain_atn(DEPTH);
15569 std::thread::Builder::new()
15570 .name("nested-rule-recovery".to_owned())
15571 .stack_size(STACK_SIZE)
15572 .spawn(move || {
15573 let mut parser = mini_parser(vec![
15574 TestToken::new(2).with_text("z"),
15575 TestToken::new(1).with_text("x"),
15576 TestToken::eof("parser-test", 2, 1, 2),
15577 ]);
15578 parser.set_build_parse_trees(false);
15579 parser.fast_first_set_prefilter = false;
15580 parser
15581 .parse_atn_rule(&atn, 0)
15582 .expect("nested recovery should grow the native stack");
15583 assert_eq!(parser.input.index(), 2);
15584 assert_eq!(parser.number_of_syntax_errors(), 1);
15585 })
15586 .expect("small-stack thread should start")
15587 .join()
15588 .expect("nested rule recovery should not overflow its stack");
15589 }
15590
15591 #[test]
15592 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
15593 const REPETITIONS: usize = 64;
15594
15595 let atn = ambiguous_ordinary_star_loop_atn();
15596 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15597 let tree = parser
15598 .parse_atn_rule(&atn, 0)
15599 .expect("ambiguous ordinary repetition should parse");
15600
15601 let root = parser
15602 .node(tree)
15603 .as_rule()
15604 .expect("entry result should be a rule");
15605 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
15606 assert_eq!(parser.input.index(), REPETITIONS);
15607 assert!(
15608 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
15609 "equivalent segmentations should keep deferred storage linear"
15610 );
15611 assert_eq!(parser.number_of_syntax_errors(), 0);
15612 }
15613
15614 #[test]
15615 fn long_ordinary_repetition_does_not_consume_native_stack() {
15616 const REPETITIONS: usize = 20_000;
15617
15618 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15619 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15620 parser.set_build_parse_trees(false);
15621 parser
15622 .parse_atn_rule(&atn, 0)
15623 .expect("long ordinary repetition should parse");
15624
15625 assert_eq!(parser.input.index(), REPETITIONS);
15626 assert_eq!(parser.number_of_syntax_errors(), 0);
15627 }
15628 }
15629
15630 #[test]
15631 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
15632 const REPETITIONS: usize = 2_000;
15633 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
15634
15635 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
15636 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
15637 let tree = parser
15638 .parse_atn_rule(&atn, 0)
15639 .expect("long rule repetition should parse");
15640
15641 let root = parser
15642 .node(tree)
15643 .as_rule()
15644 .expect("entry result should be a rule");
15645 assert_eq!(root.text(), expected_text);
15646 assert_eq!(root.child_rules(1).count(), REPETITIONS);
15647 let first_body = root.child_rules(1).next().expect("first body rule");
15648 let last_body = root.child_rules(1).next_back().expect("last body rule");
15649 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
15650 assert_eq!(
15651 last_body.stop_id().expect("last body stop").index(),
15652 REPETITIONS - 1
15653 );
15654
15655 let stats = parser.recognition_arena_stats();
15656 assert_eq!(
15657 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
15658 (REPETITIONS, REPETITIONS, 0)
15659 );
15660 assert_eq!(
15661 (stats.total_links, stats.live_links, stats.dead_links),
15662 (REPETITIONS, REPETITIONS, 0)
15663 );
15664 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
15665 assert_eq!(
15666 parser.recognition_arena.deferred_nodes.len(),
15667 REPETITIONS * 2 - 1
15668 );
15669 assert_eq!(parser.number_of_syntax_errors(), 0);
15670 }
15671 }
15672
15673 #[test]
15674 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
15675 let key = |state_number| FastRecognizeKey {
15676 state_number,
15677 stop_state: 10,
15678 index: state_number,
15679 rule_start_index: 0,
15680 decision_start_index: None,
15681 precedence: 0,
15682 recovery_symbols_id: 0,
15683 recovery_state: None,
15684 };
15685
15686 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15687 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
15688 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
15689 }
15690 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
15691 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
15692
15693 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15694 let repeated = key(1);
15695 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
15696 assert!(promote.clean_memo_enabled_for_key(&repeated));
15697 }
15698 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
15699
15700 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
15701 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
15702 }
15703 assert!(sparse.clean_memo_enabled_for_key(&repeated));
15704 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
15705 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
15706 assert!(sparse.clean_memo_enabled_for_key(&repeated));
15707 }
15708 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
15709 }
15710
15711 #[test]
15712 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
15713 assert_eq!(
15714 fast_recognize_memo_capacity(0),
15715 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
15716 );
15717 assert_eq!(
15718 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
15719 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
15720 );
15721 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
15722 assert_eq!(
15723 fast_recognize_memo_capacity(usize::MAX),
15724 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
15725 );
15726 }
15727
15728 #[test]
15729 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
15730 let mut scratch = FastRecognizeTopScratch::default();
15731 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
15732 let retained_capacity = scratch.memo.capacity();
15733 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
15734 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15735
15736 let larger_capacity = retained_capacity + 1;
15737 scratch.prepare(larger_capacity);
15738 let grown_capacity = scratch.memo.capacity();
15739 assert!(grown_capacity >= larger_capacity);
15740 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15741
15742 scratch.memo.insert(
15743 FastRecognizeKey {
15744 state_number: 0,
15745 stop_state: 0,
15746 index: 0,
15747 rule_start_index: 0,
15748 decision_start_index: None,
15749 precedence: 0,
15750 recovery_symbols_id: 0,
15751 recovery_state: None,
15752 },
15753 Rc::from([FastRecognizeOutcome {
15754 index: 0,
15755 consumed_eof: false,
15756 diagnostics: DiagnosticSeqId::EMPTY,
15757 deferred_nodes: FastDeferredNodeId::EMPTY,
15758 nodes: NodeSeqId::EMPTY,
15759 }]),
15760 );
15761 scratch.release_oversized_memo();
15762 assert!(scratch.memo.is_empty());
15763 assert_eq!(scratch.memo.capacity(), grown_capacity);
15764
15765 scratch
15766 .memo
15767 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
15768 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
15769
15770 scratch.release_oversized_memo();
15771 assert!(scratch.memo.is_empty());
15772 assert_eq!(scratch.memo.capacity(), 0);
15773 }
15774
15775 #[test]
15776 fn clean_empty_multi_alt_outcomes_are_memoized() {
15777 let mut atn = ParserAtnBuilder::new(2);
15778 assert_eq!(
15779 atn.add_state(AtnStateKind::RuleStart, Some(0))
15780 .expect("state")
15781 .index(),
15782 0
15783 );
15784 assert_eq!(
15785 atn.add_state(AtnStateKind::BlockStart, Some(0))
15786 .expect("state")
15787 .index(),
15788 1
15789 );
15790 assert_eq!(
15791 atn.add_state(AtnStateKind::RuleStop, Some(0))
15792 .expect("state")
15793 .index(),
15794 2
15795 );
15796 atn.set_rule_to_start_state(vec![0])
15797 .expect("rule start states");
15798 atn.set_rule_to_stop_state(vec![2])
15799 .expect("rule stop states");
15800 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15801 .expect("transition");
15802 atn.add_transition(
15803 1,
15804 ParserTransitionSpec::Atom {
15805 target: 2,
15806 label: 1,
15807 },
15808 )
15809 .expect("transition");
15810 atn.add_transition(
15811 1,
15812 ParserTransitionSpec::Atom {
15813 target: 2,
15814 label: 2,
15815 },
15816 )
15817 .expect("transition");
15818 let atn = finish_atn(atn);
15819
15820 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
15821 parser.fast_recovery_enabled = false;
15822 let mut visiting = FxHashSet::default();
15823 let mut memo = FxHashMap::default();
15824 let mut expected = ExpectedTokens::default();
15825 let outcomes = parser.recognize_state_fast(
15826 &atn,
15827 FastRecognizeRequest {
15828 state_number: 1,
15829 stop_state: 2,
15830 index: 0,
15831 rule_start_index: 0,
15832 decision_start_index: None,
15833 precedence: 0,
15834 depth: 0,
15835 recovery_symbols: parser.empty_recovery_symbols(),
15836 recovery_state: None,
15837 },
15838 FastRecognizeScratch {
15839 predicate_context: None,
15840 visiting: &mut visiting,
15841 memo: &mut memo,
15842 expected: &mut expected,
15843 native_depth: 0,
15844 },
15845 );
15846
15847 assert!(outcomes.is_empty());
15848 assert_eq!(memo.len(), 1);
15849 assert!(memo.values().next().expect("memo entry").is_empty());
15850
15851 parser.clean_memo_mode = CleanMemoMode::Sparse;
15852 visiting.clear();
15853 memo.clear();
15854 expected = ExpectedTokens::default();
15855 let sparse_outcomes = parser.recognize_state_fast(
15856 &atn,
15857 FastRecognizeRequest {
15858 state_number: 1,
15859 stop_state: 2,
15860 index: 0,
15861 rule_start_index: 0,
15862 decision_start_index: None,
15863 precedence: 0,
15864 depth: 0,
15865 recovery_symbols: parser.empty_recovery_symbols(),
15866 recovery_state: None,
15867 },
15868 FastRecognizeScratch {
15869 predicate_context: None,
15870 visiting: &mut visiting,
15871 memo: &mut memo,
15872 expected: &mut expected,
15873 native_depth: 0,
15874 },
15875 );
15876
15877 assert!(sparse_outcomes.is_empty());
15878 assert!(memo.is_empty());
15879 }
15880
15881 #[test]
15882 fn wildcard_matches_non_eof_only() {
15883 let mut parser = mini_parser(vec![
15884 TestToken::new(1).with_text("x"),
15885 TestToken::eof("parser-test", 1, 1, 1),
15886 ]);
15887 let matched = parser.match_wildcard().expect("wildcard");
15888 assert_eq!(parser.node(matched).text(), "x");
15889 assert!(parser.match_wildcard().is_err());
15890 }
15891
15892 #[test]
15893 fn add_parse_child_records_match_even_without_tree_building() {
15894 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15899 let token = TestToken::new(1).with_text("x");
15900
15901 parser.set_build_parse_trees(false);
15902 let mut ctx = ParserRuleContext::new(0, 0);
15903 assert!(!ctx.has_matched_child());
15904 let child = parser.terminal_tree(token.id);
15905 parser.add_parse_child(&mut ctx, child);
15906 assert_eq!(ctx.child_count(), 0);
15908 assert_eq!(parser.parse_tree_storage().node_count(), 0);
15909 assert!(ctx.has_matched_child());
15911
15912 parser.set_build_parse_trees(true);
15914 let mut ctx = ParserRuleContext::new(0, 0);
15915 let child = parser.terminal_tree(token.id);
15916 parser.add_parse_child(&mut ctx, child);
15917 assert_eq!(ctx.child_count(), 1);
15918 assert!(ctx.has_matched_child());
15919 }
15920
15921 #[test]
15922 fn disabled_tree_building_does_not_grow_flat_storage() {
15923 let mut parser = mini_parser(vec![
15924 TestToken::new(1).with_text("x"),
15925 TestToken::new(1).with_text("y"),
15926 TestToken::eof("parser-test", 2, 1, 2),
15927 ]);
15928 parser.set_build_parse_trees(false);
15929 let mut context = ParserRuleContext::new(0, -1);
15930
15931 for _ in 0..2 {
15932 let child = parser.match_token(1).expect("token should match");
15933 parser.add_parse_child(&mut context, child);
15934 }
15935 let current = parser.input.lt_id(1).expect("EOF token");
15936 let error = parser.error_tree(current);
15937 parser.add_parse_child(&mut context, error);
15938 let root = parser.rule_node(context);
15939
15940 assert_eq!(
15941 parser.parse_tree_storage().stats(),
15942 ParseTreeStats::default()
15943 );
15944 assert!(
15945 parser
15946 .parse_tree_storage()
15947 .node(parser.token_store(), root)
15948 .is_none(),
15949 "the no-tree sentinel must not resolve to stored data"
15950 );
15951 }
15952
15953 #[test]
15954 fn disabled_tree_building_skips_recognition_rule_node_storage() {
15955 let atn = ordinary_star_loop_atn();
15956 let mut parser = mini_parser(repeated_x_tokens(3));
15957 parser.set_build_parse_trees(false);
15958
15959 parser
15960 .parse_atn_rule(&atn, 0)
15961 .expect("ordinary repetition should parse without a tree");
15962
15963 assert_eq!(parser.input.index(), 3);
15964 assert!(parser.recognition_arena.nodes.is_empty());
15965 assert!(parser.recognition_arena.seq_links.is_empty());
15966 assert!(parser.recognition_arena.deferred_nodes.is_empty());
15967 assert!(parser.recognition_arena.deferred_rules.is_empty());
15968 assert!(!parser.fast_token_nodes_enabled);
15969 assert!(parser.fast_recognize_scratch.memo.is_empty());
15970 }
15971
15972 #[test]
15973 fn parser_interprets_simple_atn_rule() {
15974 let atn = token_then_eof_atn();
15975 let mut parser = mini_parser(vec![
15976 TestToken::new(1).with_text("x"),
15977 TestToken::eof("parser-test", 1, 1, 1),
15978 ]);
15979
15980 let tree = parser
15981 .parse_atn_rule(&atn, 0)
15982 .expect("artificial parser rule should parse");
15983 assert_eq!(parser.node(tree).text(), "x<EOF>");
15984 assert_eq!(parser.number_of_syntax_errors(), 0);
15985 assert_eq!(
15986 parser
15987 .node(tree)
15988 .first_rule_stop(0)
15989 .expect("rule should stop at EOF")
15990 .token_type(),
15991 TOKEN_EOF
15992 );
15993
15994 let mut parser = mini_parser(vec![
15995 TestToken::new(1).with_text("x"),
15996 TestToken::eof("parser-test", 1, 1, 1),
15997 ]);
15998 let (tree, actions) = parser
15999 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16000 .expect("runtime-option parser rule should parse");
16001 assert!(actions.is_empty());
16002 assert_eq!(
16003 parser
16004 .node(tree)
16005 .first_rule_stop(0)
16006 .expect("rule should stop at EOF")
16007 .token_type(),
16008 TOKEN_EOF
16009 );
16010 }
16011
16012 #[test]
16013 fn runtime_options_default_ignores_noop_action_transitions() {
16014 let atn = noop_action_then_token_then_eof_atn();
16015 let mut parser = mini_parser(vec![
16016 TestToken::new(1).with_text("x"),
16017 TestToken::eof("parser-test", 1, 1, 1),
16018 ]);
16019
16020 let (tree, actions) = parser
16021 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16022 .expect("no-op parser action should not force action replay");
16023
16024 assert_eq!(parser.node(tree).text(), "x<EOF>");
16025 assert!(
16026 actions.is_empty(),
16027 "action_index=None transitions are ANTLR metadata, not replay actions"
16028 );
16029 assert_eq!(parser.number_of_syntax_errors(), 0);
16030 }
16031
16032 #[test]
16033 fn parser_exposes_buffered_token_stream_after_parse() {
16034 let atn = token_then_eof_atn();
16035 let mut parser = mini_parser(vec![
16036 TestToken::new(1).with_text("x"),
16037 TestToken::eof("parser-test", 1, 1, 1),
16038 ]);
16039
16040 let tree = parser
16041 .parse_atn_rule(&atn, 0)
16042 .expect("artificial parser rule should parse");
16043 assert_eq!(parser.node(tree).text(), "x<EOF>");
16044
16045 let stream = parser.token_stream();
16046 let source_index_after_parse = stream.token_source().index;
16047 let buffered = stream.tokens().collect::<Vec<_>>();
16048 assert_eq!(buffered.len(), 2);
16049 assert_eq!(buffered[0].text(), "x");
16050 assert_eq!(buffered[0].token_id().index(), 0);
16051 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
16052 assert_eq!(stream.token_source().index, source_index_after_parse);
16053 drop(buffered);
16054
16055 let stream = parser.into_token_stream();
16056 assert_eq!(stream.token_source().index, source_index_after_parse);
16057 assert_eq!(stream.tokens().next().expect("first token").text(), "x");
16058 assert_eq!(
16059 stream.tokens().nth(1).expect("EOF token").token_type(),
16060 TOKEN_EOF
16061 );
16062 }
16063
16064 #[test]
16065 fn parser_syntax_error_count_tracks_interpreted_recovery() {
16066 let atn = token_then_eof_atn();
16067 let mut parser = mini_parser(vec![
16068 TestToken::new(1).with_text("x"),
16069 TestToken::new(2).with_text("y"),
16070 TestToken::eof("parser-test", 2, 1, 2),
16071 ]);
16072
16073 let tree = parser
16074 .parse_atn_rule(&atn, 0)
16075 .expect("invalid token should recover into an error node");
16076
16077 assert_eq!(parser.number_of_syntax_errors(), 1);
16078 assert_eq!(
16079 parser
16080 .node(tree)
16081 .first_error_token()
16082 .expect("recovery should embed an error token")
16083 .text(),
16084 "y"
16085 );
16086 }
16087
16088 #[test]
16089 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
16090 let atn = token_then_eof_atn();
16091 let mut parser = mini_parser(vec![
16092 TestToken::new(2).with_text("y"),
16093 TestToken::eof("parser-test", 1, 1, 1),
16094 ]);
16095
16096 let error = parser
16097 .parse_atn_rule(&atn, 0)
16098 .expect_err("start-rule mismatch should remain a parser error");
16099
16100 assert_eq!(parser.number_of_syntax_errors(), 1);
16101 assert!(matches!(error, AntlrError::ParserError { .. }));
16102 }
16103
16104 #[test]
16105 fn adaptive_direct_rule_uses_simulator_decision() {
16106 let atn = two_alt_decision_atn();
16107 let mut simulator = ParserAtnSimulator::new(&atn);
16108 let mut parser = mini_parser(vec![
16109 TestToken::new(2).with_text("y"),
16110 TestToken::eof("parser-test", 1, 1, 1),
16111 ]);
16112
16113 let tree = parser
16114 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
16115 .expect("direct adaptive rule should parse");
16116
16117 assert_eq!(parser.node(tree).text(), "y");
16118 assert_eq!(parser.input.index(), 1);
16119 }
16120
16121 #[test]
16122 fn adaptive_direct_rule_restores_input_on_fallback() {
16123 let atn = predicate_after_token_atn();
16124 let mut simulator = ParserAtnSimulator::new(&atn);
16125 let mut parser = mini_parser(vec![
16126 TestToken::new(1).with_text("x"),
16127 TestToken::new(2).with_text("y"),
16128 TestToken::eof("parser-test", 2, 1, 2),
16129 ]);
16130
16131 let tree = parser
16132 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
16133 .expect("fallback recognizer should parse");
16134
16135 assert_eq!(parser.node(tree).text(), "xy");
16136 assert_eq!(parser.input.index(), 2);
16137 let stats = parser.parse_tree_storage().stats();
16138 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
16139 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
16140 assert_eq!(stats.scratch_links, 0);
16141 }
16142
16143 #[test]
16144 fn unknown_predicate_policy_defaults_to_assume_true() {
16145 let atn = predicate_after_token_atn();
16146 let mut parser = mini_parser(vec![
16147 TestToken::new(1).with_text("x"),
16148 TestToken::new(2).with_text("y"),
16149 TestToken::eof("parser-test", 2, 1, 2),
16150 ]);
16151
16152 let (tree, _) = parser
16153 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16154 .expect("unknown predicate should pass under the default policy");
16155
16156 assert_eq!(parser.node(tree).text(), "xy");
16157 assert_eq!(parser.number_of_syntax_errors(), 0);
16158 }
16159
16160 #[test]
16161 fn predicate_gated_same_lookahead_uses_viable_alternative() {
16162 let atn = predicate_gated_same_lookahead_atn([0, 1]);
16163 let mut parser = mini_parser(vec![
16164 TestToken::new(1).with_text("x"),
16165 TestToken::eof("parser-test", 1, 1, 1),
16166 ]);
16167
16168 let (tree, _) = parser
16169 .parse_atn_rule_with_runtime_options(
16170 &atn,
16171 0,
16172 ParserRuntimeOptions {
16173 predicates: &[
16174 (0, 0, ParserPredicate::False),
16175 (0, 1, ParserPredicate::True),
16176 ],
16177 ..ParserRuntimeOptions::default()
16178 },
16179 )
16180 .expect("the second predicate-gated alternative should match");
16181
16182 assert_eq!(parser.node(tree).text(), "x<EOF>");
16183 assert_eq!(parser.number_of_syntax_errors(), 0);
16184 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
16185 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
16186 }
16187
16188 #[test]
16189 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
16190 let atn = token_then_eof_atn();
16194 let mut parser = mini_parser(vec![
16195 TestToken::new(1).with_text("x"),
16196 TestToken::eof("parser-test", 1, 1, 1),
16197 ]);
16198
16199 parser.unknown_predicate_hits.push((7, 3));
16201
16202 parser
16204 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16205 .expect("child rule parses");
16206
16207 let error = parser
16209 .take_unknown_semantic_error()
16210 .expect("parent's recorded coordinate must survive the nested interpreted parse");
16211 let AntlrError::Unsupported(message) = error else {
16212 panic!("expected AntlrError::Unsupported, got {error:?}");
16213 };
16214 assert!(message.contains("pred_index=3"), "message: {message}");
16215 }
16216
16217 #[test]
16218 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
16219 let atn = predicate_after_token_atn();
16220 let mut parser = mini_parser(vec![
16221 TestToken::new(1).with_text("x"),
16222 TestToken::new(2).with_text("y"),
16223 TestToken::eof("parser-test", 2, 1, 2),
16224 ]);
16225
16226 let result = parser.parse_atn_rule_with_runtime_options(
16227 &atn,
16228 0,
16229 ParserRuntimeOptions {
16230 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
16231 ..ParserRuntimeOptions::default()
16232 },
16233 );
16234
16235 assert!(
16236 result.is_err(),
16237 "the only path is predicate-guarded, so assume-false must fail the parse"
16238 );
16239 }
16240
16241 #[test]
16242 fn predicate_failure_message_keeps_semantic_recovery_path() {
16243 let atn = predicate_after_token_atn();
16244 let mut parser = mini_parser(vec![
16245 TestToken::new(1).with_text("x"),
16246 TestToken::new(2).with_text("y"),
16247 TestToken::eof("parser-test", 2, 1, 2),
16248 ]);
16249
16250 let (tree, _) = parser
16251 .parse_atn_rule_with_runtime_options(
16252 &atn,
16253 0,
16254 ParserRuntimeOptions {
16255 predicates: &[(
16256 0,
16257 0,
16258 ParserPredicate::FalseWithMessage {
16259 message: "predicate rejected input",
16260 },
16261 )],
16262 ..ParserRuntimeOptions::default()
16263 },
16264 )
16265 .expect("failure-message predicates recover through the semantic interpreter");
16266
16267 assert_eq!(parser.node(tree).text(), "xy");
16268 assert_eq!(parser.number_of_syntax_errors(), 1);
16269 assert!(
16270 parser.fast_predicate_cache.is_empty(),
16271 "failure-message predicates need the semantic interpreter's recovery outcome"
16272 );
16273 }
16274
16275 #[test]
16276 fn unknown_predicate_policy_error_names_the_coordinate() {
16277 let atn = predicate_after_token_atn();
16278 let mut parser = mini_parser(vec![
16279 TestToken::new(1).with_text("x"),
16280 TestToken::new(2).with_text("y"),
16281 TestToken::eof("parser-test", 2, 1, 2),
16282 ]);
16283
16284 let error = parser
16285 .parse_atn_rule_with_runtime_options(
16286 &atn,
16287 0,
16288 ParserRuntimeOptions {
16289 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16290 ..ParserRuntimeOptions::default()
16291 },
16292 )
16293 .expect_err("evaluating an unknown predicate under Error policy must fail");
16294
16295 let AntlrError::Unsupported(message) = error else {
16296 panic!("expected AntlrError::Unsupported, got {error:?}");
16297 };
16298 assert!(
16299 message.contains("unsupported semantic predicate"),
16300 "message should name the failure class: {message}"
16301 );
16302 assert!(
16303 message.contains("pred_index=0"),
16304 "message should carry the coordinate: {message}"
16305 );
16306 }
16307
16308 #[test]
16309 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
16310 let atn = predicate_after_token_atn();
16316 let mut parser = mini_parser(vec![
16317 TestToken::new(1).with_text("x"),
16318 TestToken::new(2).with_text("y"),
16319 TestToken::eof("parser-test", 2, 1, 2),
16320 ]);
16321
16322 parser
16323 .parse_atn_rule_with_runtime_options(
16324 &atn,
16325 0,
16326 ParserRuntimeOptions {
16327 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16328 ..ParserRuntimeOptions::default()
16329 },
16330 )
16331 .expect_err("first parse fails loud under the Error policy");
16332
16333 parser.reset_unknown_semantic_hits();
16338 assert!(
16339 parser.take_unknown_semantic_error().is_none(),
16340 "reset must drop stale unknown-predicate coordinates before a reused parse"
16341 );
16342 }
16343
16344 #[derive(Debug, Default)]
16345 struct RecordingHooks {
16346 predicates: Vec<(usize, usize, usize, Option<String>)>,
16347 actions: Vec<(usize, String, Option<String>)>,
16348 action_trees: Vec<Option<String>>,
16349 }
16350
16351 impl SemanticHooks for RecordingHooks {
16352 fn sempred<S>(
16353 &mut self,
16354 ctx: &mut ParserSemCtx<'_, S>,
16355 rule_index: usize,
16356 pred_index: usize,
16357 ) -> Option<bool>
16358 where
16359 S: TokenSource,
16360 {
16361 self.predicates.push((
16362 ctx.input_index(),
16363 rule_index,
16364 pred_index,
16365 ctx.token_text(1).map(|token| token.text().to_owned()),
16366 ));
16367 Some(true)
16368 }
16369
16370 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
16371 where
16372 S: TokenSource,
16373 {
16374 self.actions.push((
16375 action.source_state(),
16376 ctx.action_text(),
16377 ctx.rule_name().map(str::to_owned),
16378 ));
16379 self.action_trees.push(ctx.tree().map(Node::text));
16380 true
16381 }
16382 }
16383
16384 #[derive(Debug, Default)]
16385 struct RejectingPredicateHooks {
16386 predicates: Vec<(usize, usize, usize, Option<String>)>,
16387 }
16388
16389 impl SemanticHooks for RejectingPredicateHooks {
16390 fn sempred<S>(
16391 &mut self,
16392 ctx: &mut ParserSemCtx<'_, S>,
16393 rule_index: usize,
16394 pred_index: usize,
16395 ) -> Option<bool>
16396 where
16397 S: TokenSource,
16398 {
16399 self.predicates.push((
16400 ctx.input_index(),
16401 rule_index,
16402 pred_index,
16403 ctx.token_text(1).map(|token| token.text().to_owned()),
16404 ));
16405 Some(false)
16406 }
16407 }
16408
16409 #[test]
16410 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
16411 let atn = predicate_gated_same_lookahead_atn([0, 0]);
16412 let mut parser = mini_parser_with_hooks(
16413 vec![
16414 TestToken::new(1).with_text("x"),
16415 TestToken::eof("parser-test", 1, 1, 1),
16416 ],
16417 RecordingHooks::default(),
16418 );
16419
16420 let (tree, _) = parser
16421 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16422 .expect("both alternatives share one replay-safe predicate result");
16423
16424 assert_eq!(parser.node(tree).text(), "x<EOF>");
16425 assert_eq!(
16426 parser.semantic_hooks.predicates,
16427 vec![(0, 0, 0, Some("x".to_owned()))]
16428 );
16429 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
16430 }
16431
16432 #[test]
16433 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
16434 let atn = predicate_after_token_atn();
16435 let mut parser = mini_parser_with_hooks(
16436 vec![
16437 TestToken::new(1).with_text("x"),
16438 TestToken::new(2).with_text("y"),
16439 TestToken::eof("parser-test", 2, 1, 2),
16440 ],
16441 RecordingHooks::default(),
16442 );
16443
16444 let (tree, _) = parser
16445 .parse_atn_rule_with_runtime_options(
16446 &atn,
16447 0,
16448 ParserRuntimeOptions {
16449 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16450 ..ParserRuntimeOptions::default()
16451 },
16452 )
16453 .expect("hook supplies the missing predicate result");
16454
16455 assert_eq!(parser.node(tree).text(), "xy");
16456 assert_eq!(
16457 parser.semantic_hooks.predicates,
16458 vec![(1, 0, 0, Some("y".to_owned()))]
16459 );
16460 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
16461 }
16462
16463 #[test]
16464 fn runtime_options_default_preserves_semantic_hook_predicates() {
16465 let atn = predicate_after_token_atn();
16466 let mut parser = mini_parser_with_hooks(
16467 vec![
16468 TestToken::new(1).with_text("x"),
16469 TestToken::new(2).with_text("y"),
16470 TestToken::eof("parser-test", 2, 1, 2),
16471 ],
16472 RejectingPredicateHooks::default(),
16473 );
16474
16475 let result =
16476 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
16477
16478 assert!(
16479 result.is_err(),
16480 "default runtime options must not bypass semantic hooks for predicate ATNs"
16481 );
16482 assert_eq!(
16483 parser.semantic_hooks.predicates,
16484 vec![(1, 0, 0, Some("y".to_owned()))]
16485 );
16486 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
16487 }
16488
16489 #[test]
16490 fn semantic_hook_handles_committed_parser_action() {
16491 let atn = token_then_eof_atn();
16492 let mut parser = mini_parser_with_hooks(
16493 vec![
16494 TestToken::new(1).with_text("x"),
16495 TestToken::eof("parser-test", 1, 1, 1),
16496 ],
16497 RecordingHooks::default(),
16498 );
16499 let (tree, _) = parser
16500 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16501 .expect("rule parses before action hook is tested");
16502
16503 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
16504 assert_eq!(
16505 parser.semantic_hooks.actions,
16506 vec![(42, "x".to_owned(), Some("s".to_owned()))]
16507 );
16508 assert_eq!(
16509 parser.semantic_hooks.action_trees,
16510 [Some("x<EOF>".to_owned())]
16511 );
16512 }
16513
16514 #[test]
16515 fn unhandled_committed_action_fails_loud_under_error_policy() {
16516 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16520 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
16521 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
16522
16523 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
16525
16526 let error = parser
16527 .take_unknown_semantic_error()
16528 .expect("an unhandled committed action under Error policy must fail loud");
16529 let AntlrError::Unsupported(message) = error else {
16530 panic!("expected AntlrError::Unsupported, got {error:?}");
16531 };
16532 assert!(
16533 message.contains("unhandled semantic action") && message.contains("state=42"),
16534 "message should name the dropped action coordinate: {message}"
16535 );
16536
16537 let mut lenient =
16539 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16540 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
16541 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
16542 assert!(lenient.take_unknown_semantic_error().is_none());
16543 }
16544
16545 #[test]
16546 fn translated_predicate_is_unaffected_by_error_policy() {
16547 let atn = predicate_after_token_atn();
16548 let mut parser = mini_parser(vec![
16549 TestToken::new(1).with_text("x"),
16550 TestToken::new(2).with_text("y"),
16551 TestToken::eof("parser-test", 2, 1, 2),
16552 ]);
16553
16554 let (tree, _) = parser
16555 .parse_atn_rule_with_runtime_options(
16556 &atn,
16557 0,
16558 ParserRuntimeOptions {
16559 predicates: &[(0, 0, ParserPredicate::True)],
16560 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16561 ..ParserRuntimeOptions::default()
16562 },
16563 )
16564 .expect("a predicate covered by the table is not an unknown coordinate");
16565
16566 assert_eq!(parser.node(tree).text(), "xy");
16567 }
16568
16569 fn hook_predicate_semantics() -> ParserSemantics {
16574 let mut ir = SemIr::new();
16575 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
16576 ParserSemantics {
16577 ir,
16578 predicates: vec![ParserSemanticPredicate {
16579 rule_index: 0,
16580 pred_index: 0,
16581 expr,
16582 failure_message: None,
16583 }],
16584 actions: Vec::new(),
16585 }
16586 }
16587
16588 #[derive(Debug, Default)]
16589 struct DecliningHooks;
16590
16591 impl SemanticHooks for DecliningHooks {}
16592
16593 #[test]
16594 fn semir_hook_none_falls_through_to_assume_true() {
16595 let atn = predicate_after_token_atn();
16596 let semantics = hook_predicate_semantics();
16597 let mut parser = mini_parser_with_hooks(
16598 vec![
16599 TestToken::new(1).with_text("x"),
16600 TestToken::new(2).with_text("y"),
16601 TestToken::eof("parser-test", 2, 1, 2),
16602 ],
16603 DecliningHooks,
16604 );
16605
16606 let (tree, _) = parser
16607 .parse_atn_rule_with_runtime_options(
16608 &atn,
16609 0,
16610 ParserRuntimeOptions {
16611 semantics: Some(&semantics),
16612 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
16613 ..ParserRuntimeOptions::default()
16614 },
16615 )
16616 .expect("a declined SemIR hook must pass under assume-true");
16617
16618 assert_eq!(parser.node(tree).text(), "xy");
16619 }
16620
16621 #[test]
16622 fn semir_hook_none_falls_through_to_assume_false() {
16623 let atn = predicate_after_token_atn();
16624 let semantics = hook_predicate_semantics();
16625 let mut parser = mini_parser_with_hooks(
16626 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 DecliningHooks,
16632 );
16633
16634 let result = parser.parse_atn_rule_with_runtime_options(
16635 &atn,
16636 0,
16637 ParserRuntimeOptions {
16638 semantics: Some(&semantics),
16639 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
16640 ..ParserRuntimeOptions::default()
16641 },
16642 );
16643
16644 assert!(
16645 result.is_err(),
16646 "a declined SemIR hook must fail the only guarded path under assume-false"
16647 );
16648 }
16649
16650 #[test]
16651 fn semir_hook_none_records_coordinate_under_error_policy() {
16652 let atn = predicate_after_token_atn();
16653 let semantics = hook_predicate_semantics();
16654 let mut parser = mini_parser_with_hooks(
16655 vec![
16656 TestToken::new(1).with_text("x"),
16657 TestToken::new(2).with_text("y"),
16658 TestToken::eof("parser-test", 2, 1, 2),
16659 ],
16660 DecliningHooks,
16661 );
16662
16663 let error = parser
16664 .parse_atn_rule_with_runtime_options(
16665 &atn,
16666 0,
16667 ParserRuntimeOptions {
16668 semantics: Some(&semantics),
16669 unknown_predicate_policy: UnknownSemanticPolicy::Error,
16670 ..ParserRuntimeOptions::default()
16671 },
16672 )
16673 .expect_err("a declined SemIR hook under Error policy must fail the parse");
16674
16675 let AntlrError::Unsupported(message) = error else {
16676 panic!("expected AntlrError::Unsupported, got {error:?}");
16677 };
16678 assert!(
16679 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
16680 "message should name the unresolved coordinate: {message}"
16681 );
16682 }
16683
16684 #[test]
16685 fn generated_direct_predicate_honors_installed_policy() {
16686 let semantics = hook_predicate_semantics();
16692 let context = ParserRuleContext::new(0, -1);
16693
16694 let mut assume_true =
16695 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16696 assert!(
16697 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
16698 &semantics, 0, 0, &context, 0
16699 ),
16700 "default AssumeTrue accepts a declined hook"
16701 );
16702 assert!(assume_true.take_unknown_semantic_error().is_none());
16703
16704 let mut error_policy =
16705 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
16706 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
16707 assert!(
16708 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
16709 &semantics, 0, 0, &context, 0
16710 ),
16711 "Error policy rejects a declined hook on the generated-direct path"
16712 );
16713 let error = error_policy
16714 .take_unknown_semantic_error()
16715 .expect("Error policy records the unresolved coordinate for the generated path");
16716 let AntlrError::Unsupported(message) = error else {
16717 panic!("expected AntlrError::Unsupported, got {error:?}");
16718 };
16719 assert!(message.contains("pred_index=0"), "message: {message}");
16720 }
16721
16722 #[test]
16723 fn parser_rule_start_skips_leading_hidden_tokens() {
16724 let atn = token_then_eof_atn();
16725 let mut parser = mini_parser(vec![
16726 TestToken::new(99)
16727 .with_text(" ")
16728 .with_channel(HIDDEN_CHANNEL),
16729 TestToken::new(1).with_text("x"),
16730 TestToken::eof("parser-test", 2, 1, 2),
16731 ]);
16732
16733 let tree = parser
16734 .parse_atn_rule(&atn, 0)
16735 .expect("artificial parser rule should parse");
16736 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
16737 panic!("rule node should be present");
16738 };
16739 assert_eq!(
16740 rule.start()
16741 .expect("rule should have a start token")
16742 .token_type(),
16743 1
16744 );
16745 }
16746
16747 #[test]
16748 fn parser_action_after_eof_stops_at_eof_token() {
16749 let atn = eof_then_action_atn();
16750 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
16751
16752 let (_, actions) = parser
16753 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16754 .expect("EOF action rule should parse");
16755
16756 assert_eq!(actions.len(), 1);
16757 assert_eq!(actions[0].stop_index(), Some(0));
16758 assert_eq!(
16759 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
16760 ""
16761 );
16762 }
16763
16764 #[test]
16765 fn after_action_stop_uses_rule_context_stop_not_cursor() {
16766 let mut id = TestToken::new(1).with_text("x");
16771 id.set_token_index(0);
16772 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
16773 eof.set_token_index(1);
16774 let mut parser = mini_parser(vec![id.clone(), eof]);
16775 parser.consume();
16777 assert_eq!(parser.la(1), TOKEN_EOF);
16778
16779 let mut ctx = ParserRuleContext::new(0, 0);
16782 parser.set_context_stop(
16783 &mut ctx,
16784 parser.token_id_at(0).expect("ID token should be buffered"),
16785 );
16786 let tree = parser.rule_node(ctx);
16787
16788 let current_index = parser.input.index();
16789 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
16791 assert_eq!(
16793 parser.after_action_stop_index_for_tree(tree, current_index),
16794 Some(0)
16795 );
16796 }
16797
16798 #[test]
16799 fn after_action_start_uses_rule_context_start_not_cursor() {
16800 let mut parser = mini_parser(vec![
16805 TestToken::new(9)
16806 .with_text(" ")
16807 .with_channel(HIDDEN_CHANNEL),
16808 TestToken::new(9)
16809 .with_text(" ")
16810 .with_channel(HIDDEN_CHANNEL),
16811 TestToken::new(1).with_text("x"),
16812 TestToken::eof("parser-test", 3, 1, 3),
16813 ]);
16814
16815 let mut ctx = ParserRuleContext::new(0, 0);
16816 parser.set_context_start(
16817 &mut ctx,
16818 parser.token_id_at(2).expect("ID token should be buffered"),
16819 );
16820 let tree = parser.rule_node(ctx);
16821
16822 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
16825
16826 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
16828 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
16829 }
16830
16831 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
16832 FastRecognizeOutcome {
16833 index,
16834 consumed_eof,
16835 diagnostics: DiagnosticSeqId::EMPTY,
16836 deferred_nodes: FastDeferredNodeId::EMPTY,
16837 nodes: NodeSeqId(marker),
16838 }
16839 }
16840
16841 #[test]
16842 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
16843 let mut outcomes = vec![
16844 clean_fast_outcome(4, false, 0),
16845 clean_fast_outcome(2, false, 1),
16846 clean_fast_outcome(4, false, 2),
16847 clean_fast_outcome(4, true, 3),
16848 clean_fast_outcome(2, false, 4),
16849 ];
16850 let mut scratch = FastOutcomeDedupScratch::default();
16851
16852 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16853
16854 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
16855 assert_eq!(
16856 outcomes
16857 .iter()
16858 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
16859 .collect::<Vec<_>>(),
16860 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
16861 );
16862 assert!(scratch.dense_words.is_empty());
16863 assert!(scratch.sparse_keys.is_empty());
16864 }
16865
16866 #[test]
16867 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
16868 let mut scratch = FastOutcomeDedupScratch::default();
16869 let mut outcomes = (100..109)
16870 .flat_map(|index| {
16871 [
16872 clean_fast_outcome(
16873 index,
16874 false,
16875 u32::try_from(index).expect("test index fits in u32"),
16876 ),
16877 clean_fast_outcome(index, false, u32::MAX),
16878 ]
16879 })
16880 .collect();
16881
16882 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16883
16884 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
16885 assert_eq!(outcomes.len(), 9);
16886 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
16887 let dense_capacity = scratch.dense_words.capacity();
16888
16889 let mut reused = (1_000..1_009)
16890 .map(|index| {
16891 clean_fast_outcome(
16892 index,
16893 false,
16894 u32::try_from(index).expect("test index fits in u32"),
16895 )
16896 })
16897 .collect();
16898 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
16899
16900 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
16901 assert_eq!(reused.len(), 9);
16902 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
16903 }
16904
16905 #[test]
16906 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
16907 let mut scratch = FastOutcomeDedupScratch::default();
16908 let sparse_indexes = [
16909 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
16910 ];
16911 let mut outcomes = sparse_indexes
16912 .into_iter()
16913 .chain([400_000])
16914 .enumerate()
16915 .map(|(marker, index)| {
16916 clean_fast_outcome(
16917 index,
16918 false,
16919 u32::try_from(marker).expect("test marker fits in u32"),
16920 )
16921 })
16922 .collect();
16923
16924 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16925
16926 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16927 assert_eq!(outcomes.len(), sparse_indexes.len());
16928 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
16929 let sparse_capacity = scratch.sparse_keys.capacity();
16930
16931 let mut reused = sparse_indexes
16932 .into_iter()
16933 .map(|index| {
16934 clean_fast_outcome(
16935 index,
16936 false,
16937 u32::try_from(index).expect("test index fits in u32"),
16938 )
16939 })
16940 .collect();
16941 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
16942
16943 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16944 assert_eq!(reused.len(), sparse_indexes.len());
16945 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
16946 }
16947
16948 #[test]
16949 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
16950 let mut scratch = FastOutcomeDedupScratch::default();
16951 scratch
16952 .sparse_keys
16953 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
16954 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
16955 let mut outcomes = (0..9)
16956 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
16957 .collect();
16958
16959 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
16960
16961 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
16962 assert!(scratch.sparse_keys.is_empty());
16963 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
16964 }
16965
16966 #[test]
16967 fn fast_outcome_selection_respects_sll_tie_order() {
16968 let mut arena = RecognitionArena::default();
16969 let first = FastRecognizeOutcome {
16970 index: 1,
16971 consumed_eof: false,
16972 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
16973 line: 1,
16974 column: 0,
16975 message: "mismatched input 'x'".to_owned(),
16976 }]),
16977 deferred_nodes: FastDeferredNodeId::EMPTY,
16978 nodes: NodeSeqId::EMPTY,
16979 };
16980 let second = FastRecognizeOutcome {
16981 index: first.index,
16982 consumed_eof: first.consumed_eof,
16983 diagnostics: DiagnosticSeqId::EMPTY,
16984 deferred_nodes: FastDeferredNodeId::EMPTY,
16985 nodes: NodeSeqId::EMPTY,
16986 };
16987
16988 let selected = select_best_fast_outcome(
16989 [first, second].into_iter(),
16990 PredictionMode::Sll,
16991 None,
16992 |_| panic!("caller-follow token probe should not run"),
16993 &arena,
16994 )
16995 .expect("one outcome should be selected");
16996 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
16997 let eof_second = FastRecognizeOutcome {
16998 index: second.index,
16999 consumed_eof: true,
17000 diagnostics: DiagnosticSeqId::EMPTY,
17001 deferred_nodes: FastDeferredNodeId::EMPTY,
17002 nodes: NodeSeqId::EMPTY,
17003 };
17004 let selected = select_best_fast_outcome(
17005 [first, eof_second].into_iter(),
17006 PredictionMode::Sll,
17007 None,
17008 |_| panic!("caller-follow token probe should not run"),
17009 &arena,
17010 )
17011 .expect("one outcome should be selected");
17012 assert!(!selected.consumed_eof);
17013 let selected = select_best_fast_outcome(
17014 [first, second].into_iter(),
17015 PredictionMode::Ll,
17016 None,
17017 |_| panic!("caller-follow token probe should not run"),
17018 &arena,
17019 )
17020 .expect("one outcome should be selected");
17021 assert!(selected.diagnostics.is_empty());
17022 }
17023
17024 #[test]
17025 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
17026 let mut arena = RecognitionArena::default();
17027 let first = FastRecognizeOutcome {
17028 index: 3,
17029 consumed_eof: false,
17030 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17031 line: 1,
17032 column: 0,
17033 message: "mismatched input 'x' expecting 'a'".to_owned(),
17034 }]),
17035 deferred_nodes: FastDeferredNodeId::EMPTY,
17036 nodes: NodeSeqId::EMPTY,
17037 };
17038 let same_rank = FastRecognizeOutcome {
17039 index: first.index,
17040 consumed_eof: first.consumed_eof,
17041 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17042 line: 1,
17043 column: 0,
17044 message: "mismatched input 'x' expecting 'b'".to_owned(),
17045 }]),
17046 deferred_nodes: FastDeferredNodeId::EMPTY,
17047 nodes: NodeSeqId::EMPTY,
17048 };
17049 let better_rank = FastRecognizeOutcome {
17050 index: first.index,
17051 consumed_eof: first.consumed_eof,
17052 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
17053 line: 1,
17054 column: 0,
17055 message: "missing 'a' at 'x'".to_owned(),
17056 }]),
17057 deferred_nodes: FastDeferredNodeId::EMPTY,
17058 nodes: NodeSeqId::EMPTY,
17059 };
17060 let mut outcomes = vec![first, same_rank, better_rank];
17061
17062 dedupe_fast_outcomes(&mut outcomes, &arena);
17063
17064 assert_eq!(outcomes.len(), 2);
17065 assert_eq!(
17066 arena
17067 .diagnostics(outcomes[0].diagnostics)
17068 .next()
17069 .expect("first diagnostic")
17070 .message,
17071 "mismatched input 'x' expecting 'a'"
17072 );
17073 assert_eq!(
17074 arena
17075 .diagnostics(outcomes[1].diagnostics)
17076 .next()
17077 .expect("second diagnostic")
17078 .message,
17079 "missing 'a' at 'x'"
17080 );
17081 }
17082
17083 #[test]
17084 fn fast_outcome_selection_prefers_generated_caller_follow() {
17085 let arena = RecognitionArena::default();
17086 let earlier = FastRecognizeOutcome {
17087 index: 7,
17088 consumed_eof: false,
17089 diagnostics: DiagnosticSeqId::EMPTY,
17090 deferred_nodes: FastDeferredNodeId::EMPTY,
17091 nodes: NodeSeqId::EMPTY,
17092 };
17093 let later = FastRecognizeOutcome {
17094 index: 8,
17095 consumed_eof: false,
17096 diagnostics: DiagnosticSeqId::EMPTY,
17097 deferred_nodes: FastDeferredNodeId::EMPTY,
17098 nodes: NodeSeqId::EMPTY,
17099 };
17100 let mut follow = TokenBitSet::default();
17101 follow.insert(5);
17102
17103 let selected = select_best_fast_outcome(
17104 [later, earlier].into_iter(),
17105 PredictionMode::Ll,
17106 Some(&follow),
17107 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
17108 &arena,
17109 )
17110 .expect("one outcome should be selected");
17111 assert_eq!(selected.index, 7);
17112
17113 let selected = select_best_fast_outcome(
17114 [later, earlier].into_iter(),
17115 PredictionMode::Ll,
17116 Some(&follow),
17117 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
17118 &arena,
17119 )
17120 .expect("one outcome should be selected");
17121 assert_eq!(selected.index, 8);
17122
17123 let indented_next_statement = FastRecognizeOutcome {
17124 index: 9,
17125 consumed_eof: false,
17126 diagnostics: DiagnosticSeqId::EMPTY,
17127 deferred_nodes: FastDeferredNodeId::EMPTY,
17128 nodes: NodeSeqId::EMPTY,
17129 };
17130 let selected = select_best_fast_outcome(
17131 [indented_next_statement, earlier].into_iter(),
17132 PredictionMode::Ll,
17133 Some(&follow),
17134 |index| {
17135 let is_boundary = index == 7;
17136 let is_boundary_gap = matches!(index, 7 | 8);
17137 (
17138 if index == 7 { 5 } else { TOKEN_EOF },
17139 is_boundary,
17140 is_boundary_gap,
17141 )
17142 },
17143 &arena,
17144 )
17145 .expect("one outcome should be selected");
17146 assert_eq!(selected.index, 7);
17147
17148 let continuation = FastRecognizeOutcome {
17149 index: 10,
17150 consumed_eof: false,
17151 diagnostics: DiagnosticSeqId::EMPTY,
17152 deferred_nodes: FastDeferredNodeId::EMPTY,
17153 nodes: NodeSeqId::EMPTY,
17154 };
17155 let selected = select_best_fast_outcome(
17156 [continuation, earlier].into_iter(),
17157 PredictionMode::Ll,
17158 Some(&follow),
17159 |index| {
17160 let is_boundary = matches!(index, 7 | 9);
17161 (
17162 if index == 7 { 5 } else { TOKEN_EOF },
17163 is_boundary,
17164 is_boundary,
17165 )
17166 },
17167 &arena,
17168 )
17169 .expect("one outcome should be selected");
17170 assert_eq!(selected.index, 10);
17171
17172 let selected = select_best_fast_outcome(
17173 [earlier, later].into_iter(),
17174 PredictionMode::Sll,
17175 Some(&follow),
17176 |_| panic!("caller-follow token probe should not run in SLL mode"),
17177 &arena,
17178 )
17179 .expect("one outcome should be selected");
17180 assert_eq!(selected.index, 8);
17181 }
17182
17183 #[test]
17184 fn caller_follow_boundary_text_requires_separator_shape() {
17185 assert!(is_caller_follow_boundary_text(";"));
17186 assert!(is_caller_follow_boundary_text("\n"));
17187 assert!(is_caller_follow_boundary_text("\r\n "));
17188 assert!(is_caller_follow_boundary_text(";\n"));
17189 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
17190 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
17191 assert!(!is_caller_follow_boundary_text("identifier"));
17192 assert!(is_caller_follow_boundary_gap_text(" \t "));
17193 assert!(is_caller_follow_boundary_gap_text("\n "));
17194 assert!(is_caller_follow_boundary_gap_text(";\t"));
17195 assert!(!is_caller_follow_boundary_gap_text(
17196 "\"\"\"line1\nline2\"\"\""
17197 ));
17198 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
17199 }
17200
17201 #[test]
17202 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
17203 let mut parser = mini_parser(vec![
17204 TestToken::new(5).with_text("\n"),
17205 TestToken::new(6)
17206 .with_text("// comment\n")
17207 .with_channel(HIDDEN_CHANNEL),
17208 TestToken::new(1).with_text("x"),
17209 TestToken::eof("parser-test", 1, 2, 0),
17210 ]);
17211
17212 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
17213 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
17214 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
17215 }
17216
17217 #[test]
17218 fn caller_follow_token_info_uses_stream_visible_channel() {
17219 let source = Source {
17220 tokens: vec![
17221 TestToken::new(5).with_text("\n").with_channel(2),
17222 TestToken::new(1).with_text("x").with_channel(2),
17223 TestToken::new(6)
17224 .with_text("// comment\n")
17225 .with_channel(HIDDEN_CHANNEL),
17226 TestToken::eof("parser-test", 1, 2, 0),
17227 ],
17228 index: 0,
17229 };
17230 let data = RecognizerData::new(
17231 "Mini.g4",
17232 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17233 );
17234 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
17235
17236 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
17237 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
17238 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
17239 }
17240
17241 #[test]
17242 fn reset_per_parse_caches_clears_state_expected_token_cache() {
17243 let atn = token_then_eof_atn();
17244 let mut parser = mini_parser(Vec::new());
17245
17246 let _ = parser.cached_state_expected_token_set(&atn, 0);
17247 assert!(!parser.state_expected_token_cache.is_empty());
17248
17249 parser.reset_per_parse_caches();
17250 assert!(parser.state_expected_token_cache.is_empty());
17251 }
17252
17253 #[test]
17254 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
17255 let cyclic = epsilon_cycle_atn();
17256 let acyclic = token_then_eof_atn();
17257 let mut parser = mini_parser(Vec::new());
17258
17259 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
17260 assert_eq!(
17261 parser.empty_cycle_cache_atn,
17262 Some(SharedAtnCacheKey::for_atn(&cyclic))
17263 );
17264 assert_eq!(parser.empty_cycle_cache[1], Some(true));
17265
17266 parser.reset_per_parse_caches();
17267 assert_eq!(parser.empty_cycle_cache[1], Some(true));
17268 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
17269
17270 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
17271 assert_eq!(
17272 parser.empty_cycle_cache_atn,
17273 Some(SharedAtnCacheKey::for_atn(&acyclic))
17274 );
17275 assert_eq!(parser.empty_cycle_cache[1], Some(false));
17276 }
17277
17278 #[test]
17279 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
17280 let source = Source {
17281 tokens: vec![
17282 TestToken::new(1).with_text("x"),
17283 TestToken::eof("parser-test", 1, 1, 1),
17284 ],
17285 index: 0,
17286 };
17287 let data = RecognizerData::new(
17288 "Mini.g4",
17289 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17290 );
17291 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17292 let expected = ExpectedTokens {
17293 index: Some(0),
17294 symbols: BTreeSet::new(),
17295 no_viable: None,
17296 };
17297
17298 let (_, message) = parser.expected_error_message(0, 0, &expected);
17299
17300 assert_eq!(message, "mismatched input 'x'");
17301 }
17302
17303 #[test]
17304 fn eof_rule_stop_index_points_at_eof_token() {
17305 let source = Source {
17306 tokens: vec![
17307 TestToken::new(1).with_text("x"),
17308 TestToken::eof("parser-test", 1, 1, 1),
17309 ],
17310 index: 0,
17311 };
17312 let data = RecognizerData::new(
17313 "Mini.g4",
17314 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17315 );
17316 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17317
17318 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
17319 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
17320 }
17321
17322 #[test]
17323 fn generated_parser_action_uses_current_rule_stop_boundary() {
17324 let mut parser = mini_parser(vec![
17325 TestToken::new(1).with_text("x"),
17326 TestToken::eof("parser-test", 1, 1, 1),
17327 ]);
17328
17329 parser.match_token(1).expect("token should match");
17330 let action = parser.parser_action_at_current(7, 0, 0, false);
17331 assert_eq!(action.source_state(), 7);
17332 assert_eq!(action.rule_index(), 0);
17333 assert_eq!(action.start_index(), 0);
17334 assert_eq!(action.stop_index(), Some(0));
17335
17336 parser.match_eof().expect("EOF should match");
17337 let action = parser.parser_action_at_current(8, 0, 0, true);
17338 assert_eq!(action.stop_index(), Some(1));
17339 }
17340
17341 #[test]
17342 fn folds_left_recursive_boundary_into_rule_node() {
17343 let mut arena = RecognitionArena::default();
17344 let first = arena.push_node(ArenaRecognizedNode::Token {
17345 token: TokenId::try_from(0).expect("test token ID"),
17346 });
17347 let boundary =
17348 arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary { rule_index: 1 });
17349 let second = arena.push_node(ArenaRecognizedNode::Token {
17350 token: TokenId::try_from(1).expect("test token ID"),
17351 });
17352 let mut nodes = NodeSeqId::EMPTY;
17353 for node in [first, boundary, second].into_iter().rev() {
17354 nodes = arena.prepend(nodes, node);
17355 }
17356
17357 let folded = arena.fold_left_recursive_boundaries(nodes);
17358 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
17359
17360 assert_eq!(folded_nodes.len(), 2);
17361 let ArenaRecognizedNode::Rule {
17362 rule_index,
17363 invoking_state,
17364 start_index,
17365 stop_index,
17366 children,
17367 ..
17368 } = arena.node(folded_nodes[0])
17369 else {
17370 panic!("first folded node should be a rule");
17371 };
17372 assert_eq!(rule_index, 1);
17373 assert_eq!(invoking_state, -1);
17374 assert_eq!(start_index, 0);
17375 assert_eq!(stop_index, Some(0));
17376 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
17377 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
17378
17379 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
17380 assert_eq!(
17381 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17382 (4, 3, 1)
17383 );
17384 assert_eq!(
17385 (stats.total_links, stats.live_links, stats.dead_links),
17386 (9, 3, 6)
17387 );
17388 }
17389
17390 #[test]
17391 fn recognition_arena_reports_live_dead_and_retained_capacity() {
17392 let mut arena = RecognitionArena::default();
17393 let token = arena.push_node(ArenaRecognizedNode::Token {
17394 token: TokenId::try_from(0).expect("test token ID"),
17395 });
17396 let extra = arena.push_extra(RecognitionExtra::MissingToken {
17397 token_type: 2,
17398 at_index: 1,
17399 text: "<missing X>".to_owned(),
17400 });
17401 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
17402 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
17403 token: TokenId::try_from(1).expect("test token ID"),
17404 });
17405 let mut live = NodeSeqId::EMPTY;
17406 live = arena.prepend(live, missing);
17407 live = arena.prepend(live, token);
17408 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
17409 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17410 line: 1,
17411 column: 0,
17412 message: "missing X".to_owned(),
17413 }]);
17414 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17415 line: 1,
17416 column: 1,
17417 message: "discarded".to_owned(),
17418 }]);
17419 let deferred_children = arena.deferred_fragment(live);
17420 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
17421 rule_index: 0,
17422 invoking_state: -1,
17423 start_index: 0,
17424 stop_index: Some(1),
17425 deferred_children,
17426 children: NodeSeqId::EMPTY,
17427 });
17428
17429 let stats = arena.stats(live, live_diagnostics);
17430
17431 assert_eq!(
17432 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17433 (3, 2, 1)
17434 );
17435 assert_eq!(
17436 (stats.total_links, stats.live_links, stats.dead_links),
17437 (5, 3, 2)
17438 );
17439 assert_eq!(
17440 (stats.total_extras, stats.live_extras, stats.dead_extras),
17441 (3, 2, 1)
17442 );
17443 assert!(size_of::<SeqLink>() <= 8);
17444 assert!(size_of::<DiagnosticLink>() <= 8);
17445 assert!(size_of::<FastDeferredNode>() <= 12);
17446 assert!(size_of::<FastDeferredRule>() <= 28);
17447 assert!(size_of::<FastRecognizeOutcome>() <= 24);
17448 let capacities = (
17449 stats.node_capacity,
17450 stats.link_capacity,
17451 stats.extra_capacity,
17452 );
17453 let deferred_capacities = (
17454 arena.deferred_nodes.capacity(),
17455 arena.deferred_rules.capacity(),
17456 );
17457
17458 arena.reset();
17459 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
17460 assert_eq!(
17461 (reset.total_nodes, reset.total_links, reset.total_extras),
17462 (0, 0, 0)
17463 );
17464 assert_eq!(
17465 (
17466 reset.node_capacity,
17467 reset.link_capacity,
17468 reset.extra_capacity,
17469 ),
17470 capacities
17471 );
17472 assert!(arena.deferred_nodes.is_empty());
17473 assert!(arena.deferred_rules.is_empty());
17474 assert_eq!(
17475 (
17476 arena.deferred_nodes.capacity(),
17477 arena.deferred_rules.capacity(),
17478 ),
17479 deferred_capacities
17480 );
17481 }
17482
17483 #[test]
17484 fn parser_computes_recognition_arena_stats_on_demand() {
17485 let mut parser = mini_parser(Vec::new());
17486 let live = parser
17487 .recognition_arena
17488 .push_node(ArenaRecognizedNode::Token {
17489 token: TokenId::try_from(0).expect("test token ID"),
17490 });
17491 let discarded = parser
17492 .recognition_arena
17493 .push_node(ArenaRecognizedNode::ErrorToken {
17494 token: TokenId::try_from(1).expect("test token ID"),
17495 });
17496 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
17497 let _discarded_root = parser
17498 .recognition_arena
17499 .prepend(NodeSeqId::EMPTY, discarded);
17500 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
17501
17502 let stats = parser.recognition_arena_stats();
17503
17504 assert_eq!(
17505 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
17506 (2, 1, 1)
17507 );
17508 assert_eq!(
17509 (stats.total_links, stats.live_links, stats.dead_links),
17510 (2, 1, 1)
17511 );
17512 }
17513
17514 #[test]
17515 fn recognition_arena_drops_capacity_above_retention_limit() {
17516 let mut storage = Vec::<u8>::with_capacity(4);
17517 storage.extend([1, 2, 3]);
17518
17519 reset_arena_vec(&mut storage, 3);
17520
17521 assert!(storage.is_empty());
17522 assert_eq!(storage.capacity(), 0);
17523 }
17524
17525 #[test]
17526 fn recognition_arena_concatenates_diagnostics_in_source_order() {
17527 let mut arena = RecognitionArena::default();
17528 let prefix = arena.diagnostic_sequence([
17529 ParserDiagnostic {
17530 line: 1,
17531 column: 0,
17532 message: "first".to_owned(),
17533 },
17534 ParserDiagnostic {
17535 line: 1,
17536 column: 1,
17537 message: "second".to_owned(),
17538 },
17539 ]);
17540 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
17541 line: 1,
17542 column: 2,
17543 message: "third".to_owned(),
17544 }]);
17545 let extras_before = arena.extras.len();
17546
17547 let combined = arena.concat_diagnostics(prefix, suffix);
17548 let messages = arena
17549 .diagnostics(combined)
17550 .map(|diagnostic| diagnostic.message.as_str())
17551 .collect::<Vec<_>>();
17552
17553 assert_eq!(messages, ["first", "second", "third"]);
17554 assert_eq!(arena.extras.len(), extras_before);
17555 }
17556
17557 #[test]
17558 fn outcome_ties_keep_later_non_recursive_alternative() {
17559 let arena = RecognitionArena::default();
17560 let first = RecognizeOutcome {
17561 index: 1,
17562 consumed_eof: false,
17563 alt_number: 0,
17564 member_values: BTreeMap::new(),
17565 return_values: BTreeMap::new(),
17566 diagnostics: DiagnosticSeqId::EMPTY,
17567 decisions: Vec::new(),
17568 actions: vec![ParserAction::new(1, 0, 0, None)],
17569 nodes: NodeSeqId::EMPTY,
17570 };
17571 let second = RecognizeOutcome {
17572 actions: vec![ParserAction::new(2, 0, 0, None)],
17573 ..first.clone()
17574 };
17575
17576 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17577 .expect("one outcome should be selected");
17578 assert_eq!(selected.actions[0].source_state(), 2);
17579 }
17580
17581 #[test]
17582 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
17583 let arena = RecognitionArena::default();
17584 let first = RecognizeOutcome {
17585 index: 1,
17586 consumed_eof: false,
17587 alt_number: 0,
17588 member_values: BTreeMap::new(),
17589 return_values: BTreeMap::new(),
17590 diagnostics: DiagnosticSeqId::EMPTY,
17591 decisions: Vec::new(),
17592 actions: vec![ParserAction::new(1, 0, 0, None)],
17593 nodes: NodeSeqId::EMPTY,
17594 };
17595 let second = RecognizeOutcome {
17596 actions: vec![
17597 ParserAction::new(2, 0, 0, None),
17598 ParserAction::new(3, 0, 0, None),
17599 ],
17600 ..first.clone()
17601 };
17602
17603 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
17604 .expect("one outcome should be selected");
17605 assert_eq!(selected.actions.len(), 2);
17606 }
17607
17608 #[test]
17609 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
17610 let arena = RecognitionArena::default();
17611 let first = RecognizeOutcome {
17612 index: 7,
17613 consumed_eof: false,
17614 alt_number: 0,
17615 member_values: BTreeMap::new(),
17616 return_values: BTreeMap::new(),
17617 diagnostics: DiagnosticSeqId::EMPTY,
17618 decisions: vec![1, 0],
17619 actions: vec![
17620 ParserAction::new(23, 2, 2, Some(4)),
17621 ParserAction::new(23, 2, 0, Some(6)),
17622 ],
17623 nodes: NodeSeqId::EMPTY,
17624 };
17625 let second = RecognizeOutcome {
17626 decisions: vec![0, 1],
17627 actions: vec![
17628 ParserAction::new(23, 2, 2, Some(6)),
17629 ParserAction::new(23, 2, 0, Some(6)),
17630 ],
17631 ..first.clone()
17632 };
17633
17634 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17635 .expect("one outcome should be selected");
17636 assert_eq!(selected.actions[0].stop_index(), Some(6));
17637 }
17638
17639 #[test]
17640 fn outcome_ties_keep_first_recursive_tree_shape() {
17641 let mut arena = RecognitionArena::default();
17642 let token = arena.push_node(ArenaRecognizedNode::Token {
17643 token: TokenId::try_from(0).expect("test token ID"),
17644 });
17645 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
17646 let inner = arena.push_node(ArenaRecognizedNode::Rule {
17647 rule_index: 1,
17648 invoking_state: -1,
17649 alt_number: 0,
17650 start_index: 0,
17651 stop_index: Some(0),
17652 return_values: None,
17653 children: token_children,
17654 });
17655 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
17656 let outer = arena.push_node(ArenaRecognizedNode::Rule {
17657 rule_index: 1,
17658 invoking_state: -1,
17659 alt_number: 0,
17660 start_index: 0,
17661 stop_index: Some(0),
17662 return_values: None,
17663 children: inner_children,
17664 });
17665 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
17666 let first = RecognizeOutcome {
17667 index: 1,
17668 consumed_eof: false,
17669 alt_number: 0,
17670 member_values: BTreeMap::new(),
17671 return_values: BTreeMap::new(),
17672 diagnostics: DiagnosticSeqId::EMPTY,
17673 decisions: Vec::new(),
17674 actions: vec![ParserAction::new(1, 0, 0, None)],
17675 nodes: recursive_nodes,
17676 };
17677 let second = RecognizeOutcome {
17678 index: 1,
17679 consumed_eof: false,
17680 alt_number: 0,
17681 member_values: BTreeMap::new(),
17682 return_values: BTreeMap::new(),
17683 diagnostics: DiagnosticSeqId::EMPTY,
17684 decisions: Vec::new(),
17685 actions: vec![ParserAction::new(2, 0, 0, None)],
17686 nodes: recursive_nodes,
17687 };
17688
17689 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
17690 .expect("one outcome should be selected");
17691 assert_eq!(selected.actions[0].source_state(), 1);
17692 }
17693
17694 #[test]
17695 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
17696 let mut arena = RecognitionArena::default();
17697 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
17698 line: 1,
17699 column: 3,
17700 message: "missing 'Y' at '<EOF>'".to_owned(),
17701 }]);
17702 let first_alt = RecognizeOutcome {
17703 index: 2,
17704 consumed_eof: true,
17705 alt_number: 0,
17706 member_values: BTreeMap::new(),
17707 return_values: BTreeMap::new(),
17708 diagnostics: recovered_diagnostics,
17709 decisions: vec![0],
17710 actions: vec![ParserAction::new(1, 0, 0, None)],
17711 nodes: NodeSeqId::EMPTY,
17712 };
17713 let second_alt = RecognizeOutcome {
17714 diagnostics: DiagnosticSeqId::EMPTY,
17715 decisions: vec![1],
17716 actions: vec![ParserAction::new(2, 0, 0, None)],
17717 ..first_alt.clone()
17718 };
17719
17720 let selected = select_best_outcome(
17721 [second_alt, first_alt].into_iter(),
17722 PredictionMode::Sll,
17723 &arena,
17724 )
17725 .expect("one outcome should be selected");
17726 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
17727 assert_eq!(selected.decisions, [0]);
17728 }
17729}