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 ParserAtnSimulatorError, ParserSemanticCandidate,
79};
80use crate::atn::parser_atn::{
81 ParserAtn as Atn, ParserAtnState as AtnState, ParserIntervalSet, ParserTransition,
82 ParserTransitionData as Transition, ParserTransitionKind,
83};
84#[cfg(test)]
85use crate::atn::parser_atn::{ParserAtnBuilder, ParserTransitionSpec};
86use crate::char_stream::CharStream;
87use crate::errors::{AntlrError, SyntaxErrorEvent};
88use crate::int_stream::IntStream;
89use crate::lexer::{LexerCustomAction, LexerLifecycleCtx, LexerSemCtx};
90use crate::prediction::SemanticContext;
91use crate::recognizer::{Recognizer, RecognizerData};
92use crate::semir::{self, AStmt, ArithOp, CmpOp, ExprId, HookId, MemberEnv, PExpr, SemIr, StmtId};
93use crate::token::{
94 TOKEN_EOF, Token, TokenId, TokenSource, TokenSourceError, TokenSpec, TokenStore, TokenView,
95};
96use crate::token_stream::CommonTokenStream;
97use crate::tree::{
98 Node, NodeId, ParseTreeCheckpoint, ParseTreeStorage, ParsedFile, ParserRuleContext,
99};
100use crate::vocabulary::Vocabulary;
101
102type ParseTree = NodeId;
103
104const RECOGNITION_DEPTH_LIMIT: usize = 32_768;
108const FAST_RECOGNIZE_STACK_CHECK_INTERVAL: usize = 8;
111const FAST_RECOGNIZE_RED_ZONE: usize = 1024 * 1024;
112const FAST_RECOGNIZE_STACK_SIZE: usize = 4 * 1024 * 1024;
113const GENERATED_RULE_STACK_CHECK_INTERVAL: usize = 8;
119const ADAPTIVE_DIRECT_STEP_LIMIT: usize = RECOGNITION_DEPTH_LIMIT;
123
124pub fn grow_generated_rule_stack<R>(body: impl FnOnce() -> R) -> R {
131 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, body)
132}
133
134pub trait ParseListener: Send {
182 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError>;
187
188 fn exit_every_rule(&mut self, rule_index: usize) {
192 let _ = rule_index;
193 }
194}
195
196impl<T: ParseListener + ?Sized> ParseListener for Box<T> {
200 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError> {
201 (**self).enter_every_rule(event)
202 }
203
204 fn exit_every_rule(&mut self, rule_index: usize) {
205 (**self).exit_every_rule(rule_index);
206 }
207}
208
209#[derive(Debug)]
214#[non_exhaustive]
215pub struct EnterRuleEvent<'a> {
216 pub rule_index: usize,
219 pub current: Option<TokenView<'a>>,
222}
223
224struct ParseListenerSlot(Box<dyn ParseListener>);
225
226impl std::fmt::Debug for ParseListenerSlot {
227 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
228 f.write_str("ParseListener")
229 }
230}
231const CLEAN_MEMO_PROBE_LIMIT: usize = 4096;
235const CLEAN_MEMO_REPEAT_LIMIT: usize = 8;
236const CLEAN_MEMO_REPROBE_INTERVAL: usize = 262_144;
239const FAST_RECOGNIZE_VISITING_CAPACITY: usize = 256;
240const FAST_RECOGNIZE_MIN_MEMO_CAPACITY: usize = 256;
241const FAST_RECOGNIZE_MAX_MEMO_CAPACITY: usize = 524_288;
242const FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY: usize = 65_536;
243
244#[derive(Clone, Copy, Debug, Eq, PartialEq)]
245enum CleanMemoMode {
246 Probe,
247 Promote,
248 Sparse,
249}
250
251fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
252 intervals
253 .iter()
254 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
255}
256
257fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
258 let mut symbols = BTreeSet::new();
259 for (start, stop) in intervals {
260 symbols.extend(*start..=*stop);
261 }
262 symbols
263}
264
265fn interval_complement_symbols(
266 intervals: &[(i32, i32)],
267 min_vocabulary: i32,
268 max_vocabulary: i32,
269) -> BTreeSet<i32> {
270 (min_vocabulary..=max_vocabulary)
271 .filter(|symbol| !interval_set_contains(intervals, *symbol))
272 .collect()
273}
274
275#[cfg(feature = "perf-counters")]
276mod perf_counters {
277 use std::cell::Cell;
278 thread_local! {
279 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
280 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
281 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
282 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
283 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
284 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
285 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
286 pub(super) static OUTCOME_DEDUPE_INPUTS: Cell<u64> = const { Cell::new(0) };
287 pub(super) static OUTCOME_DEDUPE_REMOVED: Cell<u64> = const { Cell::new(0) };
288 pub(super) static OUTCOME_DEDUPE_INLINE: Cell<u64> = const { Cell::new(0) };
289 pub(super) static OUTCOME_DEDUPE_DENSE: Cell<u64> = const { Cell::new(0) };
290 pub(super) static OUTCOME_DEDUPE_SPARSE: Cell<u64> = const { Cell::new(0) };
291 pub(super) static OUTCOME_DEDUPE_DENSE_WORDS: Cell<u64> = const { Cell::new(0) };
292 }
293 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
294 c.with(|v| v.set(v.get() + n));
295 }
296 thread_local! {
297 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
298 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
299 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
300 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
301 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
302 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
303 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
304 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
305 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
306 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
307 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
308 }
309 pub(super) fn snapshot() -> [(&'static str, u64); 24] {
310 [
311 ("rfs_calls", RFS_CALLS.with(Cell::get)),
312 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
313 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
314 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
315 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
316 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
317 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
318 (
319 "outcome_dedupe_inputs",
320 OUTCOME_DEDUPE_INPUTS.with(Cell::get),
321 ),
322 (
323 "outcome_dedupe_removed",
324 OUTCOME_DEDUPE_REMOVED.with(Cell::get),
325 ),
326 (
327 "outcome_dedupe_inline",
328 OUTCOME_DEDUPE_INLINE.with(Cell::get),
329 ),
330 ("outcome_dedupe_dense", OUTCOME_DEDUPE_DENSE.with(Cell::get)),
331 (
332 "outcome_dedupe_sparse",
333 OUTCOME_DEDUPE_SPARSE.with(Cell::get),
334 ),
335 (
336 "outcome_dedupe_dense_words",
337 OUTCOME_DEDUPE_DENSE_WORDS.with(Cell::get),
338 ),
339 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
340 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
341 (
342 "atom_range_transitions",
343 ATOM_RANGE_TRANSITIONS.with(Cell::get),
344 ),
345 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
346 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
347 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
348 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
349 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
350 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
351 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
352 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
353 ]
354 }
355 pub fn reset() {
356 RFS_CALLS.with(|c| c.set(0));
357 RFS_MEMO_HITS.with(|c| c.set(0));
358 RFS_MEMO_MISSES.with(|c| c.set(0));
359 RFS_VISITING_CYCLE.with(|c| c.set(0));
360 MEMO_INSERTED.with(|c| c.set(0));
361 OUTCOMES_PUSHED.with(|c| c.set(0));
362 OUTCOMES_CLONED.with(|c| c.set(0));
363 OUTCOME_DEDUPE_INPUTS.with(|c| c.set(0));
364 OUTCOME_DEDUPE_REMOVED.with(|c| c.set(0));
365 OUTCOME_DEDUPE_INLINE.with(|c| c.set(0));
366 OUTCOME_DEDUPE_DENSE.with(|c| c.set(0));
367 OUTCOME_DEDUPE_SPARSE.with(|c| c.set(0));
368 OUTCOME_DEDUPE_DENSE_WORDS.with(|c| c.set(0));
369 EPSILON_TRANSITIONS.with(|c| c.set(0));
370 RULE_TRANSITIONS.with(|c| c.set(0));
371 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
372 SINGLE_TRANS_BODY.with(|c| c.set(0));
373 MULTI_TRANS_BODY.with(|c| c.set(0));
374 SINGLE_TRANS_RULE.with(|c| c.set(0));
375 SINGLE_TRANS_ATOM.with(|c| c.set(0));
376 SINGLE_TRANS_OTHER.with(|c| c.set(0));
377 OUTCOMES_RETURN_0.with(|c| c.set(0));
378 OUTCOMES_RETURN_1.with(|c| c.set(0));
379 OUTCOMES_RETURN_N.with(|c| c.set(0));
380 }
381 pub fn dump() {
382 for (name, value) in snapshot() {
383 #[allow(clippy::print_stderr)]
384 {
385 eprintln!("perf {name}={value}");
386 }
387 }
388 }
389}
390
391#[cfg(feature = "perf-counters")]
392pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
393const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
398#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
407pub struct ParserAction {
408 source_state: usize,
409 rule_index: usize,
410 action_index: Option<usize>,
411 start_index: usize,
412 stop_index: Option<usize>,
413 rule_init: bool,
414 expected_state: Option<usize>,
415}
416
417impl ParserAction {
418 pub const fn new(
420 source_state: usize,
421 rule_index: usize,
422 start_index: usize,
423 stop_index: Option<usize>,
424 ) -> Self {
425 Self {
426 source_state,
427 rule_index,
428 action_index: None,
429 start_index,
430 stop_index,
431 rule_init: false,
432 expected_state: None,
433 }
434 }
435
436 pub const fn new_indexed(
438 source_state: usize,
439 rule_index: usize,
440 action_index: usize,
441 start_index: usize,
442 stop_index: Option<usize>,
443 ) -> Self {
444 Self {
445 source_state,
446 rule_index,
447 action_index: Some(action_index),
448 start_index,
449 stop_index,
450 rule_init: false,
451 expected_state: None,
452 }
453 }
454
455 pub const fn new_rule_init(
457 rule_index: usize,
458 start_index: usize,
459 expected_state: Option<usize>,
460 ) -> Self {
461 Self {
462 source_state: usize::MAX,
463 rule_index,
464 action_index: None,
465 start_index,
466 stop_index: None,
467 rule_init: true,
468 expected_state,
469 }
470 }
471
472 pub const fn source_state(&self) -> usize {
474 self.source_state
475 }
476
477 pub const fn rule_index(&self) -> usize {
479 self.rule_index
480 }
481
482 pub const fn action_index(&self) -> Option<usize> {
484 self.action_index
485 }
486
487 pub const fn start_index(&self) -> usize {
489 self.start_index
490 }
491
492 pub const fn stop_index(&self) -> Option<usize> {
494 self.stop_index
495 }
496
497 pub const fn is_rule_init(&self) -> bool {
499 self.rule_init
500 }
501
502 pub const fn expected_state(&self) -> Option<usize> {
504 self.expected_state
505 }
506}
507
508pub struct ParserSemCtx<'a, S>
516where
517 S: TokenSource,
518{
519 input: &'a mut CommonTokenStream<S>,
520 tree_storage: &'a ParseTreeStorage,
521 rule_index: usize,
522 coordinate_index: usize,
523 rule_name: Option<String>,
524 context: Option<&'a ParserRuleContext>,
525 tree: Option<ParseTree>,
526 local_int_arg: Option<(usize, i64)>,
527 member_values: &'a MemberEnv,
528 action: Option<ParserAction>,
529}
530
531impl<S> std::fmt::Debug for ParserSemCtx<'_, S>
532where
533 S: TokenSource,
534{
535 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
536 f.debug_struct("ParserSemCtx")
537 .field("rule_index", &self.rule_index)
538 .field("coordinate_index", &self.coordinate_index)
539 .field("rule_name", &self.rule_name)
540 .field("context", &self.context)
541 .field("tree", &self.tree)
542 .field("local_int_arg", &self.local_int_arg)
543 .field("member_values", &self.member_values)
544 .field("action", &self.action)
545 .finish_non_exhaustive()
546 }
547}
548
549impl<'a, S> ParserSemCtx<'a, S>
550where
551 S: TokenSource,
552{
553 #[must_use]
555 pub const fn rule_index(&self) -> usize {
556 self.rule_index
557 }
558
559 #[must_use]
561 pub fn rule_name(&self) -> Option<&str> {
562 self.rule_name.as_deref()
563 }
564
565 #[must_use]
568 pub const fn coordinate_index(&self) -> usize {
569 self.coordinate_index
570 }
571
572 #[must_use]
574 pub fn input_index(&self) -> usize {
575 self.input.index()
576 }
577
578 pub fn la(&mut self, offset: isize) -> i32 {
580 self.input.la(offset)
581 }
582
583 pub fn lt(&self, offset: isize) -> Option<TokenView<'_>> {
585 self.input.lt(offset)
586 }
587
588 pub fn token_text(&self, offset: isize) -> Option<TokenView<'_>> {
590 self.lt(offset)
591 }
592
593 pub fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
600 self.input.get(index)
601 }
602
603 #[must_use]
606 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
607 self.context
608 }
609
610 #[must_use]
612 pub const fn parse_tree_storage(&self) -> &'a ParseTreeStorage {
613 self.tree_storage
614 }
615
616 #[must_use]
618 pub const fn token_store(&self) -> &TokenStore {
619 self.input.token_store()
620 }
621
622 #[must_use]
624 pub const fn tree_id(&self) -> Option<NodeId> {
625 self.tree
626 }
627
628 #[must_use]
631 pub fn tree(&self) -> Option<Node<'_>> {
632 self.tree
633 .and_then(|id| self.tree_storage.node(self.input.token_store(), id))
634 }
635
636 #[must_use]
638 pub fn local_int_arg(&self) -> Option<i64> {
639 self.local_int_arg.map(|(_, value)| value)
640 }
641
642 #[must_use]
644 pub fn member_int(&self, member: usize) -> Option<i64> {
645 self.member_values.scalar(member)
646 }
647
648 #[must_use]
651 pub fn member_stack_top(&self, member: usize) -> Option<i64> {
652 self.member_values.stack_top(member)
653 }
654
655 #[must_use]
657 pub fn member_stack_len(&self, member: usize) -> usize {
658 self.member_values.stack_len(member)
659 }
660
661 #[must_use]
664 pub const fn action(&self) -> Option<ParserAction> {
665 self.action
666 }
667
668 pub fn action_text(&self) -> String {
676 let Some(action) = self.action else {
677 return String::new();
678 };
679 let Some(stop) = action.stop_index() else {
680 return String::new();
681 };
682 let stop = if self
683 .input
684 .get(stop)
685 .is_some_and(|token| token.token_type() == TOKEN_EOF)
686 {
687 let Some(previous) = self.input.previous_visible_token_index(stop) else {
688 return String::new();
689 };
690 previous
691 } else {
692 stop
693 };
694 self.input.text(action.start_index(), stop)
695 }
696}
697
698pub trait SemanticHooks {
705 const ENABLES_LEXER_LIFECYCLE: bool = true;
712
713 fn observes_parser_predicates(&self) -> bool {
718 true
719 }
720
721 fn observes_parser_decisions(&self) -> bool {
726 false
727 }
728
729 fn parser_decision_override(
735 &mut self,
736 decision: usize,
737 input_index: usize,
738 alternative_count: usize,
739 ) -> Option<usize> {
740 let _ = (decision, input_index, alternative_count);
741 None
742 }
743
744 fn sempred<S>(
745 &mut self,
746 ctx: &mut ParserSemCtx<'_, S>,
747 rule_index: usize,
748 pred_index: usize,
749 ) -> Option<bool>
750 where
751 S: TokenSource,
752 {
753 let _ = (ctx, rule_index, pred_index);
754 None
755 }
756
757 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
758 where
759 S: TokenSource,
760 {
761 let _ = (ctx, action);
762 false
763 }
764
765 fn lexer_sempred<I>(
766 &mut self,
767 ctx: &mut LexerSemCtx<'_, I>,
768 rule_index: usize,
769 pred_index: usize,
770 ) -> Option<bool>
771 where
772 I: CharStream,
773 {
774 let _ = (ctx, rule_index, pred_index);
775 None
776 }
777
778 fn lexer_action<I>(&mut self, ctx: &mut LexerSemCtx<'_, I>, action: LexerCustomAction) -> bool
788 where
789 I: CharStream,
790 {
791 let _ = (ctx, action);
792 false
793 }
794
795 fn lexer_reset<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
799 where
800 I: CharStream,
801 {
802 let _ = ctx;
803 }
804
805 fn lexer_before_token<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
811 where
812 I: CharStream,
813 {
814 let _ = ctx;
815 }
816
817 fn lexer_after_accept<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
826 where
827 I: CharStream,
828 {
829 let _ = ctx;
830 }
831
832 fn lexer_token_emitted(&mut self, token: TokenView<'_>) {
839 let _ = token;
840 }
841}
842
843#[derive(Clone, Copy, Debug, Default)]
846pub struct NoSemanticHooks;
847
848impl SemanticHooks for NoSemanticHooks {
849 const ENABLES_LEXER_LIFECYCLE: bool = false;
850
851 fn observes_parser_predicates(&self) -> bool {
852 false
853 }
854}
855
856#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
863pub enum ParserPredicate {
864 True,
865 False,
866 FalseWithMessage {
868 message: &'static str,
869 },
870 Invoke {
873 value: bool,
874 },
875 LookaheadTextEquals {
876 offset: isize,
877 text: &'static str,
878 },
879 LookaheadNotEquals {
880 offset: isize,
881 token_type: i32,
882 },
883 TokenPairAdjacent,
886 ContextChildRuleTextNotEquals {
891 rule_index: usize,
892 text: &'static str,
893 },
894 LocalIntEquals {
897 value: i64,
898 },
899 LocalIntLessOrEqual {
902 value: i64,
903 },
904 MemberModuloEquals {
906 member: usize,
907 modulus: i64,
908 value: i64,
909 equals: bool,
910 },
911 MemberEquals {
913 member: usize,
914 value: i64,
915 equals: bool,
916 },
917}
918
919impl ParserPredicate {
920 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
926 match self {
927 Self::True => ir.expr(PExpr::Bool(true)),
928 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
929 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
930 Self::LookaheadTextEquals { offset, text } => {
931 let token = ir.expr(PExpr::TokenText(offset));
932 let text = ir.intern(text);
933 let text = ir.expr(PExpr::Str(text));
934 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
935 }
936 Self::LookaheadNotEquals { offset, token_type } => {
937 let actual = ir.expr(PExpr::La(offset));
938 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
939 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
940 }
941 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
942 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
943 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
944 let expected = ir.intern(text);
945 let expected = ir.expr(PExpr::Str(expected));
946 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
947 }
948 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
949 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
950 Self::MemberModuloEquals {
951 member,
952 modulus,
953 value,
954 equals,
955 } => {
956 if modulus == 0 {
957 return ir.expr(PExpr::Bool(false));
958 }
959 let member = ir.expr(PExpr::Member(member));
960 let modulus = ir.expr(PExpr::Int(modulus));
961 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
962 let expected = ir.expr(PExpr::Int(value));
963 ir.expr(PExpr::Cmp(
964 if equals { CmpOp::Eq } else { CmpOp::Ne },
965 actual,
966 expected,
967 ))
968 }
969 Self::MemberEquals {
970 member,
971 value,
972 equals,
973 } => {
974 let actual = ir.expr(PExpr::Member(member));
975 let expected = ir.expr(PExpr::Int(value));
976 ir.expr(PExpr::Cmp(
977 if equals { CmpOp::Eq } else { CmpOp::Ne },
978 actual,
979 expected,
980 ))
981 }
982 }
983 }
984
985 #[must_use]
986 pub const fn failure_message(self) -> Option<&'static str> {
987 match self {
988 Self::FalseWithMessage { message } => Some(message),
989 Self::True
990 | Self::False
991 | Self::Invoke { .. }
992 | Self::LookaheadTextEquals { .. }
993 | Self::LookaheadNotEquals { .. }
994 | Self::TokenPairAdjacent
995 | Self::ContextChildRuleTextNotEquals { .. }
996 | Self::LocalIntEquals { .. }
997 | Self::LocalIntLessOrEqual { .. }
998 | Self::MemberModuloEquals { .. }
999 | Self::MemberEquals { .. } => None,
1000 }
1001 }
1002}
1003
1004fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
1005 let local = ir.expr(PExpr::LocalArg);
1006 let absent = ir.expr(PExpr::IsNull(local));
1007 let expected = ir.expr(PExpr::Int(value));
1008 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
1009 ir.expr(PExpr::Or([absent, comparison].into()))
1010}
1011
1012#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1025pub enum UnknownSemanticPolicy {
1026 #[default]
1028 AssumeTrue,
1029 AssumeFalse,
1031 Error,
1034}
1035
1036fn apply_unknown_predicate_policy(
1045 policy: UnknownSemanticPolicy,
1046 rule_index: usize,
1047 pred_index: usize,
1048 hits: &mut Vec<(usize, usize)>,
1049) -> bool {
1050 match policy {
1051 UnknownSemanticPolicy::AssumeTrue => true,
1052 UnknownSemanticPolicy::AssumeFalse => false,
1053 UnknownSemanticPolicy::Error => {
1054 let coordinate = (rule_index, pred_index);
1055 if !hits.contains(&coordinate) {
1056 hits.push(coordinate);
1057 }
1058 false
1059 }
1060 }
1061}
1062
1063#[derive(Clone, Debug, Eq, PartialEq)]
1067pub struct ExpectedTokenSet {
1068 symbols: BTreeSet<i32>,
1069}
1070
1071impl ExpectedTokenSet {
1072 #[must_use]
1074 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
1075 expected_symbols_display(&self.symbols, vocabulary)
1076 }
1077}
1078
1079#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1084pub struct BailErrorStrategy;
1085
1086impl BailErrorStrategy {
1087 #[must_use]
1088 pub const fn new() -> Self {
1089 Self
1090 }
1091}
1092
1093#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1095pub enum PredictionMode {
1096 Ll,
1099 Sll,
1102 LlExactAmbigDetection,
1104}
1105
1106#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1112pub struct ParserRuleArg {
1113 pub source_state: usize,
1115 pub rule_index: usize,
1117 pub value: i64,
1119 pub inherit_local: bool,
1121}
1122
1123#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1125pub struct ParserMemberAction {
1126 pub source_state: usize,
1128 pub member: usize,
1130 pub delta: i64,
1132}
1133
1134#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1141pub struct ParserReturnAction {
1142 pub source_state: usize,
1144 pub rule_index: usize,
1146 pub name: &'static str,
1148 pub value: i64,
1150}
1151
1152impl ParserMemberAction {
1153 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1155 let delta = ir.expr(PExpr::Int(self.delta));
1156 ParserSemanticAction {
1157 source_state: self.source_state,
1158 rule_index: usize::MAX,
1159 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
1160 speculative: true,
1161 }
1162 }
1163}
1164
1165impl ParserReturnAction {
1166 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1168 let name = ir.intern(self.name);
1169 let value = ir.expr(PExpr::Int(self.value));
1170 ParserSemanticAction {
1171 source_state: self.source_state,
1172 rule_index: self.rule_index,
1173 stmt: ir.stmt(AStmt::SetReturn(name, value)),
1174 speculative: false,
1175 }
1176 }
1177}
1178
1179#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1181pub struct ParserSemanticPredicate {
1182 pub rule_index: usize,
1184 pub pred_index: usize,
1186 pub expr: ExprId,
1188 pub failure_message: Option<&'static str>,
1190}
1191
1192#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1194pub struct ParserSemanticAction {
1195 pub source_state: usize,
1197 pub rule_index: usize,
1199 pub stmt: StmtId,
1201 pub speculative: bool,
1203}
1204
1205#[derive(Clone, Debug, Default, Eq, PartialEq)]
1212pub struct ParserSemantics {
1213 pub ir: SemIr,
1214 pub predicates: Vec<ParserSemanticPredicate>,
1215 pub actions: Vec<ParserSemanticAction>,
1216}
1217
1218#[derive(Clone, Copy, Debug, Default)]
1220pub struct ParserRuntimeOptions<'a> {
1221 pub init_action_rules: &'a [usize],
1224 pub action_indices: &'a [(usize, usize)],
1230 pub track_alt_numbers: bool,
1232 #[doc(hidden)]
1237 pub track_context_alt_numbers: bool,
1238 pub predicates: &'a [(usize, usize, ParserPredicate)],
1240 pub semantics: Option<&'a ParserSemantics>,
1242 pub rule_args: &'a [ParserRuleArg],
1244 pub member_actions: &'a [ParserMemberAction],
1246 pub return_actions: &'a [ParserReturnAction],
1248 pub unknown_predicate_policy: UnknownSemanticPolicy,
1251}
1252
1253pub trait Parser: Recognizer {
1254 fn build_parse_trees(&self) -> bool;
1257
1258 fn set_build_parse_trees(&mut self, build: bool);
1260
1261 fn number_of_syntax_errors(&self) -> usize {
1264 0
1265 }
1266
1267 fn report_diagnostic_errors(&self) -> bool {
1270 false
1271 }
1272
1273 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
1276
1277 fn prediction_mode(&self) -> PredictionMode {
1279 PredictionMode::Ll
1280 }
1281
1282 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
1284
1285 fn max_rule_depth(&self) -> Option<usize> {
1288 None
1289 }
1290
1291 fn set_max_rule_depth(&mut self, _depth: Option<usize>) {}
1307
1308 fn add_parse_listener(&mut self, _listener: Box<dyn ParseListener>) {}
1313
1314 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
1317 Vec::new()
1318 }
1319}
1320
1321#[derive(Debug)]
1322struct LeftRecursiveCallerOverlap {
1323 atn_key: SharedAtnCacheKey,
1324 state_number: usize,
1325 symbol: i32,
1326 context_version: usize,
1327 overlaps: bool,
1328}
1329
1330const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
1331
1332#[derive(Debug)]
1333pub struct BaseParser<S, H = NoSemanticHooks> {
1334 input: CommonTokenStream<S>,
1335 tree: ParseTreeStorage,
1336 data: RecognizerData,
1337 semantic_hooks: H,
1338 decision_override_generation: usize,
1339 build_parse_trees: bool,
1340 syntax_errors: usize,
1341 report_diagnostic_errors: bool,
1342 prediction_mode: PredictionMode,
1343 prediction_diagnostics: Vec<ParserDiagnostic>,
1344 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1345 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1346 generated_sync_expected: Option<TokenBitSet>,
1347 generated_recovery_error_index: Option<usize>,
1348 generated_recovery_error_states: BTreeSet<isize>,
1349 int_members: MemberEnv,
1350 rule_context_stack: Vec<RuleContextFrame>,
1351 rule_context_version: usize,
1352 left_recursive_caller_overlap_cache:
1353 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1354 pending_invoking_states: Vec<isize>,
1355 precedence_stack: Vec<i32>,
1356 invoked_predicates: Vec<(usize, usize)>,
1360 bail_on_error: bool,
1364 parse_listeners: Vec<ParseListenerSlot>,
1369 parse_listener_abort: Option<AntlrError>,
1374 max_rule_depth: Option<usize>,
1378 rule_depth_error: Option<AntlrError>,
1383 recursion_expansions: usize,
1389 recursion_expansion_marks: Vec<usize>,
1393 unknown_predicate_policy: UnknownSemanticPolicy,
1396 unknown_predicate_hits: Vec<(usize, usize)>,
1399 unhandled_action_hits: Vec<(usize, usize)>,
1404 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1409 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1415 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1420 rule_stop_reach_cache: Vec<Option<bool>>,
1425 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1430 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1436 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1442 fast_predicate_cache: FxHashMap<(usize, usize, usize), bool>,
1446 empty_cycle_cache: Vec<Option<bool>>,
1452 empty_cycle_cache_atn: Option<SharedAtnCacheKey>,
1453 clean_memo_mode: CleanMemoMode,
1456 clean_memo_probe_seen: FxHashSet<FastRecognizeKey>,
1457 clean_memo_probe_samples: usize,
1458 clean_memo_probe_repeats: usize,
1459 clean_memo_sparse_samples: usize,
1460 fast_recognize_scratch: FastRecognizeTopScratch,
1462 fast_outcome_dedup: FastOutcomeDedupScratch,
1464 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1467 fast_first_set_prefilter: bool,
1475 fast_recovery_enabled: bool,
1479 fast_token_nodes_enabled: bool,
1484 fast_track_alt_numbers: bool,
1487 recognition_arena: RecognitionArena,
1491 last_recognition_arena_root: NodeSeqId,
1492 last_recognition_arena_diagnostics: DiagnosticSeqId,
1493}
1494
1495#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1497pub struct GeneratedDiagnosticsCheckpoint {
1498 diagnostics_len: usize,
1499 syntax_errors: usize,
1500 tree: ParseTreeCheckpoint,
1501}
1502
1503#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1506pub struct RecognitionArenaStats {
1507 pub total_nodes: usize,
1508 pub live_nodes: usize,
1509 pub dead_nodes: usize,
1510 pub node_capacity: usize,
1511 pub total_links: usize,
1512 pub live_links: usize,
1513 pub dead_links: usize,
1514 pub link_capacity: usize,
1515 pub total_extras: usize,
1516 pub live_extras: usize,
1517 pub dead_extras: usize,
1518 pub extra_capacity: usize,
1519}
1520
1521#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1522struct RuleContextFrame {
1523 rule_index: usize,
1524 invoking_state: isize,
1525}
1526
1527#[derive(Clone, Debug, Eq, PartialEq)]
1528struct RecognizeOutcome {
1529 index: usize,
1530 consumed_eof: bool,
1531 alt_number: usize,
1532 member_values: MemberEnv,
1533 return_values: BTreeMap<String, i64>,
1534 diagnostics: DiagnosticSeqId,
1535 decisions: Vec<usize>,
1536 actions: Vec<ParserAction>,
1537 nodes: NodeSeqId,
1538}
1539
1540#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1541struct FastRecognizeOutcome {
1542 index: usize,
1543 consumed_eof: bool,
1544 diagnostics: DiagnosticSeqId,
1545 deferred_nodes: FastDeferredNodeId,
1546 nodes: NodeSeqId,
1550}
1551
1552#[derive(Debug, Default)]
1553struct FastRecognizeTopScratch {
1554 visiting: FxHashSet<FastRecognizeKey>,
1555 memo: FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
1556}
1557
1558impl FastRecognizeTopScratch {
1559 fn prepare(&mut self, memo_capacity: usize) {
1560 self.visiting.clear();
1561 self.visiting.reserve(FAST_RECOGNIZE_VISITING_CAPACITY);
1562 self.memo.clear();
1563 self.memo.reserve(memo_capacity);
1564 }
1565
1566 fn release_oversized_memo(&mut self) {
1567 self.memo.clear();
1568 if self.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY {
1569 self.memo = FxHashMap::default();
1570 }
1571 }
1572}
1573
1574fn fast_recognize_memo_capacity(buffered_tokens: usize) -> usize {
1575 buffered_tokens.saturating_mul(8).clamp(
1576 FAST_RECOGNIZE_MIN_MEMO_CAPACITY,
1577 FAST_RECOGNIZE_MAX_MEMO_CAPACITY,
1578 )
1579}
1580
1581#[derive(Debug, Default)]
1582struct FastOutcomeDedupScratch {
1583 dense_words: Vec<u64>,
1584 touched_dense_words: Vec<u32>,
1585 sparse_keys: FxHashSet<(usize, bool)>,
1586}
1587
1588#[repr(transparent)]
1593#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1594struct FastDeferredNodeId(u32);
1595
1596impl FastDeferredNodeId {
1597 const EMPTY: Self = Self(u32::MAX);
1598
1599 const fn is_empty(self) -> bool {
1600 self.0 == Self::EMPTY.0
1601 }
1602}
1603
1604impl Default for FastDeferredNodeId {
1605 fn default() -> Self {
1606 Self::EMPTY
1607 }
1608}
1609
1610#[repr(transparent)]
1611#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1612struct FastDeferredRuleId(u32);
1613
1614#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1616enum FastDeferredNode {
1617 Fragment(NodeSeqId),
1618 Rule(FastDeferredRuleId),
1619 Alternative(u32),
1620 LeftRecursiveBoundary {
1621 rule_index: u32,
1622 },
1623 Concat {
1624 prefix: FastDeferredNodeId,
1625 suffix: FastDeferredNodeId,
1626 },
1627}
1628
1629#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1630struct FastDeferredRule {
1631 rule_index: u32,
1632 invoking_state: i32,
1633 start_index: u32,
1634 stop_index: Option<u32>,
1635 deferred_children: FastDeferredNodeId,
1636 children: NodeSeqId,
1637}
1638
1639#[repr(transparent)]
1640#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1641struct RecognizedNodeId(u32);
1642
1643#[repr(transparent)]
1644#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1645struct NodeSeqId(u32);
1646
1647impl NodeSeqId {
1648 const EMPTY: Self = Self(u32::MAX);
1649
1650 const fn is_empty(self) -> bool {
1651 self.0 == Self::EMPTY.0
1652 }
1653}
1654
1655impl Default for NodeSeqId {
1656 fn default() -> Self {
1657 Self::EMPTY
1658 }
1659}
1660
1661#[repr(transparent)]
1662#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1663struct DiagnosticSeqId(u32);
1664
1665impl DiagnosticSeqId {
1666 const EMPTY: Self = Self(u32::MAX);
1667
1668 const fn is_empty(self) -> bool {
1669 self.0 == Self::EMPTY.0
1670 }
1671}
1672
1673impl Default for DiagnosticSeqId {
1674 fn default() -> Self {
1675 Self::EMPTY
1676 }
1677}
1678
1679#[repr(transparent)]
1680#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1681struct RecognitionExtraId(u32);
1682
1683#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1684struct SeqLink {
1685 head: RecognizedNodeId,
1686 tail: NodeSeqId,
1687}
1688
1689#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1690struct DiagnosticLink {
1691 head: RecognitionExtraId,
1692 tail: DiagnosticSeqId,
1693}
1694
1695struct ArenaRuleSpec {
1696 rule_index: usize,
1697 invoking_state: isize,
1698 alt_number: usize,
1699 start_index: usize,
1700 stop_index: Option<usize>,
1701 return_values: BTreeMap<String, i64>,
1702 children: NodeSeqId,
1703}
1704
1705#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1708enum ArenaRecognizedNode {
1709 Token {
1710 token: TokenId,
1711 },
1712 ErrorToken {
1713 token: TokenId,
1714 },
1715 MissingToken {
1716 extra: RecognitionExtraId,
1717 },
1718 Rule {
1719 rule_index: u32,
1720 invoking_state: i32,
1721 alt_number: u32,
1722 start_index: u32,
1723 stop_index: Option<u32>,
1724 return_values: Option<RecognitionExtraId>,
1725 children: NodeSeqId,
1726 },
1727 LeftRecursiveBoundary {
1731 rule_index: u32,
1732 alt_number: u32,
1733 },
1734}
1735
1736#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1737enum RecognitionExtra {
1738 MissingToken {
1739 token_type: i32,
1740 at_index: u32,
1741 text: String,
1742 },
1743 ReturnValues(BTreeMap<String, i64>),
1744 Diagnostic(ParserDiagnostic),
1745}
1746
1747#[derive(Debug, Default)]
1748struct RecognitionArena {
1749 nodes: Vec<ArenaRecognizedNode>,
1750 seq_links: Vec<SeqLink>,
1751 diagnostic_links: Vec<DiagnosticLink>,
1752 extras: Vec<RecognitionExtra>,
1753 deferred_nodes: Vec<FastDeferredNode>,
1754 deferred_rules: Vec<FastDeferredRule>,
1755}
1756
1757const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1760const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1761const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1762const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1763const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1764const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1765
1766impl RecognitionArena {
1767 fn reset(&mut self) {
1768 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1769 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1770 reset_arena_vec(
1771 &mut self.diagnostic_links,
1772 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1773 );
1774 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1775 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1776 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1777 }
1778
1779 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1780 let id = RecognizedNodeId(
1781 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1782 );
1783 self.nodes.push(node);
1784 id
1785 }
1786
1787 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1788 let id = RecognitionExtraId(
1789 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1790 );
1791 self.extras.push(extra);
1792 id
1793 }
1794
1795 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1796 let id = NodeSeqId(
1797 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1798 );
1799 self.seq_links.push(SeqLink { head, tail });
1800 id
1801 }
1802
1803 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1804 let id = FastDeferredNodeId(
1805 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
1806 );
1807 self.deferred_nodes.push(node);
1808 id
1809 }
1810
1811 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
1812 let id = FastDeferredRuleId(
1813 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
1814 );
1815 self.deferred_rules.push(rule);
1816 id
1817 }
1818
1819 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
1820 if nodes.is_empty() {
1821 FastDeferredNodeId::EMPTY
1822 } else {
1823 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
1824 }
1825 }
1826
1827 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
1828 let rule = self.push_deferred_rule(rule);
1829 self.push_deferred_node(FastDeferredNode::Rule(rule))
1830 }
1831
1832 fn deferred_alternative(&mut self, alt_number: usize) -> FastDeferredNodeId {
1833 self.push_deferred_node(FastDeferredNode::Alternative(
1834 u32::try_from(alt_number).expect("alternative number fits in u32"),
1835 ))
1836 }
1837
1838 fn deferred_left_recursive_boundary(&mut self, rule_index: usize) -> FastDeferredNodeId {
1839 self.push_deferred_node(FastDeferredNode::LeftRecursiveBoundary {
1840 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
1841 })
1842 }
1843
1844 fn concat_deferred_nodes(
1845 &mut self,
1846 prefix: FastDeferredNodeId,
1847 suffix: FastDeferredNodeId,
1848 ) -> FastDeferredNodeId {
1849 if prefix.is_empty() {
1850 return suffix;
1851 }
1852 if suffix.is_empty() {
1853 return prefix;
1854 }
1855 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
1856 }
1857
1858 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
1859 self.deferred_nodes[id.0 as usize]
1860 }
1861
1862 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
1863 self.deferred_rules[id.0 as usize]
1864 }
1865
1866 fn prepend_diagnostic(
1867 &mut self,
1868 tail: DiagnosticSeqId,
1869 diagnostic: ParserDiagnostic,
1870 ) -> DiagnosticSeqId {
1871 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
1872 self.prepend_diagnostic_id(tail, head)
1873 }
1874
1875 fn prepend_diagnostic_id(
1876 &mut self,
1877 tail: DiagnosticSeqId,
1878 head: RecognitionExtraId,
1879 ) -> DiagnosticSeqId {
1880 let id = DiagnosticSeqId(
1881 u32::try_from(self.diagnostic_links.len())
1882 .expect("diagnostic sequence arena fits in u32"),
1883 );
1884 self.diagnostic_links.push(DiagnosticLink { head, tail });
1885 id
1886 }
1887
1888 fn concat_diagnostics(
1889 &mut self,
1890 prefix: DiagnosticSeqId,
1891 mut suffix: DiagnosticSeqId,
1892 ) -> DiagnosticSeqId {
1893 if prefix.is_empty() {
1894 return suffix;
1895 }
1896 if suffix.is_empty() {
1897 return prefix;
1898 }
1899 let mut reversed = DiagnosticSeqId::EMPTY;
1900 let mut cursor = prefix;
1901 while let Some(link) = self.diagnostic_link(cursor) {
1902 reversed = self.prepend_diagnostic_id(reversed, link.head);
1903 cursor = link.tail;
1904 }
1905 while let Some(link) = self.diagnostic_link(reversed) {
1906 suffix = self.prepend_diagnostic_id(suffix, link.head);
1907 reversed = link.tail;
1908 }
1909 suffix
1910 }
1911
1912 #[cfg(test)]
1913 fn diagnostic_sequence(
1914 &mut self,
1915 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
1916 ) -> DiagnosticSeqId {
1917 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
1918 let mut sequence = DiagnosticSeqId::EMPTY;
1919 for diagnostic in diagnostics.into_iter().rev() {
1920 sequence = self.prepend_diagnostic(sequence, diagnostic);
1921 }
1922 sequence
1923 }
1924
1925 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
1926 self.nodes[id.0 as usize]
1927 }
1928
1929 fn set_boundary_alt_number(&mut self, id: RecognizedNodeId, alt_number: u32) {
1930 let ArenaRecognizedNode::LeftRecursiveBoundary {
1931 alt_number: stored, ..
1932 } = &mut self.nodes[id.0 as usize]
1933 else {
1934 unreachable!("deferred boundary must materialize as a boundary node");
1935 };
1936 *stored = alt_number;
1937 }
1938
1939 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
1940 &self.extras[id.0 as usize]
1941 }
1942
1943 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
1944 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
1945 }
1946
1947 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
1948 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
1949 }
1950
1951 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
1952 NodeSeqIter {
1953 arena: self,
1954 cursor: sequence,
1955 }
1956 }
1957
1958 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
1959 DiagnosticSeqIter {
1960 arena: self,
1961 cursor: sequence,
1962 }
1963 }
1964
1965 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
1966 self.diagnostics(sequence).count()
1967 }
1968
1969 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
1970 self.diagnostics(sequence)
1971 .filter(|diagnostic| {
1972 diagnostic.message.starts_with("mismatched input ")
1973 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
1974 })
1975 .count()
1976 }
1977
1978 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
1979 self.diagnostics(left).cmp(self.diagnostics(right))
1980 }
1981
1982 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
1983 self.iter(sequence).count()
1984 }
1985
1986 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
1987 self.iter(sequence).any(|node| match self.node(node) {
1988 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1989 ArenaRecognizedNode::Rule { children, .. } => {
1990 self.sequence_has_left_recursive_boundary(children)
1991 }
1992 ArenaRecognizedNode::Token { .. }
1993 | ArenaRecognizedNode::ErrorToken { .. }
1994 | ArenaRecognizedNode::MissingToken { .. } => false,
1995 })
1996 }
1997
1998 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
1999 self.iter(sequence).any(|node| {
2000 matches!(
2001 self.node(node),
2002 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
2003 )
2004 })
2005 }
2006
2007 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
2008 self.iter(sequence).any(|node| {
2009 matches!(
2010 self.node(node),
2011 ArenaRecognizedNode::Token { .. }
2012 | ArenaRecognizedNode::ErrorToken { .. }
2013 | ArenaRecognizedNode::MissingToken { .. }
2014 )
2015 })
2016 }
2017
2018 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
2019 match self.node(node) {
2020 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
2021 Some(token.index())
2022 }
2023 ArenaRecognizedNode::MissingToken { extra } => {
2024 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
2025 unreachable!("missing-token node must reference missing-token extra");
2026 };
2027 Some(*at_index as usize)
2028 }
2029 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
2030 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
2031 }
2032 }
2033
2034 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
2035 match self.node(node) {
2036 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
2037 Some(token.index())
2038 }
2039 ArenaRecognizedNode::MissingToken { extra } => {
2040 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
2041 unreachable!("missing-token node must reference missing-token extra");
2042 };
2043 (*at_index as usize).checked_sub(1)
2044 }
2045 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
2046 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
2047 }
2048 }
2049
2050 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
2051 let start = self.node_start_index(node)?;
2052 let stop = self.node_stop_index(node);
2053 Some((start, stop))
2054 }
2055
2056 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
2057 self.iter(sequence)
2058 .find_map(|node| self.node_start_index(node))
2059 }
2060
2061 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
2062 let mut stop = None;
2063 for node in self.iter(sequence) {
2064 if let Some(index) = self.node_stop_index(node) {
2065 stop = Some(index);
2066 }
2067 }
2068 stop
2069 }
2070
2071 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
2072 self.iter(sequence)
2073 .any(|node| self.node_needs_stable_tie(node))
2074 }
2075
2076 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
2077 match self.node(node) {
2078 ArenaRecognizedNode::Token { .. }
2079 | ArenaRecognizedNode::ErrorToken { .. }
2080 | ArenaRecognizedNode::MissingToken { .. } => false,
2081 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
2082 ArenaRecognizedNode::Rule {
2083 rule_index,
2084 children,
2085 ..
2086 } => self.iter(children).any(|child| {
2087 matches!(
2088 self.node(child),
2089 ArenaRecognizedNode::Rule {
2090 rule_index: child_rule,
2091 ..
2092 } if child_rule == rule_index
2093 ) || self.node_needs_stable_tie(child)
2094 }),
2095 }
2096 }
2097
2098 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
2099 loop {
2100 match (self.link(left), self.link(right)) {
2101 (Some(left_link), Some(right_link)) => {
2102 let order = self.compare_nodes(left_link.head, right_link.head);
2103 if order != Ordering::Equal {
2104 return order;
2105 }
2106 left = left_link.tail;
2107 right = right_link.tail;
2108 }
2109 (None, None) => return Ordering::Equal,
2110 (None, Some(_)) => return Ordering::Less,
2111 (Some(_), None) => return Ordering::Greater,
2112 }
2113 }
2114 }
2115
2116 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
2117 let left = self.node(left);
2118 let right = self.node(right);
2119 match (left, right) {
2120 (
2121 ArenaRecognizedNode::Token { token: left },
2122 ArenaRecognizedNode::Token { token: right },
2123 )
2124 | (
2125 ArenaRecognizedNode::ErrorToken { token: left },
2126 ArenaRecognizedNode::ErrorToken { token: right },
2127 ) => left.cmp(&right),
2128 (
2129 ArenaRecognizedNode::MissingToken { extra: left },
2130 ArenaRecognizedNode::MissingToken { extra: right },
2131 ) => self.extra(left).cmp(self.extra(right)),
2132 (
2133 ArenaRecognizedNode::Rule {
2134 rule_index: left_rule,
2135 invoking_state: left_invoking,
2136 alt_number: left_alt,
2137 start_index: left_start,
2138 stop_index: left_stop,
2139 return_values: left_returns,
2140 children: left_children,
2141 },
2142 ArenaRecognizedNode::Rule {
2143 rule_index: right_rule,
2144 invoking_state: right_invoking,
2145 alt_number: right_alt,
2146 start_index: right_start,
2147 stop_index: right_stop,
2148 return_values: right_returns,
2149 children: right_children,
2150 },
2151 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
2152 .cmp(&(
2153 right_rule,
2154 right_invoking,
2155 right_alt,
2156 right_start,
2157 right_stop,
2158 ))
2159 .then_with(|| {
2160 left_returns
2161 .map(|id| self.extra(id))
2162 .cmp(&right_returns.map(|id| self.extra(id)))
2163 })
2164 .then_with(|| self.compare_sequences(left_children, right_children)),
2165 (
2166 ArenaRecognizedNode::LeftRecursiveBoundary {
2167 rule_index: left_rule,
2168 alt_number: left_alt,
2169 },
2170 ArenaRecognizedNode::LeftRecursiveBoundary {
2171 rule_index: right_rule,
2172 alt_number: right_alt,
2173 },
2174 ) => (left_rule, left_alt).cmp(&(right_rule, right_alt)),
2175 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
2176 }
2177 }
2178
2179 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
2180 let mut reversed = NodeSeqId::EMPTY;
2181 while let Some(link) = self.link(sequence) {
2182 reversed = self.prepend(reversed, link.head);
2183 sequence = link.tail;
2184 }
2185 reversed
2186 }
2187
2188 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
2189 if !self.sequence_has_direct_boundary(sequence) {
2190 return sequence;
2191 }
2192 let mut reversed = NodeSeqId::EMPTY;
2193 while let Some(link) = self.link(sequence) {
2194 match self.node(link.head) {
2195 ArenaRecognizedNode::LeftRecursiveBoundary {
2196 rule_index,
2197 alt_number,
2198 } => {
2199 if !reversed.is_empty() {
2200 let children = self.reverse_sequence(reversed);
2201 let start_index = self.sequence_start_index(children).unwrap_or_default();
2202 let stop_index = self.sequence_stop_index(children);
2203 let rule = self.push_node(ArenaRecognizedNode::Rule {
2204 rule_index,
2205 invoking_state: -1,
2206 alt_number,
2207 start_index: u32::try_from(start_index)
2208 .expect("left-recursive start index fits in u32"),
2209 stop_index: stop_index.map(|index| {
2210 u32::try_from(index).expect("left-recursive stop index fits in u32")
2211 }),
2212 return_values: None,
2213 children,
2214 });
2215 reversed = self.prepend(NodeSeqId::EMPTY, rule);
2216 }
2217 }
2218 _ => {
2219 reversed = self.prepend(reversed, link.head);
2220 }
2221 }
2222 sequence = link.tail;
2223 }
2224 self.reverse_sequence(reversed)
2225 }
2226
2227 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
2228 let mut live_nodes = vec![false; self.nodes.len()];
2229 let mut live_links = vec![false; self.seq_links.len()];
2230 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
2231 let mut live_extras = vec![false; self.extras.len()];
2232 let mut pending = vec![root];
2233 while let Some(mut sequence) = pending.pop() {
2234 while let Some(link) = self.link(sequence) {
2235 let link_index = sequence.0 as usize;
2236 if live_links[link_index] {
2237 break;
2238 }
2239 live_links[link_index] = true;
2240 let node_index = link.head.0 as usize;
2241 if !live_nodes[node_index] {
2242 live_nodes[node_index] = true;
2243 match self.node(link.head) {
2244 ArenaRecognizedNode::MissingToken { extra } => {
2245 live_extras[extra.0 as usize] = true;
2246 }
2247 ArenaRecognizedNode::Rule {
2248 return_values,
2249 children,
2250 ..
2251 } => {
2252 if let Some(extra) = return_values {
2253 live_extras[extra.0 as usize] = true;
2254 }
2255 pending.push(children);
2256 }
2257 ArenaRecognizedNode::Token { .. }
2258 | ArenaRecognizedNode::ErrorToken { .. }
2259 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
2260 }
2261 }
2262 sequence = link.tail;
2263 }
2264 }
2265 let mut diagnostics = diagnostics;
2266 while let Some(link) = self.diagnostic_link(diagnostics) {
2267 let link_index = diagnostics.0 as usize;
2268 if live_diagnostic_links[link_index] {
2269 break;
2270 }
2271 live_diagnostic_links[link_index] = true;
2272 live_extras[link.head.0 as usize] = true;
2273 diagnostics = link.tail;
2274 }
2275 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
2276 let live_link_count = live_links.into_iter().filter(|live| *live).count()
2277 + live_diagnostic_links
2278 .into_iter()
2279 .filter(|live| *live)
2280 .count();
2281 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
2282 let total_links = self.seq_links.len() + self.diagnostic_links.len();
2283 RecognitionArenaStats {
2284 total_nodes: self.nodes.len(),
2285 live_nodes: live_node_count,
2286 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
2287 node_capacity: self.nodes.capacity(),
2288 total_links,
2289 live_links: live_link_count,
2290 dead_links: total_links.saturating_sub(live_link_count),
2291 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
2292 total_extras: self.extras.len(),
2293 live_extras: live_extra_count,
2294 dead_extras: self.extras.len().saturating_sub(live_extra_count),
2295 extra_capacity: self.extras.capacity(),
2296 }
2297 }
2298}
2299
2300fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
2301 if storage.capacity() > max_retained_capacity {
2302 *storage = Vec::new();
2303 } else {
2304 storage.clear();
2305 }
2306}
2307
2308const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
2309 match node {
2310 ArenaRecognizedNode::Token { .. } => 0,
2311 ArenaRecognizedNode::ErrorToken { .. } => 1,
2312 ArenaRecognizedNode::MissingToken { .. } => 2,
2313 ArenaRecognizedNode::Rule { .. } => 3,
2314 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
2315 }
2316}
2317
2318struct NodeSeqIter<'a> {
2319 arena: &'a RecognitionArena,
2320 cursor: NodeSeqId,
2321}
2322
2323impl Iterator for NodeSeqIter<'_> {
2324 type Item = RecognizedNodeId;
2325
2326 fn next(&mut self) -> Option<Self::Item> {
2327 let link = self.arena.link(self.cursor)?;
2328 self.cursor = link.tail;
2329 Some(link.head)
2330 }
2331}
2332
2333struct DiagnosticSeqIter<'a> {
2334 arena: &'a RecognitionArena,
2335 cursor: DiagnosticSeqId,
2336}
2337
2338impl<'a> Iterator for DiagnosticSeqIter<'a> {
2339 type Item = &'a ParserDiagnostic;
2340
2341 fn next(&mut self) -> Option<Self::Item> {
2342 let link = self.arena.diagnostic_link(self.cursor)?;
2343 self.cursor = link.tail;
2344 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2345 unreachable!("diagnostic link must reference diagnostic extra");
2346 };
2347 Some(diagnostic)
2348 }
2349}
2350
2351#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2352struct ParserDiagnostic {
2353 line: usize,
2354 column: usize,
2355 message: String,
2356 offending: Option<TokenId>,
2360}
2361
2362#[derive(Clone, Debug, Default, Eq, PartialEq)]
2363struct ExpectedTokens {
2364 index: Option<usize>,
2365 symbols: BTreeSet<i32>,
2366 no_viable: Option<NoViableAlternative>,
2367}
2368
2369#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2370struct NoViableAlternative {
2371 start_index: usize,
2372 error_index: usize,
2373}
2374
2375impl ExpectedTokens {
2376 fn record_transition(
2379 &mut self,
2380 index: usize,
2381 transition: ParserTransition<'_>,
2382 max_token_type: i32,
2383 ) {
2384 let symbols = transition_expected_symbols(transition, max_token_type);
2385 match self.index {
2386 Some(current) if index < current => {}
2387 Some(current) if index == current => self.symbols.extend(symbols),
2388 _ => {
2389 self.index = Some(index);
2390 self.symbols = symbols;
2391 }
2392 }
2393 }
2394
2395 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2398 match self.no_viable {
2399 Some(current) if error_index < current.error_index => {}
2400 _ => {
2401 self.no_viable = Some(NoViableAlternative {
2402 start_index,
2403 error_index,
2404 });
2405 }
2406 }
2407 }
2408}
2409
2410#[derive(Clone, Debug, Default, Eq, PartialEq)]
2417struct TokenBitSet {
2418 words: Vec<u64>,
2419}
2420
2421impl TokenBitSet {
2422 fn insert(&mut self, symbol: i32) {
2423 let Some(slot) = token_bit_slot(symbol) else {
2424 return;
2425 };
2426 let word = slot / u64::BITS as usize;
2427 if word >= self.words.len() {
2428 self.words.resize(word + 1, 0);
2429 }
2430 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2431 }
2432
2433 fn extend_range(&mut self, start: i32, stop: i32) {
2434 let (start, stop) = if start <= stop {
2435 (start, stop)
2436 } else {
2437 (stop, start)
2438 };
2439 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2440 self.insert(TOKEN_EOF);
2441 }
2442 let positive_start = start.max(1);
2443 if positive_start > stop {
2444 return;
2445 }
2446 let Some(start_slot) = token_bit_slot(positive_start) else {
2447 return;
2448 };
2449 let Some(stop_slot) = token_bit_slot(stop) else {
2450 return;
2451 };
2452 self.extend_slot_range(start_slot, stop_slot);
2453 }
2454
2455 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2456 if start_slot > stop_slot {
2457 return;
2458 }
2459 let start_word = start_slot / u64::BITS as usize;
2460 let stop_word = stop_slot / u64::BITS as usize;
2461 if stop_word >= self.words.len() {
2462 self.words.resize(stop_word + 1, 0);
2463 }
2464 let start_offset = start_slot % u64::BITS as usize;
2465 let stop_offset = stop_slot % u64::BITS as usize;
2466 if start_word == stop_word {
2467 self.words[start_word] |=
2468 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2469 return;
2470 }
2471 self.words[start_word] |= !0_u64 << start_offset;
2472 for word in &mut self.words[(start_word + 1)..stop_word] {
2473 *word = !0_u64;
2474 }
2475 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2476 }
2477
2478 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2479 for symbol in symbols {
2480 self.insert(symbol);
2481 }
2482 }
2483
2484 fn extend_from(&mut self, other: &Self) {
2485 if other.words.len() > self.words.len() {
2486 self.words.resize(other.words.len(), 0);
2487 }
2488 for (left, right) in self.words.iter_mut().zip(&other.words) {
2489 *left |= *right;
2490 }
2491 }
2492
2493 fn contains(&self, symbol: i32) -> bool {
2494 let Some(slot) = token_bit_slot(symbol) else {
2495 return false;
2496 };
2497 let word = slot / u64::BITS as usize;
2498 self.words
2499 .get(word)
2500 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2501 }
2502
2503 fn is_empty(&self) -> bool {
2504 self.words.iter().all(|word| *word == 0)
2505 }
2506
2507 fn symbols(&self) -> impl Iterator<Item = i32> + '_ {
2508 self.words
2509 .iter()
2510 .copied()
2511 .enumerate()
2512 .flat_map(|(word_index, mut bits)| {
2513 std::iter::from_fn(move || {
2514 while bits != 0 {
2515 let bit = bits.trailing_zeros() as usize;
2516 bits &= bits - 1;
2517 if let Some(symbol) =
2518 token_bit_symbol(word_index * u64::BITS as usize + bit)
2519 {
2520 return Some(symbol);
2521 }
2522 }
2523 None
2524 })
2525 })
2526 }
2527
2528 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2529 target.extend(self.symbols());
2530 }
2531
2532 fn to_btree_set(&self) -> BTreeSet<i32> {
2533 let mut out = BTreeSet::new();
2534 self.extend_btree_set(&mut out);
2535 out
2536 }
2537}
2538
2539fn token_bit_slot(symbol: i32) -> Option<usize> {
2540 if symbol == TOKEN_EOF {
2541 Some(0)
2542 } else if symbol > 0 {
2543 usize::try_from(symbol).ok()
2544 } else {
2545 None
2546 }
2547}
2548
2549fn token_bit_symbol(slot: usize) -> Option<i32> {
2550 if slot == 0 {
2551 Some(TOKEN_EOF)
2552 } else {
2553 i32::try_from(slot).ok()
2554 }
2555}
2556
2557fn transition_expected_symbols(
2560 transition: ParserTransition<'_>,
2561 max_token_type: i32,
2562) -> BTreeSet<i32> {
2563 let mut symbols = BTreeSet::new();
2564 match &transition.data() {
2565 Transition::Atom { label, .. } => {
2566 symbols.insert(*label);
2567 }
2568 Transition::Range { start, stop, .. } => {
2569 symbols.extend(*start..=*stop);
2570 }
2571 Transition::Set { set, .. } => {
2572 for (start, stop) in set.ranges() {
2573 symbols.extend(start..=stop);
2574 }
2575 }
2576 Transition::NotSet { set, .. } => {
2577 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2578 }
2579 Transition::Wildcard { .. } => {
2580 symbols.extend(1..=max_token_type);
2581 }
2582 Transition::Epsilon { .. }
2583 | Transition::Rule { .. }
2584 | Transition::Predicate { .. }
2585 | Transition::Action { .. }
2586 | Transition::Precedence { .. } => {}
2587 }
2588 symbols
2589}
2590
2591fn transition_expected_token_set(
2592 transition: ParserTransition<'_>,
2593 max_token_type: i32,
2594) -> TokenBitSet {
2595 let mut symbols = TokenBitSet::default();
2596 match &transition.data() {
2597 Transition::Atom { label, .. } => {
2598 symbols.insert(*label);
2599 }
2600 Transition::Range { start, stop, .. } => {
2601 symbols.extend_range(*start, *stop);
2602 }
2603 Transition::Set { set, .. } => {
2604 for (start, stop) in set.ranges() {
2605 symbols.extend_range(start, stop);
2606 }
2607 }
2608 Transition::NotSet { set, .. } => {
2609 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2610 }
2611 Transition::Wildcard { .. } => {
2612 symbols.extend_range(1, max_token_type);
2613 }
2614 Transition::Epsilon { .. }
2615 | Transition::Rule { .. }
2616 | Transition::Predicate { .. }
2617 | Transition::Action { .. }
2618 | Transition::Precedence { .. } => {}
2619 }
2620 symbols
2621}
2622
2623fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2627 let mut symbols = BTreeSet::new();
2628 let mut stack = vec![state_number];
2629 let mut visited = BTreeSet::new();
2630 while let Some(current) = stack.pop() {
2631 if !visited.insert(current) {
2632 continue;
2633 }
2634 let Some(state) = atn.state(current) else {
2635 continue;
2636 };
2637 for transition in &state.transitions() {
2638 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2639 if transition_symbols.is_empty() {
2640 if transition.is_epsilon() {
2641 stack.push(transition.target());
2642 }
2643 } else {
2644 symbols.extend(transition_symbols);
2645 }
2646 }
2647 }
2648 symbols
2649}
2650
2651fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2652 let mut symbols = TokenBitSet::default();
2653 let mut stack = vec![state_number];
2654 let mut visited = BTreeSet::new();
2655 while let Some(current) = stack.pop() {
2656 if !visited.insert(current) {
2657 continue;
2658 }
2659 let Some(state) = atn.state(current) else {
2660 continue;
2661 };
2662 for transition in &state.transitions() {
2663 let transition_symbols =
2664 transition_expected_token_set(transition, atn.max_token_type());
2665 if transition_symbols.is_empty() {
2666 if transition.is_epsilon() {
2667 stack.push(transition.target());
2668 }
2669 } else {
2670 symbols.extend_from(&transition_symbols);
2671 }
2672 }
2673 }
2674 symbols
2675}
2676
2677fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2678 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2679 return false;
2680 };
2681 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2682 return false;
2683 };
2684 epsilon_reaches_state(atn, state_number, stop_state)
2685}
2686
2687fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2688 let mut stack = vec![start];
2689 let mut visited = BTreeSet::new();
2690 while let Some(current) = stack.pop() {
2691 if current == target {
2692 return true;
2693 }
2694 if !visited.insert(current) {
2695 continue;
2696 }
2697 let Some(state) = atn.state(current) else {
2698 continue;
2699 };
2700 stack.extend(
2701 state
2702 .transitions()
2703 .iter()
2704 .filter(|transition| transition.is_epsilon())
2705 .map(ParserTransition::target),
2706 );
2707 }
2708 false
2709}
2710
2711#[derive(Clone, Debug, Default, Eq, PartialEq)]
2718struct FirstSet {
2719 symbols: TokenBitSet,
2720 nullable: bool,
2721}
2722
2723type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2730
2731type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2738
2739#[derive(Debug, Default)]
2740struct LeftRecursiveOperatorLookahead {
2741 single_token: TokenBitSet,
2745 multi_token_prefix: TokenBitSet,
2750 predicate_dependent: TokenBitSet,
2751}
2752
2753#[derive(Default)]
2754struct SharedAtnCache {
2755 first_set: FirstSetCache,
2756 decision_lookahead: DecisionLookaheadCache,
2757 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2758 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2759 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2760 rule_stop_reach: FxHashMap<usize, bool>,
2761 observable_action_transitions: Option<bool>,
2762 predicate_transitions: Option<bool>,
2763}
2764
2765thread_local! {
2766 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2767 RefCell::new(FxHashMap::default());
2768}
2769
2770#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2781struct SharedAtnCacheKey {
2782 atn: usize,
2783 states: usize,
2784 state_count: usize,
2785 max_token_type: i32,
2786}
2787
2788impl SharedAtnCacheKey {
2789 fn for_atn(atn: &Atn) -> Self {
2790 let (states, state_count) = atn.storage_identity();
2791 Self {
2792 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2793 states,
2794 state_count,
2795 max_token_type: atn.max_token_type(),
2796 }
2797 }
2798}
2799
2800fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2801 SHARED_ATN_CACHES.with(|cell| {
2802 let key = SharedAtnCacheKey::for_atn(atn);
2803 let mut map = cell.borrow_mut();
2804 let cache = map.entry(key).or_default();
2805 f(&mut cache.first_set)
2806 })
2807}
2808
2809fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
2810 SHARED_ATN_CACHES.with(|cell| {
2811 let key = SharedAtnCacheKey::for_atn(atn);
2812 let mut map = cell.borrow_mut();
2813 let cache = map.entry(key).or_default();
2814 f(cache)
2815 })
2816}
2817
2818#[derive(Debug, Default)]
2827struct DecisionLookahead {
2828 transitions: Vec<TransitionLookSet>,
2829}
2830
2831#[derive(Clone, Debug, Default)]
2838struct TransitionLookSet {
2839 symbols: TokenBitSet,
2840 nullable: bool,
2841}
2842
2843struct FirstSetCtx<'a> {
2847 cache: &'a mut FirstSetCache,
2848 in_progress: BTreeSet<(usize, usize)>,
2849 hit_cycle: bool,
2850}
2851
2852fn rule_first_set(
2861 atn: &Atn,
2862 target: usize,
2863 rule_stop_state: usize,
2864 cache: &mut FirstSetCache,
2865) -> Rc<FirstSet> {
2866 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
2867 return Rc::clone(cached);
2868 }
2869 let mut ctx = FirstSetCtx {
2870 cache,
2871 in_progress: BTreeSet::new(),
2872 hit_cycle: false,
2873 };
2874 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
2875}
2876
2877fn rule_first_set_cached(
2878 atn: &Atn,
2879 target: usize,
2880 rule_stop_state: usize,
2881 ctx: &mut FirstSetCtx<'_>,
2882) -> Rc<FirstSet> {
2883 let key = (target, rule_stop_state);
2884 if let Some(cached) = ctx.cache.get(&key) {
2885 return Rc::clone(cached);
2886 }
2887 if !ctx.in_progress.insert(key) {
2888 return Rc::new(FirstSet::default());
2892 }
2893 let saved_hit_cycle = ctx.hit_cycle;
2894 ctx.hit_cycle = false;
2895 let mut first = FirstSet::default();
2896 let mut visited = BTreeSet::new();
2897 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
2898 ctx.in_progress.remove(&key);
2899 let entry = Rc::new(first);
2900 if !ctx.hit_cycle {
2901 ctx.cache.insert(key, Rc::clone(&entry));
2902 }
2903 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
2904 entry
2905}
2906
2907fn transition_first_set(
2911 atn: &Atn,
2912 transition: ParserTransition<'_>,
2913 rule_stop_state: usize,
2914 cache: &mut FirstSetCache,
2915) -> TransitionLookSet {
2916 match &transition.data() {
2917 Transition::Atom { label, .. } => {
2918 let mut symbols = TokenBitSet::default();
2919 symbols.insert(*label);
2920 TransitionLookSet {
2921 symbols,
2922 nullable: false,
2923 }
2924 }
2925 Transition::Range { start, stop, .. } => {
2926 let mut symbols = TokenBitSet::default();
2927 symbols.extend_range(*start, *stop);
2928 TransitionLookSet {
2929 symbols,
2930 nullable: false,
2931 }
2932 }
2933 Transition::Set { set, .. } => {
2934 let mut symbols = TokenBitSet::default();
2935 for (start, stop) in set.ranges() {
2936 symbols.extend_range(start, stop);
2937 }
2938 TransitionLookSet {
2939 symbols,
2940 nullable: false,
2941 }
2942 }
2943 Transition::NotSet { set, .. } => {
2944 let max = atn.max_token_type();
2945 let mut symbols = TokenBitSet::default();
2946 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
2947 TransitionLookSet {
2948 symbols,
2949 nullable: false,
2950 }
2951 }
2952 Transition::Wildcard { .. } => {
2953 let mut symbols = TokenBitSet::default();
2954 symbols.extend_range(1, atn.max_token_type());
2955 TransitionLookSet {
2956 symbols,
2957 nullable: false,
2958 }
2959 }
2960 Transition::Epsilon { target }
2961 | Transition::Action { target, .. }
2962 | Transition::Predicate { target, .. }
2963 | Transition::Precedence { target, .. } => {
2964 let first = rule_first_set(atn, *target, rule_stop_state, cache);
2967 TransitionLookSet {
2968 symbols: first.symbols.clone(),
2969 nullable: first.nullable,
2970 }
2971 }
2972 Transition::Rule {
2973 target,
2974 rule_index,
2975 follow_state,
2976 ..
2977 } => {
2978 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2979 return TransitionLookSet::default();
2980 };
2981 let child = rule_first_set(atn, *target, child_stop, cache);
2982 let mut symbols = child.symbols.clone();
2983 let nullable = if child.nullable {
2984 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
2985 symbols.extend_from(&follow.symbols);
2986 follow.nullable
2987 } else {
2988 false
2989 };
2990 TransitionLookSet { symbols, nullable }
2991 }
2992 }
2993}
2994
2995fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
3016 let mut chosen: Option<usize> = None;
3017 for (index, transition) in entry.transitions.iter().enumerate() {
3018 if transition.nullable {
3019 return None;
3020 }
3021 if transition.symbols.contains(symbol) {
3022 if chosen.is_some() {
3023 return None;
3024 }
3025 chosen = Some(index);
3026 }
3027 }
3028 chosen
3029}
3030
3031fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
3040 let mut matching_non_nullable_alt = None;
3041 let mut nullable_alt = None;
3042 for (index, transition) in entry.transitions.iter().enumerate() {
3043 if transition.nullable {
3044 if nullable_alt.is_some() {
3045 return None;
3046 }
3047 nullable_alt = Some(index);
3048 }
3049 if transition.symbols.contains(symbol) {
3050 if transition.nullable {
3051 continue;
3052 }
3053 if matching_non_nullable_alt.is_some() {
3054 return None;
3055 }
3056 matching_non_nullable_alt = Some(index);
3057 }
3058 }
3059 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
3060 return None;
3061 }
3062 if non_greedy {
3063 nullable_alt.or(matching_non_nullable_alt)
3064 } else {
3065 matching_non_nullable_alt.or(nullable_alt)
3066 }
3067}
3068
3069fn should_skip_via_lookahead(
3070 transition_kind: ParserTransitionKind,
3071 transition_index: usize,
3072 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
3073 index: usize,
3074 record_expected: bool,
3075 expected: &mut ExpectedTokens,
3076) -> bool {
3077 let prune_non_consuming = matches!(
3078 transition_kind,
3079 ParserTransitionKind::Epsilon
3080 | ParserTransitionKind::Action
3081 | ParserTransitionKind::Predicate
3082 | ParserTransitionKind::Rule
3083 | ParserTransitionKind::Precedence
3084 );
3085 if !prune_non_consuming {
3086 return false;
3087 }
3088 let Some((symbol, entry)) = lookahead_filter else {
3089 return false;
3090 };
3091 let Some(set) = entry.transitions.get(transition_index) else {
3092 return false;
3093 };
3094 if set.symbols.contains(*symbol) || set.nullable {
3095 return false;
3096 }
3097 if record_expected && !set.symbols.is_empty() {
3098 record_pruned_transition_expected(set, index, expected);
3099 }
3100 true
3101}
3102
3103fn should_skip_rule_via_first_set(
3104 first: &FirstSet,
3105 symbol: i32,
3106 record_expected: bool,
3107 index: usize,
3108 expected: &mut ExpectedTokens,
3109) -> bool {
3110 if first.nullable || first.symbols.contains(symbol) {
3111 return false;
3112 }
3113 if record_expected && !first.symbols.is_empty() {
3114 record_token_bit_expected(&first.symbols, index, expected);
3115 }
3116 true
3117}
3118
3119fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
3120 match expected.index {
3121 Some(current) if index < current => {}
3122 Some(current) if index == current => {
3123 symbols.extend_btree_set(&mut expected.symbols);
3124 }
3125 _ => {
3126 expected.index = Some(index);
3127 expected.symbols = symbols.to_btree_set();
3128 }
3129 }
3130}
3131
3132fn record_pruned_transition_expected(
3134 set: &TransitionLookSet,
3135 index: usize,
3136 expected: &mut ExpectedTokens,
3137) {
3138 match expected.index {
3139 Some(current) if index < current => {}
3140 Some(current) if index == current => {
3141 set.symbols.extend_btree_set(&mut expected.symbols);
3142 }
3143 _ => {
3144 expected.index = Some(index);
3145 expected.symbols = set.symbols.to_btree_set();
3146 }
3147 }
3148}
3149
3150fn rule_first_set_inner(
3151 atn: &Atn,
3152 state_number: usize,
3153 rule_stop_state: usize,
3154 ctx: &mut FirstSetCtx<'_>,
3155 visited: &mut BTreeSet<usize>,
3156 first: &mut FirstSet,
3157) {
3158 if !visited.insert(state_number) {
3159 return;
3160 }
3161 if state_number == rule_stop_state {
3162 first.nullable = true;
3163 return;
3164 }
3165 let Some(state) = atn.state(state_number) else {
3166 return;
3167 };
3168 for transition in &state.transitions() {
3169 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3170 if !transition_symbols.is_empty() {
3171 first.symbols.extend_iter(transition_symbols);
3172 continue;
3173 }
3174 match &transition.data() {
3175 Transition::Epsilon { target }
3176 | Transition::Action { target, .. }
3177 | Transition::Predicate { target, .. }
3178 | Transition::Precedence { target, .. } => {
3179 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
3180 }
3181 Transition::Rule {
3182 target,
3183 rule_index,
3184 follow_state,
3185 ..
3186 } => {
3187 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3188 continue;
3189 };
3190 let child_key = (*target, child_stop);
3191 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
3192 ctx.hit_cycle = true;
3193 }
3194 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
3195 first.symbols.extend_from(&child.symbols);
3196 if child.nullable {
3197 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
3198 }
3199 }
3200 Transition::Atom { .. }
3201 | Transition::Range { .. }
3202 | Transition::Set { .. }
3203 | Transition::NotSet { .. }
3204 | Transition::Wildcard { .. } => {}
3205 }
3206 }
3207}
3208
3209fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
3212 let mut symbols = BTreeSet::new();
3213 state_sync_symbols_inner(
3214 atn,
3215 state_number,
3216 stop_state,
3217 &mut BTreeSet::new(),
3218 &mut symbols,
3219 );
3220 symbols
3221}
3222
3223fn state_sync_symbols_inner(
3226 atn: &Atn,
3227 state_number: usize,
3228 stop_state: usize,
3229 visited: &mut BTreeSet<usize>,
3230 symbols: &mut BTreeSet<i32>,
3231) {
3232 if !visited.insert(state_number) {
3233 return;
3234 }
3235 if state_number == stop_state {
3236 symbols.insert(TOKEN_EOF);
3237 return;
3238 }
3239 let Some(state) = atn.state(state_number) else {
3240 return;
3241 };
3242 for transition in &state.transitions() {
3243 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3244 if transition_symbols.is_empty() {
3245 match &transition.data() {
3246 Transition::Rule { target, .. }
3247 | Transition::Epsilon { target }
3248 | Transition::Action { target, .. }
3249 | Transition::Predicate { target, .. }
3250 | Transition::Precedence { target, .. } => {
3251 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
3252 }
3253 Transition::Atom { .. }
3254 | Transition::Range { .. }
3255 | Transition::Set { .. }
3256 | Transition::NotSet { .. }
3257 | Transition::Wildcard { .. } => {}
3258 }
3259 } else {
3260 symbols.extend(transition_symbols);
3261 }
3262 }
3263}
3264
3265#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
3266struct OperatorSymbolReachability {
3267 single_token: bool,
3269 multi_token: bool,
3271 predicate_dependent: bool,
3273}
3274
3275impl OperatorSymbolReachability {
3276 const ADAPTIVE_FALLBACK: Self = Self {
3277 single_token: false,
3278 multi_token: false,
3279 predicate_dependent: true,
3280 };
3281
3282 const fn single_token(predicate_dependent: bool) -> Self {
3283 if predicate_dependent {
3284 Self {
3285 single_token: false,
3286 multi_token: false,
3287 predicate_dependent: true,
3288 }
3289 } else {
3290 Self {
3291 single_token: true,
3292 multi_token: false,
3293 predicate_dependent: false,
3294 }
3295 }
3296 }
3297
3298 const fn multi_token(predicate_dependent: bool) -> Self {
3299 if predicate_dependent {
3300 Self {
3301 single_token: false,
3302 multi_token: false,
3303 predicate_dependent: true,
3304 }
3305 } else {
3306 Self {
3307 single_token: false,
3308 multi_token: true,
3309 predicate_dependent: false,
3310 }
3311 }
3312 }
3313
3314 const fn union(self, other: Self) -> Self {
3315 Self {
3316 single_token: self.single_token || other.single_token,
3317 multi_token: self.multi_token || other.multi_token,
3318 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
3319 }
3320 }
3321}
3322
3323#[derive(Clone, Copy)]
3324struct OperatorReachabilityRequest {
3325 symbol: i32,
3326 precedence: i32,
3327 predicate_dependent: bool,
3328 operator_rule_index: usize,
3329}
3330
3331#[derive(Clone, Copy, Debug)]
3332struct OperatorRuleContinuation {
3333 stop_state: usize,
3334 follow_state: usize,
3335 return_precedence: i32,
3336}
3337
3338struct NullablePrecedenceCtx {
3339 cache: FxHashMap<(usize, usize, i32, bool), bool>,
3340 in_progress: BTreeSet<(usize, usize, i32, bool)>,
3341 hit_cycle: bool,
3342}
3343
3344fn state_is_nullable_with_precedence(
3345 atn: &Atn,
3346 state_number: usize,
3347 stop_state_number: usize,
3348 precedence: i32,
3349 allow_predicates: bool,
3350 ctx: &mut NullablePrecedenceCtx,
3351) -> bool {
3352 let saved_hit_cycle = ctx.hit_cycle;
3353 ctx.hit_cycle = false;
3354 let nullable = state_is_nullable_with_precedence_cached(
3355 atn,
3356 state_number,
3357 stop_state_number,
3358 precedence,
3359 allow_predicates,
3360 ctx,
3361 );
3362 ctx.hit_cycle = saved_hit_cycle;
3363 nullable
3364}
3365
3366fn state_is_nullable_with_precedence_cached(
3367 atn: &Atn,
3368 state_number: usize,
3369 stop_state_number: usize,
3370 precedence: i32,
3371 allow_predicates: bool,
3372 ctx: &mut NullablePrecedenceCtx,
3373) -> bool {
3374 if state_number == stop_state_number {
3375 return true;
3376 }
3377 let key = (
3378 state_number,
3379 stop_state_number,
3380 precedence,
3381 allow_predicates,
3382 );
3383 if let Some(cached) = ctx.cache.get(&key) {
3384 return *cached;
3385 }
3386 if !ctx.in_progress.insert(key) {
3387 ctx.hit_cycle = true;
3388 return false;
3389 }
3390 let saved_hit_cycle = ctx.hit_cycle;
3391 ctx.hit_cycle = false;
3392 let nullable = atn.state(state_number).is_some_and(|state| {
3393 state
3394 .transitions()
3395 .iter()
3396 .any(|transition| match &transition.data() {
3397 Transition::Rule {
3398 target,
3399 rule_index,
3400 follow_state,
3401 precedence: rule_precedence,
3402 } => {
3403 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3404 return false;
3405 };
3406 state_is_nullable_with_precedence_cached(
3407 atn,
3408 *target,
3409 child_stop,
3410 *rule_precedence,
3411 allow_predicates,
3412 ctx,
3413 ) && state_is_nullable_with_precedence_cached(
3414 atn,
3415 *follow_state,
3416 stop_state_number,
3417 precedence,
3418 allow_predicates,
3419 ctx,
3420 )
3421 }
3422 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3423 state_is_nullable_with_precedence_cached(
3424 atn,
3425 *target,
3426 stop_state_number,
3427 precedence,
3428 allow_predicates,
3429 ctx,
3430 )
3431 }
3432 Transition::Predicate { target, .. } if allow_predicates => {
3433 state_is_nullable_with_precedence_cached(
3434 atn,
3435 *target,
3436 stop_state_number,
3437 precedence,
3438 allow_predicates,
3439 ctx,
3440 )
3441 }
3442 Transition::Precedence {
3443 target,
3444 precedence: transition_precedence,
3445 } if *transition_precedence >= precedence => {
3446 state_is_nullable_with_precedence_cached(
3447 atn,
3448 *target,
3449 stop_state_number,
3450 precedence,
3451 allow_predicates,
3452 ctx,
3453 )
3454 }
3455 Transition::Atom { .. }
3456 | Transition::Range { .. }
3457 | Transition::Set { .. }
3458 | Transition::NotSet { .. }
3459 | Transition::Wildcard { .. }
3460 | Transition::Predicate { .. }
3461 | Transition::Precedence { .. } => false,
3462 })
3463 });
3464 ctx.in_progress.remove(&key);
3465 if !ctx.hit_cycle {
3466 ctx.cache.insert(key, nullable);
3467 }
3468 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3469 nullable
3470}
3471
3472fn state_operator_token_prefix_reachability(
3474 atn: &Atn,
3475 state_number: usize,
3476 request: OperatorReachabilityRequest,
3477 continuations: &[OperatorRuleContinuation],
3478 visited: &mut BTreeSet<(usize, i32, bool)>,
3479) -> OperatorSymbolReachability {
3480 let key = (
3481 state_number,
3482 request.precedence,
3483 request.predicate_dependent,
3484 );
3485 if !visited.insert(key) {
3486 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3490 }
3491 if let Some((continuation, remaining)) = continuations.split_last()
3492 && state_number == continuation.stop_state
3493 {
3494 let result = state_operator_token_prefix_reachability(
3495 atn,
3496 continuation.follow_state,
3497 OperatorReachabilityRequest {
3498 precedence: continuation.return_precedence,
3499 ..request
3500 },
3501 remaining,
3502 visited,
3503 );
3504 visited.remove(&key);
3505 return result;
3506 }
3507 let Some(state) = atn.state(state_number) else {
3508 visited.remove(&key);
3509 return OperatorSymbolReachability::default();
3510 };
3511 let completes_operator = match state.kind() {
3512 AtnStateKind::RuleStop => continuations.is_empty(),
3513 AtnStateKind::StarLoopBack
3514 | AtnStateKind::StarLoopEntry
3515 | AtnStateKind::PlusLoopBack
3516 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3517 _ => false,
3518 };
3519 if completes_operator {
3520 visited.remove(&key);
3521 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3522 }
3523 let mut reachability = OperatorSymbolReachability::default();
3524 for transition in &state.transitions() {
3525 let transition_reachability = match &transition.data() {
3526 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3527 OperatorSymbolReachability::single_token(request.predicate_dependent)
3528 }
3529 Transition::Rule {
3530 target,
3531 rule_index,
3532 follow_state,
3533 precedence: rule_precedence,
3534 } => {
3535 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3536 continue;
3537 };
3538 let mut nested = continuations.to_vec();
3539 nested.push(OperatorRuleContinuation {
3540 stop_state: child_stop,
3541 follow_state: *follow_state,
3542 return_precedence: request.precedence,
3543 });
3544 state_operator_token_prefix_reachability(
3545 atn,
3546 *target,
3547 OperatorReachabilityRequest {
3548 precedence: *rule_precedence,
3549 ..request
3550 },
3551 &nested,
3552 visited,
3553 )
3554 }
3555 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3556 state_operator_token_prefix_reachability(
3557 atn,
3558 *target,
3559 request,
3560 continuations,
3561 visited,
3562 )
3563 }
3564 Transition::Precedence {
3565 target,
3566 precedence: transition_precedence,
3567 } => {
3568 if *transition_precedence < request.precedence {
3569 OperatorSymbolReachability::default()
3570 } else {
3571 state_operator_token_prefix_reachability(
3572 atn,
3573 *target,
3574 request,
3575 continuations,
3576 visited,
3577 )
3578 }
3579 }
3580 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3581 atn,
3582 *target,
3583 OperatorReachabilityRequest {
3584 predicate_dependent: true,
3585 ..request
3586 },
3587 continuations,
3588 visited,
3589 ),
3590 Transition::Atom { .. }
3591 | Transition::Range { .. }
3592 | Transition::Set { .. }
3593 | Transition::NotSet { .. }
3594 | Transition::Wildcard { .. } => {
3595 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3596 }
3597 };
3598 reachability = reachability.union(transition_reachability);
3599 }
3600 visited.remove(&key);
3601 reachability
3602}
3603
3604fn state_can_reach_symbol_with_precedence(
3605 atn: &Atn,
3606 state_number: usize,
3607 request: OperatorReachabilityRequest,
3608 nullable_ctx: &mut NullablePrecedenceCtx,
3609 continuations: &mut Vec<OperatorRuleContinuation>,
3610 visited: &mut BTreeSet<(usize, i32, bool)>,
3611) -> OperatorSymbolReachability {
3612 let key = (
3613 state_number,
3614 request.precedence,
3615 request.predicate_dependent,
3616 );
3617 if !visited.insert(key) {
3618 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3619 }
3620 let Some(state) = atn.state(state_number) else {
3621 visited.remove(&key);
3622 return OperatorSymbolReachability::default();
3623 };
3624 let mut reachability = OperatorSymbolReachability::default();
3625 for transition in &state.transitions() {
3626 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3627 reachability = reachability.union(state_operator_token_prefix_reachability(
3628 atn,
3629 transition.target(),
3630 request,
3631 continuations,
3632 &mut BTreeSet::new(),
3633 ));
3634 continue;
3635 }
3636 let transition_reachability = match &transition.data() {
3637 Transition::Rule {
3638 target,
3639 rule_index,
3640 follow_state,
3641 precedence: rule_precedence,
3642 } => {
3643 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3644 continue;
3645 };
3646 continuations.push(OperatorRuleContinuation {
3647 stop_state: child_stop,
3648 follow_state: *follow_state,
3649 return_precedence: request.precedence,
3650 });
3651 let mut result = state_can_reach_symbol_with_precedence(
3652 atn,
3653 *target,
3654 OperatorReachabilityRequest {
3655 precedence: *rule_precedence,
3656 ..request
3657 },
3658 nullable_ctx,
3659 continuations,
3660 visited,
3661 );
3662 continuations.pop();
3663 if state_is_nullable_with_precedence(
3664 atn,
3665 *target,
3666 child_stop,
3667 *rule_precedence,
3668 true,
3669 nullable_ctx,
3670 ) {
3671 let child_predicate_dependent = request.predicate_dependent
3672 || !state_is_nullable_with_precedence(
3673 atn,
3674 *target,
3675 child_stop,
3676 *rule_precedence,
3677 false,
3678 nullable_ctx,
3679 );
3680 result = result.union(state_can_reach_symbol_with_precedence(
3681 atn,
3682 *follow_state,
3683 OperatorReachabilityRequest {
3684 predicate_dependent: child_predicate_dependent,
3685 ..request
3686 },
3687 nullable_ctx,
3688 continuations,
3689 visited,
3690 ));
3691 }
3692 result
3693 }
3694 Transition::Epsilon { target }
3695 | Transition::Action { target, .. }
3696 | Transition::Precedence { target, .. } => {
3697 if matches!(
3698 &transition.data(),
3699 Transition::Precedence {
3700 precedence: transition_precedence,
3701 ..
3702 } if *transition_precedence < request.precedence
3703 ) {
3704 continue;
3705 }
3706 state_can_reach_symbol_with_precedence(
3707 atn,
3708 *target,
3709 request,
3710 nullable_ctx,
3711 continuations,
3712 visited,
3713 )
3714 }
3715 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3716 atn,
3717 *target,
3718 OperatorReachabilityRequest {
3719 predicate_dependent: true,
3720 ..request
3721 },
3722 nullable_ctx,
3723 continuations,
3724 visited,
3725 ),
3726 Transition::Atom { .. }
3727 | Transition::Range { .. }
3728 | Transition::Set { .. }
3729 | Transition::NotSet { .. }
3730 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3731 };
3732 reachability = reachability.union(transition_reachability);
3733 }
3734 visited.remove(&key);
3735 reachability
3736}
3737
3738fn left_recursive_operator_lookahead(
3739 atn: &Atn,
3740 state_number: usize,
3741 precedence: i32,
3742) -> LeftRecursiveOperatorLookahead {
3743 let Some(state) = atn.state(state_number) else {
3744 return LeftRecursiveOperatorLookahead::default();
3745 };
3746 let Some(operator_rule_index) = state.rule_index() else {
3747 return LeftRecursiveOperatorLookahead::default();
3748 };
3749 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3750 let mut nullable_ctx = NullablePrecedenceCtx {
3751 cache: FxHashMap::default(),
3752 in_progress: BTreeSet::new(),
3753 hit_cycle: false,
3754 };
3755 for transition in &state.transitions() {
3756 let target = transition.target();
3757 if atn
3758 .state(target)
3759 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3760 {
3761 continue;
3762 }
3763 for symbol in 1..=atn.max_token_type() {
3764 let reachability = state_can_reach_symbol_with_precedence(
3765 atn,
3766 target,
3767 OperatorReachabilityRequest {
3768 symbol,
3769 precedence,
3770 predicate_dependent: false,
3771 operator_rule_index,
3772 },
3773 &mut nullable_ctx,
3774 &mut Vec::new(),
3775 &mut BTreeSet::new(),
3776 );
3777 if reachability.single_token {
3778 lookahead.single_token.insert(symbol);
3779 }
3780 if reachability.multi_token {
3781 lookahead.multi_token_prefix.insert(symbol);
3782 }
3783 if reachability.predicate_dependent {
3784 lookahead.predicate_dependent.insert(symbol);
3785 }
3786 }
3787 }
3788 lookahead
3789}
3790
3791#[derive(Debug, Default)]
3792struct StateBeforeStopLookahead {
3793 symbols: TokenBitSet,
3794 reaches_context_boundary: bool,
3795}
3796
3797fn state_before_stop_lookahead(
3798 atn: &Atn,
3799 state_number: usize,
3800 stop_state_number: usize,
3801) -> Rc<StateBeforeStopLookahead> {
3802 with_shared_atn_caches(atn, |cache| {
3803 let key = (state_number, stop_state_number);
3804 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
3805 return Rc::clone(cached);
3806 }
3807 let mut lookahead = StateBeforeStopLookahead::default();
3808 state_before_stop_lookahead_inner(
3809 atn,
3810 state_number,
3811 stop_state_number,
3812 &mut BTreeSet::new(),
3813 &mut cache.first_set,
3814 &mut lookahead,
3815 );
3816 let lookahead = Rc::new(lookahead);
3817 cache
3818 .state_before_stop_lookahead
3819 .insert(key, Rc::clone(&lookahead));
3820 lookahead
3821 })
3822}
3823
3824fn state_before_stop_lookahead_inner(
3825 atn: &Atn,
3826 state_number: usize,
3827 stop_state_number: usize,
3828 visited: &mut BTreeSet<usize>,
3829 first_set_cache: &mut FirstSetCache,
3830 lookahead: &mut StateBeforeStopLookahead,
3831) {
3832 if state_number == stop_state_number {
3833 lookahead.reaches_context_boundary = true;
3834 return;
3835 }
3836 if !visited.insert(state_number) {
3837 return;
3838 }
3839 let Some(state) = atn.state(state_number) else {
3840 return;
3841 };
3842 if state.kind() == AtnStateKind::RuleStop {
3843 lookahead.reaches_context_boundary = true;
3844 return;
3845 }
3846 for transition in &state.transitions() {
3847 match &transition.data() {
3848 Transition::Epsilon { target }
3849 | Transition::Action { target, .. }
3850 | Transition::Predicate { target, .. }
3851 | Transition::Precedence { target, .. } => {
3852 state_before_stop_lookahead_inner(
3853 atn,
3854 *target,
3855 stop_state_number,
3856 visited,
3857 first_set_cache,
3858 lookahead,
3859 );
3860 }
3861 Transition::Rule {
3862 target,
3863 rule_index,
3864 follow_state,
3865 ..
3866 } => {
3867 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3868 continue;
3869 };
3870 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
3871 lookahead.symbols.extend_from(&child.symbols);
3872 if child.nullable {
3873 state_before_stop_lookahead_inner(
3874 atn,
3875 *follow_state,
3876 stop_state_number,
3877 visited,
3878 first_set_cache,
3879 lookahead,
3880 );
3881 }
3882 }
3883 Transition::Atom { .. }
3884 | Transition::Range { .. }
3885 | Transition::Set { .. }
3886 | Transition::NotSet { .. }
3887 | Transition::Wildcard { .. } => {
3888 lookahead.symbols.extend_iter(transition_expected_symbols(
3889 transition,
3890 atn.max_token_type(),
3891 ));
3892 }
3893 }
3894 }
3895}
3896
3897fn caller_context_can_match_symbol_before_state(
3898 atn: &Atn,
3899 return_states: impl DoubleEndedIterator<Item = usize>,
3900 stop_state_number: usize,
3901 symbol: i32,
3902) -> bool {
3903 for return_state in return_states.rev() {
3904 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
3905 if lookahead.symbols.contains(symbol) {
3906 return true;
3907 }
3908 if !lookahead.reaches_context_boundary {
3909 return false;
3910 }
3911 }
3912 false
3913}
3914
3915fn next_recovery_context(
3919 atn: &Atn,
3920 state: AtnState<'_>,
3921 inherited: &BTreeSet<i32>,
3922 inherited_state: Option<usize>,
3923) -> (BTreeSet<i32>, Option<usize>) {
3924 let state_symbols = state_expected_symbols(atn, state.state_number());
3925 if state.transitions().len() > 1 && !state_symbols.is_empty() {
3926 let mut symbols = state_symbols;
3927 symbols.extend(inherited.iter().copied());
3928 return (symbols, Some(state.state_number()));
3929 }
3930 (inherited.clone(), inherited_state)
3931}
3932
3933fn recovery_expected_symbols(
3934 atn: &Atn,
3935 state_number: usize,
3936 inherited: &BTreeSet<i32>,
3937) -> BTreeSet<i32> {
3938 let mut symbols = state_expected_symbols(atn, state_number);
3939 symbols.extend(inherited.iter().copied());
3940 symbols
3941}
3942
3943fn fast_next_recovery_context<S, H>(
3947 parser: &mut BaseParser<S, H>,
3948 atn: &Atn,
3949 state: AtnState<'_>,
3950 inherited: &Rc<BTreeSet<i32>>,
3951 inherited_state: Option<usize>,
3952) -> (Rc<BTreeSet<i32>>, Option<usize>)
3953where
3954 S: TokenSource,
3955 H: SemanticHooks,
3956{
3957 if state.transitions().len() <= 1 {
3958 return (Rc::clone(inherited), inherited_state);
3959 }
3960 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
3961 if state_symbols.is_empty() {
3962 return (Rc::clone(inherited), inherited_state);
3963 }
3964 if inherited.is_empty() {
3965 return (state_symbols, Some(state.state_number()));
3966 }
3967 if Rc::ptr_eq(&state_symbols, inherited) {
3968 return (state_symbols, Some(state.state_number()));
3969 }
3970 let mut combined = (*state_symbols).clone();
3971 combined.extend(inherited.iter().copied());
3972 (
3973 parser.intern_recovery_symbols(combined),
3974 Some(state.state_number()),
3975 )
3976}
3977
3978fn fast_recovery_expected_symbols<S, H>(
3982 parser: &mut BaseParser<S, H>,
3983 atn: &Atn,
3984 state_number: usize,
3985 inherited: &Rc<BTreeSet<i32>>,
3986) -> Rc<BTreeSet<i32>>
3987where
3988 S: TokenSource,
3989 H: SemanticHooks,
3990{
3991 let cached = parser.cached_state_expected_symbols(atn, state_number);
3992 if inherited.is_empty() {
3993 return cached;
3994 }
3995 if cached.is_empty() {
3996 return Rc::clone(inherited);
3997 }
3998 if Rc::ptr_eq(&cached, inherited) {
3999 return cached;
4000 }
4001 let mut combined = (*cached).clone();
4002 combined.extend(inherited.iter().copied());
4003 parser.intern_recovery_symbols(combined)
4004}
4005
4006struct ParserTableSemCtx<'a> {
4007 member_values: &'a mut MemberEnv,
4008 return_values: &'a mut BTreeMap<String, i64>,
4009}
4010
4011impl semir::PredContext for ParserTableSemCtx<'_> {
4012 type TokenText<'a>
4013 = &'a str
4014 where
4015 Self: 'a;
4016
4017 fn la(&mut self, _offset: isize) -> i64 {
4018 i64::from(TOKEN_EOF)
4019 }
4020
4021 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
4022 None
4023 }
4024
4025 fn token_index_adjacent(&mut self) -> bool {
4026 false
4027 }
4028
4029 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
4030 None
4031 }
4032
4033 fn member(&self, member: usize) -> Option<i64> {
4034 Some(self.member_values.scalar(member).unwrap_or_default())
4035 }
4036
4037 fn member_top(&self, member: usize) -> Option<i64> {
4038 self.member_values.stack_top(member)
4039 }
4040
4041 fn member_len(&self, member: usize) -> usize {
4042 self.member_values.stack_len(member)
4043 }
4044
4045 fn local_arg(&self) -> Option<i64> {
4046 None
4047 }
4048
4049 fn column(&self) -> Option<i64> {
4050 None
4051 }
4052
4053 fn token_start_column(&self) -> Option<i64> {
4054 None
4055 }
4056
4057 fn token_text_so_far(&self) -> Option<String> {
4058 None
4059 }
4060
4061 fn hook(&mut self, _hook: HookId) -> bool {
4062 false
4063 }
4064}
4065
4066impl semir::ActContext for ParserTableSemCtx<'_> {
4067 fn set_member(&mut self, member: usize, value: i64) {
4068 self.member_values.set_scalar(member, value);
4069 }
4070
4071 fn push_member(&mut self, member: usize, value: i64) {
4072 self.member_values.push_stack(member, value);
4073 }
4074
4075 fn pop_member(&mut self, member: usize) -> Option<i64> {
4076 self.member_values.pop_stack(member)
4077 }
4078
4079 fn set_return(&mut self, name: &str, value: i64) {
4080 self.return_values.insert(name.to_owned(), value);
4081 }
4082
4083 fn action_hook(&mut self, _hook: HookId) {}
4084}
4085
4086fn apply_member_actions(
4088 source_state: usize,
4089 actions: &[ParserMemberAction],
4090 semantics: Option<&ParserSemantics>,
4091 values: &mut MemberEnv,
4092) {
4093 for action in actions
4094 .iter()
4095 .filter(|action| action.source_state == source_state)
4096 {
4097 values.add_scalar(action.member, action.delta);
4098 }
4099 let Some(semantics) = semantics else {
4100 return;
4101 };
4102 let mut return_values = BTreeMap::new();
4103 let mut ctx = ParserTableSemCtx {
4104 member_values: values,
4105 return_values: &mut return_values,
4106 };
4107 for action in semantics
4108 .actions
4109 .iter()
4110 .filter(|action| action.source_state == source_state && action.speculative)
4111 {
4112 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
4113 }
4114}
4115
4116fn member_values_after_action(
4118 source_state: usize,
4119 actions: &[ParserMemberAction],
4120 semantics: Option<&ParserSemantics>,
4121 values: &MemberEnv,
4122) -> MemberEnv {
4123 let mut values = values.clone();
4124 apply_member_actions(source_state, actions, semantics, &mut values);
4125 values
4126}
4127
4128fn return_values_after_action(
4130 source_state: usize,
4131 rule_index: usize,
4132 actions: &[ParserReturnAction],
4133 semantics: Option<&ParserSemantics>,
4134 values: &BTreeMap<String, i64>,
4135) -> BTreeMap<String, i64> {
4136 let mut values = values.clone();
4137 for action in actions
4138 .iter()
4139 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
4140 {
4141 values.insert(action.name.to_owned(), action.value);
4142 }
4143 if let Some(semantics) = semantics {
4144 let mut member_values = MemberEnv::new();
4145 let mut ctx = ParserTableSemCtx {
4146 member_values: &mut member_values,
4147 return_values: &mut values,
4148 };
4149 for action in semantics.actions.iter().filter(|action| {
4150 action.source_state == source_state
4151 && action.rule_index == rule_index
4152 && !action.speculative
4153 }) {
4154 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
4155 }
4156 }
4157 values
4158}
4159
4160fn rule_local_int_arg(
4162 rule_args: &[ParserRuleArg],
4163 source_state: usize,
4164 rule_index: usize,
4165 local_int_arg: Option<(usize, i64)>,
4166) -> Option<(usize, i64)> {
4167 rule_args
4168 .iter()
4169 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
4170 .map(|arg| {
4171 let value = if arg.inherit_local {
4172 local_int_arg.map_or(arg.value, |(_, value)| value)
4173 } else {
4174 arg.value
4175 };
4176 (rule_index, value)
4177 })
4178}
4179
4180fn stop_outcome(
4183 index: usize,
4184 consumed_eof: bool,
4185 rule_alt_number: usize,
4186 member_values: MemberEnv,
4187 return_values: BTreeMap<String, i64>,
4188) -> Vec<RecognizeOutcome> {
4189 vec![RecognizeOutcome {
4190 index,
4191 consumed_eof,
4192 alt_number: rule_alt_number,
4193 member_values,
4194 return_values,
4195 diagnostics: DiagnosticSeqId::EMPTY,
4196 decisions: Vec::new(),
4197 actions: Vec::new(),
4198 nodes: NodeSeqId::EMPTY,
4199 }]
4200}
4201
4202fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
4203 with_shared_atn_caches(atn, |cache| {
4204 *cache.observable_action_transitions.get_or_insert_with(|| {
4205 atn.states().any(|state| {
4206 state.transitions().iter().any(|transition| {
4207 matches!(
4208 &transition.data(),
4209 Transition::Action {
4210 action_index: Some(_),
4211 ..
4212 }
4213 )
4214 })
4215 })
4216 })
4217 })
4218}
4219
4220fn atn_has_predicate_transitions(atn: &Atn) -> bool {
4221 with_shared_atn_caches(atn, |cache| {
4222 *cache.predicate_transitions.get_or_insert_with(|| {
4223 atn.states().any(|state| {
4224 state
4225 .transitions()
4226 .iter()
4227 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
4228 })
4229 })
4230 })
4231}
4232
4233fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
4238 options.init_action_rules.is_empty()
4239 && options.action_indices.is_empty()
4240 && !options.track_alt_numbers
4241 && options
4242 .predicates
4243 .iter()
4244 .all(|(_, _, predicate)| predicate.failure_message().is_none())
4245 && options.semantics.is_none_or(|semantics| {
4246 semantics.actions.is_empty()
4247 && semantics
4248 .predicates
4249 .iter()
4250 .all(|predicate| predicate.failure_message.is_none())
4251 })
4252 && options.rule_args.is_empty()
4253 && options.member_actions.is_empty()
4254 && options.return_actions.is_empty()
4255 && !atn_has_observable_action_transitions(atn)
4256}
4257
4258#[derive(Clone, Debug, Eq, PartialEq)]
4259struct RecognizeRequest<'a> {
4260 state_number: usize,
4261 stop_state: usize,
4262 index: usize,
4263 rule_start_index: usize,
4264 decision_start_index: Option<usize>,
4265 init_action_rules: &'a BTreeSet<usize>,
4266 predicates: &'a [(usize, usize, ParserPredicate)],
4267 semantics: Option<&'a ParserSemantics>,
4268 rule_args: &'a [ParserRuleArg],
4269 member_actions: &'a [ParserMemberAction],
4270 return_actions: &'a [ParserReturnAction],
4271 local_int_arg: Option<(usize, i64)>,
4272 member_values: MemberEnv,
4273 return_values: BTreeMap<String, i64>,
4274 rule_alt_number: usize,
4275 track_alt_numbers: bool,
4276 consumed_eof: bool,
4277 committed_decision: bool,
4278 precedence: i32,
4281 depth: usize,
4282 recovery_symbols: BTreeSet<i32>,
4283 recovery_state: Option<usize>,
4284}
4285
4286#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
4287struct RecognizeKey {
4288 state_number: usize,
4289 stop_state: usize,
4290 index: usize,
4291 rule_start_index: usize,
4292 decision_start_index: Option<usize>,
4293 local_int_arg: Option<(usize, i64)>,
4294 member_values: MemberEnv,
4295 return_values: BTreeMap<String, i64>,
4296 rule_alt_number: usize,
4297 track_alt_numbers: bool,
4298 consumed_eof: bool,
4299 committed_decision: bool,
4300 precedence: i32,
4301 recovery_symbols: BTreeSet<i32>,
4302 recovery_state: Option<usize>,
4303}
4304
4305#[derive(Clone, Debug, Eq, PartialEq)]
4306struct EpsilonActionStep {
4307 source_state: usize,
4308 target: usize,
4309 action_rule_index: Option<usize>,
4310 action_index: Option<usize>,
4311 left_recursive_boundary: Option<usize>,
4312 decision: Option<usize>,
4313 decision_start_index: Option<usize>,
4314 alt_number: usize,
4315 recovery_symbols: BTreeSet<i32>,
4316 recovery_state: Option<usize>,
4317}
4318
4319struct RecognizeScratch<'a> {
4320 visiting: &'a mut BTreeSet<RecognizeKey>,
4321 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4322 expected: &'a mut ExpectedTokens,
4323}
4324
4325#[derive(Clone, Debug, Eq, PartialEq)]
4326struct FastRecognizeRequest {
4327 state_number: usize,
4328 stop_state: usize,
4329 index: usize,
4330 rule_start_index: usize,
4331 decision_start_index: Option<usize>,
4332 precedence: i32,
4333 depth: usize,
4334 recovery_symbols: Rc<BTreeSet<i32>>,
4335 recovery_state: Option<usize>,
4336}
4337
4338#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4339struct FastRecognizeTopRequest {
4340 start_state: usize,
4341 stop_state: usize,
4342 start_index: usize,
4343 precedence: i32,
4344 caller_follow_state: Option<usize>,
4345}
4346
4347#[derive(Clone, Copy, Debug)]
4348struct FastPredicateContext<'a> {
4349 predicates: &'a [(usize, usize, ParserPredicate)],
4350 semantics: Option<&'a ParserSemantics>,
4351 member_values: &'a MemberEnv,
4352}
4353
4354#[derive(Clone, Copy, Debug, Default)]
4355struct AltNumberTracking {
4356 public: bool,
4357 context: bool,
4358}
4359
4360impl AltNumberTracking {
4361 const fn any(self) -> bool {
4362 self.public || self.context
4363 }
4364}
4365
4366struct FastRecognizeScratch<'a, 'b> {
4367 predicate_context: Option<FastPredicateContext<'a>>,
4368 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4369 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4370 expected: &'b mut ExpectedTokens,
4371 native_depth: usize,
4372}
4373
4374#[derive(Clone, Copy, Debug)]
4375struct FastRepetitionShape {
4376 enter_target: usize,
4377 exit_target: usize,
4378 body_stop_state: usize,
4379 enter_transition_index: usize,
4380 exit_transition_index: usize,
4381}
4382
4383#[derive(Clone, Copy, Debug)]
4384struct FastRepetitionPath {
4385 index: usize,
4386 deferred_nodes: FastDeferredNodeId,
4387 diagnostics: DiagnosticSeqId,
4388 consumed_eof: bool,
4389}
4390
4391enum FastRepetitionWork {
4392 Enter(FastRepetitionPath),
4393 Exit(FastRepetitionPath),
4394}
4395
4396struct FastRepetitionCoordinates {
4401 base_index: usize,
4402 base_state: u8,
4403 later_states: Vec<u8>,
4404}
4405
4406impl FastRepetitionCoordinates {
4407 const ENTERED: u8 = 0;
4408 const EXITED: u8 = 2;
4409
4410 const fn new(base_index: usize) -> Self {
4411 Self {
4412 base_index,
4413 base_state: 0,
4414 later_states: Vec::new(),
4415 }
4416 }
4417
4418 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4419 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4420 }
4421
4422 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4423 self.insert(path.index, path.consumed_eof, Self::EXITED)
4424 }
4425
4426 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4427 let Some(offset) = index.checked_sub(self.base_index) else {
4428 return false;
4429 };
4430 let state = if offset == 0 {
4431 &mut self.base_state
4432 } else {
4433 if self.later_states.len() < offset {
4434 self.later_states.resize(offset, 0);
4435 }
4436 &mut self.later_states[offset - 1]
4437 };
4438 let bit = 1 << (base_bit + u8::from(consumed_eof));
4439 let is_new = *state & bit == 0;
4440 *state |= bit;
4441 is_new
4442 }
4443}
4444
4445fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4446 if state.precedence_rule_decision()
4447 || !matches!(
4448 state.kind(),
4449 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4450 )
4451 || state.transitions().len() != 2
4452 {
4453 return None;
4454 }
4455 let mut enter = None;
4456 let mut exit = None;
4457 for (index, transition) in state.transitions().iter().enumerate() {
4458 if transition.kind() != ParserTransitionKind::Epsilon {
4459 return None;
4460 }
4461 let target = transition.target();
4462 if atn
4463 .state(target)
4464 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4465 {
4466 if exit.replace((index, target)).is_some() {
4467 return None;
4468 }
4469 } else if enter.replace((index, target)).is_some() {
4470 return None;
4471 }
4472 }
4473 let (enter_transition_index, enter_target) = enter?;
4474 let (exit_transition_index, exit_target) = exit?;
4475 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4476 atn.state(exit_target)?.loop_back_state()?
4477 } else {
4478 state.state_number()
4479 };
4480 Some(FastRepetitionShape {
4481 enter_target,
4482 exit_target,
4483 body_stop_state,
4484 enter_transition_index,
4485 exit_transition_index,
4486 })
4487}
4488
4489fn push_fast_repetition_work(
4490 work: &mut Vec<FastRepetitionWork>,
4491 shape: FastRepetitionShape,
4492 path: FastRepetitionPath,
4493 lookahead: Option<&DecisionLookahead>,
4494 symbol: i32,
4495) {
4496 let transition_is_viable = |transition_index: usize| {
4499 let Some(entry) = lookahead else {
4500 return true;
4501 };
4502 let Some(transition) = entry.transitions.get(transition_index) else {
4503 return true;
4504 };
4505 transition.nullable || transition.symbols.contains(symbol)
4506 };
4507 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4508 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4509 if shape.enter_transition_index < shape.exit_transition_index {
4510 if exit_is_viable {
4511 work.push(FastRepetitionWork::Exit(path));
4512 }
4513 if enter_is_viable {
4514 work.push(FastRepetitionWork::Enter(path));
4515 }
4516 } else {
4517 if enter_is_viable {
4518 work.push(FastRepetitionWork::Enter(path));
4519 }
4520 if exit_is_viable {
4521 work.push(FastRepetitionWork::Exit(path));
4522 }
4523 }
4524}
4525
4526#[derive(Clone, Debug)]
4533struct FastRecognizeKey {
4534 state_number: usize,
4535 stop_state: usize,
4536 index: usize,
4537 rule_start_index: usize,
4538 decision_start_index: Option<usize>,
4539 precedence: i32,
4540 recovery_symbols_id: usize,
4541 recovery_state: Option<usize>,
4542}
4543
4544impl PartialEq for FastRecognizeKey {
4545 fn eq(&self, other: &Self) -> bool {
4546 if self.state_number != other.state_number
4547 || self.stop_state != other.stop_state
4548 || self.index != other.index
4549 || self.rule_start_index != other.rule_start_index
4550 || self.decision_start_index != other.decision_start_index
4551 || self.precedence != other.precedence
4552 || self.recovery_state != other.recovery_state
4553 || self.recovery_symbols_id != other.recovery_symbols_id
4554 {
4555 return false;
4556 }
4557 true
4558 }
4559}
4560
4561impl Eq for FastRecognizeKey {}
4562
4563impl Hash for FastRecognizeKey {
4564 fn hash<H: Hasher>(&self, hasher: &mut H) {
4565 self.state_number.hash(hasher);
4566 self.stop_state.hash(hasher);
4567 self.index.hash(hasher);
4568 self.rule_start_index.hash(hasher);
4569 self.decision_start_index.hash(hasher);
4570 self.precedence.hash(hasher);
4571 self.recovery_state.hash(hasher);
4572 self.recovery_symbols_id.hash(hasher);
4573 }
4574}
4575
4576struct FastRecoveryRequest<'a, 'b> {
4577 atn: &'a Atn,
4578 transition: ParserTransition<'a>,
4579 expected_symbols: Rc<BTreeSet<i32>>,
4580 target: usize,
4581 request: FastRecognizeRequest,
4582 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4583 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4584 expected: &'b mut ExpectedTokens,
4585}
4586
4587struct FastCurrentTokenDeletionRequest<'a, 'b> {
4588 atn: &'a Atn,
4589 expected_symbols: Rc<BTreeSet<i32>>,
4590 request: FastRecognizeRequest,
4591 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4592 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4593 expected: &'b mut ExpectedTokens,
4594}
4595
4596#[derive(Clone, Copy)]
4597struct FastChildRuleFailureRecoveryRequest<'a> {
4598 atn: &'a Atn,
4599 rule_index: usize,
4600 start_index: usize,
4601 follow_state: usize,
4602 stop_state: usize,
4603 expected: &'a ExpectedTokens,
4604}
4605
4606struct RecoveryRequest<'a, 'b> {
4607 atn: &'a Atn,
4608 transition: ParserTransition<'a>,
4609 expected_symbols: BTreeSet<i32>,
4610 target: usize,
4611 request: RecognizeRequest<'a>,
4612 visiting: &'b mut BTreeSet<RecognizeKey>,
4613 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4614 expected: &'b mut ExpectedTokens,
4615}
4616
4617struct CurrentTokenDeletionRequest<'a, 'b> {
4618 atn: &'a Atn,
4619 expected_symbols: BTreeSet<i32>,
4620 request: RecognizeRequest<'a>,
4621 visiting: &'b mut BTreeSet<RecognizeKey>,
4622 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4623 expected: &'b mut ExpectedTokens,
4624}
4625
4626struct ConsumingFailureFallback<'a> {
4629 atn: &'a Atn,
4630 target: usize,
4631 request: RecognizeRequest<'a>,
4632 symbol: i32,
4633 expected_symbols: BTreeSet<i32>,
4634 decision_start_index: Option<usize>,
4635 decision: Option<usize>,
4636}
4637
4638struct ChildRuleFailureRecovery<'a> {
4641 atn: &'a Atn,
4642 rule_index: usize,
4643 start_index: usize,
4644 follow_state: usize,
4645 stop_state: usize,
4646 member_values: MemberEnv,
4647 expected: &'a ExpectedTokens,
4648}
4649
4650#[derive(Clone, Copy, Debug)]
4652struct PredicateEval<'a> {
4653 index: usize,
4654 rule_index: usize,
4655 pred_index: usize,
4656 predicates: &'a [(usize, usize, ParserPredicate)],
4657 semantics: Option<&'a ParserSemantics>,
4658 context: Option<&'a ParserRuleContext>,
4659 local_int_arg: Option<(usize, i64)>,
4660 member_values: &'a MemberEnv,
4661}
4662
4663#[derive(Clone, Copy, Debug)]
4664struct ParserSemanticHookRequest<'a> {
4665 index: usize,
4666 rule_index: usize,
4667 pred_index: usize,
4668 context: Option<&'a ParserRuleContext>,
4669 local_int_arg: Option<(usize, i64)>,
4670 member_values: &'a MemberEnv,
4671}
4672
4673struct ParserSemIrCtx<'a, S, H>
4682where
4683 S: TokenSource,
4684 H: SemanticHooks,
4685{
4686 input: &'a mut CommonTokenStream<S>,
4687 tree_storage: &'a ParseTreeStorage,
4688 semantic_hooks: &'a mut H,
4689 rule_index: usize,
4690 coordinate_index: usize,
4691 rule_name: Option<&'a str>,
4692 context: Option<&'a ParserRuleContext>,
4693 local_int_arg: Option<(usize, i64)>,
4694 member_values: &'a MemberEnv,
4695 invoked_predicates: &'a mut Vec<(usize, usize)>,
4696 unknown_predicate_policy: UnknownSemanticPolicy,
4700 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4701}
4702
4703impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4704where
4705 S: TokenSource,
4706 H: SemanticHooks,
4707{
4708 type TokenText<'a>
4709 = TokenView<'a>
4710 where
4711 Self: 'a;
4712
4713 fn la(&mut self, offset: isize) -> i64 {
4714 i64::from(self.input.la(offset))
4715 }
4716
4717 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4718 self.input.lt(offset)
4719 }
4720
4721 fn token_index_adjacent(&mut self) -> bool {
4722 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4723 return false;
4724 };
4725 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4726 return false;
4727 };
4728 first + 1 == second
4729 }
4730
4731 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4732 self.context.and_then(|context| {
4733 context
4734 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4735 .next()
4736 .map(crate::tree::RuleNodeView::text)
4737 })
4738 }
4739
4740 fn member(&self, member: usize) -> Option<i64> {
4741 Some(self.member_values.scalar(member).unwrap_or_default())
4742 }
4743
4744 fn member_top(&self, member: usize) -> Option<i64> {
4745 self.member_values.stack_top(member)
4746 }
4747
4748 fn member_len(&self, member: usize) -> usize {
4749 self.member_values.stack_len(member)
4750 }
4751
4752 fn local_arg(&self) -> Option<i64> {
4753 self.local_int_arg.map(|(_, value)| value)
4754 }
4755
4756 fn column(&self) -> Option<i64> {
4757 None
4758 }
4759
4760 fn token_start_column(&self) -> Option<i64> {
4761 None
4762 }
4763
4764 fn token_text_so_far(&self) -> Option<String> {
4765 None
4766 }
4767
4768 fn hook(&mut self, _hook: HookId) -> bool {
4769 let mut ctx = ParserSemCtx {
4770 input: &mut *self.input,
4771 tree_storage: self.tree_storage,
4772 rule_index: self.rule_index,
4773 coordinate_index: self.coordinate_index,
4774 rule_name: self.rule_name.map(str::to_owned),
4775 context: self.context,
4776 tree: None,
4777 local_int_arg: self.local_int_arg,
4778 member_values: self.member_values,
4779 action: None,
4780 };
4781 match self
4782 .semantic_hooks
4783 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4784 {
4785 Some(result) => result,
4786 None => apply_unknown_predicate_policy(
4790 self.unknown_predicate_policy,
4791 self.rule_index,
4792 self.coordinate_index,
4793 self.unknown_predicate_hits,
4794 ),
4795 }
4796 }
4797
4798 fn trace_bool(&mut self, value: bool) -> bool {
4799 let key = (self.rule_index, self.coordinate_index);
4800 if !self.invoked_predicates.contains(&key) {
4801 self.invoked_predicates.push(key);
4802 use std::io::Write as _;
4803 let mut stdout = std::io::stdout().lock();
4804 let _ = writeln!(stdout, "eval={value}");
4805 }
4806 value
4807 }
4808}
4809
4810struct PredicateFailureRecovery<'a> {
4812 rule_index: usize,
4813 index: usize,
4814 message: &'a str,
4815 member_values: MemberEnv,
4816 return_values: BTreeMap<String, i64>,
4817 rule_alt_number: usize,
4818}
4819
4820#[derive(Debug)]
4821enum DirectAdaptiveParseControl {
4822 Fallback(DirectAdaptiveFallback),
4823}
4824
4825#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4826enum DirectAdaptiveFallback {
4827 Action,
4828 InvalidAlt,
4829 LeftRecursiveBoundary,
4830 MissingAtn,
4831 NoTransition,
4832 Predicate,
4833 Prediction,
4834 Precedence,
4835 RuleStop,
4836 SemanticContext,
4837 StepLimit,
4838 TokenMismatch,
4839 UnknownDecision,
4840}
4841
4842type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
4843
4844struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
4845where
4846 S: TokenSource,
4847 H: SemanticHooks,
4848{
4849 parser: &'sim mut BaseParser<S, H>,
4850 atn: &'atn Atn,
4851 simulator: &'sim mut ParserAtnSimulator<'atn>,
4852 decision_by_state: Vec<Option<usize>>,
4853 steps: usize,
4854}
4855
4856struct CommittedAtnParser<'atn, 'sim, 'options, S, H = NoSemanticHooks>
4857where
4858 S: TokenSource,
4859 H: SemanticHooks,
4860{
4861 parser: &'sim mut BaseParser<S, H>,
4862 atn: &'atn Atn,
4863 simulator: ParserAtnSimulator<'atn>,
4864 options: ParserRuntimeOptions<'options>,
4865 decision_by_state: Vec<Option<usize>>,
4866 action_index_by_state: FxHashMap<usize, usize>,
4867 deferred_actions: Vec<ParserAction>,
4868}
4869
4870struct CommittedRuleOutcome {
4871 tree: ParseTree,
4872 consumed_eof: bool,
4873}
4874
4875struct CommittedDecisionContext<'a> {
4876 precedence: i32,
4877 local_int_arg: Option<(usize, i64)>,
4878 context: &'a mut ParserRuleContext,
4879 entered_loops: &'a mut BTreeSet<usize>,
4880}
4881
4882#[derive(Clone, Debug, Eq, PartialEq)]
4892pub struct GeneratedMatch {
4893 children: GeneratedMatchChildren,
4894 consumed_eof: bool,
4895}
4896
4897#[derive(Clone, Copy)]
4898enum GeneratedExpectedSymbols<'a> {
4899 Tree(&'a BTreeSet<i32>),
4900 TokenSet(ParserIntervalSet<'a>),
4901 TokenSetComplement {
4902 set: ParserIntervalSet<'a>,
4903 min_vocabulary: i32,
4904 max_vocabulary: i32,
4905 },
4906}
4907
4908impl GeneratedExpectedSymbols<'_> {
4909 fn is_empty(self) -> bool {
4910 match self {
4911 Self::Tree(symbols) => symbols.is_empty(),
4912 Self::TokenSet(set) => set.is_empty(),
4913 Self::TokenSetComplement {
4914 set,
4915 min_vocabulary,
4916 max_vocabulary,
4917 } => (min_vocabulary..=max_vocabulary).all(|symbol| set.contains(symbol)),
4918 }
4919 }
4920
4921 fn first(self) -> Option<i32> {
4922 match self {
4923 Self::Tree(symbols) => symbols.iter().next().copied(),
4924 Self::TokenSet(set) => set.ranges().next().map(|(start, _)| start),
4925 Self::TokenSetComplement {
4926 set,
4927 min_vocabulary,
4928 max_vocabulary,
4929 } => (min_vocabulary..=max_vocabulary).find(|symbol| !set.contains(*symbol)),
4930 }
4931 }
4932
4933 fn display(self, vocabulary: &Vocabulary) -> String {
4934 match self {
4935 Self::Tree(symbols) => expected_symbols_display(symbols, vocabulary),
4936 Self::TokenSet(set) => expected_symbols_display_iter(
4937 set.ranges().flat_map(|(start, stop)| start..=stop),
4938 vocabulary,
4939 ),
4940 Self::TokenSetComplement {
4941 set,
4942 min_vocabulary,
4943 max_vocabulary,
4944 } => expected_symbols_display_iter(
4945 (min_vocabulary..=max_vocabulary).filter(|symbol| !set.contains(*symbol)),
4946 vocabulary,
4947 ),
4948 }
4949 }
4950}
4951
4952#[derive(Clone, Debug, Eq, PartialEq)]
4953enum GeneratedMatchChildren {
4954 One(ParseTree),
4955 Many(Vec<ParseTree>),
4956}
4957
4958struct GeneratedMatchChildrenIntoIter {
4959 one: Option<ParseTree>,
4960 many: Option<std::vec::IntoIter<ParseTree>>,
4961}
4962
4963impl Iterator for GeneratedMatchChildrenIntoIter {
4964 type Item = ParseTree;
4965
4966 fn next(&mut self) -> Option<Self::Item> {
4967 self.one
4968 .take()
4969 .or_else(|| self.many.as_mut().and_then(Iterator::next))
4970 }
4971}
4972
4973impl GeneratedMatch {
4974 #[must_use]
4978 pub fn children(&self) -> &[ParseTree] {
4979 match &self.children {
4980 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
4981 GeneratedMatchChildren::Many(children) => children,
4982 }
4983 }
4984
4985 #[must_use]
4988 pub fn into_children(self) -> Vec<ParseTree> {
4989 match self.children {
4990 GeneratedMatchChildren::One(child) => vec![child],
4991 GeneratedMatchChildren::Many(children) => children,
4992 }
4993 }
4994
4995 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
4997 match self.children {
4998 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
4999 one: Some(child),
5000 many: None,
5001 },
5002 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
5003 one: None,
5004 many: Some(children.into_iter()),
5005 },
5006 }
5007 }
5008
5009 #[must_use]
5011 pub const fn consumed_eof(&self) -> bool {
5012 self.consumed_eof
5013 }
5014}
5015
5016impl<S> BaseParser<S, NoSemanticHooks>
5017where
5018 S: TokenSource,
5019{
5020 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
5023 Self::with_semantic_hooks(input, data, NoSemanticHooks)
5024 }
5025}
5026
5027impl<S, H> BaseParser<S, H>
5028where
5029 S: TokenSource,
5030 H: SemanticHooks,
5031{
5032 pub fn with_semantic_hooks(
5034 input: CommonTokenStream<S>,
5035 data: RecognizerData,
5036 semantic_hooks: H,
5037 ) -> Self {
5038 Self {
5039 input,
5040 tree: ParseTreeStorage::new(),
5041 data,
5042 semantic_hooks,
5043 decision_override_generation: 0,
5044 build_parse_trees: true,
5045 syntax_errors: 0,
5046 report_diagnostic_errors: false,
5047 prediction_mode: PredictionMode::Ll,
5048 prediction_diagnostics: Vec::new(),
5049 reported_prediction_diagnostics: BTreeSet::new(),
5050 generated_parser_diagnostics: Vec::new(),
5051 generated_sync_expected: None,
5052 generated_recovery_error_index: None,
5053 generated_recovery_error_states: BTreeSet::new(),
5054 int_members: MemberEnv::new(),
5055 rule_context_stack: Vec::new(),
5056 rule_context_version: 0,
5057 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
5058 pending_invoking_states: Vec::new(),
5059 precedence_stack: vec![0],
5060 invoked_predicates: Vec::new(),
5061 bail_on_error: false,
5062 parse_listeners: Vec::new(),
5063 parse_listener_abort: None,
5064 max_rule_depth: None,
5065 rule_depth_error: None,
5066 recursion_expansions: 0,
5067 recursion_expansion_marks: Vec::new(),
5068 unknown_predicate_policy: UnknownSemanticPolicy::default(),
5069 unknown_predicate_hits: Vec::new(),
5070 unhandled_action_hits: Vec::new(),
5071 rule_first_set_cache: Vec::new(),
5072 state_expected_cache: FxHashMap::default(),
5073 state_expected_token_cache: FxHashMap::default(),
5074 rule_stop_reach_cache: Vec::new(),
5075 recovery_symbols_intern: FxHashMap::default(),
5076 decision_lookahead_cache: FxHashMap::default(),
5077 ll1_decision_cache: FxHashMap::default(),
5078 fast_predicate_cache: FxHashMap::default(),
5079 empty_cycle_cache: Vec::new(),
5080 empty_cycle_cache_atn: None,
5081 clean_memo_mode: CleanMemoMode::Probe,
5082 clean_memo_probe_seen: FxHashSet::default(),
5083 clean_memo_probe_samples: 0,
5084 clean_memo_probe_repeats: 0,
5085 clean_memo_sparse_samples: 0,
5086 fast_recognize_scratch: FastRecognizeTopScratch::default(),
5087 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
5088 empty_recovery_symbols: Rc::new(BTreeSet::new()),
5089 fast_first_set_prefilter: true,
5090 fast_recovery_enabled: true,
5091 fast_token_nodes_enabled: true,
5092 fast_track_alt_numbers: false,
5093 recognition_arena: RecognitionArena::default(),
5094 last_recognition_arena_root: NodeSeqId::EMPTY,
5095 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
5096 }
5097 }
5098
5099 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
5100 &mut self.input
5101 }
5102
5103 pub fn reset(&mut self) {
5108 self.input.seek(0);
5109 self.tree.reset();
5110 self.data.set_state(-1);
5111 self.syntax_errors = 0;
5112 self.prediction_diagnostics.clear();
5113 self.reported_prediction_diagnostics.clear();
5114 self.generated_parser_diagnostics.clear();
5115 self.generated_sync_expected = None;
5116 self.reset_generated_recovery_state();
5117 self.rule_context_stack.clear();
5118 self.advance_rule_context_version();
5119 self.left_recursive_caller_overlap_cache = std::array::from_fn(|_| None);
5120 self.pending_invoking_states.clear();
5121 self.precedence_stack.clear();
5122 self.precedence_stack.push(0);
5123 self.invoked_predicates.clear();
5124 self.decision_override_generation = 0;
5125 self.unknown_predicate_hits.clear();
5126 self.unhandled_action_hits.clear();
5127 self.parse_listener_abort = None;
5128 self.rule_depth_error = None;
5129 self.recursion_expansions = 0;
5130 self.recursion_expansion_marks.clear();
5131 self.reset_per_parse_caches();
5132 self.fast_first_set_prefilter = true;
5133 self.fast_recovery_enabled = true;
5134 self.fast_token_nodes_enabled = self.build_parse_trees;
5135 self.fast_track_alt_numbers = false;
5136 self.reset_recognition_arena();
5137 }
5138
5139 pub fn set_token_stream(&mut self, input: CommonTokenStream<S>) {
5141 self.input = input;
5142 self.reset();
5143 }
5144
5145 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
5156 self.unknown_predicate_policy = policy;
5157 }
5158
5159 #[must_use]
5165 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
5166 let error = self.unknown_semantic_error();
5167 self.unknown_predicate_hits.clear();
5168 self.unhandled_action_hits.clear();
5169 error
5170 }
5171
5172 pub fn reset_unknown_semantic_hits(&mut self) {
5179 self.unknown_predicate_hits.clear();
5180 self.unhandled_action_hits.clear();
5181 }
5182
5183 #[must_use]
5185 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
5186 &self.input
5187 }
5188
5189 #[must_use]
5191 pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<S> {
5192 &mut self.input
5193 }
5194
5195 #[must_use]
5197 pub const fn token_store(&self) -> &TokenStore {
5198 self.input.token_store()
5199 }
5200
5201 #[must_use]
5203 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
5204 &self.tree
5205 }
5206
5207 #[must_use]
5209 pub fn node(&self, id: NodeId) -> Node<'_> {
5210 self.tree
5211 .node(self.input.token_store(), id)
5212 .expect("parser-produced node ID should remain valid")
5213 }
5214
5215 #[must_use]
5217 pub fn into_token_stream(self) -> CommonTokenStream<S> {
5218 self.input
5219 }
5220
5221 #[must_use]
5223 pub fn into_token_store(self) -> TokenStore {
5224 self.input.into_token_store()
5225 }
5226
5227 #[must_use]
5229 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
5230 ParsedFile::new(self.input.into_token_store(), self.tree, root)
5231 }
5232
5233 pub const fn number_of_syntax_errors(&self) -> usize {
5236 self.syntax_errors
5237 }
5238
5239 #[must_use]
5245 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
5246 self.recognition_arena.stats(
5247 self.last_recognition_arena_root,
5248 self.last_recognition_arena_diagnostics,
5249 )
5250 }
5251
5252 pub const fn record_generated_syntax_error(&mut self) {
5255 self.record_syntax_errors(1);
5256 }
5257
5258 const fn record_syntax_errors(&mut self, count: usize) {
5259 self.syntax_errors = self.syntax_errors.saturating_add(count);
5260 }
5261
5262 const fn is_top_level_entry(&self) -> bool {
5264 self.rule_context_stack.is_empty() && self.pending_invoking_states.is_empty()
5265 }
5266
5267 pub fn report_token_source_errors(&mut self) {
5270 let errors = self.input.drain_source_errors();
5271 self.dispatch_token_source_errors(&errors);
5272 }
5273
5274 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
5277 GeneratedDiagnosticsCheckpoint {
5278 diagnostics_len: self.generated_parser_diagnostics.len(),
5279 syntax_errors: self.syntax_errors,
5280 tree: self.tree.checkpoint(),
5281 }
5282 }
5283
5284 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
5286 self.generated_parser_diagnostics
5287 .truncate(marker.diagnostics_len);
5288 self.syntax_errors = marker.syntax_errors;
5289 self.rollback_generated_tree(marker);
5290 }
5291
5292 pub fn rollback_generated_tree(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
5298 self.generated_sync_expected = None;
5299 self.tree.rollback(marker.tree);
5300 }
5301
5302 pub fn report_generated_parser_diagnostics(&mut self) {
5304 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
5305 let token_errors = self.input.drain_source_errors();
5306 self.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
5307 }
5308
5309 fn syntax_error_event<'a>(
5310 &'a self,
5311 offending: Option<TokenId>,
5312 line: usize,
5313 column: usize,
5314 message: &'a str,
5315 error: Option<&'a AntlrError>,
5316 ) -> SyntaxErrorEvent<'a> {
5317 let offending = offending.and_then(|token| self.token_store().view(token));
5318 SyntaxErrorEvent {
5319 offending,
5320 line,
5321 column,
5322 span: offending.and_then(|token| token.byte_span()),
5323 message,
5324 error,
5325 }
5326 }
5327
5328 pub fn report_unrecovered_parser_error(&self, error: &AntlrError) {
5333 let AntlrError::ParserError {
5334 line,
5335 column,
5336 message,
5337 offending,
5338 } = error
5339 else {
5340 return;
5341 };
5342 self.notify_error_listeners(self.syntax_error_event(
5343 *offending,
5344 *line,
5345 *column,
5346 message,
5347 Some(error),
5348 ));
5349 }
5350
5351 fn dispatch_parser_diagnostic(&self, diagnostic: &ParserDiagnostic) {
5352 self.notify_error_listeners(self.syntax_error_event(
5353 diagnostic.offending,
5354 diagnostic.line,
5355 diagnostic.column,
5356 &diagnostic.message,
5357 None,
5358 ));
5359 }
5360
5361 fn dispatch_parser_diagnostics<'a>(
5362 &self,
5363 diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>,
5364 ) {
5365 for diagnostic in diagnostics {
5366 self.dispatch_parser_diagnostic(diagnostic);
5367 }
5368 }
5369
5370 fn dispatch_token_source_error(&self, source_error: &TokenSourceError) {
5371 if self.input.token_source().report_error(source_error) {
5372 return;
5373 }
5374 self.notify_error_listeners(source_error.into());
5377 }
5378
5379 fn dispatch_token_source_errors(&self, errors: &[TokenSourceError]) {
5380 for error in errors {
5381 self.dispatch_token_source_error(error);
5382 }
5383 }
5384
5385 fn dispatch_generated_diagnostics(
5388 &self,
5389 parser_diagnostics: &[ParserDiagnostic],
5390 token_errors: &[TokenSourceError],
5391 ) {
5392 let mut token_iter = token_errors.iter().peekable();
5398 for diagnostic in parser_diagnostics {
5399 while let Some(error) = token_iter.peek() {
5400 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
5401 self.dispatch_token_source_error(error);
5402 token_iter.next();
5403 } else {
5404 break;
5405 }
5406 }
5407 self.dispatch_parser_diagnostic(diagnostic);
5408 }
5409 for error in token_iter {
5410 self.dispatch_token_source_error(error);
5411 }
5412 }
5413
5414 pub fn record_generated_ambiguity_diagnostic(
5417 &mut self,
5418 atn: &Atn,
5419 state_number: usize,
5420 start_index: usize,
5421 stop_index: usize,
5422 alts: &[usize],
5423 ) {
5424 if !self.report_diagnostic_errors || alts.len() < 2 {
5425 return;
5426 }
5427 let Some(decision) = atn
5428 .decision_to_state()
5429 .iter()
5430 .position(|candidate| candidate == state_number)
5431 else {
5432 return;
5433 };
5434 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5435 return;
5436 };
5437 let rule_name = self
5438 .rule_names()
5439 .get(rule_index)
5440 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5441 let input = display_input_text(&self.input.text(start_index, stop_index));
5442 let alts = alts
5443 .iter()
5444 .map(usize::to_string)
5445 .collect::<Vec<_>>()
5446 .join(", ");
5447 let key = (decision, start_index, format!("{alts}:{input}"));
5448 if !self.reported_prediction_diagnostics.insert(key) {
5449 return;
5450 }
5451 let start_diagnostic = diagnostic_for_token(
5452 self.token_at(start_index),
5453 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
5454 );
5455 let stop_diagnostic = diagnostic_for_token(
5456 self.token_at(stop_index),
5457 format!(
5458 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
5459 ),
5460 );
5461 self.generated_parser_diagnostics.push(start_diagnostic);
5462 self.generated_parser_diagnostics.push(stop_diagnostic);
5463 }
5464
5465 pub fn record_generated_prediction_diagnostic(
5468 &mut self,
5469 atn: &Atn,
5470 state_number: usize,
5471 prediction: &ParserAtnPrediction,
5472 ) {
5473 let Some(diagnostic) = &prediction.diagnostic else {
5474 return;
5475 };
5476 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5477 return;
5478 }
5479 let Some(decision) = atn
5480 .decision_to_state()
5481 .iter()
5482 .position(|candidate| candidate == state_number)
5483 else {
5484 return;
5485 };
5486 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5487 return;
5488 };
5489 let rule_name = self
5490 .rule_names()
5491 .get(rule_index)
5492 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5493 let attempt_input = display_input_text(
5494 &self
5495 .input
5496 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5497 );
5498 let result_input = display_input_text(
5499 &self
5500 .input
5501 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5502 );
5503 let alts = diagnostic
5504 .conflicting_alts
5505 .iter()
5506 .map(usize::to_string)
5507 .collect::<Vec<_>>()
5508 .join(", ");
5509 let key = (
5510 decision,
5511 diagnostic.start_index,
5512 format!(
5513 "{:?}:{alts}:{attempt_input}:{result_input}",
5514 diagnostic.kind
5515 ),
5516 );
5517 if !self.reported_prediction_diagnostics.insert(key) {
5518 return;
5519 }
5520 let attempt_diagnostic = diagnostic_for_token(
5521 self.token_at(diagnostic.sll_stop_index),
5522 format!(
5523 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5524 ),
5525 );
5526 self.generated_parser_diagnostics.push(attempt_diagnostic);
5527 let message = match diagnostic.kind {
5528 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5529 if !diagnostic.exact {
5534 return;
5535 }
5536 format!(
5537 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5538 )
5539 }
5540 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5541 format!(
5542 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5543 )
5544 }
5545 };
5546 let result_diagnostic =
5547 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5548 self.generated_parser_diagnostics.push(result_diagnostic);
5549 }
5550
5551 pub fn la(&self, offset: isize) -> i32 {
5552 self.input.la_token(offset)
5553 }
5554
5555 pub fn consume(&mut self) {
5556 IntStream::consume(&mut self.input);
5557 }
5558
5559 pub fn set_int_member(&mut self, member: usize, value: i64) {
5561 self.int_members.set_scalar(member, value);
5562 }
5563
5564 pub fn int_member(&self, member: usize) -> Option<i64> {
5566 self.int_members.scalar(member)
5567 }
5568
5569 pub fn push_stack_member(&mut self, member: usize, value: i64) {
5571 self.int_members.push_stack(member, value);
5572 }
5573
5574 pub fn pop_stack_member(&mut self, member: usize) -> Option<i64> {
5577 self.int_members.pop_stack(member)
5578 }
5579
5580 #[must_use]
5583 pub fn stack_member_top(&self, member: usize) -> Option<i64> {
5584 self.int_members.stack_top(member)
5585 }
5586
5587 #[must_use]
5589 pub fn stack_member_len(&self, member: usize) -> usize {
5590 self.int_members.stack_len(member)
5591 }
5592
5593 pub fn set_initial_members(&mut self, initial: impl IntoIterator<Item = (usize, i64)>) {
5600 self.int_members = MemberEnv::with_initial_scalars(initial);
5601 }
5602
5603 #[must_use]
5609 pub fn int_members_checkpoint(&self) -> MemberEnv {
5610 self.int_members.clone()
5611 }
5612
5613 pub fn restore_int_members(&mut self, members: MemberEnv) {
5615 self.int_members = members;
5616 }
5617
5618 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5620 self.int_members.add_scalar(member, delta)
5621 }
5622
5623 fn token_type_for_id(&self, id: TokenId) -> i32 {
5624 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5625 }
5626
5627 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5628 if self.build_parse_trees {
5629 self.tree.terminal(id)
5630 } else {
5631 NodeId::placeholder()
5632 }
5633 }
5634
5635 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5636 if self.build_parse_trees {
5637 self.tree.error(id)
5638 } else {
5639 NodeId::placeholder()
5640 }
5641 }
5642
5643 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5644 context.set_start_id(id);
5645 }
5646
5647 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5648 context.set_stop_id(id);
5649 }
5650
5651 fn insert_synthetic_token(
5652 &mut self,
5653 token_type: i32,
5654 text: String,
5655 line: usize,
5656 column: usize,
5657 ) -> Result<TokenId, AntlrError> {
5658 self.input
5659 .insert(
5660 TokenSpec::explicit(token_type, text)
5661 .with_span(usize::MAX, usize::MAX)
5662 .with_position(line, column),
5663 )
5664 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5665 }
5666
5667 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5674 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5675 line: 0,
5676 column: 0,
5677 message: "missing current token".to_owned(),
5678 offending: None,
5679 })?;
5680 let current_type = self.token_type_for_id(current);
5681 if current_type == token_type {
5682 self.reset_generated_recovery_state();
5683 self.consume();
5684 Ok(self.terminal_tree(current))
5685 } else {
5686 Err(AntlrError::MismatchedInput {
5687 expected: self.vocabulary().display_name(token_type),
5688 found: self.vocabulary().display_name(current_type),
5689 })
5690 }
5691 }
5692
5693 pub fn match_token_recovering(
5697 &mut self,
5698 token_type: i32,
5699 follow_state: usize,
5700 atn: &Atn,
5701 ) -> Result<GeneratedMatch, AntlrError> {
5702 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5703 line: 0,
5704 column: 0,
5705 message: "missing current token".to_owned(),
5706 offending: None,
5707 })?;
5708 let current_type = self.token_type_for_id(current);
5709 if current_type == token_type {
5710 self.generated_sync_expected = None;
5711 self.reset_generated_recovery_state();
5712 let consumed_eof = current_type == TOKEN_EOF;
5713 self.consume();
5714 return Ok(GeneratedMatch {
5715 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5716 consumed_eof,
5717 });
5718 }
5719 let mut expected_symbols = BTreeSet::new();
5720 expected_symbols.insert(token_type);
5721 self.recover_generated_match(
5722 current,
5723 GeneratedExpectedSymbols::Tree(&expected_symbols),
5724 follow_state,
5725 atn,
5726 |symbol| symbol == token_type,
5727 )
5728 }
5729
5730 pub fn match_set_recovering(
5731 &mut self,
5732 intervals: &[(i32, i32)],
5733 follow_state: usize,
5734 atn: &Atn,
5735 ) -> Result<GeneratedMatch, AntlrError> {
5736 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5737 line: 0,
5738 column: 0,
5739 message: "missing current token".to_owned(),
5740 offending: None,
5741 })?;
5742 let current_type = self.token_type_for_id(current);
5743 if interval_set_contains(intervals, current_type) {
5744 self.generated_sync_expected = None;
5745 self.reset_generated_recovery_state();
5746 let consumed_eof = current_type == TOKEN_EOF;
5747 self.consume();
5748 return Ok(GeneratedMatch {
5749 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5750 consumed_eof,
5751 });
5752 }
5753 let expected_symbols = interval_symbols(intervals);
5754 self.recover_generated_match(
5755 current,
5756 GeneratedExpectedSymbols::Tree(&expected_symbols),
5757 follow_state,
5758 atn,
5759 |symbol| interval_set_contains(intervals, symbol),
5760 )
5761 }
5762
5763 pub fn match_token_set_recovering(
5764 &mut self,
5765 set: ParserIntervalSet<'_>,
5766 follow_state: usize,
5767 atn: &Atn,
5768 ) -> Result<GeneratedMatch, AntlrError> {
5769 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5770 line: 0,
5771 column: 0,
5772 message: "missing current token".to_owned(),
5773 offending: None,
5774 })?;
5775 let current_type = self.token_type_for_id(current);
5776 if set.contains(current_type) {
5777 self.generated_sync_expected = None;
5778 self.reset_generated_recovery_state();
5779 let consumed_eof = current_type == TOKEN_EOF;
5780 self.consume();
5781 return Ok(GeneratedMatch {
5782 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5783 consumed_eof,
5784 });
5785 }
5786 self.recover_generated_match(
5787 current,
5788 GeneratedExpectedSymbols::TokenSet(set),
5789 follow_state,
5790 atn,
5791 |symbol| set.contains(symbol),
5792 )
5793 }
5794
5795 pub fn match_not_set_recovering(
5796 &mut self,
5797 intervals: &[(i32, i32)],
5798 min_vocabulary: i32,
5799 max_vocabulary: i32,
5800 follow_state: usize,
5801 atn: &Atn,
5802 ) -> Result<GeneratedMatch, AntlrError> {
5803 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5804 line: 0,
5805 column: 0,
5806 message: "missing current token".to_owned(),
5807 offending: None,
5808 })?;
5809 let current_type = self.token_type_for_id(current);
5810 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5811 && !interval_set_contains(intervals, current_type)
5812 {
5813 self.generated_sync_expected = None;
5814 self.reset_generated_recovery_state();
5815 let consumed_eof = current_type == TOKEN_EOF;
5816 self.consume();
5817 return Ok(GeneratedMatch {
5818 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5819 consumed_eof,
5820 });
5821 }
5822 let expected_symbols =
5823 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
5824 self.recover_generated_match(
5825 current,
5826 GeneratedExpectedSymbols::Tree(&expected_symbols),
5827 follow_state,
5828 atn,
5829 |symbol| {
5830 (min_vocabulary..=max_vocabulary).contains(&symbol)
5831 && !interval_set_contains(intervals, symbol)
5832 },
5833 )
5834 }
5835
5836 pub fn match_not_token_set_recovering(
5837 &mut self,
5838 set: ParserIntervalSet<'_>,
5839 min_vocabulary: i32,
5840 max_vocabulary: i32,
5841 follow_state: usize,
5842 atn: &Atn,
5843 ) -> Result<GeneratedMatch, AntlrError> {
5844 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5845 line: 0,
5846 column: 0,
5847 message: "missing current token".to_owned(),
5848 offending: None,
5849 })?;
5850 let current_type = self.token_type_for_id(current);
5851 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
5852 {
5853 self.generated_sync_expected = None;
5854 self.reset_generated_recovery_state();
5855 let consumed_eof = current_type == TOKEN_EOF;
5856 self.consume();
5857 return Ok(GeneratedMatch {
5858 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5859 consumed_eof,
5860 });
5861 }
5862 self.recover_generated_match(
5863 current,
5864 GeneratedExpectedSymbols::TokenSetComplement {
5865 set,
5866 min_vocabulary,
5867 max_vocabulary,
5868 },
5869 follow_state,
5870 atn,
5871 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
5872 )
5873 }
5874
5875 fn recover_generated_match(
5876 &mut self,
5877 current: TokenId,
5878 expected_symbols: GeneratedExpectedSymbols<'_>,
5879 follow_state: usize,
5880 atn: &Atn,
5881 matches: impl Fn(i32) -> bool,
5882 ) -> Result<GeneratedMatch, AntlrError> {
5883 let expected_display = expected_symbols.display(self.vocabulary());
5884 let (current_type, current_line, current_column, current_display) = {
5885 let token = self
5886 .input
5887 .token_view(current)
5888 .expect("current token ID should be valid");
5889 (
5890 token.token_type(),
5891 token.line(),
5892 token.column(),
5893 token_input_display(&token),
5894 )
5895 };
5896 if self.bail_on_error {
5897 return Err(AntlrError::ParserError {
5898 line: current_line,
5899 column: current_column,
5900 message: format!("mismatched input {current_display} expecting {expected_display}"),
5901 offending: Some(current),
5902 });
5903 }
5904 if current_type != TOKEN_EOF
5905 && let Some(next) = self.input.lt_id(2)
5906 && matches(self.token_type_for_id(next))
5907 {
5908 let message =
5909 format!("extraneous input {current_display} expecting {expected_display}");
5910 self.push_generated_parser_diagnostic(ParserDiagnostic {
5911 line: current_line,
5912 column: current_column,
5913 message,
5914 offending: Some(current),
5915 });
5916 self.record_syntax_errors(1);
5917 self.generated_sync_expected = None;
5918 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
5921 self.consume();
5922 self.consume();
5923 self.reset_generated_recovery_state();
5924 return Ok(GeneratedMatch {
5925 children: GeneratedMatchChildren::Many(vec![
5926 self.error_tree(current),
5927 self.terminal_tree(next),
5928 ]),
5929 consumed_eof,
5930 });
5931 }
5932 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
5933 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
5942 && self
5943 .cached_state_expected_symbols(atn, follow_state)
5944 .contains(&TOKEN_EOF);
5945 if follow_symbols.contains(¤t_type)
5946 && (current_type != TOKEN_EOF
5947 || self.rule_context_stack.len() > 1
5948 || expected_symbols.is_empty()
5949 || follow_explicitly_expects_eof)
5950 {
5951 let message = format!("missing {expected_display} at {current_display}");
5952 self.push_generated_parser_diagnostic(ParserDiagnostic {
5953 line: current_line,
5954 column: current_column,
5955 message,
5956 offending: Some(current),
5957 });
5958 self.record_syntax_errors(1);
5959 self.generated_sync_expected = None;
5960 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
5961 let missing_display = expected_symbol_display(token_type, self.vocabulary());
5962 let token = self.insert_synthetic_token(
5963 token_type,
5964 format!("<missing {missing_display}>"),
5965 current_line,
5966 current_column,
5967 )?;
5968 return Ok(GeneratedMatch {
5973 children: GeneratedMatchChildren::One(self.error_tree(token)),
5974 consumed_eof: false,
5975 });
5976 }
5977 let mismatch_expected_display = self
5978 .generated_sync_expected
5979 .take()
5980 .map_or(expected_display, |symbols| {
5981 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
5982 });
5983 Err(AntlrError::ParserError {
5984 line: current_line,
5985 column: current_column,
5986 message: format!(
5987 "mismatched input {current_display} expecting {mismatch_expected_display}"
5988 ),
5989 offending: Some(current),
5990 })
5991 }
5992
5993 fn generated_recovery_follow_symbols(
5994 &mut self,
5995 atn: &Atn,
5996 follow_state: usize,
5997 ) -> BTreeSet<i32> {
5998 let mut follow = self
5999 .cached_state_expected_symbols(atn, follow_state)
6000 .as_ref()
6001 .clone();
6002 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
6003 follow.extend(self.context_expected_symbols(atn));
6004 }
6005 follow
6006 }
6007
6008 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
6009 self.match_token(TOKEN_EOF)
6010 }
6011
6012 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
6013 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
6014 }
6015
6016 pub fn match_not_set(
6017 &mut self,
6018 intervals: &[(i32, i32)],
6019 min_vocabulary: i32,
6020 max_vocabulary: i32,
6021 ) -> Result<ParseTree, AntlrError> {
6022 self.match_interval_condition(intervals, |symbol| {
6023 (min_vocabulary..=max_vocabulary).contains(&symbol)
6024 && !interval_set_contains(intervals, symbol)
6025 })
6026 }
6027
6028 fn match_interval_condition(
6029 &mut self,
6030 intervals: &[(i32, i32)],
6031 matches: impl FnOnce(i32) -> bool,
6032 ) -> Result<ParseTree, AntlrError> {
6033 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6034 line: 0,
6035 column: 0,
6036 message: "missing current token".to_owned(),
6037 offending: None,
6038 })?;
6039 let current_type = self.token_type_for_id(current);
6040 if matches(current_type) {
6041 self.reset_generated_recovery_state();
6042 self.consume();
6043 Ok(self.terminal_tree(current))
6044 } else {
6045 Err(AntlrError::MismatchedInput {
6046 expected: self.interval_display(intervals),
6047 found: self.vocabulary().display_name(current_type),
6048 })
6049 }
6050 }
6051
6052 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
6053 let values = intervals
6054 .iter()
6055 .map(|(start, stop)| {
6056 if start == stop {
6057 self.vocabulary().display_name(*start)
6058 } else {
6059 format!(
6060 "{}..{}",
6061 self.vocabulary().display_name(*start),
6062 self.vocabulary().display_name(*stop)
6063 )
6064 }
6065 })
6066 .collect::<Vec<_>>()
6067 .join(", ");
6068 format!("{{{values}}}")
6069 }
6070
6071 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
6072 if self.build_parse_trees {
6073 self.tree.finish_rule(context)
6074 } else {
6075 NodeId::placeholder()
6076 }
6077 }
6078
6079 #[must_use]
6088 pub const fn generated_rule_stack_check_due(&self) -> bool {
6089 self.rule_context_stack
6090 .len()
6091 .is_multiple_of(GENERATED_RULE_STACK_CHECK_INTERVAL)
6092 }
6093
6094 #[inline]
6112 pub fn rule_depth_cap_violation(&mut self) -> Option<AntlrError> {
6113 let max = self.max_rule_depth?;
6114 if self.rule_depth_error.is_none()
6117 && self.rule_context_stack.len() + self.recursion_expansions < max
6118 {
6119 return None;
6120 }
6121 Some(self.rule_depth_cap_violation_cold(max))
6122 }
6123
6124 #[cold]
6125 fn rule_depth_cap_violation_cold(&mut self, max: usize) -> AntlrError {
6126 if let Some(error) = &self.rule_depth_error {
6127 return error.clone();
6128 }
6129 let current = self.input.lt(1);
6130 let (line, column) = current
6131 .as_ref()
6132 .map_or((0, 0), |token| (token.line(), token.column()));
6133 let error = AntlrError::ParserError {
6134 line,
6135 column,
6136 message: format!("rule nesting depth limit of {max} exceeded"),
6137 offending: current.as_ref().map(Token::token_id),
6138 };
6139 self.rule_depth_error = Some(error.clone());
6140 error
6141 }
6142
6143 pub const fn take_rule_depth_error(&mut self) -> Option<AntlrError> {
6150 self.rule_depth_error.take()
6151 }
6152
6153 #[must_use]
6160 pub const fn has_rule_depth_cap(&self) -> bool {
6161 self.max_rule_depth.is_some()
6162 }
6163
6164 pub fn add_parse_listener<L>(&mut self, listener: L)
6168 where
6169 L: ParseListener + 'static,
6170 {
6171 self.parse_listeners
6172 .push(ParseListenerSlot(Box::new(listener)));
6173 }
6174
6175 pub fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
6182 self.parse_listener_abort = None;
6183 self.parse_listeners.drain(..).map(|slot| slot.0).collect()
6184 }
6185
6186 #[must_use]
6192 pub const fn has_parse_listeners(&self) -> bool {
6193 !self.parse_listeners.is_empty()
6194 }
6195
6196 #[doc(hidden)]
6201 #[must_use]
6202 pub fn observes_parser_decisions(&self) -> bool {
6203 self.semantic_hooks.observes_parser_decisions()
6204 }
6205
6206 pub fn parse_listener_enter_rule(&mut self, rule_index: usize) -> Option<AntlrError> {
6217 if self.parse_listeners.is_empty() {
6218 return None;
6219 }
6220 self.parse_listener_enter_rule_dispatch(rule_index)
6221 }
6222
6223 fn parse_listener_enter_rule_dispatch(&mut self, rule_index: usize) -> Option<AntlrError> {
6224 if let Some(error) = &self.parse_listener_abort {
6225 return Some(error.clone());
6226 }
6227 let event = EnterRuleEvent {
6228 rule_index,
6229 current: self.input.lt(1),
6230 };
6231 let mut listeners = std::mem::take(&mut self.parse_listeners);
6235 let mut abort = None;
6236 for slot in &mut listeners {
6237 if let Err(error) = slot.0.enter_every_rule(&event) {
6238 abort = Some(error);
6239 break;
6240 }
6241 }
6242 self.parse_listeners = listeners;
6243 if let Some(error) = abort {
6244 self.parse_listener_abort = Some(error.clone());
6245 return Some(error);
6246 }
6247 None
6248 }
6249
6250 pub fn parse_listener_exit_rule(&mut self, rule_index: usize) {
6257 if self.parse_listeners.is_empty() {
6258 return;
6259 }
6260 for slot in self.parse_listeners.iter_mut().rev() {
6263 slot.0.exit_every_rule(rule_index);
6264 }
6265 }
6266
6267 pub const fn take_parse_listener_abort(&mut self) -> Option<AntlrError> {
6274 self.parse_listener_abort.take()
6275 }
6276
6277 pub fn take_parse_abort(&mut self) -> Option<AntlrError> {
6286 if let Some(error) = self.rule_depth_error.take() {
6287 self.parse_listener_abort = None;
6288 return Some(error);
6289 }
6290 self.parse_listener_abort.take()
6291 }
6292
6293 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
6296 self.set_state(state);
6297 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
6298 self.rule_context_stack.push(RuleContextFrame {
6299 rule_index,
6300 invoking_state,
6301 });
6302 self.advance_rule_context_version();
6303 let start_index = self.current_visible_index();
6304 let mut context = ParserRuleContext::new(rule_index, invoking_state);
6305 if let Some(token) = self.token_id_at(start_index) {
6306 self.set_context_start(&mut context, token);
6307 }
6308 context
6309 }
6310
6311 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
6318 let marker = self.pending_invoking_states.len();
6319 self.pending_invoking_states.push(invoking_state);
6320 marker
6321 }
6322
6323 pub fn discard_invoking_state(&mut self, marker: usize) {
6325 self.pending_invoking_states.truncate(marker);
6326 }
6327
6328 pub fn exit_rule(&mut self) {
6330 self.rule_context_stack.pop();
6331 self.advance_rule_context_version();
6332 }
6333
6334 pub fn prediction_context_return_states<'a>(
6337 &'a self,
6338 atn: &'a Atn,
6339 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
6340 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
6341 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
6342 return None;
6343 };
6344 let Some(Transition::Rule { follow_state, .. }) = atn
6345 .state(state_number)
6346 .and_then(|state| state.transitions().first())
6347 .map(ParserTransition::data)
6348 else {
6349 return None;
6350 };
6351 Some(follow_state)
6352 })
6353 }
6354
6355 pub const fn rule_context_version(&self) -> usize {
6360 self.rule_context_version
6361 }
6362
6363 const fn advance_rule_context_version(&mut self) {
6364 self.rule_context_version = self.rule_context_version.wrapping_add(1);
6365 }
6366
6367 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
6372 if self.build_parse_trees {
6373 self.tree.add_child(context, child);
6374 } else {
6375 context.note_matched_child();
6376 }
6377 }
6378
6379 fn release_tree_scratch_if_idle(&mut self) {
6380 if self.rule_context_stack.is_empty() {
6381 self.tree.release_scratch();
6382 }
6383 }
6384
6385 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
6387 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6388 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6389 self.set_context_stop(&mut context, token);
6390 }
6391 let node = self.rule_node(context);
6392 self.exit_rule();
6393 self.release_tree_scratch_if_idle();
6394 node
6395 }
6396
6397 pub fn recover_generated_rule(
6404 &mut self,
6405 context: &mut ParserRuleContext,
6406 atn: &Atn,
6407 error: AntlrError,
6408 ) {
6409 let diagnostic = self.generated_rule_error_diagnostic(error);
6410 self.push_generated_parser_diagnostic(diagnostic);
6411 self.generated_sync_expected = None;
6412 let error_index = self.input.index();
6413 let error_state = self.data.state();
6414 if self.generated_recovery_error_index == Some(error_index)
6419 && self.generated_recovery_error_states.contains(&error_state)
6420 && self.la(1) != TOKEN_EOF
6421 && let Some(token) = self.input.lt_id(1)
6422 {
6423 self.consume();
6424 let child = self.error_tree(token);
6425 self.add_parse_child(context, child);
6426 }
6427 let recovery_index = self.input.index();
6428 if self.generated_recovery_error_index != Some(recovery_index) {
6429 self.generated_recovery_error_index = Some(recovery_index);
6430 self.generated_recovery_error_states.clear();
6431 }
6432 self.generated_recovery_error_states.insert(error_state);
6433 let recovery_symbols = self.context_expected_symbols(atn);
6434 loop {
6435 let symbol = self.la(1);
6436 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
6437 break;
6438 }
6439 let Some(token) = self.input.lt_id(1) else {
6440 break;
6441 };
6442 self.consume();
6443 let child = self.error_tree(token);
6444 self.add_parse_child(context, child);
6445 }
6446 self.record_syntax_errors(1);
6447 }
6448
6449 fn reset_generated_recovery_state(&mut self) {
6450 if self.generated_recovery_error_index.is_some() {
6451 self.generated_recovery_error_index = None;
6452 self.generated_recovery_error_states.clear();
6453 }
6454 }
6455
6456 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
6457 if self
6458 .generated_parser_diagnostics
6459 .iter()
6460 .any(|existing| existing == &diagnostic)
6461 {
6462 return;
6463 }
6464 self.generated_parser_diagnostics.push(diagnostic);
6465 }
6466
6467 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
6468 match error {
6469 AntlrError::ParserError {
6473 line,
6474 column,
6475 message,
6476 offending,
6477 } => ParserDiagnostic {
6478 line,
6479 column,
6480 message,
6481 offending,
6482 },
6483 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
6484 self.input.lt(1),
6485 format!("mismatched input {found} expecting {expected}"),
6486 ),
6487 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
6488 self.input.lt(1),
6489 format!("no viable alternative at input {input}"),
6490 ),
6491 AntlrError::LexerError {
6492 line,
6493 column,
6494 message,
6495 } => ParserDiagnostic {
6496 line,
6497 column,
6498 message,
6499 offending: None,
6500 },
6501 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
6502 }
6503 }
6504
6505 pub fn finish_recursion_rule(
6507 &mut self,
6508 mut context: ParserRuleContext,
6509 consumed_eof: bool,
6510 ) -> ParseTree {
6511 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6512 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6513 self.set_context_stop(&mut context, token);
6514 }
6515 let node = self.rule_node(context);
6516 self.unroll_recursion_context();
6517 self.release_tree_scratch_if_idle();
6518 node
6519 }
6520
6521 pub fn enter_recursion_rule(
6523 &mut self,
6524 state: isize,
6525 rule_index: usize,
6526 precedence: i32,
6527 ) -> ParserRuleContext {
6528 self.precedence_stack.push(precedence);
6529 self.recursion_expansion_marks
6530 .push(self.recursion_expansions);
6531 self.enter_rule(state, rule_index)
6532 }
6533
6534 pub fn push_new_recursion_context(
6536 &mut self,
6537 state: isize,
6538 rule_index: usize,
6539 ) -> ParserRuleContext {
6540 self.set_state(state);
6541 self.recursion_expansions += 1;
6544 ParserRuleContext::new(rule_index, state)
6545 }
6546
6547 pub fn push_new_recursion_context_with_previous(
6550 &mut self,
6551 state: isize,
6552 rule_index: usize,
6553 current: &mut ParserRuleContext,
6554 ) {
6555 self.set_state(state);
6556 self.recursion_expansions += 1;
6562 if let Some(stop) = self
6563 .rule_stop_token_index(self.input.index(), false)
6564 .and_then(|index| self.token_id_at(index))
6565 {
6566 self.set_context_stop(current, stop);
6567 }
6568 let invoking_state = current.invoking_state();
6569 let start = current.start_id();
6570 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
6571 if start.is_some() {
6572 replacement.set_start_from_context(current);
6573 }
6574 let previous = std::mem::replace(current, replacement);
6575 if self.build_parse_trees {
6576 let previous = self.rule_node(previous);
6577 self.tree.add_child(current, previous);
6578 }
6579 }
6580
6581 pub fn unroll_recursion_context(&mut self) {
6583 if self.precedence_stack.len() > 1 {
6584 self.precedence_stack.pop();
6585 }
6586 if let Some(mark) = self.recursion_expansion_marks.pop() {
6592 self.recursion_expansions = mark;
6593 }
6594 self.exit_rule();
6595 }
6596
6597 pub fn left_recursive_loop_enter_prediction(
6611 &mut self,
6612 atn: &Atn,
6613 state_number: usize,
6614 precedence: i32,
6615 ) -> Option<bool> {
6616 let symbol = self.la(1);
6617 if symbol == TOKEN_EOF {
6618 return Some(false);
6619 }
6620 let operator_lookahead =
6621 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
6622 let can_single = operator_lookahead.single_token.contains(symbol);
6623 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
6624 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
6625 if !can_single && !can_multi && !can_predicate {
6626 return Some(false);
6627 }
6628 if can_predicate && !can_single {
6629 return None;
6630 }
6631 if !can_single && can_multi && precedence > 0 {
6635 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
6636 if baseline.single_token.contains(symbol) {
6637 return None;
6638 }
6639 }
6640 let atn_key = SharedAtnCacheKey::for_atn(atn);
6641 let cached_overlap = self
6642 .left_recursive_caller_overlap_cache
6643 .iter()
6644 .flatten()
6645 .find(|entry| {
6646 entry.atn_key == atn_key
6647 && entry.state_number == state_number
6648 && entry.symbol == symbol
6649 && entry.context_version == self.rule_context_version
6650 })
6651 .map(|entry| entry.overlaps);
6652 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
6653 let overlaps = caller_context_can_match_symbol_before_state(
6654 atn,
6655 self.prediction_context_return_states(atn),
6656 state_number,
6657 symbol,
6658 );
6659 if let Some(slot) = self
6660 .left_recursive_caller_overlap_cache
6661 .iter_mut()
6662 .find(|slot| slot.is_none())
6663 {
6664 *slot = Some(LeftRecursiveCallerOverlap {
6665 atn_key,
6666 state_number,
6667 symbol,
6668 context_version: self.rule_context_version,
6669 overlaps,
6670 });
6671 }
6672 overlaps
6673 });
6674 if caller_overlaps {
6675 return None;
6676 }
6677 Some(true)
6678 }
6679
6680 fn cached_left_recursive_operator_lookahead(
6681 atn: &Atn,
6682 state_number: usize,
6683 precedence: i32,
6684 ) -> Rc<LeftRecursiveOperatorLookahead> {
6685 with_shared_atn_caches(atn, |cache| {
6686 let key = (state_number, precedence);
6687 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
6688 return Rc::clone(cached);
6689 }
6690 let lookahead = Rc::new(left_recursive_operator_lookahead(
6691 atn,
6692 state_number,
6693 precedence,
6694 ));
6695 cache
6696 .left_recursive_operator_lookahead
6697 .insert(key, Rc::clone(&lookahead));
6698 lookahead
6699 })
6700 }
6701
6702 pub fn left_recursive_loop_enter_matches(
6705 &mut self,
6706 atn: &Atn,
6707 state_number: usize,
6708 precedence: i32,
6709 ) -> bool {
6710 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
6711 }
6712
6713 pub fn precpred(&self, precedence: i32) -> bool {
6715 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
6716 }
6717
6718 pub fn parser_semantic_predicate_matches(
6721 &mut self,
6722 predicates: &[(usize, usize, ParserPredicate)],
6723 rule_index: usize,
6724 pred_index: usize,
6725 ) -> bool {
6726 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
6727 }
6728
6729 pub fn parser_semantic_predicate_matches_with_local(
6732 &mut self,
6733 predicates: &[(usize, usize, ParserPredicate)],
6734 rule_index: usize,
6735 pred_index: usize,
6736 local_int_arg: i32,
6737 ) -> bool {
6738 self.parser_semantic_predicate_matches_inner(
6739 predicates,
6740 rule_index,
6741 pred_index,
6742 Some((rule_index, i64::from(local_int_arg))),
6743 )
6744 }
6745
6746 fn parser_semantic_predicate_matches_inner(
6747 &mut self,
6748 predicates: &[(usize, usize, ParserPredicate)],
6749 rule_index: usize,
6750 pred_index: usize,
6751 local_int_arg: Option<(usize, i64)>,
6752 ) -> bool {
6753 let index = self.input.index();
6754 let member_values = self.int_members.clone();
6755 self.parser_predicate_matches(PredicateEval {
6756 index,
6757 rule_index,
6758 pred_index,
6759 predicates,
6760 semantics: None,
6761 context: None,
6762 local_int_arg,
6763 member_values: &member_values,
6764 })
6765 }
6766
6767 pub fn parser_semantic_predicate_matches_with_context_and_local(
6770 &mut self,
6771 predicates: &[(usize, usize, ParserPredicate)],
6772 rule_index: usize,
6773 pred_index: usize,
6774 context: &ParserRuleContext,
6775 local_int_arg: i32,
6776 ) -> bool {
6777 let index = self.input.index();
6778 let member_values = self.int_members.clone();
6779 self.parser_predicate_matches(PredicateEval {
6780 index,
6781 rule_index,
6782 pred_index,
6783 predicates,
6784 semantics: None,
6785 context: Some(context),
6786 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6787 member_values: &member_values,
6788 })
6789 }
6790
6791 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
6794 &mut self,
6795 semantics: &ParserSemantics,
6796 rule_index: usize,
6797 pred_index: usize,
6798 context: &ParserRuleContext,
6799 local_int_arg: i32,
6800 ) -> bool {
6801 let index = self.input.index();
6802 let member_values = self.int_members.clone();
6803 self.parser_predicate_matches(PredicateEval {
6804 index,
6805 rule_index,
6806 pred_index,
6807 predicates: &[],
6808 semantics: Some(semantics),
6809 context: Some(context),
6810 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6811 member_values: &member_values,
6812 })
6813 }
6814
6815 pub fn parser_semantic_predicate_failure_message(
6818 &self,
6819 rule_index: usize,
6820 pred_index: usize,
6821 predicates: &[(usize, usize, ParserPredicate)],
6822 ) -> Option<&'static str> {
6823 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
6824 }
6825
6826 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
6828 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6829 line: 0,
6830 column: 0,
6831 message: "missing current token".to_owned(),
6832 offending: None,
6833 })?;
6834 if self.token_type_for_id(current) == TOKEN_EOF {
6835 return Err(AntlrError::MismatchedInput {
6836 expected: "wildcard".to_owned(),
6837 found: self.vocabulary().display_name(TOKEN_EOF),
6838 });
6839 }
6840 self.reset_generated_recovery_state();
6841 self.consume();
6842 Ok(self.terminal_tree(current))
6843 }
6844
6845 #[allow(clippy::unnecessary_wraps)]
6849 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
6850 self.set_state(state);
6851 Ok(())
6852 }
6853
6854 pub fn sync_decision(
6862 &mut self,
6863 atn: &Atn,
6864 state_number: usize,
6865 _current_context_empty: bool,
6866 loop_back: bool,
6867 ) -> Result<Vec<ParseTree>, AntlrError> {
6868 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
6869 self.generated_sync_expected = None;
6870 let Some(state) = atn.state(state_number) else {
6871 return Ok(Vec::new());
6872 };
6873 let Some(rule_index) = state.rule_index() else {
6874 return Ok(Vec::new());
6875 };
6876 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
6877 return Ok(Vec::new());
6878 };
6879 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6880 let symbol = self.la(1);
6881 let mut has_expected_symbols = false;
6882 let mut nullable = false;
6883 let mut explicit_eof_expected = false;
6891 for transition in &entry.transitions {
6892 if transition.symbols.contains(symbol) {
6893 return Ok(Vec::new());
6894 }
6895 has_expected_symbols |= !transition.symbols.is_empty();
6896 nullable |= transition.nullable;
6897 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
6898 }
6899 if nullable {
6906 if self.context_expected_contains(atn, symbol) {
6910 return Ok(Vec::new());
6911 }
6912 let mut expected = self.context_expected_token_set(atn);
6913 for transition in &entry.transitions {
6914 expected.extend_from(&transition.symbols);
6915 }
6916 self.generated_sync_expected = Some(expected);
6917 return Ok(Vec::new());
6918 }
6919 if !has_expected_symbols {
6920 return Ok(Vec::new());
6921 }
6922 let mut expected = TokenBitSet::default();
6923 for transition in &entry.transitions {
6924 expected.extend_from(&transition.symbols);
6925 }
6926 let loop_sync = loop_back;
6943 if symbol != TOKEN_EOF {
6944 let mut cursor = self.input.index();
6945 let mut skipped = Vec::new();
6946 loop {
6947 let current = self.token_type_at(cursor);
6948 if current == TOKEN_EOF {
6949 break;
6950 }
6951 skipped.push(cursor);
6952 let next = self.consume_index(cursor, current);
6953 if next == cursor {
6954 break;
6955 }
6956 let next_symbol = self.token_type_at(next);
6957 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
6965 explicit_eof_expected
6966 } else {
6967 expected.contains(next_symbol)
6968 };
6969 if next_is_expected_stop {
6970 let current_token = self.input.lt(1);
6971 let expected_symbols = expected.to_btree_set();
6972 let message = format!(
6973 "extraneous input {} expecting {}",
6974 current_token
6975 .as_ref()
6976 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6977 self.expected_symbols_display(&expected_symbols)
6978 );
6979 self.push_generated_parser_diagnostic(diagnostic_for_token(
6980 current_token,
6981 message,
6982 ));
6983 self.record_syntax_errors(1);
6984 let mut children = Vec::with_capacity(skipped.len());
6985 for index in skipped {
6986 if let Some(token) = self.token_id_at(index) {
6987 self.consume();
6988 children.push(self.error_tree(token));
6989 }
6990 }
6991 if !loop_sync {
6992 self.reset_generated_recovery_state();
6993 }
6994 return Ok(children);
6995 }
6996 if !loop_sync {
7000 break;
7001 }
7002 cursor = next;
7003 }
7004 }
7005 let current = self.input.lt(1);
7006 let expected_symbols = expected.to_btree_set();
7007 Err(AntlrError::ParserError {
7008 line: current.as_ref().map(Token::line).unwrap_or_default(),
7009 column: current.as_ref().map(Token::column).unwrap_or_default(),
7010 message: format!(
7011 "mismatched input {} expecting {}",
7012 current
7013 .as_ref()
7014 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
7015 self.expected_symbols_display(&expected_symbols)
7016 ),
7017 offending: current.as_ref().map(Token::token_id),
7018 })
7019 }
7020
7021 pub fn ll1_decision_prediction(
7028 &mut self,
7029 atn: &Atn,
7030 state_number: usize,
7031 ) -> Option<ParserAtnPrediction> {
7032 let state = atn.state(state_number)?;
7033 if state.precedence_rule_decision() {
7034 return None;
7035 }
7036 let rule_stop = state
7037 .rule_index()
7038 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
7039 let symbol = self.la(1);
7040 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
7041 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
7042 alt: alt + 1,
7043 requires_full_context: false,
7044 has_semantic_context: false,
7045 diagnostic: None,
7046 })
7047 }
7048
7049 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
7050 let mut expected = BTreeSet::new();
7051 for index in (1..self.rule_context_stack.len()).rev() {
7052 let invoking_state = self.rule_context_stack[index].invoking_state;
7053 let Ok(state_number) = usize::try_from(invoking_state) else {
7054 continue;
7055 };
7056 let Some(Transition::Rule { follow_state, .. }) = atn
7057 .state(state_number)
7058 .and_then(|state| state.transitions().first())
7059 .map(ParserTransition::data)
7060 else {
7061 continue;
7062 };
7063 let return_state = follow_state;
7064 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
7065 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
7066 return expected;
7067 }
7068 }
7069 expected.insert(TOKEN_EOF);
7070 expected
7071 }
7072
7073 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
7074 let mut expected = TokenBitSet::default();
7075 for index in (1..self.rule_context_stack.len()).rev() {
7076 let invoking_state = self.rule_context_stack[index].invoking_state;
7077 let Ok(state_number) = usize::try_from(invoking_state) else {
7078 continue;
7079 };
7080 let Some(Transition::Rule { follow_state, .. }) = atn
7081 .state(state_number)
7082 .and_then(|state| state.transitions().first())
7083 .map(ParserTransition::data)
7084 else {
7085 continue;
7086 };
7087 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
7088 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7089 return expected;
7090 }
7091 }
7092 expected.insert(TOKEN_EOF);
7093 expected
7094 }
7095
7096 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
7103 for index in (1..self.rule_context_stack.len()).rev() {
7104 let invoking_state = self.rule_context_stack[index].invoking_state;
7105 let Ok(state_number) = usize::try_from(invoking_state) else {
7106 continue;
7107 };
7108 let Some(Transition::Rule { follow_state, .. }) = atn
7109 .state(state_number)
7110 .and_then(|state| state.transitions().first())
7111 .map(ParserTransition::data)
7112 else {
7113 continue;
7114 };
7115 if self
7116 .cached_state_expected_token_set(atn, follow_state)
7117 .contains(symbol)
7118 {
7119 return true;
7120 }
7121 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7122 return false;
7123 }
7124 }
7125 symbol == TOKEN_EOF
7126 }
7127
7128 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
7130 let error_index = self.input.index();
7131 self.no_viable_alternative_error_at(start_index, error_index)
7132 }
7133
7134 pub fn no_viable_alternative_error_at(
7139 &self,
7140 start_index: usize,
7141 error_index: usize,
7142 ) -> AntlrError {
7143 let diagnostic = self.no_viable_alternative(start_index, error_index);
7144 AntlrError::ParserError {
7145 line: diagnostic.line,
7146 column: diagnostic.column,
7147 message: diagnostic.message,
7148 offending: diagnostic.offending,
7149 }
7150 }
7151
7152 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
7154 let current = self.input.lt(1);
7155 AntlrError::ParserError {
7156 line: current.as_ref().map(Token::line).unwrap_or_default(),
7157 column: current.as_ref().map(Token::column).unwrap_or_default(),
7158 message: format!("rule failed predicate: {}", message.into()),
7159 offending: current.as_ref().map(Token::token_id),
7160 }
7161 }
7162
7163 pub fn failed_predicate_option_error(
7166 &self,
7167 rule_index: usize,
7168 message: impl Into<String>,
7169 ) -> AntlrError {
7170 let current = self.input.lt(1);
7171 let rule_name = self
7172 .rule_names()
7173 .get(rule_index)
7174 .map_or_else(|| rule_index.to_string(), Clone::clone);
7175 AntlrError::ParserError {
7176 line: current.as_ref().map(Token::line).unwrap_or_default(),
7177 column: current.as_ref().map(Token::column).unwrap_or_default(),
7178 message: format!("rule {rule_name} {}", message.into()),
7179 offending: current.as_ref().map(Token::token_id),
7180 }
7181 }
7182
7183 pub fn parser_action_at_current(
7185 &mut self,
7186 source_state: usize,
7187 rule_index: usize,
7188 start_index: usize,
7189 consumed_eof: bool,
7190 ) -> ParserAction {
7191 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
7192 ParserAction::new(source_state, rule_index, start_index, stop_index)
7193 }
7194
7195 pub fn parser_action_at_current_indexed(
7197 &mut self,
7198 source_state: usize,
7199 rule_index: usize,
7200 action_index: usize,
7201 start_index: usize,
7202 consumed_eof: bool,
7203 ) -> ParserAction {
7204 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
7205 ParserAction::new_indexed(
7206 source_state,
7207 rule_index,
7208 action_index,
7209 start_index,
7210 stop_index,
7211 )
7212 }
7213
7214 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
7219 self.parser_action_hook_inner(action, None, Some(tree), None, true)
7220 }
7221
7222 pub fn parser_action_hook_with_context(
7227 &mut self,
7228 action: ParserAction,
7229 context: &ParserRuleContext,
7230 ) -> bool {
7231 self.parser_action_hook_inner(action, Some(context), None, None, true)
7232 }
7233
7234 pub fn parser_action_hook_with_context_and_local(
7240 &mut self,
7241 action: ParserAction,
7242 context: &ParserRuleContext,
7243 local_int_arg: i32,
7244 ) -> bool {
7245 self.parser_action_hook_inner(
7246 action,
7247 Some(context),
7248 None,
7249 Some((action.rule_index(), i64::from(local_int_arg))),
7250 true,
7251 )
7252 }
7253
7254 fn parser_rule_init_hook_with_context(
7259 &mut self,
7260 action: ParserAction,
7261 context: &ParserRuleContext,
7262 local_int_arg: Option<(usize, i64)>,
7263 ) -> bool {
7264 debug_assert!(action.is_rule_init());
7265 self.parser_action_hook_inner(action, Some(context), None, local_int_arg, false)
7266 }
7267
7268 fn parser_action_hook_inner(
7269 &mut self,
7270 action: ParserAction,
7271 context: Option<&ParserRuleContext>,
7272 tree: Option<ParseTree>,
7273 local_int_arg: Option<(usize, i64)>,
7274 record_unhandled: bool,
7275 ) -> bool {
7276 let rule_index = action.rule_index();
7277 let rule_name = self.rule_names().get(rule_index).cloned();
7278 let input = &mut self.input;
7279 let semantic_hooks = &mut self.semantic_hooks;
7280 let member_values = &self.int_members;
7281 let mut ctx = ParserSemCtx {
7282 input,
7283 tree_storage: &self.tree,
7284 rule_index,
7285 coordinate_index: action.action_index().unwrap_or(usize::MAX),
7286 rule_name,
7287 context,
7288 tree,
7289 local_int_arg,
7290 member_values,
7291 action: Some(action),
7292 };
7293 let handled = semantic_hooks.action(&mut ctx, action);
7294 if record_unhandled
7300 && !handled
7301 && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error)
7302 {
7303 let coordinate = (rule_index, action.source_state());
7304 if !self.unhandled_action_hits.contains(&coordinate) {
7305 self.unhandled_action_hits.push(coordinate);
7306 }
7307 }
7308 handled
7309 }
7310
7311 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
7316 &mut self,
7317 atn: &'atn Atn,
7318 simulator: &mut ParserAtnSimulator<'atn>,
7319 rule_index: usize,
7320 ) -> Result<ParseTree, AntlrError> {
7321 let start_index = self.current_visible_index();
7322 self.clear_prediction_diagnostics();
7323 self.reset_per_parse_caches();
7324 self.reset_recognition_arena();
7325 let tree_checkpoint = self.tree.checkpoint();
7326 let mut decision_by_state = vec![None; atn.states().len()];
7327 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
7328 if let Some(slot) = decision_by_state.get_mut(state_number) {
7329 *slot = Some(decision);
7330 }
7331 }
7332
7333 let result = DirectAdaptiveParser {
7334 parser: self,
7335 atn,
7336 simulator,
7337 decision_by_state,
7338 steps: 0,
7339 }
7340 .parse_rule(rule_index, -1, 0);
7341
7342 match result {
7343 Ok(tree) => {
7344 self.report_token_source_errors();
7345 self.release_tree_scratch_if_idle();
7346 Ok(tree)
7347 }
7348 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
7349 let _ = reason;
7350 self.tree.rollback(tree_checkpoint);
7351 self.input.seek(start_index);
7352 self.parse_atn_rule(atn, rule_index)
7353 }
7354 }
7355 }
7356
7357 pub fn parse_atn_rule(
7367 &mut self,
7368 atn: &Atn,
7369 rule_index: usize,
7370 ) -> Result<ParseTree, AntlrError> {
7371 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
7372 }
7373
7374 pub fn parse_atn_rule_with_precedence(
7377 &mut self,
7378 atn: &Atn,
7379 rule_index: usize,
7380 precedence: i32,
7381 ) -> Result<ParseTree, AntlrError> {
7382 self.parse_atn_rule_with_precedence_inner(
7383 atn,
7384 rule_index,
7385 precedence,
7386 None,
7387 AltNumberTracking::default(),
7388 )
7389 }
7390
7391 fn parse_atn_rule_with_precedence_inner(
7392 &mut self,
7393 atn: &Atn,
7394 rule_index: usize,
7395 precedence: i32,
7396 predicate_context: Option<FastPredicateContext<'_>>,
7397 alt_tracking: AltNumberTracking,
7398 ) -> Result<ParseTree, AntlrError> {
7399 let report_unrecovered_error = self.is_top_level_entry();
7400 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7401 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7402 })?;
7403 let stop_state = atn
7404 .rule_to_stop_state()
7405 .get(rule_index)
7406 .filter(|state| *state != usize::MAX)
7407 .ok_or_else(|| {
7408 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7409 })?;
7410
7411 let start_index = self.current_visible_index();
7412 self.clear_prediction_diagnostics();
7413 self.reset_per_parse_caches();
7414 self.reset_recognition_arena();
7415 let caller_follow_state = self.pending_invoking_follow_state(atn);
7416 self.fast_recovery_enabled = false;
7417 self.fast_token_nodes_enabled = false;
7418 self.fast_track_alt_numbers = alt_tracking.any();
7419 let top_request = FastRecognizeTopRequest {
7420 start_state,
7421 stop_state,
7422 start_index,
7423 precedence,
7424 caller_follow_state,
7425 };
7426 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
7427 self.fast_token_nodes_enabled = self.build_parse_trees;
7428 let needs_tree_retry = matches!(
7429 &first_pass,
7430 Ok((outcome, _, _))
7431 if self.build_parse_trees
7432 && self
7433 .recognition_arena
7434 .sequence_has_left_recursive_boundary(outcome.nodes)
7435 );
7436 let needs_retry = match &first_pass {
7437 Err(_) => true,
7450 Ok((outcome, _, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
7451 };
7452 let (outcome, _expected, alt_number) = if needs_retry {
7453 self.fast_first_set_prefilter = false;
7454 self.fast_recovery_enabled = false;
7455 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7456 let clean_selected = if needs_tree_retry {
7457 match clean_retry {
7458 ok @ Ok(_) => ok,
7459 Err(_) => first_pass,
7460 }
7461 } else {
7462 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
7463 };
7464 let selected = if clean_selected.is_err()
7465 || matches!(&clean_selected, Ok((outcome, _, _)) if !outcome.diagnostics.is_empty())
7466 {
7467 self.fast_recovery_enabled = true;
7468 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7469 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
7470 } else {
7471 clean_selected
7472 };
7473 self.fast_first_set_prefilter = true;
7474 self.fast_recovery_enabled = true;
7475 selected.map_err(|expected| {
7476 if predicate_context.is_some()
7477 && let Some(error) = self.unknown_semantic_error()
7478 {
7479 self.report_token_source_errors();
7480 return error;
7481 }
7482 let error = self.recognition_error(rule_index, start_index, &expected);
7483 self.record_syntax_errors(1);
7484 self.report_token_source_errors();
7485 if report_unrecovered_error {
7486 self.report_unrecovered_parser_error(&error);
7487 }
7488 error
7489 })?
7490 } else {
7491 first_pass.expect("first_pass is Ok in the no-retry branch")
7492 };
7493 if predicate_context.is_some()
7494 && let Some(error) = self.unknown_semantic_error()
7495 {
7496 self.report_token_source_errors();
7497 return Err(error);
7498 }
7499 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7500 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7501 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7502 self.report_token_source_errors();
7503 let mut context = ParserRuleContext::with_child_capacity(
7504 rule_index,
7505 self.state(),
7506 if self.build_parse_trees {
7507 self.recognition_arena.sequence_len(outcome.nodes)
7508 } else {
7509 0
7510 },
7511 );
7512 if alt_tracking.public {
7513 context.set_alt_number(alt_number.max(1));
7514 }
7515 if alt_tracking.context {
7516 context.set_context_alt_number(alt_number);
7517 }
7518 if let Some(token) = self.token_id_at(start_index) {
7519 self.set_context_start(&mut context, token);
7520 }
7521 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
7522 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
7523 self.set_context_stop(&mut context, token);
7524 }
7525 let live_root = if self.build_parse_trees {
7526 self.recognition_arena
7527 .fold_left_recursive_boundaries(outcome.nodes)
7528 } else {
7529 outcome.nodes
7530 };
7531 if self.build_parse_trees {
7532 if self
7533 .recognition_arena
7534 .sequence_has_explicit_token(live_root)
7535 {
7536 let mut cursor = live_root;
7537 while let Some(link) = self.recognition_arena.link(cursor) {
7538 let child = self.arena_recognized_node_tree(
7539 link.head,
7540 alt_tracking.public,
7541 alt_tracking.context,
7542 )?;
7543 self.tree.add_child(&mut context, child);
7544 cursor = link.tail;
7545 }
7546 } else {
7547 self.add_arena_implicit_token_children(
7548 &mut context,
7549 start_index,
7550 stop_index,
7551 live_root,
7552 alt_tracking,
7553 )?;
7554 }
7555 }
7556 self.finish_recognition_arena(live_root, outcome.diagnostics);
7557 self.input.seek(outcome.index);
7558
7559 let tree = self.rule_node(context);
7560 self.release_tree_scratch_if_idle();
7561 Ok(tree)
7562 }
7563
7564 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
7565 let invoking_state = self.pending_invoking_states.last().copied()?;
7566 let state_number = usize::try_from(invoking_state).ok()?;
7567 match atn.state(state_number)?.transitions().first()?.data() {
7568 Transition::Rule { follow_state, .. } => Some(follow_state),
7569 _ => None,
7570 }
7571 }
7572
7573 #[cfg(test)]
7574 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
7575 caller_follow_token_info_for_stream(&mut self.input, index)
7576 }
7577
7578 fn fast_recognize_top(
7583 &mut self,
7584 atn: &Atn,
7585 request: FastRecognizeTopRequest,
7586 predicate_context: Option<FastPredicateContext<'_>>,
7587 ) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
7588 let FastRecognizeTopRequest {
7589 start_state,
7590 stop_state,
7591 start_index,
7592 precedence,
7593 caller_follow_state,
7594 } = request;
7595 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
7604 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
7605 recognize_scratch.prepare(memo_capacity);
7606 let mut expected = ExpectedTokens::default();
7607 let empty_recovery = self.empty_recovery_symbols();
7608 let outcomes = self.recognize_state_fast(
7609 atn,
7610 FastRecognizeRequest {
7611 state_number: start_state,
7612 stop_state,
7613 index: start_index,
7614 rule_start_index: start_index,
7615 decision_start_index: None,
7616 precedence,
7617 depth: 0,
7618 recovery_symbols: empty_recovery,
7619 recovery_state: None,
7620 },
7621 FastRecognizeScratch {
7622 predicate_context,
7623 visiting: &mut recognize_scratch.visiting,
7624 memo: &mut recognize_scratch.memo,
7625 expected: &mut expected,
7626 native_depth: 0,
7627 },
7628 );
7629 recognize_scratch.release_oversized_memo();
7630 self.fast_recognize_scratch = recognize_scratch;
7631 #[cfg(feature = "perf-counters")]
7632 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
7633 perf_counters::dump();
7634 perf_counters::reset();
7635 }
7636 let caller_follow =
7637 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
7638 let selected = {
7639 let arena = &self.recognition_arena;
7640 let input = &mut self.input;
7641 select_best_fast_outcome(
7642 outcomes.into_iter(),
7643 self.prediction_mode,
7644 caller_follow.as_deref(),
7645 |index| caller_follow_token_info_for_stream(input, index),
7646 arena,
7647 )
7648 };
7649 match selected {
7650 Some(mut outcome) => {
7651 let alt_number = if self.build_parse_trees || self.fast_track_alt_numbers {
7652 self.materialize_fast_outcome_nodes(&mut outcome)
7653 } else {
7654 0
7655 };
7656 Ok((outcome, expected, alt_number))
7657 }
7658 None => Err(expected),
7659 }
7660 }
7661
7662 fn arena_recognized_node_tree(
7664 &mut self,
7665 node_id: RecognizedNodeId,
7666 track_alt_numbers: bool,
7667 track_context_alt_numbers: bool,
7668 ) -> Result<ParseTree, AntlrError> {
7669 let node = self.recognition_arena.node(node_id);
7670 match node {
7671 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
7672 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
7673 ArenaRecognizedNode::MissingToken { extra } => {
7674 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
7675 RecognitionExtra::MissingToken {
7676 token_type,
7677 at_index,
7678 text,
7679 } => (*token_type, *at_index as usize, text.clone()),
7680 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
7681 unreachable!("missing-token node must reference missing-token extra")
7682 }
7683 };
7684 let (line, column) = self
7685 .token_at(at_index)
7686 .map_or((0, 0), |token| (token.line(), token.column()));
7687 let token = self.insert_synthetic_token(token_type, text, line, column)?;
7688 Ok(self.error_tree(token))
7689 }
7690 ArenaRecognizedNode::Rule {
7691 rule_index,
7692 invoking_state,
7693 alt_number,
7694 start_index,
7695 stop_index,
7696 return_values,
7697 children,
7698 } => {
7699 let mut context = ParserRuleContext::with_child_capacity(
7700 rule_index as usize,
7701 invoking_state as isize,
7702 self.recognition_arena.sequence_len(children),
7703 );
7704 if track_alt_numbers {
7705 context.set_alt_number((alt_number as usize).max(1));
7706 }
7707 if track_context_alt_numbers {
7708 context.set_context_alt_number(alt_number as usize);
7709 }
7710 if let Some(extra) = return_values {
7711 let RecognitionExtra::ReturnValues(values) =
7712 self.recognition_arena.extra(extra)
7713 else {
7714 unreachable!("rule node must reference return-values extra");
7715 };
7716 for (name, value) in values {
7717 context.set_int_return(name.clone(), *value);
7718 }
7719 }
7720 if let Some(token) = self.token_id_at(start_index as usize) {
7721 self.set_context_start(&mut context, token);
7722 }
7723 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7724 self.set_context_stop(&mut context, token);
7725 }
7726 let mut cursor = self
7727 .recognition_arena
7728 .fold_left_recursive_boundaries(children);
7729 while let Some(link) = self.recognition_arena.link(cursor) {
7730 let child = self.arena_recognized_node_tree(
7731 link.head,
7732 track_alt_numbers,
7733 track_context_alt_numbers,
7734 )?;
7735 self.tree.add_child(&mut context, child);
7736 cursor = link.tail;
7737 }
7738 Ok(self.rule_node(context))
7739 }
7740 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index, .. } => {
7741 Err(AntlrError::Unsupported(format!(
7742 "unfolded left-recursive boundary for rule {rule_index}"
7743 )))
7744 }
7745 }
7746 }
7747
7748 fn arena_recognized_node_tree_with_implicit_tokens(
7749 &mut self,
7750 node_id: RecognizedNodeId,
7751 alt_tracking: AltNumberTracking,
7752 ) -> Result<ParseTree, AntlrError> {
7753 let node = self.recognition_arena.node(node_id);
7754 match node {
7755 ArenaRecognizedNode::Rule {
7756 rule_index,
7757 invoking_state,
7758 alt_number,
7759 start_index,
7760 stop_index,
7761 children,
7762 ..
7763 } => {
7764 let mut context = ParserRuleContext::with_child_capacity(
7765 rule_index as usize,
7766 invoking_state as isize,
7767 self.recognition_arena.sequence_len(children),
7768 );
7769 if alt_tracking.public {
7770 context.set_alt_number((alt_number as usize).max(1));
7771 }
7772 if alt_tracking.context {
7773 context.set_context_alt_number(alt_number as usize);
7774 }
7775 if let Some(token) = self.token_id_at(start_index as usize) {
7776 self.set_context_start(&mut context, token);
7777 }
7778 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7779 self.set_context_stop(&mut context, token);
7780 }
7781 let children = self
7782 .recognition_arena
7783 .fold_left_recursive_boundaries(children);
7784 self.add_arena_implicit_token_children(
7785 &mut context,
7786 start_index as usize,
7787 stop_index.map(|index| index as usize),
7788 children,
7789 alt_tracking,
7790 )?;
7791 Ok(self.rule_node(context))
7792 }
7793 _ => {
7794 self.arena_recognized_node_tree(node_id, alt_tracking.public, alt_tracking.context)
7795 }
7796 }
7797 }
7798
7799 fn add_arena_implicit_token_children(
7800 &mut self,
7801 context: &mut ParserRuleContext,
7802 start_index: usize,
7803 stop_index: Option<usize>,
7804 mut children: NodeSeqId,
7805 alt_tracking: AltNumberTracking,
7806 ) -> Result<(), AntlrError> {
7807 let mut cursor = Some(start_index);
7808 while let Some(link) = self.recognition_arena.link(children) {
7809 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
7810 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
7811 let child =
7812 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7813 self.tree.add_child(context, child);
7814 if let Some(child_stop) = child_stop {
7815 let next = self.next_visible_after_token(child_stop);
7816 cursor = match (cursor, next) {
7817 (None, _) | (_, None) => None,
7818 (Some(current), Some(next)) => Some(current.max(next)),
7819 };
7820 }
7821 } else {
7822 let child =
7823 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7824 self.tree.add_child(context, child);
7825 }
7826 children = link.tail;
7827 }
7828 if let Some(stop) = stop_index {
7829 self.add_visible_terminals_through(context, cursor, stop)?;
7830 }
7831 Ok(())
7832 }
7833
7834 fn add_visible_terminals_before(
7835 &mut self,
7836 context: &mut ParserRuleContext,
7837 cursor: &mut Option<usize>,
7838 before: usize,
7839 ) -> Result<(), AntlrError> {
7840 let Some(stop) = before.checked_sub(1) else {
7841 return Ok(());
7842 };
7843 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
7844 *cursor = next;
7845 Ok(())
7846 }
7847
7848 fn add_visible_terminals_through(
7849 &mut self,
7850 context: &mut ParserRuleContext,
7851 mut cursor: Option<usize>,
7852 stop: usize,
7853 ) -> Result<Option<usize>, AntlrError> {
7854 while let Some(index) = cursor {
7855 if index > stop {
7856 return Ok(Some(index));
7857 }
7858 let token = self
7859 .input
7860 .get_id(index)
7861 .ok_or_else(|| AntlrError::ParserError {
7862 line: 0,
7863 column: 0,
7864 message: format!("missing token at index {index}"),
7865 offending: None,
7866 })?;
7867 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
7868 let child = self.terminal_tree(token);
7869 self.tree.add_child(context, child);
7870 if is_eof {
7871 return Ok(None);
7872 }
7873 cursor = self.next_visible_after_token(index);
7874 }
7875 Ok(None)
7876 }
7877
7878 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
7879 let next = self.input.next_visible_after(index);
7880 (next != index).then_some(next)
7881 }
7882
7883 pub fn parse_atn_rule_with_actions(
7890 &mut self,
7891 atn: &Atn,
7892 rule_index: usize,
7893 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7894 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
7895 }
7896
7897 pub fn parse_atn_rule_with_action_inits(
7905 &mut self,
7906 atn: &Atn,
7907 rule_index: usize,
7908 init_action_rules: &[usize],
7909 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7910 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
7911 }
7912
7913 pub fn parse_atn_rule_with_action_options(
7919 &mut self,
7920 atn: &Atn,
7921 rule_index: usize,
7922 init_action_rules: &[usize],
7923 track_alt_numbers: bool,
7924 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7925 self.parse_atn_rule_with_runtime_options(
7926 atn,
7927 rule_index,
7928 ParserRuntimeOptions {
7929 init_action_rules,
7930 track_alt_numbers,
7931 ..ParserRuntimeOptions::default()
7932 },
7933 )
7934 }
7935
7936 pub fn parse_atn_rule_with_runtime_options(
7943 &mut self,
7944 atn: &Atn,
7945 rule_index: usize,
7946 options: ParserRuntimeOptions<'_>,
7947 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7948 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
7949 }
7950
7951 fn parse_atn_rule_committed_with_runtime_options(
7952 &mut self,
7953 atn: &Atn,
7954 rule_index: usize,
7955 precedence: i32,
7956 options: ParserRuntimeOptions<'_>,
7957 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7958 let top_level_entry = self.is_top_level_entry();
7959 self.unknown_predicate_policy = options.unknown_predicate_policy;
7960 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7961 let prior_unhandled_action_hits = std::mem::take(&mut self.unhandled_action_hits);
7962 self.clear_prediction_diagnostics();
7963 self.reset_per_parse_caches();
7964 self.reset_recognition_arena();
7965
7966 let mut decision_by_state = vec![None; atn.states().len()];
7967 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
7968 if let Some(slot) = decision_by_state.get_mut(state_number) {
7969 *slot = Some(decision);
7970 }
7971 }
7972 let mut action_index_by_state = FxHashMap::default();
7973 for &(state, index) in options.action_indices {
7974 action_index_by_state.entry(state).or_insert(index);
7975 }
7976 let mut simulator = ParserAtnSimulator::new(atn);
7977 simulator.set_track_prediction_rule_calls(!options.rule_args.is_empty());
7978 let (result, deferred_actions) = {
7979 let mut committed = CommittedAtnParser {
7980 parser: self,
7981 atn,
7982 simulator,
7983 options,
7984 decision_by_state,
7985 action_index_by_state,
7986 deferred_actions: Vec::new(),
7987 };
7988 let result = committed.parse_rule(rule_index, precedence, None, None);
7989 (result, committed.deferred_actions)
7990 };
7991
7992 if top_level_entry {
7993 self.report_generated_parser_diagnostics();
7994 }
7995 let semantic_error = self.unknown_semantic_error();
7996 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7997 self.restore_prior_unhandled_action_hits(prior_unhandled_action_hits);
7998 if top_level_entry && let Some(error) = self.take_parse_abort() {
7999 self.reset_unknown_semantic_hits();
8000 return Err(error);
8001 }
8002 if let Some(error) = semantic_error {
8003 if top_level_entry {
8004 self.reset_unknown_semantic_hits();
8005 }
8006 return Err(error);
8007 }
8008 let result = result.map(|outcome| (outcome.tree, deferred_actions));
8009 if top_level_entry && let Err(error) = &result {
8010 self.report_unrecovered_parser_error(error);
8011 }
8012 result
8013 }
8014
8015 pub fn parse_atn_rule_with_runtime_options_and_precedence(
8018 &mut self,
8019 atn: &Atn,
8020 rule_index: usize,
8021 precedence: i32,
8022 options: ParserRuntimeOptions<'_>,
8023 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
8024 if !options.action_indices.is_empty() {
8025 return self.parse_atn_rule_committed_with_runtime_options(
8026 atn, rule_index, precedence, options,
8027 );
8028 }
8029 let report_unrecovered_error = self.is_top_level_entry();
8030 let ParserRuntimeOptions {
8031 init_action_rules,
8032 track_alt_numbers,
8033 track_context_alt_numbers,
8034 predicates,
8035 semantics,
8036 rule_args,
8037 member_actions,
8038 return_actions,
8039 unknown_predicate_policy,
8040 ..
8041 } = options;
8042 let capture_alt_numbers = track_alt_numbers || track_context_alt_numbers;
8043 if init_action_rules.is_empty()
8044 && !capture_alt_numbers
8045 && predicates.is_empty()
8046 && semantics.is_none()
8047 && rule_args.is_empty()
8048 && member_actions.is_empty()
8049 && return_actions.is_empty()
8050 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
8051 && !atn_has_observable_action_transitions(atn)
8052 && !self.semantic_hooks.observes_parser_decisions()
8053 && (!self.semantic_hooks.observes_parser_predicates()
8054 || !atn_has_predicate_transitions(atn))
8055 {
8056 return self
8057 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
8058 .map(|tree| (tree, Vec::new()));
8059 }
8060 if !self.semantic_hooks.observes_parser_decisions()
8061 && can_use_fast_predicate_recognizer(atn, &options)
8062 {
8063 self.unknown_predicate_policy = unknown_predicate_policy;
8064 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8065 let member_values = self.int_members.clone();
8066 let result = self
8067 .parse_atn_rule_with_precedence_inner(
8068 atn,
8069 rule_index,
8070 precedence,
8071 Some(FastPredicateContext {
8072 predicates,
8073 semantics,
8074 member_values: &member_values,
8075 }),
8076 AltNumberTracking {
8077 public: track_alt_numbers,
8078 context: track_context_alt_numbers,
8079 },
8080 )
8081 .map(|tree| (tree, Vec::new()));
8082 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
8083 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8084 }
8085 return result;
8086 }
8087 self.unknown_predicate_policy = unknown_predicate_policy;
8088 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
8095 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
8096 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
8097 })?;
8098 let stop_state = atn
8099 .rule_to_stop_state()
8100 .get(rule_index)
8101 .filter(|state| *state != usize::MAX)
8102 .ok_or_else(|| {
8103 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
8104 })?;
8105
8106 let start_index = self.current_visible_index();
8107 self.clear_prediction_diagnostics();
8108 self.reset_per_parse_caches();
8109 self.reset_recognition_arena();
8110 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
8111 let invoking_state = self.pending_invoking_states.pop();
8112 let local_int_arg = invoking_state
8113 .and_then(|state| usize::try_from(state).ok())
8114 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
8115 let mut visiting = BTreeSet::new();
8116 let mut memo = BTreeMap::new();
8117 let mut expected = ExpectedTokens::default();
8118 let member_values = self.int_members.clone();
8119 let return_values = BTreeMap::new();
8120 let outcomes = self.recognize_state(
8121 atn,
8122 RecognizeRequest {
8123 state_number: start_state,
8124 stop_state,
8125 index: start_index,
8126 rule_start_index: start_index,
8127 decision_start_index: None,
8128 init_action_rules: &init_action_rules,
8129 predicates,
8130 semantics,
8131 rule_args,
8132 member_actions,
8133 return_actions,
8134 local_int_arg,
8135 member_values,
8136 return_values,
8137 rule_alt_number: 0,
8138 track_alt_numbers: capture_alt_numbers,
8139 consumed_eof: false,
8140 committed_decision: false,
8141 precedence,
8142 depth: 0,
8143 recovery_symbols: BTreeSet::new(),
8144 recovery_state: None,
8145 },
8146 &mut visiting,
8147 &mut memo,
8148 &mut expected,
8149 );
8150 if let Some(error) = self.unknown_semantic_error() {
8151 self.report_token_source_errors();
8152 return Err(error);
8159 }
8160 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
8163 let Some(outcome) = select_best_outcome(
8164 outcomes.into_iter(),
8165 self.prediction_mode,
8166 &self.recognition_arena,
8167 ) else {
8168 let error = self.recognition_error(rule_index, start_index, &expected);
8169 self.record_syntax_errors(1);
8170 self.report_token_source_errors();
8171 if report_unrecovered_error {
8172 self.report_unrecovered_parser_error(&error);
8173 }
8174 return Err(error);
8175 };
8176
8177 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
8178 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
8179 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
8180 self.report_token_source_errors();
8181 let mut actions = outcome.actions;
8182 if init_action_rules.contains(&rule_index) {
8183 actions.insert(
8184 0,
8185 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
8186 );
8187 }
8188 let mut context =
8189 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
8190 if track_alt_numbers {
8191 context.set_alt_number(outcome.alt_number.max(1));
8192 }
8193 if track_context_alt_numbers {
8194 context.set_context_alt_number(outcome.alt_number);
8195 }
8196 for (name, value) in outcome.return_values {
8197 context.set_int_return(name, value);
8198 }
8199 if let Some(token) = self.token_id_at(start_index) {
8200 self.set_context_start(&mut context, token);
8201 }
8202 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
8203 self.set_context_stop(&mut context, token);
8204 }
8205 let live_root = if self.build_parse_trees {
8206 self.recognition_arena
8207 .fold_left_recursive_boundaries(outcome.nodes)
8208 } else {
8209 outcome.nodes
8210 };
8211 if self.build_parse_trees {
8212 let mut nodes = live_root;
8213 while let Some(link) = self.recognition_arena.link(nodes) {
8214 let child = self.arena_recognized_node_tree(
8215 link.head,
8216 track_alt_numbers,
8217 track_context_alt_numbers,
8218 )?;
8219 self.tree.add_child(&mut context, child);
8220 nodes = link.tail;
8221 }
8222 }
8223 self.finish_recognition_arena(live_root, outcome.diagnostics);
8224 self.input.seek(outcome.index);
8225
8226 let tree = self.rule_node(context);
8227 self.release_tree_scratch_if_idle();
8228 Ok((tree, actions))
8229 }
8230
8231 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
8238 let mut context = ParserRuleContext::new(rule_index, self.state());
8239 while self.la(1) != TOKEN_EOF {
8240 let token_type = self.la(1);
8241 let child = self.match_token(token_type)?;
8242 if self.build_parse_trees {
8243 self.tree.add_child(&mut context, child);
8244 }
8245 }
8246 if self.build_parse_trees {
8247 let child = self.match_eof()?;
8248 self.tree.add_child(&mut context, child);
8249 }
8250 let tree = self.rule_node(context);
8251 self.release_tree_scratch_if_idle();
8252 Ok(tree)
8253 }
8254
8255 fn recognition_error(
8258 &mut self,
8259 rule_index: usize,
8260 start_index: usize,
8261 expected: &ExpectedTokens,
8262 ) -> AntlrError {
8263 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
8264 self.input.seek(index);
8265 let current = self.input.lt(1);
8266 let line = current.as_ref().map(Token::line).unwrap_or_default();
8267 let column = current.as_ref().map(Token::column).unwrap_or_default();
8268 AntlrError::ParserError {
8269 line,
8270 column,
8271 message,
8272 offending: current.as_ref().map(Token::token_id),
8273 }
8274 }
8275
8276 fn expected_error_message(
8278 &mut self,
8279 rule_index: usize,
8280 start_index: usize,
8281 expected: &ExpectedTokens,
8282 ) -> (usize, String) {
8283 let index = expected
8284 .index
8285 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
8286 .unwrap_or_else(|| self.input.index());
8287 self.input.seek(index);
8288 let current = self.input.lt(1);
8289 let message = if expected
8290 .no_viable
8291 .as_ref()
8292 .is_some_and(|no_viable| no_viable.error_index == index)
8293 {
8294 let start = expected
8295 .no_viable
8296 .as_ref()
8297 .map_or(start_index, |no_viable| no_viable.start_index);
8298 let text = display_input_text(&self.input.text(start, index));
8299 format!("no viable alternative at input '{text}'")
8300 } else if expected.symbols.is_empty() {
8301 if expected.index.is_some() {
8302 let found = current
8303 .as_ref()
8304 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
8305 if current
8306 .as_ref()
8307 .is_some_and(|token| token.token_type() == TOKEN_EOF)
8308 {
8309 format!(
8310 "missing {} at {found}",
8311 self.expected_symbols_display(&expected.symbols)
8312 )
8313 } else {
8314 format!("mismatched input {found}")
8315 }
8316 } else {
8317 format!("no viable alternative while parsing rule {rule_index}")
8318 }
8319 } else {
8320 format!(
8321 "mismatched input {} expecting {}",
8322 current
8323 .as_ref()
8324 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8325 self.expected_symbols_display(&expected.symbols)
8326 )
8327 };
8328 (index, message)
8329 }
8330
8331 fn child_rule_failure_recovery(
8334 &mut self,
8335 rule_index: usize,
8336 start_index: usize,
8337 sync_symbols: &BTreeSet<i32>,
8338 member_values: MemberEnv,
8339 expected: &ExpectedTokens,
8340 ) -> Option<RecognizeOutcome> {
8341 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
8342 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
8343 let mut next_index = error_index;
8344 loop {
8345 let symbol = self.token_type_at(next_index);
8346 if sync_symbols.contains(&symbol) {
8347 if next_index == error_index {
8348 return None;
8349 }
8350 break;
8351 }
8352 if symbol == TOKEN_EOF {
8353 break;
8354 }
8355 let after = self.consume_index(next_index, symbol);
8356 if after == next_index {
8357 break;
8358 }
8359 next_index = after;
8360 }
8361 let mut nodes = NodeSeqId::EMPTY;
8362 let error = self.arena_token_node(error_index, true);
8363 self.arena_prepend(&mut nodes, error);
8364 let diagnostics = self
8365 .recognition_arena
8366 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8367 Some(RecognizeOutcome {
8368 index: next_index,
8369 consumed_eof: false,
8370 alt_number: 0,
8371 member_values,
8372 return_values: BTreeMap::new(),
8373 diagnostics,
8374 decisions: Vec::new(),
8375 actions: Vec::new(),
8376 nodes,
8377 })
8378 }
8379
8380 fn child_rule_failure_recovery_outcomes(
8383 &mut self,
8384 request: ChildRuleFailureRecovery<'_>,
8385 ) -> Vec<RecognizeOutcome> {
8386 let sync_symbols =
8387 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
8388 self.child_rule_failure_recovery(
8389 request.rule_index,
8390 request.start_index,
8391 &sync_symbols,
8392 request.member_values,
8393 request.expected,
8394 )
8395 .into_iter()
8396 .collect()
8397 }
8398
8399 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
8401 expected_symbols_display(symbols, self.vocabulary())
8402 }
8403
8404 fn single_token_deletion(
8407 &mut self,
8408 transition: ParserTransition<'_>,
8409 index: usize,
8410 max_token_type: i32,
8411 expected_symbols: &BTreeSet<i32>,
8412 ) -> Option<(ParserDiagnostic, usize, i32)> {
8413 let current_symbol = self.token_type_at(index);
8414 if current_symbol == TOKEN_EOF {
8415 return None;
8416 }
8417 let next_index = self.consume_index(index, current_symbol);
8418 if next_index == index {
8419 return None;
8420 }
8421 let next_symbol = self.token_type_at(next_index);
8422 if !transition.matches(next_symbol, 1, max_token_type) {
8423 return None;
8424 }
8425 let transition_expected = transition_expected_symbols(transition, max_token_type);
8426 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8427 &transition_expected
8428 } else {
8429 expected_symbols
8430 });
8431 let current = self.token_at(index);
8432 let message = format!(
8433 "extraneous input {} expecting {expected_display}",
8434 current
8435 .as_ref()
8436 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8437 );
8438 Some((
8439 diagnostic_for_token(current, message),
8440 next_index,
8441 next_symbol,
8442 ))
8443 }
8444
8445 fn current_token_deletion(
8448 &mut self,
8449 index: usize,
8450 expected_symbols: &BTreeSet<i32>,
8451 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
8452 if expected_symbols.is_empty() {
8453 return None;
8454 }
8455 let current_symbol = self.token_type_at(index);
8456 if current_symbol == TOKEN_EOF {
8457 return None;
8458 }
8459 let current = self.token_at(index);
8460 let message = format!(
8461 "extraneous input {} expecting {}",
8462 current
8463 .as_ref()
8464 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8465 self.expected_symbols_display(expected_symbols)
8466 );
8467 let diagnostic = diagnostic_for_token(current, message);
8468 let mut skipped = Vec::new();
8469 let mut cursor = index;
8470 loop {
8471 let symbol = self.token_type_at(cursor);
8472 if symbol == TOKEN_EOF {
8473 return None;
8474 }
8475 skipped.push(cursor);
8476 let next_index = self.consume_index(cursor, symbol);
8477 if next_index == cursor {
8478 return None;
8479 }
8480 let next_symbol = self.token_type_at(next_index);
8481 if expected_symbols.contains(&next_symbol) {
8482 return Some((diagnostic, next_index, skipped));
8483 }
8484 cursor = next_index;
8485 }
8486 }
8487
8488 fn single_token_insertion(
8492 &mut self,
8493 transition: ParserTransition<'_>,
8494 index: usize,
8495 max_token_type: i32,
8496 expected_symbols: &BTreeSet<i32>,
8497 follow_symbols: &BTreeSet<i32>,
8498 ) -> Option<(ParserDiagnostic, i32, String)> {
8499 let current_symbol = self.token_type_at(index);
8500 if !follow_symbols.contains(¤t_symbol) {
8501 return None;
8502 }
8503 let transition_expected = transition_expected_symbols(transition, max_token_type);
8504 let token_type = transition_expected.iter().next().copied()?;
8505 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8506 &transition_expected
8507 } else {
8508 expected_symbols
8509 });
8510 let mut token_symbols = BTreeSet::new();
8511 token_symbols.insert(token_type);
8512 let missing_token_display = self.expected_symbols_display(&token_symbols);
8513 let current = self.token_at(index);
8514 let message = format!(
8515 "missing {expected_display} at {}",
8516 current
8517 .as_ref()
8518 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8519 );
8520 let text = format!("<missing {missing_token_display}>");
8521 Some((
8522 diagnostic_for_token(current.as_ref(), message),
8523 token_type,
8524 text,
8525 ))
8526 }
8527
8528 fn fast_single_token_deletion_recovery(
8532 &mut self,
8533 recovery: FastRecoveryRequest<'_, '_>,
8534 predicate_context: Option<FastPredicateContext<'_>>,
8535 ) -> Vec<FastRecognizeOutcome> {
8536 let FastRecoveryRequest {
8537 atn,
8538 transition,
8539 expected_symbols,
8540 target,
8541 request,
8542 visiting,
8543 memo,
8544 expected,
8545 } = recovery;
8546 let FastRecognizeRequest {
8547 stop_state,
8548 index,
8549 rule_start_index,
8550 decision_start_index,
8551 precedence,
8552 depth,
8553 ..
8554 } = request;
8555 let Some((diagnostic, next_index, next_symbol)) =
8556 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
8557 else {
8558 return Vec::new();
8559 };
8560 let after_next = self.consume_index(next_index, next_symbol);
8561 let empty_recovery = self.empty_recovery_symbols();
8562 self.recognize_state_fast(
8563 atn,
8564 FastRecognizeRequest {
8565 state_number: target,
8566 stop_state,
8567 index: after_next,
8568 rule_start_index,
8569 decision_start_index,
8570 precedence,
8571 depth: depth + 1,
8572 recovery_symbols: empty_recovery,
8573 recovery_state: None,
8574 },
8575 FastRecognizeScratch {
8576 predicate_context,
8577 visiting,
8578 memo,
8579 expected,
8580 native_depth: 0,
8581 },
8582 )
8583 .into_iter()
8584 .map(|mut outcome| {
8585 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
8586 outcome.diagnostics = self
8587 .recognition_arena
8588 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8589 if self.fast_token_nodes_enabled {
8590 let token = self.arena_token_node(next_index, false);
8591 self.defer_fast_outcome_node(&mut outcome, token);
8592 let error = self.arena_token_node(index, true);
8593 self.defer_fast_outcome_node(&mut outcome, error);
8594 }
8595 outcome
8596 })
8597 .collect()
8598 }
8599
8600 fn fast_single_token_insertion_recovery(
8604 &mut self,
8605 recovery: FastRecoveryRequest<'_, '_>,
8606 predicate_context: Option<FastPredicateContext<'_>>,
8607 ) -> Vec<FastRecognizeOutcome> {
8608 let FastRecoveryRequest {
8609 atn,
8610 transition,
8611 expected_symbols,
8612 target,
8613 request,
8614 visiting,
8615 memo,
8616 expected,
8617 } = recovery;
8618 let FastRecognizeRequest {
8619 stop_state,
8620 index,
8621 rule_start_index,
8622 decision_start_index,
8623 precedence,
8624 depth,
8625 ..
8626 } = request;
8627 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
8628 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
8629 transition,
8630 index,
8631 atn.max_token_type(),
8632 &expected_symbols,
8633 &follow_symbols,
8634 ) else {
8635 return Vec::new();
8636 };
8637 let empty_recovery = self.empty_recovery_symbols();
8638 self.recognize_state_fast(
8639 atn,
8640 FastRecognizeRequest {
8641 state_number: target,
8642 stop_state,
8643 index,
8644 rule_start_index,
8645 decision_start_index,
8646 precedence,
8647 depth: depth + 1,
8648 recovery_symbols: empty_recovery,
8649 recovery_state: None,
8650 },
8651 FastRecognizeScratch {
8652 predicate_context,
8653 visiting,
8654 memo,
8655 expected,
8656 native_depth: 0,
8657 },
8658 )
8659 .into_iter()
8660 .map(|mut outcome| {
8661 outcome.diagnostics = self
8662 .recognition_arena
8663 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8664 let missing = self.arena_missing_token_node(token_type, index, text.clone());
8665 self.defer_fast_outcome_node(&mut outcome, missing);
8666 outcome
8667 })
8668 .collect()
8669 }
8670
8671 fn fast_current_token_deletion_recovery(
8674 &mut self,
8675 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
8676 predicate_context: Option<FastPredicateContext<'_>>,
8677 ) -> Vec<FastRecognizeOutcome> {
8678 let FastCurrentTokenDeletionRequest {
8679 atn,
8680 expected_symbols,
8681 mut request,
8682 visiting,
8683 memo,
8684 expected,
8685 } = recovery;
8686 if request.index == request.rule_start_index {
8687 return Vec::new();
8688 }
8689 let Some((diagnostic, next_index, skipped)) =
8690 self.current_token_deletion(request.index, &expected_symbols)
8691 else {
8692 return Vec::new();
8693 };
8694 request.state_number = request.recovery_state.unwrap_or(request.state_number);
8695 request.index = next_index;
8696 request.depth += 1;
8697 request.recovery_state = None;
8698 self.recognize_state_fast(
8699 atn,
8700 request,
8701 FastRecognizeScratch {
8702 predicate_context,
8703 visiting,
8704 memo,
8705 expected,
8706 native_depth: 0,
8707 },
8708 )
8709 .into_iter()
8710 .map(|mut outcome| {
8711 outcome.diagnostics = self
8712 .recognition_arena
8713 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8714 for index in skipped.iter().rev() {
8715 let error = self.arena_token_node(*index, true);
8716 self.defer_fast_outcome_node(&mut outcome, error);
8717 }
8718 outcome
8719 })
8720 .collect()
8721 }
8722
8723 fn fast_child_rule_failure_recovery(
8726 &mut self,
8727 rule_index: usize,
8728 start_index: usize,
8729 sync_symbols: &BTreeSet<i32>,
8730 expected: &ExpectedTokens,
8731 ) -> Option<FastRecognizeOutcome> {
8732 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
8733 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
8734 let mut next_index = error_index;
8735 loop {
8736 let symbol = self.token_type_at(next_index);
8737 if sync_symbols.contains(&symbol) {
8738 if next_index == error_index {
8739 return None;
8740 }
8741 break;
8742 }
8743 if symbol == TOKEN_EOF {
8744 break;
8745 }
8746 let after = self.consume_index(next_index, symbol);
8747 if after == next_index {
8748 break;
8749 }
8750 next_index = after;
8751 }
8752 let diagnostics = self
8753 .recognition_arena
8754 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8755 let mut nodes = NodeSeqId::EMPTY;
8756 if self.fast_token_nodes_enabled {
8757 let error = self.arena_token_node(error_index, true);
8758 self.arena_prepend(&mut nodes, error);
8759 }
8760 Some(FastRecognizeOutcome {
8761 index: next_index,
8762 consumed_eof: false,
8763 diagnostics,
8764 deferred_nodes: FastDeferredNodeId::EMPTY,
8765 nodes,
8766 })
8767 }
8768
8769 fn fast_child_rule_failure_recovery_outcomes(
8772 &mut self,
8773 request: FastChildRuleFailureRecoveryRequest<'_>,
8774 ) -> Vec<FastRecognizeOutcome> {
8775 let FastChildRuleFailureRecoveryRequest {
8776 atn,
8777 rule_index,
8778 start_index,
8779 follow_state,
8780 stop_state,
8781 expected,
8782 } = request;
8783 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
8784 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
8785 .into_iter()
8786 .collect()
8787 }
8788
8789 fn defer_fast_outcome_node(
8790 &mut self,
8791 outcome: &mut FastRecognizeOutcome,
8792 node: RecognizedNodeId,
8793 ) {
8794 if outcome.deferred_nodes.is_empty() {
8795 self.arena_prepend(&mut outcome.nodes, node);
8796 return;
8797 }
8798 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
8799 let fragment = self.recognition_arena.deferred_fragment(fragment);
8800 outcome.deferred_nodes = self
8801 .recognition_arena
8802 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
8803 }
8804
8805 fn defer_fast_outcome_alternative(
8806 &mut self,
8807 outcome: &mut FastRecognizeOutcome,
8808 alt_number: usize,
8809 ) {
8810 let alternative = self.recognition_arena.deferred_alternative(alt_number);
8811 outcome.deferred_nodes = self
8812 .recognition_arena
8813 .concat_deferred_nodes(alternative, outcome.deferred_nodes);
8814 }
8815
8816 fn defer_fast_outcome_boundary(
8817 &mut self,
8818 outcome: &mut FastRecognizeOutcome,
8819 rule_index: usize,
8820 ) {
8821 let boundary = self
8822 .recognition_arena
8823 .deferred_left_recursive_boundary(rule_index);
8824 outcome.deferred_nodes = self
8825 .recognition_arena
8826 .concat_deferred_nodes(boundary, outcome.deferred_nodes);
8827 }
8828
8829 fn materialize_fast_deferred_nodes(
8830 &mut self,
8831 root: FastDeferredNodeId,
8832 initial_suffix: NodeSeqId,
8833 ) -> (NodeSeqId, usize) {
8834 if root.is_empty() {
8835 return (initial_suffix, 0);
8836 }
8837
8838 enum Frame {
8839 Visit(FastDeferredNodeId),
8840 ContinuePrefix(FastDeferredNodeId),
8841 FinishRule {
8842 rule: FastDeferredRule,
8843 parent_suffix: NodeSeqId,
8844 parent_alt_number: u32,
8845 parent_pending_boundary: Option<RecognizedNodeId>,
8846 },
8847 }
8848
8849 let mut result = initial_suffix;
8850 let mut alt_number = 0;
8854 let mut pending_boundary = None;
8855 let mut pending = Vec::with_capacity(16);
8856 pending.push(Frame::Visit(root));
8857 let mut fragment_nodes = Vec::new();
8858 while let Some(frame) = pending.pop() {
8859 match frame {
8860 Frame::Visit(deferred) => {
8861 if deferred.is_empty() {
8862 continue;
8863 }
8864
8865 match self.recognition_arena.deferred_node(deferred) {
8866 FastDeferredNode::Fragment(sequence) => {
8867 fragment_nodes.clear();
8868 fragment_nodes.extend(self.recognition_arena.iter(sequence));
8869 while let Some(node) = fragment_nodes.pop() {
8870 self.arena_prepend(&mut result, node);
8871 }
8872 }
8873 FastDeferredNode::Rule(rule) => {
8874 let rule = self.recognition_arena.deferred_rule(rule);
8875 let parent_suffix = result;
8876 let parent_alt_number = alt_number;
8877 let parent_pending_boundary = pending_boundary;
8878 result = rule.children;
8879 alt_number = 0;
8880 pending_boundary = None;
8881 pending.push(Frame::FinishRule {
8882 rule,
8883 parent_suffix,
8884 parent_alt_number,
8885 parent_pending_boundary,
8886 });
8887 pending.push(Frame::Visit(rule.deferred_children));
8888 }
8889 FastDeferredNode::Alternative(selected) => {
8890 if let Some(boundary) = pending_boundary {
8891 self.recognition_arena
8892 .set_boundary_alt_number(boundary, selected);
8893 } else {
8894 alt_number = selected;
8895 }
8896 }
8897 FastDeferredNode::LeftRecursiveBoundary { rule_index } => {
8898 let boundary = self.arena_boundary_node(rule_index as usize, 0);
8899 self.arena_prepend(&mut result, boundary);
8900 pending_boundary = Some(boundary);
8901 }
8902 FastDeferredNode::Concat {
8903 prefix,
8904 suffix: deferred_suffix,
8905 } => {
8906 pending.push(Frame::ContinuePrefix(prefix));
8907 pending.push(Frame::Visit(deferred_suffix));
8908 }
8909 }
8910 }
8911 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
8912 Frame::FinishRule {
8913 rule,
8914 parent_suffix,
8915 parent_alt_number,
8916 parent_pending_boundary,
8917 } => {
8918 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
8919 rule_index: rule.rule_index,
8920 invoking_state: rule.invoking_state,
8921 alt_number,
8922 start_index: rule.start_index,
8923 stop_index: rule.stop_index,
8924 return_values: None,
8925 children: result,
8926 });
8927 result = parent_suffix;
8928 self.arena_prepend(&mut result, node);
8929 alt_number = parent_alt_number;
8930 pending_boundary = parent_pending_boundary;
8931 }
8932 }
8933 }
8934 (result, alt_number as usize)
8935 }
8936
8937 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) -> usize {
8938 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
8939 let (nodes, alt_number) =
8940 self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
8941 outcome.nodes = nodes;
8942 alt_number
8943 }
8944
8945 fn recognize_repetition_fast(
8948 &mut self,
8949 atn: &Atn,
8950 request: &FastRecognizeRequest,
8951 shape: FastRepetitionShape,
8952 scratch: FastRecognizeScratch<'_, '_>,
8953 ) -> Vec<FastRecognizeOutcome> {
8954 let FastRecognizeScratch {
8955 predicate_context,
8956 visiting,
8957 memo,
8958 expected,
8959 native_depth,
8960 } = scratch;
8961 let lookahead = if self.fast_first_set_prefilter {
8962 atn.state(request.state_number).and_then(|state| {
8963 state
8964 .rule_index()
8965 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8966 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
8967 })
8968 } else {
8969 None
8970 };
8971 let (enter_alt_number, exit_alt_number) = if self.fast_track_alt_numbers {
8972 let state = atn
8973 .state(request.state_number)
8974 .expect("repetition request state must exist");
8975 (
8976 next_alt_number(state, 2, shape.enter_transition_index, 0, true),
8977 next_alt_number(state, 2, shape.exit_transition_index, 0, true),
8978 )
8979 } else {
8980 (0, 0)
8981 };
8982 let mut work = Vec::with_capacity(2);
8983 push_fast_repetition_work(
8984 &mut work,
8985 shape,
8986 FastRepetitionPath {
8987 index: request.index,
8988 deferred_nodes: FastDeferredNodeId::EMPTY,
8989 diagnostics: DiagnosticSeqId::EMPTY,
8990 consumed_eof: false,
8991 },
8992 lookahead.as_deref(),
8993 self.token_type_at(request.index),
8994 );
8995 let mut coordinates = FastRepetitionCoordinates::new(request.index);
8996 let mut outcomes = Vec::new();
8997 while let Some(item) = work.pop() {
8998 match item {
8999 FastRepetitionWork::Enter(path) => {
9000 if !coordinates.insert_entered(path) {
9001 continue;
9002 }
9003 let path_nodes = if enter_alt_number == 0 {
9004 path.deferred_nodes
9005 } else {
9006 let alternative = self
9007 .recognition_arena
9008 .deferred_alternative(enter_alt_number);
9009 self.recognition_arena
9010 .concat_deferred_nodes(path.deferred_nodes, alternative)
9011 };
9012 let body_outcomes = self.recognize_state_fast(
9013 atn,
9014 FastRecognizeRequest {
9015 state_number: shape.enter_target,
9016 stop_state: shape.body_stop_state,
9017 index: path.index,
9018 rule_start_index: request.rule_start_index,
9019 decision_start_index: request.decision_start_index,
9020 precedence: request.precedence,
9021 depth: request.depth.saturating_add(1),
9022 recovery_symbols: Rc::clone(&request.recovery_symbols),
9023 recovery_state: request.recovery_state,
9024 },
9025 FastRecognizeScratch {
9026 predicate_context,
9027 visiting: &mut *visiting,
9028 memo: &mut *memo,
9029 expected: &mut *expected,
9030 native_depth: native_depth + 1,
9031 },
9032 );
9033 for body in body_outcomes.into_iter().rev() {
9034 if body.index <= path.index {
9038 continue;
9039 }
9040 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
9041 let body_nodes = self
9042 .recognition_arena
9043 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
9044 let deferred_nodes = self
9045 .recognition_arena
9046 .concat_deferred_nodes(path_nodes, body_nodes);
9047 let next_path = FastRepetitionPath {
9048 index: body.index,
9049 deferred_nodes,
9050 diagnostics: self
9051 .recognition_arena
9052 .concat_diagnostics(path.diagnostics, body.diagnostics),
9053 consumed_eof: path.consumed_eof || body.consumed_eof,
9054 };
9055 let symbol = self.token_type_at(next_path.index);
9056 push_fast_repetition_work(
9057 &mut work,
9058 shape,
9059 next_path,
9060 lookahead.as_deref(),
9061 symbol,
9062 );
9063 }
9064 }
9065 FastRepetitionWork::Exit(path) => {
9066 if !coordinates.insert_exited(path) {
9067 continue;
9068 }
9069 let path_nodes = if exit_alt_number == 0 {
9070 path.deferred_nodes
9071 } else {
9072 let alternative =
9073 self.recognition_arena.deferred_alternative(exit_alt_number);
9074 self.recognition_arena
9075 .concat_deferred_nodes(path.deferred_nodes, alternative)
9076 };
9077 let suffixes = self.recognize_state_fast(
9078 atn,
9079 FastRecognizeRequest {
9080 state_number: shape.exit_target,
9081 stop_state: request.stop_state,
9082 index: path.index,
9083 rule_start_index: request.rule_start_index,
9084 decision_start_index: request.decision_start_index,
9085 precedence: request.precedence,
9086 depth: request.depth.saturating_add(1),
9087 recovery_symbols: Rc::clone(&request.recovery_symbols),
9088 recovery_state: request.recovery_state,
9089 },
9090 FastRecognizeScratch {
9091 predicate_context,
9092 visiting: &mut *visiting,
9093 memo: &mut *memo,
9094 expected: &mut *expected,
9095 native_depth: native_depth + 1,
9096 },
9097 );
9098 for mut outcome in suffixes {
9099 outcome.deferred_nodes = self
9100 .recognition_arena
9101 .concat_deferred_nodes(path_nodes, outcome.deferred_nodes);
9102 outcome.diagnostics = self
9103 .recognition_arena
9104 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
9105 outcome.consumed_eof |= path.consumed_eof;
9106 outcomes.push(outcome);
9107 }
9108 }
9109 }
9110 }
9111 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
9112 outcomes
9113 }
9114
9115 fn recognize_state_fast(
9118 &mut self,
9119 atn: &Atn,
9120 request: FastRecognizeRequest,
9121 scratch: FastRecognizeScratch<'_, '_>,
9122 ) -> Vec<FastRecognizeOutcome> {
9123 if scratch.native_depth != 0 && scratch.native_depth < FAST_RECOGNIZE_STACK_CHECK_INTERVAL {
9124 return self.recognize_state_fast_inner(atn, request, scratch);
9125 }
9126 self.recognize_state_fast_checked(atn, request, scratch)
9127 }
9128
9129 #[inline(never)]
9130 fn recognize_state_fast_checked(
9131 &mut self,
9132 atn: &Atn,
9133 request: FastRecognizeRequest,
9134 mut scratch: FastRecognizeScratch<'_, '_>,
9135 ) -> Vec<FastRecognizeOutcome> {
9136 scratch.native_depth = 1;
9137 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, || {
9138 self.recognize_state_fast_inner(atn, request, scratch)
9139 })
9140 }
9141
9142 #[allow(clippy::too_many_lines)]
9143 fn recognize_state_fast_inner(
9144 &mut self,
9145 atn: &Atn,
9146 request: FastRecognizeRequest,
9147 scratch: FastRecognizeScratch<'_, '_>,
9148 ) -> Vec<FastRecognizeOutcome> {
9149 #[cfg(feature = "perf-counters")]
9150 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
9151 let FastRecognizeScratch {
9152 predicate_context,
9153 visiting,
9154 memo,
9155 expected,
9156 native_depth,
9157 } = scratch;
9158 let FastRecognizeRequest {
9159 mut state_number,
9160 stop_state,
9161 mut index,
9162 rule_start_index,
9163 decision_start_index,
9164 precedence,
9165 mut depth,
9166 recovery_symbols,
9167 recovery_state,
9168 } = request;
9169 let max_token_type = atn.max_token_type();
9170 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
9189 let mut inline_consumed_eof = false;
9190 loop {
9191 if depth > RECOGNITION_DEPTH_LIMIT {
9192 return Vec::new();
9193 }
9194 if state_number == stop_state {
9195 let mut nodes = NodeSeqId::EMPTY;
9196 if self.fast_token_nodes_enabled {
9197 for token_index in inline_consumed_tokens.iter().rev() {
9198 let token = self.arena_token_node(*token_index, false);
9199 self.arena_prepend(&mut nodes, token);
9200 }
9201 }
9202 return vec![FastRecognizeOutcome {
9203 index,
9204 consumed_eof: inline_consumed_eof,
9205 diagnostics: DiagnosticSeqId::EMPTY,
9206 deferred_nodes: FastDeferredNodeId::EMPTY,
9207 nodes,
9208 }];
9209 }
9210 let Some(state) = atn.state(state_number) else {
9211 return Vec::new();
9212 };
9213 let transitions = state.transitions();
9214 if transitions.len() == 1 && !state.precedence_rule_decision() {
9215 let transition = transitions
9216 .first()
9217 .expect("single transition checked above");
9218 let transition_kind = transition.kind();
9219 let target = transition.target();
9220 match transition_kind {
9221 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
9222 if left_recursive_boundary(atn, state, target).is_none() =>
9223 {
9224 #[cfg(feature = "perf-counters")]
9225 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9226 state_number = target;
9227 depth += 1;
9228 continue;
9229 }
9230 ParserTransitionKind::Predicate
9231 if left_recursive_boundary(atn, state, target).is_none() =>
9232 {
9233 #[cfg(feature = "perf-counters")]
9234 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9235 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
9236 {
9237 record_predicate_no_viable(expected, decision_start_index, index);
9238 return Vec::new();
9239 }
9240 state_number = target;
9241 depth += 1;
9242 continue;
9243 }
9244 ParserTransitionKind::Precedence
9245 if packed_i32(transition.arg0()) >= precedence
9246 && left_recursive_boundary(atn, state, target).is_none() =>
9247 {
9248 #[cfg(feature = "perf-counters")]
9249 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9250 state_number = target;
9251 depth += 1;
9252 continue;
9253 }
9254 ParserTransitionKind::Atom
9264 | ParserTransitionKind::Range
9265 | ParserTransitionKind::Set
9266 | ParserTransitionKind::NotSet
9267 | ParserTransitionKind::Wildcard
9268 if !self.fast_recovery_enabled =>
9269 {
9270 let symbol = self.token_type_at(index);
9271 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9272 #[cfg(feature = "perf-counters")]
9273 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9274 if self.fast_token_nodes_enabled {
9275 inline_consumed_tokens.push(index);
9276 }
9277 inline_consumed_eof |= symbol == TOKEN_EOF;
9278 index = self.consume_index(index, symbol);
9279 state_number = target;
9280 depth += 1;
9281 continue;
9282 }
9283 }
9286 _ => {}
9287 }
9288 }
9289 break;
9290 }
9291 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
9295 let Some(state) = atn.state(state_number) else {
9296 return Vec::new();
9297 };
9298 let transitions = state.transitions();
9299 let transition_count = transitions.len();
9300 if !self.fast_recovery_enabled
9301 && let Some(shape) = fast_repetition_shape(atn, state)
9302 {
9303 let mut outcomes = self.recognize_repetition_fast(
9304 atn,
9305 &FastRecognizeRequest {
9306 state_number,
9307 stop_state,
9308 index,
9309 rule_start_index,
9310 decision_start_index,
9311 precedence,
9312 depth,
9313 recovery_symbols: Rc::clone(&recovery_symbols),
9314 recovery_state,
9315 },
9316 shape,
9317 FastRecognizeScratch {
9318 predicate_context,
9319 visiting: &mut *visiting,
9320 memo: &mut *memo,
9321 expected: &mut *expected,
9322 native_depth: native_depth + 1,
9323 },
9324 );
9325 if inline_pending {
9326 for outcome in &mut outcomes {
9327 outcome.consumed_eof |= inline_consumed_eof;
9328 if self.fast_token_nodes_enabled {
9329 for token_index in inline_consumed_tokens.iter().rev() {
9330 let token = self.arena_token_node(*token_index, false);
9331 self.defer_fast_outcome_node(outcome, token);
9332 }
9333 }
9334 }
9335 }
9336 return outcomes;
9337 }
9338 let key = if self.fast_recovery_enabled {
9348 FastRecognizeKey {
9349 state_number,
9350 stop_state,
9351 index,
9352 rule_start_index,
9353 decision_start_index,
9354 precedence,
9355 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
9356 recovery_state,
9357 }
9358 } else {
9359 FastRecognizeKey {
9360 state_number,
9361 stop_state,
9362 index,
9363 rule_start_index: 0,
9364 decision_start_index: None,
9365 precedence,
9366 recovery_symbols_id: 0,
9367 recovery_state: None,
9368 }
9369 };
9370 let memo_lookup_enabled = self.fast_recovery_enabled
9375 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
9376 if memo_lookup_enabled {
9377 if let Some(outcomes) = memo.get(&key) {
9378 #[cfg(feature = "perf-counters")]
9379 {
9380 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
9381 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
9382 }
9383 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
9387 let inline_eof = inline_consumed_eof;
9388 let inline_tokens = &inline_consumed_tokens;
9389 return outcomes
9390 .iter()
9391 .copied()
9392 .map(|mut outcome| {
9393 if inline_eof {
9394 outcome.consumed_eof = true;
9395 }
9396 if self.fast_token_nodes_enabled {
9397 for token_index in inline_tokens.iter().rev() {
9398 let token = self.arena_token_node(*token_index, false);
9399 self.defer_fast_outcome_node(&mut outcome, token);
9400 }
9401 }
9402 outcome
9403 })
9404 .collect();
9405 }
9406 return outcomes.to_vec();
9407 }
9408 #[cfg(feature = "perf-counters")]
9409 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
9410 }
9411
9412 let needs_cycle_guard = if self.fast_recovery_enabled {
9417 transitions.iter().any(ParserTransition::is_epsilon)
9418 } else {
9419 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
9420 };
9421 #[cfg(feature = "perf-counters")]
9422 if needs_cycle_guard {
9423 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
9424 } else {
9425 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
9426 match state
9427 .transitions()
9428 .first()
9429 .expect("single-transition path requires one transition")
9430 .data()
9431 {
9432 Transition::Rule { .. } => {
9433 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
9434 }
9435 Transition::Atom { .. }
9436 | Transition::Range { .. }
9437 | Transition::Set { .. }
9438 | Transition::NotSet { .. }
9439 | Transition::Wildcard { .. } => {
9440 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
9441 }
9442 _ => {
9443 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
9444 }
9445 }
9446 }
9447 let has_inserted_cycle_guard = if needs_cycle_guard {
9448 if !visiting.insert(key.clone()) {
9449 #[cfg(feature = "perf-counters")]
9450 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
9451 return Vec::new();
9452 }
9453 true
9454 } else {
9455 false
9456 };
9457 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9458 Some(index)
9459 } else {
9460 decision_start_index
9461 };
9462 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
9463 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
9464 } else {
9465 (Rc::clone(&recovery_symbols), recovery_state)
9466 };
9467
9468 let lookahead_filter = if transition_count > 1
9487 && self.fast_first_set_prefilter
9488 && !state.precedence_rule_decision()
9489 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
9490 {
9491 state
9492 .rule_index()
9493 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
9494 .map(|rule_stop| {
9495 let symbol = self.token_type_at(index);
9496 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
9497 (symbol, entry)
9498 })
9499 } else {
9500 None
9501 };
9502 let ll1_only_alt: Option<usize> = if transition_count > 1
9511 && let Some((symbol, entry)) = lookahead_filter.as_ref()
9512 {
9513 let key = (state.state_number(), *symbol);
9514 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
9515 cached
9516 } else {
9517 let result = ll1_unique_alt(entry, *symbol);
9518 self.ll1_decision_cache.insert(key, result);
9519 result
9520 }
9521 } else {
9522 None
9523 };
9524 let lookahead_filter = lookahead_filter.as_ref();
9525 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
9531 for (transition_index, transition) in transitions.iter().enumerate() {
9532 if let Some(alt) = ll1_only_alt {
9533 if alt != transition_index {
9535 continue;
9536 }
9537 }
9538 let transition_kind = transition.kind();
9539 if ll1_only_alt.is_none()
9540 && should_skip_via_lookahead(
9541 transition_kind,
9542 transition_index,
9543 lookahead_filter,
9544 index,
9545 self.fast_recovery_enabled,
9546 expected,
9547 )
9548 {
9549 continue;
9550 }
9551 let target = transition.target();
9552 let outcomes_before_transition = outcomes.len();
9553 let left_recursive_boundary = match transition_kind {
9554 ParserTransitionKind::Epsilon
9555 | ParserTransitionKind::Action
9556 | ParserTransitionKind::Predicate
9557 | ParserTransitionKind::Precedence => left_recursive_boundary(atn, state, target),
9558 ParserTransitionKind::Atom
9559 | ParserTransitionKind::Range
9560 | ParserTransitionKind::Set
9561 | ParserTransitionKind::NotSet
9562 | ParserTransitionKind::Wildcard
9563 | ParserTransitionKind::Rule => None,
9564 };
9565 match transition_kind {
9566 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
9567 #[cfg(feature = "perf-counters")]
9568 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9569 outcomes.extend(self.recognize_state_fast(
9570 atn,
9571 FastRecognizeRequest {
9572 state_number: target,
9573 stop_state,
9574 index,
9575 rule_start_index,
9576 decision_start_index: next_decision_start_index,
9577 precedence,
9578 depth: depth + 1,
9579 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9580 recovery_state: epsilon_recovery_state,
9581 },
9582 FastRecognizeScratch {
9583 predicate_context,
9584 visiting,
9585 memo,
9586 expected,
9587 native_depth: native_depth + 1,
9588 },
9589 ));
9590 }
9591 ParserTransitionKind::Predicate => {
9592 #[cfg(feature = "perf-counters")]
9593 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9594 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
9595 outcomes.extend(self.recognize_state_fast(
9596 atn,
9597 FastRecognizeRequest {
9598 state_number: target,
9599 stop_state,
9600 index,
9601 rule_start_index,
9602 decision_start_index: next_decision_start_index,
9603 precedence,
9604 depth: depth + 1,
9605 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9606 recovery_state: epsilon_recovery_state,
9607 },
9608 FastRecognizeScratch {
9609 predicate_context,
9610 visiting,
9611 memo,
9612 expected,
9613 native_depth: native_depth + 1,
9614 },
9615 ));
9616 } else {
9617 record_predicate_no_viable(expected, next_decision_start_index, index);
9618 }
9619 }
9620 ParserTransitionKind::Precedence => {
9621 let transition_precedence = packed_i32(transition.arg0());
9622 if transition_precedence >= precedence {
9623 outcomes.extend(self.recognize_state_fast(
9624 atn,
9625 FastRecognizeRequest {
9626 state_number: target,
9627 stop_state,
9628 index,
9629 rule_start_index,
9630 decision_start_index: next_decision_start_index,
9631 precedence,
9632 depth: depth + 1,
9633 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9634 recovery_state: epsilon_recovery_state,
9635 },
9636 FastRecognizeScratch {
9637 predicate_context,
9638 visiting,
9639 memo,
9640 expected,
9641 native_depth: native_depth + 1,
9642 },
9643 ));
9644 }
9645 }
9646 ParserTransitionKind::Rule => {
9647 let rule_index = transition.arg0() as usize;
9648 let follow_state = transition.arg1() as usize;
9649 let rule_precedence = packed_i32(transition.arg2());
9650 #[cfg(feature = "perf-counters")]
9651 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
9652 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
9653 continue;
9654 };
9655 let symbol = self.token_type_at(index);
9667 if self.fast_first_set_prefilter {
9668 let first = self.cached_rule_first_set(atn, target, child_stop);
9681 if should_skip_rule_via_first_set(
9682 &first,
9683 symbol,
9684 self.fast_recovery_enabled,
9685 index,
9686 expected,
9687 ) {
9688 continue;
9689 }
9690 }
9691 let expected_before_child =
9692 self.fast_recovery_enabled.then(|| expected.clone());
9693 let mut children = self.recognize_state_fast(
9694 atn,
9695 FastRecognizeRequest {
9696 state_number: target,
9697 stop_state: child_stop,
9698 index,
9699 rule_start_index: index,
9700 decision_start_index: None,
9701 precedence: rule_precedence,
9702 depth: depth + 1,
9703 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9704 recovery_state: epsilon_recovery_state,
9705 },
9706 FastRecognizeScratch {
9707 predicate_context,
9708 visiting,
9709 memo,
9710 expected,
9711 native_depth: native_depth + 1,
9712 },
9713 );
9714 if children.is_empty() && self.fast_recovery_enabled {
9715 children = self.fast_child_rule_failure_recovery_outcomes(
9716 FastChildRuleFailureRecoveryRequest {
9717 atn,
9718 rule_index,
9719 start_index: index,
9720 follow_state,
9721 stop_state,
9722 expected,
9723 },
9724 );
9725 }
9726 if let Some(expected_before_child) = expected_before_child {
9727 if children
9728 .iter()
9729 .any(|child| child.diagnostics.is_empty() && child.index > index)
9730 {
9731 *expected = expected_before_child;
9732 }
9733 }
9734 for child in children {
9735 let child_index = child.index;
9736 let child_consumed_eof = child.consumed_eof;
9737 let child_diagnostics = child.diagnostics;
9738 let empty_recovery = self.empty_recovery_symbols();
9739 let follow_outcomes = self.recognize_state_fast(
9740 atn,
9741 FastRecognizeRequest {
9742 state_number: follow_state,
9743 stop_state,
9744 index: child_index,
9745 rule_start_index,
9746 decision_start_index: next_decision_start_index,
9747 precedence,
9748 depth: depth + 1,
9749 recovery_symbols: empty_recovery,
9750 recovery_state: None,
9751 },
9752 FastRecognizeScratch {
9753 predicate_context,
9754 visiting,
9755 memo,
9756 expected,
9757 native_depth: native_depth + 1,
9758 },
9759 );
9760 if follow_outcomes.is_empty() {
9761 continue;
9762 }
9763 let child_stop_index =
9764 self.rule_stop_token_index(child_index, child_consumed_eof);
9765 let child_node = self.build_parse_trees.then(|| {
9766 self.recognition_arena.deferred_rule_node(FastDeferredRule {
9767 rule_index: u32::try_from(rule_index)
9768 .expect("rule index fits in u32"),
9769 invoking_state: i32::try_from(invoking_state_number(state_number))
9770 .expect("invoking state fits in i32"),
9771 start_index: u32::try_from(index)
9772 .expect("rule start index fits in u32"),
9773 stop_index: child_stop_index.map(|stop_index| {
9774 u32::try_from(stop_index).expect("rule stop index fits in u32")
9775 }),
9776 deferred_children: child.deferred_nodes,
9777 children: child.nodes,
9778 })
9779 });
9780 let child_diags_empty = child_diagnostics.is_empty();
9781 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
9782 outcome.consumed_eof |= child_consumed_eof;
9783 if !child_diags_empty {
9786 outcome.diagnostics = self
9787 .recognition_arena
9788 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
9789 }
9790 if let Some(child_node) = child_node {
9791 outcome.deferred_nodes = self
9792 .recognition_arena
9793 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
9794 }
9795 outcome
9796 }));
9797 }
9798 }
9799 ParserTransitionKind::Atom
9800 | ParserTransitionKind::Range
9801 | ParserTransitionKind::Set
9802 | ParserTransitionKind::NotSet
9803 | ParserTransitionKind::Wildcard => {
9804 #[cfg(feature = "perf-counters")]
9805 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9806 let symbol = self.token_type_at(index);
9807 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9808 let next_index = self.consume_index(index, symbol);
9809 let empty_recovery = self.empty_recovery_symbols();
9810 outcomes.extend(
9811 self.recognize_state_fast(
9812 atn,
9813 FastRecognizeRequest {
9814 state_number: target,
9815 stop_state,
9816 index: next_index,
9817 rule_start_index,
9818 decision_start_index: next_decision_start_index,
9819 precedence,
9820 depth: depth + 1,
9821 recovery_symbols: empty_recovery,
9822 recovery_state: None,
9823 },
9824 FastRecognizeScratch {
9825 predicate_context,
9826 visiting,
9827 memo,
9828 expected,
9829 native_depth: native_depth + 1,
9830 },
9831 )
9832 .into_iter()
9833 .map(|mut outcome| {
9834 outcome.consumed_eof |= symbol == TOKEN_EOF;
9835 if self.fast_token_nodes_enabled {
9836 let token = self.arena_token_node(index, false);
9837 self.defer_fast_outcome_node(&mut outcome, token);
9838 }
9839 outcome
9840 }),
9841 );
9842 } else {
9843 if !self.fast_recovery_enabled {
9844 continue;
9852 }
9853 let expected_symbols = fast_recovery_expected_symbols(
9854 self,
9855 atn,
9856 state.state_number(),
9857 &recovery_symbols,
9858 );
9859 if expected_symbols.contains(&symbol) {
9860 continue;
9861 }
9862 {
9863 expected.record_transition(index, transition, max_token_type);
9864 record_no_viable_if_ambiguous(
9865 expected,
9866 next_decision_start_index,
9867 index,
9868 );
9869 outcomes.extend(self.fast_single_token_deletion_recovery(
9870 FastRecoveryRequest {
9871 atn,
9872 transition,
9873 expected_symbols: Rc::clone(&expected_symbols),
9874 target,
9875 request: FastRecognizeRequest {
9876 state_number,
9877 stop_state,
9878 index,
9879 rule_start_index,
9880 decision_start_index,
9881 precedence,
9882 depth,
9883 recovery_symbols: Rc::clone(&recovery_symbols),
9884 recovery_state,
9885 },
9886 visiting,
9887 memo,
9888 expected,
9889 },
9890 predicate_context,
9891 ));
9892 if !state_is_left_recursive_rule(atn, state) {
9893 outcomes.extend(self.fast_single_token_insertion_recovery(
9894 FastRecoveryRequest {
9895 atn,
9896 transition,
9897 expected_symbols: Rc::clone(&expected_symbols),
9898 target,
9899 request: FastRecognizeRequest {
9900 state_number,
9901 stop_state,
9902 index,
9903 rule_start_index,
9904 decision_start_index,
9905 precedence,
9906 depth,
9907 recovery_symbols: Rc::clone(&recovery_symbols),
9908 recovery_state,
9909 },
9910 visiting,
9911 memo,
9912 expected,
9913 },
9914 predicate_context,
9915 ));
9916 }
9917 outcomes.extend(self.fast_current_token_deletion_recovery(
9918 FastCurrentTokenDeletionRequest {
9919 atn,
9920 expected_symbols,
9921 request: FastRecognizeRequest {
9922 state_number,
9923 stop_state,
9924 index,
9925 rule_start_index,
9926 decision_start_index,
9927 precedence,
9928 depth,
9929 recovery_symbols: Rc::clone(&recovery_symbols),
9930 recovery_state,
9931 },
9932 visiting,
9933 memo,
9934 expected,
9935 },
9936 predicate_context,
9937 ));
9938 }
9939 }
9940 }
9941 }
9942 let alt_number = next_alt_number(
9943 state,
9944 transition_count,
9945 transition_index,
9946 0,
9947 self.fast_track_alt_numbers,
9948 );
9949 if alt_number != 0 || left_recursive_boundary.is_some() {
9950 for outcome in &mut outcomes[outcomes_before_transition..] {
9951 if alt_number != 0 {
9952 self.defer_fast_outcome_alternative(outcome, alt_number);
9953 }
9954 if let Some(rule_index) = left_recursive_boundary {
9955 self.defer_fast_outcome_boundary(outcome, rule_index);
9956 }
9957 }
9958 }
9959 }
9960
9961 if has_inserted_cycle_guard {
9962 visiting.remove(&key);
9963 }
9964 if matches!(
9965 self.prediction_mode,
9966 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9967 ) && self.fast_recovery_enabled
9968 {
9969 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
9973 }
9974 if self.fast_recovery_enabled {
9975 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
9976 } else {
9977 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
9978 }
9979 let should_memoize = self.fast_recovery_enabled
9989 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
9990 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
9994 if inline_consumed_eof {
9995 outcome.consumed_eof = true;
9996 }
9997 if !inline_consumed_tokens.is_empty() {
9998 for token_index in inline_consumed_tokens.iter().rev() {
9999 let token = self.arena_token_node(*token_index, false);
10000 self.defer_fast_outcome_node(&mut outcome, token);
10001 }
10002 }
10003 outcome
10004 };
10005 if should_memoize {
10006 #[cfg(feature = "perf-counters")]
10007 {
10008 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
10009 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
10010 match outcomes.len() {
10011 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
10012 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
10013 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
10014 }
10015 }
10016 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
10021 memo.insert(key, Rc::clone(&stored));
10022 if inline_pending {
10023 return stored
10024 .iter()
10025 .copied()
10026 .map(&mut apply_inline_pending)
10027 .collect();
10028 }
10029 return stored.to_vec();
10030 }
10031 #[cfg(feature = "perf-counters")]
10032 match outcomes.len() {
10033 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
10034 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
10035 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
10036 }
10037 if inline_pending {
10038 return outcomes.into_iter().map(apply_inline_pending).collect();
10039 }
10040 outcomes
10041 }
10042
10043 fn single_token_deletion_recovery(
10046 &mut self,
10047 recovery: RecoveryRequest<'_, '_>,
10048 ) -> Vec<RecognizeOutcome> {
10049 let RecoveryRequest {
10050 atn,
10051 transition,
10052 expected_symbols,
10053 target,
10054 request,
10055 visiting,
10056 memo,
10057 expected,
10058 } = recovery;
10059 let RecognizeRequest {
10060 stop_state,
10061 index,
10062 rule_start_index,
10063 decision_start_index,
10064 init_action_rules,
10065 predicates,
10066 semantics,
10067 rule_args,
10068 member_actions,
10069 return_actions,
10070 local_int_arg,
10071 member_values,
10072 return_values,
10073 rule_alt_number,
10074 track_alt_numbers,
10075 consumed_eof,
10076 precedence,
10077 depth,
10078 ..
10079 } = request;
10080 let Some((diagnostic, next_index, next_symbol)) =
10081 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
10082 else {
10083 return Vec::new();
10084 };
10085 let after_next = self.consume_index(next_index, next_symbol);
10086 self.recognize_state(
10087 atn,
10088 RecognizeRequest {
10089 state_number: target,
10090 stop_state,
10091 index: after_next,
10092 rule_start_index,
10093 decision_start_index,
10094 init_action_rules,
10095 predicates,
10096 semantics,
10097 rule_args,
10098 member_actions,
10099 return_actions,
10100 local_int_arg,
10101 member_values,
10102 return_values,
10103 rule_alt_number,
10104 track_alt_numbers,
10105 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
10106 committed_decision: false,
10107 precedence,
10108 depth: depth + 1,
10109 recovery_symbols: BTreeSet::new(),
10110 recovery_state: None,
10111 },
10112 visiting,
10113 memo,
10114 expected,
10115 )
10116 .into_iter()
10117 .map(|mut outcome| {
10118 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
10119 outcome.diagnostics = self
10120 .recognition_arena
10121 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10122 let token = self.arena_token_node(next_index, false);
10123 self.arena_prepend(&mut outcome.nodes, token);
10124 let error = self.arena_token_node(index, true);
10125 self.arena_prepend(&mut outcome.nodes, error);
10126 outcome
10127 })
10128 .collect()
10129 }
10130
10131 fn current_token_deletion_recovery(
10134 &mut self,
10135 recovery: CurrentTokenDeletionRequest<'_, '_>,
10136 ) -> Vec<RecognizeOutcome> {
10137 let CurrentTokenDeletionRequest {
10138 atn,
10139 expected_symbols,
10140 mut request,
10141 visiting,
10142 memo,
10143 expected,
10144 } = recovery;
10145 let error_index = request.index;
10146 if error_index == request.rule_start_index {
10147 return Vec::new();
10148 }
10149 let Some((diagnostic, next_index, skipped)) =
10150 self.current_token_deletion(error_index, &expected_symbols)
10151 else {
10152 return Vec::new();
10153 };
10154 request.state_number = request.recovery_state.unwrap_or(request.state_number);
10155 request.index = next_index;
10156 request.committed_decision = false;
10157 request.depth += 1;
10158 request.recovery_state = None;
10159 self.recognize_state(atn, request, visiting, memo, expected)
10160 .into_iter()
10161 .map(|mut outcome| {
10162 outcome.diagnostics = self
10163 .recognition_arena
10164 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10165 for index in skipped.iter().rev() {
10166 let error = self.arena_token_node(*index, true);
10167 self.arena_prepend(&mut outcome.nodes, error);
10168 }
10169 outcome
10170 })
10171 .collect()
10172 }
10173
10174 fn consuming_failure_fallback(
10177 &mut self,
10178 fallback: ConsumingFailureFallback<'_>,
10179 visiting: &mut BTreeSet<RecognizeKey>,
10180 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10181 expected: &mut ExpectedTokens,
10182 ) -> Vec<RecognizeOutcome> {
10183 if fallback.expected_symbols.is_empty() {
10184 return Vec::new();
10185 }
10186 if fallback.symbol == TOKEN_EOF {
10187 return self.eof_consuming_failure_fallback(fallback, expected);
10188 }
10189 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
10190 }
10191
10192 fn non_eof_consuming_failure_fallback(
10195 &mut self,
10196 fallback: ConsumingFailureFallback<'_>,
10197 visiting: &mut BTreeSet<RecognizeKey>,
10198 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10199 expected: &mut ExpectedTokens,
10200 ) -> Vec<RecognizeOutcome> {
10201 let ConsumingFailureFallback {
10202 atn,
10203 target,
10204 request,
10205 symbol,
10206 expected_symbols,
10207 decision_start_index,
10208 decision,
10209 } = fallback;
10210 let error_index = request.index;
10211 let diagnostic =
10212 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
10213 let next_index = self.consume_index(error_index, symbol);
10214 self.recognize_state(
10215 atn,
10216 RecognizeRequest {
10217 state_number: target,
10218 stop_state: request.stop_state,
10219 index: next_index,
10220 rule_start_index: request.rule_start_index,
10221 decision_start_index,
10222 init_action_rules: request.init_action_rules,
10223 predicates: request.predicates,
10224 semantics: request.semantics,
10225 rule_args: request.rule_args,
10226 member_actions: request.member_actions,
10227 return_actions: request.return_actions,
10228 local_int_arg: request.local_int_arg,
10229 member_values: request.member_values,
10230 return_values: request.return_values,
10231 rule_alt_number: request.rule_alt_number,
10232 track_alt_numbers: request.track_alt_numbers,
10233 consumed_eof: request.consumed_eof,
10234 committed_decision: false,
10235 precedence: request.precedence,
10236 depth: request.depth + 1,
10237 recovery_symbols: BTreeSet::new(),
10238 recovery_state: None,
10239 },
10240 visiting,
10241 memo,
10242 expected,
10243 )
10244 .into_iter()
10245 .map(|mut outcome| {
10246 prepend_decision(&mut outcome, decision);
10247 outcome.diagnostics = self
10248 .recognition_arena
10249 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10250 let error = self.arena_token_node(error_index, true);
10251 self.arena_prepend(&mut outcome.nodes, error);
10252 outcome
10253 })
10254 .collect()
10255 }
10256
10257 fn eof_consuming_failure_fallback(
10260 &mut self,
10261 fallback: ConsumingFailureFallback<'_>,
10262 expected: &ExpectedTokens,
10263 ) -> Vec<RecognizeOutcome> {
10264 let request = fallback.request;
10265 if request.index == request.rule_start_index {
10266 return Vec::new();
10267 }
10268 let diagnostic =
10269 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
10270 let diagnostics = self
10271 .recognition_arena
10272 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10273 vec![RecognizeOutcome {
10274 index: request.index,
10275 consumed_eof: request.consumed_eof,
10276 alt_number: request.rule_alt_number,
10277 member_values: request.member_values,
10278 return_values: request.return_values,
10279 diagnostics,
10280 decisions: Vec::new(),
10281 actions: Vec::new(),
10282 nodes: NodeSeqId::EMPTY,
10283 }]
10284 }
10285
10286 fn single_token_insertion_recovery(
10289 &mut self,
10290 recovery: RecoveryRequest<'_, '_>,
10291 ) -> Vec<RecognizeOutcome> {
10292 let RecoveryRequest {
10293 atn,
10294 transition,
10295 expected_symbols,
10296 target,
10297 request,
10298 visiting,
10299 memo,
10300 expected,
10301 } = recovery;
10302 let RecognizeRequest {
10303 stop_state,
10304 index,
10305 rule_start_index,
10306 decision_start_index,
10307 init_action_rules,
10308 predicates,
10309 semantics,
10310 rule_args,
10311 member_actions,
10312 return_actions,
10313 local_int_arg,
10314 member_values,
10315 return_values,
10316 rule_alt_number,
10317 track_alt_numbers,
10318 consumed_eof,
10319 precedence,
10320 depth,
10321 ..
10322 } = request;
10323 let follow_symbols = state_expected_symbols(atn, transition.target());
10324 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
10325 transition,
10326 index,
10327 atn.max_token_type(),
10328 &expected_symbols,
10329 &follow_symbols,
10330 ) else {
10331 return Vec::new();
10332 };
10333 self.recognize_state(
10334 atn,
10335 RecognizeRequest {
10336 state_number: target,
10337 stop_state,
10338 index,
10339 rule_start_index,
10340 decision_start_index,
10341 init_action_rules,
10342 predicates,
10343 semantics,
10344 rule_args,
10345 member_actions,
10346 return_actions,
10347 local_int_arg,
10348 member_values,
10349 return_values,
10350 rule_alt_number,
10351 track_alt_numbers,
10352 consumed_eof,
10353 committed_decision: false,
10354 precedence,
10355 depth: depth + 1,
10356 recovery_symbols: BTreeSet::new(),
10357 recovery_state: None,
10358 },
10359 visiting,
10360 memo,
10361 expected,
10362 )
10363 .into_iter()
10364 .map(|mut outcome| {
10365 outcome.diagnostics = self
10366 .recognition_arena
10367 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10368 let missing = self.arena_missing_token_node(token_type, index, text.clone());
10369 self.arena_prepend(&mut outcome.nodes, missing);
10370 outcome
10371 })
10372 .collect()
10373 }
10374
10375 #[allow(clippy::too_many_lines)]
10378 fn recognize_state(
10379 &mut self,
10380 atn: &Atn,
10381 request: RecognizeRequest<'_>,
10382 visiting: &mut BTreeSet<RecognizeKey>,
10383 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10384 expected: &mut ExpectedTokens,
10385 ) -> Vec<RecognizeOutcome> {
10386 let request_template = request.clone();
10387 let RecognizeRequest {
10388 state_number,
10389 stop_state,
10390 index,
10391 rule_start_index,
10392 decision_start_index,
10393 init_action_rules,
10394 predicates,
10395 semantics,
10396 rule_args,
10397 member_actions,
10398 return_actions,
10399 local_int_arg,
10400 member_values,
10401 return_values,
10402 rule_alt_number,
10403 track_alt_numbers,
10404 consumed_eof,
10405 committed_decision,
10406 precedence,
10407 depth,
10408 recovery_symbols,
10409 recovery_state,
10410 } = request;
10411 if depth > RECOGNITION_DEPTH_LIMIT {
10412 return Vec::new();
10413 }
10414 if state_number == stop_state {
10415 return stop_outcome(
10416 index,
10417 consumed_eof,
10418 rule_alt_number,
10419 member_values,
10420 return_values,
10421 );
10422 }
10423 let key = RecognizeKey {
10424 state_number,
10425 stop_state,
10426 index,
10427 rule_start_index,
10428 decision_start_index,
10429 local_int_arg,
10430 member_values: member_values.clone(),
10431 return_values: return_values.clone(),
10432 rule_alt_number,
10433 track_alt_numbers,
10434 consumed_eof,
10435 committed_decision,
10436 precedence,
10437 recovery_symbols: recovery_symbols.clone(),
10438 recovery_state,
10439 };
10440 if let Some(outcomes) = memo.get(&key) {
10441 return outcomes.clone();
10442 }
10443
10444 let visit_key = key.clone();
10445 if !visiting.insert(visit_key.clone()) {
10446 return Vec::new();
10447 }
10448
10449 let Some(state) = atn.state(state_number) else {
10450 visiting.remove(&visit_key);
10451 return Vec::new();
10452 };
10453 let decision_override_generation = self.decision_override_generation;
10454 let transitions = state.transitions();
10455 let transition_count = transitions.len();
10456 let overridden_transition = if transition_count > 1
10457 && self.semantic_hooks.observes_parser_decisions()
10458 {
10459 atn.decision_to_state()
10460 .iter()
10461 .position(|candidate| candidate == state_number)
10462 .and_then(|decision| {
10463 self.semantic_hooks
10464 .parser_decision_override(decision, index, transition_count)
10465 })
10466 .and_then(|alternative| alternative.checked_sub(1))
10467 .filter(|alternative| *alternative < transition_count)
10468 } else {
10469 None
10470 };
10471 if overridden_transition.is_some() {
10472 self.decision_override_generation = self.decision_override_generation.wrapping_add(1);
10473 }
10474 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
10475 Some(index)
10476 } else {
10477 decision_start_index
10478 };
10479 let (epsilon_recovery_symbols, epsilon_recovery_state) =
10480 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
10481 let mut outcomes = Vec::new();
10482 for (transition_index, transition) in transitions.iter().enumerate() {
10483 if overridden_transition.is_some_and(|forced| forced != transition_index) {
10484 continue;
10485 }
10486 let transition_committed =
10487 committed_decision || overridden_transition == Some(transition_index);
10488 let mut transition_request = request_template.clone();
10489 transition_request.committed_decision = transition_committed;
10490 let decision =
10491 transition_decision(atn, state, transition_count, transition_index, predicates);
10492 let next_alt_number = next_alt_number(
10493 state,
10494 transition_count,
10495 transition_index,
10496 rule_alt_number,
10497 track_alt_numbers,
10498 );
10499 let transition_data = transition.data();
10500 match &transition_data {
10501 Transition::Epsilon { target } | Transition::Action { target, .. } => {
10502 let (action_rule_index, action_index) = match &transition_data {
10503 Transition::Action {
10504 rule_index,
10505 action_index,
10506 ..
10507 } => (Some(*rule_index), *action_index),
10508 _ => (None, None),
10509 };
10510 outcomes.extend(self.recognize_epsilon_or_action_step(
10511 atn,
10512 &transition_request,
10513 EpsilonActionStep {
10514 source_state: state_number,
10515 target: *target,
10516 action_rule_index,
10517 action_index,
10518 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
10519 decision,
10520 decision_start_index: next_decision_start_index,
10521 alt_number: next_alt_number,
10522 recovery_symbols: epsilon_recovery_symbols.clone(),
10523 recovery_state: epsilon_recovery_state,
10524 },
10525 RecognizeScratch {
10526 visiting,
10527 memo,
10528 expected,
10529 },
10530 ));
10531 }
10532 Transition::Predicate {
10533 target,
10534 rule_index,
10535 pred_index,
10536 ..
10537 } => {
10538 let predicate = PredicateEval {
10539 index,
10540 rule_index: *rule_index,
10541 pred_index: *pred_index,
10542 predicates,
10543 semantics,
10544 context: None,
10545 local_int_arg,
10546 member_values: &member_values,
10547 };
10548 if self.parser_predicate_matches(predicate) {
10549 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
10550 outcomes.extend(
10551 self.recognize_state(
10552 atn,
10553 RecognizeRequest {
10554 state_number: *target,
10555 stop_state,
10556 index,
10557 rule_start_index,
10558 decision_start_index: next_decision_start_index,
10559 init_action_rules,
10560 predicates,
10561 semantics,
10562 rule_args,
10563 member_actions,
10564 return_actions,
10565 local_int_arg,
10566 member_values: member_values.clone(),
10567 return_values: return_values.clone(),
10568 rule_alt_number: next_alt_number,
10569 track_alt_numbers,
10570 consumed_eof,
10571 committed_decision: transition_committed,
10572 precedence,
10573 depth: depth + 1,
10574 recovery_symbols: epsilon_recovery_symbols.clone(),
10575 recovery_state: epsilon_recovery_state,
10576 },
10577 visiting,
10578 memo,
10579 expected,
10580 )
10581 .into_iter()
10582 .map(|mut outcome| {
10583 prepend_decision(&mut outcome, decision);
10584 if let Some(rule_index) = left_recursive_boundary {
10585 let boundary =
10586 self.arena_boundary_node(rule_index, next_alt_number);
10587 self.arena_prepend(&mut outcome.nodes, boundary);
10588 }
10589 outcome
10590 }),
10591 );
10592 } else if let Some(message) = semantics
10593 .and_then(|semantics| {
10594 self.parser_semantic_ir_predicate_failure_message(
10595 *rule_index,
10596 *pred_index,
10597 semantics,
10598 )
10599 })
10600 .or_else(|| {
10601 self.parser_predicate_failure_message(
10602 *rule_index,
10603 *pred_index,
10604 predicates,
10605 )
10606 })
10607 {
10608 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
10609 rule_index: *rule_index,
10610 index,
10611 message,
10612 member_values: member_values.clone(),
10613 return_values: return_values.clone(),
10614 rule_alt_number,
10615 }));
10616 } else {
10617 record_predicate_no_viable(expected, next_decision_start_index, index);
10618 }
10619 }
10620 Transition::Precedence {
10621 target,
10622 precedence: transition_precedence,
10623 } => {
10624 if *transition_precedence >= precedence {
10625 outcomes.extend(
10626 self.recognize_state(
10627 atn,
10628 RecognizeRequest {
10629 state_number: *target,
10630 stop_state,
10631 index,
10632 rule_start_index,
10633 decision_start_index: next_decision_start_index,
10634 init_action_rules,
10635 predicates,
10636 semantics,
10637 rule_args,
10638 member_actions,
10639 return_actions,
10640 local_int_arg,
10641 member_values: member_values.clone(),
10642 return_values: return_values.clone(),
10643 rule_alt_number: next_alt_number,
10644 track_alt_numbers,
10645 consumed_eof,
10646 committed_decision: transition_committed,
10647 precedence,
10648 depth: depth + 1,
10649 recovery_symbols: epsilon_recovery_symbols.clone(),
10650 recovery_state: epsilon_recovery_state,
10651 },
10652 visiting,
10653 memo,
10654 expected,
10655 )
10656 .into_iter()
10657 .map(|mut outcome| {
10658 prepend_decision(&mut outcome, decision);
10659 outcome
10660 }),
10661 );
10662 }
10663 }
10664 Transition::Rule {
10665 target,
10666 rule_index,
10667 follow_state,
10668 precedence: rule_precedence,
10669 ..
10670 } => {
10671 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
10672 continue;
10673 };
10674 let child_local_int_arg =
10675 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
10676 let expected_before_child = expected.clone();
10677 let children = self.recognize_state(
10678 atn,
10679 RecognizeRequest {
10680 state_number: *target,
10681 stop_state: child_stop,
10682 index,
10683 rule_start_index: index,
10684 decision_start_index: None,
10685 init_action_rules,
10686 predicates,
10687 semantics,
10688 rule_args,
10689 member_actions,
10690 return_actions,
10691 local_int_arg: child_local_int_arg,
10692 member_values: member_values.clone(),
10693 return_values: BTreeMap::new(),
10694 rule_alt_number: 0,
10695 track_alt_numbers,
10696 consumed_eof: false,
10697 committed_decision: transition_committed,
10698 precedence: *rule_precedence,
10699 depth: depth + 1,
10700 recovery_symbols: epsilon_recovery_symbols.clone(),
10701 recovery_state: epsilon_recovery_state,
10702 },
10703 visiting,
10704 memo,
10705 expected,
10706 );
10707 let children = if children.is_empty() {
10708 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
10709 atn,
10710 rule_index: *rule_index,
10711 start_index: index,
10712 follow_state: *follow_state,
10713 stop_state,
10714 member_values: member_values.clone(),
10715 expected,
10716 })
10717 } else {
10718 children
10719 };
10720 let preserve_child_expected =
10721 self.child_expected_reaches_clean_eof(&children, expected);
10722 restore_expected(
10723 &children,
10724 index,
10725 expected,
10726 expected_before_child,
10727 preserve_child_expected,
10728 );
10729 for child in children {
10730 let child_stop_index =
10731 self.rule_stop_token_index(child.index, child.consumed_eof);
10732 let child_nodes = self
10733 .recognition_arena
10734 .fold_left_recursive_boundaries(child.nodes);
10735 let child_node = self.arena_rule_node(ArenaRuleSpec {
10736 rule_index: *rule_index,
10737 invoking_state: invoking_state_number(state_number),
10738 alt_number: child.alt_number,
10739 start_index: index,
10740 stop_index: child_stop_index,
10741 return_values: child.return_values.clone(),
10742 children: child_nodes,
10743 });
10744 outcomes.extend(
10745 self.recognize_state(
10746 atn,
10747 RecognizeRequest {
10748 state_number: *follow_state,
10749 stop_state,
10750 index: child.index,
10751 rule_start_index,
10752 decision_start_index: next_decision_start_index,
10753 init_action_rules,
10754 predicates,
10755 semantics,
10756 rule_args,
10757 member_actions,
10758 return_actions,
10759 local_int_arg,
10760 member_values: child.member_values.clone(),
10761 return_values: return_values.clone(),
10762 rule_alt_number,
10763 track_alt_numbers,
10764 consumed_eof: consumed_eof || child.consumed_eof,
10765 committed_decision: transition_committed
10766 && child.index == index,
10767 precedence,
10768 depth: depth + 1,
10769 recovery_symbols: BTreeSet::new(),
10770 recovery_state: None,
10771 },
10772 visiting,
10773 memo,
10774 expected,
10775 )
10776 .into_iter()
10777 .map(|mut outcome| {
10778 outcome.consumed_eof |= child.consumed_eof;
10779 outcome.diagnostics = self
10780 .recognition_arena
10781 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
10782 let mut decisions = child.decisions.clone();
10783 decisions.append(&mut outcome.decisions);
10784 outcome.decisions = decisions;
10785 prepend_decision(&mut outcome, decision);
10786 let mut actions = child.actions.clone();
10787 if init_action_rules.contains(rule_index) {
10788 actions.insert(
10789 0,
10790 ParserAction::new_rule_init(
10791 *rule_index,
10792 index,
10793 Some(*follow_state),
10794 ),
10795 );
10796 }
10797 actions.append(&mut outcome.actions);
10798 outcome.actions = actions;
10799 self.arena_prepend(&mut outcome.nodes, child_node);
10800 outcome
10801 }),
10802 );
10803 }
10804 }
10805 Transition::Atom { target, .. }
10806 | Transition::Range { target, .. }
10807 | Transition::Set { target, .. }
10808 | Transition::NotSet { target, .. }
10809 | Transition::Wildcard { target, .. } => {
10810 let symbol = self.token_type_at(index);
10811 if transition_data.matches(symbol, 1, atn.max_token_type()) {
10812 let next_index = self.consume_index(index, symbol);
10813 outcomes.extend(
10814 self.recognize_state(
10815 atn,
10816 RecognizeRequest {
10817 state_number: *target,
10818 stop_state,
10819 index: next_index,
10820 rule_start_index,
10821 decision_start_index: next_decision_start_index,
10822 init_action_rules,
10823 predicates,
10824 semantics,
10825 rule_args,
10826 member_actions,
10827 return_actions,
10828 local_int_arg,
10829 member_values: member_values.clone(),
10830 return_values: return_values.clone(),
10831 rule_alt_number: next_alt_number,
10832 track_alt_numbers,
10833 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
10834 committed_decision: false,
10835 precedence,
10836 depth: depth + 1,
10837 recovery_symbols: BTreeSet::new(),
10838 recovery_state: None,
10839 },
10840 visiting,
10841 memo,
10842 expected,
10843 )
10844 .into_iter()
10845 .map(|mut outcome| {
10846 prepend_decision(&mut outcome, decision);
10847 outcome.consumed_eof |= symbol == TOKEN_EOF;
10848 let token = self.arena_token_node(index, false);
10849 self.arena_prepend(&mut outcome.nodes, token);
10850 outcome
10851 }),
10852 );
10853 } else {
10854 let expected_symbols =
10855 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
10856 if expected_symbols.contains(&symbol) && !transition_committed {
10857 continue;
10858 }
10859 expected.record_transition(index, transition, atn.max_token_type());
10860 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
10861 let before_recovery = outcomes.len();
10862 let recovery_request = transition_request.clone();
10863 if transition_committed {
10864 outcomes.extend(self.consuming_failure_fallback(
10865 ConsumingFailureFallback {
10866 atn,
10867 target: *target,
10868 request: recovery_request,
10869 symbol,
10870 expected_symbols,
10871 decision_start_index: next_decision_start_index,
10872 decision,
10873 },
10874 visiting,
10875 memo,
10876 expected,
10877 ));
10878 break;
10879 }
10880 outcomes.extend(
10881 self.single_token_deletion_recovery(RecoveryRequest {
10882 atn,
10883 transition,
10884 expected_symbols: expected_symbols.clone(),
10885 target: *target,
10886 request: recovery_request.clone(),
10887 visiting,
10888 memo,
10889 expected,
10890 })
10891 .into_iter()
10892 .map(|mut outcome| {
10893 prepend_decision(&mut outcome, decision);
10894 outcome
10895 }),
10896 );
10897 if !state_is_left_recursive_rule(atn, state) {
10898 outcomes.extend(
10899 self.single_token_insertion_recovery(RecoveryRequest {
10900 atn,
10901 transition,
10902 expected_symbols: expected_symbols.clone(),
10903 target: *target,
10904 request: recovery_request.clone(),
10905 visiting,
10906 memo,
10907 expected,
10908 })
10909 .into_iter()
10910 .map(|mut outcome| {
10911 prepend_decision(&mut outcome, decision);
10912 outcome
10913 }),
10914 );
10915 }
10916 outcomes.extend(self.current_token_deletion_recovery(
10917 CurrentTokenDeletionRequest {
10918 atn,
10919 expected_symbols: expected_symbols.clone(),
10920 request: recovery_request.clone(),
10921 visiting,
10922 memo,
10923 expected,
10924 },
10925 ));
10926 if outcomes.len() == before_recovery {
10927 outcomes.extend(self.consuming_failure_fallback(
10928 ConsumingFailureFallback {
10929 atn,
10930 target: *target,
10931 request: recovery_request,
10932 symbol,
10933 expected_symbols,
10934 decision_start_index: next_decision_start_index,
10935 decision,
10936 },
10937 visiting,
10938 memo,
10939 expected,
10940 ));
10941 }
10942 }
10943 }
10944 }
10945 if self.decision_override_generation != decision_override_generation {
10946 break;
10947 }
10948 }
10949
10950 visiting.remove(&visit_key);
10951 self.record_prediction_diagnostics(atn, state, index, &outcomes);
10952 if matches!(
10953 self.prediction_mode,
10954 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
10955 ) {
10956 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
10957 }
10958 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
10959 memo.insert(key, outcomes.clone());
10960 outcomes
10961 }
10962
10963 fn recognize_epsilon_or_action_step(
10966 &mut self,
10967 atn: &Atn,
10968 request: &RecognizeRequest<'_>,
10969 step: EpsilonActionStep,
10970 scratch: RecognizeScratch<'_>,
10971 ) -> Vec<RecognizeOutcome> {
10972 let RecognizeScratch {
10973 visiting,
10974 memo,
10975 expected,
10976 } = scratch;
10977 let action = step.action_rule_index.map(|rule_index| {
10978 let stop_index = self.rule_stop_token_index(request.index, request.consumed_eof);
10979 step.action_index.map_or_else(
10980 || {
10981 ParserAction::new(
10982 step.source_state,
10983 rule_index,
10984 request.rule_start_index,
10985 stop_index,
10986 )
10987 },
10988 |action_index| {
10989 ParserAction::new_indexed(
10990 step.source_state,
10991 rule_index,
10992 action_index,
10993 request.rule_start_index,
10994 stop_index,
10995 )
10996 },
10997 )
10998 });
10999 let next_member_values = if action.is_some() {
11000 member_values_after_action(
11001 step.source_state,
11002 request.member_actions,
11003 request.semantics,
11004 &request.member_values,
11005 )
11006 } else {
11007 request.member_values.clone()
11008 };
11009 let next_return_values = action.map_or_else(
11010 || request.return_values.clone(),
11011 |action| {
11012 return_values_after_action(
11013 step.source_state,
11014 action.rule_index(),
11015 request.return_actions,
11016 request.semantics,
11017 &request.return_values,
11018 )
11019 },
11020 );
11021
11022 self.recognize_state(
11023 atn,
11024 RecognizeRequest {
11025 state_number: step.target,
11026 stop_state: request.stop_state,
11027 index: request.index,
11028 rule_start_index: request.rule_start_index,
11029 decision_start_index: step.decision_start_index,
11030 init_action_rules: request.init_action_rules,
11031 predicates: request.predicates,
11032 semantics: request.semantics,
11033 rule_args: request.rule_args,
11034 member_actions: request.member_actions,
11035 return_actions: request.return_actions,
11036 local_int_arg: request.local_int_arg,
11037 member_values: next_member_values,
11038 return_values: next_return_values,
11039 rule_alt_number: if step.left_recursive_boundary.is_some() {
11040 0
11041 } else {
11042 step.alt_number
11043 },
11044 track_alt_numbers: request.track_alt_numbers,
11045 consumed_eof: request.consumed_eof,
11046 committed_decision: request.committed_decision,
11047 precedence: request.precedence,
11048 depth: request.depth + 1,
11049 recovery_symbols: step.recovery_symbols,
11050 recovery_state: step.recovery_state,
11051 },
11052 visiting,
11053 memo,
11054 expected,
11055 )
11056 .into_iter()
11057 .map(|mut outcome| {
11058 prepend_decision(&mut outcome, step.decision);
11059 if let Some(rule_index) = step.left_recursive_boundary {
11060 let boundary = self.arena_boundary_node(rule_index, step.alt_number);
11061 self.arena_prepend(&mut outcome.nodes, boundary);
11062 }
11063 if let Some(action) = action {
11064 outcome.actions.insert(0, action);
11065 }
11066 outcome
11067 })
11068 .collect()
11069 }
11070
11071 fn token_type_at(&mut self, index: usize) -> i32 {
11076 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
11077 self.input.fill();
11078 }
11079 self.input.token_type_at_index(index)
11080 }
11081
11082 fn cached_state_expected_symbols(
11094 &mut self,
11095 atn: &Atn,
11096 state_number: usize,
11097 ) -> Rc<BTreeSet<i32>> {
11098 if let Some(cached) = self.state_expected_cache.get(&state_number) {
11099 return Rc::clone(cached);
11100 }
11101 let symbols = state_expected_symbols(atn, state_number);
11102 let entry = self.intern_recovery_symbols(symbols);
11103 self.state_expected_cache
11104 .insert(state_number, Rc::clone(&entry));
11105 entry
11106 }
11107
11108 fn cached_state_expected_token_set(
11109 &mut self,
11110 atn: &Atn,
11111 state_number: usize,
11112 ) -> Rc<TokenBitSet> {
11113 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
11114 return Rc::clone(cached);
11115 }
11116 let symbols = with_shared_atn_caches(atn, |cache| {
11120 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
11121 return Rc::clone(cached);
11122 }
11123 let symbols = Rc::new(state_expected_token_set(atn, state_number));
11124 cache
11125 .state_expected_tokens
11126 .insert(state_number, Rc::clone(&symbols));
11127 symbols
11128 });
11129 self.state_expected_token_cache
11130 .insert(state_number, Rc::clone(&symbols));
11131 symbols
11132 }
11133
11134 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
11135 if self.rule_stop_reach_cache.len() <= state_number {
11136 self.rule_stop_reach_cache
11137 .resize_with(atn.states().len().max(state_number + 1), || None);
11138 }
11139 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
11140 return reaches;
11141 }
11142 let reaches = with_shared_atn_caches(atn, |cache| {
11143 *cache
11144 .rule_stop_reach
11145 .entry(state_number)
11146 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
11147 });
11148 self.rule_stop_reach_cache[state_number] = Some(reaches);
11149 reaches
11150 }
11151
11152 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
11155 Rc::clone(&self.empty_recovery_symbols)
11156 }
11157
11158 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
11167 if set.is_empty() {
11168 return Rc::clone(&self.empty_recovery_symbols);
11169 }
11170 let candidate = Rc::new(set);
11171 match self.recovery_symbols_intern.get(&candidate) {
11172 Some(existing) => Rc::clone(existing),
11173 None => {
11174 self.recovery_symbols_intern
11175 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
11176 candidate
11177 }
11178 }
11179 }
11180
11181 fn cached_decision_lookahead(
11186 &mut self,
11187 atn: &Atn,
11188 state: AtnState<'_>,
11189 rule_stop_state: usize,
11190 ) -> Rc<DecisionLookahead> {
11191 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
11198 return Rc::clone(cached);
11199 }
11200 let entry = with_shared_atn_caches(atn, |cache| {
11201 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
11202 return Rc::clone(cached);
11203 }
11204 let mut entry = DecisionLookahead {
11205 transitions: Vec::with_capacity(state.transitions().len()),
11206 };
11207 for transition in &state.transitions() {
11208 entry.transitions.push(transition_first_set(
11209 atn,
11210 transition,
11211 rule_stop_state,
11212 &mut cache.first_set,
11213 ));
11214 }
11215 let entry = Rc::new(entry);
11216 cache
11217 .decision_lookahead
11218 .insert(state.state_number(), Rc::clone(&entry));
11219 entry
11220 });
11221 self.decision_lookahead_cache
11222 .insert(state.state_number(), Rc::clone(&entry));
11223 entry
11224 }
11225
11226 fn cached_rule_first_set(
11227 &mut self,
11228 atn: &Atn,
11229 target: usize,
11230 child_stop: usize,
11231 ) -> Rc<FirstSet> {
11232 if self.rule_first_set_cache.len() <= target {
11233 self.rule_first_set_cache
11234 .resize_with(atn.states().len().max(target + 1), || None);
11235 }
11236 if let Some(cached) = self
11237 .rule_first_set_cache
11238 .get(target)
11239 .and_then(Option::as_ref)
11240 {
11241 return Rc::clone(cached);
11242 }
11243 let first = with_shared_first_set_cache(atn, |cache| {
11244 rule_first_set(atn, target, child_stop, cache)
11245 });
11246 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
11247 first
11248 }
11249
11250 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
11251 let atn_key = SharedAtnCacheKey::for_atn(atn);
11252 if self.empty_cycle_cache_atn != Some(atn_key) {
11253 self.empty_cycle_cache.clear();
11254 self.empty_cycle_cache_atn = Some(atn_key);
11255 }
11256 if self.empty_cycle_cache.len() <= state_number {
11257 self.empty_cycle_cache
11258 .resize_with(atn.state_count().max(state_number + 1), || None);
11259 }
11260 if let Some(cached) = self.empty_cycle_cache[state_number] {
11261 return cached;
11262 }
11263 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
11264 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
11265 self.empty_cycle_cache[state_number] = Some(result);
11266 result
11267 }
11268
11269 fn empty_path_reaches_state(
11270 &mut self,
11271 atn: &Atn,
11272 state_number: usize,
11273 target_state: usize,
11274 visited: &mut FxHashSet<usize>,
11275 ) -> bool {
11276 enum Work {
11277 Visit(usize),
11278 RuleFollow {
11279 target: usize,
11280 rule_index: usize,
11281 follow_state: usize,
11282 },
11283 }
11284
11285 let mut work = vec![Work::Visit(state_number)];
11286 while let Some(item) = work.pop() {
11287 match item {
11288 Work::Visit(state_number) => {
11289 if !visited.insert(state_number) {
11290 continue;
11291 }
11292 let Some(state) = atn.state(state_number) else {
11293 continue;
11294 };
11295 let transitions = state.transitions();
11296 for transition_index in (0..transitions.len()).rev() {
11297 let transition = transitions
11298 .get(transition_index)
11299 .expect("in-bounds parser transition");
11300 let kind = transition.kind();
11301 let target = transition.target();
11302 match kind {
11303 ParserTransitionKind::Atom
11304 | ParserTransitionKind::Range
11305 | ParserTransitionKind::Set
11306 | ParserTransitionKind::NotSet
11307 | ParserTransitionKind::Wildcard => {}
11308 ParserTransitionKind::Rule => {
11309 if target == target_state {
11310 return true;
11311 }
11312 work.push(Work::RuleFollow {
11313 target,
11314 rule_index: transition.arg0() as usize,
11315 follow_state: transition.arg1() as usize,
11316 });
11317 work.push(Work::Visit(target));
11318 }
11319 ParserTransitionKind::Epsilon
11320 | ParserTransitionKind::Predicate
11321 | ParserTransitionKind::Action
11322 | ParserTransitionKind::Precedence => {
11323 if target == target_state {
11324 return true;
11325 }
11326 work.push(Work::Visit(target));
11327 }
11328 }
11329 }
11330 }
11331 Work::RuleFollow {
11332 target,
11333 rule_index,
11334 follow_state,
11335 } => {
11336 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
11337 continue;
11338 };
11339 if self.cached_rule_first_set(atn, target, child_stop).nullable {
11340 if follow_state == target_state {
11341 return true;
11342 }
11343 work.push(Work::Visit(follow_state));
11344 }
11345 }
11346 }
11347 }
11348 false
11349 }
11350
11351 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
11354 match self.clean_memo_mode {
11355 CleanMemoMode::Promote => true,
11356 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
11357 CleanMemoMode::Sparse => {
11358 self.clean_memo_sparse_samples += 1;
11359 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
11360 return false;
11361 }
11362 self.clean_memo_sparse_samples = 0;
11363 self.clean_memo_mode = CleanMemoMode::Probe;
11364 self.clean_memo_probe_samples = 0;
11365 self.clean_memo_probe_repeats = 0;
11366 self.clean_memo_probe_seen.clear();
11367 self.observe_clean_memo_probe(key)
11368 }
11369 }
11370 }
11371
11372 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
11373 self.clean_memo_probe_samples += 1;
11374 if !self.clean_memo_probe_seen.insert(key.clone()) {
11375 self.clean_memo_probe_repeats += 1;
11376 }
11377 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
11378 self.clean_memo_mode = CleanMemoMode::Promote;
11379 self.clean_memo_probe_seen.clear();
11380 return true;
11381 }
11382 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
11383 self.clean_memo_mode = CleanMemoMode::Sparse;
11384 self.clean_memo_sparse_samples = 0;
11385 self.clean_memo_probe_seen.clear();
11386 return false;
11387 }
11388 true
11389 }
11390
11391 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
11393 self.input.get(index)
11394 }
11395
11396 fn token_id_at(&self, index: usize) -> Option<TokenId> {
11398 self.input.get_id(index)
11399 }
11400
11401 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
11402 let token = self
11403 .token_id_at(index)
11404 .expect("recognized token index must exist in the token store");
11405 let node = if error {
11406 ArenaRecognizedNode::ErrorToken { token }
11407 } else {
11408 ArenaRecognizedNode::Token { token }
11409 };
11410 self.recognition_arena.push_node(node)
11411 }
11412
11413 fn arena_missing_token_node(
11414 &mut self,
11415 token_type: i32,
11416 at_index: usize,
11417 text: String,
11418 ) -> RecognizedNodeId {
11419 let extra = self
11420 .recognition_arena
11421 .push_extra(RecognitionExtra::MissingToken {
11422 token_type,
11423 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
11424 text,
11425 });
11426 self.recognition_arena
11427 .push_node(ArenaRecognizedNode::MissingToken { extra })
11428 }
11429
11430 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
11431 let ArenaRuleSpec {
11432 rule_index,
11433 invoking_state,
11434 alt_number,
11435 start_index,
11436 stop_index,
11437 return_values,
11438 children,
11439 } = spec;
11440 let return_values = (!return_values.is_empty()).then(|| {
11441 self.recognition_arena
11442 .push_extra(RecognitionExtra::ReturnValues(return_values))
11443 });
11444 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
11445 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11446 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
11447 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11448 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
11449 stop_index: stop_index
11450 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
11451 return_values,
11452 children,
11453 })
11454 }
11455
11456 fn arena_boundary_node(&mut self, rule_index: usize, alt_number: usize) -> RecognizedNodeId {
11457 self.recognition_arena
11458 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
11459 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11460 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11461 })
11462 }
11463
11464 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
11465 *sequence = self.recognition_arena.prepend(*sequence, node);
11466 }
11467
11468 #[allow(clippy::missing_const_for_fn)]
11471 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
11472 self.last_recognition_arena_root = root;
11473 self.last_recognition_arena_diagnostics = diagnostics;
11474 #[cfg(feature = "perf-counters")]
11475 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
11476 let stats = self.recognition_arena_stats();
11477 #[allow(clippy::print_stderr)]
11478 {
11479 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
11480 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
11481 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
11482 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
11483 eprintln!("perf recognition_links_total={}", stats.total_links);
11484 eprintln!("perf recognition_links_live={}", stats.live_links);
11485 eprintln!("perf recognition_links_dead={}", stats.dead_links);
11486 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
11487 eprintln!("perf recognition_extras_total={}", stats.total_extras);
11488 eprintln!("perf recognition_extras_live={}", stats.live_extras);
11489 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
11490 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
11491 }
11492 }
11493 }
11494
11495 fn reset_recognition_arena(&mut self) {
11496 self.recognition_arena.reset();
11497 self.last_recognition_arena_root = NodeSeqId::EMPTY;
11498 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
11499 }
11500
11501 fn current_visible_index(&mut self) -> usize {
11504 let index = self.input.index();
11505 self.input.seek(index);
11506 self.input.index()
11507 }
11508
11509 fn child_expected_reaches_clean_eof(
11512 &mut self,
11513 children: &[RecognizeOutcome],
11514 expected: &ExpectedTokens,
11515 ) -> bool {
11516 let Some(index) = expected.index else {
11517 return false;
11518 };
11519 self.token_type_at(index) == TOKEN_EOF
11520 && children
11521 .iter()
11522 .any(|child| child.diagnostics.is_empty() && child.index == index)
11523 }
11524
11525 fn previous_token_index(&self, index: usize) -> Option<usize> {
11532 self.input.previous_visible_token_index(index)
11533 }
11534
11535 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
11540 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
11541 Some(index)
11542 } else {
11543 self.previous_token_index(index)
11544 }
11545 }
11546
11547 #[must_use]
11564 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
11565 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
11566 self.rule_stop_token_index(current_index, consumed_eof)
11567 }
11568
11569 #[must_use]
11578 pub fn after_action_stop_index_for_tree(
11579 &mut self,
11580 tree: ParseTree,
11581 current_index: usize,
11582 ) -> Option<usize> {
11583 if let Some(stop) = self
11584 .node(tree)
11585 .as_rule()
11586 .and_then(crate::tree::RuleNodeView::stop_id)
11587 {
11588 return Some(stop.index());
11589 }
11590 self.after_action_stop_index(current_index)
11591 }
11592
11593 #[must_use]
11603 pub fn after_action_start_index_for_tree(
11604 &self,
11605 tree: ParseTree,
11606 fallback_index: usize,
11607 ) -> usize {
11608 if let Some(start) = self
11609 .node(tree)
11610 .as_rule()
11611 .and_then(crate::tree::RuleNodeView::start_id)
11612 {
11613 return start.index();
11614 }
11615 fallback_index
11616 }
11617
11618 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
11623 self.rule_stop_token_index(index, consumed_eof)
11624 .and_then(|token_index| self.token_id_at(token_index))
11625 }
11626
11627 fn predicate_failure_recovery(
11634 &mut self,
11635 request: PredicateFailureRecovery<'_>,
11636 ) -> RecognizeOutcome {
11637 let PredicateFailureRecovery {
11638 rule_index,
11639 index,
11640 message,
11641 member_values,
11642 return_values,
11643 rule_alt_number,
11644 } = request;
11645 let rule_name = self
11646 .rule_names()
11647 .get(rule_index)
11648 .map_or_else(|| rule_index.to_string(), Clone::clone);
11649 let diagnostic = diagnostic_for_token(
11650 self.token_at(index).as_ref(),
11651 format!("rule {rule_name} {message}"),
11652 );
11653 let mut reversed_nodes = NodeSeqId::EMPTY;
11654 let mut next_index = index;
11655 loop {
11656 let symbol = self.token_type_at(next_index);
11657 if symbol == TOKEN_EOF {
11658 break;
11659 }
11660 let error = self.arena_token_node(next_index, true);
11661 self.arena_prepend(&mut reversed_nodes, error);
11662 let after = self.consume_index(next_index, symbol);
11663 if after == next_index {
11664 break;
11665 }
11666 next_index = after;
11667 }
11668 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
11669 let diagnostics = self
11670 .recognition_arena
11671 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
11672 RecognizeOutcome {
11673 index: next_index,
11674 consumed_eof: false,
11675 alt_number: rule_alt_number,
11676 member_values,
11677 return_values,
11678 diagnostics,
11679 decisions: Vec::new(),
11680 actions: Vec::new(),
11681 nodes,
11682 }
11683 }
11684
11685 fn parser_semantic_hook_result(
11688 &mut self,
11689 request: ParserSemanticHookRequest<'_>,
11690 ) -> Option<bool> {
11691 let ParserSemanticHookRequest {
11692 index,
11693 rule_index,
11694 pred_index,
11695 context,
11696 local_int_arg,
11697 member_values,
11698 } = request;
11699 let rule_name = self.rule_names().get(rule_index).cloned();
11700 self.input.seek(index);
11701 let input = &mut self.input;
11702 let semantic_hooks = &mut self.semantic_hooks;
11703 let mut ctx = ParserSemCtx {
11704 input,
11705 tree_storage: &self.tree,
11706 rule_index,
11707 coordinate_index: pred_index,
11708 rule_name,
11709 context,
11710 tree: None,
11711 local_int_arg,
11712 member_values,
11713 action: None,
11714 };
11715 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
11716 }
11717
11718 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
11723 if prior.is_empty() {
11724 return;
11725 }
11726 let mut merged = prior;
11727 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
11728 if !merged.contains(&coordinate) {
11729 merged.push(coordinate);
11730 }
11731 }
11732 self.unknown_predicate_hits = merged;
11733 }
11734
11735 fn restore_prior_unhandled_action_hits(&mut self, prior: Vec<(usize, usize)>) {
11738 if prior.is_empty() {
11739 return;
11740 }
11741 let mut merged = prior;
11742 for coordinate in std::mem::take(&mut self.unhandled_action_hits) {
11743 if !merged.contains(&coordinate) {
11744 merged.push(coordinate);
11745 }
11746 }
11747 self.unhandled_action_hits = merged;
11748 }
11749
11750 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
11759 apply_unknown_predicate_policy(
11760 self.unknown_predicate_policy,
11761 rule_index,
11762 pred_index,
11763 &mut self.unknown_predicate_hits,
11764 )
11765 }
11766
11767 fn unknown_semantic_error(&self) -> Option<AntlrError> {
11770 use std::fmt::Write as _;
11771 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
11772 return None;
11773 }
11774 let mut message = String::new();
11775 for (rule_index, pred_index) in &self.unknown_predicate_hits {
11776 if !message.is_empty() {
11777 message.push_str("; ");
11778 }
11779 let _ = match self.rule_names().get(*rule_index) {
11780 Some(rule_name) => write!(
11781 message,
11782 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
11783 ),
11784 None => write!(
11785 message,
11786 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
11787 ),
11788 };
11789 }
11790 for (rule_index, source_state) in &self.unhandled_action_hits {
11791 if !message.is_empty() {
11792 message.push_str("; ");
11793 }
11794 let _ = match self.rule_names().get(*rule_index) {
11795 Some(rule_name) => write!(
11796 message,
11797 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
11798 ),
11799 None => write!(
11800 message,
11801 "unhandled semantic action: rule_index={rule_index} state={source_state}"
11802 ),
11803 };
11804 }
11805 Some(AntlrError::Unsupported(message))
11806 }
11807
11808 fn parser_semir_predicate_matches(
11816 &mut self,
11817 semantics: &ParserSemantics,
11818 predicate: &ParserSemanticPredicate,
11819 request: ParserSemanticHookRequest<'_>,
11820 ) -> bool {
11821 self.input.seek(request.index);
11822 let rule_name = self
11823 .data
11824 .rule_names()
11825 .get(request.rule_index)
11826 .map(String::as_str);
11827 let unknown_predicate_policy = self.unknown_predicate_policy;
11828 let mut ctx = ParserSemIrCtx {
11829 input: &mut self.input,
11830 tree_storage: &self.tree,
11831 semantic_hooks: &mut self.semantic_hooks,
11832 rule_index: request.rule_index,
11833 coordinate_index: request.pred_index,
11834 rule_name,
11835 context: request.context,
11836 local_int_arg: request.local_int_arg,
11837 member_values: request.member_values,
11838 invoked_predicates: &mut self.invoked_predicates,
11839 unknown_predicate_policy,
11840 unknown_predicate_hits: &mut self.unknown_predicate_hits,
11841 };
11842 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
11843 }
11844
11845 fn fast_parser_predicate_matches(
11846 &mut self,
11847 context: Option<FastPredicateContext<'_>>,
11848 transition: ParserTransition<'_>,
11849 index: usize,
11850 ) -> bool {
11851 let Some(context) = context else {
11852 return true;
11853 };
11854 let rule_index = transition.arg0() as usize;
11855 let pred_index = transition.arg1() as usize;
11856 let key = (index, rule_index, pred_index);
11857 if let Some(result) = self.fast_predicate_cache.get(&key) {
11858 return *result;
11859 }
11860 let result = self.parser_predicate_matches(PredicateEval {
11861 index,
11862 rule_index,
11863 pred_index,
11864 predicates: context.predicates,
11865 semantics: context.semantics,
11866 context: None,
11867 local_int_arg: None,
11868 member_values: context.member_values,
11869 });
11870 self.fast_predicate_cache.insert(key, result);
11871 result
11872 }
11873
11874 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
11875 let PredicateEval {
11876 index,
11877 rule_index,
11878 pred_index,
11879 predicates,
11880 semantics,
11881 context,
11882 local_int_arg,
11883 member_values,
11884 } = eval;
11885 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
11886 semantics
11887 .predicates
11888 .iter()
11889 .find(|predicate| {
11890 predicate.rule_index == rule_index && predicate.pred_index == pred_index
11891 })
11892 .map(|predicate| (semantics, predicate))
11893 }) {
11894 return self.parser_semir_predicate_matches(
11895 semantics,
11896 predicate,
11897 ParserSemanticHookRequest {
11898 index,
11899 rule_index,
11900 pred_index,
11901 context,
11902 local_int_arg,
11903 member_values,
11904 },
11905 );
11906 }
11907 let Some((_, _, predicate)) = predicates
11908 .iter()
11909 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
11910 else {
11911 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
11912 index,
11913 rule_index,
11914 pred_index,
11915 context,
11916 local_int_arg,
11917 member_values,
11918 }) {
11919 return result;
11920 }
11921 return self.unknown_predicate_result(rule_index, pred_index);
11922 };
11923 self.input.seek(index);
11924 match predicate {
11925 ParserPredicate::True => true,
11926 ParserPredicate::False => false,
11927 ParserPredicate::FalseWithMessage { .. } => false,
11928 ParserPredicate::Invoke { value } => {
11929 let key = (rule_index, pred_index);
11930 if !self.invoked_predicates.contains(&key) {
11931 self.invoked_predicates.push(key);
11932 use std::io::Write as _;
11933 let mut stdout = std::io::stdout().lock();
11934 let _ = writeln!(stdout, "eval={value}");
11935 }
11936 *value
11937 }
11938 ParserPredicate::LookaheadTextEquals { offset, text } => self
11939 .input
11940 .lt(*offset)
11941 .is_some_and(|token| Token::text(&token) == Some(*text)),
11942 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
11943 self.la(*offset) != *token_type
11944 }
11945 ParserPredicate::TokenPairAdjacent => {
11946 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
11947 return false;
11948 };
11949 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
11950 return false;
11951 };
11952 first + 1 == second
11953 }
11954 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
11955 .and_then(|context| {
11956 context
11957 .child_rules(&self.tree, self.input.token_store(), *rule_index)
11958 .next()
11959 .map(crate::tree::RuleNodeView::text)
11960 })
11961 .is_none_or(|actual| actual != *text),
11962 ParserPredicate::LocalIntEquals { value } => {
11963 local_int_arg.is_none_or(|(_, actual)| actual == *value)
11964 }
11965 ParserPredicate::LocalIntLessOrEqual { value } => {
11966 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
11967 }
11968 ParserPredicate::MemberModuloEquals {
11969 member,
11970 modulus,
11971 value,
11972 equals,
11973 } => {
11974 if *modulus == 0 {
11975 return false;
11976 }
11977 let actual = member_values.scalar(*member).unwrap_or_default() % *modulus;
11978 (actual == *value) == *equals
11979 }
11980 ParserPredicate::MemberEquals {
11981 member,
11982 value,
11983 equals,
11984 } => {
11985 let actual = member_values.scalar(*member).unwrap_or_default();
11986 (actual == *value) == *equals
11987 }
11988 }
11989 }
11990
11991 fn parser_predicate_failure_message(
11993 &self,
11994 rule_index: usize,
11995 pred_index: usize,
11996 predicates: &[(usize, usize, ParserPredicate)],
11997 ) -> Option<&'static str> {
11998 predicates
11999 .iter()
12000 .find_map(|(rule, pred, predicate)| match predicate {
12001 ParserPredicate::FalseWithMessage { message }
12002 if *rule == rule_index && *pred == pred_index =>
12003 {
12004 Some(*message)
12005 }
12006 _ => None,
12007 })
12008 }
12009
12010 pub fn parser_semantic_ir_predicate_failure_message(
12013 &self,
12014 rule_index: usize,
12015 pred_index: usize,
12016 semantics: &ParserSemantics,
12017 ) -> Option<&'static str> {
12018 semantics
12019 .predicates
12020 .iter()
12021 .find(|predicate| {
12022 predicate.rule_index == rule_index && predicate.pred_index == pred_index
12023 })
12024 .and_then(|predicate| predicate.failure_message)
12025 }
12026
12027 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
12036 if symbol == TOKEN_EOF {
12037 return index;
12038 }
12039 self.input.next_visible_after(index)
12040 }
12041
12042 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
12045 let text = display_input_text(&self.input.text(start_index, error_index));
12046 diagnostic_for_token(
12047 self.token_at(error_index).as_ref(),
12048 format!("no viable alternative at input '{text}'"),
12049 )
12050 }
12051
12052 fn recovery_failure_diagnostic(
12055 &self,
12056 index: usize,
12057 decision_start_index: Option<usize>,
12058 expected_symbols: &BTreeSet<i32>,
12059 ) -> ParserDiagnostic {
12060 if expected_symbols.len() > 1 {
12061 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
12062 return self.no_viable_alternative(decision_start, index);
12063 }
12064 }
12065 diagnostic_for_token(
12066 self.token_at(index).as_ref(),
12067 format!(
12068 "mismatched input {} expecting {}",
12069 self.token_at(index)
12070 .as_ref()
12071 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
12072 self.expected_symbols_display(expected_symbols)
12073 ),
12074 )
12075 }
12076
12077 fn eof_rule_recovery_diagnostic(
12080 &self,
12081 index: usize,
12082 expected_symbols: &BTreeSet<i32>,
12083 expected: &ExpectedTokens,
12084 ) -> ParserDiagnostic {
12085 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
12086 &expected.symbols
12087 } else {
12088 expected_symbols
12089 };
12090 diagnostic_for_token(
12091 self.token_at(index).as_ref(),
12092 format!(
12093 "mismatched input {} expecting {}",
12094 self.token_at(index)
12095 .as_ref()
12096 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
12097 self.expected_symbols_display(symbols)
12098 ),
12099 )
12100 }
12101
12102 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
12108 let Some(stop) = stop else {
12109 return String::new();
12110 };
12111 let stop = if self
12112 .token_at(stop)
12113 .is_some_and(|token| token.token_type() == TOKEN_EOF)
12114 {
12115 let Some(previous) = self.previous_token_index(stop) else {
12116 return String::new();
12117 };
12118 previous
12119 } else {
12120 stop
12121 };
12122 self.input.text(start, stop)
12123 }
12124
12125 fn clear_prediction_diagnostics(&mut self) {
12128 self.prediction_diagnostics.clear();
12129 self.reported_prediction_diagnostics.clear();
12130 }
12131
12132 fn reset_per_parse_caches(&mut self) {
12156 self.rule_first_set_cache.clear();
12157 self.decision_lookahead_cache.clear();
12158 self.ll1_decision_cache.clear();
12159 self.fast_predicate_cache.clear();
12160 self.rule_stop_reach_cache.clear();
12161 self.clean_memo_mode = CleanMemoMode::Probe;
12162 self.clean_memo_probe_seen.clear();
12163 self.clean_memo_probe_samples = 0;
12164 self.clean_memo_probe_repeats = 0;
12165 self.clean_memo_sparse_samples = 0;
12166 self.recovery_symbols_intern.clear();
12167 self.state_expected_cache.clear();
12168 self.state_expected_token_cache.clear();
12169 }
12170
12171 fn record_prediction_diagnostics(
12174 &mut self,
12175 atn: &Atn,
12176 state: AtnState<'_>,
12177 start_index: usize,
12178 outcomes: &[RecognizeOutcome],
12179 ) {
12180 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
12181 return;
12182 }
12183 let Some(decision) = atn
12184 .decision_to_state()
12185 .iter()
12186 .position(|state_number| state_number == state.state_number())
12187 else {
12188 return;
12189 };
12190 let Some(rule_index) = state.rule_index() else {
12191 return;
12192 };
12193 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
12194 for outcome in outcomes
12195 .iter()
12196 .filter(|outcome| outcome.diagnostics.is_empty())
12197 {
12198 let Some(alt) = outcome.decisions.first() else {
12199 continue;
12200 };
12201 alts_by_end
12202 .entry(outcome.index)
12203 .or_default()
12204 .insert(alt + 1);
12205 }
12206 let Some((&end_index, ambig_alts)) = alts_by_end
12207 .iter()
12208 .filter(|(_, alts)| alts.len() > 1)
12209 .max_by_key(|(end, _)| *end)
12210 else {
12211 return;
12212 };
12213 let rule_name = self
12214 .rule_names()
12215 .get(rule_index)
12216 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
12217 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
12218 let input = display_input_text(&self.input.text(start_index, stop_index));
12219 let alts = ambig_alts
12220 .iter()
12221 .map(usize::to_string)
12222 .collect::<Vec<_>>()
12223 .join(", ");
12224 let key = (decision, start_index, format!("{alts}:{input}"));
12225 if !self.reported_prediction_diagnostics.insert(key) {
12226 return;
12227 }
12228 let start_diagnostic = diagnostic_for_token(
12229 self.token_at(start_index),
12230 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
12231 );
12232 let stop_diagnostic = diagnostic_for_token(
12233 self.token_at(stop_index),
12234 format!(
12235 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
12236 ),
12237 );
12238 self.prediction_diagnostics.push(start_diagnostic);
12239 self.prediction_diagnostics.push(stop_diagnostic);
12240 }
12241
12242 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
12244 expected_symbols_display(
12245 &state_expected_symbols(atn, state_number),
12246 self.vocabulary(),
12247 )
12248 }
12249
12250 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
12255 let state = usize::try_from(self.data().state()).unwrap_or(0);
12256 ExpectedTokenSet {
12257 symbols: state_expected_symbols(atn, state),
12258 }
12259 }
12260
12261 pub const fn set_bail_on_error(&mut self, bail: bool) {
12264 self.bail_on_error = bail;
12265 }
12266
12267 #[must_use]
12269 pub const fn bail_on_error(&self) -> bool {
12270 self.bail_on_error
12271 }
12272
12273 pub fn rule_invocation_stack(&self) -> Vec<String> {
12276 self.rule_context_stack
12277 .iter()
12278 .rev()
12279 .map(|frame| {
12280 self.data()
12281 .rule_names()
12282 .get(frame.rule_index)
12283 .cloned()
12284 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
12285 })
12286 .collect()
12287 }
12288
12289 pub fn active_invocation_states(&self) -> Vec<isize> {
12293 self.rule_context_stack
12294 .iter()
12295 .skip(1)
12296 .rev()
12297 .map(|frame| frame.invoking_state)
12298 .collect()
12299 }
12300
12301 pub fn token_display_at(&self, index: usize) -> Option<String> {
12303 self.token_at(index).map(|token| format!("{token}"))
12304 }
12305}
12306
12307impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
12308where
12309 S: TokenSource,
12310 H: SemanticHooks,
12311{
12312 fn parse_rule(
12313 &mut self,
12314 rule_index: usize,
12315 invoking_state: isize,
12316 precedence: i32,
12317 ) -> DirectAdaptiveParseResult<ParseTree> {
12318 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
12319 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
12320 )?;
12321 let stop_state = self
12322 .atn
12323 .rule_to_stop_state()
12324 .get(rule_index)
12325 .filter(|state| *state != usize::MAX)
12326 .ok_or(DirectAdaptiveParseControl::Fallback(
12327 DirectAdaptiveFallback::MissingAtn,
12328 ))?;
12329 let start_index = self.parser.current_visible_index();
12330 let mut context = ParserRuleContext::new(rule_index, invoking_state);
12331 if let Some(token) = self.parser.token_id_at(start_index) {
12332 self.parser.set_context_start(&mut context, token);
12333 }
12334 let mut state_number = start_state;
12335 let mut consumed_eof = false;
12336 while state_number != stop_state {
12337 self.step()?;
12338 let (transition, boundary) = self.next_transition(state_number, precedence)?;
12339 if boundary.is_some() {
12340 return Err(DirectAdaptiveParseControl::Fallback(
12341 DirectAdaptiveFallback::LeftRecursiveBoundary,
12342 ));
12343 }
12344 match transition.data() {
12345 Transition::Epsilon { target } => {
12346 state_number = target;
12347 }
12348 Transition::Precedence {
12349 target,
12350 precedence: transition_precedence,
12351 } => {
12352 if transition_precedence < precedence {
12353 return Err(DirectAdaptiveParseControl::Fallback(
12354 DirectAdaptiveFallback::Precedence,
12355 ));
12356 }
12357 state_number = target;
12358 }
12359 Transition::Rule {
12360 rule_index,
12361 follow_state,
12362 precedence: rule_precedence,
12363 ..
12364 } => {
12365 let child = self.parse_rule(
12366 rule_index,
12367 invoking_state_number(state_number),
12368 rule_precedence,
12369 )?;
12370 if self.parser.build_parse_trees {
12371 self.parser.tree.add_child(&mut context, child);
12372 }
12373 state_number = follow_state;
12374 }
12375 Transition::Atom { .. }
12376 | Transition::Range { .. }
12377 | Transition::Set { .. }
12378 | Transition::NotSet { .. }
12379 | Transition::Wildcard { .. } => {
12380 let (matched_eof, child) = self.consume_transition(transition)?;
12381 consumed_eof |= matched_eof;
12382 if let Some(child) = child {
12383 self.parser.tree.add_child(&mut context, child);
12384 }
12385 state_number = transition.target();
12386 }
12387 Transition::Predicate { .. } => {
12388 return Err(DirectAdaptiveParseControl::Fallback(
12389 DirectAdaptiveFallback::Predicate,
12390 ));
12391 }
12392 Transition::Action { .. } => {
12393 return Err(DirectAdaptiveParseControl::Fallback(
12394 DirectAdaptiveFallback::Action,
12395 ));
12396 }
12397 }
12398 }
12399
12400 let stop_index = self
12401 .parser
12402 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
12403 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
12404 self.parser.set_context_stop(&mut context, token);
12405 }
12406 Ok(self.parser.rule_node(context))
12407 }
12408
12409 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
12410 self.steps += 1;
12411 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
12412 return Err(DirectAdaptiveParseControl::Fallback(
12413 DirectAdaptiveFallback::StepLimit,
12414 ));
12415 }
12416 Ok(())
12417 }
12418
12419 fn next_transition(
12420 &mut self,
12421 state_number: usize,
12422 precedence: i32,
12423 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
12424 let state = self
12425 .atn
12426 .state(state_number)
12427 .ok_or(DirectAdaptiveParseControl::Fallback(
12428 DirectAdaptiveFallback::MissingAtn,
12429 ))?;
12430 if state.is_rule_stop() {
12431 return Err(DirectAdaptiveParseControl::Fallback(
12432 DirectAdaptiveFallback::RuleStop,
12433 ));
12434 }
12435 let transition_index =
12436 self.transition_index(state_number, state.transitions().len(), precedence)?;
12437 let transition = state.transitions().get(transition_index).ok_or(
12438 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
12439 )?;
12440 let boundary = match &transition.data() {
12441 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
12442 left_recursive_boundary(self.atn, state, *target)
12443 }
12444 _ => None,
12445 };
12446 Ok((transition, boundary))
12447 }
12448
12449 fn transition_index(
12450 &mut self,
12451 state_number: usize,
12452 transition_count: usize,
12453 precedence: i32,
12454 ) -> DirectAdaptiveParseResult<usize> {
12455 match transition_count {
12456 0 => Err(DirectAdaptiveParseControl::Fallback(
12457 DirectAdaptiveFallback::NoTransition,
12458 )),
12459 1 => Ok(0),
12460 _ => {
12461 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
12462 return Ok(alt);
12463 }
12464 let decision = self
12465 .decision_by_state
12466 .get(state_number)
12467 .and_then(|decision| *decision)
12468 .ok_or(DirectAdaptiveParseControl::Fallback(
12469 DirectAdaptiveFallback::UnknownDecision,
12470 ))?;
12471 let prediction = self
12472 .simulator
12473 .adaptive_predict_stream_info_with_precedence(
12474 decision,
12475 direct_precedence(precedence),
12476 &mut self.parser.input,
12477 )
12478 .map_err(|_| {
12479 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
12480 })?;
12481 if prediction.has_semantic_context {
12482 return Err(DirectAdaptiveParseControl::Fallback(
12483 DirectAdaptiveFallback::SemanticContext,
12484 ));
12485 }
12486 prediction
12487 .alt
12488 .checked_sub(1)
12489 .filter(|index| *index < transition_count)
12490 .ok_or(DirectAdaptiveParseControl::Fallback(
12491 DirectAdaptiveFallback::InvalidAlt,
12492 ))
12493 }
12494 }
12495 }
12496
12497 fn ll1_transition_index(
12498 &mut self,
12499 state_number: usize,
12500 transition_count: usize,
12501 ) -> DirectAdaptiveParseResult<Option<usize>> {
12502 let state = self
12503 .atn
12504 .state(state_number)
12505 .ok_or(DirectAdaptiveParseControl::Fallback(
12506 DirectAdaptiveFallback::MissingAtn,
12507 ))?;
12508 if state.precedence_rule_decision() {
12509 return Ok(None);
12510 }
12511 let Some(rule_stop) = state
12512 .rule_index()
12513 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
12514 else {
12515 return Ok(None);
12516 };
12517 let symbol = self.parser.input.la_token(1);
12518 let entry = self
12519 .parser
12520 .cached_decision_lookahead(self.atn, state, rule_stop);
12521 Ok(
12522 ll1_greedy_alt(&entry, symbol, state.non_greedy())
12523 .filter(|alt| *alt < transition_count),
12524 )
12525 }
12526
12527 fn consume_transition(
12528 &mut self,
12529 transition: ParserTransition<'_>,
12530 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
12531 let symbol = self.parser.input.la_token(1);
12532 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
12533 return Err(DirectAdaptiveParseControl::Fallback(
12534 DirectAdaptiveFallback::TokenMismatch,
12535 ));
12536 }
12537 let token = self
12538 .parser
12539 .input
12540 .lt_id(1)
12541 .ok_or(DirectAdaptiveParseControl::Fallback(
12542 DirectAdaptiveFallback::TokenMismatch,
12543 ))?;
12544 let matched_eof = symbol == TOKEN_EOF;
12545 if !matched_eof {
12546 self.parser.consume();
12547 }
12548 let child = self
12549 .parser
12550 .build_parse_trees
12551 .then(|| self.parser.terminal_tree(token));
12552 Ok((matched_eof, child))
12553 }
12554}
12555
12556impl<S, H> CommittedAtnParser<'_, '_, '_, S, H>
12557where
12558 S: TokenSource,
12559 H: SemanticHooks,
12560{
12561 fn parse_rule(
12562 &mut self,
12563 rule_index: usize,
12564 precedence: i32,
12565 inherited_local_int_arg: Option<(usize, i64)>,
12566 init_expected_state: Option<usize>,
12567 ) -> Result<CommittedRuleOutcome, AntlrError> {
12568 let start_state = self
12569 .atn
12570 .rule_to_start_state()
12571 .get(rule_index)
12572 .ok_or_else(|| {
12573 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
12574 })?;
12575 let stop_state = self
12576 .atn
12577 .rule_to_stop_state()
12578 .get(rule_index)
12579 .filter(|state| *state != usize::MAX)
12580 .ok_or_else(|| {
12581 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
12582 })?;
12583 let left_recursive = self
12584 .atn
12585 .state(start_state)
12586 .is_some_and(AtnState::left_recursive_rule);
12587 if let Some(error) = self.parser.rule_depth_cap_violation() {
12588 return Err(error);
12589 }
12590 if let Some(error) = self.parser.parse_listener_enter_rule(rule_index) {
12591 return Err(error);
12592 }
12593 let mut context = if left_recursive {
12594 self.parser.enter_recursion_rule(
12595 invoking_state_number(start_state),
12596 rule_index,
12597 precedence,
12598 )
12599 } else {
12600 self.parser
12601 .enter_rule(invoking_state_number(start_state), rule_index)
12602 };
12603 let rule_start_index = self.parser.current_visible_index();
12604 let local_int_arg =
12605 usize::try_from(context.invoking_state())
12606 .ok()
12607 .and_then(|source_state| {
12608 rule_local_int_arg(
12609 self.options.rule_args,
12610 source_state,
12611 rule_index,
12612 inherited_local_int_arg,
12613 )
12614 });
12615 if self.options.init_action_rules.contains(&rule_index) {
12616 let action = ParserAction::new_rule_init(
12617 rule_index,
12618 rule_start_index,
12619 init_expected_state.or(Some(start_state)),
12620 );
12621 if !self
12622 .parser
12623 .parser_rule_init_hook_with_context(action, &context, local_int_arg)
12624 {
12625 self.deferred_actions.push(action);
12626 }
12627 }
12628 let mut consumed_eof = false;
12629 let result = self.walk_rule(
12630 rule_index,
12631 start_state,
12632 stop_state,
12633 precedence,
12634 rule_start_index,
12635 local_int_arg,
12636 left_recursive,
12637 &mut context,
12638 &mut consumed_eof,
12639 );
12640
12641 let result = match result {
12642 Ok(()) => Ok(if left_recursive {
12643 self.parser.finish_recursion_rule(context, consumed_eof)
12644 } else {
12645 self.parser.finish_rule(context, consumed_eof)
12646 }),
12647 Err(error) if self.parser.bail_on_error() => {
12648 if left_recursive {
12649 self.parser.unroll_recursion_context();
12650 } else {
12651 self.parser.exit_rule();
12652 }
12653 Err(error)
12654 }
12655 Err(error) => {
12656 self.parser
12657 .recover_generated_rule(&mut context, self.atn, error);
12658 Ok(if left_recursive {
12659 self.parser.finish_recursion_rule(context, consumed_eof)
12660 } else {
12661 self.parser.finish_rule(context, consumed_eof)
12662 })
12663 }
12664 };
12665 self.parser.parse_listener_exit_rule(rule_index);
12666 result.map(|tree| CommittedRuleOutcome { tree, consumed_eof })
12667 }
12668
12669 #[allow(clippy::too_many_arguments)]
12670 fn walk_rule(
12671 &mut self,
12672 rule_index: usize,
12673 mut state_number: usize,
12674 stop_state: usize,
12675 precedence: i32,
12676 rule_start_index: usize,
12677 local_int_arg: Option<(usize, i64)>,
12678 left_recursive: bool,
12679 context: &mut ParserRuleContext,
12680 consumed_eof: &mut bool,
12681 ) -> Result<(), AntlrError> {
12682 let mut entered_loops = BTreeSet::new();
12683 let mut visited_coordinates = FxHashSet::default();
12684 let mut guarded_input_index = self.parser.input.index();
12685 while state_number != stop_state {
12686 let input_index = self.parser.input.index();
12687 if input_index != guarded_input_index {
12688 visited_coordinates.clear();
12689 guarded_input_index = input_index;
12690 }
12691 if !visited_coordinates.insert((state_number, input_index)) {
12692 return Err(AntlrError::Unsupported(format!(
12693 "committed parser encountered a non-consuming ATN cycle at state \
12694 {state_number}"
12695 )));
12696 }
12697 let state = self.atn.state(state_number).ok_or_else(|| {
12698 AntlrError::Unsupported(format!("missing parser ATN state {state_number}"))
12699 })?;
12700 if state.is_rule_stop() {
12701 return Err(AntlrError::Unsupported(format!(
12702 "rule {rule_index} reached unexpected stop state {state_number}"
12703 )));
12704 }
12705 let transition_index = {
12706 let mut decision_context = CommittedDecisionContext {
12707 precedence,
12708 local_int_arg,
12709 context,
12710 entered_loops: &mut entered_loops,
12711 };
12712 self.transition_index(state, &mut decision_context)?
12713 };
12714 let transition = state.transitions().get(transition_index).ok_or_else(|| {
12715 AntlrError::Unsupported(format!(
12716 "missing transition {transition_index} from parser ATN state {state_number}"
12717 ))
12718 })?;
12719
12720 let next_alt = next_alt_number(
12721 state,
12722 state.transitions().len(),
12723 transition_index,
12724 context.alt_number(),
12725 self.options.track_alt_numbers,
12726 );
12727 if self.options.track_alt_numbers && context.alt_number() == 0 && next_alt != 0 {
12728 context.set_alt_number(next_alt);
12729 }
12730 let next_context_alt = next_alt_number(
12731 state,
12732 state.transitions().len(),
12733 transition_index,
12734 context.context_alt_number(),
12735 self.options.track_context_alt_numbers,
12736 );
12737 if self.options.track_context_alt_numbers
12738 && context.context_alt_number() == 0
12739 && next_context_alt != 0
12740 {
12741 context.set_context_alt_number(next_context_alt);
12742 }
12743
12744 if left_recursive
12745 && left_recursive_boundary(self.atn, state, transition.target()).is_some()
12746 {
12747 if let Some(error) = self.parser.rule_depth_cap_violation() {
12748 return Err(error);
12749 }
12750 self.parser.parse_listener_exit_rule(rule_index);
12751 self.parser.push_new_recursion_context_with_previous(
12752 invoking_state_number(
12753 self.atn
12754 .rule_to_start_state()
12755 .get(rule_index)
12756 .unwrap_or(state_number),
12757 ),
12758 rule_index,
12759 context,
12760 );
12761 if let Some(error) = self.parser.parse_listener_enter_rule(rule_index) {
12762 return Err(error);
12763 }
12764 }
12765 state_number = self.apply_transition(
12766 state_number,
12767 transition,
12768 precedence,
12769 rule_start_index,
12770 local_int_arg,
12771 context,
12772 consumed_eof,
12773 )?;
12774 }
12775 Ok(())
12776 }
12777
12778 fn transition_index(
12779 &mut self,
12780 state: AtnState<'_>,
12781 decision_context: &mut CommittedDecisionContext<'_>,
12782 ) -> Result<usize, AntlrError> {
12783 let transition_count = state.transitions().len();
12784 if transition_count == 1 {
12785 return Ok(0);
12786 }
12787 let Some(decision) = self
12788 .decision_by_state
12789 .get(state.state_number())
12790 .copied()
12791 .flatten()
12792 else {
12793 return Err(AntlrError::Unsupported(format!(
12794 "parser ATN state {} has {transition_count} transitions but is not a decision",
12795 state.state_number()
12796 )));
12797 };
12798
12799 let decision_start = self.parser.input.index();
12800 let overridden_transition = if self.parser.semantic_hooks.observes_parser_decisions() {
12801 self.parser
12802 .semantic_hooks
12803 .parser_decision_override(decision, decision_start, transition_count)
12804 .and_then(|alternative| alternative.checked_sub(1))
12805 .filter(|alternative| *alternative < transition_count)
12806 } else {
12807 None
12808 };
12809 if let Some(selected) = overridden_transition {
12810 self.update_loop_selection(state, selected, decision_context);
12811 return Ok(selected);
12812 }
12813
12814 if !state.precedence_rule_decision() {
12815 let loop_back = match state.kind() {
12816 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack => true,
12817 AtnStateKind::StarLoopEntry => decision_context
12818 .entered_loops
12819 .contains(&state.state_number()),
12820 _ => false,
12821 };
12822 let children = self.parser.sync_decision(
12823 self.atn,
12824 state.state_number(),
12825 !decision_context.context.has_matched_child(),
12826 loop_back,
12827 )?;
12828 for child in children {
12829 self.parser.add_parse_child(decision_context.context, child);
12830 }
12831 }
12832
12833 let prediction_precedence = if state.precedence_rule_decision() {
12834 usize::try_from(decision_context.precedence.max(0)).unwrap_or_default()
12835 } else {
12836 0
12837 };
12838 let prediction_context = {
12839 let return_states = self
12840 .parser
12841 .prediction_context_return_states(self.atn)
12842 .collect::<Vec<_>>();
12843 self.simulator
12844 .intern_prediction_context(self.parser.rule_context_version(), return_states)
12845 };
12846 self.simulator.set_exact_ambig_detection(
12847 self.parser.prediction_mode() == PredictionMode::LlExactAmbigDetection,
12848 );
12849 let prediction_mode = self.parser.prediction_mode();
12850 let prediction = match self.simulator.adaptive_predict_stream_info_sll_probe(
12851 decision,
12852 prediction_precedence,
12853 &mut self.parser.input,
12854 ) {
12855 Ok(prediction)
12856 if prediction.requires_full_context && prediction_mode != PredictionMode::Sll =>
12857 {
12858 self.simulator.adaptive_predict_stream_info_with_context(
12859 decision,
12860 prediction_precedence,
12861 &mut self.parser.input,
12862 prediction_context,
12863 )
12864 }
12865 prediction => prediction,
12866 };
12867 let mut prediction = match prediction {
12868 Ok(prediction) => prediction,
12869 Err(ParserAtnSimulatorError::NoViableAlt { index, .. })
12870 if state.precedence_rule_decision() =>
12871 {
12872 let enter_alt = state.transitions().iter().position(|transition| {
12873 self.atn
12874 .state(transition.target())
12875 .is_some_and(|target| target.kind() != AtnStateKind::LoopEnd)
12876 });
12877 let exit_alt = state.transitions().iter().position(|transition| {
12878 self.atn
12879 .state(transition.target())
12880 .is_some_and(|target| target.kind() == AtnStateKind::LoopEnd)
12881 });
12882 let selected = if self.parser.left_recursive_loop_enter_matches(
12883 self.atn,
12884 state.state_number(),
12885 decision_context.precedence,
12886 ) {
12887 enter_alt
12888 } else {
12889 exit_alt
12890 };
12891 let Some(selected) = selected else {
12892 return Err(self
12893 .parser
12894 .no_viable_alternative_error_at(decision_start, index));
12895 };
12896 ParserAtnPrediction {
12897 alt: selected + 1,
12898 requires_full_context: true,
12899 has_semantic_context: true,
12900 diagnostic: None,
12901 }
12902 }
12903 Err(ParserAtnSimulatorError::NoViableAlt { index, .. }) => {
12904 return Err(self
12905 .parser
12906 .no_viable_alternative_error_at(decision_start, index));
12907 }
12908 Err(ParserAtnSimulatorError::PredictionRequiresMoreLookahead) => {
12909 return Err(self.parser.no_viable_alternative_error(decision_start));
12910 }
12911 Err(error) => {
12912 return Err(AntlrError::Unsupported(format!(
12913 "committed parser prediction failed at decision {decision}: {error:?}"
12914 )));
12915 }
12916 };
12917 let mut selected = prediction
12918 .alt
12919 .checked_sub(1)
12920 .filter(|index| *index < transition_count)
12921 .ok_or_else(|| self.parser.no_viable_alternative_error(decision_start))?;
12922
12923 let semantic_candidates = self.simulator.prediction_semantic_candidates();
12924 if !semantic_candidates.is_empty() {
12925 let predicted_alt = prediction.alt;
12926 let mut semantic_results = BTreeMap::new();
12927 let selected_alt = selected + 1;
12928 let selected_matches = self.semantic_alternative_matches(
12929 selected_alt,
12930 decision_context,
12931 &semantic_candidates,
12932 );
12933 semantic_results.insert(selected_alt, selected_matches);
12934 if !selected_matches {
12935 let alternatives = semantic_candidates
12936 .iter()
12937 .map(|candidate| candidate.alt)
12938 .filter(|alternative| *alternative != 0 && *alternative <= transition_count)
12939 .collect::<BTreeSet<_>>();
12940 selected = alternatives
12941 .into_iter()
12942 .find(|alternative| {
12943 let matches = self.semantic_alternative_matches(
12944 *alternative,
12945 decision_context,
12946 &semantic_candidates,
12947 );
12948 semantic_results.insert(*alternative, matches);
12949 matches
12950 })
12951 .and_then(|alternative| alternative.checked_sub(1))
12952 .ok_or_else(|| self.parser.no_viable_alternative_error(decision_start))?;
12953 }
12954 if self.parser.report_diagnostic_errors
12955 && let Some(diagnostic) = prediction.diagnostic.as_ref()
12956 {
12957 for alternative in diagnostic.conflicting_alts.clone() {
12958 if semantic_results.contains_key(&alternative)
12959 || !semantic_candidates
12960 .iter()
12961 .any(|candidate| candidate.alt == alternative)
12962 {
12963 continue;
12964 }
12965 let matches = self.semantic_alternative_matches(
12966 alternative,
12967 decision_context,
12968 &semantic_candidates,
12969 );
12970 semantic_results.insert(alternative, matches);
12971 }
12972 }
12973 Self::filter_prediction_diagnostic(
12974 &mut prediction,
12975 predicted_alt,
12976 selected + 1,
12977 &semantic_results,
12978 );
12979 }
12980 self.parser.record_generated_prediction_diagnostic(
12981 self.atn,
12982 state.state_number(),
12983 &prediction,
12984 );
12985
12986 self.update_loop_selection(state, selected, decision_context);
12987 Ok(selected)
12988 }
12989
12990 fn semantic_alternative_matches(
12991 &mut self,
12992 alternative: usize,
12993 decision_context: &CommittedDecisionContext<'_>,
12994 candidates: &[ParserSemanticCandidate],
12995 ) -> bool {
12996 candidates
12997 .iter()
12998 .filter(|candidate| candidate.alt == alternative)
12999 .any(|candidate| {
13000 self.semantic_context_matches(&candidate.context, decision_context, candidate)
13001 })
13002 }
13003
13004 fn filter_prediction_diagnostic(
13005 prediction: &mut ParserAtnPrediction,
13006 predicted_alt: usize,
13007 selected_alt: usize,
13008 semantic_results: &BTreeMap<usize, bool>,
13009 ) {
13010 prediction.alt = selected_alt;
13011 if selected_alt != predicted_alt {
13012 prediction.diagnostic = None;
13013 return;
13014 }
13015 if let Some(diagnostic) = prediction.diagnostic.as_mut() {
13016 diagnostic
13017 .conflicting_alts
13018 .retain(|alternative| semantic_results.get(alternative).copied().unwrap_or(true));
13019 if diagnostic.conflicting_alts.len() < 2 {
13020 prediction.diagnostic = None;
13021 }
13022 }
13023 }
13024
13025 fn semantic_context_matches(
13026 &mut self,
13027 semantic_context: &SemanticContext,
13028 decision_context: &CommittedDecisionContext<'_>,
13029 candidate: &ParserSemanticCandidate,
13030 ) -> bool {
13031 match semantic_context {
13032 SemanticContext::None => true,
13033 SemanticContext::Predicate {
13034 rule_index,
13035 pred_index,
13036 ..
13037 } => {
13038 let mut matched_provenance = false;
13039 for predicate_call in candidate
13040 .predicate_calls
13041 .iter()
13042 .filter(|call| call.rule_index == *rule_index && call.pred_index == *pred_index)
13043 {
13044 matched_provenance = true;
13045 let mut local_int_arg = decision_context.local_int_arg;
13046 for rule_call in &predicate_call.rule_calls {
13047 local_int_arg = rule_local_int_arg(
13048 self.options.rule_args,
13049 rule_call.source_state,
13050 rule_call.rule_index,
13051 local_int_arg,
13052 );
13053 }
13054 if !self.semantic_predicate_matches(
13055 *rule_index,
13056 *pred_index,
13057 decision_context,
13058 local_int_arg,
13059 ) {
13060 return false;
13061 }
13062 }
13063 if matched_provenance {
13064 true
13065 } else {
13066 self.semantic_predicate_matches(
13067 *rule_index,
13068 *pred_index,
13069 decision_context,
13070 decision_context.local_int_arg,
13071 )
13072 }
13073 }
13074 SemanticContext::Precedence { precedence } => {
13075 *precedence >= decision_context.precedence
13076 }
13077 SemanticContext::And(children) => {
13078 for child in children {
13079 if !self.semantic_context_matches(child, decision_context, candidate) {
13080 return false;
13081 }
13082 }
13083 true
13084 }
13085 SemanticContext::Or(children) => {
13086 for child in children {
13087 if self.semantic_context_matches(child, decision_context, candidate) {
13088 return true;
13089 }
13090 }
13091 false
13092 }
13093 }
13094 }
13095
13096 fn semantic_predicate_matches(
13097 &mut self,
13098 rule_index: usize,
13099 pred_index: usize,
13100 decision_context: &CommittedDecisionContext<'_>,
13101 local_int_arg: Option<(usize, i64)>,
13102 ) -> bool {
13103 let member_values = self.parser.int_members.clone();
13104 self.parser.parser_predicate_matches(PredicateEval {
13105 index: self.parser.input.index(),
13106 rule_index,
13107 pred_index,
13108 predicates: self.options.predicates,
13109 semantics: self.options.semantics,
13110 context: Some(&*decision_context.context),
13111 local_int_arg,
13112 member_values: &member_values,
13113 })
13114 }
13115
13116 fn update_loop_selection(
13117 &self,
13118 state: AtnState<'_>,
13119 selected: usize,
13120 decision_context: &mut CommittedDecisionContext<'_>,
13121 ) {
13122 if state.kind() == AtnStateKind::StarLoopEntry {
13123 let enters = self
13124 .atn
13125 .state(
13126 state
13127 .transitions()
13128 .get(selected)
13129 .expect("selected transition is in bounds")
13130 .target(),
13131 )
13132 .is_some_and(|target| target.kind() != AtnStateKind::LoopEnd);
13133 if enters {
13134 decision_context.entered_loops.insert(state.state_number());
13135 } else {
13136 decision_context.entered_loops.remove(&state.state_number());
13137 }
13138 }
13139 }
13140
13141 #[allow(clippy::too_many_arguments)]
13142 fn apply_transition(
13143 &mut self,
13144 source_state: usize,
13145 transition: ParserTransition<'_>,
13146 precedence: i32,
13147 rule_start_index: usize,
13148 local_int_arg: Option<(usize, i64)>,
13149 context: &mut ParserRuleContext,
13150 consumed_eof: &mut bool,
13151 ) -> Result<usize, AntlrError> {
13152 self.parser.set_state(invoking_state_number(source_state));
13153 match transition.data() {
13154 Transition::Epsilon { target } => Ok(target),
13155 Transition::Atom { target, label } => {
13156 let matched = self
13157 .parser
13158 .match_token_recovering(label, target, self.atn)?;
13159 *consumed_eof |= matched.consumed_eof();
13160 for child in matched.into_child_iter() {
13161 self.parser.add_parse_child(context, child);
13162 }
13163 Ok(target)
13164 }
13165 Transition::Range {
13166 target,
13167 start,
13168 stop,
13169 } => {
13170 let matched =
13171 self.parser
13172 .match_set_recovering(&[(start, stop)], target, self.atn)?;
13173 *consumed_eof |= matched.consumed_eof();
13174 for child in matched.into_child_iter() {
13175 self.parser.add_parse_child(context, child);
13176 }
13177 Ok(target)
13178 }
13179 Transition::Set { target, set } => {
13180 let matched = self
13181 .parser
13182 .match_token_set_recovering(set, target, self.atn)?;
13183 *consumed_eof |= matched.consumed_eof();
13184 for child in matched.into_child_iter() {
13185 self.parser.add_parse_child(context, child);
13186 }
13187 Ok(target)
13188 }
13189 Transition::NotSet { target, set } => {
13190 let matched = self.parser.match_not_token_set_recovering(
13191 set,
13192 1,
13193 self.atn.max_token_type(),
13194 target,
13195 self.atn,
13196 )?;
13197 *consumed_eof |= matched.consumed_eof();
13198 for child in matched.into_child_iter() {
13199 self.parser.add_parse_child(context, child);
13200 }
13201 Ok(target)
13202 }
13203 Transition::Wildcard { target } => {
13204 let matched = self.parser.match_not_set_recovering(
13205 &[],
13206 1,
13207 self.atn.max_token_type(),
13208 target,
13209 self.atn,
13210 )?;
13211 *consumed_eof |= matched.consumed_eof();
13212 for child in matched.into_child_iter() {
13213 self.parser.add_parse_child(context, child);
13214 }
13215 Ok(target)
13216 }
13217 Transition::Rule {
13218 rule_index,
13219 follow_state,
13220 precedence: rule_precedence,
13221 ..
13222 } => {
13223 let marker = self
13224 .parser
13225 .push_invoking_state(invoking_state_number(source_state));
13226 let child = if self.parser.generated_rule_stack_check_due() {
13227 grow_generated_rule_stack(|| {
13228 self.parse_rule(
13229 rule_index,
13230 rule_precedence,
13231 local_int_arg,
13232 Some(follow_state),
13233 )
13234 })
13235 } else {
13236 self.parse_rule(
13237 rule_index,
13238 rule_precedence,
13239 local_int_arg,
13240 Some(follow_state),
13241 )
13242 };
13243 self.parser.discard_invoking_state(marker);
13244 let child = child?;
13245 *consumed_eof |= child.consumed_eof;
13246 self.parser.add_parse_child(context, child.tree);
13247 Ok(follow_state)
13248 }
13249 Transition::Predicate {
13250 target,
13251 rule_index,
13252 pred_index,
13253 ..
13254 } => {
13255 let member_values = self.parser.int_members.clone();
13256 if self.parser.parser_predicate_matches(PredicateEval {
13257 index: self.parser.input.index(),
13258 rule_index,
13259 pred_index,
13260 predicates: self.options.predicates,
13261 semantics: self.options.semantics,
13262 context: Some(context),
13263 local_int_arg,
13264 member_values: &member_values,
13265 }) {
13266 return Ok(target);
13267 }
13268 if let Some(message) = self
13269 .options
13270 .semantics
13271 .and_then(|semantics| {
13272 self.parser.parser_semantic_ir_predicate_failure_message(
13273 rule_index, pred_index, semantics,
13274 )
13275 })
13276 .or_else(|| {
13277 self.parser.parser_predicate_failure_message(
13278 rule_index,
13279 pred_index,
13280 self.options.predicates,
13281 )
13282 })
13283 {
13284 return Err(self
13285 .parser
13286 .failed_predicate_option_error(rule_index, message));
13287 }
13288 Err(self.parser.failed_predicate_error("semantic predicate"))
13289 }
13290 Transition::Action {
13291 target, rule_index, ..
13292 } => {
13293 self.apply_translated_actions(source_state, rule_index, context);
13294 if let Some(action_index) = self.action_index(source_state) {
13295 let action = self.parser.parser_action_at_current_indexed(
13296 source_state,
13297 rule_index,
13298 action_index,
13299 rule_start_index,
13300 *consumed_eof,
13301 );
13302 let _ = self.parser.parser_action_hook_inner(
13303 action,
13304 Some(context),
13305 None,
13306 local_int_arg,
13307 true,
13308 );
13309 }
13310 Ok(target)
13311 }
13312 Transition::Precedence {
13313 target,
13314 precedence: transition_precedence,
13315 } => {
13316 if transition_precedence >= precedence {
13317 Ok(target)
13318 } else {
13319 Err(self
13320 .parser
13321 .failed_predicate_error(format!("precpred(_ctx, {transition_precedence})")))
13322 }
13323 }
13324 }
13325 }
13326
13327 fn apply_translated_actions(
13328 &mut self,
13329 source_state: usize,
13330 rule_index: usize,
13331 context: &mut ParserRuleContext,
13332 ) {
13333 apply_member_actions(
13334 source_state,
13335 self.options.member_actions,
13336 self.options.semantics,
13337 &mut self.parser.int_members,
13338 );
13339 let return_values = return_values_after_action(
13340 source_state,
13341 rule_index,
13342 self.options.return_actions,
13343 self.options.semantics,
13344 &BTreeMap::new(),
13345 );
13346 for (name, value) in return_values {
13347 context.set_int_return(name, value);
13348 }
13349 }
13350
13351 fn action_index(&self, source_state: usize) -> Option<usize> {
13352 self.action_index_by_state.get(&source_state).copied()
13353 }
13354}
13355
13356fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
13359 if !state.precedence_rule_decision() {
13360 return None;
13361 }
13362 let target_state = atn.state(target)?;
13363 if target_state.kind() == AtnStateKind::LoopEnd {
13364 return None;
13365 }
13366 state.rule_index()
13367}
13368
13369fn next_alt_number(
13376 state: AtnState<'_>,
13377 transition_count: usize,
13378 transition_index: usize,
13379 current_alt_number: usize,
13380 track_alt_numbers: bool,
13381) -> usize {
13382 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
13383 return current_alt_number;
13384 }
13385 if matches!(
13386 state.kind(),
13387 AtnStateKind::Basic
13388 | AtnStateKind::BlockStart
13389 | AtnStateKind::PlusBlockStart
13390 | AtnStateKind::StarBlockStart
13391 | AtnStateKind::StarLoopEntry
13392 ) && !state.precedence_rule_decision()
13393 {
13394 return transition_index + 1;
13395 }
13396 current_alt_number
13397}
13398
13399fn invoking_state_number(state_number: usize) -> isize {
13402 isize::try_from(state_number).unwrap_or(isize::MAX)
13403}
13404
13405const fn packed_i32(value: u32) -> i32 {
13406 i32::from_le_bytes(value.to_le_bytes())
13407}
13408
13409fn direct_precedence(precedence: i32) -> usize {
13410 usize::try_from(precedence.max(0)).unwrap_or_default()
13411}
13412
13413fn token_input_display(token: &impl Token) -> String {
13414 format!("'{}'", token.text().unwrap_or("<EOF>"))
13415}
13416
13417fn display_input_text(text: &str) -> String {
13418 let mut out = String::new();
13419 for ch in text.chars() {
13420 match ch {
13421 '\n' => out.push_str("\\n"),
13422 '\r' => out.push_str("\\r"),
13423 '\t' => out.push_str("\\t"),
13424 other => out.push(other),
13425 }
13426 }
13427 out
13428}
13429
13430fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
13431 let (line, column, offending) = token.map_or((0, 0, None), |token| {
13432 (token.line(), token.column(), Some(token.token_id()))
13433 });
13434 ParserDiagnostic {
13435 line,
13436 column,
13437 message,
13438 offending,
13439 }
13440}
13441
13442fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
13443 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
13444}
13445
13446fn expected_symbols_display_iter(
13447 symbols: impl IntoIterator<Item = i32>,
13448 vocabulary: &Vocabulary,
13449) -> String {
13450 let items = symbols
13451 .into_iter()
13452 .map(|symbol| expected_symbol_display(symbol, vocabulary))
13453 .collect::<Vec<_>>();
13454 if let [single] = items.as_slice() {
13455 return single.clone();
13456 }
13457 format!("{{{}}}", items.join(", "))
13458}
13459
13460fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
13461 if symbol == TOKEN_EOF {
13462 return "<EOF>".to_owned();
13463 }
13464 vocabulary.display_name(symbol)
13465}
13466
13467fn caller_follow_token_info_for_stream<S: TokenSource>(
13468 input: &mut CommonTokenStream<S>,
13469 index: usize,
13470) -> (i32, bool, bool) {
13471 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
13474 input.fill();
13475 }
13476 let token_type = input.token_type_at_index(index);
13477 let visible_channel = input.channel();
13478 let token = input.get(index);
13479 let is_boundary = token
13480 .as_ref()
13481 .and_then(Token::text)
13482 .is_some_and(is_caller_follow_boundary_text);
13483 let is_boundary_gap = token.as_ref().is_some_and(|token| {
13484 token.channel() != visible_channel
13485 || is_caller_follow_boundary_gap_text(token.text_or_empty())
13486 });
13487 (token_type, is_boundary, is_boundary_gap)
13488}
13489
13490fn is_caller_follow_boundary_text(text: &str) -> bool {
13491 text.chars().any(|ch| ch == ';' || ch == '\n')
13492 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
13493}
13494
13495fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
13496 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
13497}
13498
13499fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
13503 let Some(rule_index) = state.rule_index() else {
13504 return false;
13505 };
13506 atn.rule_to_start_state()
13507 .get(rule_index)
13508 .and_then(|state_number| atn.state(state_number))
13509 .is_some_and(AtnState::left_recursive_rule)
13510}
13511
13512fn select_better_top_outcome(
13519 first: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
13520 second: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
13521 arena: &RecognitionArena,
13522) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
13523 match (first, second) {
13524 (Ok(first), Ok(second)) => {
13525 if arena.diagnostics(first.0.diagnostics).next().is_none() {
13526 Ok(first)
13527 } else {
13528 Ok(second)
13529 }
13530 }
13531 (Ok(first), Err(_)) => Ok(first),
13532 (Err(_), Ok(second)) => Ok(second),
13533 (Err(_), Err(second_expected)) => Err(second_expected),
13534 }
13535}
13536
13537fn select_best_fast_outcome(
13543 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
13544 prediction_mode: PredictionMode,
13545 caller_follow: Option<&TokenBitSet>,
13546 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
13547 arena: &RecognitionArena,
13548) -> Option<FastRecognizeOutcome> {
13549 let mut best = None;
13550 let mut best_caller_follow = None;
13551 for outcome in outcomes {
13552 if matches!(
13553 prediction_mode,
13554 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
13555 ) && outcome.diagnostics.is_empty()
13556 && let Some(follow) = caller_follow
13557 {
13558 let (token_type, is_boundary, _) = token_info_at(outcome.index);
13559 if is_boundary && follow.contains(token_type) {
13560 let replace =
13561 best_caller_follow
13562 .as_ref()
13563 .is_none_or(|existing: &FastRecognizeOutcome| {
13564 (outcome.index, outcome.consumed_eof)
13565 < (existing.index, existing.consumed_eof)
13566 });
13567 if replace {
13568 best_caller_follow = Some(outcome);
13569 }
13570 }
13571 }
13572 let Some(existing) = best else {
13573 best = Some(outcome);
13574 continue;
13575 };
13576 let outcome_position = (outcome.index, outcome.consumed_eof);
13577 let best_position = (existing.index, existing.consumed_eof);
13578 let better = match prediction_mode {
13579 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
13580 outcome_position,
13581 outcome.diagnostics,
13582 best_position,
13583 existing.diagnostics,
13584 arena,
13585 ),
13586 PredictionMode::Sll => outcome.index > existing.index,
13587 };
13588 best = Some(if better { outcome } else { existing });
13589 }
13590 let should_use_caller_follow =
13591 best_caller_follow
13592 .as_ref()
13593 .zip(best.as_ref())
13594 .is_some_and(|(candidate, selected)| {
13595 if !selected.diagnostics.is_empty() {
13596 return true;
13597 }
13598 candidate.index < selected.index
13599 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
13600 });
13601 if should_use_caller_follow {
13602 best_caller_follow
13603 } else {
13604 best
13605 }
13606}
13607
13608fn select_best_outcome(
13609 outcomes: impl Iterator<Item = RecognizeOutcome>,
13610 prediction_mode: PredictionMode,
13611 arena: &RecognitionArena,
13612) -> Option<RecognizeOutcome> {
13613 let outcomes = outcomes.collect::<Vec<_>>();
13614 let prefer_first_tie = outcomes
13615 .iter()
13616 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
13617 outcomes.into_iter().reduce(|best, outcome| {
13618 let outcome_position = (outcome.index, outcome.consumed_eof);
13619 let best_position = (best.index, best.consumed_eof);
13620 let better = match prediction_mode {
13621 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
13622 outcome_is_better(
13623 outcome_position,
13624 outcome.diagnostics,
13625 best_position,
13626 best.diagnostics,
13627 arena,
13628 ) || (outcome_position == best_position
13629 && arena.diagnostics_len(outcome.diagnostics)
13630 == arena.diagnostics_len(best.diagnostics)
13631 && arena.diagnostics_recovery_rank(outcome.diagnostics)
13632 == arena.diagnostics_recovery_rank(best.diagnostics)
13633 && (outcome.decisions < best.decisions
13634 || (!prefer_first_tie
13635 && outcome.decisions == best.decisions
13636 && outcome.actions > best.actions)))
13637 }
13638 PredictionMode::Sll => {
13639 outcome_position > best_position
13640 || (outcome_position == best_position
13641 && !prefer_first_tie
13642 && (outcome.decisions < best.decisions
13643 || (outcome.decisions == best.decisions
13644 && outcome_is_better(
13645 outcome_position,
13646 outcome.diagnostics,
13647 best_position,
13648 best.diagnostics,
13649 arena,
13650 ))))
13651 }
13652 };
13653 if better {
13654 return outcome;
13655 }
13656 best
13657 })
13658}
13659
13660fn transition_decision(
13667 atn: &Atn,
13668 state: AtnState<'_>,
13669 transition_count: usize,
13670 transition_index: usize,
13671 predicates: &[(usize, usize, ParserPredicate)],
13672) -> Option<usize> {
13673 if transition_count <= 1 || decision_reaches_unsupported_predicate(atn, state, predicates) {
13674 return None;
13675 }
13676 Some(transition_index)
13677}
13678
13679fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
13685 transition_count > 1
13686 && !matches!(
13687 state.kind(),
13688 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
13689 )
13690}
13691
13692fn record_no_viable_if_ambiguous(
13695 expected: &mut ExpectedTokens,
13696 decision_start_index: Option<usize>,
13697 index: usize,
13698) {
13699 if expected.index == Some(index) && expected.symbols.len() > 1 {
13700 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
13701 expected.record_no_viable(decision_start, index);
13702 }
13703 }
13704}
13705
13706const fn record_predicate_no_viable(
13709 expected: &mut ExpectedTokens,
13710 decision_start_index: Option<usize>,
13711 index: usize,
13712) {
13713 if let Some(decision_start) = decision_start_index {
13714 expected.record_no_viable(decision_start, index);
13715 }
13716}
13717
13718const fn no_viable_decision_start(
13720 decision_start_index: Option<usize>,
13721 index: usize,
13722) -> Option<usize> {
13723 match decision_start_index {
13724 Some(start) if index > start => Some(start),
13725 _ => None,
13726 }
13727}
13728
13729fn restore_expected(
13733 children: &[RecognizeOutcome],
13734 child_start_index: usize,
13735 expected: &mut ExpectedTokens,
13736 snapshot: ExpectedTokens,
13737 preserve_child_expected: bool,
13738) {
13739 if preserve_child_expected {
13740 return;
13741 }
13742 if children
13743 .iter()
13744 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
13745 {
13746 *expected = snapshot;
13747 }
13748}
13749
13750fn decision_reaches_unsupported_predicate(
13753 atn: &Atn,
13754 state: AtnState<'_>,
13755 predicates: &[(usize, usize, ParserPredicate)],
13756) -> bool {
13757 state.transitions().iter().any(|transition| {
13758 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
13759 })
13760}
13761
13762fn transition_reaches_unsupported_predicate(
13764 atn: &Atn,
13765 transition: ParserTransition<'_>,
13766 predicates: &[(usize, usize, ParserPredicate)],
13767 visited: &mut BTreeSet<usize>,
13768) -> bool {
13769 match &transition.data() {
13770 Transition::Predicate {
13771 rule_index,
13772 pred_index,
13773 ..
13774 } => !predicates
13775 .iter()
13776 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
13777 Transition::Epsilon { target }
13778 | Transition::Action { target, .. }
13779 | Transition::Rule { target, .. } => {
13780 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
13781 }
13782 Transition::Precedence { .. }
13783 | Transition::Atom { .. }
13784 | Transition::Range { .. }
13785 | Transition::Set { .. }
13786 | Transition::NotSet { .. }
13787 | Transition::Wildcard { .. } => false,
13788 }
13789}
13790
13791fn state_reaches_unsupported_predicate(
13793 atn: &Atn,
13794 state_number: usize,
13795 predicates: &[(usize, usize, ParserPredicate)],
13796 visited: &mut BTreeSet<usize>,
13797) -> bool {
13798 if !visited.insert(state_number) {
13799 return false;
13800 }
13801 let Some(state) = atn.state(state_number) else {
13802 return false;
13803 };
13804 state.transitions().iter().any(|transition| {
13805 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
13806 })
13807}
13808
13809fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
13811 if let Some(decision) = decision {
13812 outcome.decisions.insert(0, decision);
13813 }
13814}
13815
13816fn outcome_is_better(
13817 outcome_position: (usize, bool),
13818 outcome_diagnostics: DiagnosticSeqId,
13819 best_position: (usize, bool),
13820 best_diagnostics: DiagnosticSeqId,
13821 arena: &RecognitionArena,
13822) -> bool {
13823 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
13824 let best_len = arena.diagnostics_len(best_diagnostics);
13825 outcome_position > best_position
13826 || (outcome_position == best_position
13827 && (outcome_len < best_len
13828 || (outcome_len == best_len
13829 && arena.diagnostics_recovery_rank(outcome_diagnostics)
13830 < arena.diagnostics_recovery_rank(best_diagnostics))))
13831}
13832
13833fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
13834 if outcomes
13835 .iter()
13836 .any(|outcome| outcome.diagnostics.is_empty())
13837 {
13838 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
13839 }
13840}
13841
13842fn discard_recovered_outcomes_if_clean_path_exists(
13843 outcomes: &mut Vec<RecognizeOutcome>,
13844 arena: &RecognitionArena,
13845) {
13846 if outcomes
13847 .iter()
13848 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
13849 {
13850 return;
13851 }
13852 if outcomes
13853 .iter()
13854 .any(|outcome| outcome.diagnostics.is_empty())
13855 {
13856 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
13857 }
13858}
13859
13860fn outcome_has_rule_failure_diagnostic(
13863 outcome: &RecognizeOutcome,
13864 arena: &RecognitionArena,
13865) -> bool {
13866 arena
13867 .diagnostics(outcome.diagnostics)
13868 .any(|diagnostic| diagnostic.message.starts_with("rule "))
13869}
13870
13871fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
13885 if outcomes.len() < 2 {
13886 return;
13887 }
13888 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
13889 outcomes.retain(|outcome| {
13890 seen.insert((
13891 outcome.index,
13892 outcome.consumed_eof,
13893 arena.diagnostics_len(outcome.diagnostics),
13894 arena.diagnostics_recovery_rank(outcome.diagnostics),
13895 ))
13896 });
13897}
13898
13899const FAST_OUTCOME_INLINE_KEYS: usize = 8;
13900const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
13901const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
13902const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
13903
13904#[derive(Clone, Copy, Debug, Eq, PartialEq)]
13905enum FastOutcomeDedupStrategy {
13906 Inline,
13907 Dense,
13908 Sparse,
13909}
13910
13911impl FastOutcomeDedupScratch {
13912 fn prepare_dense(&mut self, word_count: usize) {
13913 while let Some(word_index) = self.touched_dense_words.pop() {
13914 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
13915 }
13916 if self.dense_words.len() < word_count {
13917 self.dense_words.resize(word_count, 0);
13918 }
13919 }
13920}
13921
13922fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
13923 let first_index = outcomes.first()?.index;
13924 let (min_index, max_index) = outcomes[1..].iter().fold(
13925 (first_index, first_index),
13926 |(min_index, max_index), outcome| {
13927 (min_index.min(outcome.index), max_index.max(outcome.index))
13928 },
13929 );
13930 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
13931 let bit_count = index_span.checked_mul(2)?;
13932 let word_count =
13933 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
13934 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
13935 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
13936 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
13937 .then_some((min_index, word_count))
13938}
13939
13940#[cfg(feature = "perf-counters")]
13941fn record_clean_fast_outcome_dedup(
13942 strategy: FastOutcomeDedupStrategy,
13943 input_len: usize,
13944 output_len: usize,
13945 dense_words: usize,
13946) {
13947 let counter = match strategy {
13948 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
13949 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
13950 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
13951 };
13952 perf_counters::inc(
13953 &perf_counters::OUTCOME_DEDUPE_INPUTS,
13954 u64::try_from(input_len).unwrap_or(u64::MAX),
13955 );
13956 perf_counters::inc(
13957 &perf_counters::OUTCOME_DEDUPE_REMOVED,
13958 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
13959 );
13960 perf_counters::inc(counter, 1);
13961 perf_counters::inc(
13962 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
13963 u64::try_from(dense_words).unwrap_or(u64::MAX),
13964 );
13965}
13966
13967fn dedupe_clean_fast_outcomes(
13971 outcomes: &mut Vec<FastRecognizeOutcome>,
13972 scratch: &mut FastOutcomeDedupScratch,
13973) -> FastOutcomeDedupStrategy {
13974 #[cfg(feature = "perf-counters")]
13975 let input_len = outcomes.len();
13976 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
13977 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
13978 let mut inline_len = 0_usize;
13979 outcomes.retain(|outcome| {
13980 let key = (outcome.index, outcome.consumed_eof);
13981 if inline_keys[..inline_len].contains(&key) {
13982 return false;
13983 }
13984 inline_keys[inline_len] = key;
13985 inline_len += 1;
13986 true
13987 });
13988 #[cfg(feature = "perf-counters")]
13989 record_clean_fast_outcome_dedup(
13990 FastOutcomeDedupStrategy::Inline,
13991 input_len,
13992 outcomes.len(),
13993 0,
13994 );
13995 return FastOutcomeDedupStrategy::Inline;
13996 }
13997
13998 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
13999 scratch.prepare_dense(word_count);
14000 outcomes.retain(|outcome| {
14001 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
14002 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
14003 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
14004 let word = &mut scratch.dense_words[word_index];
14005 if *word & bit != 0 {
14006 return false;
14007 }
14008 if *word == 0 {
14009 scratch
14010 .touched_dense_words
14011 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
14012 }
14013 *word |= bit;
14014 true
14015 });
14016 #[cfg(feature = "perf-counters")]
14017 record_clean_fast_outcome_dedup(
14018 FastOutcomeDedupStrategy::Dense,
14019 input_len,
14020 outcomes.len(),
14021 word_count,
14022 );
14023 return FastOutcomeDedupStrategy::Dense;
14024 }
14025
14026 scratch.sparse_keys.clear();
14027 scratch.sparse_keys.reserve(outcomes.len());
14028 outcomes.retain(|outcome| {
14029 scratch
14030 .sparse_keys
14031 .insert((outcome.index, outcome.consumed_eof))
14032 });
14033 #[cfg(feature = "perf-counters")]
14034 record_clean_fast_outcome_dedup(
14035 FastOutcomeDedupStrategy::Sparse,
14036 input_len,
14037 outcomes.len(),
14038 0,
14039 );
14040 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
14041 scratch.sparse_keys = FxHashSet::default();
14042 }
14043 FastOutcomeDedupStrategy::Sparse
14044}
14045
14046fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
14049 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
14050 outcomes
14051 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
14052}
14053
14054fn compare_recognize_outcomes(
14055 left: &RecognizeOutcome,
14056 right: &RecognizeOutcome,
14057 arena: &RecognitionArena,
14058) -> Ordering {
14059 left.index
14060 .cmp(&right.index)
14061 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
14062 .then_with(|| left.alt_number.cmp(&right.alt_number))
14063 .then_with(|| left.member_values.cmp(&right.member_values))
14064 .then_with(|| left.return_values.cmp(&right.return_values))
14065 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
14066 .then_with(|| left.decisions.cmp(&right.decisions))
14067 .then_with(|| left.actions.cmp(&right.actions))
14068 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
14069}
14070
14071impl<S, H> Recognizer for BaseParser<S, H>
14072where
14073 S: TokenSource,
14074 H: SemanticHooks,
14075{
14076 fn data(&self) -> &RecognizerData {
14077 &self.data
14078 }
14079
14080 fn data_mut(&mut self) -> &mut RecognizerData {
14081 &mut self.data
14082 }
14083}
14084
14085impl<S, H> Parser for BaseParser<S, H>
14086where
14087 S: TokenSource,
14088 H: SemanticHooks,
14089{
14090 fn build_parse_trees(&self) -> bool {
14091 self.build_parse_trees
14092 }
14093
14094 fn set_build_parse_trees(&mut self, build: bool) {
14095 self.build_parse_trees = build;
14096 }
14097
14098 fn number_of_syntax_errors(&self) -> usize {
14099 Self::number_of_syntax_errors(self)
14100 }
14101
14102 fn report_diagnostic_errors(&self) -> bool {
14103 self.report_diagnostic_errors
14104 }
14105
14106 fn set_report_diagnostic_errors(&mut self, report: bool) {
14107 self.report_diagnostic_errors = report;
14108 }
14109
14110 fn prediction_mode(&self) -> PredictionMode {
14111 self.prediction_mode
14112 }
14113
14114 fn set_prediction_mode(&mut self, mode: PredictionMode) {
14115 self.prediction_mode = mode;
14116 }
14117
14118 fn max_rule_depth(&self) -> Option<usize> {
14119 self.max_rule_depth
14120 }
14121
14122 fn set_max_rule_depth(&mut self, depth: Option<usize>) {
14123 self.max_rule_depth = depth;
14124 }
14125
14126 fn add_parse_listener(&mut self, listener: Box<dyn ParseListener>) {
14127 self.parse_listeners.push(ParseListenerSlot(listener));
14128 }
14129
14130 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
14131 Self::remove_parse_listeners(self)
14132 }
14133}
14134
14135#[cfg(test)]
14136#[allow(clippy::disallowed_methods)] mod tests {
14138 use super::*;
14139 use crate::atn::parser::{
14140 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
14141 };
14142 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
14143 use crate::token::{HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError};
14144 use crate::token_stream::CommonTokenStream;
14145 use crate::tree::{NodeKind, ParseTreeStats};
14146 use crate::vocabulary::Vocabulary;
14147 use std::cell::RefCell;
14148 use std::mem::size_of;
14149 use std::rc::Rc;
14150 use std::sync::{Arc, Mutex};
14151
14152 #[test]
14153 fn fx_hasher_write_matches_typed_methods_for_full_words() {
14154 let value: u64 = 0x0102_0304_0506_0708;
14161 let mut typed = FxHasher::default();
14162 typed.write_u64(value);
14163 let mut bytewise = FxHasher::default();
14164 bytewise.write(&value.to_le_bytes());
14165 assert_eq!(typed.finish(), bytewise.finish());
14166 }
14167
14168 #[derive(Clone, Debug)]
14169 struct TestToken {
14170 spec: TokenSpec,
14171 id: TokenId,
14172 source_name: String,
14173 }
14174
14175 impl TestToken {
14176 fn new(token_type: i32) -> Self {
14177 Self {
14178 spec: TokenSpec::explicit(token_type, ""),
14179 id: TokenId::try_from(0).expect("zero token ID"),
14180 source_name: String::new(),
14181 }
14182 }
14183
14184 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
14185 Self {
14186 spec: TokenSpec::eof(index, index, line, column),
14187 id: TokenId::try_from(0).expect("zero token ID"),
14188 source_name: source_name.to_owned(),
14189 }
14190 }
14191
14192 fn with_text(mut self, text: impl Into<String>) -> Self {
14193 self.spec.text = Some(text.into());
14194 self
14195 }
14196
14197 const fn with_channel(mut self, channel: i32) -> Self {
14198 self.spec.channel = channel;
14199 self
14200 }
14201
14202 fn with_span(mut self, start: usize, stop: usize) -> Self {
14203 self.spec = self.spec.with_span(start, stop);
14204 self
14205 }
14206
14207 fn with_byte_span(mut self, start: usize, stop: usize) -> Self {
14208 self.spec = self.spec.with_byte_span(start, stop);
14209 self
14210 }
14211
14212 const fn with_position(mut self, line: usize, column: usize) -> Self {
14213 self.spec.line = line;
14214 self.spec.column = column;
14215 self
14216 }
14217
14218 fn set_token_index(&mut self, index: isize) {
14219 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
14220 }
14221 }
14222
14223 impl Token for TestToken {
14224 fn token_id(&self) -> TokenId {
14225 self.id
14226 }
14227
14228 fn token_type(&self) -> i32 {
14229 self.spec.token_type
14230 }
14231
14232 fn channel(&self) -> i32 {
14233 self.spec.channel
14234 }
14235
14236 fn start(&self) -> usize {
14237 self.spec.start
14238 }
14239
14240 fn stop(&self) -> usize {
14241 self.spec.stop
14242 }
14243
14244 fn line(&self) -> usize {
14245 self.spec.line
14246 }
14247
14248 fn column(&self) -> usize {
14249 self.spec.column
14250 }
14251
14252 fn text(&self) -> Option<&str> {
14253 self.spec.text.as_deref()
14254 }
14255
14256 fn source_name(&self) -> &str {
14257 &self.source_name
14258 }
14259
14260 fn start_byte(&self) -> Option<usize> {
14261 (self.spec.start_byte != usize::MAX).then_some(self.spec.start_byte)
14262 }
14263
14264 fn stop_byte(&self) -> Option<usize> {
14265 (self.spec.stop_byte != usize::MAX).then_some(self.spec.stop_byte)
14266 }
14267 }
14268
14269 #[derive(Debug)]
14270 struct Source {
14271 tokens: Vec<TestToken>,
14272 index: usize,
14273 }
14274
14275 impl TokenSource for Source {
14276 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
14277 let token = self
14278 .tokens
14279 .get(self.index)
14280 .cloned()
14281 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
14282 self.index += 1;
14283 sink.push(token.spec)
14284 }
14285
14286 fn line(&self) -> usize {
14287 1
14288 }
14289
14290 fn column(&self) -> usize {
14291 self.index
14292 }
14293
14294 fn source_name(&self) -> &'static str {
14295 "parser-test"
14296 }
14297 }
14298
14299 #[derive(Clone, Debug, Eq, PartialEq)]
14300 struct RecordedDiagnostic {
14301 grammar_file_name: String,
14302 offending_text: Option<String>,
14303 line: usize,
14304 column: usize,
14305 span: Option<std::ops::Range<usize>>,
14306 message: String,
14307 error: Option<AntlrError>,
14308 }
14309
14310 #[derive(Clone, Debug)]
14311 struct RecordingErrorListener {
14312 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
14313 }
14314
14315 impl<R> crate::ErrorListener<R> for RecordingErrorListener
14316 where
14317 R: Recognizer + ?Sized,
14318 {
14319 fn syntax_error(&mut self, recognizer: &R, event: &SyntaxErrorEvent<'_>) {
14320 self.diagnostics
14321 .lock()
14322 .expect("recorded diagnostics lock")
14323 .push(RecordedDiagnostic {
14324 grammar_file_name: recognizer.grammar_file_name().to_owned(),
14325 offending_text: event
14326 .offending
14327 .and_then(|token| token.text().map(str::to_owned)),
14328 line: event.line,
14329 column: event.column,
14330 span: event.span.clone(),
14331 message: event.message.to_owned(),
14332 error: event.error.cloned(),
14333 });
14334 }
14335 }
14336
14337 #[derive(Debug)]
14338 struct ReportingSource {
14339 source: Source,
14340 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
14341 }
14342
14343 impl TokenSource for ReportingSource {
14344 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
14345 self.source.next_token(sink)
14346 }
14347
14348 fn line(&self) -> usize {
14349 self.source.line()
14350 }
14351
14352 fn column(&self) -> usize {
14353 self.source.column()
14354 }
14355
14356 fn source_name(&self) -> &str {
14357 self.source.source_name()
14358 }
14359
14360 fn report_error(&self, error: &TokenSourceError) -> bool {
14361 self.diagnostics.borrow_mut().push(error.clone());
14362 true
14363 }
14364 }
14365
14366 fn mini_parser_data() -> RecognizerData {
14367 RecognizerData::new(
14368 "Mini.g4",
14369 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
14370 )
14371 .with_rule_names(["s"])
14372 }
14373
14374 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
14375 let data = mini_parser_data();
14376 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
14377 }
14378
14379 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
14380 where
14381 H: SemanticHooks,
14382 {
14383 BaseParser::with_semantic_hooks(
14384 CommonTokenStream::new(Source { tokens, index: 0 }),
14385 mini_parser_data(),
14386 hooks,
14387 )
14388 }
14389
14390 #[test]
14391 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
14392 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
14393 parser.remove_error_listeners();
14394 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14395 parser.add_error_listener(RecordingErrorListener {
14396 diagnostics: Arc::clone(&diagnostics),
14397 });
14398 let parser_diagnostics = [ParserDiagnostic {
14399 line: 1,
14400 column: 2,
14401 message: "missing 'x' at 'y'".to_owned(),
14402 offending: None,
14403 }];
14404 let token_errors = [
14405 TokenSourceError::new(1, 1, "token recognition error at: '@'").with_span(1..2),
14406 TokenSourceError::new(1, 3, "token recognition error at: '#'").with_span(3..4),
14407 ];
14408
14409 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
14410
14411 insta::assert_debug_snapshot!(
14414 "parser_dispatches_recovery_diagnostics_through_registered_listeners",
14415 *diagnostics.lock().expect("recorded diagnostics lock")
14416 );
14417
14418 parser.remove_error_listeners();
14419 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
14420 assert_eq!(
14421 diagnostics.lock().expect("recorded diagnostics lock").len(),
14422 3
14423 );
14424 }
14425
14426 #[test]
14427 fn recovery_diagnostics_expose_the_offending_token_to_listeners() {
14428 let mut parser = mini_parser(vec![
14429 TestToken::new(7)
14430 .with_text("oops")
14431 .with_span(0, 3)
14432 .with_byte_span(0, 4)
14433 .with_position(1, 2),
14434 TestToken::eof("parser-test", 4, 1, 6),
14435 ]);
14436 parser.remove_error_listeners();
14437 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14438 parser.add_error_listener(RecordingErrorListener {
14439 diagnostics: Arc::clone(&diagnostics),
14440 });
14441 let offending = parser.input.lt_id(1);
14442 assert!(offending.is_some(), "current token should be buffered");
14443 let parser_diagnostics = [ParserDiagnostic {
14444 line: 1,
14445 column: 2,
14446 message: "extraneous input 'oops'".to_owned(),
14447 offending,
14448 }];
14449
14450 parser.dispatch_generated_diagnostics(&parser_diagnostics, &[]);
14451
14452 let recorded = diagnostics
14456 .lock()
14457 .expect("recorded diagnostics lock")
14458 .clone();
14459 insta::assert_debug_snapshot!(
14460 "recovery_diagnostics_expose_the_offending_token_to_listeners",
14461 recorded
14462 );
14463 }
14464
14465 #[test]
14466 fn recovery_diagnostics_preserve_unknown_custom_token_span() {
14467 let mut parser = mini_parser(vec![
14468 TestToken::new(7)
14469 .with_text("oops")
14470 .with_span(0, 3)
14471 .with_position(1, 2),
14472 TestToken::eof("parser-test", 4, 1, 6),
14473 ]);
14474 parser.remove_error_listeners();
14475 let diagnostics = Arc::new(Mutex::new(Vec::new()));
14476 parser.add_error_listener(RecordingErrorListener {
14477 diagnostics: Arc::clone(&diagnostics),
14478 });
14479 let offending = parser.input.lt_id(1);
14480 assert!(offending.is_some(), "current token should be buffered");
14481
14482 parser.dispatch_parser_diagnostic(&ParserDiagnostic {
14483 line: 1,
14484 column: 2,
14485 message: "extraneous input 'oops'".to_owned(),
14486 offending,
14487 });
14488
14489 let span = {
14490 let diagnostics = diagnostics.lock().expect("recorded diagnostics lock");
14491 assert_eq!(diagnostics.len(), 1);
14492 diagnostics[0].span.clone()
14493 };
14494 assert_eq!(span, None);
14495 }
14496
14497 #[test]
14498 fn parser_leaves_token_errors_to_source_owned_listeners() {
14499 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
14500 let source = ReportingSource {
14501 source: Source {
14502 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
14503 index: 0,
14504 },
14505 diagnostics: Rc::clone(&source_diagnostics),
14506 };
14507 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
14508 parser.remove_error_listeners();
14509 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
14510 parser.add_error_listener(RecordingErrorListener {
14511 diagnostics: Arc::clone(&parser_diagnostics),
14512 });
14513 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
14514
14515 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
14516
14517 assert_eq!(*source_diagnostics.borrow(), [source_error]);
14518 assert!(
14519 parser_diagnostics
14520 .lock()
14521 .expect("recorded diagnostics lock")
14522 .is_empty()
14523 );
14524 }
14525
14526 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
14527 builder.finish().expect("valid packed parser ATN")
14528 }
14529
14530 fn nested_rule_chain_atn(depth: usize) -> Atn {
14531 nested_rule_graph_atn(depth, false, false)
14532 }
14533
14534 fn nested_rule_graph_atn(depth: usize, branching: bool, consuming_follows: bool) -> Atn {
14535 assert!(depth > 0);
14536 let mut atn = ParserAtnBuilder::new(2);
14537 let mut starts = Vec::with_capacity(depth);
14538 let mut stops = Vec::with_capacity(depth);
14539 let mut follows = Vec::with_capacity(depth.saturating_sub(1));
14540 for rule_index in 0..depth {
14541 starts.push(
14542 atn.add_state(AtnStateKind::RuleStart, Some(rule_index))
14543 .expect("rule start")
14544 .index(),
14545 );
14546 }
14547 for rule_index in 0..depth {
14548 stops.push(
14549 atn.add_state(AtnStateKind::RuleStop, Some(rule_index))
14550 .expect("rule stop")
14551 .index(),
14552 );
14553 }
14554 if consuming_follows {
14555 for rule_index in 0..depth - 1 {
14556 follows.push(
14557 atn.add_state(AtnStateKind::Basic, Some(rule_index))
14558 .expect("rule follow")
14559 .index(),
14560 );
14561 }
14562 }
14563 atn.set_rule_to_start_state(starts.clone())
14564 .expect("rule start states");
14565 atn.set_rule_to_stop_state(stops.clone())
14566 .expect("rule stop states");
14567 for rule_index in 0..depth - 1 {
14568 let follow_state = if consuming_follows {
14569 follows[rule_index]
14570 } else {
14571 stops[rule_index]
14572 };
14573 atn.add_transition(
14574 starts[rule_index],
14575 ParserTransitionSpec::Rule {
14576 target: starts[rule_index + 1],
14577 rule_index: rule_index + 1,
14578 follow_state,
14579 precedence: 0,
14580 },
14581 )
14582 .expect("nested rule transition");
14583 if branching {
14584 atn.add_transition(
14585 starts[rule_index],
14586 ParserTransitionSpec::Atom {
14587 target: stops[rule_index],
14588 label: 2,
14589 },
14590 )
14591 .expect("dead branch transition");
14592 }
14593 if consuming_follows {
14594 atn.add_transition(
14595 follow_state,
14596 ParserTransitionSpec::Atom {
14597 target: stops[rule_index],
14598 label: 1,
14599 },
14600 )
14601 .expect("consuming follow transition");
14602 }
14603 }
14604 let token_set = atn.add_interval_set([(1, 1)]).expect("token set");
14605 atn.add_transition(
14606 starts[depth - 1],
14607 ParserTransitionSpec::Set {
14608 target: stops[depth - 1],
14609 set: token_set,
14610 },
14611 )
14612 .expect("terminal set transition");
14613 if branching {
14614 atn.add_transition(
14615 starts[depth - 1],
14616 ParserTransitionSpec::Atom {
14617 target: stops[depth - 1],
14618 label: 2,
14619 },
14620 )
14621 .expect("dead leaf branch transition");
14622 }
14623 finish_atn(atn)
14624 }
14625
14626 fn ordinary_star_loop_atn() -> Atn {
14627 let mut atn = ParserAtnBuilder::new(2);
14628 for (state_number, kind, rule_index) in [
14629 (0, AtnStateKind::RuleStart, 0),
14630 (1, AtnStateKind::StarLoopEntry, 0),
14631 (2, AtnStateKind::Basic, 0),
14632 (3, AtnStateKind::StarLoopBack, 0),
14633 (4, AtnStateKind::LoopEnd, 0),
14634 (5, AtnStateKind::Basic, 0),
14635 (6, AtnStateKind::RuleStop, 0),
14636 (7, AtnStateKind::RuleStart, 1),
14637 (8, AtnStateKind::Basic, 1),
14638 (9, AtnStateKind::RuleStop, 1),
14639 ] {
14640 assert_eq!(
14641 atn.add_state(kind, Some(rule_index))
14642 .expect("state")
14643 .index(),
14644 state_number
14645 );
14646 }
14647 atn.set_rule_to_start_state(vec![0, 7])
14648 .expect("rule start states");
14649 atn.set_rule_to_stop_state(vec![6, 9])
14650 .expect("rule stop states");
14651 atn.add_decision_state(1).expect("decision state");
14652 atn.set_loop_back_state(4, 3).expect("loop back state");
14653 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14654 .expect("transition");
14655 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14656 .expect("transition");
14657 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
14658 .expect("transition");
14659 atn.add_transition(
14660 2,
14661 ParserTransitionSpec::Rule {
14662 target: 7,
14663 rule_index: 1,
14664 follow_state: 3,
14665 precedence: 0,
14666 },
14667 )
14668 .expect("transition");
14669 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
14670 .expect("transition");
14671 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14672 .expect("transition");
14673 atn.add_transition(
14674 5,
14675 ParserTransitionSpec::Atom {
14676 target: 6,
14677 label: TOKEN_EOF,
14678 },
14679 )
14680 .expect("transition");
14681 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
14682 .expect("transition");
14683 atn.add_transition(
14684 8,
14685 ParserTransitionSpec::Atom {
14686 target: 9,
14687 label: 1,
14688 },
14689 )
14690 .expect("transition");
14691 finish_atn(atn)
14692 }
14693
14694 fn ambiguous_ordinary_star_loop_atn() -> Atn {
14696 let mut atn = ParserAtnBuilder::new(1);
14697 for (state_number, kind) in [
14698 (0, AtnStateKind::RuleStart),
14699 (1, AtnStateKind::StarLoopEntry),
14700 (2, AtnStateKind::StarBlockStart),
14701 (3, AtnStateKind::Basic),
14702 (4, AtnStateKind::BlockEnd),
14703 (5, AtnStateKind::StarLoopBack),
14704 (6, AtnStateKind::LoopEnd),
14705 (7, AtnStateKind::Basic),
14706 (8, AtnStateKind::RuleStop),
14707 ] {
14708 assert_eq!(
14709 atn.add_state(kind, Some(0)).expect("state").index(),
14710 state_number
14711 );
14712 }
14713 atn.set_rule_to_start_state(vec![0])
14714 .expect("rule start states");
14715 atn.set_rule_to_stop_state(vec![8])
14716 .expect("rule stop states");
14717 atn.set_end_state(2, 4).expect("block end state");
14718 atn.set_loop_back_state(6, 5).expect("loop back state");
14719 atn.add_decision_state(1).expect("decision state");
14720 atn.add_decision_state(2).expect("decision state");
14721 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14722 .expect("transition");
14723 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14724 .expect("transition");
14725 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
14726 .expect("transition");
14727 atn.add_transition(
14728 2,
14729 ParserTransitionSpec::Atom {
14730 target: 4,
14731 label: 1,
14732 },
14733 )
14734 .expect("transition");
14735 atn.add_transition(
14736 2,
14737 ParserTransitionSpec::Atom {
14738 target: 3,
14739 label: 1,
14740 },
14741 )
14742 .expect("transition");
14743 atn.add_transition(
14744 3,
14745 ParserTransitionSpec::Atom {
14746 target: 4,
14747 label: 1,
14748 },
14749 )
14750 .expect("transition");
14751 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14752 .expect("transition");
14753 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
14754 .expect("transition");
14755 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
14756 .expect("transition");
14757 atn.add_transition(
14758 7,
14759 ParserTransitionSpec::Atom {
14760 target: 8,
14761 label: TOKEN_EOF,
14762 },
14763 )
14764 .expect("transition");
14765 finish_atn(atn)
14766 }
14767
14768 fn ordinary_plus_loop_atn() -> Atn {
14769 let mut atn = ParserAtnBuilder::new(2);
14770 for (state_number, kind, rule_index) in [
14771 (0, AtnStateKind::RuleStart, 0),
14772 (1, AtnStateKind::Basic, 0),
14773 (2, AtnStateKind::PlusLoopBack, 0),
14774 (3, AtnStateKind::LoopEnd, 0),
14775 (4, AtnStateKind::Basic, 0),
14776 (5, AtnStateKind::RuleStop, 0),
14777 (6, AtnStateKind::RuleStart, 1),
14778 (7, AtnStateKind::Basic, 1),
14779 (8, AtnStateKind::RuleStop, 1),
14780 ] {
14781 assert_eq!(
14782 atn.add_state(kind, Some(rule_index))
14783 .expect("state")
14784 .index(),
14785 state_number
14786 );
14787 }
14788 atn.set_rule_to_start_state(vec![0, 6])
14789 .expect("rule start states");
14790 atn.set_rule_to_stop_state(vec![5, 8])
14791 .expect("rule stop states");
14792 atn.add_decision_state(2).expect("decision state");
14793 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14794 .expect("transition");
14795 atn.add_transition(
14796 1,
14797 ParserTransitionSpec::Rule {
14798 target: 6,
14799 rule_index: 1,
14800 follow_state: 2,
14801 precedence: 0,
14802 },
14803 )
14804 .expect("transition");
14805 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
14806 .expect("transition");
14807 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
14808 .expect("transition");
14809 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
14810 .expect("transition");
14811 atn.add_transition(
14812 4,
14813 ParserTransitionSpec::Atom {
14814 target: 5,
14815 label: TOKEN_EOF,
14816 },
14817 )
14818 .expect("transition");
14819 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
14820 .expect("transition");
14821 atn.add_transition(
14822 7,
14823 ParserTransitionSpec::Atom {
14824 target: 8,
14825 label: 1,
14826 },
14827 )
14828 .expect("transition");
14829 finish_atn(atn)
14830 }
14831
14832 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
14833 let mut tokens = (0..count)
14834 .map(|_| TestToken::new(1).with_text("x"))
14835 .collect::<Vec<_>>();
14836 tokens.push(TestToken::eof("parser-test", count, 1, count));
14837 tokens
14838 }
14839
14840 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
14841 let mut atn = ParserAtnBuilder::new(2);
14842 assert_eq!(
14843 atn.add_state(AtnStateKind::RuleStart, Some(0))
14844 .expect("state")
14845 .index(),
14846 0
14847 );
14848 assert_eq!(
14849 atn.add_state(AtnStateKind::Basic, Some(0))
14850 .expect("state")
14851 .index(),
14852 1
14853 );
14854 assert_eq!(
14855 atn.add_state(AtnStateKind::Basic, Some(0))
14856 .expect("state")
14857 .index(),
14858 2
14859 );
14860 assert_eq!(
14861 atn.add_state(AtnStateKind::RuleStart, Some(1))
14862 .expect("state")
14863 .index(),
14864 3
14865 );
14866 atn.set_left_recursive_rule(3)
14867 .expect("left-recursive rule start");
14868 assert_eq!(
14869 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
14870 .expect("state")
14871 .index(),
14872 4
14873 );
14874 atn.set_precedence_rule_decision(4)
14875 .expect("precedence decision");
14876 assert_eq!(
14877 atn.add_state(AtnStateKind::Basic, Some(1))
14878 .expect("state")
14879 .index(),
14880 5
14881 );
14882 assert_eq!(
14883 atn.add_state(AtnStateKind::Basic, Some(1))
14884 .expect("state")
14885 .index(),
14886 6
14887 );
14888 assert_eq!(
14889 atn.add_state(AtnStateKind::LoopEnd, Some(1))
14890 .expect("state")
14891 .index(),
14892 7
14893 );
14894 assert_eq!(
14895 atn.add_state(AtnStateKind::RuleStop, Some(1))
14896 .expect("state")
14897 .index(),
14898 8
14899 );
14900 assert_eq!(
14901 atn.add_state(AtnStateKind::RuleStop, Some(0))
14902 .expect("state")
14903 .index(),
14904 9
14905 );
14906 atn.set_rule_to_start_state(vec![0, 3])
14907 .expect("rule start states");
14908 atn.set_rule_to_stop_state(vec![9, 8])
14909 .expect("rule stop states");
14910 atn.add_transition(
14911 1,
14912 ParserTransitionSpec::Rule {
14913 target: 3,
14914 rule_index: 1,
14915 follow_state: 2,
14916 precedence: 0,
14917 },
14918 )
14919 .expect("transition");
14920 atn.add_transition(
14921 2,
14922 ParserTransitionSpec::Atom {
14923 target: 9,
14924 label: caller_symbol,
14925 },
14926 )
14927 .expect("transition");
14928 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14929 .expect("transition");
14930 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
14931 .expect("transition");
14932 atn.add_transition(
14933 5,
14934 ParserTransitionSpec::Precedence {
14935 target: 6,
14936 precedence: 1,
14937 },
14938 )
14939 .expect("transition");
14940 atn.add_transition(
14941 6,
14942 ParserTransitionSpec::Atom {
14943 target: 4,
14944 label: 1,
14945 },
14946 )
14947 .expect("transition");
14948 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
14949 .expect("transition");
14950 finish_atn(atn)
14951 }
14952
14953 fn labeled_left_recursive_operator_atn() -> Atn {
14954 let mut atn = ParserAtnBuilder::new(4);
14955 for (state, kind) in [
14956 (0, AtnStateKind::RuleStart),
14957 (1, AtnStateKind::BlockStart),
14958 (2, AtnStateKind::StarLoopEntry),
14959 (3, AtnStateKind::StarBlockStart),
14960 (4, AtnStateKind::Basic),
14961 (5, AtnStateKind::Basic),
14962 (6, AtnStateKind::Basic),
14963 (7, AtnStateKind::StarLoopBack),
14964 (8, AtnStateKind::LoopEnd),
14965 (9, AtnStateKind::RuleStop),
14966 ] {
14967 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
14968 }
14969 atn.set_left_recursive_rule(0)
14970 .expect("left-recursive rule start");
14971 atn.set_precedence_rule_decision(2)
14972 .expect("precedence decision");
14973 atn.set_loop_back_state(8, 7).expect("loop-back state");
14974 atn.set_rule_to_start_state(vec![0])
14975 .expect("rule start states");
14976 atn.set_rule_to_stop_state(vec![9])
14977 .expect("rule stop states");
14978 for state in [1, 2, 3] {
14979 atn.add_decision_state(state).expect("decision state");
14980 }
14981 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
14982 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
14983 .expect("epsilon transition");
14984 }
14985 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3), (6, 7, 1)] {
14986 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
14987 .expect("token transition");
14988 }
14989 for (target, precedence) in [(4, 2), (5, 1)] {
14990 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
14991 .expect("operator precedence");
14992 }
14993 finish_atn(atn)
14994 }
14995
14996 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
14997 let mut parser = mini_parser(vec![
14998 TestToken::new(symbol).with_text("lookahead"),
14999 TestToken::eof("parser-test", 1, 1, 1),
15000 ]);
15001 parser.rule_context_stack = vec![
15002 RuleContextFrame {
15003 rule_index: 0,
15004 invoking_state: -1,
15005 },
15006 RuleContextFrame {
15007 rule_index: 1,
15008 invoking_state: 1,
15009 },
15010 ];
15011 parser
15012 }
15013
15014 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
15015 let mut atn = ParserAtnBuilder::new(1);
15019 for (state, kind, rule) in [
15020 (0, AtnStateKind::RuleStart, 0),
15021 (1, AtnStateKind::StarLoopEntry, 0),
15022 (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),
15029 (9, AtnStateKind::RuleStop, 0),
15030 ] {
15031 assert_eq!(
15032 atn.add_state(kind, Some(rule)).expect("state").index(),
15033 state
15034 );
15035 if state == 0 {
15036 atn.set_left_recursive_rule(state)
15037 .expect("left-recursive rule start");
15038 } else if state == 1 {
15039 atn.set_precedence_rule_decision(state)
15040 .expect("precedence decision");
15041 }
15042 }
15043 atn.set_rule_to_start_state(vec![0])
15044 .expect("rule start states");
15045 atn.set_rule_to_stop_state(vec![9])
15046 .expect("rule stop states");
15047 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15048 .expect("ops");
15049 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
15050 .expect("exit");
15051 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15052 .expect("to shift");
15053 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15054 .expect("to rel");
15055 atn.add_transition(
15056 3,
15057 ParserTransitionSpec::Precedence {
15058 target: 4,
15059 precedence: 2,
15060 },
15061 )
15062 .expect("shift prec");
15063 atn.add_transition(
15064 4,
15065 ParserTransitionSpec::Atom {
15066 target: 5,
15067 label: 1,
15068 },
15069 )
15070 .expect("shift first >");
15071 atn.add_transition(
15072 5,
15073 ParserTransitionSpec::Atom {
15074 target: 1,
15075 label: 1,
15076 },
15077 )
15078 .expect("shift second >");
15079 atn.add_transition(
15080 6,
15081 ParserTransitionSpec::Precedence {
15082 target: 7,
15083 precedence: 1,
15084 },
15085 )
15086 .expect("rel prec");
15087 atn.add_transition(
15088 7,
15089 ParserTransitionSpec::Atom {
15090 target: 1,
15091 label: 1,
15092 },
15093 )
15094 .expect("rel >");
15095 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15096 .expect("loop end");
15097 finish_atn(atn)
15098 }
15099
15100 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
15101 let mut atn = ParserAtnBuilder::new(2);
15102 for (state, kind, rule) in [
15103 (0, AtnStateKind::RuleStart, 0),
15104 (1, AtnStateKind::StarLoopEntry, 0),
15105 (2, AtnStateKind::Basic, 0),
15106 (3, AtnStateKind::Basic, 0),
15107 (4, AtnStateKind::Basic, 0),
15108 (5, AtnStateKind::Basic, 0),
15109 (6, AtnStateKind::Basic, 0),
15110 (7, AtnStateKind::Basic, 0),
15111 (8, AtnStateKind::LoopEnd, 0),
15112 (9, AtnStateKind::RuleStop, 0),
15113 (10, AtnStateKind::RuleStart, 1),
15114 (11, AtnStateKind::Basic, 1),
15115 (12, AtnStateKind::RuleStop, 1),
15116 ] {
15117 assert_eq!(
15118 atn.add_state(kind, Some(rule)).expect("state").index(),
15119 state
15120 );
15121 if state == 0 {
15122 atn.set_left_recursive_rule(state)
15123 .expect("left-recursive rule start");
15124 } else if state == 1 {
15125 atn.set_precedence_rule_decision(state)
15126 .expect("precedence decision");
15127 }
15128 }
15129 atn.set_rule_to_start_state(vec![0, 10])
15130 .expect("rule start states");
15131 atn.set_rule_to_stop_state(vec![9, 12])
15132 .expect("rule stop states");
15133 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15134 .expect("ops");
15135 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
15136 .expect("exit");
15137 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15138 .expect("to shift");
15139 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15140 .expect("to relational");
15141 atn.add_transition(
15142 3,
15143 ParserTransitionSpec::Precedence {
15144 target: 4,
15145 precedence: 2,
15146 },
15147 )
15148 .expect("shift precedence");
15149 atn.add_transition(
15150 4,
15151 ParserTransitionSpec::Rule {
15152 target: 10,
15153 rule_index: 1,
15154 follow_state: 5,
15155 precedence: 0,
15156 },
15157 )
15158 .expect("first shift token helper");
15159 atn.add_transition(
15160 5,
15161 ParserTransitionSpec::Atom {
15162 target: 1,
15163 label: 1,
15164 },
15165 )
15166 .expect("second shift token");
15167 atn.add_transition(
15168 6,
15169 ParserTransitionSpec::Precedence {
15170 target: 7,
15171 precedence: 1,
15172 },
15173 )
15174 .expect("relational precedence");
15175 atn.add_transition(
15176 7,
15177 ParserTransitionSpec::Atom {
15178 target: 1,
15179 label: 1,
15180 },
15181 )
15182 .expect("relational token");
15183 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15184 .expect("loop end");
15185 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
15186 .expect("helper entry");
15187 atn.add_transition(
15188 11,
15189 ParserTransitionSpec::Atom {
15190 target: 12,
15191 label: 1,
15192 },
15193 )
15194 .expect("first shift token");
15195 finish_atn(atn)
15196 }
15197
15198 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
15199 let mut atn = ParserAtnBuilder::new(1);
15200 for (state, kind) in [
15201 (0, AtnStateKind::RuleStart),
15202 (1, AtnStateKind::StarLoopEntry),
15203 (2, AtnStateKind::Basic),
15204 (3, AtnStateKind::Basic),
15205 (4, AtnStateKind::Basic),
15206 (5, AtnStateKind::Basic),
15207 (6, AtnStateKind::Basic),
15208 (7, AtnStateKind::Basic),
15209 (8, AtnStateKind::Basic),
15210 (9, AtnStateKind::LoopEnd),
15211 (10, AtnStateKind::RuleStop),
15212 ] {
15213 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15214 if state == 0 {
15215 atn.set_left_recursive_rule(state)
15216 .expect("left-recursive rule start");
15217 } else if state == 1 {
15218 atn.set_precedence_rule_decision(state)
15219 .expect("precedence decision");
15220 }
15221 }
15222 atn.set_rule_to_start_state(vec![0])
15223 .expect("rule start states");
15224 atn.set_rule_to_stop_state(vec![10])
15225 .expect("rule stop states");
15226 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15227 .expect("ops");
15228 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
15229 .expect("exit");
15230 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
15231 .expect("to multi-token operator");
15232 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
15233 .expect("to predicate operator");
15234 atn.add_transition(
15235 3,
15236 ParserTransitionSpec::Precedence {
15237 target: 4,
15238 precedence: 2,
15239 },
15240 )
15241 .expect("multi-token precedence");
15242 atn.add_transition(
15243 4,
15244 ParserTransitionSpec::Atom {
15245 target: 5,
15246 label: 1,
15247 },
15248 )
15249 .expect("multi-token first");
15250 atn.add_transition(
15251 5,
15252 ParserTransitionSpec::Atom {
15253 target: 1,
15254 label: 1,
15255 },
15256 )
15257 .expect("multi-token second");
15258 atn.add_transition(
15259 6,
15260 ParserTransitionSpec::Precedence {
15261 target: 7,
15262 precedence: 2,
15263 },
15264 )
15265 .expect("predicate precedence");
15266 atn.add_transition(
15267 7,
15268 ParserTransitionSpec::Predicate {
15269 target: 8,
15270 rule_index: 0,
15271 pred_index: 0,
15272 context_dependent: false,
15273 },
15274 )
15275 .expect("operator predicate");
15276 atn.add_transition(
15277 8,
15278 ParserTransitionSpec::Atom {
15279 target: 1,
15280 label: 1,
15281 },
15282 )
15283 .expect("predicate single token");
15284 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15285 .expect("loop end");
15286 finish_atn(atn)
15287 }
15288
15289 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
15290 let mut atn = ParserAtnBuilder::new(2);
15291 for (state, kind, rule) in [
15292 (0, AtnStateKind::RuleStart, 0),
15293 (1, AtnStateKind::StarLoopEntry, 0),
15294 (2, AtnStateKind::Basic, 0),
15295 (3, AtnStateKind::Basic, 0),
15296 (4, AtnStateKind::Basic, 0),
15297 (5, AtnStateKind::LoopEnd, 0),
15298 (6, AtnStateKind::RuleStop, 0),
15299 (7, AtnStateKind::RuleStart, 1),
15300 (8, AtnStateKind::RuleStop, 1),
15301 (9, AtnStateKind::Basic, 1),
15302 ] {
15303 assert_eq!(
15304 atn.add_state(kind, Some(rule)).expect("state").index(),
15305 state
15306 );
15307 if state == 0 {
15308 atn.set_left_recursive_rule(state)
15309 .expect("left-recursive rule start");
15310 } else if state == 1 {
15311 atn.set_precedence_rule_decision(state)
15312 .expect("precedence decision");
15313 }
15314 }
15315 atn.set_rule_to_start_state(vec![0, 7])
15316 .expect("rule start states");
15317 atn.set_rule_to_stop_state(vec![6, 8])
15318 .expect("rule stop states");
15319 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15320 .expect("transition");
15321 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
15322 .expect("transition");
15323 atn.add_transition(
15324 2,
15325 ParserTransitionSpec::Precedence {
15326 target: 3,
15327 precedence: 3,
15328 },
15329 )
15330 .expect("transition");
15331 atn.add_transition(
15332 3,
15333 ParserTransitionSpec::Rule {
15334 target: 7,
15335 rule_index: 1,
15336 follow_state: 4,
15337 precedence: 0,
15338 },
15339 )
15340 .expect("transition");
15341 atn.add_transition(
15342 4,
15343 ParserTransitionSpec::Atom {
15344 target: 1,
15345 label: 1,
15346 },
15347 )
15348 .expect("transition");
15349 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15350 .expect("transition");
15351 atn.add_transition(
15352 7,
15353 ParserTransitionSpec::Precedence {
15354 target: 9,
15355 precedence: 1,
15356 },
15357 )
15358 .expect("transition");
15359 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
15360 .expect("transition");
15361 finish_atn(atn)
15362 }
15363
15364 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
15365 let mut atn = ParserAtnBuilder::new(2);
15366 for (state, kind) in [
15367 (0, AtnStateKind::RuleStart),
15368 (1, AtnStateKind::StarLoopEntry),
15369 (2, AtnStateKind::Basic),
15370 (3, AtnStateKind::Basic),
15371 (4, AtnStateKind::Basic),
15372 (5, AtnStateKind::LoopEnd),
15373 (6, AtnStateKind::RuleStop),
15374 ] {
15375 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
15376 if state == 0 {
15377 atn.set_left_recursive_rule(state)
15378 .expect("left-recursive rule start");
15379 } else if state == 1 {
15380 atn.set_precedence_rule_decision(state)
15381 .expect("precedence decision");
15382 }
15383 }
15384 atn.set_rule_to_start_state(vec![0])
15385 .expect("rule start states");
15386 atn.set_rule_to_stop_state(vec![6])
15387 .expect("rule stop states");
15388 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15389 .expect("transition");
15390 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
15391 .expect("transition");
15392 atn.add_transition(
15393 2,
15394 ParserTransitionSpec::Precedence {
15395 target: 3,
15396 precedence: 1,
15397 },
15398 )
15399 .expect("transition");
15400 atn.add_transition(
15401 3,
15402 ParserTransitionSpec::Predicate {
15403 target: 4,
15404 rule_index: 0,
15405 pred_index: 0,
15406 context_dependent: false,
15407 },
15408 )
15409 .expect("transition");
15410 atn.add_transition(
15411 4,
15412 ParserTransitionSpec::Atom {
15413 target: 1,
15414 label: 1,
15415 },
15416 )
15417 .expect("transition");
15418 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15419 .expect("transition");
15420 finish_atn(atn)
15421 }
15422
15423 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
15424 let mut atn = ParserAtnBuilder::new(2);
15425 for (state, kind, rule) in [
15426 (0, AtnStateKind::RuleStart, 0),
15427 (1, AtnStateKind::Basic, 0),
15428 (2, AtnStateKind::Basic, 0),
15429 (3, AtnStateKind::Basic, 0),
15430 (4, AtnStateKind::RuleStop, 0),
15431 (5, AtnStateKind::RuleStart, 1),
15432 (6, AtnStateKind::StarLoopEntry, 1),
15433 (7, AtnStateKind::Basic, 1),
15434 (8, AtnStateKind::Basic, 1),
15435 (9, AtnStateKind::LoopEnd, 1),
15436 (10, AtnStateKind::RuleStop, 1),
15437 (11, AtnStateKind::RuleStart, 2),
15438 (12, AtnStateKind::RuleStop, 2),
15439 ] {
15440 assert_eq!(
15441 atn.add_state(kind, Some(rule)).expect("state").index(),
15442 state
15443 );
15444 if state == 5 {
15445 atn.set_left_recursive_rule(state)
15446 .expect("left-recursive rule start");
15447 } else if state == 6 {
15448 atn.set_precedence_rule_decision(state)
15449 .expect("precedence decision");
15450 }
15451 }
15452 atn.set_rule_to_start_state(vec![0, 5, 11])
15453 .expect("rule start states");
15454 atn.set_rule_to_stop_state(vec![4, 10, 12])
15455 .expect("rule stop states");
15456 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15457 .expect("transition");
15458 atn.add_transition(
15459 1,
15460 ParserTransitionSpec::Rule {
15461 target: 5,
15462 rule_index: 1,
15463 follow_state: 2,
15464 precedence: 0,
15465 },
15466 )
15467 .expect("transition");
15468 atn.add_transition(
15469 2,
15470 ParserTransitionSpec::Rule {
15471 target: 11,
15472 rule_index: 2,
15473 follow_state: 3,
15474 precedence: 0,
15475 },
15476 )
15477 .expect("transition");
15478 atn.add_transition(
15479 3,
15480 ParserTransitionSpec::Atom {
15481 target: 4,
15482 label: caller_symbol,
15483 },
15484 )
15485 .expect("transition");
15486 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15487 .expect("transition");
15488 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
15489 .expect("transition");
15490 atn.add_transition(
15491 7,
15492 ParserTransitionSpec::Precedence {
15493 target: 8,
15494 precedence: 1,
15495 },
15496 )
15497 .expect("transition");
15498 atn.add_transition(
15499 8,
15500 ParserTransitionSpec::Atom {
15501 target: 6,
15502 label: 1,
15503 },
15504 )
15505 .expect("transition");
15506 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15507 .expect("transition");
15508 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
15509 .expect("transition");
15510 finish_atn(atn)
15511 }
15512
15513 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
15514 let mut atn = ParserAtnBuilder::new(2);
15515 for (state, kind, rule) in [
15516 (0, AtnStateKind::RuleStart, 0),
15517 (1, AtnStateKind::Basic, 0),
15518 (2, AtnStateKind::Basic, 0),
15519 (3, AtnStateKind::RuleStop, 0),
15520 (4, AtnStateKind::RuleStart, 1),
15521 (5, AtnStateKind::Basic, 1),
15522 (6, AtnStateKind::Basic, 1),
15523 (7, AtnStateKind::RuleStop, 1),
15524 (8, AtnStateKind::RuleStart, 2),
15525 (9, AtnStateKind::StarLoopEntry, 2),
15526 (10, AtnStateKind::Basic, 2),
15527 (11, AtnStateKind::Basic, 2),
15528 (12, AtnStateKind::LoopEnd, 2),
15529 (13, AtnStateKind::RuleStop, 2),
15530 ] {
15531 assert_eq!(
15532 atn.add_state(kind, Some(rule)).expect("state").index(),
15533 state
15534 );
15535 if state == 8 {
15536 atn.set_left_recursive_rule(state)
15537 .expect("left-recursive rule start");
15538 } else if state == 9 {
15539 atn.set_precedence_rule_decision(state)
15540 .expect("precedence decision");
15541 }
15542 }
15543 atn.set_rule_to_start_state(vec![0, 4, 8])
15544 .expect("rule start states");
15545 atn.set_rule_to_stop_state(vec![3, 7, 13])
15546 .expect("rule stop states");
15547 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15548 .expect("transition");
15549 atn.add_transition(
15550 1,
15551 ParserTransitionSpec::Rule {
15552 target: 4,
15553 rule_index: 1,
15554 follow_state: 2,
15555 precedence: 0,
15556 },
15557 )
15558 .expect("transition");
15559 atn.add_transition(
15560 2,
15561 ParserTransitionSpec::Atom {
15562 target: 3,
15563 label: caller_symbol,
15564 },
15565 )
15566 .expect("transition");
15567 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15568 .expect("transition");
15569 atn.add_transition(
15570 5,
15571 ParserTransitionSpec::Rule {
15572 target: 8,
15573 rule_index: 2,
15574 follow_state: 6,
15575 precedence: 0,
15576 },
15577 )
15578 .expect("transition");
15579 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
15580 .expect("transition");
15581 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
15582 .expect("transition");
15583 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
15584 .expect("transition");
15585 atn.add_transition(
15586 10,
15587 ParserTransitionSpec::Precedence {
15588 target: 11,
15589 precedence: 1,
15590 },
15591 )
15592 .expect("transition");
15593 atn.add_transition(
15594 11,
15595 ParserTransitionSpec::Atom {
15596 target: 9,
15597 label: 1,
15598 },
15599 )
15600 .expect("transition");
15601 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
15602 .expect("transition");
15603 finish_atn(atn)
15604 }
15605
15606 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
15607 let mut atn = ParserAtnBuilder::new(2);
15608 for (state, kind, rule) in [
15609 (0, AtnStateKind::RuleStart, 0),
15610 (1, AtnStateKind::Basic, 0),
15611 (2, AtnStateKind::Basic, 0),
15612 (3, AtnStateKind::RuleStop, 0),
15613 (4, AtnStateKind::RuleStart, 1),
15614 (5, AtnStateKind::StarLoopEntry, 1),
15615 (6, AtnStateKind::Basic, 1),
15616 (7, AtnStateKind::Basic, 1),
15617 (8, AtnStateKind::Basic, 1),
15618 (9, AtnStateKind::Basic, 1),
15619 (10, AtnStateKind::LoopEnd, 1),
15620 (11, AtnStateKind::RuleStop, 1),
15621 ] {
15622 assert_eq!(
15623 atn.add_state(kind, Some(rule)).expect("state").index(),
15624 state
15625 );
15626 if state == 4 {
15627 atn.set_left_recursive_rule(state)
15628 .expect("left-recursive rule start");
15629 } else if state == 5 {
15630 atn.set_precedence_rule_decision(state)
15631 .expect("precedence decision");
15632 }
15633 }
15634 atn.set_rule_to_start_state(vec![0, 4])
15635 .expect("rule start states");
15636 atn.set_rule_to_stop_state(vec![3, 11])
15637 .expect("rule stop states");
15638 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15639 .expect("transition");
15640 atn.add_transition(
15641 1,
15642 ParserTransitionSpec::Rule {
15643 target: 4,
15644 rule_index: 1,
15645 follow_state: 2,
15646 precedence: 0,
15647 },
15648 )
15649 .expect("transition");
15650 atn.add_transition(
15651 2,
15652 ParserTransitionSpec::Atom {
15653 target: 3,
15654 label: caller_symbol,
15655 },
15656 )
15657 .expect("transition");
15658 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
15659 .expect("transition");
15660 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
15661 .expect("transition");
15662 atn.add_transition(
15663 6,
15664 ParserTransitionSpec::Precedence {
15665 target: 7,
15666 precedence: 1,
15667 },
15668 )
15669 .expect("transition");
15670 atn.add_transition(
15671 7,
15672 ParserTransitionSpec::Atom {
15673 target: 8,
15674 label: 1,
15675 },
15676 )
15677 .expect("transition");
15678 atn.add_transition(
15679 8,
15680 ParserTransitionSpec::Rule {
15681 target: 4,
15682 rule_index: 1,
15683 follow_state: 9,
15684 precedence: 2,
15685 },
15686 )
15687 .expect("transition");
15688 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
15689 .expect("transition");
15690 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
15691 .expect("transition");
15692 finish_atn(atn)
15693 }
15694
15695 #[test]
15696 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
15697 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
15698 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
15699
15700 let mut overlapping = parser_inside_left_recursive_callee(1);
15701 assert_eq!(
15702 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
15703 None
15704 );
15705
15706 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
15707 assert_eq!(
15708 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
15709 Some(true)
15710 );
15711
15712 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
15713 assert_eq!(
15714 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
15715 Some(false)
15716 );
15717
15718 assert_eq!(
15719 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
15720 Some(true),
15721 "overlap results must not leak across ATNs"
15722 );
15723 }
15724
15725 #[test]
15726 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
15727 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
15728 let mut parser = mini_parser(vec![
15729 TestToken::new(1).with_text("operator"),
15730 TestToken::eof("parser-test", 1, 1, 1),
15731 ]);
15732 parser.rule_context_stack = vec![RuleContextFrame {
15733 rule_index: 0,
15734 invoking_state: -1,
15735 }];
15736
15737 assert_eq!(
15738 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
15739 Some(true)
15740 );
15741 assert_eq!(
15742 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
15743 Some(true),
15744 "cached operator lookahead must preserve the nullable prefix return path"
15745 );
15746 assert_eq!(
15747 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
15748 Some(true),
15749 "the nullable child must use its rule-call precedence, not the caller precedence"
15750 );
15751 }
15752
15753 #[test]
15754 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
15755 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
15760 let mut parser = mini_parser(vec![
15761 TestToken::new(1).with_text(">"),
15762 TestToken::new(2).with_text("id"),
15763 TestToken::eof("parser-test", 1, 1, 1),
15764 ]);
15765 parser.rule_context_stack = vec![RuleContextFrame {
15766 rule_index: 0,
15767 invoking_state: -1,
15768 }];
15769
15770 assert_eq!(
15771 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
15772 Some(true),
15773 "at low precedence relational `>` is a single-token operator"
15774 );
15775 assert_eq!(
15776 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
15777 Some(true),
15778 "relational remains single-token at its own precedence"
15779 );
15780 assert_eq!(
15781 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
15782 None,
15783 "at shift precedence, bare `>` must not force enter"
15784 );
15785 }
15786
15787 #[test]
15788 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
15789 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
15790 let mut parser = mini_parser(vec![
15791 TestToken::new(1).with_text(">"),
15792 TestToken::new(2).with_text("id"),
15793 TestToken::eof("parser-test", 1, 1, 1),
15794 ]);
15795 parser.rule_context_stack = vec![RuleContextFrame {
15796 rule_index: 0,
15797 invoking_state: -1,
15798 }];
15799
15800 assert_eq!(
15801 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
15802 Some(true),
15803 "the direct relational alternative remains a one-token operator"
15804 );
15805 assert_eq!(
15806 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
15807 None,
15808 "a token matched in the helper rule must return to the second shift token"
15809 );
15810 }
15811
15812 #[test]
15813 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
15814 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
15815 let mut parser = mini_parser(vec![
15816 TestToken::new(1).with_text(">"),
15817 TestToken::new(2).with_text("id"),
15818 TestToken::eof("parser-test", 1, 1, 1),
15819 ]);
15820 parser.rule_context_stack = vec![RuleContextFrame {
15821 rule_index: 0,
15822 invoking_state: -1,
15823 }];
15824
15825 assert_eq!(
15826 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
15827 None,
15828 "a predicate-gated single-token path must not be hidden by a multi-token path"
15829 );
15830 }
15831
15832 #[test]
15833 fn left_recursive_loop_defers_predicate_guarded_operator() {
15834 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
15835 let mut parser = mini_parser_with_hooks(
15836 vec![
15837 TestToken::new(1).with_text("operator"),
15838 TestToken::eof("parser-test", 1, 1, 1),
15839 ],
15840 RejectingPredicateHooks::default(),
15841 );
15842 parser.rule_context_stack = vec![RuleContextFrame {
15843 rule_index: 0,
15844 invoking_state: -1,
15845 }];
15846
15847 assert_eq!(
15848 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
15849 None,
15850 "a false predicate must be evaluated before entering the operator alternative"
15851 );
15852 assert_eq!(
15853 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
15854 None,
15855 "cached predicate-dependent lookahead must keep deferring"
15856 );
15857 }
15858
15859 #[test]
15860 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
15861 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
15862 let mut parser = parser_inside_left_recursive_callee(1);
15863
15864 assert_eq!(
15865 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
15866 None
15867 );
15868 assert_eq!(
15869 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
15870 None,
15871 "the cached overlap must preserve the nullable child return path"
15872 );
15873 }
15874
15875 #[test]
15876 fn left_recursive_loop_defers_through_nullable_parent_return() {
15877 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
15878 let mut parser = mini_parser(vec![
15879 TestToken::new(1).with_text("lookahead"),
15880 TestToken::eof("parser-test", 1, 1, 1),
15881 ]);
15882 parser.rule_context_stack = vec![
15883 RuleContextFrame {
15884 rule_index: 0,
15885 invoking_state: -1,
15886 },
15887 RuleContextFrame {
15888 rule_index: 1,
15889 invoking_state: 1,
15890 },
15891 RuleContextFrame {
15892 rule_index: 2,
15893 invoking_state: 5,
15894 },
15895 ];
15896
15897 assert_eq!(
15898 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
15899 None,
15900 "a nullable caller must unwind to its parent's consuming follow path"
15901 );
15902 assert_eq!(
15903 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
15904 None,
15905 "the caller-overlap cache must not retain a false negative"
15906 );
15907 }
15908
15909 #[test]
15910 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
15911 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
15912 let mut parser = mini_parser(vec![
15913 TestToken::new(1).with_text("lookahead"),
15914 TestToken::eof("parser-test", 1, 1, 1),
15915 ]);
15916 parser.rule_context_stack = vec![
15917 RuleContextFrame {
15918 rule_index: 0,
15919 invoking_state: -1,
15920 },
15921 RuleContextFrame {
15922 rule_index: 1,
15923 invoking_state: 1,
15924 },
15925 RuleContextFrame {
15926 rule_index: 1,
15927 invoking_state: 8,
15928 },
15929 ];
15930
15931 assert_eq!(
15932 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
15933 None,
15934 "a recursive operand return must preserve its parent caller context"
15935 );
15936 assert_eq!(
15937 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
15938 None,
15939 "the caller-overlap cache must preserve the loop-boundary return"
15940 );
15941 }
15942
15943 fn token_then_eof_atn() -> Atn {
15944 AtnDeserializer::new(&SerializedAtn::from_i32(&[
15945 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, ]))
15961 .deserialize_parser()
15962 .expect("artificial parser ATN should deserialize")
15963 }
15964
15965 fn epsilon_cycle_atn() -> Atn {
15966 let mut atn = ParserAtnBuilder::new(1);
15967 for (state_number, kind) in [
15968 (0, AtnStateKind::RuleStart),
15969 (1, AtnStateKind::Basic),
15970 (2, AtnStateKind::RuleStop),
15971 ] {
15972 assert_eq!(
15973 atn.add_state(kind, Some(0)).expect("state").index(),
15974 state_number
15975 );
15976 }
15977 atn.set_rule_to_start_state(vec![0])
15978 .expect("rule start states");
15979 atn.set_rule_to_stop_state(vec![2])
15980 .expect("rule stop states");
15981 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15982 .expect("transition");
15983 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
15984 .expect("self-cycle transition");
15985 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15986 .expect("exit transition");
15987 finish_atn(atn)
15988 }
15989
15990 fn committed_non_consuming_cycle_atn() -> Atn {
15991 let mut atn = ParserAtnBuilder::new(1);
15992 for (state_number, kind) in [
15993 (0, AtnStateKind::RuleStart),
15994 (1, AtnStateKind::Basic),
15995 (2, AtnStateKind::RuleStop),
15996 ] {
15997 assert_eq!(
15998 atn.add_state(kind, Some(0)).expect("state").index(),
15999 state_number
16000 );
16001 }
16002 atn.set_rule_to_start_state(vec![0])
16003 .expect("rule start states");
16004 atn.set_rule_to_stop_state(vec![2])
16005 .expect("rule stop states");
16006 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16007 .expect("cycle entry");
16008 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
16009 .expect("self-cycle transition");
16010 finish_atn(atn)
16011 }
16012
16013 fn eof_then_action_atn() -> Atn {
16014 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16015 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, ]))
16031 .deserialize_parser()
16032 .expect("artificial parser ATN should deserialize")
16033 }
16034
16035 fn noop_action_then_token_then_eof_atn() -> Atn {
16036 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16037 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, ]))
16055 .deserialize_parser()
16056 .expect("artificial no-op action ATN should deserialize")
16057 }
16058
16059 fn committed_action_then_predicate_atn() -> Atn {
16060 let mut atn = ParserAtnBuilder::new(1);
16061 for (state_number, kind) in [
16062 (0, AtnStateKind::RuleStart),
16063 (1, AtnStateKind::Basic),
16064 (2, AtnStateKind::Basic),
16065 (3, AtnStateKind::Basic),
16066 (4, AtnStateKind::RuleStop),
16067 ] {
16068 assert_eq!(
16069 atn.add_state(kind, Some(0)).expect("state").index(),
16070 state_number
16071 );
16072 }
16073 atn.set_rule_to_start_state(vec![0])
16074 .expect("rule start states");
16075 atn.set_rule_to_stop_state(vec![4])
16076 .expect("rule stop states");
16077 atn.add_transition(
16078 0,
16079 ParserTransitionSpec::Action {
16080 target: 1,
16081 rule_index: 0,
16082 action_index: None,
16083 context_dependent: false,
16084 },
16085 )
16086 .expect("action transition");
16087 atn.add_transition(
16088 1,
16089 ParserTransitionSpec::Predicate {
16090 target: 2,
16091 rule_index: 0,
16092 pred_index: 0,
16093 context_dependent: false,
16094 },
16095 )
16096 .expect("predicate transition");
16097 atn.add_transition(
16098 2,
16099 ParserTransitionSpec::Atom {
16100 target: 3,
16101 label: 1,
16102 },
16103 )
16104 .expect("token transition");
16105 atn.add_transition(
16106 3,
16107 ParserTransitionSpec::Atom {
16108 target: 4,
16109 label: TOKEN_EOF,
16110 },
16111 )
16112 .expect("EOF transition");
16113 finish_atn(atn)
16114 }
16115
16116 fn parameterized_child_action_eof_atn() -> Atn {
16118 let mut atn = ParserAtnBuilder::new(1);
16119 for (state_number, kind, rule_index) in [
16120 (0, AtnStateKind::RuleStart, 0),
16121 (1, AtnStateKind::Basic, 0),
16122 (2, AtnStateKind::Basic, 0),
16123 (3, AtnStateKind::RuleStop, 0),
16124 (4, AtnStateKind::RuleStart, 1),
16125 (5, AtnStateKind::Basic, 1),
16126 (6, AtnStateKind::RuleStop, 1),
16127 ] {
16128 assert_eq!(
16129 atn.add_state(kind, Some(rule_index))
16130 .expect("state")
16131 .index(),
16132 state_number
16133 );
16134 }
16135 atn.set_rule_to_start_state(vec![0, 4])
16136 .expect("rule start states");
16137 atn.set_rule_to_stop_state(vec![3, 6])
16138 .expect("rule stop states");
16139 atn.add_transition(
16140 0,
16141 ParserTransitionSpec::Rule {
16142 target: 4,
16143 rule_index: 1,
16144 follow_state: 1,
16145 precedence: 0,
16146 },
16147 )
16148 .expect("parameterized child call");
16149 atn.add_transition(
16150 1,
16151 ParserTransitionSpec::Action {
16152 target: 2,
16153 rule_index: 0,
16154 action_index: None,
16155 context_dependent: false,
16156 },
16157 )
16158 .expect("parent action");
16159 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
16160 .expect("parent stop");
16161 atn.add_transition(
16162 4,
16163 ParserTransitionSpec::Action {
16164 target: 5,
16165 rule_index: 1,
16166 action_index: None,
16167 context_dependent: false,
16168 },
16169 )
16170 .expect("child action");
16171 atn.add_transition(
16172 5,
16173 ParserTransitionSpec::Atom {
16174 target: 6,
16175 label: TOKEN_EOF,
16176 },
16177 )
16178 .expect("child EOF");
16179 finish_atn(atn)
16180 }
16181
16182 fn action_then_nested_rule_atn() -> Atn {
16183 let mut atn = ParserAtnBuilder::new(1);
16184 for (state_number, kind, rule_index) in [
16185 (0, AtnStateKind::RuleStart, 0),
16186 (1, AtnStateKind::Basic, 0),
16187 (2, AtnStateKind::Basic, 0),
16188 (3, AtnStateKind::RuleStop, 0),
16189 (4, AtnStateKind::RuleStart, 1),
16190 (5, AtnStateKind::RuleStop, 1),
16191 ] {
16192 assert_eq!(
16193 atn.add_state(kind, Some(rule_index))
16194 .expect("state")
16195 .index(),
16196 state_number
16197 );
16198 }
16199 atn.set_rule_to_start_state(vec![0, 4])
16200 .expect("rule start states");
16201 atn.set_rule_to_stop_state(vec![3, 5])
16202 .expect("rule stop states");
16203 atn.add_transition(
16204 0,
16205 ParserTransitionSpec::Action {
16206 target: 1,
16207 rule_index: 0,
16208 action_index: None,
16209 context_dependent: false,
16210 },
16211 )
16212 .expect("parent action");
16213 atn.add_transition(
16214 1,
16215 ParserTransitionSpec::Rule {
16216 target: 4,
16217 rule_index: 1,
16218 follow_state: 2,
16219 precedence: 0,
16220 },
16221 )
16222 .expect("nested rule call");
16223 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
16224 .expect("parent stop");
16225 atn.add_transition(
16226 4,
16227 ParserTransitionSpec::Atom {
16228 target: 5,
16229 label: TOKEN_EOF,
16230 },
16231 )
16232 .expect("child EOF");
16233 finish_atn(atn)
16234 }
16235
16236 fn losing_alternative_action_atn() -> Atn {
16237 let mut atn = ParserAtnBuilder::new(2);
16238 for (state_number, kind) in [
16239 (0, AtnStateKind::RuleStart),
16240 (1, AtnStateKind::BlockStart),
16241 (2, AtnStateKind::Basic),
16242 (3, AtnStateKind::Basic),
16243 (4, AtnStateKind::BlockEnd),
16244 (5, AtnStateKind::RuleStop),
16245 ] {
16246 assert_eq!(
16247 atn.add_state(kind, Some(0)).expect("state").index(),
16248 state_number
16249 );
16250 }
16251 atn.set_rule_to_start_state(vec![0])
16252 .expect("rule start states");
16253 atn.set_rule_to_stop_state(vec![5])
16254 .expect("rule stop states");
16255 atn.set_end_state(1, 4).expect("block end state");
16256 atn.add_decision_state(1).expect("decision state");
16257 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16258 .expect("entry transition");
16259 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16260 .expect("first alternative");
16261 atn.add_transition(
16262 1,
16263 ParserTransitionSpec::Atom {
16264 target: 4,
16265 label: 2,
16266 },
16267 )
16268 .expect("second alternative");
16269 atn.add_transition(
16270 2,
16271 ParserTransitionSpec::Action {
16272 target: 3,
16273 rule_index: 0,
16274 action_index: None,
16275 context_dependent: false,
16276 },
16277 )
16278 .expect("losing action");
16279 atn.add_transition(
16280 3,
16281 ParserTransitionSpec::Atom {
16282 target: 4,
16283 label: 1,
16284 },
16285 )
16286 .expect("first alternative token");
16287 atn.add_transition(
16288 4,
16289 ParserTransitionSpec::Atom {
16290 target: 5,
16291 label: TOKEN_EOF,
16292 },
16293 )
16294 .expect("EOF transition");
16295 finish_atn(atn)
16296 }
16297
16298 fn committed_action_star_loop_atn() -> Atn {
16299 let mut atn = ParserAtnBuilder::new(1);
16300 for (state_number, kind) in [
16301 (0, AtnStateKind::RuleStart),
16302 (1, AtnStateKind::StarLoopEntry),
16303 (2, AtnStateKind::Basic),
16304 (3, AtnStateKind::Basic),
16305 (4, AtnStateKind::StarLoopBack),
16306 (5, AtnStateKind::LoopEnd),
16307 (6, AtnStateKind::RuleStop),
16308 ] {
16309 assert_eq!(
16310 atn.add_state(kind, Some(0)).expect("state").index(),
16311 state_number
16312 );
16313 }
16314 atn.set_rule_to_start_state(vec![0])
16315 .expect("rule start states");
16316 atn.set_rule_to_stop_state(vec![6])
16317 .expect("rule stop states");
16318 atn.add_decision_state(1).expect("decision state");
16319 atn.set_loop_back_state(5, 4).expect("loop back state");
16320 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16321 .expect("entry transition");
16322 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16323 .expect("loop body");
16324 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
16325 .expect("loop exit");
16326 atn.add_transition(
16327 2,
16328 ParserTransitionSpec::Action {
16329 target: 3,
16330 rule_index: 0,
16331 action_index: None,
16332 context_dependent: false,
16333 },
16334 )
16335 .expect("loop action");
16336 atn.add_transition(
16337 3,
16338 ParserTransitionSpec::Atom {
16339 target: 4,
16340 label: 1,
16341 },
16342 )
16343 .expect("loop token");
16344 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
16345 .expect("loop back");
16346 atn.add_transition(
16347 5,
16348 ParserTransitionSpec::Atom {
16349 target: 6,
16350 label: TOKEN_EOF,
16351 },
16352 )
16353 .expect("EOF transition");
16354 finish_atn(atn)
16355 }
16356
16357 fn committed_action_left_recursive_atn() -> Atn {
16358 let mut atn = ParserAtnBuilder::new(4);
16359 for (state, kind) in [
16360 (0, AtnStateKind::RuleStart),
16361 (1, AtnStateKind::BlockStart),
16362 (2, AtnStateKind::StarLoopEntry),
16363 (3, AtnStateKind::StarBlockStart),
16364 (4, AtnStateKind::Basic),
16365 (5, AtnStateKind::Basic),
16366 (6, AtnStateKind::Basic),
16367 (7, AtnStateKind::StarLoopBack),
16368 (8, AtnStateKind::LoopEnd),
16369 (9, AtnStateKind::RuleStop),
16370 (10, AtnStateKind::Basic),
16371 ] {
16372 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
16373 }
16374 atn.set_left_recursive_rule(0)
16375 .expect("left-recursive rule start");
16376 atn.set_precedence_rule_decision(2)
16377 .expect("precedence decision");
16378 atn.set_loop_back_state(8, 7).expect("loop-back state");
16379 atn.set_rule_to_start_state(vec![0])
16380 .expect("rule start states");
16381 atn.set_rule_to_stop_state(vec![9])
16382 .expect("rule stop states");
16383 for state in [1, 2, 3] {
16384 atn.add_decision_state(state).expect("decision state");
16385 }
16386 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
16387 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
16388 .expect("epsilon transition");
16389 }
16390 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3)] {
16391 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
16392 .expect("token transition");
16393 }
16394 for (target, precedence) in [(4, 2), (5, 1)] {
16395 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
16396 .expect("operator precedence");
16397 }
16398 atn.add_transition(
16399 6,
16400 ParserTransitionSpec::Action {
16401 target: 10,
16402 rule_index: 0,
16403 action_index: None,
16404 context_dependent: false,
16405 },
16406 )
16407 .expect("operator action");
16408 atn.add_transition(
16409 10,
16410 ParserTransitionSpec::Atom {
16411 target: 7,
16412 label: 1,
16413 },
16414 )
16415 .expect("right operand");
16416 finish_atn(atn)
16417 }
16418
16419 fn two_alt_decision_atn() -> Atn {
16420 let mut atn = ParserAtnBuilder::new(2);
16421 assert_eq!(
16422 atn.add_state(AtnStateKind::RuleStart, Some(0))
16423 .expect("state")
16424 .index(),
16425 0
16426 );
16427 assert_eq!(
16428 atn.add_state(AtnStateKind::BlockStart, Some(0))
16429 .expect("state")
16430 .index(),
16431 1
16432 );
16433 assert_eq!(
16434 atn.add_state(AtnStateKind::Basic, Some(0))
16435 .expect("state")
16436 .index(),
16437 2
16438 );
16439 assert_eq!(
16440 atn.add_state(AtnStateKind::Basic, Some(0))
16441 .expect("state")
16442 .index(),
16443 3
16444 );
16445 assert_eq!(
16446 atn.add_state(AtnStateKind::BlockEnd, Some(0))
16447 .expect("state")
16448 .index(),
16449 4
16450 );
16451 assert_eq!(
16452 atn.add_state(AtnStateKind::RuleStop, Some(0))
16453 .expect("state")
16454 .index(),
16455 5
16456 );
16457 atn.set_rule_to_start_state(vec![0])
16458 .expect("rule start states");
16459 atn.set_rule_to_stop_state(vec![5])
16460 .expect("rule stop states");
16461 atn.add_decision_state(1).expect("decision state");
16462 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16463 .expect("transition");
16464 atn.add_transition(
16465 1,
16466 ParserTransitionSpec::Atom {
16467 target: 2,
16468 label: 1,
16469 },
16470 )
16471 .expect("transition");
16472 atn.add_transition(
16473 1,
16474 ParserTransitionSpec::Atom {
16475 target: 3,
16476 label: 2,
16477 },
16478 )
16479 .expect("transition");
16480 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
16481 .expect("transition");
16482 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
16483 .expect("transition");
16484 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
16485 .expect("transition");
16486 finish_atn(atn)
16487 }
16488
16489 fn optional_then_b_eof_atn() -> Atn {
16492 let mut atn = ParserAtnBuilder::new(3);
16493 assert_eq!(
16494 atn.add_state(AtnStateKind::RuleStart, Some(0))
16495 .expect("state")
16496 .index(),
16497 0
16498 );
16499 assert_eq!(
16500 atn.add_state(AtnStateKind::BlockStart, Some(0))
16501 .expect("state")
16502 .index(),
16503 1
16504 );
16505 assert_eq!(
16506 atn.add_state(AtnStateKind::Basic, Some(0))
16507 .expect("state")
16508 .index(),
16509 2
16510 );
16511 assert_eq!(
16512 atn.add_state(AtnStateKind::Basic, Some(0))
16513 .expect("state")
16514 .index(),
16515 3
16516 );
16517 assert_eq!(
16518 atn.add_state(AtnStateKind::Basic, Some(0))
16519 .expect("state")
16520 .index(),
16521 4
16522 );
16523 assert_eq!(
16524 atn.add_state(AtnStateKind::RuleStop, Some(0))
16525 .expect("state")
16526 .index(),
16527 5
16528 );
16529 atn.set_rule_to_start_state(vec![0])
16530 .expect("rule start states");
16531 atn.set_rule_to_stop_state(vec![5])
16532 .expect("rule stop states");
16533 atn.add_decision_state(1).expect("decision state");
16534 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16535 .expect("transition");
16536 atn.add_transition(
16538 1,
16539 ParserTransitionSpec::Atom {
16540 target: 3,
16541 label: 1,
16542 },
16543 )
16544 .expect("transition");
16545 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
16546 .expect("transition");
16547 atn.add_transition(
16549 3,
16550 ParserTransitionSpec::Atom {
16551 target: 4,
16552 label: 2,
16553 },
16554 )
16555 .expect("transition");
16556 atn.add_transition(
16557 4,
16558 ParserTransitionSpec::Atom {
16559 target: 5,
16560 label: TOKEN_EOF,
16561 },
16562 )
16563 .expect("transition");
16564 finish_atn(atn)
16565 }
16566
16567 #[test]
16568 fn sync_decision_deletes_only_a_single_token() {
16569 let atn = optional_then_b_eof_atn();
16577
16578 let mut single = mini_parser(vec![
16579 TestToken::new(3).with_text("c"),
16580 TestToken::new(2).with_text("b"),
16581 TestToken::eof("parser-test", 1, 2, 2),
16582 ]);
16583 single.rule_context_stack = vec![RuleContextFrame {
16584 rule_index: 0,
16585 invoking_state: 0,
16586 }];
16587 let children = single
16588 .sync_decision(&atn, 1, true, false)
16589 .expect("single extraneous token recovers");
16590 assert_eq!(children.len(), 1);
16591 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
16592 assert_eq!(single.number_of_syntax_errors(), 1);
16593 assert_eq!(single.la(1), 2);
16595
16596 let mut double = mini_parser(vec![
16597 TestToken::new(3).with_text("c"),
16598 TestToken::new(3).with_text("c"),
16599 TestToken::new(2).with_text("b"),
16600 TestToken::eof("parser-test", 1, 3, 3),
16601 ]);
16602 double.rule_context_stack = vec![RuleContextFrame {
16603 rule_index: 0,
16604 invoking_state: 0,
16605 }];
16606 let result = double.sync_decision(&atn, 1, true, false);
16607 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
16612 match error {
16613 AntlrError::ParserError { message, .. } => {
16614 assert!(message.starts_with("mismatched input"), "got: {message}");
16615 }
16616 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
16617 }
16618 assert_eq!(double.la(1), 3);
16619 }
16620
16621 fn star_loop_then_eof_atn() -> Atn {
16625 AtnDeserializer::new(&SerializedAtn::from_i32(&[
16626 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,
16627 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,
16628 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,
16629 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
16630 ]))
16631 .deserialize_parser()
16632 .expect("star-loop-then-EOF ATN should deserialize")
16633 }
16634
16635 fn nested_star_rule_atn() -> Atn {
16639 let mut atn = ParserAtnBuilder::new(2);
16640 for (state_number, kind, rule_index) in [
16641 (0, AtnStateKind::RuleStart, 0),
16642 (1, AtnStateKind::Basic, 0),
16643 (2, AtnStateKind::Basic, 0),
16644 (3, AtnStateKind::RuleStop, 0),
16645 (4, AtnStateKind::RuleStart, 1),
16646 (5, AtnStateKind::StarLoopEntry, 1),
16647 (6, AtnStateKind::Basic, 1),
16648 (7, AtnStateKind::StarLoopBack, 1),
16649 (8, AtnStateKind::LoopEnd, 1),
16650 (9, AtnStateKind::RuleStop, 1),
16651 ] {
16652 assert_eq!(
16653 atn.add_state(kind, Some(rule_index))
16654 .expect("state")
16655 .index(),
16656 state_number
16657 );
16658 }
16659 atn.set_rule_to_start_state(vec![0, 4])
16660 .expect("rule start states");
16661 atn.set_rule_to_stop_state(vec![3, 9])
16662 .expect("rule stop states");
16663 atn.add_decision_state(5).expect("decision state");
16664 atn.set_loop_back_state(8, 7).expect("loop back state");
16665 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16666 .expect("transition");
16667 atn.add_transition(
16668 1,
16669 ParserTransitionSpec::Rule {
16670 target: 4,
16671 rule_index: 1,
16672 follow_state: 2,
16673 precedence: 0,
16674 },
16675 )
16676 .expect("transition");
16677 atn.add_transition(
16678 2,
16679 ParserTransitionSpec::Atom {
16680 target: 3,
16681 label: TOKEN_EOF,
16682 },
16683 )
16684 .expect("transition");
16685 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
16686 .expect("transition");
16687 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
16688 .expect("transition");
16689 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 8 })
16690 .expect("transition");
16691 atn.add_transition(
16692 6,
16693 ParserTransitionSpec::Atom {
16694 target: 7,
16695 label: 1,
16696 },
16697 )
16698 .expect("transition");
16699 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 5 })
16700 .expect("transition");
16701 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
16702 .expect("transition");
16703 finish_atn(atn)
16704 }
16705
16706 fn plus_loop_with_recovering_body_atn() -> Atn {
16712 let mut atn = ParserAtnBuilder::new(2);
16713 assert_eq!(
16714 atn.add_state(AtnStateKind::RuleStart, Some(0))
16715 .expect("state")
16716 .index(),
16717 0
16718 );
16719 assert_eq!(
16720 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
16721 .expect("state")
16722 .index(),
16723 1
16724 );
16725 assert_eq!(
16726 atn.add_state(AtnStateKind::Basic, Some(0))
16727 .expect("state")
16728 .index(),
16729 2
16730 );
16731 assert_eq!(
16732 atn.add_state(AtnStateKind::BlockEnd, Some(0))
16733 .expect("state")
16734 .index(),
16735 3
16736 );
16737 assert_eq!(
16738 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
16739 .expect("state")
16740 .index(),
16741 4
16742 );
16743 assert_eq!(
16744 atn.add_state(AtnStateKind::LoopEnd, Some(0))
16745 .expect("state")
16746 .index(),
16747 5
16748 );
16749 assert_eq!(
16750 atn.add_state(AtnStateKind::RuleStop, Some(0))
16751 .expect("state")
16752 .index(),
16753 6
16754 );
16755 assert_eq!(
16756 atn.add_state(AtnStateKind::RuleStart, Some(1))
16757 .expect("state")
16758 .index(),
16759 7
16760 );
16761 assert_eq!(
16762 atn.add_state(AtnStateKind::Basic, Some(1))
16763 .expect("state")
16764 .index(),
16765 8
16766 );
16767 assert_eq!(
16768 atn.add_state(AtnStateKind::RuleStop, Some(1))
16769 .expect("state")
16770 .index(),
16771 9
16772 );
16773 atn.set_rule_to_start_state(vec![0, 7])
16774 .expect("rule start states");
16775 atn.set_rule_to_stop_state(vec![6, 9])
16776 .expect("rule stop states");
16777 atn.set_end_state(1, 3).expect("block end state");
16778 atn.set_loop_back_state(5, 4).expect("loop back state");
16779 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16780 .expect("transition");
16781 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
16782 .expect("transition");
16783 atn.add_transition(
16784 2,
16785 ParserTransitionSpec::Rule {
16786 target: 7,
16787 rule_index: 1,
16788 follow_state: 3,
16789 precedence: 0,
16790 },
16791 )
16792 .expect("transition");
16793 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
16794 .expect("transition");
16795 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
16796 .expect("transition");
16797 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
16798 .expect("transition");
16799 atn.add_transition(
16800 5,
16801 ParserTransitionSpec::Atom {
16802 target: 6,
16803 label: 2,
16804 },
16805 )
16806 .expect("transition");
16807 atn.add_transition(
16808 7,
16809 ParserTransitionSpec::Atom {
16810 target: 8,
16811 label: 1,
16812 },
16813 )
16814 .expect("transition");
16815 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
16816 .expect("transition");
16817 finish_atn(atn)
16818 }
16819
16820 #[test]
16821 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
16822 let atn = plus_loop_with_recovering_body_atn();
16823 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16824
16825 let error = parser
16826 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
16827 .expect_err("EOF recovery should report a bounded mismatch");
16828
16829 let AntlrError::ParserError { message, .. } = error else {
16830 panic!("expected ParserError, got {error:?}");
16831 };
16832 insta::assert_snapshot!(message, @"mismatched input '<EOF>' expecting {'x', 2}");
16833 assert_eq!(parser.number_of_syntax_errors(), 1);
16834 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
16835 }
16836
16837 #[test]
16838 fn sync_decision_deletes_token_before_eof_at_loop_back() {
16839 let atn = star_loop_then_eof_atn();
16845 let mut parser = mini_parser(vec![
16846 TestToken::new(2).with_text("c"),
16847 TestToken::eof("parser-test", 1, 1, 1),
16848 ]);
16849 parser.rule_context_stack = vec![RuleContextFrame {
16850 rule_index: 0,
16851 invoking_state: 0,
16852 }];
16853 let children = parser
16854 .sync_decision(&atn, 5, true, false)
16855 .expect("single token before EOF recovers");
16856 assert_eq!(children.len(), 1);
16857 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
16858 assert_eq!(parser.number_of_syntax_errors(), 1);
16859 assert_eq!(
16860 parser.la(1),
16861 TOKEN_EOF,
16862 "EOF is left for the rule's EOF match"
16863 );
16864 }
16865
16866 #[test]
16867 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
16868 let atn = star_loop_then_eof_atn();
16873 let mut parser = mini_parser(vec![
16874 TestToken::new(2).with_text("c"),
16875 TestToken::new(2).with_text("c"),
16876 TestToken::eof("parser-test", 1, 2, 2),
16877 ]);
16878 parser.rule_context_stack = vec![RuleContextFrame {
16879 rule_index: 0,
16880 invoking_state: 0,
16881 }];
16882 let error = parser
16883 .sync_decision(&atn, 5, true, false)
16884 .expect_err("two tokens at the loop entry must not be deleted");
16885 match error {
16886 AntlrError::ParserError { message, .. } => {
16887 assert!(message.starts_with("mismatched input"), "got: {message}");
16888 }
16889 other => panic!("expected mismatched-input ParserError, got {other:?}"),
16890 }
16891 assert_eq!(
16892 parser.la(1),
16893 2,
16894 "nothing consumed; cursor still on first `c`"
16895 );
16896 }
16897
16898 #[test]
16899 fn sync_decision_consumes_until_eof_at_loop_back() {
16900 let atn = star_loop_then_eof_atn();
16906 let mut parser = mini_parser(vec![
16907 TestToken::new(2).with_text("c"),
16908 TestToken::new(2).with_text("c"),
16909 TestToken::eof("parser-test", 1, 2, 2),
16910 ]);
16911 parser.rule_context_stack = vec![RuleContextFrame {
16912 rule_index: 0,
16913 invoking_state: 0,
16914 }];
16915 let children = parser
16916 .sync_decision(&atn, 5, false, true)
16917 .expect("loop-back multi-token deletion recovers onto EOF");
16918 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
16919 assert!(
16920 children
16921 .iter()
16922 .all(|child| parser.node(*child).kind() == NodeKind::Error)
16923 );
16924 assert_eq!(parser.number_of_syntax_errors(), 1);
16925 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
16926 }
16927
16928 #[test]
16929 fn sync_decision_returns_before_recovery_for_nullable_exit() {
16930 let atn = nested_star_rule_atn();
16931 for (current_context_empty, loop_back) in [(true, false), (false, true)] {
16932 let mut parser = mini_parser(vec![
16933 TestToken::new(2).with_text("c"),
16934 TestToken::new(1).with_text("a"),
16935 TestToken::eof("parser-test", 1, 2, 2),
16936 ]);
16937 parser.rule_context_stack = vec![
16938 RuleContextFrame {
16939 rule_index: 0,
16940 invoking_state: 0,
16941 },
16942 RuleContextFrame {
16943 rule_index: 1,
16944 invoking_state: 1,
16945 },
16946 ];
16947
16948 let children = parser
16949 .sync_decision(&atn, 5, current_context_empty, loop_back)
16950 .expect("nullable synchronization is a no-op");
16951
16952 assert!(children.is_empty());
16953 assert_eq!(parser.la(1), 2, "the caller must receive the current token");
16954 assert_eq!(parser.number_of_syntax_errors(), 0);
16955 assert_eq!(
16956 parser
16957 .generated_sync_expected
16958 .as_ref()
16959 .expect("nullable sync preserves expected symbols")
16960 .to_btree_set(),
16961 BTreeSet::from([TOKEN_EOF, 1])
16962 );
16963 }
16964 }
16965
16966 fn predicate_after_token_atn() -> Atn {
16967 let mut atn = ParserAtnBuilder::new(2);
16968 assert_eq!(
16969 atn.add_state(AtnStateKind::RuleStart, Some(0))
16970 .expect("state")
16971 .index(),
16972 0
16973 );
16974 assert_eq!(
16975 atn.add_state(AtnStateKind::Basic, Some(0))
16976 .expect("state")
16977 .index(),
16978 1
16979 );
16980 assert_eq!(
16981 atn.add_state(AtnStateKind::Basic, Some(0))
16982 .expect("state")
16983 .index(),
16984 2
16985 );
16986 assert_eq!(
16987 atn.add_state(AtnStateKind::Basic, Some(0))
16988 .expect("state")
16989 .index(),
16990 3
16991 );
16992 assert_eq!(
16993 atn.add_state(AtnStateKind::RuleStop, Some(0))
16994 .expect("state")
16995 .index(),
16996 4
16997 );
16998 atn.set_rule_to_start_state(vec![0])
16999 .expect("rule start states");
17000 atn.set_rule_to_stop_state(vec![4])
17001 .expect("rule stop states");
17002 atn.add_transition(
17003 0,
17004 ParserTransitionSpec::Atom {
17005 target: 1,
17006 label: 1,
17007 },
17008 )
17009 .expect("transition");
17010 atn.add_transition(
17011 1,
17012 ParserTransitionSpec::Predicate {
17013 target: 2,
17014 rule_index: 0,
17015 pred_index: 0,
17016 context_dependent: false,
17017 },
17018 )
17019 .expect("transition");
17020 atn.add_transition(
17021 2,
17022 ParserTransitionSpec::Atom {
17023 target: 3,
17024 label: 2,
17025 },
17026 )
17027 .expect("transition");
17028 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
17029 .expect("transition");
17030 finish_atn(atn)
17031 }
17032
17033 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
17034 let mut atn = ParserAtnBuilder::new(1);
17035 for (state_number, kind) in [
17036 (0, AtnStateKind::RuleStart),
17037 (1, AtnStateKind::BlockStart),
17038 (2, AtnStateKind::Basic),
17039 (3, AtnStateKind::Basic),
17040 (4, AtnStateKind::Basic),
17041 (5, AtnStateKind::Basic),
17042 (6, AtnStateKind::BlockEnd),
17043 (7, AtnStateKind::RuleStop),
17044 ] {
17045 assert_eq!(
17046 atn.add_state(kind, Some(0)).expect("state").index(),
17047 state_number
17048 );
17049 }
17050 atn.set_rule_to_start_state(vec![0])
17051 .expect("rule start states");
17052 atn.set_rule_to_stop_state(vec![7])
17053 .expect("rule stop states");
17054 atn.add_decision_state(1).expect("decision state");
17055 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17056 .expect("transition");
17057 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17058 .expect("transition");
17059 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17060 .expect("transition");
17061 atn.add_transition(
17062 2,
17063 ParserTransitionSpec::Predicate {
17064 target: 4,
17065 rule_index: 0,
17066 pred_index: pred_indexes[0],
17067 context_dependent: false,
17068 },
17069 )
17070 .expect("transition");
17071 atn.add_transition(
17072 3,
17073 ParserTransitionSpec::Predicate {
17074 target: 5,
17075 rule_index: 0,
17076 pred_index: pred_indexes[1],
17077 context_dependent: false,
17078 },
17079 )
17080 .expect("transition");
17081 atn.add_transition(
17082 4,
17083 ParserTransitionSpec::Atom {
17084 target: 6,
17085 label: 1,
17086 },
17087 )
17088 .expect("transition");
17089 atn.add_transition(
17090 5,
17091 ParserTransitionSpec::Atom {
17092 target: 6,
17093 label: 1,
17094 },
17095 )
17096 .expect("transition");
17097 atn.add_transition(
17098 6,
17099 ParserTransitionSpec::Atom {
17100 target: 7,
17101 label: TOKEN_EOF,
17102 },
17103 )
17104 .expect("transition");
17105 finish_atn(atn)
17106 }
17107
17108 fn semantic_fallback_viability_atn() -> Atn {
17110 let mut atn = ParserAtnBuilder::new(3);
17111 for (state_number, kind) in [
17112 (0, AtnStateKind::RuleStart),
17113 (1, AtnStateKind::BlockStart),
17114 (2, AtnStateKind::Basic),
17115 (3, AtnStateKind::Basic),
17116 (4, AtnStateKind::Basic),
17117 (5, AtnStateKind::Basic),
17118 (6, AtnStateKind::Basic),
17119 (7, AtnStateKind::Basic),
17120 (8, AtnStateKind::Basic),
17121 (9, AtnStateKind::BlockEnd),
17122 (10, AtnStateKind::RuleStop),
17123 ] {
17124 assert_eq!(
17125 atn.add_state(kind, Some(0)).expect("state").index(),
17126 state_number
17127 );
17128 }
17129 atn.set_rule_to_start_state(vec![0])
17130 .expect("rule start states");
17131 atn.set_rule_to_stop_state(vec![10])
17132 .expect("rule stop states");
17133 atn.set_end_state(1, 9).expect("block end state");
17134 atn.add_decision_state(1).expect("decision state");
17135 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17136 .expect("entry transition");
17137 atn.add_transition(
17138 1,
17139 ParserTransitionSpec::Atom {
17140 target: 2,
17141 label: 1,
17142 },
17143 )
17144 .expect("first alternative");
17145 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17146 .expect("second alternative");
17147 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
17148 .expect("third alternative");
17149 atn.add_transition(
17150 2,
17151 ParserTransitionSpec::Atom {
17152 target: 9,
17153 label: 2,
17154 },
17155 )
17156 .expect("first alternative suffix");
17157 for (source, target, pred_index) in [(3, 4, 0), (6, 7, 1)] {
17158 atn.add_transition(
17159 source,
17160 ParserTransitionSpec::Predicate {
17161 target,
17162 rule_index: 0,
17163 pred_index,
17164 context_dependent: false,
17165 },
17166 )
17167 .expect("predicate transition");
17168 }
17169 for (source, target, label) in [(4, 5, 1), (5, 9, 3), (7, 8, 1), (8, 9, 3)] {
17170 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
17171 .expect("predicate alternative token");
17172 }
17173 atn.add_transition(
17174 9,
17175 ParserTransitionSpec::Atom {
17176 target: 10,
17177 label: TOKEN_EOF,
17178 },
17179 )
17180 .expect("EOF transition");
17181 finish_atn(atn)
17182 }
17183
17184 fn rule_call_predicate_decision_atn() -> Atn {
17186 let mut atn = ParserAtnBuilder::new(1);
17187 for (state_number, kind, rule_index) in [
17188 (0, AtnStateKind::RuleStart, 0),
17189 (1, AtnStateKind::BlockStart, 0),
17190 (2, AtnStateKind::Basic, 0),
17191 (3, AtnStateKind::Basic, 0),
17192 (4, AtnStateKind::BlockEnd, 0),
17193 (5, AtnStateKind::RuleStop, 0),
17194 (6, AtnStateKind::RuleStart, 1),
17195 (7, AtnStateKind::Basic, 1),
17196 (8, AtnStateKind::RuleStop, 1),
17197 ] {
17198 assert_eq!(
17199 atn.add_state(kind, Some(rule_index))
17200 .expect("state")
17201 .index(),
17202 state_number
17203 );
17204 }
17205 atn.set_rule_to_start_state(vec![0, 6])
17206 .expect("rule start states");
17207 atn.set_rule_to_stop_state(vec![5, 8])
17208 .expect("rule stop states");
17209 atn.set_end_state(1, 4).expect("block end state");
17210 atn.add_decision_state(1).expect("decision state");
17211 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17212 .expect("entry transition");
17213 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17214 .expect("gated alternative entry");
17215 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
17216 .expect("direct alternative entry");
17217 atn.add_transition(
17218 2,
17219 ParserTransitionSpec::Rule {
17220 target: 6,
17221 rule_index: 1,
17222 follow_state: 4,
17223 precedence: 0,
17224 },
17225 )
17226 .expect("gated alternative");
17227 atn.add_transition(
17228 3,
17229 ParserTransitionSpec::Atom {
17230 target: 4,
17231 label: 1,
17232 },
17233 )
17234 .expect("direct alternative");
17235 atn.add_transition(
17236 4,
17237 ParserTransitionSpec::Atom {
17238 target: 5,
17239 label: TOKEN_EOF,
17240 },
17241 )
17242 .expect("EOF transition");
17243 atn.add_transition(
17244 6,
17245 ParserTransitionSpec::Predicate {
17246 target: 7,
17247 rule_index: 1,
17248 pred_index: 0,
17249 context_dependent: false,
17250 },
17251 )
17252 .expect("callee predicate");
17253 atn.add_transition(
17254 7,
17255 ParserTransitionSpec::Atom {
17256 target: 8,
17257 label: 1,
17258 },
17259 )
17260 .expect("callee token");
17261 finish_atn(atn)
17262 }
17263
17264 fn predicate_gated_star_loop_atn() -> Atn {
17266 let mut atn = ParserAtnBuilder::new(2);
17267 for (state_number, kind) in [
17268 (0, AtnStateKind::RuleStart),
17269 (1, AtnStateKind::StarLoopEntry),
17270 (2, AtnStateKind::Basic),
17271 (3, AtnStateKind::Basic),
17272 (4, AtnStateKind::StarLoopBack),
17273 (5, AtnStateKind::LoopEnd),
17274 (6, AtnStateKind::RuleStop),
17275 ] {
17276 assert_eq!(
17277 atn.add_state(kind, Some(0)).expect("state").index(),
17278 state_number
17279 );
17280 }
17281 atn.set_rule_to_start_state(vec![0])
17282 .expect("rule start states");
17283 atn.set_rule_to_stop_state(vec![6])
17284 .expect("rule stop states");
17285 atn.add_decision_state(1).expect("decision state");
17286 atn.set_loop_back_state(5, 4).expect("loop back state");
17287 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
17288 .expect("entry transition");
17289 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
17290 .expect("loop enter");
17291 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
17292 .expect("loop exit");
17293 atn.add_transition(
17294 2,
17295 ParserTransitionSpec::Predicate {
17296 target: 3,
17297 rule_index: 0,
17298 pred_index: 0,
17299 context_dependent: false,
17300 },
17301 )
17302 .expect("loop predicate");
17303 atn.add_transition(
17304 3,
17305 ParserTransitionSpec::Atom {
17306 target: 4,
17307 label: 1,
17308 },
17309 )
17310 .expect("loop token");
17311 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
17312 .expect("loop back");
17313 atn.add_transition(
17314 5,
17315 ParserTransitionSpec::Atom {
17316 target: 6,
17317 label: TOKEN_EOF,
17318 },
17319 )
17320 .expect("EOF transition");
17321 finish_atn(atn)
17322 }
17323
17324 fn nested_nullable_context_atn() -> Atn {
17325 let mut atn = ParserAtnBuilder::new(1);
17326 for state_number in 0..=20 {
17327 let kind = match state_number {
17328 0 | 10 | 16 => AtnStateKind::RuleStart,
17329 9 | 15 | 20 => AtnStateKind::RuleStop,
17330 _ => AtnStateKind::Basic,
17331 };
17332 let rule_index = match state_number {
17333 0..=9 => 0,
17334 10..=15 => 1,
17335 _ => 2,
17336 };
17337 assert_eq!(
17338 atn.add_state(kind, Some(rule_index))
17339 .expect("state")
17340 .index(),
17341 state_number
17342 );
17343 }
17344 atn.set_rule_to_start_state(vec![0, 10, 16])
17345 .expect("rule start states");
17346 atn.set_rule_to_stop_state(vec![9, 15, 20])
17347 .expect("rule stop states");
17348 atn.add_transition(
17349 1,
17350 ParserTransitionSpec::Rule {
17351 target: 10,
17352 rule_index: 1,
17353 follow_state: 8,
17354 precedence: 0,
17355 },
17356 )
17357 .expect("transition");
17358 atn.add_transition(
17359 8,
17360 ParserTransitionSpec::Atom {
17361 target: 9,
17362 label: 1,
17363 },
17364 )
17365 .expect("transition");
17366 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
17367 .expect("transition");
17368 atn.add_transition(
17369 2,
17370 ParserTransitionSpec::Rule {
17371 target: 16,
17372 rule_index: 2,
17373 follow_state: 14,
17374 precedence: 0,
17375 },
17376 )
17377 .expect("transition");
17378 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
17379 .expect("transition");
17380 finish_atn(atn)
17381 }
17382
17383 fn generated_match_recovery_atn() -> Atn {
17384 let mut atn = ParserAtnBuilder::new(2);
17385 assert_eq!(
17386 atn.add_state(AtnStateKind::RuleStart, Some(0))
17387 .expect("state")
17388 .index(),
17389 0
17390 );
17391 assert_eq!(
17392 atn.add_state(AtnStateKind::Basic, Some(0))
17393 .expect("state")
17394 .index(),
17395 1
17396 );
17397 assert_eq!(
17398 atn.add_state(AtnStateKind::Basic, Some(0))
17399 .expect("state")
17400 .index(),
17401 2
17402 );
17403 assert_eq!(
17404 atn.add_state(AtnStateKind::RuleStop, Some(0))
17405 .expect("state")
17406 .index(),
17407 3
17408 );
17409 assert_eq!(
17410 atn.add_state(AtnStateKind::RuleStart, Some(1))
17411 .expect("state")
17412 .index(),
17413 4
17414 );
17415 assert_eq!(
17416 atn.add_state(AtnStateKind::RuleStop, Some(1))
17417 .expect("state")
17418 .index(),
17419 5
17420 );
17421 atn.set_rule_to_start_state(vec![0, 4])
17422 .expect("rule start states");
17423 atn.set_rule_to_stop_state(vec![3, 5])
17424 .expect("rule stop states");
17425 atn.add_transition(
17426 1,
17427 ParserTransitionSpec::Rule {
17428 target: 4,
17429 rule_index: 1,
17430 follow_state: 2,
17431 precedence: 0,
17432 },
17433 )
17434 .expect("transition");
17435 atn.add_transition(
17436 2,
17437 ParserTransitionSpec::Atom {
17438 target: 3,
17439 label: TOKEN_EOF,
17440 },
17441 )
17442 .expect("transition");
17443 finish_atn(atn)
17444 }
17445
17446 fn complement_set_atn() -> Atn {
17447 let mut atn = ParserAtnBuilder::new(1);
17448 assert_eq!(
17449 atn.add_state(AtnStateKind::RuleStart, Some(0))
17450 .expect("state")
17451 .index(),
17452 0
17453 );
17454 assert_eq!(
17455 atn.add_state(AtnStateKind::RuleStop, Some(0))
17456 .expect("state")
17457 .index(),
17458 1
17459 );
17460 atn.set_rule_to_start_state(vec![0])
17461 .expect("rule start states");
17462 atn.set_rule_to_stop_state(vec![1])
17463 .expect("rule stop states");
17464 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
17465 atn.add_transition(
17466 0,
17467 ParserTransitionSpec::NotSet {
17468 target: 1,
17469 set: excluded,
17470 },
17471 )
17472 .expect("transition");
17473 finish_atn(atn)
17474 }
17475
17476 fn wildcard_then_eof_atn() -> Atn {
17479 let mut atn = ParserAtnBuilder::new(1);
17480 assert_eq!(
17481 atn.add_state(AtnStateKind::RuleStart, Some(0))
17482 .expect("state")
17483 .index(),
17484 0
17485 );
17486 assert_eq!(
17487 atn.add_state(AtnStateKind::RuleStop, Some(0))
17488 .expect("state")
17489 .index(),
17490 1
17491 );
17492 assert_eq!(
17493 atn.add_state(AtnStateKind::Basic, Some(0))
17494 .expect("state")
17495 .index(),
17496 2
17497 );
17498 atn.set_rule_to_start_state(vec![0])
17499 .expect("rule start states");
17500 atn.set_rule_to_stop_state(vec![1])
17501 .expect("rule stop states");
17502 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
17503 .expect("transition");
17504 atn.add_transition(
17505 2,
17506 ParserTransitionSpec::Atom {
17507 target: 1,
17508 label: TOKEN_EOF,
17509 },
17510 )
17511 .expect("transition");
17512 finish_atn(atn)
17513 }
17514
17515 #[test]
17516 fn parser_matches_token_and_reports_mismatch() {
17517 let source = Source {
17518 tokens: vec![
17519 TestToken::new(1).with_text("x"),
17520 TestToken::eof("parser-test", 1, 1, 1),
17521 ],
17522 index: 0,
17523 };
17524 let data = RecognizerData::new(
17525 "Mini.g4",
17526 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
17527 );
17528 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
17529 let matched = parser.match_token(1).expect("token 1 should match");
17530 assert_eq!(parser.node(matched).text(), "x");
17531 assert!(parser.match_token(1).is_err());
17532 }
17533
17534 #[test]
17535 fn parser_matches_token_sets() {
17536 let mut parser = mini_parser(vec![
17537 TestToken::new(1).with_text("x"),
17538 TestToken::eof("parser-test", 1, 1, 1),
17539 ]);
17540
17541 let matched = parser
17542 .match_set(&[(1, 1), (3, 4)])
17543 .expect("token set should match");
17544 assert_eq!(parser.node(matched).text(), "x");
17545 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
17546 }
17547
17548 #[test]
17549 fn generated_rule_api_tracks_state_and_precedence() {
17550 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17551
17552 let context = parser.enter_rule(7, 2);
17553 assert_eq!(context.rule_index(), 2);
17554 assert_eq!(parser.state(), 7);
17555 assert_eq!(
17556 parser.rule_context_stack,
17557 vec![RuleContextFrame {
17558 rule_index: 2,
17559 invoking_state: 7
17560 }]
17561 );
17562
17563 let recursive = parser.enter_recursion_rule(11, 3, 4);
17564 assert_eq!(recursive.rule_index(), 3);
17565 assert!(parser.precpred(4));
17566 assert!(parser.precpred(5));
17567 assert!(!parser.precpred(3));
17568
17569 let next = parser.push_new_recursion_context(13, 3);
17570 assert_eq!(next.invoking_state(), 13);
17571 parser.unroll_recursion_context();
17572 assert_eq!(parser.precedence_stack, vec![0]);
17573 assert_eq!(
17574 parser.rule_context_stack,
17575 vec![RuleContextFrame {
17576 rule_index: 2,
17577 invoking_state: 7
17578 }]
17579 );
17580
17581 parser.exit_rule();
17582 assert!(parser.rule_context_stack.is_empty());
17583 }
17584
17585 #[test]
17586 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
17587 let mut parser = mini_parser(vec![
17588 TestToken::new(1).with_text("x"),
17589 TestToken::eof("parser-test", 1, 1, 1),
17590 ]);
17591 let matched = parser.match_token(1).expect("token should match");
17592 assert_eq!(parser.node(matched).text(), "x");
17593 parser.record_generated_syntax_error();
17594 parser.set_int_member(7, 11);
17595 parser.set_build_parse_trees(false);
17596 parser.set_report_diagnostic_errors(true);
17597 parser.set_prediction_mode(PredictionMode::Sll);
17598 parser.set_bail_on_error(true);
17599 let _context = parser.enter_recursion_rule(9, 0, 4);
17600 parser.pending_invoking_states.push(5);
17601 parser.unknown_predicate_hits.push((0, 1));
17602 parser.unhandled_action_hits.push((0, 2));
17603
17604 parser.reset();
17605
17606 assert_eq!(parser.input.index(), 0);
17607 assert_eq!(parser.la(1), 1);
17608 assert_eq!(parser.state(), -1);
17609 assert_eq!(parser.number_of_syntax_errors(), 0);
17610 assert_eq!(parser.parse_tree_storage().node_count(), 0);
17611 assert!(parser.rule_context_stack.is_empty());
17612 assert!(parser.pending_invoking_states.is_empty());
17613 assert_eq!(parser.precedence_stack, [0]);
17614 assert!(parser.unknown_predicate_hits.is_empty());
17615 assert!(parser.unhandled_action_hits.is_empty());
17616 assert_eq!(parser.int_member(7), Some(11));
17617 assert!(!parser.build_parse_trees());
17618 assert!(parser.report_diagnostic_errors());
17619 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
17620 assert!(parser.bail_on_error());
17621 }
17622
17623 #[test]
17624 fn set_token_stream_replaces_input_and_resets_parser() {
17625 let mut parser = mini_parser(vec![
17626 TestToken::new(1).with_text("old"),
17627 TestToken::eof("parser-test", 1, 1, 1),
17628 ]);
17629 parser.consume();
17630 parser.record_generated_syntax_error();
17631 let replacement = CommonTokenStream::new(Source {
17632 tokens: vec![
17633 TestToken::new(2).with_text("new"),
17634 TestToken::eof("parser-test", 1, 1, 1),
17635 ],
17636 index: 0,
17637 });
17638
17639 parser.set_token_stream(replacement);
17640
17641 assert_eq!(parser.input.index(), 0);
17642 assert_eq!(parser.la(1), 2);
17643 assert_eq!(parser.input.text_all(), "new");
17644 assert_eq!(parser.number_of_syntax_errors(), 0);
17645 }
17646
17647 #[test]
17648 fn active_invocation_states_exclude_the_root_frame() {
17649 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17650
17651 let _root = parser.enter_rule(0, 0);
17652 assert!(parser.active_invocation_states().is_empty());
17653
17654 let marker = parser.push_invoking_state(6);
17655 let _child = parser.enter_rule(2, 1);
17656 parser.discard_invoking_state(marker);
17657 assert_eq!(parser.active_invocation_states(), [6]);
17658
17659 let marker = parser.push_invoking_state(13);
17660 let _grandchild = parser.enter_rule(4, 2);
17661 parser.discard_invoking_state(marker);
17662 assert_eq!(parser.active_invocation_states(), [13, 6]);
17663
17664 parser.exit_rule();
17665 parser.exit_rule();
17666 parser.exit_rule();
17667 }
17668
17669 #[test]
17670 fn parser_predicates_support_token_adjacency() {
17671 let mut parser = mini_parser(vec![
17672 TestToken::new(1).with_text("=").with_span(0, 0),
17673 TestToken::new(1).with_text(">").with_span(1, 1),
17674 TestToken::eof("parser-test", 2, 1, 2),
17675 ]);
17676 parser.consume();
17677 parser.consume();
17678
17679 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
17680
17681 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
17682
17683 let mut parser = mini_parser(vec![
17684 TestToken::new(1).with_text("=").with_span(0, 0),
17685 TestToken::new(1)
17686 .with_text(" ")
17687 .with_channel(HIDDEN_CHANNEL)
17688 .with_span(1, 1),
17689 TestToken::new(1).with_text(">").with_span(2, 2),
17690 TestToken::eof("parser-test", 3, 1, 3),
17691 ]);
17692 parser.consume();
17693 parser.consume();
17694
17695 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
17696 }
17697
17698 #[test]
17699 fn parser_predicates_support_context_child_text_checks() {
17700 let mut parser = mini_parser(vec![
17701 TestToken::new(1).with_text("var"),
17702 TestToken::eof("parser-test", 1, 1, 1),
17703 ]);
17704 let mut context = ParserRuleContext::new(1, 0);
17705 let mut child_context = ParserRuleContext::new(2, 0);
17706 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
17707 parser.tree.add_child(&mut child_context, terminal);
17708 let child = parser.rule_node(child_context);
17709 parser.tree.add_child(&mut context, child);
17710 let predicates = [(
17711 1,
17712 0,
17713 ParserPredicate::ContextChildRuleTextNotEquals {
17714 rule_index: 2,
17715 text: "var",
17716 },
17717 )];
17718
17719 assert!(
17720 !parser.parser_semantic_predicate_matches_with_context_and_local(
17721 &predicates,
17722 1,
17723 0,
17724 &context,
17725 0,
17726 )
17727 );
17728 }
17729
17730 #[test]
17731 fn context_expected_symbols_walks_nullable_parent_contexts() {
17732 let atn = nested_nullable_context_atn();
17733 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17734 parser.rule_context_stack = vec![
17735 RuleContextFrame {
17736 rule_index: 0,
17737 invoking_state: 0,
17738 },
17739 RuleContextFrame {
17740 rule_index: 1,
17741 invoking_state: 1,
17742 },
17743 RuleContextFrame {
17744 rule_index: 2,
17745 invoking_state: 2,
17746 },
17747 ];
17748
17749 let expected = parser.context_expected_symbols(&atn);
17750
17751 assert!(expected.contains(&1));
17752 assert!(expected.contains(&TOKEN_EOF));
17753 }
17754
17755 #[test]
17756 fn prediction_context_return_states_track_rule_stack_changes() {
17757 let atn = nested_nullable_context_atn();
17758 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17759 parser.rule_context_stack = vec![
17760 RuleContextFrame {
17761 rule_index: 0,
17762 invoking_state: 0,
17763 },
17764 RuleContextFrame {
17765 rule_index: 1,
17766 invoking_state: 1,
17767 },
17768 RuleContextFrame {
17769 rule_index: 2,
17770 invoking_state: 2,
17771 },
17772 ];
17773
17774 let initial_version = parser.rule_context_version();
17775 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
17776 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
17777 assert_eq!(first, second);
17778 assert_eq!(parser.rule_context_version(), initial_version);
17779
17780 parser.exit_rule();
17781 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
17782 assert_ne!(first, after_pop);
17783 assert_ne!(parser.rule_context_version(), initial_version);
17784 }
17785
17786 #[test]
17787 fn generated_match_token_recovers_missing_token_from_context_follow() {
17788 let atn = generated_match_recovery_atn();
17789 let data = RecognizerData::new(
17790 "Mini.g4",
17791 Vocabulary::new(
17792 [None, Some("'X'"), Some("'Y'")],
17793 [None, Some("X"), Some("Y")],
17794 [None::<&str>, None, None],
17795 ),
17796 );
17797 let mut parser = BaseParser::new(
17798 CommonTokenStream::new(Source {
17799 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
17800 index: 0,
17801 }),
17802 data,
17803 );
17804 parser.rule_context_stack = vec![
17805 RuleContextFrame {
17806 rule_index: 0,
17807 invoking_state: 0,
17808 },
17809 RuleContextFrame {
17810 rule_index: 1,
17811 invoking_state: 1,
17812 },
17813 ];
17814 assert_eq!(parser.number_of_syntax_errors(), 0);
17815
17816 let node = parser
17817 .match_token_recovering(2, 5, &atn)
17818 .expect("generated match should insert missing token");
17819
17820 assert_eq!(node.children().len(), 1);
17821 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
17822 assert_eq!(
17823 node.clone()
17824 .into_child_iter()
17825 .map(|child| parser.node(child).text())
17826 .collect::<Vec<_>>(),
17827 ["<missing 'Y'>"]
17828 );
17829 assert!(!node.consumed_eof());
17832 assert_eq!(parser.la(1), TOKEN_EOF);
17833 assert_eq!(parser.number_of_syntax_errors(), 1);
17834 assert_eq!(
17835 parser.generated_parser_diagnostics,
17836 [ParserDiagnostic {
17837 line: 1,
17838 column: 3,
17839 message: "missing 'Y' at '<EOF>'".to_owned(),
17840 offending: parser.input.lt_id(1),
17841 }]
17842 );
17843 }
17844
17845 #[test]
17846 fn generated_match_token_counts_single_token_deletion_recovery() {
17847 let atn = generated_match_recovery_atn();
17848 let data = RecognizerData::new(
17849 "Mini.g4",
17850 Vocabulary::new(
17851 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
17852 [None, Some("X"), Some("Y"), Some("Z")],
17853 [None::<&str>, None, None, None],
17854 ),
17855 );
17856 let mut parser = BaseParser::new(
17857 CommonTokenStream::new(Source {
17858 tokens: vec![
17859 TestToken::new(3).with_text("z"),
17860 TestToken::new(2).with_text("y"),
17861 TestToken::eof("parser-test", 3, 1, 3),
17862 ],
17863 index: 0,
17864 }),
17865 data,
17866 );
17867
17868 let node = parser
17869 .match_token_recovering(2, 5, &atn)
17870 .expect("generated match should delete the extraneous token");
17871
17872 assert_eq!(node.children().len(), 2);
17873 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
17874 assert_eq!(parser.node(node.children()[0]).text(), "z");
17875 assert_eq!(parser.node(node.children()[1]).text(), "y");
17876 assert_eq!(
17877 node.into_child_iter()
17878 .map(|child| parser.node(child).text())
17879 .collect::<Vec<_>>(),
17880 ["z", "y"]
17881 );
17882 assert_eq!(parser.number_of_syntax_errors(), 1);
17883 }
17884
17885 #[test]
17886 fn generated_match_token_iterates_single_success_without_a_children_vec() {
17887 let atn = generated_match_recovery_atn();
17888 let data = RecognizerData::new(
17889 "Mini.g4",
17890 Vocabulary::new(
17891 [None, Some("'X'"), Some("'Y'")],
17892 [None, Some("X"), Some("Y")],
17893 [None::<&str>, None, None],
17894 ),
17895 );
17896 let mut parser = BaseParser::new(
17897 CommonTokenStream::new(Source {
17898 tokens: vec![
17899 TestToken::new(2).with_text("y"),
17900 TestToken::eof("parser-test", 1, 1, 1),
17901 ],
17902 index: 0,
17903 }),
17904 data,
17905 );
17906
17907 let node = parser
17908 .match_token_recovering(2, 5, &atn)
17909 .expect("generated match should consume the expected token");
17910
17911 assert_eq!(
17912 node.into_child_iter()
17913 .map(|child| parser.node(child).text())
17914 .collect::<Vec<_>>(),
17915 ["y"]
17916 );
17917 assert_eq!(parser.number_of_syntax_errors(), 0);
17918 }
17919
17920 #[test]
17921 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
17922 let atn = generated_match_recovery_atn();
17923 let data = RecognizerData::new(
17924 "Mini.g4",
17925 Vocabulary::new(
17926 [None, Some("'X'"), Some("'Y'")],
17927 [None, Some("X"), Some("Y")],
17928 [None::<&str>, None, None],
17929 ),
17930 );
17931 let mut parser = BaseParser::new(
17932 CommonTokenStream::new(Source {
17933 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
17934 index: 0,
17935 }),
17936 data,
17937 );
17938 parser.rule_context_stack = vec![
17939 RuleContextFrame {
17940 rule_index: 0,
17941 invoking_state: 0,
17942 },
17943 RuleContextFrame {
17944 rule_index: 1,
17945 invoking_state: 1,
17946 },
17947 ];
17948 let marker = parser.generated_diagnostics_checkpoint();
17949
17950 let _ = parser
17951 .match_token_recovering(2, 5, &atn)
17952 .expect("generated match should insert missing token");
17953 assert_eq!(parser.number_of_syntax_errors(), 1);
17954
17955 parser.restore_generated_diagnostics(marker);
17956
17957 assert_eq!(parser.number_of_syntax_errors(), 0);
17958 assert!(parser.generated_parser_diagnostics.is_empty());
17959 }
17960
17961 #[test]
17962 fn generated_prediction_diagnostics_use_adaptive_context() {
17963 let atn = two_alt_decision_atn();
17964 let data = RecognizerData::new(
17965 "Mini.g4",
17966 Vocabulary::new(
17967 [None, Some("'x'"), Some("'y'")],
17968 [None, Some("X"), Some("Y")],
17969 [None::<&str>, None, None],
17970 ),
17971 )
17972 .with_rule_names(["s"]);
17973 let mut parser = BaseParser::new(
17974 CommonTokenStream::new(Source {
17975 tokens: vec![
17976 TestToken::new(1)
17977 .with_text("x")
17978 .with_position(1, 0)
17979 .with_span(0, 0),
17980 TestToken::new(2)
17981 .with_text("y")
17982 .with_position(1, 2)
17983 .with_span(1, 1),
17984 TestToken::eof("parser-test", 2, 1, 3),
17985 ],
17986 index: 0,
17987 }),
17988 data,
17989 );
17990 parser.set_report_diagnostic_errors(true);
17991
17992 parser.record_generated_prediction_diagnostic(
17993 &atn,
17994 1,
17995 &ParserAtnPrediction {
17996 alt: 1,
17997 requires_full_context: true,
17998 has_semantic_context: false,
17999 diagnostic: Some(ParserAtnPredictionDiagnostic {
18000 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
18001 start_index: 0,
18002 sll_stop_index: 1,
18003 ll_stop_index: 0,
18004 conflicting_alts: vec![1, 2],
18005 exact: false,
18006 }),
18007 },
18008 );
18009 parser.record_generated_prediction_diagnostic(
18014 &atn,
18015 1,
18016 &ParserAtnPrediction {
18017 alt: 1,
18018 requires_full_context: true,
18019 has_semantic_context: false,
18020 diagnostic: Some(ParserAtnPredictionDiagnostic {
18021 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
18022 start_index: 0,
18023 sll_stop_index: 1,
18024 ll_stop_index: 1,
18025 conflicting_alts: vec![1, 2],
18026 exact: false,
18027 }),
18028 },
18029 );
18030
18031 insta::assert_debug_snapshot!(
18034 "generated_prediction_diagnostics_use_adaptive_context",
18035 parser.generated_parser_diagnostics
18036 );
18037 }
18038
18039 #[test]
18040 fn generated_match_not_set_recovers_empty_complement_at_eof() {
18041 let atn = complement_set_atn();
18042 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18043 parser.rule_context_stack = vec![RuleContextFrame {
18044 rule_index: 0,
18045 invoking_state: 0,
18046 }];
18047
18048 let node = parser
18049 .match_not_token_set_recovering(
18050 atn.token_set(0).expect("excluded token set"),
18051 1,
18052 1,
18053 1,
18054 &atn,
18055 )
18056 .expect("empty complement should recover at EOF");
18057
18058 assert_eq!(node.children().len(), 1);
18059 assert!(!node.consumed_eof());
18062 assert_eq!(parser.la(1), TOKEN_EOF);
18063 assert_eq!(
18064 parser.generated_parser_diagnostics,
18065 [ParserDiagnostic {
18066 line: 1,
18067 column: 1,
18068 message: "missing {} at '<EOF>'".to_owned(),
18069 offending: parser.input.lt_id(1),
18070 }]
18071 );
18072 }
18073
18074 #[test]
18075 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
18076 let atn = wildcard_then_eof_atn();
18082 let data = RecognizerData::new(
18083 "Mini.g4",
18084 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18085 );
18086 let mut parser = BaseParser::new(
18087 CommonTokenStream::new(Source {
18088 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
18089 index: 0,
18090 }),
18091 data,
18092 );
18093 parser.rule_context_stack = vec![RuleContextFrame {
18094 rule_index: 0,
18095 invoking_state: 0,
18096 }];
18097
18098 let node = parser
18099 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
18100 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
18101
18102 assert_eq!(node.children().len(), 1);
18104 assert!(!node.consumed_eof());
18105 assert!(
18106 parser
18107 .node(node.children()[0])
18108 .text()
18109 .starts_with("<missing")
18110 );
18111 assert_eq!(parser.la(1), TOKEN_EOF);
18112 assert_eq!(
18113 parser.generated_parser_diagnostics,
18114 [ParserDiagnostic {
18115 line: 1,
18116 column: 1,
18117 message: "missing 'x' at '<EOF>'".to_owned(),
18118 offending: parser.input.lt_id(1),
18119 }]
18120 );
18121 }
18122
18123 #[test]
18124 fn generated_rule_recovery_consumes_to_parent_follow() {
18125 let atn = generated_match_recovery_atn();
18126 let data = RecognizerData::new(
18127 "Mini.g4",
18128 Vocabulary::new(
18129 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
18130 [None, Some("X"), Some("Y"), Some("Z")],
18131 [None::<&str>, None, None, None],
18132 ),
18133 );
18134 let mut parser = BaseParser::new(
18135 CommonTokenStream::new(Source {
18136 tokens: vec![
18137 TestToken::new(3).with_text("z"),
18138 TestToken::eof("parser-test", 1, 1, 1),
18139 ],
18140 index: 0,
18141 }),
18142 data,
18143 );
18144 let _parent = parser.enter_rule(0, 0);
18145 let marker = parser.push_invoking_state(1);
18146 let mut child = parser.enter_rule(4, 1);
18147 parser.discard_invoking_state(marker);
18148
18149 let offending = parser.input.lt_id(1);
18152 assert!(offending.is_some(), "the 'z' token should be buffered");
18153 parser.recover_generated_rule(
18154 &mut child,
18155 &atn,
18156 AntlrError::ParserError {
18157 line: 1,
18158 column: 0,
18159 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
18160 offending,
18161 },
18162 );
18163 let tree = parser.finish_rule(child, false);
18164
18165 assert_eq!(parser.la(1), TOKEN_EOF);
18166 assert_eq!(
18167 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
18168 "(a z)"
18169 );
18170 assert_eq!(parser.number_of_syntax_errors(), 1);
18171 assert_eq!(
18172 parser.generated_parser_diagnostics,
18173 [ParserDiagnostic {
18174 line: 1,
18175 column: 0,
18176 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
18177 offending,
18178 }]
18179 );
18180 parser.exit_rule();
18181 }
18182
18183 #[test]
18184 fn generated_rule_recovery_forces_progress_after_repeated_error_state() {
18185 let atn = nested_nullable_context_atn();
18186 let mut parser = mini_parser(vec![
18187 TestToken::new(1).with_text("x"),
18188 TestToken::eof("parser-test", 1, 1, 1),
18189 ]);
18190 parser.rule_context_stack = vec![
18191 RuleContextFrame {
18192 rule_index: 0,
18193 invoking_state: 0,
18194 },
18195 RuleContextFrame {
18196 rule_index: 1,
18197 invoking_state: 1,
18198 },
18199 RuleContextFrame {
18200 rule_index: 2,
18201 invoking_state: 2,
18202 },
18203 ];
18204 parser.set_state(20);
18205 let mut context = ParserRuleContext::new(2, 2);
18206
18207 parser.recover_generated_rule(
18208 &mut context,
18209 &atn,
18210 AntlrError::NoViableAlternative {
18211 input: "'x'".to_owned(),
18212 },
18213 );
18214 assert_eq!(parser.input.index(), 0);
18215
18216 parser.set_state(21);
18217 parser.recover_generated_rule(
18218 &mut context,
18219 &atn,
18220 AntlrError::NoViableAlternative {
18221 input: "'x'".to_owned(),
18222 },
18223 );
18224 assert_eq!(parser.input.index(), 0);
18225 assert_eq!(
18226 parser.generated_recovery_error_states,
18227 BTreeSet::from([20, 21])
18228 );
18229
18230 parser.set_state(20);
18231 parser.recover_generated_rule(
18232 &mut context,
18233 &atn,
18234 AntlrError::NoViableAlternative {
18235 input: "'x'".to_owned(),
18236 },
18237 );
18238
18239 assert_eq!(parser.input.index(), 1);
18240 assert_eq!(parser.la(1), TOKEN_EOF);
18241 assert!(context.has_matched_child());
18242 assert_eq!(parser.generated_recovery_error_states, BTreeSet::from([20]));
18243
18244 parser.match_eof().expect("EOF should match");
18245 assert_eq!(parser.generated_recovery_error_index, None);
18246 assert!(parser.generated_recovery_error_states.is_empty());
18247 }
18248
18249 #[test]
18250 fn greedy_ll1_alt_handles_nullable_loop_exit() {
18251 let mut body_symbols = TokenBitSet::default();
18252 body_symbols.insert(1);
18253 let entry = DecisionLookahead {
18254 transitions: vec![
18255 TransitionLookSet {
18256 symbols: body_symbols,
18257 nullable: false,
18258 },
18259 TransitionLookSet {
18260 symbols: TokenBitSet::default(),
18261 nullable: true,
18262 },
18263 ],
18264 };
18265
18266 assert_eq!(ll1_unique_alt(&entry, 2), None);
18267 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
18268 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
18269 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
18270 }
18271
18272 #[test]
18273 fn ordinary_repetition_builds_tree_in_input_order() {
18274 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
18275 let mut parser = mini_parser(repeated_x_tokens(3));
18276 let tree = parser
18277 .parse_atn_rule(&atn, 0)
18278 .expect("ordinary repetition should parse");
18279
18280 let root = parser
18281 .node(tree)
18282 .as_rule()
18283 .expect("entry result should be a rule");
18284 let body_rules = root.child_rules(1).collect::<Vec<_>>();
18285 assert_eq!(root.text(), "xxx<EOF>");
18286 assert_eq!(body_rules.len(), 3);
18287 assert_eq!(
18288 body_rules
18289 .iter()
18290 .map(|rule| rule.start_id().expect("body start").index())
18291 .collect::<Vec<_>>(),
18292 [0, 1, 2]
18293 );
18294 assert_eq!(
18295 body_rules
18296 .iter()
18297 .map(|rule| rule.stop_id().expect("body stop").index())
18298 .collect::<Vec<_>>(),
18299 [0, 1, 2]
18300 );
18301 assert_eq!(parser.number_of_syntax_errors(), 0);
18302 }
18303 }
18304
18305 #[test]
18306 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
18307 const DEPTH: usize = 20_000;
18308
18309 std::thread::Builder::new()
18310 .name("deferred-rule-materialization".to_owned())
18311 .stack_size(256 * 1024)
18312 .spawn(|| {
18313 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
18314 let mut root = FastDeferredNodeId::EMPTY;
18315 for depth in 0..DEPTH {
18316 root = parser
18317 .recognition_arena
18318 .deferred_rule_node(FastDeferredRule {
18319 rule_index: u32::try_from(depth).expect("depth fits in u32"),
18320 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
18321 start_index: 0,
18322 stop_index: None,
18323 deferred_children: root,
18324 children: NodeSeqId::EMPTY,
18325 });
18326 }
18327
18328 let (mut children, alt_number) =
18329 parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
18330 assert_eq!(alt_number, 0);
18331 for expected_rule in (0..DEPTH).rev() {
18332 let mut nodes = parser.recognition_arena.iter(children);
18333 let node = nodes.next().expect("nested rule node");
18334 assert!(nodes.next().is_none(), "each rule has one child");
18335 let ArenaRecognizedNode::Rule {
18336 rule_index,
18337 children: nested,
18338 ..
18339 } = parser.recognition_arena.node(node)
18340 else {
18341 panic!("expected nested rule");
18342 };
18343 assert_eq!(rule_index as usize, expected_rule);
18344 children = nested;
18345 }
18346 assert!(children.is_empty());
18347 })
18348 .expect("small-stack thread should start")
18349 .join()
18350 .expect("deferred rules should materialize without recursion");
18351 }
18352
18353 #[test]
18354 fn deferred_alternatives_preserve_left_recursive_contexts() {
18355 let mut parser = mini_parser(vec![
18356 TestToken::new(1).with_text("1"),
18357 TestToken::new(2).with_text("+"),
18358 TestToken::new(1).with_text("2"),
18359 TestToken::eof("parser-test", 3, 1, 3),
18360 ]);
18361 let base = parser.arena_token_node(0, false);
18362 let operator = parser.arena_token_node(1, false);
18363 let right = parser.arena_token_node(2, false);
18364
18365 let base = parser.recognition_arena.prepend(NodeSeqId::EMPTY, base);
18366 let base = parser.recognition_arena.deferred_fragment(base);
18367 let operator = parser.recognition_arena.prepend(NodeSeqId::EMPTY, operator);
18368 let operator = parser.recognition_arena.deferred_fragment(operator);
18369 let right = parser.recognition_arena.prepend(NodeSeqId::EMPTY, right);
18370 let right = parser.recognition_arena.deferred_fragment(right);
18371 let base_alt = parser.recognition_arena.deferred_alternative(1);
18372 let boundary = parser.recognition_arena.deferred_left_recursive_boundary(0);
18373 let operator_alt = parser.recognition_arena.deferred_alternative(6);
18374
18375 let mut deferred = FastDeferredNodeId::EMPTY;
18376 for fragment in [base_alt, base, boundary, operator_alt, operator, right] {
18377 deferred = parser
18378 .recognition_arena
18379 .concat_deferred_nodes(deferred, fragment);
18380 }
18381 let (nodes, root_alt_number) =
18382 parser.materialize_fast_deferred_nodes(deferred, NodeSeqId::EMPTY);
18383 let nodes = parser
18384 .recognition_arena
18385 .fold_left_recursive_boundaries(nodes);
18386
18387 let mut root = ParserRuleContext::new(0, -1);
18388 root.set_context_alt_number(root_alt_number);
18389 let mut cursor = nodes;
18390 while let Some(link) = parser.recognition_arena.link(cursor) {
18391 let child = parser
18392 .arena_recognized_node_tree(link.head, false, true)
18393 .expect("materialized child should become a public tree");
18394 parser.tree.add_child(&mut root, child);
18395 cursor = link.tail;
18396 }
18397 let tree = parser.rule_node(root);
18398 let contexts = parser
18399 .node(tree)
18400 .descendants()
18401 .filter_map(Node::as_rule)
18402 .map(|rule| {
18403 (
18404 rule.rule_index(),
18405 rule.alt_number(),
18406 rule.context_alt_number(),
18407 rule.text(),
18408 )
18409 })
18410 .collect::<Vec<_>>();
18411
18412 insta::assert_debug_snapshot!(
18413 "deferred_alternatives_preserve_left_recursive_contexts",
18414 contexts
18415 );
18416 }
18417
18418 #[test]
18419 fn fast_recognizer_preserves_labeled_left_recursive_operator_context() {
18420 let atn = labeled_left_recursive_operator_atn();
18421 let mut parser = mini_parser(vec![
18422 TestToken::new(1).with_text("a"),
18423 TestToken::new(3).with_text("+"),
18424 TestToken::new(1).with_text("b"),
18425 TestToken::eof("parser-test", 3, 1, 3),
18426 ]);
18427
18428 let (tree, _) = parser
18429 .parse_atn_rule_with_runtime_options(
18430 &atn,
18431 0,
18432 ParserRuntimeOptions {
18433 track_context_alt_numbers: true,
18434 ..ParserRuntimeOptions::default()
18435 },
18436 )
18437 .expect("labeled left-recursive addition should parse");
18438 let contexts = parser
18439 .node(tree)
18440 .descendants()
18441 .filter_map(Node::as_rule)
18442 .map(|rule| {
18443 let operator = rule
18444 .children()
18445 .next()
18446 .and_then(Node::as_rule)
18447 .is_some_and(|child| child.rule_index() == rule.rule_index());
18448 (operator, rule.context_alt_number(), rule.text())
18449 })
18450 .collect::<Vec<_>>();
18451
18452 insta::assert_debug_snapshot!(
18453 "fast_recognizer_preserves_labeled_left_recursive_operator_context",
18454 contexts
18455 );
18456 assert!(!parser.recognition_arena.deferred_nodes.is_empty());
18457 assert_eq!(parser.number_of_syntax_errors(), 0);
18458 }
18459
18460 #[test]
18461 fn deeply_nested_rule_calls_grow_the_stack() {
18462 const DEPTH: usize = 4_096;
18463 const STACK_SIZE: usize = 256 * 1024;
18464 let atn = nested_rule_chain_atn(DEPTH);
18465 std::thread::Builder::new()
18466 .name("nested-adaptive-set-rules".to_owned())
18467 .stack_size(STACK_SIZE)
18468 .spawn(move || {
18469 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
18470 parser.set_build_parse_trees(false);
18471 parser.fast_first_set_prefilter = false;
18474 parser
18475 .parse_atn_rule(&atn, 0)
18476 .expect("nested rule chain should grow the native stack");
18477 assert_eq!(parser.input.index(), 1);
18478 })
18479 .expect("small-stack thread should start")
18480 .join()
18481 .expect("nested rule chain should not overflow its stack");
18482 }
18483
18484 #[test]
18485 fn deeply_nested_branching_rules_grow_the_stack() {
18486 const DEPTH: usize = 4_096;
18487 const STACK_SIZE: usize = 256 * 1024;
18488 let atn = nested_rule_graph_atn(DEPTH, true, false);
18489 std::thread::Builder::new()
18490 .name("nested-branching-rules".to_owned())
18491 .stack_size(STACK_SIZE)
18492 .spawn(move || {
18493 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
18494 parser.set_build_parse_trees(false);
18495 parser
18496 .parse_atn_rule(&atn, 0)
18497 .expect("branching rule chain should grow the native stack");
18498 assert_eq!(parser.input.index(), 1);
18499 })
18500 .expect("small-stack thread should start")
18501 .join()
18502 .expect("branching rule chain should not overflow its stack");
18503 }
18504
18505 #[test]
18506 fn deeply_nested_rule_follows_grow_the_stack() {
18507 const DEPTH: usize = 4_096;
18508 const STACK_SIZE: usize = 256 * 1024;
18509 let atn = nested_rule_graph_atn(DEPTH, false, true);
18510 std::thread::Builder::new()
18511 .name("nested-rule-follows".to_owned())
18512 .stack_size(STACK_SIZE)
18513 .spawn(move || {
18514 let mut parser = mini_parser(repeated_x_tokens(DEPTH));
18515 parser.set_build_parse_trees(false);
18516 parser.fast_first_set_prefilter = false;
18517 parser
18518 .parse_atn_rule(&atn, 0)
18519 .expect("rule follow chain should grow the native stack");
18520 assert_eq!(parser.input.index(), DEPTH);
18521 })
18522 .expect("small-stack thread should start")
18523 .join()
18524 .expect("nested rule follow chain should not overflow its stack");
18525 }
18526
18527 #[test]
18528 fn deeply_nested_recovery_grows_the_stack() {
18529 const DEPTH: usize = 4_096;
18530 const STACK_SIZE: usize = 256 * 1024;
18531 let atn = nested_rule_chain_atn(DEPTH);
18532 std::thread::Builder::new()
18533 .name("nested-rule-recovery".to_owned())
18534 .stack_size(STACK_SIZE)
18535 .spawn(move || {
18536 let mut parser = mini_parser(vec![
18537 TestToken::new(2).with_text("z"),
18538 TestToken::new(1).with_text("x"),
18539 TestToken::eof("parser-test", 2, 1, 2),
18540 ]);
18541 parser.set_build_parse_trees(false);
18542 parser.fast_first_set_prefilter = false;
18543 parser
18544 .parse_atn_rule(&atn, 0)
18545 .expect("nested recovery should grow the native stack");
18546 assert_eq!(parser.input.index(), 2);
18547 assert_eq!(parser.number_of_syntax_errors(), 1);
18548 })
18549 .expect("small-stack thread should start")
18550 .join()
18551 .expect("nested rule recovery should not overflow its stack");
18552 }
18553
18554 #[test]
18555 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
18556 const REPETITIONS: usize = 64;
18557
18558 let atn = ambiguous_ordinary_star_loop_atn();
18559 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
18560 let tree = parser
18561 .parse_atn_rule(&atn, 0)
18562 .expect("ambiguous ordinary repetition should parse");
18563
18564 let root = parser
18565 .node(tree)
18566 .as_rule()
18567 .expect("entry result should be a rule");
18568 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
18569 assert_eq!(parser.input.index(), REPETITIONS);
18570 assert!(
18571 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
18572 "equivalent segmentations should keep deferred storage linear"
18573 );
18574 assert_eq!(parser.number_of_syntax_errors(), 0);
18575 }
18576
18577 #[test]
18578 fn long_ordinary_repetition_does_not_consume_native_stack() {
18579 const REPETITIONS: usize = 20_000;
18580
18581 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
18582 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
18583 parser.set_build_parse_trees(false);
18584 parser
18585 .parse_atn_rule(&atn, 0)
18586 .expect("long ordinary repetition should parse");
18587
18588 assert_eq!(parser.input.index(), REPETITIONS);
18589 assert_eq!(parser.number_of_syntax_errors(), 0);
18590 }
18591 }
18592
18593 #[test]
18594 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
18595 const REPETITIONS: usize = 2_000;
18596 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
18597
18598 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
18599 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
18600 let tree = parser
18601 .parse_atn_rule(&atn, 0)
18602 .expect("long rule repetition should parse");
18603
18604 let root = parser
18605 .node(tree)
18606 .as_rule()
18607 .expect("entry result should be a rule");
18608 assert_eq!(root.text(), expected_text);
18609 assert_eq!(root.child_rules(1).count(), REPETITIONS);
18610 let first_body = root.child_rules(1).next().expect("first body rule");
18611 let last_body = root.child_rules(1).next_back().expect("last body rule");
18612 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
18613 assert_eq!(
18614 last_body.stop_id().expect("last body stop").index(),
18615 REPETITIONS - 1
18616 );
18617
18618 let stats = parser.recognition_arena_stats();
18619 assert_eq!(
18620 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18621 (REPETITIONS, REPETITIONS, 0)
18622 );
18623 assert_eq!(
18624 (stats.total_links, stats.live_links, stats.dead_links),
18625 (REPETITIONS, REPETITIONS, 0)
18626 );
18627 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
18628 assert_eq!(
18629 parser.recognition_arena.deferred_nodes.len(),
18630 REPETITIONS * 2 - 1
18631 );
18632 assert_eq!(parser.number_of_syntax_errors(), 0);
18633 }
18634 }
18635
18636 #[test]
18637 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
18638 let key = |state_number| FastRecognizeKey {
18639 state_number,
18640 stop_state: 10,
18641 index: state_number,
18642 rule_start_index: 0,
18643 decision_start_index: None,
18644 precedence: 0,
18645 recovery_symbols_id: 0,
18646 recovery_state: None,
18647 };
18648
18649 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18650 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
18651 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
18652 }
18653 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
18654 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
18655
18656 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18657 let repeated = key(1);
18658 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
18659 assert!(promote.clean_memo_enabled_for_key(&repeated));
18660 }
18661 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
18662
18663 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
18664 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
18665 }
18666 assert!(sparse.clean_memo_enabled_for_key(&repeated));
18667 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
18668 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
18669 assert!(sparse.clean_memo_enabled_for_key(&repeated));
18670 }
18671 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
18672 }
18673
18674 #[test]
18675 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
18676 assert_eq!(
18677 fast_recognize_memo_capacity(0),
18678 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
18679 );
18680 assert_eq!(
18681 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
18682 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
18683 );
18684 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
18685 assert_eq!(
18686 fast_recognize_memo_capacity(usize::MAX),
18687 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
18688 );
18689 }
18690
18691 #[test]
18692 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
18693 let mut scratch = FastRecognizeTopScratch::default();
18694 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
18695 let retained_capacity = scratch.memo.capacity();
18696 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
18697 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
18698
18699 let larger_capacity = retained_capacity + 1;
18700 scratch.prepare(larger_capacity);
18701 let grown_capacity = scratch.memo.capacity();
18702 assert!(grown_capacity >= larger_capacity);
18703 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
18704
18705 scratch.memo.insert(
18706 FastRecognizeKey {
18707 state_number: 0,
18708 stop_state: 0,
18709 index: 0,
18710 rule_start_index: 0,
18711 decision_start_index: None,
18712 precedence: 0,
18713 recovery_symbols_id: 0,
18714 recovery_state: None,
18715 },
18716 Rc::from([FastRecognizeOutcome {
18717 index: 0,
18718 consumed_eof: false,
18719 diagnostics: DiagnosticSeqId::EMPTY,
18720 deferred_nodes: FastDeferredNodeId::EMPTY,
18721 nodes: NodeSeqId::EMPTY,
18722 }]),
18723 );
18724 scratch.release_oversized_memo();
18725 assert!(scratch.memo.is_empty());
18726 assert_eq!(scratch.memo.capacity(), grown_capacity);
18727
18728 scratch
18729 .memo
18730 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
18731 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
18732
18733 scratch.release_oversized_memo();
18734 assert!(scratch.memo.is_empty());
18735 assert_eq!(scratch.memo.capacity(), 0);
18736 }
18737
18738 #[test]
18739 fn clean_empty_multi_alt_outcomes_are_memoized() {
18740 let mut atn = ParserAtnBuilder::new(2);
18741 assert_eq!(
18742 atn.add_state(AtnStateKind::RuleStart, Some(0))
18743 .expect("state")
18744 .index(),
18745 0
18746 );
18747 assert_eq!(
18748 atn.add_state(AtnStateKind::BlockStart, Some(0))
18749 .expect("state")
18750 .index(),
18751 1
18752 );
18753 assert_eq!(
18754 atn.add_state(AtnStateKind::RuleStop, Some(0))
18755 .expect("state")
18756 .index(),
18757 2
18758 );
18759 atn.set_rule_to_start_state(vec![0])
18760 .expect("rule start states");
18761 atn.set_rule_to_stop_state(vec![2])
18762 .expect("rule stop states");
18763 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
18764 .expect("transition");
18765 atn.add_transition(
18766 1,
18767 ParserTransitionSpec::Atom {
18768 target: 2,
18769 label: 1,
18770 },
18771 )
18772 .expect("transition");
18773 atn.add_transition(
18774 1,
18775 ParserTransitionSpec::Atom {
18776 target: 2,
18777 label: 2,
18778 },
18779 )
18780 .expect("transition");
18781 let atn = finish_atn(atn);
18782
18783 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
18784 parser.fast_recovery_enabled = false;
18785 let mut visiting = FxHashSet::default();
18786 let mut memo = FxHashMap::default();
18787 let mut expected = ExpectedTokens::default();
18788 let outcomes = parser.recognize_state_fast(
18789 &atn,
18790 FastRecognizeRequest {
18791 state_number: 1,
18792 stop_state: 2,
18793 index: 0,
18794 rule_start_index: 0,
18795 decision_start_index: None,
18796 precedence: 0,
18797 depth: 0,
18798 recovery_symbols: parser.empty_recovery_symbols(),
18799 recovery_state: None,
18800 },
18801 FastRecognizeScratch {
18802 predicate_context: None,
18803 visiting: &mut visiting,
18804 memo: &mut memo,
18805 expected: &mut expected,
18806 native_depth: 0,
18807 },
18808 );
18809
18810 assert!(outcomes.is_empty());
18811 assert_eq!(memo.len(), 1);
18812 assert!(memo.values().next().expect("memo entry").is_empty());
18813
18814 parser.clean_memo_mode = CleanMemoMode::Sparse;
18815 visiting.clear();
18816 memo.clear();
18817 expected = ExpectedTokens::default();
18818 let sparse_outcomes = parser.recognize_state_fast(
18819 &atn,
18820 FastRecognizeRequest {
18821 state_number: 1,
18822 stop_state: 2,
18823 index: 0,
18824 rule_start_index: 0,
18825 decision_start_index: None,
18826 precedence: 0,
18827 depth: 0,
18828 recovery_symbols: parser.empty_recovery_symbols(),
18829 recovery_state: None,
18830 },
18831 FastRecognizeScratch {
18832 predicate_context: None,
18833 visiting: &mut visiting,
18834 memo: &mut memo,
18835 expected: &mut expected,
18836 native_depth: 0,
18837 },
18838 );
18839
18840 assert!(sparse_outcomes.is_empty());
18841 assert!(memo.is_empty());
18842 }
18843
18844 #[test]
18845 fn wildcard_matches_non_eof_only() {
18846 let mut parser = mini_parser(vec![
18847 TestToken::new(1).with_text("x"),
18848 TestToken::eof("parser-test", 1, 1, 1),
18849 ]);
18850 let matched = parser.match_wildcard().expect("wildcard");
18851 assert_eq!(parser.node(matched).text(), "x");
18852 assert!(parser.match_wildcard().is_err());
18853 }
18854
18855 #[test]
18856 fn add_parse_child_records_match_even_without_tree_building() {
18857 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
18862 let token = TestToken::new(1).with_text("x");
18863
18864 parser.set_build_parse_trees(false);
18865 let mut ctx = ParserRuleContext::new(0, 0);
18866 assert!(!ctx.has_matched_child());
18867 let child = parser.terminal_tree(token.id);
18868 parser.add_parse_child(&mut ctx, child);
18869 assert_eq!(ctx.child_count(), 0);
18871 assert_eq!(parser.parse_tree_storage().node_count(), 0);
18872 assert!(ctx.has_matched_child());
18874
18875 parser.set_build_parse_trees(true);
18877 let mut ctx = ParserRuleContext::new(0, 0);
18878 let child = parser.terminal_tree(token.id);
18879 parser.add_parse_child(&mut ctx, child);
18880 assert_eq!(ctx.child_count(), 1);
18881 assert!(ctx.has_matched_child());
18882 }
18883
18884 #[test]
18885 fn disabled_tree_building_does_not_grow_flat_storage() {
18886 let mut parser = mini_parser(vec![
18887 TestToken::new(1).with_text("x"),
18888 TestToken::new(1).with_text("y"),
18889 TestToken::eof("parser-test", 2, 1, 2),
18890 ]);
18891 parser.set_build_parse_trees(false);
18892 let mut context = ParserRuleContext::new(0, -1);
18893
18894 for _ in 0..2 {
18895 let child = parser.match_token(1).expect("token should match");
18896 parser.add_parse_child(&mut context, child);
18897 }
18898 let current = parser.input.lt_id(1).expect("EOF token");
18899 let error = parser.error_tree(current);
18900 parser.add_parse_child(&mut context, error);
18901 let root = parser.rule_node(context);
18902
18903 assert_eq!(
18904 parser.parse_tree_storage().stats(),
18905 ParseTreeStats::default()
18906 );
18907 assert!(
18908 parser
18909 .parse_tree_storage()
18910 .node(parser.token_store(), root)
18911 .is_none(),
18912 "the no-tree sentinel must not resolve to stored data"
18913 );
18914 }
18915
18916 #[test]
18917 fn disabled_tree_building_skips_recognition_rule_node_storage() {
18918 let atn = ordinary_star_loop_atn();
18919 let mut parser = mini_parser(repeated_x_tokens(3));
18920 parser.set_build_parse_trees(false);
18921
18922 parser
18923 .parse_atn_rule(&atn, 0)
18924 .expect("ordinary repetition should parse without a tree");
18925
18926 assert_eq!(parser.input.index(), 3);
18927 assert!(parser.recognition_arena.nodes.is_empty());
18928 assert!(parser.recognition_arena.seq_links.is_empty());
18929 assert!(parser.recognition_arena.deferred_nodes.is_empty());
18930 assert!(parser.recognition_arena.deferred_rules.is_empty());
18931 assert!(!parser.fast_token_nodes_enabled);
18932 assert!(parser.fast_recognize_scratch.memo.is_empty());
18933 }
18934
18935 #[test]
18936 fn parser_interprets_simple_atn_rule() {
18937 let atn = token_then_eof_atn();
18938 let mut parser = mini_parser(vec![
18939 TestToken::new(1).with_text("x"),
18940 TestToken::eof("parser-test", 1, 1, 1),
18941 ]);
18942
18943 let tree = parser
18944 .parse_atn_rule(&atn, 0)
18945 .expect("artificial parser rule should parse");
18946 assert_eq!(parser.node(tree).text(), "x<EOF>");
18947 assert_eq!(parser.number_of_syntax_errors(), 0);
18948 assert_eq!(
18949 parser
18950 .node(tree)
18951 .first_rule_stop(0)
18952 .expect("rule should stop at EOF")
18953 .token_type(),
18954 TOKEN_EOF
18955 );
18956
18957 let mut parser = mini_parser(vec![
18958 TestToken::new(1).with_text("x"),
18959 TestToken::eof("parser-test", 1, 1, 1),
18960 ]);
18961 let (tree, actions) = parser
18962 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
18963 .expect("runtime-option parser rule should parse");
18964 assert!(actions.is_empty());
18965 assert_eq!(
18966 parser
18967 .node(tree)
18968 .first_rule_stop(0)
18969 .expect("rule should stop at EOF")
18970 .token_type(),
18971 TOKEN_EOF
18972 );
18973 }
18974
18975 #[test]
18976 fn runtime_options_default_ignores_noop_action_transitions() {
18977 let atn = noop_action_then_token_then_eof_atn();
18978 let mut parser = mini_parser(vec![
18979 TestToken::new(1).with_text("x"),
18980 TestToken::eof("parser-test", 1, 1, 1),
18981 ]);
18982
18983 let (tree, actions) = parser
18984 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
18985 .expect("no-op parser action should not force action replay");
18986
18987 assert_eq!(parser.node(tree).text(), "x<EOF>");
18988 assert!(
18989 actions.is_empty(),
18990 "action_index=None transitions are ANTLR metadata, not replay actions"
18991 );
18992 assert_eq!(parser.number_of_syntax_errors(), 0);
18993 }
18994
18995 #[test]
18996 fn parser_exposes_buffered_token_stream_after_parse() {
18997 let atn = token_then_eof_atn();
18998 let mut parser = mini_parser(vec![
18999 TestToken::new(1).with_text("x"),
19000 TestToken::eof("parser-test", 1, 1, 1),
19001 ]);
19002
19003 let tree = parser
19004 .parse_atn_rule(&atn, 0)
19005 .expect("artificial parser rule should parse");
19006 assert_eq!(parser.node(tree).text(), "x<EOF>");
19007
19008 let stream = parser.token_stream();
19009 let source_index_after_parse = stream.token_source().index;
19010 let buffered = stream.tokens().collect::<Vec<_>>();
19011 assert_eq!(buffered.len(), 2);
19012 assert_eq!(buffered[0].text(), Some("x"));
19013 assert_eq!(buffered[0].token_id().index(), 0);
19014 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
19015 assert_eq!(stream.token_source().index, source_index_after_parse);
19016 drop(buffered);
19017
19018 let stream = parser.into_token_stream();
19019 assert_eq!(stream.token_source().index, source_index_after_parse);
19020 assert_eq!(
19021 stream.tokens().next().expect("first token").text(),
19022 Some("x")
19023 );
19024 assert_eq!(
19025 stream.tokens().nth(1).expect("EOF token").token_type(),
19026 TOKEN_EOF
19027 );
19028 }
19029
19030 #[test]
19031 fn parsed_file_exposes_all_buffered_tokens() {
19032 let atn = token_then_eof_atn();
19033 let mut parser = mini_parser(vec![
19034 TestToken::new(99)
19035 .with_text(" comment")
19036 .with_channel(HIDDEN_CHANNEL),
19037 TestToken::new(1).with_text("x"),
19038 TestToken::eof("parser-test", 9, 1, 9),
19039 ]);
19040
19041 let tree = parser
19042 .parse_atn_rule(&atn, 0)
19043 .expect("artificial parser rule should parse");
19044 let parsed = parser.into_parsed_file(tree);
19045
19046 insta::assert_debug_snapshot!(
19049 "parsed_file_exposes_all_buffered_tokens",
19050 parsed
19051 .tokens()
19052 .iter()
19053 .map(|token| (token.token_type(), token.channel(), token.text()))
19054 .collect::<Vec<_>>()
19055 );
19056 assert_eq!(parsed.tokens().into_iter().count(), 3);
19057 }
19058
19059 #[test]
19060 fn parser_syntax_error_count_tracks_interpreted_recovery() {
19061 let atn = token_then_eof_atn();
19062 let mut parser = mini_parser(vec![
19063 TestToken::new(1).with_text("x"),
19064 TestToken::new(2).with_text("y"),
19065 TestToken::eof("parser-test", 2, 1, 2),
19066 ]);
19067
19068 let tree = parser
19069 .parse_atn_rule(&atn, 0)
19070 .expect("invalid token should recover into an error node");
19071
19072 assert_eq!(parser.number_of_syntax_errors(), 1);
19073 assert_eq!(
19074 parser
19075 .node(tree)
19076 .first_error_token()
19077 .expect("recovery should embed an error token")
19078 .text(),
19079 Some("y")
19080 );
19081 }
19082
19083 #[test]
19084 fn failed_interpreted_parse_notifies_error_listener() {
19085 let atn = token_then_eof_atn();
19086 let mut parser = mini_parser(vec![
19087 TestToken::new(2)
19088 .with_text("y")
19089 .with_span(0, 0)
19090 .with_byte_span(0, 1)
19091 .with_position(3, 5),
19092 TestToken::eof("parser-test", 1, 1, 1),
19093 ]);
19094 parser.remove_error_listeners();
19095 let diagnostics = Arc::new(Mutex::new(Vec::new()));
19096 parser.add_error_listener(RecordingErrorListener {
19097 diagnostics: Arc::clone(&diagnostics),
19098 });
19099
19100 let error = parser
19101 .parse_atn_rule(&atn, 0)
19102 .expect_err("start-rule mismatch should remain a parser error");
19103
19104 assert_eq!(parser.number_of_syntax_errors(), 1);
19105 assert!(matches!(&error, AntlrError::ParserError { .. }));
19106 insta::assert_debug_snapshot!(
19107 "failed_interpreted_parse_notifies_error_listener",
19108 *diagnostics.lock().expect("recorded diagnostics lock")
19109 );
19110 }
19111
19112 #[test]
19113 fn adaptive_direct_rule_uses_simulator_decision() {
19114 let atn = two_alt_decision_atn();
19115 let mut simulator = ParserAtnSimulator::new(&atn);
19116 let mut parser = mini_parser(vec![
19117 TestToken::new(2).with_text("y"),
19118 TestToken::eof("parser-test", 1, 1, 1),
19119 ]);
19120
19121 let tree = parser
19122 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
19123 .expect("direct adaptive rule should parse");
19124
19125 assert_eq!(parser.node(tree).text(), "y");
19126 assert_eq!(parser.input.index(), 1);
19127 }
19128
19129 #[test]
19130 fn adaptive_direct_rule_restores_input_on_fallback() {
19131 let atn = predicate_after_token_atn();
19132 let mut simulator = ParserAtnSimulator::new(&atn);
19133 let mut parser = mini_parser(vec![
19134 TestToken::new(1).with_text("x"),
19135 TestToken::new(2).with_text("y"),
19136 TestToken::eof("parser-test", 2, 1, 2),
19137 ]);
19138
19139 let tree = parser
19140 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
19141 .expect("fallback recognizer should parse");
19142
19143 assert_eq!(parser.node(tree).text(), "xy");
19144 assert_eq!(parser.input.index(), 2);
19145 let stats = parser.parse_tree_storage().stats();
19146 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
19147 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
19148 assert_eq!(stats.scratch_links, 0);
19149 }
19150
19151 #[test]
19152 fn unknown_predicate_policy_defaults_to_assume_true() {
19153 let atn = predicate_after_token_atn();
19154 let mut parser = mini_parser(vec![
19155 TestToken::new(1).with_text("x"),
19156 TestToken::new(2).with_text("y"),
19157 TestToken::eof("parser-test", 2, 1, 2),
19158 ]);
19159
19160 let (tree, _) = parser
19161 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19162 .expect("unknown predicate should pass under the default policy");
19163
19164 assert_eq!(parser.node(tree).text(), "xy");
19165 assert_eq!(parser.number_of_syntax_errors(), 0);
19166 }
19167
19168 #[test]
19169 fn private_context_alt_tracking_keeps_fast_predicate_recognition() {
19170 let atn = predicate_gated_same_lookahead_atn([0, 1]);
19171 let mut parser = mini_parser(vec![
19172 TestToken::new(1).with_text("x"),
19173 TestToken::eof("parser-test", 1, 1, 1),
19174 ]);
19175
19176 let (tree, _) = parser
19177 .parse_atn_rule_with_runtime_options(
19178 &atn,
19179 0,
19180 ParserRuntimeOptions {
19181 predicates: &[
19182 (0, 0, ParserPredicate::False),
19183 (0, 1, ParserPredicate::True),
19184 ],
19185 track_context_alt_numbers: true,
19186 ..ParserRuntimeOptions::default()
19187 },
19188 )
19189 .expect("the second predicate-gated alternative should match");
19190
19191 let root = parser.node(tree).as_rule().expect("entry result is a rule");
19192 insta::assert_debug_snapshot!(
19193 "private_context_alt_tracking_keeps_fast_predicate_recognition",
19194 (root.alt_number(), root.context_alt_number(), root.text())
19195 );
19196 assert_eq!(parser.number_of_syntax_errors(), 0);
19197 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
19198 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
19199 }
19200
19201 #[test]
19202 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
19203 let atn = token_then_eof_atn();
19207 let mut parser = mini_parser(vec![
19208 TestToken::new(1).with_text("x"),
19209 TestToken::eof("parser-test", 1, 1, 1),
19210 ]);
19211
19212 parser.unknown_predicate_hits.push((7, 3));
19214
19215 parser
19217 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19218 .expect("child rule parses");
19219
19220 let error = parser
19222 .take_unknown_semantic_error()
19223 .expect("parent's recorded coordinate must survive the nested interpreted parse");
19224 let AntlrError::Unsupported(message) = error else {
19225 panic!("expected AntlrError::Unsupported, got {error:?}");
19226 };
19227 assert!(message.contains("pred_index=3"), "message: {message}");
19228 }
19229
19230 #[test]
19231 fn nested_committed_parse_preserves_prior_unhandled_action_hits() {
19232 let atn = token_then_eof_atn();
19233 let mut parser = mini_parser(vec![
19234 TestToken::new(1).with_text("x"),
19235 TestToken::eof("parser-test", 1, 1, 1),
19236 ]);
19237 parser.unhandled_action_hits.push((7, 42));
19238
19239 parser
19240 .parse_atn_rule_with_runtime_options(
19241 &atn,
19242 0,
19243 ParserRuntimeOptions {
19244 action_indices: &[(usize::MAX, 0)],
19245 ..ParserRuntimeOptions::default()
19246 },
19247 )
19248 .expect("a child with no action miss must not observe its parent's miss");
19249
19250 let error = parser
19251 .take_unknown_semantic_error()
19252 .expect("the parent's action miss must survive the nested committed parse");
19253 let AntlrError::Unsupported(message) = error else {
19254 panic!("expected AntlrError::Unsupported, got {error:?}");
19255 };
19256 assert!(
19257 message.contains("rule_index=7") && message.contains("state=42"),
19258 "message: {message}"
19259 );
19260 }
19261
19262 #[test]
19263 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
19264 let atn = predicate_after_token_atn();
19265 let mut parser = mini_parser(vec![
19266 TestToken::new(1).with_text("x"),
19267 TestToken::new(2).with_text("y"),
19268 TestToken::eof("parser-test", 2, 1, 2),
19269 ]);
19270
19271 let result = parser.parse_atn_rule_with_runtime_options(
19272 &atn,
19273 0,
19274 ParserRuntimeOptions {
19275 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
19276 ..ParserRuntimeOptions::default()
19277 },
19278 );
19279
19280 assert!(
19281 result.is_err(),
19282 "the only path is predicate-guarded, so assume-false must fail the parse"
19283 );
19284 }
19285
19286 #[test]
19287 fn predicate_failure_message_keeps_semantic_recovery_path() {
19288 let atn = predicate_after_token_atn();
19289 let mut parser = mini_parser(vec![
19290 TestToken::new(1).with_text("x"),
19291 TestToken::new(2).with_text("y"),
19292 TestToken::eof("parser-test", 2, 1, 2),
19293 ]);
19294
19295 let (tree, _) = parser
19296 .parse_atn_rule_with_runtime_options(
19297 &atn,
19298 0,
19299 ParserRuntimeOptions {
19300 predicates: &[(
19301 0,
19302 0,
19303 ParserPredicate::FalseWithMessage {
19304 message: "predicate rejected input",
19305 },
19306 )],
19307 ..ParserRuntimeOptions::default()
19308 },
19309 )
19310 .expect("failure-message predicates recover through the semantic interpreter");
19311
19312 assert_eq!(parser.node(tree).text(), "xy");
19313 assert_eq!(parser.number_of_syntax_errors(), 1);
19314 assert!(
19315 parser.fast_predicate_cache.is_empty(),
19316 "failure-message predicates need the semantic interpreter's recovery outcome"
19317 );
19318 }
19319
19320 #[test]
19321 fn unknown_predicate_policy_error_names_the_coordinate() {
19322 let atn = predicate_after_token_atn();
19323 let mut parser = mini_parser(vec![
19324 TestToken::new(1).with_text("x"),
19325 TestToken::new(2).with_text("y"),
19326 TestToken::eof("parser-test", 2, 1, 2),
19327 ]);
19328
19329 let error = parser
19330 .parse_atn_rule_with_runtime_options(
19331 &atn,
19332 0,
19333 ParserRuntimeOptions {
19334 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19335 ..ParserRuntimeOptions::default()
19336 },
19337 )
19338 .expect_err("evaluating an unknown predicate under Error policy must fail");
19339
19340 let AntlrError::Unsupported(message) = error else {
19341 panic!("expected AntlrError::Unsupported, got {error:?}");
19342 };
19343 assert!(
19344 message.contains("unsupported semantic predicate"),
19345 "message should name the failure class: {message}"
19346 );
19347 assert!(
19348 message.contains("pred_index=0"),
19349 "message should carry the coordinate: {message}"
19350 );
19351 }
19352
19353 #[test]
19354 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
19355 let atn = predicate_after_token_atn();
19361 let mut parser = mini_parser(vec![
19362 TestToken::new(1).with_text("x"),
19363 TestToken::new(2).with_text("y"),
19364 TestToken::eof("parser-test", 2, 1, 2),
19365 ]);
19366
19367 parser
19368 .parse_atn_rule_with_runtime_options(
19369 &atn,
19370 0,
19371 ParserRuntimeOptions {
19372 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19373 ..ParserRuntimeOptions::default()
19374 },
19375 )
19376 .expect_err("first parse fails loud under the Error policy");
19377
19378 parser.reset_unknown_semantic_hits();
19383 assert!(
19384 parser.take_unknown_semantic_error().is_none(),
19385 "reset must drop stale unknown-predicate coordinates before a reused parse"
19386 );
19387 }
19388
19389 #[derive(Debug, Default)]
19390 struct RecordingHooks {
19391 predicates: Vec<(usize, usize, usize, Option<String>)>,
19392 actions: Vec<(usize, String, Option<String>)>,
19393 action_trees: Vec<Option<String>>,
19394 }
19395
19396 impl SemanticHooks for RecordingHooks {
19397 fn sempred<S>(
19398 &mut self,
19399 ctx: &mut ParserSemCtx<'_, S>,
19400 rule_index: usize,
19401 pred_index: usize,
19402 ) -> Option<bool>
19403 where
19404 S: TokenSource,
19405 {
19406 self.predicates.push((
19407 ctx.input_index(),
19408 rule_index,
19409 pred_index,
19410 ctx.token_text(1)
19411 .and_then(|token| token.text().map(str::to_owned)),
19412 ));
19413 Some(true)
19414 }
19415
19416 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19417 where
19418 S: TokenSource,
19419 {
19420 self.actions.push((
19421 action.source_state(),
19422 ctx.action_text(),
19423 ctx.rule_name().map(str::to_owned),
19424 ));
19425 self.action_trees.push(ctx.tree().map(Node::text));
19426 true
19427 }
19428 }
19429
19430 #[derive(Debug, Default)]
19431 struct StatefulActionHooks {
19432 entered: bool,
19433 events: Vec<String>,
19434 }
19435
19436 impl SemanticHooks for StatefulActionHooks {
19437 fn sempred<S>(
19438 &mut self,
19439 _ctx: &mut ParserSemCtx<'_, S>,
19440 _rule_index: usize,
19441 _pred_index: usize,
19442 ) -> Option<bool>
19443 where
19444 S: TokenSource,
19445 {
19446 self.events.push(format!("predicate:{}", self.entered));
19447 Some(self.entered)
19448 }
19449
19450 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19451 where
19452 S: TokenSource,
19453 {
19454 self.events.push(format!(
19455 "action:{}",
19456 action
19457 .action_index()
19458 .map_or_else(|| "legacy".to_owned(), |index| index.to_string())
19459 ));
19460 self.entered = true;
19461 true
19462 }
19463 }
19464
19465 #[derive(Debug, Default)]
19466 struct InitOrderingHooks {
19467 initialized: bool,
19468 events: Vec<String>,
19469 }
19470
19471 impl SemanticHooks for InitOrderingHooks {
19472 fn sempred<S>(
19473 &mut self,
19474 _ctx: &mut ParserSemCtx<'_, S>,
19475 _rule_index: usize,
19476 _pred_index: usize,
19477 ) -> Option<bool>
19478 where
19479 S: TokenSource,
19480 {
19481 self.events.push(format!("predicate:{}", self.initialized));
19482 Some(self.initialized)
19483 }
19484
19485 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19486 where
19487 S: TokenSource,
19488 {
19489 if action.is_rule_init() {
19490 self.initialized = true;
19491 self.events.push("init".to_owned());
19492 } else {
19493 self.events.push(format!(
19494 "action:{}:initialized={}",
19495 action
19496 .action_index()
19497 .map_or_else(|| "legacy".to_owned(), |index| index.to_string()),
19498 self.initialized
19499 ));
19500 }
19501 true
19502 }
19503 }
19504
19505 #[derive(Debug, Default)]
19506 struct ActionContextHooks {
19507 actions: Vec<(usize, Option<i64>, Option<usize>)>,
19508 }
19509
19510 impl SemanticHooks for ActionContextHooks {
19511 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19512 where
19513 S: TokenSource,
19514 {
19515 self.actions.push((
19516 action.action_index().unwrap_or(usize::MAX),
19517 ctx.local_int_arg(),
19518 action.stop_index(),
19519 ));
19520 true
19521 }
19522 }
19523
19524 #[derive(Debug, Default)]
19525 struct DecliningActionHooks {
19526 actions: Vec<usize>,
19527 }
19528
19529 impl SemanticHooks for DecliningActionHooks {
19530 fn action<S>(&mut self, _ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
19531 where
19532 S: TokenSource,
19533 {
19534 self.actions.push(action.source_state());
19535 false
19536 }
19537 }
19538
19539 #[derive(Debug, Default)]
19540 struct ForcedSecondAlternativeHooks {
19541 decisions: Vec<(usize, usize, usize)>,
19542 }
19543
19544 impl SemanticHooks for ForcedSecondAlternativeHooks {
19545 fn observes_parser_decisions(&self) -> bool {
19546 true
19547 }
19548
19549 fn parser_decision_override(
19550 &mut self,
19551 decision: usize,
19552 input_index: usize,
19553 alternative_count: usize,
19554 ) -> Option<usize> {
19555 self.decisions
19556 .push((decision, input_index, alternative_count));
19557 Some(2)
19558 }
19559 }
19560
19561 struct RecordingParseListener {
19562 events: Arc<Mutex<Vec<String>>>,
19563 }
19564
19565 impl ParseListener for RecordingParseListener {
19566 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError> {
19567 self.events
19568 .lock()
19569 .expect("parse-listener event lock")
19570 .push(format!("enter:{}", event.rule_index));
19571 Ok(())
19572 }
19573
19574 fn exit_every_rule(&mut self, rule_index: usize) {
19575 self.events
19576 .lock()
19577 .expect("parse-listener event lock")
19578 .push(format!("exit:{rule_index}"));
19579 }
19580 }
19581
19582 #[derive(Debug, Default)]
19583 struct RejectingPredicateHooks {
19584 predicates: Vec<(usize, usize, usize, Option<String>)>,
19585 }
19586
19587 impl SemanticHooks for RejectingPredicateHooks {
19588 fn sempred<S>(
19589 &mut self,
19590 ctx: &mut ParserSemCtx<'_, S>,
19591 rule_index: usize,
19592 pred_index: usize,
19593 ) -> Option<bool>
19594 where
19595 S: TokenSource,
19596 {
19597 self.predicates.push((
19598 ctx.input_index(),
19599 rule_index,
19600 pred_index,
19601 ctx.token_text(1)
19602 .and_then(|token| token.text().map(str::to_owned)),
19603 ));
19604 Some(false)
19605 }
19606 }
19607
19608 #[test]
19609 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
19610 let atn = predicate_gated_same_lookahead_atn([0, 0]);
19611 let mut parser = mini_parser_with_hooks(
19612 vec![
19613 TestToken::new(1).with_text("x"),
19614 TestToken::eof("parser-test", 1, 1, 1),
19615 ],
19616 RecordingHooks::default(),
19617 );
19618
19619 let (tree, _) = parser
19620 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
19621 .expect("both alternatives share one replay-safe predicate result");
19622
19623 assert_eq!(parser.node(tree).text(), "x<EOF>");
19624 assert_eq!(
19625 parser.semantic_hooks.predicates,
19626 vec![(0, 0, 0, Some("x".to_owned()))]
19627 );
19628 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
19629 }
19630
19631 #[test]
19632 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
19633 let atn = predicate_after_token_atn();
19634 let mut parser = mini_parser_with_hooks(
19635 vec![
19636 TestToken::new(1).with_text("x"),
19637 TestToken::new(2).with_text("y"),
19638 TestToken::eof("parser-test", 2, 1, 2),
19639 ],
19640 RecordingHooks::default(),
19641 );
19642
19643 let (tree, _) = parser
19644 .parse_atn_rule_with_runtime_options(
19645 &atn,
19646 0,
19647 ParserRuntimeOptions {
19648 unknown_predicate_policy: UnknownSemanticPolicy::Error,
19649 ..ParserRuntimeOptions::default()
19650 },
19651 )
19652 .expect("hook supplies the missing predicate result");
19653
19654 assert_eq!(parser.node(tree).text(), "xy");
19655 assert_eq!(
19656 parser.semantic_hooks.predicates,
19657 vec![(1, 0, 0, Some("y".to_owned()))]
19658 );
19659 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
19660 }
19661
19662 #[test]
19663 fn runtime_options_default_preserves_semantic_hook_predicates() {
19664 let atn = predicate_after_token_atn();
19665 let mut parser = mini_parser_with_hooks(
19666 vec![
19667 TestToken::new(1).with_text("x"),
19668 TestToken::new(2).with_text("y"),
19669 TestToken::eof("parser-test", 2, 1, 2),
19670 ],
19671 RejectingPredicateHooks::default(),
19672 );
19673
19674 let result =
19675 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
19676
19677 assert!(
19678 result.is_err(),
19679 "default runtime options must not bypass semantic hooks for predicate ATNs"
19680 );
19681 assert_eq!(
19682 parser.semantic_hooks.predicates,
19683 vec![(1, 0, 0, Some("y".to_owned()))]
19684 );
19685 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
19686 }
19687
19688 #[test]
19689 fn committed_action_runs_before_later_predicate() {
19690 let atn = committed_action_then_predicate_atn();
19691 let mut parser = mini_parser_with_hooks(
19692 vec![
19693 TestToken::new(1).with_text("x"),
19694 TestToken::eof("parser-test", 1, 1, 1),
19695 ],
19696 StatefulActionHooks::default(),
19697 );
19698
19699 let (tree, deferred_actions) = parser
19700 .parse_atn_rule_with_runtime_options(
19701 &atn,
19702 0,
19703 ParserRuntimeOptions {
19704 action_indices: &[(0, 7)],
19705 ..ParserRuntimeOptions::default()
19706 },
19707 )
19708 .expect("the predicate should observe the preceding committed action");
19709
19710 assert_eq!(parser.node(tree).text(), "x<EOF>");
19711 assert!(deferred_actions.is_empty());
19712 assert_eq!(parser.semantic_hooks.events, ["action:7", "predicate:true"]);
19713 }
19714
19715 #[test]
19716 fn committed_action_hook_observes_parameterized_rule_argument() {
19717 let atn = parameterized_child_action_eof_atn();
19718 let rule_args = [ParserRuleArg {
19719 source_state: 0,
19720 rule_index: 1,
19721 value: 42,
19722 inherit_local: false,
19723 }];
19724 let mut parser = mini_parser_with_hooks(
19725 vec![TestToken::eof("parser-test", 0, 1, 0)],
19726 ActionContextHooks::default(),
19727 );
19728
19729 parser
19730 .parse_atn_rule_with_runtime_options(
19731 &atn,
19732 0,
19733 ParserRuntimeOptions {
19734 action_indices: &[(1, 20), (4, 10)],
19735 rule_args: &rule_args,
19736 ..ParserRuntimeOptions::default()
19737 },
19738 )
19739 .expect("the parameterized child should parse");
19740
19741 assert_eq!(
19742 parser.semantic_hooks.actions[0],
19743 (10, Some(42), None),
19744 "the child action should observe its invocation argument"
19745 );
19746 }
19747
19748 #[test]
19749 fn committed_parent_propagates_child_eof_consumption() {
19750 let atn = parameterized_child_action_eof_atn();
19751 let mut parser = mini_parser_with_hooks(
19752 vec![TestToken::eof("parser-test", 0, 1, 0)],
19753 ActionContextHooks::default(),
19754 );
19755
19756 let (tree, _) = parser
19757 .parse_atn_rule_with_runtime_options(
19758 &atn,
19759 0,
19760 ParserRuntimeOptions {
19761 action_indices: &[(1, 20), (4, 10)],
19762 ..ParserRuntimeOptions::default()
19763 },
19764 )
19765 .expect("the parent should retain its child's EOF boundary");
19766
19767 assert_eq!(
19768 parser.semantic_hooks.actions[1],
19769 (20, None, Some(0)),
19770 "the parent action should stop at EOF"
19771 );
19772 let root = parser.node(tree).as_rule().expect("entry result is a rule");
19773 assert_eq!(root.stop().map(|token| token.token_type()), Some(TOKEN_EOF));
19774 let child = root
19775 .child_rules(1)
19776 .next()
19777 .expect("the parent should contain the child rule");
19778 assert_eq!(
19779 child.stop().map(|token| token.token_type()),
19780 Some(TOKEN_EOF)
19781 );
19782 }
19783
19784 #[test]
19785 fn committed_walker_does_not_run_action_in_losing_alternative() {
19786 let atn = losing_alternative_action_atn();
19787 let mut parser = mini_parser_with_hooks(
19788 vec![
19789 TestToken::new(2).with_text("y"),
19790 TestToken::eof("parser-test", 1, 1, 1),
19791 ],
19792 StatefulActionHooks::default(),
19793 );
19794
19795 let (tree, deferred_actions) = parser
19796 .parse_atn_rule_with_runtime_options(
19797 &atn,
19798 0,
19799 ParserRuntimeOptions {
19800 action_indices: &[(2, 0)],
19801 ..ParserRuntimeOptions::default()
19802 },
19803 )
19804 .expect("the token-led second alternative should be selected");
19805
19806 assert_eq!(parser.node(tree).text(), "y");
19807 assert!(deferred_actions.is_empty());
19808 assert!(parser.semantic_hooks.events.is_empty());
19809 }
19810
19811 #[test]
19812 fn committed_walker_honors_decision_overrides() {
19813 let atn = predicate_gated_same_lookahead_atn([0, 1]);
19814 let predicates = [(0, 0, ParserPredicate::True), (0, 1, ParserPredicate::True)];
19815 let mut parser = mini_parser_with_hooks(
19816 vec![
19817 TestToken::new(1).with_text("x"),
19818 TestToken::eof("parser-test", 1, 1, 1),
19819 ],
19820 ForcedSecondAlternativeHooks::default(),
19821 );
19822
19823 let (tree, deferred_actions) = parser
19824 .parse_atn_rule_with_runtime_options(
19825 &atn,
19826 0,
19827 ParserRuntimeOptions {
19828 action_indices: &[(usize::MAX, 0)],
19829 track_alt_numbers: true,
19830 predicates: &predicates,
19831 ..ParserRuntimeOptions::default()
19832 },
19833 )
19834 .expect("the forced second alternative should parse");
19835
19836 let root = parser.node(tree).as_rule().expect("entry result is a rule");
19837 assert_eq!(root.alt_number(), 2);
19838 assert_eq!(root.text(), "x<EOF>");
19839 assert!(deferred_actions.is_empty());
19840 assert_eq!(parser.semantic_hooks.decisions, [(0, 0, 2)]);
19841 assert_eq!(parser.number_of_syntax_errors(), 0);
19842 }
19843
19844 #[test]
19845 fn committed_walker_sll_mode_does_not_report_full_context_diagnostics() {
19846 let atn = predicate_gated_same_lookahead_atn([0, 1]);
19847 let predicates = [(0, 0, ParserPredicate::True), (0, 1, ParserPredicate::True)];
19848 let diagnostics = Arc::new(Mutex::new(Vec::new()));
19849 let mut parser = mini_parser(vec![
19850 TestToken::new(1).with_text("x"),
19851 TestToken::eof("parser-test", 1, 1, 1),
19852 ]);
19853 parser.set_prediction_mode(PredictionMode::Sll);
19854 parser.set_report_diagnostic_errors(true);
19855 parser.remove_error_listeners();
19856 parser.add_error_listener(RecordingErrorListener {
19857 diagnostics: Arc::clone(&diagnostics),
19858 });
19859
19860 let (tree, deferred_actions) = parser
19861 .parse_atn_rule_with_runtime_options(
19862 &atn,
19863 0,
19864 ParserRuntimeOptions {
19865 action_indices: &[(usize::MAX, 0)],
19866 predicates: &predicates,
19867 ..ParserRuntimeOptions::default()
19868 },
19869 )
19870 .expect("SLL prediction should select the first viable alternative");
19871
19872 assert_eq!(parser.node(tree).text(), "x<EOF>");
19873 assert!(deferred_actions.is_empty());
19874 assert_eq!(parser.number_of_syntax_errors(), 0);
19875 assert!(
19876 diagnostics
19877 .lock()
19878 .expect("recorded diagnostics lock")
19879 .is_empty(),
19880 "SLL mode must not retry with full context or report LL diagnostics"
19881 );
19882 }
19883
19884 #[test]
19885 fn committed_walker_filters_diagnostics_after_semantic_selection() {
19886 let atn = predicate_gated_same_lookahead_atn([0, 1]);
19887 let predicates = [
19888 (0, 0, ParserPredicate::False),
19889 (0, 1, ParserPredicate::True),
19890 ];
19891 let diagnostics = Arc::new(Mutex::new(Vec::new()));
19892 let mut parser = mini_parser(vec![
19893 TestToken::new(1).with_text("x"),
19894 TestToken::eof("parser-test", 1, 1, 1),
19895 ]);
19896 parser.set_prediction_mode(PredictionMode::LlExactAmbigDetection);
19897 parser.set_report_diagnostic_errors(true);
19898 parser.remove_error_listeners();
19899 parser.add_error_listener(RecordingErrorListener {
19900 diagnostics: Arc::clone(&diagnostics),
19901 });
19902
19903 let (tree, _) = parser
19904 .parse_atn_rule_with_runtime_options(
19905 &atn,
19906 0,
19907 ParserRuntimeOptions {
19908 action_indices: &[(usize::MAX, 0)],
19909 track_alt_numbers: true,
19910 predicates: &predicates,
19911 ..ParserRuntimeOptions::default()
19912 },
19913 )
19914 .expect("the true predicate should make the second alternative unique");
19915
19916 let root = parser.node(tree).as_rule().expect("entry result is a rule");
19917 assert_eq!(root.alt_number(), 2);
19918 assert!(
19919 diagnostics
19920 .lock()
19921 .expect("recorded diagnostics lock")
19922 .is_empty(),
19923 "predicate filtering made the decision unambiguous"
19924 );
19925 }
19926
19927 #[test]
19928 fn committed_walker_skips_diagnostic_only_predicates_when_reporting_is_disabled() {
19929 let atn = predicate_gated_same_lookahead_atn([0, 1]);
19930 let mut parser = mini_parser_with_hooks(
19931 vec![
19932 TestToken::new(1).with_text("x"),
19933 TestToken::eof("parser-test", 1, 1, 1),
19934 ],
19935 RecordingHooks::default(),
19936 );
19937 parser.set_prediction_mode(PredictionMode::LlExactAmbigDetection);
19938
19939 let (tree, _) = parser
19940 .parse_atn_rule_with_runtime_options(
19941 &atn,
19942 0,
19943 ParserRuntimeOptions {
19944 action_indices: &[(usize::MAX, 0)],
19945 track_alt_numbers: true,
19946 ..ParserRuntimeOptions::default()
19947 },
19948 )
19949 .expect("the first predicate-bearing alternative should parse");
19950
19951 let root = parser.node(tree).as_rule().expect("entry result is a rule");
19952 assert_eq!(root.alt_number(), 1);
19953 assert_eq!(
19954 parser.semantic_hooks.predicates,
19955 [
19956 (0, 0, 0, Some("x".to_owned())),
19957 (0, 0, 0, Some("x".to_owned())),
19958 ],
19959 "diagnostic-only alternatives must not invoke semantic hooks"
19960 );
19961 }
19962
19963 #[test]
19964 fn committed_walker_falls_back_only_to_simulator_viable_alternatives() {
19965 let atn = semantic_fallback_viability_atn();
19966 let predicates = [
19967 (0, 0, ParserPredicate::False),
19968 (0, 1, ParserPredicate::True),
19969 ];
19970 let mut parser = mini_parser(vec![
19971 TestToken::new(1).with_text("a"),
19972 TestToken::new(3).with_text("c"),
19973 TestToken::eof("parser-test", 2, 1, 2),
19974 ]);
19975
19976 let (tree, deferred_actions) = parser
19977 .parse_atn_rule_with_runtime_options(
19978 &atn,
19979 0,
19980 ParserRuntimeOptions {
19981 action_indices: &[(usize::MAX, 0)],
19982 track_alt_numbers: true,
19983 predicates: &predicates,
19984 ..ParserRuntimeOptions::default()
19985 },
19986 )
19987 .expect("the true A C alternative should survive semantic fallback");
19988
19989 let root = parser.node(tree).as_rule().expect("entry result is a rule");
19990 assert_eq!(root.alt_number(), 3);
19991 assert_eq!(root.text(), "ac<EOF>");
19992 assert!(deferred_actions.is_empty());
19993 assert_eq!(parser.number_of_syntax_errors(), 0);
19994 }
19995
19996 #[test]
19997 fn committed_walker_evaluates_predicates_reached_through_rule_calls() {
19998 let atn = rule_call_predicate_decision_atn();
19999 let predicates = [(1, 0, ParserPredicate::False)];
20000 let mut parser = mini_parser(vec![
20001 TestToken::new(1).with_text("a"),
20002 TestToken::eof("parser-test", 1, 1, 1),
20003 ]);
20004
20005 let (tree, deferred_actions) = parser
20006 .parse_atn_rule_with_runtime_options(
20007 &atn,
20008 0,
20009 ParserRuntimeOptions {
20010 action_indices: &[(usize::MAX, 0)],
20011 track_alt_numbers: true,
20012 predicates: &predicates,
20013 ..ParserRuntimeOptions::default()
20014 },
20015 )
20016 .expect("the direct caller alternative should survive the false callee predicate");
20017
20018 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20019 assert_eq!(root.alt_number(), 2);
20020 assert_eq!(root.text(), "a<EOF>");
20021 assert_eq!(root.child_rules(1).count(), 0);
20022 assert!(deferred_actions.is_empty());
20023 assert_eq!(parser.number_of_syntax_errors(), 0);
20024 }
20025
20026 #[test]
20027 fn committed_walker_uses_callee_argument_for_prediction_predicates() {
20028 let atn = rule_call_predicate_decision_atn();
20029 let predicates = [(1, 0, ParserPredicate::LocalIntEquals { value: 1 })];
20030 let rule_args = [ParserRuleArg {
20031 source_state: 2,
20032 rule_index: 1,
20033 value: 2,
20034 inherit_local: false,
20035 }];
20036 let mut parser = mini_parser(vec![
20037 TestToken::new(1).with_text("a"),
20038 TestToken::eof("parser-test", 1, 1, 1),
20039 ]);
20040
20041 let (tree, _) = parser
20042 .parse_atn_rule_with_runtime_options(
20043 &atn,
20044 0,
20045 ParserRuntimeOptions {
20046 action_indices: &[(usize::MAX, 0)],
20047 track_alt_numbers: true,
20048 predicates: &predicates,
20049 rule_args: &rule_args,
20050 ..ParserRuntimeOptions::default()
20051 },
20052 )
20053 .expect("the direct alternative should survive the false callee predicate");
20054
20055 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20056 assert_eq!(root.alt_number(), 2);
20057 assert_eq!(root.child_rules(1).count(), 0);
20058 assert_eq!(parser.number_of_syntax_errors(), 0);
20059 }
20060
20061 #[test]
20062 fn committed_predicate_star_loop_uses_single_token_deletion() {
20063 let atn = predicate_gated_star_loop_atn();
20064 let predicates = [(0, 0, ParserPredicate::True)];
20065 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20066 let mut parser = mini_parser(vec![
20067 TestToken::new(2).with_text("x"),
20068 TestToken::new(1).with_text("a"),
20069 TestToken::eof("parser-test", 2, 1, 2),
20070 ]);
20071 parser.remove_error_listeners();
20072 parser.add_error_listener(RecordingErrorListener {
20073 diagnostics: Arc::clone(&diagnostics),
20074 });
20075
20076 let (tree, deferred_actions) = parser
20077 .parse_atn_rule_with_runtime_options(
20078 &atn,
20079 0,
20080 ParserRuntimeOptions {
20081 action_indices: &[(usize::MAX, 0)],
20082 predicates: &predicates,
20083 ..ParserRuntimeOptions::default()
20084 },
20085 )
20086 .expect("the loop decision should delete the extraneous token and continue");
20087
20088 assert_eq!(parser.node(tree).text(), "xa<EOF>");
20089 assert!(deferred_actions.is_empty());
20090 assert_eq!(parser.number_of_syntax_errors(), 1);
20091 insta::assert_debug_snapshot!(
20092 "committed_predicate_star_loop_uses_single_token_deletion",
20093 *diagnostics.lock().expect("recorded diagnostics lock")
20094 );
20095 }
20096
20097 #[test]
20098 fn committed_walker_applies_legacy_and_semir_actions_before_indexed_hooks() {
20099 let atn = committed_action_then_predicate_atn();
20100 let member_actions = [ParserMemberAction {
20101 source_state: 0,
20102 member: 0,
20103 delta: 2,
20104 }];
20105 let return_actions = [ParserReturnAction {
20106 source_state: 0,
20107 rule_index: 0,
20108 name: "legacy",
20109 value: 3,
20110 }];
20111 let predicates = [(
20112 0,
20113 0,
20114 ParserPredicate::MemberEquals {
20115 member: 0,
20116 value: 7,
20117 equals: true,
20118 },
20119 )];
20120 let mut ir = SemIr::new();
20121 let semantic_member = ParserMemberAction {
20122 source_state: 0,
20123 member: 0,
20124 delta: 5,
20125 }
20126 .lower_into_semir(&mut ir);
20127 let semantic_return = ParserReturnAction {
20128 source_state: 0,
20129 rule_index: 0,
20130 name: "semantic",
20131 value: 11,
20132 }
20133 .lower_into_semir(&mut ir);
20134 let semantics = ParserSemantics {
20135 ir,
20136 predicates: Vec::new(),
20137 actions: vec![semantic_member, semantic_return],
20138 };
20139 let mut parser = mini_parser_with_hooks(
20140 vec![
20141 TestToken::new(1).with_text("x"),
20142 TestToken::eof("parser-test", 1, 1, 1),
20143 ],
20144 StatefulActionHooks::default(),
20145 );
20146
20147 let (tree, deferred_actions) = parser
20148 .parse_atn_rule_with_runtime_options(
20149 &atn,
20150 0,
20151 ParserRuntimeOptions {
20152 action_indices: &[(0, 7)],
20153 predicates: &predicates,
20154 semantics: Some(&semantics),
20155 member_actions: &member_actions,
20156 return_actions: &return_actions,
20157 ..ParserRuntimeOptions::default()
20158 },
20159 )
20160 .expect("the predicate should observe both committed member actions");
20161
20162 let root = parser.node(tree).as_rule().expect("entry result is a rule");
20163 assert_eq!(root.text(), "x<EOF>");
20164 assert_eq!(root.int_return("legacy"), Some(3));
20165 assert_eq!(root.int_return("semantic"), Some(11));
20166 assert_eq!(parser.int_member(0), Some(7));
20167 assert!(deferred_actions.is_empty());
20168 assert_eq!(parser.semantic_hooks.events, ["action:7"]);
20169 assert_eq!(parser.number_of_syntax_errors(), 0);
20170 }
20171
20172 #[test]
20173 fn committed_walker_runs_action_once_per_star_loop_iteration() {
20174 let atn = committed_action_star_loop_atn();
20175 let mut parser = mini_parser_with_hooks(
20176 vec![
20177 TestToken::new(1).with_text("a"),
20178 TestToken::new(1).with_text("b"),
20179 TestToken::eof("parser-test", 2, 1, 2),
20180 ],
20181 StatefulActionHooks::default(),
20182 );
20183
20184 let (tree, deferred_actions) = parser
20185 .parse_atn_rule_with_runtime_options(
20186 &atn,
20187 0,
20188 ParserRuntimeOptions {
20189 action_indices: &[(2, 3)],
20190 ..ParserRuntimeOptions::default()
20191 },
20192 )
20193 .expect("the committed star loop should parse");
20194
20195 assert_eq!(parser.node(tree).text(), "ab<EOF>");
20196 assert!(deferred_actions.is_empty());
20197 assert_eq!(parser.semantic_hooks.events, ["action:3", "action:3"]);
20198 }
20199
20200 #[test]
20201 fn committed_walker_has_no_total_step_cap() {
20202 const TOKEN_COUNT: usize = RECOGNITION_DEPTH_LIMIT + 1;
20203 let atn = committed_action_star_loop_atn();
20204 let mut parser = mini_parser(repeated_x_tokens(TOKEN_COUNT));
20205 parser.set_build_parse_trees(false);
20206
20207 parser
20208 .parse_atn_rule_with_runtime_options(
20209 &atn,
20210 0,
20211 ParserRuntimeOptions {
20212 action_indices: &[(usize::MAX, 0)],
20213 ..ParserRuntimeOptions::default()
20214 },
20215 )
20216 .expect("valid committed loops must not have a total-work cap");
20217
20218 assert_eq!(parser.input.index(), TOKEN_COUNT);
20219 assert_eq!(parser.number_of_syntax_errors(), 0);
20220 }
20221
20222 #[test]
20223 fn committed_walker_rejects_non_consuming_cycles() {
20224 let atn = committed_non_consuming_cycle_atn();
20225 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
20226 parser.set_bail_on_error(true);
20227
20228 let error = parser
20229 .parse_atn_rule_with_runtime_options(
20230 &atn,
20231 0,
20232 ParserRuntimeOptions {
20233 action_indices: &[(usize::MAX, 0)],
20234 ..ParserRuntimeOptions::default()
20235 },
20236 )
20237 .expect_err("a non-consuming cycle must not spin forever");
20238
20239 assert!(
20240 error.to_string().contains("non-consuming ATN cycle"),
20241 "unexpected error: {error}"
20242 );
20243 }
20244
20245 #[test]
20246 fn deeply_nested_committed_rule_calls_grow_the_stack() {
20247 const DEPTH: usize = 4_096;
20248 const STACK_SIZE: usize = 256 * 1024;
20249 let atn = nested_rule_chain_atn(DEPTH);
20250 std::thread::Builder::new()
20251 .name("nested-committed-rules".to_owned())
20252 .stack_size(STACK_SIZE)
20253 .spawn(move || {
20254 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
20255 parser.set_build_parse_trees(false);
20256 parser
20257 .parse_atn_rule_with_runtime_options(
20258 &atn,
20259 0,
20260 ParserRuntimeOptions {
20261 action_indices: &[(usize::MAX, 0)],
20262 ..ParserRuntimeOptions::default()
20263 },
20264 )
20265 .expect("nested committed rules should grow the native stack");
20266 assert_eq!(parser.input.index(), 1);
20267 })
20268 .expect("small-stack thread should start")
20269 .join()
20270 .expect("nested committed rules should not overflow their stack");
20271 }
20272
20273 #[test]
20274 fn committed_walker_runs_action_once_per_left_recursive_operator() {
20275 let atn = committed_action_left_recursive_atn();
20276 let mut parser = mini_parser_with_hooks(
20277 vec![
20278 TestToken::new(1).with_text("a"),
20279 TestToken::new(3).with_text("+"),
20280 TestToken::new(1).with_text("b"),
20281 TestToken::new(3).with_text("+"),
20282 TestToken::new(1).with_text("c"),
20283 TestToken::eof("parser-test", 5, 1, 5),
20284 ],
20285 StatefulActionHooks::default(),
20286 );
20287
20288 let (tree, deferred_actions) = parser
20289 .parse_atn_rule_with_runtime_options(
20290 &atn,
20291 0,
20292 ParserRuntimeOptions {
20293 action_indices: &[(6, 11)],
20294 ..ParserRuntimeOptions::default()
20295 },
20296 )
20297 .expect("the committed left-recursive rule should parse");
20298
20299 assert_eq!(parser.node(tree).text(), "a+b+c");
20300 assert!(deferred_actions.is_empty());
20301 assert_eq!(parser.semantic_hooks.events, ["action:11", "action:11"]);
20302 }
20303
20304 #[test]
20305 fn committed_left_recursive_depth_cap_keeps_listener_events_balanced() {
20306 let atn = committed_action_left_recursive_atn();
20307 let events = Arc::new(Mutex::new(Vec::new()));
20308 let mut parser = mini_parser(vec![
20309 TestToken::new(1).with_text("a"),
20310 TestToken::new(3).with_text("+"),
20311 TestToken::new(1).with_text("b"),
20312 TestToken::eof("parser-test", 3, 1, 3),
20313 ]);
20314 parser.set_max_rule_depth(Some(1));
20315 parser.add_parse_listener(RecordingParseListener {
20316 events: Arc::clone(&events),
20317 });
20318
20319 let error = parser
20320 .parse_atn_rule_with_runtime_options(
20321 &atn,
20322 0,
20323 ParserRuntimeOptions {
20324 action_indices: &[(6, 11)],
20325 ..ParserRuntimeOptions::default()
20326 },
20327 )
20328 .expect_err("the left-recursive expansion should exceed the depth cap");
20329
20330 insta::assert_debug_snapshot!(
20331 "committed_left_recursive_depth_cap_keeps_listener_events_balanced",
20332 (
20333 error.to_string(),
20334 events.lock().expect("parse-listener event lock").as_slice(),
20335 )
20336 );
20337 }
20338
20339 #[test]
20340 fn committed_walker_preserves_nested_rule_listener_events() {
20341 let atn = ordinary_star_loop_atn();
20342 let events = Arc::new(Mutex::new(Vec::new()));
20343 let mut parser = mini_parser(vec![
20344 TestToken::new(1).with_text("a"),
20345 TestToken::new(1).with_text("b"),
20346 TestToken::eof("parser-test", 2, 1, 2),
20347 ]);
20348 parser.add_parse_listener(RecordingParseListener {
20349 events: Arc::clone(&events),
20350 });
20351
20352 let (tree, _) = parser
20353 .parse_atn_rule_with_runtime_options(
20354 &atn,
20355 0,
20356 ParserRuntimeOptions {
20357 action_indices: &[(usize::MAX, 0)],
20358 ..ParserRuntimeOptions::default()
20359 },
20360 )
20361 .expect("the committed nested-rule path should parse");
20362
20363 assert_eq!(parser.node(tree).text(), "ab<EOF>");
20364 assert_eq!(
20365 *events.lock().expect("parse-listener event lock"),
20366 [
20367 "enter:0", "enter:1", "exit:1", "enter:1", "exit:1", "exit:0",
20368 ]
20369 );
20370 }
20371
20372 #[test]
20373 fn committed_walker_enforces_rule_depth_cap() {
20374 let atn = ordinary_star_loop_atn();
20375 let mut parser = mini_parser(vec![
20376 TestToken::new(1).with_text("a"),
20377 TestToken::eof("parser-test", 1, 1, 1),
20378 ]);
20379 parser.set_max_rule_depth(Some(1));
20380
20381 let error = parser
20382 .parse_atn_rule_with_runtime_options(
20383 &atn,
20384 0,
20385 ParserRuntimeOptions {
20386 action_indices: &[(usize::MAX, 0)],
20387 ..ParserRuntimeOptions::default()
20388 },
20389 )
20390 .expect_err("the nested rule should exceed the committed-path cap");
20391
20392 assert!(
20393 error
20394 .to_string()
20395 .contains("rule nesting depth limit of 1 exceeded"),
20396 "unexpected error: {error}"
20397 );
20398 }
20399
20400 #[test]
20401 fn committed_abort_precedes_and_clears_unhandled_action_error() {
20402 let atn = action_then_nested_rule_atn();
20403 let mut parser = mini_parser_with_hooks(
20404 vec![TestToken::eof("parser-test", 0, 1, 0)],
20405 DecliningActionHooks::default(),
20406 );
20407 parser.set_max_rule_depth(Some(1));
20408
20409 let error = parser
20410 .parse_atn_rule_with_runtime_options(
20411 &atn,
20412 0,
20413 ParserRuntimeOptions {
20414 action_indices: &[(0, 7)],
20415 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20416 ..ParserRuntimeOptions::default()
20417 },
20418 )
20419 .expect_err("the recovered child abort must outrank the earlier action miss");
20420
20421 assert_eq!(parser.semantic_hooks.actions, [0]);
20422 assert!(
20423 error
20424 .to_string()
20425 .contains("rule nesting depth limit of 1 exceeded"),
20426 "unexpected error: {error}"
20427 );
20428 assert!(
20429 parser.take_parse_abort().is_none(),
20430 "the returned abort must not remain sticky"
20431 );
20432 assert!(
20433 parser.take_unknown_semantic_error().is_none(),
20434 "the masked action miss must not poison parser reuse"
20435 );
20436 }
20437
20438 #[test]
20439 fn top_level_committed_semantic_error_does_not_poison_reuse() {
20440 let atn = committed_action_then_predicate_atn();
20441 let predicates = [(0, 0, ParserPredicate::True)];
20442 let mut parser = mini_parser_with_hooks(
20443 vec![
20444 TestToken::new(1).with_text("x"),
20445 TestToken::eof("parser-test", 1, 1, 1),
20446 ],
20447 DecliningActionHooks::default(),
20448 );
20449
20450 let error = parser
20451 .parse_atn_rule_with_runtime_options(
20452 &atn,
20453 0,
20454 ParserRuntimeOptions {
20455 action_indices: &[(0, 7)],
20456 predicates: &predicates,
20457 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20458 ..ParserRuntimeOptions::default()
20459 },
20460 )
20461 .expect_err("the declined committed action must fail loud");
20462 assert!(
20463 error.to_string().contains("unhandled semantic action"),
20464 "unexpected error: {error}"
20465 );
20466
20467 parser.input.seek(0);
20468 let (tree, _) = parser
20469 .parse_atn_rule_with_runtime_options(
20470 &atn,
20471 0,
20472 ParserRuntimeOptions {
20473 predicates: &predicates,
20474 ..ParserRuntimeOptions::default()
20475 },
20476 )
20477 .expect("a clean interpreted reuse must not observe the prior action miss");
20478
20479 assert_eq!(parser.node(tree).text(), "x<EOF>");
20480 assert!(
20481 parser.take_unknown_semantic_error().is_none(),
20482 "the returned top-level semantic error must drain its recorded hit"
20483 );
20484 }
20485
20486 #[test]
20487 fn committed_walker_runs_handled_rule_init_before_indexed_action() {
20488 let atn = committed_action_then_predicate_atn();
20489 let mut parser = mini_parser_with_hooks(
20490 vec![
20491 TestToken::new(1).with_text("x"),
20492 TestToken::eof("parser-test", 1, 1, 1),
20493 ],
20494 InitOrderingHooks::default(),
20495 );
20496
20497 let (_, deferred_actions) = parser
20498 .parse_atn_rule_with_runtime_options(
20499 &atn,
20500 0,
20501 ParserRuntimeOptions {
20502 init_action_rules: &[0],
20503 action_indices: &[(0, 7)],
20504 ..ParserRuntimeOptions::default()
20505 },
20506 )
20507 .expect("the named action should observe rule-init state");
20508
20509 assert!(deferred_actions.is_empty());
20510 assert_eq!(
20511 parser.semantic_hooks.events,
20512 ["init", "action:7:initialized=true", "predicate:true",]
20513 );
20514 }
20515
20516 #[test]
20517 fn committed_walker_defers_unhandled_rule_init_for_legacy_replay() {
20518 let atn = token_then_eof_atn();
20519 let mut parser = mini_parser(vec![
20520 TestToken::new(1).with_text("x"),
20521 TestToken::eof("parser-test", 1, 1, 1),
20522 ]);
20523
20524 let (_, deferred_actions) = parser
20525 .parse_atn_rule_with_runtime_options(
20526 &atn,
20527 0,
20528 ParserRuntimeOptions {
20529 init_action_rules: &[0],
20530 action_indices: &[(usize::MAX, 0)],
20531 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20532 ..ParserRuntimeOptions::default()
20533 },
20534 )
20535 .expect("a declined init should remain available for legacy replay");
20536
20537 assert_eq!(
20538 deferred_actions,
20539 [ParserAction::new_rule_init(0, 0, Some(0))]
20540 );
20541 }
20542
20543 #[test]
20544 fn committed_walker_dispatches_recovery_diagnostics() {
20545 let atn = noop_action_then_token_then_eof_atn();
20546 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20547 let mut parser = mini_parser_with_hooks(
20548 vec![
20549 TestToken::new(1).with_text("x"),
20550 TestToken::new(2).with_text("y"),
20551 TestToken::eof("parser-test", 2, 1, 2),
20552 ],
20553 StatefulActionHooks::default(),
20554 );
20555 parser.remove_error_listeners();
20556 parser.add_error_listener(RecordingErrorListener {
20557 diagnostics: Arc::clone(&diagnostics),
20558 });
20559
20560 let (tree, _) = parser
20561 .parse_atn_rule_with_runtime_options(
20562 &atn,
20563 0,
20564 ParserRuntimeOptions {
20565 action_indices: &[(0, 5)],
20566 ..ParserRuntimeOptions::default()
20567 },
20568 )
20569 .expect("the committed rule should recover");
20570
20571 assert_eq!(parser.node(tree).text(), "xy<EOF>");
20572 assert_eq!(parser.number_of_syntax_errors(), 1);
20573 insta::assert_debug_snapshot!(
20574 "committed_walker_dispatches_recovery_diagnostics",
20575 *diagnostics.lock().expect("recorded diagnostics lock")
20576 );
20577 }
20578
20579 #[test]
20580 fn committed_bail_error_notifies_error_listener() {
20581 let atn = noop_action_then_token_then_eof_atn();
20582 let diagnostics = Arc::new(Mutex::new(Vec::new()));
20583 let mut parser = mini_parser(vec![
20584 TestToken::new(2)
20585 .with_text("y")
20586 .with_span(0, 0)
20587 .with_byte_span(0, 1)
20588 .with_position(3, 5),
20589 TestToken::eof("parser-test", 1, 1, 1),
20590 ]);
20591 parser.set_bail_on_error(true);
20592 parser.remove_error_listeners();
20593 parser.add_error_listener(RecordingErrorListener {
20594 diagnostics: Arc::clone(&diagnostics),
20595 });
20596
20597 let error = parser
20598 .parse_atn_rule_with_runtime_options(
20599 &atn,
20600 0,
20601 ParserRuntimeOptions {
20602 action_indices: &[(0, 5)],
20603 ..ParserRuntimeOptions::default()
20604 },
20605 )
20606 .expect_err("bail mode must return the committed token mismatch");
20607 let diagnostics = diagnostics
20608 .lock()
20609 .expect("recorded diagnostics lock")
20610 .clone();
20611
20612 insta::assert_debug_snapshot!(
20613 "committed_bail_error_notifies_error_listener",
20614 (error, diagnostics)
20615 );
20616 }
20617
20618 #[test]
20619 fn semantic_hook_handles_committed_parser_action() {
20620 let atn = token_then_eof_atn();
20621 let mut parser = mini_parser_with_hooks(
20622 vec![
20623 TestToken::new(1).with_text("x"),
20624 TestToken::eof("parser-test", 1, 1, 1),
20625 ],
20626 RecordingHooks::default(),
20627 );
20628 let (tree, _) = parser
20629 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
20630 .expect("rule parses before action hook is tested");
20631
20632 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
20633 assert_eq!(
20634 parser.semantic_hooks.actions,
20635 vec![(42, "x".to_owned(), Some("s".to_owned()))]
20636 );
20637 assert_eq!(
20638 parser.semantic_hooks.action_trees,
20639 [Some("x<EOF>".to_owned())]
20640 );
20641 }
20642
20643 #[test]
20644 fn unhandled_committed_action_fails_loud_under_error_policy() {
20645 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
20649 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
20650 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
20651
20652 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
20654
20655 let error = parser
20656 .take_unknown_semantic_error()
20657 .expect("an unhandled committed action under Error policy must fail loud");
20658 let AntlrError::Unsupported(message) = error else {
20659 panic!("expected AntlrError::Unsupported, got {error:?}");
20660 };
20661 assert!(
20662 message.contains("unhandled semantic action") && message.contains("state=42"),
20663 "message should name the dropped action coordinate: {message}"
20664 );
20665
20666 let mut lenient =
20668 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
20669 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
20670 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
20671 assert!(lenient.take_unknown_semantic_error().is_none());
20672 }
20673
20674 #[test]
20675 fn translated_predicate_is_unaffected_by_error_policy() {
20676 let atn = predicate_after_token_atn();
20677 let mut parser = mini_parser(vec![
20678 TestToken::new(1).with_text("x"),
20679 TestToken::new(2).with_text("y"),
20680 TestToken::eof("parser-test", 2, 1, 2),
20681 ]);
20682
20683 let (tree, _) = parser
20684 .parse_atn_rule_with_runtime_options(
20685 &atn,
20686 0,
20687 ParserRuntimeOptions {
20688 predicates: &[(0, 0, ParserPredicate::True)],
20689 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20690 ..ParserRuntimeOptions::default()
20691 },
20692 )
20693 .expect("a predicate covered by the table is not an unknown coordinate");
20694
20695 assert_eq!(parser.node(tree).text(), "xy");
20696 }
20697
20698 #[test]
20703 fn parser_speculative_replay_threads_stack_member_state() {
20704 let mut ir = SemIr::new();
20705 let one = ir.expr(PExpr::Int(1));
20706 let push = ir.stmt(AStmt::PushMember(0, one));
20707 let pop = ir.stmt(AStmt::PopMember(0));
20708 let semantics = ParserSemantics {
20709 ir,
20710 predicates: Vec::new(),
20711 actions: vec![
20712 ParserSemanticAction {
20713 source_state: 1,
20714 rule_index: usize::MAX,
20715 stmt: push,
20716 speculative: true,
20717 },
20718 ParserSemanticAction {
20719 source_state: 2,
20720 rule_index: usize::MAX,
20721 stmt: pop,
20722 speculative: true,
20723 },
20724 ],
20725 };
20726
20727 let pushed = member_values_after_action(1, &[], Some(&semantics), &MemberEnv::new());
20729 assert_eq!(pushed.stack_top(0), Some(1));
20730 assert_eq!(pushed.stack_len(0), 1);
20731
20732 assert_eq!(MemberEnv::new().stack_len(0), 0);
20735
20736 let popped = member_values_after_action(2, &[], Some(&semantics), &pushed);
20739 assert_eq!(popped.stack_top(0), None);
20740 assert_eq!(popped, MemberEnv::new(), "emptied stack must canonicalize");
20741
20742 let underflowed = member_values_after_action(2, &[], Some(&semantics), &MemberEnv::new());
20744 assert_eq!(underflowed, MemberEnv::new());
20745 }
20746
20747 fn hook_predicate_semantics() -> ParserSemantics {
20752 let mut ir = SemIr::new();
20753 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
20754 ParserSemantics {
20755 ir,
20756 predicates: vec![ParserSemanticPredicate {
20757 rule_index: 0,
20758 pred_index: 0,
20759 expr,
20760 failure_message: None,
20761 }],
20762 actions: Vec::new(),
20763 }
20764 }
20765
20766 #[derive(Debug, Default)]
20767 struct DecliningHooks;
20768
20769 impl SemanticHooks for DecliningHooks {}
20770
20771 #[test]
20772 fn semir_hook_none_falls_through_to_assume_true() {
20773 let atn = predicate_after_token_atn();
20774 let semantics = hook_predicate_semantics();
20775 let mut parser = mini_parser_with_hooks(
20776 vec![
20777 TestToken::new(1).with_text("x"),
20778 TestToken::new(2).with_text("y"),
20779 TestToken::eof("parser-test", 2, 1, 2),
20780 ],
20781 DecliningHooks,
20782 );
20783
20784 let (tree, _) = parser
20785 .parse_atn_rule_with_runtime_options(
20786 &atn,
20787 0,
20788 ParserRuntimeOptions {
20789 semantics: Some(&semantics),
20790 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
20791 ..ParserRuntimeOptions::default()
20792 },
20793 )
20794 .expect("a declined SemIR hook must pass under assume-true");
20795
20796 assert_eq!(parser.node(tree).text(), "xy");
20797 }
20798
20799 #[test]
20800 fn semir_hook_none_falls_through_to_assume_false() {
20801 let atn = predicate_after_token_atn();
20802 let semantics = hook_predicate_semantics();
20803 let mut parser = mini_parser_with_hooks(
20804 vec![
20805 TestToken::new(1).with_text("x"),
20806 TestToken::new(2).with_text("y"),
20807 TestToken::eof("parser-test", 2, 1, 2),
20808 ],
20809 DecliningHooks,
20810 );
20811
20812 let result = parser.parse_atn_rule_with_runtime_options(
20813 &atn,
20814 0,
20815 ParserRuntimeOptions {
20816 semantics: Some(&semantics),
20817 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
20818 ..ParserRuntimeOptions::default()
20819 },
20820 );
20821
20822 assert!(
20823 result.is_err(),
20824 "a declined SemIR hook must fail the only guarded path under assume-false"
20825 );
20826 }
20827
20828 #[test]
20829 fn semir_hook_none_records_coordinate_under_error_policy() {
20830 let atn = predicate_after_token_atn();
20831 let semantics = hook_predicate_semantics();
20832 let mut parser = mini_parser_with_hooks(
20833 vec![
20834 TestToken::new(1).with_text("x"),
20835 TestToken::new(2).with_text("y"),
20836 TestToken::eof("parser-test", 2, 1, 2),
20837 ],
20838 DecliningHooks,
20839 );
20840
20841 let error = parser
20842 .parse_atn_rule_with_runtime_options(
20843 &atn,
20844 0,
20845 ParserRuntimeOptions {
20846 semantics: Some(&semantics),
20847 unknown_predicate_policy: UnknownSemanticPolicy::Error,
20848 ..ParserRuntimeOptions::default()
20849 },
20850 )
20851 .expect_err("a declined SemIR hook under Error policy must fail the parse");
20852
20853 let AntlrError::Unsupported(message) = error else {
20854 panic!("expected AntlrError::Unsupported, got {error:?}");
20855 };
20856 assert!(
20857 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
20858 "message should name the unresolved coordinate: {message}"
20859 );
20860 }
20861
20862 #[test]
20863 fn generated_direct_predicate_honors_installed_policy() {
20864 let semantics = hook_predicate_semantics();
20870 let context = ParserRuleContext::new(0, -1);
20871
20872 let mut assume_true =
20873 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
20874 assert!(
20875 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
20876 &semantics, 0, 0, &context, 0
20877 ),
20878 "default AssumeTrue accepts a declined hook"
20879 );
20880 assert!(assume_true.take_unknown_semantic_error().is_none());
20881
20882 let mut error_policy =
20883 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
20884 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
20885 assert!(
20886 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
20887 &semantics, 0, 0, &context, 0
20888 ),
20889 "Error policy rejects a declined hook on the generated-direct path"
20890 );
20891 let error = error_policy
20892 .take_unknown_semantic_error()
20893 .expect("Error policy records the unresolved coordinate for the generated path");
20894 let AntlrError::Unsupported(message) = error else {
20895 panic!("expected AntlrError::Unsupported, got {error:?}");
20896 };
20897 assert!(message.contains("pred_index=0"), "message: {message}");
20898 }
20899
20900 #[test]
20901 fn parser_rule_start_skips_leading_hidden_tokens() {
20902 let atn = token_then_eof_atn();
20903 let mut parser = mini_parser(vec![
20904 TestToken::new(99)
20905 .with_text(" ")
20906 .with_channel(HIDDEN_CHANNEL),
20907 TestToken::new(1).with_text("x"),
20908 TestToken::eof("parser-test", 2, 1, 2),
20909 ]);
20910
20911 let tree = parser
20912 .parse_atn_rule(&atn, 0)
20913 .expect("artificial parser rule should parse");
20914 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
20915 panic!("rule node should be present");
20916 };
20917 assert_eq!(
20918 rule.start()
20919 .expect("rule should have a start token")
20920 .token_type(),
20921 1
20922 );
20923 }
20924
20925 #[test]
20926 fn parser_action_after_eof_stops_at_eof_token() {
20927 let atn = eof_then_action_atn();
20928 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
20929
20930 let (_, actions) = parser
20931 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
20932 .expect("EOF action rule should parse");
20933
20934 assert_eq!(actions.len(), 1);
20935 assert_eq!(actions[0].stop_index(), Some(0));
20936 assert_eq!(
20937 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
20938 ""
20939 );
20940 }
20941
20942 #[test]
20943 fn after_action_stop_uses_rule_context_stop_not_cursor() {
20944 let mut id = TestToken::new(1).with_text("x");
20949 id.set_token_index(0);
20950 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
20951 eof.set_token_index(1);
20952 let mut parser = mini_parser(vec![id.clone(), eof]);
20953 parser.consume();
20955 assert_eq!(parser.la(1), TOKEN_EOF);
20956
20957 let mut ctx = ParserRuleContext::new(0, 0);
20960 parser.set_context_stop(
20961 &mut ctx,
20962 parser.token_id_at(0).expect("ID token should be buffered"),
20963 );
20964 let tree = parser.rule_node(ctx);
20965
20966 let current_index = parser.input.index();
20967 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
20969 assert_eq!(
20971 parser.after_action_stop_index_for_tree(tree, current_index),
20972 Some(0)
20973 );
20974 }
20975
20976 #[test]
20977 fn after_action_start_uses_rule_context_start_not_cursor() {
20978 let mut parser = mini_parser(vec![
20983 TestToken::new(9)
20984 .with_text(" ")
20985 .with_channel(HIDDEN_CHANNEL),
20986 TestToken::new(9)
20987 .with_text(" ")
20988 .with_channel(HIDDEN_CHANNEL),
20989 TestToken::new(1).with_text("x"),
20990 TestToken::eof("parser-test", 3, 1, 3),
20991 ]);
20992
20993 let mut ctx = ParserRuleContext::new(0, 0);
20994 parser.set_context_start(
20995 &mut ctx,
20996 parser.token_id_at(2).expect("ID token should be buffered"),
20997 );
20998 let tree = parser.rule_node(ctx);
20999
21000 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
21003
21004 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
21006 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
21007 }
21008
21009 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
21010 FastRecognizeOutcome {
21011 index,
21012 consumed_eof,
21013 diagnostics: DiagnosticSeqId::EMPTY,
21014 deferred_nodes: FastDeferredNodeId::EMPTY,
21015 nodes: NodeSeqId(marker),
21016 }
21017 }
21018
21019 #[test]
21020 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
21021 let mut outcomes = vec![
21022 clean_fast_outcome(4, false, 0),
21023 clean_fast_outcome(2, false, 1),
21024 clean_fast_outcome(4, false, 2),
21025 clean_fast_outcome(4, true, 3),
21026 clean_fast_outcome(2, false, 4),
21027 ];
21028 let mut scratch = FastOutcomeDedupScratch::default();
21029
21030 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21031
21032 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
21033 assert_eq!(
21034 outcomes
21035 .iter()
21036 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
21037 .collect::<Vec<_>>(),
21038 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
21039 );
21040 assert!(scratch.dense_words.is_empty());
21041 assert!(scratch.sparse_keys.is_empty());
21042 }
21043
21044 #[test]
21045 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
21046 let mut scratch = FastOutcomeDedupScratch::default();
21047 let mut outcomes = (100..109)
21048 .flat_map(|index| {
21049 [
21050 clean_fast_outcome(
21051 index,
21052 false,
21053 u32::try_from(index).expect("test index fits in u32"),
21054 ),
21055 clean_fast_outcome(index, false, u32::MAX),
21056 ]
21057 })
21058 .collect();
21059
21060 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21061
21062 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
21063 assert_eq!(outcomes.len(), 9);
21064 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
21065 let dense_capacity = scratch.dense_words.capacity();
21066
21067 let mut reused = (1_000..1_009)
21068 .map(|index| {
21069 clean_fast_outcome(
21070 index,
21071 false,
21072 u32::try_from(index).expect("test index fits in u32"),
21073 )
21074 })
21075 .collect();
21076 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
21077
21078 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
21079 assert_eq!(reused.len(), 9);
21080 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
21081 }
21082
21083 #[test]
21084 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
21085 let mut scratch = FastOutcomeDedupScratch::default();
21086 let sparse_indexes = [
21087 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
21088 ];
21089 let mut outcomes = sparse_indexes
21090 .into_iter()
21091 .chain([400_000])
21092 .enumerate()
21093 .map(|(marker, index)| {
21094 clean_fast_outcome(
21095 index,
21096 false,
21097 u32::try_from(marker).expect("test marker fits in u32"),
21098 )
21099 })
21100 .collect();
21101
21102 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21103
21104 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21105 assert_eq!(outcomes.len(), sparse_indexes.len());
21106 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
21107 let sparse_capacity = scratch.sparse_keys.capacity();
21108
21109 let mut reused = sparse_indexes
21110 .into_iter()
21111 .map(|index| {
21112 clean_fast_outcome(
21113 index,
21114 false,
21115 u32::try_from(index).expect("test index fits in u32"),
21116 )
21117 })
21118 .collect();
21119 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
21120
21121 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21122 assert_eq!(reused.len(), sparse_indexes.len());
21123 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
21124 }
21125
21126 #[test]
21127 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
21128 let mut scratch = FastOutcomeDedupScratch::default();
21129 scratch
21130 .sparse_keys
21131 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
21132 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
21133 let mut outcomes = (0..9)
21134 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
21135 .collect();
21136
21137 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
21138
21139 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
21140 assert!(scratch.sparse_keys.is_empty());
21141 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
21142 }
21143
21144 #[test]
21145 fn fast_outcome_selection_respects_sll_tie_order() {
21146 let mut arena = RecognitionArena::default();
21147 let first = FastRecognizeOutcome {
21148 index: 1,
21149 consumed_eof: false,
21150 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21151 line: 1,
21152 column: 0,
21153 message: "mismatched input 'x'".to_owned(),
21154 offending: None,
21155 }]),
21156 deferred_nodes: FastDeferredNodeId::EMPTY,
21157 nodes: NodeSeqId::EMPTY,
21158 };
21159 let second = FastRecognizeOutcome {
21160 index: first.index,
21161 consumed_eof: first.consumed_eof,
21162 diagnostics: DiagnosticSeqId::EMPTY,
21163 deferred_nodes: FastDeferredNodeId::EMPTY,
21164 nodes: NodeSeqId::EMPTY,
21165 };
21166
21167 let selected = select_best_fast_outcome(
21168 [first, second].into_iter(),
21169 PredictionMode::Sll,
21170 None,
21171 |_| panic!("caller-follow token probe should not run"),
21172 &arena,
21173 )
21174 .expect("one outcome should be selected");
21175 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
21176 let eof_second = FastRecognizeOutcome {
21177 index: second.index,
21178 consumed_eof: true,
21179 diagnostics: DiagnosticSeqId::EMPTY,
21180 deferred_nodes: FastDeferredNodeId::EMPTY,
21181 nodes: NodeSeqId::EMPTY,
21182 };
21183 let selected = select_best_fast_outcome(
21184 [first, eof_second].into_iter(),
21185 PredictionMode::Sll,
21186 None,
21187 |_| panic!("caller-follow token probe should not run"),
21188 &arena,
21189 )
21190 .expect("one outcome should be selected");
21191 assert!(!selected.consumed_eof);
21192 let selected = select_best_fast_outcome(
21193 [first, second].into_iter(),
21194 PredictionMode::Ll,
21195 None,
21196 |_| panic!("caller-follow token probe should not run"),
21197 &arena,
21198 )
21199 .expect("one outcome should be selected");
21200 assert!(selected.diagnostics.is_empty());
21201 }
21202
21203 #[test]
21204 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
21205 let mut arena = RecognitionArena::default();
21206 let first = FastRecognizeOutcome {
21207 index: 3,
21208 consumed_eof: false,
21209 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21210 line: 1,
21211 column: 0,
21212 message: "mismatched input 'x' expecting 'a'".to_owned(),
21213 offending: None,
21214 }]),
21215 deferred_nodes: FastDeferredNodeId::EMPTY,
21216 nodes: NodeSeqId::EMPTY,
21217 };
21218 let same_rank = FastRecognizeOutcome {
21219 index: first.index,
21220 consumed_eof: first.consumed_eof,
21221 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21222 line: 1,
21223 column: 0,
21224 message: "mismatched input 'x' expecting 'b'".to_owned(),
21225 offending: None,
21226 }]),
21227 deferred_nodes: FastDeferredNodeId::EMPTY,
21228 nodes: NodeSeqId::EMPTY,
21229 };
21230 let better_rank = FastRecognizeOutcome {
21231 index: first.index,
21232 consumed_eof: first.consumed_eof,
21233 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
21234 line: 1,
21235 column: 0,
21236 message: "missing 'a' at 'x'".to_owned(),
21237 offending: None,
21238 }]),
21239 deferred_nodes: FastDeferredNodeId::EMPTY,
21240 nodes: NodeSeqId::EMPTY,
21241 };
21242 let mut outcomes = vec![first, same_rank, better_rank];
21243
21244 dedupe_fast_outcomes(&mut outcomes, &arena);
21245
21246 assert_eq!(outcomes.len(), 2);
21247 assert_eq!(
21248 arena
21249 .diagnostics(outcomes[0].diagnostics)
21250 .next()
21251 .expect("first diagnostic")
21252 .message,
21253 "mismatched input 'x' expecting 'a'"
21254 );
21255 assert_eq!(
21256 arena
21257 .diagnostics(outcomes[1].diagnostics)
21258 .next()
21259 .expect("second diagnostic")
21260 .message,
21261 "missing 'a' at 'x'"
21262 );
21263 }
21264
21265 #[test]
21266 fn fast_outcome_selection_prefers_generated_caller_follow() {
21267 let arena = RecognitionArena::default();
21268 let earlier = FastRecognizeOutcome {
21269 index: 7,
21270 consumed_eof: false,
21271 diagnostics: DiagnosticSeqId::EMPTY,
21272 deferred_nodes: FastDeferredNodeId::EMPTY,
21273 nodes: NodeSeqId::EMPTY,
21274 };
21275 let later = FastRecognizeOutcome {
21276 index: 8,
21277 consumed_eof: false,
21278 diagnostics: DiagnosticSeqId::EMPTY,
21279 deferred_nodes: FastDeferredNodeId::EMPTY,
21280 nodes: NodeSeqId::EMPTY,
21281 };
21282 let mut follow = TokenBitSet::default();
21283 follow.insert(5);
21284
21285 let selected = select_best_fast_outcome(
21286 [later, earlier].into_iter(),
21287 PredictionMode::Ll,
21288 Some(&follow),
21289 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
21290 &arena,
21291 )
21292 .expect("one outcome should be selected");
21293 assert_eq!(selected.index, 7);
21294
21295 let selected = select_best_fast_outcome(
21296 [later, earlier].into_iter(),
21297 PredictionMode::Ll,
21298 Some(&follow),
21299 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
21300 &arena,
21301 )
21302 .expect("one outcome should be selected");
21303 assert_eq!(selected.index, 8);
21304
21305 let indented_next_statement = FastRecognizeOutcome {
21306 index: 9,
21307 consumed_eof: false,
21308 diagnostics: DiagnosticSeqId::EMPTY,
21309 deferred_nodes: FastDeferredNodeId::EMPTY,
21310 nodes: NodeSeqId::EMPTY,
21311 };
21312 let selected = select_best_fast_outcome(
21313 [indented_next_statement, earlier].into_iter(),
21314 PredictionMode::Ll,
21315 Some(&follow),
21316 |index| {
21317 let is_boundary = index == 7;
21318 let is_boundary_gap = matches!(index, 7 | 8);
21319 (
21320 if index == 7 { 5 } else { TOKEN_EOF },
21321 is_boundary,
21322 is_boundary_gap,
21323 )
21324 },
21325 &arena,
21326 )
21327 .expect("one outcome should be selected");
21328 assert_eq!(selected.index, 7);
21329
21330 let continuation = FastRecognizeOutcome {
21331 index: 10,
21332 consumed_eof: false,
21333 diagnostics: DiagnosticSeqId::EMPTY,
21334 deferred_nodes: FastDeferredNodeId::EMPTY,
21335 nodes: NodeSeqId::EMPTY,
21336 };
21337 let selected = select_best_fast_outcome(
21338 [continuation, earlier].into_iter(),
21339 PredictionMode::Ll,
21340 Some(&follow),
21341 |index| {
21342 let is_boundary = matches!(index, 7 | 9);
21343 (
21344 if index == 7 { 5 } else { TOKEN_EOF },
21345 is_boundary,
21346 is_boundary,
21347 )
21348 },
21349 &arena,
21350 )
21351 .expect("one outcome should be selected");
21352 assert_eq!(selected.index, 10);
21353
21354 let selected = select_best_fast_outcome(
21355 [earlier, later].into_iter(),
21356 PredictionMode::Sll,
21357 Some(&follow),
21358 |_| panic!("caller-follow token probe should not run in SLL mode"),
21359 &arena,
21360 )
21361 .expect("one outcome should be selected");
21362 assert_eq!(selected.index, 8);
21363 }
21364
21365 #[test]
21366 fn caller_follow_boundary_text_requires_separator_shape() {
21367 assert!(is_caller_follow_boundary_text(";"));
21368 assert!(is_caller_follow_boundary_text("\n"));
21369 assert!(is_caller_follow_boundary_text("\r\n "));
21370 assert!(is_caller_follow_boundary_text(";\n"));
21371 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
21372 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
21373 assert!(!is_caller_follow_boundary_text("identifier"));
21374 assert!(is_caller_follow_boundary_gap_text(" \t "));
21375 assert!(is_caller_follow_boundary_gap_text("\n "));
21376 assert!(is_caller_follow_boundary_gap_text(";\t"));
21377 assert!(!is_caller_follow_boundary_gap_text(
21378 "\"\"\"line1\nline2\"\"\""
21379 ));
21380 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
21381 }
21382
21383 #[test]
21384 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
21385 let mut parser = mini_parser(vec![
21386 TestToken::new(5).with_text("\n"),
21387 TestToken::new(6)
21388 .with_text("// comment\n")
21389 .with_channel(HIDDEN_CHANNEL),
21390 TestToken::new(1).with_text("x"),
21391 TestToken::eof("parser-test", 1, 2, 0),
21392 ]);
21393
21394 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
21395 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
21396 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
21397 }
21398
21399 #[test]
21400 fn caller_follow_token_info_uses_stream_visible_channel() {
21401 let source = Source {
21402 tokens: vec![
21403 TestToken::new(5).with_text("\n").with_channel(2),
21404 TestToken::new(1).with_text("x").with_channel(2),
21405 TestToken::new(6)
21406 .with_text("// comment\n")
21407 .with_channel(HIDDEN_CHANNEL),
21408 TestToken::eof("parser-test", 1, 2, 0),
21409 ],
21410 index: 0,
21411 };
21412 let data = RecognizerData::new(
21413 "Mini.g4",
21414 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
21415 );
21416 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
21417
21418 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
21419 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
21420 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
21421 }
21422
21423 #[test]
21424 fn reset_per_parse_caches_clears_state_expected_token_cache() {
21425 let atn = token_then_eof_atn();
21426 let mut parser = mini_parser(Vec::new());
21427
21428 let _ = parser.cached_state_expected_token_set(&atn, 0);
21429 assert!(!parser.state_expected_token_cache.is_empty());
21430
21431 parser.reset_per_parse_caches();
21432 assert!(parser.state_expected_token_cache.is_empty());
21433 }
21434
21435 #[test]
21436 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
21437 let cyclic = epsilon_cycle_atn();
21438 let acyclic = token_then_eof_atn();
21439 let mut parser = mini_parser(Vec::new());
21440
21441 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
21442 assert_eq!(
21443 parser.empty_cycle_cache_atn,
21444 Some(SharedAtnCacheKey::for_atn(&cyclic))
21445 );
21446 assert_eq!(parser.empty_cycle_cache[1], Some(true));
21447
21448 parser.reset_per_parse_caches();
21449 assert_eq!(parser.empty_cycle_cache[1], Some(true));
21450 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
21451
21452 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
21453 assert_eq!(
21454 parser.empty_cycle_cache_atn,
21455 Some(SharedAtnCacheKey::for_atn(&acyclic))
21456 );
21457 assert_eq!(parser.empty_cycle_cache[1], Some(false));
21458 }
21459
21460 #[test]
21461 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
21462 let source = Source {
21463 tokens: vec![
21464 TestToken::new(1).with_text("x"),
21465 TestToken::eof("parser-test", 1, 1, 1),
21466 ],
21467 index: 0,
21468 };
21469 let data = RecognizerData::new(
21470 "Mini.g4",
21471 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
21472 );
21473 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
21474 let expected = ExpectedTokens {
21475 index: Some(0),
21476 symbols: BTreeSet::new(),
21477 no_viable: None,
21478 };
21479
21480 let (_, message) = parser.expected_error_message(0, 0, &expected);
21481
21482 assert_eq!(message, "mismatched input 'x'");
21483 }
21484
21485 #[test]
21486 fn eof_rule_stop_index_points_at_eof_token() {
21487 let source = Source {
21488 tokens: vec![
21489 TestToken::new(1).with_text("x"),
21490 TestToken::eof("parser-test", 1, 1, 1),
21491 ],
21492 index: 0,
21493 };
21494 let data = RecognizerData::new(
21495 "Mini.g4",
21496 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
21497 );
21498 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
21499
21500 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
21501 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
21502 }
21503
21504 #[test]
21505 fn generated_parser_action_uses_current_rule_stop_boundary() {
21506 let mut parser = mini_parser(vec![
21507 TestToken::new(1).with_text("x"),
21508 TestToken::eof("parser-test", 1, 1, 1),
21509 ]);
21510
21511 parser.match_token(1).expect("token should match");
21512 let action = parser.parser_action_at_current(7, 0, 0, false);
21513 assert_eq!(action.source_state(), 7);
21514 assert_eq!(action.rule_index(), 0);
21515 assert_eq!(action.start_index(), 0);
21516 assert_eq!(action.stop_index(), Some(0));
21517
21518 parser.match_eof().expect("EOF should match");
21519 let action = parser.parser_action_at_current(8, 0, 0, true);
21520 assert_eq!(action.stop_index(), Some(1));
21521 }
21522
21523 #[test]
21524 fn folds_left_recursive_boundary_into_rule_node() {
21525 let mut arena = RecognitionArena::default();
21526 let first = arena.push_node(ArenaRecognizedNode::Token {
21527 token: TokenId::try_from(0).expect("test token ID"),
21528 });
21529 let boundary = arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
21530 rule_index: 1,
21531 alt_number: 3,
21532 });
21533 let second = arena.push_node(ArenaRecognizedNode::Token {
21534 token: TokenId::try_from(1).expect("test token ID"),
21535 });
21536 let mut nodes = NodeSeqId::EMPTY;
21537 for node in [first, boundary, second].into_iter().rev() {
21538 nodes = arena.prepend(nodes, node);
21539 }
21540
21541 let folded = arena.fold_left_recursive_boundaries(nodes);
21542 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
21543
21544 assert_eq!(folded_nodes.len(), 2);
21545 let ArenaRecognizedNode::Rule {
21546 rule_index,
21547 invoking_state,
21548 alt_number,
21549 start_index,
21550 stop_index,
21551 children,
21552 ..
21553 } = arena.node(folded_nodes[0])
21554 else {
21555 panic!("first folded node should be a rule");
21556 };
21557 insta::assert_debug_snapshot!(
21561 "folds_left_recursive_boundary_into_rule_node",
21562 (
21563 rule_index,
21564 invoking_state,
21565 alt_number,
21566 start_index,
21567 stop_index
21568 )
21569 );
21570 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
21571 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
21572
21573 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
21574 assert_eq!(
21575 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
21576 (4, 3, 1)
21577 );
21578 assert_eq!(
21579 (stats.total_links, stats.live_links, stats.dead_links),
21580 (9, 3, 6)
21581 );
21582 }
21583
21584 #[test]
21585 fn recognition_arena_reports_live_dead_and_retained_capacity() {
21586 let mut arena = RecognitionArena::default();
21587 let token = arena.push_node(ArenaRecognizedNode::Token {
21588 token: TokenId::try_from(0).expect("test token ID"),
21589 });
21590 let extra = arena.push_extra(RecognitionExtra::MissingToken {
21591 token_type: 2,
21592 at_index: 1,
21593 text: "<missing X>".to_owned(),
21594 });
21595 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
21596 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
21597 token: TokenId::try_from(1).expect("test token ID"),
21598 });
21599 let mut live = NodeSeqId::EMPTY;
21600 live = arena.prepend(live, missing);
21601 live = arena.prepend(live, token);
21602 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
21603 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
21604 line: 1,
21605 column: 0,
21606 message: "missing X".to_owned(),
21607 offending: None,
21608 }]);
21609 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
21610 line: 1,
21611 column: 1,
21612 message: "discarded".to_owned(),
21613 offending: None,
21614 }]);
21615 let deferred_children = arena.deferred_fragment(live);
21616 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
21617 rule_index: 0,
21618 invoking_state: -1,
21619 start_index: 0,
21620 stop_index: Some(1),
21621 deferred_children,
21622 children: NodeSeqId::EMPTY,
21623 });
21624
21625 let stats = arena.stats(live, live_diagnostics);
21626
21627 assert_eq!(
21628 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
21629 (3, 2, 1)
21630 );
21631 assert_eq!(
21632 (stats.total_links, stats.live_links, stats.dead_links),
21633 (5, 3, 2)
21634 );
21635 assert_eq!(
21636 (stats.total_extras, stats.live_extras, stats.dead_extras),
21637 (3, 2, 1)
21638 );
21639 assert!(size_of::<SeqLink>() <= 8);
21640 assert!(size_of::<DiagnosticLink>() <= 8);
21641 assert!(size_of::<FastDeferredNode>() <= 12);
21642 assert!(size_of::<FastDeferredRule>() <= 28);
21643 assert!(size_of::<FastRecognizeOutcome>() <= 24);
21644 let capacities = (
21645 stats.node_capacity,
21646 stats.link_capacity,
21647 stats.extra_capacity,
21648 );
21649 let deferred_capacities = (
21650 arena.deferred_nodes.capacity(),
21651 arena.deferred_rules.capacity(),
21652 );
21653
21654 arena.reset();
21655 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
21656 assert_eq!(
21657 (reset.total_nodes, reset.total_links, reset.total_extras),
21658 (0, 0, 0)
21659 );
21660 assert_eq!(
21661 (
21662 reset.node_capacity,
21663 reset.link_capacity,
21664 reset.extra_capacity,
21665 ),
21666 capacities
21667 );
21668 assert!(arena.deferred_nodes.is_empty());
21669 assert!(arena.deferred_rules.is_empty());
21670 assert_eq!(
21671 (
21672 arena.deferred_nodes.capacity(),
21673 arena.deferred_rules.capacity(),
21674 ),
21675 deferred_capacities
21676 );
21677 }
21678
21679 #[test]
21680 fn parser_computes_recognition_arena_stats_on_demand() {
21681 let mut parser = mini_parser(Vec::new());
21682 let live = parser
21683 .recognition_arena
21684 .push_node(ArenaRecognizedNode::Token {
21685 token: TokenId::try_from(0).expect("test token ID"),
21686 });
21687 let discarded = parser
21688 .recognition_arena
21689 .push_node(ArenaRecognizedNode::ErrorToken {
21690 token: TokenId::try_from(1).expect("test token ID"),
21691 });
21692 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
21693 let _discarded_root = parser
21694 .recognition_arena
21695 .prepend(NodeSeqId::EMPTY, discarded);
21696 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
21697
21698 let stats = parser.recognition_arena_stats();
21699
21700 assert_eq!(
21701 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
21702 (2, 1, 1)
21703 );
21704 assert_eq!(
21705 (stats.total_links, stats.live_links, stats.dead_links),
21706 (2, 1, 1)
21707 );
21708 }
21709
21710 #[test]
21711 fn recognition_arena_drops_capacity_above_retention_limit() {
21712 let mut storage = Vec::<u8>::with_capacity(4);
21713 storage.extend([1, 2, 3]);
21714
21715 reset_arena_vec(&mut storage, 3);
21716
21717 assert!(storage.is_empty());
21718 assert_eq!(storage.capacity(), 0);
21719 }
21720
21721 #[test]
21722 fn recognition_arena_concatenates_diagnostics_in_source_order() {
21723 let mut arena = RecognitionArena::default();
21724 let prefix = arena.diagnostic_sequence([
21725 ParserDiagnostic {
21726 line: 1,
21727 column: 0,
21728 message: "first".to_owned(),
21729 offending: None,
21730 },
21731 ParserDiagnostic {
21732 line: 1,
21733 column: 1,
21734 message: "second".to_owned(),
21735 offending: None,
21736 },
21737 ]);
21738 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
21739 line: 1,
21740 column: 2,
21741 message: "third".to_owned(),
21742 offending: None,
21743 }]);
21744 let extras_before = arena.extras.len();
21745
21746 let combined = arena.concat_diagnostics(prefix, suffix);
21747 let messages = arena
21748 .diagnostics(combined)
21749 .map(|diagnostic| diagnostic.message.as_str())
21750 .collect::<Vec<_>>();
21751
21752 assert_eq!(messages, ["first", "second", "third"]);
21753 assert_eq!(arena.extras.len(), extras_before);
21754 }
21755
21756 #[test]
21757 fn outcome_ties_keep_later_non_recursive_alternative() {
21758 let arena = RecognitionArena::default();
21759 let first = RecognizeOutcome {
21760 index: 1,
21761 consumed_eof: false,
21762 alt_number: 0,
21763 member_values: MemberEnv::new(),
21764 return_values: BTreeMap::new(),
21765 diagnostics: DiagnosticSeqId::EMPTY,
21766 decisions: Vec::new(),
21767 actions: vec![ParserAction::new(1, 0, 0, None)],
21768 nodes: NodeSeqId::EMPTY,
21769 };
21770 let second = RecognizeOutcome {
21771 actions: vec![ParserAction::new(2, 0, 0, None)],
21772 ..first.clone()
21773 };
21774
21775 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
21776 .expect("one outcome should be selected");
21777 assert_eq!(selected.actions[0].source_state(), 2);
21778 }
21779
21780 #[test]
21781 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
21782 let arena = RecognitionArena::default();
21783 let first = RecognizeOutcome {
21784 index: 1,
21785 consumed_eof: false,
21786 alt_number: 0,
21787 member_values: MemberEnv::new(),
21788 return_values: BTreeMap::new(),
21789 diagnostics: DiagnosticSeqId::EMPTY,
21790 decisions: Vec::new(),
21791 actions: vec![ParserAction::new(1, 0, 0, None)],
21792 nodes: NodeSeqId::EMPTY,
21793 };
21794 let second = RecognizeOutcome {
21795 actions: vec![
21796 ParserAction::new(2, 0, 0, None),
21797 ParserAction::new(3, 0, 0, None),
21798 ],
21799 ..first.clone()
21800 };
21801
21802 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
21803 .expect("one outcome should be selected");
21804 assert_eq!(selected.actions.len(), 2);
21805 }
21806
21807 #[test]
21808 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
21809 let arena = RecognitionArena::default();
21810 let first = RecognizeOutcome {
21811 index: 7,
21812 consumed_eof: false,
21813 alt_number: 0,
21814 member_values: MemberEnv::new(),
21815 return_values: BTreeMap::new(),
21816 diagnostics: DiagnosticSeqId::EMPTY,
21817 decisions: vec![1, 0],
21818 actions: vec![
21819 ParserAction::new(23, 2, 2, Some(4)),
21820 ParserAction::new(23, 2, 0, Some(6)),
21821 ],
21822 nodes: NodeSeqId::EMPTY,
21823 };
21824 let second = RecognizeOutcome {
21825 decisions: vec![0, 1],
21826 actions: vec![
21827 ParserAction::new(23, 2, 2, Some(6)),
21828 ParserAction::new(23, 2, 0, Some(6)),
21829 ],
21830 ..first.clone()
21831 };
21832
21833 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
21834 .expect("one outcome should be selected");
21835 assert_eq!(selected.actions[0].stop_index(), Some(6));
21836 }
21837
21838 #[test]
21839 fn outcome_ties_keep_first_recursive_tree_shape() {
21840 let mut arena = RecognitionArena::default();
21841 let token = arena.push_node(ArenaRecognizedNode::Token {
21842 token: TokenId::try_from(0).expect("test token ID"),
21843 });
21844 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
21845 let inner = arena.push_node(ArenaRecognizedNode::Rule {
21846 rule_index: 1,
21847 invoking_state: -1,
21848 alt_number: 0,
21849 start_index: 0,
21850 stop_index: Some(0),
21851 return_values: None,
21852 children: token_children,
21853 });
21854 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
21855 let outer = arena.push_node(ArenaRecognizedNode::Rule {
21856 rule_index: 1,
21857 invoking_state: -1,
21858 alt_number: 0,
21859 start_index: 0,
21860 stop_index: Some(0),
21861 return_values: None,
21862 children: inner_children,
21863 });
21864 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
21865 let first = RecognizeOutcome {
21866 index: 1,
21867 consumed_eof: false,
21868 alt_number: 0,
21869 member_values: MemberEnv::new(),
21870 return_values: BTreeMap::new(),
21871 diagnostics: DiagnosticSeqId::EMPTY,
21872 decisions: Vec::new(),
21873 actions: vec![ParserAction::new(1, 0, 0, None)],
21874 nodes: recursive_nodes,
21875 };
21876 let second = RecognizeOutcome {
21877 index: 1,
21878 consumed_eof: false,
21879 alt_number: 0,
21880 member_values: MemberEnv::new(),
21881 return_values: BTreeMap::new(),
21882 diagnostics: DiagnosticSeqId::EMPTY,
21883 decisions: Vec::new(),
21884 actions: vec![ParserAction::new(2, 0, 0, None)],
21885 nodes: recursive_nodes,
21886 };
21887
21888 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
21889 .expect("one outcome should be selected");
21890 assert_eq!(selected.actions[0].source_state(), 1);
21891 }
21892
21893 #[test]
21894 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
21895 let mut arena = RecognitionArena::default();
21896 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
21897 line: 1,
21898 column: 3,
21899 message: "missing 'Y' at '<EOF>'".to_owned(),
21900 offending: None,
21901 }]);
21902 let first_alt = RecognizeOutcome {
21903 index: 2,
21904 consumed_eof: true,
21905 alt_number: 0,
21906 member_values: MemberEnv::new(),
21907 return_values: BTreeMap::new(),
21908 diagnostics: recovered_diagnostics,
21909 decisions: vec![0],
21910 actions: vec![ParserAction::new(1, 0, 0, None)],
21911 nodes: NodeSeqId::EMPTY,
21912 };
21913 let second_alt = RecognizeOutcome {
21914 diagnostics: DiagnosticSeqId::EMPTY,
21915 decisions: vec![1],
21916 actions: vec![ParserAction::new(2, 0, 0, None)],
21917 ..first_alt.clone()
21918 };
21919
21920 let selected = select_best_outcome(
21921 [second_alt, first_alt].into_iter(),
21922 PredictionMode::Sll,
21923 &arena,
21924 )
21925 .expect("one outcome should be selected");
21926 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
21927 assert_eq!(selected.decisions, [0]);
21928 }
21929}