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 GENERATED_RULE_STACK_CHECK_INTERVAL: usize = 8;
117const ADAPTIVE_DIRECT_STEP_LIMIT: usize = RECOGNITION_DEPTH_LIMIT;
121
122pub fn grow_generated_rule_stack<R>(body: impl FnOnce() -> R) -> R {
129 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, body)
130}
131
132pub trait ParseListener: Send {
180 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError>;
185
186 fn exit_every_rule(&mut self, rule_index: usize) {
190 let _ = rule_index;
191 }
192}
193
194impl<T: ParseListener + ?Sized> ParseListener for Box<T> {
198 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError> {
199 (**self).enter_every_rule(event)
200 }
201
202 fn exit_every_rule(&mut self, rule_index: usize) {
203 (**self).exit_every_rule(rule_index);
204 }
205}
206
207#[derive(Debug)]
212#[non_exhaustive]
213pub struct EnterRuleEvent<'a> {
214 pub rule_index: usize,
217 pub current: Option<TokenView<'a>>,
220}
221
222struct ParseListenerSlot(Box<dyn ParseListener>);
223
224impl std::fmt::Debug for ParseListenerSlot {
225 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
226 f.write_str("ParseListener")
227 }
228}
229const CLEAN_MEMO_PROBE_LIMIT: usize = 4096;
233const CLEAN_MEMO_REPEAT_LIMIT: usize = 8;
234const CLEAN_MEMO_REPROBE_INTERVAL: usize = 262_144;
237const FAST_RECOGNIZE_VISITING_CAPACITY: usize = 256;
238const FAST_RECOGNIZE_MIN_MEMO_CAPACITY: usize = 256;
239const FAST_RECOGNIZE_MAX_MEMO_CAPACITY: usize = 524_288;
240const FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY: usize = 65_536;
241
242#[derive(Clone, Copy, Debug, Eq, PartialEq)]
243enum CleanMemoMode {
244 Probe,
245 Promote,
246 Sparse,
247}
248
249fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
250 intervals
251 .iter()
252 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
253}
254
255fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
256 let mut symbols = BTreeSet::new();
257 for (start, stop) in intervals {
258 symbols.extend(*start..=*stop);
259 }
260 symbols
261}
262
263fn interval_complement_symbols(
264 intervals: &[(i32, i32)],
265 min_vocabulary: i32,
266 max_vocabulary: i32,
267) -> BTreeSet<i32> {
268 (min_vocabulary..=max_vocabulary)
269 .filter(|symbol| !interval_set_contains(intervals, *symbol))
270 .collect()
271}
272
273#[cfg(feature = "perf-counters")]
274mod perf_counters {
275 use std::cell::Cell;
276 thread_local! {
277 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
278 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
279 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
280 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
281 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
282 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
283 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
284 pub(super) static OUTCOME_DEDUPE_INPUTS: Cell<u64> = const { Cell::new(0) };
285 pub(super) static OUTCOME_DEDUPE_REMOVED: Cell<u64> = const { Cell::new(0) };
286 pub(super) static OUTCOME_DEDUPE_INLINE: Cell<u64> = const { Cell::new(0) };
287 pub(super) static OUTCOME_DEDUPE_DENSE: Cell<u64> = const { Cell::new(0) };
288 pub(super) static OUTCOME_DEDUPE_SPARSE: Cell<u64> = const { Cell::new(0) };
289 pub(super) static OUTCOME_DEDUPE_DENSE_WORDS: Cell<u64> = const { Cell::new(0) };
290 }
291 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
292 c.with(|v| v.set(v.get() + n));
293 }
294 thread_local! {
295 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
296 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
297 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
298 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
299 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
300 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
301 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
302 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
303 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
304 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
305 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
306 }
307 pub(super) fn snapshot() -> [(&'static str, u64); 24] {
308 [
309 ("rfs_calls", RFS_CALLS.with(Cell::get)),
310 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
311 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
312 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
313 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
314 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
315 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
316 (
317 "outcome_dedupe_inputs",
318 OUTCOME_DEDUPE_INPUTS.with(Cell::get),
319 ),
320 (
321 "outcome_dedupe_removed",
322 OUTCOME_DEDUPE_REMOVED.with(Cell::get),
323 ),
324 (
325 "outcome_dedupe_inline",
326 OUTCOME_DEDUPE_INLINE.with(Cell::get),
327 ),
328 ("outcome_dedupe_dense", OUTCOME_DEDUPE_DENSE.with(Cell::get)),
329 (
330 "outcome_dedupe_sparse",
331 OUTCOME_DEDUPE_SPARSE.with(Cell::get),
332 ),
333 (
334 "outcome_dedupe_dense_words",
335 OUTCOME_DEDUPE_DENSE_WORDS.with(Cell::get),
336 ),
337 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
338 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
339 (
340 "atom_range_transitions",
341 ATOM_RANGE_TRANSITIONS.with(Cell::get),
342 ),
343 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
344 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
345 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
346 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
347 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
348 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
349 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
350 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
351 ]
352 }
353 pub fn reset() {
354 RFS_CALLS.with(|c| c.set(0));
355 RFS_MEMO_HITS.with(|c| c.set(0));
356 RFS_MEMO_MISSES.with(|c| c.set(0));
357 RFS_VISITING_CYCLE.with(|c| c.set(0));
358 MEMO_INSERTED.with(|c| c.set(0));
359 OUTCOMES_PUSHED.with(|c| c.set(0));
360 OUTCOMES_CLONED.with(|c| c.set(0));
361 OUTCOME_DEDUPE_INPUTS.with(|c| c.set(0));
362 OUTCOME_DEDUPE_REMOVED.with(|c| c.set(0));
363 OUTCOME_DEDUPE_INLINE.with(|c| c.set(0));
364 OUTCOME_DEDUPE_DENSE.with(|c| c.set(0));
365 OUTCOME_DEDUPE_SPARSE.with(|c| c.set(0));
366 OUTCOME_DEDUPE_DENSE_WORDS.with(|c| c.set(0));
367 EPSILON_TRANSITIONS.with(|c| c.set(0));
368 RULE_TRANSITIONS.with(|c| c.set(0));
369 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
370 SINGLE_TRANS_BODY.with(|c| c.set(0));
371 MULTI_TRANS_BODY.with(|c| c.set(0));
372 SINGLE_TRANS_RULE.with(|c| c.set(0));
373 SINGLE_TRANS_ATOM.with(|c| c.set(0));
374 SINGLE_TRANS_OTHER.with(|c| c.set(0));
375 OUTCOMES_RETURN_0.with(|c| c.set(0));
376 OUTCOMES_RETURN_1.with(|c| c.set(0));
377 OUTCOMES_RETURN_N.with(|c| c.set(0));
378 }
379 pub fn dump() {
380 for (name, value) in snapshot() {
381 #[allow(clippy::print_stderr)]
382 {
383 eprintln!("perf {name}={value}");
384 }
385 }
386 }
387}
388
389#[cfg(feature = "perf-counters")]
390pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
391const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
396#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
405pub struct ParserAction {
406 source_state: usize,
407 rule_index: usize,
408 start_index: usize,
409 stop_index: Option<usize>,
410 rule_init: bool,
411 expected_state: Option<usize>,
412}
413
414impl ParserAction {
415 pub const fn new(
417 source_state: usize,
418 rule_index: usize,
419 start_index: usize,
420 stop_index: Option<usize>,
421 ) -> Self {
422 Self {
423 source_state,
424 rule_index,
425 start_index,
426 stop_index,
427 rule_init: false,
428 expected_state: None,
429 }
430 }
431
432 pub const fn new_rule_init(
434 rule_index: usize,
435 start_index: usize,
436 expected_state: Option<usize>,
437 ) -> Self {
438 Self {
439 source_state: usize::MAX,
440 rule_index,
441 start_index,
442 stop_index: None,
443 rule_init: true,
444 expected_state,
445 }
446 }
447
448 pub const fn source_state(&self) -> usize {
450 self.source_state
451 }
452
453 pub const fn rule_index(&self) -> usize {
455 self.rule_index
456 }
457
458 pub const fn start_index(&self) -> usize {
460 self.start_index
461 }
462
463 pub const fn stop_index(&self) -> Option<usize> {
465 self.stop_index
466 }
467
468 pub const fn is_rule_init(&self) -> bool {
470 self.rule_init
471 }
472
473 pub const fn expected_state(&self) -> Option<usize> {
475 self.expected_state
476 }
477}
478
479pub struct ParserSemCtx<'a, S>
487where
488 S: TokenSource,
489{
490 input: &'a mut CommonTokenStream<S>,
491 tree_storage: &'a ParseTreeStorage,
492 rule_index: usize,
493 coordinate_index: usize,
494 rule_name: Option<String>,
495 context: Option<&'a ParserRuleContext>,
496 tree: Option<ParseTree>,
497 local_int_arg: Option<(usize, i64)>,
498 member_values: &'a BTreeMap<usize, i64>,
499 action: Option<ParserAction>,
500}
501
502impl<S> std::fmt::Debug for ParserSemCtx<'_, S>
503where
504 S: TokenSource,
505{
506 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
507 f.debug_struct("ParserSemCtx")
508 .field("rule_index", &self.rule_index)
509 .field("coordinate_index", &self.coordinate_index)
510 .field("rule_name", &self.rule_name)
511 .field("context", &self.context)
512 .field("tree", &self.tree)
513 .field("local_int_arg", &self.local_int_arg)
514 .field("member_values", &self.member_values)
515 .field("action", &self.action)
516 .finish_non_exhaustive()
517 }
518}
519
520impl<'a, S> ParserSemCtx<'a, S>
521where
522 S: TokenSource,
523{
524 #[must_use]
526 pub const fn rule_index(&self) -> usize {
527 self.rule_index
528 }
529
530 #[must_use]
532 pub fn rule_name(&self) -> Option<&str> {
533 self.rule_name.as_deref()
534 }
535
536 #[must_use]
540 pub const fn coordinate_index(&self) -> usize {
541 self.coordinate_index
542 }
543
544 #[must_use]
546 pub fn input_index(&self) -> usize {
547 self.input.index()
548 }
549
550 pub fn la(&mut self, offset: isize) -> i32 {
552 self.input.la(offset)
553 }
554
555 pub fn lt(&self, offset: isize) -> Option<TokenView<'_>> {
557 self.input.lt(offset)
558 }
559
560 pub fn token_text(&self, offset: isize) -> Option<TokenView<'_>> {
562 self.lt(offset)
563 }
564
565 pub fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
572 self.input.get(index)
573 }
574
575 #[must_use]
578 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
579 self.context
580 }
581
582 #[must_use]
584 pub const fn parse_tree_storage(&self) -> &'a ParseTreeStorage {
585 self.tree_storage
586 }
587
588 #[must_use]
590 pub const fn token_store(&self) -> &TokenStore {
591 self.input.token_store()
592 }
593
594 #[must_use]
596 pub const fn tree_id(&self) -> Option<NodeId> {
597 self.tree
598 }
599
600 #[must_use]
603 pub fn tree(&self) -> Option<Node<'_>> {
604 self.tree
605 .and_then(|id| self.tree_storage.node(self.input.token_store(), id))
606 }
607
608 #[must_use]
610 pub fn local_int_arg(&self) -> Option<i64> {
611 self.local_int_arg.map(|(_, value)| value)
612 }
613
614 #[must_use]
616 pub fn member_int(&self, member: usize) -> Option<i64> {
617 self.member_values.get(&member).copied()
618 }
619
620 #[must_use]
623 pub const fn action(&self) -> Option<ParserAction> {
624 self.action
625 }
626
627 pub fn action_text(&self) -> String {
635 let Some(action) = self.action else {
636 return String::new();
637 };
638 let Some(stop) = action.stop_index() else {
639 return String::new();
640 };
641 let stop = if self
642 .input
643 .get(stop)
644 .is_some_and(|token| token.token_type() == TOKEN_EOF)
645 {
646 let Some(previous) = self.input.previous_visible_token_index(stop) else {
647 return String::new();
648 };
649 previous
650 } else {
651 stop
652 };
653 self.input.text(action.start_index(), stop)
654 }
655}
656
657pub trait SemanticHooks {
664 const ENABLES_LEXER_LIFECYCLE: bool = true;
671
672 fn observes_parser_predicates(&self) -> bool {
677 true
678 }
679
680 fn observes_parser_decisions(&self) -> bool {
685 false
686 }
687
688 fn parser_decision_override(
694 &mut self,
695 decision: usize,
696 input_index: usize,
697 alternative_count: usize,
698 ) -> Option<usize> {
699 let _ = (decision, input_index, alternative_count);
700 None
701 }
702
703 fn sempred<S>(
704 &mut self,
705 ctx: &mut ParserSemCtx<'_, S>,
706 rule_index: usize,
707 pred_index: usize,
708 ) -> Option<bool>
709 where
710 S: TokenSource,
711 {
712 let _ = (ctx, rule_index, pred_index);
713 None
714 }
715
716 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
717 where
718 S: TokenSource,
719 {
720 let _ = (ctx, action);
721 false
722 }
723
724 fn lexer_sempred<I>(
725 &mut self,
726 ctx: &mut LexerSemCtx<'_, I>,
727 rule_index: usize,
728 pred_index: usize,
729 ) -> Option<bool>
730 where
731 I: CharStream,
732 {
733 let _ = (ctx, rule_index, pred_index);
734 None
735 }
736
737 fn lexer_action<I>(&mut self, ctx: &mut LexerSemCtx<'_, I>, action: LexerCustomAction) -> bool
747 where
748 I: CharStream,
749 {
750 let _ = (ctx, action);
751 false
752 }
753
754 fn lexer_reset<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
758 where
759 I: CharStream,
760 {
761 let _ = ctx;
762 }
763
764 fn lexer_before_token<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
770 where
771 I: CharStream,
772 {
773 let _ = ctx;
774 }
775
776 fn lexer_after_accept<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
785 where
786 I: CharStream,
787 {
788 let _ = ctx;
789 }
790
791 fn lexer_token_emitted(&mut self, token: TokenView<'_>) {
798 let _ = token;
799 }
800}
801
802#[derive(Clone, Copy, Debug, Default)]
805pub struct NoSemanticHooks;
806
807impl SemanticHooks for NoSemanticHooks {
808 const ENABLES_LEXER_LIFECYCLE: bool = false;
809
810 fn observes_parser_predicates(&self) -> bool {
811 false
812 }
813}
814
815#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
822pub enum ParserPredicate {
823 True,
824 False,
825 FalseWithMessage {
827 message: &'static str,
828 },
829 Invoke {
832 value: bool,
833 },
834 LookaheadTextEquals {
835 offset: isize,
836 text: &'static str,
837 },
838 LookaheadNotEquals {
839 offset: isize,
840 token_type: i32,
841 },
842 TokenPairAdjacent,
845 ContextChildRuleTextNotEquals {
850 rule_index: usize,
851 text: &'static str,
852 },
853 LocalIntEquals {
856 value: i64,
857 },
858 LocalIntLessOrEqual {
861 value: i64,
862 },
863 MemberModuloEquals {
865 member: usize,
866 modulus: i64,
867 value: i64,
868 equals: bool,
869 },
870 MemberEquals {
872 member: usize,
873 value: i64,
874 equals: bool,
875 },
876}
877
878impl ParserPredicate {
879 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
885 match self {
886 Self::True => ir.expr(PExpr::Bool(true)),
887 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
888 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
889 Self::LookaheadTextEquals { offset, text } => {
890 let token = ir.expr(PExpr::TokenText(offset));
891 let text = ir.intern(text);
892 let text = ir.expr(PExpr::Str(text));
893 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
894 }
895 Self::LookaheadNotEquals { offset, token_type } => {
896 let actual = ir.expr(PExpr::La(offset));
897 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
898 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
899 }
900 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
901 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
902 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
903 let expected = ir.intern(text);
904 let expected = ir.expr(PExpr::Str(expected));
905 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
906 }
907 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
908 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
909 Self::MemberModuloEquals {
910 member,
911 modulus,
912 value,
913 equals,
914 } => {
915 if modulus == 0 {
916 return ir.expr(PExpr::Bool(false));
917 }
918 let member = ir.expr(PExpr::Member(member));
919 let modulus = ir.expr(PExpr::Int(modulus));
920 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
921 let expected = ir.expr(PExpr::Int(value));
922 ir.expr(PExpr::Cmp(
923 if equals { CmpOp::Eq } else { CmpOp::Ne },
924 actual,
925 expected,
926 ))
927 }
928 Self::MemberEquals {
929 member,
930 value,
931 equals,
932 } => {
933 let actual = ir.expr(PExpr::Member(member));
934 let expected = ir.expr(PExpr::Int(value));
935 ir.expr(PExpr::Cmp(
936 if equals { CmpOp::Eq } else { CmpOp::Ne },
937 actual,
938 expected,
939 ))
940 }
941 }
942 }
943
944 #[must_use]
945 pub const fn failure_message(self) -> Option<&'static str> {
946 match self {
947 Self::FalseWithMessage { message } => Some(message),
948 Self::True
949 | Self::False
950 | Self::Invoke { .. }
951 | Self::LookaheadTextEquals { .. }
952 | Self::LookaheadNotEquals { .. }
953 | Self::TokenPairAdjacent
954 | Self::ContextChildRuleTextNotEquals { .. }
955 | Self::LocalIntEquals { .. }
956 | Self::LocalIntLessOrEqual { .. }
957 | Self::MemberModuloEquals { .. }
958 | Self::MemberEquals { .. } => None,
959 }
960 }
961}
962
963fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
964 let local = ir.expr(PExpr::LocalArg);
965 let absent = ir.expr(PExpr::IsNull(local));
966 let expected = ir.expr(PExpr::Int(value));
967 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
968 ir.expr(PExpr::Or([absent, comparison].into()))
969}
970
971#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
984pub enum UnknownSemanticPolicy {
985 #[default]
987 AssumeTrue,
988 AssumeFalse,
990 Error,
993}
994
995fn apply_unknown_predicate_policy(
1004 policy: UnknownSemanticPolicy,
1005 rule_index: usize,
1006 pred_index: usize,
1007 hits: &mut Vec<(usize, usize)>,
1008) -> bool {
1009 match policy {
1010 UnknownSemanticPolicy::AssumeTrue => true,
1011 UnknownSemanticPolicy::AssumeFalse => false,
1012 UnknownSemanticPolicy::Error => {
1013 let coordinate = (rule_index, pred_index);
1014 if !hits.contains(&coordinate) {
1015 hits.push(coordinate);
1016 }
1017 false
1018 }
1019 }
1020}
1021
1022#[derive(Clone, Debug, Eq, PartialEq)]
1026pub struct ExpectedTokenSet {
1027 symbols: BTreeSet<i32>,
1028}
1029
1030impl ExpectedTokenSet {
1031 #[must_use]
1033 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
1034 expected_symbols_display(&self.symbols, vocabulary)
1035 }
1036}
1037
1038#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1043pub struct BailErrorStrategy;
1044
1045impl BailErrorStrategy {
1046 #[must_use]
1047 pub const fn new() -> Self {
1048 Self
1049 }
1050}
1051
1052#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1054pub enum PredictionMode {
1055 Ll,
1058 Sll,
1061 LlExactAmbigDetection,
1063}
1064
1065#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1071pub struct ParserRuleArg {
1072 pub source_state: usize,
1074 pub rule_index: usize,
1076 pub value: i64,
1078 pub inherit_local: bool,
1080}
1081
1082#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1084pub struct ParserMemberAction {
1085 pub source_state: usize,
1087 pub member: usize,
1089 pub delta: i64,
1091}
1092
1093#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1100pub struct ParserReturnAction {
1101 pub source_state: usize,
1103 pub rule_index: usize,
1105 pub name: &'static str,
1107 pub value: i64,
1109}
1110
1111impl ParserMemberAction {
1112 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1114 let delta = ir.expr(PExpr::Int(self.delta));
1115 ParserSemanticAction {
1116 source_state: self.source_state,
1117 rule_index: usize::MAX,
1118 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
1119 speculative: true,
1120 }
1121 }
1122}
1123
1124impl ParserReturnAction {
1125 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1127 let name = ir.intern(self.name);
1128 let value = ir.expr(PExpr::Int(self.value));
1129 ParserSemanticAction {
1130 source_state: self.source_state,
1131 rule_index: self.rule_index,
1132 stmt: ir.stmt(AStmt::SetReturn(name, value)),
1133 speculative: false,
1134 }
1135 }
1136}
1137
1138#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1140pub struct ParserSemanticPredicate {
1141 pub rule_index: usize,
1143 pub pred_index: usize,
1145 pub expr: ExprId,
1147 pub failure_message: Option<&'static str>,
1149}
1150
1151#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1153pub struct ParserSemanticAction {
1154 pub source_state: usize,
1156 pub rule_index: usize,
1158 pub stmt: StmtId,
1160 pub speculative: bool,
1162}
1163
1164#[derive(Clone, Debug, Default, Eq, PartialEq)]
1171pub struct ParserSemantics {
1172 pub ir: SemIr,
1173 pub predicates: Vec<ParserSemanticPredicate>,
1174 pub actions: Vec<ParserSemanticAction>,
1175}
1176
1177#[derive(Clone, Copy, Debug, Default)]
1179pub struct ParserRuntimeOptions<'a> {
1180 pub init_action_rules: &'a [usize],
1182 pub track_alt_numbers: bool,
1184 #[doc(hidden)]
1189 pub track_context_alt_numbers: bool,
1190 pub predicates: &'a [(usize, usize, ParserPredicate)],
1192 pub semantics: Option<&'a ParserSemantics>,
1194 pub rule_args: &'a [ParserRuleArg],
1196 pub member_actions: &'a [ParserMemberAction],
1198 pub return_actions: &'a [ParserReturnAction],
1200 pub unknown_predicate_policy: UnknownSemanticPolicy,
1203}
1204
1205pub trait Parser: Recognizer {
1206 fn build_parse_trees(&self) -> bool;
1209
1210 fn set_build_parse_trees(&mut self, build: bool);
1212
1213 fn number_of_syntax_errors(&self) -> usize {
1216 0
1217 }
1218
1219 fn report_diagnostic_errors(&self) -> bool {
1222 false
1223 }
1224
1225 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
1228
1229 fn prediction_mode(&self) -> PredictionMode {
1231 PredictionMode::Ll
1232 }
1233
1234 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
1236
1237 fn max_rule_depth(&self) -> Option<usize> {
1240 None
1241 }
1242
1243 fn set_max_rule_depth(&mut self, _depth: Option<usize>) {}
1259
1260 fn add_parse_listener(&mut self, _listener: Box<dyn ParseListener>) {}
1265
1266 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
1269 Vec::new()
1270 }
1271}
1272
1273#[derive(Debug)]
1274struct LeftRecursiveCallerOverlap {
1275 atn_key: SharedAtnCacheKey,
1276 state_number: usize,
1277 symbol: i32,
1278 context_version: usize,
1279 overlaps: bool,
1280}
1281
1282const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
1283
1284#[derive(Debug)]
1285pub struct BaseParser<S, H = NoSemanticHooks> {
1286 input: CommonTokenStream<S>,
1287 tree: ParseTreeStorage,
1288 data: RecognizerData,
1289 semantic_hooks: H,
1290 decision_override_generation: usize,
1291 build_parse_trees: bool,
1292 syntax_errors: usize,
1293 report_diagnostic_errors: bool,
1294 prediction_mode: PredictionMode,
1295 prediction_diagnostics: Vec<ParserDiagnostic>,
1296 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1297 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1298 generated_sync_expected: Option<TokenBitSet>,
1299 generated_recovery_error_index: Option<usize>,
1300 generated_recovery_error_states: BTreeSet<isize>,
1301 int_members: BTreeMap<usize, i64>,
1302 rule_context_stack: Vec<RuleContextFrame>,
1303 rule_context_version: usize,
1304 left_recursive_caller_overlap_cache:
1305 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1306 pending_invoking_states: Vec<isize>,
1307 precedence_stack: Vec<i32>,
1308 invoked_predicates: Vec<(usize, usize)>,
1312 bail_on_error: bool,
1316 parse_listeners: Vec<ParseListenerSlot>,
1321 parse_listener_abort: Option<AntlrError>,
1326 max_rule_depth: Option<usize>,
1330 rule_depth_error: Option<AntlrError>,
1335 recursion_expansions: usize,
1341 recursion_expansion_marks: Vec<usize>,
1345 unknown_predicate_policy: UnknownSemanticPolicy,
1348 unknown_predicate_hits: Vec<(usize, usize)>,
1351 unhandled_action_hits: Vec<(usize, usize)>,
1356 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1361 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1367 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1372 rule_stop_reach_cache: Vec<Option<bool>>,
1377 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1382 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1388 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1394 fast_predicate_cache: FxHashMap<(usize, usize, usize), bool>,
1398 empty_cycle_cache: Vec<Option<bool>>,
1404 empty_cycle_cache_atn: Option<SharedAtnCacheKey>,
1405 clean_memo_mode: CleanMemoMode,
1408 clean_memo_probe_seen: FxHashSet<FastRecognizeKey>,
1409 clean_memo_probe_samples: usize,
1410 clean_memo_probe_repeats: usize,
1411 clean_memo_sparse_samples: usize,
1412 fast_recognize_scratch: FastRecognizeTopScratch,
1414 fast_outcome_dedup: FastOutcomeDedupScratch,
1416 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1419 fast_first_set_prefilter: bool,
1427 fast_recovery_enabled: bool,
1431 fast_token_nodes_enabled: bool,
1436 fast_track_alt_numbers: bool,
1439 recognition_arena: RecognitionArena,
1443 last_recognition_arena_root: NodeSeqId,
1444 last_recognition_arena_diagnostics: DiagnosticSeqId,
1445}
1446
1447#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1449pub struct GeneratedDiagnosticsCheckpoint {
1450 diagnostics_len: usize,
1451 syntax_errors: usize,
1452 tree: ParseTreeCheckpoint,
1453}
1454
1455#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1458pub struct RecognitionArenaStats {
1459 pub total_nodes: usize,
1460 pub live_nodes: usize,
1461 pub dead_nodes: usize,
1462 pub node_capacity: usize,
1463 pub total_links: usize,
1464 pub live_links: usize,
1465 pub dead_links: usize,
1466 pub link_capacity: usize,
1467 pub total_extras: usize,
1468 pub live_extras: usize,
1469 pub dead_extras: usize,
1470 pub extra_capacity: usize,
1471}
1472
1473#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1474struct RuleContextFrame {
1475 rule_index: usize,
1476 invoking_state: isize,
1477}
1478
1479#[derive(Clone, Debug, Eq, PartialEq)]
1480struct RecognizeOutcome {
1481 index: usize,
1482 consumed_eof: bool,
1483 alt_number: usize,
1484 member_values: BTreeMap<usize, i64>,
1485 return_values: BTreeMap<String, i64>,
1486 diagnostics: DiagnosticSeqId,
1487 decisions: Vec<usize>,
1488 actions: Vec<ParserAction>,
1489 nodes: NodeSeqId,
1490}
1491
1492#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1493struct FastRecognizeOutcome {
1494 index: usize,
1495 consumed_eof: bool,
1496 diagnostics: DiagnosticSeqId,
1497 deferred_nodes: FastDeferredNodeId,
1498 nodes: NodeSeqId,
1502}
1503
1504#[derive(Debug, Default)]
1505struct FastRecognizeTopScratch {
1506 visiting: FxHashSet<FastRecognizeKey>,
1507 memo: FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
1508}
1509
1510impl FastRecognizeTopScratch {
1511 fn prepare(&mut self, memo_capacity: usize) {
1512 self.visiting.clear();
1513 self.visiting.reserve(FAST_RECOGNIZE_VISITING_CAPACITY);
1514 self.memo.clear();
1515 self.memo.reserve(memo_capacity);
1516 }
1517
1518 fn release_oversized_memo(&mut self) {
1519 self.memo.clear();
1520 if self.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY {
1521 self.memo = FxHashMap::default();
1522 }
1523 }
1524}
1525
1526fn fast_recognize_memo_capacity(buffered_tokens: usize) -> usize {
1527 buffered_tokens.saturating_mul(8).clamp(
1528 FAST_RECOGNIZE_MIN_MEMO_CAPACITY,
1529 FAST_RECOGNIZE_MAX_MEMO_CAPACITY,
1530 )
1531}
1532
1533#[derive(Debug, Default)]
1534struct FastOutcomeDedupScratch {
1535 dense_words: Vec<u64>,
1536 touched_dense_words: Vec<u32>,
1537 sparse_keys: FxHashSet<(usize, bool)>,
1538}
1539
1540#[repr(transparent)]
1545#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1546struct FastDeferredNodeId(u32);
1547
1548impl FastDeferredNodeId {
1549 const EMPTY: Self = Self(u32::MAX);
1550
1551 const fn is_empty(self) -> bool {
1552 self.0 == Self::EMPTY.0
1553 }
1554}
1555
1556impl Default for FastDeferredNodeId {
1557 fn default() -> Self {
1558 Self::EMPTY
1559 }
1560}
1561
1562#[repr(transparent)]
1563#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1564struct FastDeferredRuleId(u32);
1565
1566#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1568enum FastDeferredNode {
1569 Fragment(NodeSeqId),
1570 Rule(FastDeferredRuleId),
1571 Alternative(u32),
1572 LeftRecursiveBoundary {
1573 rule_index: u32,
1574 },
1575 Concat {
1576 prefix: FastDeferredNodeId,
1577 suffix: FastDeferredNodeId,
1578 },
1579}
1580
1581#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1582struct FastDeferredRule {
1583 rule_index: u32,
1584 invoking_state: i32,
1585 start_index: u32,
1586 stop_index: Option<u32>,
1587 deferred_children: FastDeferredNodeId,
1588 children: NodeSeqId,
1589}
1590
1591#[repr(transparent)]
1592#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1593struct RecognizedNodeId(u32);
1594
1595#[repr(transparent)]
1596#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1597struct NodeSeqId(u32);
1598
1599impl NodeSeqId {
1600 const EMPTY: Self = Self(u32::MAX);
1601
1602 const fn is_empty(self) -> bool {
1603 self.0 == Self::EMPTY.0
1604 }
1605}
1606
1607impl Default for NodeSeqId {
1608 fn default() -> Self {
1609 Self::EMPTY
1610 }
1611}
1612
1613#[repr(transparent)]
1614#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1615struct DiagnosticSeqId(u32);
1616
1617impl DiagnosticSeqId {
1618 const EMPTY: Self = Self(u32::MAX);
1619
1620 const fn is_empty(self) -> bool {
1621 self.0 == Self::EMPTY.0
1622 }
1623}
1624
1625impl Default for DiagnosticSeqId {
1626 fn default() -> Self {
1627 Self::EMPTY
1628 }
1629}
1630
1631#[repr(transparent)]
1632#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1633struct RecognitionExtraId(u32);
1634
1635#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1636struct SeqLink {
1637 head: RecognizedNodeId,
1638 tail: NodeSeqId,
1639}
1640
1641#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1642struct DiagnosticLink {
1643 head: RecognitionExtraId,
1644 tail: DiagnosticSeqId,
1645}
1646
1647struct ArenaRuleSpec {
1648 rule_index: usize,
1649 invoking_state: isize,
1650 alt_number: usize,
1651 start_index: usize,
1652 stop_index: Option<usize>,
1653 return_values: BTreeMap<String, i64>,
1654 children: NodeSeqId,
1655}
1656
1657#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1660enum ArenaRecognizedNode {
1661 Token {
1662 token: TokenId,
1663 },
1664 ErrorToken {
1665 token: TokenId,
1666 },
1667 MissingToken {
1668 extra: RecognitionExtraId,
1669 },
1670 Rule {
1671 rule_index: u32,
1672 invoking_state: i32,
1673 alt_number: u32,
1674 start_index: u32,
1675 stop_index: Option<u32>,
1676 return_values: Option<RecognitionExtraId>,
1677 children: NodeSeqId,
1678 },
1679 LeftRecursiveBoundary {
1683 rule_index: u32,
1684 alt_number: u32,
1685 },
1686}
1687
1688#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1689enum RecognitionExtra {
1690 MissingToken {
1691 token_type: i32,
1692 at_index: u32,
1693 text: String,
1694 },
1695 ReturnValues(BTreeMap<String, i64>),
1696 Diagnostic(ParserDiagnostic),
1697}
1698
1699#[derive(Debug, Default)]
1700struct RecognitionArena {
1701 nodes: Vec<ArenaRecognizedNode>,
1702 seq_links: Vec<SeqLink>,
1703 diagnostic_links: Vec<DiagnosticLink>,
1704 extras: Vec<RecognitionExtra>,
1705 deferred_nodes: Vec<FastDeferredNode>,
1706 deferred_rules: Vec<FastDeferredRule>,
1707}
1708
1709const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1712const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1713const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1714const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1715const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1716const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1717
1718impl RecognitionArena {
1719 fn reset(&mut self) {
1720 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1721 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1722 reset_arena_vec(
1723 &mut self.diagnostic_links,
1724 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1725 );
1726 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1727 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1728 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1729 }
1730
1731 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1732 let id = RecognizedNodeId(
1733 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1734 );
1735 self.nodes.push(node);
1736 id
1737 }
1738
1739 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1740 let id = RecognitionExtraId(
1741 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1742 );
1743 self.extras.push(extra);
1744 id
1745 }
1746
1747 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1748 let id = NodeSeqId(
1749 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1750 );
1751 self.seq_links.push(SeqLink { head, tail });
1752 id
1753 }
1754
1755 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1756 let id = FastDeferredNodeId(
1757 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
1758 );
1759 self.deferred_nodes.push(node);
1760 id
1761 }
1762
1763 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
1764 let id = FastDeferredRuleId(
1765 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
1766 );
1767 self.deferred_rules.push(rule);
1768 id
1769 }
1770
1771 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
1772 if nodes.is_empty() {
1773 FastDeferredNodeId::EMPTY
1774 } else {
1775 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
1776 }
1777 }
1778
1779 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
1780 let rule = self.push_deferred_rule(rule);
1781 self.push_deferred_node(FastDeferredNode::Rule(rule))
1782 }
1783
1784 fn deferred_alternative(&mut self, alt_number: usize) -> FastDeferredNodeId {
1785 self.push_deferred_node(FastDeferredNode::Alternative(
1786 u32::try_from(alt_number).expect("alternative number fits in u32"),
1787 ))
1788 }
1789
1790 fn deferred_left_recursive_boundary(&mut self, rule_index: usize) -> FastDeferredNodeId {
1791 self.push_deferred_node(FastDeferredNode::LeftRecursiveBoundary {
1792 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
1793 })
1794 }
1795
1796 fn concat_deferred_nodes(
1797 &mut self,
1798 prefix: FastDeferredNodeId,
1799 suffix: FastDeferredNodeId,
1800 ) -> FastDeferredNodeId {
1801 if prefix.is_empty() {
1802 return suffix;
1803 }
1804 if suffix.is_empty() {
1805 return prefix;
1806 }
1807 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
1808 }
1809
1810 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
1811 self.deferred_nodes[id.0 as usize]
1812 }
1813
1814 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
1815 self.deferred_rules[id.0 as usize]
1816 }
1817
1818 fn prepend_diagnostic(
1819 &mut self,
1820 tail: DiagnosticSeqId,
1821 diagnostic: ParserDiagnostic,
1822 ) -> DiagnosticSeqId {
1823 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
1824 self.prepend_diagnostic_id(tail, head)
1825 }
1826
1827 fn prepend_diagnostic_id(
1828 &mut self,
1829 tail: DiagnosticSeqId,
1830 head: RecognitionExtraId,
1831 ) -> DiagnosticSeqId {
1832 let id = DiagnosticSeqId(
1833 u32::try_from(self.diagnostic_links.len())
1834 .expect("diagnostic sequence arena fits in u32"),
1835 );
1836 self.diagnostic_links.push(DiagnosticLink { head, tail });
1837 id
1838 }
1839
1840 fn concat_diagnostics(
1841 &mut self,
1842 prefix: DiagnosticSeqId,
1843 mut suffix: DiagnosticSeqId,
1844 ) -> DiagnosticSeqId {
1845 if prefix.is_empty() {
1846 return suffix;
1847 }
1848 if suffix.is_empty() {
1849 return prefix;
1850 }
1851 let mut reversed = DiagnosticSeqId::EMPTY;
1852 let mut cursor = prefix;
1853 while let Some(link) = self.diagnostic_link(cursor) {
1854 reversed = self.prepend_diagnostic_id(reversed, link.head);
1855 cursor = link.tail;
1856 }
1857 while let Some(link) = self.diagnostic_link(reversed) {
1858 suffix = self.prepend_diagnostic_id(suffix, link.head);
1859 reversed = link.tail;
1860 }
1861 suffix
1862 }
1863
1864 #[cfg(test)]
1865 fn diagnostic_sequence(
1866 &mut self,
1867 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
1868 ) -> DiagnosticSeqId {
1869 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
1870 let mut sequence = DiagnosticSeqId::EMPTY;
1871 for diagnostic in diagnostics.into_iter().rev() {
1872 sequence = self.prepend_diagnostic(sequence, diagnostic);
1873 }
1874 sequence
1875 }
1876
1877 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
1878 self.nodes[id.0 as usize]
1879 }
1880
1881 fn set_boundary_alt_number(&mut self, id: RecognizedNodeId, alt_number: u32) {
1882 let ArenaRecognizedNode::LeftRecursiveBoundary {
1883 alt_number: stored, ..
1884 } = &mut self.nodes[id.0 as usize]
1885 else {
1886 unreachable!("deferred boundary must materialize as a boundary node");
1887 };
1888 *stored = alt_number;
1889 }
1890
1891 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
1892 &self.extras[id.0 as usize]
1893 }
1894
1895 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
1896 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
1897 }
1898
1899 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
1900 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
1901 }
1902
1903 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
1904 NodeSeqIter {
1905 arena: self,
1906 cursor: sequence,
1907 }
1908 }
1909
1910 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
1911 DiagnosticSeqIter {
1912 arena: self,
1913 cursor: sequence,
1914 }
1915 }
1916
1917 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
1918 self.diagnostics(sequence).count()
1919 }
1920
1921 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
1922 self.diagnostics(sequence)
1923 .filter(|diagnostic| {
1924 diagnostic.message.starts_with("mismatched input ")
1925 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
1926 })
1927 .count()
1928 }
1929
1930 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
1931 self.diagnostics(left).cmp(self.diagnostics(right))
1932 }
1933
1934 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
1935 self.iter(sequence).count()
1936 }
1937
1938 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
1939 self.iter(sequence).any(|node| match self.node(node) {
1940 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1941 ArenaRecognizedNode::Rule { children, .. } => {
1942 self.sequence_has_left_recursive_boundary(children)
1943 }
1944 ArenaRecognizedNode::Token { .. }
1945 | ArenaRecognizedNode::ErrorToken { .. }
1946 | ArenaRecognizedNode::MissingToken { .. } => false,
1947 })
1948 }
1949
1950 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
1951 self.iter(sequence).any(|node| {
1952 matches!(
1953 self.node(node),
1954 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
1955 )
1956 })
1957 }
1958
1959 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
1960 self.iter(sequence).any(|node| {
1961 matches!(
1962 self.node(node),
1963 ArenaRecognizedNode::Token { .. }
1964 | ArenaRecognizedNode::ErrorToken { .. }
1965 | ArenaRecognizedNode::MissingToken { .. }
1966 )
1967 })
1968 }
1969
1970 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
1971 match self.node(node) {
1972 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1973 Some(token.index())
1974 }
1975 ArenaRecognizedNode::MissingToken { extra } => {
1976 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1977 unreachable!("missing-token node must reference missing-token extra");
1978 };
1979 Some(*at_index as usize)
1980 }
1981 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
1982 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1983 }
1984 }
1985
1986 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
1987 match self.node(node) {
1988 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1989 Some(token.index())
1990 }
1991 ArenaRecognizedNode::MissingToken { extra } => {
1992 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1993 unreachable!("missing-token node must reference missing-token extra");
1994 };
1995 (*at_index as usize).checked_sub(1)
1996 }
1997 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
1998 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1999 }
2000 }
2001
2002 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
2003 let start = self.node_start_index(node)?;
2004 let stop = self.node_stop_index(node);
2005 Some((start, stop))
2006 }
2007
2008 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
2009 self.iter(sequence)
2010 .find_map(|node| self.node_start_index(node))
2011 }
2012
2013 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
2014 let mut stop = None;
2015 for node in self.iter(sequence) {
2016 if let Some(index) = self.node_stop_index(node) {
2017 stop = Some(index);
2018 }
2019 }
2020 stop
2021 }
2022
2023 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
2024 self.iter(sequence)
2025 .any(|node| self.node_needs_stable_tie(node))
2026 }
2027
2028 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
2029 match self.node(node) {
2030 ArenaRecognizedNode::Token { .. }
2031 | ArenaRecognizedNode::ErrorToken { .. }
2032 | ArenaRecognizedNode::MissingToken { .. } => false,
2033 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
2034 ArenaRecognizedNode::Rule {
2035 rule_index,
2036 children,
2037 ..
2038 } => self.iter(children).any(|child| {
2039 matches!(
2040 self.node(child),
2041 ArenaRecognizedNode::Rule {
2042 rule_index: child_rule,
2043 ..
2044 } if child_rule == rule_index
2045 ) || self.node_needs_stable_tie(child)
2046 }),
2047 }
2048 }
2049
2050 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
2051 loop {
2052 match (self.link(left), self.link(right)) {
2053 (Some(left_link), Some(right_link)) => {
2054 let order = self.compare_nodes(left_link.head, right_link.head);
2055 if order != Ordering::Equal {
2056 return order;
2057 }
2058 left = left_link.tail;
2059 right = right_link.tail;
2060 }
2061 (None, None) => return Ordering::Equal,
2062 (None, Some(_)) => return Ordering::Less,
2063 (Some(_), None) => return Ordering::Greater,
2064 }
2065 }
2066 }
2067
2068 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
2069 let left = self.node(left);
2070 let right = self.node(right);
2071 match (left, right) {
2072 (
2073 ArenaRecognizedNode::Token { token: left },
2074 ArenaRecognizedNode::Token { token: right },
2075 )
2076 | (
2077 ArenaRecognizedNode::ErrorToken { token: left },
2078 ArenaRecognizedNode::ErrorToken { token: right },
2079 ) => left.cmp(&right),
2080 (
2081 ArenaRecognizedNode::MissingToken { extra: left },
2082 ArenaRecognizedNode::MissingToken { extra: right },
2083 ) => self.extra(left).cmp(self.extra(right)),
2084 (
2085 ArenaRecognizedNode::Rule {
2086 rule_index: left_rule,
2087 invoking_state: left_invoking,
2088 alt_number: left_alt,
2089 start_index: left_start,
2090 stop_index: left_stop,
2091 return_values: left_returns,
2092 children: left_children,
2093 },
2094 ArenaRecognizedNode::Rule {
2095 rule_index: right_rule,
2096 invoking_state: right_invoking,
2097 alt_number: right_alt,
2098 start_index: right_start,
2099 stop_index: right_stop,
2100 return_values: right_returns,
2101 children: right_children,
2102 },
2103 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
2104 .cmp(&(
2105 right_rule,
2106 right_invoking,
2107 right_alt,
2108 right_start,
2109 right_stop,
2110 ))
2111 .then_with(|| {
2112 left_returns
2113 .map(|id| self.extra(id))
2114 .cmp(&right_returns.map(|id| self.extra(id)))
2115 })
2116 .then_with(|| self.compare_sequences(left_children, right_children)),
2117 (
2118 ArenaRecognizedNode::LeftRecursiveBoundary {
2119 rule_index: left_rule,
2120 alt_number: left_alt,
2121 },
2122 ArenaRecognizedNode::LeftRecursiveBoundary {
2123 rule_index: right_rule,
2124 alt_number: right_alt,
2125 },
2126 ) => (left_rule, left_alt).cmp(&(right_rule, right_alt)),
2127 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
2128 }
2129 }
2130
2131 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
2132 let mut reversed = NodeSeqId::EMPTY;
2133 while let Some(link) = self.link(sequence) {
2134 reversed = self.prepend(reversed, link.head);
2135 sequence = link.tail;
2136 }
2137 reversed
2138 }
2139
2140 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
2141 if !self.sequence_has_direct_boundary(sequence) {
2142 return sequence;
2143 }
2144 let mut reversed = NodeSeqId::EMPTY;
2145 while let Some(link) = self.link(sequence) {
2146 match self.node(link.head) {
2147 ArenaRecognizedNode::LeftRecursiveBoundary {
2148 rule_index,
2149 alt_number,
2150 } => {
2151 if !reversed.is_empty() {
2152 let children = self.reverse_sequence(reversed);
2153 let start_index = self.sequence_start_index(children).unwrap_or_default();
2154 let stop_index = self.sequence_stop_index(children);
2155 let rule = self.push_node(ArenaRecognizedNode::Rule {
2156 rule_index,
2157 invoking_state: -1,
2158 alt_number,
2159 start_index: u32::try_from(start_index)
2160 .expect("left-recursive start index fits in u32"),
2161 stop_index: stop_index.map(|index| {
2162 u32::try_from(index).expect("left-recursive stop index fits in u32")
2163 }),
2164 return_values: None,
2165 children,
2166 });
2167 reversed = self.prepend(NodeSeqId::EMPTY, rule);
2168 }
2169 }
2170 _ => {
2171 reversed = self.prepend(reversed, link.head);
2172 }
2173 }
2174 sequence = link.tail;
2175 }
2176 self.reverse_sequence(reversed)
2177 }
2178
2179 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
2180 let mut live_nodes = vec![false; self.nodes.len()];
2181 let mut live_links = vec![false; self.seq_links.len()];
2182 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
2183 let mut live_extras = vec![false; self.extras.len()];
2184 let mut pending = vec![root];
2185 while let Some(mut sequence) = pending.pop() {
2186 while let Some(link) = self.link(sequence) {
2187 let link_index = sequence.0 as usize;
2188 if live_links[link_index] {
2189 break;
2190 }
2191 live_links[link_index] = true;
2192 let node_index = link.head.0 as usize;
2193 if !live_nodes[node_index] {
2194 live_nodes[node_index] = true;
2195 match self.node(link.head) {
2196 ArenaRecognizedNode::MissingToken { extra } => {
2197 live_extras[extra.0 as usize] = true;
2198 }
2199 ArenaRecognizedNode::Rule {
2200 return_values,
2201 children,
2202 ..
2203 } => {
2204 if let Some(extra) = return_values {
2205 live_extras[extra.0 as usize] = true;
2206 }
2207 pending.push(children);
2208 }
2209 ArenaRecognizedNode::Token { .. }
2210 | ArenaRecognizedNode::ErrorToken { .. }
2211 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
2212 }
2213 }
2214 sequence = link.tail;
2215 }
2216 }
2217 let mut diagnostics = diagnostics;
2218 while let Some(link) = self.diagnostic_link(diagnostics) {
2219 let link_index = diagnostics.0 as usize;
2220 if live_diagnostic_links[link_index] {
2221 break;
2222 }
2223 live_diagnostic_links[link_index] = true;
2224 live_extras[link.head.0 as usize] = true;
2225 diagnostics = link.tail;
2226 }
2227 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
2228 let live_link_count = live_links.into_iter().filter(|live| *live).count()
2229 + live_diagnostic_links
2230 .into_iter()
2231 .filter(|live| *live)
2232 .count();
2233 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
2234 let total_links = self.seq_links.len() + self.diagnostic_links.len();
2235 RecognitionArenaStats {
2236 total_nodes: self.nodes.len(),
2237 live_nodes: live_node_count,
2238 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
2239 node_capacity: self.nodes.capacity(),
2240 total_links,
2241 live_links: live_link_count,
2242 dead_links: total_links.saturating_sub(live_link_count),
2243 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
2244 total_extras: self.extras.len(),
2245 live_extras: live_extra_count,
2246 dead_extras: self.extras.len().saturating_sub(live_extra_count),
2247 extra_capacity: self.extras.capacity(),
2248 }
2249 }
2250}
2251
2252fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
2253 if storage.capacity() > max_retained_capacity {
2254 *storage = Vec::new();
2255 } else {
2256 storage.clear();
2257 }
2258}
2259
2260const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
2261 match node {
2262 ArenaRecognizedNode::Token { .. } => 0,
2263 ArenaRecognizedNode::ErrorToken { .. } => 1,
2264 ArenaRecognizedNode::MissingToken { .. } => 2,
2265 ArenaRecognizedNode::Rule { .. } => 3,
2266 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
2267 }
2268}
2269
2270struct NodeSeqIter<'a> {
2271 arena: &'a RecognitionArena,
2272 cursor: NodeSeqId,
2273}
2274
2275impl Iterator for NodeSeqIter<'_> {
2276 type Item = RecognizedNodeId;
2277
2278 fn next(&mut self) -> Option<Self::Item> {
2279 let link = self.arena.link(self.cursor)?;
2280 self.cursor = link.tail;
2281 Some(link.head)
2282 }
2283}
2284
2285struct DiagnosticSeqIter<'a> {
2286 arena: &'a RecognitionArena,
2287 cursor: DiagnosticSeqId,
2288}
2289
2290impl<'a> Iterator for DiagnosticSeqIter<'a> {
2291 type Item = &'a ParserDiagnostic;
2292
2293 fn next(&mut self) -> Option<Self::Item> {
2294 let link = self.arena.diagnostic_link(self.cursor)?;
2295 self.cursor = link.tail;
2296 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2297 unreachable!("diagnostic link must reference diagnostic extra");
2298 };
2299 Some(diagnostic)
2300 }
2301}
2302
2303#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2304struct ParserDiagnostic {
2305 line: usize,
2306 column: usize,
2307 message: String,
2308 offending: Option<TokenId>,
2312}
2313
2314#[derive(Clone, Debug, Default, Eq, PartialEq)]
2315struct ExpectedTokens {
2316 index: Option<usize>,
2317 symbols: BTreeSet<i32>,
2318 no_viable: Option<NoViableAlternative>,
2319}
2320
2321#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2322struct NoViableAlternative {
2323 start_index: usize,
2324 error_index: usize,
2325}
2326
2327impl ExpectedTokens {
2328 fn record_transition(
2331 &mut self,
2332 index: usize,
2333 transition: ParserTransition<'_>,
2334 max_token_type: i32,
2335 ) {
2336 let symbols = transition_expected_symbols(transition, max_token_type);
2337 match self.index {
2338 Some(current) if index < current => {}
2339 Some(current) if index == current => self.symbols.extend(symbols),
2340 _ => {
2341 self.index = Some(index);
2342 self.symbols = symbols;
2343 }
2344 }
2345 }
2346
2347 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2350 match self.no_viable {
2351 Some(current) if error_index < current.error_index => {}
2352 _ => {
2353 self.no_viable = Some(NoViableAlternative {
2354 start_index,
2355 error_index,
2356 });
2357 }
2358 }
2359 }
2360}
2361
2362#[derive(Clone, Debug, Default, Eq, PartialEq)]
2369struct TokenBitSet {
2370 words: Vec<u64>,
2371}
2372
2373impl TokenBitSet {
2374 fn insert(&mut self, symbol: i32) {
2375 let Some(slot) = token_bit_slot(symbol) else {
2376 return;
2377 };
2378 let word = slot / u64::BITS as usize;
2379 if word >= self.words.len() {
2380 self.words.resize(word + 1, 0);
2381 }
2382 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2383 }
2384
2385 fn extend_range(&mut self, start: i32, stop: i32) {
2386 let (start, stop) = if start <= stop {
2387 (start, stop)
2388 } else {
2389 (stop, start)
2390 };
2391 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2392 self.insert(TOKEN_EOF);
2393 }
2394 let positive_start = start.max(1);
2395 if positive_start > stop {
2396 return;
2397 }
2398 let Some(start_slot) = token_bit_slot(positive_start) else {
2399 return;
2400 };
2401 let Some(stop_slot) = token_bit_slot(stop) else {
2402 return;
2403 };
2404 self.extend_slot_range(start_slot, stop_slot);
2405 }
2406
2407 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2408 if start_slot > stop_slot {
2409 return;
2410 }
2411 let start_word = start_slot / u64::BITS as usize;
2412 let stop_word = stop_slot / u64::BITS as usize;
2413 if stop_word >= self.words.len() {
2414 self.words.resize(stop_word + 1, 0);
2415 }
2416 let start_offset = start_slot % u64::BITS as usize;
2417 let stop_offset = stop_slot % u64::BITS as usize;
2418 if start_word == stop_word {
2419 self.words[start_word] |=
2420 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2421 return;
2422 }
2423 self.words[start_word] |= !0_u64 << start_offset;
2424 for word in &mut self.words[(start_word + 1)..stop_word] {
2425 *word = !0_u64;
2426 }
2427 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2428 }
2429
2430 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2431 for symbol in symbols {
2432 self.insert(symbol);
2433 }
2434 }
2435
2436 fn extend_from(&mut self, other: &Self) {
2437 if other.words.len() > self.words.len() {
2438 self.words.resize(other.words.len(), 0);
2439 }
2440 for (left, right) in self.words.iter_mut().zip(&other.words) {
2441 *left |= *right;
2442 }
2443 }
2444
2445 fn contains(&self, symbol: i32) -> bool {
2446 let Some(slot) = token_bit_slot(symbol) else {
2447 return false;
2448 };
2449 let word = slot / u64::BITS as usize;
2450 self.words
2451 .get(word)
2452 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2453 }
2454
2455 fn is_empty(&self) -> bool {
2456 self.words.iter().all(|word| *word == 0)
2457 }
2458
2459 fn symbols(&self) -> impl Iterator<Item = i32> + '_ {
2460 self.words
2461 .iter()
2462 .copied()
2463 .enumerate()
2464 .flat_map(|(word_index, mut bits)| {
2465 std::iter::from_fn(move || {
2466 while bits != 0 {
2467 let bit = bits.trailing_zeros() as usize;
2468 bits &= bits - 1;
2469 if let Some(symbol) =
2470 token_bit_symbol(word_index * u64::BITS as usize + bit)
2471 {
2472 return Some(symbol);
2473 }
2474 }
2475 None
2476 })
2477 })
2478 }
2479
2480 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2481 target.extend(self.symbols());
2482 }
2483
2484 fn to_btree_set(&self) -> BTreeSet<i32> {
2485 let mut out = BTreeSet::new();
2486 self.extend_btree_set(&mut out);
2487 out
2488 }
2489}
2490
2491fn token_bit_slot(symbol: i32) -> Option<usize> {
2492 if symbol == TOKEN_EOF {
2493 Some(0)
2494 } else if symbol > 0 {
2495 usize::try_from(symbol).ok()
2496 } else {
2497 None
2498 }
2499}
2500
2501fn token_bit_symbol(slot: usize) -> Option<i32> {
2502 if slot == 0 {
2503 Some(TOKEN_EOF)
2504 } else {
2505 i32::try_from(slot).ok()
2506 }
2507}
2508
2509fn transition_expected_symbols(
2512 transition: ParserTransition<'_>,
2513 max_token_type: i32,
2514) -> BTreeSet<i32> {
2515 let mut symbols = BTreeSet::new();
2516 match &transition.data() {
2517 Transition::Atom { label, .. } => {
2518 symbols.insert(*label);
2519 }
2520 Transition::Range { start, stop, .. } => {
2521 symbols.extend(*start..=*stop);
2522 }
2523 Transition::Set { set, .. } => {
2524 for (start, stop) in set.ranges() {
2525 symbols.extend(start..=stop);
2526 }
2527 }
2528 Transition::NotSet { set, .. } => {
2529 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2530 }
2531 Transition::Wildcard { .. } => {
2532 symbols.extend(1..=max_token_type);
2533 }
2534 Transition::Epsilon { .. }
2535 | Transition::Rule { .. }
2536 | Transition::Predicate { .. }
2537 | Transition::Action { .. }
2538 | Transition::Precedence { .. } => {}
2539 }
2540 symbols
2541}
2542
2543fn transition_expected_token_set(
2544 transition: ParserTransition<'_>,
2545 max_token_type: i32,
2546) -> TokenBitSet {
2547 let mut symbols = TokenBitSet::default();
2548 match &transition.data() {
2549 Transition::Atom { label, .. } => {
2550 symbols.insert(*label);
2551 }
2552 Transition::Range { start, stop, .. } => {
2553 symbols.extend_range(*start, *stop);
2554 }
2555 Transition::Set { set, .. } => {
2556 for (start, stop) in set.ranges() {
2557 symbols.extend_range(start, stop);
2558 }
2559 }
2560 Transition::NotSet { set, .. } => {
2561 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2562 }
2563 Transition::Wildcard { .. } => {
2564 symbols.extend_range(1, max_token_type);
2565 }
2566 Transition::Epsilon { .. }
2567 | Transition::Rule { .. }
2568 | Transition::Predicate { .. }
2569 | Transition::Action { .. }
2570 | Transition::Precedence { .. } => {}
2571 }
2572 symbols
2573}
2574
2575fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2579 let mut symbols = BTreeSet::new();
2580 let mut stack = vec![state_number];
2581 let mut visited = BTreeSet::new();
2582 while let Some(current) = stack.pop() {
2583 if !visited.insert(current) {
2584 continue;
2585 }
2586 let Some(state) = atn.state(current) else {
2587 continue;
2588 };
2589 for transition in &state.transitions() {
2590 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2591 if transition_symbols.is_empty() {
2592 if transition.is_epsilon() {
2593 stack.push(transition.target());
2594 }
2595 } else {
2596 symbols.extend(transition_symbols);
2597 }
2598 }
2599 }
2600 symbols
2601}
2602
2603fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2604 let mut symbols = TokenBitSet::default();
2605 let mut stack = vec![state_number];
2606 let mut visited = BTreeSet::new();
2607 while let Some(current) = stack.pop() {
2608 if !visited.insert(current) {
2609 continue;
2610 }
2611 let Some(state) = atn.state(current) else {
2612 continue;
2613 };
2614 for transition in &state.transitions() {
2615 let transition_symbols =
2616 transition_expected_token_set(transition, atn.max_token_type());
2617 if transition_symbols.is_empty() {
2618 if transition.is_epsilon() {
2619 stack.push(transition.target());
2620 }
2621 } else {
2622 symbols.extend_from(&transition_symbols);
2623 }
2624 }
2625 }
2626 symbols
2627}
2628
2629fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2630 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2631 return false;
2632 };
2633 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2634 return false;
2635 };
2636 epsilon_reaches_state(atn, state_number, stop_state)
2637}
2638
2639fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2640 let mut stack = vec![start];
2641 let mut visited = BTreeSet::new();
2642 while let Some(current) = stack.pop() {
2643 if current == target {
2644 return true;
2645 }
2646 if !visited.insert(current) {
2647 continue;
2648 }
2649 let Some(state) = atn.state(current) else {
2650 continue;
2651 };
2652 stack.extend(
2653 state
2654 .transitions()
2655 .iter()
2656 .filter(|transition| transition.is_epsilon())
2657 .map(ParserTransition::target),
2658 );
2659 }
2660 false
2661}
2662
2663#[derive(Clone, Debug, Default, Eq, PartialEq)]
2670struct FirstSet {
2671 symbols: TokenBitSet,
2672 nullable: bool,
2673}
2674
2675type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2682
2683type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2690
2691#[derive(Debug, Default)]
2692struct LeftRecursiveOperatorLookahead {
2693 single_token: TokenBitSet,
2697 multi_token_prefix: TokenBitSet,
2702 predicate_dependent: TokenBitSet,
2703}
2704
2705#[derive(Default)]
2706struct SharedAtnCache {
2707 first_set: FirstSetCache,
2708 decision_lookahead: DecisionLookaheadCache,
2709 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2710 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2711 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2712 rule_stop_reach: FxHashMap<usize, bool>,
2713 observable_action_transitions: Option<bool>,
2714 predicate_transitions: Option<bool>,
2715}
2716
2717thread_local! {
2718 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2719 RefCell::new(FxHashMap::default());
2720}
2721
2722#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2733struct SharedAtnCacheKey {
2734 atn: usize,
2735 states: usize,
2736 state_count: usize,
2737 max_token_type: i32,
2738}
2739
2740impl SharedAtnCacheKey {
2741 fn for_atn(atn: &Atn) -> Self {
2742 let (states, state_count) = atn.storage_identity();
2743 Self {
2744 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2745 states,
2746 state_count,
2747 max_token_type: atn.max_token_type(),
2748 }
2749 }
2750}
2751
2752fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2753 SHARED_ATN_CACHES.with(|cell| {
2754 let key = SharedAtnCacheKey::for_atn(atn);
2755 let mut map = cell.borrow_mut();
2756 let cache = map.entry(key).or_default();
2757 f(&mut cache.first_set)
2758 })
2759}
2760
2761fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
2762 SHARED_ATN_CACHES.with(|cell| {
2763 let key = SharedAtnCacheKey::for_atn(atn);
2764 let mut map = cell.borrow_mut();
2765 let cache = map.entry(key).or_default();
2766 f(cache)
2767 })
2768}
2769
2770#[derive(Debug, Default)]
2779struct DecisionLookahead {
2780 transitions: Vec<TransitionLookSet>,
2781}
2782
2783#[derive(Clone, Debug, Default)]
2790struct TransitionLookSet {
2791 symbols: TokenBitSet,
2792 nullable: bool,
2793}
2794
2795struct FirstSetCtx<'a> {
2799 cache: &'a mut FirstSetCache,
2800 in_progress: BTreeSet<(usize, usize)>,
2801 hit_cycle: bool,
2802}
2803
2804fn rule_first_set(
2813 atn: &Atn,
2814 target: usize,
2815 rule_stop_state: usize,
2816 cache: &mut FirstSetCache,
2817) -> Rc<FirstSet> {
2818 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
2819 return Rc::clone(cached);
2820 }
2821 let mut ctx = FirstSetCtx {
2822 cache,
2823 in_progress: BTreeSet::new(),
2824 hit_cycle: false,
2825 };
2826 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
2827}
2828
2829fn rule_first_set_cached(
2830 atn: &Atn,
2831 target: usize,
2832 rule_stop_state: usize,
2833 ctx: &mut FirstSetCtx<'_>,
2834) -> Rc<FirstSet> {
2835 let key = (target, rule_stop_state);
2836 if let Some(cached) = ctx.cache.get(&key) {
2837 return Rc::clone(cached);
2838 }
2839 if !ctx.in_progress.insert(key) {
2840 return Rc::new(FirstSet::default());
2844 }
2845 let saved_hit_cycle = ctx.hit_cycle;
2846 ctx.hit_cycle = false;
2847 let mut first = FirstSet::default();
2848 let mut visited = BTreeSet::new();
2849 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
2850 ctx.in_progress.remove(&key);
2851 let entry = Rc::new(first);
2852 if !ctx.hit_cycle {
2853 ctx.cache.insert(key, Rc::clone(&entry));
2854 }
2855 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
2856 entry
2857}
2858
2859fn transition_first_set(
2863 atn: &Atn,
2864 transition: ParserTransition<'_>,
2865 rule_stop_state: usize,
2866 cache: &mut FirstSetCache,
2867) -> TransitionLookSet {
2868 match &transition.data() {
2869 Transition::Atom { label, .. } => {
2870 let mut symbols = TokenBitSet::default();
2871 symbols.insert(*label);
2872 TransitionLookSet {
2873 symbols,
2874 nullable: false,
2875 }
2876 }
2877 Transition::Range { start, stop, .. } => {
2878 let mut symbols = TokenBitSet::default();
2879 symbols.extend_range(*start, *stop);
2880 TransitionLookSet {
2881 symbols,
2882 nullable: false,
2883 }
2884 }
2885 Transition::Set { set, .. } => {
2886 let mut symbols = TokenBitSet::default();
2887 for (start, stop) in set.ranges() {
2888 symbols.extend_range(start, stop);
2889 }
2890 TransitionLookSet {
2891 symbols,
2892 nullable: false,
2893 }
2894 }
2895 Transition::NotSet { set, .. } => {
2896 let max = atn.max_token_type();
2897 let mut symbols = TokenBitSet::default();
2898 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
2899 TransitionLookSet {
2900 symbols,
2901 nullable: false,
2902 }
2903 }
2904 Transition::Wildcard { .. } => {
2905 let mut symbols = TokenBitSet::default();
2906 symbols.extend_range(1, atn.max_token_type());
2907 TransitionLookSet {
2908 symbols,
2909 nullable: false,
2910 }
2911 }
2912 Transition::Epsilon { target }
2913 | Transition::Action { target, .. }
2914 | Transition::Predicate { target, .. }
2915 | Transition::Precedence { target, .. } => {
2916 let first = rule_first_set(atn, *target, rule_stop_state, cache);
2919 TransitionLookSet {
2920 symbols: first.symbols.clone(),
2921 nullable: first.nullable,
2922 }
2923 }
2924 Transition::Rule {
2925 target,
2926 rule_index,
2927 follow_state,
2928 ..
2929 } => {
2930 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2931 return TransitionLookSet::default();
2932 };
2933 let child = rule_first_set(atn, *target, child_stop, cache);
2934 let mut symbols = child.symbols.clone();
2935 let nullable = if child.nullable {
2936 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
2937 symbols.extend_from(&follow.symbols);
2938 follow.nullable
2939 } else {
2940 false
2941 };
2942 TransitionLookSet { symbols, nullable }
2943 }
2944 }
2945}
2946
2947fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
2968 let mut chosen: Option<usize> = None;
2969 for (index, transition) in entry.transitions.iter().enumerate() {
2970 if transition.nullable {
2971 return None;
2972 }
2973 if transition.symbols.contains(symbol) {
2974 if chosen.is_some() {
2975 return None;
2976 }
2977 chosen = Some(index);
2978 }
2979 }
2980 chosen
2981}
2982
2983fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
2992 let mut matching_non_nullable_alt = None;
2993 let mut nullable_alt = None;
2994 for (index, transition) in entry.transitions.iter().enumerate() {
2995 if transition.nullable {
2996 if nullable_alt.is_some() {
2997 return None;
2998 }
2999 nullable_alt = Some(index);
3000 }
3001 if transition.symbols.contains(symbol) {
3002 if transition.nullable {
3003 continue;
3004 }
3005 if matching_non_nullable_alt.is_some() {
3006 return None;
3007 }
3008 matching_non_nullable_alt = Some(index);
3009 }
3010 }
3011 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
3012 return None;
3013 }
3014 if non_greedy {
3015 nullable_alt.or(matching_non_nullable_alt)
3016 } else {
3017 matching_non_nullable_alt.or(nullable_alt)
3018 }
3019}
3020
3021fn should_skip_via_lookahead(
3022 transition_kind: ParserTransitionKind,
3023 transition_index: usize,
3024 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
3025 index: usize,
3026 record_expected: bool,
3027 expected: &mut ExpectedTokens,
3028) -> bool {
3029 let prune_non_consuming = matches!(
3030 transition_kind,
3031 ParserTransitionKind::Epsilon
3032 | ParserTransitionKind::Action
3033 | ParserTransitionKind::Predicate
3034 | ParserTransitionKind::Rule
3035 | ParserTransitionKind::Precedence
3036 );
3037 if !prune_non_consuming {
3038 return false;
3039 }
3040 let Some((symbol, entry)) = lookahead_filter else {
3041 return false;
3042 };
3043 let Some(set) = entry.transitions.get(transition_index) else {
3044 return false;
3045 };
3046 if set.symbols.contains(*symbol) || set.nullable {
3047 return false;
3048 }
3049 if record_expected && !set.symbols.is_empty() {
3050 record_pruned_transition_expected(set, index, expected);
3051 }
3052 true
3053}
3054
3055fn should_skip_rule_via_first_set(
3056 first: &FirstSet,
3057 symbol: i32,
3058 record_expected: bool,
3059 index: usize,
3060 expected: &mut ExpectedTokens,
3061) -> bool {
3062 if first.nullable || first.symbols.contains(symbol) {
3063 return false;
3064 }
3065 if record_expected && !first.symbols.is_empty() {
3066 record_token_bit_expected(&first.symbols, index, expected);
3067 }
3068 true
3069}
3070
3071fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
3072 match expected.index {
3073 Some(current) if index < current => {}
3074 Some(current) if index == current => {
3075 symbols.extend_btree_set(&mut expected.symbols);
3076 }
3077 _ => {
3078 expected.index = Some(index);
3079 expected.symbols = symbols.to_btree_set();
3080 }
3081 }
3082}
3083
3084fn record_pruned_transition_expected(
3086 set: &TransitionLookSet,
3087 index: usize,
3088 expected: &mut ExpectedTokens,
3089) {
3090 match expected.index {
3091 Some(current) if index < current => {}
3092 Some(current) if index == current => {
3093 set.symbols.extend_btree_set(&mut expected.symbols);
3094 }
3095 _ => {
3096 expected.index = Some(index);
3097 expected.symbols = set.symbols.to_btree_set();
3098 }
3099 }
3100}
3101
3102fn rule_first_set_inner(
3103 atn: &Atn,
3104 state_number: usize,
3105 rule_stop_state: usize,
3106 ctx: &mut FirstSetCtx<'_>,
3107 visited: &mut BTreeSet<usize>,
3108 first: &mut FirstSet,
3109) {
3110 if !visited.insert(state_number) {
3111 return;
3112 }
3113 if state_number == rule_stop_state {
3114 first.nullable = true;
3115 return;
3116 }
3117 let Some(state) = atn.state(state_number) else {
3118 return;
3119 };
3120 for transition in &state.transitions() {
3121 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3122 if !transition_symbols.is_empty() {
3123 first.symbols.extend_iter(transition_symbols);
3124 continue;
3125 }
3126 match &transition.data() {
3127 Transition::Epsilon { target }
3128 | Transition::Action { target, .. }
3129 | Transition::Predicate { target, .. }
3130 | Transition::Precedence { target, .. } => {
3131 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
3132 }
3133 Transition::Rule {
3134 target,
3135 rule_index,
3136 follow_state,
3137 ..
3138 } => {
3139 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3140 continue;
3141 };
3142 let child_key = (*target, child_stop);
3143 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
3144 ctx.hit_cycle = true;
3145 }
3146 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
3147 first.symbols.extend_from(&child.symbols);
3148 if child.nullable {
3149 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
3150 }
3151 }
3152 Transition::Atom { .. }
3153 | Transition::Range { .. }
3154 | Transition::Set { .. }
3155 | Transition::NotSet { .. }
3156 | Transition::Wildcard { .. } => {}
3157 }
3158 }
3159}
3160
3161fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
3164 let mut symbols = BTreeSet::new();
3165 state_sync_symbols_inner(
3166 atn,
3167 state_number,
3168 stop_state,
3169 &mut BTreeSet::new(),
3170 &mut symbols,
3171 );
3172 symbols
3173}
3174
3175fn state_sync_symbols_inner(
3178 atn: &Atn,
3179 state_number: usize,
3180 stop_state: usize,
3181 visited: &mut BTreeSet<usize>,
3182 symbols: &mut BTreeSet<i32>,
3183) {
3184 if !visited.insert(state_number) {
3185 return;
3186 }
3187 if state_number == stop_state {
3188 symbols.insert(TOKEN_EOF);
3189 return;
3190 }
3191 let Some(state) = atn.state(state_number) else {
3192 return;
3193 };
3194 for transition in &state.transitions() {
3195 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3196 if transition_symbols.is_empty() {
3197 match &transition.data() {
3198 Transition::Rule { target, .. }
3199 | Transition::Epsilon { target }
3200 | Transition::Action { target, .. }
3201 | Transition::Predicate { target, .. }
3202 | Transition::Precedence { target, .. } => {
3203 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
3204 }
3205 Transition::Atom { .. }
3206 | Transition::Range { .. }
3207 | Transition::Set { .. }
3208 | Transition::NotSet { .. }
3209 | Transition::Wildcard { .. } => {}
3210 }
3211 } else {
3212 symbols.extend(transition_symbols);
3213 }
3214 }
3215}
3216
3217#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
3218struct OperatorSymbolReachability {
3219 single_token: bool,
3221 multi_token: bool,
3223 predicate_dependent: bool,
3225}
3226
3227impl OperatorSymbolReachability {
3228 const ADAPTIVE_FALLBACK: Self = Self {
3229 single_token: false,
3230 multi_token: false,
3231 predicate_dependent: true,
3232 };
3233
3234 const fn single_token(predicate_dependent: bool) -> Self {
3235 if predicate_dependent {
3236 Self {
3237 single_token: false,
3238 multi_token: false,
3239 predicate_dependent: true,
3240 }
3241 } else {
3242 Self {
3243 single_token: true,
3244 multi_token: false,
3245 predicate_dependent: false,
3246 }
3247 }
3248 }
3249
3250 const fn multi_token(predicate_dependent: bool) -> Self {
3251 if predicate_dependent {
3252 Self {
3253 single_token: false,
3254 multi_token: false,
3255 predicate_dependent: true,
3256 }
3257 } else {
3258 Self {
3259 single_token: false,
3260 multi_token: true,
3261 predicate_dependent: false,
3262 }
3263 }
3264 }
3265
3266 const fn union(self, other: Self) -> Self {
3267 Self {
3268 single_token: self.single_token || other.single_token,
3269 multi_token: self.multi_token || other.multi_token,
3270 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
3271 }
3272 }
3273}
3274
3275#[derive(Clone, Copy)]
3276struct OperatorReachabilityRequest {
3277 symbol: i32,
3278 precedence: i32,
3279 predicate_dependent: bool,
3280 operator_rule_index: usize,
3281}
3282
3283#[derive(Clone, Copy, Debug)]
3284struct OperatorRuleContinuation {
3285 stop_state: usize,
3286 follow_state: usize,
3287 return_precedence: i32,
3288}
3289
3290struct NullablePrecedenceCtx {
3291 cache: FxHashMap<(usize, usize, i32, bool), bool>,
3292 in_progress: BTreeSet<(usize, usize, i32, bool)>,
3293 hit_cycle: bool,
3294}
3295
3296fn state_is_nullable_with_precedence(
3297 atn: &Atn,
3298 state_number: usize,
3299 stop_state_number: usize,
3300 precedence: i32,
3301 allow_predicates: bool,
3302 ctx: &mut NullablePrecedenceCtx,
3303) -> bool {
3304 let saved_hit_cycle = ctx.hit_cycle;
3305 ctx.hit_cycle = false;
3306 let nullable = state_is_nullable_with_precedence_cached(
3307 atn,
3308 state_number,
3309 stop_state_number,
3310 precedence,
3311 allow_predicates,
3312 ctx,
3313 );
3314 ctx.hit_cycle = saved_hit_cycle;
3315 nullable
3316}
3317
3318fn state_is_nullable_with_precedence_cached(
3319 atn: &Atn,
3320 state_number: usize,
3321 stop_state_number: usize,
3322 precedence: i32,
3323 allow_predicates: bool,
3324 ctx: &mut NullablePrecedenceCtx,
3325) -> bool {
3326 if state_number == stop_state_number {
3327 return true;
3328 }
3329 let key = (
3330 state_number,
3331 stop_state_number,
3332 precedence,
3333 allow_predicates,
3334 );
3335 if let Some(cached) = ctx.cache.get(&key) {
3336 return *cached;
3337 }
3338 if !ctx.in_progress.insert(key) {
3339 ctx.hit_cycle = true;
3340 return false;
3341 }
3342 let saved_hit_cycle = ctx.hit_cycle;
3343 ctx.hit_cycle = false;
3344 let nullable = atn.state(state_number).is_some_and(|state| {
3345 state
3346 .transitions()
3347 .iter()
3348 .any(|transition| match &transition.data() {
3349 Transition::Rule {
3350 target,
3351 rule_index,
3352 follow_state,
3353 precedence: rule_precedence,
3354 } => {
3355 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3356 return false;
3357 };
3358 state_is_nullable_with_precedence_cached(
3359 atn,
3360 *target,
3361 child_stop,
3362 *rule_precedence,
3363 allow_predicates,
3364 ctx,
3365 ) && state_is_nullable_with_precedence_cached(
3366 atn,
3367 *follow_state,
3368 stop_state_number,
3369 precedence,
3370 allow_predicates,
3371 ctx,
3372 )
3373 }
3374 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3375 state_is_nullable_with_precedence_cached(
3376 atn,
3377 *target,
3378 stop_state_number,
3379 precedence,
3380 allow_predicates,
3381 ctx,
3382 )
3383 }
3384 Transition::Predicate { target, .. } if allow_predicates => {
3385 state_is_nullable_with_precedence_cached(
3386 atn,
3387 *target,
3388 stop_state_number,
3389 precedence,
3390 allow_predicates,
3391 ctx,
3392 )
3393 }
3394 Transition::Precedence {
3395 target,
3396 precedence: transition_precedence,
3397 } if *transition_precedence >= precedence => {
3398 state_is_nullable_with_precedence_cached(
3399 atn,
3400 *target,
3401 stop_state_number,
3402 precedence,
3403 allow_predicates,
3404 ctx,
3405 )
3406 }
3407 Transition::Atom { .. }
3408 | Transition::Range { .. }
3409 | Transition::Set { .. }
3410 | Transition::NotSet { .. }
3411 | Transition::Wildcard { .. }
3412 | Transition::Predicate { .. }
3413 | Transition::Precedence { .. } => false,
3414 })
3415 });
3416 ctx.in_progress.remove(&key);
3417 if !ctx.hit_cycle {
3418 ctx.cache.insert(key, nullable);
3419 }
3420 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3421 nullable
3422}
3423
3424fn state_operator_token_prefix_reachability(
3426 atn: &Atn,
3427 state_number: usize,
3428 request: OperatorReachabilityRequest,
3429 continuations: &[OperatorRuleContinuation],
3430 visited: &mut BTreeSet<(usize, i32, bool)>,
3431) -> OperatorSymbolReachability {
3432 let key = (
3433 state_number,
3434 request.precedence,
3435 request.predicate_dependent,
3436 );
3437 if !visited.insert(key) {
3438 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3442 }
3443 if let Some((continuation, remaining)) = continuations.split_last()
3444 && state_number == continuation.stop_state
3445 {
3446 let result = state_operator_token_prefix_reachability(
3447 atn,
3448 continuation.follow_state,
3449 OperatorReachabilityRequest {
3450 precedence: continuation.return_precedence,
3451 ..request
3452 },
3453 remaining,
3454 visited,
3455 );
3456 visited.remove(&key);
3457 return result;
3458 }
3459 let Some(state) = atn.state(state_number) else {
3460 visited.remove(&key);
3461 return OperatorSymbolReachability::default();
3462 };
3463 let completes_operator = match state.kind() {
3464 AtnStateKind::RuleStop => continuations.is_empty(),
3465 AtnStateKind::StarLoopBack
3466 | AtnStateKind::StarLoopEntry
3467 | AtnStateKind::PlusLoopBack
3468 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3469 _ => false,
3470 };
3471 if completes_operator {
3472 visited.remove(&key);
3473 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3474 }
3475 let mut reachability = OperatorSymbolReachability::default();
3476 for transition in &state.transitions() {
3477 let transition_reachability = match &transition.data() {
3478 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3479 OperatorSymbolReachability::single_token(request.predicate_dependent)
3480 }
3481 Transition::Rule {
3482 target,
3483 rule_index,
3484 follow_state,
3485 precedence: rule_precedence,
3486 } => {
3487 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3488 continue;
3489 };
3490 let mut nested = continuations.to_vec();
3491 nested.push(OperatorRuleContinuation {
3492 stop_state: child_stop,
3493 follow_state: *follow_state,
3494 return_precedence: request.precedence,
3495 });
3496 state_operator_token_prefix_reachability(
3497 atn,
3498 *target,
3499 OperatorReachabilityRequest {
3500 precedence: *rule_precedence,
3501 ..request
3502 },
3503 &nested,
3504 visited,
3505 )
3506 }
3507 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3508 state_operator_token_prefix_reachability(
3509 atn,
3510 *target,
3511 request,
3512 continuations,
3513 visited,
3514 )
3515 }
3516 Transition::Precedence {
3517 target,
3518 precedence: transition_precedence,
3519 } => {
3520 if *transition_precedence < request.precedence {
3521 OperatorSymbolReachability::default()
3522 } else {
3523 state_operator_token_prefix_reachability(
3524 atn,
3525 *target,
3526 request,
3527 continuations,
3528 visited,
3529 )
3530 }
3531 }
3532 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3533 atn,
3534 *target,
3535 OperatorReachabilityRequest {
3536 predicate_dependent: true,
3537 ..request
3538 },
3539 continuations,
3540 visited,
3541 ),
3542 Transition::Atom { .. }
3543 | Transition::Range { .. }
3544 | Transition::Set { .. }
3545 | Transition::NotSet { .. }
3546 | Transition::Wildcard { .. } => {
3547 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3548 }
3549 };
3550 reachability = reachability.union(transition_reachability);
3551 }
3552 visited.remove(&key);
3553 reachability
3554}
3555
3556fn state_can_reach_symbol_with_precedence(
3557 atn: &Atn,
3558 state_number: usize,
3559 request: OperatorReachabilityRequest,
3560 nullable_ctx: &mut NullablePrecedenceCtx,
3561 continuations: &mut Vec<OperatorRuleContinuation>,
3562 visited: &mut BTreeSet<(usize, i32, bool)>,
3563) -> OperatorSymbolReachability {
3564 let key = (
3565 state_number,
3566 request.precedence,
3567 request.predicate_dependent,
3568 );
3569 if !visited.insert(key) {
3570 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3571 }
3572 let Some(state) = atn.state(state_number) else {
3573 visited.remove(&key);
3574 return OperatorSymbolReachability::default();
3575 };
3576 let mut reachability = OperatorSymbolReachability::default();
3577 for transition in &state.transitions() {
3578 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3579 reachability = reachability.union(state_operator_token_prefix_reachability(
3580 atn,
3581 transition.target(),
3582 request,
3583 continuations,
3584 &mut BTreeSet::new(),
3585 ));
3586 continue;
3587 }
3588 let transition_reachability = match &transition.data() {
3589 Transition::Rule {
3590 target,
3591 rule_index,
3592 follow_state,
3593 precedence: rule_precedence,
3594 } => {
3595 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3596 continue;
3597 };
3598 continuations.push(OperatorRuleContinuation {
3599 stop_state: child_stop,
3600 follow_state: *follow_state,
3601 return_precedence: request.precedence,
3602 });
3603 let mut result = state_can_reach_symbol_with_precedence(
3604 atn,
3605 *target,
3606 OperatorReachabilityRequest {
3607 precedence: *rule_precedence,
3608 ..request
3609 },
3610 nullable_ctx,
3611 continuations,
3612 visited,
3613 );
3614 continuations.pop();
3615 if state_is_nullable_with_precedence(
3616 atn,
3617 *target,
3618 child_stop,
3619 *rule_precedence,
3620 true,
3621 nullable_ctx,
3622 ) {
3623 let child_predicate_dependent = request.predicate_dependent
3624 || !state_is_nullable_with_precedence(
3625 atn,
3626 *target,
3627 child_stop,
3628 *rule_precedence,
3629 false,
3630 nullable_ctx,
3631 );
3632 result = result.union(state_can_reach_symbol_with_precedence(
3633 atn,
3634 *follow_state,
3635 OperatorReachabilityRequest {
3636 predicate_dependent: child_predicate_dependent,
3637 ..request
3638 },
3639 nullable_ctx,
3640 continuations,
3641 visited,
3642 ));
3643 }
3644 result
3645 }
3646 Transition::Epsilon { target }
3647 | Transition::Action { target, .. }
3648 | Transition::Precedence { target, .. } => {
3649 if matches!(
3650 &transition.data(),
3651 Transition::Precedence {
3652 precedence: transition_precedence,
3653 ..
3654 } if *transition_precedence < request.precedence
3655 ) {
3656 continue;
3657 }
3658 state_can_reach_symbol_with_precedence(
3659 atn,
3660 *target,
3661 request,
3662 nullable_ctx,
3663 continuations,
3664 visited,
3665 )
3666 }
3667 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3668 atn,
3669 *target,
3670 OperatorReachabilityRequest {
3671 predicate_dependent: true,
3672 ..request
3673 },
3674 nullable_ctx,
3675 continuations,
3676 visited,
3677 ),
3678 Transition::Atom { .. }
3679 | Transition::Range { .. }
3680 | Transition::Set { .. }
3681 | Transition::NotSet { .. }
3682 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3683 };
3684 reachability = reachability.union(transition_reachability);
3685 }
3686 visited.remove(&key);
3687 reachability
3688}
3689
3690fn left_recursive_operator_lookahead(
3691 atn: &Atn,
3692 state_number: usize,
3693 precedence: i32,
3694) -> LeftRecursiveOperatorLookahead {
3695 let Some(state) = atn.state(state_number) else {
3696 return LeftRecursiveOperatorLookahead::default();
3697 };
3698 let Some(operator_rule_index) = state.rule_index() else {
3699 return LeftRecursiveOperatorLookahead::default();
3700 };
3701 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3702 let mut nullable_ctx = NullablePrecedenceCtx {
3703 cache: FxHashMap::default(),
3704 in_progress: BTreeSet::new(),
3705 hit_cycle: false,
3706 };
3707 for transition in &state.transitions() {
3708 let target = transition.target();
3709 if atn
3710 .state(target)
3711 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3712 {
3713 continue;
3714 }
3715 for symbol in 1..=atn.max_token_type() {
3716 let reachability = state_can_reach_symbol_with_precedence(
3717 atn,
3718 target,
3719 OperatorReachabilityRequest {
3720 symbol,
3721 precedence,
3722 predicate_dependent: false,
3723 operator_rule_index,
3724 },
3725 &mut nullable_ctx,
3726 &mut Vec::new(),
3727 &mut BTreeSet::new(),
3728 );
3729 if reachability.single_token {
3730 lookahead.single_token.insert(symbol);
3731 }
3732 if reachability.multi_token {
3733 lookahead.multi_token_prefix.insert(symbol);
3734 }
3735 if reachability.predicate_dependent {
3736 lookahead.predicate_dependent.insert(symbol);
3737 }
3738 }
3739 }
3740 lookahead
3741}
3742
3743#[derive(Debug, Default)]
3744struct StateBeforeStopLookahead {
3745 symbols: TokenBitSet,
3746 reaches_context_boundary: bool,
3747}
3748
3749fn state_before_stop_lookahead(
3750 atn: &Atn,
3751 state_number: usize,
3752 stop_state_number: usize,
3753) -> Rc<StateBeforeStopLookahead> {
3754 with_shared_atn_caches(atn, |cache| {
3755 let key = (state_number, stop_state_number);
3756 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
3757 return Rc::clone(cached);
3758 }
3759 let mut lookahead = StateBeforeStopLookahead::default();
3760 state_before_stop_lookahead_inner(
3761 atn,
3762 state_number,
3763 stop_state_number,
3764 &mut BTreeSet::new(),
3765 &mut cache.first_set,
3766 &mut lookahead,
3767 );
3768 let lookahead = Rc::new(lookahead);
3769 cache
3770 .state_before_stop_lookahead
3771 .insert(key, Rc::clone(&lookahead));
3772 lookahead
3773 })
3774}
3775
3776fn state_before_stop_lookahead_inner(
3777 atn: &Atn,
3778 state_number: usize,
3779 stop_state_number: usize,
3780 visited: &mut BTreeSet<usize>,
3781 first_set_cache: &mut FirstSetCache,
3782 lookahead: &mut StateBeforeStopLookahead,
3783) {
3784 if state_number == stop_state_number {
3785 lookahead.reaches_context_boundary = true;
3786 return;
3787 }
3788 if !visited.insert(state_number) {
3789 return;
3790 }
3791 let Some(state) = atn.state(state_number) else {
3792 return;
3793 };
3794 if state.kind() == AtnStateKind::RuleStop {
3795 lookahead.reaches_context_boundary = true;
3796 return;
3797 }
3798 for transition in &state.transitions() {
3799 match &transition.data() {
3800 Transition::Epsilon { target }
3801 | Transition::Action { target, .. }
3802 | Transition::Predicate { target, .. }
3803 | Transition::Precedence { target, .. } => {
3804 state_before_stop_lookahead_inner(
3805 atn,
3806 *target,
3807 stop_state_number,
3808 visited,
3809 first_set_cache,
3810 lookahead,
3811 );
3812 }
3813 Transition::Rule {
3814 target,
3815 rule_index,
3816 follow_state,
3817 ..
3818 } => {
3819 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3820 continue;
3821 };
3822 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
3823 lookahead.symbols.extend_from(&child.symbols);
3824 if child.nullable {
3825 state_before_stop_lookahead_inner(
3826 atn,
3827 *follow_state,
3828 stop_state_number,
3829 visited,
3830 first_set_cache,
3831 lookahead,
3832 );
3833 }
3834 }
3835 Transition::Atom { .. }
3836 | Transition::Range { .. }
3837 | Transition::Set { .. }
3838 | Transition::NotSet { .. }
3839 | Transition::Wildcard { .. } => {
3840 lookahead.symbols.extend_iter(transition_expected_symbols(
3841 transition,
3842 atn.max_token_type(),
3843 ));
3844 }
3845 }
3846 }
3847}
3848
3849fn caller_context_can_match_symbol_before_state(
3850 atn: &Atn,
3851 return_states: impl DoubleEndedIterator<Item = usize>,
3852 stop_state_number: usize,
3853 symbol: i32,
3854) -> bool {
3855 for return_state in return_states.rev() {
3856 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
3857 if lookahead.symbols.contains(symbol) {
3858 return true;
3859 }
3860 if !lookahead.reaches_context_boundary {
3861 return false;
3862 }
3863 }
3864 false
3865}
3866
3867fn next_recovery_context(
3871 atn: &Atn,
3872 state: AtnState<'_>,
3873 inherited: &BTreeSet<i32>,
3874 inherited_state: Option<usize>,
3875) -> (BTreeSet<i32>, Option<usize>) {
3876 let state_symbols = state_expected_symbols(atn, state.state_number());
3877 if state.transitions().len() > 1 && !state_symbols.is_empty() {
3878 let mut symbols = state_symbols;
3879 symbols.extend(inherited.iter().copied());
3880 return (symbols, Some(state.state_number()));
3881 }
3882 (inherited.clone(), inherited_state)
3883}
3884
3885fn recovery_expected_symbols(
3886 atn: &Atn,
3887 state_number: usize,
3888 inherited: &BTreeSet<i32>,
3889) -> BTreeSet<i32> {
3890 let mut symbols = state_expected_symbols(atn, state_number);
3891 symbols.extend(inherited.iter().copied());
3892 symbols
3893}
3894
3895fn fast_next_recovery_context<S, H>(
3899 parser: &mut BaseParser<S, H>,
3900 atn: &Atn,
3901 state: AtnState<'_>,
3902 inherited: &Rc<BTreeSet<i32>>,
3903 inherited_state: Option<usize>,
3904) -> (Rc<BTreeSet<i32>>, Option<usize>)
3905where
3906 S: TokenSource,
3907 H: SemanticHooks,
3908{
3909 if state.transitions().len() <= 1 {
3910 return (Rc::clone(inherited), inherited_state);
3911 }
3912 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
3913 if state_symbols.is_empty() {
3914 return (Rc::clone(inherited), inherited_state);
3915 }
3916 if inherited.is_empty() {
3917 return (state_symbols, Some(state.state_number()));
3918 }
3919 if Rc::ptr_eq(&state_symbols, inherited) {
3920 return (state_symbols, Some(state.state_number()));
3921 }
3922 let mut combined = (*state_symbols).clone();
3923 combined.extend(inherited.iter().copied());
3924 (
3925 parser.intern_recovery_symbols(combined),
3926 Some(state.state_number()),
3927 )
3928}
3929
3930fn fast_recovery_expected_symbols<S, H>(
3934 parser: &mut BaseParser<S, H>,
3935 atn: &Atn,
3936 state_number: usize,
3937 inherited: &Rc<BTreeSet<i32>>,
3938) -> Rc<BTreeSet<i32>>
3939where
3940 S: TokenSource,
3941 H: SemanticHooks,
3942{
3943 let cached = parser.cached_state_expected_symbols(atn, state_number);
3944 if inherited.is_empty() {
3945 return cached;
3946 }
3947 if cached.is_empty() {
3948 return Rc::clone(inherited);
3949 }
3950 if Rc::ptr_eq(&cached, inherited) {
3951 return cached;
3952 }
3953 let mut combined = (*cached).clone();
3954 combined.extend(inherited.iter().copied());
3955 parser.intern_recovery_symbols(combined)
3956}
3957
3958struct ParserTableSemCtx<'a> {
3959 member_values: &'a mut BTreeMap<usize, i64>,
3960 return_values: &'a mut BTreeMap<String, i64>,
3961}
3962
3963impl semir::PredContext for ParserTableSemCtx<'_> {
3964 type TokenText<'a>
3965 = &'a str
3966 where
3967 Self: 'a;
3968
3969 fn la(&mut self, _offset: isize) -> i64 {
3970 i64::from(TOKEN_EOF)
3971 }
3972
3973 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
3974 None
3975 }
3976
3977 fn token_index_adjacent(&mut self) -> bool {
3978 false
3979 }
3980
3981 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
3982 None
3983 }
3984
3985 fn member(&self, member: usize) -> Option<i64> {
3986 Some(self.member_values.get(&member).copied().unwrap_or_default())
3987 }
3988
3989 fn local_arg(&self) -> Option<i64> {
3990 None
3991 }
3992
3993 fn column(&self) -> Option<i64> {
3994 None
3995 }
3996
3997 fn token_start_column(&self) -> Option<i64> {
3998 None
3999 }
4000
4001 fn token_text_so_far(&self) -> Option<String> {
4002 None
4003 }
4004
4005 fn hook(&mut self, _hook: HookId) -> bool {
4006 false
4007 }
4008}
4009
4010impl semir::ActContext for ParserTableSemCtx<'_> {
4011 fn set_member(&mut self, member: usize, value: i64) {
4012 self.member_values.insert(member, value);
4013 }
4014
4015 fn set_return(&mut self, name: &str, value: i64) {
4016 self.return_values.insert(name.to_owned(), value);
4017 }
4018
4019 fn action_hook(&mut self, _hook: HookId) {}
4020}
4021
4022fn apply_member_actions(
4024 source_state: usize,
4025 actions: &[ParserMemberAction],
4026 semantics: Option<&ParserSemantics>,
4027 values: &mut BTreeMap<usize, i64>,
4028) {
4029 for action in actions
4030 .iter()
4031 .filter(|action| action.source_state == source_state)
4032 {
4033 *values.entry(action.member).or_default() += action.delta;
4034 }
4035 let Some(semantics) = semantics else {
4036 return;
4037 };
4038 let mut return_values = BTreeMap::new();
4039 let mut ctx = ParserTableSemCtx {
4040 member_values: values,
4041 return_values: &mut return_values,
4042 };
4043 for action in semantics
4044 .actions
4045 .iter()
4046 .filter(|action| action.source_state == source_state && action.speculative)
4047 {
4048 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
4049 }
4050}
4051
4052fn member_values_after_action(
4054 source_state: usize,
4055 actions: &[ParserMemberAction],
4056 semantics: Option<&ParserSemantics>,
4057 values: &BTreeMap<usize, i64>,
4058) -> BTreeMap<usize, i64> {
4059 let mut values = values.clone();
4060 apply_member_actions(source_state, actions, semantics, &mut values);
4061 values
4062}
4063
4064fn return_values_after_action(
4066 source_state: usize,
4067 rule_index: usize,
4068 actions: &[ParserReturnAction],
4069 semantics: Option<&ParserSemantics>,
4070 values: &BTreeMap<String, i64>,
4071) -> BTreeMap<String, i64> {
4072 let mut values = values.clone();
4073 for action in actions
4074 .iter()
4075 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
4076 {
4077 values.insert(action.name.to_owned(), action.value);
4078 }
4079 if let Some(semantics) = semantics {
4080 let mut member_values = BTreeMap::new();
4081 let mut ctx = ParserTableSemCtx {
4082 member_values: &mut member_values,
4083 return_values: &mut values,
4084 };
4085 for action in semantics.actions.iter().filter(|action| {
4086 action.source_state == source_state
4087 && action.rule_index == rule_index
4088 && !action.speculative
4089 }) {
4090 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
4091 }
4092 }
4093 values
4094}
4095
4096fn rule_local_int_arg(
4098 rule_args: &[ParserRuleArg],
4099 source_state: usize,
4100 rule_index: usize,
4101 local_int_arg: Option<(usize, i64)>,
4102) -> Option<(usize, i64)> {
4103 rule_args
4104 .iter()
4105 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
4106 .map(|arg| {
4107 let value = if arg.inherit_local {
4108 local_int_arg.map_or(arg.value, |(_, value)| value)
4109 } else {
4110 arg.value
4111 };
4112 (rule_index, value)
4113 })
4114}
4115
4116fn stop_outcome(
4119 index: usize,
4120 consumed_eof: bool,
4121 rule_alt_number: usize,
4122 member_values: BTreeMap<usize, i64>,
4123 return_values: BTreeMap<String, i64>,
4124) -> Vec<RecognizeOutcome> {
4125 vec![RecognizeOutcome {
4126 index,
4127 consumed_eof,
4128 alt_number: rule_alt_number,
4129 member_values,
4130 return_values,
4131 diagnostics: DiagnosticSeqId::EMPTY,
4132 decisions: Vec::new(),
4133 actions: Vec::new(),
4134 nodes: NodeSeqId::EMPTY,
4135 }]
4136}
4137
4138fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
4139 with_shared_atn_caches(atn, |cache| {
4140 *cache.observable_action_transitions.get_or_insert_with(|| {
4141 atn.states().any(|state| {
4142 state.transitions().iter().any(|transition| {
4143 matches!(
4144 &transition.data(),
4145 Transition::Action {
4146 action_index: Some(_),
4147 ..
4148 }
4149 )
4150 })
4151 })
4152 })
4153 })
4154}
4155
4156fn atn_has_predicate_transitions(atn: &Atn) -> bool {
4157 with_shared_atn_caches(atn, |cache| {
4158 *cache.predicate_transitions.get_or_insert_with(|| {
4159 atn.states().any(|state| {
4160 state
4161 .transitions()
4162 .iter()
4163 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
4164 })
4165 })
4166 })
4167}
4168
4169fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
4174 options.init_action_rules.is_empty()
4175 && !options.track_alt_numbers
4176 && options
4177 .predicates
4178 .iter()
4179 .all(|(_, _, predicate)| predicate.failure_message().is_none())
4180 && options.semantics.is_none_or(|semantics| {
4181 semantics.actions.is_empty()
4182 && semantics
4183 .predicates
4184 .iter()
4185 .all(|predicate| predicate.failure_message.is_none())
4186 })
4187 && options.rule_args.is_empty()
4188 && options.member_actions.is_empty()
4189 && options.return_actions.is_empty()
4190 && !atn_has_observable_action_transitions(atn)
4191}
4192
4193#[derive(Clone, Debug, Eq, PartialEq)]
4194struct RecognizeRequest<'a> {
4195 state_number: usize,
4196 stop_state: usize,
4197 index: usize,
4198 rule_start_index: usize,
4199 decision_start_index: Option<usize>,
4200 init_action_rules: &'a BTreeSet<usize>,
4201 predicates: &'a [(usize, usize, ParserPredicate)],
4202 semantics: Option<&'a ParserSemantics>,
4203 rule_args: &'a [ParserRuleArg],
4204 member_actions: &'a [ParserMemberAction],
4205 return_actions: &'a [ParserReturnAction],
4206 local_int_arg: Option<(usize, i64)>,
4207 member_values: BTreeMap<usize, i64>,
4208 return_values: BTreeMap<String, i64>,
4209 rule_alt_number: usize,
4210 track_alt_numbers: bool,
4211 consumed_eof: bool,
4212 committed_decision: bool,
4213 precedence: i32,
4216 depth: usize,
4217 recovery_symbols: BTreeSet<i32>,
4218 recovery_state: Option<usize>,
4219}
4220
4221#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
4222struct RecognizeKey {
4223 state_number: usize,
4224 stop_state: usize,
4225 index: usize,
4226 rule_start_index: usize,
4227 decision_start_index: Option<usize>,
4228 local_int_arg: Option<(usize, i64)>,
4229 member_values: BTreeMap<usize, i64>,
4230 return_values: BTreeMap<String, i64>,
4231 rule_alt_number: usize,
4232 track_alt_numbers: bool,
4233 consumed_eof: bool,
4234 committed_decision: bool,
4235 precedence: i32,
4236 recovery_symbols: BTreeSet<i32>,
4237 recovery_state: Option<usize>,
4238}
4239
4240#[derive(Clone, Debug, Eq, PartialEq)]
4241struct EpsilonActionStep {
4242 source_state: usize,
4243 target: usize,
4244 action_rule_index: Option<usize>,
4245 left_recursive_boundary: Option<usize>,
4246 decision: Option<usize>,
4247 decision_start_index: Option<usize>,
4248 alt_number: usize,
4249 recovery_symbols: BTreeSet<i32>,
4250 recovery_state: Option<usize>,
4251}
4252
4253struct RecognizeScratch<'a> {
4254 visiting: &'a mut BTreeSet<RecognizeKey>,
4255 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4256 expected: &'a mut ExpectedTokens,
4257}
4258
4259#[derive(Clone, Debug, Eq, PartialEq)]
4260struct FastRecognizeRequest {
4261 state_number: usize,
4262 stop_state: usize,
4263 index: usize,
4264 rule_start_index: usize,
4265 decision_start_index: Option<usize>,
4266 precedence: i32,
4267 depth: usize,
4268 recovery_symbols: Rc<BTreeSet<i32>>,
4269 recovery_state: Option<usize>,
4270}
4271
4272#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4273struct FastRecognizeTopRequest {
4274 start_state: usize,
4275 stop_state: usize,
4276 start_index: usize,
4277 precedence: i32,
4278 caller_follow_state: Option<usize>,
4279}
4280
4281#[derive(Clone, Copy, Debug)]
4282struct FastPredicateContext<'a> {
4283 predicates: &'a [(usize, usize, ParserPredicate)],
4284 semantics: Option<&'a ParserSemantics>,
4285 member_values: &'a BTreeMap<usize, i64>,
4286}
4287
4288#[derive(Clone, Copy, Debug, Default)]
4289struct AltNumberTracking {
4290 public: bool,
4291 context: bool,
4292}
4293
4294impl AltNumberTracking {
4295 const fn any(self) -> bool {
4296 self.public || self.context
4297 }
4298}
4299
4300struct FastRecognizeScratch<'a, 'b> {
4301 predicate_context: Option<FastPredicateContext<'a>>,
4302 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4303 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4304 expected: &'b mut ExpectedTokens,
4305 native_depth: usize,
4306}
4307
4308#[derive(Clone, Copy, Debug)]
4309struct FastRepetitionShape {
4310 enter_target: usize,
4311 exit_target: usize,
4312 body_stop_state: usize,
4313 enter_transition_index: usize,
4314 exit_transition_index: usize,
4315}
4316
4317#[derive(Clone, Copy, Debug)]
4318struct FastRepetitionPath {
4319 index: usize,
4320 deferred_nodes: FastDeferredNodeId,
4321 diagnostics: DiagnosticSeqId,
4322 consumed_eof: bool,
4323}
4324
4325enum FastRepetitionWork {
4326 Enter(FastRepetitionPath),
4327 Exit(FastRepetitionPath),
4328}
4329
4330struct FastRepetitionCoordinates {
4335 base_index: usize,
4336 base_state: u8,
4337 later_states: Vec<u8>,
4338}
4339
4340impl FastRepetitionCoordinates {
4341 const ENTERED: u8 = 0;
4342 const EXITED: u8 = 2;
4343
4344 const fn new(base_index: usize) -> Self {
4345 Self {
4346 base_index,
4347 base_state: 0,
4348 later_states: Vec::new(),
4349 }
4350 }
4351
4352 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4353 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4354 }
4355
4356 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4357 self.insert(path.index, path.consumed_eof, Self::EXITED)
4358 }
4359
4360 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4361 let Some(offset) = index.checked_sub(self.base_index) else {
4362 return false;
4363 };
4364 let state = if offset == 0 {
4365 &mut self.base_state
4366 } else {
4367 if self.later_states.len() < offset {
4368 self.later_states.resize(offset, 0);
4369 }
4370 &mut self.later_states[offset - 1]
4371 };
4372 let bit = 1 << (base_bit + u8::from(consumed_eof));
4373 let is_new = *state & bit == 0;
4374 *state |= bit;
4375 is_new
4376 }
4377}
4378
4379fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4380 if state.precedence_rule_decision()
4381 || !matches!(
4382 state.kind(),
4383 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4384 )
4385 || state.transitions().len() != 2
4386 {
4387 return None;
4388 }
4389 let mut enter = None;
4390 let mut exit = None;
4391 for (index, transition) in state.transitions().iter().enumerate() {
4392 if transition.kind() != ParserTransitionKind::Epsilon {
4393 return None;
4394 }
4395 let target = transition.target();
4396 if atn
4397 .state(target)
4398 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4399 {
4400 if exit.replace((index, target)).is_some() {
4401 return None;
4402 }
4403 } else if enter.replace((index, target)).is_some() {
4404 return None;
4405 }
4406 }
4407 let (enter_transition_index, enter_target) = enter?;
4408 let (exit_transition_index, exit_target) = exit?;
4409 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4410 atn.state(exit_target)?.loop_back_state()?
4411 } else {
4412 state.state_number()
4413 };
4414 Some(FastRepetitionShape {
4415 enter_target,
4416 exit_target,
4417 body_stop_state,
4418 enter_transition_index,
4419 exit_transition_index,
4420 })
4421}
4422
4423fn push_fast_repetition_work(
4424 work: &mut Vec<FastRepetitionWork>,
4425 shape: FastRepetitionShape,
4426 path: FastRepetitionPath,
4427 lookahead: Option<&DecisionLookahead>,
4428 symbol: i32,
4429) {
4430 let transition_is_viable = |transition_index: usize| {
4433 let Some(entry) = lookahead else {
4434 return true;
4435 };
4436 let Some(transition) = entry.transitions.get(transition_index) else {
4437 return true;
4438 };
4439 transition.nullable || transition.symbols.contains(symbol)
4440 };
4441 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4442 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4443 if shape.enter_transition_index < shape.exit_transition_index {
4444 if exit_is_viable {
4445 work.push(FastRepetitionWork::Exit(path));
4446 }
4447 if enter_is_viable {
4448 work.push(FastRepetitionWork::Enter(path));
4449 }
4450 } else {
4451 if enter_is_viable {
4452 work.push(FastRepetitionWork::Enter(path));
4453 }
4454 if exit_is_viable {
4455 work.push(FastRepetitionWork::Exit(path));
4456 }
4457 }
4458}
4459
4460#[derive(Clone, Debug)]
4467struct FastRecognizeKey {
4468 state_number: usize,
4469 stop_state: usize,
4470 index: usize,
4471 rule_start_index: usize,
4472 decision_start_index: Option<usize>,
4473 precedence: i32,
4474 recovery_symbols_id: usize,
4475 recovery_state: Option<usize>,
4476}
4477
4478impl PartialEq for FastRecognizeKey {
4479 fn eq(&self, other: &Self) -> bool {
4480 if self.state_number != other.state_number
4481 || self.stop_state != other.stop_state
4482 || self.index != other.index
4483 || self.rule_start_index != other.rule_start_index
4484 || self.decision_start_index != other.decision_start_index
4485 || self.precedence != other.precedence
4486 || self.recovery_state != other.recovery_state
4487 || self.recovery_symbols_id != other.recovery_symbols_id
4488 {
4489 return false;
4490 }
4491 true
4492 }
4493}
4494
4495impl Eq for FastRecognizeKey {}
4496
4497impl Hash for FastRecognizeKey {
4498 fn hash<H: Hasher>(&self, hasher: &mut H) {
4499 self.state_number.hash(hasher);
4500 self.stop_state.hash(hasher);
4501 self.index.hash(hasher);
4502 self.rule_start_index.hash(hasher);
4503 self.decision_start_index.hash(hasher);
4504 self.precedence.hash(hasher);
4505 self.recovery_state.hash(hasher);
4506 self.recovery_symbols_id.hash(hasher);
4507 }
4508}
4509
4510struct FastRecoveryRequest<'a, 'b> {
4511 atn: &'a Atn,
4512 transition: ParserTransition<'a>,
4513 expected_symbols: Rc<BTreeSet<i32>>,
4514 target: usize,
4515 request: FastRecognizeRequest,
4516 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4517 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4518 expected: &'b mut ExpectedTokens,
4519}
4520
4521struct FastCurrentTokenDeletionRequest<'a, 'b> {
4522 atn: &'a Atn,
4523 expected_symbols: Rc<BTreeSet<i32>>,
4524 request: FastRecognizeRequest,
4525 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4526 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4527 expected: &'b mut ExpectedTokens,
4528}
4529
4530#[derive(Clone, Copy)]
4531struct FastChildRuleFailureRecoveryRequest<'a> {
4532 atn: &'a Atn,
4533 rule_index: usize,
4534 start_index: usize,
4535 follow_state: usize,
4536 stop_state: usize,
4537 expected: &'a ExpectedTokens,
4538}
4539
4540struct RecoveryRequest<'a, 'b> {
4541 atn: &'a Atn,
4542 transition: ParserTransition<'a>,
4543 expected_symbols: BTreeSet<i32>,
4544 target: usize,
4545 request: RecognizeRequest<'a>,
4546 visiting: &'b mut BTreeSet<RecognizeKey>,
4547 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4548 expected: &'b mut ExpectedTokens,
4549}
4550
4551struct CurrentTokenDeletionRequest<'a, 'b> {
4552 atn: &'a Atn,
4553 expected_symbols: BTreeSet<i32>,
4554 request: RecognizeRequest<'a>,
4555 visiting: &'b mut BTreeSet<RecognizeKey>,
4556 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4557 expected: &'b mut ExpectedTokens,
4558}
4559
4560struct ConsumingFailureFallback<'a> {
4563 atn: &'a Atn,
4564 target: usize,
4565 request: RecognizeRequest<'a>,
4566 symbol: i32,
4567 expected_symbols: BTreeSet<i32>,
4568 decision_start_index: Option<usize>,
4569 decision: Option<usize>,
4570}
4571
4572struct ChildRuleFailureRecovery<'a> {
4575 atn: &'a Atn,
4576 rule_index: usize,
4577 start_index: usize,
4578 follow_state: usize,
4579 stop_state: usize,
4580 member_values: BTreeMap<usize, i64>,
4581 expected: &'a ExpectedTokens,
4582}
4583
4584#[derive(Clone, Copy, Debug)]
4586struct PredicateEval<'a> {
4587 index: usize,
4588 rule_index: usize,
4589 pred_index: usize,
4590 predicates: &'a [(usize, usize, ParserPredicate)],
4591 semantics: Option<&'a ParserSemantics>,
4592 context: Option<&'a ParserRuleContext>,
4593 local_int_arg: Option<(usize, i64)>,
4594 member_values: &'a BTreeMap<usize, i64>,
4595}
4596
4597#[derive(Clone, Copy, Debug)]
4598struct ParserSemanticHookRequest<'a> {
4599 index: usize,
4600 rule_index: usize,
4601 pred_index: usize,
4602 context: Option<&'a ParserRuleContext>,
4603 local_int_arg: Option<(usize, i64)>,
4604 member_values: &'a BTreeMap<usize, i64>,
4605}
4606
4607struct ParserSemIrCtx<'a, S, H>
4616where
4617 S: TokenSource,
4618 H: SemanticHooks,
4619{
4620 input: &'a mut CommonTokenStream<S>,
4621 tree_storage: &'a ParseTreeStorage,
4622 semantic_hooks: &'a mut H,
4623 rule_index: usize,
4624 coordinate_index: usize,
4625 rule_name: Option<&'a str>,
4626 context: Option<&'a ParserRuleContext>,
4627 local_int_arg: Option<(usize, i64)>,
4628 member_values: &'a BTreeMap<usize, i64>,
4629 invoked_predicates: &'a mut Vec<(usize, usize)>,
4630 unknown_predicate_policy: UnknownSemanticPolicy,
4634 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4635}
4636
4637impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4638where
4639 S: TokenSource,
4640 H: SemanticHooks,
4641{
4642 type TokenText<'a>
4643 = TokenView<'a>
4644 where
4645 Self: 'a;
4646
4647 fn la(&mut self, offset: isize) -> i64 {
4648 i64::from(self.input.la(offset))
4649 }
4650
4651 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4652 self.input.lt(offset)
4653 }
4654
4655 fn token_index_adjacent(&mut self) -> bool {
4656 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4657 return false;
4658 };
4659 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4660 return false;
4661 };
4662 first + 1 == second
4663 }
4664
4665 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4666 self.context.and_then(|context| {
4667 context
4668 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4669 .next()
4670 .map(crate::tree::RuleNodeView::text)
4671 })
4672 }
4673
4674 fn member(&self, member: usize) -> Option<i64> {
4675 Some(self.member_values.get(&member).copied().unwrap_or_default())
4676 }
4677
4678 fn local_arg(&self) -> Option<i64> {
4679 self.local_int_arg.map(|(_, value)| value)
4680 }
4681
4682 fn column(&self) -> Option<i64> {
4683 None
4684 }
4685
4686 fn token_start_column(&self) -> Option<i64> {
4687 None
4688 }
4689
4690 fn token_text_so_far(&self) -> Option<String> {
4691 None
4692 }
4693
4694 fn hook(&mut self, _hook: HookId) -> bool {
4695 let mut ctx = ParserSemCtx {
4696 input: &mut *self.input,
4697 tree_storage: self.tree_storage,
4698 rule_index: self.rule_index,
4699 coordinate_index: self.coordinate_index,
4700 rule_name: self.rule_name.map(str::to_owned),
4701 context: self.context,
4702 tree: None,
4703 local_int_arg: self.local_int_arg,
4704 member_values: self.member_values,
4705 action: None,
4706 };
4707 match self
4708 .semantic_hooks
4709 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4710 {
4711 Some(result) => result,
4712 None => apply_unknown_predicate_policy(
4716 self.unknown_predicate_policy,
4717 self.rule_index,
4718 self.coordinate_index,
4719 self.unknown_predicate_hits,
4720 ),
4721 }
4722 }
4723
4724 fn trace_bool(&mut self, value: bool) -> bool {
4725 let key = (self.rule_index, self.coordinate_index);
4726 if !self.invoked_predicates.contains(&key) {
4727 self.invoked_predicates.push(key);
4728 use std::io::Write as _;
4729 let mut stdout = std::io::stdout().lock();
4730 let _ = writeln!(stdout, "eval={value}");
4731 }
4732 value
4733 }
4734}
4735
4736struct PredicateFailureRecovery<'a> {
4738 rule_index: usize,
4739 index: usize,
4740 message: &'a str,
4741 member_values: BTreeMap<usize, i64>,
4742 return_values: BTreeMap<String, i64>,
4743 rule_alt_number: usize,
4744}
4745
4746#[derive(Debug)]
4747enum DirectAdaptiveParseControl {
4748 Fallback(DirectAdaptiveFallback),
4749}
4750
4751#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4752enum DirectAdaptiveFallback {
4753 Action,
4754 InvalidAlt,
4755 LeftRecursiveBoundary,
4756 MissingAtn,
4757 NoTransition,
4758 Predicate,
4759 Prediction,
4760 Precedence,
4761 RuleStop,
4762 SemanticContext,
4763 StepLimit,
4764 TokenMismatch,
4765 UnknownDecision,
4766}
4767
4768type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
4769
4770struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
4771where
4772 S: TokenSource,
4773 H: SemanticHooks,
4774{
4775 parser: &'sim mut BaseParser<S, H>,
4776 atn: &'atn Atn,
4777 simulator: &'sim mut ParserAtnSimulator<'atn>,
4778 decision_by_state: Vec<Option<usize>>,
4779 steps: usize,
4780}
4781
4782#[derive(Clone, Debug, Eq, PartialEq)]
4792pub struct GeneratedMatch {
4793 children: GeneratedMatchChildren,
4794 consumed_eof: bool,
4795}
4796
4797#[derive(Clone, Copy)]
4798enum GeneratedExpectedSymbols<'a> {
4799 Tree(&'a BTreeSet<i32>),
4800 TokenSet(ParserIntervalSet<'a>),
4801 TokenSetComplement {
4802 set: ParserIntervalSet<'a>,
4803 min_vocabulary: i32,
4804 max_vocabulary: i32,
4805 },
4806}
4807
4808impl GeneratedExpectedSymbols<'_> {
4809 fn is_empty(self) -> bool {
4810 match self {
4811 Self::Tree(symbols) => symbols.is_empty(),
4812 Self::TokenSet(set) => set.is_empty(),
4813 Self::TokenSetComplement {
4814 set,
4815 min_vocabulary,
4816 max_vocabulary,
4817 } => (min_vocabulary..=max_vocabulary).all(|symbol| set.contains(symbol)),
4818 }
4819 }
4820
4821 fn first(self) -> Option<i32> {
4822 match self {
4823 Self::Tree(symbols) => symbols.iter().next().copied(),
4824 Self::TokenSet(set) => set.ranges().next().map(|(start, _)| start),
4825 Self::TokenSetComplement {
4826 set,
4827 min_vocabulary,
4828 max_vocabulary,
4829 } => (min_vocabulary..=max_vocabulary).find(|symbol| !set.contains(*symbol)),
4830 }
4831 }
4832
4833 fn display(self, vocabulary: &Vocabulary) -> String {
4834 match self {
4835 Self::Tree(symbols) => expected_symbols_display(symbols, vocabulary),
4836 Self::TokenSet(set) => expected_symbols_display_iter(
4837 set.ranges().flat_map(|(start, stop)| start..=stop),
4838 vocabulary,
4839 ),
4840 Self::TokenSetComplement {
4841 set,
4842 min_vocabulary,
4843 max_vocabulary,
4844 } => expected_symbols_display_iter(
4845 (min_vocabulary..=max_vocabulary).filter(|symbol| !set.contains(*symbol)),
4846 vocabulary,
4847 ),
4848 }
4849 }
4850}
4851
4852#[derive(Clone, Debug, Eq, PartialEq)]
4853enum GeneratedMatchChildren {
4854 One(ParseTree),
4855 Many(Vec<ParseTree>),
4856}
4857
4858struct GeneratedMatchChildrenIntoIter {
4859 one: Option<ParseTree>,
4860 many: Option<std::vec::IntoIter<ParseTree>>,
4861}
4862
4863impl Iterator for GeneratedMatchChildrenIntoIter {
4864 type Item = ParseTree;
4865
4866 fn next(&mut self) -> Option<Self::Item> {
4867 self.one
4868 .take()
4869 .or_else(|| self.many.as_mut().and_then(Iterator::next))
4870 }
4871}
4872
4873impl GeneratedMatch {
4874 #[must_use]
4878 pub fn children(&self) -> &[ParseTree] {
4879 match &self.children {
4880 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
4881 GeneratedMatchChildren::Many(children) => children,
4882 }
4883 }
4884
4885 #[must_use]
4888 pub fn into_children(self) -> Vec<ParseTree> {
4889 match self.children {
4890 GeneratedMatchChildren::One(child) => vec![child],
4891 GeneratedMatchChildren::Many(children) => children,
4892 }
4893 }
4894
4895 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
4897 match self.children {
4898 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
4899 one: Some(child),
4900 many: None,
4901 },
4902 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
4903 one: None,
4904 many: Some(children.into_iter()),
4905 },
4906 }
4907 }
4908
4909 #[must_use]
4911 pub const fn consumed_eof(&self) -> bool {
4912 self.consumed_eof
4913 }
4914}
4915
4916impl<S> BaseParser<S, NoSemanticHooks>
4917where
4918 S: TokenSource,
4919{
4920 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
4923 Self::with_semantic_hooks(input, data, NoSemanticHooks)
4924 }
4925}
4926
4927impl<S, H> BaseParser<S, H>
4928where
4929 S: TokenSource,
4930 H: SemanticHooks,
4931{
4932 pub fn with_semantic_hooks(
4934 input: CommonTokenStream<S>,
4935 data: RecognizerData,
4936 semantic_hooks: H,
4937 ) -> Self {
4938 Self {
4939 input,
4940 tree: ParseTreeStorage::new(),
4941 data,
4942 semantic_hooks,
4943 decision_override_generation: 0,
4944 build_parse_trees: true,
4945 syntax_errors: 0,
4946 report_diagnostic_errors: false,
4947 prediction_mode: PredictionMode::Ll,
4948 prediction_diagnostics: Vec::new(),
4949 reported_prediction_diagnostics: BTreeSet::new(),
4950 generated_parser_diagnostics: Vec::new(),
4951 generated_sync_expected: None,
4952 generated_recovery_error_index: None,
4953 generated_recovery_error_states: BTreeSet::new(),
4954 int_members: BTreeMap::new(),
4955 rule_context_stack: Vec::new(),
4956 rule_context_version: 0,
4957 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
4958 pending_invoking_states: Vec::new(),
4959 precedence_stack: vec![0],
4960 invoked_predicates: Vec::new(),
4961 bail_on_error: false,
4962 parse_listeners: Vec::new(),
4963 parse_listener_abort: None,
4964 max_rule_depth: None,
4965 rule_depth_error: None,
4966 recursion_expansions: 0,
4967 recursion_expansion_marks: Vec::new(),
4968 unknown_predicate_policy: UnknownSemanticPolicy::default(),
4969 unknown_predicate_hits: Vec::new(),
4970 unhandled_action_hits: Vec::new(),
4971 rule_first_set_cache: Vec::new(),
4972 state_expected_cache: FxHashMap::default(),
4973 state_expected_token_cache: FxHashMap::default(),
4974 rule_stop_reach_cache: Vec::new(),
4975 recovery_symbols_intern: FxHashMap::default(),
4976 decision_lookahead_cache: FxHashMap::default(),
4977 ll1_decision_cache: FxHashMap::default(),
4978 fast_predicate_cache: FxHashMap::default(),
4979 empty_cycle_cache: Vec::new(),
4980 empty_cycle_cache_atn: None,
4981 clean_memo_mode: CleanMemoMode::Probe,
4982 clean_memo_probe_seen: FxHashSet::default(),
4983 clean_memo_probe_samples: 0,
4984 clean_memo_probe_repeats: 0,
4985 clean_memo_sparse_samples: 0,
4986 fast_recognize_scratch: FastRecognizeTopScratch::default(),
4987 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
4988 empty_recovery_symbols: Rc::new(BTreeSet::new()),
4989 fast_first_set_prefilter: true,
4990 fast_recovery_enabled: true,
4991 fast_token_nodes_enabled: true,
4992 fast_track_alt_numbers: false,
4993 recognition_arena: RecognitionArena::default(),
4994 last_recognition_arena_root: NodeSeqId::EMPTY,
4995 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
4996 }
4997 }
4998
4999 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
5000 &mut self.input
5001 }
5002
5003 pub fn reset(&mut self) {
5008 self.input.seek(0);
5009 self.tree.reset();
5010 self.data.set_state(-1);
5011 self.syntax_errors = 0;
5012 self.prediction_diagnostics.clear();
5013 self.reported_prediction_diagnostics.clear();
5014 self.generated_parser_diagnostics.clear();
5015 self.generated_sync_expected = None;
5016 self.reset_generated_recovery_state();
5017 self.rule_context_stack.clear();
5018 self.advance_rule_context_version();
5019 self.left_recursive_caller_overlap_cache = std::array::from_fn(|_| None);
5020 self.pending_invoking_states.clear();
5021 self.precedence_stack.clear();
5022 self.precedence_stack.push(0);
5023 self.invoked_predicates.clear();
5024 self.decision_override_generation = 0;
5025 self.unknown_predicate_hits.clear();
5026 self.unhandled_action_hits.clear();
5027 self.parse_listener_abort = None;
5028 self.rule_depth_error = None;
5029 self.recursion_expansions = 0;
5030 self.recursion_expansion_marks.clear();
5031 self.reset_per_parse_caches();
5032 self.fast_first_set_prefilter = true;
5033 self.fast_recovery_enabled = true;
5034 self.fast_token_nodes_enabled = self.build_parse_trees;
5035 self.fast_track_alt_numbers = false;
5036 self.reset_recognition_arena();
5037 }
5038
5039 pub fn set_token_stream(&mut self, input: CommonTokenStream<S>) {
5041 self.input = input;
5042 self.reset();
5043 }
5044
5045 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
5056 self.unknown_predicate_policy = policy;
5057 }
5058
5059 #[must_use]
5065 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
5066 let error = self.unknown_semantic_error();
5067 self.unknown_predicate_hits.clear();
5068 self.unhandled_action_hits.clear();
5069 error
5070 }
5071
5072 pub fn reset_unknown_semantic_hits(&mut self) {
5079 self.unknown_predicate_hits.clear();
5080 self.unhandled_action_hits.clear();
5081 }
5082
5083 #[must_use]
5085 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
5086 &self.input
5087 }
5088
5089 #[must_use]
5091 pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<S> {
5092 &mut self.input
5093 }
5094
5095 #[must_use]
5097 pub const fn token_store(&self) -> &TokenStore {
5098 self.input.token_store()
5099 }
5100
5101 #[must_use]
5103 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
5104 &self.tree
5105 }
5106
5107 #[must_use]
5109 pub fn node(&self, id: NodeId) -> Node<'_> {
5110 self.tree
5111 .node(self.input.token_store(), id)
5112 .expect("parser-produced node ID should remain valid")
5113 }
5114
5115 #[must_use]
5117 pub fn into_token_stream(self) -> CommonTokenStream<S> {
5118 self.input
5119 }
5120
5121 #[must_use]
5123 pub fn into_token_store(self) -> TokenStore {
5124 self.input.into_token_store()
5125 }
5126
5127 #[must_use]
5129 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
5130 ParsedFile::new(self.input.into_token_store(), self.tree, root)
5131 }
5132
5133 pub const fn number_of_syntax_errors(&self) -> usize {
5136 self.syntax_errors
5137 }
5138
5139 #[must_use]
5145 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
5146 self.recognition_arena.stats(
5147 self.last_recognition_arena_root,
5148 self.last_recognition_arena_diagnostics,
5149 )
5150 }
5151
5152 pub const fn record_generated_syntax_error(&mut self) {
5155 self.record_syntax_errors(1);
5156 }
5157
5158 const fn record_syntax_errors(&mut self, count: usize) {
5159 self.syntax_errors = self.syntax_errors.saturating_add(count);
5160 }
5161
5162 pub fn report_token_source_errors(&mut self) {
5165 let errors = self.input.drain_source_errors();
5166 self.dispatch_token_source_errors(&errors);
5167 }
5168
5169 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
5172 GeneratedDiagnosticsCheckpoint {
5173 diagnostics_len: self.generated_parser_diagnostics.len(),
5174 syntax_errors: self.syntax_errors,
5175 tree: self.tree.checkpoint(),
5176 }
5177 }
5178
5179 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
5181 self.generated_parser_diagnostics
5182 .truncate(marker.diagnostics_len);
5183 self.syntax_errors = marker.syntax_errors;
5184 self.generated_sync_expected = None;
5185 self.tree.rollback(marker.tree);
5186 }
5187
5188 pub fn report_generated_parser_diagnostics(&mut self) {
5190 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
5191 let token_errors = self.input.drain_source_errors();
5192 self.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
5193 }
5194
5195 fn dispatch_parser_diagnostic(&self, diagnostic: &ParserDiagnostic) {
5196 let offending = diagnostic
5197 .offending
5198 .and_then(|token| self.token_store().view(token));
5199 self.notify_error_listeners(
5200 offending,
5201 diagnostic.line,
5202 diagnostic.column,
5203 &diagnostic.message,
5204 None,
5205 );
5206 }
5207
5208 fn dispatch_parser_diagnostics<'a>(
5209 &self,
5210 diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>,
5211 ) {
5212 for diagnostic in diagnostics {
5213 self.dispatch_parser_diagnostic(diagnostic);
5214 }
5215 }
5216
5217 fn dispatch_token_source_error(&self, source_error: &TokenSourceError) {
5218 if self.input.token_source().report_error(source_error) {
5219 return;
5220 }
5221 self.notify_error_listeners(
5224 None,
5225 source_error.line,
5226 source_error.column,
5227 &source_error.message,
5228 None,
5229 );
5230 }
5231
5232 fn dispatch_token_source_errors(&self, errors: &[TokenSourceError]) {
5233 for error in errors {
5234 self.dispatch_token_source_error(error);
5235 }
5236 }
5237
5238 fn dispatch_generated_diagnostics(
5241 &self,
5242 parser_diagnostics: &[ParserDiagnostic],
5243 token_errors: &[TokenSourceError],
5244 ) {
5245 let mut token_iter = token_errors.iter().peekable();
5251 for diagnostic in parser_diagnostics {
5252 while let Some(error) = token_iter.peek() {
5253 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
5254 self.dispatch_token_source_error(error);
5255 token_iter.next();
5256 } else {
5257 break;
5258 }
5259 }
5260 self.dispatch_parser_diagnostic(diagnostic);
5261 }
5262 for error in token_iter {
5263 self.dispatch_token_source_error(error);
5264 }
5265 }
5266
5267 pub fn record_generated_ambiguity_diagnostic(
5270 &mut self,
5271 atn: &Atn,
5272 state_number: usize,
5273 start_index: usize,
5274 stop_index: usize,
5275 alts: &[usize],
5276 ) {
5277 if !self.report_diagnostic_errors || alts.len() < 2 {
5278 return;
5279 }
5280 let Some(decision) = atn
5281 .decision_to_state()
5282 .iter()
5283 .position(|candidate| candidate == state_number)
5284 else {
5285 return;
5286 };
5287 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5288 return;
5289 };
5290 let rule_name = self
5291 .rule_names()
5292 .get(rule_index)
5293 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5294 let input = display_input_text(&self.input.text(start_index, stop_index));
5295 let alts = alts
5296 .iter()
5297 .map(usize::to_string)
5298 .collect::<Vec<_>>()
5299 .join(", ");
5300 let key = (decision, start_index, format!("{alts}:{input}"));
5301 if !self.reported_prediction_diagnostics.insert(key) {
5302 return;
5303 }
5304 let start_diagnostic = diagnostic_for_token(
5305 self.token_at(start_index),
5306 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
5307 );
5308 let stop_diagnostic = diagnostic_for_token(
5309 self.token_at(stop_index),
5310 format!(
5311 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
5312 ),
5313 );
5314 self.generated_parser_diagnostics.push(start_diagnostic);
5315 self.generated_parser_diagnostics.push(stop_diagnostic);
5316 }
5317
5318 pub fn record_generated_prediction_diagnostic(
5321 &mut self,
5322 atn: &Atn,
5323 state_number: usize,
5324 prediction: &ParserAtnPrediction,
5325 ) {
5326 let Some(diagnostic) = &prediction.diagnostic else {
5327 return;
5328 };
5329 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5330 return;
5331 }
5332 let Some(decision) = atn
5333 .decision_to_state()
5334 .iter()
5335 .position(|candidate| candidate == state_number)
5336 else {
5337 return;
5338 };
5339 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5340 return;
5341 };
5342 let rule_name = self
5343 .rule_names()
5344 .get(rule_index)
5345 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5346 let attempt_input = display_input_text(
5347 &self
5348 .input
5349 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5350 );
5351 let result_input = display_input_text(
5352 &self
5353 .input
5354 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5355 );
5356 let alts = diagnostic
5357 .conflicting_alts
5358 .iter()
5359 .map(usize::to_string)
5360 .collect::<Vec<_>>()
5361 .join(", ");
5362 let key = (
5363 decision,
5364 diagnostic.start_index,
5365 format!(
5366 "{:?}:{alts}:{attempt_input}:{result_input}",
5367 diagnostic.kind
5368 ),
5369 );
5370 if !self.reported_prediction_diagnostics.insert(key) {
5371 return;
5372 }
5373 let attempt_diagnostic = diagnostic_for_token(
5374 self.token_at(diagnostic.sll_stop_index),
5375 format!(
5376 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5377 ),
5378 );
5379 self.generated_parser_diagnostics.push(attempt_diagnostic);
5380 let message = match diagnostic.kind {
5381 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5382 if !diagnostic.exact {
5387 return;
5388 }
5389 format!(
5390 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5391 )
5392 }
5393 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5394 format!(
5395 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5396 )
5397 }
5398 };
5399 let result_diagnostic =
5400 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5401 self.generated_parser_diagnostics.push(result_diagnostic);
5402 }
5403
5404 pub fn la(&self, offset: isize) -> i32 {
5405 self.input.la_token(offset)
5406 }
5407
5408 pub fn consume(&mut self) {
5409 IntStream::consume(&mut self.input);
5410 }
5411
5412 pub fn set_int_member(&mut self, member: usize, value: i64) {
5414 self.int_members.insert(member, value);
5415 }
5416
5417 pub fn int_member(&self, member: usize) -> Option<i64> {
5419 self.int_members.get(&member).copied()
5420 }
5421
5422 pub fn int_members_checkpoint(&self) -> BTreeMap<usize, i64> {
5425 self.int_members.clone()
5426 }
5427
5428 pub fn restore_int_members(&mut self, members: BTreeMap<usize, i64>) {
5430 self.int_members = members;
5431 }
5432
5433 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5435 let value = self.int_members.entry(member).or_default();
5436 *value += delta;
5437 *value
5438 }
5439
5440 fn token_type_for_id(&self, id: TokenId) -> i32 {
5441 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5442 }
5443
5444 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5445 if self.build_parse_trees {
5446 self.tree.terminal(id)
5447 } else {
5448 NodeId::placeholder()
5449 }
5450 }
5451
5452 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5453 if self.build_parse_trees {
5454 self.tree.error(id)
5455 } else {
5456 NodeId::placeholder()
5457 }
5458 }
5459
5460 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5461 context.set_start_id(id);
5462 }
5463
5464 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5465 context.set_stop_id(id);
5466 }
5467
5468 fn insert_synthetic_token(
5469 &mut self,
5470 token_type: i32,
5471 text: String,
5472 line: usize,
5473 column: usize,
5474 ) -> Result<TokenId, AntlrError> {
5475 self.input
5476 .insert(
5477 TokenSpec::explicit(token_type, text)
5478 .with_span(usize::MAX, usize::MAX)
5479 .with_byte_span(0, 0)
5480 .with_position(line, column),
5481 )
5482 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5483 }
5484
5485 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5492 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5493 line: 0,
5494 column: 0,
5495 message: "missing current token".to_owned(),
5496 offending: None,
5497 })?;
5498 let current_type = self.token_type_for_id(current);
5499 if current_type == token_type {
5500 self.reset_generated_recovery_state();
5501 self.consume();
5502 Ok(self.terminal_tree(current))
5503 } else {
5504 Err(AntlrError::MismatchedInput {
5505 expected: self.vocabulary().display_name(token_type),
5506 found: self.vocabulary().display_name(current_type),
5507 })
5508 }
5509 }
5510
5511 pub fn match_token_recovering(
5515 &mut self,
5516 token_type: i32,
5517 follow_state: usize,
5518 atn: &Atn,
5519 ) -> Result<GeneratedMatch, AntlrError> {
5520 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5521 line: 0,
5522 column: 0,
5523 message: "missing current token".to_owned(),
5524 offending: None,
5525 })?;
5526 let current_type = self.token_type_for_id(current);
5527 if current_type == token_type {
5528 self.generated_sync_expected = None;
5529 self.reset_generated_recovery_state();
5530 let consumed_eof = current_type == TOKEN_EOF;
5531 self.consume();
5532 return Ok(GeneratedMatch {
5533 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5534 consumed_eof,
5535 });
5536 }
5537 let mut expected_symbols = BTreeSet::new();
5538 expected_symbols.insert(token_type);
5539 self.recover_generated_match(
5540 current,
5541 GeneratedExpectedSymbols::Tree(&expected_symbols),
5542 follow_state,
5543 atn,
5544 |symbol| symbol == token_type,
5545 )
5546 }
5547
5548 pub fn match_set_recovering(
5549 &mut self,
5550 intervals: &[(i32, i32)],
5551 follow_state: usize,
5552 atn: &Atn,
5553 ) -> Result<GeneratedMatch, AntlrError> {
5554 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5555 line: 0,
5556 column: 0,
5557 message: "missing current token".to_owned(),
5558 offending: None,
5559 })?;
5560 let current_type = self.token_type_for_id(current);
5561 if interval_set_contains(intervals, current_type) {
5562 self.generated_sync_expected = None;
5563 self.reset_generated_recovery_state();
5564 let consumed_eof = current_type == TOKEN_EOF;
5565 self.consume();
5566 return Ok(GeneratedMatch {
5567 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5568 consumed_eof,
5569 });
5570 }
5571 let expected_symbols = interval_symbols(intervals);
5572 self.recover_generated_match(
5573 current,
5574 GeneratedExpectedSymbols::Tree(&expected_symbols),
5575 follow_state,
5576 atn,
5577 |symbol| interval_set_contains(intervals, symbol),
5578 )
5579 }
5580
5581 pub fn match_token_set_recovering(
5582 &mut self,
5583 set: ParserIntervalSet<'_>,
5584 follow_state: usize,
5585 atn: &Atn,
5586 ) -> Result<GeneratedMatch, AntlrError> {
5587 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5588 line: 0,
5589 column: 0,
5590 message: "missing current token".to_owned(),
5591 offending: None,
5592 })?;
5593 let current_type = self.token_type_for_id(current);
5594 if set.contains(current_type) {
5595 self.generated_sync_expected = None;
5596 self.reset_generated_recovery_state();
5597 let consumed_eof = current_type == TOKEN_EOF;
5598 self.consume();
5599 return Ok(GeneratedMatch {
5600 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5601 consumed_eof,
5602 });
5603 }
5604 self.recover_generated_match(
5605 current,
5606 GeneratedExpectedSymbols::TokenSet(set),
5607 follow_state,
5608 atn,
5609 |symbol| set.contains(symbol),
5610 )
5611 }
5612
5613 pub fn match_not_set_recovering(
5614 &mut self,
5615 intervals: &[(i32, i32)],
5616 min_vocabulary: i32,
5617 max_vocabulary: i32,
5618 follow_state: usize,
5619 atn: &Atn,
5620 ) -> Result<GeneratedMatch, AntlrError> {
5621 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5622 line: 0,
5623 column: 0,
5624 message: "missing current token".to_owned(),
5625 offending: None,
5626 })?;
5627 let current_type = self.token_type_for_id(current);
5628 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5629 && !interval_set_contains(intervals, current_type)
5630 {
5631 self.generated_sync_expected = None;
5632 self.reset_generated_recovery_state();
5633 let consumed_eof = current_type == TOKEN_EOF;
5634 self.consume();
5635 return Ok(GeneratedMatch {
5636 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5637 consumed_eof,
5638 });
5639 }
5640 let expected_symbols =
5641 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
5642 self.recover_generated_match(
5643 current,
5644 GeneratedExpectedSymbols::Tree(&expected_symbols),
5645 follow_state,
5646 atn,
5647 |symbol| {
5648 (min_vocabulary..=max_vocabulary).contains(&symbol)
5649 && !interval_set_contains(intervals, symbol)
5650 },
5651 )
5652 }
5653
5654 pub fn match_not_token_set_recovering(
5655 &mut self,
5656 set: ParserIntervalSet<'_>,
5657 min_vocabulary: i32,
5658 max_vocabulary: i32,
5659 follow_state: usize,
5660 atn: &Atn,
5661 ) -> Result<GeneratedMatch, AntlrError> {
5662 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5663 line: 0,
5664 column: 0,
5665 message: "missing current token".to_owned(),
5666 offending: None,
5667 })?;
5668 let current_type = self.token_type_for_id(current);
5669 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
5670 {
5671 self.generated_sync_expected = None;
5672 self.reset_generated_recovery_state();
5673 let consumed_eof = current_type == TOKEN_EOF;
5674 self.consume();
5675 return Ok(GeneratedMatch {
5676 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5677 consumed_eof,
5678 });
5679 }
5680 self.recover_generated_match(
5681 current,
5682 GeneratedExpectedSymbols::TokenSetComplement {
5683 set,
5684 min_vocabulary,
5685 max_vocabulary,
5686 },
5687 follow_state,
5688 atn,
5689 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
5690 )
5691 }
5692
5693 fn recover_generated_match(
5694 &mut self,
5695 current: TokenId,
5696 expected_symbols: GeneratedExpectedSymbols<'_>,
5697 follow_state: usize,
5698 atn: &Atn,
5699 matches: impl Fn(i32) -> bool,
5700 ) -> Result<GeneratedMatch, AntlrError> {
5701 let expected_display = expected_symbols.display(self.vocabulary());
5702 let (current_type, current_line, current_column, current_display) = {
5703 let token = self
5704 .input
5705 .token_view(current)
5706 .expect("current token ID should be valid");
5707 (
5708 token.token_type(),
5709 token.line(),
5710 token.column(),
5711 token_input_display(&token),
5712 )
5713 };
5714 if self.bail_on_error {
5715 return Err(AntlrError::ParserError {
5716 line: current_line,
5717 column: current_column,
5718 message: format!("mismatched input {current_display} expecting {expected_display}"),
5719 offending: Some(current),
5720 });
5721 }
5722 if current_type != TOKEN_EOF
5723 && let Some(next) = self.input.lt_id(2)
5724 && matches(self.token_type_for_id(next))
5725 {
5726 let message =
5727 format!("extraneous input {current_display} expecting {expected_display}");
5728 self.push_generated_parser_diagnostic(ParserDiagnostic {
5729 line: current_line,
5730 column: current_column,
5731 message,
5732 offending: Some(current),
5733 });
5734 self.record_syntax_errors(1);
5735 self.generated_sync_expected = None;
5736 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
5739 self.consume();
5740 self.consume();
5741 self.reset_generated_recovery_state();
5742 return Ok(GeneratedMatch {
5743 children: GeneratedMatchChildren::Many(vec![
5744 self.error_tree(current),
5745 self.terminal_tree(next),
5746 ]),
5747 consumed_eof,
5748 });
5749 }
5750 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
5751 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
5760 && self
5761 .cached_state_expected_symbols(atn, follow_state)
5762 .contains(&TOKEN_EOF);
5763 if follow_symbols.contains(¤t_type)
5764 && (current_type != TOKEN_EOF
5765 || self.rule_context_stack.len() > 1
5766 || expected_symbols.is_empty()
5767 || follow_explicitly_expects_eof)
5768 {
5769 let message = format!("missing {expected_display} at {current_display}");
5770 self.push_generated_parser_diagnostic(ParserDiagnostic {
5771 line: current_line,
5772 column: current_column,
5773 message,
5774 offending: Some(current),
5775 });
5776 self.record_syntax_errors(1);
5777 self.generated_sync_expected = None;
5778 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
5779 let missing_display = expected_symbol_display(token_type, self.vocabulary());
5780 let token = self.insert_synthetic_token(
5781 token_type,
5782 format!("<missing {missing_display}>"),
5783 current_line,
5784 current_column,
5785 )?;
5786 return Ok(GeneratedMatch {
5791 children: GeneratedMatchChildren::One(self.error_tree(token)),
5792 consumed_eof: false,
5793 });
5794 }
5795 let mismatch_expected_display = self
5796 .generated_sync_expected
5797 .take()
5798 .map_or(expected_display, |symbols| {
5799 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
5800 });
5801 Err(AntlrError::ParserError {
5802 line: current_line,
5803 column: current_column,
5804 message: format!(
5805 "mismatched input {current_display} expecting {mismatch_expected_display}"
5806 ),
5807 offending: Some(current),
5808 })
5809 }
5810
5811 fn generated_recovery_follow_symbols(
5812 &mut self,
5813 atn: &Atn,
5814 follow_state: usize,
5815 ) -> BTreeSet<i32> {
5816 let mut follow = self
5817 .cached_state_expected_symbols(atn, follow_state)
5818 .as_ref()
5819 .clone();
5820 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
5821 follow.extend(self.context_expected_symbols(atn));
5822 }
5823 follow
5824 }
5825
5826 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
5827 self.match_token(TOKEN_EOF)
5828 }
5829
5830 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
5831 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
5832 }
5833
5834 pub fn match_not_set(
5835 &mut self,
5836 intervals: &[(i32, i32)],
5837 min_vocabulary: i32,
5838 max_vocabulary: i32,
5839 ) -> Result<ParseTree, AntlrError> {
5840 self.match_interval_condition(intervals, |symbol| {
5841 (min_vocabulary..=max_vocabulary).contains(&symbol)
5842 && !interval_set_contains(intervals, symbol)
5843 })
5844 }
5845
5846 fn match_interval_condition(
5847 &mut self,
5848 intervals: &[(i32, i32)],
5849 matches: impl FnOnce(i32) -> bool,
5850 ) -> Result<ParseTree, AntlrError> {
5851 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5852 line: 0,
5853 column: 0,
5854 message: "missing current token".to_owned(),
5855 offending: None,
5856 })?;
5857 let current_type = self.token_type_for_id(current);
5858 if matches(current_type) {
5859 self.reset_generated_recovery_state();
5860 self.consume();
5861 Ok(self.terminal_tree(current))
5862 } else {
5863 Err(AntlrError::MismatchedInput {
5864 expected: self.interval_display(intervals),
5865 found: self.vocabulary().display_name(current_type),
5866 })
5867 }
5868 }
5869
5870 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
5871 let values = intervals
5872 .iter()
5873 .map(|(start, stop)| {
5874 if start == stop {
5875 self.vocabulary().display_name(*start)
5876 } else {
5877 format!(
5878 "{}..{}",
5879 self.vocabulary().display_name(*start),
5880 self.vocabulary().display_name(*stop)
5881 )
5882 }
5883 })
5884 .collect::<Vec<_>>()
5885 .join(", ");
5886 format!("{{{values}}}")
5887 }
5888
5889 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
5890 if self.build_parse_trees {
5891 self.tree.finish_rule(context)
5892 } else {
5893 NodeId::placeholder()
5894 }
5895 }
5896
5897 #[must_use]
5906 pub const fn generated_rule_stack_check_due(&self) -> bool {
5907 self.rule_context_stack
5908 .len()
5909 .is_multiple_of(GENERATED_RULE_STACK_CHECK_INTERVAL)
5910 }
5911
5912 #[inline]
5930 pub fn rule_depth_cap_violation(&mut self) -> Option<AntlrError> {
5931 let max = self.max_rule_depth?;
5932 if self.rule_depth_error.is_none()
5935 && self.rule_context_stack.len() + self.recursion_expansions < max
5936 {
5937 return None;
5938 }
5939 Some(self.rule_depth_cap_violation_cold(max))
5940 }
5941
5942 #[cold]
5943 fn rule_depth_cap_violation_cold(&mut self, max: usize) -> AntlrError {
5944 if let Some(error) = &self.rule_depth_error {
5945 return error.clone();
5946 }
5947 let current = self.input.lt(1);
5948 let (line, column) = current
5949 .as_ref()
5950 .map_or((0, 0), |token| (token.line(), token.column()));
5951 let error = AntlrError::ParserError {
5952 line,
5953 column,
5954 message: format!("rule nesting depth limit of {max} exceeded"),
5955 offending: current.as_ref().map(Token::token_id),
5956 };
5957 self.rule_depth_error = Some(error.clone());
5958 error
5959 }
5960
5961 pub const fn take_rule_depth_error(&mut self) -> Option<AntlrError> {
5968 self.rule_depth_error.take()
5969 }
5970
5971 #[must_use]
5978 pub const fn has_rule_depth_cap(&self) -> bool {
5979 self.max_rule_depth.is_some()
5980 }
5981
5982 pub fn add_parse_listener<L>(&mut self, listener: L)
5986 where
5987 L: ParseListener + 'static,
5988 {
5989 self.parse_listeners
5990 .push(ParseListenerSlot(Box::new(listener)));
5991 }
5992
5993 pub fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
6000 self.parse_listener_abort = None;
6001 self.parse_listeners.drain(..).map(|slot| slot.0).collect()
6002 }
6003
6004 #[must_use]
6010 pub const fn has_parse_listeners(&self) -> bool {
6011 !self.parse_listeners.is_empty()
6012 }
6013
6014 pub fn parse_listener_enter_rule(&mut self, rule_index: usize) -> Option<AntlrError> {
6025 if self.parse_listeners.is_empty() {
6026 return None;
6027 }
6028 self.parse_listener_enter_rule_dispatch(rule_index)
6029 }
6030
6031 fn parse_listener_enter_rule_dispatch(&mut self, rule_index: usize) -> Option<AntlrError> {
6032 if let Some(error) = &self.parse_listener_abort {
6033 return Some(error.clone());
6034 }
6035 let event = EnterRuleEvent {
6036 rule_index,
6037 current: self.input.lt(1),
6038 };
6039 let mut listeners = std::mem::take(&mut self.parse_listeners);
6043 let mut abort = None;
6044 for slot in &mut listeners {
6045 if let Err(error) = slot.0.enter_every_rule(&event) {
6046 abort = Some(error);
6047 break;
6048 }
6049 }
6050 self.parse_listeners = listeners;
6051 if let Some(error) = abort {
6052 self.parse_listener_abort = Some(error.clone());
6053 return Some(error);
6054 }
6055 None
6056 }
6057
6058 pub fn parse_listener_exit_rule(&mut self, rule_index: usize) {
6065 if self.parse_listeners.is_empty() {
6066 return;
6067 }
6068 for slot in self.parse_listeners.iter_mut().rev() {
6071 slot.0.exit_every_rule(rule_index);
6072 }
6073 }
6074
6075 pub const fn take_parse_listener_abort(&mut self) -> Option<AntlrError> {
6082 self.parse_listener_abort.take()
6083 }
6084
6085 pub fn take_parse_abort(&mut self) -> Option<AntlrError> {
6094 if let Some(error) = self.rule_depth_error.take() {
6095 self.parse_listener_abort = None;
6096 return Some(error);
6097 }
6098 self.parse_listener_abort.take()
6099 }
6100
6101 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
6104 self.set_state(state);
6105 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
6106 self.rule_context_stack.push(RuleContextFrame {
6107 rule_index,
6108 invoking_state,
6109 });
6110 self.advance_rule_context_version();
6111 let start_index = self.current_visible_index();
6112 let mut context = ParserRuleContext::new(rule_index, invoking_state);
6113 if let Some(token) = self.token_id_at(start_index) {
6114 self.set_context_start(&mut context, token);
6115 }
6116 context
6117 }
6118
6119 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
6126 let marker = self.pending_invoking_states.len();
6127 self.pending_invoking_states.push(invoking_state);
6128 marker
6129 }
6130
6131 pub fn discard_invoking_state(&mut self, marker: usize) {
6133 self.pending_invoking_states.truncate(marker);
6134 }
6135
6136 pub fn exit_rule(&mut self) {
6138 self.rule_context_stack.pop();
6139 self.advance_rule_context_version();
6140 }
6141
6142 pub fn prediction_context_return_states<'a>(
6145 &'a self,
6146 atn: &'a Atn,
6147 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
6148 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
6149 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
6150 return None;
6151 };
6152 let Some(Transition::Rule { follow_state, .. }) = atn
6153 .state(state_number)
6154 .and_then(|state| state.transitions().first())
6155 .map(ParserTransition::data)
6156 else {
6157 return None;
6158 };
6159 Some(follow_state)
6160 })
6161 }
6162
6163 pub const fn rule_context_version(&self) -> usize {
6168 self.rule_context_version
6169 }
6170
6171 const fn advance_rule_context_version(&mut self) {
6172 self.rule_context_version = self.rule_context_version.wrapping_add(1);
6173 }
6174
6175 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
6180 if self.build_parse_trees {
6181 self.tree.add_child(context, child);
6182 } else {
6183 context.note_matched_child();
6184 }
6185 }
6186
6187 fn release_tree_scratch_if_idle(&mut self) {
6188 if self.rule_context_stack.is_empty() {
6189 self.tree.release_scratch();
6190 }
6191 }
6192
6193 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
6195 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6196 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6197 self.set_context_stop(&mut context, token);
6198 }
6199 let node = self.rule_node(context);
6200 self.exit_rule();
6201 self.release_tree_scratch_if_idle();
6202 node
6203 }
6204
6205 pub fn recover_generated_rule(
6212 &mut self,
6213 context: &mut ParserRuleContext,
6214 atn: &Atn,
6215 error: AntlrError,
6216 ) {
6217 let diagnostic = self.generated_rule_error_diagnostic(error);
6218 self.push_generated_parser_diagnostic(diagnostic);
6219 self.generated_sync_expected = None;
6220 let error_index = self.input.index();
6221 let error_state = self.data.state();
6222 if self.generated_recovery_error_index == Some(error_index)
6227 && self.generated_recovery_error_states.contains(&error_state)
6228 && self.la(1) != TOKEN_EOF
6229 && let Some(token) = self.input.lt_id(1)
6230 {
6231 self.consume();
6232 let child = self.error_tree(token);
6233 self.add_parse_child(context, child);
6234 }
6235 let recovery_index = self.input.index();
6236 if self.generated_recovery_error_index != Some(recovery_index) {
6237 self.generated_recovery_error_index = Some(recovery_index);
6238 self.generated_recovery_error_states.clear();
6239 }
6240 self.generated_recovery_error_states.insert(error_state);
6241 let recovery_symbols = self.context_expected_symbols(atn);
6242 loop {
6243 let symbol = self.la(1);
6244 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
6245 break;
6246 }
6247 let Some(token) = self.input.lt_id(1) else {
6248 break;
6249 };
6250 self.consume();
6251 let child = self.error_tree(token);
6252 self.add_parse_child(context, child);
6253 }
6254 self.record_syntax_errors(1);
6255 }
6256
6257 fn reset_generated_recovery_state(&mut self) {
6258 if self.generated_recovery_error_index.is_some() {
6259 self.generated_recovery_error_index = None;
6260 self.generated_recovery_error_states.clear();
6261 }
6262 }
6263
6264 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
6265 if self
6266 .generated_parser_diagnostics
6267 .iter()
6268 .any(|existing| existing == &diagnostic)
6269 {
6270 return;
6271 }
6272 self.generated_parser_diagnostics.push(diagnostic);
6273 }
6274
6275 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
6276 match error {
6277 AntlrError::ParserError {
6281 line,
6282 column,
6283 message,
6284 offending,
6285 } => ParserDiagnostic {
6286 line,
6287 column,
6288 message,
6289 offending,
6290 },
6291 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
6292 self.input.lt(1),
6293 format!("mismatched input {found} expecting {expected}"),
6294 ),
6295 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
6296 self.input.lt(1),
6297 format!("no viable alternative at input {input}"),
6298 ),
6299 AntlrError::LexerError {
6300 line,
6301 column,
6302 message,
6303 } => ParserDiagnostic {
6304 line,
6305 column,
6306 message,
6307 offending: None,
6308 },
6309 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
6310 }
6311 }
6312
6313 pub fn finish_recursion_rule(
6315 &mut self,
6316 mut context: ParserRuleContext,
6317 consumed_eof: bool,
6318 ) -> ParseTree {
6319 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6320 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6321 self.set_context_stop(&mut context, token);
6322 }
6323 let node = self.rule_node(context);
6324 self.unroll_recursion_context();
6325 self.release_tree_scratch_if_idle();
6326 node
6327 }
6328
6329 pub fn enter_recursion_rule(
6331 &mut self,
6332 state: isize,
6333 rule_index: usize,
6334 precedence: i32,
6335 ) -> ParserRuleContext {
6336 self.precedence_stack.push(precedence);
6337 self.recursion_expansion_marks
6338 .push(self.recursion_expansions);
6339 self.enter_rule(state, rule_index)
6340 }
6341
6342 pub fn push_new_recursion_context(
6344 &mut self,
6345 state: isize,
6346 rule_index: usize,
6347 ) -> ParserRuleContext {
6348 self.set_state(state);
6349 self.recursion_expansions += 1;
6352 ParserRuleContext::new(rule_index, state)
6353 }
6354
6355 pub fn push_new_recursion_context_with_previous(
6358 &mut self,
6359 state: isize,
6360 rule_index: usize,
6361 current: &mut ParserRuleContext,
6362 ) {
6363 self.set_state(state);
6364 self.recursion_expansions += 1;
6370 if let Some(stop) = self
6371 .rule_stop_token_index(self.input.index(), false)
6372 .and_then(|index| self.token_id_at(index))
6373 {
6374 self.set_context_stop(current, stop);
6375 }
6376 let invoking_state = current.invoking_state();
6377 let start = current.start_id();
6378 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
6379 if start.is_some() {
6380 replacement.set_start_from_context(current);
6381 }
6382 let previous = std::mem::replace(current, replacement);
6383 if self.build_parse_trees {
6384 let previous = self.rule_node(previous);
6385 self.tree.add_child(current, previous);
6386 }
6387 }
6388
6389 pub fn unroll_recursion_context(&mut self) {
6391 if self.precedence_stack.len() > 1 {
6392 self.precedence_stack.pop();
6393 }
6394 if let Some(mark) = self.recursion_expansion_marks.pop() {
6400 self.recursion_expansions = mark;
6401 }
6402 self.exit_rule();
6403 }
6404
6405 pub fn left_recursive_loop_enter_prediction(
6419 &mut self,
6420 atn: &Atn,
6421 state_number: usize,
6422 precedence: i32,
6423 ) -> Option<bool> {
6424 let symbol = self.la(1);
6425 if symbol == TOKEN_EOF {
6426 return Some(false);
6427 }
6428 let operator_lookahead =
6429 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
6430 let can_single = operator_lookahead.single_token.contains(symbol);
6431 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
6432 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
6433 if !can_single && !can_multi && !can_predicate {
6434 return Some(false);
6435 }
6436 if can_predicate && !can_single {
6437 return None;
6438 }
6439 if !can_single && can_multi && precedence > 0 {
6443 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
6444 if baseline.single_token.contains(symbol) {
6445 return None;
6446 }
6447 }
6448 let atn_key = SharedAtnCacheKey::for_atn(atn);
6449 let cached_overlap = self
6450 .left_recursive_caller_overlap_cache
6451 .iter()
6452 .flatten()
6453 .find(|entry| {
6454 entry.atn_key == atn_key
6455 && entry.state_number == state_number
6456 && entry.symbol == symbol
6457 && entry.context_version == self.rule_context_version
6458 })
6459 .map(|entry| entry.overlaps);
6460 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
6461 let overlaps = caller_context_can_match_symbol_before_state(
6462 atn,
6463 self.prediction_context_return_states(atn),
6464 state_number,
6465 symbol,
6466 );
6467 if let Some(slot) = self
6468 .left_recursive_caller_overlap_cache
6469 .iter_mut()
6470 .find(|slot| slot.is_none())
6471 {
6472 *slot = Some(LeftRecursiveCallerOverlap {
6473 atn_key,
6474 state_number,
6475 symbol,
6476 context_version: self.rule_context_version,
6477 overlaps,
6478 });
6479 }
6480 overlaps
6481 });
6482 if caller_overlaps {
6483 return None;
6484 }
6485 Some(true)
6486 }
6487
6488 fn cached_left_recursive_operator_lookahead(
6489 atn: &Atn,
6490 state_number: usize,
6491 precedence: i32,
6492 ) -> Rc<LeftRecursiveOperatorLookahead> {
6493 with_shared_atn_caches(atn, |cache| {
6494 let key = (state_number, precedence);
6495 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
6496 return Rc::clone(cached);
6497 }
6498 let lookahead = Rc::new(left_recursive_operator_lookahead(
6499 atn,
6500 state_number,
6501 precedence,
6502 ));
6503 cache
6504 .left_recursive_operator_lookahead
6505 .insert(key, Rc::clone(&lookahead));
6506 lookahead
6507 })
6508 }
6509
6510 pub fn left_recursive_loop_enter_matches(
6513 &mut self,
6514 atn: &Atn,
6515 state_number: usize,
6516 precedence: i32,
6517 ) -> bool {
6518 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
6519 }
6520
6521 pub fn precpred(&self, precedence: i32) -> bool {
6523 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
6524 }
6525
6526 pub fn parser_semantic_predicate_matches(
6529 &mut self,
6530 predicates: &[(usize, usize, ParserPredicate)],
6531 rule_index: usize,
6532 pred_index: usize,
6533 ) -> bool {
6534 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
6535 }
6536
6537 pub fn parser_semantic_predicate_matches_with_local(
6540 &mut self,
6541 predicates: &[(usize, usize, ParserPredicate)],
6542 rule_index: usize,
6543 pred_index: usize,
6544 local_int_arg: i32,
6545 ) -> bool {
6546 self.parser_semantic_predicate_matches_inner(
6547 predicates,
6548 rule_index,
6549 pred_index,
6550 Some((rule_index, i64::from(local_int_arg))),
6551 )
6552 }
6553
6554 fn parser_semantic_predicate_matches_inner(
6555 &mut self,
6556 predicates: &[(usize, usize, ParserPredicate)],
6557 rule_index: usize,
6558 pred_index: usize,
6559 local_int_arg: Option<(usize, i64)>,
6560 ) -> bool {
6561 let index = self.input.index();
6562 let member_values = self.int_members.clone();
6563 self.parser_predicate_matches(PredicateEval {
6564 index,
6565 rule_index,
6566 pred_index,
6567 predicates,
6568 semantics: None,
6569 context: None,
6570 local_int_arg,
6571 member_values: &member_values,
6572 })
6573 }
6574
6575 pub fn parser_semantic_predicate_matches_with_context_and_local(
6578 &mut self,
6579 predicates: &[(usize, usize, ParserPredicate)],
6580 rule_index: usize,
6581 pred_index: usize,
6582 context: &ParserRuleContext,
6583 local_int_arg: i32,
6584 ) -> bool {
6585 let index = self.input.index();
6586 let member_values = self.int_members.clone();
6587 self.parser_predicate_matches(PredicateEval {
6588 index,
6589 rule_index,
6590 pred_index,
6591 predicates,
6592 semantics: None,
6593 context: Some(context),
6594 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6595 member_values: &member_values,
6596 })
6597 }
6598
6599 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
6602 &mut self,
6603 semantics: &ParserSemantics,
6604 rule_index: usize,
6605 pred_index: usize,
6606 context: &ParserRuleContext,
6607 local_int_arg: i32,
6608 ) -> bool {
6609 let index = self.input.index();
6610 let member_values = self.int_members.clone();
6611 self.parser_predicate_matches(PredicateEval {
6612 index,
6613 rule_index,
6614 pred_index,
6615 predicates: &[],
6616 semantics: Some(semantics),
6617 context: Some(context),
6618 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6619 member_values: &member_values,
6620 })
6621 }
6622
6623 pub fn parser_semantic_predicate_failure_message(
6626 &self,
6627 rule_index: usize,
6628 pred_index: usize,
6629 predicates: &[(usize, usize, ParserPredicate)],
6630 ) -> Option<&'static str> {
6631 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
6632 }
6633
6634 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
6636 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6637 line: 0,
6638 column: 0,
6639 message: "missing current token".to_owned(),
6640 offending: None,
6641 })?;
6642 if self.token_type_for_id(current) == TOKEN_EOF {
6643 return Err(AntlrError::MismatchedInput {
6644 expected: "wildcard".to_owned(),
6645 found: self.vocabulary().display_name(TOKEN_EOF),
6646 });
6647 }
6648 self.reset_generated_recovery_state();
6649 self.consume();
6650 Ok(self.terminal_tree(current))
6651 }
6652
6653 #[allow(clippy::unnecessary_wraps)]
6657 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
6658 self.set_state(state);
6659 Ok(())
6660 }
6661
6662 pub fn sync_decision(
6670 &mut self,
6671 atn: &Atn,
6672 state_number: usize,
6673 current_context_empty: bool,
6674 loop_back: bool,
6675 ) -> Result<Vec<ParseTree>, AntlrError> {
6676 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
6677 self.generated_sync_expected = None;
6678 let Some(state) = atn.state(state_number) else {
6679 return Ok(Vec::new());
6680 };
6681 let Some(rule_index) = state.rule_index() else {
6682 return Ok(Vec::new());
6683 };
6684 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
6685 return Ok(Vec::new());
6686 };
6687 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6688 let symbol = self.la(1);
6689 let mut has_expected_symbols = false;
6690 let mut nullable = false;
6691 let mut explicit_eof_expected = false;
6699 for transition in &entry.transitions {
6700 if transition.symbols.contains(symbol) {
6701 return Ok(Vec::new());
6702 }
6703 has_expected_symbols |= !transition.symbols.is_empty();
6704 nullable |= transition.nullable;
6705 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
6706 }
6707 if nullable && self.context_expected_contains(atn, symbol) {
6712 return Ok(Vec::new());
6713 }
6714 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
6715 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
6716 return Ok(Vec::new());
6717 }
6718 let mut expected = TokenBitSet::default();
6719 for transition in &entry.transitions {
6720 expected.extend_from(&transition.symbols);
6721 }
6722 if let Some(context_expected) = context_expected {
6723 expected.extend_from(&context_expected);
6724 }
6725 let can_delete_in_place =
6726 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
6727 let loop_sync = loop_back;
6744 if symbol != TOKEN_EOF && can_delete_in_place {
6745 let mut cursor = self.input.index();
6746 let mut skipped = Vec::new();
6747 loop {
6748 let current = self.token_type_at(cursor);
6749 if current == TOKEN_EOF {
6750 break;
6751 }
6752 skipped.push(cursor);
6753 let next = self.consume_index(cursor, current);
6754 if next == cursor {
6755 break;
6756 }
6757 let next_symbol = self.token_type_at(next);
6758 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
6766 explicit_eof_expected
6767 } else {
6768 expected.contains(next_symbol)
6769 };
6770 if next_is_expected_stop {
6771 let current_token = self.input.lt(1);
6772 let expected_symbols = expected.to_btree_set();
6773 let message = format!(
6774 "extraneous input {} expecting {}",
6775 current_token
6776 .as_ref()
6777 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6778 self.expected_symbols_display(&expected_symbols)
6779 );
6780 self.push_generated_parser_diagnostic(diagnostic_for_token(
6781 current_token,
6782 message,
6783 ));
6784 self.record_syntax_errors(1);
6785 let mut children = Vec::with_capacity(skipped.len());
6786 for index in skipped {
6787 if let Some(token) = self.token_id_at(index) {
6788 self.consume();
6789 children.push(self.error_tree(token));
6790 }
6791 }
6792 if !loop_sync {
6793 self.reset_generated_recovery_state();
6794 }
6795 return Ok(children);
6796 }
6797 if !loop_sync {
6801 break;
6802 }
6803 cursor = next;
6804 }
6805 }
6806 if nullable {
6807 self.generated_sync_expected = Some(expected);
6808 return Ok(Vec::new());
6809 }
6810 let current = self.input.lt(1);
6811 let expected_symbols = expected.to_btree_set();
6812 Err(AntlrError::ParserError {
6813 line: current.as_ref().map(Token::line).unwrap_or_default(),
6814 column: current.as_ref().map(Token::column).unwrap_or_default(),
6815 message: format!(
6816 "mismatched input {} expecting {}",
6817 current
6818 .as_ref()
6819 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6820 self.expected_symbols_display(&expected_symbols)
6821 ),
6822 offending: current.as_ref().map(Token::token_id),
6823 })
6824 }
6825
6826 pub fn ll1_decision_prediction(
6833 &mut self,
6834 atn: &Atn,
6835 state_number: usize,
6836 ) -> Option<ParserAtnPrediction> {
6837 let state = atn.state(state_number)?;
6838 if state.precedence_rule_decision() {
6839 return None;
6840 }
6841 let rule_stop = state
6842 .rule_index()
6843 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
6844 let symbol = self.la(1);
6845 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6846 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
6847 alt: alt + 1,
6848 requires_full_context: false,
6849 has_semantic_context: false,
6850 diagnostic: None,
6851 })
6852 }
6853
6854 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
6855 let mut expected = BTreeSet::new();
6856 for index in (1..self.rule_context_stack.len()).rev() {
6857 let invoking_state = self.rule_context_stack[index].invoking_state;
6858 let Ok(state_number) = usize::try_from(invoking_state) else {
6859 continue;
6860 };
6861 let Some(Transition::Rule { follow_state, .. }) = atn
6862 .state(state_number)
6863 .and_then(|state| state.transitions().first())
6864 .map(ParserTransition::data)
6865 else {
6866 continue;
6867 };
6868 let return_state = follow_state;
6869 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
6870 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
6871 return expected;
6872 }
6873 }
6874 expected.insert(TOKEN_EOF);
6875 expected
6876 }
6877
6878 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
6879 let mut expected = TokenBitSet::default();
6880 for index in (1..self.rule_context_stack.len()).rev() {
6881 let invoking_state = self.rule_context_stack[index].invoking_state;
6882 let Ok(state_number) = usize::try_from(invoking_state) else {
6883 continue;
6884 };
6885 let Some(Transition::Rule { follow_state, .. }) = atn
6886 .state(state_number)
6887 .and_then(|state| state.transitions().first())
6888 .map(ParserTransition::data)
6889 else {
6890 continue;
6891 };
6892 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
6893 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6894 return expected;
6895 }
6896 }
6897 expected.insert(TOKEN_EOF);
6898 expected
6899 }
6900
6901 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
6912 for index in (1..self.rule_context_stack.len()).rev() {
6913 let invoking_state = self.rule_context_stack[index].invoking_state;
6914 let Ok(state_number) = usize::try_from(invoking_state) else {
6915 continue;
6916 };
6917 let Some(Transition::Rule { follow_state, .. }) = atn
6918 .state(state_number)
6919 .and_then(|state| state.transitions().first())
6920 .map(ParserTransition::data)
6921 else {
6922 continue;
6923 };
6924 if self
6925 .cached_state_expected_token_set(atn, follow_state)
6926 .contains(symbol)
6927 {
6928 return true;
6929 }
6930 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
6931 return false;
6932 }
6933 }
6934 symbol == TOKEN_EOF
6935 }
6936
6937 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
6939 let error_index = self.input.index();
6940 self.no_viable_alternative_error_at(start_index, error_index)
6941 }
6942
6943 pub fn no_viable_alternative_error_at(
6948 &self,
6949 start_index: usize,
6950 error_index: usize,
6951 ) -> AntlrError {
6952 let diagnostic = self.no_viable_alternative(start_index, error_index);
6953 AntlrError::ParserError {
6954 line: diagnostic.line,
6955 column: diagnostic.column,
6956 message: diagnostic.message,
6957 offending: diagnostic.offending,
6958 }
6959 }
6960
6961 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
6963 let current = self.input.lt(1);
6964 AntlrError::ParserError {
6965 line: current.as_ref().map(Token::line).unwrap_or_default(),
6966 column: current.as_ref().map(Token::column).unwrap_or_default(),
6967 message: format!("rule failed predicate: {}", message.into()),
6968 offending: current.as_ref().map(Token::token_id),
6969 }
6970 }
6971
6972 pub fn failed_predicate_option_error(
6975 &self,
6976 rule_index: usize,
6977 message: impl Into<String>,
6978 ) -> AntlrError {
6979 let current = self.input.lt(1);
6980 let rule_name = self
6981 .rule_names()
6982 .get(rule_index)
6983 .map_or_else(|| rule_index.to_string(), Clone::clone);
6984 AntlrError::ParserError {
6985 line: current.as_ref().map(Token::line).unwrap_or_default(),
6986 column: current.as_ref().map(Token::column).unwrap_or_default(),
6987 message: format!("rule {rule_name} {}", message.into()),
6988 offending: current.as_ref().map(Token::token_id),
6989 }
6990 }
6991
6992 pub fn parser_action_at_current(
6994 &mut self,
6995 source_state: usize,
6996 rule_index: usize,
6997 start_index: usize,
6998 consumed_eof: bool,
6999 ) -> ParserAction {
7000 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
7001 ParserAction::new(source_state, rule_index, start_index, stop_index)
7002 }
7003
7004 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
7009 let rule_index = action.rule_index();
7010 let rule_name = self.rule_names().get(rule_index).cloned();
7011 let context = None;
7012 let input = &mut self.input;
7013 let semantic_hooks = &mut self.semantic_hooks;
7014 let member_values = &self.int_members;
7015 let mut ctx = ParserSemCtx {
7016 input,
7017 tree_storage: &self.tree,
7018 rule_index,
7019 coordinate_index: usize::MAX,
7020 rule_name,
7021 context,
7022 tree: Some(tree),
7023 local_int_arg: None,
7024 member_values,
7025 action: Some(action),
7026 };
7027 let handled = semantic_hooks.action(&mut ctx, action);
7028 if !handled && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error) {
7034 let coordinate = (rule_index, action.source_state());
7035 if !self.unhandled_action_hits.contains(&coordinate) {
7036 self.unhandled_action_hits.push(coordinate);
7037 }
7038 }
7039 handled
7040 }
7041
7042 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
7047 &mut self,
7048 atn: &'atn Atn,
7049 simulator: &mut ParserAtnSimulator<'atn>,
7050 rule_index: usize,
7051 ) -> Result<ParseTree, AntlrError> {
7052 let start_index = self.current_visible_index();
7053 self.clear_prediction_diagnostics();
7054 self.reset_per_parse_caches();
7055 self.reset_recognition_arena();
7056 let tree_checkpoint = self.tree.checkpoint();
7057 let mut decision_by_state = vec![None; atn.states().len()];
7058 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
7059 if let Some(slot) = decision_by_state.get_mut(state_number) {
7060 *slot = Some(decision);
7061 }
7062 }
7063
7064 let result = DirectAdaptiveParser {
7065 parser: self,
7066 atn,
7067 simulator,
7068 decision_by_state,
7069 steps: 0,
7070 }
7071 .parse_rule(rule_index, -1, 0);
7072
7073 match result {
7074 Ok(tree) => {
7075 self.report_token_source_errors();
7076 self.release_tree_scratch_if_idle();
7077 Ok(tree)
7078 }
7079 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
7080 let _ = reason;
7081 self.tree.rollback(tree_checkpoint);
7082 self.input.seek(start_index);
7083 self.parse_atn_rule(atn, rule_index)
7084 }
7085 }
7086 }
7087
7088 pub fn parse_atn_rule(
7098 &mut self,
7099 atn: &Atn,
7100 rule_index: usize,
7101 ) -> Result<ParseTree, AntlrError> {
7102 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
7103 }
7104
7105 pub fn parse_atn_rule_with_precedence(
7108 &mut self,
7109 atn: &Atn,
7110 rule_index: usize,
7111 precedence: i32,
7112 ) -> Result<ParseTree, AntlrError> {
7113 self.parse_atn_rule_with_precedence_inner(
7114 atn,
7115 rule_index,
7116 precedence,
7117 None,
7118 AltNumberTracking::default(),
7119 )
7120 }
7121
7122 fn parse_atn_rule_with_precedence_inner(
7123 &mut self,
7124 atn: &Atn,
7125 rule_index: usize,
7126 precedence: i32,
7127 predicate_context: Option<FastPredicateContext<'_>>,
7128 alt_tracking: AltNumberTracking,
7129 ) -> Result<ParseTree, AntlrError> {
7130 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7131 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7132 })?;
7133 let stop_state = atn
7134 .rule_to_stop_state()
7135 .get(rule_index)
7136 .filter(|state| *state != usize::MAX)
7137 .ok_or_else(|| {
7138 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7139 })?;
7140
7141 let start_index = self.current_visible_index();
7142 self.clear_prediction_diagnostics();
7143 self.reset_per_parse_caches();
7144 self.reset_recognition_arena();
7145 let caller_follow_state = self.pending_invoking_follow_state(atn);
7146 self.fast_recovery_enabled = false;
7147 self.fast_token_nodes_enabled = false;
7148 self.fast_track_alt_numbers = alt_tracking.any();
7149 let top_request = FastRecognizeTopRequest {
7150 start_state,
7151 stop_state,
7152 start_index,
7153 precedence,
7154 caller_follow_state,
7155 };
7156 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
7157 self.fast_token_nodes_enabled = self.build_parse_trees;
7158 let needs_tree_retry = matches!(
7159 &first_pass,
7160 Ok((outcome, _, _))
7161 if self.build_parse_trees
7162 && self
7163 .recognition_arena
7164 .sequence_has_left_recursive_boundary(outcome.nodes)
7165 );
7166 let needs_retry = match &first_pass {
7167 Err(_) => true,
7180 Ok((outcome, _, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
7181 };
7182 let (outcome, _expected, alt_number) = if needs_retry {
7183 self.fast_first_set_prefilter = false;
7184 self.fast_recovery_enabled = false;
7185 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7186 let clean_selected = if needs_tree_retry {
7187 match clean_retry {
7188 ok @ Ok(_) => ok,
7189 Err(_) => first_pass,
7190 }
7191 } else {
7192 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
7193 };
7194 let selected = if clean_selected.is_err()
7195 || matches!(&clean_selected, Ok((outcome, _, _)) if !outcome.diagnostics.is_empty())
7196 {
7197 self.fast_recovery_enabled = true;
7198 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7199 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
7200 } else {
7201 clean_selected
7202 };
7203 self.fast_first_set_prefilter = true;
7204 self.fast_recovery_enabled = true;
7205 selected.map_err(|expected| {
7206 if predicate_context.is_some()
7207 && let Some(error) = self.unknown_semantic_error()
7208 {
7209 self.report_token_source_errors();
7210 return error;
7211 }
7212 let error = self.recognition_error(rule_index, start_index, &expected);
7213 self.record_syntax_errors(1);
7214 self.report_token_source_errors();
7215 error
7216 })?
7217 } else {
7218 first_pass.expect("first_pass is Ok in the no-retry branch")
7219 };
7220 if predicate_context.is_some()
7221 && let Some(error) = self.unknown_semantic_error()
7222 {
7223 self.report_token_source_errors();
7224 return Err(error);
7225 }
7226 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7227 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7228 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7229 self.report_token_source_errors();
7230 let mut context = ParserRuleContext::with_child_capacity(
7231 rule_index,
7232 self.state(),
7233 if self.build_parse_trees {
7234 self.recognition_arena.sequence_len(outcome.nodes)
7235 } else {
7236 0
7237 },
7238 );
7239 if alt_tracking.public {
7240 context.set_alt_number(alt_number.max(1));
7241 }
7242 if alt_tracking.context {
7243 context.set_context_alt_number(alt_number);
7244 }
7245 if let Some(token) = self.token_id_at(start_index) {
7246 self.set_context_start(&mut context, token);
7247 }
7248 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
7249 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
7250 self.set_context_stop(&mut context, token);
7251 }
7252 let live_root = if self.build_parse_trees {
7253 self.recognition_arena
7254 .fold_left_recursive_boundaries(outcome.nodes)
7255 } else {
7256 outcome.nodes
7257 };
7258 if self.build_parse_trees {
7259 if self
7260 .recognition_arena
7261 .sequence_has_explicit_token(live_root)
7262 {
7263 let mut cursor = live_root;
7264 while let Some(link) = self.recognition_arena.link(cursor) {
7265 let child = self.arena_recognized_node_tree(
7266 link.head,
7267 alt_tracking.public,
7268 alt_tracking.context,
7269 )?;
7270 self.tree.add_child(&mut context, child);
7271 cursor = link.tail;
7272 }
7273 } else {
7274 self.add_arena_implicit_token_children(
7275 &mut context,
7276 start_index,
7277 stop_index,
7278 live_root,
7279 alt_tracking,
7280 )?;
7281 }
7282 }
7283 self.finish_recognition_arena(live_root, outcome.diagnostics);
7284 self.input.seek(outcome.index);
7285
7286 let tree = self.rule_node(context);
7287 self.release_tree_scratch_if_idle();
7288 Ok(tree)
7289 }
7290
7291 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
7292 let invoking_state = self.pending_invoking_states.last().copied()?;
7293 let state_number = usize::try_from(invoking_state).ok()?;
7294 match atn.state(state_number)?.transitions().first()?.data() {
7295 Transition::Rule { follow_state, .. } => Some(follow_state),
7296 _ => None,
7297 }
7298 }
7299
7300 #[cfg(test)]
7301 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
7302 caller_follow_token_info_for_stream(&mut self.input, index)
7303 }
7304
7305 fn fast_recognize_top(
7310 &mut self,
7311 atn: &Atn,
7312 request: FastRecognizeTopRequest,
7313 predicate_context: Option<FastPredicateContext<'_>>,
7314 ) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
7315 let FastRecognizeTopRequest {
7316 start_state,
7317 stop_state,
7318 start_index,
7319 precedence,
7320 caller_follow_state,
7321 } = request;
7322 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
7331 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
7332 recognize_scratch.prepare(memo_capacity);
7333 let mut expected = ExpectedTokens::default();
7334 let empty_recovery = self.empty_recovery_symbols();
7335 let outcomes = self.recognize_state_fast(
7336 atn,
7337 FastRecognizeRequest {
7338 state_number: start_state,
7339 stop_state,
7340 index: start_index,
7341 rule_start_index: start_index,
7342 decision_start_index: None,
7343 precedence,
7344 depth: 0,
7345 recovery_symbols: empty_recovery,
7346 recovery_state: None,
7347 },
7348 FastRecognizeScratch {
7349 predicate_context,
7350 visiting: &mut recognize_scratch.visiting,
7351 memo: &mut recognize_scratch.memo,
7352 expected: &mut expected,
7353 native_depth: 0,
7354 },
7355 );
7356 recognize_scratch.release_oversized_memo();
7357 self.fast_recognize_scratch = recognize_scratch;
7358 #[cfg(feature = "perf-counters")]
7359 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
7360 perf_counters::dump();
7361 perf_counters::reset();
7362 }
7363 let caller_follow =
7364 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
7365 let selected = {
7366 let arena = &self.recognition_arena;
7367 let input = &mut self.input;
7368 select_best_fast_outcome(
7369 outcomes.into_iter(),
7370 self.prediction_mode,
7371 caller_follow.as_deref(),
7372 |index| caller_follow_token_info_for_stream(input, index),
7373 arena,
7374 )
7375 };
7376 match selected {
7377 Some(mut outcome) => {
7378 let alt_number = if self.build_parse_trees || self.fast_track_alt_numbers {
7379 self.materialize_fast_outcome_nodes(&mut outcome)
7380 } else {
7381 0
7382 };
7383 Ok((outcome, expected, alt_number))
7384 }
7385 None => Err(expected),
7386 }
7387 }
7388
7389 fn arena_recognized_node_tree(
7391 &mut self,
7392 node_id: RecognizedNodeId,
7393 track_alt_numbers: bool,
7394 track_context_alt_numbers: bool,
7395 ) -> Result<ParseTree, AntlrError> {
7396 let node = self.recognition_arena.node(node_id);
7397 match node {
7398 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
7399 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
7400 ArenaRecognizedNode::MissingToken { extra } => {
7401 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
7402 RecognitionExtra::MissingToken {
7403 token_type,
7404 at_index,
7405 text,
7406 } => (*token_type, *at_index as usize, text.clone()),
7407 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
7408 unreachable!("missing-token node must reference missing-token extra")
7409 }
7410 };
7411 let (line, column) = self
7412 .token_at(at_index)
7413 .map_or((0, 0), |token| (token.line(), token.column()));
7414 let token = self.insert_synthetic_token(token_type, text, line, column)?;
7415 Ok(self.error_tree(token))
7416 }
7417 ArenaRecognizedNode::Rule {
7418 rule_index,
7419 invoking_state,
7420 alt_number,
7421 start_index,
7422 stop_index,
7423 return_values,
7424 children,
7425 } => {
7426 let mut context = ParserRuleContext::with_child_capacity(
7427 rule_index as usize,
7428 invoking_state as isize,
7429 self.recognition_arena.sequence_len(children),
7430 );
7431 if track_alt_numbers {
7432 context.set_alt_number((alt_number as usize).max(1));
7433 }
7434 if track_context_alt_numbers {
7435 context.set_context_alt_number(alt_number as usize);
7436 }
7437 if let Some(extra) = return_values {
7438 let RecognitionExtra::ReturnValues(values) =
7439 self.recognition_arena.extra(extra)
7440 else {
7441 unreachable!("rule node must reference return-values extra");
7442 };
7443 for (name, value) in values {
7444 context.set_int_return(name.clone(), *value);
7445 }
7446 }
7447 if let Some(token) = self.token_id_at(start_index as usize) {
7448 self.set_context_start(&mut context, token);
7449 }
7450 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7451 self.set_context_stop(&mut context, token);
7452 }
7453 let mut cursor = self
7454 .recognition_arena
7455 .fold_left_recursive_boundaries(children);
7456 while let Some(link) = self.recognition_arena.link(cursor) {
7457 let child = self.arena_recognized_node_tree(
7458 link.head,
7459 track_alt_numbers,
7460 track_context_alt_numbers,
7461 )?;
7462 self.tree.add_child(&mut context, child);
7463 cursor = link.tail;
7464 }
7465 Ok(self.rule_node(context))
7466 }
7467 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index, .. } => {
7468 Err(AntlrError::Unsupported(format!(
7469 "unfolded left-recursive boundary for rule {rule_index}"
7470 )))
7471 }
7472 }
7473 }
7474
7475 fn arena_recognized_node_tree_with_implicit_tokens(
7476 &mut self,
7477 node_id: RecognizedNodeId,
7478 alt_tracking: AltNumberTracking,
7479 ) -> Result<ParseTree, AntlrError> {
7480 let node = self.recognition_arena.node(node_id);
7481 match node {
7482 ArenaRecognizedNode::Rule {
7483 rule_index,
7484 invoking_state,
7485 alt_number,
7486 start_index,
7487 stop_index,
7488 children,
7489 ..
7490 } => {
7491 let mut context = ParserRuleContext::with_child_capacity(
7492 rule_index as usize,
7493 invoking_state as isize,
7494 self.recognition_arena.sequence_len(children),
7495 );
7496 if alt_tracking.public {
7497 context.set_alt_number((alt_number as usize).max(1));
7498 }
7499 if alt_tracking.context {
7500 context.set_context_alt_number(alt_number as usize);
7501 }
7502 if let Some(token) = self.token_id_at(start_index as usize) {
7503 self.set_context_start(&mut context, token);
7504 }
7505 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7506 self.set_context_stop(&mut context, token);
7507 }
7508 let children = self
7509 .recognition_arena
7510 .fold_left_recursive_boundaries(children);
7511 self.add_arena_implicit_token_children(
7512 &mut context,
7513 start_index as usize,
7514 stop_index.map(|index| index as usize),
7515 children,
7516 alt_tracking,
7517 )?;
7518 Ok(self.rule_node(context))
7519 }
7520 _ => {
7521 self.arena_recognized_node_tree(node_id, alt_tracking.public, alt_tracking.context)
7522 }
7523 }
7524 }
7525
7526 fn add_arena_implicit_token_children(
7527 &mut self,
7528 context: &mut ParserRuleContext,
7529 start_index: usize,
7530 stop_index: Option<usize>,
7531 mut children: NodeSeqId,
7532 alt_tracking: AltNumberTracking,
7533 ) -> Result<(), AntlrError> {
7534 let mut cursor = Some(start_index);
7535 while let Some(link) = self.recognition_arena.link(children) {
7536 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
7537 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
7538 let child =
7539 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7540 self.tree.add_child(context, child);
7541 if let Some(child_stop) = child_stop {
7542 let next = self.next_visible_after_token(child_stop);
7543 cursor = match (cursor, next) {
7544 (None, _) | (_, None) => None,
7545 (Some(current), Some(next)) => Some(current.max(next)),
7546 };
7547 }
7548 } else {
7549 let child =
7550 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7551 self.tree.add_child(context, child);
7552 }
7553 children = link.tail;
7554 }
7555 if let Some(stop) = stop_index {
7556 self.add_visible_terminals_through(context, cursor, stop)?;
7557 }
7558 Ok(())
7559 }
7560
7561 fn add_visible_terminals_before(
7562 &mut self,
7563 context: &mut ParserRuleContext,
7564 cursor: &mut Option<usize>,
7565 before: usize,
7566 ) -> Result<(), AntlrError> {
7567 let Some(stop) = before.checked_sub(1) else {
7568 return Ok(());
7569 };
7570 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
7571 *cursor = next;
7572 Ok(())
7573 }
7574
7575 fn add_visible_terminals_through(
7576 &mut self,
7577 context: &mut ParserRuleContext,
7578 mut cursor: Option<usize>,
7579 stop: usize,
7580 ) -> Result<Option<usize>, AntlrError> {
7581 while let Some(index) = cursor {
7582 if index > stop {
7583 return Ok(Some(index));
7584 }
7585 let token = self
7586 .input
7587 .get_id(index)
7588 .ok_or_else(|| AntlrError::ParserError {
7589 line: 0,
7590 column: 0,
7591 message: format!("missing token at index {index}"),
7592 offending: None,
7593 })?;
7594 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
7595 let child = self.terminal_tree(token);
7596 self.tree.add_child(context, child);
7597 if is_eof {
7598 return Ok(None);
7599 }
7600 cursor = self.next_visible_after_token(index);
7601 }
7602 Ok(None)
7603 }
7604
7605 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
7606 let next = self.input.next_visible_after(index);
7607 (next != index).then_some(next)
7608 }
7609
7610 pub fn parse_atn_rule_with_actions(
7617 &mut self,
7618 atn: &Atn,
7619 rule_index: usize,
7620 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7621 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
7622 }
7623
7624 pub fn parse_atn_rule_with_action_inits(
7632 &mut self,
7633 atn: &Atn,
7634 rule_index: usize,
7635 init_action_rules: &[usize],
7636 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7637 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
7638 }
7639
7640 pub fn parse_atn_rule_with_action_options(
7646 &mut self,
7647 atn: &Atn,
7648 rule_index: usize,
7649 init_action_rules: &[usize],
7650 track_alt_numbers: bool,
7651 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7652 self.parse_atn_rule_with_runtime_options(
7653 atn,
7654 rule_index,
7655 ParserRuntimeOptions {
7656 init_action_rules,
7657 track_alt_numbers,
7658 ..ParserRuntimeOptions::default()
7659 },
7660 )
7661 }
7662
7663 pub fn parse_atn_rule_with_runtime_options(
7670 &mut self,
7671 atn: &Atn,
7672 rule_index: usize,
7673 options: ParserRuntimeOptions<'_>,
7674 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7675 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
7676 }
7677
7678 pub fn parse_atn_rule_with_runtime_options_and_precedence(
7681 &mut self,
7682 atn: &Atn,
7683 rule_index: usize,
7684 precedence: i32,
7685 options: ParserRuntimeOptions<'_>,
7686 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7687 let ParserRuntimeOptions {
7688 init_action_rules,
7689 track_alt_numbers,
7690 track_context_alt_numbers,
7691 predicates,
7692 semantics,
7693 rule_args,
7694 member_actions,
7695 return_actions,
7696 unknown_predicate_policy,
7697 } = options;
7698 let capture_alt_numbers = track_alt_numbers || track_context_alt_numbers;
7699 if init_action_rules.is_empty()
7700 && !capture_alt_numbers
7701 && predicates.is_empty()
7702 && semantics.is_none()
7703 && rule_args.is_empty()
7704 && member_actions.is_empty()
7705 && return_actions.is_empty()
7706 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
7707 && !atn_has_observable_action_transitions(atn)
7708 && !self.semantic_hooks.observes_parser_decisions()
7709 && (!self.semantic_hooks.observes_parser_predicates()
7710 || !atn_has_predicate_transitions(atn))
7711 {
7712 return self
7713 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
7714 .map(|tree| (tree, Vec::new()));
7715 }
7716 if !self.semantic_hooks.observes_parser_decisions()
7717 && can_use_fast_predicate_recognizer(atn, &options)
7718 {
7719 self.unknown_predicate_policy = unknown_predicate_policy;
7720 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7721 let member_values = self.int_members.clone();
7722 let result = self
7723 .parse_atn_rule_with_precedence_inner(
7724 atn,
7725 rule_index,
7726 precedence,
7727 Some(FastPredicateContext {
7728 predicates,
7729 semantics,
7730 member_values: &member_values,
7731 }),
7732 AltNumberTracking {
7733 public: track_alt_numbers,
7734 context: track_context_alt_numbers,
7735 },
7736 )
7737 .map(|tree| (tree, Vec::new()));
7738 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
7739 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7740 }
7741 return result;
7742 }
7743 self.unknown_predicate_policy = unknown_predicate_policy;
7744 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7751 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7752 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7753 })?;
7754 let stop_state = atn
7755 .rule_to_stop_state()
7756 .get(rule_index)
7757 .filter(|state| *state != usize::MAX)
7758 .ok_or_else(|| {
7759 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7760 })?;
7761
7762 let start_index = self.current_visible_index();
7763 self.clear_prediction_diagnostics();
7764 self.reset_per_parse_caches();
7765 self.reset_recognition_arena();
7766 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
7767 let invoking_state = self.pending_invoking_states.pop();
7768 let local_int_arg = invoking_state
7769 .and_then(|state| usize::try_from(state).ok())
7770 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
7771 let mut visiting = BTreeSet::new();
7772 let mut memo = BTreeMap::new();
7773 let mut expected = ExpectedTokens::default();
7774 let member_values = self.int_members.clone();
7775 let return_values = BTreeMap::new();
7776 let outcomes = self.recognize_state(
7777 atn,
7778 RecognizeRequest {
7779 state_number: start_state,
7780 stop_state,
7781 index: start_index,
7782 rule_start_index: start_index,
7783 decision_start_index: None,
7784 init_action_rules: &init_action_rules,
7785 predicates,
7786 semantics,
7787 rule_args,
7788 member_actions,
7789 return_actions,
7790 local_int_arg,
7791 member_values,
7792 return_values,
7793 rule_alt_number: 0,
7794 track_alt_numbers: capture_alt_numbers,
7795 consumed_eof: false,
7796 committed_decision: false,
7797 precedence,
7798 depth: 0,
7799 recovery_symbols: BTreeSet::new(),
7800 recovery_state: None,
7801 },
7802 &mut visiting,
7803 &mut memo,
7804 &mut expected,
7805 );
7806 if let Some(error) = self.unknown_semantic_error() {
7807 self.report_token_source_errors();
7808 return Err(error);
7815 }
7816 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7819 let Some(outcome) = select_best_outcome(
7820 outcomes.into_iter(),
7821 self.prediction_mode,
7822 &self.recognition_arena,
7823 ) else {
7824 let error = self.recognition_error(rule_index, start_index, &expected);
7825 self.record_syntax_errors(1);
7826 self.report_token_source_errors();
7827 return Err(error);
7828 };
7829
7830 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7831 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7832 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7833 self.report_token_source_errors();
7834 let mut actions = outcome.actions;
7835 if init_action_rules.contains(&rule_index) {
7836 actions.insert(
7837 0,
7838 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
7839 );
7840 }
7841 let mut context =
7842 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
7843 if track_alt_numbers {
7844 context.set_alt_number(outcome.alt_number.max(1));
7845 }
7846 if track_context_alt_numbers {
7847 context.set_context_alt_number(outcome.alt_number);
7848 }
7849 for (name, value) in outcome.return_values {
7850 context.set_int_return(name, value);
7851 }
7852 if let Some(token) = self.token_id_at(start_index) {
7853 self.set_context_start(&mut context, token);
7854 }
7855 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
7856 self.set_context_stop(&mut context, token);
7857 }
7858 let live_root = if self.build_parse_trees {
7859 self.recognition_arena
7860 .fold_left_recursive_boundaries(outcome.nodes)
7861 } else {
7862 outcome.nodes
7863 };
7864 if self.build_parse_trees {
7865 let mut nodes = live_root;
7866 while let Some(link) = self.recognition_arena.link(nodes) {
7867 let child = self.arena_recognized_node_tree(
7868 link.head,
7869 track_alt_numbers,
7870 track_context_alt_numbers,
7871 )?;
7872 self.tree.add_child(&mut context, child);
7873 nodes = link.tail;
7874 }
7875 }
7876 self.finish_recognition_arena(live_root, outcome.diagnostics);
7877 self.input.seek(outcome.index);
7878
7879 let tree = self.rule_node(context);
7880 self.release_tree_scratch_if_idle();
7881 Ok((tree, actions))
7882 }
7883
7884 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
7891 let mut context = ParserRuleContext::new(rule_index, self.state());
7892 while self.la(1) != TOKEN_EOF {
7893 let token_type = self.la(1);
7894 let child = self.match_token(token_type)?;
7895 if self.build_parse_trees {
7896 self.tree.add_child(&mut context, child);
7897 }
7898 }
7899 if self.build_parse_trees {
7900 let child = self.match_eof()?;
7901 self.tree.add_child(&mut context, child);
7902 }
7903 let tree = self.rule_node(context);
7904 self.release_tree_scratch_if_idle();
7905 Ok(tree)
7906 }
7907
7908 fn recognition_error(
7911 &mut self,
7912 rule_index: usize,
7913 start_index: usize,
7914 expected: &ExpectedTokens,
7915 ) -> AntlrError {
7916 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
7917 self.input.seek(index);
7918 let current = self.input.lt(1);
7919 let line = current.as_ref().map(Token::line).unwrap_or_default();
7920 let column = current.as_ref().map(Token::column).unwrap_or_default();
7921 AntlrError::ParserError {
7922 line,
7923 column,
7924 message,
7925 offending: current.as_ref().map(Token::token_id),
7926 }
7927 }
7928
7929 fn expected_error_message(
7931 &mut self,
7932 rule_index: usize,
7933 start_index: usize,
7934 expected: &ExpectedTokens,
7935 ) -> (usize, String) {
7936 let index = expected
7937 .index
7938 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
7939 .unwrap_or_else(|| self.input.index());
7940 self.input.seek(index);
7941 let current = self.input.lt(1);
7942 let message = if expected
7943 .no_viable
7944 .as_ref()
7945 .is_some_and(|no_viable| no_viable.error_index == index)
7946 {
7947 let start = expected
7948 .no_viable
7949 .as_ref()
7950 .map_or(start_index, |no_viable| no_viable.start_index);
7951 let text = display_input_text(&self.input.text(start, index));
7952 format!("no viable alternative at input '{text}'")
7953 } else if expected.symbols.is_empty() {
7954 if expected.index.is_some() {
7955 let found = current
7956 .as_ref()
7957 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
7958 if current
7959 .as_ref()
7960 .is_some_and(|token| token.token_type() == TOKEN_EOF)
7961 {
7962 format!(
7963 "missing {} at {found}",
7964 self.expected_symbols_display(&expected.symbols)
7965 )
7966 } else {
7967 format!("mismatched input {found}")
7968 }
7969 } else {
7970 format!("no viable alternative while parsing rule {rule_index}")
7971 }
7972 } else {
7973 format!(
7974 "mismatched input {} expecting {}",
7975 current
7976 .as_ref()
7977 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7978 self.expected_symbols_display(&expected.symbols)
7979 )
7980 };
7981 (index, message)
7982 }
7983
7984 fn child_rule_failure_recovery(
7987 &mut self,
7988 rule_index: usize,
7989 start_index: usize,
7990 sync_symbols: &BTreeSet<i32>,
7991 member_values: BTreeMap<usize, i64>,
7992 expected: &ExpectedTokens,
7993 ) -> Option<RecognizeOutcome> {
7994 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
7995 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
7996 let mut next_index = error_index;
7997 loop {
7998 let symbol = self.token_type_at(next_index);
7999 if sync_symbols.contains(&symbol) {
8000 if next_index == error_index {
8001 return None;
8002 }
8003 break;
8004 }
8005 if symbol == TOKEN_EOF {
8006 break;
8007 }
8008 let after = self.consume_index(next_index, symbol);
8009 if after == next_index {
8010 break;
8011 }
8012 next_index = after;
8013 }
8014 let mut nodes = NodeSeqId::EMPTY;
8015 let error = self.arena_token_node(error_index, true);
8016 self.arena_prepend(&mut nodes, error);
8017 let diagnostics = self
8018 .recognition_arena
8019 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8020 Some(RecognizeOutcome {
8021 index: next_index,
8022 consumed_eof: false,
8023 alt_number: 0,
8024 member_values,
8025 return_values: BTreeMap::new(),
8026 diagnostics,
8027 decisions: Vec::new(),
8028 actions: Vec::new(),
8029 nodes,
8030 })
8031 }
8032
8033 fn child_rule_failure_recovery_outcomes(
8036 &mut self,
8037 request: ChildRuleFailureRecovery<'_>,
8038 ) -> Vec<RecognizeOutcome> {
8039 let sync_symbols =
8040 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
8041 self.child_rule_failure_recovery(
8042 request.rule_index,
8043 request.start_index,
8044 &sync_symbols,
8045 request.member_values,
8046 request.expected,
8047 )
8048 .into_iter()
8049 .collect()
8050 }
8051
8052 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
8054 expected_symbols_display(symbols, self.vocabulary())
8055 }
8056
8057 fn single_token_deletion(
8060 &mut self,
8061 transition: ParserTransition<'_>,
8062 index: usize,
8063 max_token_type: i32,
8064 expected_symbols: &BTreeSet<i32>,
8065 ) -> Option<(ParserDiagnostic, usize, i32)> {
8066 let current_symbol = self.token_type_at(index);
8067 if current_symbol == TOKEN_EOF {
8068 return None;
8069 }
8070 let next_index = self.consume_index(index, current_symbol);
8071 if next_index == index {
8072 return None;
8073 }
8074 let next_symbol = self.token_type_at(next_index);
8075 if !transition.matches(next_symbol, 1, max_token_type) {
8076 return None;
8077 }
8078 let transition_expected = transition_expected_symbols(transition, max_token_type);
8079 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8080 &transition_expected
8081 } else {
8082 expected_symbols
8083 });
8084 let current = self.token_at(index);
8085 let message = format!(
8086 "extraneous input {} expecting {expected_display}",
8087 current
8088 .as_ref()
8089 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8090 );
8091 Some((
8092 diagnostic_for_token(current, message),
8093 next_index,
8094 next_symbol,
8095 ))
8096 }
8097
8098 fn current_token_deletion(
8101 &mut self,
8102 index: usize,
8103 expected_symbols: &BTreeSet<i32>,
8104 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
8105 if expected_symbols.is_empty() {
8106 return None;
8107 }
8108 let current_symbol = self.token_type_at(index);
8109 if current_symbol == TOKEN_EOF {
8110 return None;
8111 }
8112 let current = self.token_at(index);
8113 let message = format!(
8114 "extraneous input {} expecting {}",
8115 current
8116 .as_ref()
8117 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8118 self.expected_symbols_display(expected_symbols)
8119 );
8120 let diagnostic = diagnostic_for_token(current, message);
8121 let mut skipped = Vec::new();
8122 let mut cursor = index;
8123 loop {
8124 let symbol = self.token_type_at(cursor);
8125 if symbol == TOKEN_EOF {
8126 return None;
8127 }
8128 skipped.push(cursor);
8129 let next_index = self.consume_index(cursor, symbol);
8130 if next_index == cursor {
8131 return None;
8132 }
8133 let next_symbol = self.token_type_at(next_index);
8134 if expected_symbols.contains(&next_symbol) {
8135 return Some((diagnostic, next_index, skipped));
8136 }
8137 cursor = next_index;
8138 }
8139 }
8140
8141 fn single_token_insertion(
8145 &mut self,
8146 transition: ParserTransition<'_>,
8147 index: usize,
8148 max_token_type: i32,
8149 expected_symbols: &BTreeSet<i32>,
8150 follow_symbols: &BTreeSet<i32>,
8151 ) -> Option<(ParserDiagnostic, i32, String)> {
8152 let current_symbol = self.token_type_at(index);
8153 if !follow_symbols.contains(¤t_symbol) {
8154 return None;
8155 }
8156 let transition_expected = transition_expected_symbols(transition, max_token_type);
8157 let token_type = transition_expected.iter().next().copied()?;
8158 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8159 &transition_expected
8160 } else {
8161 expected_symbols
8162 });
8163 let mut token_symbols = BTreeSet::new();
8164 token_symbols.insert(token_type);
8165 let missing_token_display = self.expected_symbols_display(&token_symbols);
8166 let current = self.token_at(index);
8167 let message = format!(
8168 "missing {expected_display} at {}",
8169 current
8170 .as_ref()
8171 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8172 );
8173 let text = format!("<missing {missing_token_display}>");
8174 Some((
8175 diagnostic_for_token(current.as_ref(), message),
8176 token_type,
8177 text,
8178 ))
8179 }
8180
8181 fn fast_single_token_deletion_recovery(
8185 &mut self,
8186 recovery: FastRecoveryRequest<'_, '_>,
8187 predicate_context: Option<FastPredicateContext<'_>>,
8188 ) -> Vec<FastRecognizeOutcome> {
8189 let FastRecoveryRequest {
8190 atn,
8191 transition,
8192 expected_symbols,
8193 target,
8194 request,
8195 visiting,
8196 memo,
8197 expected,
8198 } = recovery;
8199 let FastRecognizeRequest {
8200 stop_state,
8201 index,
8202 rule_start_index,
8203 decision_start_index,
8204 precedence,
8205 depth,
8206 ..
8207 } = request;
8208 let Some((diagnostic, next_index, next_symbol)) =
8209 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
8210 else {
8211 return Vec::new();
8212 };
8213 let after_next = self.consume_index(next_index, next_symbol);
8214 let empty_recovery = self.empty_recovery_symbols();
8215 self.recognize_state_fast(
8216 atn,
8217 FastRecognizeRequest {
8218 state_number: target,
8219 stop_state,
8220 index: after_next,
8221 rule_start_index,
8222 decision_start_index,
8223 precedence,
8224 depth: depth + 1,
8225 recovery_symbols: empty_recovery,
8226 recovery_state: None,
8227 },
8228 FastRecognizeScratch {
8229 predicate_context,
8230 visiting,
8231 memo,
8232 expected,
8233 native_depth: 0,
8234 },
8235 )
8236 .into_iter()
8237 .map(|mut outcome| {
8238 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
8239 outcome.diagnostics = self
8240 .recognition_arena
8241 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8242 if self.fast_token_nodes_enabled {
8243 let token = self.arena_token_node(next_index, false);
8244 self.defer_fast_outcome_node(&mut outcome, token);
8245 let error = self.arena_token_node(index, true);
8246 self.defer_fast_outcome_node(&mut outcome, error);
8247 }
8248 outcome
8249 })
8250 .collect()
8251 }
8252
8253 fn fast_single_token_insertion_recovery(
8257 &mut self,
8258 recovery: FastRecoveryRequest<'_, '_>,
8259 predicate_context: Option<FastPredicateContext<'_>>,
8260 ) -> Vec<FastRecognizeOutcome> {
8261 let FastRecoveryRequest {
8262 atn,
8263 transition,
8264 expected_symbols,
8265 target,
8266 request,
8267 visiting,
8268 memo,
8269 expected,
8270 } = recovery;
8271 let FastRecognizeRequest {
8272 stop_state,
8273 index,
8274 rule_start_index,
8275 decision_start_index,
8276 precedence,
8277 depth,
8278 ..
8279 } = request;
8280 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
8281 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
8282 transition,
8283 index,
8284 atn.max_token_type(),
8285 &expected_symbols,
8286 &follow_symbols,
8287 ) else {
8288 return Vec::new();
8289 };
8290 let empty_recovery = self.empty_recovery_symbols();
8291 self.recognize_state_fast(
8292 atn,
8293 FastRecognizeRequest {
8294 state_number: target,
8295 stop_state,
8296 index,
8297 rule_start_index,
8298 decision_start_index,
8299 precedence,
8300 depth: depth + 1,
8301 recovery_symbols: empty_recovery,
8302 recovery_state: None,
8303 },
8304 FastRecognizeScratch {
8305 predicate_context,
8306 visiting,
8307 memo,
8308 expected,
8309 native_depth: 0,
8310 },
8311 )
8312 .into_iter()
8313 .map(|mut outcome| {
8314 outcome.diagnostics = self
8315 .recognition_arena
8316 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8317 let missing = self.arena_missing_token_node(token_type, index, text.clone());
8318 self.defer_fast_outcome_node(&mut outcome, missing);
8319 outcome
8320 })
8321 .collect()
8322 }
8323
8324 fn fast_current_token_deletion_recovery(
8327 &mut self,
8328 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
8329 predicate_context: Option<FastPredicateContext<'_>>,
8330 ) -> Vec<FastRecognizeOutcome> {
8331 let FastCurrentTokenDeletionRequest {
8332 atn,
8333 expected_symbols,
8334 mut request,
8335 visiting,
8336 memo,
8337 expected,
8338 } = recovery;
8339 if request.index == request.rule_start_index {
8340 return Vec::new();
8341 }
8342 let Some((diagnostic, next_index, skipped)) =
8343 self.current_token_deletion(request.index, &expected_symbols)
8344 else {
8345 return Vec::new();
8346 };
8347 request.state_number = request.recovery_state.unwrap_or(request.state_number);
8348 request.index = next_index;
8349 request.depth += 1;
8350 request.recovery_state = None;
8351 self.recognize_state_fast(
8352 atn,
8353 request,
8354 FastRecognizeScratch {
8355 predicate_context,
8356 visiting,
8357 memo,
8358 expected,
8359 native_depth: 0,
8360 },
8361 )
8362 .into_iter()
8363 .map(|mut outcome| {
8364 outcome.diagnostics = self
8365 .recognition_arena
8366 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8367 for index in skipped.iter().rev() {
8368 let error = self.arena_token_node(*index, true);
8369 self.defer_fast_outcome_node(&mut outcome, error);
8370 }
8371 outcome
8372 })
8373 .collect()
8374 }
8375
8376 fn fast_child_rule_failure_recovery(
8379 &mut self,
8380 rule_index: usize,
8381 start_index: usize,
8382 sync_symbols: &BTreeSet<i32>,
8383 expected: &ExpectedTokens,
8384 ) -> Option<FastRecognizeOutcome> {
8385 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
8386 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
8387 let mut next_index = error_index;
8388 loop {
8389 let symbol = self.token_type_at(next_index);
8390 if sync_symbols.contains(&symbol) {
8391 if next_index == error_index {
8392 return None;
8393 }
8394 break;
8395 }
8396 if symbol == TOKEN_EOF {
8397 break;
8398 }
8399 let after = self.consume_index(next_index, symbol);
8400 if after == next_index {
8401 break;
8402 }
8403 next_index = after;
8404 }
8405 let diagnostics = self
8406 .recognition_arena
8407 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8408 let mut nodes = NodeSeqId::EMPTY;
8409 if self.fast_token_nodes_enabled {
8410 let error = self.arena_token_node(error_index, true);
8411 self.arena_prepend(&mut nodes, error);
8412 }
8413 Some(FastRecognizeOutcome {
8414 index: next_index,
8415 consumed_eof: false,
8416 diagnostics,
8417 deferred_nodes: FastDeferredNodeId::EMPTY,
8418 nodes,
8419 })
8420 }
8421
8422 fn fast_child_rule_failure_recovery_outcomes(
8425 &mut self,
8426 request: FastChildRuleFailureRecoveryRequest<'_>,
8427 ) -> Vec<FastRecognizeOutcome> {
8428 let FastChildRuleFailureRecoveryRequest {
8429 atn,
8430 rule_index,
8431 start_index,
8432 follow_state,
8433 stop_state,
8434 expected,
8435 } = request;
8436 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
8437 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
8438 .into_iter()
8439 .collect()
8440 }
8441
8442 fn defer_fast_outcome_node(
8443 &mut self,
8444 outcome: &mut FastRecognizeOutcome,
8445 node: RecognizedNodeId,
8446 ) {
8447 if outcome.deferred_nodes.is_empty() {
8448 self.arena_prepend(&mut outcome.nodes, node);
8449 return;
8450 }
8451 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
8452 let fragment = self.recognition_arena.deferred_fragment(fragment);
8453 outcome.deferred_nodes = self
8454 .recognition_arena
8455 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
8456 }
8457
8458 fn defer_fast_outcome_alternative(
8459 &mut self,
8460 outcome: &mut FastRecognizeOutcome,
8461 alt_number: usize,
8462 ) {
8463 let alternative = self.recognition_arena.deferred_alternative(alt_number);
8464 outcome.deferred_nodes = self
8465 .recognition_arena
8466 .concat_deferred_nodes(alternative, outcome.deferred_nodes);
8467 }
8468
8469 fn defer_fast_outcome_boundary(
8470 &mut self,
8471 outcome: &mut FastRecognizeOutcome,
8472 rule_index: usize,
8473 ) {
8474 let boundary = self
8475 .recognition_arena
8476 .deferred_left_recursive_boundary(rule_index);
8477 outcome.deferred_nodes = self
8478 .recognition_arena
8479 .concat_deferred_nodes(boundary, outcome.deferred_nodes);
8480 }
8481
8482 fn materialize_fast_deferred_nodes(
8483 &mut self,
8484 root: FastDeferredNodeId,
8485 initial_suffix: NodeSeqId,
8486 ) -> (NodeSeqId, usize) {
8487 if root.is_empty() {
8488 return (initial_suffix, 0);
8489 }
8490
8491 enum Frame {
8492 Visit(FastDeferredNodeId),
8493 ContinuePrefix(FastDeferredNodeId),
8494 FinishRule {
8495 rule: FastDeferredRule,
8496 parent_suffix: NodeSeqId,
8497 parent_alt_number: u32,
8498 parent_pending_boundary: Option<RecognizedNodeId>,
8499 },
8500 }
8501
8502 let mut result = initial_suffix;
8503 let mut alt_number = 0;
8507 let mut pending_boundary = None;
8508 let mut pending = Vec::with_capacity(16);
8509 pending.push(Frame::Visit(root));
8510 let mut fragment_nodes = Vec::new();
8511 while let Some(frame) = pending.pop() {
8512 match frame {
8513 Frame::Visit(deferred) => {
8514 if deferred.is_empty() {
8515 continue;
8516 }
8517
8518 match self.recognition_arena.deferred_node(deferred) {
8519 FastDeferredNode::Fragment(sequence) => {
8520 fragment_nodes.clear();
8521 fragment_nodes.extend(self.recognition_arena.iter(sequence));
8522 while let Some(node) = fragment_nodes.pop() {
8523 self.arena_prepend(&mut result, node);
8524 }
8525 }
8526 FastDeferredNode::Rule(rule) => {
8527 let rule = self.recognition_arena.deferred_rule(rule);
8528 let parent_suffix = result;
8529 let parent_alt_number = alt_number;
8530 let parent_pending_boundary = pending_boundary;
8531 result = rule.children;
8532 alt_number = 0;
8533 pending_boundary = None;
8534 pending.push(Frame::FinishRule {
8535 rule,
8536 parent_suffix,
8537 parent_alt_number,
8538 parent_pending_boundary,
8539 });
8540 pending.push(Frame::Visit(rule.deferred_children));
8541 }
8542 FastDeferredNode::Alternative(selected) => {
8543 if let Some(boundary) = pending_boundary {
8544 self.recognition_arena
8545 .set_boundary_alt_number(boundary, selected);
8546 } else {
8547 alt_number = selected;
8548 }
8549 }
8550 FastDeferredNode::LeftRecursiveBoundary { rule_index } => {
8551 let boundary = self.arena_boundary_node(rule_index as usize, 0);
8552 self.arena_prepend(&mut result, boundary);
8553 pending_boundary = Some(boundary);
8554 }
8555 FastDeferredNode::Concat {
8556 prefix,
8557 suffix: deferred_suffix,
8558 } => {
8559 pending.push(Frame::ContinuePrefix(prefix));
8560 pending.push(Frame::Visit(deferred_suffix));
8561 }
8562 }
8563 }
8564 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
8565 Frame::FinishRule {
8566 rule,
8567 parent_suffix,
8568 parent_alt_number,
8569 parent_pending_boundary,
8570 } => {
8571 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
8572 rule_index: rule.rule_index,
8573 invoking_state: rule.invoking_state,
8574 alt_number,
8575 start_index: rule.start_index,
8576 stop_index: rule.stop_index,
8577 return_values: None,
8578 children: result,
8579 });
8580 result = parent_suffix;
8581 self.arena_prepend(&mut result, node);
8582 alt_number = parent_alt_number;
8583 pending_boundary = parent_pending_boundary;
8584 }
8585 }
8586 }
8587 (result, alt_number as usize)
8588 }
8589
8590 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) -> usize {
8591 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
8592 let (nodes, alt_number) =
8593 self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
8594 outcome.nodes = nodes;
8595 alt_number
8596 }
8597
8598 fn recognize_repetition_fast(
8601 &mut self,
8602 atn: &Atn,
8603 request: &FastRecognizeRequest,
8604 shape: FastRepetitionShape,
8605 scratch: FastRecognizeScratch<'_, '_>,
8606 ) -> Vec<FastRecognizeOutcome> {
8607 let FastRecognizeScratch {
8608 predicate_context,
8609 visiting,
8610 memo,
8611 expected,
8612 native_depth,
8613 } = scratch;
8614 let lookahead = if self.fast_first_set_prefilter {
8615 atn.state(request.state_number).and_then(|state| {
8616 state
8617 .rule_index()
8618 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8619 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
8620 })
8621 } else {
8622 None
8623 };
8624 let (enter_alt_number, exit_alt_number) = if self.fast_track_alt_numbers {
8625 let state = atn
8626 .state(request.state_number)
8627 .expect("repetition request state must exist");
8628 (
8629 next_alt_number(state, 2, shape.enter_transition_index, 0, true),
8630 next_alt_number(state, 2, shape.exit_transition_index, 0, true),
8631 )
8632 } else {
8633 (0, 0)
8634 };
8635 let mut work = Vec::with_capacity(2);
8636 push_fast_repetition_work(
8637 &mut work,
8638 shape,
8639 FastRepetitionPath {
8640 index: request.index,
8641 deferred_nodes: FastDeferredNodeId::EMPTY,
8642 diagnostics: DiagnosticSeqId::EMPTY,
8643 consumed_eof: false,
8644 },
8645 lookahead.as_deref(),
8646 self.token_type_at(request.index),
8647 );
8648 let mut coordinates = FastRepetitionCoordinates::new(request.index);
8649 let mut outcomes = Vec::new();
8650 while let Some(item) = work.pop() {
8651 match item {
8652 FastRepetitionWork::Enter(path) => {
8653 if !coordinates.insert_entered(path) {
8654 continue;
8655 }
8656 let path_nodes = if enter_alt_number == 0 {
8657 path.deferred_nodes
8658 } else {
8659 let alternative = self
8660 .recognition_arena
8661 .deferred_alternative(enter_alt_number);
8662 self.recognition_arena
8663 .concat_deferred_nodes(path.deferred_nodes, alternative)
8664 };
8665 let body_outcomes = self.recognize_state_fast(
8666 atn,
8667 FastRecognizeRequest {
8668 state_number: shape.enter_target,
8669 stop_state: shape.body_stop_state,
8670 index: path.index,
8671 rule_start_index: request.rule_start_index,
8672 decision_start_index: request.decision_start_index,
8673 precedence: request.precedence,
8674 depth: request.depth.saturating_add(1),
8675 recovery_symbols: Rc::clone(&request.recovery_symbols),
8676 recovery_state: request.recovery_state,
8677 },
8678 FastRecognizeScratch {
8679 predicate_context,
8680 visiting: &mut *visiting,
8681 memo: &mut *memo,
8682 expected: &mut *expected,
8683 native_depth: native_depth + 1,
8684 },
8685 );
8686 for body in body_outcomes.into_iter().rev() {
8687 if body.index <= path.index {
8691 continue;
8692 }
8693 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
8694 let body_nodes = self
8695 .recognition_arena
8696 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
8697 let deferred_nodes = self
8698 .recognition_arena
8699 .concat_deferred_nodes(path_nodes, body_nodes);
8700 let next_path = FastRepetitionPath {
8701 index: body.index,
8702 deferred_nodes,
8703 diagnostics: self
8704 .recognition_arena
8705 .concat_diagnostics(path.diagnostics, body.diagnostics),
8706 consumed_eof: path.consumed_eof || body.consumed_eof,
8707 };
8708 let symbol = self.token_type_at(next_path.index);
8709 push_fast_repetition_work(
8710 &mut work,
8711 shape,
8712 next_path,
8713 lookahead.as_deref(),
8714 symbol,
8715 );
8716 }
8717 }
8718 FastRepetitionWork::Exit(path) => {
8719 if !coordinates.insert_exited(path) {
8720 continue;
8721 }
8722 let path_nodes = if exit_alt_number == 0 {
8723 path.deferred_nodes
8724 } else {
8725 let alternative =
8726 self.recognition_arena.deferred_alternative(exit_alt_number);
8727 self.recognition_arena
8728 .concat_deferred_nodes(path.deferred_nodes, alternative)
8729 };
8730 let suffixes = self.recognize_state_fast(
8731 atn,
8732 FastRecognizeRequest {
8733 state_number: shape.exit_target,
8734 stop_state: request.stop_state,
8735 index: path.index,
8736 rule_start_index: request.rule_start_index,
8737 decision_start_index: request.decision_start_index,
8738 precedence: request.precedence,
8739 depth: request.depth.saturating_add(1),
8740 recovery_symbols: Rc::clone(&request.recovery_symbols),
8741 recovery_state: request.recovery_state,
8742 },
8743 FastRecognizeScratch {
8744 predicate_context,
8745 visiting: &mut *visiting,
8746 memo: &mut *memo,
8747 expected: &mut *expected,
8748 native_depth: native_depth + 1,
8749 },
8750 );
8751 for mut outcome in suffixes {
8752 outcome.deferred_nodes = self
8753 .recognition_arena
8754 .concat_deferred_nodes(path_nodes, outcome.deferred_nodes);
8755 outcome.diagnostics = self
8756 .recognition_arena
8757 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
8758 outcome.consumed_eof |= path.consumed_eof;
8759 outcomes.push(outcome);
8760 }
8761 }
8762 }
8763 }
8764 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8765 outcomes
8766 }
8767
8768 fn recognize_state_fast(
8771 &mut self,
8772 atn: &Atn,
8773 request: FastRecognizeRequest,
8774 scratch: FastRecognizeScratch<'_, '_>,
8775 ) -> Vec<FastRecognizeOutcome> {
8776 if scratch.native_depth != 0 && scratch.native_depth < FAST_RECOGNIZE_STACK_CHECK_INTERVAL {
8777 return self.recognize_state_fast_inner(atn, request, scratch);
8778 }
8779 self.recognize_state_fast_checked(atn, request, scratch)
8780 }
8781
8782 #[inline(never)]
8783 fn recognize_state_fast_checked(
8784 &mut self,
8785 atn: &Atn,
8786 request: FastRecognizeRequest,
8787 mut scratch: FastRecognizeScratch<'_, '_>,
8788 ) -> Vec<FastRecognizeOutcome> {
8789 scratch.native_depth = 1;
8790 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, || {
8791 self.recognize_state_fast_inner(atn, request, scratch)
8792 })
8793 }
8794
8795 #[allow(clippy::too_many_lines)]
8796 fn recognize_state_fast_inner(
8797 &mut self,
8798 atn: &Atn,
8799 request: FastRecognizeRequest,
8800 scratch: FastRecognizeScratch<'_, '_>,
8801 ) -> Vec<FastRecognizeOutcome> {
8802 #[cfg(feature = "perf-counters")]
8803 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
8804 let FastRecognizeScratch {
8805 predicate_context,
8806 visiting,
8807 memo,
8808 expected,
8809 native_depth,
8810 } = scratch;
8811 let FastRecognizeRequest {
8812 mut state_number,
8813 stop_state,
8814 mut index,
8815 rule_start_index,
8816 decision_start_index,
8817 precedence,
8818 mut depth,
8819 recovery_symbols,
8820 recovery_state,
8821 } = request;
8822 let max_token_type = atn.max_token_type();
8823 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
8842 let mut inline_consumed_eof = false;
8843 loop {
8844 if depth > RECOGNITION_DEPTH_LIMIT {
8845 return Vec::new();
8846 }
8847 if state_number == stop_state {
8848 let mut nodes = NodeSeqId::EMPTY;
8849 if self.fast_token_nodes_enabled {
8850 for token_index in inline_consumed_tokens.iter().rev() {
8851 let token = self.arena_token_node(*token_index, false);
8852 self.arena_prepend(&mut nodes, token);
8853 }
8854 }
8855 return vec![FastRecognizeOutcome {
8856 index,
8857 consumed_eof: inline_consumed_eof,
8858 diagnostics: DiagnosticSeqId::EMPTY,
8859 deferred_nodes: FastDeferredNodeId::EMPTY,
8860 nodes,
8861 }];
8862 }
8863 let Some(state) = atn.state(state_number) else {
8864 return Vec::new();
8865 };
8866 let transitions = state.transitions();
8867 if transitions.len() == 1 && !state.precedence_rule_decision() {
8868 let transition = transitions
8869 .first()
8870 .expect("single transition checked above");
8871 let transition_kind = transition.kind();
8872 let target = transition.target();
8873 match transition_kind {
8874 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
8875 if left_recursive_boundary(atn, state, target).is_none() =>
8876 {
8877 #[cfg(feature = "perf-counters")]
8878 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8879 state_number = target;
8880 depth += 1;
8881 continue;
8882 }
8883 ParserTransitionKind::Predicate
8884 if left_recursive_boundary(atn, state, target).is_none() =>
8885 {
8886 #[cfg(feature = "perf-counters")]
8887 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8888 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
8889 {
8890 record_predicate_no_viable(expected, decision_start_index, index);
8891 return Vec::new();
8892 }
8893 state_number = target;
8894 depth += 1;
8895 continue;
8896 }
8897 ParserTransitionKind::Precedence
8898 if packed_i32(transition.arg0()) >= precedence
8899 && left_recursive_boundary(atn, state, target).is_none() =>
8900 {
8901 #[cfg(feature = "perf-counters")]
8902 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
8903 state_number = target;
8904 depth += 1;
8905 continue;
8906 }
8907 ParserTransitionKind::Atom
8917 | ParserTransitionKind::Range
8918 | ParserTransitionKind::Set
8919 | ParserTransitionKind::NotSet
8920 | ParserTransitionKind::Wildcard
8921 if !self.fast_recovery_enabled =>
8922 {
8923 let symbol = self.token_type_at(index);
8924 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
8925 #[cfg(feature = "perf-counters")]
8926 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
8927 if self.fast_token_nodes_enabled {
8928 inline_consumed_tokens.push(index);
8929 }
8930 inline_consumed_eof |= symbol == TOKEN_EOF;
8931 index = self.consume_index(index, symbol);
8932 state_number = target;
8933 depth += 1;
8934 continue;
8935 }
8936 }
8939 _ => {}
8940 }
8941 }
8942 break;
8943 }
8944 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
8948 let Some(state) = atn.state(state_number) else {
8949 return Vec::new();
8950 };
8951 let transitions = state.transitions();
8952 let transition_count = transitions.len();
8953 if !self.fast_recovery_enabled
8954 && let Some(shape) = fast_repetition_shape(atn, state)
8955 {
8956 let mut outcomes = self.recognize_repetition_fast(
8957 atn,
8958 &FastRecognizeRequest {
8959 state_number,
8960 stop_state,
8961 index,
8962 rule_start_index,
8963 decision_start_index,
8964 precedence,
8965 depth,
8966 recovery_symbols: Rc::clone(&recovery_symbols),
8967 recovery_state,
8968 },
8969 shape,
8970 FastRecognizeScratch {
8971 predicate_context,
8972 visiting: &mut *visiting,
8973 memo: &mut *memo,
8974 expected: &mut *expected,
8975 native_depth: native_depth + 1,
8976 },
8977 );
8978 if inline_pending {
8979 for outcome in &mut outcomes {
8980 outcome.consumed_eof |= inline_consumed_eof;
8981 if self.fast_token_nodes_enabled {
8982 for token_index in inline_consumed_tokens.iter().rev() {
8983 let token = self.arena_token_node(*token_index, false);
8984 self.defer_fast_outcome_node(outcome, token);
8985 }
8986 }
8987 }
8988 }
8989 return outcomes;
8990 }
8991 let key = if self.fast_recovery_enabled {
9001 FastRecognizeKey {
9002 state_number,
9003 stop_state,
9004 index,
9005 rule_start_index,
9006 decision_start_index,
9007 precedence,
9008 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
9009 recovery_state,
9010 }
9011 } else {
9012 FastRecognizeKey {
9013 state_number,
9014 stop_state,
9015 index,
9016 rule_start_index: 0,
9017 decision_start_index: None,
9018 precedence,
9019 recovery_symbols_id: 0,
9020 recovery_state: None,
9021 }
9022 };
9023 let memo_lookup_enabled = self.fast_recovery_enabled
9028 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
9029 if memo_lookup_enabled {
9030 if let Some(outcomes) = memo.get(&key) {
9031 #[cfg(feature = "perf-counters")]
9032 {
9033 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
9034 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
9035 }
9036 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
9040 let inline_eof = inline_consumed_eof;
9041 let inline_tokens = &inline_consumed_tokens;
9042 return outcomes
9043 .iter()
9044 .copied()
9045 .map(|mut outcome| {
9046 if inline_eof {
9047 outcome.consumed_eof = true;
9048 }
9049 if self.fast_token_nodes_enabled {
9050 for token_index in inline_tokens.iter().rev() {
9051 let token = self.arena_token_node(*token_index, false);
9052 self.defer_fast_outcome_node(&mut outcome, token);
9053 }
9054 }
9055 outcome
9056 })
9057 .collect();
9058 }
9059 return outcomes.to_vec();
9060 }
9061 #[cfg(feature = "perf-counters")]
9062 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
9063 }
9064
9065 let needs_cycle_guard = if self.fast_recovery_enabled {
9070 transitions.iter().any(ParserTransition::is_epsilon)
9071 } else {
9072 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
9073 };
9074 #[cfg(feature = "perf-counters")]
9075 if needs_cycle_guard {
9076 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
9077 } else {
9078 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
9079 match state
9080 .transitions()
9081 .first()
9082 .expect("single-transition path requires one transition")
9083 .data()
9084 {
9085 Transition::Rule { .. } => {
9086 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
9087 }
9088 Transition::Atom { .. }
9089 | Transition::Range { .. }
9090 | Transition::Set { .. }
9091 | Transition::NotSet { .. }
9092 | Transition::Wildcard { .. } => {
9093 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
9094 }
9095 _ => {
9096 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
9097 }
9098 }
9099 }
9100 let has_inserted_cycle_guard = if needs_cycle_guard {
9101 if !visiting.insert(key.clone()) {
9102 #[cfg(feature = "perf-counters")]
9103 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
9104 return Vec::new();
9105 }
9106 true
9107 } else {
9108 false
9109 };
9110 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9111 Some(index)
9112 } else {
9113 decision_start_index
9114 };
9115 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
9116 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
9117 } else {
9118 (Rc::clone(&recovery_symbols), recovery_state)
9119 };
9120
9121 let lookahead_filter = if transition_count > 1
9140 && self.fast_first_set_prefilter
9141 && !state.precedence_rule_decision()
9142 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
9143 {
9144 state
9145 .rule_index()
9146 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
9147 .map(|rule_stop| {
9148 let symbol = self.token_type_at(index);
9149 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
9150 (symbol, entry)
9151 })
9152 } else {
9153 None
9154 };
9155 let ll1_only_alt: Option<usize> = if transition_count > 1
9164 && let Some((symbol, entry)) = lookahead_filter.as_ref()
9165 {
9166 let key = (state.state_number(), *symbol);
9167 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
9168 cached
9169 } else {
9170 let result = ll1_unique_alt(entry, *symbol);
9171 self.ll1_decision_cache.insert(key, result);
9172 result
9173 }
9174 } else {
9175 None
9176 };
9177 let lookahead_filter = lookahead_filter.as_ref();
9178 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
9184 for (transition_index, transition) in transitions.iter().enumerate() {
9185 if let Some(alt) = ll1_only_alt {
9186 if alt != transition_index {
9188 continue;
9189 }
9190 }
9191 let transition_kind = transition.kind();
9192 if ll1_only_alt.is_none()
9193 && should_skip_via_lookahead(
9194 transition_kind,
9195 transition_index,
9196 lookahead_filter,
9197 index,
9198 self.fast_recovery_enabled,
9199 expected,
9200 )
9201 {
9202 continue;
9203 }
9204 let target = transition.target();
9205 let outcomes_before_transition = outcomes.len();
9206 let left_recursive_boundary = match transition_kind {
9207 ParserTransitionKind::Epsilon
9208 | ParserTransitionKind::Action
9209 | ParserTransitionKind::Predicate
9210 | ParserTransitionKind::Precedence => left_recursive_boundary(atn, state, target),
9211 ParserTransitionKind::Atom
9212 | ParserTransitionKind::Range
9213 | ParserTransitionKind::Set
9214 | ParserTransitionKind::NotSet
9215 | ParserTransitionKind::Wildcard
9216 | ParserTransitionKind::Rule => None,
9217 };
9218 match transition_kind {
9219 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
9220 #[cfg(feature = "perf-counters")]
9221 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9222 outcomes.extend(self.recognize_state_fast(
9223 atn,
9224 FastRecognizeRequest {
9225 state_number: target,
9226 stop_state,
9227 index,
9228 rule_start_index,
9229 decision_start_index: next_decision_start_index,
9230 precedence,
9231 depth: depth + 1,
9232 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9233 recovery_state: epsilon_recovery_state,
9234 },
9235 FastRecognizeScratch {
9236 predicate_context,
9237 visiting,
9238 memo,
9239 expected,
9240 native_depth: native_depth + 1,
9241 },
9242 ));
9243 }
9244 ParserTransitionKind::Predicate => {
9245 #[cfg(feature = "perf-counters")]
9246 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9247 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
9248 outcomes.extend(self.recognize_state_fast(
9249 atn,
9250 FastRecognizeRequest {
9251 state_number: target,
9252 stop_state,
9253 index,
9254 rule_start_index,
9255 decision_start_index: next_decision_start_index,
9256 precedence,
9257 depth: depth + 1,
9258 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9259 recovery_state: epsilon_recovery_state,
9260 },
9261 FastRecognizeScratch {
9262 predicate_context,
9263 visiting,
9264 memo,
9265 expected,
9266 native_depth: native_depth + 1,
9267 },
9268 ));
9269 } else {
9270 record_predicate_no_viable(expected, next_decision_start_index, index);
9271 }
9272 }
9273 ParserTransitionKind::Precedence => {
9274 let transition_precedence = packed_i32(transition.arg0());
9275 if transition_precedence >= precedence {
9276 outcomes.extend(self.recognize_state_fast(
9277 atn,
9278 FastRecognizeRequest {
9279 state_number: target,
9280 stop_state,
9281 index,
9282 rule_start_index,
9283 decision_start_index: next_decision_start_index,
9284 precedence,
9285 depth: depth + 1,
9286 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9287 recovery_state: epsilon_recovery_state,
9288 },
9289 FastRecognizeScratch {
9290 predicate_context,
9291 visiting,
9292 memo,
9293 expected,
9294 native_depth: native_depth + 1,
9295 },
9296 ));
9297 }
9298 }
9299 ParserTransitionKind::Rule => {
9300 let rule_index = transition.arg0() as usize;
9301 let follow_state = transition.arg1() as usize;
9302 let rule_precedence = packed_i32(transition.arg2());
9303 #[cfg(feature = "perf-counters")]
9304 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
9305 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
9306 continue;
9307 };
9308 let symbol = self.token_type_at(index);
9320 if self.fast_first_set_prefilter {
9321 let first = self.cached_rule_first_set(atn, target, child_stop);
9334 if should_skip_rule_via_first_set(
9335 &first,
9336 symbol,
9337 self.fast_recovery_enabled,
9338 index,
9339 expected,
9340 ) {
9341 continue;
9342 }
9343 }
9344 let expected_before_child =
9345 self.fast_recovery_enabled.then(|| expected.clone());
9346 let mut children = self.recognize_state_fast(
9347 atn,
9348 FastRecognizeRequest {
9349 state_number: target,
9350 stop_state: child_stop,
9351 index,
9352 rule_start_index: index,
9353 decision_start_index: None,
9354 precedence: rule_precedence,
9355 depth: depth + 1,
9356 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9357 recovery_state: epsilon_recovery_state,
9358 },
9359 FastRecognizeScratch {
9360 predicate_context,
9361 visiting,
9362 memo,
9363 expected,
9364 native_depth: native_depth + 1,
9365 },
9366 );
9367 if children.is_empty() && self.fast_recovery_enabled {
9368 children = self.fast_child_rule_failure_recovery_outcomes(
9369 FastChildRuleFailureRecoveryRequest {
9370 atn,
9371 rule_index,
9372 start_index: index,
9373 follow_state,
9374 stop_state,
9375 expected,
9376 },
9377 );
9378 }
9379 if let Some(expected_before_child) = expected_before_child {
9380 if children
9381 .iter()
9382 .any(|child| child.diagnostics.is_empty() && child.index > index)
9383 {
9384 *expected = expected_before_child;
9385 }
9386 }
9387 for child in children {
9388 let child_index = child.index;
9389 let child_consumed_eof = child.consumed_eof;
9390 let child_diagnostics = child.diagnostics;
9391 let empty_recovery = self.empty_recovery_symbols();
9392 let follow_outcomes = self.recognize_state_fast(
9393 atn,
9394 FastRecognizeRequest {
9395 state_number: follow_state,
9396 stop_state,
9397 index: child_index,
9398 rule_start_index,
9399 decision_start_index: next_decision_start_index,
9400 precedence,
9401 depth: depth + 1,
9402 recovery_symbols: empty_recovery,
9403 recovery_state: None,
9404 },
9405 FastRecognizeScratch {
9406 predicate_context,
9407 visiting,
9408 memo,
9409 expected,
9410 native_depth: native_depth + 1,
9411 },
9412 );
9413 if follow_outcomes.is_empty() {
9414 continue;
9415 }
9416 let child_stop_index =
9417 self.rule_stop_token_index(child_index, child_consumed_eof);
9418 let child_node = self.build_parse_trees.then(|| {
9419 self.recognition_arena.deferred_rule_node(FastDeferredRule {
9420 rule_index: u32::try_from(rule_index)
9421 .expect("rule index fits in u32"),
9422 invoking_state: i32::try_from(invoking_state_number(state_number))
9423 .expect("invoking state fits in i32"),
9424 start_index: u32::try_from(index)
9425 .expect("rule start index fits in u32"),
9426 stop_index: child_stop_index.map(|stop_index| {
9427 u32::try_from(stop_index).expect("rule stop index fits in u32")
9428 }),
9429 deferred_children: child.deferred_nodes,
9430 children: child.nodes,
9431 })
9432 });
9433 let child_diags_empty = child_diagnostics.is_empty();
9434 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
9435 outcome.consumed_eof |= child_consumed_eof;
9436 if !child_diags_empty {
9439 outcome.diagnostics = self
9440 .recognition_arena
9441 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
9442 }
9443 if let Some(child_node) = child_node {
9444 outcome.deferred_nodes = self
9445 .recognition_arena
9446 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
9447 }
9448 outcome
9449 }));
9450 }
9451 }
9452 ParserTransitionKind::Atom
9453 | ParserTransitionKind::Range
9454 | ParserTransitionKind::Set
9455 | ParserTransitionKind::NotSet
9456 | ParserTransitionKind::Wildcard => {
9457 #[cfg(feature = "perf-counters")]
9458 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9459 let symbol = self.token_type_at(index);
9460 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9461 let next_index = self.consume_index(index, symbol);
9462 let empty_recovery = self.empty_recovery_symbols();
9463 outcomes.extend(
9464 self.recognize_state_fast(
9465 atn,
9466 FastRecognizeRequest {
9467 state_number: target,
9468 stop_state,
9469 index: next_index,
9470 rule_start_index,
9471 decision_start_index: next_decision_start_index,
9472 precedence,
9473 depth: depth + 1,
9474 recovery_symbols: empty_recovery,
9475 recovery_state: None,
9476 },
9477 FastRecognizeScratch {
9478 predicate_context,
9479 visiting,
9480 memo,
9481 expected,
9482 native_depth: native_depth + 1,
9483 },
9484 )
9485 .into_iter()
9486 .map(|mut outcome| {
9487 outcome.consumed_eof |= symbol == TOKEN_EOF;
9488 if self.fast_token_nodes_enabled {
9489 let token = self.arena_token_node(index, false);
9490 self.defer_fast_outcome_node(&mut outcome, token);
9491 }
9492 outcome
9493 }),
9494 );
9495 } else {
9496 if !self.fast_recovery_enabled {
9497 continue;
9505 }
9506 let expected_symbols = fast_recovery_expected_symbols(
9507 self,
9508 atn,
9509 state.state_number(),
9510 &recovery_symbols,
9511 );
9512 if expected_symbols.contains(&symbol) {
9513 continue;
9514 }
9515 {
9516 expected.record_transition(index, transition, max_token_type);
9517 record_no_viable_if_ambiguous(
9518 expected,
9519 next_decision_start_index,
9520 index,
9521 );
9522 outcomes.extend(self.fast_single_token_deletion_recovery(
9523 FastRecoveryRequest {
9524 atn,
9525 transition,
9526 expected_symbols: Rc::clone(&expected_symbols),
9527 target,
9528 request: FastRecognizeRequest {
9529 state_number,
9530 stop_state,
9531 index,
9532 rule_start_index,
9533 decision_start_index,
9534 precedence,
9535 depth,
9536 recovery_symbols: Rc::clone(&recovery_symbols),
9537 recovery_state,
9538 },
9539 visiting,
9540 memo,
9541 expected,
9542 },
9543 predicate_context,
9544 ));
9545 if !state_is_left_recursive_rule(atn, state) {
9546 outcomes.extend(self.fast_single_token_insertion_recovery(
9547 FastRecoveryRequest {
9548 atn,
9549 transition,
9550 expected_symbols: Rc::clone(&expected_symbols),
9551 target,
9552 request: FastRecognizeRequest {
9553 state_number,
9554 stop_state,
9555 index,
9556 rule_start_index,
9557 decision_start_index,
9558 precedence,
9559 depth,
9560 recovery_symbols: Rc::clone(&recovery_symbols),
9561 recovery_state,
9562 },
9563 visiting,
9564 memo,
9565 expected,
9566 },
9567 predicate_context,
9568 ));
9569 }
9570 outcomes.extend(self.fast_current_token_deletion_recovery(
9571 FastCurrentTokenDeletionRequest {
9572 atn,
9573 expected_symbols,
9574 request: FastRecognizeRequest {
9575 state_number,
9576 stop_state,
9577 index,
9578 rule_start_index,
9579 decision_start_index,
9580 precedence,
9581 depth,
9582 recovery_symbols: Rc::clone(&recovery_symbols),
9583 recovery_state,
9584 },
9585 visiting,
9586 memo,
9587 expected,
9588 },
9589 predicate_context,
9590 ));
9591 }
9592 }
9593 }
9594 }
9595 let alt_number = next_alt_number(
9596 state,
9597 transition_count,
9598 transition_index,
9599 0,
9600 self.fast_track_alt_numbers,
9601 );
9602 if alt_number != 0 || left_recursive_boundary.is_some() {
9603 for outcome in &mut outcomes[outcomes_before_transition..] {
9604 if alt_number != 0 {
9605 self.defer_fast_outcome_alternative(outcome, alt_number);
9606 }
9607 if let Some(rule_index) = left_recursive_boundary {
9608 self.defer_fast_outcome_boundary(outcome, rule_index);
9609 }
9610 }
9611 }
9612 }
9613
9614 if has_inserted_cycle_guard {
9615 visiting.remove(&key);
9616 }
9617 if matches!(
9618 self.prediction_mode,
9619 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9620 ) && self.fast_recovery_enabled
9621 {
9622 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
9626 }
9627 if self.fast_recovery_enabled {
9628 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
9629 } else {
9630 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
9631 }
9632 let should_memoize = self.fast_recovery_enabled
9642 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
9643 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
9647 if inline_consumed_eof {
9648 outcome.consumed_eof = true;
9649 }
9650 if !inline_consumed_tokens.is_empty() {
9651 for token_index in inline_consumed_tokens.iter().rev() {
9652 let token = self.arena_token_node(*token_index, false);
9653 self.defer_fast_outcome_node(&mut outcome, token);
9654 }
9655 }
9656 outcome
9657 };
9658 if should_memoize {
9659 #[cfg(feature = "perf-counters")]
9660 {
9661 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
9662 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
9663 match outcomes.len() {
9664 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
9665 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
9666 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
9667 }
9668 }
9669 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
9674 memo.insert(key, Rc::clone(&stored));
9675 if inline_pending {
9676 return stored
9677 .iter()
9678 .copied()
9679 .map(&mut apply_inline_pending)
9680 .collect();
9681 }
9682 return stored.to_vec();
9683 }
9684 #[cfg(feature = "perf-counters")]
9685 match outcomes.len() {
9686 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
9687 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
9688 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
9689 }
9690 if inline_pending {
9691 return outcomes.into_iter().map(apply_inline_pending).collect();
9692 }
9693 outcomes
9694 }
9695
9696 fn single_token_deletion_recovery(
9699 &mut self,
9700 recovery: RecoveryRequest<'_, '_>,
9701 ) -> Vec<RecognizeOutcome> {
9702 let RecoveryRequest {
9703 atn,
9704 transition,
9705 expected_symbols,
9706 target,
9707 request,
9708 visiting,
9709 memo,
9710 expected,
9711 } = recovery;
9712 let RecognizeRequest {
9713 stop_state,
9714 index,
9715 rule_start_index,
9716 decision_start_index,
9717 init_action_rules,
9718 predicates,
9719 semantics,
9720 rule_args,
9721 member_actions,
9722 return_actions,
9723 local_int_arg,
9724 member_values,
9725 return_values,
9726 rule_alt_number,
9727 track_alt_numbers,
9728 consumed_eof,
9729 precedence,
9730 depth,
9731 ..
9732 } = request;
9733 let Some((diagnostic, next_index, next_symbol)) =
9734 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
9735 else {
9736 return Vec::new();
9737 };
9738 let after_next = self.consume_index(next_index, next_symbol);
9739 self.recognize_state(
9740 atn,
9741 RecognizeRequest {
9742 state_number: target,
9743 stop_state,
9744 index: after_next,
9745 rule_start_index,
9746 decision_start_index,
9747 init_action_rules,
9748 predicates,
9749 semantics,
9750 rule_args,
9751 member_actions,
9752 return_actions,
9753 local_int_arg,
9754 member_values,
9755 return_values,
9756 rule_alt_number,
9757 track_alt_numbers,
9758 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
9759 committed_decision: false,
9760 precedence,
9761 depth: depth + 1,
9762 recovery_symbols: BTreeSet::new(),
9763 recovery_state: None,
9764 },
9765 visiting,
9766 memo,
9767 expected,
9768 )
9769 .into_iter()
9770 .map(|mut outcome| {
9771 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
9772 outcome.diagnostics = self
9773 .recognition_arena
9774 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9775 let token = self.arena_token_node(next_index, false);
9776 self.arena_prepend(&mut outcome.nodes, token);
9777 let error = self.arena_token_node(index, true);
9778 self.arena_prepend(&mut outcome.nodes, error);
9779 outcome
9780 })
9781 .collect()
9782 }
9783
9784 fn current_token_deletion_recovery(
9787 &mut self,
9788 recovery: CurrentTokenDeletionRequest<'_, '_>,
9789 ) -> Vec<RecognizeOutcome> {
9790 let CurrentTokenDeletionRequest {
9791 atn,
9792 expected_symbols,
9793 mut request,
9794 visiting,
9795 memo,
9796 expected,
9797 } = recovery;
9798 let error_index = request.index;
9799 if error_index == request.rule_start_index {
9800 return Vec::new();
9801 }
9802 let Some((diagnostic, next_index, skipped)) =
9803 self.current_token_deletion(error_index, &expected_symbols)
9804 else {
9805 return Vec::new();
9806 };
9807 request.state_number = request.recovery_state.unwrap_or(request.state_number);
9808 request.index = next_index;
9809 request.committed_decision = false;
9810 request.depth += 1;
9811 request.recovery_state = None;
9812 self.recognize_state(atn, request, visiting, memo, expected)
9813 .into_iter()
9814 .map(|mut outcome| {
9815 outcome.diagnostics = self
9816 .recognition_arena
9817 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9818 for index in skipped.iter().rev() {
9819 let error = self.arena_token_node(*index, true);
9820 self.arena_prepend(&mut outcome.nodes, error);
9821 }
9822 outcome
9823 })
9824 .collect()
9825 }
9826
9827 fn consuming_failure_fallback(
9830 &mut self,
9831 fallback: ConsumingFailureFallback<'_>,
9832 visiting: &mut BTreeSet<RecognizeKey>,
9833 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9834 expected: &mut ExpectedTokens,
9835 ) -> Vec<RecognizeOutcome> {
9836 if fallback.expected_symbols.is_empty() {
9837 return Vec::new();
9838 }
9839 if fallback.symbol == TOKEN_EOF {
9840 return self.eof_consuming_failure_fallback(fallback, expected);
9841 }
9842 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
9843 }
9844
9845 fn non_eof_consuming_failure_fallback(
9848 &mut self,
9849 fallback: ConsumingFailureFallback<'_>,
9850 visiting: &mut BTreeSet<RecognizeKey>,
9851 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9852 expected: &mut ExpectedTokens,
9853 ) -> Vec<RecognizeOutcome> {
9854 let ConsumingFailureFallback {
9855 atn,
9856 target,
9857 request,
9858 symbol,
9859 expected_symbols,
9860 decision_start_index,
9861 decision,
9862 } = fallback;
9863 let error_index = request.index;
9864 let diagnostic =
9865 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
9866 let next_index = self.consume_index(error_index, symbol);
9867 self.recognize_state(
9868 atn,
9869 RecognizeRequest {
9870 state_number: target,
9871 stop_state: request.stop_state,
9872 index: next_index,
9873 rule_start_index: request.rule_start_index,
9874 decision_start_index,
9875 init_action_rules: request.init_action_rules,
9876 predicates: request.predicates,
9877 semantics: request.semantics,
9878 rule_args: request.rule_args,
9879 member_actions: request.member_actions,
9880 return_actions: request.return_actions,
9881 local_int_arg: request.local_int_arg,
9882 member_values: request.member_values,
9883 return_values: request.return_values,
9884 rule_alt_number: request.rule_alt_number,
9885 track_alt_numbers: request.track_alt_numbers,
9886 consumed_eof: request.consumed_eof,
9887 committed_decision: false,
9888 precedence: request.precedence,
9889 depth: request.depth + 1,
9890 recovery_symbols: BTreeSet::new(),
9891 recovery_state: None,
9892 },
9893 visiting,
9894 memo,
9895 expected,
9896 )
9897 .into_iter()
9898 .map(|mut outcome| {
9899 prepend_decision(&mut outcome, decision);
9900 outcome.diagnostics = self
9901 .recognition_arena
9902 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9903 let error = self.arena_token_node(error_index, true);
9904 self.arena_prepend(&mut outcome.nodes, error);
9905 outcome
9906 })
9907 .collect()
9908 }
9909
9910 fn eof_consuming_failure_fallback(
9913 &mut self,
9914 fallback: ConsumingFailureFallback<'_>,
9915 expected: &ExpectedTokens,
9916 ) -> Vec<RecognizeOutcome> {
9917 let request = fallback.request;
9918 if request.index == request.rule_start_index {
9919 return Vec::new();
9920 }
9921 let diagnostic =
9922 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
9923 let diagnostics = self
9924 .recognition_arena
9925 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
9926 vec![RecognizeOutcome {
9927 index: request.index,
9928 consumed_eof: request.consumed_eof,
9929 alt_number: request.rule_alt_number,
9930 member_values: request.member_values,
9931 return_values: request.return_values,
9932 diagnostics,
9933 decisions: Vec::new(),
9934 actions: Vec::new(),
9935 nodes: NodeSeqId::EMPTY,
9936 }]
9937 }
9938
9939 fn single_token_insertion_recovery(
9942 &mut self,
9943 recovery: RecoveryRequest<'_, '_>,
9944 ) -> Vec<RecognizeOutcome> {
9945 let RecoveryRequest {
9946 atn,
9947 transition,
9948 expected_symbols,
9949 target,
9950 request,
9951 visiting,
9952 memo,
9953 expected,
9954 } = recovery;
9955 let RecognizeRequest {
9956 stop_state,
9957 index,
9958 rule_start_index,
9959 decision_start_index,
9960 init_action_rules,
9961 predicates,
9962 semantics,
9963 rule_args,
9964 member_actions,
9965 return_actions,
9966 local_int_arg,
9967 member_values,
9968 return_values,
9969 rule_alt_number,
9970 track_alt_numbers,
9971 consumed_eof,
9972 precedence,
9973 depth,
9974 ..
9975 } = request;
9976 let follow_symbols = state_expected_symbols(atn, transition.target());
9977 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
9978 transition,
9979 index,
9980 atn.max_token_type(),
9981 &expected_symbols,
9982 &follow_symbols,
9983 ) else {
9984 return Vec::new();
9985 };
9986 self.recognize_state(
9987 atn,
9988 RecognizeRequest {
9989 state_number: target,
9990 stop_state,
9991 index,
9992 rule_start_index,
9993 decision_start_index,
9994 init_action_rules,
9995 predicates,
9996 semantics,
9997 rule_args,
9998 member_actions,
9999 return_actions,
10000 local_int_arg,
10001 member_values,
10002 return_values,
10003 rule_alt_number,
10004 track_alt_numbers,
10005 consumed_eof,
10006 committed_decision: false,
10007 precedence,
10008 depth: depth + 1,
10009 recovery_symbols: BTreeSet::new(),
10010 recovery_state: None,
10011 },
10012 visiting,
10013 memo,
10014 expected,
10015 )
10016 .into_iter()
10017 .map(|mut outcome| {
10018 outcome.diagnostics = self
10019 .recognition_arena
10020 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10021 let missing = self.arena_missing_token_node(token_type, index, text.clone());
10022 self.arena_prepend(&mut outcome.nodes, missing);
10023 outcome
10024 })
10025 .collect()
10026 }
10027
10028 #[allow(clippy::too_many_lines)]
10031 fn recognize_state(
10032 &mut self,
10033 atn: &Atn,
10034 request: RecognizeRequest<'_>,
10035 visiting: &mut BTreeSet<RecognizeKey>,
10036 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10037 expected: &mut ExpectedTokens,
10038 ) -> Vec<RecognizeOutcome> {
10039 let request_template = request.clone();
10040 let RecognizeRequest {
10041 state_number,
10042 stop_state,
10043 index,
10044 rule_start_index,
10045 decision_start_index,
10046 init_action_rules,
10047 predicates,
10048 semantics,
10049 rule_args,
10050 member_actions,
10051 return_actions,
10052 local_int_arg,
10053 member_values,
10054 return_values,
10055 rule_alt_number,
10056 track_alt_numbers,
10057 consumed_eof,
10058 committed_decision,
10059 precedence,
10060 depth,
10061 recovery_symbols,
10062 recovery_state,
10063 } = request;
10064 if depth > RECOGNITION_DEPTH_LIMIT {
10065 return Vec::new();
10066 }
10067 if state_number == stop_state {
10068 return stop_outcome(
10069 index,
10070 consumed_eof,
10071 rule_alt_number,
10072 member_values,
10073 return_values,
10074 );
10075 }
10076 let key = RecognizeKey {
10077 state_number,
10078 stop_state,
10079 index,
10080 rule_start_index,
10081 decision_start_index,
10082 local_int_arg,
10083 member_values: member_values.clone(),
10084 return_values: return_values.clone(),
10085 rule_alt_number,
10086 track_alt_numbers,
10087 consumed_eof,
10088 committed_decision,
10089 precedence,
10090 recovery_symbols: recovery_symbols.clone(),
10091 recovery_state,
10092 };
10093 if let Some(outcomes) = memo.get(&key) {
10094 return outcomes.clone();
10095 }
10096
10097 let visit_key = key.clone();
10098 if !visiting.insert(visit_key.clone()) {
10099 return Vec::new();
10100 }
10101
10102 let Some(state) = atn.state(state_number) else {
10103 visiting.remove(&visit_key);
10104 return Vec::new();
10105 };
10106 let decision_override_generation = self.decision_override_generation;
10107 let transitions = state.transitions();
10108 let transition_count = transitions.len();
10109 let overridden_transition = if transition_count > 1
10110 && self.semantic_hooks.observes_parser_decisions()
10111 {
10112 atn.decision_to_state()
10113 .iter()
10114 .position(|candidate| candidate == state_number)
10115 .and_then(|decision| {
10116 self.semantic_hooks
10117 .parser_decision_override(decision, index, transition_count)
10118 })
10119 .and_then(|alternative| alternative.checked_sub(1))
10120 .filter(|alternative| *alternative < transition_count)
10121 } else {
10122 None
10123 };
10124 if overridden_transition.is_some() {
10125 self.decision_override_generation = self.decision_override_generation.wrapping_add(1);
10126 }
10127 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
10128 Some(index)
10129 } else {
10130 decision_start_index
10131 };
10132 let (epsilon_recovery_symbols, epsilon_recovery_state) =
10133 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
10134 let mut outcomes = Vec::new();
10135 for (transition_index, transition) in transitions.iter().enumerate() {
10136 if overridden_transition.is_some_and(|forced| forced != transition_index) {
10137 continue;
10138 }
10139 let transition_committed =
10140 committed_decision || overridden_transition == Some(transition_index);
10141 let mut transition_request = request_template.clone();
10142 transition_request.committed_decision = transition_committed;
10143 let decision =
10144 transition_decision(atn, state, transition_count, transition_index, predicates);
10145 let next_alt_number = next_alt_number(
10146 state,
10147 transition_count,
10148 transition_index,
10149 rule_alt_number,
10150 track_alt_numbers,
10151 );
10152 let transition_data = transition.data();
10153 match &transition_data {
10154 Transition::Epsilon { target } | Transition::Action { target, .. } => {
10155 let action_rule_index = match &transition_data {
10156 Transition::Action { rule_index, .. } => Some(*rule_index),
10157 _ => None,
10158 };
10159 outcomes.extend(self.recognize_epsilon_or_action_step(
10160 atn,
10161 &transition_request,
10162 EpsilonActionStep {
10163 source_state: state_number,
10164 target: *target,
10165 action_rule_index,
10166 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
10167 decision,
10168 decision_start_index: next_decision_start_index,
10169 alt_number: next_alt_number,
10170 recovery_symbols: epsilon_recovery_symbols.clone(),
10171 recovery_state: epsilon_recovery_state,
10172 },
10173 RecognizeScratch {
10174 visiting,
10175 memo,
10176 expected,
10177 },
10178 ));
10179 }
10180 Transition::Predicate {
10181 target,
10182 rule_index,
10183 pred_index,
10184 ..
10185 } => {
10186 let predicate = PredicateEval {
10187 index,
10188 rule_index: *rule_index,
10189 pred_index: *pred_index,
10190 predicates,
10191 semantics,
10192 context: None,
10193 local_int_arg,
10194 member_values: &member_values,
10195 };
10196 if self.parser_predicate_matches(predicate) {
10197 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
10198 outcomes.extend(
10199 self.recognize_state(
10200 atn,
10201 RecognizeRequest {
10202 state_number: *target,
10203 stop_state,
10204 index,
10205 rule_start_index,
10206 decision_start_index: next_decision_start_index,
10207 init_action_rules,
10208 predicates,
10209 semantics,
10210 rule_args,
10211 member_actions,
10212 return_actions,
10213 local_int_arg,
10214 member_values: member_values.clone(),
10215 return_values: return_values.clone(),
10216 rule_alt_number: next_alt_number,
10217 track_alt_numbers,
10218 consumed_eof,
10219 committed_decision: transition_committed,
10220 precedence,
10221 depth: depth + 1,
10222 recovery_symbols: epsilon_recovery_symbols.clone(),
10223 recovery_state: epsilon_recovery_state,
10224 },
10225 visiting,
10226 memo,
10227 expected,
10228 )
10229 .into_iter()
10230 .map(|mut outcome| {
10231 prepend_decision(&mut outcome, decision);
10232 if let Some(rule_index) = left_recursive_boundary {
10233 let boundary =
10234 self.arena_boundary_node(rule_index, next_alt_number);
10235 self.arena_prepend(&mut outcome.nodes, boundary);
10236 }
10237 outcome
10238 }),
10239 );
10240 } else if let Some(message) = semantics
10241 .and_then(|semantics| {
10242 self.parser_semantic_ir_predicate_failure_message(
10243 *rule_index,
10244 *pred_index,
10245 semantics,
10246 )
10247 })
10248 .or_else(|| {
10249 self.parser_predicate_failure_message(
10250 *rule_index,
10251 *pred_index,
10252 predicates,
10253 )
10254 })
10255 {
10256 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
10257 rule_index: *rule_index,
10258 index,
10259 message,
10260 member_values: member_values.clone(),
10261 return_values: return_values.clone(),
10262 rule_alt_number,
10263 }));
10264 } else {
10265 record_predicate_no_viable(expected, next_decision_start_index, index);
10266 }
10267 }
10268 Transition::Precedence {
10269 target,
10270 precedence: transition_precedence,
10271 } => {
10272 if *transition_precedence >= precedence {
10273 outcomes.extend(
10274 self.recognize_state(
10275 atn,
10276 RecognizeRequest {
10277 state_number: *target,
10278 stop_state,
10279 index,
10280 rule_start_index,
10281 decision_start_index: next_decision_start_index,
10282 init_action_rules,
10283 predicates,
10284 semantics,
10285 rule_args,
10286 member_actions,
10287 return_actions,
10288 local_int_arg,
10289 member_values: member_values.clone(),
10290 return_values: return_values.clone(),
10291 rule_alt_number: next_alt_number,
10292 track_alt_numbers,
10293 consumed_eof,
10294 committed_decision: transition_committed,
10295 precedence,
10296 depth: depth + 1,
10297 recovery_symbols: epsilon_recovery_symbols.clone(),
10298 recovery_state: epsilon_recovery_state,
10299 },
10300 visiting,
10301 memo,
10302 expected,
10303 )
10304 .into_iter()
10305 .map(|mut outcome| {
10306 prepend_decision(&mut outcome, decision);
10307 outcome
10308 }),
10309 );
10310 }
10311 }
10312 Transition::Rule {
10313 target,
10314 rule_index,
10315 follow_state,
10316 precedence: rule_precedence,
10317 ..
10318 } => {
10319 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
10320 continue;
10321 };
10322 let child_local_int_arg =
10323 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
10324 let expected_before_child = expected.clone();
10325 let children = self.recognize_state(
10326 atn,
10327 RecognizeRequest {
10328 state_number: *target,
10329 stop_state: child_stop,
10330 index,
10331 rule_start_index: index,
10332 decision_start_index: None,
10333 init_action_rules,
10334 predicates,
10335 semantics,
10336 rule_args,
10337 member_actions,
10338 return_actions,
10339 local_int_arg: child_local_int_arg,
10340 member_values: member_values.clone(),
10341 return_values: BTreeMap::new(),
10342 rule_alt_number: 0,
10343 track_alt_numbers,
10344 consumed_eof: false,
10345 committed_decision: transition_committed,
10346 precedence: *rule_precedence,
10347 depth: depth + 1,
10348 recovery_symbols: epsilon_recovery_symbols.clone(),
10349 recovery_state: epsilon_recovery_state,
10350 },
10351 visiting,
10352 memo,
10353 expected,
10354 );
10355 let children = if children.is_empty() {
10356 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
10357 atn,
10358 rule_index: *rule_index,
10359 start_index: index,
10360 follow_state: *follow_state,
10361 stop_state,
10362 member_values: member_values.clone(),
10363 expected,
10364 })
10365 } else {
10366 children
10367 };
10368 let preserve_child_expected =
10369 self.child_expected_reaches_clean_eof(&children, expected);
10370 restore_expected(
10371 &children,
10372 index,
10373 expected,
10374 expected_before_child,
10375 preserve_child_expected,
10376 );
10377 for child in children {
10378 let child_stop_index =
10379 self.rule_stop_token_index(child.index, child.consumed_eof);
10380 let child_nodes = self
10381 .recognition_arena
10382 .fold_left_recursive_boundaries(child.nodes);
10383 let child_node = self.arena_rule_node(ArenaRuleSpec {
10384 rule_index: *rule_index,
10385 invoking_state: invoking_state_number(state_number),
10386 alt_number: child.alt_number,
10387 start_index: index,
10388 stop_index: child_stop_index,
10389 return_values: child.return_values.clone(),
10390 children: child_nodes,
10391 });
10392 outcomes.extend(
10393 self.recognize_state(
10394 atn,
10395 RecognizeRequest {
10396 state_number: *follow_state,
10397 stop_state,
10398 index: child.index,
10399 rule_start_index,
10400 decision_start_index: next_decision_start_index,
10401 init_action_rules,
10402 predicates,
10403 semantics,
10404 rule_args,
10405 member_actions,
10406 return_actions,
10407 local_int_arg,
10408 member_values: child.member_values.clone(),
10409 return_values: return_values.clone(),
10410 rule_alt_number,
10411 track_alt_numbers,
10412 consumed_eof: consumed_eof || child.consumed_eof,
10413 committed_decision: transition_committed
10414 && child.index == index,
10415 precedence,
10416 depth: depth + 1,
10417 recovery_symbols: BTreeSet::new(),
10418 recovery_state: None,
10419 },
10420 visiting,
10421 memo,
10422 expected,
10423 )
10424 .into_iter()
10425 .map(|mut outcome| {
10426 outcome.consumed_eof |= child.consumed_eof;
10427 outcome.diagnostics = self
10428 .recognition_arena
10429 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
10430 let mut decisions = child.decisions.clone();
10431 decisions.append(&mut outcome.decisions);
10432 outcome.decisions = decisions;
10433 prepend_decision(&mut outcome, decision);
10434 let mut actions = child.actions.clone();
10435 if init_action_rules.contains(rule_index) {
10436 actions.insert(
10437 0,
10438 ParserAction::new_rule_init(
10439 *rule_index,
10440 index,
10441 Some(*follow_state),
10442 ),
10443 );
10444 }
10445 actions.append(&mut outcome.actions);
10446 outcome.actions = actions;
10447 self.arena_prepend(&mut outcome.nodes, child_node);
10448 outcome
10449 }),
10450 );
10451 }
10452 }
10453 Transition::Atom { target, .. }
10454 | Transition::Range { target, .. }
10455 | Transition::Set { target, .. }
10456 | Transition::NotSet { target, .. }
10457 | Transition::Wildcard { target, .. } => {
10458 let symbol = self.token_type_at(index);
10459 if transition_data.matches(symbol, 1, atn.max_token_type()) {
10460 let next_index = self.consume_index(index, symbol);
10461 outcomes.extend(
10462 self.recognize_state(
10463 atn,
10464 RecognizeRequest {
10465 state_number: *target,
10466 stop_state,
10467 index: next_index,
10468 rule_start_index,
10469 decision_start_index: next_decision_start_index,
10470 init_action_rules,
10471 predicates,
10472 semantics,
10473 rule_args,
10474 member_actions,
10475 return_actions,
10476 local_int_arg,
10477 member_values: member_values.clone(),
10478 return_values: return_values.clone(),
10479 rule_alt_number: next_alt_number,
10480 track_alt_numbers,
10481 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
10482 committed_decision: false,
10483 precedence,
10484 depth: depth + 1,
10485 recovery_symbols: BTreeSet::new(),
10486 recovery_state: None,
10487 },
10488 visiting,
10489 memo,
10490 expected,
10491 )
10492 .into_iter()
10493 .map(|mut outcome| {
10494 prepend_decision(&mut outcome, decision);
10495 outcome.consumed_eof |= symbol == TOKEN_EOF;
10496 let token = self.arena_token_node(index, false);
10497 self.arena_prepend(&mut outcome.nodes, token);
10498 outcome
10499 }),
10500 );
10501 } else {
10502 let expected_symbols =
10503 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
10504 if expected_symbols.contains(&symbol) && !transition_committed {
10505 continue;
10506 }
10507 expected.record_transition(index, transition, atn.max_token_type());
10508 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
10509 let before_recovery = outcomes.len();
10510 let recovery_request = transition_request.clone();
10511 if transition_committed {
10512 outcomes.extend(self.consuming_failure_fallback(
10513 ConsumingFailureFallback {
10514 atn,
10515 target: *target,
10516 request: recovery_request,
10517 symbol,
10518 expected_symbols,
10519 decision_start_index: next_decision_start_index,
10520 decision,
10521 },
10522 visiting,
10523 memo,
10524 expected,
10525 ));
10526 break;
10527 }
10528 outcomes.extend(
10529 self.single_token_deletion_recovery(RecoveryRequest {
10530 atn,
10531 transition,
10532 expected_symbols: expected_symbols.clone(),
10533 target: *target,
10534 request: recovery_request.clone(),
10535 visiting,
10536 memo,
10537 expected,
10538 })
10539 .into_iter()
10540 .map(|mut outcome| {
10541 prepend_decision(&mut outcome, decision);
10542 outcome
10543 }),
10544 );
10545 if !state_is_left_recursive_rule(atn, state) {
10546 outcomes.extend(
10547 self.single_token_insertion_recovery(RecoveryRequest {
10548 atn,
10549 transition,
10550 expected_symbols: expected_symbols.clone(),
10551 target: *target,
10552 request: recovery_request.clone(),
10553 visiting,
10554 memo,
10555 expected,
10556 })
10557 .into_iter()
10558 .map(|mut outcome| {
10559 prepend_decision(&mut outcome, decision);
10560 outcome
10561 }),
10562 );
10563 }
10564 outcomes.extend(self.current_token_deletion_recovery(
10565 CurrentTokenDeletionRequest {
10566 atn,
10567 expected_symbols: expected_symbols.clone(),
10568 request: recovery_request.clone(),
10569 visiting,
10570 memo,
10571 expected,
10572 },
10573 ));
10574 if outcomes.len() == before_recovery {
10575 outcomes.extend(self.consuming_failure_fallback(
10576 ConsumingFailureFallback {
10577 atn,
10578 target: *target,
10579 request: recovery_request,
10580 symbol,
10581 expected_symbols,
10582 decision_start_index: next_decision_start_index,
10583 decision,
10584 },
10585 visiting,
10586 memo,
10587 expected,
10588 ));
10589 }
10590 }
10591 }
10592 }
10593 if self.decision_override_generation != decision_override_generation {
10594 break;
10595 }
10596 }
10597
10598 visiting.remove(&visit_key);
10599 self.record_prediction_diagnostics(atn, state, index, &outcomes);
10600 if matches!(
10601 self.prediction_mode,
10602 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
10603 ) {
10604 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
10605 }
10606 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
10607 memo.insert(key, outcomes.clone());
10608 outcomes
10609 }
10610
10611 fn recognize_epsilon_or_action_step(
10614 &mut self,
10615 atn: &Atn,
10616 request: &RecognizeRequest<'_>,
10617 step: EpsilonActionStep,
10618 scratch: RecognizeScratch<'_>,
10619 ) -> Vec<RecognizeOutcome> {
10620 let RecognizeScratch {
10621 visiting,
10622 memo,
10623 expected,
10624 } = scratch;
10625 let action = step.action_rule_index.map(|rule_index| {
10626 ParserAction::new(
10627 step.source_state,
10628 rule_index,
10629 request.rule_start_index,
10630 self.rule_stop_token_index(request.index, request.consumed_eof),
10631 )
10632 });
10633 let next_member_values = if action.is_some() {
10634 member_values_after_action(
10635 step.source_state,
10636 request.member_actions,
10637 request.semantics,
10638 &request.member_values,
10639 )
10640 } else {
10641 request.member_values.clone()
10642 };
10643 let next_return_values = action.map_or_else(
10644 || request.return_values.clone(),
10645 |action| {
10646 return_values_after_action(
10647 step.source_state,
10648 action.rule_index(),
10649 request.return_actions,
10650 request.semantics,
10651 &request.return_values,
10652 )
10653 },
10654 );
10655
10656 self.recognize_state(
10657 atn,
10658 RecognizeRequest {
10659 state_number: step.target,
10660 stop_state: request.stop_state,
10661 index: request.index,
10662 rule_start_index: request.rule_start_index,
10663 decision_start_index: step.decision_start_index,
10664 init_action_rules: request.init_action_rules,
10665 predicates: request.predicates,
10666 semantics: request.semantics,
10667 rule_args: request.rule_args,
10668 member_actions: request.member_actions,
10669 return_actions: request.return_actions,
10670 local_int_arg: request.local_int_arg,
10671 member_values: next_member_values,
10672 return_values: next_return_values,
10673 rule_alt_number: if step.left_recursive_boundary.is_some() {
10674 0
10675 } else {
10676 step.alt_number
10677 },
10678 track_alt_numbers: request.track_alt_numbers,
10679 consumed_eof: request.consumed_eof,
10680 committed_decision: request.committed_decision,
10681 precedence: request.precedence,
10682 depth: request.depth + 1,
10683 recovery_symbols: step.recovery_symbols,
10684 recovery_state: step.recovery_state,
10685 },
10686 visiting,
10687 memo,
10688 expected,
10689 )
10690 .into_iter()
10691 .map(|mut outcome| {
10692 prepend_decision(&mut outcome, step.decision);
10693 if let Some(rule_index) = step.left_recursive_boundary {
10694 let boundary = self.arena_boundary_node(rule_index, step.alt_number);
10695 self.arena_prepend(&mut outcome.nodes, boundary);
10696 }
10697 if let Some(action) = action {
10698 outcome.actions.insert(0, action);
10699 }
10700 outcome
10701 })
10702 .collect()
10703 }
10704
10705 fn token_type_at(&mut self, index: usize) -> i32 {
10710 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
10711 self.input.fill();
10712 }
10713 self.input.token_type_at_index(index)
10714 }
10715
10716 fn cached_state_expected_symbols(
10728 &mut self,
10729 atn: &Atn,
10730 state_number: usize,
10731 ) -> Rc<BTreeSet<i32>> {
10732 if let Some(cached) = self.state_expected_cache.get(&state_number) {
10733 return Rc::clone(cached);
10734 }
10735 let symbols = state_expected_symbols(atn, state_number);
10736 let entry = self.intern_recovery_symbols(symbols);
10737 self.state_expected_cache
10738 .insert(state_number, Rc::clone(&entry));
10739 entry
10740 }
10741
10742 fn cached_state_expected_token_set(
10743 &mut self,
10744 atn: &Atn,
10745 state_number: usize,
10746 ) -> Rc<TokenBitSet> {
10747 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
10748 return Rc::clone(cached);
10749 }
10750 let symbols = with_shared_atn_caches(atn, |cache| {
10754 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
10755 return Rc::clone(cached);
10756 }
10757 let symbols = Rc::new(state_expected_token_set(atn, state_number));
10758 cache
10759 .state_expected_tokens
10760 .insert(state_number, Rc::clone(&symbols));
10761 symbols
10762 });
10763 self.state_expected_token_cache
10764 .insert(state_number, Rc::clone(&symbols));
10765 symbols
10766 }
10767
10768 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
10769 if self.rule_stop_reach_cache.len() <= state_number {
10770 self.rule_stop_reach_cache
10771 .resize_with(atn.states().len().max(state_number + 1), || None);
10772 }
10773 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
10774 return reaches;
10775 }
10776 let reaches = with_shared_atn_caches(atn, |cache| {
10777 *cache
10778 .rule_stop_reach
10779 .entry(state_number)
10780 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
10781 });
10782 self.rule_stop_reach_cache[state_number] = Some(reaches);
10783 reaches
10784 }
10785
10786 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
10789 Rc::clone(&self.empty_recovery_symbols)
10790 }
10791
10792 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
10801 if set.is_empty() {
10802 return Rc::clone(&self.empty_recovery_symbols);
10803 }
10804 let candidate = Rc::new(set);
10805 match self.recovery_symbols_intern.get(&candidate) {
10806 Some(existing) => Rc::clone(existing),
10807 None => {
10808 self.recovery_symbols_intern
10809 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
10810 candidate
10811 }
10812 }
10813 }
10814
10815 fn cached_decision_lookahead(
10820 &mut self,
10821 atn: &Atn,
10822 state: AtnState<'_>,
10823 rule_stop_state: usize,
10824 ) -> Rc<DecisionLookahead> {
10825 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
10832 return Rc::clone(cached);
10833 }
10834 let entry = with_shared_atn_caches(atn, |cache| {
10835 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
10836 return Rc::clone(cached);
10837 }
10838 let mut entry = DecisionLookahead {
10839 transitions: Vec::with_capacity(state.transitions().len()),
10840 };
10841 for transition in &state.transitions() {
10842 entry.transitions.push(transition_first_set(
10843 atn,
10844 transition,
10845 rule_stop_state,
10846 &mut cache.first_set,
10847 ));
10848 }
10849 let entry = Rc::new(entry);
10850 cache
10851 .decision_lookahead
10852 .insert(state.state_number(), Rc::clone(&entry));
10853 entry
10854 });
10855 self.decision_lookahead_cache
10856 .insert(state.state_number(), Rc::clone(&entry));
10857 entry
10858 }
10859
10860 fn cached_rule_first_set(
10861 &mut self,
10862 atn: &Atn,
10863 target: usize,
10864 child_stop: usize,
10865 ) -> Rc<FirstSet> {
10866 if self.rule_first_set_cache.len() <= target {
10867 self.rule_first_set_cache
10868 .resize_with(atn.states().len().max(target + 1), || None);
10869 }
10870 if let Some(cached) = self
10871 .rule_first_set_cache
10872 .get(target)
10873 .and_then(Option::as_ref)
10874 {
10875 return Rc::clone(cached);
10876 }
10877 let first = with_shared_first_set_cache(atn, |cache| {
10878 rule_first_set(atn, target, child_stop, cache)
10879 });
10880 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
10881 first
10882 }
10883
10884 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
10885 let atn_key = SharedAtnCacheKey::for_atn(atn);
10886 if self.empty_cycle_cache_atn != Some(atn_key) {
10887 self.empty_cycle_cache.clear();
10888 self.empty_cycle_cache_atn = Some(atn_key);
10889 }
10890 if self.empty_cycle_cache.len() <= state_number {
10891 self.empty_cycle_cache
10892 .resize_with(atn.state_count().max(state_number + 1), || None);
10893 }
10894 if let Some(cached) = self.empty_cycle_cache[state_number] {
10895 return cached;
10896 }
10897 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
10898 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
10899 self.empty_cycle_cache[state_number] = Some(result);
10900 result
10901 }
10902
10903 fn empty_path_reaches_state(
10904 &mut self,
10905 atn: &Atn,
10906 state_number: usize,
10907 target_state: usize,
10908 visited: &mut FxHashSet<usize>,
10909 ) -> bool {
10910 enum Work {
10911 Visit(usize),
10912 RuleFollow {
10913 target: usize,
10914 rule_index: usize,
10915 follow_state: usize,
10916 },
10917 }
10918
10919 let mut work = vec![Work::Visit(state_number)];
10920 while let Some(item) = work.pop() {
10921 match item {
10922 Work::Visit(state_number) => {
10923 if !visited.insert(state_number) {
10924 continue;
10925 }
10926 let Some(state) = atn.state(state_number) else {
10927 continue;
10928 };
10929 let transitions = state.transitions();
10930 for transition_index in (0..transitions.len()).rev() {
10931 let transition = transitions
10932 .get(transition_index)
10933 .expect("in-bounds parser transition");
10934 let kind = transition.kind();
10935 let target = transition.target();
10936 match kind {
10937 ParserTransitionKind::Atom
10938 | ParserTransitionKind::Range
10939 | ParserTransitionKind::Set
10940 | ParserTransitionKind::NotSet
10941 | ParserTransitionKind::Wildcard => {}
10942 ParserTransitionKind::Rule => {
10943 if target == target_state {
10944 return true;
10945 }
10946 work.push(Work::RuleFollow {
10947 target,
10948 rule_index: transition.arg0() as usize,
10949 follow_state: transition.arg1() as usize,
10950 });
10951 work.push(Work::Visit(target));
10952 }
10953 ParserTransitionKind::Epsilon
10954 | ParserTransitionKind::Predicate
10955 | ParserTransitionKind::Action
10956 | ParserTransitionKind::Precedence => {
10957 if target == target_state {
10958 return true;
10959 }
10960 work.push(Work::Visit(target));
10961 }
10962 }
10963 }
10964 }
10965 Work::RuleFollow {
10966 target,
10967 rule_index,
10968 follow_state,
10969 } => {
10970 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
10971 continue;
10972 };
10973 if self.cached_rule_first_set(atn, target, child_stop).nullable {
10974 if follow_state == target_state {
10975 return true;
10976 }
10977 work.push(Work::Visit(follow_state));
10978 }
10979 }
10980 }
10981 }
10982 false
10983 }
10984
10985 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
10988 match self.clean_memo_mode {
10989 CleanMemoMode::Promote => true,
10990 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
10991 CleanMemoMode::Sparse => {
10992 self.clean_memo_sparse_samples += 1;
10993 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
10994 return false;
10995 }
10996 self.clean_memo_sparse_samples = 0;
10997 self.clean_memo_mode = CleanMemoMode::Probe;
10998 self.clean_memo_probe_samples = 0;
10999 self.clean_memo_probe_repeats = 0;
11000 self.clean_memo_probe_seen.clear();
11001 self.observe_clean_memo_probe(key)
11002 }
11003 }
11004 }
11005
11006 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
11007 self.clean_memo_probe_samples += 1;
11008 if !self.clean_memo_probe_seen.insert(key.clone()) {
11009 self.clean_memo_probe_repeats += 1;
11010 }
11011 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
11012 self.clean_memo_mode = CleanMemoMode::Promote;
11013 self.clean_memo_probe_seen.clear();
11014 return true;
11015 }
11016 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
11017 self.clean_memo_mode = CleanMemoMode::Sparse;
11018 self.clean_memo_sparse_samples = 0;
11019 self.clean_memo_probe_seen.clear();
11020 return false;
11021 }
11022 true
11023 }
11024
11025 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
11027 self.input.get(index)
11028 }
11029
11030 fn token_id_at(&self, index: usize) -> Option<TokenId> {
11032 self.input.get_id(index)
11033 }
11034
11035 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
11036 let token = self
11037 .token_id_at(index)
11038 .expect("recognized token index must exist in the token store");
11039 let node = if error {
11040 ArenaRecognizedNode::ErrorToken { token }
11041 } else {
11042 ArenaRecognizedNode::Token { token }
11043 };
11044 self.recognition_arena.push_node(node)
11045 }
11046
11047 fn arena_missing_token_node(
11048 &mut self,
11049 token_type: i32,
11050 at_index: usize,
11051 text: String,
11052 ) -> RecognizedNodeId {
11053 let extra = self
11054 .recognition_arena
11055 .push_extra(RecognitionExtra::MissingToken {
11056 token_type,
11057 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
11058 text,
11059 });
11060 self.recognition_arena
11061 .push_node(ArenaRecognizedNode::MissingToken { extra })
11062 }
11063
11064 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
11065 let ArenaRuleSpec {
11066 rule_index,
11067 invoking_state,
11068 alt_number,
11069 start_index,
11070 stop_index,
11071 return_values,
11072 children,
11073 } = spec;
11074 let return_values = (!return_values.is_empty()).then(|| {
11075 self.recognition_arena
11076 .push_extra(RecognitionExtra::ReturnValues(return_values))
11077 });
11078 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
11079 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11080 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
11081 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11082 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
11083 stop_index: stop_index
11084 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
11085 return_values,
11086 children,
11087 })
11088 }
11089
11090 fn arena_boundary_node(&mut self, rule_index: usize, alt_number: usize) -> RecognizedNodeId {
11091 self.recognition_arena
11092 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
11093 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11094 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11095 })
11096 }
11097
11098 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
11099 *sequence = self.recognition_arena.prepend(*sequence, node);
11100 }
11101
11102 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
11103 self.last_recognition_arena_root = root;
11104 self.last_recognition_arena_diagnostics = diagnostics;
11105 #[cfg(feature = "perf-counters")]
11106 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
11107 let stats = self.recognition_arena_stats();
11108 #[allow(clippy::print_stderr)]
11109 {
11110 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
11111 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
11112 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
11113 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
11114 eprintln!("perf recognition_links_total={}", stats.total_links);
11115 eprintln!("perf recognition_links_live={}", stats.live_links);
11116 eprintln!("perf recognition_links_dead={}", stats.dead_links);
11117 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
11118 eprintln!("perf recognition_extras_total={}", stats.total_extras);
11119 eprintln!("perf recognition_extras_live={}", stats.live_extras);
11120 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
11121 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
11122 }
11123 }
11124 }
11125
11126 fn reset_recognition_arena(&mut self) {
11127 self.recognition_arena.reset();
11128 self.last_recognition_arena_root = NodeSeqId::EMPTY;
11129 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
11130 }
11131
11132 fn current_visible_index(&mut self) -> usize {
11135 let index = self.input.index();
11136 self.input.seek(index);
11137 self.input.index()
11138 }
11139
11140 fn child_expected_reaches_clean_eof(
11143 &mut self,
11144 children: &[RecognizeOutcome],
11145 expected: &ExpectedTokens,
11146 ) -> bool {
11147 let Some(index) = expected.index else {
11148 return false;
11149 };
11150 self.token_type_at(index) == TOKEN_EOF
11151 && children
11152 .iter()
11153 .any(|child| child.diagnostics.is_empty() && child.index == index)
11154 }
11155
11156 fn previous_token_index(&self, index: usize) -> Option<usize> {
11163 self.input.previous_visible_token_index(index)
11164 }
11165
11166 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
11171 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
11172 Some(index)
11173 } else {
11174 self.previous_token_index(index)
11175 }
11176 }
11177
11178 #[must_use]
11195 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
11196 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
11197 self.rule_stop_token_index(current_index, consumed_eof)
11198 }
11199
11200 #[must_use]
11209 pub fn after_action_stop_index_for_tree(
11210 &mut self,
11211 tree: ParseTree,
11212 current_index: usize,
11213 ) -> Option<usize> {
11214 if let Some(stop) = self
11215 .node(tree)
11216 .as_rule()
11217 .and_then(crate::tree::RuleNodeView::stop_id)
11218 {
11219 return Some(stop.index());
11220 }
11221 self.after_action_stop_index(current_index)
11222 }
11223
11224 #[must_use]
11234 pub fn after_action_start_index_for_tree(
11235 &self,
11236 tree: ParseTree,
11237 fallback_index: usize,
11238 ) -> usize {
11239 if let Some(start) = self
11240 .node(tree)
11241 .as_rule()
11242 .and_then(crate::tree::RuleNodeView::start_id)
11243 {
11244 return start.index();
11245 }
11246 fallback_index
11247 }
11248
11249 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
11254 self.rule_stop_token_index(index, consumed_eof)
11255 .and_then(|token_index| self.token_id_at(token_index))
11256 }
11257
11258 fn predicate_failure_recovery(
11265 &mut self,
11266 request: PredicateFailureRecovery<'_>,
11267 ) -> RecognizeOutcome {
11268 let PredicateFailureRecovery {
11269 rule_index,
11270 index,
11271 message,
11272 member_values,
11273 return_values,
11274 rule_alt_number,
11275 } = request;
11276 let rule_name = self
11277 .rule_names()
11278 .get(rule_index)
11279 .map_or_else(|| rule_index.to_string(), Clone::clone);
11280 let diagnostic = diagnostic_for_token(
11281 self.token_at(index).as_ref(),
11282 format!("rule {rule_name} {message}"),
11283 );
11284 let mut reversed_nodes = NodeSeqId::EMPTY;
11285 let mut next_index = index;
11286 loop {
11287 let symbol = self.token_type_at(next_index);
11288 if symbol == TOKEN_EOF {
11289 break;
11290 }
11291 let error = self.arena_token_node(next_index, true);
11292 self.arena_prepend(&mut reversed_nodes, error);
11293 let after = self.consume_index(next_index, symbol);
11294 if after == next_index {
11295 break;
11296 }
11297 next_index = after;
11298 }
11299 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
11300 let diagnostics = self
11301 .recognition_arena
11302 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
11303 RecognizeOutcome {
11304 index: next_index,
11305 consumed_eof: false,
11306 alt_number: rule_alt_number,
11307 member_values,
11308 return_values,
11309 diagnostics,
11310 decisions: Vec::new(),
11311 actions: Vec::new(),
11312 nodes,
11313 }
11314 }
11315
11316 fn parser_semantic_hook_result(
11319 &mut self,
11320 request: ParserSemanticHookRequest<'_>,
11321 ) -> Option<bool> {
11322 let ParserSemanticHookRequest {
11323 index,
11324 rule_index,
11325 pred_index,
11326 context,
11327 local_int_arg,
11328 member_values,
11329 } = request;
11330 let rule_name = self.rule_names().get(rule_index).cloned();
11331 self.input.seek(index);
11332 let input = &mut self.input;
11333 let semantic_hooks = &mut self.semantic_hooks;
11334 let mut ctx = ParserSemCtx {
11335 input,
11336 tree_storage: &self.tree,
11337 rule_index,
11338 coordinate_index: pred_index,
11339 rule_name,
11340 context,
11341 tree: None,
11342 local_int_arg,
11343 member_values,
11344 action: None,
11345 };
11346 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
11347 }
11348
11349 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
11354 if prior.is_empty() {
11355 return;
11356 }
11357 let mut merged = prior;
11358 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
11359 if !merged.contains(&coordinate) {
11360 merged.push(coordinate);
11361 }
11362 }
11363 self.unknown_predicate_hits = merged;
11364 }
11365
11366 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
11375 apply_unknown_predicate_policy(
11376 self.unknown_predicate_policy,
11377 rule_index,
11378 pred_index,
11379 &mut self.unknown_predicate_hits,
11380 )
11381 }
11382
11383 fn unknown_semantic_error(&self) -> Option<AntlrError> {
11386 use std::fmt::Write as _;
11387 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
11388 return None;
11389 }
11390 let mut message = String::new();
11391 for (rule_index, pred_index) in &self.unknown_predicate_hits {
11392 if !message.is_empty() {
11393 message.push_str("; ");
11394 }
11395 let _ = match self.rule_names().get(*rule_index) {
11396 Some(rule_name) => write!(
11397 message,
11398 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
11399 ),
11400 None => write!(
11401 message,
11402 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
11403 ),
11404 };
11405 }
11406 for (rule_index, source_state) in &self.unhandled_action_hits {
11407 if !message.is_empty() {
11408 message.push_str("; ");
11409 }
11410 let _ = match self.rule_names().get(*rule_index) {
11411 Some(rule_name) => write!(
11412 message,
11413 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
11414 ),
11415 None => write!(
11416 message,
11417 "unhandled semantic action: rule_index={rule_index} state={source_state}"
11418 ),
11419 };
11420 }
11421 Some(AntlrError::Unsupported(message))
11422 }
11423
11424 fn parser_semir_predicate_matches(
11432 &mut self,
11433 semantics: &ParserSemantics,
11434 predicate: &ParserSemanticPredicate,
11435 request: ParserSemanticHookRequest<'_>,
11436 ) -> bool {
11437 self.input.seek(request.index);
11438 let rule_name = self
11439 .data
11440 .rule_names()
11441 .get(request.rule_index)
11442 .map(String::as_str);
11443 let unknown_predicate_policy = self.unknown_predicate_policy;
11444 let mut ctx = ParserSemIrCtx {
11445 input: &mut self.input,
11446 tree_storage: &self.tree,
11447 semantic_hooks: &mut self.semantic_hooks,
11448 rule_index: request.rule_index,
11449 coordinate_index: request.pred_index,
11450 rule_name,
11451 context: request.context,
11452 local_int_arg: request.local_int_arg,
11453 member_values: request.member_values,
11454 invoked_predicates: &mut self.invoked_predicates,
11455 unknown_predicate_policy,
11456 unknown_predicate_hits: &mut self.unknown_predicate_hits,
11457 };
11458 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
11459 }
11460
11461 fn fast_parser_predicate_matches(
11462 &mut self,
11463 context: Option<FastPredicateContext<'_>>,
11464 transition: ParserTransition<'_>,
11465 index: usize,
11466 ) -> bool {
11467 let Some(context) = context else {
11468 return true;
11469 };
11470 let rule_index = transition.arg0() as usize;
11471 let pred_index = transition.arg1() as usize;
11472 let key = (index, rule_index, pred_index);
11473 if let Some(result) = self.fast_predicate_cache.get(&key) {
11474 return *result;
11475 }
11476 let result = self.parser_predicate_matches(PredicateEval {
11477 index,
11478 rule_index,
11479 pred_index,
11480 predicates: context.predicates,
11481 semantics: context.semantics,
11482 context: None,
11483 local_int_arg: None,
11484 member_values: context.member_values,
11485 });
11486 self.fast_predicate_cache.insert(key, result);
11487 result
11488 }
11489
11490 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
11491 let PredicateEval {
11492 index,
11493 rule_index,
11494 pred_index,
11495 predicates,
11496 semantics,
11497 context,
11498 local_int_arg,
11499 member_values,
11500 } = eval;
11501 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
11502 semantics
11503 .predicates
11504 .iter()
11505 .find(|predicate| {
11506 predicate.rule_index == rule_index && predicate.pred_index == pred_index
11507 })
11508 .map(|predicate| (semantics, predicate))
11509 }) {
11510 return self.parser_semir_predicate_matches(
11511 semantics,
11512 predicate,
11513 ParserSemanticHookRequest {
11514 index,
11515 rule_index,
11516 pred_index,
11517 context,
11518 local_int_arg,
11519 member_values,
11520 },
11521 );
11522 }
11523 let Some((_, _, predicate)) = predicates
11524 .iter()
11525 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
11526 else {
11527 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
11528 index,
11529 rule_index,
11530 pred_index,
11531 context,
11532 local_int_arg,
11533 member_values,
11534 }) {
11535 return result;
11536 }
11537 return self.unknown_predicate_result(rule_index, pred_index);
11538 };
11539 self.input.seek(index);
11540 match predicate {
11541 ParserPredicate::True => true,
11542 ParserPredicate::False => false,
11543 ParserPredicate::FalseWithMessage { .. } => false,
11544 ParserPredicate::Invoke { value } => {
11545 let key = (rule_index, pred_index);
11546 if !self.invoked_predicates.contains(&key) {
11547 self.invoked_predicates.push(key);
11548 use std::io::Write as _;
11549 let mut stdout = std::io::stdout().lock();
11550 let _ = writeln!(stdout, "eval={value}");
11551 }
11552 *value
11553 }
11554 ParserPredicate::LookaheadTextEquals { offset, text } => self
11555 .input
11556 .lt(*offset)
11557 .is_some_and(|token| Token::text(&token) == Some(*text)),
11558 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
11559 self.la(*offset) != *token_type
11560 }
11561 ParserPredicate::TokenPairAdjacent => {
11562 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
11563 return false;
11564 };
11565 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
11566 return false;
11567 };
11568 first + 1 == second
11569 }
11570 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
11571 .and_then(|context| {
11572 context
11573 .child_rules(&self.tree, self.input.token_store(), *rule_index)
11574 .next()
11575 .map(crate::tree::RuleNodeView::text)
11576 })
11577 .is_none_or(|actual| actual != *text),
11578 ParserPredicate::LocalIntEquals { value } => {
11579 local_int_arg.is_none_or(|(_, actual)| actual == *value)
11580 }
11581 ParserPredicate::LocalIntLessOrEqual { value } => {
11582 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
11583 }
11584 ParserPredicate::MemberModuloEquals {
11585 member,
11586 modulus,
11587 value,
11588 equals,
11589 } => {
11590 if *modulus == 0 {
11591 return false;
11592 }
11593 let actual = member_values.get(member).copied().unwrap_or_default() % *modulus;
11594 (actual == *value) == *equals
11595 }
11596 ParserPredicate::MemberEquals {
11597 member,
11598 value,
11599 equals,
11600 } => {
11601 let actual = member_values.get(member).copied().unwrap_or_default();
11602 (actual == *value) == *equals
11603 }
11604 }
11605 }
11606
11607 fn parser_predicate_failure_message(
11609 &self,
11610 rule_index: usize,
11611 pred_index: usize,
11612 predicates: &[(usize, usize, ParserPredicate)],
11613 ) -> Option<&'static str> {
11614 predicates
11615 .iter()
11616 .find_map(|(rule, pred, predicate)| match predicate {
11617 ParserPredicate::FalseWithMessage { message }
11618 if *rule == rule_index && *pred == pred_index =>
11619 {
11620 Some(*message)
11621 }
11622 _ => None,
11623 })
11624 }
11625
11626 pub fn parser_semantic_ir_predicate_failure_message(
11629 &self,
11630 rule_index: usize,
11631 pred_index: usize,
11632 semantics: &ParserSemantics,
11633 ) -> Option<&'static str> {
11634 semantics
11635 .predicates
11636 .iter()
11637 .find(|predicate| {
11638 predicate.rule_index == rule_index && predicate.pred_index == pred_index
11639 })
11640 .and_then(|predicate| predicate.failure_message)
11641 }
11642
11643 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
11652 if symbol == TOKEN_EOF {
11653 return index;
11654 }
11655 self.input.next_visible_after(index)
11656 }
11657
11658 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
11661 let text = display_input_text(&self.input.text(start_index, error_index));
11662 diagnostic_for_token(
11663 self.token_at(error_index).as_ref(),
11664 format!("no viable alternative at input '{text}'"),
11665 )
11666 }
11667
11668 fn recovery_failure_diagnostic(
11671 &self,
11672 index: usize,
11673 decision_start_index: Option<usize>,
11674 expected_symbols: &BTreeSet<i32>,
11675 ) -> ParserDiagnostic {
11676 if expected_symbols.len() > 1 {
11677 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
11678 return self.no_viable_alternative(decision_start, index);
11679 }
11680 }
11681 diagnostic_for_token(
11682 self.token_at(index).as_ref(),
11683 format!(
11684 "mismatched input {} expecting {}",
11685 self.token_at(index)
11686 .as_ref()
11687 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
11688 self.expected_symbols_display(expected_symbols)
11689 ),
11690 )
11691 }
11692
11693 fn eof_rule_recovery_diagnostic(
11696 &self,
11697 index: usize,
11698 expected_symbols: &BTreeSet<i32>,
11699 expected: &ExpectedTokens,
11700 ) -> ParserDiagnostic {
11701 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
11702 &expected.symbols
11703 } else {
11704 expected_symbols
11705 };
11706 diagnostic_for_token(
11707 self.token_at(index).as_ref(),
11708 format!(
11709 "mismatched input {} expecting {}",
11710 self.token_at(index)
11711 .as_ref()
11712 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
11713 self.expected_symbols_display(symbols)
11714 ),
11715 )
11716 }
11717
11718 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
11724 let Some(stop) = stop else {
11725 return String::new();
11726 };
11727 let stop = if self
11728 .token_at(stop)
11729 .is_some_and(|token| token.token_type() == TOKEN_EOF)
11730 {
11731 let Some(previous) = self.previous_token_index(stop) else {
11732 return String::new();
11733 };
11734 previous
11735 } else {
11736 stop
11737 };
11738 self.input.text(start, stop)
11739 }
11740
11741 fn clear_prediction_diagnostics(&mut self) {
11744 self.prediction_diagnostics.clear();
11745 self.reported_prediction_diagnostics.clear();
11746 }
11747
11748 fn reset_per_parse_caches(&mut self) {
11772 self.rule_first_set_cache.clear();
11773 self.decision_lookahead_cache.clear();
11774 self.ll1_decision_cache.clear();
11775 self.fast_predicate_cache.clear();
11776 self.rule_stop_reach_cache.clear();
11777 self.clean_memo_mode = CleanMemoMode::Probe;
11778 self.clean_memo_probe_seen.clear();
11779 self.clean_memo_probe_samples = 0;
11780 self.clean_memo_probe_repeats = 0;
11781 self.clean_memo_sparse_samples = 0;
11782 self.recovery_symbols_intern.clear();
11783 self.state_expected_cache.clear();
11784 self.state_expected_token_cache.clear();
11785 }
11786
11787 fn record_prediction_diagnostics(
11790 &mut self,
11791 atn: &Atn,
11792 state: AtnState<'_>,
11793 start_index: usize,
11794 outcomes: &[RecognizeOutcome],
11795 ) {
11796 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
11797 return;
11798 }
11799 let Some(decision) = atn
11800 .decision_to_state()
11801 .iter()
11802 .position(|state_number| state_number == state.state_number())
11803 else {
11804 return;
11805 };
11806 let Some(rule_index) = state.rule_index() else {
11807 return;
11808 };
11809 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
11810 for outcome in outcomes
11811 .iter()
11812 .filter(|outcome| outcome.diagnostics.is_empty())
11813 {
11814 let Some(alt) = outcome.decisions.first() else {
11815 continue;
11816 };
11817 alts_by_end
11818 .entry(outcome.index)
11819 .or_default()
11820 .insert(alt + 1);
11821 }
11822 let Some((&end_index, ambig_alts)) = alts_by_end
11823 .iter()
11824 .filter(|(_, alts)| alts.len() > 1)
11825 .max_by_key(|(end, _)| *end)
11826 else {
11827 return;
11828 };
11829 let rule_name = self
11830 .rule_names()
11831 .get(rule_index)
11832 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
11833 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
11834 let input = display_input_text(&self.input.text(start_index, stop_index));
11835 let alts = ambig_alts
11836 .iter()
11837 .map(usize::to_string)
11838 .collect::<Vec<_>>()
11839 .join(", ");
11840 let key = (decision, start_index, format!("{alts}:{input}"));
11841 if !self.reported_prediction_diagnostics.insert(key) {
11842 return;
11843 }
11844 let start_diagnostic = diagnostic_for_token(
11845 self.token_at(start_index),
11846 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
11847 );
11848 let stop_diagnostic = diagnostic_for_token(
11849 self.token_at(stop_index),
11850 format!(
11851 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
11852 ),
11853 );
11854 self.prediction_diagnostics.push(start_diagnostic);
11855 self.prediction_diagnostics.push(stop_diagnostic);
11856 }
11857
11858 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
11860 expected_symbols_display(
11861 &state_expected_symbols(atn, state_number),
11862 self.vocabulary(),
11863 )
11864 }
11865
11866 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
11871 let state = usize::try_from(self.data().state()).unwrap_or(0);
11872 ExpectedTokenSet {
11873 symbols: state_expected_symbols(atn, state),
11874 }
11875 }
11876
11877 pub const fn set_bail_on_error(&mut self, bail: bool) {
11880 self.bail_on_error = bail;
11881 }
11882
11883 #[must_use]
11885 pub const fn bail_on_error(&self) -> bool {
11886 self.bail_on_error
11887 }
11888
11889 pub fn rule_invocation_stack(&self) -> Vec<String> {
11892 self.rule_context_stack
11893 .iter()
11894 .rev()
11895 .map(|frame| {
11896 self.data()
11897 .rule_names()
11898 .get(frame.rule_index)
11899 .cloned()
11900 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
11901 })
11902 .collect()
11903 }
11904
11905 pub fn active_invocation_states(&self) -> Vec<isize> {
11909 self.rule_context_stack
11910 .iter()
11911 .skip(1)
11912 .rev()
11913 .map(|frame| frame.invoking_state)
11914 .collect()
11915 }
11916
11917 pub fn token_display_at(&self, index: usize) -> Option<String> {
11919 self.token_at(index).map(|token| format!("{token}"))
11920 }
11921}
11922
11923impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
11924where
11925 S: TokenSource,
11926 H: SemanticHooks,
11927{
11928 fn parse_rule(
11929 &mut self,
11930 rule_index: usize,
11931 invoking_state: isize,
11932 precedence: i32,
11933 ) -> DirectAdaptiveParseResult<ParseTree> {
11934 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
11935 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
11936 )?;
11937 let stop_state = self
11938 .atn
11939 .rule_to_stop_state()
11940 .get(rule_index)
11941 .filter(|state| *state != usize::MAX)
11942 .ok_or(DirectAdaptiveParseControl::Fallback(
11943 DirectAdaptiveFallback::MissingAtn,
11944 ))?;
11945 let start_index = self.parser.current_visible_index();
11946 let mut context = ParserRuleContext::new(rule_index, invoking_state);
11947 if let Some(token) = self.parser.token_id_at(start_index) {
11948 self.parser.set_context_start(&mut context, token);
11949 }
11950 let mut state_number = start_state;
11951 let mut consumed_eof = false;
11952 while state_number != stop_state {
11953 self.step()?;
11954 let (transition, boundary) = self.next_transition(state_number, precedence)?;
11955 if boundary.is_some() {
11956 return Err(DirectAdaptiveParseControl::Fallback(
11957 DirectAdaptiveFallback::LeftRecursiveBoundary,
11958 ));
11959 }
11960 match transition.data() {
11961 Transition::Epsilon { target } => {
11962 state_number = target;
11963 }
11964 Transition::Precedence {
11965 target,
11966 precedence: transition_precedence,
11967 } => {
11968 if transition_precedence < precedence {
11969 return Err(DirectAdaptiveParseControl::Fallback(
11970 DirectAdaptiveFallback::Precedence,
11971 ));
11972 }
11973 state_number = target;
11974 }
11975 Transition::Rule {
11976 rule_index,
11977 follow_state,
11978 precedence: rule_precedence,
11979 ..
11980 } => {
11981 let child = self.parse_rule(
11982 rule_index,
11983 invoking_state_number(state_number),
11984 rule_precedence,
11985 )?;
11986 if self.parser.build_parse_trees {
11987 self.parser.tree.add_child(&mut context, child);
11988 }
11989 state_number = follow_state;
11990 }
11991 Transition::Atom { .. }
11992 | Transition::Range { .. }
11993 | Transition::Set { .. }
11994 | Transition::NotSet { .. }
11995 | Transition::Wildcard { .. } => {
11996 let (matched_eof, child) = self.consume_transition(transition)?;
11997 consumed_eof |= matched_eof;
11998 if let Some(child) = child {
11999 self.parser.tree.add_child(&mut context, child);
12000 }
12001 state_number = transition.target();
12002 }
12003 Transition::Predicate { .. } => {
12004 return Err(DirectAdaptiveParseControl::Fallback(
12005 DirectAdaptiveFallback::Predicate,
12006 ));
12007 }
12008 Transition::Action { .. } => {
12009 return Err(DirectAdaptiveParseControl::Fallback(
12010 DirectAdaptiveFallback::Action,
12011 ));
12012 }
12013 }
12014 }
12015
12016 let stop_index = self
12017 .parser
12018 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
12019 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
12020 self.parser.set_context_stop(&mut context, token);
12021 }
12022 Ok(self.parser.rule_node(context))
12023 }
12024
12025 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
12026 self.steps += 1;
12027 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
12028 return Err(DirectAdaptiveParseControl::Fallback(
12029 DirectAdaptiveFallback::StepLimit,
12030 ));
12031 }
12032 Ok(())
12033 }
12034
12035 fn next_transition(
12036 &mut self,
12037 state_number: usize,
12038 precedence: i32,
12039 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
12040 let state = self
12041 .atn
12042 .state(state_number)
12043 .ok_or(DirectAdaptiveParseControl::Fallback(
12044 DirectAdaptiveFallback::MissingAtn,
12045 ))?;
12046 if state.is_rule_stop() {
12047 return Err(DirectAdaptiveParseControl::Fallback(
12048 DirectAdaptiveFallback::RuleStop,
12049 ));
12050 }
12051 let transition_index =
12052 self.transition_index(state_number, state.transitions().len(), precedence)?;
12053 let transition = state.transitions().get(transition_index).ok_or(
12054 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
12055 )?;
12056 let boundary = match &transition.data() {
12057 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
12058 left_recursive_boundary(self.atn, state, *target)
12059 }
12060 _ => None,
12061 };
12062 Ok((transition, boundary))
12063 }
12064
12065 fn transition_index(
12066 &mut self,
12067 state_number: usize,
12068 transition_count: usize,
12069 precedence: i32,
12070 ) -> DirectAdaptiveParseResult<usize> {
12071 match transition_count {
12072 0 => Err(DirectAdaptiveParseControl::Fallback(
12073 DirectAdaptiveFallback::NoTransition,
12074 )),
12075 1 => Ok(0),
12076 _ => {
12077 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
12078 return Ok(alt);
12079 }
12080 let decision = self
12081 .decision_by_state
12082 .get(state_number)
12083 .and_then(|decision| *decision)
12084 .ok_or(DirectAdaptiveParseControl::Fallback(
12085 DirectAdaptiveFallback::UnknownDecision,
12086 ))?;
12087 let prediction = self
12088 .simulator
12089 .adaptive_predict_stream_info_with_precedence(
12090 decision,
12091 direct_precedence(precedence),
12092 &mut self.parser.input,
12093 )
12094 .map_err(|_| {
12095 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
12096 })?;
12097 if prediction.has_semantic_context {
12098 return Err(DirectAdaptiveParseControl::Fallback(
12099 DirectAdaptiveFallback::SemanticContext,
12100 ));
12101 }
12102 prediction
12103 .alt
12104 .checked_sub(1)
12105 .filter(|index| *index < transition_count)
12106 .ok_or(DirectAdaptiveParseControl::Fallback(
12107 DirectAdaptiveFallback::InvalidAlt,
12108 ))
12109 }
12110 }
12111 }
12112
12113 fn ll1_transition_index(
12114 &mut self,
12115 state_number: usize,
12116 transition_count: usize,
12117 ) -> DirectAdaptiveParseResult<Option<usize>> {
12118 let state = self
12119 .atn
12120 .state(state_number)
12121 .ok_or(DirectAdaptiveParseControl::Fallback(
12122 DirectAdaptiveFallback::MissingAtn,
12123 ))?;
12124 if state.precedence_rule_decision() {
12125 return Ok(None);
12126 }
12127 let Some(rule_stop) = state
12128 .rule_index()
12129 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
12130 else {
12131 return Ok(None);
12132 };
12133 let symbol = self.parser.input.la_token(1);
12134 let entry = self
12135 .parser
12136 .cached_decision_lookahead(self.atn, state, rule_stop);
12137 Ok(
12138 ll1_greedy_alt(&entry, symbol, state.non_greedy())
12139 .filter(|alt| *alt < transition_count),
12140 )
12141 }
12142
12143 fn consume_transition(
12144 &mut self,
12145 transition: ParserTransition<'_>,
12146 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
12147 let symbol = self.parser.input.la_token(1);
12148 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
12149 return Err(DirectAdaptiveParseControl::Fallback(
12150 DirectAdaptiveFallback::TokenMismatch,
12151 ));
12152 }
12153 let token = self
12154 .parser
12155 .input
12156 .lt_id(1)
12157 .ok_or(DirectAdaptiveParseControl::Fallback(
12158 DirectAdaptiveFallback::TokenMismatch,
12159 ))?;
12160 let matched_eof = symbol == TOKEN_EOF;
12161 if !matched_eof {
12162 self.parser.consume();
12163 }
12164 let child = self
12165 .parser
12166 .build_parse_trees
12167 .then(|| self.parser.terminal_tree(token));
12168 Ok((matched_eof, child))
12169 }
12170}
12171
12172fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
12175 if !state.precedence_rule_decision() {
12176 return None;
12177 }
12178 let target_state = atn.state(target)?;
12179 if target_state.kind() == AtnStateKind::LoopEnd {
12180 return None;
12181 }
12182 state.rule_index()
12183}
12184
12185fn next_alt_number(
12192 state: AtnState<'_>,
12193 transition_count: usize,
12194 transition_index: usize,
12195 current_alt_number: usize,
12196 track_alt_numbers: bool,
12197) -> usize {
12198 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
12199 return current_alt_number;
12200 }
12201 if matches!(
12202 state.kind(),
12203 AtnStateKind::Basic
12204 | AtnStateKind::BlockStart
12205 | AtnStateKind::PlusBlockStart
12206 | AtnStateKind::StarBlockStart
12207 | AtnStateKind::StarLoopEntry
12208 ) && !state.precedence_rule_decision()
12209 {
12210 return transition_index + 1;
12211 }
12212 current_alt_number
12213}
12214
12215fn invoking_state_number(state_number: usize) -> isize {
12218 isize::try_from(state_number).unwrap_or(isize::MAX)
12219}
12220
12221const fn packed_i32(value: u32) -> i32 {
12222 i32::from_le_bytes(value.to_le_bytes())
12223}
12224
12225fn direct_precedence(precedence: i32) -> usize {
12226 usize::try_from(precedence.max(0)).unwrap_or_default()
12227}
12228
12229fn token_input_display(token: &impl Token) -> String {
12230 format!("'{}'", token.text().unwrap_or("<EOF>"))
12231}
12232
12233fn display_input_text(text: &str) -> String {
12234 let mut out = String::new();
12235 for ch in text.chars() {
12236 match ch {
12237 '\n' => out.push_str("\\n"),
12238 '\r' => out.push_str("\\r"),
12239 '\t' => out.push_str("\\t"),
12240 other => out.push(other),
12241 }
12242 }
12243 out
12244}
12245
12246fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
12247 let (line, column, offending) = token.map_or((0, 0, None), |token| {
12248 (token.line(), token.column(), Some(token.token_id()))
12249 });
12250 ParserDiagnostic {
12251 line,
12252 column,
12253 message,
12254 offending,
12255 }
12256}
12257
12258fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
12259 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
12260}
12261
12262fn expected_symbols_display_iter(
12263 symbols: impl IntoIterator<Item = i32>,
12264 vocabulary: &Vocabulary,
12265) -> String {
12266 let items = symbols
12267 .into_iter()
12268 .map(|symbol| expected_symbol_display(symbol, vocabulary))
12269 .collect::<Vec<_>>();
12270 if let [single] = items.as_slice() {
12271 return single.clone();
12272 }
12273 format!("{{{}}}", items.join(", "))
12274}
12275
12276fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
12277 if symbol == TOKEN_EOF {
12278 return "<EOF>".to_owned();
12279 }
12280 vocabulary.display_name(symbol)
12281}
12282
12283fn caller_follow_token_info_for_stream<S: TokenSource>(
12284 input: &mut CommonTokenStream<S>,
12285 index: usize,
12286) -> (i32, bool, bool) {
12287 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
12290 input.fill();
12291 }
12292 let token_type = input.token_type_at_index(index);
12293 let visible_channel = input.channel();
12294 let token = input.get(index);
12295 let is_boundary = token
12296 .as_ref()
12297 .and_then(Token::text)
12298 .is_some_and(is_caller_follow_boundary_text);
12299 let is_boundary_gap = token.as_ref().is_some_and(|token| {
12300 token.channel() != visible_channel
12301 || is_caller_follow_boundary_gap_text(token.text_or_empty())
12302 });
12303 (token_type, is_boundary, is_boundary_gap)
12304}
12305
12306fn is_caller_follow_boundary_text(text: &str) -> bool {
12307 text.chars().any(|ch| ch == ';' || ch == '\n')
12308 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
12309}
12310
12311fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
12312 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
12313}
12314
12315fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
12319 let Some(rule_index) = state.rule_index() else {
12320 return false;
12321 };
12322 atn.rule_to_start_state()
12323 .get(rule_index)
12324 .and_then(|state_number| atn.state(state_number))
12325 .is_some_and(AtnState::left_recursive_rule)
12326}
12327
12328fn select_better_top_outcome(
12335 first: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
12336 second: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
12337 arena: &RecognitionArena,
12338) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
12339 match (first, second) {
12340 (Ok(first), Ok(second)) => {
12341 if arena.diagnostics(first.0.diagnostics).next().is_none() {
12342 Ok(first)
12343 } else {
12344 Ok(second)
12345 }
12346 }
12347 (Ok(first), Err(_)) => Ok(first),
12348 (Err(_), Ok(second)) => Ok(second),
12349 (Err(_), Err(second_expected)) => Err(second_expected),
12350 }
12351}
12352
12353fn select_best_fast_outcome(
12359 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
12360 prediction_mode: PredictionMode,
12361 caller_follow: Option<&TokenBitSet>,
12362 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
12363 arena: &RecognitionArena,
12364) -> Option<FastRecognizeOutcome> {
12365 let mut best = None;
12366 let mut best_caller_follow = None;
12367 for outcome in outcomes {
12368 if matches!(
12369 prediction_mode,
12370 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
12371 ) && outcome.diagnostics.is_empty()
12372 && let Some(follow) = caller_follow
12373 {
12374 let (token_type, is_boundary, _) = token_info_at(outcome.index);
12375 if is_boundary && follow.contains(token_type) {
12376 let replace =
12377 best_caller_follow
12378 .as_ref()
12379 .is_none_or(|existing: &FastRecognizeOutcome| {
12380 (outcome.index, outcome.consumed_eof)
12381 < (existing.index, existing.consumed_eof)
12382 });
12383 if replace {
12384 best_caller_follow = Some(outcome);
12385 }
12386 }
12387 }
12388 let Some(existing) = best else {
12389 best = Some(outcome);
12390 continue;
12391 };
12392 let outcome_position = (outcome.index, outcome.consumed_eof);
12393 let best_position = (existing.index, existing.consumed_eof);
12394 let better = match prediction_mode {
12395 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
12396 outcome_position,
12397 outcome.diagnostics,
12398 best_position,
12399 existing.diagnostics,
12400 arena,
12401 ),
12402 PredictionMode::Sll => outcome.index > existing.index,
12403 };
12404 best = Some(if better { outcome } else { existing });
12405 }
12406 let should_use_caller_follow =
12407 best_caller_follow
12408 .as_ref()
12409 .zip(best.as_ref())
12410 .is_some_and(|(candidate, selected)| {
12411 if !selected.diagnostics.is_empty() {
12412 return true;
12413 }
12414 candidate.index < selected.index
12415 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
12416 });
12417 if should_use_caller_follow {
12418 best_caller_follow
12419 } else {
12420 best
12421 }
12422}
12423
12424fn select_best_outcome(
12425 outcomes: impl Iterator<Item = RecognizeOutcome>,
12426 prediction_mode: PredictionMode,
12427 arena: &RecognitionArena,
12428) -> Option<RecognizeOutcome> {
12429 let outcomes = outcomes.collect::<Vec<_>>();
12430 let prefer_first_tie = outcomes
12431 .iter()
12432 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
12433 outcomes.into_iter().reduce(|best, outcome| {
12434 let outcome_position = (outcome.index, outcome.consumed_eof);
12435 let best_position = (best.index, best.consumed_eof);
12436 let better = match prediction_mode {
12437 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
12438 outcome_is_better(
12439 outcome_position,
12440 outcome.diagnostics,
12441 best_position,
12442 best.diagnostics,
12443 arena,
12444 ) || (outcome_position == best_position
12445 && arena.diagnostics_len(outcome.diagnostics)
12446 == arena.diagnostics_len(best.diagnostics)
12447 && arena.diagnostics_recovery_rank(outcome.diagnostics)
12448 == arena.diagnostics_recovery_rank(best.diagnostics)
12449 && (outcome.decisions < best.decisions
12450 || (!prefer_first_tie
12451 && outcome.decisions == best.decisions
12452 && outcome.actions > best.actions)))
12453 }
12454 PredictionMode::Sll => {
12455 outcome_position > best_position
12456 || (outcome_position == best_position
12457 && !prefer_first_tie
12458 && (outcome.decisions < best.decisions
12459 || (outcome.decisions == best.decisions
12460 && outcome_is_better(
12461 outcome_position,
12462 outcome.diagnostics,
12463 best_position,
12464 best.diagnostics,
12465 arena,
12466 ))))
12467 }
12468 };
12469 if better {
12470 return outcome;
12471 }
12472 best
12473 })
12474}
12475
12476fn transition_decision(
12483 atn: &Atn,
12484 state: AtnState<'_>,
12485 transition_count: usize,
12486 transition_index: usize,
12487 predicates: &[(usize, usize, ParserPredicate)],
12488) -> Option<usize> {
12489 if transition_count <= 1 || decision_reaches_unsupported_predicate(atn, state, predicates) {
12490 return None;
12491 }
12492 Some(transition_index)
12493}
12494
12495fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
12501 transition_count > 1
12502 && !matches!(
12503 state.kind(),
12504 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
12505 )
12506}
12507
12508fn record_no_viable_if_ambiguous(
12511 expected: &mut ExpectedTokens,
12512 decision_start_index: Option<usize>,
12513 index: usize,
12514) {
12515 if expected.index == Some(index) && expected.symbols.len() > 1 {
12516 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
12517 expected.record_no_viable(decision_start, index);
12518 }
12519 }
12520}
12521
12522const fn record_predicate_no_viable(
12525 expected: &mut ExpectedTokens,
12526 decision_start_index: Option<usize>,
12527 index: usize,
12528) {
12529 if let Some(decision_start) = decision_start_index {
12530 expected.record_no_viable(decision_start, index);
12531 }
12532}
12533
12534const fn no_viable_decision_start(
12536 decision_start_index: Option<usize>,
12537 index: usize,
12538) -> Option<usize> {
12539 match decision_start_index {
12540 Some(start) if index > start => Some(start),
12541 _ => None,
12542 }
12543}
12544
12545fn restore_expected(
12549 children: &[RecognizeOutcome],
12550 child_start_index: usize,
12551 expected: &mut ExpectedTokens,
12552 snapshot: ExpectedTokens,
12553 preserve_child_expected: bool,
12554) {
12555 if preserve_child_expected {
12556 return;
12557 }
12558 if children
12559 .iter()
12560 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
12561 {
12562 *expected = snapshot;
12563 }
12564}
12565
12566fn decision_reaches_unsupported_predicate(
12569 atn: &Atn,
12570 state: AtnState<'_>,
12571 predicates: &[(usize, usize, ParserPredicate)],
12572) -> bool {
12573 state.transitions().iter().any(|transition| {
12574 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
12575 })
12576}
12577
12578fn transition_reaches_unsupported_predicate(
12580 atn: &Atn,
12581 transition: ParserTransition<'_>,
12582 predicates: &[(usize, usize, ParserPredicate)],
12583 visited: &mut BTreeSet<usize>,
12584) -> bool {
12585 match &transition.data() {
12586 Transition::Predicate {
12587 rule_index,
12588 pred_index,
12589 ..
12590 } => !predicates
12591 .iter()
12592 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
12593 Transition::Epsilon { target }
12594 | Transition::Action { target, .. }
12595 | Transition::Rule { target, .. } => {
12596 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
12597 }
12598 Transition::Precedence { .. }
12599 | Transition::Atom { .. }
12600 | Transition::Range { .. }
12601 | Transition::Set { .. }
12602 | Transition::NotSet { .. }
12603 | Transition::Wildcard { .. } => false,
12604 }
12605}
12606
12607fn state_reaches_unsupported_predicate(
12609 atn: &Atn,
12610 state_number: usize,
12611 predicates: &[(usize, usize, ParserPredicate)],
12612 visited: &mut BTreeSet<usize>,
12613) -> bool {
12614 if !visited.insert(state_number) {
12615 return false;
12616 }
12617 let Some(state) = atn.state(state_number) else {
12618 return false;
12619 };
12620 state.transitions().iter().any(|transition| {
12621 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
12622 })
12623}
12624
12625fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
12627 if let Some(decision) = decision {
12628 outcome.decisions.insert(0, decision);
12629 }
12630}
12631
12632fn outcome_is_better(
12633 outcome_position: (usize, bool),
12634 outcome_diagnostics: DiagnosticSeqId,
12635 best_position: (usize, bool),
12636 best_diagnostics: DiagnosticSeqId,
12637 arena: &RecognitionArena,
12638) -> bool {
12639 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
12640 let best_len = arena.diagnostics_len(best_diagnostics);
12641 outcome_position > best_position
12642 || (outcome_position == best_position
12643 && (outcome_len < best_len
12644 || (outcome_len == best_len
12645 && arena.diagnostics_recovery_rank(outcome_diagnostics)
12646 < arena.diagnostics_recovery_rank(best_diagnostics))))
12647}
12648
12649fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
12650 if outcomes
12651 .iter()
12652 .any(|outcome| outcome.diagnostics.is_empty())
12653 {
12654 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
12655 }
12656}
12657
12658fn discard_recovered_outcomes_if_clean_path_exists(
12659 outcomes: &mut Vec<RecognizeOutcome>,
12660 arena: &RecognitionArena,
12661) {
12662 if outcomes
12663 .iter()
12664 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
12665 {
12666 return;
12667 }
12668 if outcomes
12669 .iter()
12670 .any(|outcome| outcome.diagnostics.is_empty())
12671 {
12672 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
12673 }
12674}
12675
12676fn outcome_has_rule_failure_diagnostic(
12679 outcome: &RecognizeOutcome,
12680 arena: &RecognitionArena,
12681) -> bool {
12682 arena
12683 .diagnostics(outcome.diagnostics)
12684 .any(|diagnostic| diagnostic.message.starts_with("rule "))
12685}
12686
12687fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
12701 if outcomes.len() < 2 {
12702 return;
12703 }
12704 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
12705 outcomes.retain(|outcome| {
12706 seen.insert((
12707 outcome.index,
12708 outcome.consumed_eof,
12709 arena.diagnostics_len(outcome.diagnostics),
12710 arena.diagnostics_recovery_rank(outcome.diagnostics),
12711 ))
12712 });
12713}
12714
12715const FAST_OUTCOME_INLINE_KEYS: usize = 8;
12716const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
12717const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
12718const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
12719
12720#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12721enum FastOutcomeDedupStrategy {
12722 Inline,
12723 Dense,
12724 Sparse,
12725}
12726
12727impl FastOutcomeDedupScratch {
12728 fn prepare_dense(&mut self, word_count: usize) {
12729 while let Some(word_index) = self.touched_dense_words.pop() {
12730 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
12731 }
12732 if self.dense_words.len() < word_count {
12733 self.dense_words.resize(word_count, 0);
12734 }
12735 }
12736}
12737
12738fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
12739 let first_index = outcomes.first()?.index;
12740 let (min_index, max_index) = outcomes[1..].iter().fold(
12741 (first_index, first_index),
12742 |(min_index, max_index), outcome| {
12743 (min_index.min(outcome.index), max_index.max(outcome.index))
12744 },
12745 );
12746 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
12747 let bit_count = index_span.checked_mul(2)?;
12748 let word_count =
12749 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
12750 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
12751 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
12752 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
12753 .then_some((min_index, word_count))
12754}
12755
12756#[cfg(feature = "perf-counters")]
12757fn record_clean_fast_outcome_dedup(
12758 strategy: FastOutcomeDedupStrategy,
12759 input_len: usize,
12760 output_len: usize,
12761 dense_words: usize,
12762) {
12763 let counter = match strategy {
12764 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
12765 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
12766 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
12767 };
12768 perf_counters::inc(
12769 &perf_counters::OUTCOME_DEDUPE_INPUTS,
12770 u64::try_from(input_len).unwrap_or(u64::MAX),
12771 );
12772 perf_counters::inc(
12773 &perf_counters::OUTCOME_DEDUPE_REMOVED,
12774 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
12775 );
12776 perf_counters::inc(counter, 1);
12777 perf_counters::inc(
12778 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
12779 u64::try_from(dense_words).unwrap_or(u64::MAX),
12780 );
12781}
12782
12783fn dedupe_clean_fast_outcomes(
12787 outcomes: &mut Vec<FastRecognizeOutcome>,
12788 scratch: &mut FastOutcomeDedupScratch,
12789) -> FastOutcomeDedupStrategy {
12790 #[cfg(feature = "perf-counters")]
12791 let input_len = outcomes.len();
12792 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
12793 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
12794 let mut inline_len = 0_usize;
12795 outcomes.retain(|outcome| {
12796 let key = (outcome.index, outcome.consumed_eof);
12797 if inline_keys[..inline_len].contains(&key) {
12798 return false;
12799 }
12800 inline_keys[inline_len] = key;
12801 inline_len += 1;
12802 true
12803 });
12804 #[cfg(feature = "perf-counters")]
12805 record_clean_fast_outcome_dedup(
12806 FastOutcomeDedupStrategy::Inline,
12807 input_len,
12808 outcomes.len(),
12809 0,
12810 );
12811 return FastOutcomeDedupStrategy::Inline;
12812 }
12813
12814 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
12815 scratch.prepare_dense(word_count);
12816 outcomes.retain(|outcome| {
12817 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
12818 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
12819 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
12820 let word = &mut scratch.dense_words[word_index];
12821 if *word & bit != 0 {
12822 return false;
12823 }
12824 if *word == 0 {
12825 scratch
12826 .touched_dense_words
12827 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
12828 }
12829 *word |= bit;
12830 true
12831 });
12832 #[cfg(feature = "perf-counters")]
12833 record_clean_fast_outcome_dedup(
12834 FastOutcomeDedupStrategy::Dense,
12835 input_len,
12836 outcomes.len(),
12837 word_count,
12838 );
12839 return FastOutcomeDedupStrategy::Dense;
12840 }
12841
12842 scratch.sparse_keys.clear();
12843 scratch.sparse_keys.reserve(outcomes.len());
12844 outcomes.retain(|outcome| {
12845 scratch
12846 .sparse_keys
12847 .insert((outcome.index, outcome.consumed_eof))
12848 });
12849 #[cfg(feature = "perf-counters")]
12850 record_clean_fast_outcome_dedup(
12851 FastOutcomeDedupStrategy::Sparse,
12852 input_len,
12853 outcomes.len(),
12854 0,
12855 );
12856 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
12857 scratch.sparse_keys = FxHashSet::default();
12858 }
12859 FastOutcomeDedupStrategy::Sparse
12860}
12861
12862fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
12865 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
12866 outcomes
12867 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
12868}
12869
12870fn compare_recognize_outcomes(
12871 left: &RecognizeOutcome,
12872 right: &RecognizeOutcome,
12873 arena: &RecognitionArena,
12874) -> Ordering {
12875 left.index
12876 .cmp(&right.index)
12877 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
12878 .then_with(|| left.alt_number.cmp(&right.alt_number))
12879 .then_with(|| left.member_values.cmp(&right.member_values))
12880 .then_with(|| left.return_values.cmp(&right.return_values))
12881 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
12882 .then_with(|| left.decisions.cmp(&right.decisions))
12883 .then_with(|| left.actions.cmp(&right.actions))
12884 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
12885}
12886
12887impl<S, H> Recognizer for BaseParser<S, H>
12888where
12889 S: TokenSource,
12890 H: SemanticHooks,
12891{
12892 fn data(&self) -> &RecognizerData {
12893 &self.data
12894 }
12895
12896 fn data_mut(&mut self) -> &mut RecognizerData {
12897 &mut self.data
12898 }
12899}
12900
12901impl<S, H> Parser for BaseParser<S, H>
12902where
12903 S: TokenSource,
12904 H: SemanticHooks,
12905{
12906 fn build_parse_trees(&self) -> bool {
12907 self.build_parse_trees
12908 }
12909
12910 fn set_build_parse_trees(&mut self, build: bool) {
12911 self.build_parse_trees = build;
12912 }
12913
12914 fn number_of_syntax_errors(&self) -> usize {
12915 Self::number_of_syntax_errors(self)
12916 }
12917
12918 fn report_diagnostic_errors(&self) -> bool {
12919 self.report_diagnostic_errors
12920 }
12921
12922 fn set_report_diagnostic_errors(&mut self, report: bool) {
12923 self.report_diagnostic_errors = report;
12924 }
12925
12926 fn prediction_mode(&self) -> PredictionMode {
12927 self.prediction_mode
12928 }
12929
12930 fn set_prediction_mode(&mut self, mode: PredictionMode) {
12931 self.prediction_mode = mode;
12932 }
12933
12934 fn max_rule_depth(&self) -> Option<usize> {
12935 self.max_rule_depth
12936 }
12937
12938 fn set_max_rule_depth(&mut self, depth: Option<usize>) {
12939 self.max_rule_depth = depth;
12940 }
12941
12942 fn add_parse_listener(&mut self, listener: Box<dyn ParseListener>) {
12943 self.parse_listeners.push(ParseListenerSlot(listener));
12944 }
12945
12946 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
12947 Self::remove_parse_listeners(self)
12948 }
12949}
12950
12951#[cfg(test)]
12952#[allow(clippy::disallowed_methods)] mod tests {
12954 use super::*;
12955 use crate::atn::parser::{
12956 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
12957 };
12958 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
12959 use crate::token::{
12960 HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError, TokenView,
12961 };
12962 use crate::token_stream::CommonTokenStream;
12963 use crate::tree::{NodeKind, ParseTreeStats};
12964 use crate::vocabulary::Vocabulary;
12965 use std::cell::RefCell;
12966 use std::mem::size_of;
12967 use std::rc::Rc;
12968 use std::sync::{Arc, Mutex};
12969
12970 #[test]
12971 fn fx_hasher_write_matches_typed_methods_for_full_words() {
12972 let value: u64 = 0x0102_0304_0506_0708;
12979 let mut typed = FxHasher::default();
12980 typed.write_u64(value);
12981 let mut bytewise = FxHasher::default();
12982 bytewise.write(&value.to_le_bytes());
12983 assert_eq!(typed.finish(), bytewise.finish());
12984 }
12985
12986 #[derive(Clone, Debug)]
12987 struct TestToken {
12988 spec: TokenSpec,
12989 id: TokenId,
12990 source_name: String,
12991 }
12992
12993 impl TestToken {
12994 fn new(token_type: i32) -> Self {
12995 Self {
12996 spec: TokenSpec::explicit(token_type, ""),
12997 id: TokenId::try_from(0).expect("zero token ID"),
12998 source_name: String::new(),
12999 }
13000 }
13001
13002 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
13003 Self {
13004 spec: TokenSpec::eof(index, index, line, column),
13005 id: TokenId::try_from(0).expect("zero token ID"),
13006 source_name: source_name.to_owned(),
13007 }
13008 }
13009
13010 fn with_text(mut self, text: impl Into<String>) -> Self {
13011 self.spec.text = Some(text.into());
13012 self
13013 }
13014
13015 const fn with_channel(mut self, channel: i32) -> Self {
13016 self.spec.channel = channel;
13017 self
13018 }
13019
13020 const fn with_span(mut self, start: usize, stop: usize) -> Self {
13021 self.spec.start = start;
13022 self.spec.stop = stop;
13023 self.spec.start_byte = start;
13024 self.spec.stop_byte = match stop.checked_add(1) {
13025 Some(end) if end >= start => end,
13026 Some(_) | None => start,
13027 };
13028 self
13029 }
13030
13031 const fn with_position(mut self, line: usize, column: usize) -> Self {
13032 self.spec.line = line;
13033 self.spec.column = column;
13034 self
13035 }
13036
13037 fn set_token_index(&mut self, index: isize) {
13038 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
13039 }
13040 }
13041
13042 impl Token for TestToken {
13043 fn token_id(&self) -> TokenId {
13044 self.id
13045 }
13046
13047 fn token_type(&self) -> i32 {
13048 self.spec.token_type
13049 }
13050
13051 fn channel(&self) -> i32 {
13052 self.spec.channel
13053 }
13054
13055 fn start(&self) -> usize {
13056 self.spec.start
13057 }
13058
13059 fn stop(&self) -> usize {
13060 self.spec.stop
13061 }
13062
13063 fn line(&self) -> usize {
13064 self.spec.line
13065 }
13066
13067 fn column(&self) -> usize {
13068 self.spec.column
13069 }
13070
13071 fn text(&self) -> Option<&str> {
13072 self.spec.text.as_deref()
13073 }
13074
13075 fn source_name(&self) -> &str {
13076 &self.source_name
13077 }
13078
13079 fn start_byte(&self) -> usize {
13080 self.spec.start_byte
13081 }
13082
13083 fn stop_byte(&self) -> usize {
13084 self.spec.stop_byte
13085 }
13086 }
13087
13088 #[derive(Debug)]
13089 struct Source {
13090 tokens: Vec<TestToken>,
13091 index: usize,
13092 }
13093
13094 impl TokenSource for Source {
13095 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
13096 let token = self
13097 .tokens
13098 .get(self.index)
13099 .cloned()
13100 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
13101 self.index += 1;
13102 sink.push(token.spec)
13103 }
13104
13105 fn line(&self) -> usize {
13106 1
13107 }
13108
13109 fn column(&self) -> usize {
13110 self.index
13111 }
13112
13113 fn source_name(&self) -> &'static str {
13114 "parser-test"
13115 }
13116 }
13117
13118 #[derive(Clone, Debug, Eq, PartialEq)]
13119 struct RecordedDiagnostic {
13120 grammar_file_name: String,
13121 offending_text: Option<String>,
13122 line: usize,
13123 column: usize,
13124 message: String,
13125 error: Option<AntlrError>,
13126 }
13127
13128 #[derive(Clone, Debug)]
13129 struct RecordingErrorListener {
13130 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
13131 }
13132
13133 impl<R> crate::ErrorListener<R> for RecordingErrorListener
13134 where
13135 R: Recognizer + ?Sized,
13136 {
13137 fn syntax_error(
13138 &mut self,
13139 recognizer: &R,
13140 offending: Option<TokenView<'_>>,
13141 line: usize,
13142 column: usize,
13143 message: &str,
13144 error: Option<&AntlrError>,
13145 ) {
13146 self.diagnostics
13147 .lock()
13148 .expect("recorded diagnostics lock")
13149 .push(RecordedDiagnostic {
13150 grammar_file_name: recognizer.grammar_file_name().to_owned(),
13151 offending_text: offending.and_then(|token| token.text().map(str::to_owned)),
13152 line,
13153 column,
13154 message: message.to_owned(),
13155 error: error.cloned(),
13156 });
13157 }
13158 }
13159
13160 #[derive(Debug)]
13161 struct ReportingSource {
13162 source: Source,
13163 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
13164 }
13165
13166 impl TokenSource for ReportingSource {
13167 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
13168 self.source.next_token(sink)
13169 }
13170
13171 fn line(&self) -> usize {
13172 self.source.line()
13173 }
13174
13175 fn column(&self) -> usize {
13176 self.source.column()
13177 }
13178
13179 fn source_name(&self) -> &str {
13180 self.source.source_name()
13181 }
13182
13183 fn report_error(&self, error: &TokenSourceError) -> bool {
13184 self.diagnostics.borrow_mut().push(error.clone());
13185 true
13186 }
13187 }
13188
13189 fn mini_parser_data() -> RecognizerData {
13190 RecognizerData::new(
13191 "Mini.g4",
13192 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
13193 )
13194 .with_rule_names(["s"])
13195 }
13196
13197 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
13198 let data = mini_parser_data();
13199 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
13200 }
13201
13202 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
13203 where
13204 H: SemanticHooks,
13205 {
13206 BaseParser::with_semantic_hooks(
13207 CommonTokenStream::new(Source { tokens, index: 0 }),
13208 mini_parser_data(),
13209 hooks,
13210 )
13211 }
13212
13213 #[test]
13214 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
13215 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
13216 parser.remove_error_listeners();
13217 let diagnostics = Arc::new(Mutex::new(Vec::new()));
13218 parser.add_error_listener(RecordingErrorListener {
13219 diagnostics: Arc::clone(&diagnostics),
13220 });
13221 let parser_diagnostics = [ParserDiagnostic {
13222 line: 1,
13223 column: 2,
13224 message: "missing 'x' at 'y'".to_owned(),
13225 offending: None,
13226 }];
13227 let token_errors = [
13228 TokenSourceError::new(1, 1, "token recognition error at: '@'"),
13229 TokenSourceError::new(1, 3, "token recognition error at: '#'"),
13230 ];
13231
13232 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
13233
13234 insta::assert_debug_snapshot!(
13237 "parser_dispatches_recovery_diagnostics_through_registered_listeners",
13238 *diagnostics.lock().expect("recorded diagnostics lock")
13239 );
13240
13241 parser.remove_error_listeners();
13242 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
13243 assert_eq!(
13244 diagnostics.lock().expect("recorded diagnostics lock").len(),
13245 3
13246 );
13247 }
13248
13249 #[test]
13250 fn recovery_diagnostics_expose_the_offending_token_to_listeners() {
13251 let mut parser = mini_parser(vec![
13252 TestToken::new(7)
13253 .with_text("oops")
13254 .with_span(0, 3)
13255 .with_position(1, 2),
13256 TestToken::eof("parser-test", 4, 1, 6),
13257 ]);
13258 parser.remove_error_listeners();
13259 let diagnostics = Arc::new(Mutex::new(Vec::new()));
13260 parser.add_error_listener(RecordingErrorListener {
13261 diagnostics: Arc::clone(&diagnostics),
13262 });
13263 let offending = parser.input.lt_id(1);
13264 assert!(offending.is_some(), "current token should be buffered");
13265 let parser_diagnostics = [ParserDiagnostic {
13266 line: 1,
13267 column: 2,
13268 message: "extraneous input 'oops'".to_owned(),
13269 offending,
13270 }];
13271
13272 parser.dispatch_generated_diagnostics(&parser_diagnostics, &[]);
13273
13274 let recorded = diagnostics
13278 .lock()
13279 .expect("recorded diagnostics lock")
13280 .clone();
13281 insta::assert_debug_snapshot!(
13282 "recovery_diagnostics_expose_the_offending_token_to_listeners",
13283 recorded
13284 );
13285 }
13286
13287 #[test]
13288 fn parser_leaves_token_errors_to_source_owned_listeners() {
13289 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
13290 let source = ReportingSource {
13291 source: Source {
13292 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
13293 index: 0,
13294 },
13295 diagnostics: Rc::clone(&source_diagnostics),
13296 };
13297 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
13298 parser.remove_error_listeners();
13299 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
13300 parser.add_error_listener(RecordingErrorListener {
13301 diagnostics: Arc::clone(&parser_diagnostics),
13302 });
13303 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
13304
13305 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
13306
13307 assert_eq!(*source_diagnostics.borrow(), [source_error]);
13308 assert!(
13309 parser_diagnostics
13310 .lock()
13311 .expect("recorded diagnostics lock")
13312 .is_empty()
13313 );
13314 }
13315
13316 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
13317 builder.finish().expect("valid packed parser ATN")
13318 }
13319
13320 fn nested_rule_chain_atn(depth: usize) -> Atn {
13321 nested_rule_graph_atn(depth, false, false)
13322 }
13323
13324 fn nested_rule_graph_atn(depth: usize, branching: bool, consuming_follows: bool) -> Atn {
13325 assert!(depth > 0);
13326 let mut atn = ParserAtnBuilder::new(2);
13327 let mut starts = Vec::with_capacity(depth);
13328 let mut stops = Vec::with_capacity(depth);
13329 let mut follows = Vec::with_capacity(depth.saturating_sub(1));
13330 for rule_index in 0..depth {
13331 starts.push(
13332 atn.add_state(AtnStateKind::RuleStart, Some(rule_index))
13333 .expect("rule start")
13334 .index(),
13335 );
13336 }
13337 for rule_index in 0..depth {
13338 stops.push(
13339 atn.add_state(AtnStateKind::RuleStop, Some(rule_index))
13340 .expect("rule stop")
13341 .index(),
13342 );
13343 }
13344 if consuming_follows {
13345 for rule_index in 0..depth - 1 {
13346 follows.push(
13347 atn.add_state(AtnStateKind::Basic, Some(rule_index))
13348 .expect("rule follow")
13349 .index(),
13350 );
13351 }
13352 }
13353 atn.set_rule_to_start_state(starts.clone())
13354 .expect("rule start states");
13355 atn.set_rule_to_stop_state(stops.clone())
13356 .expect("rule stop states");
13357 for rule_index in 0..depth - 1 {
13358 let follow_state = if consuming_follows {
13359 follows[rule_index]
13360 } else {
13361 stops[rule_index]
13362 };
13363 atn.add_transition(
13364 starts[rule_index],
13365 ParserTransitionSpec::Rule {
13366 target: starts[rule_index + 1],
13367 rule_index: rule_index + 1,
13368 follow_state,
13369 precedence: 0,
13370 },
13371 )
13372 .expect("nested rule transition");
13373 if branching {
13374 atn.add_transition(
13375 starts[rule_index],
13376 ParserTransitionSpec::Atom {
13377 target: stops[rule_index],
13378 label: 2,
13379 },
13380 )
13381 .expect("dead branch transition");
13382 }
13383 if consuming_follows {
13384 atn.add_transition(
13385 follow_state,
13386 ParserTransitionSpec::Atom {
13387 target: stops[rule_index],
13388 label: 1,
13389 },
13390 )
13391 .expect("consuming follow transition");
13392 }
13393 }
13394 let token_set = atn.add_interval_set([(1, 1)]).expect("token set");
13395 atn.add_transition(
13396 starts[depth - 1],
13397 ParserTransitionSpec::Set {
13398 target: stops[depth - 1],
13399 set: token_set,
13400 },
13401 )
13402 .expect("terminal set transition");
13403 if branching {
13404 atn.add_transition(
13405 starts[depth - 1],
13406 ParserTransitionSpec::Atom {
13407 target: stops[depth - 1],
13408 label: 2,
13409 },
13410 )
13411 .expect("dead leaf branch transition");
13412 }
13413 finish_atn(atn)
13414 }
13415
13416 fn ordinary_star_loop_atn() -> Atn {
13417 let mut atn = ParserAtnBuilder::new(2);
13418 for (state_number, kind, rule_index) in [
13419 (0, AtnStateKind::RuleStart, 0),
13420 (1, AtnStateKind::StarLoopEntry, 0),
13421 (2, AtnStateKind::Basic, 0),
13422 (3, AtnStateKind::StarLoopBack, 0),
13423 (4, AtnStateKind::LoopEnd, 0),
13424 (5, AtnStateKind::Basic, 0),
13425 (6, AtnStateKind::RuleStop, 0),
13426 (7, AtnStateKind::RuleStart, 1),
13427 (8, AtnStateKind::Basic, 1),
13428 (9, AtnStateKind::RuleStop, 1),
13429 ] {
13430 assert_eq!(
13431 atn.add_state(kind, Some(rule_index))
13432 .expect("state")
13433 .index(),
13434 state_number
13435 );
13436 }
13437 atn.set_rule_to_start_state(vec![0, 7])
13438 .expect("rule start states");
13439 atn.set_rule_to_stop_state(vec![6, 9])
13440 .expect("rule stop states");
13441 atn.add_decision_state(1).expect("decision state");
13442 atn.set_loop_back_state(4, 3).expect("loop back state");
13443 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13444 .expect("transition");
13445 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13446 .expect("transition");
13447 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
13448 .expect("transition");
13449 atn.add_transition(
13450 2,
13451 ParserTransitionSpec::Rule {
13452 target: 7,
13453 rule_index: 1,
13454 follow_state: 3,
13455 precedence: 0,
13456 },
13457 )
13458 .expect("transition");
13459 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
13460 .expect("transition");
13461 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13462 .expect("transition");
13463 atn.add_transition(
13464 5,
13465 ParserTransitionSpec::Atom {
13466 target: 6,
13467 label: TOKEN_EOF,
13468 },
13469 )
13470 .expect("transition");
13471 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
13472 .expect("transition");
13473 atn.add_transition(
13474 8,
13475 ParserTransitionSpec::Atom {
13476 target: 9,
13477 label: 1,
13478 },
13479 )
13480 .expect("transition");
13481 finish_atn(atn)
13482 }
13483
13484 fn ambiguous_ordinary_star_loop_atn() -> Atn {
13486 let mut atn = ParserAtnBuilder::new(1);
13487 for (state_number, kind) in [
13488 (0, AtnStateKind::RuleStart),
13489 (1, AtnStateKind::StarLoopEntry),
13490 (2, AtnStateKind::StarBlockStart),
13491 (3, AtnStateKind::Basic),
13492 (4, AtnStateKind::BlockEnd),
13493 (5, AtnStateKind::StarLoopBack),
13494 (6, AtnStateKind::LoopEnd),
13495 (7, AtnStateKind::Basic),
13496 (8, AtnStateKind::RuleStop),
13497 ] {
13498 assert_eq!(
13499 atn.add_state(kind, Some(0)).expect("state").index(),
13500 state_number
13501 );
13502 }
13503 atn.set_rule_to_start_state(vec![0])
13504 .expect("rule start states");
13505 atn.set_rule_to_stop_state(vec![8])
13506 .expect("rule stop states");
13507 atn.set_end_state(2, 4).expect("block end state");
13508 atn.set_loop_back_state(6, 5).expect("loop back state");
13509 atn.add_decision_state(1).expect("decision state");
13510 atn.add_decision_state(2).expect("decision state");
13511 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13512 .expect("transition");
13513 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13514 .expect("transition");
13515 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
13516 .expect("transition");
13517 atn.add_transition(
13518 2,
13519 ParserTransitionSpec::Atom {
13520 target: 4,
13521 label: 1,
13522 },
13523 )
13524 .expect("transition");
13525 atn.add_transition(
13526 2,
13527 ParserTransitionSpec::Atom {
13528 target: 3,
13529 label: 1,
13530 },
13531 )
13532 .expect("transition");
13533 atn.add_transition(
13534 3,
13535 ParserTransitionSpec::Atom {
13536 target: 4,
13537 label: 1,
13538 },
13539 )
13540 .expect("transition");
13541 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13542 .expect("transition");
13543 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
13544 .expect("transition");
13545 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13546 .expect("transition");
13547 atn.add_transition(
13548 7,
13549 ParserTransitionSpec::Atom {
13550 target: 8,
13551 label: TOKEN_EOF,
13552 },
13553 )
13554 .expect("transition");
13555 finish_atn(atn)
13556 }
13557
13558 fn ordinary_plus_loop_atn() -> Atn {
13559 let mut atn = ParserAtnBuilder::new(2);
13560 for (state_number, kind, rule_index) in [
13561 (0, AtnStateKind::RuleStart, 0),
13562 (1, AtnStateKind::Basic, 0),
13563 (2, AtnStateKind::PlusLoopBack, 0),
13564 (3, AtnStateKind::LoopEnd, 0),
13565 (4, AtnStateKind::Basic, 0),
13566 (5, AtnStateKind::RuleStop, 0),
13567 (6, AtnStateKind::RuleStart, 1),
13568 (7, AtnStateKind::Basic, 1),
13569 (8, AtnStateKind::RuleStop, 1),
13570 ] {
13571 assert_eq!(
13572 atn.add_state(kind, Some(rule_index))
13573 .expect("state")
13574 .index(),
13575 state_number
13576 );
13577 }
13578 atn.set_rule_to_start_state(vec![0, 6])
13579 .expect("rule start states");
13580 atn.set_rule_to_stop_state(vec![5, 8])
13581 .expect("rule stop states");
13582 atn.add_decision_state(2).expect("decision state");
13583 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13584 .expect("transition");
13585 atn.add_transition(
13586 1,
13587 ParserTransitionSpec::Rule {
13588 target: 6,
13589 rule_index: 1,
13590 follow_state: 2,
13591 precedence: 0,
13592 },
13593 )
13594 .expect("transition");
13595 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
13596 .expect("transition");
13597 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13598 .expect("transition");
13599 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
13600 .expect("transition");
13601 atn.add_transition(
13602 4,
13603 ParserTransitionSpec::Atom {
13604 target: 5,
13605 label: TOKEN_EOF,
13606 },
13607 )
13608 .expect("transition");
13609 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13610 .expect("transition");
13611 atn.add_transition(
13612 7,
13613 ParserTransitionSpec::Atom {
13614 target: 8,
13615 label: 1,
13616 },
13617 )
13618 .expect("transition");
13619 finish_atn(atn)
13620 }
13621
13622 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
13623 let mut tokens = (0..count)
13624 .map(|_| TestToken::new(1).with_text("x"))
13625 .collect::<Vec<_>>();
13626 tokens.push(TestToken::eof("parser-test", count, 1, count));
13627 tokens
13628 }
13629
13630 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
13631 let mut atn = ParserAtnBuilder::new(2);
13632 assert_eq!(
13633 atn.add_state(AtnStateKind::RuleStart, Some(0))
13634 .expect("state")
13635 .index(),
13636 0
13637 );
13638 assert_eq!(
13639 atn.add_state(AtnStateKind::Basic, Some(0))
13640 .expect("state")
13641 .index(),
13642 1
13643 );
13644 assert_eq!(
13645 atn.add_state(AtnStateKind::Basic, Some(0))
13646 .expect("state")
13647 .index(),
13648 2
13649 );
13650 assert_eq!(
13651 atn.add_state(AtnStateKind::RuleStart, Some(1))
13652 .expect("state")
13653 .index(),
13654 3
13655 );
13656 atn.set_left_recursive_rule(3)
13657 .expect("left-recursive rule start");
13658 assert_eq!(
13659 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
13660 .expect("state")
13661 .index(),
13662 4
13663 );
13664 atn.set_precedence_rule_decision(4)
13665 .expect("precedence decision");
13666 assert_eq!(
13667 atn.add_state(AtnStateKind::Basic, Some(1))
13668 .expect("state")
13669 .index(),
13670 5
13671 );
13672 assert_eq!(
13673 atn.add_state(AtnStateKind::Basic, Some(1))
13674 .expect("state")
13675 .index(),
13676 6
13677 );
13678 assert_eq!(
13679 atn.add_state(AtnStateKind::LoopEnd, Some(1))
13680 .expect("state")
13681 .index(),
13682 7
13683 );
13684 assert_eq!(
13685 atn.add_state(AtnStateKind::RuleStop, Some(1))
13686 .expect("state")
13687 .index(),
13688 8
13689 );
13690 assert_eq!(
13691 atn.add_state(AtnStateKind::RuleStop, Some(0))
13692 .expect("state")
13693 .index(),
13694 9
13695 );
13696 atn.set_rule_to_start_state(vec![0, 3])
13697 .expect("rule start states");
13698 atn.set_rule_to_stop_state(vec![9, 8])
13699 .expect("rule stop states");
13700 atn.add_transition(
13701 1,
13702 ParserTransitionSpec::Rule {
13703 target: 3,
13704 rule_index: 1,
13705 follow_state: 2,
13706 precedence: 0,
13707 },
13708 )
13709 .expect("transition");
13710 atn.add_transition(
13711 2,
13712 ParserTransitionSpec::Atom {
13713 target: 9,
13714 label: caller_symbol,
13715 },
13716 )
13717 .expect("transition");
13718 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13719 .expect("transition");
13720 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
13721 .expect("transition");
13722 atn.add_transition(
13723 5,
13724 ParserTransitionSpec::Precedence {
13725 target: 6,
13726 precedence: 1,
13727 },
13728 )
13729 .expect("transition");
13730 atn.add_transition(
13731 6,
13732 ParserTransitionSpec::Atom {
13733 target: 4,
13734 label: 1,
13735 },
13736 )
13737 .expect("transition");
13738 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
13739 .expect("transition");
13740 finish_atn(atn)
13741 }
13742
13743 fn labeled_left_recursive_operator_atn() -> Atn {
13744 let mut atn = ParserAtnBuilder::new(4);
13745 for (state, kind) in [
13746 (0, AtnStateKind::RuleStart),
13747 (1, AtnStateKind::BlockStart),
13748 (2, AtnStateKind::StarLoopEntry),
13749 (3, AtnStateKind::StarBlockStart),
13750 (4, AtnStateKind::Basic),
13751 (5, AtnStateKind::Basic),
13752 (6, AtnStateKind::Basic),
13753 (7, AtnStateKind::StarLoopBack),
13754 (8, AtnStateKind::LoopEnd),
13755 (9, AtnStateKind::RuleStop),
13756 ] {
13757 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13758 }
13759 atn.set_left_recursive_rule(0)
13760 .expect("left-recursive rule start");
13761 atn.set_precedence_rule_decision(2)
13762 .expect("precedence decision");
13763 atn.set_loop_back_state(8, 7).expect("loop-back state");
13764 atn.set_rule_to_start_state(vec![0])
13765 .expect("rule start states");
13766 atn.set_rule_to_stop_state(vec![9])
13767 .expect("rule stop states");
13768 for state in [1, 2, 3] {
13769 atn.add_decision_state(state).expect("decision state");
13770 }
13771 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
13772 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
13773 .expect("epsilon transition");
13774 }
13775 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3), (6, 7, 1)] {
13776 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
13777 .expect("token transition");
13778 }
13779 for (target, precedence) in [(4, 2), (5, 1)] {
13780 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
13781 .expect("operator precedence");
13782 }
13783 finish_atn(atn)
13784 }
13785
13786 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
13787 let mut parser = mini_parser(vec![
13788 TestToken::new(symbol).with_text("lookahead"),
13789 TestToken::eof("parser-test", 1, 1, 1),
13790 ]);
13791 parser.rule_context_stack = vec![
13792 RuleContextFrame {
13793 rule_index: 0,
13794 invoking_state: -1,
13795 },
13796 RuleContextFrame {
13797 rule_index: 1,
13798 invoking_state: 1,
13799 },
13800 ];
13801 parser
13802 }
13803
13804 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
13805 let mut atn = ParserAtnBuilder::new(1);
13809 for (state, kind, rule) in [
13810 (0, AtnStateKind::RuleStart, 0),
13811 (1, AtnStateKind::StarLoopEntry, 0),
13812 (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),
13819 (9, AtnStateKind::RuleStop, 0),
13820 ] {
13821 assert_eq!(
13822 atn.add_state(kind, Some(rule)).expect("state").index(),
13823 state
13824 );
13825 if state == 0 {
13826 atn.set_left_recursive_rule(state)
13827 .expect("left-recursive rule start");
13828 } else if state == 1 {
13829 atn.set_precedence_rule_decision(state)
13830 .expect("precedence decision");
13831 }
13832 }
13833 atn.set_rule_to_start_state(vec![0])
13834 .expect("rule start states");
13835 atn.set_rule_to_stop_state(vec![9])
13836 .expect("rule stop states");
13837 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13838 .expect("ops");
13839 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
13840 .expect("exit");
13841 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13842 .expect("to shift");
13843 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13844 .expect("to rel");
13845 atn.add_transition(
13846 3,
13847 ParserTransitionSpec::Precedence {
13848 target: 4,
13849 precedence: 2,
13850 },
13851 )
13852 .expect("shift prec");
13853 atn.add_transition(
13854 4,
13855 ParserTransitionSpec::Atom {
13856 target: 5,
13857 label: 1,
13858 },
13859 )
13860 .expect("shift first >");
13861 atn.add_transition(
13862 5,
13863 ParserTransitionSpec::Atom {
13864 target: 1,
13865 label: 1,
13866 },
13867 )
13868 .expect("shift second >");
13869 atn.add_transition(
13870 6,
13871 ParserTransitionSpec::Precedence {
13872 target: 7,
13873 precedence: 1,
13874 },
13875 )
13876 .expect("rel prec");
13877 atn.add_transition(
13878 7,
13879 ParserTransitionSpec::Atom {
13880 target: 1,
13881 label: 1,
13882 },
13883 )
13884 .expect("rel >");
13885 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
13886 .expect("loop end");
13887 finish_atn(atn)
13888 }
13889
13890 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
13891 let mut atn = ParserAtnBuilder::new(2);
13892 for (state, kind, rule) in [
13893 (0, AtnStateKind::RuleStart, 0),
13894 (1, AtnStateKind::StarLoopEntry, 0),
13895 (2, AtnStateKind::Basic, 0),
13896 (3, AtnStateKind::Basic, 0),
13897 (4, AtnStateKind::Basic, 0),
13898 (5, AtnStateKind::Basic, 0),
13899 (6, AtnStateKind::Basic, 0),
13900 (7, AtnStateKind::Basic, 0),
13901 (8, AtnStateKind::LoopEnd, 0),
13902 (9, AtnStateKind::RuleStop, 0),
13903 (10, AtnStateKind::RuleStart, 1),
13904 (11, AtnStateKind::Basic, 1),
13905 (12, AtnStateKind::RuleStop, 1),
13906 ] {
13907 assert_eq!(
13908 atn.add_state(kind, Some(rule)).expect("state").index(),
13909 state
13910 );
13911 if state == 0 {
13912 atn.set_left_recursive_rule(state)
13913 .expect("left-recursive rule start");
13914 } else if state == 1 {
13915 atn.set_precedence_rule_decision(state)
13916 .expect("precedence decision");
13917 }
13918 }
13919 atn.set_rule_to_start_state(vec![0, 10])
13920 .expect("rule start states");
13921 atn.set_rule_to_stop_state(vec![9, 12])
13922 .expect("rule stop states");
13923 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13924 .expect("ops");
13925 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
13926 .expect("exit");
13927 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13928 .expect("to shift");
13929 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13930 .expect("to relational");
13931 atn.add_transition(
13932 3,
13933 ParserTransitionSpec::Precedence {
13934 target: 4,
13935 precedence: 2,
13936 },
13937 )
13938 .expect("shift precedence");
13939 atn.add_transition(
13940 4,
13941 ParserTransitionSpec::Rule {
13942 target: 10,
13943 rule_index: 1,
13944 follow_state: 5,
13945 precedence: 0,
13946 },
13947 )
13948 .expect("first shift token helper");
13949 atn.add_transition(
13950 5,
13951 ParserTransitionSpec::Atom {
13952 target: 1,
13953 label: 1,
13954 },
13955 )
13956 .expect("second shift token");
13957 atn.add_transition(
13958 6,
13959 ParserTransitionSpec::Precedence {
13960 target: 7,
13961 precedence: 1,
13962 },
13963 )
13964 .expect("relational precedence");
13965 atn.add_transition(
13966 7,
13967 ParserTransitionSpec::Atom {
13968 target: 1,
13969 label: 1,
13970 },
13971 )
13972 .expect("relational token");
13973 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
13974 .expect("loop end");
13975 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
13976 .expect("helper entry");
13977 atn.add_transition(
13978 11,
13979 ParserTransitionSpec::Atom {
13980 target: 12,
13981 label: 1,
13982 },
13983 )
13984 .expect("first shift token");
13985 finish_atn(atn)
13986 }
13987
13988 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
13989 let mut atn = ParserAtnBuilder::new(1);
13990 for (state, kind) in [
13991 (0, AtnStateKind::RuleStart),
13992 (1, AtnStateKind::StarLoopEntry),
13993 (2, AtnStateKind::Basic),
13994 (3, AtnStateKind::Basic),
13995 (4, AtnStateKind::Basic),
13996 (5, AtnStateKind::Basic),
13997 (6, AtnStateKind::Basic),
13998 (7, AtnStateKind::Basic),
13999 (8, AtnStateKind::Basic),
14000 (9, AtnStateKind::LoopEnd),
14001 (10, AtnStateKind::RuleStop),
14002 ] {
14003 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
14004 if state == 0 {
14005 atn.set_left_recursive_rule(state)
14006 .expect("left-recursive rule start");
14007 } else if state == 1 {
14008 atn.set_precedence_rule_decision(state)
14009 .expect("precedence decision");
14010 }
14011 }
14012 atn.set_rule_to_start_state(vec![0])
14013 .expect("rule start states");
14014 atn.set_rule_to_stop_state(vec![10])
14015 .expect("rule stop states");
14016 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14017 .expect("ops");
14018 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
14019 .expect("exit");
14020 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
14021 .expect("to multi-token operator");
14022 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
14023 .expect("to predicate operator");
14024 atn.add_transition(
14025 3,
14026 ParserTransitionSpec::Precedence {
14027 target: 4,
14028 precedence: 2,
14029 },
14030 )
14031 .expect("multi-token precedence");
14032 atn.add_transition(
14033 4,
14034 ParserTransitionSpec::Atom {
14035 target: 5,
14036 label: 1,
14037 },
14038 )
14039 .expect("multi-token first");
14040 atn.add_transition(
14041 5,
14042 ParserTransitionSpec::Atom {
14043 target: 1,
14044 label: 1,
14045 },
14046 )
14047 .expect("multi-token second");
14048 atn.add_transition(
14049 6,
14050 ParserTransitionSpec::Precedence {
14051 target: 7,
14052 precedence: 2,
14053 },
14054 )
14055 .expect("predicate precedence");
14056 atn.add_transition(
14057 7,
14058 ParserTransitionSpec::Predicate {
14059 target: 8,
14060 rule_index: 0,
14061 pred_index: 0,
14062 context_dependent: false,
14063 },
14064 )
14065 .expect("operator predicate");
14066 atn.add_transition(
14067 8,
14068 ParserTransitionSpec::Atom {
14069 target: 1,
14070 label: 1,
14071 },
14072 )
14073 .expect("predicate single token");
14074 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
14075 .expect("loop end");
14076 finish_atn(atn)
14077 }
14078
14079 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
14080 let mut atn = ParserAtnBuilder::new(2);
14081 for (state, kind, rule) in [
14082 (0, AtnStateKind::RuleStart, 0),
14083 (1, AtnStateKind::StarLoopEntry, 0),
14084 (2, AtnStateKind::Basic, 0),
14085 (3, AtnStateKind::Basic, 0),
14086 (4, AtnStateKind::Basic, 0),
14087 (5, AtnStateKind::LoopEnd, 0),
14088 (6, AtnStateKind::RuleStop, 0),
14089 (7, AtnStateKind::RuleStart, 1),
14090 (8, AtnStateKind::RuleStop, 1),
14091 (9, AtnStateKind::Basic, 1),
14092 ] {
14093 assert_eq!(
14094 atn.add_state(kind, Some(rule)).expect("state").index(),
14095 state
14096 );
14097 if state == 0 {
14098 atn.set_left_recursive_rule(state)
14099 .expect("left-recursive rule start");
14100 } else if state == 1 {
14101 atn.set_precedence_rule_decision(state)
14102 .expect("precedence decision");
14103 }
14104 }
14105 atn.set_rule_to_start_state(vec![0, 7])
14106 .expect("rule start states");
14107 atn.set_rule_to_stop_state(vec![6, 8])
14108 .expect("rule stop states");
14109 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14110 .expect("transition");
14111 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
14112 .expect("transition");
14113 atn.add_transition(
14114 2,
14115 ParserTransitionSpec::Precedence {
14116 target: 3,
14117 precedence: 3,
14118 },
14119 )
14120 .expect("transition");
14121 atn.add_transition(
14122 3,
14123 ParserTransitionSpec::Rule {
14124 target: 7,
14125 rule_index: 1,
14126 follow_state: 4,
14127 precedence: 0,
14128 },
14129 )
14130 .expect("transition");
14131 atn.add_transition(
14132 4,
14133 ParserTransitionSpec::Atom {
14134 target: 1,
14135 label: 1,
14136 },
14137 )
14138 .expect("transition");
14139 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
14140 .expect("transition");
14141 atn.add_transition(
14142 7,
14143 ParserTransitionSpec::Precedence {
14144 target: 9,
14145 precedence: 1,
14146 },
14147 )
14148 .expect("transition");
14149 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
14150 .expect("transition");
14151 finish_atn(atn)
14152 }
14153
14154 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
14155 let mut atn = ParserAtnBuilder::new(2);
14156 for (state, kind) in [
14157 (0, AtnStateKind::RuleStart),
14158 (1, AtnStateKind::StarLoopEntry),
14159 (2, AtnStateKind::Basic),
14160 (3, AtnStateKind::Basic),
14161 (4, AtnStateKind::Basic),
14162 (5, AtnStateKind::LoopEnd),
14163 (6, AtnStateKind::RuleStop),
14164 ] {
14165 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
14166 if state == 0 {
14167 atn.set_left_recursive_rule(state)
14168 .expect("left-recursive rule start");
14169 } else if state == 1 {
14170 atn.set_precedence_rule_decision(state)
14171 .expect("precedence decision");
14172 }
14173 }
14174 atn.set_rule_to_start_state(vec![0])
14175 .expect("rule start states");
14176 atn.set_rule_to_stop_state(vec![6])
14177 .expect("rule stop states");
14178 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14179 .expect("transition");
14180 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
14181 .expect("transition");
14182 atn.add_transition(
14183 2,
14184 ParserTransitionSpec::Precedence {
14185 target: 3,
14186 precedence: 1,
14187 },
14188 )
14189 .expect("transition");
14190 atn.add_transition(
14191 3,
14192 ParserTransitionSpec::Predicate {
14193 target: 4,
14194 rule_index: 0,
14195 pred_index: 0,
14196 context_dependent: false,
14197 },
14198 )
14199 .expect("transition");
14200 atn.add_transition(
14201 4,
14202 ParserTransitionSpec::Atom {
14203 target: 1,
14204 label: 1,
14205 },
14206 )
14207 .expect("transition");
14208 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
14209 .expect("transition");
14210 finish_atn(atn)
14211 }
14212
14213 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
14214 let mut atn = ParserAtnBuilder::new(2);
14215 for (state, kind, rule) in [
14216 (0, AtnStateKind::RuleStart, 0),
14217 (1, AtnStateKind::Basic, 0),
14218 (2, AtnStateKind::Basic, 0),
14219 (3, AtnStateKind::Basic, 0),
14220 (4, AtnStateKind::RuleStop, 0),
14221 (5, AtnStateKind::RuleStart, 1),
14222 (6, AtnStateKind::StarLoopEntry, 1),
14223 (7, AtnStateKind::Basic, 1),
14224 (8, AtnStateKind::Basic, 1),
14225 (9, AtnStateKind::LoopEnd, 1),
14226 (10, AtnStateKind::RuleStop, 1),
14227 (11, AtnStateKind::RuleStart, 2),
14228 (12, AtnStateKind::RuleStop, 2),
14229 ] {
14230 assert_eq!(
14231 atn.add_state(kind, Some(rule)).expect("state").index(),
14232 state
14233 );
14234 if state == 5 {
14235 atn.set_left_recursive_rule(state)
14236 .expect("left-recursive rule start");
14237 } else if state == 6 {
14238 atn.set_precedence_rule_decision(state)
14239 .expect("precedence decision");
14240 }
14241 }
14242 atn.set_rule_to_start_state(vec![0, 5, 11])
14243 .expect("rule start states");
14244 atn.set_rule_to_stop_state(vec![4, 10, 12])
14245 .expect("rule stop states");
14246 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14247 .expect("transition");
14248 atn.add_transition(
14249 1,
14250 ParserTransitionSpec::Rule {
14251 target: 5,
14252 rule_index: 1,
14253 follow_state: 2,
14254 precedence: 0,
14255 },
14256 )
14257 .expect("transition");
14258 atn.add_transition(
14259 2,
14260 ParserTransitionSpec::Rule {
14261 target: 11,
14262 rule_index: 2,
14263 follow_state: 3,
14264 precedence: 0,
14265 },
14266 )
14267 .expect("transition");
14268 atn.add_transition(
14269 3,
14270 ParserTransitionSpec::Atom {
14271 target: 4,
14272 label: caller_symbol,
14273 },
14274 )
14275 .expect("transition");
14276 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
14277 .expect("transition");
14278 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
14279 .expect("transition");
14280 atn.add_transition(
14281 7,
14282 ParserTransitionSpec::Precedence {
14283 target: 8,
14284 precedence: 1,
14285 },
14286 )
14287 .expect("transition");
14288 atn.add_transition(
14289 8,
14290 ParserTransitionSpec::Atom {
14291 target: 6,
14292 label: 1,
14293 },
14294 )
14295 .expect("transition");
14296 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
14297 .expect("transition");
14298 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
14299 .expect("transition");
14300 finish_atn(atn)
14301 }
14302
14303 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
14304 let mut atn = ParserAtnBuilder::new(2);
14305 for (state, kind, rule) in [
14306 (0, AtnStateKind::RuleStart, 0),
14307 (1, AtnStateKind::Basic, 0),
14308 (2, AtnStateKind::Basic, 0),
14309 (3, AtnStateKind::RuleStop, 0),
14310 (4, AtnStateKind::RuleStart, 1),
14311 (5, AtnStateKind::Basic, 1),
14312 (6, AtnStateKind::Basic, 1),
14313 (7, AtnStateKind::RuleStop, 1),
14314 (8, AtnStateKind::RuleStart, 2),
14315 (9, AtnStateKind::StarLoopEntry, 2),
14316 (10, AtnStateKind::Basic, 2),
14317 (11, AtnStateKind::Basic, 2),
14318 (12, AtnStateKind::LoopEnd, 2),
14319 (13, AtnStateKind::RuleStop, 2),
14320 ] {
14321 assert_eq!(
14322 atn.add_state(kind, Some(rule)).expect("state").index(),
14323 state
14324 );
14325 if state == 8 {
14326 atn.set_left_recursive_rule(state)
14327 .expect("left-recursive rule start");
14328 } else if state == 9 {
14329 atn.set_precedence_rule_decision(state)
14330 .expect("precedence decision");
14331 }
14332 }
14333 atn.set_rule_to_start_state(vec![0, 4, 8])
14334 .expect("rule start states");
14335 atn.set_rule_to_stop_state(vec![3, 7, 13])
14336 .expect("rule stop states");
14337 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14338 .expect("transition");
14339 atn.add_transition(
14340 1,
14341 ParserTransitionSpec::Rule {
14342 target: 4,
14343 rule_index: 1,
14344 follow_state: 2,
14345 precedence: 0,
14346 },
14347 )
14348 .expect("transition");
14349 atn.add_transition(
14350 2,
14351 ParserTransitionSpec::Atom {
14352 target: 3,
14353 label: caller_symbol,
14354 },
14355 )
14356 .expect("transition");
14357 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14358 .expect("transition");
14359 atn.add_transition(
14360 5,
14361 ParserTransitionSpec::Rule {
14362 target: 8,
14363 rule_index: 2,
14364 follow_state: 6,
14365 precedence: 0,
14366 },
14367 )
14368 .expect("transition");
14369 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
14370 .expect("transition");
14371 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
14372 .expect("transition");
14373 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
14374 .expect("transition");
14375 atn.add_transition(
14376 10,
14377 ParserTransitionSpec::Precedence {
14378 target: 11,
14379 precedence: 1,
14380 },
14381 )
14382 .expect("transition");
14383 atn.add_transition(
14384 11,
14385 ParserTransitionSpec::Atom {
14386 target: 9,
14387 label: 1,
14388 },
14389 )
14390 .expect("transition");
14391 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
14392 .expect("transition");
14393 finish_atn(atn)
14394 }
14395
14396 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
14397 let mut atn = ParserAtnBuilder::new(2);
14398 for (state, kind, rule) in [
14399 (0, AtnStateKind::RuleStart, 0),
14400 (1, AtnStateKind::Basic, 0),
14401 (2, AtnStateKind::Basic, 0),
14402 (3, AtnStateKind::RuleStop, 0),
14403 (4, AtnStateKind::RuleStart, 1),
14404 (5, AtnStateKind::StarLoopEntry, 1),
14405 (6, AtnStateKind::Basic, 1),
14406 (7, AtnStateKind::Basic, 1),
14407 (8, AtnStateKind::Basic, 1),
14408 (9, AtnStateKind::Basic, 1),
14409 (10, AtnStateKind::LoopEnd, 1),
14410 (11, AtnStateKind::RuleStop, 1),
14411 ] {
14412 assert_eq!(
14413 atn.add_state(kind, Some(rule)).expect("state").index(),
14414 state
14415 );
14416 if state == 4 {
14417 atn.set_left_recursive_rule(state)
14418 .expect("left-recursive rule start");
14419 } else if state == 5 {
14420 atn.set_precedence_rule_decision(state)
14421 .expect("precedence decision");
14422 }
14423 }
14424 atn.set_rule_to_start_state(vec![0, 4])
14425 .expect("rule start states");
14426 atn.set_rule_to_stop_state(vec![3, 11])
14427 .expect("rule stop states");
14428 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14429 .expect("transition");
14430 atn.add_transition(
14431 1,
14432 ParserTransitionSpec::Rule {
14433 target: 4,
14434 rule_index: 1,
14435 follow_state: 2,
14436 precedence: 0,
14437 },
14438 )
14439 .expect("transition");
14440 atn.add_transition(
14441 2,
14442 ParserTransitionSpec::Atom {
14443 target: 3,
14444 label: caller_symbol,
14445 },
14446 )
14447 .expect("transition");
14448 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
14449 .expect("transition");
14450 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
14451 .expect("transition");
14452 atn.add_transition(
14453 6,
14454 ParserTransitionSpec::Precedence {
14455 target: 7,
14456 precedence: 1,
14457 },
14458 )
14459 .expect("transition");
14460 atn.add_transition(
14461 7,
14462 ParserTransitionSpec::Atom {
14463 target: 8,
14464 label: 1,
14465 },
14466 )
14467 .expect("transition");
14468 atn.add_transition(
14469 8,
14470 ParserTransitionSpec::Rule {
14471 target: 4,
14472 rule_index: 1,
14473 follow_state: 9,
14474 precedence: 2,
14475 },
14476 )
14477 .expect("transition");
14478 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
14479 .expect("transition");
14480 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
14481 .expect("transition");
14482 finish_atn(atn)
14483 }
14484
14485 #[test]
14486 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
14487 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
14488 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
14489
14490 let mut overlapping = parser_inside_left_recursive_callee(1);
14491 assert_eq!(
14492 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
14493 None
14494 );
14495
14496 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
14497 assert_eq!(
14498 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
14499 Some(true)
14500 );
14501
14502 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
14503 assert_eq!(
14504 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
14505 Some(false)
14506 );
14507
14508 assert_eq!(
14509 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
14510 Some(true),
14511 "overlap results must not leak across ATNs"
14512 );
14513 }
14514
14515 #[test]
14516 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
14517 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
14518 let mut parser = mini_parser(vec![
14519 TestToken::new(1).with_text("operator"),
14520 TestToken::eof("parser-test", 1, 1, 1),
14521 ]);
14522 parser.rule_context_stack = vec![RuleContextFrame {
14523 rule_index: 0,
14524 invoking_state: -1,
14525 }];
14526
14527 assert_eq!(
14528 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14529 Some(true)
14530 );
14531 assert_eq!(
14532 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14533 Some(true),
14534 "cached operator lookahead must preserve the nullable prefix return path"
14535 );
14536 assert_eq!(
14537 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14538 Some(true),
14539 "the nullable child must use its rule-call precedence, not the caller precedence"
14540 );
14541 }
14542
14543 #[test]
14544 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
14545 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
14550 let mut parser = mini_parser(vec![
14551 TestToken::new(1).with_text(">"),
14552 TestToken::new(2).with_text("id"),
14553 TestToken::eof("parser-test", 1, 1, 1),
14554 ]);
14555 parser.rule_context_stack = vec![RuleContextFrame {
14556 rule_index: 0,
14557 invoking_state: -1,
14558 }];
14559
14560 assert_eq!(
14561 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14562 Some(true),
14563 "at low precedence relational `>` is a single-token operator"
14564 );
14565 assert_eq!(
14566 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
14567 Some(true),
14568 "relational remains single-token at its own precedence"
14569 );
14570 assert_eq!(
14571 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14572 None,
14573 "at shift precedence, bare `>` must not force enter"
14574 );
14575 }
14576
14577 #[test]
14578 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
14579 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
14580 let mut parser = mini_parser(vec![
14581 TestToken::new(1).with_text(">"),
14582 TestToken::new(2).with_text("id"),
14583 TestToken::eof("parser-test", 1, 1, 1),
14584 ]);
14585 parser.rule_context_stack = vec![RuleContextFrame {
14586 rule_index: 0,
14587 invoking_state: -1,
14588 }];
14589
14590 assert_eq!(
14591 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14592 Some(true),
14593 "the direct relational alternative remains a one-token operator"
14594 );
14595 assert_eq!(
14596 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14597 None,
14598 "a token matched in the helper rule must return to the second shift token"
14599 );
14600 }
14601
14602 #[test]
14603 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
14604 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
14605 let mut parser = mini_parser(vec![
14606 TestToken::new(1).with_text(">"),
14607 TestToken::new(2).with_text("id"),
14608 TestToken::eof("parser-test", 1, 1, 1),
14609 ]);
14610 parser.rule_context_stack = vec![RuleContextFrame {
14611 rule_index: 0,
14612 invoking_state: -1,
14613 }];
14614
14615 assert_eq!(
14616 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14617 None,
14618 "a predicate-gated single-token path must not be hidden by a multi-token path"
14619 );
14620 }
14621
14622 #[test]
14623 fn left_recursive_loop_defers_predicate_guarded_operator() {
14624 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
14625 let mut parser = mini_parser_with_hooks(
14626 vec![
14627 TestToken::new(1).with_text("operator"),
14628 TestToken::eof("parser-test", 1, 1, 1),
14629 ],
14630 RejectingPredicateHooks::default(),
14631 );
14632 parser.rule_context_stack = vec![RuleContextFrame {
14633 rule_index: 0,
14634 invoking_state: -1,
14635 }];
14636
14637 assert_eq!(
14638 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14639 None,
14640 "a false predicate must be evaluated before entering the operator alternative"
14641 );
14642 assert_eq!(
14643 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14644 None,
14645 "cached predicate-dependent lookahead must keep deferring"
14646 );
14647 }
14648
14649 #[test]
14650 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
14651 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
14652 let mut parser = parser_inside_left_recursive_callee(1);
14653
14654 assert_eq!(
14655 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
14656 None
14657 );
14658 assert_eq!(
14659 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
14660 None,
14661 "the cached overlap must preserve the nullable child return path"
14662 );
14663 }
14664
14665 #[test]
14666 fn left_recursive_loop_defers_through_nullable_parent_return() {
14667 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
14668 let mut parser = mini_parser(vec![
14669 TestToken::new(1).with_text("lookahead"),
14670 TestToken::eof("parser-test", 1, 1, 1),
14671 ]);
14672 parser.rule_context_stack = vec![
14673 RuleContextFrame {
14674 rule_index: 0,
14675 invoking_state: -1,
14676 },
14677 RuleContextFrame {
14678 rule_index: 1,
14679 invoking_state: 1,
14680 },
14681 RuleContextFrame {
14682 rule_index: 2,
14683 invoking_state: 5,
14684 },
14685 ];
14686
14687 assert_eq!(
14688 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
14689 None,
14690 "a nullable caller must unwind to its parent's consuming follow path"
14691 );
14692 assert_eq!(
14693 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
14694 None,
14695 "the caller-overlap cache must not retain a false negative"
14696 );
14697 }
14698
14699 #[test]
14700 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
14701 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
14702 let mut parser = mini_parser(vec![
14703 TestToken::new(1).with_text("lookahead"),
14704 TestToken::eof("parser-test", 1, 1, 1),
14705 ]);
14706 parser.rule_context_stack = vec![
14707 RuleContextFrame {
14708 rule_index: 0,
14709 invoking_state: -1,
14710 },
14711 RuleContextFrame {
14712 rule_index: 1,
14713 invoking_state: 1,
14714 },
14715 RuleContextFrame {
14716 rule_index: 1,
14717 invoking_state: 8,
14718 },
14719 ];
14720
14721 assert_eq!(
14722 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
14723 None,
14724 "a recursive operand return must preserve its parent caller context"
14725 );
14726 assert_eq!(
14727 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
14728 None,
14729 "the caller-overlap cache must preserve the loop-boundary return"
14730 );
14731 }
14732
14733 fn token_then_eof_atn() -> Atn {
14734 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14735 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, ]))
14751 .deserialize_parser()
14752 .expect("artificial parser ATN should deserialize")
14753 }
14754
14755 fn epsilon_cycle_atn() -> Atn {
14756 let mut atn = ParserAtnBuilder::new(1);
14757 for (state_number, kind) in [
14758 (0, AtnStateKind::RuleStart),
14759 (1, AtnStateKind::Basic),
14760 (2, AtnStateKind::RuleStop),
14761 ] {
14762 assert_eq!(
14763 atn.add_state(kind, Some(0)).expect("state").index(),
14764 state_number
14765 );
14766 }
14767 atn.set_rule_to_start_state(vec![0])
14768 .expect("rule start states");
14769 atn.set_rule_to_stop_state(vec![2])
14770 .expect("rule stop states");
14771 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14772 .expect("transition");
14773 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
14774 .expect("self-cycle transition");
14775 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14776 .expect("exit transition");
14777 finish_atn(atn)
14778 }
14779
14780 fn eof_then_action_atn() -> Atn {
14781 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14782 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, ]))
14798 .deserialize_parser()
14799 .expect("artificial parser ATN should deserialize")
14800 }
14801
14802 fn noop_action_then_token_then_eof_atn() -> Atn {
14803 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14804 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, ]))
14822 .deserialize_parser()
14823 .expect("artificial no-op action ATN should deserialize")
14824 }
14825
14826 fn two_alt_decision_atn() -> Atn {
14827 let mut atn = ParserAtnBuilder::new(2);
14828 assert_eq!(
14829 atn.add_state(AtnStateKind::RuleStart, Some(0))
14830 .expect("state")
14831 .index(),
14832 0
14833 );
14834 assert_eq!(
14835 atn.add_state(AtnStateKind::BlockStart, Some(0))
14836 .expect("state")
14837 .index(),
14838 1
14839 );
14840 assert_eq!(
14841 atn.add_state(AtnStateKind::Basic, Some(0))
14842 .expect("state")
14843 .index(),
14844 2
14845 );
14846 assert_eq!(
14847 atn.add_state(AtnStateKind::Basic, Some(0))
14848 .expect("state")
14849 .index(),
14850 3
14851 );
14852 assert_eq!(
14853 atn.add_state(AtnStateKind::BlockEnd, Some(0))
14854 .expect("state")
14855 .index(),
14856 4
14857 );
14858 assert_eq!(
14859 atn.add_state(AtnStateKind::RuleStop, Some(0))
14860 .expect("state")
14861 .index(),
14862 5
14863 );
14864 atn.set_rule_to_start_state(vec![0])
14865 .expect("rule start states");
14866 atn.set_rule_to_stop_state(vec![5])
14867 .expect("rule stop states");
14868 atn.add_decision_state(1).expect("decision state");
14869 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14870 .expect("transition");
14871 atn.add_transition(
14872 1,
14873 ParserTransitionSpec::Atom {
14874 target: 2,
14875 label: 1,
14876 },
14877 )
14878 .expect("transition");
14879 atn.add_transition(
14880 1,
14881 ParserTransitionSpec::Atom {
14882 target: 3,
14883 label: 2,
14884 },
14885 )
14886 .expect("transition");
14887 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
14888 .expect("transition");
14889 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14890 .expect("transition");
14891 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14892 .expect("transition");
14893 finish_atn(atn)
14894 }
14895
14896 fn optional_then_b_eof_atn() -> Atn {
14899 let mut atn = ParserAtnBuilder::new(3);
14900 assert_eq!(
14901 atn.add_state(AtnStateKind::RuleStart, Some(0))
14902 .expect("state")
14903 .index(),
14904 0
14905 );
14906 assert_eq!(
14907 atn.add_state(AtnStateKind::BlockStart, Some(0))
14908 .expect("state")
14909 .index(),
14910 1
14911 );
14912 assert_eq!(
14913 atn.add_state(AtnStateKind::Basic, Some(0))
14914 .expect("state")
14915 .index(),
14916 2
14917 );
14918 assert_eq!(
14919 atn.add_state(AtnStateKind::Basic, Some(0))
14920 .expect("state")
14921 .index(),
14922 3
14923 );
14924 assert_eq!(
14925 atn.add_state(AtnStateKind::Basic, Some(0))
14926 .expect("state")
14927 .index(),
14928 4
14929 );
14930 assert_eq!(
14931 atn.add_state(AtnStateKind::RuleStop, Some(0))
14932 .expect("state")
14933 .index(),
14934 5
14935 );
14936 atn.set_rule_to_start_state(vec![0])
14937 .expect("rule start states");
14938 atn.set_rule_to_stop_state(vec![5])
14939 .expect("rule stop states");
14940 atn.add_decision_state(1).expect("decision state");
14941 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14942 .expect("transition");
14943 atn.add_transition(
14945 1,
14946 ParserTransitionSpec::Atom {
14947 target: 3,
14948 label: 1,
14949 },
14950 )
14951 .expect("transition");
14952 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
14953 .expect("transition");
14954 atn.add_transition(
14956 3,
14957 ParserTransitionSpec::Atom {
14958 target: 4,
14959 label: 2,
14960 },
14961 )
14962 .expect("transition");
14963 atn.add_transition(
14964 4,
14965 ParserTransitionSpec::Atom {
14966 target: 5,
14967 label: TOKEN_EOF,
14968 },
14969 )
14970 .expect("transition");
14971 finish_atn(atn)
14972 }
14973
14974 #[test]
14975 fn sync_decision_deletes_only_a_single_token() {
14976 let atn = optional_then_b_eof_atn();
14984
14985 let mut single = mini_parser(vec![
14986 TestToken::new(3).with_text("c"),
14987 TestToken::new(2).with_text("b"),
14988 TestToken::eof("parser-test", 1, 2, 2),
14989 ]);
14990 single.rule_context_stack = vec![RuleContextFrame {
14991 rule_index: 0,
14992 invoking_state: 0,
14993 }];
14994 let children = single
14995 .sync_decision(&atn, 1, true, false)
14996 .expect("single extraneous token recovers");
14997 assert_eq!(children.len(), 1);
14998 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
14999 assert_eq!(single.number_of_syntax_errors(), 1);
15000 assert_eq!(single.la(1), 2);
15002
15003 let mut double = mini_parser(vec![
15004 TestToken::new(3).with_text("c"),
15005 TestToken::new(3).with_text("c"),
15006 TestToken::new(2).with_text("b"),
15007 TestToken::eof("parser-test", 1, 3, 3),
15008 ]);
15009 double.rule_context_stack = vec![RuleContextFrame {
15010 rule_index: 0,
15011 invoking_state: 0,
15012 }];
15013 let result = double.sync_decision(&atn, 1, true, false);
15014 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
15019 match error {
15020 AntlrError::ParserError { message, .. } => {
15021 assert!(message.starts_with("mismatched input"), "got: {message}");
15022 }
15023 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
15024 }
15025 assert_eq!(double.la(1), 3);
15026 }
15027
15028 fn star_loop_then_eof_atn() -> Atn {
15032 AtnDeserializer::new(&SerializedAtn::from_i32(&[
15033 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,
15034 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,
15035 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,
15036 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
15037 ]))
15038 .deserialize_parser()
15039 .expect("star-loop-then-EOF ATN should deserialize")
15040 }
15041
15042 fn plus_loop_with_recovering_body_atn() -> Atn {
15048 let mut atn = ParserAtnBuilder::new(2);
15049 assert_eq!(
15050 atn.add_state(AtnStateKind::RuleStart, Some(0))
15051 .expect("state")
15052 .index(),
15053 0
15054 );
15055 assert_eq!(
15056 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
15057 .expect("state")
15058 .index(),
15059 1
15060 );
15061 assert_eq!(
15062 atn.add_state(AtnStateKind::Basic, Some(0))
15063 .expect("state")
15064 .index(),
15065 2
15066 );
15067 assert_eq!(
15068 atn.add_state(AtnStateKind::BlockEnd, Some(0))
15069 .expect("state")
15070 .index(),
15071 3
15072 );
15073 assert_eq!(
15074 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
15075 .expect("state")
15076 .index(),
15077 4
15078 );
15079 assert_eq!(
15080 atn.add_state(AtnStateKind::LoopEnd, Some(0))
15081 .expect("state")
15082 .index(),
15083 5
15084 );
15085 assert_eq!(
15086 atn.add_state(AtnStateKind::RuleStop, Some(0))
15087 .expect("state")
15088 .index(),
15089 6
15090 );
15091 assert_eq!(
15092 atn.add_state(AtnStateKind::RuleStart, Some(1))
15093 .expect("state")
15094 .index(),
15095 7
15096 );
15097 assert_eq!(
15098 atn.add_state(AtnStateKind::Basic, Some(1))
15099 .expect("state")
15100 .index(),
15101 8
15102 );
15103 assert_eq!(
15104 atn.add_state(AtnStateKind::RuleStop, Some(1))
15105 .expect("state")
15106 .index(),
15107 9
15108 );
15109 atn.set_rule_to_start_state(vec![0, 7])
15110 .expect("rule start states");
15111 atn.set_rule_to_stop_state(vec![6, 9])
15112 .expect("rule stop states");
15113 atn.set_end_state(1, 3).expect("block end state");
15114 atn.set_loop_back_state(5, 4).expect("loop back state");
15115 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15116 .expect("transition");
15117 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15118 .expect("transition");
15119 atn.add_transition(
15120 2,
15121 ParserTransitionSpec::Rule {
15122 target: 7,
15123 rule_index: 1,
15124 follow_state: 3,
15125 precedence: 0,
15126 },
15127 )
15128 .expect("transition");
15129 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
15130 .expect("transition");
15131 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
15132 .expect("transition");
15133 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15134 .expect("transition");
15135 atn.add_transition(
15136 5,
15137 ParserTransitionSpec::Atom {
15138 target: 6,
15139 label: 2,
15140 },
15141 )
15142 .expect("transition");
15143 atn.add_transition(
15144 7,
15145 ParserTransitionSpec::Atom {
15146 target: 8,
15147 label: 1,
15148 },
15149 )
15150 .expect("transition");
15151 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15152 .expect("transition");
15153 finish_atn(atn)
15154 }
15155
15156 #[test]
15157 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
15158 let atn = plus_loop_with_recovering_body_atn();
15159 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15160
15161 let error = parser
15162 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15163 .expect_err("EOF recovery should report a bounded mismatch");
15164
15165 let AntlrError::ParserError { message, .. } = error else {
15166 panic!("expected ParserError, got {error:?}");
15167 };
15168 insta::assert_snapshot!(message, @"mismatched input '<EOF>' expecting {'x', 2}");
15169 assert_eq!(parser.number_of_syntax_errors(), 1);
15170 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
15171 }
15172
15173 #[test]
15174 fn sync_decision_deletes_token_before_eof_at_loop_back() {
15175 let atn = star_loop_then_eof_atn();
15181 let mut parser = mini_parser(vec![
15182 TestToken::new(2).with_text("c"),
15183 TestToken::eof("parser-test", 1, 1, 1),
15184 ]);
15185 parser.rule_context_stack = vec![RuleContextFrame {
15186 rule_index: 0,
15187 invoking_state: 0,
15188 }];
15189 let children = parser
15190 .sync_decision(&atn, 5, true, false)
15191 .expect("single token before EOF recovers");
15192 assert_eq!(children.len(), 1);
15193 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
15194 assert_eq!(parser.number_of_syntax_errors(), 1);
15195 assert_eq!(
15196 parser.la(1),
15197 TOKEN_EOF,
15198 "EOF is left for the rule's EOF match"
15199 );
15200 }
15201
15202 #[test]
15203 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
15204 let atn = star_loop_then_eof_atn();
15209 let mut parser = mini_parser(vec![
15210 TestToken::new(2).with_text("c"),
15211 TestToken::new(2).with_text("c"),
15212 TestToken::eof("parser-test", 1, 2, 2),
15213 ]);
15214 parser.rule_context_stack = vec![RuleContextFrame {
15215 rule_index: 0,
15216 invoking_state: 0,
15217 }];
15218 let error = parser
15219 .sync_decision(&atn, 5, true, false)
15220 .expect_err("two tokens at the loop entry must not be deleted");
15221 match error {
15222 AntlrError::ParserError { message, .. } => {
15223 assert!(message.starts_with("mismatched input"), "got: {message}");
15224 }
15225 other => panic!("expected mismatched-input ParserError, got {other:?}"),
15226 }
15227 assert_eq!(
15228 parser.la(1),
15229 2,
15230 "nothing consumed; cursor still on first `c`"
15231 );
15232 }
15233
15234 #[test]
15235 fn sync_decision_consumes_until_eof_at_loop_back() {
15236 let atn = star_loop_then_eof_atn();
15242 let mut parser = mini_parser(vec![
15243 TestToken::new(2).with_text("c"),
15244 TestToken::new(2).with_text("c"),
15245 TestToken::eof("parser-test", 1, 2, 2),
15246 ]);
15247 parser.rule_context_stack = vec![RuleContextFrame {
15248 rule_index: 0,
15249 invoking_state: 0,
15250 }];
15251 let children = parser
15252 .sync_decision(&atn, 5, false, true)
15253 .expect("loop-back multi-token deletion recovers onto EOF");
15254 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
15255 assert!(
15256 children
15257 .iter()
15258 .all(|child| parser.node(*child).kind() == NodeKind::Error)
15259 );
15260 assert_eq!(parser.number_of_syntax_errors(), 1);
15261 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
15262 }
15263
15264 fn predicate_after_token_atn() -> Atn {
15265 let mut atn = ParserAtnBuilder::new(2);
15266 assert_eq!(
15267 atn.add_state(AtnStateKind::RuleStart, Some(0))
15268 .expect("state")
15269 .index(),
15270 0
15271 );
15272 assert_eq!(
15273 atn.add_state(AtnStateKind::Basic, Some(0))
15274 .expect("state")
15275 .index(),
15276 1
15277 );
15278 assert_eq!(
15279 atn.add_state(AtnStateKind::Basic, Some(0))
15280 .expect("state")
15281 .index(),
15282 2
15283 );
15284 assert_eq!(
15285 atn.add_state(AtnStateKind::Basic, Some(0))
15286 .expect("state")
15287 .index(),
15288 3
15289 );
15290 assert_eq!(
15291 atn.add_state(AtnStateKind::RuleStop, Some(0))
15292 .expect("state")
15293 .index(),
15294 4
15295 );
15296 atn.set_rule_to_start_state(vec![0])
15297 .expect("rule start states");
15298 atn.set_rule_to_stop_state(vec![4])
15299 .expect("rule stop states");
15300 atn.add_transition(
15301 0,
15302 ParserTransitionSpec::Atom {
15303 target: 1,
15304 label: 1,
15305 },
15306 )
15307 .expect("transition");
15308 atn.add_transition(
15309 1,
15310 ParserTransitionSpec::Predicate {
15311 target: 2,
15312 rule_index: 0,
15313 pred_index: 0,
15314 context_dependent: false,
15315 },
15316 )
15317 .expect("transition");
15318 atn.add_transition(
15319 2,
15320 ParserTransitionSpec::Atom {
15321 target: 3,
15322 label: 2,
15323 },
15324 )
15325 .expect("transition");
15326 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
15327 .expect("transition");
15328 finish_atn(atn)
15329 }
15330
15331 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
15332 let mut atn = ParserAtnBuilder::new(1);
15333 for (state_number, kind) in [
15334 (0, AtnStateKind::RuleStart),
15335 (1, AtnStateKind::BlockStart),
15336 (2, AtnStateKind::Basic),
15337 (3, AtnStateKind::Basic),
15338 (4, AtnStateKind::Basic),
15339 (5, AtnStateKind::Basic),
15340 (6, AtnStateKind::BlockEnd),
15341 (7, AtnStateKind::RuleStop),
15342 ] {
15343 assert_eq!(
15344 atn.add_state(kind, Some(0)).expect("state").index(),
15345 state_number
15346 );
15347 }
15348 atn.set_rule_to_start_state(vec![0])
15349 .expect("rule start states");
15350 atn.set_rule_to_stop_state(vec![7])
15351 .expect("rule stop states");
15352 atn.add_decision_state(1).expect("decision state");
15353 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15354 .expect("transition");
15355 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15356 .expect("transition");
15357 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
15358 .expect("transition");
15359 atn.add_transition(
15360 2,
15361 ParserTransitionSpec::Predicate {
15362 target: 4,
15363 rule_index: 0,
15364 pred_index: pred_indexes[0],
15365 context_dependent: false,
15366 },
15367 )
15368 .expect("transition");
15369 atn.add_transition(
15370 3,
15371 ParserTransitionSpec::Predicate {
15372 target: 5,
15373 rule_index: 0,
15374 pred_index: pred_indexes[1],
15375 context_dependent: false,
15376 },
15377 )
15378 .expect("transition");
15379 atn.add_transition(
15380 4,
15381 ParserTransitionSpec::Atom {
15382 target: 6,
15383 label: 1,
15384 },
15385 )
15386 .expect("transition");
15387 atn.add_transition(
15388 5,
15389 ParserTransitionSpec::Atom {
15390 target: 6,
15391 label: 1,
15392 },
15393 )
15394 .expect("transition");
15395 atn.add_transition(
15396 6,
15397 ParserTransitionSpec::Atom {
15398 target: 7,
15399 label: TOKEN_EOF,
15400 },
15401 )
15402 .expect("transition");
15403 finish_atn(atn)
15404 }
15405
15406 fn nested_nullable_context_atn() -> Atn {
15407 let mut atn = ParserAtnBuilder::new(1);
15408 for state_number in 0..=20 {
15409 let kind = match state_number {
15410 0 | 10 | 16 => AtnStateKind::RuleStart,
15411 9 | 15 | 20 => AtnStateKind::RuleStop,
15412 _ => AtnStateKind::Basic,
15413 };
15414 let rule_index = match state_number {
15415 0..=9 => 0,
15416 10..=15 => 1,
15417 _ => 2,
15418 };
15419 assert_eq!(
15420 atn.add_state(kind, Some(rule_index))
15421 .expect("state")
15422 .index(),
15423 state_number
15424 );
15425 }
15426 atn.set_rule_to_start_state(vec![0, 10, 16])
15427 .expect("rule start states");
15428 atn.set_rule_to_stop_state(vec![9, 15, 20])
15429 .expect("rule stop states");
15430 atn.add_transition(
15431 1,
15432 ParserTransitionSpec::Rule {
15433 target: 10,
15434 rule_index: 1,
15435 follow_state: 8,
15436 precedence: 0,
15437 },
15438 )
15439 .expect("transition");
15440 atn.add_transition(
15441 8,
15442 ParserTransitionSpec::Atom {
15443 target: 9,
15444 label: 1,
15445 },
15446 )
15447 .expect("transition");
15448 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15449 .expect("transition");
15450 atn.add_transition(
15451 2,
15452 ParserTransitionSpec::Rule {
15453 target: 16,
15454 rule_index: 2,
15455 follow_state: 14,
15456 precedence: 0,
15457 },
15458 )
15459 .expect("transition");
15460 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
15461 .expect("transition");
15462 finish_atn(atn)
15463 }
15464
15465 fn generated_match_recovery_atn() -> Atn {
15466 let mut atn = ParserAtnBuilder::new(2);
15467 assert_eq!(
15468 atn.add_state(AtnStateKind::RuleStart, Some(0))
15469 .expect("state")
15470 .index(),
15471 0
15472 );
15473 assert_eq!(
15474 atn.add_state(AtnStateKind::Basic, Some(0))
15475 .expect("state")
15476 .index(),
15477 1
15478 );
15479 assert_eq!(
15480 atn.add_state(AtnStateKind::Basic, Some(0))
15481 .expect("state")
15482 .index(),
15483 2
15484 );
15485 assert_eq!(
15486 atn.add_state(AtnStateKind::RuleStop, Some(0))
15487 .expect("state")
15488 .index(),
15489 3
15490 );
15491 assert_eq!(
15492 atn.add_state(AtnStateKind::RuleStart, Some(1))
15493 .expect("state")
15494 .index(),
15495 4
15496 );
15497 assert_eq!(
15498 atn.add_state(AtnStateKind::RuleStop, Some(1))
15499 .expect("state")
15500 .index(),
15501 5
15502 );
15503 atn.set_rule_to_start_state(vec![0, 4])
15504 .expect("rule start states");
15505 atn.set_rule_to_stop_state(vec![3, 5])
15506 .expect("rule stop states");
15507 atn.add_transition(
15508 1,
15509 ParserTransitionSpec::Rule {
15510 target: 4,
15511 rule_index: 1,
15512 follow_state: 2,
15513 precedence: 0,
15514 },
15515 )
15516 .expect("transition");
15517 atn.add_transition(
15518 2,
15519 ParserTransitionSpec::Atom {
15520 target: 3,
15521 label: TOKEN_EOF,
15522 },
15523 )
15524 .expect("transition");
15525 finish_atn(atn)
15526 }
15527
15528 fn complement_set_atn() -> Atn {
15529 let mut atn = ParserAtnBuilder::new(1);
15530 assert_eq!(
15531 atn.add_state(AtnStateKind::RuleStart, Some(0))
15532 .expect("state")
15533 .index(),
15534 0
15535 );
15536 assert_eq!(
15537 atn.add_state(AtnStateKind::RuleStop, Some(0))
15538 .expect("state")
15539 .index(),
15540 1
15541 );
15542 atn.set_rule_to_start_state(vec![0])
15543 .expect("rule start states");
15544 atn.set_rule_to_stop_state(vec![1])
15545 .expect("rule stop states");
15546 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
15547 atn.add_transition(
15548 0,
15549 ParserTransitionSpec::NotSet {
15550 target: 1,
15551 set: excluded,
15552 },
15553 )
15554 .expect("transition");
15555 finish_atn(atn)
15556 }
15557
15558 fn wildcard_then_eof_atn() -> Atn {
15561 let mut atn = ParserAtnBuilder::new(1);
15562 assert_eq!(
15563 atn.add_state(AtnStateKind::RuleStart, Some(0))
15564 .expect("state")
15565 .index(),
15566 0
15567 );
15568 assert_eq!(
15569 atn.add_state(AtnStateKind::RuleStop, Some(0))
15570 .expect("state")
15571 .index(),
15572 1
15573 );
15574 assert_eq!(
15575 atn.add_state(AtnStateKind::Basic, Some(0))
15576 .expect("state")
15577 .index(),
15578 2
15579 );
15580 atn.set_rule_to_start_state(vec![0])
15581 .expect("rule start states");
15582 atn.set_rule_to_stop_state(vec![1])
15583 .expect("rule stop states");
15584 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
15585 .expect("transition");
15586 atn.add_transition(
15587 2,
15588 ParserTransitionSpec::Atom {
15589 target: 1,
15590 label: TOKEN_EOF,
15591 },
15592 )
15593 .expect("transition");
15594 finish_atn(atn)
15595 }
15596
15597 #[test]
15598 fn parser_matches_token_and_reports_mismatch() {
15599 let source = Source {
15600 tokens: vec![
15601 TestToken::new(1).with_text("x"),
15602 TestToken::eof("parser-test", 1, 1, 1),
15603 ],
15604 index: 0,
15605 };
15606 let data = RecognizerData::new(
15607 "Mini.g4",
15608 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
15609 );
15610 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
15611 let matched = parser.match_token(1).expect("token 1 should match");
15612 assert_eq!(parser.node(matched).text(), "x");
15613 assert!(parser.match_token(1).is_err());
15614 }
15615
15616 #[test]
15617 fn parser_matches_token_sets() {
15618 let mut parser = mini_parser(vec![
15619 TestToken::new(1).with_text("x"),
15620 TestToken::eof("parser-test", 1, 1, 1),
15621 ]);
15622
15623 let matched = parser
15624 .match_set(&[(1, 1), (3, 4)])
15625 .expect("token set should match");
15626 assert_eq!(parser.node(matched).text(), "x");
15627 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
15628 }
15629
15630 #[test]
15631 fn generated_rule_api_tracks_state_and_precedence() {
15632 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15633
15634 let context = parser.enter_rule(7, 2);
15635 assert_eq!(context.rule_index(), 2);
15636 assert_eq!(parser.state(), 7);
15637 assert_eq!(
15638 parser.rule_context_stack,
15639 vec![RuleContextFrame {
15640 rule_index: 2,
15641 invoking_state: 7
15642 }]
15643 );
15644
15645 let recursive = parser.enter_recursion_rule(11, 3, 4);
15646 assert_eq!(recursive.rule_index(), 3);
15647 assert!(parser.precpred(4));
15648 assert!(parser.precpred(5));
15649 assert!(!parser.precpred(3));
15650
15651 let next = parser.push_new_recursion_context(13, 3);
15652 assert_eq!(next.invoking_state(), 13);
15653 parser.unroll_recursion_context();
15654 assert_eq!(parser.precedence_stack, vec![0]);
15655 assert_eq!(
15656 parser.rule_context_stack,
15657 vec![RuleContextFrame {
15658 rule_index: 2,
15659 invoking_state: 7
15660 }]
15661 );
15662
15663 parser.exit_rule();
15664 assert!(parser.rule_context_stack.is_empty());
15665 }
15666
15667 #[test]
15668 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
15669 let mut parser = mini_parser(vec![
15670 TestToken::new(1).with_text("x"),
15671 TestToken::eof("parser-test", 1, 1, 1),
15672 ]);
15673 let matched = parser.match_token(1).expect("token should match");
15674 assert_eq!(parser.node(matched).text(), "x");
15675 parser.record_generated_syntax_error();
15676 parser.set_int_member(7, 11);
15677 parser.set_build_parse_trees(false);
15678 parser.set_report_diagnostic_errors(true);
15679 parser.set_prediction_mode(PredictionMode::Sll);
15680 parser.set_bail_on_error(true);
15681 let _context = parser.enter_recursion_rule(9, 0, 4);
15682 parser.pending_invoking_states.push(5);
15683 parser.unknown_predicate_hits.push((0, 1));
15684 parser.unhandled_action_hits.push((0, 2));
15685
15686 parser.reset();
15687
15688 assert_eq!(parser.input.index(), 0);
15689 assert_eq!(parser.la(1), 1);
15690 assert_eq!(parser.state(), -1);
15691 assert_eq!(parser.number_of_syntax_errors(), 0);
15692 assert_eq!(parser.parse_tree_storage().node_count(), 0);
15693 assert!(parser.rule_context_stack.is_empty());
15694 assert!(parser.pending_invoking_states.is_empty());
15695 assert_eq!(parser.precedence_stack, [0]);
15696 assert!(parser.unknown_predicate_hits.is_empty());
15697 assert!(parser.unhandled_action_hits.is_empty());
15698 assert_eq!(parser.int_member(7), Some(11));
15699 assert!(!parser.build_parse_trees());
15700 assert!(parser.report_diagnostic_errors());
15701 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
15702 assert!(parser.bail_on_error());
15703 }
15704
15705 #[test]
15706 fn set_token_stream_replaces_input_and_resets_parser() {
15707 let mut parser = mini_parser(vec![
15708 TestToken::new(1).with_text("old"),
15709 TestToken::eof("parser-test", 1, 1, 1),
15710 ]);
15711 parser.consume();
15712 parser.record_generated_syntax_error();
15713 let replacement = CommonTokenStream::new(Source {
15714 tokens: vec![
15715 TestToken::new(2).with_text("new"),
15716 TestToken::eof("parser-test", 1, 1, 1),
15717 ],
15718 index: 0,
15719 });
15720
15721 parser.set_token_stream(replacement);
15722
15723 assert_eq!(parser.input.index(), 0);
15724 assert_eq!(parser.la(1), 2);
15725 assert_eq!(parser.input.text_all(), "new");
15726 assert_eq!(parser.number_of_syntax_errors(), 0);
15727 }
15728
15729 #[test]
15730 fn active_invocation_states_exclude_the_root_frame() {
15731 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15732
15733 let _root = parser.enter_rule(0, 0);
15734 assert!(parser.active_invocation_states().is_empty());
15735
15736 let marker = parser.push_invoking_state(6);
15737 let _child = parser.enter_rule(2, 1);
15738 parser.discard_invoking_state(marker);
15739 assert_eq!(parser.active_invocation_states(), [6]);
15740
15741 let marker = parser.push_invoking_state(13);
15742 let _grandchild = parser.enter_rule(4, 2);
15743 parser.discard_invoking_state(marker);
15744 assert_eq!(parser.active_invocation_states(), [13, 6]);
15745
15746 parser.exit_rule();
15747 parser.exit_rule();
15748 parser.exit_rule();
15749 }
15750
15751 #[test]
15752 fn parser_predicates_support_token_adjacency() {
15753 let mut parser = mini_parser(vec![
15754 TestToken::new(1).with_text("=").with_span(0, 0),
15755 TestToken::new(1).with_text(">").with_span(1, 1),
15756 TestToken::eof("parser-test", 2, 1, 2),
15757 ]);
15758 parser.consume();
15759 parser.consume();
15760
15761 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
15762
15763 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
15764
15765 let mut parser = mini_parser(vec![
15766 TestToken::new(1).with_text("=").with_span(0, 0),
15767 TestToken::new(1)
15768 .with_text(" ")
15769 .with_channel(HIDDEN_CHANNEL)
15770 .with_span(1, 1),
15771 TestToken::new(1).with_text(">").with_span(2, 2),
15772 TestToken::eof("parser-test", 3, 1, 3),
15773 ]);
15774 parser.consume();
15775 parser.consume();
15776
15777 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
15778 }
15779
15780 #[test]
15781 fn parser_predicates_support_context_child_text_checks() {
15782 let mut parser = mini_parser(vec![
15783 TestToken::new(1).with_text("var"),
15784 TestToken::eof("parser-test", 1, 1, 1),
15785 ]);
15786 let mut context = ParserRuleContext::new(1, 0);
15787 let mut child_context = ParserRuleContext::new(2, 0);
15788 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
15789 parser.tree.add_child(&mut child_context, terminal);
15790 let child = parser.rule_node(child_context);
15791 parser.tree.add_child(&mut context, child);
15792 let predicates = [(
15793 1,
15794 0,
15795 ParserPredicate::ContextChildRuleTextNotEquals {
15796 rule_index: 2,
15797 text: "var",
15798 },
15799 )];
15800
15801 assert!(
15802 !parser.parser_semantic_predicate_matches_with_context_and_local(
15803 &predicates,
15804 1,
15805 0,
15806 &context,
15807 0,
15808 )
15809 );
15810 }
15811
15812 #[test]
15813 fn context_expected_symbols_walks_nullable_parent_contexts() {
15814 let atn = nested_nullable_context_atn();
15815 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15816 parser.rule_context_stack = vec![
15817 RuleContextFrame {
15818 rule_index: 0,
15819 invoking_state: 0,
15820 },
15821 RuleContextFrame {
15822 rule_index: 1,
15823 invoking_state: 1,
15824 },
15825 RuleContextFrame {
15826 rule_index: 2,
15827 invoking_state: 2,
15828 },
15829 ];
15830
15831 let expected = parser.context_expected_symbols(&atn);
15832
15833 assert!(expected.contains(&1));
15834 assert!(expected.contains(&TOKEN_EOF));
15835 }
15836
15837 #[test]
15838 fn prediction_context_return_states_track_rule_stack_changes() {
15839 let atn = nested_nullable_context_atn();
15840 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15841 parser.rule_context_stack = vec![
15842 RuleContextFrame {
15843 rule_index: 0,
15844 invoking_state: 0,
15845 },
15846 RuleContextFrame {
15847 rule_index: 1,
15848 invoking_state: 1,
15849 },
15850 RuleContextFrame {
15851 rule_index: 2,
15852 invoking_state: 2,
15853 },
15854 ];
15855
15856 let initial_version = parser.rule_context_version();
15857 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15858 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15859 assert_eq!(first, second);
15860 assert_eq!(parser.rule_context_version(), initial_version);
15861
15862 parser.exit_rule();
15863 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15864 assert_ne!(first, after_pop);
15865 assert_ne!(parser.rule_context_version(), initial_version);
15866 }
15867
15868 #[test]
15869 fn generated_match_token_recovers_missing_token_from_context_follow() {
15870 let atn = generated_match_recovery_atn();
15871 let data = RecognizerData::new(
15872 "Mini.g4",
15873 Vocabulary::new(
15874 [None, Some("'X'"), Some("'Y'")],
15875 [None, Some("X"), Some("Y")],
15876 [None::<&str>, None, None],
15877 ),
15878 );
15879 let mut parser = BaseParser::new(
15880 CommonTokenStream::new(Source {
15881 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
15882 index: 0,
15883 }),
15884 data,
15885 );
15886 parser.rule_context_stack = vec![
15887 RuleContextFrame {
15888 rule_index: 0,
15889 invoking_state: 0,
15890 },
15891 RuleContextFrame {
15892 rule_index: 1,
15893 invoking_state: 1,
15894 },
15895 ];
15896 assert_eq!(parser.number_of_syntax_errors(), 0);
15897
15898 let node = parser
15899 .match_token_recovering(2, 5, &atn)
15900 .expect("generated match should insert missing token");
15901
15902 assert_eq!(node.children().len(), 1);
15903 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
15904 assert_eq!(
15905 node.clone()
15906 .into_child_iter()
15907 .map(|child| parser.node(child).text())
15908 .collect::<Vec<_>>(),
15909 ["<missing 'Y'>"]
15910 );
15911 assert!(!node.consumed_eof());
15914 assert_eq!(parser.la(1), TOKEN_EOF);
15915 assert_eq!(parser.number_of_syntax_errors(), 1);
15916 assert_eq!(
15917 parser.generated_parser_diagnostics,
15918 [ParserDiagnostic {
15919 line: 1,
15920 column: 3,
15921 message: "missing 'Y' at '<EOF>'".to_owned(),
15922 offending: parser.input.lt_id(1),
15923 }]
15924 );
15925 }
15926
15927 #[test]
15928 fn generated_match_token_counts_single_token_deletion_recovery() {
15929 let atn = generated_match_recovery_atn();
15930 let data = RecognizerData::new(
15931 "Mini.g4",
15932 Vocabulary::new(
15933 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
15934 [None, Some("X"), Some("Y"), Some("Z")],
15935 [None::<&str>, None, None, None],
15936 ),
15937 );
15938 let mut parser = BaseParser::new(
15939 CommonTokenStream::new(Source {
15940 tokens: vec![
15941 TestToken::new(3).with_text("z"),
15942 TestToken::new(2).with_text("y"),
15943 TestToken::eof("parser-test", 3, 1, 3),
15944 ],
15945 index: 0,
15946 }),
15947 data,
15948 );
15949
15950 let node = parser
15951 .match_token_recovering(2, 5, &atn)
15952 .expect("generated match should delete the extraneous token");
15953
15954 assert_eq!(node.children().len(), 2);
15955 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
15956 assert_eq!(parser.node(node.children()[0]).text(), "z");
15957 assert_eq!(parser.node(node.children()[1]).text(), "y");
15958 assert_eq!(
15959 node.into_child_iter()
15960 .map(|child| parser.node(child).text())
15961 .collect::<Vec<_>>(),
15962 ["z", "y"]
15963 );
15964 assert_eq!(parser.number_of_syntax_errors(), 1);
15965 }
15966
15967 #[test]
15968 fn generated_match_token_iterates_single_success_without_a_children_vec() {
15969 let atn = generated_match_recovery_atn();
15970 let data = RecognizerData::new(
15971 "Mini.g4",
15972 Vocabulary::new(
15973 [None, Some("'X'"), Some("'Y'")],
15974 [None, Some("X"), Some("Y")],
15975 [None::<&str>, None, None],
15976 ),
15977 );
15978 let mut parser = BaseParser::new(
15979 CommonTokenStream::new(Source {
15980 tokens: vec![
15981 TestToken::new(2).with_text("y"),
15982 TestToken::eof("parser-test", 1, 1, 1),
15983 ],
15984 index: 0,
15985 }),
15986 data,
15987 );
15988
15989 let node = parser
15990 .match_token_recovering(2, 5, &atn)
15991 .expect("generated match should consume the expected token");
15992
15993 assert_eq!(
15994 node.into_child_iter()
15995 .map(|child| parser.node(child).text())
15996 .collect::<Vec<_>>(),
15997 ["y"]
15998 );
15999 assert_eq!(parser.number_of_syntax_errors(), 0);
16000 }
16001
16002 #[test]
16003 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
16004 let atn = generated_match_recovery_atn();
16005 let data = RecognizerData::new(
16006 "Mini.g4",
16007 Vocabulary::new(
16008 [None, Some("'X'"), Some("'Y'")],
16009 [None, Some("X"), Some("Y")],
16010 [None::<&str>, None, None],
16011 ),
16012 );
16013 let mut parser = BaseParser::new(
16014 CommonTokenStream::new(Source {
16015 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
16016 index: 0,
16017 }),
16018 data,
16019 );
16020 parser.rule_context_stack = vec![
16021 RuleContextFrame {
16022 rule_index: 0,
16023 invoking_state: 0,
16024 },
16025 RuleContextFrame {
16026 rule_index: 1,
16027 invoking_state: 1,
16028 },
16029 ];
16030 let marker = parser.generated_diagnostics_checkpoint();
16031
16032 let _ = parser
16033 .match_token_recovering(2, 5, &atn)
16034 .expect("generated match should insert missing token");
16035 assert_eq!(parser.number_of_syntax_errors(), 1);
16036
16037 parser.restore_generated_diagnostics(marker);
16038
16039 assert_eq!(parser.number_of_syntax_errors(), 0);
16040 assert!(parser.generated_parser_diagnostics.is_empty());
16041 }
16042
16043 #[test]
16044 fn generated_prediction_diagnostics_use_adaptive_context() {
16045 let atn = two_alt_decision_atn();
16046 let data = RecognizerData::new(
16047 "Mini.g4",
16048 Vocabulary::new(
16049 [None, Some("'x'"), Some("'y'")],
16050 [None, Some("X"), Some("Y")],
16051 [None::<&str>, None, None],
16052 ),
16053 )
16054 .with_rule_names(["s"]);
16055 let mut parser = BaseParser::new(
16056 CommonTokenStream::new(Source {
16057 tokens: vec![
16058 TestToken::new(1)
16059 .with_text("x")
16060 .with_position(1, 0)
16061 .with_span(0, 0),
16062 TestToken::new(2)
16063 .with_text("y")
16064 .with_position(1, 2)
16065 .with_span(1, 1),
16066 TestToken::eof("parser-test", 2, 1, 3),
16067 ],
16068 index: 0,
16069 }),
16070 data,
16071 );
16072 parser.set_report_diagnostic_errors(true);
16073
16074 parser.record_generated_prediction_diagnostic(
16075 &atn,
16076 1,
16077 &ParserAtnPrediction {
16078 alt: 1,
16079 requires_full_context: true,
16080 has_semantic_context: false,
16081 diagnostic: Some(ParserAtnPredictionDiagnostic {
16082 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
16083 start_index: 0,
16084 sll_stop_index: 1,
16085 ll_stop_index: 0,
16086 conflicting_alts: vec![1, 2],
16087 exact: false,
16088 }),
16089 },
16090 );
16091 parser.record_generated_prediction_diagnostic(
16096 &atn,
16097 1,
16098 &ParserAtnPrediction {
16099 alt: 1,
16100 requires_full_context: true,
16101 has_semantic_context: false,
16102 diagnostic: Some(ParserAtnPredictionDiagnostic {
16103 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
16104 start_index: 0,
16105 sll_stop_index: 1,
16106 ll_stop_index: 1,
16107 conflicting_alts: vec![1, 2],
16108 exact: false,
16109 }),
16110 },
16111 );
16112
16113 insta::assert_debug_snapshot!(
16116 "generated_prediction_diagnostics_use_adaptive_context",
16117 parser.generated_parser_diagnostics
16118 );
16119 }
16120
16121 #[test]
16122 fn generated_match_not_set_recovers_empty_complement_at_eof() {
16123 let atn = complement_set_atn();
16124 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16125 parser.rule_context_stack = vec![RuleContextFrame {
16126 rule_index: 0,
16127 invoking_state: 0,
16128 }];
16129
16130 let node = parser
16131 .match_not_token_set_recovering(
16132 atn.token_set(0).expect("excluded token set"),
16133 1,
16134 1,
16135 1,
16136 &atn,
16137 )
16138 .expect("empty complement should recover at EOF");
16139
16140 assert_eq!(node.children().len(), 1);
16141 assert!(!node.consumed_eof());
16144 assert_eq!(parser.la(1), TOKEN_EOF);
16145 assert_eq!(
16146 parser.generated_parser_diagnostics,
16147 [ParserDiagnostic {
16148 line: 1,
16149 column: 1,
16150 message: "missing {} at '<EOF>'".to_owned(),
16151 offending: parser.input.lt_id(1),
16152 }]
16153 );
16154 }
16155
16156 #[test]
16157 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
16158 let atn = wildcard_then_eof_atn();
16164 let data = RecognizerData::new(
16165 "Mini.g4",
16166 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
16167 );
16168 let mut parser = BaseParser::new(
16169 CommonTokenStream::new(Source {
16170 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
16171 index: 0,
16172 }),
16173 data,
16174 );
16175 parser.rule_context_stack = vec![RuleContextFrame {
16176 rule_index: 0,
16177 invoking_state: 0,
16178 }];
16179
16180 let node = parser
16181 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
16182 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
16183
16184 assert_eq!(node.children().len(), 1);
16186 assert!(!node.consumed_eof());
16187 assert!(
16188 parser
16189 .node(node.children()[0])
16190 .text()
16191 .starts_with("<missing")
16192 );
16193 assert_eq!(parser.la(1), TOKEN_EOF);
16194 assert_eq!(
16195 parser.generated_parser_diagnostics,
16196 [ParserDiagnostic {
16197 line: 1,
16198 column: 1,
16199 message: "missing 'x' at '<EOF>'".to_owned(),
16200 offending: parser.input.lt_id(1),
16201 }]
16202 );
16203 }
16204
16205 #[test]
16206 fn generated_rule_recovery_consumes_to_parent_follow() {
16207 let atn = generated_match_recovery_atn();
16208 let data = RecognizerData::new(
16209 "Mini.g4",
16210 Vocabulary::new(
16211 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
16212 [None, Some("X"), Some("Y"), Some("Z")],
16213 [None::<&str>, None, None, None],
16214 ),
16215 );
16216 let mut parser = BaseParser::new(
16217 CommonTokenStream::new(Source {
16218 tokens: vec![
16219 TestToken::new(3).with_text("z"),
16220 TestToken::eof("parser-test", 1, 1, 1),
16221 ],
16222 index: 0,
16223 }),
16224 data,
16225 );
16226 let _parent = parser.enter_rule(0, 0);
16227 let marker = parser.push_invoking_state(1);
16228 let mut child = parser.enter_rule(4, 1);
16229 parser.discard_invoking_state(marker);
16230
16231 let offending = parser.input.lt_id(1);
16234 assert!(offending.is_some(), "the 'z' token should be buffered");
16235 parser.recover_generated_rule(
16236 &mut child,
16237 &atn,
16238 AntlrError::ParserError {
16239 line: 1,
16240 column: 0,
16241 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
16242 offending,
16243 },
16244 );
16245 let tree = parser.finish_rule(child, false);
16246
16247 assert_eq!(parser.la(1), TOKEN_EOF);
16248 assert_eq!(
16249 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
16250 "(a z)"
16251 );
16252 assert_eq!(parser.number_of_syntax_errors(), 1);
16253 assert_eq!(
16254 parser.generated_parser_diagnostics,
16255 [ParserDiagnostic {
16256 line: 1,
16257 column: 0,
16258 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
16259 offending,
16260 }]
16261 );
16262 parser.exit_rule();
16263 }
16264
16265 #[test]
16266 fn generated_rule_recovery_forces_progress_after_repeated_error_state() {
16267 let atn = nested_nullable_context_atn();
16268 let mut parser = mini_parser(vec![
16269 TestToken::new(1).with_text("x"),
16270 TestToken::eof("parser-test", 1, 1, 1),
16271 ]);
16272 parser.rule_context_stack = vec![
16273 RuleContextFrame {
16274 rule_index: 0,
16275 invoking_state: 0,
16276 },
16277 RuleContextFrame {
16278 rule_index: 1,
16279 invoking_state: 1,
16280 },
16281 RuleContextFrame {
16282 rule_index: 2,
16283 invoking_state: 2,
16284 },
16285 ];
16286 parser.set_state(20);
16287 let mut context = ParserRuleContext::new(2, 2);
16288
16289 parser.recover_generated_rule(
16290 &mut context,
16291 &atn,
16292 AntlrError::NoViableAlternative {
16293 input: "'x'".to_owned(),
16294 },
16295 );
16296 assert_eq!(parser.input.index(), 0);
16297
16298 parser.set_state(21);
16299 parser.recover_generated_rule(
16300 &mut context,
16301 &atn,
16302 AntlrError::NoViableAlternative {
16303 input: "'x'".to_owned(),
16304 },
16305 );
16306 assert_eq!(parser.input.index(), 0);
16307 assert_eq!(
16308 parser.generated_recovery_error_states,
16309 BTreeSet::from([20, 21])
16310 );
16311
16312 parser.set_state(20);
16313 parser.recover_generated_rule(
16314 &mut context,
16315 &atn,
16316 AntlrError::NoViableAlternative {
16317 input: "'x'".to_owned(),
16318 },
16319 );
16320
16321 assert_eq!(parser.input.index(), 1);
16322 assert_eq!(parser.la(1), TOKEN_EOF);
16323 assert!(context.has_matched_child());
16324 assert_eq!(parser.generated_recovery_error_states, BTreeSet::from([20]));
16325
16326 parser.match_eof().expect("EOF should match");
16327 assert_eq!(parser.generated_recovery_error_index, None);
16328 assert!(parser.generated_recovery_error_states.is_empty());
16329 }
16330
16331 #[test]
16332 fn greedy_ll1_alt_handles_nullable_loop_exit() {
16333 let mut body_symbols = TokenBitSet::default();
16334 body_symbols.insert(1);
16335 let entry = DecisionLookahead {
16336 transitions: vec![
16337 TransitionLookSet {
16338 symbols: body_symbols,
16339 nullable: false,
16340 },
16341 TransitionLookSet {
16342 symbols: TokenBitSet::default(),
16343 nullable: true,
16344 },
16345 ],
16346 };
16347
16348 assert_eq!(ll1_unique_alt(&entry, 2), None);
16349 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
16350 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
16351 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
16352 }
16353
16354 #[test]
16355 fn ordinary_repetition_builds_tree_in_input_order() {
16356 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
16357 let mut parser = mini_parser(repeated_x_tokens(3));
16358 let tree = parser
16359 .parse_atn_rule(&atn, 0)
16360 .expect("ordinary repetition should parse");
16361
16362 let root = parser
16363 .node(tree)
16364 .as_rule()
16365 .expect("entry result should be a rule");
16366 let body_rules = root.child_rules(1).collect::<Vec<_>>();
16367 assert_eq!(root.text(), "xxx<EOF>");
16368 assert_eq!(body_rules.len(), 3);
16369 assert_eq!(
16370 body_rules
16371 .iter()
16372 .map(|rule| rule.start_id().expect("body start").index())
16373 .collect::<Vec<_>>(),
16374 [0, 1, 2]
16375 );
16376 assert_eq!(
16377 body_rules
16378 .iter()
16379 .map(|rule| rule.stop_id().expect("body stop").index())
16380 .collect::<Vec<_>>(),
16381 [0, 1, 2]
16382 );
16383 assert_eq!(parser.number_of_syntax_errors(), 0);
16384 }
16385 }
16386
16387 #[test]
16388 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
16389 const DEPTH: usize = 20_000;
16390
16391 std::thread::Builder::new()
16392 .name("deferred-rule-materialization".to_owned())
16393 .stack_size(256 * 1024)
16394 .spawn(|| {
16395 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
16396 let mut root = FastDeferredNodeId::EMPTY;
16397 for depth in 0..DEPTH {
16398 root = parser
16399 .recognition_arena
16400 .deferred_rule_node(FastDeferredRule {
16401 rule_index: u32::try_from(depth).expect("depth fits in u32"),
16402 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
16403 start_index: 0,
16404 stop_index: None,
16405 deferred_children: root,
16406 children: NodeSeqId::EMPTY,
16407 });
16408 }
16409
16410 let (mut children, alt_number) =
16411 parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
16412 assert_eq!(alt_number, 0);
16413 for expected_rule in (0..DEPTH).rev() {
16414 let mut nodes = parser.recognition_arena.iter(children);
16415 let node = nodes.next().expect("nested rule node");
16416 assert!(nodes.next().is_none(), "each rule has one child");
16417 let ArenaRecognizedNode::Rule {
16418 rule_index,
16419 children: nested,
16420 ..
16421 } = parser.recognition_arena.node(node)
16422 else {
16423 panic!("expected nested rule");
16424 };
16425 assert_eq!(rule_index as usize, expected_rule);
16426 children = nested;
16427 }
16428 assert!(children.is_empty());
16429 })
16430 .expect("small-stack thread should start")
16431 .join()
16432 .expect("deferred rules should materialize without recursion");
16433 }
16434
16435 #[test]
16436 fn deferred_alternatives_preserve_left_recursive_contexts() {
16437 let mut parser = mini_parser(vec![
16438 TestToken::new(1).with_text("1"),
16439 TestToken::new(2).with_text("+"),
16440 TestToken::new(1).with_text("2"),
16441 TestToken::eof("parser-test", 3, 1, 3),
16442 ]);
16443 let base = parser.arena_token_node(0, false);
16444 let operator = parser.arena_token_node(1, false);
16445 let right = parser.arena_token_node(2, false);
16446
16447 let base = parser.recognition_arena.prepend(NodeSeqId::EMPTY, base);
16448 let base = parser.recognition_arena.deferred_fragment(base);
16449 let operator = parser.recognition_arena.prepend(NodeSeqId::EMPTY, operator);
16450 let operator = parser.recognition_arena.deferred_fragment(operator);
16451 let right = parser.recognition_arena.prepend(NodeSeqId::EMPTY, right);
16452 let right = parser.recognition_arena.deferred_fragment(right);
16453 let base_alt = parser.recognition_arena.deferred_alternative(1);
16454 let boundary = parser.recognition_arena.deferred_left_recursive_boundary(0);
16455 let operator_alt = parser.recognition_arena.deferred_alternative(6);
16456
16457 let mut deferred = FastDeferredNodeId::EMPTY;
16458 for fragment in [base_alt, base, boundary, operator_alt, operator, right] {
16459 deferred = parser
16460 .recognition_arena
16461 .concat_deferred_nodes(deferred, fragment);
16462 }
16463 let (nodes, root_alt_number) =
16464 parser.materialize_fast_deferred_nodes(deferred, NodeSeqId::EMPTY);
16465 let nodes = parser
16466 .recognition_arena
16467 .fold_left_recursive_boundaries(nodes);
16468
16469 let mut root = ParserRuleContext::new(0, -1);
16470 root.set_context_alt_number(root_alt_number);
16471 let mut cursor = nodes;
16472 while let Some(link) = parser.recognition_arena.link(cursor) {
16473 let child = parser
16474 .arena_recognized_node_tree(link.head, false, true)
16475 .expect("materialized child should become a public tree");
16476 parser.tree.add_child(&mut root, child);
16477 cursor = link.tail;
16478 }
16479 let tree = parser.rule_node(root);
16480 let contexts = parser
16481 .node(tree)
16482 .descendants()
16483 .filter_map(Node::as_rule)
16484 .map(|rule| {
16485 (
16486 rule.rule_index(),
16487 rule.alt_number(),
16488 rule.context_alt_number(),
16489 rule.text(),
16490 )
16491 })
16492 .collect::<Vec<_>>();
16493
16494 insta::assert_debug_snapshot!(
16495 "deferred_alternatives_preserve_left_recursive_contexts",
16496 contexts
16497 );
16498 }
16499
16500 #[test]
16501 fn fast_recognizer_preserves_labeled_left_recursive_operator_context() {
16502 let atn = labeled_left_recursive_operator_atn();
16503 let mut parser = mini_parser(vec![
16504 TestToken::new(1).with_text("a"),
16505 TestToken::new(3).with_text("+"),
16506 TestToken::new(1).with_text("b"),
16507 TestToken::eof("parser-test", 3, 1, 3),
16508 ]);
16509
16510 let (tree, _) = parser
16511 .parse_atn_rule_with_runtime_options(
16512 &atn,
16513 0,
16514 ParserRuntimeOptions {
16515 track_context_alt_numbers: true,
16516 ..ParserRuntimeOptions::default()
16517 },
16518 )
16519 .expect("labeled left-recursive addition should parse");
16520 let contexts = parser
16521 .node(tree)
16522 .descendants()
16523 .filter_map(Node::as_rule)
16524 .map(|rule| {
16525 let operator = rule
16526 .children()
16527 .next()
16528 .and_then(Node::as_rule)
16529 .is_some_and(|child| child.rule_index() == rule.rule_index());
16530 (operator, rule.context_alt_number(), rule.text())
16531 })
16532 .collect::<Vec<_>>();
16533
16534 insta::assert_debug_snapshot!(
16535 "fast_recognizer_preserves_labeled_left_recursive_operator_context",
16536 contexts
16537 );
16538 assert!(!parser.recognition_arena.deferred_nodes.is_empty());
16539 assert_eq!(parser.number_of_syntax_errors(), 0);
16540 }
16541
16542 #[test]
16543 fn deeply_nested_rule_calls_grow_the_stack() {
16544 const DEPTH: usize = 4_096;
16545 const STACK_SIZE: usize = 256 * 1024;
16546 let atn = nested_rule_chain_atn(DEPTH);
16547 std::thread::Builder::new()
16548 .name("nested-adaptive-set-rules".to_owned())
16549 .stack_size(STACK_SIZE)
16550 .spawn(move || {
16551 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
16552 parser.set_build_parse_trees(false);
16553 parser.fast_first_set_prefilter = false;
16556 parser
16557 .parse_atn_rule(&atn, 0)
16558 .expect("nested rule chain should grow the native stack");
16559 assert_eq!(parser.input.index(), 1);
16560 })
16561 .expect("small-stack thread should start")
16562 .join()
16563 .expect("nested rule chain should not overflow its stack");
16564 }
16565
16566 #[test]
16567 fn deeply_nested_branching_rules_grow_the_stack() {
16568 const DEPTH: usize = 4_096;
16569 const STACK_SIZE: usize = 256 * 1024;
16570 let atn = nested_rule_graph_atn(DEPTH, true, false);
16571 std::thread::Builder::new()
16572 .name("nested-branching-rules".to_owned())
16573 .stack_size(STACK_SIZE)
16574 .spawn(move || {
16575 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
16576 parser.set_build_parse_trees(false);
16577 parser
16578 .parse_atn_rule(&atn, 0)
16579 .expect("branching rule chain should grow the native stack");
16580 assert_eq!(parser.input.index(), 1);
16581 })
16582 .expect("small-stack thread should start")
16583 .join()
16584 .expect("branching rule chain should not overflow its stack");
16585 }
16586
16587 #[test]
16588 fn deeply_nested_rule_follows_grow_the_stack() {
16589 const DEPTH: usize = 4_096;
16590 const STACK_SIZE: usize = 256 * 1024;
16591 let atn = nested_rule_graph_atn(DEPTH, false, true);
16592 std::thread::Builder::new()
16593 .name("nested-rule-follows".to_owned())
16594 .stack_size(STACK_SIZE)
16595 .spawn(move || {
16596 let mut parser = mini_parser(repeated_x_tokens(DEPTH));
16597 parser.set_build_parse_trees(false);
16598 parser.fast_first_set_prefilter = false;
16599 parser
16600 .parse_atn_rule(&atn, 0)
16601 .expect("rule follow chain should grow the native stack");
16602 assert_eq!(parser.input.index(), DEPTH);
16603 })
16604 .expect("small-stack thread should start")
16605 .join()
16606 .expect("nested rule follow chain should not overflow its stack");
16607 }
16608
16609 #[test]
16610 fn deeply_nested_recovery_grows_the_stack() {
16611 const DEPTH: usize = 4_096;
16612 const STACK_SIZE: usize = 256 * 1024;
16613 let atn = nested_rule_chain_atn(DEPTH);
16614 std::thread::Builder::new()
16615 .name("nested-rule-recovery".to_owned())
16616 .stack_size(STACK_SIZE)
16617 .spawn(move || {
16618 let mut parser = mini_parser(vec![
16619 TestToken::new(2).with_text("z"),
16620 TestToken::new(1).with_text("x"),
16621 TestToken::eof("parser-test", 2, 1, 2),
16622 ]);
16623 parser.set_build_parse_trees(false);
16624 parser.fast_first_set_prefilter = false;
16625 parser
16626 .parse_atn_rule(&atn, 0)
16627 .expect("nested recovery should grow the native stack");
16628 assert_eq!(parser.input.index(), 2);
16629 assert_eq!(parser.number_of_syntax_errors(), 1);
16630 })
16631 .expect("small-stack thread should start")
16632 .join()
16633 .expect("nested rule recovery should not overflow its stack");
16634 }
16635
16636 #[test]
16637 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
16638 const REPETITIONS: usize = 64;
16639
16640 let atn = ambiguous_ordinary_star_loop_atn();
16641 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16642 let tree = parser
16643 .parse_atn_rule(&atn, 0)
16644 .expect("ambiguous ordinary repetition should parse");
16645
16646 let root = parser
16647 .node(tree)
16648 .as_rule()
16649 .expect("entry result should be a rule");
16650 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
16651 assert_eq!(parser.input.index(), REPETITIONS);
16652 assert!(
16653 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
16654 "equivalent segmentations should keep deferred storage linear"
16655 );
16656 assert_eq!(parser.number_of_syntax_errors(), 0);
16657 }
16658
16659 #[test]
16660 fn long_ordinary_repetition_does_not_consume_native_stack() {
16661 const REPETITIONS: usize = 20_000;
16662
16663 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
16664 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16665 parser.set_build_parse_trees(false);
16666 parser
16667 .parse_atn_rule(&atn, 0)
16668 .expect("long ordinary repetition should parse");
16669
16670 assert_eq!(parser.input.index(), REPETITIONS);
16671 assert_eq!(parser.number_of_syntax_errors(), 0);
16672 }
16673 }
16674
16675 #[test]
16676 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
16677 const REPETITIONS: usize = 2_000;
16678 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
16679
16680 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
16681 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16682 let tree = parser
16683 .parse_atn_rule(&atn, 0)
16684 .expect("long rule repetition should parse");
16685
16686 let root = parser
16687 .node(tree)
16688 .as_rule()
16689 .expect("entry result should be a rule");
16690 assert_eq!(root.text(), expected_text);
16691 assert_eq!(root.child_rules(1).count(), REPETITIONS);
16692 let first_body = root.child_rules(1).next().expect("first body rule");
16693 let last_body = root.child_rules(1).next_back().expect("last body rule");
16694 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
16695 assert_eq!(
16696 last_body.stop_id().expect("last body stop").index(),
16697 REPETITIONS - 1
16698 );
16699
16700 let stats = parser.recognition_arena_stats();
16701 assert_eq!(
16702 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
16703 (REPETITIONS, REPETITIONS, 0)
16704 );
16705 assert_eq!(
16706 (stats.total_links, stats.live_links, stats.dead_links),
16707 (REPETITIONS, REPETITIONS, 0)
16708 );
16709 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
16710 assert_eq!(
16711 parser.recognition_arena.deferred_nodes.len(),
16712 REPETITIONS * 2 - 1
16713 );
16714 assert_eq!(parser.number_of_syntax_errors(), 0);
16715 }
16716 }
16717
16718 #[test]
16719 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
16720 let key = |state_number| FastRecognizeKey {
16721 state_number,
16722 stop_state: 10,
16723 index: state_number,
16724 rule_start_index: 0,
16725 decision_start_index: None,
16726 precedence: 0,
16727 recovery_symbols_id: 0,
16728 recovery_state: None,
16729 };
16730
16731 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16732 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
16733 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
16734 }
16735 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
16736 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
16737
16738 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16739 let repeated = key(1);
16740 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
16741 assert!(promote.clean_memo_enabled_for_key(&repeated));
16742 }
16743 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
16744
16745 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
16746 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
16747 }
16748 assert!(sparse.clean_memo_enabled_for_key(&repeated));
16749 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
16750 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
16751 assert!(sparse.clean_memo_enabled_for_key(&repeated));
16752 }
16753 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
16754 }
16755
16756 #[test]
16757 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
16758 assert_eq!(
16759 fast_recognize_memo_capacity(0),
16760 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
16761 );
16762 assert_eq!(
16763 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
16764 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
16765 );
16766 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
16767 assert_eq!(
16768 fast_recognize_memo_capacity(usize::MAX),
16769 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
16770 );
16771 }
16772
16773 #[test]
16774 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
16775 let mut scratch = FastRecognizeTopScratch::default();
16776 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
16777 let retained_capacity = scratch.memo.capacity();
16778 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
16779 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16780
16781 let larger_capacity = retained_capacity + 1;
16782 scratch.prepare(larger_capacity);
16783 let grown_capacity = scratch.memo.capacity();
16784 assert!(grown_capacity >= larger_capacity);
16785 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16786
16787 scratch.memo.insert(
16788 FastRecognizeKey {
16789 state_number: 0,
16790 stop_state: 0,
16791 index: 0,
16792 rule_start_index: 0,
16793 decision_start_index: None,
16794 precedence: 0,
16795 recovery_symbols_id: 0,
16796 recovery_state: None,
16797 },
16798 Rc::from([FastRecognizeOutcome {
16799 index: 0,
16800 consumed_eof: false,
16801 diagnostics: DiagnosticSeqId::EMPTY,
16802 deferred_nodes: FastDeferredNodeId::EMPTY,
16803 nodes: NodeSeqId::EMPTY,
16804 }]),
16805 );
16806 scratch.release_oversized_memo();
16807 assert!(scratch.memo.is_empty());
16808 assert_eq!(scratch.memo.capacity(), grown_capacity);
16809
16810 scratch
16811 .memo
16812 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
16813 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16814
16815 scratch.release_oversized_memo();
16816 assert!(scratch.memo.is_empty());
16817 assert_eq!(scratch.memo.capacity(), 0);
16818 }
16819
16820 #[test]
16821 fn clean_empty_multi_alt_outcomes_are_memoized() {
16822 let mut atn = ParserAtnBuilder::new(2);
16823 assert_eq!(
16824 atn.add_state(AtnStateKind::RuleStart, Some(0))
16825 .expect("state")
16826 .index(),
16827 0
16828 );
16829 assert_eq!(
16830 atn.add_state(AtnStateKind::BlockStart, Some(0))
16831 .expect("state")
16832 .index(),
16833 1
16834 );
16835 assert_eq!(
16836 atn.add_state(AtnStateKind::RuleStop, Some(0))
16837 .expect("state")
16838 .index(),
16839 2
16840 );
16841 atn.set_rule_to_start_state(vec![0])
16842 .expect("rule start states");
16843 atn.set_rule_to_stop_state(vec![2])
16844 .expect("rule stop states");
16845 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16846 .expect("transition");
16847 atn.add_transition(
16848 1,
16849 ParserTransitionSpec::Atom {
16850 target: 2,
16851 label: 1,
16852 },
16853 )
16854 .expect("transition");
16855 atn.add_transition(
16856 1,
16857 ParserTransitionSpec::Atom {
16858 target: 2,
16859 label: 2,
16860 },
16861 )
16862 .expect("transition");
16863 let atn = finish_atn(atn);
16864
16865 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
16866 parser.fast_recovery_enabled = false;
16867 let mut visiting = FxHashSet::default();
16868 let mut memo = FxHashMap::default();
16869 let mut expected = ExpectedTokens::default();
16870 let outcomes = parser.recognize_state_fast(
16871 &atn,
16872 FastRecognizeRequest {
16873 state_number: 1,
16874 stop_state: 2,
16875 index: 0,
16876 rule_start_index: 0,
16877 decision_start_index: None,
16878 precedence: 0,
16879 depth: 0,
16880 recovery_symbols: parser.empty_recovery_symbols(),
16881 recovery_state: None,
16882 },
16883 FastRecognizeScratch {
16884 predicate_context: None,
16885 visiting: &mut visiting,
16886 memo: &mut memo,
16887 expected: &mut expected,
16888 native_depth: 0,
16889 },
16890 );
16891
16892 assert!(outcomes.is_empty());
16893 assert_eq!(memo.len(), 1);
16894 assert!(memo.values().next().expect("memo entry").is_empty());
16895
16896 parser.clean_memo_mode = CleanMemoMode::Sparse;
16897 visiting.clear();
16898 memo.clear();
16899 expected = ExpectedTokens::default();
16900 let sparse_outcomes = parser.recognize_state_fast(
16901 &atn,
16902 FastRecognizeRequest {
16903 state_number: 1,
16904 stop_state: 2,
16905 index: 0,
16906 rule_start_index: 0,
16907 decision_start_index: None,
16908 precedence: 0,
16909 depth: 0,
16910 recovery_symbols: parser.empty_recovery_symbols(),
16911 recovery_state: None,
16912 },
16913 FastRecognizeScratch {
16914 predicate_context: None,
16915 visiting: &mut visiting,
16916 memo: &mut memo,
16917 expected: &mut expected,
16918 native_depth: 0,
16919 },
16920 );
16921
16922 assert!(sparse_outcomes.is_empty());
16923 assert!(memo.is_empty());
16924 }
16925
16926 #[test]
16927 fn wildcard_matches_non_eof_only() {
16928 let mut parser = mini_parser(vec![
16929 TestToken::new(1).with_text("x"),
16930 TestToken::eof("parser-test", 1, 1, 1),
16931 ]);
16932 let matched = parser.match_wildcard().expect("wildcard");
16933 assert_eq!(parser.node(matched).text(), "x");
16934 assert!(parser.match_wildcard().is_err());
16935 }
16936
16937 #[test]
16938 fn add_parse_child_records_match_even_without_tree_building() {
16939 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16944 let token = TestToken::new(1).with_text("x");
16945
16946 parser.set_build_parse_trees(false);
16947 let mut ctx = ParserRuleContext::new(0, 0);
16948 assert!(!ctx.has_matched_child());
16949 let child = parser.terminal_tree(token.id);
16950 parser.add_parse_child(&mut ctx, child);
16951 assert_eq!(ctx.child_count(), 0);
16953 assert_eq!(parser.parse_tree_storage().node_count(), 0);
16954 assert!(ctx.has_matched_child());
16956
16957 parser.set_build_parse_trees(true);
16959 let mut ctx = ParserRuleContext::new(0, 0);
16960 let child = parser.terminal_tree(token.id);
16961 parser.add_parse_child(&mut ctx, child);
16962 assert_eq!(ctx.child_count(), 1);
16963 assert!(ctx.has_matched_child());
16964 }
16965
16966 #[test]
16967 fn disabled_tree_building_does_not_grow_flat_storage() {
16968 let mut parser = mini_parser(vec![
16969 TestToken::new(1).with_text("x"),
16970 TestToken::new(1).with_text("y"),
16971 TestToken::eof("parser-test", 2, 1, 2),
16972 ]);
16973 parser.set_build_parse_trees(false);
16974 let mut context = ParserRuleContext::new(0, -1);
16975
16976 for _ in 0..2 {
16977 let child = parser.match_token(1).expect("token should match");
16978 parser.add_parse_child(&mut context, child);
16979 }
16980 let current = parser.input.lt_id(1).expect("EOF token");
16981 let error = parser.error_tree(current);
16982 parser.add_parse_child(&mut context, error);
16983 let root = parser.rule_node(context);
16984
16985 assert_eq!(
16986 parser.parse_tree_storage().stats(),
16987 ParseTreeStats::default()
16988 );
16989 assert!(
16990 parser
16991 .parse_tree_storage()
16992 .node(parser.token_store(), root)
16993 .is_none(),
16994 "the no-tree sentinel must not resolve to stored data"
16995 );
16996 }
16997
16998 #[test]
16999 fn disabled_tree_building_skips_recognition_rule_node_storage() {
17000 let atn = ordinary_star_loop_atn();
17001 let mut parser = mini_parser(repeated_x_tokens(3));
17002 parser.set_build_parse_trees(false);
17003
17004 parser
17005 .parse_atn_rule(&atn, 0)
17006 .expect("ordinary repetition should parse without a tree");
17007
17008 assert_eq!(parser.input.index(), 3);
17009 assert!(parser.recognition_arena.nodes.is_empty());
17010 assert!(parser.recognition_arena.seq_links.is_empty());
17011 assert!(parser.recognition_arena.deferred_nodes.is_empty());
17012 assert!(parser.recognition_arena.deferred_rules.is_empty());
17013 assert!(!parser.fast_token_nodes_enabled);
17014 assert!(parser.fast_recognize_scratch.memo.is_empty());
17015 }
17016
17017 #[test]
17018 fn parser_interprets_simple_atn_rule() {
17019 let atn = token_then_eof_atn();
17020 let mut parser = mini_parser(vec![
17021 TestToken::new(1).with_text("x"),
17022 TestToken::eof("parser-test", 1, 1, 1),
17023 ]);
17024
17025 let tree = parser
17026 .parse_atn_rule(&atn, 0)
17027 .expect("artificial parser rule should parse");
17028 assert_eq!(parser.node(tree).text(), "x<EOF>");
17029 assert_eq!(parser.number_of_syntax_errors(), 0);
17030 assert_eq!(
17031 parser
17032 .node(tree)
17033 .first_rule_stop(0)
17034 .expect("rule should stop at EOF")
17035 .token_type(),
17036 TOKEN_EOF
17037 );
17038
17039 let mut parser = mini_parser(vec![
17040 TestToken::new(1).with_text("x"),
17041 TestToken::eof("parser-test", 1, 1, 1),
17042 ]);
17043 let (tree, actions) = parser
17044 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17045 .expect("runtime-option parser rule should parse");
17046 assert!(actions.is_empty());
17047 assert_eq!(
17048 parser
17049 .node(tree)
17050 .first_rule_stop(0)
17051 .expect("rule should stop at EOF")
17052 .token_type(),
17053 TOKEN_EOF
17054 );
17055 }
17056
17057 #[test]
17058 fn runtime_options_default_ignores_noop_action_transitions() {
17059 let atn = noop_action_then_token_then_eof_atn();
17060 let mut parser = mini_parser(vec![
17061 TestToken::new(1).with_text("x"),
17062 TestToken::eof("parser-test", 1, 1, 1),
17063 ]);
17064
17065 let (tree, actions) = parser
17066 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17067 .expect("no-op parser action should not force action replay");
17068
17069 assert_eq!(parser.node(tree).text(), "x<EOF>");
17070 assert!(
17071 actions.is_empty(),
17072 "action_index=None transitions are ANTLR metadata, not replay actions"
17073 );
17074 assert_eq!(parser.number_of_syntax_errors(), 0);
17075 }
17076
17077 #[test]
17078 fn parser_exposes_buffered_token_stream_after_parse() {
17079 let atn = token_then_eof_atn();
17080 let mut parser = mini_parser(vec![
17081 TestToken::new(1).with_text("x"),
17082 TestToken::eof("parser-test", 1, 1, 1),
17083 ]);
17084
17085 let tree = parser
17086 .parse_atn_rule(&atn, 0)
17087 .expect("artificial parser rule should parse");
17088 assert_eq!(parser.node(tree).text(), "x<EOF>");
17089
17090 let stream = parser.token_stream();
17091 let source_index_after_parse = stream.token_source().index;
17092 let buffered = stream.tokens().collect::<Vec<_>>();
17093 assert_eq!(buffered.len(), 2);
17094 assert_eq!(buffered[0].text(), Some("x"));
17095 assert_eq!(buffered[0].token_id().index(), 0);
17096 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
17097 assert_eq!(stream.token_source().index, source_index_after_parse);
17098 drop(buffered);
17099
17100 let stream = parser.into_token_stream();
17101 assert_eq!(stream.token_source().index, source_index_after_parse);
17102 assert_eq!(
17103 stream.tokens().next().expect("first token").text(),
17104 Some("x")
17105 );
17106 assert_eq!(
17107 stream.tokens().nth(1).expect("EOF token").token_type(),
17108 TOKEN_EOF
17109 );
17110 }
17111
17112 #[test]
17113 fn parsed_file_exposes_all_buffered_tokens() {
17114 let atn = token_then_eof_atn();
17115 let mut parser = mini_parser(vec![
17116 TestToken::new(99)
17117 .with_text(" comment")
17118 .with_channel(HIDDEN_CHANNEL),
17119 TestToken::new(1).with_text("x"),
17120 TestToken::eof("parser-test", 9, 1, 9),
17121 ]);
17122
17123 let tree = parser
17124 .parse_atn_rule(&atn, 0)
17125 .expect("artificial parser rule should parse");
17126 let parsed = parser.into_parsed_file(tree);
17127
17128 insta::assert_debug_snapshot!(
17131 "parsed_file_exposes_all_buffered_tokens",
17132 parsed
17133 .tokens()
17134 .iter()
17135 .map(|token| (token.token_type(), token.channel(), token.text()))
17136 .collect::<Vec<_>>()
17137 );
17138 assert_eq!(parsed.tokens().into_iter().count(), 3);
17139 }
17140
17141 #[test]
17142 fn parser_syntax_error_count_tracks_interpreted_recovery() {
17143 let atn = token_then_eof_atn();
17144 let mut parser = mini_parser(vec![
17145 TestToken::new(1).with_text("x"),
17146 TestToken::new(2).with_text("y"),
17147 TestToken::eof("parser-test", 2, 1, 2),
17148 ]);
17149
17150 let tree = parser
17151 .parse_atn_rule(&atn, 0)
17152 .expect("invalid token should recover into an error node");
17153
17154 assert_eq!(parser.number_of_syntax_errors(), 1);
17155 assert_eq!(
17156 parser
17157 .node(tree)
17158 .first_error_token()
17159 .expect("recovery should embed an error token")
17160 .text(),
17161 Some("y")
17162 );
17163 }
17164
17165 #[test]
17166 fn parser_syntax_error_count_tracks_failed_interpreted_parse() {
17167 let atn = token_then_eof_atn();
17168 let mut parser = mini_parser(vec![
17169 TestToken::new(2).with_text("y"),
17170 TestToken::eof("parser-test", 1, 1, 1),
17171 ]);
17172
17173 let error = parser
17174 .parse_atn_rule(&atn, 0)
17175 .expect_err("start-rule mismatch should remain a parser error");
17176
17177 assert_eq!(parser.number_of_syntax_errors(), 1);
17178 assert!(matches!(error, AntlrError::ParserError { .. }));
17179 }
17180
17181 #[test]
17182 fn adaptive_direct_rule_uses_simulator_decision() {
17183 let atn = two_alt_decision_atn();
17184 let mut simulator = ParserAtnSimulator::new(&atn);
17185 let mut parser = mini_parser(vec![
17186 TestToken::new(2).with_text("y"),
17187 TestToken::eof("parser-test", 1, 1, 1),
17188 ]);
17189
17190 let tree = parser
17191 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
17192 .expect("direct adaptive rule should parse");
17193
17194 assert_eq!(parser.node(tree).text(), "y");
17195 assert_eq!(parser.input.index(), 1);
17196 }
17197
17198 #[test]
17199 fn adaptive_direct_rule_restores_input_on_fallback() {
17200 let atn = predicate_after_token_atn();
17201 let mut simulator = ParserAtnSimulator::new(&atn);
17202 let mut parser = mini_parser(vec![
17203 TestToken::new(1).with_text("x"),
17204 TestToken::new(2).with_text("y"),
17205 TestToken::eof("parser-test", 2, 1, 2),
17206 ]);
17207
17208 let tree = parser
17209 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
17210 .expect("fallback recognizer should parse");
17211
17212 assert_eq!(parser.node(tree).text(), "xy");
17213 assert_eq!(parser.input.index(), 2);
17214 let stats = parser.parse_tree_storage().stats();
17215 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
17216 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
17217 assert_eq!(stats.scratch_links, 0);
17218 }
17219
17220 #[test]
17221 fn unknown_predicate_policy_defaults_to_assume_true() {
17222 let atn = predicate_after_token_atn();
17223 let mut parser = mini_parser(vec![
17224 TestToken::new(1).with_text("x"),
17225 TestToken::new(2).with_text("y"),
17226 TestToken::eof("parser-test", 2, 1, 2),
17227 ]);
17228
17229 let (tree, _) = parser
17230 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17231 .expect("unknown predicate should pass under the default policy");
17232
17233 assert_eq!(parser.node(tree).text(), "xy");
17234 assert_eq!(parser.number_of_syntax_errors(), 0);
17235 }
17236
17237 #[test]
17238 fn private_context_alt_tracking_keeps_fast_predicate_recognition() {
17239 let atn = predicate_gated_same_lookahead_atn([0, 1]);
17240 let mut parser = mini_parser(vec![
17241 TestToken::new(1).with_text("x"),
17242 TestToken::eof("parser-test", 1, 1, 1),
17243 ]);
17244
17245 let (tree, _) = parser
17246 .parse_atn_rule_with_runtime_options(
17247 &atn,
17248 0,
17249 ParserRuntimeOptions {
17250 predicates: &[
17251 (0, 0, ParserPredicate::False),
17252 (0, 1, ParserPredicate::True),
17253 ],
17254 track_context_alt_numbers: true,
17255 ..ParserRuntimeOptions::default()
17256 },
17257 )
17258 .expect("the second predicate-gated alternative should match");
17259
17260 let root = parser.node(tree).as_rule().expect("entry result is a rule");
17261 insta::assert_debug_snapshot!(
17262 "private_context_alt_tracking_keeps_fast_predicate_recognition",
17263 (root.alt_number(), root.context_alt_number(), root.text())
17264 );
17265 assert_eq!(parser.number_of_syntax_errors(), 0);
17266 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
17267 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
17268 }
17269
17270 #[test]
17271 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
17272 let atn = token_then_eof_atn();
17276 let mut parser = mini_parser(vec![
17277 TestToken::new(1).with_text("x"),
17278 TestToken::eof("parser-test", 1, 1, 1),
17279 ]);
17280
17281 parser.unknown_predicate_hits.push((7, 3));
17283
17284 parser
17286 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17287 .expect("child rule parses");
17288
17289 let error = parser
17291 .take_unknown_semantic_error()
17292 .expect("parent's recorded coordinate must survive the nested interpreted parse");
17293 let AntlrError::Unsupported(message) = error else {
17294 panic!("expected AntlrError::Unsupported, got {error:?}");
17295 };
17296 assert!(message.contains("pred_index=3"), "message: {message}");
17297 }
17298
17299 #[test]
17300 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
17301 let atn = predicate_after_token_atn();
17302 let mut parser = mini_parser(vec![
17303 TestToken::new(1).with_text("x"),
17304 TestToken::new(2).with_text("y"),
17305 TestToken::eof("parser-test", 2, 1, 2),
17306 ]);
17307
17308 let result = parser.parse_atn_rule_with_runtime_options(
17309 &atn,
17310 0,
17311 ParserRuntimeOptions {
17312 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
17313 ..ParserRuntimeOptions::default()
17314 },
17315 );
17316
17317 assert!(
17318 result.is_err(),
17319 "the only path is predicate-guarded, so assume-false must fail the parse"
17320 );
17321 }
17322
17323 #[test]
17324 fn predicate_failure_message_keeps_semantic_recovery_path() {
17325 let atn = predicate_after_token_atn();
17326 let mut parser = mini_parser(vec![
17327 TestToken::new(1).with_text("x"),
17328 TestToken::new(2).with_text("y"),
17329 TestToken::eof("parser-test", 2, 1, 2),
17330 ]);
17331
17332 let (tree, _) = parser
17333 .parse_atn_rule_with_runtime_options(
17334 &atn,
17335 0,
17336 ParserRuntimeOptions {
17337 predicates: &[(
17338 0,
17339 0,
17340 ParserPredicate::FalseWithMessage {
17341 message: "predicate rejected input",
17342 },
17343 )],
17344 ..ParserRuntimeOptions::default()
17345 },
17346 )
17347 .expect("failure-message predicates recover through the semantic interpreter");
17348
17349 assert_eq!(parser.node(tree).text(), "xy");
17350 assert_eq!(parser.number_of_syntax_errors(), 1);
17351 assert!(
17352 parser.fast_predicate_cache.is_empty(),
17353 "failure-message predicates need the semantic interpreter's recovery outcome"
17354 );
17355 }
17356
17357 #[test]
17358 fn unknown_predicate_policy_error_names_the_coordinate() {
17359 let atn = predicate_after_token_atn();
17360 let mut parser = mini_parser(vec![
17361 TestToken::new(1).with_text("x"),
17362 TestToken::new(2).with_text("y"),
17363 TestToken::eof("parser-test", 2, 1, 2),
17364 ]);
17365
17366 let error = parser
17367 .parse_atn_rule_with_runtime_options(
17368 &atn,
17369 0,
17370 ParserRuntimeOptions {
17371 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17372 ..ParserRuntimeOptions::default()
17373 },
17374 )
17375 .expect_err("evaluating an unknown predicate under Error policy must fail");
17376
17377 let AntlrError::Unsupported(message) = error else {
17378 panic!("expected AntlrError::Unsupported, got {error:?}");
17379 };
17380 assert!(
17381 message.contains("unsupported semantic predicate"),
17382 "message should name the failure class: {message}"
17383 );
17384 assert!(
17385 message.contains("pred_index=0"),
17386 "message should carry the coordinate: {message}"
17387 );
17388 }
17389
17390 #[test]
17391 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
17392 let atn = predicate_after_token_atn();
17398 let mut parser = mini_parser(vec![
17399 TestToken::new(1).with_text("x"),
17400 TestToken::new(2).with_text("y"),
17401 TestToken::eof("parser-test", 2, 1, 2),
17402 ]);
17403
17404 parser
17405 .parse_atn_rule_with_runtime_options(
17406 &atn,
17407 0,
17408 ParserRuntimeOptions {
17409 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17410 ..ParserRuntimeOptions::default()
17411 },
17412 )
17413 .expect_err("first parse fails loud under the Error policy");
17414
17415 parser.reset_unknown_semantic_hits();
17420 assert!(
17421 parser.take_unknown_semantic_error().is_none(),
17422 "reset must drop stale unknown-predicate coordinates before a reused parse"
17423 );
17424 }
17425
17426 #[derive(Debug, Default)]
17427 struct RecordingHooks {
17428 predicates: Vec<(usize, usize, usize, Option<String>)>,
17429 actions: Vec<(usize, String, Option<String>)>,
17430 action_trees: Vec<Option<String>>,
17431 }
17432
17433 impl SemanticHooks for RecordingHooks {
17434 fn sempred<S>(
17435 &mut self,
17436 ctx: &mut ParserSemCtx<'_, S>,
17437 rule_index: usize,
17438 pred_index: usize,
17439 ) -> Option<bool>
17440 where
17441 S: TokenSource,
17442 {
17443 self.predicates.push((
17444 ctx.input_index(),
17445 rule_index,
17446 pred_index,
17447 ctx.token_text(1)
17448 .and_then(|token| token.text().map(str::to_owned)),
17449 ));
17450 Some(true)
17451 }
17452
17453 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
17454 where
17455 S: TokenSource,
17456 {
17457 self.actions.push((
17458 action.source_state(),
17459 ctx.action_text(),
17460 ctx.rule_name().map(str::to_owned),
17461 ));
17462 self.action_trees.push(ctx.tree().map(Node::text));
17463 true
17464 }
17465 }
17466
17467 #[derive(Debug, Default)]
17468 struct RejectingPredicateHooks {
17469 predicates: Vec<(usize, usize, usize, Option<String>)>,
17470 }
17471
17472 impl SemanticHooks for RejectingPredicateHooks {
17473 fn sempred<S>(
17474 &mut self,
17475 ctx: &mut ParserSemCtx<'_, S>,
17476 rule_index: usize,
17477 pred_index: usize,
17478 ) -> Option<bool>
17479 where
17480 S: TokenSource,
17481 {
17482 self.predicates.push((
17483 ctx.input_index(),
17484 rule_index,
17485 pred_index,
17486 ctx.token_text(1)
17487 .and_then(|token| token.text().map(str::to_owned)),
17488 ));
17489 Some(false)
17490 }
17491 }
17492
17493 #[test]
17494 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
17495 let atn = predicate_gated_same_lookahead_atn([0, 0]);
17496 let mut parser = mini_parser_with_hooks(
17497 vec![
17498 TestToken::new(1).with_text("x"),
17499 TestToken::eof("parser-test", 1, 1, 1),
17500 ],
17501 RecordingHooks::default(),
17502 );
17503
17504 let (tree, _) = parser
17505 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17506 .expect("both alternatives share one replay-safe predicate result");
17507
17508 assert_eq!(parser.node(tree).text(), "x<EOF>");
17509 assert_eq!(
17510 parser.semantic_hooks.predicates,
17511 vec![(0, 0, 0, Some("x".to_owned()))]
17512 );
17513 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
17514 }
17515
17516 #[test]
17517 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
17518 let atn = predicate_after_token_atn();
17519 let mut parser = mini_parser_with_hooks(
17520 vec![
17521 TestToken::new(1).with_text("x"),
17522 TestToken::new(2).with_text("y"),
17523 TestToken::eof("parser-test", 2, 1, 2),
17524 ],
17525 RecordingHooks::default(),
17526 );
17527
17528 let (tree, _) = parser
17529 .parse_atn_rule_with_runtime_options(
17530 &atn,
17531 0,
17532 ParserRuntimeOptions {
17533 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17534 ..ParserRuntimeOptions::default()
17535 },
17536 )
17537 .expect("hook supplies the missing predicate result");
17538
17539 assert_eq!(parser.node(tree).text(), "xy");
17540 assert_eq!(
17541 parser.semantic_hooks.predicates,
17542 vec![(1, 0, 0, Some("y".to_owned()))]
17543 );
17544 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
17545 }
17546
17547 #[test]
17548 fn runtime_options_default_preserves_semantic_hook_predicates() {
17549 let atn = predicate_after_token_atn();
17550 let mut parser = mini_parser_with_hooks(
17551 vec![
17552 TestToken::new(1).with_text("x"),
17553 TestToken::new(2).with_text("y"),
17554 TestToken::eof("parser-test", 2, 1, 2),
17555 ],
17556 RejectingPredicateHooks::default(),
17557 );
17558
17559 let result =
17560 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
17561
17562 assert!(
17563 result.is_err(),
17564 "default runtime options must not bypass semantic hooks for predicate ATNs"
17565 );
17566 assert_eq!(
17567 parser.semantic_hooks.predicates,
17568 vec![(1, 0, 0, Some("y".to_owned()))]
17569 );
17570 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
17571 }
17572
17573 #[test]
17574 fn semantic_hook_handles_committed_parser_action() {
17575 let atn = token_then_eof_atn();
17576 let mut parser = mini_parser_with_hooks(
17577 vec![
17578 TestToken::new(1).with_text("x"),
17579 TestToken::eof("parser-test", 1, 1, 1),
17580 ],
17581 RecordingHooks::default(),
17582 );
17583 let (tree, _) = parser
17584 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17585 .expect("rule parses before action hook is tested");
17586
17587 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17588 assert_eq!(
17589 parser.semantic_hooks.actions,
17590 vec![(42, "x".to_owned(), Some("s".to_owned()))]
17591 );
17592 assert_eq!(
17593 parser.semantic_hooks.action_trees,
17594 [Some("x<EOF>".to_owned())]
17595 );
17596 }
17597
17598 #[test]
17599 fn unhandled_committed_action_fails_loud_under_error_policy() {
17600 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17604 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
17605 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
17606
17607 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17609
17610 let error = parser
17611 .take_unknown_semantic_error()
17612 .expect("an unhandled committed action under Error policy must fail loud");
17613 let AntlrError::Unsupported(message) = error else {
17614 panic!("expected AntlrError::Unsupported, got {error:?}");
17615 };
17616 assert!(
17617 message.contains("unhandled semantic action") && message.contains("state=42"),
17618 "message should name the dropped action coordinate: {message}"
17619 );
17620
17621 let mut lenient =
17623 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17624 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
17625 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17626 assert!(lenient.take_unknown_semantic_error().is_none());
17627 }
17628
17629 #[test]
17630 fn translated_predicate_is_unaffected_by_error_policy() {
17631 let atn = predicate_after_token_atn();
17632 let mut parser = mini_parser(vec![
17633 TestToken::new(1).with_text("x"),
17634 TestToken::new(2).with_text("y"),
17635 TestToken::eof("parser-test", 2, 1, 2),
17636 ]);
17637
17638 let (tree, _) = parser
17639 .parse_atn_rule_with_runtime_options(
17640 &atn,
17641 0,
17642 ParserRuntimeOptions {
17643 predicates: &[(0, 0, ParserPredicate::True)],
17644 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17645 ..ParserRuntimeOptions::default()
17646 },
17647 )
17648 .expect("a predicate covered by the table is not an unknown coordinate");
17649
17650 assert_eq!(parser.node(tree).text(), "xy");
17651 }
17652
17653 fn hook_predicate_semantics() -> ParserSemantics {
17658 let mut ir = SemIr::new();
17659 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
17660 ParserSemantics {
17661 ir,
17662 predicates: vec![ParserSemanticPredicate {
17663 rule_index: 0,
17664 pred_index: 0,
17665 expr,
17666 failure_message: None,
17667 }],
17668 actions: Vec::new(),
17669 }
17670 }
17671
17672 #[derive(Debug, Default)]
17673 struct DecliningHooks;
17674
17675 impl SemanticHooks for DecliningHooks {}
17676
17677 #[test]
17678 fn semir_hook_none_falls_through_to_assume_true() {
17679 let atn = predicate_after_token_atn();
17680 let semantics = hook_predicate_semantics();
17681 let mut parser = mini_parser_with_hooks(
17682 vec![
17683 TestToken::new(1).with_text("x"),
17684 TestToken::new(2).with_text("y"),
17685 TestToken::eof("parser-test", 2, 1, 2),
17686 ],
17687 DecliningHooks,
17688 );
17689
17690 let (tree, _) = parser
17691 .parse_atn_rule_with_runtime_options(
17692 &atn,
17693 0,
17694 ParserRuntimeOptions {
17695 semantics: Some(&semantics),
17696 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
17697 ..ParserRuntimeOptions::default()
17698 },
17699 )
17700 .expect("a declined SemIR hook must pass under assume-true");
17701
17702 assert_eq!(parser.node(tree).text(), "xy");
17703 }
17704
17705 #[test]
17706 fn semir_hook_none_falls_through_to_assume_false() {
17707 let atn = predicate_after_token_atn();
17708 let semantics = hook_predicate_semantics();
17709 let mut parser = mini_parser_with_hooks(
17710 vec![
17711 TestToken::new(1).with_text("x"),
17712 TestToken::new(2).with_text("y"),
17713 TestToken::eof("parser-test", 2, 1, 2),
17714 ],
17715 DecliningHooks,
17716 );
17717
17718 let result = parser.parse_atn_rule_with_runtime_options(
17719 &atn,
17720 0,
17721 ParserRuntimeOptions {
17722 semantics: Some(&semantics),
17723 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
17724 ..ParserRuntimeOptions::default()
17725 },
17726 );
17727
17728 assert!(
17729 result.is_err(),
17730 "a declined SemIR hook must fail the only guarded path under assume-false"
17731 );
17732 }
17733
17734 #[test]
17735 fn semir_hook_none_records_coordinate_under_error_policy() {
17736 let atn = predicate_after_token_atn();
17737 let semantics = hook_predicate_semantics();
17738 let mut parser = mini_parser_with_hooks(
17739 vec![
17740 TestToken::new(1).with_text("x"),
17741 TestToken::new(2).with_text("y"),
17742 TestToken::eof("parser-test", 2, 1, 2),
17743 ],
17744 DecliningHooks,
17745 );
17746
17747 let error = parser
17748 .parse_atn_rule_with_runtime_options(
17749 &atn,
17750 0,
17751 ParserRuntimeOptions {
17752 semantics: Some(&semantics),
17753 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17754 ..ParserRuntimeOptions::default()
17755 },
17756 )
17757 .expect_err("a declined SemIR hook under Error policy must fail the parse");
17758
17759 let AntlrError::Unsupported(message) = error else {
17760 panic!("expected AntlrError::Unsupported, got {error:?}");
17761 };
17762 assert!(
17763 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
17764 "message should name the unresolved coordinate: {message}"
17765 );
17766 }
17767
17768 #[test]
17769 fn generated_direct_predicate_honors_installed_policy() {
17770 let semantics = hook_predicate_semantics();
17776 let context = ParserRuleContext::new(0, -1);
17777
17778 let mut assume_true =
17779 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17780 assert!(
17781 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
17782 &semantics, 0, 0, &context, 0
17783 ),
17784 "default AssumeTrue accepts a declined hook"
17785 );
17786 assert!(assume_true.take_unknown_semantic_error().is_none());
17787
17788 let mut error_policy =
17789 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17790 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
17791 assert!(
17792 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
17793 &semantics, 0, 0, &context, 0
17794 ),
17795 "Error policy rejects a declined hook on the generated-direct path"
17796 );
17797 let error = error_policy
17798 .take_unknown_semantic_error()
17799 .expect("Error policy records the unresolved coordinate for the generated path");
17800 let AntlrError::Unsupported(message) = error else {
17801 panic!("expected AntlrError::Unsupported, got {error:?}");
17802 };
17803 assert!(message.contains("pred_index=0"), "message: {message}");
17804 }
17805
17806 #[test]
17807 fn parser_rule_start_skips_leading_hidden_tokens() {
17808 let atn = token_then_eof_atn();
17809 let mut parser = mini_parser(vec![
17810 TestToken::new(99)
17811 .with_text(" ")
17812 .with_channel(HIDDEN_CHANNEL),
17813 TestToken::new(1).with_text("x"),
17814 TestToken::eof("parser-test", 2, 1, 2),
17815 ]);
17816
17817 let tree = parser
17818 .parse_atn_rule(&atn, 0)
17819 .expect("artificial parser rule should parse");
17820 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
17821 panic!("rule node should be present");
17822 };
17823 assert_eq!(
17824 rule.start()
17825 .expect("rule should have a start token")
17826 .token_type(),
17827 1
17828 );
17829 }
17830
17831 #[test]
17832 fn parser_action_after_eof_stops_at_eof_token() {
17833 let atn = eof_then_action_atn();
17834 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
17835
17836 let (_, actions) = parser
17837 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17838 .expect("EOF action rule should parse");
17839
17840 assert_eq!(actions.len(), 1);
17841 assert_eq!(actions[0].stop_index(), Some(0));
17842 assert_eq!(
17843 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
17844 ""
17845 );
17846 }
17847
17848 #[test]
17849 fn after_action_stop_uses_rule_context_stop_not_cursor() {
17850 let mut id = TestToken::new(1).with_text("x");
17855 id.set_token_index(0);
17856 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
17857 eof.set_token_index(1);
17858 let mut parser = mini_parser(vec![id.clone(), eof]);
17859 parser.consume();
17861 assert_eq!(parser.la(1), TOKEN_EOF);
17862
17863 let mut ctx = ParserRuleContext::new(0, 0);
17866 parser.set_context_stop(
17867 &mut ctx,
17868 parser.token_id_at(0).expect("ID token should be buffered"),
17869 );
17870 let tree = parser.rule_node(ctx);
17871
17872 let current_index = parser.input.index();
17873 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
17875 assert_eq!(
17877 parser.after_action_stop_index_for_tree(tree, current_index),
17878 Some(0)
17879 );
17880 }
17881
17882 #[test]
17883 fn after_action_start_uses_rule_context_start_not_cursor() {
17884 let mut parser = mini_parser(vec![
17889 TestToken::new(9)
17890 .with_text(" ")
17891 .with_channel(HIDDEN_CHANNEL),
17892 TestToken::new(9)
17893 .with_text(" ")
17894 .with_channel(HIDDEN_CHANNEL),
17895 TestToken::new(1).with_text("x"),
17896 TestToken::eof("parser-test", 3, 1, 3),
17897 ]);
17898
17899 let mut ctx = ParserRuleContext::new(0, 0);
17900 parser.set_context_start(
17901 &mut ctx,
17902 parser.token_id_at(2).expect("ID token should be buffered"),
17903 );
17904 let tree = parser.rule_node(ctx);
17905
17906 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
17909
17910 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
17912 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
17913 }
17914
17915 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
17916 FastRecognizeOutcome {
17917 index,
17918 consumed_eof,
17919 diagnostics: DiagnosticSeqId::EMPTY,
17920 deferred_nodes: FastDeferredNodeId::EMPTY,
17921 nodes: NodeSeqId(marker),
17922 }
17923 }
17924
17925 #[test]
17926 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
17927 let mut outcomes = vec![
17928 clean_fast_outcome(4, false, 0),
17929 clean_fast_outcome(2, false, 1),
17930 clean_fast_outcome(4, false, 2),
17931 clean_fast_outcome(4, true, 3),
17932 clean_fast_outcome(2, false, 4),
17933 ];
17934 let mut scratch = FastOutcomeDedupScratch::default();
17935
17936 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17937
17938 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
17939 assert_eq!(
17940 outcomes
17941 .iter()
17942 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
17943 .collect::<Vec<_>>(),
17944 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
17945 );
17946 assert!(scratch.dense_words.is_empty());
17947 assert!(scratch.sparse_keys.is_empty());
17948 }
17949
17950 #[test]
17951 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
17952 let mut scratch = FastOutcomeDedupScratch::default();
17953 let mut outcomes = (100..109)
17954 .flat_map(|index| {
17955 [
17956 clean_fast_outcome(
17957 index,
17958 false,
17959 u32::try_from(index).expect("test index fits in u32"),
17960 ),
17961 clean_fast_outcome(index, false, u32::MAX),
17962 ]
17963 })
17964 .collect();
17965
17966 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
17967
17968 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
17969 assert_eq!(outcomes.len(), 9);
17970 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
17971 let dense_capacity = scratch.dense_words.capacity();
17972
17973 let mut reused = (1_000..1_009)
17974 .map(|index| {
17975 clean_fast_outcome(
17976 index,
17977 false,
17978 u32::try_from(index).expect("test index fits in u32"),
17979 )
17980 })
17981 .collect();
17982 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
17983
17984 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
17985 assert_eq!(reused.len(), 9);
17986 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
17987 }
17988
17989 #[test]
17990 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
17991 let mut scratch = FastOutcomeDedupScratch::default();
17992 let sparse_indexes = [
17993 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
17994 ];
17995 let mut outcomes = sparse_indexes
17996 .into_iter()
17997 .chain([400_000])
17998 .enumerate()
17999 .map(|(marker, index)| {
18000 clean_fast_outcome(
18001 index,
18002 false,
18003 u32::try_from(marker).expect("test marker fits in u32"),
18004 )
18005 })
18006 .collect();
18007
18008 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
18009
18010 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
18011 assert_eq!(outcomes.len(), sparse_indexes.len());
18012 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
18013 let sparse_capacity = scratch.sparse_keys.capacity();
18014
18015 let mut reused = sparse_indexes
18016 .into_iter()
18017 .map(|index| {
18018 clean_fast_outcome(
18019 index,
18020 false,
18021 u32::try_from(index).expect("test index fits in u32"),
18022 )
18023 })
18024 .collect();
18025 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
18026
18027 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
18028 assert_eq!(reused.len(), sparse_indexes.len());
18029 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
18030 }
18031
18032 #[test]
18033 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
18034 let mut scratch = FastOutcomeDedupScratch::default();
18035 scratch
18036 .sparse_keys
18037 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
18038 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
18039 let mut outcomes = (0..9)
18040 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
18041 .collect();
18042
18043 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
18044
18045 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
18046 assert!(scratch.sparse_keys.is_empty());
18047 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
18048 }
18049
18050 #[test]
18051 fn fast_outcome_selection_respects_sll_tie_order() {
18052 let mut arena = RecognitionArena::default();
18053 let first = FastRecognizeOutcome {
18054 index: 1,
18055 consumed_eof: false,
18056 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
18057 line: 1,
18058 column: 0,
18059 message: "mismatched input 'x'".to_owned(),
18060 offending: None,
18061 }]),
18062 deferred_nodes: FastDeferredNodeId::EMPTY,
18063 nodes: NodeSeqId::EMPTY,
18064 };
18065 let second = FastRecognizeOutcome {
18066 index: first.index,
18067 consumed_eof: first.consumed_eof,
18068 diagnostics: DiagnosticSeqId::EMPTY,
18069 deferred_nodes: FastDeferredNodeId::EMPTY,
18070 nodes: NodeSeqId::EMPTY,
18071 };
18072
18073 let selected = select_best_fast_outcome(
18074 [first, second].into_iter(),
18075 PredictionMode::Sll,
18076 None,
18077 |_| panic!("caller-follow token probe should not run"),
18078 &arena,
18079 )
18080 .expect("one outcome should be selected");
18081 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
18082 let eof_second = FastRecognizeOutcome {
18083 index: second.index,
18084 consumed_eof: true,
18085 diagnostics: DiagnosticSeqId::EMPTY,
18086 deferred_nodes: FastDeferredNodeId::EMPTY,
18087 nodes: NodeSeqId::EMPTY,
18088 };
18089 let selected = select_best_fast_outcome(
18090 [first, eof_second].into_iter(),
18091 PredictionMode::Sll,
18092 None,
18093 |_| panic!("caller-follow token probe should not run"),
18094 &arena,
18095 )
18096 .expect("one outcome should be selected");
18097 assert!(!selected.consumed_eof);
18098 let selected = select_best_fast_outcome(
18099 [first, second].into_iter(),
18100 PredictionMode::Ll,
18101 None,
18102 |_| panic!("caller-follow token probe should not run"),
18103 &arena,
18104 )
18105 .expect("one outcome should be selected");
18106 assert!(selected.diagnostics.is_empty());
18107 }
18108
18109 #[test]
18110 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
18111 let mut arena = RecognitionArena::default();
18112 let first = FastRecognizeOutcome {
18113 index: 3,
18114 consumed_eof: false,
18115 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
18116 line: 1,
18117 column: 0,
18118 message: "mismatched input 'x' expecting 'a'".to_owned(),
18119 offending: None,
18120 }]),
18121 deferred_nodes: FastDeferredNodeId::EMPTY,
18122 nodes: NodeSeqId::EMPTY,
18123 };
18124 let same_rank = FastRecognizeOutcome {
18125 index: first.index,
18126 consumed_eof: first.consumed_eof,
18127 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
18128 line: 1,
18129 column: 0,
18130 message: "mismatched input 'x' expecting 'b'".to_owned(),
18131 offending: None,
18132 }]),
18133 deferred_nodes: FastDeferredNodeId::EMPTY,
18134 nodes: NodeSeqId::EMPTY,
18135 };
18136 let better_rank = FastRecognizeOutcome {
18137 index: first.index,
18138 consumed_eof: first.consumed_eof,
18139 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
18140 line: 1,
18141 column: 0,
18142 message: "missing 'a' at 'x'".to_owned(),
18143 offending: None,
18144 }]),
18145 deferred_nodes: FastDeferredNodeId::EMPTY,
18146 nodes: NodeSeqId::EMPTY,
18147 };
18148 let mut outcomes = vec![first, same_rank, better_rank];
18149
18150 dedupe_fast_outcomes(&mut outcomes, &arena);
18151
18152 assert_eq!(outcomes.len(), 2);
18153 assert_eq!(
18154 arena
18155 .diagnostics(outcomes[0].diagnostics)
18156 .next()
18157 .expect("first diagnostic")
18158 .message,
18159 "mismatched input 'x' expecting 'a'"
18160 );
18161 assert_eq!(
18162 arena
18163 .diagnostics(outcomes[1].diagnostics)
18164 .next()
18165 .expect("second diagnostic")
18166 .message,
18167 "missing 'a' at 'x'"
18168 );
18169 }
18170
18171 #[test]
18172 fn fast_outcome_selection_prefers_generated_caller_follow() {
18173 let arena = RecognitionArena::default();
18174 let earlier = FastRecognizeOutcome {
18175 index: 7,
18176 consumed_eof: false,
18177 diagnostics: DiagnosticSeqId::EMPTY,
18178 deferred_nodes: FastDeferredNodeId::EMPTY,
18179 nodes: NodeSeqId::EMPTY,
18180 };
18181 let later = FastRecognizeOutcome {
18182 index: 8,
18183 consumed_eof: false,
18184 diagnostics: DiagnosticSeqId::EMPTY,
18185 deferred_nodes: FastDeferredNodeId::EMPTY,
18186 nodes: NodeSeqId::EMPTY,
18187 };
18188 let mut follow = TokenBitSet::default();
18189 follow.insert(5);
18190
18191 let selected = select_best_fast_outcome(
18192 [later, earlier].into_iter(),
18193 PredictionMode::Ll,
18194 Some(&follow),
18195 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
18196 &arena,
18197 )
18198 .expect("one outcome should be selected");
18199 assert_eq!(selected.index, 7);
18200
18201 let selected = select_best_fast_outcome(
18202 [later, earlier].into_iter(),
18203 PredictionMode::Ll,
18204 Some(&follow),
18205 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
18206 &arena,
18207 )
18208 .expect("one outcome should be selected");
18209 assert_eq!(selected.index, 8);
18210
18211 let indented_next_statement = FastRecognizeOutcome {
18212 index: 9,
18213 consumed_eof: false,
18214 diagnostics: DiagnosticSeqId::EMPTY,
18215 deferred_nodes: FastDeferredNodeId::EMPTY,
18216 nodes: NodeSeqId::EMPTY,
18217 };
18218 let selected = select_best_fast_outcome(
18219 [indented_next_statement, earlier].into_iter(),
18220 PredictionMode::Ll,
18221 Some(&follow),
18222 |index| {
18223 let is_boundary = index == 7;
18224 let is_boundary_gap = matches!(index, 7 | 8);
18225 (
18226 if index == 7 { 5 } else { TOKEN_EOF },
18227 is_boundary,
18228 is_boundary_gap,
18229 )
18230 },
18231 &arena,
18232 )
18233 .expect("one outcome should be selected");
18234 assert_eq!(selected.index, 7);
18235
18236 let continuation = FastRecognizeOutcome {
18237 index: 10,
18238 consumed_eof: false,
18239 diagnostics: DiagnosticSeqId::EMPTY,
18240 deferred_nodes: FastDeferredNodeId::EMPTY,
18241 nodes: NodeSeqId::EMPTY,
18242 };
18243 let selected = select_best_fast_outcome(
18244 [continuation, earlier].into_iter(),
18245 PredictionMode::Ll,
18246 Some(&follow),
18247 |index| {
18248 let is_boundary = matches!(index, 7 | 9);
18249 (
18250 if index == 7 { 5 } else { TOKEN_EOF },
18251 is_boundary,
18252 is_boundary,
18253 )
18254 },
18255 &arena,
18256 )
18257 .expect("one outcome should be selected");
18258 assert_eq!(selected.index, 10);
18259
18260 let selected = select_best_fast_outcome(
18261 [earlier, later].into_iter(),
18262 PredictionMode::Sll,
18263 Some(&follow),
18264 |_| panic!("caller-follow token probe should not run in SLL mode"),
18265 &arena,
18266 )
18267 .expect("one outcome should be selected");
18268 assert_eq!(selected.index, 8);
18269 }
18270
18271 #[test]
18272 fn caller_follow_boundary_text_requires_separator_shape() {
18273 assert!(is_caller_follow_boundary_text(";"));
18274 assert!(is_caller_follow_boundary_text("\n"));
18275 assert!(is_caller_follow_boundary_text("\r\n "));
18276 assert!(is_caller_follow_boundary_text(";\n"));
18277 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
18278 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
18279 assert!(!is_caller_follow_boundary_text("identifier"));
18280 assert!(is_caller_follow_boundary_gap_text(" \t "));
18281 assert!(is_caller_follow_boundary_gap_text("\n "));
18282 assert!(is_caller_follow_boundary_gap_text(";\t"));
18283 assert!(!is_caller_follow_boundary_gap_text(
18284 "\"\"\"line1\nline2\"\"\""
18285 ));
18286 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
18287 }
18288
18289 #[test]
18290 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
18291 let mut parser = mini_parser(vec![
18292 TestToken::new(5).with_text("\n"),
18293 TestToken::new(6)
18294 .with_text("// comment\n")
18295 .with_channel(HIDDEN_CHANNEL),
18296 TestToken::new(1).with_text("x"),
18297 TestToken::eof("parser-test", 1, 2, 0),
18298 ]);
18299
18300 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
18301 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
18302 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
18303 }
18304
18305 #[test]
18306 fn caller_follow_token_info_uses_stream_visible_channel() {
18307 let source = Source {
18308 tokens: vec![
18309 TestToken::new(5).with_text("\n").with_channel(2),
18310 TestToken::new(1).with_text("x").with_channel(2),
18311 TestToken::new(6)
18312 .with_text("// comment\n")
18313 .with_channel(HIDDEN_CHANNEL),
18314 TestToken::eof("parser-test", 1, 2, 0),
18315 ],
18316 index: 0,
18317 };
18318 let data = RecognizerData::new(
18319 "Mini.g4",
18320 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18321 );
18322 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
18323
18324 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
18325 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
18326 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
18327 }
18328
18329 #[test]
18330 fn reset_per_parse_caches_clears_state_expected_token_cache() {
18331 let atn = token_then_eof_atn();
18332 let mut parser = mini_parser(Vec::new());
18333
18334 let _ = parser.cached_state_expected_token_set(&atn, 0);
18335 assert!(!parser.state_expected_token_cache.is_empty());
18336
18337 parser.reset_per_parse_caches();
18338 assert!(parser.state_expected_token_cache.is_empty());
18339 }
18340
18341 #[test]
18342 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
18343 let cyclic = epsilon_cycle_atn();
18344 let acyclic = token_then_eof_atn();
18345 let mut parser = mini_parser(Vec::new());
18346
18347 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
18348 assert_eq!(
18349 parser.empty_cycle_cache_atn,
18350 Some(SharedAtnCacheKey::for_atn(&cyclic))
18351 );
18352 assert_eq!(parser.empty_cycle_cache[1], Some(true));
18353
18354 parser.reset_per_parse_caches();
18355 assert_eq!(parser.empty_cycle_cache[1], Some(true));
18356 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
18357
18358 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
18359 assert_eq!(
18360 parser.empty_cycle_cache_atn,
18361 Some(SharedAtnCacheKey::for_atn(&acyclic))
18362 );
18363 assert_eq!(parser.empty_cycle_cache[1], Some(false));
18364 }
18365
18366 #[test]
18367 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
18368 let source = Source {
18369 tokens: vec![
18370 TestToken::new(1).with_text("x"),
18371 TestToken::eof("parser-test", 1, 1, 1),
18372 ],
18373 index: 0,
18374 };
18375 let data = RecognizerData::new(
18376 "Mini.g4",
18377 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18378 );
18379 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
18380 let expected = ExpectedTokens {
18381 index: Some(0),
18382 symbols: BTreeSet::new(),
18383 no_viable: None,
18384 };
18385
18386 let (_, message) = parser.expected_error_message(0, 0, &expected);
18387
18388 assert_eq!(message, "mismatched input 'x'");
18389 }
18390
18391 #[test]
18392 fn eof_rule_stop_index_points_at_eof_token() {
18393 let source = Source {
18394 tokens: vec![
18395 TestToken::new(1).with_text("x"),
18396 TestToken::eof("parser-test", 1, 1, 1),
18397 ],
18398 index: 0,
18399 };
18400 let data = RecognizerData::new(
18401 "Mini.g4",
18402 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18403 );
18404 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
18405
18406 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
18407 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
18408 }
18409
18410 #[test]
18411 fn generated_parser_action_uses_current_rule_stop_boundary() {
18412 let mut parser = mini_parser(vec![
18413 TestToken::new(1).with_text("x"),
18414 TestToken::eof("parser-test", 1, 1, 1),
18415 ]);
18416
18417 parser.match_token(1).expect("token should match");
18418 let action = parser.parser_action_at_current(7, 0, 0, false);
18419 assert_eq!(action.source_state(), 7);
18420 assert_eq!(action.rule_index(), 0);
18421 assert_eq!(action.start_index(), 0);
18422 assert_eq!(action.stop_index(), Some(0));
18423
18424 parser.match_eof().expect("EOF should match");
18425 let action = parser.parser_action_at_current(8, 0, 0, true);
18426 assert_eq!(action.stop_index(), Some(1));
18427 }
18428
18429 #[test]
18430 fn folds_left_recursive_boundary_into_rule_node() {
18431 let mut arena = RecognitionArena::default();
18432 let first = arena.push_node(ArenaRecognizedNode::Token {
18433 token: TokenId::try_from(0).expect("test token ID"),
18434 });
18435 let boundary = arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
18436 rule_index: 1,
18437 alt_number: 3,
18438 });
18439 let second = arena.push_node(ArenaRecognizedNode::Token {
18440 token: TokenId::try_from(1).expect("test token ID"),
18441 });
18442 let mut nodes = NodeSeqId::EMPTY;
18443 for node in [first, boundary, second].into_iter().rev() {
18444 nodes = arena.prepend(nodes, node);
18445 }
18446
18447 let folded = arena.fold_left_recursive_boundaries(nodes);
18448 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
18449
18450 assert_eq!(folded_nodes.len(), 2);
18451 let ArenaRecognizedNode::Rule {
18452 rule_index,
18453 invoking_state,
18454 alt_number,
18455 start_index,
18456 stop_index,
18457 children,
18458 ..
18459 } = arena.node(folded_nodes[0])
18460 else {
18461 panic!("first folded node should be a rule");
18462 };
18463 insta::assert_debug_snapshot!(
18467 "folds_left_recursive_boundary_into_rule_node",
18468 (
18469 rule_index,
18470 invoking_state,
18471 alt_number,
18472 start_index,
18473 stop_index
18474 )
18475 );
18476 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
18477 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
18478
18479 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
18480 assert_eq!(
18481 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18482 (4, 3, 1)
18483 );
18484 assert_eq!(
18485 (stats.total_links, stats.live_links, stats.dead_links),
18486 (9, 3, 6)
18487 );
18488 }
18489
18490 #[test]
18491 fn recognition_arena_reports_live_dead_and_retained_capacity() {
18492 let mut arena = RecognitionArena::default();
18493 let token = arena.push_node(ArenaRecognizedNode::Token {
18494 token: TokenId::try_from(0).expect("test token ID"),
18495 });
18496 let extra = arena.push_extra(RecognitionExtra::MissingToken {
18497 token_type: 2,
18498 at_index: 1,
18499 text: "<missing X>".to_owned(),
18500 });
18501 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
18502 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
18503 token: TokenId::try_from(1).expect("test token ID"),
18504 });
18505 let mut live = NodeSeqId::EMPTY;
18506 live = arena.prepend(live, missing);
18507 live = arena.prepend(live, token);
18508 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
18509 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
18510 line: 1,
18511 column: 0,
18512 message: "missing X".to_owned(),
18513 offending: None,
18514 }]);
18515 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
18516 line: 1,
18517 column: 1,
18518 message: "discarded".to_owned(),
18519 offending: None,
18520 }]);
18521 let deferred_children = arena.deferred_fragment(live);
18522 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
18523 rule_index: 0,
18524 invoking_state: -1,
18525 start_index: 0,
18526 stop_index: Some(1),
18527 deferred_children,
18528 children: NodeSeqId::EMPTY,
18529 });
18530
18531 let stats = arena.stats(live, live_diagnostics);
18532
18533 assert_eq!(
18534 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18535 (3, 2, 1)
18536 );
18537 assert_eq!(
18538 (stats.total_links, stats.live_links, stats.dead_links),
18539 (5, 3, 2)
18540 );
18541 assert_eq!(
18542 (stats.total_extras, stats.live_extras, stats.dead_extras),
18543 (3, 2, 1)
18544 );
18545 assert!(size_of::<SeqLink>() <= 8);
18546 assert!(size_of::<DiagnosticLink>() <= 8);
18547 assert!(size_of::<FastDeferredNode>() <= 12);
18548 assert!(size_of::<FastDeferredRule>() <= 28);
18549 assert!(size_of::<FastRecognizeOutcome>() <= 24);
18550 let capacities = (
18551 stats.node_capacity,
18552 stats.link_capacity,
18553 stats.extra_capacity,
18554 );
18555 let deferred_capacities = (
18556 arena.deferred_nodes.capacity(),
18557 arena.deferred_rules.capacity(),
18558 );
18559
18560 arena.reset();
18561 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
18562 assert_eq!(
18563 (reset.total_nodes, reset.total_links, reset.total_extras),
18564 (0, 0, 0)
18565 );
18566 assert_eq!(
18567 (
18568 reset.node_capacity,
18569 reset.link_capacity,
18570 reset.extra_capacity,
18571 ),
18572 capacities
18573 );
18574 assert!(arena.deferred_nodes.is_empty());
18575 assert!(arena.deferred_rules.is_empty());
18576 assert_eq!(
18577 (
18578 arena.deferred_nodes.capacity(),
18579 arena.deferred_rules.capacity(),
18580 ),
18581 deferred_capacities
18582 );
18583 }
18584
18585 #[test]
18586 fn parser_computes_recognition_arena_stats_on_demand() {
18587 let mut parser = mini_parser(Vec::new());
18588 let live = parser
18589 .recognition_arena
18590 .push_node(ArenaRecognizedNode::Token {
18591 token: TokenId::try_from(0).expect("test token ID"),
18592 });
18593 let discarded = parser
18594 .recognition_arena
18595 .push_node(ArenaRecognizedNode::ErrorToken {
18596 token: TokenId::try_from(1).expect("test token ID"),
18597 });
18598 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
18599 let _discarded_root = parser
18600 .recognition_arena
18601 .prepend(NodeSeqId::EMPTY, discarded);
18602 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
18603
18604 let stats = parser.recognition_arena_stats();
18605
18606 assert_eq!(
18607 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18608 (2, 1, 1)
18609 );
18610 assert_eq!(
18611 (stats.total_links, stats.live_links, stats.dead_links),
18612 (2, 1, 1)
18613 );
18614 }
18615
18616 #[test]
18617 fn recognition_arena_drops_capacity_above_retention_limit() {
18618 let mut storage = Vec::<u8>::with_capacity(4);
18619 storage.extend([1, 2, 3]);
18620
18621 reset_arena_vec(&mut storage, 3);
18622
18623 assert!(storage.is_empty());
18624 assert_eq!(storage.capacity(), 0);
18625 }
18626
18627 #[test]
18628 fn recognition_arena_concatenates_diagnostics_in_source_order() {
18629 let mut arena = RecognitionArena::default();
18630 let prefix = arena.diagnostic_sequence([
18631 ParserDiagnostic {
18632 line: 1,
18633 column: 0,
18634 message: "first".to_owned(),
18635 offending: None,
18636 },
18637 ParserDiagnostic {
18638 line: 1,
18639 column: 1,
18640 message: "second".to_owned(),
18641 offending: None,
18642 },
18643 ]);
18644 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
18645 line: 1,
18646 column: 2,
18647 message: "third".to_owned(),
18648 offending: None,
18649 }]);
18650 let extras_before = arena.extras.len();
18651
18652 let combined = arena.concat_diagnostics(prefix, suffix);
18653 let messages = arena
18654 .diagnostics(combined)
18655 .map(|diagnostic| diagnostic.message.as_str())
18656 .collect::<Vec<_>>();
18657
18658 assert_eq!(messages, ["first", "second", "third"]);
18659 assert_eq!(arena.extras.len(), extras_before);
18660 }
18661
18662 #[test]
18663 fn outcome_ties_keep_later_non_recursive_alternative() {
18664 let arena = RecognitionArena::default();
18665 let first = RecognizeOutcome {
18666 index: 1,
18667 consumed_eof: false,
18668 alt_number: 0,
18669 member_values: BTreeMap::new(),
18670 return_values: BTreeMap::new(),
18671 diagnostics: DiagnosticSeqId::EMPTY,
18672 decisions: Vec::new(),
18673 actions: vec![ParserAction::new(1, 0, 0, None)],
18674 nodes: NodeSeqId::EMPTY,
18675 };
18676 let second = RecognizeOutcome {
18677 actions: vec![ParserAction::new(2, 0, 0, None)],
18678 ..first.clone()
18679 };
18680
18681 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18682 .expect("one outcome should be selected");
18683 assert_eq!(selected.actions[0].source_state(), 2);
18684 }
18685
18686 #[test]
18687 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
18688 let arena = RecognitionArena::default();
18689 let first = RecognizeOutcome {
18690 index: 1,
18691 consumed_eof: false,
18692 alt_number: 0,
18693 member_values: BTreeMap::new(),
18694 return_values: BTreeMap::new(),
18695 diagnostics: DiagnosticSeqId::EMPTY,
18696 decisions: Vec::new(),
18697 actions: vec![ParserAction::new(1, 0, 0, None)],
18698 nodes: NodeSeqId::EMPTY,
18699 };
18700 let second = RecognizeOutcome {
18701 actions: vec![
18702 ParserAction::new(2, 0, 0, None),
18703 ParserAction::new(3, 0, 0, None),
18704 ],
18705 ..first.clone()
18706 };
18707
18708 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
18709 .expect("one outcome should be selected");
18710 assert_eq!(selected.actions.len(), 2);
18711 }
18712
18713 #[test]
18714 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
18715 let arena = RecognitionArena::default();
18716 let first = RecognizeOutcome {
18717 index: 7,
18718 consumed_eof: false,
18719 alt_number: 0,
18720 member_values: BTreeMap::new(),
18721 return_values: BTreeMap::new(),
18722 diagnostics: DiagnosticSeqId::EMPTY,
18723 decisions: vec![1, 0],
18724 actions: vec![
18725 ParserAction::new(23, 2, 2, Some(4)),
18726 ParserAction::new(23, 2, 0, Some(6)),
18727 ],
18728 nodes: NodeSeqId::EMPTY,
18729 };
18730 let second = RecognizeOutcome {
18731 decisions: vec![0, 1],
18732 actions: vec![
18733 ParserAction::new(23, 2, 2, Some(6)),
18734 ParserAction::new(23, 2, 0, Some(6)),
18735 ],
18736 ..first.clone()
18737 };
18738
18739 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18740 .expect("one outcome should be selected");
18741 assert_eq!(selected.actions[0].stop_index(), Some(6));
18742 }
18743
18744 #[test]
18745 fn outcome_ties_keep_first_recursive_tree_shape() {
18746 let mut arena = RecognitionArena::default();
18747 let token = arena.push_node(ArenaRecognizedNode::Token {
18748 token: TokenId::try_from(0).expect("test token ID"),
18749 });
18750 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
18751 let inner = arena.push_node(ArenaRecognizedNode::Rule {
18752 rule_index: 1,
18753 invoking_state: -1,
18754 alt_number: 0,
18755 start_index: 0,
18756 stop_index: Some(0),
18757 return_values: None,
18758 children: token_children,
18759 });
18760 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
18761 let outer = arena.push_node(ArenaRecognizedNode::Rule {
18762 rule_index: 1,
18763 invoking_state: -1,
18764 alt_number: 0,
18765 start_index: 0,
18766 stop_index: Some(0),
18767 return_values: None,
18768 children: inner_children,
18769 });
18770 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
18771 let first = RecognizeOutcome {
18772 index: 1,
18773 consumed_eof: false,
18774 alt_number: 0,
18775 member_values: BTreeMap::new(),
18776 return_values: BTreeMap::new(),
18777 diagnostics: DiagnosticSeqId::EMPTY,
18778 decisions: Vec::new(),
18779 actions: vec![ParserAction::new(1, 0, 0, None)],
18780 nodes: recursive_nodes,
18781 };
18782 let second = RecognizeOutcome {
18783 index: 1,
18784 consumed_eof: false,
18785 alt_number: 0,
18786 member_values: BTreeMap::new(),
18787 return_values: BTreeMap::new(),
18788 diagnostics: DiagnosticSeqId::EMPTY,
18789 decisions: Vec::new(),
18790 actions: vec![ParserAction::new(2, 0, 0, None)],
18791 nodes: recursive_nodes,
18792 };
18793
18794 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18795 .expect("one outcome should be selected");
18796 assert_eq!(selected.actions[0].source_state(), 1);
18797 }
18798
18799 #[test]
18800 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
18801 let mut arena = RecognitionArena::default();
18802 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
18803 line: 1,
18804 column: 3,
18805 message: "missing 'Y' at '<EOF>'".to_owned(),
18806 offending: None,
18807 }]);
18808 let first_alt = RecognizeOutcome {
18809 index: 2,
18810 consumed_eof: true,
18811 alt_number: 0,
18812 member_values: BTreeMap::new(),
18813 return_values: BTreeMap::new(),
18814 diagnostics: recovered_diagnostics,
18815 decisions: vec![0],
18816 actions: vec![ParserAction::new(1, 0, 0, None)],
18817 nodes: NodeSeqId::EMPTY,
18818 };
18819 let second_alt = RecognizeOutcome {
18820 diagnostics: DiagnosticSeqId::EMPTY,
18821 decisions: vec![1],
18822 actions: vec![ParserAction::new(2, 0, 0, None)],
18823 ..first_alt.clone()
18824 };
18825
18826 let selected = select_best_outcome(
18827 [second_alt, first_alt].into_iter(),
18828 PredictionMode::Sll,
18829 &arena,
18830 )
18831 .expect("one outcome should be selected");
18832 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
18833 assert_eq!(selected.decisions, [0]);
18834 }
18835}