1use std::cell::RefCell;
7use std::cmp::Ordering;
8#[allow(clippy::disallowed_types)]
9use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
10use std::hash::{BuildHasherDefault, Hash, Hasher};
11use std::rc::Rc;
12
13#[derive(Clone, Copy, Default)]
20struct FxHasher {
21 hash: u64,
22}
23
24const FX_ROT: u32 = 5;
25const FX_SEED: u64 = 0x51_7c_c1_b7_27_22_0a_95;
26
27impl Hasher for FxHasher {
28 #[inline]
36 fn write(&mut self, mut bytes: &[u8]) {
37 while bytes.len() >= 8 {
38 let (head, rest) = bytes.split_at(8);
39 let word = u64::from_le_bytes(head.try_into().expect("8-byte chunk"));
40 self.hash = (self.hash.rotate_left(FX_ROT) ^ word).wrapping_mul(FX_SEED);
41 bytes = rest;
42 }
43 for byte in bytes {
44 self.hash = (self.hash.rotate_left(FX_ROT) ^ u64::from(*byte)).wrapping_mul(FX_SEED);
45 }
46 }
47 #[inline]
48 fn write_u64(&mut self, value: u64) {
49 self.hash = (self.hash.rotate_left(FX_ROT) ^ value).wrapping_mul(FX_SEED);
50 }
51 #[inline]
52 fn write_usize(&mut self, value: usize) {
53 self.write_u64(value as u64);
54 }
55 #[inline]
56 fn write_u32(&mut self, value: u32) {
57 self.write_u64(u64::from(value));
58 }
59 #[inline]
60 fn write_i32(&mut self, value: i32) {
61 self.write_u64(u64::from(i32::cast_unsigned(value)));
62 }
63 #[inline]
64 fn finish(&self) -> u64 {
65 self.hash
66 }
67}
68
69type FxBuildHasher = BuildHasherDefault<FxHasher>;
70#[allow(clippy::disallowed_types)]
71type FxHashMap<K, V> = HashMap<K, V, FxBuildHasher>;
72#[allow(clippy::disallowed_types)]
73type FxHashSet<K> = HashSet<K, FxBuildHasher>;
74
75use crate::atn::AtnStateKind;
76use crate::atn::parser::{
77 ParserAtnPrediction, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
78};
79use crate::atn::parser_atn::{
80 ParserAtn as Atn, ParserAtnState as AtnState, ParserIntervalSet, ParserTransition,
81 ParserTransitionData as Transition, ParserTransitionKind,
82};
83#[cfg(test)]
84use crate::atn::parser_atn::{ParserAtnBuilder, ParserTransitionSpec};
85use crate::char_stream::CharStream;
86use crate::errors::AntlrError;
87use crate::int_stream::IntStream;
88use crate::lexer::{LexerCustomAction, LexerLifecycleCtx, LexerSemCtx};
89use crate::recognizer::{Recognizer, RecognizerData};
90use crate::semir::{self, AStmt, ArithOp, CmpOp, ExprId, HookId, MemberEnv, PExpr, SemIr, StmtId};
91use crate::token::{
92 TOKEN_EOF, Token, TokenId, TokenSource, TokenSourceError, TokenSpec, TokenStore, TokenView,
93};
94use crate::token_stream::CommonTokenStream;
95use crate::tree::{
96 Node, NodeId, ParseTreeCheckpoint, ParseTreeStorage, ParsedFile, ParserRuleContext,
97};
98use crate::vocabulary::Vocabulary;
99
100type ParseTree = NodeId;
101
102const RECOGNITION_DEPTH_LIMIT: usize = 32_768;
106const FAST_RECOGNIZE_STACK_CHECK_INTERVAL: usize = 8;
109const FAST_RECOGNIZE_RED_ZONE: usize = 1024 * 1024;
110const FAST_RECOGNIZE_STACK_SIZE: usize = 4 * 1024 * 1024;
111const GENERATED_RULE_STACK_CHECK_INTERVAL: usize = 8;
117const ADAPTIVE_DIRECT_STEP_LIMIT: usize = RECOGNITION_DEPTH_LIMIT;
121
122pub fn grow_generated_rule_stack<R>(body: impl FnOnce() -> R) -> R {
129 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, body)
130}
131
132pub trait ParseListener: Send {
180 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError>;
185
186 fn exit_every_rule(&mut self, rule_index: usize) {
190 let _ = rule_index;
191 }
192}
193
194impl<T: ParseListener + ?Sized> ParseListener for Box<T> {
198 fn enter_every_rule(&mut self, event: &EnterRuleEvent<'_>) -> Result<(), AntlrError> {
199 (**self).enter_every_rule(event)
200 }
201
202 fn exit_every_rule(&mut self, rule_index: usize) {
203 (**self).exit_every_rule(rule_index);
204 }
205}
206
207#[derive(Debug)]
212#[non_exhaustive]
213pub struct EnterRuleEvent<'a> {
214 pub rule_index: usize,
217 pub current: Option<TokenView<'a>>,
220}
221
222struct ParseListenerSlot(Box<dyn ParseListener>);
223
224impl std::fmt::Debug for ParseListenerSlot {
225 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
226 f.write_str("ParseListener")
227 }
228}
229const CLEAN_MEMO_PROBE_LIMIT: usize = 4096;
233const CLEAN_MEMO_REPEAT_LIMIT: usize = 8;
234const CLEAN_MEMO_REPROBE_INTERVAL: usize = 262_144;
237const FAST_RECOGNIZE_VISITING_CAPACITY: usize = 256;
238const FAST_RECOGNIZE_MIN_MEMO_CAPACITY: usize = 256;
239const FAST_RECOGNIZE_MAX_MEMO_CAPACITY: usize = 524_288;
240const FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY: usize = 65_536;
241
242#[derive(Clone, Copy, Debug, Eq, PartialEq)]
243enum CleanMemoMode {
244 Probe,
245 Promote,
246 Sparse,
247}
248
249fn interval_set_contains(intervals: &[(i32, i32)], symbol: i32) -> bool {
250 intervals
251 .iter()
252 .any(|(start, stop)| (*start..=*stop).contains(&symbol))
253}
254
255fn interval_symbols(intervals: &[(i32, i32)]) -> BTreeSet<i32> {
256 let mut symbols = BTreeSet::new();
257 for (start, stop) in intervals {
258 symbols.extend(*start..=*stop);
259 }
260 symbols
261}
262
263fn interval_complement_symbols(
264 intervals: &[(i32, i32)],
265 min_vocabulary: i32,
266 max_vocabulary: i32,
267) -> BTreeSet<i32> {
268 (min_vocabulary..=max_vocabulary)
269 .filter(|symbol| !interval_set_contains(intervals, *symbol))
270 .collect()
271}
272
273#[cfg(feature = "perf-counters")]
274mod perf_counters {
275 use std::cell::Cell;
276 thread_local! {
277 pub(super) static RFS_CALLS: Cell<u64> = const { Cell::new(0) };
278 pub(super) static RFS_MEMO_HITS: Cell<u64> = const { Cell::new(0) };
279 pub(super) static RFS_MEMO_MISSES: Cell<u64> = const { Cell::new(0) };
280 pub(super) static RFS_VISITING_CYCLE: Cell<u64> = const { Cell::new(0) };
281 pub(super) static MEMO_INSERTED: Cell<u64> = const { Cell::new(0) };
282 pub(super) static OUTCOMES_PUSHED: Cell<u64> = const { Cell::new(0) };
283 pub(super) static OUTCOMES_CLONED: Cell<u64> = const { Cell::new(0) };
284 pub(super) static OUTCOME_DEDUPE_INPUTS: Cell<u64> = const { Cell::new(0) };
285 pub(super) static OUTCOME_DEDUPE_REMOVED: Cell<u64> = const { Cell::new(0) };
286 pub(super) static OUTCOME_DEDUPE_INLINE: Cell<u64> = const { Cell::new(0) };
287 pub(super) static OUTCOME_DEDUPE_DENSE: Cell<u64> = const { Cell::new(0) };
288 pub(super) static OUTCOME_DEDUPE_SPARSE: Cell<u64> = const { Cell::new(0) };
289 pub(super) static OUTCOME_DEDUPE_DENSE_WORDS: Cell<u64> = const { Cell::new(0) };
290 }
291 pub(super) fn inc(c: &'static std::thread::LocalKey<Cell<u64>>, n: u64) {
292 c.with(|v| v.set(v.get() + n));
293 }
294 thread_local! {
295 pub(super) static EPSILON_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
296 pub(super) static RULE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
297 pub(super) static ATOM_RANGE_TRANSITIONS: Cell<u64> = const { Cell::new(0) };
298 pub(super) static SINGLE_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
299 pub(super) static MULTI_TRANS_BODY: Cell<u64> = const { Cell::new(0) };
300 pub(super) static SINGLE_TRANS_RULE: Cell<u64> = const { Cell::new(0) };
301 pub(super) static SINGLE_TRANS_ATOM: Cell<u64> = const { Cell::new(0) };
302 pub(super) static SINGLE_TRANS_OTHER: Cell<u64> = const { Cell::new(0) };
303 pub(super) static OUTCOMES_RETURN_0: Cell<u64> = const { Cell::new(0) };
304 pub(super) static OUTCOMES_RETURN_1: Cell<u64> = const { Cell::new(0) };
305 pub(super) static OUTCOMES_RETURN_N: Cell<u64> = const { Cell::new(0) };
306 }
307 pub(super) fn snapshot() -> [(&'static str, u64); 24] {
308 [
309 ("rfs_calls", RFS_CALLS.with(Cell::get)),
310 ("rfs_memo_hits", RFS_MEMO_HITS.with(Cell::get)),
311 ("rfs_memo_misses", RFS_MEMO_MISSES.with(Cell::get)),
312 ("rfs_visiting_cycle", RFS_VISITING_CYCLE.with(Cell::get)),
313 ("memo_inserted", MEMO_INSERTED.with(Cell::get)),
314 ("outcomes_pushed", OUTCOMES_PUSHED.with(Cell::get)),
315 ("outcomes_cloned", OUTCOMES_CLONED.with(Cell::get)),
316 (
317 "outcome_dedupe_inputs",
318 OUTCOME_DEDUPE_INPUTS.with(Cell::get),
319 ),
320 (
321 "outcome_dedupe_removed",
322 OUTCOME_DEDUPE_REMOVED.with(Cell::get),
323 ),
324 (
325 "outcome_dedupe_inline",
326 OUTCOME_DEDUPE_INLINE.with(Cell::get),
327 ),
328 ("outcome_dedupe_dense", OUTCOME_DEDUPE_DENSE.with(Cell::get)),
329 (
330 "outcome_dedupe_sparse",
331 OUTCOME_DEDUPE_SPARSE.with(Cell::get),
332 ),
333 (
334 "outcome_dedupe_dense_words",
335 OUTCOME_DEDUPE_DENSE_WORDS.with(Cell::get),
336 ),
337 ("epsilon_transitions", EPSILON_TRANSITIONS.with(Cell::get)),
338 ("rule_transitions", RULE_TRANSITIONS.with(Cell::get)),
339 (
340 "atom_range_transitions",
341 ATOM_RANGE_TRANSITIONS.with(Cell::get),
342 ),
343 ("single_trans_body", SINGLE_TRANS_BODY.with(Cell::get)),
344 ("multi_trans_body", MULTI_TRANS_BODY.with(Cell::get)),
345 ("single_trans_rule", SINGLE_TRANS_RULE.with(Cell::get)),
346 ("single_trans_atom", SINGLE_TRANS_ATOM.with(Cell::get)),
347 ("single_trans_other", SINGLE_TRANS_OTHER.with(Cell::get)),
348 ("outcomes_return_0", OUTCOMES_RETURN_0.with(Cell::get)),
349 ("outcomes_return_1", OUTCOMES_RETURN_1.with(Cell::get)),
350 ("outcomes_return_n", OUTCOMES_RETURN_N.with(Cell::get)),
351 ]
352 }
353 pub fn reset() {
354 RFS_CALLS.with(|c| c.set(0));
355 RFS_MEMO_HITS.with(|c| c.set(0));
356 RFS_MEMO_MISSES.with(|c| c.set(0));
357 RFS_VISITING_CYCLE.with(|c| c.set(0));
358 MEMO_INSERTED.with(|c| c.set(0));
359 OUTCOMES_PUSHED.with(|c| c.set(0));
360 OUTCOMES_CLONED.with(|c| c.set(0));
361 OUTCOME_DEDUPE_INPUTS.with(|c| c.set(0));
362 OUTCOME_DEDUPE_REMOVED.with(|c| c.set(0));
363 OUTCOME_DEDUPE_INLINE.with(|c| c.set(0));
364 OUTCOME_DEDUPE_DENSE.with(|c| c.set(0));
365 OUTCOME_DEDUPE_SPARSE.with(|c| c.set(0));
366 OUTCOME_DEDUPE_DENSE_WORDS.with(|c| c.set(0));
367 EPSILON_TRANSITIONS.with(|c| c.set(0));
368 RULE_TRANSITIONS.with(|c| c.set(0));
369 ATOM_RANGE_TRANSITIONS.with(|c| c.set(0));
370 SINGLE_TRANS_BODY.with(|c| c.set(0));
371 MULTI_TRANS_BODY.with(|c| c.set(0));
372 SINGLE_TRANS_RULE.with(|c| c.set(0));
373 SINGLE_TRANS_ATOM.with(|c| c.set(0));
374 SINGLE_TRANS_OTHER.with(|c| c.set(0));
375 OUTCOMES_RETURN_0.with(|c| c.set(0));
376 OUTCOMES_RETURN_1.with(|c| c.set(0));
377 OUTCOMES_RETURN_N.with(|c| c.set(0));
378 }
379 pub fn dump() {
380 for (name, value) in snapshot() {
381 #[allow(clippy::print_stderr)]
382 {
383 eprintln!("perf {name}={value}");
384 }
385 }
386 }
387}
388
389#[cfg(feature = "perf-counters")]
390pub use perf_counters::{dump as dump_perf_counters, reset as reset_perf_counters};
391const FAST_RECOGNIZER_DEFERRED_FILL_AT: usize = 64;
396#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
405pub struct ParserAction {
406 source_state: usize,
407 rule_index: usize,
408 start_index: usize,
409 stop_index: Option<usize>,
410 rule_init: bool,
411 expected_state: Option<usize>,
412}
413
414impl ParserAction {
415 pub const fn new(
417 source_state: usize,
418 rule_index: usize,
419 start_index: usize,
420 stop_index: Option<usize>,
421 ) -> Self {
422 Self {
423 source_state,
424 rule_index,
425 start_index,
426 stop_index,
427 rule_init: false,
428 expected_state: None,
429 }
430 }
431
432 pub const fn new_rule_init(
434 rule_index: usize,
435 start_index: usize,
436 expected_state: Option<usize>,
437 ) -> Self {
438 Self {
439 source_state: usize::MAX,
440 rule_index,
441 start_index,
442 stop_index: None,
443 rule_init: true,
444 expected_state,
445 }
446 }
447
448 pub const fn source_state(&self) -> usize {
450 self.source_state
451 }
452
453 pub const fn rule_index(&self) -> usize {
455 self.rule_index
456 }
457
458 pub const fn start_index(&self) -> usize {
460 self.start_index
461 }
462
463 pub const fn stop_index(&self) -> Option<usize> {
465 self.stop_index
466 }
467
468 pub const fn is_rule_init(&self) -> bool {
470 self.rule_init
471 }
472
473 pub const fn expected_state(&self) -> Option<usize> {
475 self.expected_state
476 }
477}
478
479pub struct ParserSemCtx<'a, S>
487where
488 S: TokenSource,
489{
490 input: &'a mut CommonTokenStream<S>,
491 tree_storage: &'a ParseTreeStorage,
492 rule_index: usize,
493 coordinate_index: usize,
494 rule_name: Option<String>,
495 context: Option<&'a ParserRuleContext>,
496 tree: Option<ParseTree>,
497 local_int_arg: Option<(usize, i64)>,
498 member_values: &'a MemberEnv,
499 action: Option<ParserAction>,
500}
501
502impl<S> std::fmt::Debug for ParserSemCtx<'_, S>
503where
504 S: TokenSource,
505{
506 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
507 f.debug_struct("ParserSemCtx")
508 .field("rule_index", &self.rule_index)
509 .field("coordinate_index", &self.coordinate_index)
510 .field("rule_name", &self.rule_name)
511 .field("context", &self.context)
512 .field("tree", &self.tree)
513 .field("local_int_arg", &self.local_int_arg)
514 .field("member_values", &self.member_values)
515 .field("action", &self.action)
516 .finish_non_exhaustive()
517 }
518}
519
520impl<'a, S> ParserSemCtx<'a, S>
521where
522 S: TokenSource,
523{
524 #[must_use]
526 pub const fn rule_index(&self) -> usize {
527 self.rule_index
528 }
529
530 #[must_use]
532 pub fn rule_name(&self) -> Option<&str> {
533 self.rule_name.as_deref()
534 }
535
536 #[must_use]
540 pub const fn coordinate_index(&self) -> usize {
541 self.coordinate_index
542 }
543
544 #[must_use]
546 pub fn input_index(&self) -> usize {
547 self.input.index()
548 }
549
550 pub fn la(&mut self, offset: isize) -> i32 {
552 self.input.la(offset)
553 }
554
555 pub fn lt(&self, offset: isize) -> Option<TokenView<'_>> {
557 self.input.lt(offset)
558 }
559
560 pub fn token_text(&self, offset: isize) -> Option<TokenView<'_>> {
562 self.lt(offset)
563 }
564
565 pub fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
572 self.input.get(index)
573 }
574
575 #[must_use]
578 pub const fn context(&self) -> Option<&'a ParserRuleContext> {
579 self.context
580 }
581
582 #[must_use]
584 pub const fn parse_tree_storage(&self) -> &'a ParseTreeStorage {
585 self.tree_storage
586 }
587
588 #[must_use]
590 pub const fn token_store(&self) -> &TokenStore {
591 self.input.token_store()
592 }
593
594 #[must_use]
596 pub const fn tree_id(&self) -> Option<NodeId> {
597 self.tree
598 }
599
600 #[must_use]
603 pub fn tree(&self) -> Option<Node<'_>> {
604 self.tree
605 .and_then(|id| self.tree_storage.node(self.input.token_store(), id))
606 }
607
608 #[must_use]
610 pub fn local_int_arg(&self) -> Option<i64> {
611 self.local_int_arg.map(|(_, value)| value)
612 }
613
614 #[must_use]
616 pub fn member_int(&self, member: usize) -> Option<i64> {
617 self.member_values.scalar(member)
618 }
619
620 #[must_use]
623 pub fn member_stack_top(&self, member: usize) -> Option<i64> {
624 self.member_values.stack_top(member)
625 }
626
627 #[must_use]
629 pub fn member_stack_len(&self, member: usize) -> usize {
630 self.member_values.stack_len(member)
631 }
632
633 #[must_use]
636 pub const fn action(&self) -> Option<ParserAction> {
637 self.action
638 }
639
640 pub fn action_text(&self) -> String {
648 let Some(action) = self.action else {
649 return String::new();
650 };
651 let Some(stop) = action.stop_index() else {
652 return String::new();
653 };
654 let stop = if self
655 .input
656 .get(stop)
657 .is_some_and(|token| token.token_type() == TOKEN_EOF)
658 {
659 let Some(previous) = self.input.previous_visible_token_index(stop) else {
660 return String::new();
661 };
662 previous
663 } else {
664 stop
665 };
666 self.input.text(action.start_index(), stop)
667 }
668}
669
670pub trait SemanticHooks {
677 const ENABLES_LEXER_LIFECYCLE: bool = true;
684
685 fn observes_parser_predicates(&self) -> bool {
690 true
691 }
692
693 fn observes_parser_decisions(&self) -> bool {
698 false
699 }
700
701 fn parser_decision_override(
707 &mut self,
708 decision: usize,
709 input_index: usize,
710 alternative_count: usize,
711 ) -> Option<usize> {
712 let _ = (decision, input_index, alternative_count);
713 None
714 }
715
716 fn sempred<S>(
717 &mut self,
718 ctx: &mut ParserSemCtx<'_, S>,
719 rule_index: usize,
720 pred_index: usize,
721 ) -> Option<bool>
722 where
723 S: TokenSource,
724 {
725 let _ = (ctx, rule_index, pred_index);
726 None
727 }
728
729 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
730 where
731 S: TokenSource,
732 {
733 let _ = (ctx, action);
734 false
735 }
736
737 fn lexer_sempred<I>(
738 &mut self,
739 ctx: &mut LexerSemCtx<'_, I>,
740 rule_index: usize,
741 pred_index: usize,
742 ) -> Option<bool>
743 where
744 I: CharStream,
745 {
746 let _ = (ctx, rule_index, pred_index);
747 None
748 }
749
750 fn lexer_action<I>(&mut self, ctx: &mut LexerSemCtx<'_, I>, action: LexerCustomAction) -> bool
760 where
761 I: CharStream,
762 {
763 let _ = (ctx, action);
764 false
765 }
766
767 fn lexer_reset<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
771 where
772 I: CharStream,
773 {
774 let _ = ctx;
775 }
776
777 fn lexer_before_token<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
783 where
784 I: CharStream,
785 {
786 let _ = ctx;
787 }
788
789 fn lexer_after_accept<I>(&mut self, ctx: &mut LexerLifecycleCtx<'_, I>)
798 where
799 I: CharStream,
800 {
801 let _ = ctx;
802 }
803
804 fn lexer_token_emitted(&mut self, token: TokenView<'_>) {
811 let _ = token;
812 }
813}
814
815#[derive(Clone, Copy, Debug, Default)]
818pub struct NoSemanticHooks;
819
820impl SemanticHooks for NoSemanticHooks {
821 const ENABLES_LEXER_LIFECYCLE: bool = false;
822
823 fn observes_parser_predicates(&self) -> bool {
824 false
825 }
826}
827
828#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
835pub enum ParserPredicate {
836 True,
837 False,
838 FalseWithMessage {
840 message: &'static str,
841 },
842 Invoke {
845 value: bool,
846 },
847 LookaheadTextEquals {
848 offset: isize,
849 text: &'static str,
850 },
851 LookaheadNotEquals {
852 offset: isize,
853 token_type: i32,
854 },
855 TokenPairAdjacent,
858 ContextChildRuleTextNotEquals {
863 rule_index: usize,
864 text: &'static str,
865 },
866 LocalIntEquals {
869 value: i64,
870 },
871 LocalIntLessOrEqual {
874 value: i64,
875 },
876 MemberModuloEquals {
878 member: usize,
879 modulus: i64,
880 value: i64,
881 equals: bool,
882 },
883 MemberEquals {
885 member: usize,
886 value: i64,
887 equals: bool,
888 },
889}
890
891impl ParserPredicate {
892 pub fn lower_into_semir(self, ir: &mut SemIr) -> ExprId {
898 match self {
899 Self::True => ir.expr(PExpr::Bool(true)),
900 Self::False | Self::FalseWithMessage { .. } => ir.expr(PExpr::Bool(false)),
901 Self::Invoke { value } => ir.expr(PExpr::EvalTrace(value)),
902 Self::LookaheadTextEquals { offset, text } => {
903 let token = ir.expr(PExpr::TokenText(offset));
904 let text = ir.intern(text);
905 let text = ir.expr(PExpr::Str(text));
906 ir.expr(PExpr::Cmp(CmpOp::Eq, token, text))
907 }
908 Self::LookaheadNotEquals { offset, token_type } => {
909 let actual = ir.expr(PExpr::La(offset));
910 let expected = ir.expr(PExpr::Int(i64::from(token_type)));
911 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
912 }
913 Self::TokenPairAdjacent => ir.expr(PExpr::TokenIndexAdjacent),
914 Self::ContextChildRuleTextNotEquals { rule_index, text } => {
915 let actual = ir.expr(PExpr::CtxRuleText(rule_index));
916 let expected = ir.intern(text);
917 let expected = ir.expr(PExpr::Str(expected));
918 ir.expr(PExpr::Cmp(CmpOp::Ne, actual, expected))
919 }
920 Self::LocalIntEquals { value } => local_arg_comparison(ir, CmpOp::Eq, value),
921 Self::LocalIntLessOrEqual { value } => local_arg_comparison(ir, CmpOp::Le, value),
922 Self::MemberModuloEquals {
923 member,
924 modulus,
925 value,
926 equals,
927 } => {
928 if modulus == 0 {
929 return ir.expr(PExpr::Bool(false));
930 }
931 let member = ir.expr(PExpr::Member(member));
932 let modulus = ir.expr(PExpr::Int(modulus));
933 let actual = ir.expr(PExpr::Arith(ArithOp::Mod, member, modulus));
934 let expected = ir.expr(PExpr::Int(value));
935 ir.expr(PExpr::Cmp(
936 if equals { CmpOp::Eq } else { CmpOp::Ne },
937 actual,
938 expected,
939 ))
940 }
941 Self::MemberEquals {
942 member,
943 value,
944 equals,
945 } => {
946 let actual = ir.expr(PExpr::Member(member));
947 let expected = ir.expr(PExpr::Int(value));
948 ir.expr(PExpr::Cmp(
949 if equals { CmpOp::Eq } else { CmpOp::Ne },
950 actual,
951 expected,
952 ))
953 }
954 }
955 }
956
957 #[must_use]
958 pub const fn failure_message(self) -> Option<&'static str> {
959 match self {
960 Self::FalseWithMessage { message } => Some(message),
961 Self::True
962 | Self::False
963 | Self::Invoke { .. }
964 | Self::LookaheadTextEquals { .. }
965 | Self::LookaheadNotEquals { .. }
966 | Self::TokenPairAdjacent
967 | Self::ContextChildRuleTextNotEquals { .. }
968 | Self::LocalIntEquals { .. }
969 | Self::LocalIntLessOrEqual { .. }
970 | Self::MemberModuloEquals { .. }
971 | Self::MemberEquals { .. } => None,
972 }
973 }
974}
975
976fn local_arg_comparison(ir: &mut SemIr, op: CmpOp, value: i64) -> ExprId {
977 let local = ir.expr(PExpr::LocalArg);
978 let absent = ir.expr(PExpr::IsNull(local));
979 let expected = ir.expr(PExpr::Int(value));
980 let comparison = ir.expr(PExpr::Cmp(op, local, expected));
981 ir.expr(PExpr::Or([absent, comparison].into()))
982}
983
984#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
997pub enum UnknownSemanticPolicy {
998 #[default]
1000 AssumeTrue,
1001 AssumeFalse,
1003 Error,
1006}
1007
1008fn apply_unknown_predicate_policy(
1017 policy: UnknownSemanticPolicy,
1018 rule_index: usize,
1019 pred_index: usize,
1020 hits: &mut Vec<(usize, usize)>,
1021) -> bool {
1022 match policy {
1023 UnknownSemanticPolicy::AssumeTrue => true,
1024 UnknownSemanticPolicy::AssumeFalse => false,
1025 UnknownSemanticPolicy::Error => {
1026 let coordinate = (rule_index, pred_index);
1027 if !hits.contains(&coordinate) {
1028 hits.push(coordinate);
1029 }
1030 false
1031 }
1032 }
1033}
1034
1035#[derive(Clone, Debug, Eq, PartialEq)]
1039pub struct ExpectedTokenSet {
1040 symbols: BTreeSet<i32>,
1041}
1042
1043impl ExpectedTokenSet {
1044 #[must_use]
1046 pub fn to_token_string(&self, vocabulary: &Vocabulary) -> String {
1047 expected_symbols_display(&self.symbols, vocabulary)
1048 }
1049}
1050
1051#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1056pub struct BailErrorStrategy;
1057
1058impl BailErrorStrategy {
1059 #[must_use]
1060 pub const fn new() -> Self {
1061 Self
1062 }
1063}
1064
1065#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1067pub enum PredictionMode {
1068 Ll,
1071 Sll,
1074 LlExactAmbigDetection,
1076}
1077
1078#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1084pub struct ParserRuleArg {
1085 pub source_state: usize,
1087 pub rule_index: usize,
1089 pub value: i64,
1091 pub inherit_local: bool,
1093}
1094
1095#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1097pub struct ParserMemberAction {
1098 pub source_state: usize,
1100 pub member: usize,
1102 pub delta: i64,
1104}
1105
1106#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1113pub struct ParserReturnAction {
1114 pub source_state: usize,
1116 pub rule_index: usize,
1118 pub name: &'static str,
1120 pub value: i64,
1122}
1123
1124impl ParserMemberAction {
1125 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1127 let delta = ir.expr(PExpr::Int(self.delta));
1128 ParserSemanticAction {
1129 source_state: self.source_state,
1130 rule_index: usize::MAX,
1131 stmt: ir.stmt(AStmt::AddMember(self.member, delta)),
1132 speculative: true,
1133 }
1134 }
1135}
1136
1137impl ParserReturnAction {
1138 pub fn lower_into_semir(self, ir: &mut SemIr) -> ParserSemanticAction {
1140 let name = ir.intern(self.name);
1141 let value = ir.expr(PExpr::Int(self.value));
1142 ParserSemanticAction {
1143 source_state: self.source_state,
1144 rule_index: self.rule_index,
1145 stmt: ir.stmt(AStmt::SetReturn(name, value)),
1146 speculative: false,
1147 }
1148 }
1149}
1150
1151#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1153pub struct ParserSemanticPredicate {
1154 pub rule_index: usize,
1156 pub pred_index: usize,
1158 pub expr: ExprId,
1160 pub failure_message: Option<&'static str>,
1162}
1163
1164#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1166pub struct ParserSemanticAction {
1167 pub source_state: usize,
1169 pub rule_index: usize,
1171 pub stmt: StmtId,
1173 pub speculative: bool,
1175}
1176
1177#[derive(Clone, Debug, Default, Eq, PartialEq)]
1184pub struct ParserSemantics {
1185 pub ir: SemIr,
1186 pub predicates: Vec<ParserSemanticPredicate>,
1187 pub actions: Vec<ParserSemanticAction>,
1188}
1189
1190#[derive(Clone, Copy, Debug, Default)]
1192pub struct ParserRuntimeOptions<'a> {
1193 pub init_action_rules: &'a [usize],
1195 pub track_alt_numbers: bool,
1197 #[doc(hidden)]
1202 pub track_context_alt_numbers: bool,
1203 pub predicates: &'a [(usize, usize, ParserPredicate)],
1205 pub semantics: Option<&'a ParserSemantics>,
1207 pub rule_args: &'a [ParserRuleArg],
1209 pub member_actions: &'a [ParserMemberAction],
1211 pub return_actions: &'a [ParserReturnAction],
1213 pub unknown_predicate_policy: UnknownSemanticPolicy,
1216}
1217
1218pub trait Parser: Recognizer {
1219 fn build_parse_trees(&self) -> bool;
1222
1223 fn set_build_parse_trees(&mut self, build: bool);
1225
1226 fn number_of_syntax_errors(&self) -> usize {
1229 0
1230 }
1231
1232 fn report_diagnostic_errors(&self) -> bool {
1235 false
1236 }
1237
1238 fn set_report_diagnostic_errors(&mut self, _report: bool) {}
1241
1242 fn prediction_mode(&self) -> PredictionMode {
1244 PredictionMode::Ll
1245 }
1246
1247 fn set_prediction_mode(&mut self, _mode: PredictionMode) {}
1249
1250 fn max_rule_depth(&self) -> Option<usize> {
1253 None
1254 }
1255
1256 fn set_max_rule_depth(&mut self, _depth: Option<usize>) {}
1272
1273 fn add_parse_listener(&mut self, _listener: Box<dyn ParseListener>) {}
1278
1279 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
1282 Vec::new()
1283 }
1284}
1285
1286#[derive(Debug)]
1287struct LeftRecursiveCallerOverlap {
1288 atn_key: SharedAtnCacheKey,
1289 state_number: usize,
1290 symbol: i32,
1291 context_version: usize,
1292 overlaps: bool,
1293}
1294
1295const LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE: usize = 16;
1296
1297#[derive(Debug)]
1298pub struct BaseParser<S, H = NoSemanticHooks> {
1299 input: CommonTokenStream<S>,
1300 tree: ParseTreeStorage,
1301 data: RecognizerData,
1302 semantic_hooks: H,
1303 decision_override_generation: usize,
1304 build_parse_trees: bool,
1305 syntax_errors: usize,
1306 report_diagnostic_errors: bool,
1307 prediction_mode: PredictionMode,
1308 prediction_diagnostics: Vec<ParserDiagnostic>,
1309 reported_prediction_diagnostics: BTreeSet<(usize, usize, String)>,
1310 generated_parser_diagnostics: Vec<ParserDiagnostic>,
1311 generated_sync_expected: Option<TokenBitSet>,
1312 generated_recovery_error_index: Option<usize>,
1313 generated_recovery_error_states: BTreeSet<isize>,
1314 int_members: MemberEnv,
1315 rule_context_stack: Vec<RuleContextFrame>,
1316 rule_context_version: usize,
1317 left_recursive_caller_overlap_cache:
1318 [Option<LeftRecursiveCallerOverlap>; LEFT_RECURSIVE_CALLER_OVERLAP_CACHE_SIZE],
1319 pending_invoking_states: Vec<isize>,
1320 precedence_stack: Vec<i32>,
1321 invoked_predicates: Vec<(usize, usize)>,
1325 bail_on_error: bool,
1329 parse_listeners: Vec<ParseListenerSlot>,
1334 parse_listener_abort: Option<AntlrError>,
1339 max_rule_depth: Option<usize>,
1343 rule_depth_error: Option<AntlrError>,
1348 recursion_expansions: usize,
1354 recursion_expansion_marks: Vec<usize>,
1358 unknown_predicate_policy: UnknownSemanticPolicy,
1361 unknown_predicate_hits: Vec<(usize, usize)>,
1364 unhandled_action_hits: Vec<(usize, usize)>,
1369 rule_first_set_cache: Vec<Option<Rc<FirstSet>>>,
1374 state_expected_cache: FxHashMap<usize, Rc<BTreeSet<i32>>>,
1380 state_expected_token_cache: FxHashMap<usize, Rc<TokenBitSet>>,
1385 rule_stop_reach_cache: Vec<Option<bool>>,
1390 recovery_symbols_intern: FxHashMap<Rc<BTreeSet<i32>>, Rc<BTreeSet<i32>>>,
1395 decision_lookahead_cache: FxHashMap<usize, Rc<DecisionLookahead>>,
1401 ll1_decision_cache: FxHashMap<(usize, i32), Option<usize>>,
1407 fast_predicate_cache: FxHashMap<(usize, usize, usize), bool>,
1411 empty_cycle_cache: Vec<Option<bool>>,
1417 empty_cycle_cache_atn: Option<SharedAtnCacheKey>,
1418 clean_memo_mode: CleanMemoMode,
1421 clean_memo_probe_seen: FxHashSet<FastRecognizeKey>,
1422 clean_memo_probe_samples: usize,
1423 clean_memo_probe_repeats: usize,
1424 clean_memo_sparse_samples: usize,
1425 fast_recognize_scratch: FastRecognizeTopScratch,
1427 fast_outcome_dedup: FastOutcomeDedupScratch,
1429 empty_recovery_symbols: Rc<BTreeSet<i32>>,
1432 fast_first_set_prefilter: bool,
1440 fast_recovery_enabled: bool,
1444 fast_token_nodes_enabled: bool,
1449 fast_track_alt_numbers: bool,
1452 recognition_arena: RecognitionArena,
1456 last_recognition_arena_root: NodeSeqId,
1457 last_recognition_arena_diagnostics: DiagnosticSeqId,
1458}
1459
1460#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1462pub struct GeneratedDiagnosticsCheckpoint {
1463 diagnostics_len: usize,
1464 syntax_errors: usize,
1465 tree: ParseTreeCheckpoint,
1466}
1467
1468#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1471pub struct RecognitionArenaStats {
1472 pub total_nodes: usize,
1473 pub live_nodes: usize,
1474 pub dead_nodes: usize,
1475 pub node_capacity: usize,
1476 pub total_links: usize,
1477 pub live_links: usize,
1478 pub dead_links: usize,
1479 pub link_capacity: usize,
1480 pub total_extras: usize,
1481 pub live_extras: usize,
1482 pub dead_extras: usize,
1483 pub extra_capacity: usize,
1484}
1485
1486#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1487struct RuleContextFrame {
1488 rule_index: usize,
1489 invoking_state: isize,
1490}
1491
1492#[derive(Clone, Debug, Eq, PartialEq)]
1493struct RecognizeOutcome {
1494 index: usize,
1495 consumed_eof: bool,
1496 alt_number: usize,
1497 member_values: MemberEnv,
1498 return_values: BTreeMap<String, i64>,
1499 diagnostics: DiagnosticSeqId,
1500 decisions: Vec<usize>,
1501 actions: Vec<ParserAction>,
1502 nodes: NodeSeqId,
1503}
1504
1505#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1506struct FastRecognizeOutcome {
1507 index: usize,
1508 consumed_eof: bool,
1509 diagnostics: DiagnosticSeqId,
1510 deferred_nodes: FastDeferredNodeId,
1511 nodes: NodeSeqId,
1515}
1516
1517#[derive(Debug, Default)]
1518struct FastRecognizeTopScratch {
1519 visiting: FxHashSet<FastRecognizeKey>,
1520 memo: FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
1521}
1522
1523impl FastRecognizeTopScratch {
1524 fn prepare(&mut self, memo_capacity: usize) {
1525 self.visiting.clear();
1526 self.visiting.reserve(FAST_RECOGNIZE_VISITING_CAPACITY);
1527 self.memo.clear();
1528 self.memo.reserve(memo_capacity);
1529 }
1530
1531 fn release_oversized_memo(&mut self) {
1532 self.memo.clear();
1533 if self.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY {
1534 self.memo = FxHashMap::default();
1535 }
1536 }
1537}
1538
1539fn fast_recognize_memo_capacity(buffered_tokens: usize) -> usize {
1540 buffered_tokens.saturating_mul(8).clamp(
1541 FAST_RECOGNIZE_MIN_MEMO_CAPACITY,
1542 FAST_RECOGNIZE_MAX_MEMO_CAPACITY,
1543 )
1544}
1545
1546#[derive(Debug, Default)]
1547struct FastOutcomeDedupScratch {
1548 dense_words: Vec<u64>,
1549 touched_dense_words: Vec<u32>,
1550 sparse_keys: FxHashSet<(usize, bool)>,
1551}
1552
1553#[repr(transparent)]
1558#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1559struct FastDeferredNodeId(u32);
1560
1561impl FastDeferredNodeId {
1562 const EMPTY: Self = Self(u32::MAX);
1563
1564 const fn is_empty(self) -> bool {
1565 self.0 == Self::EMPTY.0
1566 }
1567}
1568
1569impl Default for FastDeferredNodeId {
1570 fn default() -> Self {
1571 Self::EMPTY
1572 }
1573}
1574
1575#[repr(transparent)]
1576#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1577struct FastDeferredRuleId(u32);
1578
1579#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1581enum FastDeferredNode {
1582 Fragment(NodeSeqId),
1583 Rule(FastDeferredRuleId),
1584 Alternative(u32),
1585 LeftRecursiveBoundary {
1586 rule_index: u32,
1587 },
1588 Concat {
1589 prefix: FastDeferredNodeId,
1590 suffix: FastDeferredNodeId,
1591 },
1592}
1593
1594#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1595struct FastDeferredRule {
1596 rule_index: u32,
1597 invoking_state: i32,
1598 start_index: u32,
1599 stop_index: Option<u32>,
1600 deferred_children: FastDeferredNodeId,
1601 children: NodeSeqId,
1602}
1603
1604#[repr(transparent)]
1605#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1606struct RecognizedNodeId(u32);
1607
1608#[repr(transparent)]
1609#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1610struct NodeSeqId(u32);
1611
1612impl NodeSeqId {
1613 const EMPTY: Self = Self(u32::MAX);
1614
1615 const fn is_empty(self) -> bool {
1616 self.0 == Self::EMPTY.0
1617 }
1618}
1619
1620impl Default for NodeSeqId {
1621 fn default() -> Self {
1622 Self::EMPTY
1623 }
1624}
1625
1626#[repr(transparent)]
1627#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1628struct DiagnosticSeqId(u32);
1629
1630impl DiagnosticSeqId {
1631 const EMPTY: Self = Self(u32::MAX);
1632
1633 const fn is_empty(self) -> bool {
1634 self.0 == Self::EMPTY.0
1635 }
1636}
1637
1638impl Default for DiagnosticSeqId {
1639 fn default() -> Self {
1640 Self::EMPTY
1641 }
1642}
1643
1644#[repr(transparent)]
1645#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1646struct RecognitionExtraId(u32);
1647
1648#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1649struct SeqLink {
1650 head: RecognizedNodeId,
1651 tail: NodeSeqId,
1652}
1653
1654#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1655struct DiagnosticLink {
1656 head: RecognitionExtraId,
1657 tail: DiagnosticSeqId,
1658}
1659
1660struct ArenaRuleSpec {
1661 rule_index: usize,
1662 invoking_state: isize,
1663 alt_number: usize,
1664 start_index: usize,
1665 stop_index: Option<usize>,
1666 return_values: BTreeMap<String, i64>,
1667 children: NodeSeqId,
1668}
1669
1670#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1673enum ArenaRecognizedNode {
1674 Token {
1675 token: TokenId,
1676 },
1677 ErrorToken {
1678 token: TokenId,
1679 },
1680 MissingToken {
1681 extra: RecognitionExtraId,
1682 },
1683 Rule {
1684 rule_index: u32,
1685 invoking_state: i32,
1686 alt_number: u32,
1687 start_index: u32,
1688 stop_index: Option<u32>,
1689 return_values: Option<RecognitionExtraId>,
1690 children: NodeSeqId,
1691 },
1692 LeftRecursiveBoundary {
1696 rule_index: u32,
1697 alt_number: u32,
1698 },
1699}
1700
1701#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
1702enum RecognitionExtra {
1703 MissingToken {
1704 token_type: i32,
1705 at_index: u32,
1706 text: String,
1707 },
1708 ReturnValues(BTreeMap<String, i64>),
1709 Diagnostic(ParserDiagnostic),
1710}
1711
1712#[derive(Debug, Default)]
1713struct RecognitionArena {
1714 nodes: Vec<ArenaRecognizedNode>,
1715 seq_links: Vec<SeqLink>,
1716 diagnostic_links: Vec<DiagnosticLink>,
1717 extras: Vec<RecognitionExtra>,
1718 deferred_nodes: Vec<FastDeferredNode>,
1719 deferred_rules: Vec<FastDeferredRule>,
1720}
1721
1722const MAX_RETAINED_RECOGNITION_NODES: usize = 131_072;
1725const MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS: usize = 262_144;
1726const MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS: usize = 65_536;
1727const MAX_RETAINED_RECOGNITION_EXTRAS: usize = 32_768;
1728const MAX_RETAINED_FAST_DEFERRED_NODES: usize = 262_144;
1729const MAX_RETAINED_FAST_DEFERRED_RULES: usize = 131_072;
1730
1731impl RecognitionArena {
1732 fn reset(&mut self) {
1733 reset_arena_vec(&mut self.nodes, MAX_RETAINED_RECOGNITION_NODES);
1734 reset_arena_vec(&mut self.seq_links, MAX_RETAINED_RECOGNITION_SEQUENCE_LINKS);
1735 reset_arena_vec(
1736 &mut self.diagnostic_links,
1737 MAX_RETAINED_RECOGNITION_DIAGNOSTIC_LINKS,
1738 );
1739 reset_arena_vec(&mut self.extras, MAX_RETAINED_RECOGNITION_EXTRAS);
1740 reset_arena_vec(&mut self.deferred_nodes, MAX_RETAINED_FAST_DEFERRED_NODES);
1741 reset_arena_vec(&mut self.deferred_rules, MAX_RETAINED_FAST_DEFERRED_RULES);
1742 }
1743
1744 fn push_node(&mut self, node: ArenaRecognizedNode) -> RecognizedNodeId {
1745 let id = RecognizedNodeId(
1746 u32::try_from(self.nodes.len()).expect("recognition node arena fits in u32"),
1747 );
1748 self.nodes.push(node);
1749 id
1750 }
1751
1752 fn push_extra(&mut self, extra: RecognitionExtra) -> RecognitionExtraId {
1753 let id = RecognitionExtraId(
1754 u32::try_from(self.extras.len()).expect("recognition extra arena fits in u32"),
1755 );
1756 self.extras.push(extra);
1757 id
1758 }
1759
1760 fn prepend(&mut self, tail: NodeSeqId, head: RecognizedNodeId) -> NodeSeqId {
1761 let id = NodeSeqId(
1762 u32::try_from(self.seq_links.len()).expect("node sequence arena fits in u32"),
1763 );
1764 self.seq_links.push(SeqLink { head, tail });
1765 id
1766 }
1767
1768 fn push_deferred_node(&mut self, node: FastDeferredNode) -> FastDeferredNodeId {
1769 let id = FastDeferredNodeId(
1770 u32::try_from(self.deferred_nodes.len()).expect("deferred node arena fits in u32"),
1771 );
1772 self.deferred_nodes.push(node);
1773 id
1774 }
1775
1776 fn push_deferred_rule(&mut self, rule: FastDeferredRule) -> FastDeferredRuleId {
1777 let id = FastDeferredRuleId(
1778 u32::try_from(self.deferred_rules.len()).expect("deferred rule arena fits in u32"),
1779 );
1780 self.deferred_rules.push(rule);
1781 id
1782 }
1783
1784 fn deferred_fragment(&mut self, nodes: NodeSeqId) -> FastDeferredNodeId {
1785 if nodes.is_empty() {
1786 FastDeferredNodeId::EMPTY
1787 } else {
1788 self.push_deferred_node(FastDeferredNode::Fragment(nodes))
1789 }
1790 }
1791
1792 fn deferred_rule_node(&mut self, rule: FastDeferredRule) -> FastDeferredNodeId {
1793 let rule = self.push_deferred_rule(rule);
1794 self.push_deferred_node(FastDeferredNode::Rule(rule))
1795 }
1796
1797 fn deferred_alternative(&mut self, alt_number: usize) -> FastDeferredNodeId {
1798 self.push_deferred_node(FastDeferredNode::Alternative(
1799 u32::try_from(alt_number).expect("alternative number fits in u32"),
1800 ))
1801 }
1802
1803 fn deferred_left_recursive_boundary(&mut self, rule_index: usize) -> FastDeferredNodeId {
1804 self.push_deferred_node(FastDeferredNode::LeftRecursiveBoundary {
1805 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
1806 })
1807 }
1808
1809 fn concat_deferred_nodes(
1810 &mut self,
1811 prefix: FastDeferredNodeId,
1812 suffix: FastDeferredNodeId,
1813 ) -> FastDeferredNodeId {
1814 if prefix.is_empty() {
1815 return suffix;
1816 }
1817 if suffix.is_empty() {
1818 return prefix;
1819 }
1820 self.push_deferred_node(FastDeferredNode::Concat { prefix, suffix })
1821 }
1822
1823 fn deferred_node(&self, id: FastDeferredNodeId) -> FastDeferredNode {
1824 self.deferred_nodes[id.0 as usize]
1825 }
1826
1827 fn deferred_rule(&self, id: FastDeferredRuleId) -> FastDeferredRule {
1828 self.deferred_rules[id.0 as usize]
1829 }
1830
1831 fn prepend_diagnostic(
1832 &mut self,
1833 tail: DiagnosticSeqId,
1834 diagnostic: ParserDiagnostic,
1835 ) -> DiagnosticSeqId {
1836 let head = self.push_extra(RecognitionExtra::Diagnostic(diagnostic));
1837 self.prepend_diagnostic_id(tail, head)
1838 }
1839
1840 fn prepend_diagnostic_id(
1841 &mut self,
1842 tail: DiagnosticSeqId,
1843 head: RecognitionExtraId,
1844 ) -> DiagnosticSeqId {
1845 let id = DiagnosticSeqId(
1846 u32::try_from(self.diagnostic_links.len())
1847 .expect("diagnostic sequence arena fits in u32"),
1848 );
1849 self.diagnostic_links.push(DiagnosticLink { head, tail });
1850 id
1851 }
1852
1853 fn concat_diagnostics(
1854 &mut self,
1855 prefix: DiagnosticSeqId,
1856 mut suffix: DiagnosticSeqId,
1857 ) -> DiagnosticSeqId {
1858 if prefix.is_empty() {
1859 return suffix;
1860 }
1861 if suffix.is_empty() {
1862 return prefix;
1863 }
1864 let mut reversed = DiagnosticSeqId::EMPTY;
1865 let mut cursor = prefix;
1866 while let Some(link) = self.diagnostic_link(cursor) {
1867 reversed = self.prepend_diagnostic_id(reversed, link.head);
1868 cursor = link.tail;
1869 }
1870 while let Some(link) = self.diagnostic_link(reversed) {
1871 suffix = self.prepend_diagnostic_id(suffix, link.head);
1872 reversed = link.tail;
1873 }
1874 suffix
1875 }
1876
1877 #[cfg(test)]
1878 fn diagnostic_sequence(
1879 &mut self,
1880 diagnostics: impl IntoIterator<Item = ParserDiagnostic>,
1881 ) -> DiagnosticSeqId {
1882 let diagnostics = diagnostics.into_iter().collect::<Vec<_>>();
1883 let mut sequence = DiagnosticSeqId::EMPTY;
1884 for diagnostic in diagnostics.into_iter().rev() {
1885 sequence = self.prepend_diagnostic(sequence, diagnostic);
1886 }
1887 sequence
1888 }
1889
1890 fn node(&self, id: RecognizedNodeId) -> ArenaRecognizedNode {
1891 self.nodes[id.0 as usize]
1892 }
1893
1894 fn set_boundary_alt_number(&mut self, id: RecognizedNodeId, alt_number: u32) {
1895 let ArenaRecognizedNode::LeftRecursiveBoundary {
1896 alt_number: stored, ..
1897 } = &mut self.nodes[id.0 as usize]
1898 else {
1899 unreachable!("deferred boundary must materialize as a boundary node");
1900 };
1901 *stored = alt_number;
1902 }
1903
1904 fn extra(&self, id: RecognitionExtraId) -> &RecognitionExtra {
1905 &self.extras[id.0 as usize]
1906 }
1907
1908 fn link(&self, id: NodeSeqId) -> Option<SeqLink> {
1909 (!id.is_empty()).then(|| self.seq_links[id.0 as usize])
1910 }
1911
1912 fn diagnostic_link(&self, id: DiagnosticSeqId) -> Option<DiagnosticLink> {
1913 (!id.is_empty()).then(|| self.diagnostic_links[id.0 as usize])
1914 }
1915
1916 const fn iter(&self, sequence: NodeSeqId) -> NodeSeqIter<'_> {
1917 NodeSeqIter {
1918 arena: self,
1919 cursor: sequence,
1920 }
1921 }
1922
1923 const fn diagnostics(&self, sequence: DiagnosticSeqId) -> DiagnosticSeqIter<'_> {
1924 DiagnosticSeqIter {
1925 arena: self,
1926 cursor: sequence,
1927 }
1928 }
1929
1930 fn diagnostics_len(&self, sequence: DiagnosticSeqId) -> usize {
1931 self.diagnostics(sequence).count()
1932 }
1933
1934 fn diagnostics_recovery_rank(&self, sequence: DiagnosticSeqId) -> usize {
1935 self.diagnostics(sequence)
1936 .filter(|diagnostic| {
1937 diagnostic.message.starts_with("mismatched input ")
1938 && !diagnostic.message.starts_with("mismatched input '<EOF>' ")
1939 })
1940 .count()
1941 }
1942
1943 fn compare_diagnostics(&self, left: DiagnosticSeqId, right: DiagnosticSeqId) -> Ordering {
1944 self.diagnostics(left).cmp(self.diagnostics(right))
1945 }
1946
1947 fn sequence_len(&self, sequence: NodeSeqId) -> usize {
1948 self.iter(sequence).count()
1949 }
1950
1951 fn sequence_has_left_recursive_boundary(&self, sequence: NodeSeqId) -> bool {
1952 self.iter(sequence).any(|node| match self.node(node) {
1953 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
1954 ArenaRecognizedNode::Rule { children, .. } => {
1955 self.sequence_has_left_recursive_boundary(children)
1956 }
1957 ArenaRecognizedNode::Token { .. }
1958 | ArenaRecognizedNode::ErrorToken { .. }
1959 | ArenaRecognizedNode::MissingToken { .. } => false,
1960 })
1961 }
1962
1963 fn sequence_has_direct_boundary(&self, sequence: NodeSeqId) -> bool {
1964 self.iter(sequence).any(|node| {
1965 matches!(
1966 self.node(node),
1967 ArenaRecognizedNode::LeftRecursiveBoundary { .. }
1968 )
1969 })
1970 }
1971
1972 fn sequence_has_explicit_token(&self, sequence: NodeSeqId) -> bool {
1973 self.iter(sequence).any(|node| {
1974 matches!(
1975 self.node(node),
1976 ArenaRecognizedNode::Token { .. }
1977 | ArenaRecognizedNode::ErrorToken { .. }
1978 | ArenaRecognizedNode::MissingToken { .. }
1979 )
1980 })
1981 }
1982
1983 fn node_start_index(&self, node: RecognizedNodeId) -> Option<usize> {
1984 match self.node(node) {
1985 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
1986 Some(token.index())
1987 }
1988 ArenaRecognizedNode::MissingToken { extra } => {
1989 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
1990 unreachable!("missing-token node must reference missing-token extra");
1991 };
1992 Some(*at_index as usize)
1993 }
1994 ArenaRecognizedNode::Rule { start_index, .. } => Some(start_index as usize),
1995 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
1996 }
1997 }
1998
1999 fn node_stop_index(&self, node: RecognizedNodeId) -> Option<usize> {
2000 match self.node(node) {
2001 ArenaRecognizedNode::Token { token } | ArenaRecognizedNode::ErrorToken { token } => {
2002 Some(token.index())
2003 }
2004 ArenaRecognizedNode::MissingToken { extra } => {
2005 let RecognitionExtra::MissingToken { at_index, .. } = self.extra(extra) else {
2006 unreachable!("missing-token node must reference missing-token extra");
2007 };
2008 (*at_index as usize).checked_sub(1)
2009 }
2010 ArenaRecognizedNode::Rule { stop_index, .. } => stop_index.map(|index| index as usize),
2011 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => None,
2012 }
2013 }
2014
2015 fn node_span(&self, node: RecognizedNodeId) -> Option<(usize, Option<usize>)> {
2016 let start = self.node_start_index(node)?;
2017 let stop = self.node_stop_index(node);
2018 Some((start, stop))
2019 }
2020
2021 fn sequence_start_index(&self, sequence: NodeSeqId) -> Option<usize> {
2022 self.iter(sequence)
2023 .find_map(|node| self.node_start_index(node))
2024 }
2025
2026 fn sequence_stop_index(&self, sequence: NodeSeqId) -> Option<usize> {
2027 let mut stop = None;
2028 for node in self.iter(sequence) {
2029 if let Some(index) = self.node_stop_index(node) {
2030 stop = Some(index);
2031 }
2032 }
2033 stop
2034 }
2035
2036 fn sequence_needs_stable_tie(&self, sequence: NodeSeqId) -> bool {
2037 self.iter(sequence)
2038 .any(|node| self.node_needs_stable_tie(node))
2039 }
2040
2041 fn node_needs_stable_tie(&self, node: RecognizedNodeId) -> bool {
2042 match self.node(node) {
2043 ArenaRecognizedNode::Token { .. }
2044 | ArenaRecognizedNode::ErrorToken { .. }
2045 | ArenaRecognizedNode::MissingToken { .. } => false,
2046 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => true,
2047 ArenaRecognizedNode::Rule {
2048 rule_index,
2049 children,
2050 ..
2051 } => self.iter(children).any(|child| {
2052 matches!(
2053 self.node(child),
2054 ArenaRecognizedNode::Rule {
2055 rule_index: child_rule,
2056 ..
2057 } if child_rule == rule_index
2058 ) || self.node_needs_stable_tie(child)
2059 }),
2060 }
2061 }
2062
2063 fn compare_sequences(&self, mut left: NodeSeqId, mut right: NodeSeqId) -> Ordering {
2064 loop {
2065 match (self.link(left), self.link(right)) {
2066 (Some(left_link), Some(right_link)) => {
2067 let order = self.compare_nodes(left_link.head, right_link.head);
2068 if order != Ordering::Equal {
2069 return order;
2070 }
2071 left = left_link.tail;
2072 right = right_link.tail;
2073 }
2074 (None, None) => return Ordering::Equal,
2075 (None, Some(_)) => return Ordering::Less,
2076 (Some(_), None) => return Ordering::Greater,
2077 }
2078 }
2079 }
2080
2081 fn compare_nodes(&self, left: RecognizedNodeId, right: RecognizedNodeId) -> Ordering {
2082 let left = self.node(left);
2083 let right = self.node(right);
2084 match (left, right) {
2085 (
2086 ArenaRecognizedNode::Token { token: left },
2087 ArenaRecognizedNode::Token { token: right },
2088 )
2089 | (
2090 ArenaRecognizedNode::ErrorToken { token: left },
2091 ArenaRecognizedNode::ErrorToken { token: right },
2092 ) => left.cmp(&right),
2093 (
2094 ArenaRecognizedNode::MissingToken { extra: left },
2095 ArenaRecognizedNode::MissingToken { extra: right },
2096 ) => self.extra(left).cmp(self.extra(right)),
2097 (
2098 ArenaRecognizedNode::Rule {
2099 rule_index: left_rule,
2100 invoking_state: left_invoking,
2101 alt_number: left_alt,
2102 start_index: left_start,
2103 stop_index: left_stop,
2104 return_values: left_returns,
2105 children: left_children,
2106 },
2107 ArenaRecognizedNode::Rule {
2108 rule_index: right_rule,
2109 invoking_state: right_invoking,
2110 alt_number: right_alt,
2111 start_index: right_start,
2112 stop_index: right_stop,
2113 return_values: right_returns,
2114 children: right_children,
2115 },
2116 ) => (left_rule, left_invoking, left_alt, left_start, left_stop)
2117 .cmp(&(
2118 right_rule,
2119 right_invoking,
2120 right_alt,
2121 right_start,
2122 right_stop,
2123 ))
2124 .then_with(|| {
2125 left_returns
2126 .map(|id| self.extra(id))
2127 .cmp(&right_returns.map(|id| self.extra(id)))
2128 })
2129 .then_with(|| self.compare_sequences(left_children, right_children)),
2130 (
2131 ArenaRecognizedNode::LeftRecursiveBoundary {
2132 rule_index: left_rule,
2133 alt_number: left_alt,
2134 },
2135 ArenaRecognizedNode::LeftRecursiveBoundary {
2136 rule_index: right_rule,
2137 alt_number: right_alt,
2138 },
2139 ) => (left_rule, left_alt).cmp(&(right_rule, right_alt)),
2140 (left, right) => recognition_node_kind(&left).cmp(&recognition_node_kind(&right)),
2141 }
2142 }
2143
2144 fn reverse_sequence(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
2145 let mut reversed = NodeSeqId::EMPTY;
2146 while let Some(link) = self.link(sequence) {
2147 reversed = self.prepend(reversed, link.head);
2148 sequence = link.tail;
2149 }
2150 reversed
2151 }
2152
2153 fn fold_left_recursive_boundaries(&mut self, mut sequence: NodeSeqId) -> NodeSeqId {
2154 if !self.sequence_has_direct_boundary(sequence) {
2155 return sequence;
2156 }
2157 let mut reversed = NodeSeqId::EMPTY;
2158 while let Some(link) = self.link(sequence) {
2159 match self.node(link.head) {
2160 ArenaRecognizedNode::LeftRecursiveBoundary {
2161 rule_index,
2162 alt_number,
2163 } => {
2164 if !reversed.is_empty() {
2165 let children = self.reverse_sequence(reversed);
2166 let start_index = self.sequence_start_index(children).unwrap_or_default();
2167 let stop_index = self.sequence_stop_index(children);
2168 let rule = self.push_node(ArenaRecognizedNode::Rule {
2169 rule_index,
2170 invoking_state: -1,
2171 alt_number,
2172 start_index: u32::try_from(start_index)
2173 .expect("left-recursive start index fits in u32"),
2174 stop_index: stop_index.map(|index| {
2175 u32::try_from(index).expect("left-recursive stop index fits in u32")
2176 }),
2177 return_values: None,
2178 children,
2179 });
2180 reversed = self.prepend(NodeSeqId::EMPTY, rule);
2181 }
2182 }
2183 _ => {
2184 reversed = self.prepend(reversed, link.head);
2185 }
2186 }
2187 sequence = link.tail;
2188 }
2189 self.reverse_sequence(reversed)
2190 }
2191
2192 fn stats(&self, root: NodeSeqId, diagnostics: DiagnosticSeqId) -> RecognitionArenaStats {
2193 let mut live_nodes = vec![false; self.nodes.len()];
2194 let mut live_links = vec![false; self.seq_links.len()];
2195 let mut live_diagnostic_links = vec![false; self.diagnostic_links.len()];
2196 let mut live_extras = vec![false; self.extras.len()];
2197 let mut pending = vec![root];
2198 while let Some(mut sequence) = pending.pop() {
2199 while let Some(link) = self.link(sequence) {
2200 let link_index = sequence.0 as usize;
2201 if live_links[link_index] {
2202 break;
2203 }
2204 live_links[link_index] = true;
2205 let node_index = link.head.0 as usize;
2206 if !live_nodes[node_index] {
2207 live_nodes[node_index] = true;
2208 match self.node(link.head) {
2209 ArenaRecognizedNode::MissingToken { extra } => {
2210 live_extras[extra.0 as usize] = true;
2211 }
2212 ArenaRecognizedNode::Rule {
2213 return_values,
2214 children,
2215 ..
2216 } => {
2217 if let Some(extra) = return_values {
2218 live_extras[extra.0 as usize] = true;
2219 }
2220 pending.push(children);
2221 }
2222 ArenaRecognizedNode::Token { .. }
2223 | ArenaRecognizedNode::ErrorToken { .. }
2224 | ArenaRecognizedNode::LeftRecursiveBoundary { .. } => {}
2225 }
2226 }
2227 sequence = link.tail;
2228 }
2229 }
2230 let mut diagnostics = diagnostics;
2231 while let Some(link) = self.diagnostic_link(diagnostics) {
2232 let link_index = diagnostics.0 as usize;
2233 if live_diagnostic_links[link_index] {
2234 break;
2235 }
2236 live_diagnostic_links[link_index] = true;
2237 live_extras[link.head.0 as usize] = true;
2238 diagnostics = link.tail;
2239 }
2240 let live_node_count = live_nodes.into_iter().filter(|live| *live).count();
2241 let live_link_count = live_links.into_iter().filter(|live| *live).count()
2242 + live_diagnostic_links
2243 .into_iter()
2244 .filter(|live| *live)
2245 .count();
2246 let live_extra_count = live_extras.into_iter().filter(|live| *live).count();
2247 let total_links = self.seq_links.len() + self.diagnostic_links.len();
2248 RecognitionArenaStats {
2249 total_nodes: self.nodes.len(),
2250 live_nodes: live_node_count,
2251 dead_nodes: self.nodes.len().saturating_sub(live_node_count),
2252 node_capacity: self.nodes.capacity(),
2253 total_links,
2254 live_links: live_link_count,
2255 dead_links: total_links.saturating_sub(live_link_count),
2256 link_capacity: self.seq_links.capacity() + self.diagnostic_links.capacity(),
2257 total_extras: self.extras.len(),
2258 live_extras: live_extra_count,
2259 dead_extras: self.extras.len().saturating_sub(live_extra_count),
2260 extra_capacity: self.extras.capacity(),
2261 }
2262 }
2263}
2264
2265fn reset_arena_vec<T>(storage: &mut Vec<T>, max_retained_capacity: usize) {
2266 if storage.capacity() > max_retained_capacity {
2267 *storage = Vec::new();
2268 } else {
2269 storage.clear();
2270 }
2271}
2272
2273const fn recognition_node_kind(node: &ArenaRecognizedNode) -> u8 {
2274 match node {
2275 ArenaRecognizedNode::Token { .. } => 0,
2276 ArenaRecognizedNode::ErrorToken { .. } => 1,
2277 ArenaRecognizedNode::MissingToken { .. } => 2,
2278 ArenaRecognizedNode::Rule { .. } => 3,
2279 ArenaRecognizedNode::LeftRecursiveBoundary { .. } => 4,
2280 }
2281}
2282
2283struct NodeSeqIter<'a> {
2284 arena: &'a RecognitionArena,
2285 cursor: NodeSeqId,
2286}
2287
2288impl Iterator for NodeSeqIter<'_> {
2289 type Item = RecognizedNodeId;
2290
2291 fn next(&mut self) -> Option<Self::Item> {
2292 let link = self.arena.link(self.cursor)?;
2293 self.cursor = link.tail;
2294 Some(link.head)
2295 }
2296}
2297
2298struct DiagnosticSeqIter<'a> {
2299 arena: &'a RecognitionArena,
2300 cursor: DiagnosticSeqId,
2301}
2302
2303impl<'a> Iterator for DiagnosticSeqIter<'a> {
2304 type Item = &'a ParserDiagnostic;
2305
2306 fn next(&mut self) -> Option<Self::Item> {
2307 let link = self.arena.diagnostic_link(self.cursor)?;
2308 self.cursor = link.tail;
2309 let RecognitionExtra::Diagnostic(diagnostic) = self.arena.extra(link.head) else {
2310 unreachable!("diagnostic link must reference diagnostic extra");
2311 };
2312 Some(diagnostic)
2313 }
2314}
2315
2316#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
2317struct ParserDiagnostic {
2318 line: usize,
2319 column: usize,
2320 message: String,
2321 offending: Option<TokenId>,
2325}
2326
2327#[derive(Clone, Debug, Default, Eq, PartialEq)]
2328struct ExpectedTokens {
2329 index: Option<usize>,
2330 symbols: BTreeSet<i32>,
2331 no_viable: Option<NoViableAlternative>,
2332}
2333
2334#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2335struct NoViableAlternative {
2336 start_index: usize,
2337 error_index: usize,
2338}
2339
2340impl ExpectedTokens {
2341 fn record_transition(
2344 &mut self,
2345 index: usize,
2346 transition: ParserTransition<'_>,
2347 max_token_type: i32,
2348 ) {
2349 let symbols = transition_expected_symbols(transition, max_token_type);
2350 match self.index {
2351 Some(current) if index < current => {}
2352 Some(current) if index == current => self.symbols.extend(symbols),
2353 _ => {
2354 self.index = Some(index);
2355 self.symbols = symbols;
2356 }
2357 }
2358 }
2359
2360 const fn record_no_viable(&mut self, start_index: usize, error_index: usize) {
2363 match self.no_viable {
2364 Some(current) if error_index < current.error_index => {}
2365 _ => {
2366 self.no_viable = Some(NoViableAlternative {
2367 start_index,
2368 error_index,
2369 });
2370 }
2371 }
2372 }
2373}
2374
2375#[derive(Clone, Debug, Default, Eq, PartialEq)]
2382struct TokenBitSet {
2383 words: Vec<u64>,
2384}
2385
2386impl TokenBitSet {
2387 fn insert(&mut self, symbol: i32) {
2388 let Some(slot) = token_bit_slot(symbol) else {
2389 return;
2390 };
2391 let word = slot / u64::BITS as usize;
2392 if word >= self.words.len() {
2393 self.words.resize(word + 1, 0);
2394 }
2395 self.words[word] |= 1_u64 << (slot % u64::BITS as usize);
2396 }
2397
2398 fn extend_range(&mut self, start: i32, stop: i32) {
2399 let (start, stop) = if start <= stop {
2400 (start, stop)
2401 } else {
2402 (stop, start)
2403 };
2404 if start <= TOKEN_EOF && stop >= TOKEN_EOF {
2405 self.insert(TOKEN_EOF);
2406 }
2407 let positive_start = start.max(1);
2408 if positive_start > stop {
2409 return;
2410 }
2411 let Some(start_slot) = token_bit_slot(positive_start) else {
2412 return;
2413 };
2414 let Some(stop_slot) = token_bit_slot(stop) else {
2415 return;
2416 };
2417 self.extend_slot_range(start_slot, stop_slot);
2418 }
2419
2420 fn extend_slot_range(&mut self, start_slot: usize, stop_slot: usize) {
2421 if start_slot > stop_slot {
2422 return;
2423 }
2424 let start_word = start_slot / u64::BITS as usize;
2425 let stop_word = stop_slot / u64::BITS as usize;
2426 if stop_word >= self.words.len() {
2427 self.words.resize(stop_word + 1, 0);
2428 }
2429 let start_offset = start_slot % u64::BITS as usize;
2430 let stop_offset = stop_slot % u64::BITS as usize;
2431 if start_word == stop_word {
2432 self.words[start_word] |=
2433 (!0_u64 << start_offset) & (!0_u64 >> (u64::BITS as usize - 1 - stop_offset));
2434 return;
2435 }
2436 self.words[start_word] |= !0_u64 << start_offset;
2437 for word in &mut self.words[(start_word + 1)..stop_word] {
2438 *word = !0_u64;
2439 }
2440 self.words[stop_word] |= !0_u64 >> (u64::BITS as usize - 1 - stop_offset);
2441 }
2442
2443 fn extend_iter(&mut self, symbols: impl IntoIterator<Item = i32>) {
2444 for symbol in symbols {
2445 self.insert(symbol);
2446 }
2447 }
2448
2449 fn extend_from(&mut self, other: &Self) {
2450 if other.words.len() > self.words.len() {
2451 self.words.resize(other.words.len(), 0);
2452 }
2453 for (left, right) in self.words.iter_mut().zip(&other.words) {
2454 *left |= *right;
2455 }
2456 }
2457
2458 fn contains(&self, symbol: i32) -> bool {
2459 let Some(slot) = token_bit_slot(symbol) else {
2460 return false;
2461 };
2462 let word = slot / u64::BITS as usize;
2463 self.words
2464 .get(word)
2465 .is_some_and(|bits| bits & (1_u64 << (slot % u64::BITS as usize)) != 0)
2466 }
2467
2468 fn is_empty(&self) -> bool {
2469 self.words.iter().all(|word| *word == 0)
2470 }
2471
2472 fn symbols(&self) -> impl Iterator<Item = i32> + '_ {
2473 self.words
2474 .iter()
2475 .copied()
2476 .enumerate()
2477 .flat_map(|(word_index, mut bits)| {
2478 std::iter::from_fn(move || {
2479 while bits != 0 {
2480 let bit = bits.trailing_zeros() as usize;
2481 bits &= bits - 1;
2482 if let Some(symbol) =
2483 token_bit_symbol(word_index * u64::BITS as usize + bit)
2484 {
2485 return Some(symbol);
2486 }
2487 }
2488 None
2489 })
2490 })
2491 }
2492
2493 fn extend_btree_set(&self, target: &mut BTreeSet<i32>) {
2494 target.extend(self.symbols());
2495 }
2496
2497 fn to_btree_set(&self) -> BTreeSet<i32> {
2498 let mut out = BTreeSet::new();
2499 self.extend_btree_set(&mut out);
2500 out
2501 }
2502}
2503
2504fn token_bit_slot(symbol: i32) -> Option<usize> {
2505 if symbol == TOKEN_EOF {
2506 Some(0)
2507 } else if symbol > 0 {
2508 usize::try_from(symbol).ok()
2509 } else {
2510 None
2511 }
2512}
2513
2514fn token_bit_symbol(slot: usize) -> Option<i32> {
2515 if slot == 0 {
2516 Some(TOKEN_EOF)
2517 } else {
2518 i32::try_from(slot).ok()
2519 }
2520}
2521
2522fn transition_expected_symbols(
2525 transition: ParserTransition<'_>,
2526 max_token_type: i32,
2527) -> BTreeSet<i32> {
2528 let mut symbols = BTreeSet::new();
2529 match &transition.data() {
2530 Transition::Atom { label, .. } => {
2531 symbols.insert(*label);
2532 }
2533 Transition::Range { start, stop, .. } => {
2534 symbols.extend(*start..=*stop);
2535 }
2536 Transition::Set { set, .. } => {
2537 for (start, stop) in set.ranges() {
2538 symbols.extend(start..=stop);
2539 }
2540 }
2541 Transition::NotSet { set, .. } => {
2542 symbols.extend((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2543 }
2544 Transition::Wildcard { .. } => {
2545 symbols.extend(1..=max_token_type);
2546 }
2547 Transition::Epsilon { .. }
2548 | Transition::Rule { .. }
2549 | Transition::Predicate { .. }
2550 | Transition::Action { .. }
2551 | Transition::Precedence { .. } => {}
2552 }
2553 symbols
2554}
2555
2556fn transition_expected_token_set(
2557 transition: ParserTransition<'_>,
2558 max_token_type: i32,
2559) -> TokenBitSet {
2560 let mut symbols = TokenBitSet::default();
2561 match &transition.data() {
2562 Transition::Atom { label, .. } => {
2563 symbols.insert(*label);
2564 }
2565 Transition::Range { start, stop, .. } => {
2566 symbols.extend_range(*start, *stop);
2567 }
2568 Transition::Set { set, .. } => {
2569 for (start, stop) in set.ranges() {
2570 symbols.extend_range(start, stop);
2571 }
2572 }
2573 Transition::NotSet { set, .. } => {
2574 symbols.extend_iter((1..=max_token_type).filter(|symbol| !set.contains(*symbol)));
2575 }
2576 Transition::Wildcard { .. } => {
2577 symbols.extend_range(1, max_token_type);
2578 }
2579 Transition::Epsilon { .. }
2580 | Transition::Rule { .. }
2581 | Transition::Predicate { .. }
2582 | Transition::Action { .. }
2583 | Transition::Precedence { .. } => {}
2584 }
2585 symbols
2586}
2587
2588fn state_expected_symbols(atn: &Atn, state_number: usize) -> BTreeSet<i32> {
2592 let mut symbols = BTreeSet::new();
2593 let mut stack = vec![state_number];
2594 let mut visited = BTreeSet::new();
2595 while let Some(current) = stack.pop() {
2596 if !visited.insert(current) {
2597 continue;
2598 }
2599 let Some(state) = atn.state(current) else {
2600 continue;
2601 };
2602 for transition in &state.transitions() {
2603 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
2604 if transition_symbols.is_empty() {
2605 if transition.is_epsilon() {
2606 stack.push(transition.target());
2607 }
2608 } else {
2609 symbols.extend(transition_symbols);
2610 }
2611 }
2612 }
2613 symbols
2614}
2615
2616fn state_expected_token_set(atn: &Atn, state_number: usize) -> TokenBitSet {
2617 let mut symbols = TokenBitSet::default();
2618 let mut stack = vec![state_number];
2619 let mut visited = BTreeSet::new();
2620 while let Some(current) = stack.pop() {
2621 if !visited.insert(current) {
2622 continue;
2623 }
2624 let Some(state) = atn.state(current) else {
2625 continue;
2626 };
2627 for transition in &state.transitions() {
2628 let transition_symbols =
2629 transition_expected_token_set(transition, atn.max_token_type());
2630 if transition_symbols.is_empty() {
2631 if transition.is_epsilon() {
2632 stack.push(transition.target());
2633 }
2634 } else {
2635 symbols.extend_from(&transition_symbols);
2636 }
2637 }
2638 }
2639 symbols
2640}
2641
2642fn state_can_reach_rule_stop(atn: &Atn, state_number: usize) -> bool {
2643 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
2644 return false;
2645 };
2646 let Some(stop_state) = atn.rule_to_stop_state().get(rule_index) else {
2647 return false;
2648 };
2649 epsilon_reaches_state(atn, state_number, stop_state)
2650}
2651
2652fn epsilon_reaches_state(atn: &Atn, start: usize, target: usize) -> bool {
2653 let mut stack = vec![start];
2654 let mut visited = BTreeSet::new();
2655 while let Some(current) = stack.pop() {
2656 if current == target {
2657 return true;
2658 }
2659 if !visited.insert(current) {
2660 continue;
2661 }
2662 let Some(state) = atn.state(current) else {
2663 continue;
2664 };
2665 stack.extend(
2666 state
2667 .transitions()
2668 .iter()
2669 .filter(|transition| transition.is_epsilon())
2670 .map(ParserTransition::target),
2671 );
2672 }
2673 false
2674}
2675
2676#[derive(Clone, Debug, Default, Eq, PartialEq)]
2683struct FirstSet {
2684 symbols: TokenBitSet,
2685 nullable: bool,
2686}
2687
2688type FirstSetCache = FxHashMap<(usize, usize), Rc<FirstSet>>;
2695
2696type DecisionLookaheadCache = FxHashMap<usize, Rc<DecisionLookahead>>;
2703
2704#[derive(Debug, Default)]
2705struct LeftRecursiveOperatorLookahead {
2706 single_token: TokenBitSet,
2710 multi_token_prefix: TokenBitSet,
2715 predicate_dependent: TokenBitSet,
2716}
2717
2718#[derive(Default)]
2719struct SharedAtnCache {
2720 first_set: FirstSetCache,
2721 decision_lookahead: DecisionLookaheadCache,
2722 left_recursive_operator_lookahead: FxHashMap<(usize, i32), Rc<LeftRecursiveOperatorLookahead>>,
2723 state_before_stop_lookahead: FxHashMap<(usize, usize), Rc<StateBeforeStopLookahead>>,
2724 state_expected_tokens: FxHashMap<usize, Rc<TokenBitSet>>,
2725 rule_stop_reach: FxHashMap<usize, bool>,
2726 observable_action_transitions: Option<bool>,
2727 predicate_transitions: Option<bool>,
2728}
2729
2730thread_local! {
2731 static SHARED_ATN_CACHES: RefCell<FxHashMap<SharedAtnCacheKey, SharedAtnCache>> =
2732 RefCell::new(FxHashMap::default());
2733}
2734
2735#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
2746struct SharedAtnCacheKey {
2747 atn: usize,
2748 states: usize,
2749 state_count: usize,
2750 max_token_type: i32,
2751}
2752
2753impl SharedAtnCacheKey {
2754 fn for_atn(atn: &Atn) -> Self {
2755 let (states, state_count) = atn.storage_identity();
2756 Self {
2757 atn: std::ptr::from_ref::<Atn>(atn) as usize,
2758 states,
2759 state_count,
2760 max_token_type: atn.max_token_type(),
2761 }
2762 }
2763}
2764
2765fn with_shared_first_set_cache<R>(atn: &Atn, f: impl FnOnce(&mut FirstSetCache) -> R) -> R {
2766 SHARED_ATN_CACHES.with(|cell| {
2767 let key = SharedAtnCacheKey::for_atn(atn);
2768 let mut map = cell.borrow_mut();
2769 let cache = map.entry(key).or_default();
2770 f(&mut cache.first_set)
2771 })
2772}
2773
2774fn with_shared_atn_caches<R>(atn: &Atn, f: impl FnOnce(&mut SharedAtnCache) -> R) -> R {
2775 SHARED_ATN_CACHES.with(|cell| {
2776 let key = SharedAtnCacheKey::for_atn(atn);
2777 let mut map = cell.borrow_mut();
2778 let cache = map.entry(key).or_default();
2779 f(cache)
2780 })
2781}
2782
2783#[derive(Debug, Default)]
2792struct DecisionLookahead {
2793 transitions: Vec<TransitionLookSet>,
2794}
2795
2796#[derive(Clone, Debug, Default)]
2803struct TransitionLookSet {
2804 symbols: TokenBitSet,
2805 nullable: bool,
2806}
2807
2808struct FirstSetCtx<'a> {
2812 cache: &'a mut FirstSetCache,
2813 in_progress: BTreeSet<(usize, usize)>,
2814 hit_cycle: bool,
2815}
2816
2817fn rule_first_set(
2826 atn: &Atn,
2827 target: usize,
2828 rule_stop_state: usize,
2829 cache: &mut FirstSetCache,
2830) -> Rc<FirstSet> {
2831 if let Some(cached) = cache.get(&(target, rule_stop_state)) {
2832 return Rc::clone(cached);
2833 }
2834 let mut ctx = FirstSetCtx {
2835 cache,
2836 in_progress: BTreeSet::new(),
2837 hit_cycle: false,
2838 };
2839 rule_first_set_cached(atn, target, rule_stop_state, &mut ctx)
2840}
2841
2842fn rule_first_set_cached(
2843 atn: &Atn,
2844 target: usize,
2845 rule_stop_state: usize,
2846 ctx: &mut FirstSetCtx<'_>,
2847) -> Rc<FirstSet> {
2848 let key = (target, rule_stop_state);
2849 if let Some(cached) = ctx.cache.get(&key) {
2850 return Rc::clone(cached);
2851 }
2852 if !ctx.in_progress.insert(key) {
2853 return Rc::new(FirstSet::default());
2857 }
2858 let saved_hit_cycle = ctx.hit_cycle;
2859 ctx.hit_cycle = false;
2860 let mut first = FirstSet::default();
2861 let mut visited = BTreeSet::new();
2862 rule_first_set_inner(atn, target, rule_stop_state, ctx, &mut visited, &mut first);
2863 ctx.in_progress.remove(&key);
2864 let entry = Rc::new(first);
2865 if !ctx.hit_cycle {
2866 ctx.cache.insert(key, Rc::clone(&entry));
2867 }
2868 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
2869 entry
2870}
2871
2872fn transition_first_set(
2876 atn: &Atn,
2877 transition: ParserTransition<'_>,
2878 rule_stop_state: usize,
2879 cache: &mut FirstSetCache,
2880) -> TransitionLookSet {
2881 match &transition.data() {
2882 Transition::Atom { label, .. } => {
2883 let mut symbols = TokenBitSet::default();
2884 symbols.insert(*label);
2885 TransitionLookSet {
2886 symbols,
2887 nullable: false,
2888 }
2889 }
2890 Transition::Range { start, stop, .. } => {
2891 let mut symbols = TokenBitSet::default();
2892 symbols.extend_range(*start, *stop);
2893 TransitionLookSet {
2894 symbols,
2895 nullable: false,
2896 }
2897 }
2898 Transition::Set { set, .. } => {
2899 let mut symbols = TokenBitSet::default();
2900 for (start, stop) in set.ranges() {
2901 symbols.extend_range(start, stop);
2902 }
2903 TransitionLookSet {
2904 symbols,
2905 nullable: false,
2906 }
2907 }
2908 Transition::NotSet { set, .. } => {
2909 let max = atn.max_token_type();
2910 let mut symbols = TokenBitSet::default();
2911 symbols.extend_iter((1..=max).filter(|symbol| !set.contains(*symbol)));
2912 TransitionLookSet {
2913 symbols,
2914 nullable: false,
2915 }
2916 }
2917 Transition::Wildcard { .. } => {
2918 let mut symbols = TokenBitSet::default();
2919 symbols.extend_range(1, atn.max_token_type());
2920 TransitionLookSet {
2921 symbols,
2922 nullable: false,
2923 }
2924 }
2925 Transition::Epsilon { target }
2926 | Transition::Action { target, .. }
2927 | Transition::Predicate { target, .. }
2928 | Transition::Precedence { target, .. } => {
2929 let first = rule_first_set(atn, *target, rule_stop_state, cache);
2932 TransitionLookSet {
2933 symbols: first.symbols.clone(),
2934 nullable: first.nullable,
2935 }
2936 }
2937 Transition::Rule {
2938 target,
2939 rule_index,
2940 follow_state,
2941 ..
2942 } => {
2943 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
2944 return TransitionLookSet::default();
2945 };
2946 let child = rule_first_set(atn, *target, child_stop, cache);
2947 let mut symbols = child.symbols.clone();
2948 let nullable = if child.nullable {
2949 let follow = rule_first_set(atn, *follow_state, rule_stop_state, cache);
2950 symbols.extend_from(&follow.symbols);
2951 follow.nullable
2952 } else {
2953 false
2954 };
2955 TransitionLookSet { symbols, nullable }
2956 }
2957 }
2958}
2959
2960fn ll1_unique_alt(entry: &DecisionLookahead, symbol: i32) -> Option<usize> {
2981 let mut chosen: Option<usize> = None;
2982 for (index, transition) in entry.transitions.iter().enumerate() {
2983 if transition.nullable {
2984 return None;
2985 }
2986 if transition.symbols.contains(symbol) {
2987 if chosen.is_some() {
2988 return None;
2989 }
2990 chosen = Some(index);
2991 }
2992 }
2993 chosen
2994}
2995
2996fn ll1_greedy_alt(entry: &DecisionLookahead, symbol: i32, non_greedy: bool) -> Option<usize> {
3005 let mut matching_non_nullable_alt = None;
3006 let mut nullable_alt = None;
3007 for (index, transition) in entry.transitions.iter().enumerate() {
3008 if transition.nullable {
3009 if nullable_alt.is_some() {
3010 return None;
3011 }
3012 nullable_alt = Some(index);
3013 }
3014 if transition.symbols.contains(symbol) {
3015 if transition.nullable {
3016 continue;
3017 }
3018 if matching_non_nullable_alt.is_some() {
3019 return None;
3020 }
3021 matching_non_nullable_alt = Some(index);
3022 }
3023 }
3024 if matching_non_nullable_alt.is_some() && nullable_alt.is_some() {
3025 return None;
3026 }
3027 if non_greedy {
3028 nullable_alt.or(matching_non_nullable_alt)
3029 } else {
3030 matching_non_nullable_alt.or(nullable_alt)
3031 }
3032}
3033
3034fn should_skip_via_lookahead(
3035 transition_kind: ParserTransitionKind,
3036 transition_index: usize,
3037 lookahead_filter: Option<&(i32, Rc<DecisionLookahead>)>,
3038 index: usize,
3039 record_expected: bool,
3040 expected: &mut ExpectedTokens,
3041) -> bool {
3042 let prune_non_consuming = matches!(
3043 transition_kind,
3044 ParserTransitionKind::Epsilon
3045 | ParserTransitionKind::Action
3046 | ParserTransitionKind::Predicate
3047 | ParserTransitionKind::Rule
3048 | ParserTransitionKind::Precedence
3049 );
3050 if !prune_non_consuming {
3051 return false;
3052 }
3053 let Some((symbol, entry)) = lookahead_filter else {
3054 return false;
3055 };
3056 let Some(set) = entry.transitions.get(transition_index) else {
3057 return false;
3058 };
3059 if set.symbols.contains(*symbol) || set.nullable {
3060 return false;
3061 }
3062 if record_expected && !set.symbols.is_empty() {
3063 record_pruned_transition_expected(set, index, expected);
3064 }
3065 true
3066}
3067
3068fn should_skip_rule_via_first_set(
3069 first: &FirstSet,
3070 symbol: i32,
3071 record_expected: bool,
3072 index: usize,
3073 expected: &mut ExpectedTokens,
3074) -> bool {
3075 if first.nullable || first.symbols.contains(symbol) {
3076 return false;
3077 }
3078 if record_expected && !first.symbols.is_empty() {
3079 record_token_bit_expected(&first.symbols, index, expected);
3080 }
3081 true
3082}
3083
3084fn record_token_bit_expected(symbols: &TokenBitSet, index: usize, expected: &mut ExpectedTokens) {
3085 match expected.index {
3086 Some(current) if index < current => {}
3087 Some(current) if index == current => {
3088 symbols.extend_btree_set(&mut expected.symbols);
3089 }
3090 _ => {
3091 expected.index = Some(index);
3092 expected.symbols = symbols.to_btree_set();
3093 }
3094 }
3095}
3096
3097fn record_pruned_transition_expected(
3099 set: &TransitionLookSet,
3100 index: usize,
3101 expected: &mut ExpectedTokens,
3102) {
3103 match expected.index {
3104 Some(current) if index < current => {}
3105 Some(current) if index == current => {
3106 set.symbols.extend_btree_set(&mut expected.symbols);
3107 }
3108 _ => {
3109 expected.index = Some(index);
3110 expected.symbols = set.symbols.to_btree_set();
3111 }
3112 }
3113}
3114
3115fn rule_first_set_inner(
3116 atn: &Atn,
3117 state_number: usize,
3118 rule_stop_state: usize,
3119 ctx: &mut FirstSetCtx<'_>,
3120 visited: &mut BTreeSet<usize>,
3121 first: &mut FirstSet,
3122) {
3123 if !visited.insert(state_number) {
3124 return;
3125 }
3126 if state_number == rule_stop_state {
3127 first.nullable = true;
3128 return;
3129 }
3130 let Some(state) = atn.state(state_number) else {
3131 return;
3132 };
3133 for transition in &state.transitions() {
3134 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3135 if !transition_symbols.is_empty() {
3136 first.symbols.extend_iter(transition_symbols);
3137 continue;
3138 }
3139 match &transition.data() {
3140 Transition::Epsilon { target }
3141 | Transition::Action { target, .. }
3142 | Transition::Predicate { target, .. }
3143 | Transition::Precedence { target, .. } => {
3144 rule_first_set_inner(atn, *target, rule_stop_state, ctx, visited, first);
3145 }
3146 Transition::Rule {
3147 target,
3148 rule_index,
3149 follow_state,
3150 ..
3151 } => {
3152 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3153 continue;
3154 };
3155 let child_key = (*target, child_stop);
3156 if ctx.in_progress.contains(&child_key) && !ctx.cache.contains_key(&child_key) {
3157 ctx.hit_cycle = true;
3158 }
3159 let child = rule_first_set_cached(atn, *target, child_stop, ctx);
3160 first.symbols.extend_from(&child.symbols);
3161 if child.nullable {
3162 rule_first_set_inner(atn, *follow_state, rule_stop_state, ctx, visited, first);
3163 }
3164 }
3165 Transition::Atom { .. }
3166 | Transition::Range { .. }
3167 | Transition::Set { .. }
3168 | Transition::NotSet { .. }
3169 | Transition::Wildcard { .. } => {}
3170 }
3171 }
3172}
3173
3174fn state_sync_symbols(atn: &Atn, state_number: usize, stop_state: usize) -> BTreeSet<i32> {
3177 let mut symbols = BTreeSet::new();
3178 state_sync_symbols_inner(
3179 atn,
3180 state_number,
3181 stop_state,
3182 &mut BTreeSet::new(),
3183 &mut symbols,
3184 );
3185 symbols
3186}
3187
3188fn state_sync_symbols_inner(
3191 atn: &Atn,
3192 state_number: usize,
3193 stop_state: usize,
3194 visited: &mut BTreeSet<usize>,
3195 symbols: &mut BTreeSet<i32>,
3196) {
3197 if !visited.insert(state_number) {
3198 return;
3199 }
3200 if state_number == stop_state {
3201 symbols.insert(TOKEN_EOF);
3202 return;
3203 }
3204 let Some(state) = atn.state(state_number) else {
3205 return;
3206 };
3207 for transition in &state.transitions() {
3208 let transition_symbols = transition_expected_symbols(transition, atn.max_token_type());
3209 if transition_symbols.is_empty() {
3210 match &transition.data() {
3211 Transition::Rule { target, .. }
3212 | Transition::Epsilon { target }
3213 | Transition::Action { target, .. }
3214 | Transition::Predicate { target, .. }
3215 | Transition::Precedence { target, .. } => {
3216 state_sync_symbols_inner(atn, *target, stop_state, visited, symbols);
3217 }
3218 Transition::Atom { .. }
3219 | Transition::Range { .. }
3220 | Transition::Set { .. }
3221 | Transition::NotSet { .. }
3222 | Transition::Wildcard { .. } => {}
3223 }
3224 } else {
3225 symbols.extend(transition_symbols);
3226 }
3227 }
3228}
3229
3230#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
3231struct OperatorSymbolReachability {
3232 single_token: bool,
3234 multi_token: bool,
3236 predicate_dependent: bool,
3238}
3239
3240impl OperatorSymbolReachability {
3241 const ADAPTIVE_FALLBACK: Self = Self {
3242 single_token: false,
3243 multi_token: false,
3244 predicate_dependent: true,
3245 };
3246
3247 const fn single_token(predicate_dependent: bool) -> Self {
3248 if predicate_dependent {
3249 Self {
3250 single_token: false,
3251 multi_token: false,
3252 predicate_dependent: true,
3253 }
3254 } else {
3255 Self {
3256 single_token: true,
3257 multi_token: false,
3258 predicate_dependent: false,
3259 }
3260 }
3261 }
3262
3263 const fn multi_token(predicate_dependent: bool) -> Self {
3264 if predicate_dependent {
3265 Self {
3266 single_token: false,
3267 multi_token: false,
3268 predicate_dependent: true,
3269 }
3270 } else {
3271 Self {
3272 single_token: false,
3273 multi_token: true,
3274 predicate_dependent: false,
3275 }
3276 }
3277 }
3278
3279 const fn union(self, other: Self) -> Self {
3280 Self {
3281 single_token: self.single_token || other.single_token,
3282 multi_token: self.multi_token || other.multi_token,
3283 predicate_dependent: self.predicate_dependent || other.predicate_dependent,
3284 }
3285 }
3286}
3287
3288#[derive(Clone, Copy)]
3289struct OperatorReachabilityRequest {
3290 symbol: i32,
3291 precedence: i32,
3292 predicate_dependent: bool,
3293 operator_rule_index: usize,
3294}
3295
3296#[derive(Clone, Copy, Debug)]
3297struct OperatorRuleContinuation {
3298 stop_state: usize,
3299 follow_state: usize,
3300 return_precedence: i32,
3301}
3302
3303struct NullablePrecedenceCtx {
3304 cache: FxHashMap<(usize, usize, i32, bool), bool>,
3305 in_progress: BTreeSet<(usize, usize, i32, bool)>,
3306 hit_cycle: bool,
3307}
3308
3309fn state_is_nullable_with_precedence(
3310 atn: &Atn,
3311 state_number: usize,
3312 stop_state_number: usize,
3313 precedence: i32,
3314 allow_predicates: bool,
3315 ctx: &mut NullablePrecedenceCtx,
3316) -> bool {
3317 let saved_hit_cycle = ctx.hit_cycle;
3318 ctx.hit_cycle = false;
3319 let nullable = state_is_nullable_with_precedence_cached(
3320 atn,
3321 state_number,
3322 stop_state_number,
3323 precedence,
3324 allow_predicates,
3325 ctx,
3326 );
3327 ctx.hit_cycle = saved_hit_cycle;
3328 nullable
3329}
3330
3331fn state_is_nullable_with_precedence_cached(
3332 atn: &Atn,
3333 state_number: usize,
3334 stop_state_number: usize,
3335 precedence: i32,
3336 allow_predicates: bool,
3337 ctx: &mut NullablePrecedenceCtx,
3338) -> bool {
3339 if state_number == stop_state_number {
3340 return true;
3341 }
3342 let key = (
3343 state_number,
3344 stop_state_number,
3345 precedence,
3346 allow_predicates,
3347 );
3348 if let Some(cached) = ctx.cache.get(&key) {
3349 return *cached;
3350 }
3351 if !ctx.in_progress.insert(key) {
3352 ctx.hit_cycle = true;
3353 return false;
3354 }
3355 let saved_hit_cycle = ctx.hit_cycle;
3356 ctx.hit_cycle = false;
3357 let nullable = atn.state(state_number).is_some_and(|state| {
3358 state
3359 .transitions()
3360 .iter()
3361 .any(|transition| match &transition.data() {
3362 Transition::Rule {
3363 target,
3364 rule_index,
3365 follow_state,
3366 precedence: rule_precedence,
3367 } => {
3368 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3369 return false;
3370 };
3371 state_is_nullable_with_precedence_cached(
3372 atn,
3373 *target,
3374 child_stop,
3375 *rule_precedence,
3376 allow_predicates,
3377 ctx,
3378 ) && state_is_nullable_with_precedence_cached(
3379 atn,
3380 *follow_state,
3381 stop_state_number,
3382 precedence,
3383 allow_predicates,
3384 ctx,
3385 )
3386 }
3387 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3388 state_is_nullable_with_precedence_cached(
3389 atn,
3390 *target,
3391 stop_state_number,
3392 precedence,
3393 allow_predicates,
3394 ctx,
3395 )
3396 }
3397 Transition::Predicate { target, .. } if allow_predicates => {
3398 state_is_nullable_with_precedence_cached(
3399 atn,
3400 *target,
3401 stop_state_number,
3402 precedence,
3403 allow_predicates,
3404 ctx,
3405 )
3406 }
3407 Transition::Precedence {
3408 target,
3409 precedence: transition_precedence,
3410 } if *transition_precedence >= precedence => {
3411 state_is_nullable_with_precedence_cached(
3412 atn,
3413 *target,
3414 stop_state_number,
3415 precedence,
3416 allow_predicates,
3417 ctx,
3418 )
3419 }
3420 Transition::Atom { .. }
3421 | Transition::Range { .. }
3422 | Transition::Set { .. }
3423 | Transition::NotSet { .. }
3424 | Transition::Wildcard { .. }
3425 | Transition::Predicate { .. }
3426 | Transition::Precedence { .. } => false,
3427 })
3428 });
3429 ctx.in_progress.remove(&key);
3430 if !ctx.hit_cycle {
3431 ctx.cache.insert(key, nullable);
3432 }
3433 ctx.hit_cycle = saved_hit_cycle || ctx.hit_cycle;
3434 nullable
3435}
3436
3437fn state_operator_token_prefix_reachability(
3439 atn: &Atn,
3440 state_number: usize,
3441 request: OperatorReachabilityRequest,
3442 continuations: &[OperatorRuleContinuation],
3443 visited: &mut BTreeSet<(usize, i32, bool)>,
3444) -> OperatorSymbolReachability {
3445 let key = (
3446 state_number,
3447 request.precedence,
3448 request.predicate_dependent,
3449 );
3450 if !visited.insert(key) {
3451 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3455 }
3456 if let Some((continuation, remaining)) = continuations.split_last()
3457 && state_number == continuation.stop_state
3458 {
3459 let result = state_operator_token_prefix_reachability(
3460 atn,
3461 continuation.follow_state,
3462 OperatorReachabilityRequest {
3463 precedence: continuation.return_precedence,
3464 ..request
3465 },
3466 remaining,
3467 visited,
3468 );
3469 visited.remove(&key);
3470 return result;
3471 }
3472 let Some(state) = atn.state(state_number) else {
3473 visited.remove(&key);
3474 return OperatorSymbolReachability::default();
3475 };
3476 let completes_operator = match state.kind() {
3477 AtnStateKind::RuleStop => continuations.is_empty(),
3478 AtnStateKind::StarLoopBack
3479 | AtnStateKind::StarLoopEntry
3480 | AtnStateKind::PlusLoopBack
3481 | AtnStateKind::LoopEnd => state.rule_index() == Some(request.operator_rule_index),
3482 _ => false,
3483 };
3484 if completes_operator {
3485 visited.remove(&key);
3486 return OperatorSymbolReachability::single_token(request.predicate_dependent);
3487 }
3488 let mut reachability = OperatorSymbolReachability::default();
3489 for transition in &state.transitions() {
3490 let transition_reachability = match &transition.data() {
3491 Transition::Rule { rule_index, .. } if *rule_index == request.operator_rule_index => {
3492 OperatorSymbolReachability::single_token(request.predicate_dependent)
3493 }
3494 Transition::Rule {
3495 target,
3496 rule_index,
3497 follow_state,
3498 precedence: rule_precedence,
3499 } => {
3500 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3501 continue;
3502 };
3503 let mut nested = continuations.to_vec();
3504 nested.push(OperatorRuleContinuation {
3505 stop_state: child_stop,
3506 follow_state: *follow_state,
3507 return_precedence: request.precedence,
3508 });
3509 state_operator_token_prefix_reachability(
3510 atn,
3511 *target,
3512 OperatorReachabilityRequest {
3513 precedence: *rule_precedence,
3514 ..request
3515 },
3516 &nested,
3517 visited,
3518 )
3519 }
3520 Transition::Epsilon { target } | Transition::Action { target, .. } => {
3521 state_operator_token_prefix_reachability(
3522 atn,
3523 *target,
3524 request,
3525 continuations,
3526 visited,
3527 )
3528 }
3529 Transition::Precedence {
3530 target,
3531 precedence: transition_precedence,
3532 } => {
3533 if *transition_precedence < request.precedence {
3534 OperatorSymbolReachability::default()
3535 } else {
3536 state_operator_token_prefix_reachability(
3537 atn,
3538 *target,
3539 request,
3540 continuations,
3541 visited,
3542 )
3543 }
3544 }
3545 Transition::Predicate { target, .. } => state_operator_token_prefix_reachability(
3546 atn,
3547 *target,
3548 OperatorReachabilityRequest {
3549 predicate_dependent: true,
3550 ..request
3551 },
3552 continuations,
3553 visited,
3554 ),
3555 Transition::Atom { .. }
3556 | Transition::Range { .. }
3557 | Transition::Set { .. }
3558 | Transition::NotSet { .. }
3559 | Transition::Wildcard { .. } => {
3560 OperatorSymbolReachability::multi_token(request.predicate_dependent)
3561 }
3562 };
3563 reachability = reachability.union(transition_reachability);
3564 }
3565 visited.remove(&key);
3566 reachability
3567}
3568
3569fn state_can_reach_symbol_with_precedence(
3570 atn: &Atn,
3571 state_number: usize,
3572 request: OperatorReachabilityRequest,
3573 nullable_ctx: &mut NullablePrecedenceCtx,
3574 continuations: &mut Vec<OperatorRuleContinuation>,
3575 visited: &mut BTreeSet<(usize, i32, bool)>,
3576) -> OperatorSymbolReachability {
3577 let key = (
3578 state_number,
3579 request.precedence,
3580 request.predicate_dependent,
3581 );
3582 if !visited.insert(key) {
3583 return OperatorSymbolReachability::ADAPTIVE_FALLBACK;
3584 }
3585 let Some(state) = atn.state(state_number) else {
3586 visited.remove(&key);
3587 return OperatorSymbolReachability::default();
3588 };
3589 let mut reachability = OperatorSymbolReachability::default();
3590 for transition in &state.transitions() {
3591 if transition.matches(request.symbol, 1, atn.max_token_type()) {
3592 reachability = reachability.union(state_operator_token_prefix_reachability(
3593 atn,
3594 transition.target(),
3595 request,
3596 continuations,
3597 &mut BTreeSet::new(),
3598 ));
3599 continue;
3600 }
3601 let transition_reachability = match &transition.data() {
3602 Transition::Rule {
3603 target,
3604 rule_index,
3605 follow_state,
3606 precedence: rule_precedence,
3607 } => {
3608 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3609 continue;
3610 };
3611 continuations.push(OperatorRuleContinuation {
3612 stop_state: child_stop,
3613 follow_state: *follow_state,
3614 return_precedence: request.precedence,
3615 });
3616 let mut result = state_can_reach_symbol_with_precedence(
3617 atn,
3618 *target,
3619 OperatorReachabilityRequest {
3620 precedence: *rule_precedence,
3621 ..request
3622 },
3623 nullable_ctx,
3624 continuations,
3625 visited,
3626 );
3627 continuations.pop();
3628 if state_is_nullable_with_precedence(
3629 atn,
3630 *target,
3631 child_stop,
3632 *rule_precedence,
3633 true,
3634 nullable_ctx,
3635 ) {
3636 let child_predicate_dependent = request.predicate_dependent
3637 || !state_is_nullable_with_precedence(
3638 atn,
3639 *target,
3640 child_stop,
3641 *rule_precedence,
3642 false,
3643 nullable_ctx,
3644 );
3645 result = result.union(state_can_reach_symbol_with_precedence(
3646 atn,
3647 *follow_state,
3648 OperatorReachabilityRequest {
3649 predicate_dependent: child_predicate_dependent,
3650 ..request
3651 },
3652 nullable_ctx,
3653 continuations,
3654 visited,
3655 ));
3656 }
3657 result
3658 }
3659 Transition::Epsilon { target }
3660 | Transition::Action { target, .. }
3661 | Transition::Precedence { target, .. } => {
3662 if matches!(
3663 &transition.data(),
3664 Transition::Precedence {
3665 precedence: transition_precedence,
3666 ..
3667 } if *transition_precedence < request.precedence
3668 ) {
3669 continue;
3670 }
3671 state_can_reach_symbol_with_precedence(
3672 atn,
3673 *target,
3674 request,
3675 nullable_ctx,
3676 continuations,
3677 visited,
3678 )
3679 }
3680 Transition::Predicate { target, .. } => state_can_reach_symbol_with_precedence(
3681 atn,
3682 *target,
3683 OperatorReachabilityRequest {
3684 predicate_dependent: true,
3685 ..request
3686 },
3687 nullable_ctx,
3688 continuations,
3689 visited,
3690 ),
3691 Transition::Atom { .. }
3692 | Transition::Range { .. }
3693 | Transition::Set { .. }
3694 | Transition::NotSet { .. }
3695 | Transition::Wildcard { .. } => OperatorSymbolReachability::default(),
3696 };
3697 reachability = reachability.union(transition_reachability);
3698 }
3699 visited.remove(&key);
3700 reachability
3701}
3702
3703fn left_recursive_operator_lookahead(
3704 atn: &Atn,
3705 state_number: usize,
3706 precedence: i32,
3707) -> LeftRecursiveOperatorLookahead {
3708 let Some(state) = atn.state(state_number) else {
3709 return LeftRecursiveOperatorLookahead::default();
3710 };
3711 let Some(operator_rule_index) = state.rule_index() else {
3712 return LeftRecursiveOperatorLookahead::default();
3713 };
3714 let mut lookahead = LeftRecursiveOperatorLookahead::default();
3715 let mut nullable_ctx = NullablePrecedenceCtx {
3716 cache: FxHashMap::default(),
3717 in_progress: BTreeSet::new(),
3718 hit_cycle: false,
3719 };
3720 for transition in &state.transitions() {
3721 let target = transition.target();
3722 if atn
3723 .state(target)
3724 .is_some_and(|state| state.kind() == AtnStateKind::LoopEnd)
3725 {
3726 continue;
3727 }
3728 for symbol in 1..=atn.max_token_type() {
3729 let reachability = state_can_reach_symbol_with_precedence(
3730 atn,
3731 target,
3732 OperatorReachabilityRequest {
3733 symbol,
3734 precedence,
3735 predicate_dependent: false,
3736 operator_rule_index,
3737 },
3738 &mut nullable_ctx,
3739 &mut Vec::new(),
3740 &mut BTreeSet::new(),
3741 );
3742 if reachability.single_token {
3743 lookahead.single_token.insert(symbol);
3744 }
3745 if reachability.multi_token {
3746 lookahead.multi_token_prefix.insert(symbol);
3747 }
3748 if reachability.predicate_dependent {
3749 lookahead.predicate_dependent.insert(symbol);
3750 }
3751 }
3752 }
3753 lookahead
3754}
3755
3756#[derive(Debug, Default)]
3757struct StateBeforeStopLookahead {
3758 symbols: TokenBitSet,
3759 reaches_context_boundary: bool,
3760}
3761
3762fn state_before_stop_lookahead(
3763 atn: &Atn,
3764 state_number: usize,
3765 stop_state_number: usize,
3766) -> Rc<StateBeforeStopLookahead> {
3767 with_shared_atn_caches(atn, |cache| {
3768 let key = (state_number, stop_state_number);
3769 if let Some(cached) = cache.state_before_stop_lookahead.get(&key) {
3770 return Rc::clone(cached);
3771 }
3772 let mut lookahead = StateBeforeStopLookahead::default();
3773 state_before_stop_lookahead_inner(
3774 atn,
3775 state_number,
3776 stop_state_number,
3777 &mut BTreeSet::new(),
3778 &mut cache.first_set,
3779 &mut lookahead,
3780 );
3781 let lookahead = Rc::new(lookahead);
3782 cache
3783 .state_before_stop_lookahead
3784 .insert(key, Rc::clone(&lookahead));
3785 lookahead
3786 })
3787}
3788
3789fn state_before_stop_lookahead_inner(
3790 atn: &Atn,
3791 state_number: usize,
3792 stop_state_number: usize,
3793 visited: &mut BTreeSet<usize>,
3794 first_set_cache: &mut FirstSetCache,
3795 lookahead: &mut StateBeforeStopLookahead,
3796) {
3797 if state_number == stop_state_number {
3798 lookahead.reaches_context_boundary = true;
3799 return;
3800 }
3801 if !visited.insert(state_number) {
3802 return;
3803 }
3804 let Some(state) = atn.state(state_number) else {
3805 return;
3806 };
3807 if state.kind() == AtnStateKind::RuleStop {
3808 lookahead.reaches_context_boundary = true;
3809 return;
3810 }
3811 for transition in &state.transitions() {
3812 match &transition.data() {
3813 Transition::Epsilon { target }
3814 | Transition::Action { target, .. }
3815 | Transition::Predicate { target, .. }
3816 | Transition::Precedence { target, .. } => {
3817 state_before_stop_lookahead_inner(
3818 atn,
3819 *target,
3820 stop_state_number,
3821 visited,
3822 first_set_cache,
3823 lookahead,
3824 );
3825 }
3826 Transition::Rule {
3827 target,
3828 rule_index,
3829 follow_state,
3830 ..
3831 } => {
3832 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
3833 continue;
3834 };
3835 let child = rule_first_set(atn, *target, child_stop, first_set_cache);
3836 lookahead.symbols.extend_from(&child.symbols);
3837 if child.nullable {
3838 state_before_stop_lookahead_inner(
3839 atn,
3840 *follow_state,
3841 stop_state_number,
3842 visited,
3843 first_set_cache,
3844 lookahead,
3845 );
3846 }
3847 }
3848 Transition::Atom { .. }
3849 | Transition::Range { .. }
3850 | Transition::Set { .. }
3851 | Transition::NotSet { .. }
3852 | Transition::Wildcard { .. } => {
3853 lookahead.symbols.extend_iter(transition_expected_symbols(
3854 transition,
3855 atn.max_token_type(),
3856 ));
3857 }
3858 }
3859 }
3860}
3861
3862fn caller_context_can_match_symbol_before_state(
3863 atn: &Atn,
3864 return_states: impl DoubleEndedIterator<Item = usize>,
3865 stop_state_number: usize,
3866 symbol: i32,
3867) -> bool {
3868 for return_state in return_states.rev() {
3869 let lookahead = state_before_stop_lookahead(atn, return_state, stop_state_number);
3870 if lookahead.symbols.contains(symbol) {
3871 return true;
3872 }
3873 if !lookahead.reaches_context_boundary {
3874 return false;
3875 }
3876 }
3877 false
3878}
3879
3880fn next_recovery_context(
3884 atn: &Atn,
3885 state: AtnState<'_>,
3886 inherited: &BTreeSet<i32>,
3887 inherited_state: Option<usize>,
3888) -> (BTreeSet<i32>, Option<usize>) {
3889 let state_symbols = state_expected_symbols(atn, state.state_number());
3890 if state.transitions().len() > 1 && !state_symbols.is_empty() {
3891 let mut symbols = state_symbols;
3892 symbols.extend(inherited.iter().copied());
3893 return (symbols, Some(state.state_number()));
3894 }
3895 (inherited.clone(), inherited_state)
3896}
3897
3898fn recovery_expected_symbols(
3899 atn: &Atn,
3900 state_number: usize,
3901 inherited: &BTreeSet<i32>,
3902) -> BTreeSet<i32> {
3903 let mut symbols = state_expected_symbols(atn, state_number);
3904 symbols.extend(inherited.iter().copied());
3905 symbols
3906}
3907
3908fn fast_next_recovery_context<S, H>(
3912 parser: &mut BaseParser<S, H>,
3913 atn: &Atn,
3914 state: AtnState<'_>,
3915 inherited: &Rc<BTreeSet<i32>>,
3916 inherited_state: Option<usize>,
3917) -> (Rc<BTreeSet<i32>>, Option<usize>)
3918where
3919 S: TokenSource,
3920 H: SemanticHooks,
3921{
3922 if state.transitions().len() <= 1 {
3923 return (Rc::clone(inherited), inherited_state);
3924 }
3925 let state_symbols = parser.cached_state_expected_symbols(atn, state.state_number());
3926 if state_symbols.is_empty() {
3927 return (Rc::clone(inherited), inherited_state);
3928 }
3929 if inherited.is_empty() {
3930 return (state_symbols, Some(state.state_number()));
3931 }
3932 if Rc::ptr_eq(&state_symbols, inherited) {
3933 return (state_symbols, Some(state.state_number()));
3934 }
3935 let mut combined = (*state_symbols).clone();
3936 combined.extend(inherited.iter().copied());
3937 (
3938 parser.intern_recovery_symbols(combined),
3939 Some(state.state_number()),
3940 )
3941}
3942
3943fn fast_recovery_expected_symbols<S, H>(
3947 parser: &mut BaseParser<S, H>,
3948 atn: &Atn,
3949 state_number: usize,
3950 inherited: &Rc<BTreeSet<i32>>,
3951) -> Rc<BTreeSet<i32>>
3952where
3953 S: TokenSource,
3954 H: SemanticHooks,
3955{
3956 let cached = parser.cached_state_expected_symbols(atn, state_number);
3957 if inherited.is_empty() {
3958 return cached;
3959 }
3960 if cached.is_empty() {
3961 return Rc::clone(inherited);
3962 }
3963 if Rc::ptr_eq(&cached, inherited) {
3964 return cached;
3965 }
3966 let mut combined = (*cached).clone();
3967 combined.extend(inherited.iter().copied());
3968 parser.intern_recovery_symbols(combined)
3969}
3970
3971struct ParserTableSemCtx<'a> {
3972 member_values: &'a mut MemberEnv,
3973 return_values: &'a mut BTreeMap<String, i64>,
3974}
3975
3976impl semir::PredContext for ParserTableSemCtx<'_> {
3977 type TokenText<'a>
3978 = &'a str
3979 where
3980 Self: 'a;
3981
3982 fn la(&mut self, _offset: isize) -> i64 {
3983 i64::from(TOKEN_EOF)
3984 }
3985
3986 fn token_text(&mut self, _offset: isize) -> Option<Self::TokenText<'_>> {
3987 None
3988 }
3989
3990 fn token_index_adjacent(&mut self) -> bool {
3991 false
3992 }
3993
3994 fn ctx_rule_text(&self, _rule_index: usize) -> Option<String> {
3995 None
3996 }
3997
3998 fn member(&self, member: usize) -> Option<i64> {
3999 Some(self.member_values.scalar(member).unwrap_or_default())
4000 }
4001
4002 fn member_top(&self, member: usize) -> Option<i64> {
4003 self.member_values.stack_top(member)
4004 }
4005
4006 fn member_len(&self, member: usize) -> usize {
4007 self.member_values.stack_len(member)
4008 }
4009
4010 fn local_arg(&self) -> Option<i64> {
4011 None
4012 }
4013
4014 fn column(&self) -> Option<i64> {
4015 None
4016 }
4017
4018 fn token_start_column(&self) -> Option<i64> {
4019 None
4020 }
4021
4022 fn token_text_so_far(&self) -> Option<String> {
4023 None
4024 }
4025
4026 fn hook(&mut self, _hook: HookId) -> bool {
4027 false
4028 }
4029}
4030
4031impl semir::ActContext for ParserTableSemCtx<'_> {
4032 fn set_member(&mut self, member: usize, value: i64) {
4033 self.member_values.set_scalar(member, value);
4034 }
4035
4036 fn push_member(&mut self, member: usize, value: i64) {
4037 self.member_values.push_stack(member, value);
4038 }
4039
4040 fn pop_member(&mut self, member: usize) -> Option<i64> {
4041 self.member_values.pop_stack(member)
4042 }
4043
4044 fn set_return(&mut self, name: &str, value: i64) {
4045 self.return_values.insert(name.to_owned(), value);
4046 }
4047
4048 fn action_hook(&mut self, _hook: HookId) {}
4049}
4050
4051fn apply_member_actions(
4053 source_state: usize,
4054 actions: &[ParserMemberAction],
4055 semantics: Option<&ParserSemantics>,
4056 values: &mut MemberEnv,
4057) {
4058 for action in actions
4059 .iter()
4060 .filter(|action| action.source_state == source_state)
4061 {
4062 values.add_scalar(action.member, action.delta);
4063 }
4064 let Some(semantics) = semantics else {
4065 return;
4066 };
4067 let mut return_values = BTreeMap::new();
4068 let mut ctx = ParserTableSemCtx {
4069 member_values: values,
4070 return_values: &mut return_values,
4071 };
4072 for action in semantics
4073 .actions
4074 .iter()
4075 .filter(|action| action.source_state == source_state && action.speculative)
4076 {
4077 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
4078 }
4079}
4080
4081fn member_values_after_action(
4083 source_state: usize,
4084 actions: &[ParserMemberAction],
4085 semantics: Option<&ParserSemantics>,
4086 values: &MemberEnv,
4087) -> MemberEnv {
4088 let mut values = values.clone();
4089 apply_member_actions(source_state, actions, semantics, &mut values);
4090 values
4091}
4092
4093fn return_values_after_action(
4095 source_state: usize,
4096 rule_index: usize,
4097 actions: &[ParserReturnAction],
4098 semantics: Option<&ParserSemantics>,
4099 values: &BTreeMap<String, i64>,
4100) -> BTreeMap<String, i64> {
4101 let mut values = values.clone();
4102 for action in actions
4103 .iter()
4104 .filter(|action| action.source_state == source_state && action.rule_index == rule_index)
4105 {
4106 values.insert(action.name.to_owned(), action.value);
4107 }
4108 if let Some(semantics) = semantics {
4109 let mut member_values = MemberEnv::new();
4110 let mut ctx = ParserTableSemCtx {
4111 member_values: &mut member_values,
4112 return_values: &mut values,
4113 };
4114 for action in semantics.actions.iter().filter(|action| {
4115 action.source_state == source_state
4116 && action.rule_index == rule_index
4117 && !action.speculative
4118 }) {
4119 semir::exec_stmt(&semantics.ir, action.stmt, &mut ctx);
4120 }
4121 }
4122 values
4123}
4124
4125fn rule_local_int_arg(
4127 rule_args: &[ParserRuleArg],
4128 source_state: usize,
4129 rule_index: usize,
4130 local_int_arg: Option<(usize, i64)>,
4131) -> Option<(usize, i64)> {
4132 rule_args
4133 .iter()
4134 .find(|arg| arg.source_state == source_state && arg.rule_index == rule_index)
4135 .map(|arg| {
4136 let value = if arg.inherit_local {
4137 local_int_arg.map_or(arg.value, |(_, value)| value)
4138 } else {
4139 arg.value
4140 };
4141 (rule_index, value)
4142 })
4143}
4144
4145fn stop_outcome(
4148 index: usize,
4149 consumed_eof: bool,
4150 rule_alt_number: usize,
4151 member_values: MemberEnv,
4152 return_values: BTreeMap<String, i64>,
4153) -> Vec<RecognizeOutcome> {
4154 vec![RecognizeOutcome {
4155 index,
4156 consumed_eof,
4157 alt_number: rule_alt_number,
4158 member_values,
4159 return_values,
4160 diagnostics: DiagnosticSeqId::EMPTY,
4161 decisions: Vec::new(),
4162 actions: Vec::new(),
4163 nodes: NodeSeqId::EMPTY,
4164 }]
4165}
4166
4167fn atn_has_observable_action_transitions(atn: &Atn) -> bool {
4168 with_shared_atn_caches(atn, |cache| {
4169 *cache.observable_action_transitions.get_or_insert_with(|| {
4170 atn.states().any(|state| {
4171 state.transitions().iter().any(|transition| {
4172 matches!(
4173 &transition.data(),
4174 Transition::Action {
4175 action_index: Some(_),
4176 ..
4177 }
4178 )
4179 })
4180 })
4181 })
4182 })
4183}
4184
4185fn atn_has_predicate_transitions(atn: &Atn) -> bool {
4186 with_shared_atn_caches(atn, |cache| {
4187 *cache.predicate_transitions.get_or_insert_with(|| {
4188 atn.states().any(|state| {
4189 state
4190 .transitions()
4191 .iter()
4192 .any(|transition| matches!(&transition.data(), Transition::Predicate { .. }))
4193 })
4194 })
4195 })
4196}
4197
4198fn can_use_fast_predicate_recognizer(atn: &Atn, options: &ParserRuntimeOptions<'_>) -> bool {
4203 options.init_action_rules.is_empty()
4204 && !options.track_alt_numbers
4205 && options
4206 .predicates
4207 .iter()
4208 .all(|(_, _, predicate)| predicate.failure_message().is_none())
4209 && options.semantics.is_none_or(|semantics| {
4210 semantics.actions.is_empty()
4211 && semantics
4212 .predicates
4213 .iter()
4214 .all(|predicate| predicate.failure_message.is_none())
4215 })
4216 && options.rule_args.is_empty()
4217 && options.member_actions.is_empty()
4218 && options.return_actions.is_empty()
4219 && !atn_has_observable_action_transitions(atn)
4220}
4221
4222#[derive(Clone, Debug, Eq, PartialEq)]
4223struct RecognizeRequest<'a> {
4224 state_number: usize,
4225 stop_state: usize,
4226 index: usize,
4227 rule_start_index: usize,
4228 decision_start_index: Option<usize>,
4229 init_action_rules: &'a BTreeSet<usize>,
4230 predicates: &'a [(usize, usize, ParserPredicate)],
4231 semantics: Option<&'a ParserSemantics>,
4232 rule_args: &'a [ParserRuleArg],
4233 member_actions: &'a [ParserMemberAction],
4234 return_actions: &'a [ParserReturnAction],
4235 local_int_arg: Option<(usize, i64)>,
4236 member_values: MemberEnv,
4237 return_values: BTreeMap<String, i64>,
4238 rule_alt_number: usize,
4239 track_alt_numbers: bool,
4240 consumed_eof: bool,
4241 committed_decision: bool,
4242 precedence: i32,
4245 depth: usize,
4246 recovery_symbols: BTreeSet<i32>,
4247 recovery_state: Option<usize>,
4248}
4249
4250#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
4251struct RecognizeKey {
4252 state_number: usize,
4253 stop_state: usize,
4254 index: usize,
4255 rule_start_index: usize,
4256 decision_start_index: Option<usize>,
4257 local_int_arg: Option<(usize, i64)>,
4258 member_values: MemberEnv,
4259 return_values: BTreeMap<String, i64>,
4260 rule_alt_number: usize,
4261 track_alt_numbers: bool,
4262 consumed_eof: bool,
4263 committed_decision: bool,
4264 precedence: i32,
4265 recovery_symbols: BTreeSet<i32>,
4266 recovery_state: Option<usize>,
4267}
4268
4269#[derive(Clone, Debug, Eq, PartialEq)]
4270struct EpsilonActionStep {
4271 source_state: usize,
4272 target: usize,
4273 action_rule_index: Option<usize>,
4274 left_recursive_boundary: Option<usize>,
4275 decision: Option<usize>,
4276 decision_start_index: Option<usize>,
4277 alt_number: usize,
4278 recovery_symbols: BTreeSet<i32>,
4279 recovery_state: Option<usize>,
4280}
4281
4282struct RecognizeScratch<'a> {
4283 visiting: &'a mut BTreeSet<RecognizeKey>,
4284 memo: &'a mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4285 expected: &'a mut ExpectedTokens,
4286}
4287
4288#[derive(Clone, Debug, Eq, PartialEq)]
4289struct FastRecognizeRequest {
4290 state_number: usize,
4291 stop_state: usize,
4292 index: usize,
4293 rule_start_index: usize,
4294 decision_start_index: Option<usize>,
4295 precedence: i32,
4296 depth: usize,
4297 recovery_symbols: Rc<BTreeSet<i32>>,
4298 recovery_state: Option<usize>,
4299}
4300
4301#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4302struct FastRecognizeTopRequest {
4303 start_state: usize,
4304 stop_state: usize,
4305 start_index: usize,
4306 precedence: i32,
4307 caller_follow_state: Option<usize>,
4308}
4309
4310#[derive(Clone, Copy, Debug)]
4311struct FastPredicateContext<'a> {
4312 predicates: &'a [(usize, usize, ParserPredicate)],
4313 semantics: Option<&'a ParserSemantics>,
4314 member_values: &'a MemberEnv,
4315}
4316
4317#[derive(Clone, Copy, Debug, Default)]
4318struct AltNumberTracking {
4319 public: bool,
4320 context: bool,
4321}
4322
4323impl AltNumberTracking {
4324 const fn any(self) -> bool {
4325 self.public || self.context
4326 }
4327}
4328
4329struct FastRecognizeScratch<'a, 'b> {
4330 predicate_context: Option<FastPredicateContext<'a>>,
4331 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4332 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4333 expected: &'b mut ExpectedTokens,
4334 native_depth: usize,
4335}
4336
4337#[derive(Clone, Copy, Debug)]
4338struct FastRepetitionShape {
4339 enter_target: usize,
4340 exit_target: usize,
4341 body_stop_state: usize,
4342 enter_transition_index: usize,
4343 exit_transition_index: usize,
4344}
4345
4346#[derive(Clone, Copy, Debug)]
4347struct FastRepetitionPath {
4348 index: usize,
4349 deferred_nodes: FastDeferredNodeId,
4350 diagnostics: DiagnosticSeqId,
4351 consumed_eof: bool,
4352}
4353
4354enum FastRepetitionWork {
4355 Enter(FastRepetitionPath),
4356 Exit(FastRepetitionPath),
4357}
4358
4359struct FastRepetitionCoordinates {
4364 base_index: usize,
4365 base_state: u8,
4366 later_states: Vec<u8>,
4367}
4368
4369impl FastRepetitionCoordinates {
4370 const ENTERED: u8 = 0;
4371 const EXITED: u8 = 2;
4372
4373 const fn new(base_index: usize) -> Self {
4374 Self {
4375 base_index,
4376 base_state: 0,
4377 later_states: Vec::new(),
4378 }
4379 }
4380
4381 fn insert_entered(&mut self, path: FastRepetitionPath) -> bool {
4382 self.insert(path.index, path.consumed_eof, Self::ENTERED)
4383 }
4384
4385 fn insert_exited(&mut self, path: FastRepetitionPath) -> bool {
4386 self.insert(path.index, path.consumed_eof, Self::EXITED)
4387 }
4388
4389 fn insert(&mut self, index: usize, consumed_eof: bool, base_bit: u8) -> bool {
4390 let Some(offset) = index.checked_sub(self.base_index) else {
4391 return false;
4392 };
4393 let state = if offset == 0 {
4394 &mut self.base_state
4395 } else {
4396 if self.later_states.len() < offset {
4397 self.later_states.resize(offset, 0);
4398 }
4399 &mut self.later_states[offset - 1]
4400 };
4401 let bit = 1 << (base_bit + u8::from(consumed_eof));
4402 let is_new = *state & bit == 0;
4403 *state |= bit;
4404 is_new
4405 }
4406}
4407
4408fn fast_repetition_shape(atn: &Atn, state: AtnState<'_>) -> Option<FastRepetitionShape> {
4409 if state.precedence_rule_decision()
4410 || !matches!(
4411 state.kind(),
4412 AtnStateKind::StarLoopEntry | AtnStateKind::PlusLoopBack
4413 )
4414 || state.transitions().len() != 2
4415 {
4416 return None;
4417 }
4418 let mut enter = None;
4419 let mut exit = None;
4420 for (index, transition) in state.transitions().iter().enumerate() {
4421 if transition.kind() != ParserTransitionKind::Epsilon {
4422 return None;
4423 }
4424 let target = transition.target();
4425 if atn
4426 .state(target)
4427 .is_some_and(|target_state| target_state.kind() == AtnStateKind::LoopEnd)
4428 {
4429 if exit.replace((index, target)).is_some() {
4430 return None;
4431 }
4432 } else if enter.replace((index, target)).is_some() {
4433 return None;
4434 }
4435 }
4436 let (enter_transition_index, enter_target) = enter?;
4437 let (exit_transition_index, exit_target) = exit?;
4438 let body_stop_state = if state.kind() == AtnStateKind::StarLoopEntry {
4439 atn.state(exit_target)?.loop_back_state()?
4440 } else {
4441 state.state_number()
4442 };
4443 Some(FastRepetitionShape {
4444 enter_target,
4445 exit_target,
4446 body_stop_state,
4447 enter_transition_index,
4448 exit_transition_index,
4449 })
4450}
4451
4452fn push_fast_repetition_work(
4453 work: &mut Vec<FastRepetitionWork>,
4454 shape: FastRepetitionShape,
4455 path: FastRepetitionPath,
4456 lookahead: Option<&DecisionLookahead>,
4457 symbol: i32,
4458) {
4459 let transition_is_viable = |transition_index: usize| {
4462 let Some(entry) = lookahead else {
4463 return true;
4464 };
4465 let Some(transition) = entry.transitions.get(transition_index) else {
4466 return true;
4467 };
4468 transition.nullable || transition.symbols.contains(symbol)
4469 };
4470 let enter_is_viable = transition_is_viable(shape.enter_transition_index);
4471 let exit_is_viable = transition_is_viable(shape.exit_transition_index);
4472 if shape.enter_transition_index < shape.exit_transition_index {
4473 if exit_is_viable {
4474 work.push(FastRepetitionWork::Exit(path));
4475 }
4476 if enter_is_viable {
4477 work.push(FastRepetitionWork::Enter(path));
4478 }
4479 } else {
4480 if enter_is_viable {
4481 work.push(FastRepetitionWork::Enter(path));
4482 }
4483 if exit_is_viable {
4484 work.push(FastRepetitionWork::Exit(path));
4485 }
4486 }
4487}
4488
4489#[derive(Clone, Debug)]
4496struct FastRecognizeKey {
4497 state_number: usize,
4498 stop_state: usize,
4499 index: usize,
4500 rule_start_index: usize,
4501 decision_start_index: Option<usize>,
4502 precedence: i32,
4503 recovery_symbols_id: usize,
4504 recovery_state: Option<usize>,
4505}
4506
4507impl PartialEq for FastRecognizeKey {
4508 fn eq(&self, other: &Self) -> bool {
4509 if self.state_number != other.state_number
4510 || self.stop_state != other.stop_state
4511 || self.index != other.index
4512 || self.rule_start_index != other.rule_start_index
4513 || self.decision_start_index != other.decision_start_index
4514 || self.precedence != other.precedence
4515 || self.recovery_state != other.recovery_state
4516 || self.recovery_symbols_id != other.recovery_symbols_id
4517 {
4518 return false;
4519 }
4520 true
4521 }
4522}
4523
4524impl Eq for FastRecognizeKey {}
4525
4526impl Hash for FastRecognizeKey {
4527 fn hash<H: Hasher>(&self, hasher: &mut H) {
4528 self.state_number.hash(hasher);
4529 self.stop_state.hash(hasher);
4530 self.index.hash(hasher);
4531 self.rule_start_index.hash(hasher);
4532 self.decision_start_index.hash(hasher);
4533 self.precedence.hash(hasher);
4534 self.recovery_state.hash(hasher);
4535 self.recovery_symbols_id.hash(hasher);
4536 }
4537}
4538
4539struct FastRecoveryRequest<'a, 'b> {
4540 atn: &'a Atn,
4541 transition: ParserTransition<'a>,
4542 expected_symbols: Rc<BTreeSet<i32>>,
4543 target: usize,
4544 request: FastRecognizeRequest,
4545 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4546 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4547 expected: &'b mut ExpectedTokens,
4548}
4549
4550struct FastCurrentTokenDeletionRequest<'a, 'b> {
4551 atn: &'a Atn,
4552 expected_symbols: Rc<BTreeSet<i32>>,
4553 request: FastRecognizeRequest,
4554 visiting: &'b mut FxHashSet<FastRecognizeKey>,
4555 memo: &'b mut FxHashMap<FastRecognizeKey, Rc<[FastRecognizeOutcome]>>,
4556 expected: &'b mut ExpectedTokens,
4557}
4558
4559#[derive(Clone, Copy)]
4560struct FastChildRuleFailureRecoveryRequest<'a> {
4561 atn: &'a Atn,
4562 rule_index: usize,
4563 start_index: usize,
4564 follow_state: usize,
4565 stop_state: usize,
4566 expected: &'a ExpectedTokens,
4567}
4568
4569struct RecoveryRequest<'a, 'b> {
4570 atn: &'a Atn,
4571 transition: ParserTransition<'a>,
4572 expected_symbols: BTreeSet<i32>,
4573 target: usize,
4574 request: RecognizeRequest<'a>,
4575 visiting: &'b mut BTreeSet<RecognizeKey>,
4576 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4577 expected: &'b mut ExpectedTokens,
4578}
4579
4580struct CurrentTokenDeletionRequest<'a, 'b> {
4581 atn: &'a Atn,
4582 expected_symbols: BTreeSet<i32>,
4583 request: RecognizeRequest<'a>,
4584 visiting: &'b mut BTreeSet<RecognizeKey>,
4585 memo: &'b mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
4586 expected: &'b mut ExpectedTokens,
4587}
4588
4589struct ConsumingFailureFallback<'a> {
4592 atn: &'a Atn,
4593 target: usize,
4594 request: RecognizeRequest<'a>,
4595 symbol: i32,
4596 expected_symbols: BTreeSet<i32>,
4597 decision_start_index: Option<usize>,
4598 decision: Option<usize>,
4599}
4600
4601struct ChildRuleFailureRecovery<'a> {
4604 atn: &'a Atn,
4605 rule_index: usize,
4606 start_index: usize,
4607 follow_state: usize,
4608 stop_state: usize,
4609 member_values: MemberEnv,
4610 expected: &'a ExpectedTokens,
4611}
4612
4613#[derive(Clone, Copy, Debug)]
4615struct PredicateEval<'a> {
4616 index: usize,
4617 rule_index: usize,
4618 pred_index: usize,
4619 predicates: &'a [(usize, usize, ParserPredicate)],
4620 semantics: Option<&'a ParserSemantics>,
4621 context: Option<&'a ParserRuleContext>,
4622 local_int_arg: Option<(usize, i64)>,
4623 member_values: &'a MemberEnv,
4624}
4625
4626#[derive(Clone, Copy, Debug)]
4627struct ParserSemanticHookRequest<'a> {
4628 index: usize,
4629 rule_index: usize,
4630 pred_index: usize,
4631 context: Option<&'a ParserRuleContext>,
4632 local_int_arg: Option<(usize, i64)>,
4633 member_values: &'a MemberEnv,
4634}
4635
4636struct ParserSemIrCtx<'a, S, H>
4645where
4646 S: TokenSource,
4647 H: SemanticHooks,
4648{
4649 input: &'a mut CommonTokenStream<S>,
4650 tree_storage: &'a ParseTreeStorage,
4651 semantic_hooks: &'a mut H,
4652 rule_index: usize,
4653 coordinate_index: usize,
4654 rule_name: Option<&'a str>,
4655 context: Option<&'a ParserRuleContext>,
4656 local_int_arg: Option<(usize, i64)>,
4657 member_values: &'a MemberEnv,
4658 invoked_predicates: &'a mut Vec<(usize, usize)>,
4659 unknown_predicate_policy: UnknownSemanticPolicy,
4663 unknown_predicate_hits: &'a mut Vec<(usize, usize)>,
4664}
4665
4666impl<S, H> semir::PredContext for ParserSemIrCtx<'_, S, H>
4667where
4668 S: TokenSource,
4669 H: SemanticHooks,
4670{
4671 type TokenText<'a>
4672 = TokenView<'a>
4673 where
4674 Self: 'a;
4675
4676 fn la(&mut self, offset: isize) -> i64 {
4677 i64::from(self.input.la(offset))
4678 }
4679
4680 fn token_text(&mut self, offset: isize) -> Option<Self::TokenText<'_>> {
4681 self.input.lt(offset)
4682 }
4683
4684 fn token_index_adjacent(&mut self) -> bool {
4685 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
4686 return false;
4687 };
4688 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
4689 return false;
4690 };
4691 first + 1 == second
4692 }
4693
4694 fn ctx_rule_text(&self, rule_index: usize) -> Option<String> {
4695 self.context.and_then(|context| {
4696 context
4697 .child_rules(self.tree_storage, self.input.token_store(), rule_index)
4698 .next()
4699 .map(crate::tree::RuleNodeView::text)
4700 })
4701 }
4702
4703 fn member(&self, member: usize) -> Option<i64> {
4704 Some(self.member_values.scalar(member).unwrap_or_default())
4705 }
4706
4707 fn member_top(&self, member: usize) -> Option<i64> {
4708 self.member_values.stack_top(member)
4709 }
4710
4711 fn member_len(&self, member: usize) -> usize {
4712 self.member_values.stack_len(member)
4713 }
4714
4715 fn local_arg(&self) -> Option<i64> {
4716 self.local_int_arg.map(|(_, value)| value)
4717 }
4718
4719 fn column(&self) -> Option<i64> {
4720 None
4721 }
4722
4723 fn token_start_column(&self) -> Option<i64> {
4724 None
4725 }
4726
4727 fn token_text_so_far(&self) -> Option<String> {
4728 None
4729 }
4730
4731 fn hook(&mut self, _hook: HookId) -> bool {
4732 let mut ctx = ParserSemCtx {
4733 input: &mut *self.input,
4734 tree_storage: self.tree_storage,
4735 rule_index: self.rule_index,
4736 coordinate_index: self.coordinate_index,
4737 rule_name: self.rule_name.map(str::to_owned),
4738 context: self.context,
4739 tree: None,
4740 local_int_arg: self.local_int_arg,
4741 member_values: self.member_values,
4742 action: None,
4743 };
4744 match self
4745 .semantic_hooks
4746 .sempred(&mut ctx, self.rule_index, self.coordinate_index)
4747 {
4748 Some(result) => result,
4749 None => apply_unknown_predicate_policy(
4753 self.unknown_predicate_policy,
4754 self.rule_index,
4755 self.coordinate_index,
4756 self.unknown_predicate_hits,
4757 ),
4758 }
4759 }
4760
4761 fn trace_bool(&mut self, value: bool) -> bool {
4762 let key = (self.rule_index, self.coordinate_index);
4763 if !self.invoked_predicates.contains(&key) {
4764 self.invoked_predicates.push(key);
4765 use std::io::Write as _;
4766 let mut stdout = std::io::stdout().lock();
4767 let _ = writeln!(stdout, "eval={value}");
4768 }
4769 value
4770 }
4771}
4772
4773struct PredicateFailureRecovery<'a> {
4775 rule_index: usize,
4776 index: usize,
4777 message: &'a str,
4778 member_values: MemberEnv,
4779 return_values: BTreeMap<String, i64>,
4780 rule_alt_number: usize,
4781}
4782
4783#[derive(Debug)]
4784enum DirectAdaptiveParseControl {
4785 Fallback(DirectAdaptiveFallback),
4786}
4787
4788#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4789enum DirectAdaptiveFallback {
4790 Action,
4791 InvalidAlt,
4792 LeftRecursiveBoundary,
4793 MissingAtn,
4794 NoTransition,
4795 Predicate,
4796 Prediction,
4797 Precedence,
4798 RuleStop,
4799 SemanticContext,
4800 StepLimit,
4801 TokenMismatch,
4802 UnknownDecision,
4803}
4804
4805type DirectAdaptiveParseResult<T> = Result<T, DirectAdaptiveParseControl>;
4806
4807struct DirectAdaptiveParser<'atn, 'sim, S, H = NoSemanticHooks>
4808where
4809 S: TokenSource,
4810 H: SemanticHooks,
4811{
4812 parser: &'sim mut BaseParser<S, H>,
4813 atn: &'atn Atn,
4814 simulator: &'sim mut ParserAtnSimulator<'atn>,
4815 decision_by_state: Vec<Option<usize>>,
4816 steps: usize,
4817}
4818
4819#[derive(Clone, Debug, Eq, PartialEq)]
4829pub struct GeneratedMatch {
4830 children: GeneratedMatchChildren,
4831 consumed_eof: bool,
4832}
4833
4834#[derive(Clone, Copy)]
4835enum GeneratedExpectedSymbols<'a> {
4836 Tree(&'a BTreeSet<i32>),
4837 TokenSet(ParserIntervalSet<'a>),
4838 TokenSetComplement {
4839 set: ParserIntervalSet<'a>,
4840 min_vocabulary: i32,
4841 max_vocabulary: i32,
4842 },
4843}
4844
4845impl GeneratedExpectedSymbols<'_> {
4846 fn is_empty(self) -> bool {
4847 match self {
4848 Self::Tree(symbols) => symbols.is_empty(),
4849 Self::TokenSet(set) => set.is_empty(),
4850 Self::TokenSetComplement {
4851 set,
4852 min_vocabulary,
4853 max_vocabulary,
4854 } => (min_vocabulary..=max_vocabulary).all(|symbol| set.contains(symbol)),
4855 }
4856 }
4857
4858 fn first(self) -> Option<i32> {
4859 match self {
4860 Self::Tree(symbols) => symbols.iter().next().copied(),
4861 Self::TokenSet(set) => set.ranges().next().map(|(start, _)| start),
4862 Self::TokenSetComplement {
4863 set,
4864 min_vocabulary,
4865 max_vocabulary,
4866 } => (min_vocabulary..=max_vocabulary).find(|symbol| !set.contains(*symbol)),
4867 }
4868 }
4869
4870 fn display(self, vocabulary: &Vocabulary) -> String {
4871 match self {
4872 Self::Tree(symbols) => expected_symbols_display(symbols, vocabulary),
4873 Self::TokenSet(set) => expected_symbols_display_iter(
4874 set.ranges().flat_map(|(start, stop)| start..=stop),
4875 vocabulary,
4876 ),
4877 Self::TokenSetComplement {
4878 set,
4879 min_vocabulary,
4880 max_vocabulary,
4881 } => expected_symbols_display_iter(
4882 (min_vocabulary..=max_vocabulary).filter(|symbol| !set.contains(*symbol)),
4883 vocabulary,
4884 ),
4885 }
4886 }
4887}
4888
4889#[derive(Clone, Debug, Eq, PartialEq)]
4890enum GeneratedMatchChildren {
4891 One(ParseTree),
4892 Many(Vec<ParseTree>),
4893}
4894
4895struct GeneratedMatchChildrenIntoIter {
4896 one: Option<ParseTree>,
4897 many: Option<std::vec::IntoIter<ParseTree>>,
4898}
4899
4900impl Iterator for GeneratedMatchChildrenIntoIter {
4901 type Item = ParseTree;
4902
4903 fn next(&mut self) -> Option<Self::Item> {
4904 self.one
4905 .take()
4906 .or_else(|| self.many.as_mut().and_then(Iterator::next))
4907 }
4908}
4909
4910impl GeneratedMatch {
4911 #[must_use]
4915 pub fn children(&self) -> &[ParseTree] {
4916 match &self.children {
4917 GeneratedMatchChildren::One(child) => std::slice::from_ref(child),
4918 GeneratedMatchChildren::Many(children) => children,
4919 }
4920 }
4921
4922 #[must_use]
4925 pub fn into_children(self) -> Vec<ParseTree> {
4926 match self.children {
4927 GeneratedMatchChildren::One(child) => vec![child],
4928 GeneratedMatchChildren::Many(children) => children,
4929 }
4930 }
4931
4932 pub fn into_child_iter(self) -> impl Iterator<Item = ParseTree> {
4934 match self.children {
4935 GeneratedMatchChildren::One(child) => GeneratedMatchChildrenIntoIter {
4936 one: Some(child),
4937 many: None,
4938 },
4939 GeneratedMatchChildren::Many(children) => GeneratedMatchChildrenIntoIter {
4940 one: None,
4941 many: Some(children.into_iter()),
4942 },
4943 }
4944 }
4945
4946 #[must_use]
4948 pub const fn consumed_eof(&self) -> bool {
4949 self.consumed_eof
4950 }
4951}
4952
4953impl<S> BaseParser<S, NoSemanticHooks>
4954where
4955 S: TokenSource,
4956{
4957 pub fn new(input: CommonTokenStream<S>, data: RecognizerData) -> Self {
4960 Self::with_semantic_hooks(input, data, NoSemanticHooks)
4961 }
4962}
4963
4964impl<S, H> BaseParser<S, H>
4965where
4966 S: TokenSource,
4967 H: SemanticHooks,
4968{
4969 pub fn with_semantic_hooks(
4971 input: CommonTokenStream<S>,
4972 data: RecognizerData,
4973 semantic_hooks: H,
4974 ) -> Self {
4975 Self {
4976 input,
4977 tree: ParseTreeStorage::new(),
4978 data,
4979 semantic_hooks,
4980 decision_override_generation: 0,
4981 build_parse_trees: true,
4982 syntax_errors: 0,
4983 report_diagnostic_errors: false,
4984 prediction_mode: PredictionMode::Ll,
4985 prediction_diagnostics: Vec::new(),
4986 reported_prediction_diagnostics: BTreeSet::new(),
4987 generated_parser_diagnostics: Vec::new(),
4988 generated_sync_expected: None,
4989 generated_recovery_error_index: None,
4990 generated_recovery_error_states: BTreeSet::new(),
4991 int_members: MemberEnv::new(),
4992 rule_context_stack: Vec::new(),
4993 rule_context_version: 0,
4994 left_recursive_caller_overlap_cache: std::array::from_fn(|_| None),
4995 pending_invoking_states: Vec::new(),
4996 precedence_stack: vec![0],
4997 invoked_predicates: Vec::new(),
4998 bail_on_error: false,
4999 parse_listeners: Vec::new(),
5000 parse_listener_abort: None,
5001 max_rule_depth: None,
5002 rule_depth_error: None,
5003 recursion_expansions: 0,
5004 recursion_expansion_marks: Vec::new(),
5005 unknown_predicate_policy: UnknownSemanticPolicy::default(),
5006 unknown_predicate_hits: Vec::new(),
5007 unhandled_action_hits: Vec::new(),
5008 rule_first_set_cache: Vec::new(),
5009 state_expected_cache: FxHashMap::default(),
5010 state_expected_token_cache: FxHashMap::default(),
5011 rule_stop_reach_cache: Vec::new(),
5012 recovery_symbols_intern: FxHashMap::default(),
5013 decision_lookahead_cache: FxHashMap::default(),
5014 ll1_decision_cache: FxHashMap::default(),
5015 fast_predicate_cache: FxHashMap::default(),
5016 empty_cycle_cache: Vec::new(),
5017 empty_cycle_cache_atn: None,
5018 clean_memo_mode: CleanMemoMode::Probe,
5019 clean_memo_probe_seen: FxHashSet::default(),
5020 clean_memo_probe_samples: 0,
5021 clean_memo_probe_repeats: 0,
5022 clean_memo_sparse_samples: 0,
5023 fast_recognize_scratch: FastRecognizeTopScratch::default(),
5024 fast_outcome_dedup: FastOutcomeDedupScratch::default(),
5025 empty_recovery_symbols: Rc::new(BTreeSet::new()),
5026 fast_first_set_prefilter: true,
5027 fast_recovery_enabled: true,
5028 fast_token_nodes_enabled: true,
5029 fast_track_alt_numbers: false,
5030 recognition_arena: RecognitionArena::default(),
5031 last_recognition_arena_root: NodeSeqId::EMPTY,
5032 last_recognition_arena_diagnostics: DiagnosticSeqId::EMPTY,
5033 }
5034 }
5035
5036 pub const fn input(&mut self) -> &mut CommonTokenStream<S> {
5037 &mut self.input
5038 }
5039
5040 pub fn reset(&mut self) {
5045 self.input.seek(0);
5046 self.tree.reset();
5047 self.data.set_state(-1);
5048 self.syntax_errors = 0;
5049 self.prediction_diagnostics.clear();
5050 self.reported_prediction_diagnostics.clear();
5051 self.generated_parser_diagnostics.clear();
5052 self.generated_sync_expected = None;
5053 self.reset_generated_recovery_state();
5054 self.rule_context_stack.clear();
5055 self.advance_rule_context_version();
5056 self.left_recursive_caller_overlap_cache = std::array::from_fn(|_| None);
5057 self.pending_invoking_states.clear();
5058 self.precedence_stack.clear();
5059 self.precedence_stack.push(0);
5060 self.invoked_predicates.clear();
5061 self.decision_override_generation = 0;
5062 self.unknown_predicate_hits.clear();
5063 self.unhandled_action_hits.clear();
5064 self.parse_listener_abort = None;
5065 self.rule_depth_error = None;
5066 self.recursion_expansions = 0;
5067 self.recursion_expansion_marks.clear();
5068 self.reset_per_parse_caches();
5069 self.fast_first_set_prefilter = true;
5070 self.fast_recovery_enabled = true;
5071 self.fast_token_nodes_enabled = self.build_parse_trees;
5072 self.fast_track_alt_numbers = false;
5073 self.reset_recognition_arena();
5074 }
5075
5076 pub fn set_token_stream(&mut self, input: CommonTokenStream<S>) {
5078 self.input = input;
5079 self.reset();
5080 }
5081
5082 pub const fn set_unknown_predicate_policy(&mut self, policy: UnknownSemanticPolicy) {
5093 self.unknown_predicate_policy = policy;
5094 }
5095
5096 #[must_use]
5102 pub fn take_unknown_semantic_error(&mut self) -> Option<AntlrError> {
5103 let error = self.unknown_semantic_error();
5104 self.unknown_predicate_hits.clear();
5105 self.unhandled_action_hits.clear();
5106 error
5107 }
5108
5109 pub fn reset_unknown_semantic_hits(&mut self) {
5116 self.unknown_predicate_hits.clear();
5117 self.unhandled_action_hits.clear();
5118 }
5119
5120 #[must_use]
5122 pub const fn token_stream(&self) -> &CommonTokenStream<S> {
5123 &self.input
5124 }
5125
5126 #[must_use]
5128 pub const fn token_stream_mut(&mut self) -> &mut CommonTokenStream<S> {
5129 &mut self.input
5130 }
5131
5132 #[must_use]
5134 pub const fn token_store(&self) -> &TokenStore {
5135 self.input.token_store()
5136 }
5137
5138 #[must_use]
5140 pub const fn parse_tree_storage(&self) -> &ParseTreeStorage {
5141 &self.tree
5142 }
5143
5144 #[must_use]
5146 pub fn node(&self, id: NodeId) -> Node<'_> {
5147 self.tree
5148 .node(self.input.token_store(), id)
5149 .expect("parser-produced node ID should remain valid")
5150 }
5151
5152 #[must_use]
5154 pub fn into_token_stream(self) -> CommonTokenStream<S> {
5155 self.input
5156 }
5157
5158 #[must_use]
5160 pub fn into_token_store(self) -> TokenStore {
5161 self.input.into_token_store()
5162 }
5163
5164 #[must_use]
5166 pub fn into_parsed_file(self, root: NodeId) -> ParsedFile {
5167 ParsedFile::new(self.input.into_token_store(), self.tree, root)
5168 }
5169
5170 pub const fn number_of_syntax_errors(&self) -> usize {
5173 self.syntax_errors
5174 }
5175
5176 #[must_use]
5182 pub fn recognition_arena_stats(&self) -> RecognitionArenaStats {
5183 self.recognition_arena.stats(
5184 self.last_recognition_arena_root,
5185 self.last_recognition_arena_diagnostics,
5186 )
5187 }
5188
5189 pub const fn record_generated_syntax_error(&mut self) {
5192 self.record_syntax_errors(1);
5193 }
5194
5195 const fn record_syntax_errors(&mut self, count: usize) {
5196 self.syntax_errors = self.syntax_errors.saturating_add(count);
5197 }
5198
5199 const fn is_top_level_entry(&self) -> bool {
5201 self.rule_context_stack.is_empty() && self.pending_invoking_states.is_empty()
5202 }
5203
5204 pub fn report_token_source_errors(&mut self) {
5207 let errors = self.input.drain_source_errors();
5208 self.dispatch_token_source_errors(&errors);
5209 }
5210
5211 pub const fn generated_diagnostics_checkpoint(&self) -> GeneratedDiagnosticsCheckpoint {
5214 GeneratedDiagnosticsCheckpoint {
5215 diagnostics_len: self.generated_parser_diagnostics.len(),
5216 syntax_errors: self.syntax_errors,
5217 tree: self.tree.checkpoint(),
5218 }
5219 }
5220
5221 pub fn restore_generated_diagnostics(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
5223 self.generated_parser_diagnostics
5224 .truncate(marker.diagnostics_len);
5225 self.syntax_errors = marker.syntax_errors;
5226 self.rollback_generated_tree(marker);
5227 }
5228
5229 pub fn rollback_generated_tree(&mut self, marker: GeneratedDiagnosticsCheckpoint) {
5235 self.generated_sync_expected = None;
5236 self.tree.rollback(marker.tree);
5237 }
5238
5239 pub fn report_generated_parser_diagnostics(&mut self) {
5241 let parser_diagnostics = std::mem::take(&mut self.generated_parser_diagnostics);
5242 let token_errors = self.input.drain_source_errors();
5243 self.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
5244 }
5245
5246 pub fn report_unrecovered_parser_error(&self, error: &AntlrError) {
5251 let AntlrError::ParserError {
5252 line,
5253 column,
5254 message,
5255 offending,
5256 } = error
5257 else {
5258 return;
5259 };
5260 let offending = offending.and_then(|token| self.token_store().view(token));
5261 self.notify_error_listeners(offending, *line, *column, message, Some(error));
5262 }
5263
5264 fn dispatch_parser_diagnostic(&self, diagnostic: &ParserDiagnostic) {
5265 let offending = diagnostic
5266 .offending
5267 .and_then(|token| self.token_store().view(token));
5268 self.notify_error_listeners(
5269 offending,
5270 diagnostic.line,
5271 diagnostic.column,
5272 &diagnostic.message,
5273 None,
5274 );
5275 }
5276
5277 fn dispatch_parser_diagnostics<'a>(
5278 &self,
5279 diagnostics: impl IntoIterator<Item = &'a ParserDiagnostic>,
5280 ) {
5281 for diagnostic in diagnostics {
5282 self.dispatch_parser_diagnostic(diagnostic);
5283 }
5284 }
5285
5286 fn dispatch_token_source_error(&self, source_error: &TokenSourceError) {
5287 if self.input.token_source().report_error(source_error) {
5288 return;
5289 }
5290 self.notify_error_listeners(
5293 None,
5294 source_error.line,
5295 source_error.column,
5296 &source_error.message,
5297 None,
5298 );
5299 }
5300
5301 fn dispatch_token_source_errors(&self, errors: &[TokenSourceError]) {
5302 for error in errors {
5303 self.dispatch_token_source_error(error);
5304 }
5305 }
5306
5307 fn dispatch_generated_diagnostics(
5310 &self,
5311 parser_diagnostics: &[ParserDiagnostic],
5312 token_errors: &[TokenSourceError],
5313 ) {
5314 let mut token_iter = token_errors.iter().peekable();
5320 for diagnostic in parser_diagnostics {
5321 while let Some(error) = token_iter.peek() {
5322 if (error.line, error.column) <= (diagnostic.line, diagnostic.column) {
5323 self.dispatch_token_source_error(error);
5324 token_iter.next();
5325 } else {
5326 break;
5327 }
5328 }
5329 self.dispatch_parser_diagnostic(diagnostic);
5330 }
5331 for error in token_iter {
5332 self.dispatch_token_source_error(error);
5333 }
5334 }
5335
5336 pub fn record_generated_ambiguity_diagnostic(
5339 &mut self,
5340 atn: &Atn,
5341 state_number: usize,
5342 start_index: usize,
5343 stop_index: usize,
5344 alts: &[usize],
5345 ) {
5346 if !self.report_diagnostic_errors || alts.len() < 2 {
5347 return;
5348 }
5349 let Some(decision) = atn
5350 .decision_to_state()
5351 .iter()
5352 .position(|candidate| candidate == state_number)
5353 else {
5354 return;
5355 };
5356 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5357 return;
5358 };
5359 let rule_name = self
5360 .rule_names()
5361 .get(rule_index)
5362 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5363 let input = display_input_text(&self.input.text(start_index, stop_index));
5364 let alts = alts
5365 .iter()
5366 .map(usize::to_string)
5367 .collect::<Vec<_>>()
5368 .join(", ");
5369 let key = (decision, start_index, format!("{alts}:{input}"));
5370 if !self.reported_prediction_diagnostics.insert(key) {
5371 return;
5372 }
5373 let start_diagnostic = diagnostic_for_token(
5374 self.token_at(start_index),
5375 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
5376 );
5377 let stop_diagnostic = diagnostic_for_token(
5378 self.token_at(stop_index),
5379 format!(
5380 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
5381 ),
5382 );
5383 self.generated_parser_diagnostics.push(start_diagnostic);
5384 self.generated_parser_diagnostics.push(stop_diagnostic);
5385 }
5386
5387 pub fn record_generated_prediction_diagnostic(
5390 &mut self,
5391 atn: &Atn,
5392 state_number: usize,
5393 prediction: &ParserAtnPrediction,
5394 ) {
5395 let Some(diagnostic) = &prediction.diagnostic else {
5396 return;
5397 };
5398 if !self.report_diagnostic_errors || diagnostic.conflicting_alts.len() < 2 {
5399 return;
5400 }
5401 let Some(decision) = atn
5402 .decision_to_state()
5403 .iter()
5404 .position(|candidate| candidate == state_number)
5405 else {
5406 return;
5407 };
5408 let Some(rule_index) = atn.state(state_number).and_then(AtnState::rule_index) else {
5409 return;
5410 };
5411 let rule_name = self
5412 .rule_names()
5413 .get(rule_index)
5414 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
5415 let attempt_input = display_input_text(
5416 &self
5417 .input
5418 .text(diagnostic.start_index, diagnostic.sll_stop_index),
5419 );
5420 let result_input = display_input_text(
5421 &self
5422 .input
5423 .text(diagnostic.start_index, diagnostic.ll_stop_index),
5424 );
5425 let alts = diagnostic
5426 .conflicting_alts
5427 .iter()
5428 .map(usize::to_string)
5429 .collect::<Vec<_>>()
5430 .join(", ");
5431 let key = (
5432 decision,
5433 diagnostic.start_index,
5434 format!(
5435 "{:?}:{alts}:{attempt_input}:{result_input}",
5436 diagnostic.kind
5437 ),
5438 );
5439 if !self.reported_prediction_diagnostics.insert(key) {
5440 return;
5441 }
5442 let attempt_diagnostic = diagnostic_for_token(
5443 self.token_at(diagnostic.sll_stop_index),
5444 format!(
5445 "reportAttemptingFullContext d={decision} ({rule_name}), input='{attempt_input}'"
5446 ),
5447 );
5448 self.generated_parser_diagnostics.push(attempt_diagnostic);
5449 let message = match diagnostic.kind {
5450 ParserAtnPredictionDiagnosticKind::Ambiguity => {
5451 if !diagnostic.exact {
5456 return;
5457 }
5458 format!(
5459 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{result_input}'"
5460 )
5461 }
5462 ParserAtnPredictionDiagnosticKind::ContextSensitivity => {
5463 format!(
5464 "reportContextSensitivity d={decision} ({rule_name}), input='{result_input}'"
5465 )
5466 }
5467 };
5468 let result_diagnostic =
5469 diagnostic_for_token(self.token_at(diagnostic.ll_stop_index), message);
5470 self.generated_parser_diagnostics.push(result_diagnostic);
5471 }
5472
5473 pub fn la(&self, offset: isize) -> i32 {
5474 self.input.la_token(offset)
5475 }
5476
5477 pub fn consume(&mut self) {
5478 IntStream::consume(&mut self.input);
5479 }
5480
5481 pub fn set_int_member(&mut self, member: usize, value: i64) {
5483 self.int_members.set_scalar(member, value);
5484 }
5485
5486 pub fn int_member(&self, member: usize) -> Option<i64> {
5488 self.int_members.scalar(member)
5489 }
5490
5491 pub fn push_stack_member(&mut self, member: usize, value: i64) {
5493 self.int_members.push_stack(member, value);
5494 }
5495
5496 pub fn pop_stack_member(&mut self, member: usize) -> Option<i64> {
5499 self.int_members.pop_stack(member)
5500 }
5501
5502 #[must_use]
5505 pub fn stack_member_top(&self, member: usize) -> Option<i64> {
5506 self.int_members.stack_top(member)
5507 }
5508
5509 #[must_use]
5511 pub fn stack_member_len(&self, member: usize) -> usize {
5512 self.int_members.stack_len(member)
5513 }
5514
5515 pub fn set_initial_members(&mut self, initial: impl IntoIterator<Item = (usize, i64)>) {
5522 self.int_members = MemberEnv::with_initial_scalars(initial);
5523 }
5524
5525 #[must_use]
5531 pub fn int_members_checkpoint(&self) -> MemberEnv {
5532 self.int_members.clone()
5533 }
5534
5535 pub fn restore_int_members(&mut self, members: MemberEnv) {
5537 self.int_members = members;
5538 }
5539
5540 pub fn add_int_member(&mut self, member: usize, delta: i64) -> i64 {
5542 self.int_members.add_scalar(member, delta)
5543 }
5544
5545 fn token_type_for_id(&self, id: TokenId) -> i32 {
5546 self.input.token_store().token_type(id).unwrap_or(TOKEN_EOF)
5547 }
5548
5549 fn terminal_tree(&mut self, id: TokenId) -> ParseTree {
5550 if self.build_parse_trees {
5551 self.tree.terminal(id)
5552 } else {
5553 NodeId::placeholder()
5554 }
5555 }
5556
5557 fn error_tree(&mut self, id: TokenId) -> ParseTree {
5558 if self.build_parse_trees {
5559 self.tree.error(id)
5560 } else {
5561 NodeId::placeholder()
5562 }
5563 }
5564
5565 const fn set_context_start(&self, context: &mut ParserRuleContext, id: TokenId) {
5566 context.set_start_id(id);
5567 }
5568
5569 const fn set_context_stop(&self, context: &mut ParserRuleContext, id: TokenId) {
5570 context.set_stop_id(id);
5571 }
5572
5573 fn insert_synthetic_token(
5574 &mut self,
5575 token_type: i32,
5576 text: String,
5577 line: usize,
5578 column: usize,
5579 ) -> Result<TokenId, AntlrError> {
5580 self.input
5581 .insert(
5582 TokenSpec::explicit(token_type, text)
5583 .with_span(usize::MAX, usize::MAX)
5584 .with_byte_span(0, 0)
5585 .with_position(line, column),
5586 )
5587 .map_err(|error| AntlrError::Unsupported(error.to_string()))
5588 }
5589
5590 pub fn match_token(&mut self, token_type: i32) -> Result<ParseTree, AntlrError> {
5597 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5598 line: 0,
5599 column: 0,
5600 message: "missing current token".to_owned(),
5601 offending: None,
5602 })?;
5603 let current_type = self.token_type_for_id(current);
5604 if current_type == token_type {
5605 self.reset_generated_recovery_state();
5606 self.consume();
5607 Ok(self.terminal_tree(current))
5608 } else {
5609 Err(AntlrError::MismatchedInput {
5610 expected: self.vocabulary().display_name(token_type),
5611 found: self.vocabulary().display_name(current_type),
5612 })
5613 }
5614 }
5615
5616 pub fn match_token_recovering(
5620 &mut self,
5621 token_type: i32,
5622 follow_state: usize,
5623 atn: &Atn,
5624 ) -> Result<GeneratedMatch, AntlrError> {
5625 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5626 line: 0,
5627 column: 0,
5628 message: "missing current token".to_owned(),
5629 offending: None,
5630 })?;
5631 let current_type = self.token_type_for_id(current);
5632 if current_type == token_type {
5633 self.generated_sync_expected = None;
5634 self.reset_generated_recovery_state();
5635 let consumed_eof = current_type == TOKEN_EOF;
5636 self.consume();
5637 return Ok(GeneratedMatch {
5638 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5639 consumed_eof,
5640 });
5641 }
5642 let mut expected_symbols = BTreeSet::new();
5643 expected_symbols.insert(token_type);
5644 self.recover_generated_match(
5645 current,
5646 GeneratedExpectedSymbols::Tree(&expected_symbols),
5647 follow_state,
5648 atn,
5649 |symbol| symbol == token_type,
5650 )
5651 }
5652
5653 pub fn match_set_recovering(
5654 &mut self,
5655 intervals: &[(i32, i32)],
5656 follow_state: usize,
5657 atn: &Atn,
5658 ) -> Result<GeneratedMatch, AntlrError> {
5659 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5660 line: 0,
5661 column: 0,
5662 message: "missing current token".to_owned(),
5663 offending: None,
5664 })?;
5665 let current_type = self.token_type_for_id(current);
5666 if interval_set_contains(intervals, current_type) {
5667 self.generated_sync_expected = None;
5668 self.reset_generated_recovery_state();
5669 let consumed_eof = current_type == TOKEN_EOF;
5670 self.consume();
5671 return Ok(GeneratedMatch {
5672 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5673 consumed_eof,
5674 });
5675 }
5676 let expected_symbols = interval_symbols(intervals);
5677 self.recover_generated_match(
5678 current,
5679 GeneratedExpectedSymbols::Tree(&expected_symbols),
5680 follow_state,
5681 atn,
5682 |symbol| interval_set_contains(intervals, symbol),
5683 )
5684 }
5685
5686 pub fn match_token_set_recovering(
5687 &mut self,
5688 set: ParserIntervalSet<'_>,
5689 follow_state: usize,
5690 atn: &Atn,
5691 ) -> Result<GeneratedMatch, AntlrError> {
5692 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5693 line: 0,
5694 column: 0,
5695 message: "missing current token".to_owned(),
5696 offending: None,
5697 })?;
5698 let current_type = self.token_type_for_id(current);
5699 if set.contains(current_type) {
5700 self.generated_sync_expected = None;
5701 self.reset_generated_recovery_state();
5702 let consumed_eof = current_type == TOKEN_EOF;
5703 self.consume();
5704 return Ok(GeneratedMatch {
5705 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5706 consumed_eof,
5707 });
5708 }
5709 self.recover_generated_match(
5710 current,
5711 GeneratedExpectedSymbols::TokenSet(set),
5712 follow_state,
5713 atn,
5714 |symbol| set.contains(symbol),
5715 )
5716 }
5717
5718 pub fn match_not_set_recovering(
5719 &mut self,
5720 intervals: &[(i32, i32)],
5721 min_vocabulary: i32,
5722 max_vocabulary: i32,
5723 follow_state: usize,
5724 atn: &Atn,
5725 ) -> Result<GeneratedMatch, AntlrError> {
5726 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5727 line: 0,
5728 column: 0,
5729 message: "missing current token".to_owned(),
5730 offending: None,
5731 })?;
5732 let current_type = self.token_type_for_id(current);
5733 if (min_vocabulary..=max_vocabulary).contains(¤t_type)
5734 && !interval_set_contains(intervals, current_type)
5735 {
5736 self.generated_sync_expected = None;
5737 self.reset_generated_recovery_state();
5738 let consumed_eof = current_type == TOKEN_EOF;
5739 self.consume();
5740 return Ok(GeneratedMatch {
5741 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5742 consumed_eof,
5743 });
5744 }
5745 let expected_symbols =
5746 interval_complement_symbols(intervals, min_vocabulary, max_vocabulary);
5747 self.recover_generated_match(
5748 current,
5749 GeneratedExpectedSymbols::Tree(&expected_symbols),
5750 follow_state,
5751 atn,
5752 |symbol| {
5753 (min_vocabulary..=max_vocabulary).contains(&symbol)
5754 && !interval_set_contains(intervals, symbol)
5755 },
5756 )
5757 }
5758
5759 pub fn match_not_token_set_recovering(
5760 &mut self,
5761 set: ParserIntervalSet<'_>,
5762 min_vocabulary: i32,
5763 max_vocabulary: i32,
5764 follow_state: usize,
5765 atn: &Atn,
5766 ) -> Result<GeneratedMatch, AntlrError> {
5767 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5768 line: 0,
5769 column: 0,
5770 message: "missing current token".to_owned(),
5771 offending: None,
5772 })?;
5773 let current_type = self.token_type_for_id(current);
5774 if (min_vocabulary..=max_vocabulary).contains(¤t_type) && !set.contains(current_type)
5775 {
5776 self.generated_sync_expected = None;
5777 self.reset_generated_recovery_state();
5778 let consumed_eof = current_type == TOKEN_EOF;
5779 self.consume();
5780 return Ok(GeneratedMatch {
5781 children: GeneratedMatchChildren::One(self.terminal_tree(current)),
5782 consumed_eof,
5783 });
5784 }
5785 self.recover_generated_match(
5786 current,
5787 GeneratedExpectedSymbols::TokenSetComplement {
5788 set,
5789 min_vocabulary,
5790 max_vocabulary,
5791 },
5792 follow_state,
5793 atn,
5794 |symbol| (min_vocabulary..=max_vocabulary).contains(&symbol) && !set.contains(symbol),
5795 )
5796 }
5797
5798 fn recover_generated_match(
5799 &mut self,
5800 current: TokenId,
5801 expected_symbols: GeneratedExpectedSymbols<'_>,
5802 follow_state: usize,
5803 atn: &Atn,
5804 matches: impl Fn(i32) -> bool,
5805 ) -> Result<GeneratedMatch, AntlrError> {
5806 let expected_display = expected_symbols.display(self.vocabulary());
5807 let (current_type, current_line, current_column, current_display) = {
5808 let token = self
5809 .input
5810 .token_view(current)
5811 .expect("current token ID should be valid");
5812 (
5813 token.token_type(),
5814 token.line(),
5815 token.column(),
5816 token_input_display(&token),
5817 )
5818 };
5819 if self.bail_on_error {
5820 return Err(AntlrError::ParserError {
5821 line: current_line,
5822 column: current_column,
5823 message: format!("mismatched input {current_display} expecting {expected_display}"),
5824 offending: Some(current),
5825 });
5826 }
5827 if current_type != TOKEN_EOF
5828 && let Some(next) = self.input.lt_id(2)
5829 && matches(self.token_type_for_id(next))
5830 {
5831 let message =
5832 format!("extraneous input {current_display} expecting {expected_display}");
5833 self.push_generated_parser_diagnostic(ParserDiagnostic {
5834 line: current_line,
5835 column: current_column,
5836 message,
5837 offending: Some(current),
5838 });
5839 self.record_syntax_errors(1);
5840 self.generated_sync_expected = None;
5841 let consumed_eof = self.token_type_for_id(next) == TOKEN_EOF;
5844 self.consume();
5845 self.consume();
5846 self.reset_generated_recovery_state();
5847 return Ok(GeneratedMatch {
5848 children: GeneratedMatchChildren::Many(vec![
5849 self.error_tree(current),
5850 self.terminal_tree(next),
5851 ]),
5852 consumed_eof,
5853 });
5854 }
5855 let follow_symbols = self.generated_recovery_follow_symbols(atn, follow_state);
5856 let follow_explicitly_expects_eof = current_type == TOKEN_EOF
5865 && self
5866 .cached_state_expected_symbols(atn, follow_state)
5867 .contains(&TOKEN_EOF);
5868 if follow_symbols.contains(¤t_type)
5869 && (current_type != TOKEN_EOF
5870 || self.rule_context_stack.len() > 1
5871 || expected_symbols.is_empty()
5872 || follow_explicitly_expects_eof)
5873 {
5874 let message = format!("missing {expected_display} at {current_display}");
5875 self.push_generated_parser_diagnostic(ParserDiagnostic {
5876 line: current_line,
5877 column: current_column,
5878 message,
5879 offending: Some(current),
5880 });
5881 self.record_syntax_errors(1);
5882 self.generated_sync_expected = None;
5883 let token_type = expected_symbols.first().unwrap_or(TOKEN_EOF);
5884 let missing_display = expected_symbol_display(token_type, self.vocabulary());
5885 let token = self.insert_synthetic_token(
5886 token_type,
5887 format!("<missing {missing_display}>"),
5888 current_line,
5889 current_column,
5890 )?;
5891 return Ok(GeneratedMatch {
5896 children: GeneratedMatchChildren::One(self.error_tree(token)),
5897 consumed_eof: false,
5898 });
5899 }
5900 let mismatch_expected_display = self
5901 .generated_sync_expected
5902 .take()
5903 .map_or(expected_display, |symbols| {
5904 expected_symbols_display_iter(symbols.symbols(), self.vocabulary())
5905 });
5906 Err(AntlrError::ParserError {
5907 line: current_line,
5908 column: current_column,
5909 message: format!(
5910 "mismatched input {current_display} expecting {mismatch_expected_display}"
5911 ),
5912 offending: Some(current),
5913 })
5914 }
5915
5916 fn generated_recovery_follow_symbols(
5917 &mut self,
5918 atn: &Atn,
5919 follow_state: usize,
5920 ) -> BTreeSet<i32> {
5921 let mut follow = self
5922 .cached_state_expected_symbols(atn, follow_state)
5923 .as_ref()
5924 .clone();
5925 if self.cached_state_can_reach_rule_stop(atn, follow_state) {
5926 follow.extend(self.context_expected_symbols(atn));
5927 }
5928 follow
5929 }
5930
5931 pub fn match_eof(&mut self) -> Result<ParseTree, AntlrError> {
5932 self.match_token(TOKEN_EOF)
5933 }
5934
5935 pub fn match_set(&mut self, intervals: &[(i32, i32)]) -> Result<ParseTree, AntlrError> {
5936 self.match_interval_condition(intervals, |symbol| interval_set_contains(intervals, symbol))
5937 }
5938
5939 pub fn match_not_set(
5940 &mut self,
5941 intervals: &[(i32, i32)],
5942 min_vocabulary: i32,
5943 max_vocabulary: i32,
5944 ) -> Result<ParseTree, AntlrError> {
5945 self.match_interval_condition(intervals, |symbol| {
5946 (min_vocabulary..=max_vocabulary).contains(&symbol)
5947 && !interval_set_contains(intervals, symbol)
5948 })
5949 }
5950
5951 fn match_interval_condition(
5952 &mut self,
5953 intervals: &[(i32, i32)],
5954 matches: impl FnOnce(i32) -> bool,
5955 ) -> Result<ParseTree, AntlrError> {
5956 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
5957 line: 0,
5958 column: 0,
5959 message: "missing current token".to_owned(),
5960 offending: None,
5961 })?;
5962 let current_type = self.token_type_for_id(current);
5963 if matches(current_type) {
5964 self.reset_generated_recovery_state();
5965 self.consume();
5966 Ok(self.terminal_tree(current))
5967 } else {
5968 Err(AntlrError::MismatchedInput {
5969 expected: self.interval_display(intervals),
5970 found: self.vocabulary().display_name(current_type),
5971 })
5972 }
5973 }
5974
5975 fn interval_display(&self, intervals: &[(i32, i32)]) -> String {
5976 let values = intervals
5977 .iter()
5978 .map(|(start, stop)| {
5979 if start == stop {
5980 self.vocabulary().display_name(*start)
5981 } else {
5982 format!(
5983 "{}..{}",
5984 self.vocabulary().display_name(*start),
5985 self.vocabulary().display_name(*stop)
5986 )
5987 }
5988 })
5989 .collect::<Vec<_>>()
5990 .join(", ");
5991 format!("{{{values}}}")
5992 }
5993
5994 pub fn rule_node(&mut self, context: ParserRuleContext) -> ParseTree {
5995 if self.build_parse_trees {
5996 self.tree.finish_rule(context)
5997 } else {
5998 NodeId::placeholder()
5999 }
6000 }
6001
6002 #[must_use]
6011 pub const fn generated_rule_stack_check_due(&self) -> bool {
6012 self.rule_context_stack
6013 .len()
6014 .is_multiple_of(GENERATED_RULE_STACK_CHECK_INTERVAL)
6015 }
6016
6017 #[inline]
6035 pub fn rule_depth_cap_violation(&mut self) -> Option<AntlrError> {
6036 let max = self.max_rule_depth?;
6037 if self.rule_depth_error.is_none()
6040 && self.rule_context_stack.len() + self.recursion_expansions < max
6041 {
6042 return None;
6043 }
6044 Some(self.rule_depth_cap_violation_cold(max))
6045 }
6046
6047 #[cold]
6048 fn rule_depth_cap_violation_cold(&mut self, max: usize) -> AntlrError {
6049 if let Some(error) = &self.rule_depth_error {
6050 return error.clone();
6051 }
6052 let current = self.input.lt(1);
6053 let (line, column) = current
6054 .as_ref()
6055 .map_or((0, 0), |token| (token.line(), token.column()));
6056 let error = AntlrError::ParserError {
6057 line,
6058 column,
6059 message: format!("rule nesting depth limit of {max} exceeded"),
6060 offending: current.as_ref().map(Token::token_id),
6061 };
6062 self.rule_depth_error = Some(error.clone());
6063 error
6064 }
6065
6066 pub const fn take_rule_depth_error(&mut self) -> Option<AntlrError> {
6073 self.rule_depth_error.take()
6074 }
6075
6076 #[must_use]
6083 pub const fn has_rule_depth_cap(&self) -> bool {
6084 self.max_rule_depth.is_some()
6085 }
6086
6087 pub fn add_parse_listener<L>(&mut self, listener: L)
6091 where
6092 L: ParseListener + 'static,
6093 {
6094 self.parse_listeners
6095 .push(ParseListenerSlot(Box::new(listener)));
6096 }
6097
6098 pub fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
6105 self.parse_listener_abort = None;
6106 self.parse_listeners.drain(..).map(|slot| slot.0).collect()
6107 }
6108
6109 #[must_use]
6115 pub const fn has_parse_listeners(&self) -> bool {
6116 !self.parse_listeners.is_empty()
6117 }
6118
6119 #[doc(hidden)]
6124 #[must_use]
6125 pub fn observes_parser_decisions(&self) -> bool {
6126 self.semantic_hooks.observes_parser_decisions()
6127 }
6128
6129 pub fn parse_listener_enter_rule(&mut self, rule_index: usize) -> Option<AntlrError> {
6140 if self.parse_listeners.is_empty() {
6141 return None;
6142 }
6143 self.parse_listener_enter_rule_dispatch(rule_index)
6144 }
6145
6146 fn parse_listener_enter_rule_dispatch(&mut self, rule_index: usize) -> Option<AntlrError> {
6147 if let Some(error) = &self.parse_listener_abort {
6148 return Some(error.clone());
6149 }
6150 let event = EnterRuleEvent {
6151 rule_index,
6152 current: self.input.lt(1),
6153 };
6154 let mut listeners = std::mem::take(&mut self.parse_listeners);
6158 let mut abort = None;
6159 for slot in &mut listeners {
6160 if let Err(error) = slot.0.enter_every_rule(&event) {
6161 abort = Some(error);
6162 break;
6163 }
6164 }
6165 self.parse_listeners = listeners;
6166 if let Some(error) = abort {
6167 self.parse_listener_abort = Some(error.clone());
6168 return Some(error);
6169 }
6170 None
6171 }
6172
6173 pub fn parse_listener_exit_rule(&mut self, rule_index: usize) {
6180 if self.parse_listeners.is_empty() {
6181 return;
6182 }
6183 for slot in self.parse_listeners.iter_mut().rev() {
6186 slot.0.exit_every_rule(rule_index);
6187 }
6188 }
6189
6190 pub const fn take_parse_listener_abort(&mut self) -> Option<AntlrError> {
6197 self.parse_listener_abort.take()
6198 }
6199
6200 pub fn take_parse_abort(&mut self) -> Option<AntlrError> {
6209 if let Some(error) = self.rule_depth_error.take() {
6210 self.parse_listener_abort = None;
6211 return Some(error);
6212 }
6213 self.parse_listener_abort.take()
6214 }
6215
6216 pub fn enter_rule(&mut self, state: isize, rule_index: usize) -> ParserRuleContext {
6219 self.set_state(state);
6220 let invoking_state = self.pending_invoking_states.pop().unwrap_or(state);
6221 self.rule_context_stack.push(RuleContextFrame {
6222 rule_index,
6223 invoking_state,
6224 });
6225 self.advance_rule_context_version();
6226 let start_index = self.current_visible_index();
6227 let mut context = ParserRuleContext::new(rule_index, invoking_state);
6228 if let Some(token) = self.token_id_at(start_index) {
6229 self.set_context_start(&mut context, token);
6230 }
6231 context
6232 }
6233
6234 pub fn push_invoking_state(&mut self, invoking_state: isize) -> usize {
6241 let marker = self.pending_invoking_states.len();
6242 self.pending_invoking_states.push(invoking_state);
6243 marker
6244 }
6245
6246 pub fn discard_invoking_state(&mut self, marker: usize) {
6248 self.pending_invoking_states.truncate(marker);
6249 }
6250
6251 pub fn exit_rule(&mut self) {
6253 self.rule_context_stack.pop();
6254 self.advance_rule_context_version();
6255 }
6256
6257 pub fn prediction_context_return_states<'a>(
6260 &'a self,
6261 atn: &'a Atn,
6262 ) -> impl DoubleEndedIterator<Item = usize> + 'a {
6263 self.rule_context_stack.iter().skip(1).filter_map(|frame| {
6264 let Ok(state_number) = usize::try_from(frame.invoking_state) else {
6265 return None;
6266 };
6267 let Some(Transition::Rule { follow_state, .. }) = atn
6268 .state(state_number)
6269 .and_then(|state| state.transitions().first())
6270 .map(ParserTransition::data)
6271 else {
6272 return None;
6273 };
6274 Some(follow_state)
6275 })
6276 }
6277
6278 pub const fn rule_context_version(&self) -> usize {
6283 self.rule_context_version
6284 }
6285
6286 const fn advance_rule_context_version(&mut self) {
6287 self.rule_context_version = self.rule_context_version.wrapping_add(1);
6288 }
6289
6290 pub fn add_parse_child(&mut self, context: &mut ParserRuleContext, child: ParseTree) {
6295 if self.build_parse_trees {
6296 self.tree.add_child(context, child);
6297 } else {
6298 context.note_matched_child();
6299 }
6300 }
6301
6302 fn release_tree_scratch_if_idle(&mut self) {
6303 if self.rule_context_stack.is_empty() {
6304 self.tree.release_scratch();
6305 }
6306 }
6307
6308 pub fn finish_rule(&mut self, mut context: ParserRuleContext, consumed_eof: bool) -> ParseTree {
6310 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6311 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6312 self.set_context_stop(&mut context, token);
6313 }
6314 let node = self.rule_node(context);
6315 self.exit_rule();
6316 self.release_tree_scratch_if_idle();
6317 node
6318 }
6319
6320 pub fn recover_generated_rule(
6327 &mut self,
6328 context: &mut ParserRuleContext,
6329 atn: &Atn,
6330 error: AntlrError,
6331 ) {
6332 let diagnostic = self.generated_rule_error_diagnostic(error);
6333 self.push_generated_parser_diagnostic(diagnostic);
6334 self.generated_sync_expected = None;
6335 let error_index = self.input.index();
6336 let error_state = self.data.state();
6337 if self.generated_recovery_error_index == Some(error_index)
6342 && self.generated_recovery_error_states.contains(&error_state)
6343 && self.la(1) != TOKEN_EOF
6344 && let Some(token) = self.input.lt_id(1)
6345 {
6346 self.consume();
6347 let child = self.error_tree(token);
6348 self.add_parse_child(context, child);
6349 }
6350 let recovery_index = self.input.index();
6351 if self.generated_recovery_error_index != Some(recovery_index) {
6352 self.generated_recovery_error_index = Some(recovery_index);
6353 self.generated_recovery_error_states.clear();
6354 }
6355 self.generated_recovery_error_states.insert(error_state);
6356 let recovery_symbols = self.context_expected_symbols(atn);
6357 loop {
6358 let symbol = self.la(1);
6359 if symbol == TOKEN_EOF || recovery_symbols.contains(&symbol) {
6360 break;
6361 }
6362 let Some(token) = self.input.lt_id(1) else {
6363 break;
6364 };
6365 self.consume();
6366 let child = self.error_tree(token);
6367 self.add_parse_child(context, child);
6368 }
6369 self.record_syntax_errors(1);
6370 }
6371
6372 fn reset_generated_recovery_state(&mut self) {
6373 if self.generated_recovery_error_index.is_some() {
6374 self.generated_recovery_error_index = None;
6375 self.generated_recovery_error_states.clear();
6376 }
6377 }
6378
6379 fn push_generated_parser_diagnostic(&mut self, diagnostic: ParserDiagnostic) {
6380 if self
6381 .generated_parser_diagnostics
6382 .iter()
6383 .any(|existing| existing == &diagnostic)
6384 {
6385 return;
6386 }
6387 self.generated_parser_diagnostics.push(diagnostic);
6388 }
6389
6390 fn generated_rule_error_diagnostic(&self, error: AntlrError) -> ParserDiagnostic {
6391 match error {
6392 AntlrError::ParserError {
6396 line,
6397 column,
6398 message,
6399 offending,
6400 } => ParserDiagnostic {
6401 line,
6402 column,
6403 message,
6404 offending,
6405 },
6406 AntlrError::MismatchedInput { expected, found } => diagnostic_for_token(
6407 self.input.lt(1),
6408 format!("mismatched input {found} expecting {expected}"),
6409 ),
6410 AntlrError::NoViableAlternative { input } => diagnostic_for_token(
6411 self.input.lt(1),
6412 format!("no viable alternative at input {input}"),
6413 ),
6414 AntlrError::LexerError {
6415 line,
6416 column,
6417 message,
6418 } => ParserDiagnostic {
6419 line,
6420 column,
6421 message,
6422 offending: None,
6423 },
6424 AntlrError::Unsupported(message) => diagnostic_for_token(self.input.lt(1), message),
6425 }
6426 }
6427
6428 pub fn finish_recursion_rule(
6430 &mut self,
6431 mut context: ParserRuleContext,
6432 consumed_eof: bool,
6433 ) -> ParseTree {
6434 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
6435 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index)) {
6436 self.set_context_stop(&mut context, token);
6437 }
6438 let node = self.rule_node(context);
6439 self.unroll_recursion_context();
6440 self.release_tree_scratch_if_idle();
6441 node
6442 }
6443
6444 pub fn enter_recursion_rule(
6446 &mut self,
6447 state: isize,
6448 rule_index: usize,
6449 precedence: i32,
6450 ) -> ParserRuleContext {
6451 self.precedence_stack.push(precedence);
6452 self.recursion_expansion_marks
6453 .push(self.recursion_expansions);
6454 self.enter_rule(state, rule_index)
6455 }
6456
6457 pub fn push_new_recursion_context(
6459 &mut self,
6460 state: isize,
6461 rule_index: usize,
6462 ) -> ParserRuleContext {
6463 self.set_state(state);
6464 self.recursion_expansions += 1;
6467 ParserRuleContext::new(rule_index, state)
6468 }
6469
6470 pub fn push_new_recursion_context_with_previous(
6473 &mut self,
6474 state: isize,
6475 rule_index: usize,
6476 current: &mut ParserRuleContext,
6477 ) {
6478 self.set_state(state);
6479 self.recursion_expansions += 1;
6485 if let Some(stop) = self
6486 .rule_stop_token_index(self.input.index(), false)
6487 .and_then(|index| self.token_id_at(index))
6488 {
6489 self.set_context_stop(current, stop);
6490 }
6491 let invoking_state = current.invoking_state();
6492 let start = current.start_id();
6493 let mut replacement = ParserRuleContext::new(rule_index, invoking_state);
6494 if start.is_some() {
6495 replacement.set_start_from_context(current);
6496 }
6497 let previous = std::mem::replace(current, replacement);
6498 if self.build_parse_trees {
6499 let previous = self.rule_node(previous);
6500 self.tree.add_child(current, previous);
6501 }
6502 }
6503
6504 pub fn unroll_recursion_context(&mut self) {
6506 if self.precedence_stack.len() > 1 {
6507 self.precedence_stack.pop();
6508 }
6509 if let Some(mark) = self.recursion_expansion_marks.pop() {
6515 self.recursion_expansions = mark;
6516 }
6517 self.exit_rule();
6518 }
6519
6520 pub fn left_recursive_loop_enter_prediction(
6534 &mut self,
6535 atn: &Atn,
6536 state_number: usize,
6537 precedence: i32,
6538 ) -> Option<bool> {
6539 let symbol = self.la(1);
6540 if symbol == TOKEN_EOF {
6541 return Some(false);
6542 }
6543 let operator_lookahead =
6544 Self::cached_left_recursive_operator_lookahead(atn, state_number, precedence);
6545 let can_single = operator_lookahead.single_token.contains(symbol);
6546 let can_multi = operator_lookahead.multi_token_prefix.contains(symbol);
6547 let can_predicate = operator_lookahead.predicate_dependent.contains(symbol);
6548 if !can_single && !can_multi && !can_predicate {
6549 return Some(false);
6550 }
6551 if can_predicate && !can_single {
6552 return None;
6553 }
6554 if !can_single && can_multi && precedence > 0 {
6558 let baseline = Self::cached_left_recursive_operator_lookahead(atn, state_number, 0);
6559 if baseline.single_token.contains(symbol) {
6560 return None;
6561 }
6562 }
6563 let atn_key = SharedAtnCacheKey::for_atn(atn);
6564 let cached_overlap = self
6565 .left_recursive_caller_overlap_cache
6566 .iter()
6567 .flatten()
6568 .find(|entry| {
6569 entry.atn_key == atn_key
6570 && entry.state_number == state_number
6571 && entry.symbol == symbol
6572 && entry.context_version == self.rule_context_version
6573 })
6574 .map(|entry| entry.overlaps);
6575 let caller_overlaps = cached_overlap.unwrap_or_else(|| {
6576 let overlaps = caller_context_can_match_symbol_before_state(
6577 atn,
6578 self.prediction_context_return_states(atn),
6579 state_number,
6580 symbol,
6581 );
6582 if let Some(slot) = self
6583 .left_recursive_caller_overlap_cache
6584 .iter_mut()
6585 .find(|slot| slot.is_none())
6586 {
6587 *slot = Some(LeftRecursiveCallerOverlap {
6588 atn_key,
6589 state_number,
6590 symbol,
6591 context_version: self.rule_context_version,
6592 overlaps,
6593 });
6594 }
6595 overlaps
6596 });
6597 if caller_overlaps {
6598 return None;
6599 }
6600 Some(true)
6601 }
6602
6603 fn cached_left_recursive_operator_lookahead(
6604 atn: &Atn,
6605 state_number: usize,
6606 precedence: i32,
6607 ) -> Rc<LeftRecursiveOperatorLookahead> {
6608 with_shared_atn_caches(atn, |cache| {
6609 let key = (state_number, precedence);
6610 if let Some(cached) = cache.left_recursive_operator_lookahead.get(&key) {
6611 return Rc::clone(cached);
6612 }
6613 let lookahead = Rc::new(left_recursive_operator_lookahead(
6614 atn,
6615 state_number,
6616 precedence,
6617 ));
6618 cache
6619 .left_recursive_operator_lookahead
6620 .insert(key, Rc::clone(&lookahead));
6621 lookahead
6622 })
6623 }
6624
6625 pub fn left_recursive_loop_enter_matches(
6628 &mut self,
6629 atn: &Atn,
6630 state_number: usize,
6631 precedence: i32,
6632 ) -> bool {
6633 self.left_recursive_loop_enter_prediction(atn, state_number, precedence) == Some(true)
6634 }
6635
6636 pub fn precpred(&self, precedence: i32) -> bool {
6638 precedence >= self.precedence_stack.last().copied().unwrap_or_default()
6639 }
6640
6641 pub fn parser_semantic_predicate_matches(
6644 &mut self,
6645 predicates: &[(usize, usize, ParserPredicate)],
6646 rule_index: usize,
6647 pred_index: usize,
6648 ) -> bool {
6649 self.parser_semantic_predicate_matches_inner(predicates, rule_index, pred_index, None)
6650 }
6651
6652 pub fn parser_semantic_predicate_matches_with_local(
6655 &mut self,
6656 predicates: &[(usize, usize, ParserPredicate)],
6657 rule_index: usize,
6658 pred_index: usize,
6659 local_int_arg: i32,
6660 ) -> bool {
6661 self.parser_semantic_predicate_matches_inner(
6662 predicates,
6663 rule_index,
6664 pred_index,
6665 Some((rule_index, i64::from(local_int_arg))),
6666 )
6667 }
6668
6669 fn parser_semantic_predicate_matches_inner(
6670 &mut self,
6671 predicates: &[(usize, usize, ParserPredicate)],
6672 rule_index: usize,
6673 pred_index: usize,
6674 local_int_arg: Option<(usize, i64)>,
6675 ) -> bool {
6676 let index = self.input.index();
6677 let member_values = self.int_members.clone();
6678 self.parser_predicate_matches(PredicateEval {
6679 index,
6680 rule_index,
6681 pred_index,
6682 predicates,
6683 semantics: None,
6684 context: None,
6685 local_int_arg,
6686 member_values: &member_values,
6687 })
6688 }
6689
6690 pub fn parser_semantic_predicate_matches_with_context_and_local(
6693 &mut self,
6694 predicates: &[(usize, usize, ParserPredicate)],
6695 rule_index: usize,
6696 pred_index: usize,
6697 context: &ParserRuleContext,
6698 local_int_arg: i32,
6699 ) -> bool {
6700 let index = self.input.index();
6701 let member_values = self.int_members.clone();
6702 self.parser_predicate_matches(PredicateEval {
6703 index,
6704 rule_index,
6705 pred_index,
6706 predicates,
6707 semantics: None,
6708 context: Some(context),
6709 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6710 member_values: &member_values,
6711 })
6712 }
6713
6714 pub fn parser_semantic_ir_predicate_matches_with_context_and_local(
6717 &mut self,
6718 semantics: &ParserSemantics,
6719 rule_index: usize,
6720 pred_index: usize,
6721 context: &ParserRuleContext,
6722 local_int_arg: i32,
6723 ) -> bool {
6724 let index = self.input.index();
6725 let member_values = self.int_members.clone();
6726 self.parser_predicate_matches(PredicateEval {
6727 index,
6728 rule_index,
6729 pred_index,
6730 predicates: &[],
6731 semantics: Some(semantics),
6732 context: Some(context),
6733 local_int_arg: Some((rule_index, i64::from(local_int_arg))),
6734 member_values: &member_values,
6735 })
6736 }
6737
6738 pub fn parser_semantic_predicate_failure_message(
6741 &self,
6742 rule_index: usize,
6743 pred_index: usize,
6744 predicates: &[(usize, usize, ParserPredicate)],
6745 ) -> Option<&'static str> {
6746 self.parser_predicate_failure_message(rule_index, pred_index, predicates)
6747 }
6748
6749 pub fn match_wildcard(&mut self) -> Result<ParseTree, AntlrError> {
6751 let current = self.input.lt_id(1).ok_or_else(|| AntlrError::ParserError {
6752 line: 0,
6753 column: 0,
6754 message: "missing current token".to_owned(),
6755 offending: None,
6756 })?;
6757 if self.token_type_for_id(current) == TOKEN_EOF {
6758 return Err(AntlrError::MismatchedInput {
6759 expected: "wildcard".to_owned(),
6760 found: self.vocabulary().display_name(TOKEN_EOF),
6761 });
6762 }
6763 self.reset_generated_recovery_state();
6764 self.consume();
6765 Ok(self.terminal_tree(current))
6766 }
6767
6768 #[allow(clippy::unnecessary_wraps)]
6772 pub fn sync(&mut self, state: isize) -> Result<(), AntlrError> {
6773 self.set_state(state);
6774 Ok(())
6775 }
6776
6777 pub fn sync_decision(
6785 &mut self,
6786 atn: &Atn,
6787 state_number: usize,
6788 current_context_empty: bool,
6789 loop_back: bool,
6790 ) -> Result<Vec<ParseTree>, AntlrError> {
6791 self.set_state(isize::try_from(state_number).unwrap_or(isize::MAX));
6792 self.generated_sync_expected = None;
6793 let Some(state) = atn.state(state_number) else {
6794 return Ok(Vec::new());
6795 };
6796 let Some(rule_index) = state.rule_index() else {
6797 return Ok(Vec::new());
6798 };
6799 let Some(rule_stop) = atn.rule_to_stop_state().get(rule_index) else {
6800 return Ok(Vec::new());
6801 };
6802 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6803 let symbol = self.la(1);
6804 let mut has_expected_symbols = false;
6805 let mut nullable = false;
6806 let mut explicit_eof_expected = false;
6814 for transition in &entry.transitions {
6815 if transition.symbols.contains(symbol) {
6816 return Ok(Vec::new());
6817 }
6818 has_expected_symbols |= !transition.symbols.is_empty();
6819 nullable |= transition.nullable;
6820 explicit_eof_expected |= transition.symbols.contains(TOKEN_EOF);
6821 }
6822 if nullable && self.context_expected_contains(atn, symbol) {
6827 return Ok(Vec::new());
6828 }
6829 let context_expected = nullable.then(|| self.context_expected_token_set(atn));
6830 if !has_expected_symbols && context_expected.as_ref().is_none_or(TokenBitSet::is_empty) {
6831 return Ok(Vec::new());
6832 }
6833 let mut expected = TokenBitSet::default();
6834 for transition in &entry.transitions {
6835 expected.extend_from(&transition.symbols);
6836 }
6837 if let Some(context_expected) = context_expected {
6838 expected.extend_from(&context_expected);
6839 }
6840 let can_delete_in_place =
6841 !(nullable && current_context_empty && self.rule_context_stack.len() > 1);
6842 let loop_sync = loop_back;
6859 if symbol != TOKEN_EOF && can_delete_in_place {
6860 let mut cursor = self.input.index();
6861 let mut skipped = Vec::new();
6862 loop {
6863 let current = self.token_type_at(cursor);
6864 if current == TOKEN_EOF {
6865 break;
6866 }
6867 skipped.push(cursor);
6868 let next = self.consume_index(cursor, current);
6869 if next == cursor {
6870 break;
6871 }
6872 let next_symbol = self.token_type_at(next);
6873 let next_is_expected_stop = if next_symbol == TOKEN_EOF {
6881 explicit_eof_expected
6882 } else {
6883 expected.contains(next_symbol)
6884 };
6885 if next_is_expected_stop {
6886 let current_token = self.input.lt(1);
6887 let expected_symbols = expected.to_btree_set();
6888 let message = format!(
6889 "extraneous input {} expecting {}",
6890 current_token
6891 .as_ref()
6892 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6893 self.expected_symbols_display(&expected_symbols)
6894 );
6895 self.push_generated_parser_diagnostic(diagnostic_for_token(
6896 current_token,
6897 message,
6898 ));
6899 self.record_syntax_errors(1);
6900 let mut children = Vec::with_capacity(skipped.len());
6901 for index in skipped {
6902 if let Some(token) = self.token_id_at(index) {
6903 self.consume();
6904 children.push(self.error_tree(token));
6905 }
6906 }
6907 if !loop_sync {
6908 self.reset_generated_recovery_state();
6909 }
6910 return Ok(children);
6911 }
6912 if !loop_sync {
6916 break;
6917 }
6918 cursor = next;
6919 }
6920 }
6921 if nullable {
6922 self.generated_sync_expected = Some(expected);
6923 return Ok(Vec::new());
6924 }
6925 let current = self.input.lt(1);
6926 let expected_symbols = expected.to_btree_set();
6927 Err(AntlrError::ParserError {
6928 line: current.as_ref().map(Token::line).unwrap_or_default(),
6929 column: current.as_ref().map(Token::column).unwrap_or_default(),
6930 message: format!(
6931 "mismatched input {} expecting {}",
6932 current
6933 .as_ref()
6934 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
6935 self.expected_symbols_display(&expected_symbols)
6936 ),
6937 offending: current.as_ref().map(Token::token_id),
6938 })
6939 }
6940
6941 pub fn ll1_decision_prediction(
6948 &mut self,
6949 atn: &Atn,
6950 state_number: usize,
6951 ) -> Option<ParserAtnPrediction> {
6952 let state = atn.state(state_number)?;
6953 if state.precedence_rule_decision() {
6954 return None;
6955 }
6956 let rule_stop = state
6957 .rule_index()
6958 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))?;
6959 let symbol = self.la(1);
6960 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
6961 ll1_greedy_alt(&entry, symbol, state.non_greedy()).map(|alt| ParserAtnPrediction {
6962 alt: alt + 1,
6963 requires_full_context: false,
6964 has_semantic_context: false,
6965 diagnostic: None,
6966 })
6967 }
6968
6969 fn context_expected_symbols(&mut self, atn: &Atn) -> BTreeSet<i32> {
6970 let mut expected = BTreeSet::new();
6971 for index in (1..self.rule_context_stack.len()).rev() {
6972 let invoking_state = self.rule_context_stack[index].invoking_state;
6973 let Ok(state_number) = usize::try_from(invoking_state) else {
6974 continue;
6975 };
6976 let Some(Transition::Rule { follow_state, .. }) = atn
6977 .state(state_number)
6978 .and_then(|state| state.transitions().first())
6979 .map(ParserTransition::data)
6980 else {
6981 continue;
6982 };
6983 let return_state = follow_state;
6984 expected.extend(self.cached_state_expected_symbols(atn, return_state).iter());
6985 if !self.cached_state_can_reach_rule_stop(atn, return_state) {
6986 return expected;
6987 }
6988 }
6989 expected.insert(TOKEN_EOF);
6990 expected
6991 }
6992
6993 fn context_expected_token_set(&mut self, atn: &Atn) -> TokenBitSet {
6994 let mut expected = TokenBitSet::default();
6995 for index in (1..self.rule_context_stack.len()).rev() {
6996 let invoking_state = self.rule_context_stack[index].invoking_state;
6997 let Ok(state_number) = usize::try_from(invoking_state) else {
6998 continue;
6999 };
7000 let Some(Transition::Rule { follow_state, .. }) = atn
7001 .state(state_number)
7002 .and_then(|state| state.transitions().first())
7003 .map(ParserTransition::data)
7004 else {
7005 continue;
7006 };
7007 expected.extend_from(&self.cached_state_expected_token_set(atn, follow_state));
7008 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7009 return expected;
7010 }
7011 }
7012 expected.insert(TOKEN_EOF);
7013 expected
7014 }
7015
7016 fn context_expected_contains(&mut self, atn: &Atn, symbol: i32) -> bool {
7027 for index in (1..self.rule_context_stack.len()).rev() {
7028 let invoking_state = self.rule_context_stack[index].invoking_state;
7029 let Ok(state_number) = usize::try_from(invoking_state) else {
7030 continue;
7031 };
7032 let Some(Transition::Rule { follow_state, .. }) = atn
7033 .state(state_number)
7034 .and_then(|state| state.transitions().first())
7035 .map(ParserTransition::data)
7036 else {
7037 continue;
7038 };
7039 if self
7040 .cached_state_expected_token_set(atn, follow_state)
7041 .contains(symbol)
7042 {
7043 return true;
7044 }
7045 if !self.cached_state_can_reach_rule_stop(atn, follow_state) {
7046 return false;
7047 }
7048 }
7049 symbol == TOKEN_EOF
7050 }
7051
7052 pub fn no_viable_alternative_error(&self, start_index: usize) -> AntlrError {
7054 let error_index = self.input.index();
7055 self.no_viable_alternative_error_at(start_index, error_index)
7056 }
7057
7058 pub fn no_viable_alternative_error_at(
7063 &self,
7064 start_index: usize,
7065 error_index: usize,
7066 ) -> AntlrError {
7067 let diagnostic = self.no_viable_alternative(start_index, error_index);
7068 AntlrError::ParserError {
7069 line: diagnostic.line,
7070 column: diagnostic.column,
7071 message: diagnostic.message,
7072 offending: diagnostic.offending,
7073 }
7074 }
7075
7076 pub fn failed_predicate_error(&self, message: impl Into<String>) -> AntlrError {
7078 let current = self.input.lt(1);
7079 AntlrError::ParserError {
7080 line: current.as_ref().map(Token::line).unwrap_or_default(),
7081 column: current.as_ref().map(Token::column).unwrap_or_default(),
7082 message: format!("rule failed predicate: {}", message.into()),
7083 offending: current.as_ref().map(Token::token_id),
7084 }
7085 }
7086
7087 pub fn failed_predicate_option_error(
7090 &self,
7091 rule_index: usize,
7092 message: impl Into<String>,
7093 ) -> AntlrError {
7094 let current = self.input.lt(1);
7095 let rule_name = self
7096 .rule_names()
7097 .get(rule_index)
7098 .map_or_else(|| rule_index.to_string(), Clone::clone);
7099 AntlrError::ParserError {
7100 line: current.as_ref().map(Token::line).unwrap_or_default(),
7101 column: current.as_ref().map(Token::column).unwrap_or_default(),
7102 message: format!("rule {rule_name} {}", message.into()),
7103 offending: current.as_ref().map(Token::token_id),
7104 }
7105 }
7106
7107 pub fn parser_action_at_current(
7109 &mut self,
7110 source_state: usize,
7111 rule_index: usize,
7112 start_index: usize,
7113 consumed_eof: bool,
7114 ) -> ParserAction {
7115 let stop_index = self.rule_stop_token_index(self.input.index(), consumed_eof);
7116 ParserAction::new(source_state, rule_index, start_index, stop_index)
7117 }
7118
7119 pub fn parser_action_hook(&mut self, action: ParserAction, tree: ParseTree) -> bool {
7124 let rule_index = action.rule_index();
7125 let rule_name = self.rule_names().get(rule_index).cloned();
7126 let context = None;
7127 let input = &mut self.input;
7128 let semantic_hooks = &mut self.semantic_hooks;
7129 let member_values = &self.int_members;
7130 let mut ctx = ParserSemCtx {
7131 input,
7132 tree_storage: &self.tree,
7133 rule_index,
7134 coordinate_index: usize::MAX,
7135 rule_name,
7136 context,
7137 tree: Some(tree),
7138 local_int_arg: None,
7139 member_values,
7140 action: Some(action),
7141 };
7142 let handled = semantic_hooks.action(&mut ctx, action);
7143 if !handled && matches!(self.unknown_predicate_policy, UnknownSemanticPolicy::Error) {
7149 let coordinate = (rule_index, action.source_state());
7150 if !self.unhandled_action_hits.contains(&coordinate) {
7151 self.unhandled_action_hits.push(coordinate);
7152 }
7153 }
7154 handled
7155 }
7156
7157 pub fn parse_atn_rule_adaptive_or_fallback<'atn>(
7162 &mut self,
7163 atn: &'atn Atn,
7164 simulator: &mut ParserAtnSimulator<'atn>,
7165 rule_index: usize,
7166 ) -> Result<ParseTree, AntlrError> {
7167 let start_index = self.current_visible_index();
7168 self.clear_prediction_diagnostics();
7169 self.reset_per_parse_caches();
7170 self.reset_recognition_arena();
7171 let tree_checkpoint = self.tree.checkpoint();
7172 let mut decision_by_state = vec![None; atn.states().len()];
7173 for (decision, state_number) in atn.decision_to_state().iter().enumerate() {
7174 if let Some(slot) = decision_by_state.get_mut(state_number) {
7175 *slot = Some(decision);
7176 }
7177 }
7178
7179 let result = DirectAdaptiveParser {
7180 parser: self,
7181 atn,
7182 simulator,
7183 decision_by_state,
7184 steps: 0,
7185 }
7186 .parse_rule(rule_index, -1, 0);
7187
7188 match result {
7189 Ok(tree) => {
7190 self.report_token_source_errors();
7191 self.release_tree_scratch_if_idle();
7192 Ok(tree)
7193 }
7194 Err(DirectAdaptiveParseControl::Fallback(reason)) => {
7195 let _ = reason;
7196 self.tree.rollback(tree_checkpoint);
7197 self.input.seek(start_index);
7198 self.parse_atn_rule(atn, rule_index)
7199 }
7200 }
7201 }
7202
7203 pub fn parse_atn_rule(
7213 &mut self,
7214 atn: &Atn,
7215 rule_index: usize,
7216 ) -> Result<ParseTree, AntlrError> {
7217 self.parse_atn_rule_with_precedence(atn, rule_index, 0)
7218 }
7219
7220 pub fn parse_atn_rule_with_precedence(
7223 &mut self,
7224 atn: &Atn,
7225 rule_index: usize,
7226 precedence: i32,
7227 ) -> Result<ParseTree, AntlrError> {
7228 self.parse_atn_rule_with_precedence_inner(
7229 atn,
7230 rule_index,
7231 precedence,
7232 None,
7233 AltNumberTracking::default(),
7234 )
7235 }
7236
7237 fn parse_atn_rule_with_precedence_inner(
7238 &mut self,
7239 atn: &Atn,
7240 rule_index: usize,
7241 precedence: i32,
7242 predicate_context: Option<FastPredicateContext<'_>>,
7243 alt_tracking: AltNumberTracking,
7244 ) -> Result<ParseTree, AntlrError> {
7245 let report_unrecovered_error = self.is_top_level_entry();
7246 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7247 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7248 })?;
7249 let stop_state = atn
7250 .rule_to_stop_state()
7251 .get(rule_index)
7252 .filter(|state| *state != usize::MAX)
7253 .ok_or_else(|| {
7254 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7255 })?;
7256
7257 let start_index = self.current_visible_index();
7258 self.clear_prediction_diagnostics();
7259 self.reset_per_parse_caches();
7260 self.reset_recognition_arena();
7261 let caller_follow_state = self.pending_invoking_follow_state(atn);
7262 self.fast_recovery_enabled = false;
7263 self.fast_token_nodes_enabled = false;
7264 self.fast_track_alt_numbers = alt_tracking.any();
7265 let top_request = FastRecognizeTopRequest {
7266 start_state,
7267 stop_state,
7268 start_index,
7269 precedence,
7270 caller_follow_state,
7271 };
7272 let first_pass = self.fast_recognize_top(atn, top_request, predicate_context);
7273 self.fast_token_nodes_enabled = self.build_parse_trees;
7274 let needs_tree_retry = matches!(
7275 &first_pass,
7276 Ok((outcome, _, _))
7277 if self.build_parse_trees
7278 && self
7279 .recognition_arena
7280 .sequence_has_left_recursive_boundary(outcome.nodes)
7281 );
7282 let needs_retry = match &first_pass {
7283 Err(_) => true,
7296 Ok((outcome, _, _)) => !outcome.diagnostics.is_empty() || needs_tree_retry,
7297 };
7298 let (outcome, _expected, alt_number) = if needs_retry {
7299 self.fast_first_set_prefilter = false;
7300 self.fast_recovery_enabled = false;
7301 let clean_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7302 let clean_selected = if needs_tree_retry {
7303 match clean_retry {
7304 ok @ Ok(_) => ok,
7305 Err(_) => first_pass,
7306 }
7307 } else {
7308 select_better_top_outcome(first_pass, clean_retry, &self.recognition_arena)
7309 };
7310 let selected = if clean_selected.is_err()
7311 || matches!(&clean_selected, Ok((outcome, _, _)) if !outcome.diagnostics.is_empty())
7312 {
7313 self.fast_recovery_enabled = true;
7314 let recovery_retry = self.fast_recognize_top(atn, top_request, predicate_context);
7315 select_better_top_outcome(clean_selected, recovery_retry, &self.recognition_arena)
7316 } else {
7317 clean_selected
7318 };
7319 self.fast_first_set_prefilter = true;
7320 self.fast_recovery_enabled = true;
7321 selected.map_err(|expected| {
7322 if predicate_context.is_some()
7323 && let Some(error) = self.unknown_semantic_error()
7324 {
7325 self.report_token_source_errors();
7326 return error;
7327 }
7328 let error = self.recognition_error(rule_index, start_index, &expected);
7329 self.record_syntax_errors(1);
7330 self.report_token_source_errors();
7331 if report_unrecovered_error {
7332 self.report_unrecovered_parser_error(&error);
7333 }
7334 error
7335 })?
7336 } else {
7337 first_pass.expect("first_pass is Ok in the no-retry branch")
7338 };
7339 if predicate_context.is_some()
7340 && let Some(error) = self.unknown_semantic_error()
7341 {
7342 self.report_token_source_errors();
7343 return Err(error);
7344 }
7345 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7346 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7347 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7348 self.report_token_source_errors();
7349 let mut context = ParserRuleContext::with_child_capacity(
7350 rule_index,
7351 self.state(),
7352 if self.build_parse_trees {
7353 self.recognition_arena.sequence_len(outcome.nodes)
7354 } else {
7355 0
7356 },
7357 );
7358 if alt_tracking.public {
7359 context.set_alt_number(alt_number.max(1));
7360 }
7361 if alt_tracking.context {
7362 context.set_context_alt_number(alt_number);
7363 }
7364 if let Some(token) = self.token_id_at(start_index) {
7365 self.set_context_start(&mut context, token);
7366 }
7367 let stop_index = self.rule_stop_token_index(outcome.index, outcome.consumed_eof);
7368 if let Some(token) = stop_index.and_then(|token_index| self.token_id_at(token_index)) {
7369 self.set_context_stop(&mut context, token);
7370 }
7371 let live_root = if self.build_parse_trees {
7372 self.recognition_arena
7373 .fold_left_recursive_boundaries(outcome.nodes)
7374 } else {
7375 outcome.nodes
7376 };
7377 if self.build_parse_trees {
7378 if self
7379 .recognition_arena
7380 .sequence_has_explicit_token(live_root)
7381 {
7382 let mut cursor = live_root;
7383 while let Some(link) = self.recognition_arena.link(cursor) {
7384 let child = self.arena_recognized_node_tree(
7385 link.head,
7386 alt_tracking.public,
7387 alt_tracking.context,
7388 )?;
7389 self.tree.add_child(&mut context, child);
7390 cursor = link.tail;
7391 }
7392 } else {
7393 self.add_arena_implicit_token_children(
7394 &mut context,
7395 start_index,
7396 stop_index,
7397 live_root,
7398 alt_tracking,
7399 )?;
7400 }
7401 }
7402 self.finish_recognition_arena(live_root, outcome.diagnostics);
7403 self.input.seek(outcome.index);
7404
7405 let tree = self.rule_node(context);
7406 self.release_tree_scratch_if_idle();
7407 Ok(tree)
7408 }
7409
7410 fn pending_invoking_follow_state(&self, atn: &Atn) -> Option<usize> {
7411 let invoking_state = self.pending_invoking_states.last().copied()?;
7412 let state_number = usize::try_from(invoking_state).ok()?;
7413 match atn.state(state_number)?.transitions().first()?.data() {
7414 Transition::Rule { follow_state, .. } => Some(follow_state),
7415 _ => None,
7416 }
7417 }
7418
7419 #[cfg(test)]
7420 fn caller_follow_token_info(&mut self, index: usize) -> (i32, bool, bool) {
7421 caller_follow_token_info_for_stream(&mut self.input, index)
7422 }
7423
7424 fn fast_recognize_top(
7429 &mut self,
7430 atn: &Atn,
7431 request: FastRecognizeTopRequest,
7432 predicate_context: Option<FastPredicateContext<'_>>,
7433 ) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
7434 let FastRecognizeTopRequest {
7435 start_state,
7436 stop_state,
7437 start_index,
7438 precedence,
7439 caller_follow_state,
7440 } = request;
7441 let memo_capacity = fast_recognize_memo_capacity(self.input.size());
7450 let mut recognize_scratch = std::mem::take(&mut self.fast_recognize_scratch);
7451 recognize_scratch.prepare(memo_capacity);
7452 let mut expected = ExpectedTokens::default();
7453 let empty_recovery = self.empty_recovery_symbols();
7454 let outcomes = self.recognize_state_fast(
7455 atn,
7456 FastRecognizeRequest {
7457 state_number: start_state,
7458 stop_state,
7459 index: start_index,
7460 rule_start_index: start_index,
7461 decision_start_index: None,
7462 precedence,
7463 depth: 0,
7464 recovery_symbols: empty_recovery,
7465 recovery_state: None,
7466 },
7467 FastRecognizeScratch {
7468 predicate_context,
7469 visiting: &mut recognize_scratch.visiting,
7470 memo: &mut recognize_scratch.memo,
7471 expected: &mut expected,
7472 native_depth: 0,
7473 },
7474 );
7475 recognize_scratch.release_oversized_memo();
7476 self.fast_recognize_scratch = recognize_scratch;
7477 #[cfg(feature = "perf-counters")]
7478 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
7479 perf_counters::dump();
7480 perf_counters::reset();
7481 }
7482 let caller_follow =
7483 caller_follow_state.map(|state| self.cached_state_expected_token_set(atn, state));
7484 let selected = {
7485 let arena = &self.recognition_arena;
7486 let input = &mut self.input;
7487 select_best_fast_outcome(
7488 outcomes.into_iter(),
7489 self.prediction_mode,
7490 caller_follow.as_deref(),
7491 |index| caller_follow_token_info_for_stream(input, index),
7492 arena,
7493 )
7494 };
7495 match selected {
7496 Some(mut outcome) => {
7497 let alt_number = if self.build_parse_trees || self.fast_track_alt_numbers {
7498 self.materialize_fast_outcome_nodes(&mut outcome)
7499 } else {
7500 0
7501 };
7502 Ok((outcome, expected, alt_number))
7503 }
7504 None => Err(expected),
7505 }
7506 }
7507
7508 fn arena_recognized_node_tree(
7510 &mut self,
7511 node_id: RecognizedNodeId,
7512 track_alt_numbers: bool,
7513 track_context_alt_numbers: bool,
7514 ) -> Result<ParseTree, AntlrError> {
7515 let node = self.recognition_arena.node(node_id);
7516 match node {
7517 ArenaRecognizedNode::Token { token } => Ok(self.terminal_tree(token)),
7518 ArenaRecognizedNode::ErrorToken { token } => Ok(self.error_tree(token)),
7519 ArenaRecognizedNode::MissingToken { extra } => {
7520 let (token_type, at_index, text) = match self.recognition_arena.extra(extra) {
7521 RecognitionExtra::MissingToken {
7522 token_type,
7523 at_index,
7524 text,
7525 } => (*token_type, *at_index as usize, text.clone()),
7526 RecognitionExtra::ReturnValues(_) | RecognitionExtra::Diagnostic(_) => {
7527 unreachable!("missing-token node must reference missing-token extra")
7528 }
7529 };
7530 let (line, column) = self
7531 .token_at(at_index)
7532 .map_or((0, 0), |token| (token.line(), token.column()));
7533 let token = self.insert_synthetic_token(token_type, text, line, column)?;
7534 Ok(self.error_tree(token))
7535 }
7536 ArenaRecognizedNode::Rule {
7537 rule_index,
7538 invoking_state,
7539 alt_number,
7540 start_index,
7541 stop_index,
7542 return_values,
7543 children,
7544 } => {
7545 let mut context = ParserRuleContext::with_child_capacity(
7546 rule_index as usize,
7547 invoking_state as isize,
7548 self.recognition_arena.sequence_len(children),
7549 );
7550 if track_alt_numbers {
7551 context.set_alt_number((alt_number as usize).max(1));
7552 }
7553 if track_context_alt_numbers {
7554 context.set_context_alt_number(alt_number as usize);
7555 }
7556 if let Some(extra) = return_values {
7557 let RecognitionExtra::ReturnValues(values) =
7558 self.recognition_arena.extra(extra)
7559 else {
7560 unreachable!("rule node must reference return-values extra");
7561 };
7562 for (name, value) in values {
7563 context.set_int_return(name.clone(), *value);
7564 }
7565 }
7566 if let Some(token) = self.token_id_at(start_index as usize) {
7567 self.set_context_start(&mut context, token);
7568 }
7569 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7570 self.set_context_stop(&mut context, token);
7571 }
7572 let mut cursor = self
7573 .recognition_arena
7574 .fold_left_recursive_boundaries(children);
7575 while let Some(link) = self.recognition_arena.link(cursor) {
7576 let child = self.arena_recognized_node_tree(
7577 link.head,
7578 track_alt_numbers,
7579 track_context_alt_numbers,
7580 )?;
7581 self.tree.add_child(&mut context, child);
7582 cursor = link.tail;
7583 }
7584 Ok(self.rule_node(context))
7585 }
7586 ArenaRecognizedNode::LeftRecursiveBoundary { rule_index, .. } => {
7587 Err(AntlrError::Unsupported(format!(
7588 "unfolded left-recursive boundary for rule {rule_index}"
7589 )))
7590 }
7591 }
7592 }
7593
7594 fn arena_recognized_node_tree_with_implicit_tokens(
7595 &mut self,
7596 node_id: RecognizedNodeId,
7597 alt_tracking: AltNumberTracking,
7598 ) -> Result<ParseTree, AntlrError> {
7599 let node = self.recognition_arena.node(node_id);
7600 match node {
7601 ArenaRecognizedNode::Rule {
7602 rule_index,
7603 invoking_state,
7604 alt_number,
7605 start_index,
7606 stop_index,
7607 children,
7608 ..
7609 } => {
7610 let mut context = ParserRuleContext::with_child_capacity(
7611 rule_index as usize,
7612 invoking_state as isize,
7613 self.recognition_arena.sequence_len(children),
7614 );
7615 if alt_tracking.public {
7616 context.set_alt_number((alt_number as usize).max(1));
7617 }
7618 if alt_tracking.context {
7619 context.set_context_alt_number(alt_number as usize);
7620 }
7621 if let Some(token) = self.token_id_at(start_index as usize) {
7622 self.set_context_start(&mut context, token);
7623 }
7624 if let Some(token) = stop_index.and_then(|index| self.token_id_at(index as usize)) {
7625 self.set_context_stop(&mut context, token);
7626 }
7627 let children = self
7628 .recognition_arena
7629 .fold_left_recursive_boundaries(children);
7630 self.add_arena_implicit_token_children(
7631 &mut context,
7632 start_index as usize,
7633 stop_index.map(|index| index as usize),
7634 children,
7635 alt_tracking,
7636 )?;
7637 Ok(self.rule_node(context))
7638 }
7639 _ => {
7640 self.arena_recognized_node_tree(node_id, alt_tracking.public, alt_tracking.context)
7641 }
7642 }
7643 }
7644
7645 fn add_arena_implicit_token_children(
7646 &mut self,
7647 context: &mut ParserRuleContext,
7648 start_index: usize,
7649 stop_index: Option<usize>,
7650 mut children: NodeSeqId,
7651 alt_tracking: AltNumberTracking,
7652 ) -> Result<(), AntlrError> {
7653 let mut cursor = Some(start_index);
7654 while let Some(link) = self.recognition_arena.link(children) {
7655 if let Some((child_start, child_stop)) = self.recognition_arena.node_span(link.head) {
7656 self.add_visible_terminals_before(context, &mut cursor, child_start)?;
7657 let child =
7658 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7659 self.tree.add_child(context, child);
7660 if let Some(child_stop) = child_stop {
7661 let next = self.next_visible_after_token(child_stop);
7662 cursor = match (cursor, next) {
7663 (None, _) | (_, None) => None,
7664 (Some(current), Some(next)) => Some(current.max(next)),
7665 };
7666 }
7667 } else {
7668 let child =
7669 self.arena_recognized_node_tree_with_implicit_tokens(link.head, alt_tracking)?;
7670 self.tree.add_child(context, child);
7671 }
7672 children = link.tail;
7673 }
7674 if let Some(stop) = stop_index {
7675 self.add_visible_terminals_through(context, cursor, stop)?;
7676 }
7677 Ok(())
7678 }
7679
7680 fn add_visible_terminals_before(
7681 &mut self,
7682 context: &mut ParserRuleContext,
7683 cursor: &mut Option<usize>,
7684 before: usize,
7685 ) -> Result<(), AntlrError> {
7686 let Some(stop) = before.checked_sub(1) else {
7687 return Ok(());
7688 };
7689 let next = self.add_visible_terminals_through(context, *cursor, stop)?;
7690 *cursor = next;
7691 Ok(())
7692 }
7693
7694 fn add_visible_terminals_through(
7695 &mut self,
7696 context: &mut ParserRuleContext,
7697 mut cursor: Option<usize>,
7698 stop: usize,
7699 ) -> Result<Option<usize>, AntlrError> {
7700 while let Some(index) = cursor {
7701 if index > stop {
7702 return Ok(Some(index));
7703 }
7704 let token = self
7705 .input
7706 .get_id(index)
7707 .ok_or_else(|| AntlrError::ParserError {
7708 line: 0,
7709 column: 0,
7710 message: format!("missing token at index {index}"),
7711 offending: None,
7712 })?;
7713 let is_eof = self.token_type_for_id(token) == TOKEN_EOF;
7714 let child = self.terminal_tree(token);
7715 self.tree.add_child(context, child);
7716 if is_eof {
7717 return Ok(None);
7718 }
7719 cursor = self.next_visible_after_token(index);
7720 }
7721 Ok(None)
7722 }
7723
7724 fn next_visible_after_token(&mut self, index: usize) -> Option<usize> {
7725 let next = self.input.next_visible_after(index);
7726 (next != index).then_some(next)
7727 }
7728
7729 pub fn parse_atn_rule_with_actions(
7736 &mut self,
7737 atn: &Atn,
7738 rule_index: usize,
7739 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7740 self.parse_atn_rule_with_action_options(atn, rule_index, &[], false)
7741 }
7742
7743 pub fn parse_atn_rule_with_action_inits(
7751 &mut self,
7752 atn: &Atn,
7753 rule_index: usize,
7754 init_action_rules: &[usize],
7755 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7756 self.parse_atn_rule_with_action_options(atn, rule_index, init_action_rules, false)
7757 }
7758
7759 pub fn parse_atn_rule_with_action_options(
7765 &mut self,
7766 atn: &Atn,
7767 rule_index: usize,
7768 init_action_rules: &[usize],
7769 track_alt_numbers: bool,
7770 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7771 self.parse_atn_rule_with_runtime_options(
7772 atn,
7773 rule_index,
7774 ParserRuntimeOptions {
7775 init_action_rules,
7776 track_alt_numbers,
7777 ..ParserRuntimeOptions::default()
7778 },
7779 )
7780 }
7781
7782 pub fn parse_atn_rule_with_runtime_options(
7789 &mut self,
7790 atn: &Atn,
7791 rule_index: usize,
7792 options: ParserRuntimeOptions<'_>,
7793 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7794 self.parse_atn_rule_with_runtime_options_and_precedence(atn, rule_index, 0, options)
7795 }
7796
7797 pub fn parse_atn_rule_with_runtime_options_and_precedence(
7800 &mut self,
7801 atn: &Atn,
7802 rule_index: usize,
7803 precedence: i32,
7804 options: ParserRuntimeOptions<'_>,
7805 ) -> Result<(ParseTree, Vec<ParserAction>), AntlrError> {
7806 let report_unrecovered_error = self.is_top_level_entry();
7807 let ParserRuntimeOptions {
7808 init_action_rules,
7809 track_alt_numbers,
7810 track_context_alt_numbers,
7811 predicates,
7812 semantics,
7813 rule_args,
7814 member_actions,
7815 return_actions,
7816 unknown_predicate_policy,
7817 } = options;
7818 let capture_alt_numbers = track_alt_numbers || track_context_alt_numbers;
7819 if init_action_rules.is_empty()
7820 && !capture_alt_numbers
7821 && predicates.is_empty()
7822 && semantics.is_none()
7823 && rule_args.is_empty()
7824 && member_actions.is_empty()
7825 && return_actions.is_empty()
7826 && unknown_predicate_policy == UnknownSemanticPolicy::AssumeTrue
7827 && !atn_has_observable_action_transitions(atn)
7828 && !self.semantic_hooks.observes_parser_decisions()
7829 && (!self.semantic_hooks.observes_parser_predicates()
7830 || !atn_has_predicate_transitions(atn))
7831 {
7832 return self
7833 .parse_atn_rule_with_precedence(atn, rule_index, precedence)
7834 .map(|tree| (tree, Vec::new()));
7835 }
7836 if !self.semantic_hooks.observes_parser_decisions()
7837 && can_use_fast_predicate_recognizer(atn, &options)
7838 {
7839 self.unknown_predicate_policy = unknown_predicate_policy;
7840 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7841 let member_values = self.int_members.clone();
7842 let result = self
7843 .parse_atn_rule_with_precedence_inner(
7844 atn,
7845 rule_index,
7846 precedence,
7847 Some(FastPredicateContext {
7848 predicates,
7849 semantics,
7850 member_values: &member_values,
7851 }),
7852 AltNumberTracking {
7853 public: track_alt_numbers,
7854 context: track_context_alt_numbers,
7855 },
7856 )
7857 .map(|tree| (tree, Vec::new()));
7858 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
7859 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7860 }
7861 return result;
7862 }
7863 self.unknown_predicate_policy = unknown_predicate_policy;
7864 let prior_unknown_predicate_hits = std::mem::take(&mut self.unknown_predicate_hits);
7871 let start_state = atn.rule_to_start_state().get(rule_index).ok_or_else(|| {
7872 AntlrError::Unsupported(format!("rule {rule_index} has no start state"))
7873 })?;
7874 let stop_state = atn
7875 .rule_to_stop_state()
7876 .get(rule_index)
7877 .filter(|state| *state != usize::MAX)
7878 .ok_or_else(|| {
7879 AntlrError::Unsupported(format!("rule {rule_index} has no stop state"))
7880 })?;
7881
7882 let start_index = self.current_visible_index();
7883 self.clear_prediction_diagnostics();
7884 self.reset_per_parse_caches();
7885 self.reset_recognition_arena();
7886 let init_action_rules = init_action_rules.iter().copied().collect::<BTreeSet<_>>();
7887 let invoking_state = self.pending_invoking_states.pop();
7888 let local_int_arg = invoking_state
7889 .and_then(|state| usize::try_from(state).ok())
7890 .and_then(|state| rule_local_int_arg(rule_args, state, rule_index, None));
7891 let mut visiting = BTreeSet::new();
7892 let mut memo = BTreeMap::new();
7893 let mut expected = ExpectedTokens::default();
7894 let member_values = self.int_members.clone();
7895 let return_values = BTreeMap::new();
7896 let outcomes = self.recognize_state(
7897 atn,
7898 RecognizeRequest {
7899 state_number: start_state,
7900 stop_state,
7901 index: start_index,
7902 rule_start_index: start_index,
7903 decision_start_index: None,
7904 init_action_rules: &init_action_rules,
7905 predicates,
7906 semantics,
7907 rule_args,
7908 member_actions,
7909 return_actions,
7910 local_int_arg,
7911 member_values,
7912 return_values,
7913 rule_alt_number: 0,
7914 track_alt_numbers: capture_alt_numbers,
7915 consumed_eof: false,
7916 committed_decision: false,
7917 precedence,
7918 depth: 0,
7919 recovery_symbols: BTreeSet::new(),
7920 recovery_state: None,
7921 },
7922 &mut visiting,
7923 &mut memo,
7924 &mut expected,
7925 );
7926 if let Some(error) = self.unknown_semantic_error() {
7927 self.report_token_source_errors();
7928 return Err(error);
7935 }
7936 self.restore_prior_unknown_predicate_hits(prior_unknown_predicate_hits);
7939 let Some(outcome) = select_best_outcome(
7940 outcomes.into_iter(),
7941 self.prediction_mode,
7942 &self.recognition_arena,
7943 ) else {
7944 let error = self.recognition_error(rule_index, start_index, &expected);
7945 self.record_syntax_errors(1);
7946 self.report_token_source_errors();
7947 if report_unrecovered_error {
7948 self.report_unrecovered_parser_error(&error);
7949 }
7950 return Err(error);
7951 };
7952
7953 self.record_syntax_errors(self.recognition_arena.diagnostics_len(outcome.diagnostics));
7954 self.dispatch_parser_diagnostics(&self.prediction_diagnostics);
7955 self.dispatch_parser_diagnostics(self.recognition_arena.diagnostics(outcome.diagnostics));
7956 self.report_token_source_errors();
7957 let mut actions = outcome.actions;
7958 if init_action_rules.contains(&rule_index) {
7959 actions.insert(
7960 0,
7961 ParserAction::new_rule_init(rule_index, start_index, Some(start_state)),
7962 );
7963 }
7964 let mut context =
7965 ParserRuleContext::new(rule_index, invoking_state.unwrap_or_else(|| self.state()));
7966 if track_alt_numbers {
7967 context.set_alt_number(outcome.alt_number.max(1));
7968 }
7969 if track_context_alt_numbers {
7970 context.set_context_alt_number(outcome.alt_number);
7971 }
7972 for (name, value) in outcome.return_values {
7973 context.set_int_return(name, value);
7974 }
7975 if let Some(token) = self.token_id_at(start_index) {
7976 self.set_context_start(&mut context, token);
7977 }
7978 if let Some(token) = self.rule_stop_token_id(outcome.index, outcome.consumed_eof) {
7979 self.set_context_stop(&mut context, token);
7980 }
7981 let live_root = if self.build_parse_trees {
7982 self.recognition_arena
7983 .fold_left_recursive_boundaries(outcome.nodes)
7984 } else {
7985 outcome.nodes
7986 };
7987 if self.build_parse_trees {
7988 let mut nodes = live_root;
7989 while let Some(link) = self.recognition_arena.link(nodes) {
7990 let child = self.arena_recognized_node_tree(
7991 link.head,
7992 track_alt_numbers,
7993 track_context_alt_numbers,
7994 )?;
7995 self.tree.add_child(&mut context, child);
7996 nodes = link.tail;
7997 }
7998 }
7999 self.finish_recognition_arena(live_root, outcome.diagnostics);
8000 self.input.seek(outcome.index);
8001
8002 let tree = self.rule_node(context);
8003 self.release_tree_scratch_if_idle();
8004 Ok((tree, actions))
8005 }
8006
8007 pub fn parse_interpreted_rule(&mut self, rule_index: usize) -> Result<ParseTree, AntlrError> {
8014 let mut context = ParserRuleContext::new(rule_index, self.state());
8015 while self.la(1) != TOKEN_EOF {
8016 let token_type = self.la(1);
8017 let child = self.match_token(token_type)?;
8018 if self.build_parse_trees {
8019 self.tree.add_child(&mut context, child);
8020 }
8021 }
8022 if self.build_parse_trees {
8023 let child = self.match_eof()?;
8024 self.tree.add_child(&mut context, child);
8025 }
8026 let tree = self.rule_node(context);
8027 self.release_tree_scratch_if_idle();
8028 Ok(tree)
8029 }
8030
8031 fn recognition_error(
8034 &mut self,
8035 rule_index: usize,
8036 start_index: usize,
8037 expected: &ExpectedTokens,
8038 ) -> AntlrError {
8039 let (index, message) = self.expected_error_message(rule_index, start_index, expected);
8040 self.input.seek(index);
8041 let current = self.input.lt(1);
8042 let line = current.as_ref().map(Token::line).unwrap_or_default();
8043 let column = current.as_ref().map(Token::column).unwrap_or_default();
8044 AntlrError::ParserError {
8045 line,
8046 column,
8047 message,
8048 offending: current.as_ref().map(Token::token_id),
8049 }
8050 }
8051
8052 fn expected_error_message(
8054 &mut self,
8055 rule_index: usize,
8056 start_index: usize,
8057 expected: &ExpectedTokens,
8058 ) -> (usize, String) {
8059 let index = expected
8060 .index
8061 .or_else(|| expected.no_viable.map(|no_viable| no_viable.error_index))
8062 .unwrap_or_else(|| self.input.index());
8063 self.input.seek(index);
8064 let current = self.input.lt(1);
8065 let message = if expected
8066 .no_viable
8067 .as_ref()
8068 .is_some_and(|no_viable| no_viable.error_index == index)
8069 {
8070 let start = expected
8071 .no_viable
8072 .as_ref()
8073 .map_or(start_index, |no_viable| no_viable.start_index);
8074 let text = display_input_text(&self.input.text(start, index));
8075 format!("no viable alternative at input '{text}'")
8076 } else if expected.symbols.is_empty() {
8077 if expected.index.is_some() {
8078 let found = current
8079 .as_ref()
8080 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display);
8081 if current
8082 .as_ref()
8083 .is_some_and(|token| token.token_type() == TOKEN_EOF)
8084 {
8085 format!(
8086 "missing {} at {found}",
8087 self.expected_symbols_display(&expected.symbols)
8088 )
8089 } else {
8090 format!("mismatched input {found}")
8091 }
8092 } else {
8093 format!("no viable alternative while parsing rule {rule_index}")
8094 }
8095 } else {
8096 format!(
8097 "mismatched input {} expecting {}",
8098 current
8099 .as_ref()
8100 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8101 self.expected_symbols_display(&expected.symbols)
8102 )
8103 };
8104 (index, message)
8105 }
8106
8107 fn child_rule_failure_recovery(
8110 &mut self,
8111 rule_index: usize,
8112 start_index: usize,
8113 sync_symbols: &BTreeSet<i32>,
8114 member_values: MemberEnv,
8115 expected: &ExpectedTokens,
8116 ) -> Option<RecognizeOutcome> {
8117 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
8118 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
8119 let mut next_index = error_index;
8120 loop {
8121 let symbol = self.token_type_at(next_index);
8122 if sync_symbols.contains(&symbol) {
8123 if next_index == error_index {
8124 return None;
8125 }
8126 break;
8127 }
8128 if symbol == TOKEN_EOF {
8129 break;
8130 }
8131 let after = self.consume_index(next_index, symbol);
8132 if after == next_index {
8133 break;
8134 }
8135 next_index = after;
8136 }
8137 let mut nodes = NodeSeqId::EMPTY;
8138 let error = self.arena_token_node(error_index, true);
8139 self.arena_prepend(&mut nodes, error);
8140 let diagnostics = self
8141 .recognition_arena
8142 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8143 Some(RecognizeOutcome {
8144 index: next_index,
8145 consumed_eof: false,
8146 alt_number: 0,
8147 member_values,
8148 return_values: BTreeMap::new(),
8149 diagnostics,
8150 decisions: Vec::new(),
8151 actions: Vec::new(),
8152 nodes,
8153 })
8154 }
8155
8156 fn child_rule_failure_recovery_outcomes(
8159 &mut self,
8160 request: ChildRuleFailureRecovery<'_>,
8161 ) -> Vec<RecognizeOutcome> {
8162 let sync_symbols =
8163 state_sync_symbols(request.atn, request.follow_state, request.stop_state);
8164 self.child_rule_failure_recovery(
8165 request.rule_index,
8166 request.start_index,
8167 &sync_symbols,
8168 request.member_values,
8169 request.expected,
8170 )
8171 .into_iter()
8172 .collect()
8173 }
8174
8175 fn expected_symbols_display(&self, symbols: &BTreeSet<i32>) -> String {
8177 expected_symbols_display(symbols, self.vocabulary())
8178 }
8179
8180 fn single_token_deletion(
8183 &mut self,
8184 transition: ParserTransition<'_>,
8185 index: usize,
8186 max_token_type: i32,
8187 expected_symbols: &BTreeSet<i32>,
8188 ) -> Option<(ParserDiagnostic, usize, i32)> {
8189 let current_symbol = self.token_type_at(index);
8190 if current_symbol == TOKEN_EOF {
8191 return None;
8192 }
8193 let next_index = self.consume_index(index, current_symbol);
8194 if next_index == index {
8195 return None;
8196 }
8197 let next_symbol = self.token_type_at(next_index);
8198 if !transition.matches(next_symbol, 1, max_token_type) {
8199 return None;
8200 }
8201 let transition_expected = transition_expected_symbols(transition, max_token_type);
8202 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8203 &transition_expected
8204 } else {
8205 expected_symbols
8206 });
8207 let current = self.token_at(index);
8208 let message = format!(
8209 "extraneous input {} expecting {expected_display}",
8210 current
8211 .as_ref()
8212 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8213 );
8214 Some((
8215 diagnostic_for_token(current, message),
8216 next_index,
8217 next_symbol,
8218 ))
8219 }
8220
8221 fn current_token_deletion(
8224 &mut self,
8225 index: usize,
8226 expected_symbols: &BTreeSet<i32>,
8227 ) -> Option<(ParserDiagnostic, usize, Vec<usize>)> {
8228 if expected_symbols.is_empty() {
8229 return None;
8230 }
8231 let current_symbol = self.token_type_at(index);
8232 if current_symbol == TOKEN_EOF {
8233 return None;
8234 }
8235 let current = self.token_at(index);
8236 let message = format!(
8237 "extraneous input {} expecting {}",
8238 current
8239 .as_ref()
8240 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
8241 self.expected_symbols_display(expected_symbols)
8242 );
8243 let diagnostic = diagnostic_for_token(current, message);
8244 let mut skipped = Vec::new();
8245 let mut cursor = index;
8246 loop {
8247 let symbol = self.token_type_at(cursor);
8248 if symbol == TOKEN_EOF {
8249 return None;
8250 }
8251 skipped.push(cursor);
8252 let next_index = self.consume_index(cursor, symbol);
8253 if next_index == cursor {
8254 return None;
8255 }
8256 let next_symbol = self.token_type_at(next_index);
8257 if expected_symbols.contains(&next_symbol) {
8258 return Some((diagnostic, next_index, skipped));
8259 }
8260 cursor = next_index;
8261 }
8262 }
8263
8264 fn single_token_insertion(
8268 &mut self,
8269 transition: ParserTransition<'_>,
8270 index: usize,
8271 max_token_type: i32,
8272 expected_symbols: &BTreeSet<i32>,
8273 follow_symbols: &BTreeSet<i32>,
8274 ) -> Option<(ParserDiagnostic, i32, String)> {
8275 let current_symbol = self.token_type_at(index);
8276 if !follow_symbols.contains(¤t_symbol) {
8277 return None;
8278 }
8279 let transition_expected = transition_expected_symbols(transition, max_token_type);
8280 let token_type = transition_expected.iter().next().copied()?;
8281 let expected_display = self.expected_symbols_display(if expected_symbols.is_empty() {
8282 &transition_expected
8283 } else {
8284 expected_symbols
8285 });
8286 let mut token_symbols = BTreeSet::new();
8287 token_symbols.insert(token_type);
8288 let missing_token_display = self.expected_symbols_display(&token_symbols);
8289 let current = self.token_at(index);
8290 let message = format!(
8291 "missing {expected_display} at {}",
8292 current
8293 .as_ref()
8294 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display)
8295 );
8296 let text = format!("<missing {missing_token_display}>");
8297 Some((
8298 diagnostic_for_token(current.as_ref(), message),
8299 token_type,
8300 text,
8301 ))
8302 }
8303
8304 fn fast_single_token_deletion_recovery(
8308 &mut self,
8309 recovery: FastRecoveryRequest<'_, '_>,
8310 predicate_context: Option<FastPredicateContext<'_>>,
8311 ) -> Vec<FastRecognizeOutcome> {
8312 let FastRecoveryRequest {
8313 atn,
8314 transition,
8315 expected_symbols,
8316 target,
8317 request,
8318 visiting,
8319 memo,
8320 expected,
8321 } = recovery;
8322 let FastRecognizeRequest {
8323 stop_state,
8324 index,
8325 rule_start_index,
8326 decision_start_index,
8327 precedence,
8328 depth,
8329 ..
8330 } = request;
8331 let Some((diagnostic, next_index, next_symbol)) =
8332 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
8333 else {
8334 return Vec::new();
8335 };
8336 let after_next = self.consume_index(next_index, next_symbol);
8337 let empty_recovery = self.empty_recovery_symbols();
8338 self.recognize_state_fast(
8339 atn,
8340 FastRecognizeRequest {
8341 state_number: target,
8342 stop_state,
8343 index: after_next,
8344 rule_start_index,
8345 decision_start_index,
8346 precedence,
8347 depth: depth + 1,
8348 recovery_symbols: empty_recovery,
8349 recovery_state: None,
8350 },
8351 FastRecognizeScratch {
8352 predicate_context,
8353 visiting,
8354 memo,
8355 expected,
8356 native_depth: 0,
8357 },
8358 )
8359 .into_iter()
8360 .map(|mut outcome| {
8361 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
8362 outcome.diagnostics = self
8363 .recognition_arena
8364 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8365 if self.fast_token_nodes_enabled {
8366 let token = self.arena_token_node(next_index, false);
8367 self.defer_fast_outcome_node(&mut outcome, token);
8368 let error = self.arena_token_node(index, true);
8369 self.defer_fast_outcome_node(&mut outcome, error);
8370 }
8371 outcome
8372 })
8373 .collect()
8374 }
8375
8376 fn fast_single_token_insertion_recovery(
8380 &mut self,
8381 recovery: FastRecoveryRequest<'_, '_>,
8382 predicate_context: Option<FastPredicateContext<'_>>,
8383 ) -> Vec<FastRecognizeOutcome> {
8384 let FastRecoveryRequest {
8385 atn,
8386 transition,
8387 expected_symbols,
8388 target,
8389 request,
8390 visiting,
8391 memo,
8392 expected,
8393 } = recovery;
8394 let FastRecognizeRequest {
8395 stop_state,
8396 index,
8397 rule_start_index,
8398 decision_start_index,
8399 precedence,
8400 depth,
8401 ..
8402 } = request;
8403 let follow_symbols = self.cached_state_expected_symbols(atn, transition.target());
8404 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
8405 transition,
8406 index,
8407 atn.max_token_type(),
8408 &expected_symbols,
8409 &follow_symbols,
8410 ) else {
8411 return Vec::new();
8412 };
8413 let empty_recovery = self.empty_recovery_symbols();
8414 self.recognize_state_fast(
8415 atn,
8416 FastRecognizeRequest {
8417 state_number: target,
8418 stop_state,
8419 index,
8420 rule_start_index,
8421 decision_start_index,
8422 precedence,
8423 depth: depth + 1,
8424 recovery_symbols: empty_recovery,
8425 recovery_state: None,
8426 },
8427 FastRecognizeScratch {
8428 predicate_context,
8429 visiting,
8430 memo,
8431 expected,
8432 native_depth: 0,
8433 },
8434 )
8435 .into_iter()
8436 .map(|mut outcome| {
8437 outcome.diagnostics = self
8438 .recognition_arena
8439 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8440 let missing = self.arena_missing_token_node(token_type, index, text.clone());
8441 self.defer_fast_outcome_node(&mut outcome, missing);
8442 outcome
8443 })
8444 .collect()
8445 }
8446
8447 fn fast_current_token_deletion_recovery(
8450 &mut self,
8451 recovery: FastCurrentTokenDeletionRequest<'_, '_>,
8452 predicate_context: Option<FastPredicateContext<'_>>,
8453 ) -> Vec<FastRecognizeOutcome> {
8454 let FastCurrentTokenDeletionRequest {
8455 atn,
8456 expected_symbols,
8457 mut request,
8458 visiting,
8459 memo,
8460 expected,
8461 } = recovery;
8462 if request.index == request.rule_start_index {
8463 return Vec::new();
8464 }
8465 let Some((diagnostic, next_index, skipped)) =
8466 self.current_token_deletion(request.index, &expected_symbols)
8467 else {
8468 return Vec::new();
8469 };
8470 request.state_number = request.recovery_state.unwrap_or(request.state_number);
8471 request.index = next_index;
8472 request.depth += 1;
8473 request.recovery_state = None;
8474 self.recognize_state_fast(
8475 atn,
8476 request,
8477 FastRecognizeScratch {
8478 predicate_context,
8479 visiting,
8480 memo,
8481 expected,
8482 native_depth: 0,
8483 },
8484 )
8485 .into_iter()
8486 .map(|mut outcome| {
8487 outcome.diagnostics = self
8488 .recognition_arena
8489 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
8490 for index in skipped.iter().rev() {
8491 let error = self.arena_token_node(*index, true);
8492 self.defer_fast_outcome_node(&mut outcome, error);
8493 }
8494 outcome
8495 })
8496 .collect()
8497 }
8498
8499 fn fast_child_rule_failure_recovery(
8502 &mut self,
8503 rule_index: usize,
8504 start_index: usize,
8505 sync_symbols: &BTreeSet<i32>,
8506 expected: &ExpectedTokens,
8507 ) -> Option<FastRecognizeOutcome> {
8508 let (error_index, message) = self.expected_error_message(rule_index, start_index, expected);
8509 let diagnostic = diagnostic_for_token(self.token_at(error_index), message);
8510 let mut next_index = error_index;
8511 loop {
8512 let symbol = self.token_type_at(next_index);
8513 if sync_symbols.contains(&symbol) {
8514 if next_index == error_index {
8515 return None;
8516 }
8517 break;
8518 }
8519 if symbol == TOKEN_EOF {
8520 break;
8521 }
8522 let after = self.consume_index(next_index, symbol);
8523 if after == next_index {
8524 break;
8525 }
8526 next_index = after;
8527 }
8528 let diagnostics = self
8529 .recognition_arena
8530 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
8531 let mut nodes = NodeSeqId::EMPTY;
8532 if self.fast_token_nodes_enabled {
8533 let error = self.arena_token_node(error_index, true);
8534 self.arena_prepend(&mut nodes, error);
8535 }
8536 Some(FastRecognizeOutcome {
8537 index: next_index,
8538 consumed_eof: false,
8539 diagnostics,
8540 deferred_nodes: FastDeferredNodeId::EMPTY,
8541 nodes,
8542 })
8543 }
8544
8545 fn fast_child_rule_failure_recovery_outcomes(
8548 &mut self,
8549 request: FastChildRuleFailureRecoveryRequest<'_>,
8550 ) -> Vec<FastRecognizeOutcome> {
8551 let FastChildRuleFailureRecoveryRequest {
8552 atn,
8553 rule_index,
8554 start_index,
8555 follow_state,
8556 stop_state,
8557 expected,
8558 } = request;
8559 let sync_symbols = state_sync_symbols(atn, follow_state, stop_state);
8560 self.fast_child_rule_failure_recovery(rule_index, start_index, &sync_symbols, expected)
8561 .into_iter()
8562 .collect()
8563 }
8564
8565 fn defer_fast_outcome_node(
8566 &mut self,
8567 outcome: &mut FastRecognizeOutcome,
8568 node: RecognizedNodeId,
8569 ) {
8570 if outcome.deferred_nodes.is_empty() {
8571 self.arena_prepend(&mut outcome.nodes, node);
8572 return;
8573 }
8574 let fragment = self.recognition_arena.prepend(NodeSeqId::EMPTY, node);
8575 let fragment = self.recognition_arena.deferred_fragment(fragment);
8576 outcome.deferred_nodes = self
8577 .recognition_arena
8578 .concat_deferred_nodes(fragment, outcome.deferred_nodes);
8579 }
8580
8581 fn defer_fast_outcome_alternative(
8582 &mut self,
8583 outcome: &mut FastRecognizeOutcome,
8584 alt_number: usize,
8585 ) {
8586 let alternative = self.recognition_arena.deferred_alternative(alt_number);
8587 outcome.deferred_nodes = self
8588 .recognition_arena
8589 .concat_deferred_nodes(alternative, outcome.deferred_nodes);
8590 }
8591
8592 fn defer_fast_outcome_boundary(
8593 &mut self,
8594 outcome: &mut FastRecognizeOutcome,
8595 rule_index: usize,
8596 ) {
8597 let boundary = self
8598 .recognition_arena
8599 .deferred_left_recursive_boundary(rule_index);
8600 outcome.deferred_nodes = self
8601 .recognition_arena
8602 .concat_deferred_nodes(boundary, outcome.deferred_nodes);
8603 }
8604
8605 fn materialize_fast_deferred_nodes(
8606 &mut self,
8607 root: FastDeferredNodeId,
8608 initial_suffix: NodeSeqId,
8609 ) -> (NodeSeqId, usize) {
8610 if root.is_empty() {
8611 return (initial_suffix, 0);
8612 }
8613
8614 enum Frame {
8615 Visit(FastDeferredNodeId),
8616 ContinuePrefix(FastDeferredNodeId),
8617 FinishRule {
8618 rule: FastDeferredRule,
8619 parent_suffix: NodeSeqId,
8620 parent_alt_number: u32,
8621 parent_pending_boundary: Option<RecognizedNodeId>,
8622 },
8623 }
8624
8625 let mut result = initial_suffix;
8626 let mut alt_number = 0;
8630 let mut pending_boundary = None;
8631 let mut pending = Vec::with_capacity(16);
8632 pending.push(Frame::Visit(root));
8633 let mut fragment_nodes = Vec::new();
8634 while let Some(frame) = pending.pop() {
8635 match frame {
8636 Frame::Visit(deferred) => {
8637 if deferred.is_empty() {
8638 continue;
8639 }
8640
8641 match self.recognition_arena.deferred_node(deferred) {
8642 FastDeferredNode::Fragment(sequence) => {
8643 fragment_nodes.clear();
8644 fragment_nodes.extend(self.recognition_arena.iter(sequence));
8645 while let Some(node) = fragment_nodes.pop() {
8646 self.arena_prepend(&mut result, node);
8647 }
8648 }
8649 FastDeferredNode::Rule(rule) => {
8650 let rule = self.recognition_arena.deferred_rule(rule);
8651 let parent_suffix = result;
8652 let parent_alt_number = alt_number;
8653 let parent_pending_boundary = pending_boundary;
8654 result = rule.children;
8655 alt_number = 0;
8656 pending_boundary = None;
8657 pending.push(Frame::FinishRule {
8658 rule,
8659 parent_suffix,
8660 parent_alt_number,
8661 parent_pending_boundary,
8662 });
8663 pending.push(Frame::Visit(rule.deferred_children));
8664 }
8665 FastDeferredNode::Alternative(selected) => {
8666 if let Some(boundary) = pending_boundary {
8667 self.recognition_arena
8668 .set_boundary_alt_number(boundary, selected);
8669 } else {
8670 alt_number = selected;
8671 }
8672 }
8673 FastDeferredNode::LeftRecursiveBoundary { rule_index } => {
8674 let boundary = self.arena_boundary_node(rule_index as usize, 0);
8675 self.arena_prepend(&mut result, boundary);
8676 pending_boundary = Some(boundary);
8677 }
8678 FastDeferredNode::Concat {
8679 prefix,
8680 suffix: deferred_suffix,
8681 } => {
8682 pending.push(Frame::ContinuePrefix(prefix));
8683 pending.push(Frame::Visit(deferred_suffix));
8684 }
8685 }
8686 }
8687 Frame::ContinuePrefix(prefix) => pending.push(Frame::Visit(prefix)),
8688 Frame::FinishRule {
8689 rule,
8690 parent_suffix,
8691 parent_alt_number,
8692 parent_pending_boundary,
8693 } => {
8694 let node = self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
8695 rule_index: rule.rule_index,
8696 invoking_state: rule.invoking_state,
8697 alt_number,
8698 start_index: rule.start_index,
8699 stop_index: rule.stop_index,
8700 return_values: None,
8701 children: result,
8702 });
8703 result = parent_suffix;
8704 self.arena_prepend(&mut result, node);
8705 alt_number = parent_alt_number;
8706 pending_boundary = parent_pending_boundary;
8707 }
8708 }
8709 }
8710 (result, alt_number as usize)
8711 }
8712
8713 fn materialize_fast_outcome_nodes(&mut self, outcome: &mut FastRecognizeOutcome) -> usize {
8714 let deferred_nodes = std::mem::take(&mut outcome.deferred_nodes);
8715 let (nodes, alt_number) =
8716 self.materialize_fast_deferred_nodes(deferred_nodes, outcome.nodes);
8717 outcome.nodes = nodes;
8718 alt_number
8719 }
8720
8721 fn recognize_repetition_fast(
8724 &mut self,
8725 atn: &Atn,
8726 request: &FastRecognizeRequest,
8727 shape: FastRepetitionShape,
8728 scratch: FastRecognizeScratch<'_, '_>,
8729 ) -> Vec<FastRecognizeOutcome> {
8730 let FastRecognizeScratch {
8731 predicate_context,
8732 visiting,
8733 memo,
8734 expected,
8735 native_depth,
8736 } = scratch;
8737 let lookahead = if self.fast_first_set_prefilter {
8738 atn.state(request.state_number).and_then(|state| {
8739 state
8740 .rule_index()
8741 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
8742 .map(|rule_stop| self.cached_decision_lookahead(atn, state, rule_stop))
8743 })
8744 } else {
8745 None
8746 };
8747 let (enter_alt_number, exit_alt_number) = if self.fast_track_alt_numbers {
8748 let state = atn
8749 .state(request.state_number)
8750 .expect("repetition request state must exist");
8751 (
8752 next_alt_number(state, 2, shape.enter_transition_index, 0, true),
8753 next_alt_number(state, 2, shape.exit_transition_index, 0, true),
8754 )
8755 } else {
8756 (0, 0)
8757 };
8758 let mut work = Vec::with_capacity(2);
8759 push_fast_repetition_work(
8760 &mut work,
8761 shape,
8762 FastRepetitionPath {
8763 index: request.index,
8764 deferred_nodes: FastDeferredNodeId::EMPTY,
8765 diagnostics: DiagnosticSeqId::EMPTY,
8766 consumed_eof: false,
8767 },
8768 lookahead.as_deref(),
8769 self.token_type_at(request.index),
8770 );
8771 let mut coordinates = FastRepetitionCoordinates::new(request.index);
8772 let mut outcomes = Vec::new();
8773 while let Some(item) = work.pop() {
8774 match item {
8775 FastRepetitionWork::Enter(path) => {
8776 if !coordinates.insert_entered(path) {
8777 continue;
8778 }
8779 let path_nodes = if enter_alt_number == 0 {
8780 path.deferred_nodes
8781 } else {
8782 let alternative = self
8783 .recognition_arena
8784 .deferred_alternative(enter_alt_number);
8785 self.recognition_arena
8786 .concat_deferred_nodes(path.deferred_nodes, alternative)
8787 };
8788 let body_outcomes = self.recognize_state_fast(
8789 atn,
8790 FastRecognizeRequest {
8791 state_number: shape.enter_target,
8792 stop_state: shape.body_stop_state,
8793 index: path.index,
8794 rule_start_index: request.rule_start_index,
8795 decision_start_index: request.decision_start_index,
8796 precedence: request.precedence,
8797 depth: request.depth.saturating_add(1),
8798 recovery_symbols: Rc::clone(&request.recovery_symbols),
8799 recovery_state: request.recovery_state,
8800 },
8801 FastRecognizeScratch {
8802 predicate_context,
8803 visiting: &mut *visiting,
8804 memo: &mut *memo,
8805 expected: &mut *expected,
8806 native_depth: native_depth + 1,
8807 },
8808 );
8809 for body in body_outcomes.into_iter().rev() {
8810 if body.index <= path.index {
8814 continue;
8815 }
8816 let body_fragment = self.recognition_arena.deferred_fragment(body.nodes);
8817 let body_nodes = self
8818 .recognition_arena
8819 .concat_deferred_nodes(body.deferred_nodes, body_fragment);
8820 let deferred_nodes = self
8821 .recognition_arena
8822 .concat_deferred_nodes(path_nodes, body_nodes);
8823 let next_path = FastRepetitionPath {
8824 index: body.index,
8825 deferred_nodes,
8826 diagnostics: self
8827 .recognition_arena
8828 .concat_diagnostics(path.diagnostics, body.diagnostics),
8829 consumed_eof: path.consumed_eof || body.consumed_eof,
8830 };
8831 let symbol = self.token_type_at(next_path.index);
8832 push_fast_repetition_work(
8833 &mut work,
8834 shape,
8835 next_path,
8836 lookahead.as_deref(),
8837 symbol,
8838 );
8839 }
8840 }
8841 FastRepetitionWork::Exit(path) => {
8842 if !coordinates.insert_exited(path) {
8843 continue;
8844 }
8845 let path_nodes = if exit_alt_number == 0 {
8846 path.deferred_nodes
8847 } else {
8848 let alternative =
8849 self.recognition_arena.deferred_alternative(exit_alt_number);
8850 self.recognition_arena
8851 .concat_deferred_nodes(path.deferred_nodes, alternative)
8852 };
8853 let suffixes = self.recognize_state_fast(
8854 atn,
8855 FastRecognizeRequest {
8856 state_number: shape.exit_target,
8857 stop_state: request.stop_state,
8858 index: path.index,
8859 rule_start_index: request.rule_start_index,
8860 decision_start_index: request.decision_start_index,
8861 precedence: request.precedence,
8862 depth: request.depth.saturating_add(1),
8863 recovery_symbols: Rc::clone(&request.recovery_symbols),
8864 recovery_state: request.recovery_state,
8865 },
8866 FastRecognizeScratch {
8867 predicate_context,
8868 visiting: &mut *visiting,
8869 memo: &mut *memo,
8870 expected: &mut *expected,
8871 native_depth: native_depth + 1,
8872 },
8873 );
8874 for mut outcome in suffixes {
8875 outcome.deferred_nodes = self
8876 .recognition_arena
8877 .concat_deferred_nodes(path_nodes, outcome.deferred_nodes);
8878 outcome.diagnostics = self
8879 .recognition_arena
8880 .concat_diagnostics(path.diagnostics, outcome.diagnostics);
8881 outcome.consumed_eof |= path.consumed_eof;
8882 outcomes.push(outcome);
8883 }
8884 }
8885 }
8886 }
8887 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
8888 outcomes
8889 }
8890
8891 fn recognize_state_fast(
8894 &mut self,
8895 atn: &Atn,
8896 request: FastRecognizeRequest,
8897 scratch: FastRecognizeScratch<'_, '_>,
8898 ) -> Vec<FastRecognizeOutcome> {
8899 if scratch.native_depth != 0 && scratch.native_depth < FAST_RECOGNIZE_STACK_CHECK_INTERVAL {
8900 return self.recognize_state_fast_inner(atn, request, scratch);
8901 }
8902 self.recognize_state_fast_checked(atn, request, scratch)
8903 }
8904
8905 #[inline(never)]
8906 fn recognize_state_fast_checked(
8907 &mut self,
8908 atn: &Atn,
8909 request: FastRecognizeRequest,
8910 mut scratch: FastRecognizeScratch<'_, '_>,
8911 ) -> Vec<FastRecognizeOutcome> {
8912 scratch.native_depth = 1;
8913 stacker::maybe_grow(FAST_RECOGNIZE_RED_ZONE, FAST_RECOGNIZE_STACK_SIZE, || {
8914 self.recognize_state_fast_inner(atn, request, scratch)
8915 })
8916 }
8917
8918 #[allow(clippy::too_many_lines)]
8919 fn recognize_state_fast_inner(
8920 &mut self,
8921 atn: &Atn,
8922 request: FastRecognizeRequest,
8923 scratch: FastRecognizeScratch<'_, '_>,
8924 ) -> Vec<FastRecognizeOutcome> {
8925 #[cfg(feature = "perf-counters")]
8926 perf_counters::inc(&perf_counters::RFS_CALLS, 1);
8927 let FastRecognizeScratch {
8928 predicate_context,
8929 visiting,
8930 memo,
8931 expected,
8932 native_depth,
8933 } = scratch;
8934 let FastRecognizeRequest {
8935 mut state_number,
8936 stop_state,
8937 mut index,
8938 rule_start_index,
8939 decision_start_index,
8940 precedence,
8941 mut depth,
8942 recovery_symbols,
8943 recovery_state,
8944 } = request;
8945 let max_token_type = atn.max_token_type();
8946 let mut inline_consumed_tokens: Vec<usize> = Vec::new();
8965 let mut inline_consumed_eof = false;
8966 loop {
8967 if depth > RECOGNITION_DEPTH_LIMIT {
8968 return Vec::new();
8969 }
8970 if state_number == stop_state {
8971 let mut nodes = NodeSeqId::EMPTY;
8972 if self.fast_token_nodes_enabled {
8973 for token_index in inline_consumed_tokens.iter().rev() {
8974 let token = self.arena_token_node(*token_index, false);
8975 self.arena_prepend(&mut nodes, token);
8976 }
8977 }
8978 return vec![FastRecognizeOutcome {
8979 index,
8980 consumed_eof: inline_consumed_eof,
8981 diagnostics: DiagnosticSeqId::EMPTY,
8982 deferred_nodes: FastDeferredNodeId::EMPTY,
8983 nodes,
8984 }];
8985 }
8986 let Some(state) = atn.state(state_number) else {
8987 return Vec::new();
8988 };
8989 let transitions = state.transitions();
8990 if transitions.len() == 1 && !state.precedence_rule_decision() {
8991 let transition = transitions
8992 .first()
8993 .expect("single transition checked above");
8994 let transition_kind = transition.kind();
8995 let target = transition.target();
8996 match transition_kind {
8997 ParserTransitionKind::Epsilon | ParserTransitionKind::Action
8998 if left_recursive_boundary(atn, state, target).is_none() =>
8999 {
9000 #[cfg(feature = "perf-counters")]
9001 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9002 state_number = target;
9003 depth += 1;
9004 continue;
9005 }
9006 ParserTransitionKind::Predicate
9007 if left_recursive_boundary(atn, state, target).is_none() =>
9008 {
9009 #[cfg(feature = "perf-counters")]
9010 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9011 if !self.fast_parser_predicate_matches(predicate_context, transition, index)
9012 {
9013 record_predicate_no_viable(expected, decision_start_index, index);
9014 return Vec::new();
9015 }
9016 state_number = target;
9017 depth += 1;
9018 continue;
9019 }
9020 ParserTransitionKind::Precedence
9021 if packed_i32(transition.arg0()) >= precedence
9022 && left_recursive_boundary(atn, state, target).is_none() =>
9023 {
9024 #[cfg(feature = "perf-counters")]
9025 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9026 state_number = target;
9027 depth += 1;
9028 continue;
9029 }
9030 ParserTransitionKind::Atom
9040 | ParserTransitionKind::Range
9041 | ParserTransitionKind::Set
9042 | ParserTransitionKind::NotSet
9043 | ParserTransitionKind::Wildcard
9044 if !self.fast_recovery_enabled =>
9045 {
9046 let symbol = self.token_type_at(index);
9047 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9048 #[cfg(feature = "perf-counters")]
9049 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9050 if self.fast_token_nodes_enabled {
9051 inline_consumed_tokens.push(index);
9052 }
9053 inline_consumed_eof |= symbol == TOKEN_EOF;
9054 index = self.consume_index(index, symbol);
9055 state_number = target;
9056 depth += 1;
9057 continue;
9058 }
9059 }
9062 _ => {}
9063 }
9064 }
9065 break;
9066 }
9067 let inline_pending = !inline_consumed_tokens.is_empty() || inline_consumed_eof;
9071 let Some(state) = atn.state(state_number) else {
9072 return Vec::new();
9073 };
9074 let transitions = state.transitions();
9075 let transition_count = transitions.len();
9076 if !self.fast_recovery_enabled
9077 && let Some(shape) = fast_repetition_shape(atn, state)
9078 {
9079 let mut outcomes = self.recognize_repetition_fast(
9080 atn,
9081 &FastRecognizeRequest {
9082 state_number,
9083 stop_state,
9084 index,
9085 rule_start_index,
9086 decision_start_index,
9087 precedence,
9088 depth,
9089 recovery_symbols: Rc::clone(&recovery_symbols),
9090 recovery_state,
9091 },
9092 shape,
9093 FastRecognizeScratch {
9094 predicate_context,
9095 visiting: &mut *visiting,
9096 memo: &mut *memo,
9097 expected: &mut *expected,
9098 native_depth: native_depth + 1,
9099 },
9100 );
9101 if inline_pending {
9102 for outcome in &mut outcomes {
9103 outcome.consumed_eof |= inline_consumed_eof;
9104 if self.fast_token_nodes_enabled {
9105 for token_index in inline_consumed_tokens.iter().rev() {
9106 let token = self.arena_token_node(*token_index, false);
9107 self.defer_fast_outcome_node(outcome, token);
9108 }
9109 }
9110 }
9111 }
9112 return outcomes;
9113 }
9114 let key = if self.fast_recovery_enabled {
9124 FastRecognizeKey {
9125 state_number,
9126 stop_state,
9127 index,
9128 rule_start_index,
9129 decision_start_index,
9130 precedence,
9131 recovery_symbols_id: Rc::as_ptr(&recovery_symbols) as usize,
9132 recovery_state,
9133 }
9134 } else {
9135 FastRecognizeKey {
9136 state_number,
9137 stop_state,
9138 index,
9139 rule_start_index: 0,
9140 decision_start_index: None,
9141 precedence,
9142 recovery_symbols_id: 0,
9143 recovery_state: None,
9144 }
9145 };
9146 let memo_lookup_enabled = self.fast_recovery_enabled
9151 || (transition_count > 1 && self.clean_memo_enabled_for_key(&key));
9152 if memo_lookup_enabled {
9153 if let Some(outcomes) = memo.get(&key) {
9154 #[cfg(feature = "perf-counters")]
9155 {
9156 perf_counters::inc(&perf_counters::RFS_MEMO_HITS, 1);
9157 perf_counters::inc(&perf_counters::OUTCOMES_CLONED, outcomes.len() as u64);
9158 }
9159 if !inline_consumed_tokens.is_empty() || inline_consumed_eof {
9163 let inline_eof = inline_consumed_eof;
9164 let inline_tokens = &inline_consumed_tokens;
9165 return outcomes
9166 .iter()
9167 .copied()
9168 .map(|mut outcome| {
9169 if inline_eof {
9170 outcome.consumed_eof = true;
9171 }
9172 if self.fast_token_nodes_enabled {
9173 for token_index in inline_tokens.iter().rev() {
9174 let token = self.arena_token_node(*token_index, false);
9175 self.defer_fast_outcome_node(&mut outcome, token);
9176 }
9177 }
9178 outcome
9179 })
9180 .collect();
9181 }
9182 return outcomes.to_vec();
9183 }
9184 #[cfg(feature = "perf-counters")]
9185 perf_counters::inc(&perf_counters::RFS_MEMO_MISSES, 1);
9186 }
9187
9188 let needs_cycle_guard = if self.fast_recovery_enabled {
9193 transitions.iter().any(ParserTransition::is_epsilon)
9194 } else {
9195 transition_count > 1 && self.state_can_reenter_without_consuming(atn, state_number)
9196 };
9197 #[cfg(feature = "perf-counters")]
9198 if needs_cycle_guard {
9199 perf_counters::inc(&perf_counters::MULTI_TRANS_BODY, 1);
9200 } else {
9201 perf_counters::inc(&perf_counters::SINGLE_TRANS_BODY, 1);
9202 match state
9203 .transitions()
9204 .first()
9205 .expect("single-transition path requires one transition")
9206 .data()
9207 {
9208 Transition::Rule { .. } => {
9209 perf_counters::inc(&perf_counters::SINGLE_TRANS_RULE, 1);
9210 }
9211 Transition::Atom { .. }
9212 | Transition::Range { .. }
9213 | Transition::Set { .. }
9214 | Transition::NotSet { .. }
9215 | Transition::Wildcard { .. } => {
9216 perf_counters::inc(&perf_counters::SINGLE_TRANS_ATOM, 1);
9217 }
9218 _ => {
9219 perf_counters::inc(&perf_counters::SINGLE_TRANS_OTHER, 1);
9220 }
9221 }
9222 }
9223 let has_inserted_cycle_guard = if needs_cycle_guard {
9224 if !visiting.insert(key.clone()) {
9225 #[cfg(feature = "perf-counters")]
9226 perf_counters::inc(&perf_counters::RFS_VISITING_CYCLE, 1);
9227 return Vec::new();
9228 }
9229 true
9230 } else {
9231 false
9232 };
9233 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
9234 Some(index)
9235 } else {
9236 decision_start_index
9237 };
9238 let (epsilon_recovery_symbols, epsilon_recovery_state) = if self.fast_recovery_enabled {
9239 fast_next_recovery_context(self, atn, state, &recovery_symbols, recovery_state)
9240 } else {
9241 (Rc::clone(&recovery_symbols), recovery_state)
9242 };
9243
9244 let lookahead_filter = if transition_count > 1
9263 && self.fast_first_set_prefilter
9264 && !state.precedence_rule_decision()
9265 && (!self.fast_recovery_enabled || state.kind() != AtnStateKind::RuleStart)
9266 {
9267 state
9268 .rule_index()
9269 .and_then(|rule_index| atn.rule_to_stop_state().get(rule_index))
9270 .map(|rule_stop| {
9271 let symbol = self.token_type_at(index);
9272 let entry = self.cached_decision_lookahead(atn, state, rule_stop);
9273 (symbol, entry)
9274 })
9275 } else {
9276 None
9277 };
9278 let ll1_only_alt: Option<usize> = if transition_count > 1
9287 && let Some((symbol, entry)) = lookahead_filter.as_ref()
9288 {
9289 let key = (state.state_number(), *symbol);
9290 if let Some(&cached) = self.ll1_decision_cache.get(&key) {
9291 cached
9292 } else {
9293 let result = ll1_unique_alt(entry, *symbol);
9294 self.ll1_decision_cache.insert(key, result);
9295 result
9296 }
9297 } else {
9298 None
9299 };
9300 let lookahead_filter = lookahead_filter.as_ref();
9301 let mut outcomes: Vec<FastRecognizeOutcome> = Vec::with_capacity(transition_count.min(2));
9307 for (transition_index, transition) in transitions.iter().enumerate() {
9308 if let Some(alt) = ll1_only_alt {
9309 if alt != transition_index {
9311 continue;
9312 }
9313 }
9314 let transition_kind = transition.kind();
9315 if ll1_only_alt.is_none()
9316 && should_skip_via_lookahead(
9317 transition_kind,
9318 transition_index,
9319 lookahead_filter,
9320 index,
9321 self.fast_recovery_enabled,
9322 expected,
9323 )
9324 {
9325 continue;
9326 }
9327 let target = transition.target();
9328 let outcomes_before_transition = outcomes.len();
9329 let left_recursive_boundary = match transition_kind {
9330 ParserTransitionKind::Epsilon
9331 | ParserTransitionKind::Action
9332 | ParserTransitionKind::Predicate
9333 | ParserTransitionKind::Precedence => left_recursive_boundary(atn, state, target),
9334 ParserTransitionKind::Atom
9335 | ParserTransitionKind::Range
9336 | ParserTransitionKind::Set
9337 | ParserTransitionKind::NotSet
9338 | ParserTransitionKind::Wildcard
9339 | ParserTransitionKind::Rule => None,
9340 };
9341 match transition_kind {
9342 ParserTransitionKind::Epsilon | ParserTransitionKind::Action => {
9343 #[cfg(feature = "perf-counters")]
9344 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9345 outcomes.extend(self.recognize_state_fast(
9346 atn,
9347 FastRecognizeRequest {
9348 state_number: target,
9349 stop_state,
9350 index,
9351 rule_start_index,
9352 decision_start_index: next_decision_start_index,
9353 precedence,
9354 depth: depth + 1,
9355 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9356 recovery_state: epsilon_recovery_state,
9357 },
9358 FastRecognizeScratch {
9359 predicate_context,
9360 visiting,
9361 memo,
9362 expected,
9363 native_depth: native_depth + 1,
9364 },
9365 ));
9366 }
9367 ParserTransitionKind::Predicate => {
9368 #[cfg(feature = "perf-counters")]
9369 perf_counters::inc(&perf_counters::EPSILON_TRANSITIONS, 1);
9370 if self.fast_parser_predicate_matches(predicate_context, transition, index) {
9371 outcomes.extend(self.recognize_state_fast(
9372 atn,
9373 FastRecognizeRequest {
9374 state_number: target,
9375 stop_state,
9376 index,
9377 rule_start_index,
9378 decision_start_index: next_decision_start_index,
9379 precedence,
9380 depth: depth + 1,
9381 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9382 recovery_state: epsilon_recovery_state,
9383 },
9384 FastRecognizeScratch {
9385 predicate_context,
9386 visiting,
9387 memo,
9388 expected,
9389 native_depth: native_depth + 1,
9390 },
9391 ));
9392 } else {
9393 record_predicate_no_viable(expected, next_decision_start_index, index);
9394 }
9395 }
9396 ParserTransitionKind::Precedence => {
9397 let transition_precedence = packed_i32(transition.arg0());
9398 if transition_precedence >= precedence {
9399 outcomes.extend(self.recognize_state_fast(
9400 atn,
9401 FastRecognizeRequest {
9402 state_number: target,
9403 stop_state,
9404 index,
9405 rule_start_index,
9406 decision_start_index: next_decision_start_index,
9407 precedence,
9408 depth: depth + 1,
9409 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9410 recovery_state: epsilon_recovery_state,
9411 },
9412 FastRecognizeScratch {
9413 predicate_context,
9414 visiting,
9415 memo,
9416 expected,
9417 native_depth: native_depth + 1,
9418 },
9419 ));
9420 }
9421 }
9422 ParserTransitionKind::Rule => {
9423 let rule_index = transition.arg0() as usize;
9424 let follow_state = transition.arg1() as usize;
9425 let rule_precedence = packed_i32(transition.arg2());
9426 #[cfg(feature = "perf-counters")]
9427 perf_counters::inc(&perf_counters::RULE_TRANSITIONS, 1);
9428 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
9429 continue;
9430 };
9431 let symbol = self.token_type_at(index);
9443 if self.fast_first_set_prefilter {
9444 let first = self.cached_rule_first_set(atn, target, child_stop);
9457 if should_skip_rule_via_first_set(
9458 &first,
9459 symbol,
9460 self.fast_recovery_enabled,
9461 index,
9462 expected,
9463 ) {
9464 continue;
9465 }
9466 }
9467 let expected_before_child =
9468 self.fast_recovery_enabled.then(|| expected.clone());
9469 let mut children = self.recognize_state_fast(
9470 atn,
9471 FastRecognizeRequest {
9472 state_number: target,
9473 stop_state: child_stop,
9474 index,
9475 rule_start_index: index,
9476 decision_start_index: None,
9477 precedence: rule_precedence,
9478 depth: depth + 1,
9479 recovery_symbols: Rc::clone(&epsilon_recovery_symbols),
9480 recovery_state: epsilon_recovery_state,
9481 },
9482 FastRecognizeScratch {
9483 predicate_context,
9484 visiting,
9485 memo,
9486 expected,
9487 native_depth: native_depth + 1,
9488 },
9489 );
9490 if children.is_empty() && self.fast_recovery_enabled {
9491 children = self.fast_child_rule_failure_recovery_outcomes(
9492 FastChildRuleFailureRecoveryRequest {
9493 atn,
9494 rule_index,
9495 start_index: index,
9496 follow_state,
9497 stop_state,
9498 expected,
9499 },
9500 );
9501 }
9502 if let Some(expected_before_child) = expected_before_child {
9503 if children
9504 .iter()
9505 .any(|child| child.diagnostics.is_empty() && child.index > index)
9506 {
9507 *expected = expected_before_child;
9508 }
9509 }
9510 for child in children {
9511 let child_index = child.index;
9512 let child_consumed_eof = child.consumed_eof;
9513 let child_diagnostics = child.diagnostics;
9514 let empty_recovery = self.empty_recovery_symbols();
9515 let follow_outcomes = self.recognize_state_fast(
9516 atn,
9517 FastRecognizeRequest {
9518 state_number: follow_state,
9519 stop_state,
9520 index: child_index,
9521 rule_start_index,
9522 decision_start_index: next_decision_start_index,
9523 precedence,
9524 depth: depth + 1,
9525 recovery_symbols: empty_recovery,
9526 recovery_state: None,
9527 },
9528 FastRecognizeScratch {
9529 predicate_context,
9530 visiting,
9531 memo,
9532 expected,
9533 native_depth: native_depth + 1,
9534 },
9535 );
9536 if follow_outcomes.is_empty() {
9537 continue;
9538 }
9539 let child_stop_index =
9540 self.rule_stop_token_index(child_index, child_consumed_eof);
9541 let child_node = self.build_parse_trees.then(|| {
9542 self.recognition_arena.deferred_rule_node(FastDeferredRule {
9543 rule_index: u32::try_from(rule_index)
9544 .expect("rule index fits in u32"),
9545 invoking_state: i32::try_from(invoking_state_number(state_number))
9546 .expect("invoking state fits in i32"),
9547 start_index: u32::try_from(index)
9548 .expect("rule start index fits in u32"),
9549 stop_index: child_stop_index.map(|stop_index| {
9550 u32::try_from(stop_index).expect("rule stop index fits in u32")
9551 }),
9552 deferred_children: child.deferred_nodes,
9553 children: child.nodes,
9554 })
9555 });
9556 let child_diags_empty = child_diagnostics.is_empty();
9557 outcomes.extend(follow_outcomes.into_iter().map(|mut outcome| {
9558 outcome.consumed_eof |= child_consumed_eof;
9559 if !child_diags_empty {
9562 outcome.diagnostics = self
9563 .recognition_arena
9564 .concat_diagnostics(child_diagnostics, outcome.diagnostics);
9565 }
9566 if let Some(child_node) = child_node {
9567 outcome.deferred_nodes = self
9568 .recognition_arena
9569 .concat_deferred_nodes(child_node, outcome.deferred_nodes);
9570 }
9571 outcome
9572 }));
9573 }
9574 }
9575 ParserTransitionKind::Atom
9576 | ParserTransitionKind::Range
9577 | ParserTransitionKind::Set
9578 | ParserTransitionKind::NotSet
9579 | ParserTransitionKind::Wildcard => {
9580 #[cfg(feature = "perf-counters")]
9581 perf_counters::inc(&perf_counters::ATOM_RANGE_TRANSITIONS, 1);
9582 let symbol = self.token_type_at(index);
9583 if transition.matches_kind(transition_kind, symbol, 1, max_token_type) {
9584 let next_index = self.consume_index(index, symbol);
9585 let empty_recovery = self.empty_recovery_symbols();
9586 outcomes.extend(
9587 self.recognize_state_fast(
9588 atn,
9589 FastRecognizeRequest {
9590 state_number: target,
9591 stop_state,
9592 index: next_index,
9593 rule_start_index,
9594 decision_start_index: next_decision_start_index,
9595 precedence,
9596 depth: depth + 1,
9597 recovery_symbols: empty_recovery,
9598 recovery_state: None,
9599 },
9600 FastRecognizeScratch {
9601 predicate_context,
9602 visiting,
9603 memo,
9604 expected,
9605 native_depth: native_depth + 1,
9606 },
9607 )
9608 .into_iter()
9609 .map(|mut outcome| {
9610 outcome.consumed_eof |= symbol == TOKEN_EOF;
9611 if self.fast_token_nodes_enabled {
9612 let token = self.arena_token_node(index, false);
9613 self.defer_fast_outcome_node(&mut outcome, token);
9614 }
9615 outcome
9616 }),
9617 );
9618 } else {
9619 if !self.fast_recovery_enabled {
9620 continue;
9628 }
9629 let expected_symbols = fast_recovery_expected_symbols(
9630 self,
9631 atn,
9632 state.state_number(),
9633 &recovery_symbols,
9634 );
9635 if expected_symbols.contains(&symbol) {
9636 continue;
9637 }
9638 {
9639 expected.record_transition(index, transition, max_token_type);
9640 record_no_viable_if_ambiguous(
9641 expected,
9642 next_decision_start_index,
9643 index,
9644 );
9645 outcomes.extend(self.fast_single_token_deletion_recovery(
9646 FastRecoveryRequest {
9647 atn,
9648 transition,
9649 expected_symbols: Rc::clone(&expected_symbols),
9650 target,
9651 request: FastRecognizeRequest {
9652 state_number,
9653 stop_state,
9654 index,
9655 rule_start_index,
9656 decision_start_index,
9657 precedence,
9658 depth,
9659 recovery_symbols: Rc::clone(&recovery_symbols),
9660 recovery_state,
9661 },
9662 visiting,
9663 memo,
9664 expected,
9665 },
9666 predicate_context,
9667 ));
9668 if !state_is_left_recursive_rule(atn, state) {
9669 outcomes.extend(self.fast_single_token_insertion_recovery(
9670 FastRecoveryRequest {
9671 atn,
9672 transition,
9673 expected_symbols: Rc::clone(&expected_symbols),
9674 target,
9675 request: FastRecognizeRequest {
9676 state_number,
9677 stop_state,
9678 index,
9679 rule_start_index,
9680 decision_start_index,
9681 precedence,
9682 depth,
9683 recovery_symbols: Rc::clone(&recovery_symbols),
9684 recovery_state,
9685 },
9686 visiting,
9687 memo,
9688 expected,
9689 },
9690 predicate_context,
9691 ));
9692 }
9693 outcomes.extend(self.fast_current_token_deletion_recovery(
9694 FastCurrentTokenDeletionRequest {
9695 atn,
9696 expected_symbols,
9697 request: FastRecognizeRequest {
9698 state_number,
9699 stop_state,
9700 index,
9701 rule_start_index,
9702 decision_start_index,
9703 precedence,
9704 depth,
9705 recovery_symbols: Rc::clone(&recovery_symbols),
9706 recovery_state,
9707 },
9708 visiting,
9709 memo,
9710 expected,
9711 },
9712 predicate_context,
9713 ));
9714 }
9715 }
9716 }
9717 }
9718 let alt_number = next_alt_number(
9719 state,
9720 transition_count,
9721 transition_index,
9722 0,
9723 self.fast_track_alt_numbers,
9724 );
9725 if alt_number != 0 || left_recursive_boundary.is_some() {
9726 for outcome in &mut outcomes[outcomes_before_transition..] {
9727 if alt_number != 0 {
9728 self.defer_fast_outcome_alternative(outcome, alt_number);
9729 }
9730 if let Some(rule_index) = left_recursive_boundary {
9731 self.defer_fast_outcome_boundary(outcome, rule_index);
9732 }
9733 }
9734 }
9735 }
9736
9737 if has_inserted_cycle_guard {
9738 visiting.remove(&key);
9739 }
9740 if matches!(
9741 self.prediction_mode,
9742 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
9743 ) && self.fast_recovery_enabled
9744 {
9745 discard_recovered_fast_outcomes_if_clean_path_exists(&mut outcomes);
9749 }
9750 if self.fast_recovery_enabled {
9751 dedupe_fast_outcomes(&mut outcomes, &self.recognition_arena);
9752 } else {
9753 dedupe_clean_fast_outcomes(&mut outcomes, &mut self.fast_outcome_dedup);
9754 }
9755 let should_memoize = self.fast_recovery_enabled
9765 || (transition_count > 1 && self.clean_memo_mode != CleanMemoMode::Sparse);
9766 let mut apply_inline_pending = |mut outcome: FastRecognizeOutcome| -> FastRecognizeOutcome {
9770 if inline_consumed_eof {
9771 outcome.consumed_eof = true;
9772 }
9773 if !inline_consumed_tokens.is_empty() {
9774 for token_index in inline_consumed_tokens.iter().rev() {
9775 let token = self.arena_token_node(*token_index, false);
9776 self.defer_fast_outcome_node(&mut outcome, token);
9777 }
9778 }
9779 outcome
9780 };
9781 if should_memoize {
9782 #[cfg(feature = "perf-counters")]
9783 {
9784 perf_counters::inc(&perf_counters::MEMO_INSERTED, 1);
9785 perf_counters::inc(&perf_counters::OUTCOMES_PUSHED, outcomes.len() as u64);
9786 match outcomes.len() {
9787 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
9788 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
9789 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
9790 }
9791 }
9792 let stored: Rc<[FastRecognizeOutcome]> = Rc::from(outcomes);
9797 memo.insert(key, Rc::clone(&stored));
9798 if inline_pending {
9799 return stored
9800 .iter()
9801 .copied()
9802 .map(&mut apply_inline_pending)
9803 .collect();
9804 }
9805 return stored.to_vec();
9806 }
9807 #[cfg(feature = "perf-counters")]
9808 match outcomes.len() {
9809 0 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_0, 1),
9810 1 => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_1, 1),
9811 _ => perf_counters::inc(&perf_counters::OUTCOMES_RETURN_N, 1),
9812 }
9813 if inline_pending {
9814 return outcomes.into_iter().map(apply_inline_pending).collect();
9815 }
9816 outcomes
9817 }
9818
9819 fn single_token_deletion_recovery(
9822 &mut self,
9823 recovery: RecoveryRequest<'_, '_>,
9824 ) -> Vec<RecognizeOutcome> {
9825 let RecoveryRequest {
9826 atn,
9827 transition,
9828 expected_symbols,
9829 target,
9830 request,
9831 visiting,
9832 memo,
9833 expected,
9834 } = recovery;
9835 let RecognizeRequest {
9836 stop_state,
9837 index,
9838 rule_start_index,
9839 decision_start_index,
9840 init_action_rules,
9841 predicates,
9842 semantics,
9843 rule_args,
9844 member_actions,
9845 return_actions,
9846 local_int_arg,
9847 member_values,
9848 return_values,
9849 rule_alt_number,
9850 track_alt_numbers,
9851 consumed_eof,
9852 precedence,
9853 depth,
9854 ..
9855 } = request;
9856 let Some((diagnostic, next_index, next_symbol)) =
9857 self.single_token_deletion(transition, index, atn.max_token_type(), &expected_symbols)
9858 else {
9859 return Vec::new();
9860 };
9861 let after_next = self.consume_index(next_index, next_symbol);
9862 self.recognize_state(
9863 atn,
9864 RecognizeRequest {
9865 state_number: target,
9866 stop_state,
9867 index: after_next,
9868 rule_start_index,
9869 decision_start_index,
9870 init_action_rules,
9871 predicates,
9872 semantics,
9873 rule_args,
9874 member_actions,
9875 return_actions,
9876 local_int_arg,
9877 member_values,
9878 return_values,
9879 rule_alt_number,
9880 track_alt_numbers,
9881 consumed_eof: consumed_eof || next_symbol == TOKEN_EOF,
9882 committed_decision: false,
9883 precedence,
9884 depth: depth + 1,
9885 recovery_symbols: BTreeSet::new(),
9886 recovery_state: None,
9887 },
9888 visiting,
9889 memo,
9890 expected,
9891 )
9892 .into_iter()
9893 .map(|mut outcome| {
9894 outcome.consumed_eof |= next_symbol == TOKEN_EOF;
9895 outcome.diagnostics = self
9896 .recognition_arena
9897 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9898 let token = self.arena_token_node(next_index, false);
9899 self.arena_prepend(&mut outcome.nodes, token);
9900 let error = self.arena_token_node(index, true);
9901 self.arena_prepend(&mut outcome.nodes, error);
9902 outcome
9903 })
9904 .collect()
9905 }
9906
9907 fn current_token_deletion_recovery(
9910 &mut self,
9911 recovery: CurrentTokenDeletionRequest<'_, '_>,
9912 ) -> Vec<RecognizeOutcome> {
9913 let CurrentTokenDeletionRequest {
9914 atn,
9915 expected_symbols,
9916 mut request,
9917 visiting,
9918 memo,
9919 expected,
9920 } = recovery;
9921 let error_index = request.index;
9922 if error_index == request.rule_start_index {
9923 return Vec::new();
9924 }
9925 let Some((diagnostic, next_index, skipped)) =
9926 self.current_token_deletion(error_index, &expected_symbols)
9927 else {
9928 return Vec::new();
9929 };
9930 request.state_number = request.recovery_state.unwrap_or(request.state_number);
9931 request.index = next_index;
9932 request.committed_decision = false;
9933 request.depth += 1;
9934 request.recovery_state = None;
9935 self.recognize_state(atn, request, visiting, memo, expected)
9936 .into_iter()
9937 .map(|mut outcome| {
9938 outcome.diagnostics = self
9939 .recognition_arena
9940 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
9941 for index in skipped.iter().rev() {
9942 let error = self.arena_token_node(*index, true);
9943 self.arena_prepend(&mut outcome.nodes, error);
9944 }
9945 outcome
9946 })
9947 .collect()
9948 }
9949
9950 fn consuming_failure_fallback(
9953 &mut self,
9954 fallback: ConsumingFailureFallback<'_>,
9955 visiting: &mut BTreeSet<RecognizeKey>,
9956 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9957 expected: &mut ExpectedTokens,
9958 ) -> Vec<RecognizeOutcome> {
9959 if fallback.expected_symbols.is_empty() {
9960 return Vec::new();
9961 }
9962 if fallback.symbol == TOKEN_EOF {
9963 return self.eof_consuming_failure_fallback(fallback, expected);
9964 }
9965 self.non_eof_consuming_failure_fallback(fallback, visiting, memo, expected)
9966 }
9967
9968 fn non_eof_consuming_failure_fallback(
9971 &mut self,
9972 fallback: ConsumingFailureFallback<'_>,
9973 visiting: &mut BTreeSet<RecognizeKey>,
9974 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
9975 expected: &mut ExpectedTokens,
9976 ) -> Vec<RecognizeOutcome> {
9977 let ConsumingFailureFallback {
9978 atn,
9979 target,
9980 request,
9981 symbol,
9982 expected_symbols,
9983 decision_start_index,
9984 decision,
9985 } = fallback;
9986 let error_index = request.index;
9987 let diagnostic =
9988 self.recovery_failure_diagnostic(error_index, decision_start_index, &expected_symbols);
9989 let next_index = self.consume_index(error_index, symbol);
9990 self.recognize_state(
9991 atn,
9992 RecognizeRequest {
9993 state_number: target,
9994 stop_state: request.stop_state,
9995 index: next_index,
9996 rule_start_index: request.rule_start_index,
9997 decision_start_index,
9998 init_action_rules: request.init_action_rules,
9999 predicates: request.predicates,
10000 semantics: request.semantics,
10001 rule_args: request.rule_args,
10002 member_actions: request.member_actions,
10003 return_actions: request.return_actions,
10004 local_int_arg: request.local_int_arg,
10005 member_values: request.member_values,
10006 return_values: request.return_values,
10007 rule_alt_number: request.rule_alt_number,
10008 track_alt_numbers: request.track_alt_numbers,
10009 consumed_eof: request.consumed_eof,
10010 committed_decision: false,
10011 precedence: request.precedence,
10012 depth: request.depth + 1,
10013 recovery_symbols: BTreeSet::new(),
10014 recovery_state: None,
10015 },
10016 visiting,
10017 memo,
10018 expected,
10019 )
10020 .into_iter()
10021 .map(|mut outcome| {
10022 prepend_decision(&mut outcome, decision);
10023 outcome.diagnostics = self
10024 .recognition_arena
10025 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10026 let error = self.arena_token_node(error_index, true);
10027 self.arena_prepend(&mut outcome.nodes, error);
10028 outcome
10029 })
10030 .collect()
10031 }
10032
10033 fn eof_consuming_failure_fallback(
10036 &mut self,
10037 fallback: ConsumingFailureFallback<'_>,
10038 expected: &ExpectedTokens,
10039 ) -> Vec<RecognizeOutcome> {
10040 let request = fallback.request;
10041 if request.index == request.rule_start_index {
10042 return Vec::new();
10043 }
10044 let diagnostic =
10045 self.eof_rule_recovery_diagnostic(request.index, &fallback.expected_symbols, expected);
10046 let diagnostics = self
10047 .recognition_arena
10048 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
10049 vec![RecognizeOutcome {
10050 index: request.index,
10051 consumed_eof: request.consumed_eof,
10052 alt_number: request.rule_alt_number,
10053 member_values: request.member_values,
10054 return_values: request.return_values,
10055 diagnostics,
10056 decisions: Vec::new(),
10057 actions: Vec::new(),
10058 nodes: NodeSeqId::EMPTY,
10059 }]
10060 }
10061
10062 fn single_token_insertion_recovery(
10065 &mut self,
10066 recovery: RecoveryRequest<'_, '_>,
10067 ) -> Vec<RecognizeOutcome> {
10068 let RecoveryRequest {
10069 atn,
10070 transition,
10071 expected_symbols,
10072 target,
10073 request,
10074 visiting,
10075 memo,
10076 expected,
10077 } = recovery;
10078 let RecognizeRequest {
10079 stop_state,
10080 index,
10081 rule_start_index,
10082 decision_start_index,
10083 init_action_rules,
10084 predicates,
10085 semantics,
10086 rule_args,
10087 member_actions,
10088 return_actions,
10089 local_int_arg,
10090 member_values,
10091 return_values,
10092 rule_alt_number,
10093 track_alt_numbers,
10094 consumed_eof,
10095 precedence,
10096 depth,
10097 ..
10098 } = request;
10099 let follow_symbols = state_expected_symbols(atn, transition.target());
10100 let Some((diagnostic, token_type, text)) = self.single_token_insertion(
10101 transition,
10102 index,
10103 atn.max_token_type(),
10104 &expected_symbols,
10105 &follow_symbols,
10106 ) else {
10107 return Vec::new();
10108 };
10109 self.recognize_state(
10110 atn,
10111 RecognizeRequest {
10112 state_number: target,
10113 stop_state,
10114 index,
10115 rule_start_index,
10116 decision_start_index,
10117 init_action_rules,
10118 predicates,
10119 semantics,
10120 rule_args,
10121 member_actions,
10122 return_actions,
10123 local_int_arg,
10124 member_values,
10125 return_values,
10126 rule_alt_number,
10127 track_alt_numbers,
10128 consumed_eof,
10129 committed_decision: false,
10130 precedence,
10131 depth: depth + 1,
10132 recovery_symbols: BTreeSet::new(),
10133 recovery_state: None,
10134 },
10135 visiting,
10136 memo,
10137 expected,
10138 )
10139 .into_iter()
10140 .map(|mut outcome| {
10141 outcome.diagnostics = self
10142 .recognition_arena
10143 .prepend_diagnostic(outcome.diagnostics, diagnostic.clone());
10144 let missing = self.arena_missing_token_node(token_type, index, text.clone());
10145 self.arena_prepend(&mut outcome.nodes, missing);
10146 outcome
10147 })
10148 .collect()
10149 }
10150
10151 #[allow(clippy::too_many_lines)]
10154 fn recognize_state(
10155 &mut self,
10156 atn: &Atn,
10157 request: RecognizeRequest<'_>,
10158 visiting: &mut BTreeSet<RecognizeKey>,
10159 memo: &mut BTreeMap<RecognizeKey, Vec<RecognizeOutcome>>,
10160 expected: &mut ExpectedTokens,
10161 ) -> Vec<RecognizeOutcome> {
10162 let request_template = request.clone();
10163 let RecognizeRequest {
10164 state_number,
10165 stop_state,
10166 index,
10167 rule_start_index,
10168 decision_start_index,
10169 init_action_rules,
10170 predicates,
10171 semantics,
10172 rule_args,
10173 member_actions,
10174 return_actions,
10175 local_int_arg,
10176 member_values,
10177 return_values,
10178 rule_alt_number,
10179 track_alt_numbers,
10180 consumed_eof,
10181 committed_decision,
10182 precedence,
10183 depth,
10184 recovery_symbols,
10185 recovery_state,
10186 } = request;
10187 if depth > RECOGNITION_DEPTH_LIMIT {
10188 return Vec::new();
10189 }
10190 if state_number == stop_state {
10191 return stop_outcome(
10192 index,
10193 consumed_eof,
10194 rule_alt_number,
10195 member_values,
10196 return_values,
10197 );
10198 }
10199 let key = RecognizeKey {
10200 state_number,
10201 stop_state,
10202 index,
10203 rule_start_index,
10204 decision_start_index,
10205 local_int_arg,
10206 member_values: member_values.clone(),
10207 return_values: return_values.clone(),
10208 rule_alt_number,
10209 track_alt_numbers,
10210 consumed_eof,
10211 committed_decision,
10212 precedence,
10213 recovery_symbols: recovery_symbols.clone(),
10214 recovery_state,
10215 };
10216 if let Some(outcomes) = memo.get(&key) {
10217 return outcomes.clone();
10218 }
10219
10220 let visit_key = key.clone();
10221 if !visiting.insert(visit_key.clone()) {
10222 return Vec::new();
10223 }
10224
10225 let Some(state) = atn.state(state_number) else {
10226 visiting.remove(&visit_key);
10227 return Vec::new();
10228 };
10229 let decision_override_generation = self.decision_override_generation;
10230 let transitions = state.transitions();
10231 let transition_count = transitions.len();
10232 let overridden_transition = if transition_count > 1
10233 && self.semantic_hooks.observes_parser_decisions()
10234 {
10235 atn.decision_to_state()
10236 .iter()
10237 .position(|candidate| candidate == state_number)
10238 .and_then(|decision| {
10239 self.semantic_hooks
10240 .parser_decision_override(decision, index, transition_count)
10241 })
10242 .and_then(|alternative| alternative.checked_sub(1))
10243 .filter(|alternative| *alternative < transition_count)
10244 } else {
10245 None
10246 };
10247 if overridden_transition.is_some() {
10248 self.decision_override_generation = self.decision_override_generation.wrapping_add(1);
10249 }
10250 let next_decision_start_index = if starts_prediction_decision(state, transition_count) {
10251 Some(index)
10252 } else {
10253 decision_start_index
10254 };
10255 let (epsilon_recovery_symbols, epsilon_recovery_state) =
10256 next_recovery_context(atn, state, &recovery_symbols, recovery_state);
10257 let mut outcomes = Vec::new();
10258 for (transition_index, transition) in transitions.iter().enumerate() {
10259 if overridden_transition.is_some_and(|forced| forced != transition_index) {
10260 continue;
10261 }
10262 let transition_committed =
10263 committed_decision || overridden_transition == Some(transition_index);
10264 let mut transition_request = request_template.clone();
10265 transition_request.committed_decision = transition_committed;
10266 let decision =
10267 transition_decision(atn, state, transition_count, transition_index, predicates);
10268 let next_alt_number = next_alt_number(
10269 state,
10270 transition_count,
10271 transition_index,
10272 rule_alt_number,
10273 track_alt_numbers,
10274 );
10275 let transition_data = transition.data();
10276 match &transition_data {
10277 Transition::Epsilon { target } | Transition::Action { target, .. } => {
10278 let action_rule_index = match &transition_data {
10279 Transition::Action { rule_index, .. } => Some(*rule_index),
10280 _ => None,
10281 };
10282 outcomes.extend(self.recognize_epsilon_or_action_step(
10283 atn,
10284 &transition_request,
10285 EpsilonActionStep {
10286 source_state: state_number,
10287 target: *target,
10288 action_rule_index,
10289 left_recursive_boundary: left_recursive_boundary(atn, state, *target),
10290 decision,
10291 decision_start_index: next_decision_start_index,
10292 alt_number: next_alt_number,
10293 recovery_symbols: epsilon_recovery_symbols.clone(),
10294 recovery_state: epsilon_recovery_state,
10295 },
10296 RecognizeScratch {
10297 visiting,
10298 memo,
10299 expected,
10300 },
10301 ));
10302 }
10303 Transition::Predicate {
10304 target,
10305 rule_index,
10306 pred_index,
10307 ..
10308 } => {
10309 let predicate = PredicateEval {
10310 index,
10311 rule_index: *rule_index,
10312 pred_index: *pred_index,
10313 predicates,
10314 semantics,
10315 context: None,
10316 local_int_arg,
10317 member_values: &member_values,
10318 };
10319 if self.parser_predicate_matches(predicate) {
10320 let left_recursive_boundary = left_recursive_boundary(atn, state, *target);
10321 outcomes.extend(
10322 self.recognize_state(
10323 atn,
10324 RecognizeRequest {
10325 state_number: *target,
10326 stop_state,
10327 index,
10328 rule_start_index,
10329 decision_start_index: next_decision_start_index,
10330 init_action_rules,
10331 predicates,
10332 semantics,
10333 rule_args,
10334 member_actions,
10335 return_actions,
10336 local_int_arg,
10337 member_values: member_values.clone(),
10338 return_values: return_values.clone(),
10339 rule_alt_number: next_alt_number,
10340 track_alt_numbers,
10341 consumed_eof,
10342 committed_decision: transition_committed,
10343 precedence,
10344 depth: depth + 1,
10345 recovery_symbols: epsilon_recovery_symbols.clone(),
10346 recovery_state: epsilon_recovery_state,
10347 },
10348 visiting,
10349 memo,
10350 expected,
10351 )
10352 .into_iter()
10353 .map(|mut outcome| {
10354 prepend_decision(&mut outcome, decision);
10355 if let Some(rule_index) = left_recursive_boundary {
10356 let boundary =
10357 self.arena_boundary_node(rule_index, next_alt_number);
10358 self.arena_prepend(&mut outcome.nodes, boundary);
10359 }
10360 outcome
10361 }),
10362 );
10363 } else if let Some(message) = semantics
10364 .and_then(|semantics| {
10365 self.parser_semantic_ir_predicate_failure_message(
10366 *rule_index,
10367 *pred_index,
10368 semantics,
10369 )
10370 })
10371 .or_else(|| {
10372 self.parser_predicate_failure_message(
10373 *rule_index,
10374 *pred_index,
10375 predicates,
10376 )
10377 })
10378 {
10379 outcomes.push(self.predicate_failure_recovery(PredicateFailureRecovery {
10380 rule_index: *rule_index,
10381 index,
10382 message,
10383 member_values: member_values.clone(),
10384 return_values: return_values.clone(),
10385 rule_alt_number,
10386 }));
10387 } else {
10388 record_predicate_no_viable(expected, next_decision_start_index, index);
10389 }
10390 }
10391 Transition::Precedence {
10392 target,
10393 precedence: transition_precedence,
10394 } => {
10395 if *transition_precedence >= precedence {
10396 outcomes.extend(
10397 self.recognize_state(
10398 atn,
10399 RecognizeRequest {
10400 state_number: *target,
10401 stop_state,
10402 index,
10403 rule_start_index,
10404 decision_start_index: next_decision_start_index,
10405 init_action_rules,
10406 predicates,
10407 semantics,
10408 rule_args,
10409 member_actions,
10410 return_actions,
10411 local_int_arg,
10412 member_values: member_values.clone(),
10413 return_values: return_values.clone(),
10414 rule_alt_number: next_alt_number,
10415 track_alt_numbers,
10416 consumed_eof,
10417 committed_decision: transition_committed,
10418 precedence,
10419 depth: depth + 1,
10420 recovery_symbols: epsilon_recovery_symbols.clone(),
10421 recovery_state: epsilon_recovery_state,
10422 },
10423 visiting,
10424 memo,
10425 expected,
10426 )
10427 .into_iter()
10428 .map(|mut outcome| {
10429 prepend_decision(&mut outcome, decision);
10430 outcome
10431 }),
10432 );
10433 }
10434 }
10435 Transition::Rule {
10436 target,
10437 rule_index,
10438 follow_state,
10439 precedence: rule_precedence,
10440 ..
10441 } => {
10442 let Some(child_stop) = atn.rule_to_stop_state().get(*rule_index) else {
10443 continue;
10444 };
10445 let child_local_int_arg =
10446 rule_local_int_arg(rule_args, state_number, *rule_index, local_int_arg);
10447 let expected_before_child = expected.clone();
10448 let children = self.recognize_state(
10449 atn,
10450 RecognizeRequest {
10451 state_number: *target,
10452 stop_state: child_stop,
10453 index,
10454 rule_start_index: index,
10455 decision_start_index: None,
10456 init_action_rules,
10457 predicates,
10458 semantics,
10459 rule_args,
10460 member_actions,
10461 return_actions,
10462 local_int_arg: child_local_int_arg,
10463 member_values: member_values.clone(),
10464 return_values: BTreeMap::new(),
10465 rule_alt_number: 0,
10466 track_alt_numbers,
10467 consumed_eof: false,
10468 committed_decision: transition_committed,
10469 precedence: *rule_precedence,
10470 depth: depth + 1,
10471 recovery_symbols: epsilon_recovery_symbols.clone(),
10472 recovery_state: epsilon_recovery_state,
10473 },
10474 visiting,
10475 memo,
10476 expected,
10477 );
10478 let children = if children.is_empty() {
10479 self.child_rule_failure_recovery_outcomes(ChildRuleFailureRecovery {
10480 atn,
10481 rule_index: *rule_index,
10482 start_index: index,
10483 follow_state: *follow_state,
10484 stop_state,
10485 member_values: member_values.clone(),
10486 expected,
10487 })
10488 } else {
10489 children
10490 };
10491 let preserve_child_expected =
10492 self.child_expected_reaches_clean_eof(&children, expected);
10493 restore_expected(
10494 &children,
10495 index,
10496 expected,
10497 expected_before_child,
10498 preserve_child_expected,
10499 );
10500 for child in children {
10501 let child_stop_index =
10502 self.rule_stop_token_index(child.index, child.consumed_eof);
10503 let child_nodes = self
10504 .recognition_arena
10505 .fold_left_recursive_boundaries(child.nodes);
10506 let child_node = self.arena_rule_node(ArenaRuleSpec {
10507 rule_index: *rule_index,
10508 invoking_state: invoking_state_number(state_number),
10509 alt_number: child.alt_number,
10510 start_index: index,
10511 stop_index: child_stop_index,
10512 return_values: child.return_values.clone(),
10513 children: child_nodes,
10514 });
10515 outcomes.extend(
10516 self.recognize_state(
10517 atn,
10518 RecognizeRequest {
10519 state_number: *follow_state,
10520 stop_state,
10521 index: child.index,
10522 rule_start_index,
10523 decision_start_index: next_decision_start_index,
10524 init_action_rules,
10525 predicates,
10526 semantics,
10527 rule_args,
10528 member_actions,
10529 return_actions,
10530 local_int_arg,
10531 member_values: child.member_values.clone(),
10532 return_values: return_values.clone(),
10533 rule_alt_number,
10534 track_alt_numbers,
10535 consumed_eof: consumed_eof || child.consumed_eof,
10536 committed_decision: transition_committed
10537 && child.index == index,
10538 precedence,
10539 depth: depth + 1,
10540 recovery_symbols: BTreeSet::new(),
10541 recovery_state: None,
10542 },
10543 visiting,
10544 memo,
10545 expected,
10546 )
10547 .into_iter()
10548 .map(|mut outcome| {
10549 outcome.consumed_eof |= child.consumed_eof;
10550 outcome.diagnostics = self
10551 .recognition_arena
10552 .concat_diagnostics(child.diagnostics, outcome.diagnostics);
10553 let mut decisions = child.decisions.clone();
10554 decisions.append(&mut outcome.decisions);
10555 outcome.decisions = decisions;
10556 prepend_decision(&mut outcome, decision);
10557 let mut actions = child.actions.clone();
10558 if init_action_rules.contains(rule_index) {
10559 actions.insert(
10560 0,
10561 ParserAction::new_rule_init(
10562 *rule_index,
10563 index,
10564 Some(*follow_state),
10565 ),
10566 );
10567 }
10568 actions.append(&mut outcome.actions);
10569 outcome.actions = actions;
10570 self.arena_prepend(&mut outcome.nodes, child_node);
10571 outcome
10572 }),
10573 );
10574 }
10575 }
10576 Transition::Atom { target, .. }
10577 | Transition::Range { target, .. }
10578 | Transition::Set { target, .. }
10579 | Transition::NotSet { target, .. }
10580 | Transition::Wildcard { target, .. } => {
10581 let symbol = self.token_type_at(index);
10582 if transition_data.matches(symbol, 1, atn.max_token_type()) {
10583 let next_index = self.consume_index(index, symbol);
10584 outcomes.extend(
10585 self.recognize_state(
10586 atn,
10587 RecognizeRequest {
10588 state_number: *target,
10589 stop_state,
10590 index: next_index,
10591 rule_start_index,
10592 decision_start_index: next_decision_start_index,
10593 init_action_rules,
10594 predicates,
10595 semantics,
10596 rule_args,
10597 member_actions,
10598 return_actions,
10599 local_int_arg,
10600 member_values: member_values.clone(),
10601 return_values: return_values.clone(),
10602 rule_alt_number: next_alt_number,
10603 track_alt_numbers,
10604 consumed_eof: consumed_eof || symbol == TOKEN_EOF,
10605 committed_decision: false,
10606 precedence,
10607 depth: depth + 1,
10608 recovery_symbols: BTreeSet::new(),
10609 recovery_state: None,
10610 },
10611 visiting,
10612 memo,
10613 expected,
10614 )
10615 .into_iter()
10616 .map(|mut outcome| {
10617 prepend_decision(&mut outcome, decision);
10618 outcome.consumed_eof |= symbol == TOKEN_EOF;
10619 let token = self.arena_token_node(index, false);
10620 self.arena_prepend(&mut outcome.nodes, token);
10621 outcome
10622 }),
10623 );
10624 } else {
10625 let expected_symbols =
10626 recovery_expected_symbols(atn, state.state_number(), &recovery_symbols);
10627 if expected_symbols.contains(&symbol) && !transition_committed {
10628 continue;
10629 }
10630 expected.record_transition(index, transition, atn.max_token_type());
10631 record_no_viable_if_ambiguous(expected, next_decision_start_index, index);
10632 let before_recovery = outcomes.len();
10633 let recovery_request = transition_request.clone();
10634 if transition_committed {
10635 outcomes.extend(self.consuming_failure_fallback(
10636 ConsumingFailureFallback {
10637 atn,
10638 target: *target,
10639 request: recovery_request,
10640 symbol,
10641 expected_symbols,
10642 decision_start_index: next_decision_start_index,
10643 decision,
10644 },
10645 visiting,
10646 memo,
10647 expected,
10648 ));
10649 break;
10650 }
10651 outcomes.extend(
10652 self.single_token_deletion_recovery(RecoveryRequest {
10653 atn,
10654 transition,
10655 expected_symbols: expected_symbols.clone(),
10656 target: *target,
10657 request: recovery_request.clone(),
10658 visiting,
10659 memo,
10660 expected,
10661 })
10662 .into_iter()
10663 .map(|mut outcome| {
10664 prepend_decision(&mut outcome, decision);
10665 outcome
10666 }),
10667 );
10668 if !state_is_left_recursive_rule(atn, state) {
10669 outcomes.extend(
10670 self.single_token_insertion_recovery(RecoveryRequest {
10671 atn,
10672 transition,
10673 expected_symbols: expected_symbols.clone(),
10674 target: *target,
10675 request: recovery_request.clone(),
10676 visiting,
10677 memo,
10678 expected,
10679 })
10680 .into_iter()
10681 .map(|mut outcome| {
10682 prepend_decision(&mut outcome, decision);
10683 outcome
10684 }),
10685 );
10686 }
10687 outcomes.extend(self.current_token_deletion_recovery(
10688 CurrentTokenDeletionRequest {
10689 atn,
10690 expected_symbols: expected_symbols.clone(),
10691 request: recovery_request.clone(),
10692 visiting,
10693 memo,
10694 expected,
10695 },
10696 ));
10697 if outcomes.len() == before_recovery {
10698 outcomes.extend(self.consuming_failure_fallback(
10699 ConsumingFailureFallback {
10700 atn,
10701 target: *target,
10702 request: recovery_request,
10703 symbol,
10704 expected_symbols,
10705 decision_start_index: next_decision_start_index,
10706 decision,
10707 },
10708 visiting,
10709 memo,
10710 expected,
10711 ));
10712 }
10713 }
10714 }
10715 }
10716 if self.decision_override_generation != decision_override_generation {
10717 break;
10718 }
10719 }
10720
10721 visiting.remove(&visit_key);
10722 self.record_prediction_diagnostics(atn, state, index, &outcomes);
10723 if matches!(
10724 self.prediction_mode,
10725 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
10726 ) {
10727 discard_recovered_outcomes_if_clean_path_exists(&mut outcomes, &self.recognition_arena);
10728 }
10729 dedupe_outcomes(&mut outcomes, &self.recognition_arena);
10730 memo.insert(key, outcomes.clone());
10731 outcomes
10732 }
10733
10734 fn recognize_epsilon_or_action_step(
10737 &mut self,
10738 atn: &Atn,
10739 request: &RecognizeRequest<'_>,
10740 step: EpsilonActionStep,
10741 scratch: RecognizeScratch<'_>,
10742 ) -> Vec<RecognizeOutcome> {
10743 let RecognizeScratch {
10744 visiting,
10745 memo,
10746 expected,
10747 } = scratch;
10748 let action = step.action_rule_index.map(|rule_index| {
10749 ParserAction::new(
10750 step.source_state,
10751 rule_index,
10752 request.rule_start_index,
10753 self.rule_stop_token_index(request.index, request.consumed_eof),
10754 )
10755 });
10756 let next_member_values = if action.is_some() {
10757 member_values_after_action(
10758 step.source_state,
10759 request.member_actions,
10760 request.semantics,
10761 &request.member_values,
10762 )
10763 } else {
10764 request.member_values.clone()
10765 };
10766 let next_return_values = action.map_or_else(
10767 || request.return_values.clone(),
10768 |action| {
10769 return_values_after_action(
10770 step.source_state,
10771 action.rule_index(),
10772 request.return_actions,
10773 request.semantics,
10774 &request.return_values,
10775 )
10776 },
10777 );
10778
10779 self.recognize_state(
10780 atn,
10781 RecognizeRequest {
10782 state_number: step.target,
10783 stop_state: request.stop_state,
10784 index: request.index,
10785 rule_start_index: request.rule_start_index,
10786 decision_start_index: step.decision_start_index,
10787 init_action_rules: request.init_action_rules,
10788 predicates: request.predicates,
10789 semantics: request.semantics,
10790 rule_args: request.rule_args,
10791 member_actions: request.member_actions,
10792 return_actions: request.return_actions,
10793 local_int_arg: request.local_int_arg,
10794 member_values: next_member_values,
10795 return_values: next_return_values,
10796 rule_alt_number: if step.left_recursive_boundary.is_some() {
10797 0
10798 } else {
10799 step.alt_number
10800 },
10801 track_alt_numbers: request.track_alt_numbers,
10802 consumed_eof: request.consumed_eof,
10803 committed_decision: request.committed_decision,
10804 precedence: request.precedence,
10805 depth: request.depth + 1,
10806 recovery_symbols: step.recovery_symbols,
10807 recovery_state: step.recovery_state,
10808 },
10809 visiting,
10810 memo,
10811 expected,
10812 )
10813 .into_iter()
10814 .map(|mut outcome| {
10815 prepend_decision(&mut outcome, step.decision);
10816 if let Some(rule_index) = step.left_recursive_boundary {
10817 let boundary = self.arena_boundary_node(rule_index, step.alt_number);
10818 self.arena_prepend(&mut outcome.nodes, boundary);
10819 }
10820 if let Some(action) = action {
10821 outcome.actions.insert(0, action);
10822 }
10823 outcome
10824 })
10825 .collect()
10826 }
10827
10828 fn token_type_at(&mut self, index: usize) -> i32 {
10833 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !self.input.is_filled() {
10834 self.input.fill();
10835 }
10836 self.input.token_type_at_index(index)
10837 }
10838
10839 fn cached_state_expected_symbols(
10851 &mut self,
10852 atn: &Atn,
10853 state_number: usize,
10854 ) -> Rc<BTreeSet<i32>> {
10855 if let Some(cached) = self.state_expected_cache.get(&state_number) {
10856 return Rc::clone(cached);
10857 }
10858 let symbols = state_expected_symbols(atn, state_number);
10859 let entry = self.intern_recovery_symbols(symbols);
10860 self.state_expected_cache
10861 .insert(state_number, Rc::clone(&entry));
10862 entry
10863 }
10864
10865 fn cached_state_expected_token_set(
10866 &mut self,
10867 atn: &Atn,
10868 state_number: usize,
10869 ) -> Rc<TokenBitSet> {
10870 if let Some(cached) = self.state_expected_token_cache.get(&state_number) {
10871 return Rc::clone(cached);
10872 }
10873 let symbols = with_shared_atn_caches(atn, |cache| {
10877 if let Some(cached) = cache.state_expected_tokens.get(&state_number) {
10878 return Rc::clone(cached);
10879 }
10880 let symbols = Rc::new(state_expected_token_set(atn, state_number));
10881 cache
10882 .state_expected_tokens
10883 .insert(state_number, Rc::clone(&symbols));
10884 symbols
10885 });
10886 self.state_expected_token_cache
10887 .insert(state_number, Rc::clone(&symbols));
10888 symbols
10889 }
10890
10891 fn cached_state_can_reach_rule_stop(&mut self, atn: &Atn, state_number: usize) -> bool {
10892 if self.rule_stop_reach_cache.len() <= state_number {
10893 self.rule_stop_reach_cache
10894 .resize_with(atn.states().len().max(state_number + 1), || None);
10895 }
10896 if let Some(reaches) = self.rule_stop_reach_cache[state_number] {
10897 return reaches;
10898 }
10899 let reaches = with_shared_atn_caches(atn, |cache| {
10900 *cache
10901 .rule_stop_reach
10902 .entry(state_number)
10903 .or_insert_with(|| state_can_reach_rule_stop(atn, state_number))
10904 });
10905 self.rule_stop_reach_cache[state_number] = Some(reaches);
10906 reaches
10907 }
10908
10909 fn empty_recovery_symbols(&self) -> Rc<BTreeSet<i32>> {
10912 Rc::clone(&self.empty_recovery_symbols)
10913 }
10914
10915 fn intern_recovery_symbols(&mut self, set: BTreeSet<i32>) -> Rc<BTreeSet<i32>> {
10924 if set.is_empty() {
10925 return Rc::clone(&self.empty_recovery_symbols);
10926 }
10927 let candidate = Rc::new(set);
10928 match self.recovery_symbols_intern.get(&candidate) {
10929 Some(existing) => Rc::clone(existing),
10930 None => {
10931 self.recovery_symbols_intern
10932 .insert(Rc::clone(&candidate), Rc::clone(&candidate));
10933 candidate
10934 }
10935 }
10936 }
10937
10938 fn cached_decision_lookahead(
10943 &mut self,
10944 atn: &Atn,
10945 state: AtnState<'_>,
10946 rule_stop_state: usize,
10947 ) -> Rc<DecisionLookahead> {
10948 if let Some(cached) = self.decision_lookahead_cache.get(&state.state_number()) {
10955 return Rc::clone(cached);
10956 }
10957 let entry = with_shared_atn_caches(atn, |cache| {
10958 if let Some(cached) = cache.decision_lookahead.get(&state.state_number()) {
10959 return Rc::clone(cached);
10960 }
10961 let mut entry = DecisionLookahead {
10962 transitions: Vec::with_capacity(state.transitions().len()),
10963 };
10964 for transition in &state.transitions() {
10965 entry.transitions.push(transition_first_set(
10966 atn,
10967 transition,
10968 rule_stop_state,
10969 &mut cache.first_set,
10970 ));
10971 }
10972 let entry = Rc::new(entry);
10973 cache
10974 .decision_lookahead
10975 .insert(state.state_number(), Rc::clone(&entry));
10976 entry
10977 });
10978 self.decision_lookahead_cache
10979 .insert(state.state_number(), Rc::clone(&entry));
10980 entry
10981 }
10982
10983 fn cached_rule_first_set(
10984 &mut self,
10985 atn: &Atn,
10986 target: usize,
10987 child_stop: usize,
10988 ) -> Rc<FirstSet> {
10989 if self.rule_first_set_cache.len() <= target {
10990 self.rule_first_set_cache
10991 .resize_with(atn.states().len().max(target + 1), || None);
10992 }
10993 if let Some(cached) = self
10994 .rule_first_set_cache
10995 .get(target)
10996 .and_then(Option::as_ref)
10997 {
10998 return Rc::clone(cached);
10999 }
11000 let first = with_shared_first_set_cache(atn, |cache| {
11001 rule_first_set(atn, target, child_stop, cache)
11002 });
11003 self.rule_first_set_cache[target] = Some(Rc::clone(&first));
11004 first
11005 }
11006
11007 fn state_can_reenter_without_consuming(&mut self, atn: &Atn, state_number: usize) -> bool {
11008 let atn_key = SharedAtnCacheKey::for_atn(atn);
11009 if self.empty_cycle_cache_atn != Some(atn_key) {
11010 self.empty_cycle_cache.clear();
11011 self.empty_cycle_cache_atn = Some(atn_key);
11012 }
11013 if self.empty_cycle_cache.len() <= state_number {
11014 self.empty_cycle_cache
11015 .resize_with(atn.state_count().max(state_number + 1), || None);
11016 }
11017 if let Some(cached) = self.empty_cycle_cache[state_number] {
11018 return cached;
11019 }
11020 let mut visited = FxHashSet::with_capacity_and_hasher(64, FxBuildHasher::default());
11021 let result = self.empty_path_reaches_state(atn, state_number, state_number, &mut visited);
11022 self.empty_cycle_cache[state_number] = Some(result);
11023 result
11024 }
11025
11026 fn empty_path_reaches_state(
11027 &mut self,
11028 atn: &Atn,
11029 state_number: usize,
11030 target_state: usize,
11031 visited: &mut FxHashSet<usize>,
11032 ) -> bool {
11033 enum Work {
11034 Visit(usize),
11035 RuleFollow {
11036 target: usize,
11037 rule_index: usize,
11038 follow_state: usize,
11039 },
11040 }
11041
11042 let mut work = vec![Work::Visit(state_number)];
11043 while let Some(item) = work.pop() {
11044 match item {
11045 Work::Visit(state_number) => {
11046 if !visited.insert(state_number) {
11047 continue;
11048 }
11049 let Some(state) = atn.state(state_number) else {
11050 continue;
11051 };
11052 let transitions = state.transitions();
11053 for transition_index in (0..transitions.len()).rev() {
11054 let transition = transitions
11055 .get(transition_index)
11056 .expect("in-bounds parser transition");
11057 let kind = transition.kind();
11058 let target = transition.target();
11059 match kind {
11060 ParserTransitionKind::Atom
11061 | ParserTransitionKind::Range
11062 | ParserTransitionKind::Set
11063 | ParserTransitionKind::NotSet
11064 | ParserTransitionKind::Wildcard => {}
11065 ParserTransitionKind::Rule => {
11066 if target == target_state {
11067 return true;
11068 }
11069 work.push(Work::RuleFollow {
11070 target,
11071 rule_index: transition.arg0() as usize,
11072 follow_state: transition.arg1() as usize,
11073 });
11074 work.push(Work::Visit(target));
11075 }
11076 ParserTransitionKind::Epsilon
11077 | ParserTransitionKind::Predicate
11078 | ParserTransitionKind::Action
11079 | ParserTransitionKind::Precedence => {
11080 if target == target_state {
11081 return true;
11082 }
11083 work.push(Work::Visit(target));
11084 }
11085 }
11086 }
11087 }
11088 Work::RuleFollow {
11089 target,
11090 rule_index,
11091 follow_state,
11092 } => {
11093 let Some(child_stop) = atn.rule_to_stop_state().get(rule_index) else {
11094 continue;
11095 };
11096 if self.cached_rule_first_set(atn, target, child_stop).nullable {
11097 if follow_state == target_state {
11098 return true;
11099 }
11100 work.push(Work::Visit(follow_state));
11101 }
11102 }
11103 }
11104 }
11105 false
11106 }
11107
11108 fn clean_memo_enabled_for_key(&mut self, key: &FastRecognizeKey) -> bool {
11111 match self.clean_memo_mode {
11112 CleanMemoMode::Promote => true,
11113 CleanMemoMode::Probe => self.observe_clean_memo_probe(key),
11114 CleanMemoMode::Sparse => {
11115 self.clean_memo_sparse_samples += 1;
11116 if self.clean_memo_sparse_samples < CLEAN_MEMO_REPROBE_INTERVAL {
11117 return false;
11118 }
11119 self.clean_memo_sparse_samples = 0;
11120 self.clean_memo_mode = CleanMemoMode::Probe;
11121 self.clean_memo_probe_samples = 0;
11122 self.clean_memo_probe_repeats = 0;
11123 self.clean_memo_probe_seen.clear();
11124 self.observe_clean_memo_probe(key)
11125 }
11126 }
11127 }
11128
11129 fn observe_clean_memo_probe(&mut self, key: &FastRecognizeKey) -> bool {
11130 self.clean_memo_probe_samples += 1;
11131 if !self.clean_memo_probe_seen.insert(key.clone()) {
11132 self.clean_memo_probe_repeats += 1;
11133 }
11134 if self.clean_memo_probe_repeats >= CLEAN_MEMO_REPEAT_LIMIT {
11135 self.clean_memo_mode = CleanMemoMode::Promote;
11136 self.clean_memo_probe_seen.clear();
11137 return true;
11138 }
11139 if self.clean_memo_probe_samples >= CLEAN_MEMO_PROBE_LIMIT {
11140 self.clean_memo_mode = CleanMemoMode::Sparse;
11141 self.clean_memo_sparse_samples = 0;
11142 self.clean_memo_probe_seen.clear();
11143 return false;
11144 }
11145 true
11146 }
11147
11148 fn token_at(&self, index: usize) -> Option<TokenView<'_>> {
11150 self.input.get(index)
11151 }
11152
11153 fn token_id_at(&self, index: usize) -> Option<TokenId> {
11155 self.input.get_id(index)
11156 }
11157
11158 fn arena_token_node(&mut self, index: usize, error: bool) -> RecognizedNodeId {
11159 let token = self
11160 .token_id_at(index)
11161 .expect("recognized token index must exist in the token store");
11162 let node = if error {
11163 ArenaRecognizedNode::ErrorToken { token }
11164 } else {
11165 ArenaRecognizedNode::Token { token }
11166 };
11167 self.recognition_arena.push_node(node)
11168 }
11169
11170 fn arena_missing_token_node(
11171 &mut self,
11172 token_type: i32,
11173 at_index: usize,
11174 text: String,
11175 ) -> RecognizedNodeId {
11176 let extra = self
11177 .recognition_arena
11178 .push_extra(RecognitionExtra::MissingToken {
11179 token_type,
11180 at_index: u32::try_from(at_index).expect("missing-token stream index fits in u32"),
11181 text,
11182 });
11183 self.recognition_arena
11184 .push_node(ArenaRecognizedNode::MissingToken { extra })
11185 }
11186
11187 fn arena_rule_node(&mut self, spec: ArenaRuleSpec) -> RecognizedNodeId {
11188 let ArenaRuleSpec {
11189 rule_index,
11190 invoking_state,
11191 alt_number,
11192 start_index,
11193 stop_index,
11194 return_values,
11195 children,
11196 } = spec;
11197 let return_values = (!return_values.is_empty()).then(|| {
11198 self.recognition_arena
11199 .push_extra(RecognitionExtra::ReturnValues(return_values))
11200 });
11201 self.recognition_arena.push_node(ArenaRecognizedNode::Rule {
11202 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11203 invoking_state: i32::try_from(invoking_state).expect("invoking state fits in i32"),
11204 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11205 start_index: u32::try_from(start_index).expect("rule start index fits in u32"),
11206 stop_index: stop_index
11207 .map(|index| u32::try_from(index).expect("rule stop index fits in u32")),
11208 return_values,
11209 children,
11210 })
11211 }
11212
11213 fn arena_boundary_node(&mut self, rule_index: usize, alt_number: usize) -> RecognizedNodeId {
11214 self.recognition_arena
11215 .push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
11216 rule_index: u32::try_from(rule_index).expect("rule index fits in u32"),
11217 alt_number: u32::try_from(alt_number).expect("alternative number fits in u32"),
11218 })
11219 }
11220
11221 fn arena_prepend(&mut self, sequence: &mut NodeSeqId, node: RecognizedNodeId) {
11222 *sequence = self.recognition_arena.prepend(*sequence, node);
11223 }
11224
11225 fn finish_recognition_arena(&mut self, root: NodeSeqId, diagnostics: DiagnosticSeqId) {
11226 self.last_recognition_arena_root = root;
11227 self.last_recognition_arena_diagnostics = diagnostics;
11228 #[cfg(feature = "perf-counters")]
11229 if std::env::var("ANTLR_PERF_DUMP").is_ok() {
11230 let stats = self.recognition_arena_stats();
11231 #[allow(clippy::print_stderr)]
11232 {
11233 eprintln!("perf recognition_nodes_total={}", stats.total_nodes);
11234 eprintln!("perf recognition_nodes_live={}", stats.live_nodes);
11235 eprintln!("perf recognition_nodes_dead={}", stats.dead_nodes);
11236 eprintln!("perf recognition_nodes_capacity={}", stats.node_capacity);
11237 eprintln!("perf recognition_links_total={}", stats.total_links);
11238 eprintln!("perf recognition_links_live={}", stats.live_links);
11239 eprintln!("perf recognition_links_dead={}", stats.dead_links);
11240 eprintln!("perf recognition_links_capacity={}", stats.link_capacity);
11241 eprintln!("perf recognition_extras_total={}", stats.total_extras);
11242 eprintln!("perf recognition_extras_live={}", stats.live_extras);
11243 eprintln!("perf recognition_extras_dead={}", stats.dead_extras);
11244 eprintln!("perf recognition_extras_capacity={}", stats.extra_capacity);
11245 }
11246 }
11247 }
11248
11249 fn reset_recognition_arena(&mut self) {
11250 self.recognition_arena.reset();
11251 self.last_recognition_arena_root = NodeSeqId::EMPTY;
11252 self.last_recognition_arena_diagnostics = DiagnosticSeqId::EMPTY;
11253 }
11254
11255 fn current_visible_index(&mut self) -> usize {
11258 let index = self.input.index();
11259 self.input.seek(index);
11260 self.input.index()
11261 }
11262
11263 fn child_expected_reaches_clean_eof(
11266 &mut self,
11267 children: &[RecognizeOutcome],
11268 expected: &ExpectedTokens,
11269 ) -> bool {
11270 let Some(index) = expected.index else {
11271 return false;
11272 };
11273 self.token_type_at(index) == TOKEN_EOF
11274 && children
11275 .iter()
11276 .any(|child| child.diagnostics.is_empty() && child.index == index)
11277 }
11278
11279 fn previous_token_index(&self, index: usize) -> Option<usize> {
11286 self.input.previous_visible_token_index(index)
11287 }
11288
11289 fn rule_stop_token_index(&mut self, index: usize, consumed_eof: bool) -> Option<usize> {
11294 if consumed_eof && self.token_type_at(index) == TOKEN_EOF {
11295 Some(index)
11296 } else {
11297 self.previous_token_index(index)
11298 }
11299 }
11300
11301 #[must_use]
11318 pub fn after_action_stop_index(&mut self, current_index: usize) -> Option<usize> {
11319 let consumed_eof = self.token_type_at(current_index) == TOKEN_EOF;
11320 self.rule_stop_token_index(current_index, consumed_eof)
11321 }
11322
11323 #[must_use]
11332 pub fn after_action_stop_index_for_tree(
11333 &mut self,
11334 tree: ParseTree,
11335 current_index: usize,
11336 ) -> Option<usize> {
11337 if let Some(stop) = self
11338 .node(tree)
11339 .as_rule()
11340 .and_then(crate::tree::RuleNodeView::stop_id)
11341 {
11342 return Some(stop.index());
11343 }
11344 self.after_action_stop_index(current_index)
11345 }
11346
11347 #[must_use]
11357 pub fn after_action_start_index_for_tree(
11358 &self,
11359 tree: ParseTree,
11360 fallback_index: usize,
11361 ) -> usize {
11362 if let Some(start) = self
11363 .node(tree)
11364 .as_rule()
11365 .and_then(crate::tree::RuleNodeView::start_id)
11366 {
11367 return start.index();
11368 }
11369 fallback_index
11370 }
11371
11372 fn rule_stop_token_id(&mut self, index: usize, consumed_eof: bool) -> Option<TokenId> {
11377 self.rule_stop_token_index(index, consumed_eof)
11378 .and_then(|token_index| self.token_id_at(token_index))
11379 }
11380
11381 fn predicate_failure_recovery(
11388 &mut self,
11389 request: PredicateFailureRecovery<'_>,
11390 ) -> RecognizeOutcome {
11391 let PredicateFailureRecovery {
11392 rule_index,
11393 index,
11394 message,
11395 member_values,
11396 return_values,
11397 rule_alt_number,
11398 } = request;
11399 let rule_name = self
11400 .rule_names()
11401 .get(rule_index)
11402 .map_or_else(|| rule_index.to_string(), Clone::clone);
11403 let diagnostic = diagnostic_for_token(
11404 self.token_at(index).as_ref(),
11405 format!("rule {rule_name} {message}"),
11406 );
11407 let mut reversed_nodes = NodeSeqId::EMPTY;
11408 let mut next_index = index;
11409 loop {
11410 let symbol = self.token_type_at(next_index);
11411 if symbol == TOKEN_EOF {
11412 break;
11413 }
11414 let error = self.arena_token_node(next_index, true);
11415 self.arena_prepend(&mut reversed_nodes, error);
11416 let after = self.consume_index(next_index, symbol);
11417 if after == next_index {
11418 break;
11419 }
11420 next_index = after;
11421 }
11422 let nodes = self.recognition_arena.reverse_sequence(reversed_nodes);
11423 let diagnostics = self
11424 .recognition_arena
11425 .prepend_diagnostic(DiagnosticSeqId::EMPTY, diagnostic);
11426 RecognizeOutcome {
11427 index: next_index,
11428 consumed_eof: false,
11429 alt_number: rule_alt_number,
11430 member_values,
11431 return_values,
11432 diagnostics,
11433 decisions: Vec::new(),
11434 actions: Vec::new(),
11435 nodes,
11436 }
11437 }
11438
11439 fn parser_semantic_hook_result(
11442 &mut self,
11443 request: ParserSemanticHookRequest<'_>,
11444 ) -> Option<bool> {
11445 let ParserSemanticHookRequest {
11446 index,
11447 rule_index,
11448 pred_index,
11449 context,
11450 local_int_arg,
11451 member_values,
11452 } = request;
11453 let rule_name = self.rule_names().get(rule_index).cloned();
11454 self.input.seek(index);
11455 let input = &mut self.input;
11456 let semantic_hooks = &mut self.semantic_hooks;
11457 let mut ctx = ParserSemCtx {
11458 input,
11459 tree_storage: &self.tree,
11460 rule_index,
11461 coordinate_index: pred_index,
11462 rule_name,
11463 context,
11464 tree: None,
11465 local_int_arg,
11466 member_values,
11467 action: None,
11468 };
11469 semantic_hooks.sempred(&mut ctx, rule_index, pred_index)
11470 }
11471
11472 fn restore_prior_unknown_predicate_hits(&mut self, prior: Vec<(usize, usize)>) {
11477 if prior.is_empty() {
11478 return;
11479 }
11480 let mut merged = prior;
11481 for coordinate in std::mem::take(&mut self.unknown_predicate_hits) {
11482 if !merged.contains(&coordinate) {
11483 merged.push(coordinate);
11484 }
11485 }
11486 self.unknown_predicate_hits = merged;
11487 }
11488
11489 fn unknown_predicate_result(&mut self, rule_index: usize, pred_index: usize) -> bool {
11498 apply_unknown_predicate_policy(
11499 self.unknown_predicate_policy,
11500 rule_index,
11501 pred_index,
11502 &mut self.unknown_predicate_hits,
11503 )
11504 }
11505
11506 fn unknown_semantic_error(&self) -> Option<AntlrError> {
11509 use std::fmt::Write as _;
11510 if self.unknown_predicate_hits.is_empty() && self.unhandled_action_hits.is_empty() {
11511 return None;
11512 }
11513 let mut message = String::new();
11514 for (rule_index, pred_index) in &self.unknown_predicate_hits {
11515 if !message.is_empty() {
11516 message.push_str("; ");
11517 }
11518 let _ = match self.rule_names().get(*rule_index) {
11519 Some(rule_name) => write!(
11520 message,
11521 "unsupported semantic predicate: rule={rule_name}({rule_index}) pred_index={pred_index}"
11522 ),
11523 None => write!(
11524 message,
11525 "unsupported semantic predicate: rule_index={rule_index} pred_index={pred_index}"
11526 ),
11527 };
11528 }
11529 for (rule_index, source_state) in &self.unhandled_action_hits {
11530 if !message.is_empty() {
11531 message.push_str("; ");
11532 }
11533 let _ = match self.rule_names().get(*rule_index) {
11534 Some(rule_name) => write!(
11535 message,
11536 "unhandled semantic action: rule={rule_name}({rule_index}) state={source_state}"
11537 ),
11538 None => write!(
11539 message,
11540 "unhandled semantic action: rule_index={rule_index} state={source_state}"
11541 ),
11542 };
11543 }
11544 Some(AntlrError::Unsupported(message))
11545 }
11546
11547 fn parser_semir_predicate_matches(
11555 &mut self,
11556 semantics: &ParserSemantics,
11557 predicate: &ParserSemanticPredicate,
11558 request: ParserSemanticHookRequest<'_>,
11559 ) -> bool {
11560 self.input.seek(request.index);
11561 let rule_name = self
11562 .data
11563 .rule_names()
11564 .get(request.rule_index)
11565 .map(String::as_str);
11566 let unknown_predicate_policy = self.unknown_predicate_policy;
11567 let mut ctx = ParserSemIrCtx {
11568 input: &mut self.input,
11569 tree_storage: &self.tree,
11570 semantic_hooks: &mut self.semantic_hooks,
11571 rule_index: request.rule_index,
11572 coordinate_index: request.pred_index,
11573 rule_name,
11574 context: request.context,
11575 local_int_arg: request.local_int_arg,
11576 member_values: request.member_values,
11577 invoked_predicates: &mut self.invoked_predicates,
11578 unknown_predicate_policy,
11579 unknown_predicate_hits: &mut self.unknown_predicate_hits,
11580 };
11581 semir::eval_pred(&semantics.ir, predicate.expr, &mut ctx)
11582 }
11583
11584 fn fast_parser_predicate_matches(
11585 &mut self,
11586 context: Option<FastPredicateContext<'_>>,
11587 transition: ParserTransition<'_>,
11588 index: usize,
11589 ) -> bool {
11590 let Some(context) = context else {
11591 return true;
11592 };
11593 let rule_index = transition.arg0() as usize;
11594 let pred_index = transition.arg1() as usize;
11595 let key = (index, rule_index, pred_index);
11596 if let Some(result) = self.fast_predicate_cache.get(&key) {
11597 return *result;
11598 }
11599 let result = self.parser_predicate_matches(PredicateEval {
11600 index,
11601 rule_index,
11602 pred_index,
11603 predicates: context.predicates,
11604 semantics: context.semantics,
11605 context: None,
11606 local_int_arg: None,
11607 member_values: context.member_values,
11608 });
11609 self.fast_predicate_cache.insert(key, result);
11610 result
11611 }
11612
11613 fn parser_predicate_matches(&mut self, eval: PredicateEval<'_>) -> bool {
11614 let PredicateEval {
11615 index,
11616 rule_index,
11617 pred_index,
11618 predicates,
11619 semantics,
11620 context,
11621 local_int_arg,
11622 member_values,
11623 } = eval;
11624 if let Some((semantics, predicate)) = semantics.and_then(|semantics| {
11625 semantics
11626 .predicates
11627 .iter()
11628 .find(|predicate| {
11629 predicate.rule_index == rule_index && predicate.pred_index == pred_index
11630 })
11631 .map(|predicate| (semantics, predicate))
11632 }) {
11633 return self.parser_semir_predicate_matches(
11634 semantics,
11635 predicate,
11636 ParserSemanticHookRequest {
11637 index,
11638 rule_index,
11639 pred_index,
11640 context,
11641 local_int_arg,
11642 member_values,
11643 },
11644 );
11645 }
11646 let Some((_, _, predicate)) = predicates
11647 .iter()
11648 .find(|(rule, pred, _)| *rule == rule_index && *pred == pred_index)
11649 else {
11650 if let Some(result) = self.parser_semantic_hook_result(ParserSemanticHookRequest {
11651 index,
11652 rule_index,
11653 pred_index,
11654 context,
11655 local_int_arg,
11656 member_values,
11657 }) {
11658 return result;
11659 }
11660 return self.unknown_predicate_result(rule_index, pred_index);
11661 };
11662 self.input.seek(index);
11663 match predicate {
11664 ParserPredicate::True => true,
11665 ParserPredicate::False => false,
11666 ParserPredicate::FalseWithMessage { .. } => false,
11667 ParserPredicate::Invoke { value } => {
11668 let key = (rule_index, pred_index);
11669 if !self.invoked_predicates.contains(&key) {
11670 self.invoked_predicates.push(key);
11671 use std::io::Write as _;
11672 let mut stdout = std::io::stdout().lock();
11673 let _ = writeln!(stdout, "eval={value}");
11674 }
11675 *value
11676 }
11677 ParserPredicate::LookaheadTextEquals { offset, text } => self
11678 .input
11679 .lt(*offset)
11680 .is_some_and(|token| Token::text(&token) == Some(*text)),
11681 ParserPredicate::LookaheadNotEquals { offset, token_type } => {
11682 self.la(*offset) != *token_type
11683 }
11684 ParserPredicate::TokenPairAdjacent => {
11685 let Some(first) = self.input.lt_id(-2).map(TokenId::index) else {
11686 return false;
11687 };
11688 let Some(second) = self.input.lt_id(-1).map(TokenId::index) else {
11689 return false;
11690 };
11691 first + 1 == second
11692 }
11693 ParserPredicate::ContextChildRuleTextNotEquals { rule_index, text } => context
11694 .and_then(|context| {
11695 context
11696 .child_rules(&self.tree, self.input.token_store(), *rule_index)
11697 .next()
11698 .map(crate::tree::RuleNodeView::text)
11699 })
11700 .is_none_or(|actual| actual != *text),
11701 ParserPredicate::LocalIntEquals { value } => {
11702 local_int_arg.is_none_or(|(_, actual)| actual == *value)
11703 }
11704 ParserPredicate::LocalIntLessOrEqual { value } => {
11705 local_int_arg.is_none_or(|(_, actual)| actual <= *value)
11706 }
11707 ParserPredicate::MemberModuloEquals {
11708 member,
11709 modulus,
11710 value,
11711 equals,
11712 } => {
11713 if *modulus == 0 {
11714 return false;
11715 }
11716 let actual = member_values.scalar(*member).unwrap_or_default() % *modulus;
11717 (actual == *value) == *equals
11718 }
11719 ParserPredicate::MemberEquals {
11720 member,
11721 value,
11722 equals,
11723 } => {
11724 let actual = member_values.scalar(*member).unwrap_or_default();
11725 (actual == *value) == *equals
11726 }
11727 }
11728 }
11729
11730 fn parser_predicate_failure_message(
11732 &self,
11733 rule_index: usize,
11734 pred_index: usize,
11735 predicates: &[(usize, usize, ParserPredicate)],
11736 ) -> Option<&'static str> {
11737 predicates
11738 .iter()
11739 .find_map(|(rule, pred, predicate)| match predicate {
11740 ParserPredicate::FalseWithMessage { message }
11741 if *rule == rule_index && *pred == pred_index =>
11742 {
11743 Some(*message)
11744 }
11745 _ => None,
11746 })
11747 }
11748
11749 pub fn parser_semantic_ir_predicate_failure_message(
11752 &self,
11753 rule_index: usize,
11754 pred_index: usize,
11755 semantics: &ParserSemantics,
11756 ) -> Option<&'static str> {
11757 semantics
11758 .predicates
11759 .iter()
11760 .find(|predicate| {
11761 predicate.rule_index == rule_index && predicate.pred_index == pred_index
11762 })
11763 .and_then(|predicate| predicate.failure_message)
11764 }
11765
11766 fn consume_index(&mut self, index: usize, symbol: i32) -> usize {
11775 if symbol == TOKEN_EOF {
11776 return index;
11777 }
11778 self.input.next_visible_after(index)
11779 }
11780
11781 fn no_viable_alternative(&self, start_index: usize, error_index: usize) -> ParserDiagnostic {
11784 let text = display_input_text(&self.input.text(start_index, error_index));
11785 diagnostic_for_token(
11786 self.token_at(error_index).as_ref(),
11787 format!("no viable alternative at input '{text}'"),
11788 )
11789 }
11790
11791 fn recovery_failure_diagnostic(
11794 &self,
11795 index: usize,
11796 decision_start_index: Option<usize>,
11797 expected_symbols: &BTreeSet<i32>,
11798 ) -> ParserDiagnostic {
11799 if expected_symbols.len() > 1 {
11800 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
11801 return self.no_viable_alternative(decision_start, index);
11802 }
11803 }
11804 diagnostic_for_token(
11805 self.token_at(index).as_ref(),
11806 format!(
11807 "mismatched input {} expecting {}",
11808 self.token_at(index)
11809 .as_ref()
11810 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
11811 self.expected_symbols_display(expected_symbols)
11812 ),
11813 )
11814 }
11815
11816 fn eof_rule_recovery_diagnostic(
11819 &self,
11820 index: usize,
11821 expected_symbols: &BTreeSet<i32>,
11822 expected: &ExpectedTokens,
11823 ) -> ParserDiagnostic {
11824 let symbols = if expected.index == Some(index) && !expected.symbols.is_empty() {
11825 &expected.symbols
11826 } else {
11827 expected_symbols
11828 };
11829 diagnostic_for_token(
11830 self.token_at(index).as_ref(),
11831 format!(
11832 "mismatched input {} expecting {}",
11833 self.token_at(index)
11834 .as_ref()
11835 .map_or_else(|| "'<EOF>'".to_owned(), token_input_display),
11836 self.expected_symbols_display(symbols)
11837 ),
11838 )
11839 }
11840
11841 pub fn text_interval(&self, start: usize, stop: Option<usize>) -> String {
11847 let Some(stop) = stop else {
11848 return String::new();
11849 };
11850 let stop = if self
11851 .token_at(stop)
11852 .is_some_and(|token| token.token_type() == TOKEN_EOF)
11853 {
11854 let Some(previous) = self.previous_token_index(stop) else {
11855 return String::new();
11856 };
11857 previous
11858 } else {
11859 stop
11860 };
11861 self.input.text(start, stop)
11862 }
11863
11864 fn clear_prediction_diagnostics(&mut self) {
11867 self.prediction_diagnostics.clear();
11868 self.reported_prediction_diagnostics.clear();
11869 }
11870
11871 fn reset_per_parse_caches(&mut self) {
11895 self.rule_first_set_cache.clear();
11896 self.decision_lookahead_cache.clear();
11897 self.ll1_decision_cache.clear();
11898 self.fast_predicate_cache.clear();
11899 self.rule_stop_reach_cache.clear();
11900 self.clean_memo_mode = CleanMemoMode::Probe;
11901 self.clean_memo_probe_seen.clear();
11902 self.clean_memo_probe_samples = 0;
11903 self.clean_memo_probe_repeats = 0;
11904 self.clean_memo_sparse_samples = 0;
11905 self.recovery_symbols_intern.clear();
11906 self.state_expected_cache.clear();
11907 self.state_expected_token_cache.clear();
11908 }
11909
11910 fn record_prediction_diagnostics(
11913 &mut self,
11914 atn: &Atn,
11915 state: AtnState<'_>,
11916 start_index: usize,
11917 outcomes: &[RecognizeOutcome],
11918 ) {
11919 if !self.report_diagnostic_errors || state.transitions().len() < 2 {
11920 return;
11921 }
11922 let Some(decision) = atn
11923 .decision_to_state()
11924 .iter()
11925 .position(|state_number| state_number == state.state_number())
11926 else {
11927 return;
11928 };
11929 let Some(rule_index) = state.rule_index() else {
11930 return;
11931 };
11932 let mut alts_by_end = BTreeMap::<usize, BTreeSet<usize>>::new();
11933 for outcome in outcomes
11934 .iter()
11935 .filter(|outcome| outcome.diagnostics.is_empty())
11936 {
11937 let Some(alt) = outcome.decisions.first() else {
11938 continue;
11939 };
11940 alts_by_end
11941 .entry(outcome.index)
11942 .or_default()
11943 .insert(alt + 1);
11944 }
11945 let Some((&end_index, ambig_alts)) = alts_by_end
11946 .iter()
11947 .filter(|(_, alts)| alts.len() > 1)
11948 .max_by_key(|(end, _)| *end)
11949 else {
11950 return;
11951 };
11952 let rule_name = self
11953 .rule_names()
11954 .get(rule_index)
11955 .map_or_else(|| "<unknown>".to_owned(), Clone::clone);
11956 let stop_index = self.previous_token_index(end_index).unwrap_or(start_index);
11957 let input = display_input_text(&self.input.text(start_index, stop_index));
11958 let alts = ambig_alts
11959 .iter()
11960 .map(usize::to_string)
11961 .collect::<Vec<_>>()
11962 .join(", ");
11963 let key = (decision, start_index, format!("{alts}:{input}"));
11964 if !self.reported_prediction_diagnostics.insert(key) {
11965 return;
11966 }
11967 let start_diagnostic = diagnostic_for_token(
11968 self.token_at(start_index),
11969 format!("reportAttemptingFullContext d={decision} ({rule_name}), input='{input}'"),
11970 );
11971 let stop_diagnostic = diagnostic_for_token(
11972 self.token_at(stop_index),
11973 format!(
11974 "reportAmbiguity d={decision} ({rule_name}): ambigAlts={{{alts}}}, input='{input}'"
11975 ),
11976 );
11977 self.prediction_diagnostics.push(start_diagnostic);
11978 self.prediction_diagnostics.push(stop_diagnostic);
11979 }
11980
11981 pub fn expected_tokens_at_state(&self, atn: &Atn, state_number: usize) -> String {
11983 expected_symbols_display(
11984 &state_expected_symbols(atn, state_number),
11985 self.vocabulary(),
11986 )
11987 }
11988
11989 pub fn expected_tokens_current(&self, atn: &Atn) -> ExpectedTokenSet {
11994 let state = usize::try_from(self.data().state()).unwrap_or(0);
11995 ExpectedTokenSet {
11996 symbols: state_expected_symbols(atn, state),
11997 }
11998 }
11999
12000 pub const fn set_bail_on_error(&mut self, bail: bool) {
12003 self.bail_on_error = bail;
12004 }
12005
12006 #[must_use]
12008 pub const fn bail_on_error(&self) -> bool {
12009 self.bail_on_error
12010 }
12011
12012 pub fn rule_invocation_stack(&self) -> Vec<String> {
12015 self.rule_context_stack
12016 .iter()
12017 .rev()
12018 .map(|frame| {
12019 self.data()
12020 .rule_names()
12021 .get(frame.rule_index)
12022 .cloned()
12023 .unwrap_or_else(|| format!("<{}>", frame.rule_index))
12024 })
12025 .collect()
12026 }
12027
12028 pub fn active_invocation_states(&self) -> Vec<isize> {
12032 self.rule_context_stack
12033 .iter()
12034 .skip(1)
12035 .rev()
12036 .map(|frame| frame.invoking_state)
12037 .collect()
12038 }
12039
12040 pub fn token_display_at(&self, index: usize) -> Option<String> {
12042 self.token_at(index).map(|token| format!("{token}"))
12043 }
12044}
12045
12046impl<'atn, S, H> DirectAdaptiveParser<'atn, '_, S, H>
12047where
12048 S: TokenSource,
12049 H: SemanticHooks,
12050{
12051 fn parse_rule(
12052 &mut self,
12053 rule_index: usize,
12054 invoking_state: isize,
12055 precedence: i32,
12056 ) -> DirectAdaptiveParseResult<ParseTree> {
12057 let start_state = self.atn.rule_to_start_state().get(rule_index).ok_or(
12058 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::MissingAtn),
12059 )?;
12060 let stop_state = self
12061 .atn
12062 .rule_to_stop_state()
12063 .get(rule_index)
12064 .filter(|state| *state != usize::MAX)
12065 .ok_or(DirectAdaptiveParseControl::Fallback(
12066 DirectAdaptiveFallback::MissingAtn,
12067 ))?;
12068 let start_index = self.parser.current_visible_index();
12069 let mut context = ParserRuleContext::new(rule_index, invoking_state);
12070 if let Some(token) = self.parser.token_id_at(start_index) {
12071 self.parser.set_context_start(&mut context, token);
12072 }
12073 let mut state_number = start_state;
12074 let mut consumed_eof = false;
12075 while state_number != stop_state {
12076 self.step()?;
12077 let (transition, boundary) = self.next_transition(state_number, precedence)?;
12078 if boundary.is_some() {
12079 return Err(DirectAdaptiveParseControl::Fallback(
12080 DirectAdaptiveFallback::LeftRecursiveBoundary,
12081 ));
12082 }
12083 match transition.data() {
12084 Transition::Epsilon { target } => {
12085 state_number = target;
12086 }
12087 Transition::Precedence {
12088 target,
12089 precedence: transition_precedence,
12090 } => {
12091 if transition_precedence < precedence {
12092 return Err(DirectAdaptiveParseControl::Fallback(
12093 DirectAdaptiveFallback::Precedence,
12094 ));
12095 }
12096 state_number = target;
12097 }
12098 Transition::Rule {
12099 rule_index,
12100 follow_state,
12101 precedence: rule_precedence,
12102 ..
12103 } => {
12104 let child = self.parse_rule(
12105 rule_index,
12106 invoking_state_number(state_number),
12107 rule_precedence,
12108 )?;
12109 if self.parser.build_parse_trees {
12110 self.parser.tree.add_child(&mut context, child);
12111 }
12112 state_number = follow_state;
12113 }
12114 Transition::Atom { .. }
12115 | Transition::Range { .. }
12116 | Transition::Set { .. }
12117 | Transition::NotSet { .. }
12118 | Transition::Wildcard { .. } => {
12119 let (matched_eof, child) = self.consume_transition(transition)?;
12120 consumed_eof |= matched_eof;
12121 if let Some(child) = child {
12122 self.parser.tree.add_child(&mut context, child);
12123 }
12124 state_number = transition.target();
12125 }
12126 Transition::Predicate { .. } => {
12127 return Err(DirectAdaptiveParseControl::Fallback(
12128 DirectAdaptiveFallback::Predicate,
12129 ));
12130 }
12131 Transition::Action { .. } => {
12132 return Err(DirectAdaptiveParseControl::Fallback(
12133 DirectAdaptiveFallback::Action,
12134 ));
12135 }
12136 }
12137 }
12138
12139 let stop_index = self
12140 .parser
12141 .rule_stop_token_index(self.parser.input.index(), consumed_eof);
12142 if let Some(token) = stop_index.and_then(|index| self.parser.token_id_at(index)) {
12143 self.parser.set_context_stop(&mut context, token);
12144 }
12145 Ok(self.parser.rule_node(context))
12146 }
12147
12148 const fn step(&mut self) -> DirectAdaptiveParseResult<()> {
12149 self.steps += 1;
12150 if self.steps > ADAPTIVE_DIRECT_STEP_LIMIT {
12151 return Err(DirectAdaptiveParseControl::Fallback(
12152 DirectAdaptiveFallback::StepLimit,
12153 ));
12154 }
12155 Ok(())
12156 }
12157
12158 fn next_transition(
12159 &mut self,
12160 state_number: usize,
12161 precedence: i32,
12162 ) -> DirectAdaptiveParseResult<(ParserTransition<'atn>, Option<usize>)> {
12163 let state = self
12164 .atn
12165 .state(state_number)
12166 .ok_or(DirectAdaptiveParseControl::Fallback(
12167 DirectAdaptiveFallback::MissingAtn,
12168 ))?;
12169 if state.is_rule_stop() {
12170 return Err(DirectAdaptiveParseControl::Fallback(
12171 DirectAdaptiveFallback::RuleStop,
12172 ));
12173 }
12174 let transition_index =
12175 self.transition_index(state_number, state.transitions().len(), precedence)?;
12176 let transition = state.transitions().get(transition_index).ok_or(
12177 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::NoTransition),
12178 )?;
12179 let boundary = match &transition.data() {
12180 Transition::Epsilon { target } | Transition::Precedence { target, .. } => {
12181 left_recursive_boundary(self.atn, state, *target)
12182 }
12183 _ => None,
12184 };
12185 Ok((transition, boundary))
12186 }
12187
12188 fn transition_index(
12189 &mut self,
12190 state_number: usize,
12191 transition_count: usize,
12192 precedence: i32,
12193 ) -> DirectAdaptiveParseResult<usize> {
12194 match transition_count {
12195 0 => Err(DirectAdaptiveParseControl::Fallback(
12196 DirectAdaptiveFallback::NoTransition,
12197 )),
12198 1 => Ok(0),
12199 _ => {
12200 if let Some(alt) = self.ll1_transition_index(state_number, transition_count)? {
12201 return Ok(alt);
12202 }
12203 let decision = self
12204 .decision_by_state
12205 .get(state_number)
12206 .and_then(|decision| *decision)
12207 .ok_or(DirectAdaptiveParseControl::Fallback(
12208 DirectAdaptiveFallback::UnknownDecision,
12209 ))?;
12210 let prediction = self
12211 .simulator
12212 .adaptive_predict_stream_info_with_precedence(
12213 decision,
12214 direct_precedence(precedence),
12215 &mut self.parser.input,
12216 )
12217 .map_err(|_| {
12218 DirectAdaptiveParseControl::Fallback(DirectAdaptiveFallback::Prediction)
12219 })?;
12220 if prediction.has_semantic_context {
12221 return Err(DirectAdaptiveParseControl::Fallback(
12222 DirectAdaptiveFallback::SemanticContext,
12223 ));
12224 }
12225 prediction
12226 .alt
12227 .checked_sub(1)
12228 .filter(|index| *index < transition_count)
12229 .ok_or(DirectAdaptiveParseControl::Fallback(
12230 DirectAdaptiveFallback::InvalidAlt,
12231 ))
12232 }
12233 }
12234 }
12235
12236 fn ll1_transition_index(
12237 &mut self,
12238 state_number: usize,
12239 transition_count: usize,
12240 ) -> DirectAdaptiveParseResult<Option<usize>> {
12241 let state = self
12242 .atn
12243 .state(state_number)
12244 .ok_or(DirectAdaptiveParseControl::Fallback(
12245 DirectAdaptiveFallback::MissingAtn,
12246 ))?;
12247 if state.precedence_rule_decision() {
12248 return Ok(None);
12249 }
12250 let Some(rule_stop) = state
12251 .rule_index()
12252 .and_then(|rule_index| self.atn.rule_to_stop_state().get(rule_index))
12253 else {
12254 return Ok(None);
12255 };
12256 let symbol = self.parser.input.la_token(1);
12257 let entry = self
12258 .parser
12259 .cached_decision_lookahead(self.atn, state, rule_stop);
12260 Ok(
12261 ll1_greedy_alt(&entry, symbol, state.non_greedy())
12262 .filter(|alt| *alt < transition_count),
12263 )
12264 }
12265
12266 fn consume_transition(
12267 &mut self,
12268 transition: ParserTransition<'_>,
12269 ) -> DirectAdaptiveParseResult<(bool, Option<ParseTree>)> {
12270 let symbol = self.parser.input.la_token(1);
12271 if !transition.matches(symbol, 1, self.atn.max_token_type()) {
12272 return Err(DirectAdaptiveParseControl::Fallback(
12273 DirectAdaptiveFallback::TokenMismatch,
12274 ));
12275 }
12276 let token = self
12277 .parser
12278 .input
12279 .lt_id(1)
12280 .ok_or(DirectAdaptiveParseControl::Fallback(
12281 DirectAdaptiveFallback::TokenMismatch,
12282 ))?;
12283 let matched_eof = symbol == TOKEN_EOF;
12284 if !matched_eof {
12285 self.parser.consume();
12286 }
12287 let child = self
12288 .parser
12289 .build_parse_trees
12290 .then(|| self.parser.terminal_tree(token));
12291 Ok((matched_eof, child))
12292 }
12293}
12294
12295fn left_recursive_boundary(atn: &Atn, state: AtnState<'_>, target: usize) -> Option<usize> {
12298 if !state.precedence_rule_decision() {
12299 return None;
12300 }
12301 let target_state = atn.state(target)?;
12302 if target_state.kind() == AtnStateKind::LoopEnd {
12303 return None;
12304 }
12305 state.rule_index()
12306}
12307
12308fn next_alt_number(
12315 state: AtnState<'_>,
12316 transition_count: usize,
12317 transition_index: usize,
12318 current_alt_number: usize,
12319 track_alt_numbers: bool,
12320) -> usize {
12321 if !track_alt_numbers || current_alt_number != 0 || transition_count <= 1 {
12322 return current_alt_number;
12323 }
12324 if matches!(
12325 state.kind(),
12326 AtnStateKind::Basic
12327 | AtnStateKind::BlockStart
12328 | AtnStateKind::PlusBlockStart
12329 | AtnStateKind::StarBlockStart
12330 | AtnStateKind::StarLoopEntry
12331 ) && !state.precedence_rule_decision()
12332 {
12333 return transition_index + 1;
12334 }
12335 current_alt_number
12336}
12337
12338fn invoking_state_number(state_number: usize) -> isize {
12341 isize::try_from(state_number).unwrap_or(isize::MAX)
12342}
12343
12344const fn packed_i32(value: u32) -> i32 {
12345 i32::from_le_bytes(value.to_le_bytes())
12346}
12347
12348fn direct_precedence(precedence: i32) -> usize {
12349 usize::try_from(precedence.max(0)).unwrap_or_default()
12350}
12351
12352fn token_input_display(token: &impl Token) -> String {
12353 format!("'{}'", token.text().unwrap_or("<EOF>"))
12354}
12355
12356fn display_input_text(text: &str) -> String {
12357 let mut out = String::new();
12358 for ch in text.chars() {
12359 match ch {
12360 '\n' => out.push_str("\\n"),
12361 '\r' => out.push_str("\\r"),
12362 '\t' => out.push_str("\\t"),
12363 other => out.push(other),
12364 }
12365 }
12366 out
12367}
12368
12369fn diagnostic_for_token<T: Token>(token: Option<T>, message: String) -> ParserDiagnostic {
12370 let (line, column, offending) = token.map_or((0, 0, None), |token| {
12371 (token.line(), token.column(), Some(token.token_id()))
12372 });
12373 ParserDiagnostic {
12374 line,
12375 column,
12376 message,
12377 offending,
12378 }
12379}
12380
12381fn expected_symbols_display(symbols: &BTreeSet<i32>, vocabulary: &Vocabulary) -> String {
12382 expected_symbols_display_iter(symbols.iter().copied(), vocabulary)
12383}
12384
12385fn expected_symbols_display_iter(
12386 symbols: impl IntoIterator<Item = i32>,
12387 vocabulary: &Vocabulary,
12388) -> String {
12389 let items = symbols
12390 .into_iter()
12391 .map(|symbol| expected_symbol_display(symbol, vocabulary))
12392 .collect::<Vec<_>>();
12393 if let [single] = items.as_slice() {
12394 return single.clone();
12395 }
12396 format!("{{{}}}", items.join(", "))
12397}
12398
12399fn expected_symbol_display(symbol: i32, vocabulary: &Vocabulary) -> String {
12400 if symbol == TOKEN_EOF {
12401 return "<EOF>".to_owned();
12402 }
12403 vocabulary.display_name(symbol)
12404}
12405
12406fn caller_follow_token_info_for_stream<S: TokenSource>(
12407 input: &mut CommonTokenStream<S>,
12408 index: usize,
12409) -> (i32, bool, bool) {
12410 if index >= FAST_RECOGNIZER_DEFERRED_FILL_AT && !input.is_filled() {
12413 input.fill();
12414 }
12415 let token_type = input.token_type_at_index(index);
12416 let visible_channel = input.channel();
12417 let token = input.get(index);
12418 let is_boundary = token
12419 .as_ref()
12420 .and_then(Token::text)
12421 .is_some_and(is_caller_follow_boundary_text);
12422 let is_boundary_gap = token.as_ref().is_some_and(|token| {
12423 token.channel() != visible_channel
12424 || is_caller_follow_boundary_gap_text(token.text_or_empty())
12425 });
12426 (token_type, is_boundary, is_boundary_gap)
12427}
12428
12429fn is_caller_follow_boundary_text(text: &str) -> bool {
12430 text.chars().any(|ch| ch == ';' || ch == '\n')
12431 && text.chars().all(|ch| ch.is_whitespace() || ch == ';')
12432}
12433
12434fn is_caller_follow_boundary_gap_text(text: &str) -> bool {
12435 text.chars().all(|ch| ch.is_whitespace() || ch == ';')
12436}
12437
12438fn state_is_left_recursive_rule(atn: &Atn, state: AtnState<'_>) -> bool {
12442 let Some(rule_index) = state.rule_index() else {
12443 return false;
12444 };
12445 atn.rule_to_start_state()
12446 .get(rule_index)
12447 .and_then(|state_number| atn.state(state_number))
12448 .is_some_and(AtnState::left_recursive_rule)
12449}
12450
12451fn select_better_top_outcome(
12458 first: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
12459 second: Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens>,
12460 arena: &RecognitionArena,
12461) -> Result<(FastRecognizeOutcome, ExpectedTokens, usize), ExpectedTokens> {
12462 match (first, second) {
12463 (Ok(first), Ok(second)) => {
12464 if arena.diagnostics(first.0.diagnostics).next().is_none() {
12465 Ok(first)
12466 } else {
12467 Ok(second)
12468 }
12469 }
12470 (Ok(first), Err(_)) => Ok(first),
12471 (Err(_), Ok(second)) => Ok(second),
12472 (Err(_), Err(second_expected)) => Err(second_expected),
12473 }
12474}
12475
12476fn select_best_fast_outcome(
12482 outcomes: impl Iterator<Item = FastRecognizeOutcome>,
12483 prediction_mode: PredictionMode,
12484 caller_follow: Option<&TokenBitSet>,
12485 mut token_info_at: impl FnMut(usize) -> (i32, bool, bool),
12486 arena: &RecognitionArena,
12487) -> Option<FastRecognizeOutcome> {
12488 let mut best = None;
12489 let mut best_caller_follow = None;
12490 for outcome in outcomes {
12491 if matches!(
12492 prediction_mode,
12493 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection
12494 ) && outcome.diagnostics.is_empty()
12495 && let Some(follow) = caller_follow
12496 {
12497 let (token_type, is_boundary, _) = token_info_at(outcome.index);
12498 if is_boundary && follow.contains(token_type) {
12499 let replace =
12500 best_caller_follow
12501 .as_ref()
12502 .is_none_or(|existing: &FastRecognizeOutcome| {
12503 (outcome.index, outcome.consumed_eof)
12504 < (existing.index, existing.consumed_eof)
12505 });
12506 if replace {
12507 best_caller_follow = Some(outcome);
12508 }
12509 }
12510 }
12511 let Some(existing) = best else {
12512 best = Some(outcome);
12513 continue;
12514 };
12515 let outcome_position = (outcome.index, outcome.consumed_eof);
12516 let best_position = (existing.index, existing.consumed_eof);
12517 let better = match prediction_mode {
12518 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => outcome_is_better(
12519 outcome_position,
12520 outcome.diagnostics,
12521 best_position,
12522 existing.diagnostics,
12523 arena,
12524 ),
12525 PredictionMode::Sll => outcome.index > existing.index,
12526 };
12527 best = Some(if better { outcome } else { existing });
12528 }
12529 let should_use_caller_follow =
12530 best_caller_follow
12531 .as_ref()
12532 .zip(best.as_ref())
12533 .is_some_and(|(candidate, selected)| {
12534 if !selected.diagnostics.is_empty() {
12535 return true;
12536 }
12537 candidate.index < selected.index
12538 && (candidate.index..selected.index).all(|index| token_info_at(index).2)
12539 });
12540 if should_use_caller_follow {
12541 best_caller_follow
12542 } else {
12543 best
12544 }
12545}
12546
12547fn select_best_outcome(
12548 outcomes: impl Iterator<Item = RecognizeOutcome>,
12549 prediction_mode: PredictionMode,
12550 arena: &RecognitionArena,
12551) -> Option<RecognizeOutcome> {
12552 let outcomes = outcomes.collect::<Vec<_>>();
12553 let prefer_first_tie = outcomes
12554 .iter()
12555 .any(|outcome| arena.sequence_needs_stable_tie(outcome.nodes));
12556 outcomes.into_iter().reduce(|best, outcome| {
12557 let outcome_position = (outcome.index, outcome.consumed_eof);
12558 let best_position = (best.index, best.consumed_eof);
12559 let better = match prediction_mode {
12560 PredictionMode::Ll | PredictionMode::LlExactAmbigDetection => {
12561 outcome_is_better(
12562 outcome_position,
12563 outcome.diagnostics,
12564 best_position,
12565 best.diagnostics,
12566 arena,
12567 ) || (outcome_position == best_position
12568 && arena.diagnostics_len(outcome.diagnostics)
12569 == arena.diagnostics_len(best.diagnostics)
12570 && arena.diagnostics_recovery_rank(outcome.diagnostics)
12571 == arena.diagnostics_recovery_rank(best.diagnostics)
12572 && (outcome.decisions < best.decisions
12573 || (!prefer_first_tie
12574 && outcome.decisions == best.decisions
12575 && outcome.actions > best.actions)))
12576 }
12577 PredictionMode::Sll => {
12578 outcome_position > best_position
12579 || (outcome_position == best_position
12580 && !prefer_first_tie
12581 && (outcome.decisions < best.decisions
12582 || (outcome.decisions == best.decisions
12583 && outcome_is_better(
12584 outcome_position,
12585 outcome.diagnostics,
12586 best_position,
12587 best.diagnostics,
12588 arena,
12589 ))))
12590 }
12591 };
12592 if better {
12593 return outcome;
12594 }
12595 best
12596 })
12597}
12598
12599fn transition_decision(
12606 atn: &Atn,
12607 state: AtnState<'_>,
12608 transition_count: usize,
12609 transition_index: usize,
12610 predicates: &[(usize, usize, ParserPredicate)],
12611) -> Option<usize> {
12612 if transition_count <= 1 || decision_reaches_unsupported_predicate(atn, state, predicates) {
12613 return None;
12614 }
12615 Some(transition_index)
12616}
12617
12618fn starts_prediction_decision(state: AtnState<'_>, transition_count: usize) -> bool {
12624 transition_count > 1
12625 && !matches!(
12626 state.kind(),
12627 AtnStateKind::PlusLoopBack | AtnStateKind::StarLoopBack | AtnStateKind::StarLoopEntry
12628 )
12629}
12630
12631fn record_no_viable_if_ambiguous(
12634 expected: &mut ExpectedTokens,
12635 decision_start_index: Option<usize>,
12636 index: usize,
12637) {
12638 if expected.index == Some(index) && expected.symbols.len() > 1 {
12639 if let Some(decision_start) = no_viable_decision_start(decision_start_index, index) {
12640 expected.record_no_viable(decision_start, index);
12641 }
12642 }
12643}
12644
12645const fn record_predicate_no_viable(
12648 expected: &mut ExpectedTokens,
12649 decision_start_index: Option<usize>,
12650 index: usize,
12651) {
12652 if let Some(decision_start) = decision_start_index {
12653 expected.record_no_viable(decision_start, index);
12654 }
12655}
12656
12657const fn no_viable_decision_start(
12659 decision_start_index: Option<usize>,
12660 index: usize,
12661) -> Option<usize> {
12662 match decision_start_index {
12663 Some(start) if index > start => Some(start),
12664 _ => None,
12665 }
12666}
12667
12668fn restore_expected(
12672 children: &[RecognizeOutcome],
12673 child_start_index: usize,
12674 expected: &mut ExpectedTokens,
12675 snapshot: ExpectedTokens,
12676 preserve_child_expected: bool,
12677) {
12678 if preserve_child_expected {
12679 return;
12680 }
12681 if children
12682 .iter()
12683 .any(|child| child.diagnostics.is_empty() && child.index > child_start_index)
12684 {
12685 *expected = snapshot;
12686 }
12687}
12688
12689fn decision_reaches_unsupported_predicate(
12692 atn: &Atn,
12693 state: AtnState<'_>,
12694 predicates: &[(usize, usize, ParserPredicate)],
12695) -> bool {
12696 state.transitions().iter().any(|transition| {
12697 transition_reaches_unsupported_predicate(atn, transition, predicates, &mut BTreeSet::new())
12698 })
12699}
12700
12701fn transition_reaches_unsupported_predicate(
12703 atn: &Atn,
12704 transition: ParserTransition<'_>,
12705 predicates: &[(usize, usize, ParserPredicate)],
12706 visited: &mut BTreeSet<usize>,
12707) -> bool {
12708 match &transition.data() {
12709 Transition::Predicate {
12710 rule_index,
12711 pred_index,
12712 ..
12713 } => !predicates
12714 .iter()
12715 .any(|(rule, pred, _)| rule == rule_index && pred == pred_index),
12716 Transition::Epsilon { target }
12717 | Transition::Action { target, .. }
12718 | Transition::Rule { target, .. } => {
12719 state_reaches_unsupported_predicate(atn, *target, predicates, visited)
12720 }
12721 Transition::Precedence { .. }
12722 | Transition::Atom { .. }
12723 | Transition::Range { .. }
12724 | Transition::Set { .. }
12725 | Transition::NotSet { .. }
12726 | Transition::Wildcard { .. } => false,
12727 }
12728}
12729
12730fn state_reaches_unsupported_predicate(
12732 atn: &Atn,
12733 state_number: usize,
12734 predicates: &[(usize, usize, ParserPredicate)],
12735 visited: &mut BTreeSet<usize>,
12736) -> bool {
12737 if !visited.insert(state_number) {
12738 return false;
12739 }
12740 let Some(state) = atn.state(state_number) else {
12741 return false;
12742 };
12743 state.transitions().iter().any(|transition| {
12744 transition_reaches_unsupported_predicate(atn, transition, predicates, visited)
12745 })
12746}
12747
12748fn prepend_decision(outcome: &mut RecognizeOutcome, decision: Option<usize>) {
12750 if let Some(decision) = decision {
12751 outcome.decisions.insert(0, decision);
12752 }
12753}
12754
12755fn outcome_is_better(
12756 outcome_position: (usize, bool),
12757 outcome_diagnostics: DiagnosticSeqId,
12758 best_position: (usize, bool),
12759 best_diagnostics: DiagnosticSeqId,
12760 arena: &RecognitionArena,
12761) -> bool {
12762 let outcome_len = arena.diagnostics_len(outcome_diagnostics);
12763 let best_len = arena.diagnostics_len(best_diagnostics);
12764 outcome_position > best_position
12765 || (outcome_position == best_position
12766 && (outcome_len < best_len
12767 || (outcome_len == best_len
12768 && arena.diagnostics_recovery_rank(outcome_diagnostics)
12769 < arena.diagnostics_recovery_rank(best_diagnostics))))
12770}
12771
12772fn discard_recovered_fast_outcomes_if_clean_path_exists(outcomes: &mut Vec<FastRecognizeOutcome>) {
12773 if outcomes
12774 .iter()
12775 .any(|outcome| outcome.diagnostics.is_empty())
12776 {
12777 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
12778 }
12779}
12780
12781fn discard_recovered_outcomes_if_clean_path_exists(
12782 outcomes: &mut Vec<RecognizeOutcome>,
12783 arena: &RecognitionArena,
12784) {
12785 if outcomes
12786 .iter()
12787 .any(|outcome| outcome_has_rule_failure_diagnostic(outcome, arena))
12788 {
12789 return;
12790 }
12791 if outcomes
12792 .iter()
12793 .any(|outcome| outcome.diagnostics.is_empty())
12794 {
12795 outcomes.retain(|outcome| outcome.diagnostics.is_empty());
12796 }
12797}
12798
12799fn outcome_has_rule_failure_diagnostic(
12802 outcome: &RecognizeOutcome,
12803 arena: &RecognitionArena,
12804) -> bool {
12805 arena
12806 .diagnostics(outcome.diagnostics)
12807 .any(|diagnostic| diagnostic.message.starts_with("rule "))
12808}
12809
12810fn dedupe_fast_outcomes(outcomes: &mut Vec<FastRecognizeOutcome>, arena: &RecognitionArena) {
12824 if outcomes.len() < 2 {
12825 return;
12826 }
12827 let mut seen = FxHashSet::with_capacity_and_hasher(outcomes.len(), FxBuildHasher::default());
12828 outcomes.retain(|outcome| {
12829 seen.insert((
12830 outcome.index,
12831 outcome.consumed_eof,
12832 arena.diagnostics_len(outcome.diagnostics),
12833 arena.diagnostics_recovery_rank(outcome.diagnostics),
12834 ))
12835 });
12836}
12837
12838const FAST_OUTCOME_INLINE_KEYS: usize = 8;
12839const FAST_OUTCOME_BITS_PER_WORD: usize = 64;
12840const MAX_FAST_OUTCOME_DENSE_BYTES: usize = 64 * 1024;
12841const MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS: usize = 65_536;
12842
12843#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12844enum FastOutcomeDedupStrategy {
12845 Inline,
12846 Dense,
12847 Sparse,
12848}
12849
12850impl FastOutcomeDedupScratch {
12851 fn prepare_dense(&mut self, word_count: usize) {
12852 while let Some(word_index) = self.touched_dense_words.pop() {
12853 self.dense_words[usize::try_from(word_index).expect("u32 fits in usize")] = 0;
12854 }
12855 if self.dense_words.len() < word_count {
12856 self.dense_words.resize(word_count, 0);
12857 }
12858 }
12859}
12860
12861fn clean_fast_outcome_dense_layout(outcomes: &[FastRecognizeOutcome]) -> Option<(usize, usize)> {
12862 let first_index = outcomes.first()?.index;
12863 let (min_index, max_index) = outcomes[1..].iter().fold(
12864 (first_index, first_index),
12865 |(min_index, max_index), outcome| {
12866 (min_index.min(outcome.index), max_index.max(outcome.index))
12867 },
12868 );
12869 let index_span = max_index.checked_sub(min_index)?.checked_add(1)?;
12870 let bit_count = index_span.checked_mul(2)?;
12871 let word_count =
12872 bit_count.checked_add(FAST_OUTCOME_BITS_PER_WORD - 1)? / FAST_OUTCOME_BITS_PER_WORD;
12873 let dense_bytes = word_count.checked_mul(size_of::<u64>())?;
12874 let sparse_key_bytes = outcomes.len().checked_mul(size_of::<(usize, bool)>())?;
12875 (dense_bytes <= MAX_FAST_OUTCOME_DENSE_BYTES && dense_bytes <= sparse_key_bytes)
12876 .then_some((min_index, word_count))
12877}
12878
12879#[cfg(feature = "perf-counters")]
12880fn record_clean_fast_outcome_dedup(
12881 strategy: FastOutcomeDedupStrategy,
12882 input_len: usize,
12883 output_len: usize,
12884 dense_words: usize,
12885) {
12886 let counter = match strategy {
12887 FastOutcomeDedupStrategy::Inline => &perf_counters::OUTCOME_DEDUPE_INLINE,
12888 FastOutcomeDedupStrategy::Dense => &perf_counters::OUTCOME_DEDUPE_DENSE,
12889 FastOutcomeDedupStrategy::Sparse => &perf_counters::OUTCOME_DEDUPE_SPARSE,
12890 };
12891 perf_counters::inc(
12892 &perf_counters::OUTCOME_DEDUPE_INPUTS,
12893 u64::try_from(input_len).unwrap_or(u64::MAX),
12894 );
12895 perf_counters::inc(
12896 &perf_counters::OUTCOME_DEDUPE_REMOVED,
12897 u64::try_from(input_len - output_len).unwrap_or(u64::MAX),
12898 );
12899 perf_counters::inc(counter, 1);
12900 perf_counters::inc(
12901 &perf_counters::OUTCOME_DEDUPE_DENSE_WORDS,
12902 u64::try_from(dense_words).unwrap_or(u64::MAX),
12903 );
12904}
12905
12906fn dedupe_clean_fast_outcomes(
12910 outcomes: &mut Vec<FastRecognizeOutcome>,
12911 scratch: &mut FastOutcomeDedupScratch,
12912) -> FastOutcomeDedupStrategy {
12913 #[cfg(feature = "perf-counters")]
12914 let input_len = outcomes.len();
12915 if outcomes.len() <= FAST_OUTCOME_INLINE_KEYS {
12916 let mut inline_keys = [(0, false); FAST_OUTCOME_INLINE_KEYS];
12917 let mut inline_len = 0_usize;
12918 outcomes.retain(|outcome| {
12919 let key = (outcome.index, outcome.consumed_eof);
12920 if inline_keys[..inline_len].contains(&key) {
12921 return false;
12922 }
12923 inline_keys[inline_len] = key;
12924 inline_len += 1;
12925 true
12926 });
12927 #[cfg(feature = "perf-counters")]
12928 record_clean_fast_outcome_dedup(
12929 FastOutcomeDedupStrategy::Inline,
12930 input_len,
12931 outcomes.len(),
12932 0,
12933 );
12934 return FastOutcomeDedupStrategy::Inline;
12935 }
12936
12937 if let Some((base_index, word_count)) = clean_fast_outcome_dense_layout(outcomes) {
12938 scratch.prepare_dense(word_count);
12939 outcomes.retain(|outcome| {
12940 let bit_index = (outcome.index - base_index) * 2 + usize::from(outcome.consumed_eof);
12941 let word_index = bit_index / FAST_OUTCOME_BITS_PER_WORD;
12942 let bit = 1_u64 << (bit_index % FAST_OUTCOME_BITS_PER_WORD);
12943 let word = &mut scratch.dense_words[word_index];
12944 if *word & bit != 0 {
12945 return false;
12946 }
12947 if *word == 0 {
12948 scratch
12949 .touched_dense_words
12950 .push(u32::try_from(word_index).expect("dense outcome bitmap is capped"));
12951 }
12952 *word |= bit;
12953 true
12954 });
12955 #[cfg(feature = "perf-counters")]
12956 record_clean_fast_outcome_dedup(
12957 FastOutcomeDedupStrategy::Dense,
12958 input_len,
12959 outcomes.len(),
12960 word_count,
12961 );
12962 return FastOutcomeDedupStrategy::Dense;
12963 }
12964
12965 scratch.sparse_keys.clear();
12966 scratch.sparse_keys.reserve(outcomes.len());
12967 outcomes.retain(|outcome| {
12968 scratch
12969 .sparse_keys
12970 .insert((outcome.index, outcome.consumed_eof))
12971 });
12972 #[cfg(feature = "perf-counters")]
12973 record_clean_fast_outcome_dedup(
12974 FastOutcomeDedupStrategy::Sparse,
12975 input_len,
12976 outcomes.len(),
12977 0,
12978 );
12979 if scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS {
12980 scratch.sparse_keys = FxHashSet::default();
12981 }
12982 FastOutcomeDedupStrategy::Sparse
12983}
12984
12985fn dedupe_outcomes(outcomes: &mut Vec<RecognizeOutcome>, arena: &RecognitionArena) {
12988 outcomes.sort_unstable_by(|left, right| compare_recognize_outcomes(left, right, arena));
12989 outcomes
12990 .dedup_by(|left, right| compare_recognize_outcomes(left, right, arena) == Ordering::Equal);
12991}
12992
12993fn compare_recognize_outcomes(
12994 left: &RecognizeOutcome,
12995 right: &RecognizeOutcome,
12996 arena: &RecognitionArena,
12997) -> Ordering {
12998 left.index
12999 .cmp(&right.index)
13000 .then_with(|| left.consumed_eof.cmp(&right.consumed_eof))
13001 .then_with(|| left.alt_number.cmp(&right.alt_number))
13002 .then_with(|| left.member_values.cmp(&right.member_values))
13003 .then_with(|| left.return_values.cmp(&right.return_values))
13004 .then_with(|| arena.compare_diagnostics(left.diagnostics, right.diagnostics))
13005 .then_with(|| left.decisions.cmp(&right.decisions))
13006 .then_with(|| left.actions.cmp(&right.actions))
13007 .then_with(|| arena.compare_sequences(left.nodes, right.nodes))
13008}
13009
13010impl<S, H> Recognizer for BaseParser<S, H>
13011where
13012 S: TokenSource,
13013 H: SemanticHooks,
13014{
13015 fn data(&self) -> &RecognizerData {
13016 &self.data
13017 }
13018
13019 fn data_mut(&mut self) -> &mut RecognizerData {
13020 &mut self.data
13021 }
13022}
13023
13024impl<S, H> Parser for BaseParser<S, H>
13025where
13026 S: TokenSource,
13027 H: SemanticHooks,
13028{
13029 fn build_parse_trees(&self) -> bool {
13030 self.build_parse_trees
13031 }
13032
13033 fn set_build_parse_trees(&mut self, build: bool) {
13034 self.build_parse_trees = build;
13035 }
13036
13037 fn number_of_syntax_errors(&self) -> usize {
13038 Self::number_of_syntax_errors(self)
13039 }
13040
13041 fn report_diagnostic_errors(&self) -> bool {
13042 self.report_diagnostic_errors
13043 }
13044
13045 fn set_report_diagnostic_errors(&mut self, report: bool) {
13046 self.report_diagnostic_errors = report;
13047 }
13048
13049 fn prediction_mode(&self) -> PredictionMode {
13050 self.prediction_mode
13051 }
13052
13053 fn set_prediction_mode(&mut self, mode: PredictionMode) {
13054 self.prediction_mode = mode;
13055 }
13056
13057 fn max_rule_depth(&self) -> Option<usize> {
13058 self.max_rule_depth
13059 }
13060
13061 fn set_max_rule_depth(&mut self, depth: Option<usize>) {
13062 self.max_rule_depth = depth;
13063 }
13064
13065 fn add_parse_listener(&mut self, listener: Box<dyn ParseListener>) {
13066 self.parse_listeners.push(ParseListenerSlot(listener));
13067 }
13068
13069 fn remove_parse_listeners(&mut self) -> Vec<Box<dyn ParseListener>> {
13070 Self::remove_parse_listeners(self)
13071 }
13072}
13073
13074#[cfg(test)]
13075#[allow(clippy::disallowed_methods)] mod tests {
13077 use super::*;
13078 use crate::atn::parser::{
13079 ParserAtnPredictionDiagnostic, ParserAtnPredictionDiagnosticKind, ParserAtnSimulator,
13080 };
13081 use crate::atn::serialized::{AtnDeserializer, SerializedAtn};
13082 use crate::token::{
13083 HIDDEN_CHANNEL, Token, TokenId, TokenSink, TokenSpec, TokenStoreError, TokenView,
13084 };
13085 use crate::token_stream::CommonTokenStream;
13086 use crate::tree::{NodeKind, ParseTreeStats};
13087 use crate::vocabulary::Vocabulary;
13088 use std::cell::RefCell;
13089 use std::mem::size_of;
13090 use std::rc::Rc;
13091 use std::sync::{Arc, Mutex};
13092
13093 #[test]
13094 fn fx_hasher_write_matches_typed_methods_for_full_words() {
13095 let value: u64 = 0x0102_0304_0506_0708;
13102 let mut typed = FxHasher::default();
13103 typed.write_u64(value);
13104 let mut bytewise = FxHasher::default();
13105 bytewise.write(&value.to_le_bytes());
13106 assert_eq!(typed.finish(), bytewise.finish());
13107 }
13108
13109 #[derive(Clone, Debug)]
13110 struct TestToken {
13111 spec: TokenSpec,
13112 id: TokenId,
13113 source_name: String,
13114 }
13115
13116 impl TestToken {
13117 fn new(token_type: i32) -> Self {
13118 Self {
13119 spec: TokenSpec::explicit(token_type, ""),
13120 id: TokenId::try_from(0).expect("zero token ID"),
13121 source_name: String::new(),
13122 }
13123 }
13124
13125 fn eof(source_name: &str, index: usize, line: usize, column: usize) -> Self {
13126 Self {
13127 spec: TokenSpec::eof(index, index, line, column),
13128 id: TokenId::try_from(0).expect("zero token ID"),
13129 source_name: source_name.to_owned(),
13130 }
13131 }
13132
13133 fn with_text(mut self, text: impl Into<String>) -> Self {
13134 self.spec.text = Some(text.into());
13135 self
13136 }
13137
13138 const fn with_channel(mut self, channel: i32) -> Self {
13139 self.spec.channel = channel;
13140 self
13141 }
13142
13143 const fn with_span(mut self, start: usize, stop: usize) -> Self {
13144 self.spec.start = start;
13145 self.spec.stop = stop;
13146 self.spec.start_byte = start;
13147 self.spec.stop_byte = match stop.checked_add(1) {
13148 Some(end) if end >= start => end,
13149 Some(_) | None => start,
13150 };
13151 self
13152 }
13153
13154 const fn with_position(mut self, line: usize, column: usize) -> Self {
13155 self.spec.line = line;
13156 self.spec.column = column;
13157 self
13158 }
13159
13160 fn set_token_index(&mut self, index: isize) {
13161 self.id = TokenId::try_from(index.max(0).cast_unsigned()).expect("test token index");
13162 }
13163 }
13164
13165 impl Token for TestToken {
13166 fn token_id(&self) -> TokenId {
13167 self.id
13168 }
13169
13170 fn token_type(&self) -> i32 {
13171 self.spec.token_type
13172 }
13173
13174 fn channel(&self) -> i32 {
13175 self.spec.channel
13176 }
13177
13178 fn start(&self) -> usize {
13179 self.spec.start
13180 }
13181
13182 fn stop(&self) -> usize {
13183 self.spec.stop
13184 }
13185
13186 fn line(&self) -> usize {
13187 self.spec.line
13188 }
13189
13190 fn column(&self) -> usize {
13191 self.spec.column
13192 }
13193
13194 fn text(&self) -> Option<&str> {
13195 self.spec.text.as_deref()
13196 }
13197
13198 fn source_name(&self) -> &str {
13199 &self.source_name
13200 }
13201
13202 fn start_byte(&self) -> usize {
13203 self.spec.start_byte
13204 }
13205
13206 fn stop_byte(&self) -> usize {
13207 self.spec.stop_byte
13208 }
13209 }
13210
13211 #[derive(Debug)]
13212 struct Source {
13213 tokens: Vec<TestToken>,
13214 index: usize,
13215 }
13216
13217 impl TokenSource for Source {
13218 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
13219 let token = self
13220 .tokens
13221 .get(self.index)
13222 .cloned()
13223 .unwrap_or_else(|| TestToken::eof("parser-test", self.index, 1, self.index));
13224 self.index += 1;
13225 sink.push(token.spec)
13226 }
13227
13228 fn line(&self) -> usize {
13229 1
13230 }
13231
13232 fn column(&self) -> usize {
13233 self.index
13234 }
13235
13236 fn source_name(&self) -> &'static str {
13237 "parser-test"
13238 }
13239 }
13240
13241 #[derive(Clone, Debug, Eq, PartialEq)]
13242 struct RecordedDiagnostic {
13243 grammar_file_name: String,
13244 offending_text: Option<String>,
13245 line: usize,
13246 column: usize,
13247 message: String,
13248 error: Option<AntlrError>,
13249 }
13250
13251 #[derive(Clone, Debug)]
13252 struct RecordingErrorListener {
13253 diagnostics: Arc<Mutex<Vec<RecordedDiagnostic>>>,
13254 }
13255
13256 impl<R> crate::ErrorListener<R> for RecordingErrorListener
13257 where
13258 R: Recognizer + ?Sized,
13259 {
13260 fn syntax_error(
13261 &mut self,
13262 recognizer: &R,
13263 offending: Option<TokenView<'_>>,
13264 line: usize,
13265 column: usize,
13266 message: &str,
13267 error: Option<&AntlrError>,
13268 ) {
13269 self.diagnostics
13270 .lock()
13271 .expect("recorded diagnostics lock")
13272 .push(RecordedDiagnostic {
13273 grammar_file_name: recognizer.grammar_file_name().to_owned(),
13274 offending_text: offending.and_then(|token| token.text().map(str::to_owned)),
13275 line,
13276 column,
13277 message: message.to_owned(),
13278 error: error.cloned(),
13279 });
13280 }
13281 }
13282
13283 #[derive(Debug)]
13284 struct ReportingSource {
13285 source: Source,
13286 diagnostics: Rc<RefCell<Vec<TokenSourceError>>>,
13287 }
13288
13289 impl TokenSource for ReportingSource {
13290 fn next_token(&mut self, sink: &mut TokenSink<'_>) -> Result<TokenId, TokenStoreError> {
13291 self.source.next_token(sink)
13292 }
13293
13294 fn line(&self) -> usize {
13295 self.source.line()
13296 }
13297
13298 fn column(&self) -> usize {
13299 self.source.column()
13300 }
13301
13302 fn source_name(&self) -> &str {
13303 self.source.source_name()
13304 }
13305
13306 fn report_error(&self, error: &TokenSourceError) -> bool {
13307 self.diagnostics.borrow_mut().push(error.clone());
13308 true
13309 }
13310 }
13311
13312 fn mini_parser_data() -> RecognizerData {
13313 RecognizerData::new(
13314 "Mini.g4",
13315 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
13316 )
13317 .with_rule_names(["s"])
13318 }
13319
13320 fn mini_parser(tokens: Vec<TestToken>) -> BaseParser<Source> {
13321 let data = mini_parser_data();
13322 BaseParser::new(CommonTokenStream::new(Source { tokens, index: 0 }), data)
13323 }
13324
13325 fn mini_parser_with_hooks<H>(tokens: Vec<TestToken>, hooks: H) -> BaseParser<Source, H>
13326 where
13327 H: SemanticHooks,
13328 {
13329 BaseParser::with_semantic_hooks(
13330 CommonTokenStream::new(Source { tokens, index: 0 }),
13331 mini_parser_data(),
13332 hooks,
13333 )
13334 }
13335
13336 #[test]
13337 fn parser_dispatches_recovery_diagnostics_through_registered_listeners() {
13338 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
13339 parser.remove_error_listeners();
13340 let diagnostics = Arc::new(Mutex::new(Vec::new()));
13341 parser.add_error_listener(RecordingErrorListener {
13342 diagnostics: Arc::clone(&diagnostics),
13343 });
13344 let parser_diagnostics = [ParserDiagnostic {
13345 line: 1,
13346 column: 2,
13347 message: "missing 'x' at 'y'".to_owned(),
13348 offending: None,
13349 }];
13350 let token_errors = [
13351 TokenSourceError::new(1, 1, "token recognition error at: '@'"),
13352 TokenSourceError::new(1, 3, "token recognition error at: '#'"),
13353 ];
13354
13355 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
13356
13357 insta::assert_debug_snapshot!(
13360 "parser_dispatches_recovery_diagnostics_through_registered_listeners",
13361 *diagnostics.lock().expect("recorded diagnostics lock")
13362 );
13363
13364 parser.remove_error_listeners();
13365 parser.dispatch_generated_diagnostics(&parser_diagnostics, &token_errors);
13366 assert_eq!(
13367 diagnostics.lock().expect("recorded diagnostics lock").len(),
13368 3
13369 );
13370 }
13371
13372 #[test]
13373 fn recovery_diagnostics_expose_the_offending_token_to_listeners() {
13374 let mut parser = mini_parser(vec![
13375 TestToken::new(7)
13376 .with_text("oops")
13377 .with_span(0, 3)
13378 .with_position(1, 2),
13379 TestToken::eof("parser-test", 4, 1, 6),
13380 ]);
13381 parser.remove_error_listeners();
13382 let diagnostics = Arc::new(Mutex::new(Vec::new()));
13383 parser.add_error_listener(RecordingErrorListener {
13384 diagnostics: Arc::clone(&diagnostics),
13385 });
13386 let offending = parser.input.lt_id(1);
13387 assert!(offending.is_some(), "current token should be buffered");
13388 let parser_diagnostics = [ParserDiagnostic {
13389 line: 1,
13390 column: 2,
13391 message: "extraneous input 'oops'".to_owned(),
13392 offending,
13393 }];
13394
13395 parser.dispatch_generated_diagnostics(&parser_diagnostics, &[]);
13396
13397 let recorded = diagnostics
13401 .lock()
13402 .expect("recorded diagnostics lock")
13403 .clone();
13404 insta::assert_debug_snapshot!(
13405 "recovery_diagnostics_expose_the_offending_token_to_listeners",
13406 recorded
13407 );
13408 }
13409
13410 #[test]
13411 fn parser_leaves_token_errors_to_source_owned_listeners() {
13412 let source_diagnostics = Rc::new(RefCell::new(Vec::new()));
13413 let source = ReportingSource {
13414 source: Source {
13415 tokens: vec![TestToken::eof("parser-test", 0, 1, 0)],
13416 index: 0,
13417 },
13418 diagnostics: Rc::clone(&source_diagnostics),
13419 };
13420 let mut parser = BaseParser::new(CommonTokenStream::new(source), mini_parser_data());
13421 parser.remove_error_listeners();
13422 let parser_diagnostics = Arc::new(Mutex::new(Vec::new()));
13423 parser.add_error_listener(RecordingErrorListener {
13424 diagnostics: Arc::clone(&parser_diagnostics),
13425 });
13426 let source_error = TokenSourceError::new(2, 4, "token recognition error at: '$'");
13427
13428 parser.dispatch_token_source_errors(std::slice::from_ref(&source_error));
13429
13430 assert_eq!(*source_diagnostics.borrow(), [source_error]);
13431 assert!(
13432 parser_diagnostics
13433 .lock()
13434 .expect("recorded diagnostics lock")
13435 .is_empty()
13436 );
13437 }
13438
13439 fn finish_atn(builder: ParserAtnBuilder) -> Atn {
13440 builder.finish().expect("valid packed parser ATN")
13441 }
13442
13443 fn nested_rule_chain_atn(depth: usize) -> Atn {
13444 nested_rule_graph_atn(depth, false, false)
13445 }
13446
13447 fn nested_rule_graph_atn(depth: usize, branching: bool, consuming_follows: bool) -> Atn {
13448 assert!(depth > 0);
13449 let mut atn = ParserAtnBuilder::new(2);
13450 let mut starts = Vec::with_capacity(depth);
13451 let mut stops = Vec::with_capacity(depth);
13452 let mut follows = Vec::with_capacity(depth.saturating_sub(1));
13453 for rule_index in 0..depth {
13454 starts.push(
13455 atn.add_state(AtnStateKind::RuleStart, Some(rule_index))
13456 .expect("rule start")
13457 .index(),
13458 );
13459 }
13460 for rule_index in 0..depth {
13461 stops.push(
13462 atn.add_state(AtnStateKind::RuleStop, Some(rule_index))
13463 .expect("rule stop")
13464 .index(),
13465 );
13466 }
13467 if consuming_follows {
13468 for rule_index in 0..depth - 1 {
13469 follows.push(
13470 atn.add_state(AtnStateKind::Basic, Some(rule_index))
13471 .expect("rule follow")
13472 .index(),
13473 );
13474 }
13475 }
13476 atn.set_rule_to_start_state(starts.clone())
13477 .expect("rule start states");
13478 atn.set_rule_to_stop_state(stops.clone())
13479 .expect("rule stop states");
13480 for rule_index in 0..depth - 1 {
13481 let follow_state = if consuming_follows {
13482 follows[rule_index]
13483 } else {
13484 stops[rule_index]
13485 };
13486 atn.add_transition(
13487 starts[rule_index],
13488 ParserTransitionSpec::Rule {
13489 target: starts[rule_index + 1],
13490 rule_index: rule_index + 1,
13491 follow_state,
13492 precedence: 0,
13493 },
13494 )
13495 .expect("nested rule transition");
13496 if branching {
13497 atn.add_transition(
13498 starts[rule_index],
13499 ParserTransitionSpec::Atom {
13500 target: stops[rule_index],
13501 label: 2,
13502 },
13503 )
13504 .expect("dead branch transition");
13505 }
13506 if consuming_follows {
13507 atn.add_transition(
13508 follow_state,
13509 ParserTransitionSpec::Atom {
13510 target: stops[rule_index],
13511 label: 1,
13512 },
13513 )
13514 .expect("consuming follow transition");
13515 }
13516 }
13517 let token_set = atn.add_interval_set([(1, 1)]).expect("token set");
13518 atn.add_transition(
13519 starts[depth - 1],
13520 ParserTransitionSpec::Set {
13521 target: stops[depth - 1],
13522 set: token_set,
13523 },
13524 )
13525 .expect("terminal set transition");
13526 if branching {
13527 atn.add_transition(
13528 starts[depth - 1],
13529 ParserTransitionSpec::Atom {
13530 target: stops[depth - 1],
13531 label: 2,
13532 },
13533 )
13534 .expect("dead leaf branch transition");
13535 }
13536 finish_atn(atn)
13537 }
13538
13539 fn ordinary_star_loop_atn() -> Atn {
13540 let mut atn = ParserAtnBuilder::new(2);
13541 for (state_number, kind, rule_index) in [
13542 (0, AtnStateKind::RuleStart, 0),
13543 (1, AtnStateKind::StarLoopEntry, 0),
13544 (2, AtnStateKind::Basic, 0),
13545 (3, AtnStateKind::StarLoopBack, 0),
13546 (4, AtnStateKind::LoopEnd, 0),
13547 (5, AtnStateKind::Basic, 0),
13548 (6, AtnStateKind::RuleStop, 0),
13549 (7, AtnStateKind::RuleStart, 1),
13550 (8, AtnStateKind::Basic, 1),
13551 (9, AtnStateKind::RuleStop, 1),
13552 ] {
13553 assert_eq!(
13554 atn.add_state(kind, Some(rule_index))
13555 .expect("state")
13556 .index(),
13557 state_number
13558 );
13559 }
13560 atn.set_rule_to_start_state(vec![0, 7])
13561 .expect("rule start states");
13562 atn.set_rule_to_stop_state(vec![6, 9])
13563 .expect("rule stop states");
13564 atn.add_decision_state(1).expect("decision state");
13565 atn.set_loop_back_state(4, 3).expect("loop back state");
13566 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13567 .expect("transition");
13568 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13569 .expect("transition");
13570 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 4 })
13571 .expect("transition");
13572 atn.add_transition(
13573 2,
13574 ParserTransitionSpec::Rule {
13575 target: 7,
13576 rule_index: 1,
13577 follow_state: 3,
13578 precedence: 0,
13579 },
13580 )
13581 .expect("transition");
13582 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 1 })
13583 .expect("transition");
13584 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13585 .expect("transition");
13586 atn.add_transition(
13587 5,
13588 ParserTransitionSpec::Atom {
13589 target: 6,
13590 label: TOKEN_EOF,
13591 },
13592 )
13593 .expect("transition");
13594 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
13595 .expect("transition");
13596 atn.add_transition(
13597 8,
13598 ParserTransitionSpec::Atom {
13599 target: 9,
13600 label: 1,
13601 },
13602 )
13603 .expect("transition");
13604 finish_atn(atn)
13605 }
13606
13607 fn ambiguous_ordinary_star_loop_atn() -> Atn {
13609 let mut atn = ParserAtnBuilder::new(1);
13610 for (state_number, kind) in [
13611 (0, AtnStateKind::RuleStart),
13612 (1, AtnStateKind::StarLoopEntry),
13613 (2, AtnStateKind::StarBlockStart),
13614 (3, AtnStateKind::Basic),
13615 (4, AtnStateKind::BlockEnd),
13616 (5, AtnStateKind::StarLoopBack),
13617 (6, AtnStateKind::LoopEnd),
13618 (7, AtnStateKind::Basic),
13619 (8, AtnStateKind::RuleStop),
13620 ] {
13621 assert_eq!(
13622 atn.add_state(kind, Some(0)).expect("state").index(),
13623 state_number
13624 );
13625 }
13626 atn.set_rule_to_start_state(vec![0])
13627 .expect("rule start states");
13628 atn.set_rule_to_stop_state(vec![8])
13629 .expect("rule stop states");
13630 atn.set_end_state(2, 4).expect("block end state");
13631 atn.set_loop_back_state(6, 5).expect("loop back state");
13632 atn.add_decision_state(1).expect("decision state");
13633 atn.add_decision_state(2).expect("decision state");
13634 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13635 .expect("transition");
13636 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13637 .expect("transition");
13638 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 6 })
13639 .expect("transition");
13640 atn.add_transition(
13641 2,
13642 ParserTransitionSpec::Atom {
13643 target: 4,
13644 label: 1,
13645 },
13646 )
13647 .expect("transition");
13648 atn.add_transition(
13649 2,
13650 ParserTransitionSpec::Atom {
13651 target: 3,
13652 label: 1,
13653 },
13654 )
13655 .expect("transition");
13656 atn.add_transition(
13657 3,
13658 ParserTransitionSpec::Atom {
13659 target: 4,
13660 label: 1,
13661 },
13662 )
13663 .expect("transition");
13664 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13665 .expect("transition");
13666 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 1 })
13667 .expect("transition");
13668 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13669 .expect("transition");
13670 atn.add_transition(
13671 7,
13672 ParserTransitionSpec::Atom {
13673 target: 8,
13674 label: TOKEN_EOF,
13675 },
13676 )
13677 .expect("transition");
13678 finish_atn(atn)
13679 }
13680
13681 fn ordinary_plus_loop_atn() -> Atn {
13682 let mut atn = ParserAtnBuilder::new(2);
13683 for (state_number, kind, rule_index) in [
13684 (0, AtnStateKind::RuleStart, 0),
13685 (1, AtnStateKind::Basic, 0),
13686 (2, AtnStateKind::PlusLoopBack, 0),
13687 (3, AtnStateKind::LoopEnd, 0),
13688 (4, AtnStateKind::Basic, 0),
13689 (5, AtnStateKind::RuleStop, 0),
13690 (6, AtnStateKind::RuleStart, 1),
13691 (7, AtnStateKind::Basic, 1),
13692 (8, AtnStateKind::RuleStop, 1),
13693 ] {
13694 assert_eq!(
13695 atn.add_state(kind, Some(rule_index))
13696 .expect("state")
13697 .index(),
13698 state_number
13699 );
13700 }
13701 atn.set_rule_to_start_state(vec![0, 6])
13702 .expect("rule start states");
13703 atn.set_rule_to_stop_state(vec![5, 8])
13704 .expect("rule stop states");
13705 atn.add_decision_state(2).expect("decision state");
13706 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
13707 .expect("transition");
13708 atn.add_transition(
13709 1,
13710 ParserTransitionSpec::Rule {
13711 target: 6,
13712 rule_index: 1,
13713 follow_state: 2,
13714 precedence: 0,
13715 },
13716 )
13717 .expect("transition");
13718 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 1 })
13719 .expect("transition");
13720 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13721 .expect("transition");
13722 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
13723 .expect("transition");
13724 atn.add_transition(
13725 4,
13726 ParserTransitionSpec::Atom {
13727 target: 5,
13728 label: TOKEN_EOF,
13729 },
13730 )
13731 .expect("transition");
13732 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
13733 .expect("transition");
13734 atn.add_transition(
13735 7,
13736 ParserTransitionSpec::Atom {
13737 target: 8,
13738 label: 1,
13739 },
13740 )
13741 .expect("transition");
13742 finish_atn(atn)
13743 }
13744
13745 fn repeated_x_tokens(count: usize) -> Vec<TestToken> {
13746 let mut tokens = (0..count)
13747 .map(|_| TestToken::new(1).with_text("x"))
13748 .collect::<Vec<_>>();
13749 tokens.push(TestToken::eof("parser-test", count, 1, count));
13750 tokens
13751 }
13752
13753 fn left_recursive_loop_with_caller_follow_atn(caller_symbol: i32) -> Atn {
13754 let mut atn = ParserAtnBuilder::new(2);
13755 assert_eq!(
13756 atn.add_state(AtnStateKind::RuleStart, Some(0))
13757 .expect("state")
13758 .index(),
13759 0
13760 );
13761 assert_eq!(
13762 atn.add_state(AtnStateKind::Basic, Some(0))
13763 .expect("state")
13764 .index(),
13765 1
13766 );
13767 assert_eq!(
13768 atn.add_state(AtnStateKind::Basic, Some(0))
13769 .expect("state")
13770 .index(),
13771 2
13772 );
13773 assert_eq!(
13774 atn.add_state(AtnStateKind::RuleStart, Some(1))
13775 .expect("state")
13776 .index(),
13777 3
13778 );
13779 atn.set_left_recursive_rule(3)
13780 .expect("left-recursive rule start");
13781 assert_eq!(
13782 atn.add_state(AtnStateKind::StarLoopEntry, Some(1))
13783 .expect("state")
13784 .index(),
13785 4
13786 );
13787 atn.set_precedence_rule_decision(4)
13788 .expect("precedence decision");
13789 assert_eq!(
13790 atn.add_state(AtnStateKind::Basic, Some(1))
13791 .expect("state")
13792 .index(),
13793 5
13794 );
13795 assert_eq!(
13796 atn.add_state(AtnStateKind::Basic, Some(1))
13797 .expect("state")
13798 .index(),
13799 6
13800 );
13801 assert_eq!(
13802 atn.add_state(AtnStateKind::LoopEnd, Some(1))
13803 .expect("state")
13804 .index(),
13805 7
13806 );
13807 assert_eq!(
13808 atn.add_state(AtnStateKind::RuleStop, Some(1))
13809 .expect("state")
13810 .index(),
13811 8
13812 );
13813 assert_eq!(
13814 atn.add_state(AtnStateKind::RuleStop, Some(0))
13815 .expect("state")
13816 .index(),
13817 9
13818 );
13819 atn.set_rule_to_start_state(vec![0, 3])
13820 .expect("rule start states");
13821 atn.set_rule_to_stop_state(vec![9, 8])
13822 .expect("rule stop states");
13823 atn.add_transition(
13824 1,
13825 ParserTransitionSpec::Rule {
13826 target: 3,
13827 rule_index: 1,
13828 follow_state: 2,
13829 precedence: 0,
13830 },
13831 )
13832 .expect("transition");
13833 atn.add_transition(
13834 2,
13835 ParserTransitionSpec::Atom {
13836 target: 9,
13837 label: caller_symbol,
13838 },
13839 )
13840 .expect("transition");
13841 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
13842 .expect("transition");
13843 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 7 })
13844 .expect("transition");
13845 atn.add_transition(
13846 5,
13847 ParserTransitionSpec::Precedence {
13848 target: 6,
13849 precedence: 1,
13850 },
13851 )
13852 .expect("transition");
13853 atn.add_transition(
13854 6,
13855 ParserTransitionSpec::Atom {
13856 target: 4,
13857 label: 1,
13858 },
13859 )
13860 .expect("transition");
13861 atn.add_transition(7, ParserTransitionSpec::Epsilon { target: 8 })
13862 .expect("transition");
13863 finish_atn(atn)
13864 }
13865
13866 fn labeled_left_recursive_operator_atn() -> Atn {
13867 let mut atn = ParserAtnBuilder::new(4);
13868 for (state, kind) in [
13869 (0, AtnStateKind::RuleStart),
13870 (1, AtnStateKind::BlockStart),
13871 (2, AtnStateKind::StarLoopEntry),
13872 (3, AtnStateKind::StarBlockStart),
13873 (4, AtnStateKind::Basic),
13874 (5, AtnStateKind::Basic),
13875 (6, AtnStateKind::Basic),
13876 (7, AtnStateKind::StarLoopBack),
13877 (8, AtnStateKind::LoopEnd),
13878 (9, AtnStateKind::RuleStop),
13879 ] {
13880 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
13881 }
13882 atn.set_left_recursive_rule(0)
13883 .expect("left-recursive rule start");
13884 atn.set_precedence_rule_decision(2)
13885 .expect("precedence decision");
13886 atn.set_loop_back_state(8, 7).expect("loop-back state");
13887 atn.set_rule_to_start_state(vec![0])
13888 .expect("rule start states");
13889 atn.set_rule_to_stop_state(vec![9])
13890 .expect("rule stop states");
13891 for state in [1, 2, 3] {
13892 atn.add_decision_state(state).expect("decision state");
13893 }
13894 for (source, target) in [(0, 1), (2, 3), (2, 8), (7, 2), (8, 9)] {
13895 atn.add_transition(source, ParserTransitionSpec::Epsilon { target })
13896 .expect("epsilon transition");
13897 }
13898 for (source, target, label) in [(1, 2, 1), (1, 2, 2), (4, 6, 4), (5, 6, 3), (6, 7, 1)] {
13899 atn.add_transition(source, ParserTransitionSpec::Atom { target, label })
13900 .expect("token transition");
13901 }
13902 for (target, precedence) in [(4, 2), (5, 1)] {
13903 atn.add_transition(3, ParserTransitionSpec::Precedence { target, precedence })
13904 .expect("operator precedence");
13905 }
13906 finish_atn(atn)
13907 }
13908
13909 fn parser_inside_left_recursive_callee(symbol: i32) -> BaseParser<Source> {
13910 let mut parser = mini_parser(vec![
13911 TestToken::new(symbol).with_text("lookahead"),
13912 TestToken::eof("parser-test", 1, 1, 1),
13913 ]);
13914 parser.rule_context_stack = vec![
13915 RuleContextFrame {
13916 rule_index: 0,
13917 invoking_state: -1,
13918 },
13919 RuleContextFrame {
13920 rule_index: 1,
13921 invoking_state: 1,
13922 },
13923 ];
13924 parser
13925 }
13926
13927 fn left_recursive_loop_with_shared_gt_prefix_atn() -> Atn {
13928 let mut atn = ParserAtnBuilder::new(1);
13932 for (state, kind, rule) in [
13933 (0, AtnStateKind::RuleStart, 0),
13934 (1, AtnStateKind::StarLoopEntry, 0),
13935 (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),
13942 (9, AtnStateKind::RuleStop, 0),
13943 ] {
13944 assert_eq!(
13945 atn.add_state(kind, Some(rule)).expect("state").index(),
13946 state
13947 );
13948 if state == 0 {
13949 atn.set_left_recursive_rule(state)
13950 .expect("left-recursive rule start");
13951 } else if state == 1 {
13952 atn.set_precedence_rule_decision(state)
13953 .expect("precedence decision");
13954 }
13955 }
13956 atn.set_rule_to_start_state(vec![0])
13957 .expect("rule start states");
13958 atn.set_rule_to_stop_state(vec![9])
13959 .expect("rule stop states");
13960 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
13961 .expect("ops");
13962 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
13963 .expect("exit");
13964 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
13965 .expect("to shift");
13966 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
13967 .expect("to rel");
13968 atn.add_transition(
13969 3,
13970 ParserTransitionSpec::Precedence {
13971 target: 4,
13972 precedence: 2,
13973 },
13974 )
13975 .expect("shift prec");
13976 atn.add_transition(
13977 4,
13978 ParserTransitionSpec::Atom {
13979 target: 5,
13980 label: 1,
13981 },
13982 )
13983 .expect("shift first >");
13984 atn.add_transition(
13985 5,
13986 ParserTransitionSpec::Atom {
13987 target: 1,
13988 label: 1,
13989 },
13990 )
13991 .expect("shift second >");
13992 atn.add_transition(
13993 6,
13994 ParserTransitionSpec::Precedence {
13995 target: 7,
13996 precedence: 1,
13997 },
13998 )
13999 .expect("rel prec");
14000 atn.add_transition(
14001 7,
14002 ParserTransitionSpec::Atom {
14003 target: 1,
14004 label: 1,
14005 },
14006 )
14007 .expect("rel >");
14008 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14009 .expect("loop end");
14010 finish_atn(atn)
14011 }
14012
14013 fn left_recursive_loop_with_rule_wrapped_gt_prefix_atn() -> Atn {
14014 let mut atn = ParserAtnBuilder::new(2);
14015 for (state, kind, rule) in [
14016 (0, AtnStateKind::RuleStart, 0),
14017 (1, AtnStateKind::StarLoopEntry, 0),
14018 (2, AtnStateKind::Basic, 0),
14019 (3, AtnStateKind::Basic, 0),
14020 (4, AtnStateKind::Basic, 0),
14021 (5, AtnStateKind::Basic, 0),
14022 (6, AtnStateKind::Basic, 0),
14023 (7, AtnStateKind::Basic, 0),
14024 (8, AtnStateKind::LoopEnd, 0),
14025 (9, AtnStateKind::RuleStop, 0),
14026 (10, AtnStateKind::RuleStart, 1),
14027 (11, AtnStateKind::Basic, 1),
14028 (12, AtnStateKind::RuleStop, 1),
14029 ] {
14030 assert_eq!(
14031 atn.add_state(kind, Some(rule)).expect("state").index(),
14032 state
14033 );
14034 if state == 0 {
14035 atn.set_left_recursive_rule(state)
14036 .expect("left-recursive rule start");
14037 } else if state == 1 {
14038 atn.set_precedence_rule_decision(state)
14039 .expect("precedence decision");
14040 }
14041 }
14042 atn.set_rule_to_start_state(vec![0, 10])
14043 .expect("rule start states");
14044 atn.set_rule_to_stop_state(vec![9, 12])
14045 .expect("rule stop states");
14046 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14047 .expect("ops");
14048 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 8 })
14049 .expect("exit");
14050 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
14051 .expect("to shift");
14052 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
14053 .expect("to relational");
14054 atn.add_transition(
14055 3,
14056 ParserTransitionSpec::Precedence {
14057 target: 4,
14058 precedence: 2,
14059 },
14060 )
14061 .expect("shift precedence");
14062 atn.add_transition(
14063 4,
14064 ParserTransitionSpec::Rule {
14065 target: 10,
14066 rule_index: 1,
14067 follow_state: 5,
14068 precedence: 0,
14069 },
14070 )
14071 .expect("first shift token helper");
14072 atn.add_transition(
14073 5,
14074 ParserTransitionSpec::Atom {
14075 target: 1,
14076 label: 1,
14077 },
14078 )
14079 .expect("second shift token");
14080 atn.add_transition(
14081 6,
14082 ParserTransitionSpec::Precedence {
14083 target: 7,
14084 precedence: 1,
14085 },
14086 )
14087 .expect("relational precedence");
14088 atn.add_transition(
14089 7,
14090 ParserTransitionSpec::Atom {
14091 target: 1,
14092 label: 1,
14093 },
14094 )
14095 .expect("relational token");
14096 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
14097 .expect("loop end");
14098 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
14099 .expect("helper entry");
14100 atn.add_transition(
14101 11,
14102 ParserTransitionSpec::Atom {
14103 target: 12,
14104 label: 1,
14105 },
14106 )
14107 .expect("first shift token");
14108 finish_atn(atn)
14109 }
14110
14111 fn left_recursive_loop_with_predicate_and_multi_token_prefix_atn() -> Atn {
14112 let mut atn = ParserAtnBuilder::new(1);
14113 for (state, kind) in [
14114 (0, AtnStateKind::RuleStart),
14115 (1, AtnStateKind::StarLoopEntry),
14116 (2, AtnStateKind::Basic),
14117 (3, AtnStateKind::Basic),
14118 (4, AtnStateKind::Basic),
14119 (5, AtnStateKind::Basic),
14120 (6, AtnStateKind::Basic),
14121 (7, AtnStateKind::Basic),
14122 (8, AtnStateKind::Basic),
14123 (9, AtnStateKind::LoopEnd),
14124 (10, AtnStateKind::RuleStop),
14125 ] {
14126 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
14127 if state == 0 {
14128 atn.set_left_recursive_rule(state)
14129 .expect("left-recursive rule start");
14130 } else if state == 1 {
14131 atn.set_precedence_rule_decision(state)
14132 .expect("precedence decision");
14133 }
14134 }
14135 atn.set_rule_to_start_state(vec![0])
14136 .expect("rule start states");
14137 atn.set_rule_to_stop_state(vec![10])
14138 .expect("rule stop states");
14139 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14140 .expect("ops");
14141 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 9 })
14142 .expect("exit");
14143 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 3 })
14144 .expect("to multi-token operator");
14145 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 6 })
14146 .expect("to predicate operator");
14147 atn.add_transition(
14148 3,
14149 ParserTransitionSpec::Precedence {
14150 target: 4,
14151 precedence: 2,
14152 },
14153 )
14154 .expect("multi-token precedence");
14155 atn.add_transition(
14156 4,
14157 ParserTransitionSpec::Atom {
14158 target: 5,
14159 label: 1,
14160 },
14161 )
14162 .expect("multi-token first");
14163 atn.add_transition(
14164 5,
14165 ParserTransitionSpec::Atom {
14166 target: 1,
14167 label: 1,
14168 },
14169 )
14170 .expect("multi-token second");
14171 atn.add_transition(
14172 6,
14173 ParserTransitionSpec::Precedence {
14174 target: 7,
14175 precedence: 2,
14176 },
14177 )
14178 .expect("predicate precedence");
14179 atn.add_transition(
14180 7,
14181 ParserTransitionSpec::Predicate {
14182 target: 8,
14183 rule_index: 0,
14184 pred_index: 0,
14185 context_dependent: false,
14186 },
14187 )
14188 .expect("operator predicate");
14189 atn.add_transition(
14190 8,
14191 ParserTransitionSpec::Atom {
14192 target: 1,
14193 label: 1,
14194 },
14195 )
14196 .expect("predicate single token");
14197 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
14198 .expect("loop end");
14199 finish_atn(atn)
14200 }
14201
14202 fn left_recursive_loop_with_nullable_operator_prefix_atn() -> Atn {
14203 let mut atn = ParserAtnBuilder::new(2);
14204 for (state, kind, rule) in [
14205 (0, AtnStateKind::RuleStart, 0),
14206 (1, AtnStateKind::StarLoopEntry, 0),
14207 (2, AtnStateKind::Basic, 0),
14208 (3, AtnStateKind::Basic, 0),
14209 (4, AtnStateKind::Basic, 0),
14210 (5, AtnStateKind::LoopEnd, 0),
14211 (6, AtnStateKind::RuleStop, 0),
14212 (7, AtnStateKind::RuleStart, 1),
14213 (8, AtnStateKind::RuleStop, 1),
14214 (9, AtnStateKind::Basic, 1),
14215 ] {
14216 assert_eq!(
14217 atn.add_state(kind, Some(rule)).expect("state").index(),
14218 state
14219 );
14220 if state == 0 {
14221 atn.set_left_recursive_rule(state)
14222 .expect("left-recursive rule start");
14223 } else if state == 1 {
14224 atn.set_precedence_rule_decision(state)
14225 .expect("precedence decision");
14226 }
14227 }
14228 atn.set_rule_to_start_state(vec![0, 7])
14229 .expect("rule start states");
14230 atn.set_rule_to_stop_state(vec![6, 8])
14231 .expect("rule stop states");
14232 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14233 .expect("transition");
14234 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
14235 .expect("transition");
14236 atn.add_transition(
14237 2,
14238 ParserTransitionSpec::Precedence {
14239 target: 3,
14240 precedence: 3,
14241 },
14242 )
14243 .expect("transition");
14244 atn.add_transition(
14245 3,
14246 ParserTransitionSpec::Rule {
14247 target: 7,
14248 rule_index: 1,
14249 follow_state: 4,
14250 precedence: 0,
14251 },
14252 )
14253 .expect("transition");
14254 atn.add_transition(
14255 4,
14256 ParserTransitionSpec::Atom {
14257 target: 1,
14258 label: 1,
14259 },
14260 )
14261 .expect("transition");
14262 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
14263 .expect("transition");
14264 atn.add_transition(
14265 7,
14266 ParserTransitionSpec::Precedence {
14267 target: 9,
14268 precedence: 1,
14269 },
14270 )
14271 .expect("transition");
14272 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 8 })
14273 .expect("transition");
14274 finish_atn(atn)
14275 }
14276
14277 fn left_recursive_loop_with_predicate_guarded_operator_atn() -> Atn {
14278 let mut atn = ParserAtnBuilder::new(2);
14279 for (state, kind) in [
14280 (0, AtnStateKind::RuleStart),
14281 (1, AtnStateKind::StarLoopEntry),
14282 (2, AtnStateKind::Basic),
14283 (3, AtnStateKind::Basic),
14284 (4, AtnStateKind::Basic),
14285 (5, AtnStateKind::LoopEnd),
14286 (6, AtnStateKind::RuleStop),
14287 ] {
14288 assert_eq!(atn.add_state(kind, Some(0)).expect("state").index(), state);
14289 if state == 0 {
14290 atn.set_left_recursive_rule(state)
14291 .expect("left-recursive rule start");
14292 } else if state == 1 {
14293 atn.set_precedence_rule_decision(state)
14294 .expect("precedence decision");
14295 }
14296 }
14297 atn.set_rule_to_start_state(vec![0])
14298 .expect("rule start states");
14299 atn.set_rule_to_stop_state(vec![6])
14300 .expect("rule stop states");
14301 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14302 .expect("transition");
14303 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 5 })
14304 .expect("transition");
14305 atn.add_transition(
14306 2,
14307 ParserTransitionSpec::Precedence {
14308 target: 3,
14309 precedence: 1,
14310 },
14311 )
14312 .expect("transition");
14313 atn.add_transition(
14314 3,
14315 ParserTransitionSpec::Predicate {
14316 target: 4,
14317 rule_index: 0,
14318 pred_index: 0,
14319 context_dependent: false,
14320 },
14321 )
14322 .expect("transition");
14323 atn.add_transition(
14324 4,
14325 ParserTransitionSpec::Atom {
14326 target: 1,
14327 label: 1,
14328 },
14329 )
14330 .expect("transition");
14331 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
14332 .expect("transition");
14333 finish_atn(atn)
14334 }
14335
14336 fn left_recursive_loop_with_nullable_follow_call_atn(caller_symbol: i32) -> Atn {
14337 let mut atn = ParserAtnBuilder::new(2);
14338 for (state, kind, rule) in [
14339 (0, AtnStateKind::RuleStart, 0),
14340 (1, AtnStateKind::Basic, 0),
14341 (2, AtnStateKind::Basic, 0),
14342 (3, AtnStateKind::Basic, 0),
14343 (4, AtnStateKind::RuleStop, 0),
14344 (5, AtnStateKind::RuleStart, 1),
14345 (6, AtnStateKind::StarLoopEntry, 1),
14346 (7, AtnStateKind::Basic, 1),
14347 (8, AtnStateKind::Basic, 1),
14348 (9, AtnStateKind::LoopEnd, 1),
14349 (10, AtnStateKind::RuleStop, 1),
14350 (11, AtnStateKind::RuleStart, 2),
14351 (12, AtnStateKind::RuleStop, 2),
14352 ] {
14353 assert_eq!(
14354 atn.add_state(kind, Some(rule)).expect("state").index(),
14355 state
14356 );
14357 if state == 5 {
14358 atn.set_left_recursive_rule(state)
14359 .expect("left-recursive rule start");
14360 } else if state == 6 {
14361 atn.set_precedence_rule_decision(state)
14362 .expect("precedence decision");
14363 }
14364 }
14365 atn.set_rule_to_start_state(vec![0, 5, 11])
14366 .expect("rule start states");
14367 atn.set_rule_to_stop_state(vec![4, 10, 12])
14368 .expect("rule stop states");
14369 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14370 .expect("transition");
14371 atn.add_transition(
14372 1,
14373 ParserTransitionSpec::Rule {
14374 target: 5,
14375 rule_index: 1,
14376 follow_state: 2,
14377 precedence: 0,
14378 },
14379 )
14380 .expect("transition");
14381 atn.add_transition(
14382 2,
14383 ParserTransitionSpec::Rule {
14384 target: 11,
14385 rule_index: 2,
14386 follow_state: 3,
14387 precedence: 0,
14388 },
14389 )
14390 .expect("transition");
14391 atn.add_transition(
14392 3,
14393 ParserTransitionSpec::Atom {
14394 target: 4,
14395 label: caller_symbol,
14396 },
14397 )
14398 .expect("transition");
14399 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
14400 .expect("transition");
14401 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 9 })
14402 .expect("transition");
14403 atn.add_transition(
14404 7,
14405 ParserTransitionSpec::Precedence {
14406 target: 8,
14407 precedence: 1,
14408 },
14409 )
14410 .expect("transition");
14411 atn.add_transition(
14412 8,
14413 ParserTransitionSpec::Atom {
14414 target: 6,
14415 label: 1,
14416 },
14417 )
14418 .expect("transition");
14419 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
14420 .expect("transition");
14421 atn.add_transition(11, ParserTransitionSpec::Epsilon { target: 12 })
14422 .expect("transition");
14423 finish_atn(atn)
14424 }
14425
14426 fn left_recursive_loop_with_nullable_parent_return_atn(caller_symbol: i32) -> Atn {
14427 let mut atn = ParserAtnBuilder::new(2);
14428 for (state, kind, rule) in [
14429 (0, AtnStateKind::RuleStart, 0),
14430 (1, AtnStateKind::Basic, 0),
14431 (2, AtnStateKind::Basic, 0),
14432 (3, AtnStateKind::RuleStop, 0),
14433 (4, AtnStateKind::RuleStart, 1),
14434 (5, AtnStateKind::Basic, 1),
14435 (6, AtnStateKind::Basic, 1),
14436 (7, AtnStateKind::RuleStop, 1),
14437 (8, AtnStateKind::RuleStart, 2),
14438 (9, AtnStateKind::StarLoopEntry, 2),
14439 (10, AtnStateKind::Basic, 2),
14440 (11, AtnStateKind::Basic, 2),
14441 (12, AtnStateKind::LoopEnd, 2),
14442 (13, AtnStateKind::RuleStop, 2),
14443 ] {
14444 assert_eq!(
14445 atn.add_state(kind, Some(rule)).expect("state").index(),
14446 state
14447 );
14448 if state == 8 {
14449 atn.set_left_recursive_rule(state)
14450 .expect("left-recursive rule start");
14451 } else if state == 9 {
14452 atn.set_precedence_rule_decision(state)
14453 .expect("precedence decision");
14454 }
14455 }
14456 atn.set_rule_to_start_state(vec![0, 4, 8])
14457 .expect("rule start states");
14458 atn.set_rule_to_stop_state(vec![3, 7, 13])
14459 .expect("rule stop states");
14460 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14461 .expect("transition");
14462 atn.add_transition(
14463 1,
14464 ParserTransitionSpec::Rule {
14465 target: 4,
14466 rule_index: 1,
14467 follow_state: 2,
14468 precedence: 0,
14469 },
14470 )
14471 .expect("transition");
14472 atn.add_transition(
14473 2,
14474 ParserTransitionSpec::Atom {
14475 target: 3,
14476 label: caller_symbol,
14477 },
14478 )
14479 .expect("transition");
14480 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
14481 .expect("transition");
14482 atn.add_transition(
14483 5,
14484 ParserTransitionSpec::Rule {
14485 target: 8,
14486 rule_index: 2,
14487 follow_state: 6,
14488 precedence: 0,
14489 },
14490 )
14491 .expect("transition");
14492 atn.add_transition(6, ParserTransitionSpec::Epsilon { target: 7 })
14493 .expect("transition");
14494 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 10 })
14495 .expect("transition");
14496 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 12 })
14497 .expect("transition");
14498 atn.add_transition(
14499 10,
14500 ParserTransitionSpec::Precedence {
14501 target: 11,
14502 precedence: 1,
14503 },
14504 )
14505 .expect("transition");
14506 atn.add_transition(
14507 11,
14508 ParserTransitionSpec::Atom {
14509 target: 9,
14510 label: 1,
14511 },
14512 )
14513 .expect("transition");
14514 atn.add_transition(12, ParserTransitionSpec::Epsilon { target: 13 })
14515 .expect("transition");
14516 finish_atn(atn)
14517 }
14518
14519 fn left_recursive_loop_with_recursive_operand_return_atn(caller_symbol: i32) -> Atn {
14520 let mut atn = ParserAtnBuilder::new(2);
14521 for (state, kind, rule) in [
14522 (0, AtnStateKind::RuleStart, 0),
14523 (1, AtnStateKind::Basic, 0),
14524 (2, AtnStateKind::Basic, 0),
14525 (3, AtnStateKind::RuleStop, 0),
14526 (4, AtnStateKind::RuleStart, 1),
14527 (5, AtnStateKind::StarLoopEntry, 1),
14528 (6, AtnStateKind::Basic, 1),
14529 (7, AtnStateKind::Basic, 1),
14530 (8, AtnStateKind::Basic, 1),
14531 (9, AtnStateKind::Basic, 1),
14532 (10, AtnStateKind::LoopEnd, 1),
14533 (11, AtnStateKind::RuleStop, 1),
14534 ] {
14535 assert_eq!(
14536 atn.add_state(kind, Some(rule)).expect("state").index(),
14537 state
14538 );
14539 if state == 4 {
14540 atn.set_left_recursive_rule(state)
14541 .expect("left-recursive rule start");
14542 } else if state == 5 {
14543 atn.set_precedence_rule_decision(state)
14544 .expect("precedence decision");
14545 }
14546 }
14547 atn.set_rule_to_start_state(vec![0, 4])
14548 .expect("rule start states");
14549 atn.set_rule_to_stop_state(vec![3, 11])
14550 .expect("rule stop states");
14551 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14552 .expect("transition");
14553 atn.add_transition(
14554 1,
14555 ParserTransitionSpec::Rule {
14556 target: 4,
14557 rule_index: 1,
14558 follow_state: 2,
14559 precedence: 0,
14560 },
14561 )
14562 .expect("transition");
14563 atn.add_transition(
14564 2,
14565 ParserTransitionSpec::Atom {
14566 target: 3,
14567 label: caller_symbol,
14568 },
14569 )
14570 .expect("transition");
14571 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 6 })
14572 .expect("transition");
14573 atn.add_transition(5, ParserTransitionSpec::Epsilon { target: 10 })
14574 .expect("transition");
14575 atn.add_transition(
14576 6,
14577 ParserTransitionSpec::Precedence {
14578 target: 7,
14579 precedence: 1,
14580 },
14581 )
14582 .expect("transition");
14583 atn.add_transition(
14584 7,
14585 ParserTransitionSpec::Atom {
14586 target: 8,
14587 label: 1,
14588 },
14589 )
14590 .expect("transition");
14591 atn.add_transition(
14592 8,
14593 ParserTransitionSpec::Rule {
14594 target: 4,
14595 rule_index: 1,
14596 follow_state: 9,
14597 precedence: 2,
14598 },
14599 )
14600 .expect("transition");
14601 atn.add_transition(9, ParserTransitionSpec::Epsilon { target: 5 })
14602 .expect("transition");
14603 atn.add_transition(10, ParserTransitionSpec::Epsilon { target: 11 })
14604 .expect("transition");
14605 finish_atn(atn)
14606 }
14607
14608 #[test]
14609 fn left_recursive_loop_defers_overlapping_caller_lookahead() {
14610 let overlapping_atn = left_recursive_loop_with_caller_follow_atn(1);
14611 let unambiguous_atn = left_recursive_loop_with_caller_follow_atn(2);
14612
14613 let mut overlapping = parser_inside_left_recursive_callee(1);
14614 assert_eq!(
14615 overlapping.left_recursive_loop_enter_prediction(&overlapping_atn, 4, 0),
14616 None
14617 );
14618
14619 let mut unambiguous_enter = parser_inside_left_recursive_callee(1);
14620 assert_eq!(
14621 unambiguous_enter.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
14622 Some(true)
14623 );
14624
14625 let mut unambiguous_exit = parser_inside_left_recursive_callee(2);
14626 assert_eq!(
14627 unambiguous_exit.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
14628 Some(false)
14629 );
14630
14631 assert_eq!(
14632 overlapping.left_recursive_loop_enter_prediction(&unambiguous_atn, 4, 0),
14633 Some(true),
14634 "overlap results must not leak across ATNs"
14635 );
14636 }
14637
14638 #[test]
14639 fn left_recursive_loop_enters_after_nullable_operator_prefix() {
14640 let atn = left_recursive_loop_with_nullable_operator_prefix_atn();
14641 let mut parser = mini_parser(vec![
14642 TestToken::new(1).with_text("operator"),
14643 TestToken::eof("parser-test", 1, 1, 1),
14644 ]);
14645 parser.rule_context_stack = vec![RuleContextFrame {
14646 rule_index: 0,
14647 invoking_state: -1,
14648 }];
14649
14650 assert_eq!(
14651 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14652 Some(true)
14653 );
14654 assert_eq!(
14655 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14656 Some(true),
14657 "cached operator lookahead must preserve the nullable prefix return path"
14658 );
14659 assert_eq!(
14660 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14661 Some(true),
14662 "the nullable child must use its rule-call precedence, not the caller precedence"
14663 );
14664 }
14665
14666 #[test]
14667 fn left_recursive_loop_defers_multi_token_prefix_that_shadows_lower_single_token() {
14668 let atn = left_recursive_loop_with_shared_gt_prefix_atn();
14673 let mut parser = mini_parser(vec![
14674 TestToken::new(1).with_text(">"),
14675 TestToken::new(2).with_text("id"),
14676 TestToken::eof("parser-test", 1, 1, 1),
14677 ]);
14678 parser.rule_context_stack = vec![RuleContextFrame {
14679 rule_index: 0,
14680 invoking_state: -1,
14681 }];
14682
14683 assert_eq!(
14684 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14685 Some(true),
14686 "at low precedence relational `>` is a single-token operator"
14687 );
14688 assert_eq!(
14689 parser.left_recursive_loop_enter_prediction(&atn, 1, 1),
14690 Some(true),
14691 "relational remains single-token at its own precedence"
14692 );
14693 assert_eq!(
14694 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14695 None,
14696 "at shift precedence, bare `>` must not force enter"
14697 );
14698 }
14699
14700 #[test]
14701 fn left_recursive_loop_preserves_rule_wrapped_operator_continuation() {
14702 let atn = left_recursive_loop_with_rule_wrapped_gt_prefix_atn();
14703 let mut parser = mini_parser(vec![
14704 TestToken::new(1).with_text(">"),
14705 TestToken::new(2).with_text("id"),
14706 TestToken::eof("parser-test", 1, 1, 1),
14707 ]);
14708 parser.rule_context_stack = vec![RuleContextFrame {
14709 rule_index: 0,
14710 invoking_state: -1,
14711 }];
14712
14713 assert_eq!(
14714 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14715 Some(true),
14716 "the direct relational alternative remains a one-token operator"
14717 );
14718 assert_eq!(
14719 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14720 None,
14721 "a token matched in the helper rule must return to the second shift token"
14722 );
14723 }
14724
14725 #[test]
14726 fn left_recursive_loop_preserves_predicate_and_multi_token_reachability() {
14727 let atn = left_recursive_loop_with_predicate_and_multi_token_prefix_atn();
14728 let mut parser = mini_parser(vec![
14729 TestToken::new(1).with_text(">"),
14730 TestToken::new(2).with_text("id"),
14731 TestToken::eof("parser-test", 1, 1, 1),
14732 ]);
14733 parser.rule_context_stack = vec![RuleContextFrame {
14734 rule_index: 0,
14735 invoking_state: -1,
14736 }];
14737
14738 assert_eq!(
14739 parser.left_recursive_loop_enter_prediction(&atn, 1, 2),
14740 None,
14741 "a predicate-gated single-token path must not be hidden by a multi-token path"
14742 );
14743 }
14744
14745 #[test]
14746 fn left_recursive_loop_defers_predicate_guarded_operator() {
14747 let atn = left_recursive_loop_with_predicate_guarded_operator_atn();
14748 let mut parser = mini_parser_with_hooks(
14749 vec![
14750 TestToken::new(1).with_text("operator"),
14751 TestToken::eof("parser-test", 1, 1, 1),
14752 ],
14753 RejectingPredicateHooks::default(),
14754 );
14755 parser.rule_context_stack = vec![RuleContextFrame {
14756 rule_index: 0,
14757 invoking_state: -1,
14758 }];
14759
14760 assert_eq!(
14761 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14762 None,
14763 "a false predicate must be evaluated before entering the operator alternative"
14764 );
14765 assert_eq!(
14766 parser.left_recursive_loop_enter_prediction(&atn, 1, 0),
14767 None,
14768 "cached predicate-dependent lookahead must keep deferring"
14769 );
14770 }
14771
14772 #[test]
14773 fn left_recursive_loop_defers_through_nullable_caller_rule_call() {
14774 let atn = left_recursive_loop_with_nullable_follow_call_atn(1);
14775 let mut parser = parser_inside_left_recursive_callee(1);
14776
14777 assert_eq!(
14778 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
14779 None
14780 );
14781 assert_eq!(
14782 parser.left_recursive_loop_enter_prediction(&atn, 6, 0),
14783 None,
14784 "the cached overlap must preserve the nullable child return path"
14785 );
14786 }
14787
14788 #[test]
14789 fn left_recursive_loop_defers_through_nullable_parent_return() {
14790 let atn = left_recursive_loop_with_nullable_parent_return_atn(1);
14791 let mut parser = mini_parser(vec![
14792 TestToken::new(1).with_text("lookahead"),
14793 TestToken::eof("parser-test", 1, 1, 1),
14794 ]);
14795 parser.rule_context_stack = vec![
14796 RuleContextFrame {
14797 rule_index: 0,
14798 invoking_state: -1,
14799 },
14800 RuleContextFrame {
14801 rule_index: 1,
14802 invoking_state: 1,
14803 },
14804 RuleContextFrame {
14805 rule_index: 2,
14806 invoking_state: 5,
14807 },
14808 ];
14809
14810 assert_eq!(
14811 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
14812 None,
14813 "a nullable caller must unwind to its parent's consuming follow path"
14814 );
14815 assert_eq!(
14816 parser.left_recursive_loop_enter_prediction(&atn, 9, 0),
14817 None,
14818 "the caller-overlap cache must not retain a false negative"
14819 );
14820 }
14821
14822 #[test]
14823 fn left_recursive_loop_defers_after_recursive_operand_returns_to_loop() {
14824 let atn = left_recursive_loop_with_recursive_operand_return_atn(1);
14825 let mut parser = mini_parser(vec![
14826 TestToken::new(1).with_text("lookahead"),
14827 TestToken::eof("parser-test", 1, 1, 1),
14828 ]);
14829 parser.rule_context_stack = vec![
14830 RuleContextFrame {
14831 rule_index: 0,
14832 invoking_state: -1,
14833 },
14834 RuleContextFrame {
14835 rule_index: 1,
14836 invoking_state: 1,
14837 },
14838 RuleContextFrame {
14839 rule_index: 1,
14840 invoking_state: 8,
14841 },
14842 ];
14843
14844 assert_eq!(
14845 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
14846 None,
14847 "a recursive operand return must preserve its parent caller context"
14848 );
14849 assert_eq!(
14850 parser.left_recursive_loop_enter_prediction(&atn, 5, 0),
14851 None,
14852 "the caller-overlap cache must preserve the loop-boundary return"
14853 );
14854 }
14855
14856 fn token_then_eof_atn() -> Atn {
14857 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14858 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, ]))
14874 .deserialize_parser()
14875 .expect("artificial parser ATN should deserialize")
14876 }
14877
14878 fn epsilon_cycle_atn() -> Atn {
14879 let mut atn = ParserAtnBuilder::new(1);
14880 for (state_number, kind) in [
14881 (0, AtnStateKind::RuleStart),
14882 (1, AtnStateKind::Basic),
14883 (2, AtnStateKind::RuleStop),
14884 ] {
14885 assert_eq!(
14886 atn.add_state(kind, Some(0)).expect("state").index(),
14887 state_number
14888 );
14889 }
14890 atn.set_rule_to_start_state(vec![0])
14891 .expect("rule start states");
14892 atn.set_rule_to_stop_state(vec![2])
14893 .expect("rule stop states");
14894 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14895 .expect("transition");
14896 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 1 })
14897 .expect("self-cycle transition");
14898 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
14899 .expect("exit transition");
14900 finish_atn(atn)
14901 }
14902
14903 fn eof_then_action_atn() -> Atn {
14904 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14905 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, ]))
14921 .deserialize_parser()
14922 .expect("artificial parser ATN should deserialize")
14923 }
14924
14925 fn noop_action_then_token_then_eof_atn() -> Atn {
14926 AtnDeserializer::new(&SerializedAtn::from_i32(&[
14927 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, ]))
14945 .deserialize_parser()
14946 .expect("artificial no-op action ATN should deserialize")
14947 }
14948
14949 fn two_alt_decision_atn() -> Atn {
14950 let mut atn = ParserAtnBuilder::new(2);
14951 assert_eq!(
14952 atn.add_state(AtnStateKind::RuleStart, Some(0))
14953 .expect("state")
14954 .index(),
14955 0
14956 );
14957 assert_eq!(
14958 atn.add_state(AtnStateKind::BlockStart, Some(0))
14959 .expect("state")
14960 .index(),
14961 1
14962 );
14963 assert_eq!(
14964 atn.add_state(AtnStateKind::Basic, Some(0))
14965 .expect("state")
14966 .index(),
14967 2
14968 );
14969 assert_eq!(
14970 atn.add_state(AtnStateKind::Basic, Some(0))
14971 .expect("state")
14972 .index(),
14973 3
14974 );
14975 assert_eq!(
14976 atn.add_state(AtnStateKind::BlockEnd, Some(0))
14977 .expect("state")
14978 .index(),
14979 4
14980 );
14981 assert_eq!(
14982 atn.add_state(AtnStateKind::RuleStop, Some(0))
14983 .expect("state")
14984 .index(),
14985 5
14986 );
14987 atn.set_rule_to_start_state(vec![0])
14988 .expect("rule start states");
14989 atn.set_rule_to_stop_state(vec![5])
14990 .expect("rule stop states");
14991 atn.add_decision_state(1).expect("decision state");
14992 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
14993 .expect("transition");
14994 atn.add_transition(
14995 1,
14996 ParserTransitionSpec::Atom {
14997 target: 2,
14998 label: 1,
14999 },
15000 )
15001 .expect("transition");
15002 atn.add_transition(
15003 1,
15004 ParserTransitionSpec::Atom {
15005 target: 3,
15006 label: 2,
15007 },
15008 )
15009 .expect("transition");
15010 atn.add_transition(2, ParserTransitionSpec::Epsilon { target: 4 })
15011 .expect("transition");
15012 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
15013 .expect("transition");
15014 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15015 .expect("transition");
15016 finish_atn(atn)
15017 }
15018
15019 fn optional_then_b_eof_atn() -> Atn {
15022 let mut atn = ParserAtnBuilder::new(3);
15023 assert_eq!(
15024 atn.add_state(AtnStateKind::RuleStart, Some(0))
15025 .expect("state")
15026 .index(),
15027 0
15028 );
15029 assert_eq!(
15030 atn.add_state(AtnStateKind::BlockStart, Some(0))
15031 .expect("state")
15032 .index(),
15033 1
15034 );
15035 assert_eq!(
15036 atn.add_state(AtnStateKind::Basic, Some(0))
15037 .expect("state")
15038 .index(),
15039 2
15040 );
15041 assert_eq!(
15042 atn.add_state(AtnStateKind::Basic, Some(0))
15043 .expect("state")
15044 .index(),
15045 3
15046 );
15047 assert_eq!(
15048 atn.add_state(AtnStateKind::Basic, Some(0))
15049 .expect("state")
15050 .index(),
15051 4
15052 );
15053 assert_eq!(
15054 atn.add_state(AtnStateKind::RuleStop, Some(0))
15055 .expect("state")
15056 .index(),
15057 5
15058 );
15059 atn.set_rule_to_start_state(vec![0])
15060 .expect("rule start states");
15061 atn.set_rule_to_stop_state(vec![5])
15062 .expect("rule stop states");
15063 atn.add_decision_state(1).expect("decision state");
15064 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15065 .expect("transition");
15066 atn.add_transition(
15068 1,
15069 ParserTransitionSpec::Atom {
15070 target: 3,
15071 label: 1,
15072 },
15073 )
15074 .expect("transition");
15075 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
15076 .expect("transition");
15077 atn.add_transition(
15079 3,
15080 ParserTransitionSpec::Atom {
15081 target: 4,
15082 label: 2,
15083 },
15084 )
15085 .expect("transition");
15086 atn.add_transition(
15087 4,
15088 ParserTransitionSpec::Atom {
15089 target: 5,
15090 label: TOKEN_EOF,
15091 },
15092 )
15093 .expect("transition");
15094 finish_atn(atn)
15095 }
15096
15097 #[test]
15098 fn sync_decision_deletes_only_a_single_token() {
15099 let atn = optional_then_b_eof_atn();
15107
15108 let mut single = mini_parser(vec![
15109 TestToken::new(3).with_text("c"),
15110 TestToken::new(2).with_text("b"),
15111 TestToken::eof("parser-test", 1, 2, 2),
15112 ]);
15113 single.rule_context_stack = vec![RuleContextFrame {
15114 rule_index: 0,
15115 invoking_state: 0,
15116 }];
15117 let children = single
15118 .sync_decision(&atn, 1, true, false)
15119 .expect("single extraneous token recovers");
15120 assert_eq!(children.len(), 1);
15121 assert_eq!(single.node(children[0]).kind(), NodeKind::Error);
15122 assert_eq!(single.number_of_syntax_errors(), 1);
15123 assert_eq!(single.la(1), 2);
15125
15126 let mut double = mini_parser(vec![
15127 TestToken::new(3).with_text("c"),
15128 TestToken::new(3).with_text("c"),
15129 TestToken::new(2).with_text("b"),
15130 TestToken::eof("parser-test", 1, 3, 3),
15131 ]);
15132 double.rule_context_stack = vec![RuleContextFrame {
15133 rule_index: 0,
15134 invoking_state: 0,
15135 }];
15136 let result = double.sync_decision(&atn, 1, true, false);
15137 let error = result.expect_err("two extraneous tokens must not be deleted by sync");
15142 match error {
15143 AntlrError::ParserError { message, .. } => {
15144 assert!(message.starts_with("mismatched input"), "got: {message}");
15145 }
15146 other => panic!("expected a mismatched-input ParserError, got {other:?}"),
15147 }
15148 assert_eq!(double.la(1), 3);
15149 }
15150
15151 fn star_loop_then_eof_atn() -> Atn {
15155 AtnDeserializer::new(&SerializedAtn::from_i32(&[
15156 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,
15157 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,
15158 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,
15159 0, 0, 1, 9, 1, 1, 0, 0, 0, 1, 5,
15160 ]))
15161 .deserialize_parser()
15162 .expect("star-loop-then-EOF ATN should deserialize")
15163 }
15164
15165 fn plus_loop_with_recovering_body_atn() -> Atn {
15171 let mut atn = ParserAtnBuilder::new(2);
15172 assert_eq!(
15173 atn.add_state(AtnStateKind::RuleStart, Some(0))
15174 .expect("state")
15175 .index(),
15176 0
15177 );
15178 assert_eq!(
15179 atn.add_state(AtnStateKind::PlusBlockStart, Some(0))
15180 .expect("state")
15181 .index(),
15182 1
15183 );
15184 assert_eq!(
15185 atn.add_state(AtnStateKind::Basic, Some(0))
15186 .expect("state")
15187 .index(),
15188 2
15189 );
15190 assert_eq!(
15191 atn.add_state(AtnStateKind::BlockEnd, Some(0))
15192 .expect("state")
15193 .index(),
15194 3
15195 );
15196 assert_eq!(
15197 atn.add_state(AtnStateKind::PlusLoopBack, Some(0))
15198 .expect("state")
15199 .index(),
15200 4
15201 );
15202 assert_eq!(
15203 atn.add_state(AtnStateKind::LoopEnd, Some(0))
15204 .expect("state")
15205 .index(),
15206 5
15207 );
15208 assert_eq!(
15209 atn.add_state(AtnStateKind::RuleStop, Some(0))
15210 .expect("state")
15211 .index(),
15212 6
15213 );
15214 assert_eq!(
15215 atn.add_state(AtnStateKind::RuleStart, Some(1))
15216 .expect("state")
15217 .index(),
15218 7
15219 );
15220 assert_eq!(
15221 atn.add_state(AtnStateKind::Basic, Some(1))
15222 .expect("state")
15223 .index(),
15224 8
15225 );
15226 assert_eq!(
15227 atn.add_state(AtnStateKind::RuleStop, Some(1))
15228 .expect("state")
15229 .index(),
15230 9
15231 );
15232 atn.set_rule_to_start_state(vec![0, 7])
15233 .expect("rule start states");
15234 atn.set_rule_to_stop_state(vec![6, 9])
15235 .expect("rule stop states");
15236 atn.set_end_state(1, 3).expect("block end state");
15237 atn.set_loop_back_state(5, 4).expect("loop back state");
15238 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15239 .expect("transition");
15240 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15241 .expect("transition");
15242 atn.add_transition(
15243 2,
15244 ParserTransitionSpec::Rule {
15245 target: 7,
15246 rule_index: 1,
15247 follow_state: 3,
15248 precedence: 0,
15249 },
15250 )
15251 .expect("transition");
15252 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
15253 .expect("transition");
15254 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 1 })
15255 .expect("transition");
15256 atn.add_transition(4, ParserTransitionSpec::Epsilon { target: 5 })
15257 .expect("transition");
15258 atn.add_transition(
15259 5,
15260 ParserTransitionSpec::Atom {
15261 target: 6,
15262 label: 2,
15263 },
15264 )
15265 .expect("transition");
15266 atn.add_transition(
15267 7,
15268 ParserTransitionSpec::Atom {
15269 target: 8,
15270 label: 1,
15271 },
15272 )
15273 .expect("transition");
15274 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15275 .expect("transition");
15276 finish_atn(atn)
15277 }
15278
15279 #[test]
15280 fn runtime_options_default_exits_recovering_empty_plus_iteration() {
15281 let atn = plus_loop_with_recovering_body_atn();
15282 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15283
15284 let error = parser
15285 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
15286 .expect_err("EOF recovery should report a bounded mismatch");
15287
15288 let AntlrError::ParserError { message, .. } = error else {
15289 panic!("expected ParserError, got {error:?}");
15290 };
15291 insta::assert_snapshot!(message, @"mismatched input '<EOF>' expecting {'x', 2}");
15292 assert_eq!(parser.number_of_syntax_errors(), 1);
15293 assert_eq!(parser.input.index(), 0, "EOF remains unconsumed");
15294 }
15295
15296 #[test]
15297 fn sync_decision_deletes_token_before_eof_at_loop_back() {
15298 let atn = star_loop_then_eof_atn();
15304 let mut parser = mini_parser(vec![
15305 TestToken::new(2).with_text("c"),
15306 TestToken::eof("parser-test", 1, 1, 1),
15307 ]);
15308 parser.rule_context_stack = vec![RuleContextFrame {
15309 rule_index: 0,
15310 invoking_state: 0,
15311 }];
15312 let children = parser
15313 .sync_decision(&atn, 5, true, false)
15314 .expect("single token before EOF recovers");
15315 assert_eq!(children.len(), 1);
15316 assert_eq!(parser.node(children[0]).kind(), NodeKind::Error);
15317 assert_eq!(parser.number_of_syntax_errors(), 1);
15318 assert_eq!(
15319 parser.la(1),
15320 TOKEN_EOF,
15321 "EOF is left for the rule's EOF match"
15322 );
15323 }
15324
15325 #[test]
15326 fn sync_decision_does_not_delete_two_tokens_before_eof_at_loop_entry() {
15327 let atn = star_loop_then_eof_atn();
15332 let mut parser = mini_parser(vec![
15333 TestToken::new(2).with_text("c"),
15334 TestToken::new(2).with_text("c"),
15335 TestToken::eof("parser-test", 1, 2, 2),
15336 ]);
15337 parser.rule_context_stack = vec![RuleContextFrame {
15338 rule_index: 0,
15339 invoking_state: 0,
15340 }];
15341 let error = parser
15342 .sync_decision(&atn, 5, true, false)
15343 .expect_err("two tokens at the loop entry must not be deleted");
15344 match error {
15345 AntlrError::ParserError { message, .. } => {
15346 assert!(message.starts_with("mismatched input"), "got: {message}");
15347 }
15348 other => panic!("expected mismatched-input ParserError, got {other:?}"),
15349 }
15350 assert_eq!(
15351 parser.la(1),
15352 2,
15353 "nothing consumed; cursor still on first `c`"
15354 );
15355 }
15356
15357 #[test]
15358 fn sync_decision_consumes_until_eof_at_loop_back() {
15359 let atn = star_loop_then_eof_atn();
15365 let mut parser = mini_parser(vec![
15366 TestToken::new(2).with_text("c"),
15367 TestToken::new(2).with_text("c"),
15368 TestToken::eof("parser-test", 1, 2, 2),
15369 ]);
15370 parser.rule_context_stack = vec![RuleContextFrame {
15371 rule_index: 0,
15372 invoking_state: 0,
15373 }];
15374 let children = parser
15375 .sync_decision(&atn, 5, false, true)
15376 .expect("loop-back multi-token deletion recovers onto EOF");
15377 assert_eq!(children.len(), 2, "both `c`s deleted as error nodes");
15378 assert!(
15379 children
15380 .iter()
15381 .all(|child| parser.node(*child).kind() == NodeKind::Error)
15382 );
15383 assert_eq!(parser.number_of_syntax_errors(), 1);
15384 assert_eq!(parser.la(1), TOKEN_EOF, "EOF left for the rule's EOF match");
15385 }
15386
15387 fn predicate_after_token_atn() -> Atn {
15388 let mut atn = ParserAtnBuilder::new(2);
15389 assert_eq!(
15390 atn.add_state(AtnStateKind::RuleStart, Some(0))
15391 .expect("state")
15392 .index(),
15393 0
15394 );
15395 assert_eq!(
15396 atn.add_state(AtnStateKind::Basic, Some(0))
15397 .expect("state")
15398 .index(),
15399 1
15400 );
15401 assert_eq!(
15402 atn.add_state(AtnStateKind::Basic, Some(0))
15403 .expect("state")
15404 .index(),
15405 2
15406 );
15407 assert_eq!(
15408 atn.add_state(AtnStateKind::Basic, Some(0))
15409 .expect("state")
15410 .index(),
15411 3
15412 );
15413 assert_eq!(
15414 atn.add_state(AtnStateKind::RuleStop, Some(0))
15415 .expect("state")
15416 .index(),
15417 4
15418 );
15419 atn.set_rule_to_start_state(vec![0])
15420 .expect("rule start states");
15421 atn.set_rule_to_stop_state(vec![4])
15422 .expect("rule stop states");
15423 atn.add_transition(
15424 0,
15425 ParserTransitionSpec::Atom {
15426 target: 1,
15427 label: 1,
15428 },
15429 )
15430 .expect("transition");
15431 atn.add_transition(
15432 1,
15433 ParserTransitionSpec::Predicate {
15434 target: 2,
15435 rule_index: 0,
15436 pred_index: 0,
15437 context_dependent: false,
15438 },
15439 )
15440 .expect("transition");
15441 atn.add_transition(
15442 2,
15443 ParserTransitionSpec::Atom {
15444 target: 3,
15445 label: 2,
15446 },
15447 )
15448 .expect("transition");
15449 atn.add_transition(3, ParserTransitionSpec::Epsilon { target: 4 })
15450 .expect("transition");
15451 finish_atn(atn)
15452 }
15453
15454 fn predicate_gated_same_lookahead_atn(pred_indexes: [usize; 2]) -> Atn {
15455 let mut atn = ParserAtnBuilder::new(1);
15456 for (state_number, kind) in [
15457 (0, AtnStateKind::RuleStart),
15458 (1, AtnStateKind::BlockStart),
15459 (2, AtnStateKind::Basic),
15460 (3, AtnStateKind::Basic),
15461 (4, AtnStateKind::Basic),
15462 (5, AtnStateKind::Basic),
15463 (6, AtnStateKind::BlockEnd),
15464 (7, AtnStateKind::RuleStop),
15465 ] {
15466 assert_eq!(
15467 atn.add_state(kind, Some(0)).expect("state").index(),
15468 state_number
15469 );
15470 }
15471 atn.set_rule_to_start_state(vec![0])
15472 .expect("rule start states");
15473 atn.set_rule_to_stop_state(vec![7])
15474 .expect("rule stop states");
15475 atn.add_decision_state(1).expect("decision state");
15476 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
15477 .expect("transition");
15478 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 2 })
15479 .expect("transition");
15480 atn.add_transition(1, ParserTransitionSpec::Epsilon { target: 3 })
15481 .expect("transition");
15482 atn.add_transition(
15483 2,
15484 ParserTransitionSpec::Predicate {
15485 target: 4,
15486 rule_index: 0,
15487 pred_index: pred_indexes[0],
15488 context_dependent: false,
15489 },
15490 )
15491 .expect("transition");
15492 atn.add_transition(
15493 3,
15494 ParserTransitionSpec::Predicate {
15495 target: 5,
15496 rule_index: 0,
15497 pred_index: pred_indexes[1],
15498 context_dependent: false,
15499 },
15500 )
15501 .expect("transition");
15502 atn.add_transition(
15503 4,
15504 ParserTransitionSpec::Atom {
15505 target: 6,
15506 label: 1,
15507 },
15508 )
15509 .expect("transition");
15510 atn.add_transition(
15511 5,
15512 ParserTransitionSpec::Atom {
15513 target: 6,
15514 label: 1,
15515 },
15516 )
15517 .expect("transition");
15518 atn.add_transition(
15519 6,
15520 ParserTransitionSpec::Atom {
15521 target: 7,
15522 label: TOKEN_EOF,
15523 },
15524 )
15525 .expect("transition");
15526 finish_atn(atn)
15527 }
15528
15529 fn nested_nullable_context_atn() -> Atn {
15530 let mut atn = ParserAtnBuilder::new(1);
15531 for state_number in 0..=20 {
15532 let kind = match state_number {
15533 0 | 10 | 16 => AtnStateKind::RuleStart,
15534 9 | 15 | 20 => AtnStateKind::RuleStop,
15535 _ => AtnStateKind::Basic,
15536 };
15537 let rule_index = match state_number {
15538 0..=9 => 0,
15539 10..=15 => 1,
15540 _ => 2,
15541 };
15542 assert_eq!(
15543 atn.add_state(kind, Some(rule_index))
15544 .expect("state")
15545 .index(),
15546 state_number
15547 );
15548 }
15549 atn.set_rule_to_start_state(vec![0, 10, 16])
15550 .expect("rule start states");
15551 atn.set_rule_to_stop_state(vec![9, 15, 20])
15552 .expect("rule stop states");
15553 atn.add_transition(
15554 1,
15555 ParserTransitionSpec::Rule {
15556 target: 10,
15557 rule_index: 1,
15558 follow_state: 8,
15559 precedence: 0,
15560 },
15561 )
15562 .expect("transition");
15563 atn.add_transition(
15564 8,
15565 ParserTransitionSpec::Atom {
15566 target: 9,
15567 label: 1,
15568 },
15569 )
15570 .expect("transition");
15571 atn.add_transition(8, ParserTransitionSpec::Epsilon { target: 9 })
15572 .expect("transition");
15573 atn.add_transition(
15574 2,
15575 ParserTransitionSpec::Rule {
15576 target: 16,
15577 rule_index: 2,
15578 follow_state: 14,
15579 precedence: 0,
15580 },
15581 )
15582 .expect("transition");
15583 atn.add_transition(14, ParserTransitionSpec::Epsilon { target: 15 })
15584 .expect("transition");
15585 finish_atn(atn)
15586 }
15587
15588 fn generated_match_recovery_atn() -> Atn {
15589 let mut atn = ParserAtnBuilder::new(2);
15590 assert_eq!(
15591 atn.add_state(AtnStateKind::RuleStart, Some(0))
15592 .expect("state")
15593 .index(),
15594 0
15595 );
15596 assert_eq!(
15597 atn.add_state(AtnStateKind::Basic, Some(0))
15598 .expect("state")
15599 .index(),
15600 1
15601 );
15602 assert_eq!(
15603 atn.add_state(AtnStateKind::Basic, Some(0))
15604 .expect("state")
15605 .index(),
15606 2
15607 );
15608 assert_eq!(
15609 atn.add_state(AtnStateKind::RuleStop, Some(0))
15610 .expect("state")
15611 .index(),
15612 3
15613 );
15614 assert_eq!(
15615 atn.add_state(AtnStateKind::RuleStart, Some(1))
15616 .expect("state")
15617 .index(),
15618 4
15619 );
15620 assert_eq!(
15621 atn.add_state(AtnStateKind::RuleStop, Some(1))
15622 .expect("state")
15623 .index(),
15624 5
15625 );
15626 atn.set_rule_to_start_state(vec![0, 4])
15627 .expect("rule start states");
15628 atn.set_rule_to_stop_state(vec![3, 5])
15629 .expect("rule stop states");
15630 atn.add_transition(
15631 1,
15632 ParserTransitionSpec::Rule {
15633 target: 4,
15634 rule_index: 1,
15635 follow_state: 2,
15636 precedence: 0,
15637 },
15638 )
15639 .expect("transition");
15640 atn.add_transition(
15641 2,
15642 ParserTransitionSpec::Atom {
15643 target: 3,
15644 label: TOKEN_EOF,
15645 },
15646 )
15647 .expect("transition");
15648 finish_atn(atn)
15649 }
15650
15651 fn complement_set_atn() -> Atn {
15652 let mut atn = ParserAtnBuilder::new(1);
15653 assert_eq!(
15654 atn.add_state(AtnStateKind::RuleStart, Some(0))
15655 .expect("state")
15656 .index(),
15657 0
15658 );
15659 assert_eq!(
15660 atn.add_state(AtnStateKind::RuleStop, Some(0))
15661 .expect("state")
15662 .index(),
15663 1
15664 );
15665 atn.set_rule_to_start_state(vec![0])
15666 .expect("rule start states");
15667 atn.set_rule_to_stop_state(vec![1])
15668 .expect("rule stop states");
15669 let excluded = atn.add_interval_set([(1, 1)]).expect("excluded set");
15670 atn.add_transition(
15671 0,
15672 ParserTransitionSpec::NotSet {
15673 target: 1,
15674 set: excluded,
15675 },
15676 )
15677 .expect("transition");
15678 finish_atn(atn)
15679 }
15680
15681 fn wildcard_then_eof_atn() -> Atn {
15684 let mut atn = ParserAtnBuilder::new(1);
15685 assert_eq!(
15686 atn.add_state(AtnStateKind::RuleStart, Some(0))
15687 .expect("state")
15688 .index(),
15689 0
15690 );
15691 assert_eq!(
15692 atn.add_state(AtnStateKind::RuleStop, Some(0))
15693 .expect("state")
15694 .index(),
15695 1
15696 );
15697 assert_eq!(
15698 atn.add_state(AtnStateKind::Basic, Some(0))
15699 .expect("state")
15700 .index(),
15701 2
15702 );
15703 atn.set_rule_to_start_state(vec![0])
15704 .expect("rule start states");
15705 atn.set_rule_to_stop_state(vec![1])
15706 .expect("rule stop states");
15707 atn.add_transition(0, ParserTransitionSpec::Wildcard { target: 2 })
15708 .expect("transition");
15709 atn.add_transition(
15710 2,
15711 ParserTransitionSpec::Atom {
15712 target: 1,
15713 label: TOKEN_EOF,
15714 },
15715 )
15716 .expect("transition");
15717 finish_atn(atn)
15718 }
15719
15720 #[test]
15721 fn parser_matches_token_and_reports_mismatch() {
15722 let source = Source {
15723 tokens: vec![
15724 TestToken::new(1).with_text("x"),
15725 TestToken::eof("parser-test", 1, 1, 1),
15726 ],
15727 index: 0,
15728 };
15729 let data = RecognizerData::new(
15730 "Mini.g4",
15731 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
15732 );
15733 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
15734 let matched = parser.match_token(1).expect("token 1 should match");
15735 assert_eq!(parser.node(matched).text(), "x");
15736 assert!(parser.match_token(1).is_err());
15737 }
15738
15739 #[test]
15740 fn parser_matches_token_sets() {
15741 let mut parser = mini_parser(vec![
15742 TestToken::new(1).with_text("x"),
15743 TestToken::eof("parser-test", 1, 1, 1),
15744 ]);
15745
15746 let matched = parser
15747 .match_set(&[(1, 1), (3, 4)])
15748 .expect("token set should match");
15749 assert_eq!(parser.node(matched).text(), "x");
15750 assert!(parser.match_not_set(&[(1, 1)], 1, 4).is_err());
15751 }
15752
15753 #[test]
15754 fn generated_rule_api_tracks_state_and_precedence() {
15755 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15756
15757 let context = parser.enter_rule(7, 2);
15758 assert_eq!(context.rule_index(), 2);
15759 assert_eq!(parser.state(), 7);
15760 assert_eq!(
15761 parser.rule_context_stack,
15762 vec![RuleContextFrame {
15763 rule_index: 2,
15764 invoking_state: 7
15765 }]
15766 );
15767
15768 let recursive = parser.enter_recursion_rule(11, 3, 4);
15769 assert_eq!(recursive.rule_index(), 3);
15770 assert!(parser.precpred(4));
15771 assert!(parser.precpred(5));
15772 assert!(!parser.precpred(3));
15773
15774 let next = parser.push_new_recursion_context(13, 3);
15775 assert_eq!(next.invoking_state(), 13);
15776 parser.unroll_recursion_context();
15777 assert_eq!(parser.precedence_stack, vec![0]);
15778 assert_eq!(
15779 parser.rule_context_stack,
15780 vec![RuleContextFrame {
15781 rule_index: 2,
15782 invoking_state: 7
15783 }]
15784 );
15785
15786 parser.exit_rule();
15787 assert!(parser.rule_context_stack.is_empty());
15788 }
15789
15790 #[test]
15791 fn reset_rewinds_input_and_clears_parser_owned_parse_state() {
15792 let mut parser = mini_parser(vec![
15793 TestToken::new(1).with_text("x"),
15794 TestToken::eof("parser-test", 1, 1, 1),
15795 ]);
15796 let matched = parser.match_token(1).expect("token should match");
15797 assert_eq!(parser.node(matched).text(), "x");
15798 parser.record_generated_syntax_error();
15799 parser.set_int_member(7, 11);
15800 parser.set_build_parse_trees(false);
15801 parser.set_report_diagnostic_errors(true);
15802 parser.set_prediction_mode(PredictionMode::Sll);
15803 parser.set_bail_on_error(true);
15804 let _context = parser.enter_recursion_rule(9, 0, 4);
15805 parser.pending_invoking_states.push(5);
15806 parser.unknown_predicate_hits.push((0, 1));
15807 parser.unhandled_action_hits.push((0, 2));
15808
15809 parser.reset();
15810
15811 assert_eq!(parser.input.index(), 0);
15812 assert_eq!(parser.la(1), 1);
15813 assert_eq!(parser.state(), -1);
15814 assert_eq!(parser.number_of_syntax_errors(), 0);
15815 assert_eq!(parser.parse_tree_storage().node_count(), 0);
15816 assert!(parser.rule_context_stack.is_empty());
15817 assert!(parser.pending_invoking_states.is_empty());
15818 assert_eq!(parser.precedence_stack, [0]);
15819 assert!(parser.unknown_predicate_hits.is_empty());
15820 assert!(parser.unhandled_action_hits.is_empty());
15821 assert_eq!(parser.int_member(7), Some(11));
15822 assert!(!parser.build_parse_trees());
15823 assert!(parser.report_diagnostic_errors());
15824 assert_eq!(parser.prediction_mode(), PredictionMode::Sll);
15825 assert!(parser.bail_on_error());
15826 }
15827
15828 #[test]
15829 fn set_token_stream_replaces_input_and_resets_parser() {
15830 let mut parser = mini_parser(vec![
15831 TestToken::new(1).with_text("old"),
15832 TestToken::eof("parser-test", 1, 1, 1),
15833 ]);
15834 parser.consume();
15835 parser.record_generated_syntax_error();
15836 let replacement = CommonTokenStream::new(Source {
15837 tokens: vec![
15838 TestToken::new(2).with_text("new"),
15839 TestToken::eof("parser-test", 1, 1, 1),
15840 ],
15841 index: 0,
15842 });
15843
15844 parser.set_token_stream(replacement);
15845
15846 assert_eq!(parser.input.index(), 0);
15847 assert_eq!(parser.la(1), 2);
15848 assert_eq!(parser.input.text_all(), "new");
15849 assert_eq!(parser.number_of_syntax_errors(), 0);
15850 }
15851
15852 #[test]
15853 fn active_invocation_states_exclude_the_root_frame() {
15854 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15855
15856 let _root = parser.enter_rule(0, 0);
15857 assert!(parser.active_invocation_states().is_empty());
15858
15859 let marker = parser.push_invoking_state(6);
15860 let _child = parser.enter_rule(2, 1);
15861 parser.discard_invoking_state(marker);
15862 assert_eq!(parser.active_invocation_states(), [6]);
15863
15864 let marker = parser.push_invoking_state(13);
15865 let _grandchild = parser.enter_rule(4, 2);
15866 parser.discard_invoking_state(marker);
15867 assert_eq!(parser.active_invocation_states(), [13, 6]);
15868
15869 parser.exit_rule();
15870 parser.exit_rule();
15871 parser.exit_rule();
15872 }
15873
15874 #[test]
15875 fn parser_predicates_support_token_adjacency() {
15876 let mut parser = mini_parser(vec![
15877 TestToken::new(1).with_text("=").with_span(0, 0),
15878 TestToken::new(1).with_text(">").with_span(1, 1),
15879 TestToken::eof("parser-test", 2, 1, 2),
15880 ]);
15881 parser.consume();
15882 parser.consume();
15883
15884 let predicates = [(0, 0, ParserPredicate::TokenPairAdjacent)];
15885
15886 assert!(parser.parser_semantic_predicate_matches(&predicates, 0, 0));
15887
15888 let mut parser = mini_parser(vec![
15889 TestToken::new(1).with_text("=").with_span(0, 0),
15890 TestToken::new(1)
15891 .with_text(" ")
15892 .with_channel(HIDDEN_CHANNEL)
15893 .with_span(1, 1),
15894 TestToken::new(1).with_text(">").with_span(2, 2),
15895 TestToken::eof("parser-test", 3, 1, 3),
15896 ]);
15897 parser.consume();
15898 parser.consume();
15899
15900 assert!(!parser.parser_semantic_predicate_matches(&predicates, 0, 0));
15901 }
15902
15903 #[test]
15904 fn parser_predicates_support_context_child_text_checks() {
15905 let mut parser = mini_parser(vec![
15906 TestToken::new(1).with_text("var"),
15907 TestToken::eof("parser-test", 1, 1, 1),
15908 ]);
15909 let mut context = ParserRuleContext::new(1, 0);
15910 let mut child_context = ParserRuleContext::new(2, 0);
15911 let terminal = parser.terminal_tree(TokenId::try_from(0).expect("test token ID"));
15912 parser.tree.add_child(&mut child_context, terminal);
15913 let child = parser.rule_node(child_context);
15914 parser.tree.add_child(&mut context, child);
15915 let predicates = [(
15916 1,
15917 0,
15918 ParserPredicate::ContextChildRuleTextNotEquals {
15919 rule_index: 2,
15920 text: "var",
15921 },
15922 )];
15923
15924 assert!(
15925 !parser.parser_semantic_predicate_matches_with_context_and_local(
15926 &predicates,
15927 1,
15928 0,
15929 &context,
15930 0,
15931 )
15932 );
15933 }
15934
15935 #[test]
15936 fn context_expected_symbols_walks_nullable_parent_contexts() {
15937 let atn = nested_nullable_context_atn();
15938 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15939 parser.rule_context_stack = vec![
15940 RuleContextFrame {
15941 rule_index: 0,
15942 invoking_state: 0,
15943 },
15944 RuleContextFrame {
15945 rule_index: 1,
15946 invoking_state: 1,
15947 },
15948 RuleContextFrame {
15949 rule_index: 2,
15950 invoking_state: 2,
15951 },
15952 ];
15953
15954 let expected = parser.context_expected_symbols(&atn);
15955
15956 assert!(expected.contains(&1));
15957 assert!(expected.contains(&TOKEN_EOF));
15958 }
15959
15960 #[test]
15961 fn prediction_context_return_states_track_rule_stack_changes() {
15962 let atn = nested_nullable_context_atn();
15963 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
15964 parser.rule_context_stack = vec![
15965 RuleContextFrame {
15966 rule_index: 0,
15967 invoking_state: 0,
15968 },
15969 RuleContextFrame {
15970 rule_index: 1,
15971 invoking_state: 1,
15972 },
15973 RuleContextFrame {
15974 rule_index: 2,
15975 invoking_state: 2,
15976 },
15977 ];
15978
15979 let initial_version = parser.rule_context_version();
15980 let first: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15981 let second: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15982 assert_eq!(first, second);
15983 assert_eq!(parser.rule_context_version(), initial_version);
15984
15985 parser.exit_rule();
15986 let after_pop: Vec<_> = parser.prediction_context_return_states(&atn).collect();
15987 assert_ne!(first, after_pop);
15988 assert_ne!(parser.rule_context_version(), initial_version);
15989 }
15990
15991 #[test]
15992 fn generated_match_token_recovers_missing_token_from_context_follow() {
15993 let atn = generated_match_recovery_atn();
15994 let data = RecognizerData::new(
15995 "Mini.g4",
15996 Vocabulary::new(
15997 [None, Some("'X'"), Some("'Y'")],
15998 [None, Some("X"), Some("Y")],
15999 [None::<&str>, None, None],
16000 ),
16001 );
16002 let mut parser = BaseParser::new(
16003 CommonTokenStream::new(Source {
16004 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
16005 index: 0,
16006 }),
16007 data,
16008 );
16009 parser.rule_context_stack = vec![
16010 RuleContextFrame {
16011 rule_index: 0,
16012 invoking_state: 0,
16013 },
16014 RuleContextFrame {
16015 rule_index: 1,
16016 invoking_state: 1,
16017 },
16018 ];
16019 assert_eq!(parser.number_of_syntax_errors(), 0);
16020
16021 let node = parser
16022 .match_token_recovering(2, 5, &atn)
16023 .expect("generated match should insert missing token");
16024
16025 assert_eq!(node.children().len(), 1);
16026 assert_eq!(parser.node(node.children()[0]).text(), "<missing 'Y'>");
16027 assert_eq!(
16028 node.clone()
16029 .into_child_iter()
16030 .map(|child| parser.node(child).text())
16031 .collect::<Vec<_>>(),
16032 ["<missing 'Y'>"]
16033 );
16034 assert!(!node.consumed_eof());
16037 assert_eq!(parser.la(1), TOKEN_EOF);
16038 assert_eq!(parser.number_of_syntax_errors(), 1);
16039 assert_eq!(
16040 parser.generated_parser_diagnostics,
16041 [ParserDiagnostic {
16042 line: 1,
16043 column: 3,
16044 message: "missing 'Y' at '<EOF>'".to_owned(),
16045 offending: parser.input.lt_id(1),
16046 }]
16047 );
16048 }
16049
16050 #[test]
16051 fn generated_match_token_counts_single_token_deletion_recovery() {
16052 let atn = generated_match_recovery_atn();
16053 let data = RecognizerData::new(
16054 "Mini.g4",
16055 Vocabulary::new(
16056 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
16057 [None, Some("X"), Some("Y"), Some("Z")],
16058 [None::<&str>, None, None, None],
16059 ),
16060 );
16061 let mut parser = BaseParser::new(
16062 CommonTokenStream::new(Source {
16063 tokens: vec![
16064 TestToken::new(3).with_text("z"),
16065 TestToken::new(2).with_text("y"),
16066 TestToken::eof("parser-test", 3, 1, 3),
16067 ],
16068 index: 0,
16069 }),
16070 data,
16071 );
16072
16073 let node = parser
16074 .match_token_recovering(2, 5, &atn)
16075 .expect("generated match should delete the extraneous token");
16076
16077 assert_eq!(node.children().len(), 2);
16078 assert_eq!(parser.node(node.children()[0]).kind(), NodeKind::Error);
16079 assert_eq!(parser.node(node.children()[0]).text(), "z");
16080 assert_eq!(parser.node(node.children()[1]).text(), "y");
16081 assert_eq!(
16082 node.into_child_iter()
16083 .map(|child| parser.node(child).text())
16084 .collect::<Vec<_>>(),
16085 ["z", "y"]
16086 );
16087 assert_eq!(parser.number_of_syntax_errors(), 1);
16088 }
16089
16090 #[test]
16091 fn generated_match_token_iterates_single_success_without_a_children_vec() {
16092 let atn = generated_match_recovery_atn();
16093 let data = RecognizerData::new(
16094 "Mini.g4",
16095 Vocabulary::new(
16096 [None, Some("'X'"), Some("'Y'")],
16097 [None, Some("X"), Some("Y")],
16098 [None::<&str>, None, None],
16099 ),
16100 );
16101 let mut parser = BaseParser::new(
16102 CommonTokenStream::new(Source {
16103 tokens: vec![
16104 TestToken::new(2).with_text("y"),
16105 TestToken::eof("parser-test", 1, 1, 1),
16106 ],
16107 index: 0,
16108 }),
16109 data,
16110 );
16111
16112 let node = parser
16113 .match_token_recovering(2, 5, &atn)
16114 .expect("generated match should consume the expected token");
16115
16116 assert_eq!(
16117 node.into_child_iter()
16118 .map(|child| parser.node(child).text())
16119 .collect::<Vec<_>>(),
16120 ["y"]
16121 );
16122 assert_eq!(parser.number_of_syntax_errors(), 0);
16123 }
16124
16125 #[test]
16126 fn generated_diagnostic_restore_rolls_back_syntax_error_count() {
16127 let atn = generated_match_recovery_atn();
16128 let data = RecognizerData::new(
16129 "Mini.g4",
16130 Vocabulary::new(
16131 [None, Some("'X'"), Some("'Y'")],
16132 [None, Some("X"), Some("Y")],
16133 [None::<&str>, None, None],
16134 ),
16135 );
16136 let mut parser = BaseParser::new(
16137 CommonTokenStream::new(Source {
16138 tokens: vec![TestToken::eof("parser-test", 3, 1, 3)],
16139 index: 0,
16140 }),
16141 data,
16142 );
16143 parser.rule_context_stack = vec![
16144 RuleContextFrame {
16145 rule_index: 0,
16146 invoking_state: 0,
16147 },
16148 RuleContextFrame {
16149 rule_index: 1,
16150 invoking_state: 1,
16151 },
16152 ];
16153 let marker = parser.generated_diagnostics_checkpoint();
16154
16155 let _ = parser
16156 .match_token_recovering(2, 5, &atn)
16157 .expect("generated match should insert missing token");
16158 assert_eq!(parser.number_of_syntax_errors(), 1);
16159
16160 parser.restore_generated_diagnostics(marker);
16161
16162 assert_eq!(parser.number_of_syntax_errors(), 0);
16163 assert!(parser.generated_parser_diagnostics.is_empty());
16164 }
16165
16166 #[test]
16167 fn generated_prediction_diagnostics_use_adaptive_context() {
16168 let atn = two_alt_decision_atn();
16169 let data = RecognizerData::new(
16170 "Mini.g4",
16171 Vocabulary::new(
16172 [None, Some("'x'"), Some("'y'")],
16173 [None, Some("X"), Some("Y")],
16174 [None::<&str>, None, None],
16175 ),
16176 )
16177 .with_rule_names(["s"]);
16178 let mut parser = BaseParser::new(
16179 CommonTokenStream::new(Source {
16180 tokens: vec![
16181 TestToken::new(1)
16182 .with_text("x")
16183 .with_position(1, 0)
16184 .with_span(0, 0),
16185 TestToken::new(2)
16186 .with_text("y")
16187 .with_position(1, 2)
16188 .with_span(1, 1),
16189 TestToken::eof("parser-test", 2, 1, 3),
16190 ],
16191 index: 0,
16192 }),
16193 data,
16194 );
16195 parser.set_report_diagnostic_errors(true);
16196
16197 parser.record_generated_prediction_diagnostic(
16198 &atn,
16199 1,
16200 &ParserAtnPrediction {
16201 alt: 1,
16202 requires_full_context: true,
16203 has_semantic_context: false,
16204 diagnostic: Some(ParserAtnPredictionDiagnostic {
16205 kind: ParserAtnPredictionDiagnosticKind::ContextSensitivity,
16206 start_index: 0,
16207 sll_stop_index: 1,
16208 ll_stop_index: 0,
16209 conflicting_alts: vec![1, 2],
16210 exact: false,
16211 }),
16212 },
16213 );
16214 parser.record_generated_prediction_diagnostic(
16219 &atn,
16220 1,
16221 &ParserAtnPrediction {
16222 alt: 1,
16223 requires_full_context: true,
16224 has_semantic_context: false,
16225 diagnostic: Some(ParserAtnPredictionDiagnostic {
16226 kind: ParserAtnPredictionDiagnosticKind::Ambiguity,
16227 start_index: 0,
16228 sll_stop_index: 1,
16229 ll_stop_index: 1,
16230 conflicting_alts: vec![1, 2],
16231 exact: false,
16232 }),
16233 },
16234 );
16235
16236 insta::assert_debug_snapshot!(
16239 "generated_prediction_diagnostics_use_adaptive_context",
16240 parser.generated_parser_diagnostics
16241 );
16242 }
16243
16244 #[test]
16245 fn generated_match_not_set_recovers_empty_complement_at_eof() {
16246 let atn = complement_set_atn();
16247 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16248 parser.rule_context_stack = vec![RuleContextFrame {
16249 rule_index: 0,
16250 invoking_state: 0,
16251 }];
16252
16253 let node = parser
16254 .match_not_token_set_recovering(
16255 atn.token_set(0).expect("excluded token set"),
16256 1,
16257 1,
16258 1,
16259 &atn,
16260 )
16261 .expect("empty complement should recover at EOF");
16262
16263 assert_eq!(node.children().len(), 1);
16264 assert!(!node.consumed_eof());
16267 assert_eq!(parser.la(1), TOKEN_EOF);
16268 assert_eq!(
16269 parser.generated_parser_diagnostics,
16270 [ParserDiagnostic {
16271 line: 1,
16272 column: 1,
16273 message: "missing {} at '<EOF>'".to_owned(),
16274 offending: parser.input.lt_id(1),
16275 }]
16276 );
16277 }
16278
16279 #[test]
16280 fn wildcard_recovers_via_insertion_when_follow_expects_eof_at_eof() {
16281 let atn = wildcard_then_eof_atn();
16287 let data = RecognizerData::new(
16288 "Mini.g4",
16289 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
16290 );
16291 let mut parser = BaseParser::new(
16292 CommonTokenStream::new(Source {
16293 tokens: vec![TestToken::eof("parser-test", 1, 1, 1)],
16294 index: 0,
16295 }),
16296 data,
16297 );
16298 parser.rule_context_stack = vec![RuleContextFrame {
16299 rule_index: 0,
16300 invoking_state: 0,
16301 }];
16302
16303 let node = parser
16304 .match_not_set_recovering(&[], 1, atn.max_token_type(), 2, &atn)
16305 .expect("wildcard at EOF should recover by insertion when follow expects EOF");
16306
16307 assert_eq!(node.children().len(), 1);
16309 assert!(!node.consumed_eof());
16310 assert!(
16311 parser
16312 .node(node.children()[0])
16313 .text()
16314 .starts_with("<missing")
16315 );
16316 assert_eq!(parser.la(1), TOKEN_EOF);
16317 assert_eq!(
16318 parser.generated_parser_diagnostics,
16319 [ParserDiagnostic {
16320 line: 1,
16321 column: 1,
16322 message: "missing 'x' at '<EOF>'".to_owned(),
16323 offending: parser.input.lt_id(1),
16324 }]
16325 );
16326 }
16327
16328 #[test]
16329 fn generated_rule_recovery_consumes_to_parent_follow() {
16330 let atn = generated_match_recovery_atn();
16331 let data = RecognizerData::new(
16332 "Mini.g4",
16333 Vocabulary::new(
16334 [None, Some("'X'"), Some("'Y'"), Some("'Z'")],
16335 [None, Some("X"), Some("Y"), Some("Z")],
16336 [None::<&str>, None, None, None],
16337 ),
16338 );
16339 let mut parser = BaseParser::new(
16340 CommonTokenStream::new(Source {
16341 tokens: vec![
16342 TestToken::new(3).with_text("z"),
16343 TestToken::eof("parser-test", 1, 1, 1),
16344 ],
16345 index: 0,
16346 }),
16347 data,
16348 );
16349 let _parent = parser.enter_rule(0, 0);
16350 let marker = parser.push_invoking_state(1);
16351 let mut child = parser.enter_rule(4, 1);
16352 parser.discard_invoking_state(marker);
16353
16354 let offending = parser.input.lt_id(1);
16357 assert!(offending.is_some(), "the 'z' token should be buffered");
16358 parser.recover_generated_rule(
16359 &mut child,
16360 &atn,
16361 AntlrError::ParserError {
16362 line: 1,
16363 column: 0,
16364 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
16365 offending,
16366 },
16367 );
16368 let tree = parser.finish_rule(child, false);
16369
16370 assert_eq!(parser.la(1), TOKEN_EOF);
16371 assert_eq!(
16372 parser.node(tree).to_string_tree_with_names(&["s", "a"]),
16373 "(a z)"
16374 );
16375 assert_eq!(parser.number_of_syntax_errors(), 1);
16376 assert_eq!(
16377 parser.generated_parser_diagnostics,
16378 [ParserDiagnostic {
16379 line: 1,
16380 column: 0,
16381 message: "mismatched input 'z' expecting {'X', 'Y'}".to_owned(),
16382 offending,
16383 }]
16384 );
16385 parser.exit_rule();
16386 }
16387
16388 #[test]
16389 fn generated_rule_recovery_forces_progress_after_repeated_error_state() {
16390 let atn = nested_nullable_context_atn();
16391 let mut parser = mini_parser(vec![
16392 TestToken::new(1).with_text("x"),
16393 TestToken::eof("parser-test", 1, 1, 1),
16394 ]);
16395 parser.rule_context_stack = vec![
16396 RuleContextFrame {
16397 rule_index: 0,
16398 invoking_state: 0,
16399 },
16400 RuleContextFrame {
16401 rule_index: 1,
16402 invoking_state: 1,
16403 },
16404 RuleContextFrame {
16405 rule_index: 2,
16406 invoking_state: 2,
16407 },
16408 ];
16409 parser.set_state(20);
16410 let mut context = ParserRuleContext::new(2, 2);
16411
16412 parser.recover_generated_rule(
16413 &mut context,
16414 &atn,
16415 AntlrError::NoViableAlternative {
16416 input: "'x'".to_owned(),
16417 },
16418 );
16419 assert_eq!(parser.input.index(), 0);
16420
16421 parser.set_state(21);
16422 parser.recover_generated_rule(
16423 &mut context,
16424 &atn,
16425 AntlrError::NoViableAlternative {
16426 input: "'x'".to_owned(),
16427 },
16428 );
16429 assert_eq!(parser.input.index(), 0);
16430 assert_eq!(
16431 parser.generated_recovery_error_states,
16432 BTreeSet::from([20, 21])
16433 );
16434
16435 parser.set_state(20);
16436 parser.recover_generated_rule(
16437 &mut context,
16438 &atn,
16439 AntlrError::NoViableAlternative {
16440 input: "'x'".to_owned(),
16441 },
16442 );
16443
16444 assert_eq!(parser.input.index(), 1);
16445 assert_eq!(parser.la(1), TOKEN_EOF);
16446 assert!(context.has_matched_child());
16447 assert_eq!(parser.generated_recovery_error_states, BTreeSet::from([20]));
16448
16449 parser.match_eof().expect("EOF should match");
16450 assert_eq!(parser.generated_recovery_error_index, None);
16451 assert!(parser.generated_recovery_error_states.is_empty());
16452 }
16453
16454 #[test]
16455 fn greedy_ll1_alt_handles_nullable_loop_exit() {
16456 let mut body_symbols = TokenBitSet::default();
16457 body_symbols.insert(1);
16458 let entry = DecisionLookahead {
16459 transitions: vec![
16460 TransitionLookSet {
16461 symbols: body_symbols,
16462 nullable: false,
16463 },
16464 TransitionLookSet {
16465 symbols: TokenBitSet::default(),
16466 nullable: true,
16467 },
16468 ],
16469 };
16470
16471 assert_eq!(ll1_unique_alt(&entry, 2), None);
16472 assert_eq!(ll1_greedy_alt(&entry, 2, false), Some(1));
16473 assert_eq!(ll1_greedy_alt(&entry, 1, false), None);
16474 assert_eq!(ll1_greedy_alt(&entry, 1, true), None);
16475 }
16476
16477 #[test]
16478 fn ordinary_repetition_builds_tree_in_input_order() {
16479 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
16480 let mut parser = mini_parser(repeated_x_tokens(3));
16481 let tree = parser
16482 .parse_atn_rule(&atn, 0)
16483 .expect("ordinary repetition should parse");
16484
16485 let root = parser
16486 .node(tree)
16487 .as_rule()
16488 .expect("entry result should be a rule");
16489 let body_rules = root.child_rules(1).collect::<Vec<_>>();
16490 assert_eq!(root.text(), "xxx<EOF>");
16491 assert_eq!(body_rules.len(), 3);
16492 assert_eq!(
16493 body_rules
16494 .iter()
16495 .map(|rule| rule.start_id().expect("body start").index())
16496 .collect::<Vec<_>>(),
16497 [0, 1, 2]
16498 );
16499 assert_eq!(
16500 body_rules
16501 .iter()
16502 .map(|rule| rule.stop_id().expect("body stop").index())
16503 .collect::<Vec<_>>(),
16504 [0, 1, 2]
16505 );
16506 assert_eq!(parser.number_of_syntax_errors(), 0);
16507 }
16508 }
16509
16510 #[test]
16511 fn deeply_nested_deferred_rules_materialize_on_small_stack() {
16512 const DEPTH: usize = 20_000;
16513
16514 std::thread::Builder::new()
16515 .name("deferred-rule-materialization".to_owned())
16516 .stack_size(256 * 1024)
16517 .spawn(|| {
16518 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
16519 let mut root = FastDeferredNodeId::EMPTY;
16520 for depth in 0..DEPTH {
16521 root = parser
16522 .recognition_arena
16523 .deferred_rule_node(FastDeferredRule {
16524 rule_index: u32::try_from(depth).expect("depth fits in u32"),
16525 invoking_state: i32::try_from(depth).expect("depth fits in i32"),
16526 start_index: 0,
16527 stop_index: None,
16528 deferred_children: root,
16529 children: NodeSeqId::EMPTY,
16530 });
16531 }
16532
16533 let (mut children, alt_number) =
16534 parser.materialize_fast_deferred_nodes(root, NodeSeqId::EMPTY);
16535 assert_eq!(alt_number, 0);
16536 for expected_rule in (0..DEPTH).rev() {
16537 let mut nodes = parser.recognition_arena.iter(children);
16538 let node = nodes.next().expect("nested rule node");
16539 assert!(nodes.next().is_none(), "each rule has one child");
16540 let ArenaRecognizedNode::Rule {
16541 rule_index,
16542 children: nested,
16543 ..
16544 } = parser.recognition_arena.node(node)
16545 else {
16546 panic!("expected nested rule");
16547 };
16548 assert_eq!(rule_index as usize, expected_rule);
16549 children = nested;
16550 }
16551 assert!(children.is_empty());
16552 })
16553 .expect("small-stack thread should start")
16554 .join()
16555 .expect("deferred rules should materialize without recursion");
16556 }
16557
16558 #[test]
16559 fn deferred_alternatives_preserve_left_recursive_contexts() {
16560 let mut parser = mini_parser(vec![
16561 TestToken::new(1).with_text("1"),
16562 TestToken::new(2).with_text("+"),
16563 TestToken::new(1).with_text("2"),
16564 TestToken::eof("parser-test", 3, 1, 3),
16565 ]);
16566 let base = parser.arena_token_node(0, false);
16567 let operator = parser.arena_token_node(1, false);
16568 let right = parser.arena_token_node(2, false);
16569
16570 let base = parser.recognition_arena.prepend(NodeSeqId::EMPTY, base);
16571 let base = parser.recognition_arena.deferred_fragment(base);
16572 let operator = parser.recognition_arena.prepend(NodeSeqId::EMPTY, operator);
16573 let operator = parser.recognition_arena.deferred_fragment(operator);
16574 let right = parser.recognition_arena.prepend(NodeSeqId::EMPTY, right);
16575 let right = parser.recognition_arena.deferred_fragment(right);
16576 let base_alt = parser.recognition_arena.deferred_alternative(1);
16577 let boundary = parser.recognition_arena.deferred_left_recursive_boundary(0);
16578 let operator_alt = parser.recognition_arena.deferred_alternative(6);
16579
16580 let mut deferred = FastDeferredNodeId::EMPTY;
16581 for fragment in [base_alt, base, boundary, operator_alt, operator, right] {
16582 deferred = parser
16583 .recognition_arena
16584 .concat_deferred_nodes(deferred, fragment);
16585 }
16586 let (nodes, root_alt_number) =
16587 parser.materialize_fast_deferred_nodes(deferred, NodeSeqId::EMPTY);
16588 let nodes = parser
16589 .recognition_arena
16590 .fold_left_recursive_boundaries(nodes);
16591
16592 let mut root = ParserRuleContext::new(0, -1);
16593 root.set_context_alt_number(root_alt_number);
16594 let mut cursor = nodes;
16595 while let Some(link) = parser.recognition_arena.link(cursor) {
16596 let child = parser
16597 .arena_recognized_node_tree(link.head, false, true)
16598 .expect("materialized child should become a public tree");
16599 parser.tree.add_child(&mut root, child);
16600 cursor = link.tail;
16601 }
16602 let tree = parser.rule_node(root);
16603 let contexts = parser
16604 .node(tree)
16605 .descendants()
16606 .filter_map(Node::as_rule)
16607 .map(|rule| {
16608 (
16609 rule.rule_index(),
16610 rule.alt_number(),
16611 rule.context_alt_number(),
16612 rule.text(),
16613 )
16614 })
16615 .collect::<Vec<_>>();
16616
16617 insta::assert_debug_snapshot!(
16618 "deferred_alternatives_preserve_left_recursive_contexts",
16619 contexts
16620 );
16621 }
16622
16623 #[test]
16624 fn fast_recognizer_preserves_labeled_left_recursive_operator_context() {
16625 let atn = labeled_left_recursive_operator_atn();
16626 let mut parser = mini_parser(vec![
16627 TestToken::new(1).with_text("a"),
16628 TestToken::new(3).with_text("+"),
16629 TestToken::new(1).with_text("b"),
16630 TestToken::eof("parser-test", 3, 1, 3),
16631 ]);
16632
16633 let (tree, _) = parser
16634 .parse_atn_rule_with_runtime_options(
16635 &atn,
16636 0,
16637 ParserRuntimeOptions {
16638 track_context_alt_numbers: true,
16639 ..ParserRuntimeOptions::default()
16640 },
16641 )
16642 .expect("labeled left-recursive addition should parse");
16643 let contexts = parser
16644 .node(tree)
16645 .descendants()
16646 .filter_map(Node::as_rule)
16647 .map(|rule| {
16648 let operator = rule
16649 .children()
16650 .next()
16651 .and_then(Node::as_rule)
16652 .is_some_and(|child| child.rule_index() == rule.rule_index());
16653 (operator, rule.context_alt_number(), rule.text())
16654 })
16655 .collect::<Vec<_>>();
16656
16657 insta::assert_debug_snapshot!(
16658 "fast_recognizer_preserves_labeled_left_recursive_operator_context",
16659 contexts
16660 );
16661 assert!(!parser.recognition_arena.deferred_nodes.is_empty());
16662 assert_eq!(parser.number_of_syntax_errors(), 0);
16663 }
16664
16665 #[test]
16666 fn deeply_nested_rule_calls_grow_the_stack() {
16667 const DEPTH: usize = 4_096;
16668 const STACK_SIZE: usize = 256 * 1024;
16669 let atn = nested_rule_chain_atn(DEPTH);
16670 std::thread::Builder::new()
16671 .name("nested-adaptive-set-rules".to_owned())
16672 .stack_size(STACK_SIZE)
16673 .spawn(move || {
16674 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
16675 parser.set_build_parse_trees(false);
16676 parser.fast_first_set_prefilter = false;
16679 parser
16680 .parse_atn_rule(&atn, 0)
16681 .expect("nested rule chain should grow the native stack");
16682 assert_eq!(parser.input.index(), 1);
16683 })
16684 .expect("small-stack thread should start")
16685 .join()
16686 .expect("nested rule chain should not overflow its stack");
16687 }
16688
16689 #[test]
16690 fn deeply_nested_branching_rules_grow_the_stack() {
16691 const DEPTH: usize = 4_096;
16692 const STACK_SIZE: usize = 256 * 1024;
16693 let atn = nested_rule_graph_atn(DEPTH, true, false);
16694 std::thread::Builder::new()
16695 .name("nested-branching-rules".to_owned())
16696 .stack_size(STACK_SIZE)
16697 .spawn(move || {
16698 let mut parser = mini_parser(vec![TestToken::new(1).with_text("x")]);
16699 parser.set_build_parse_trees(false);
16700 parser
16701 .parse_atn_rule(&atn, 0)
16702 .expect("branching rule chain should grow the native stack");
16703 assert_eq!(parser.input.index(), 1);
16704 })
16705 .expect("small-stack thread should start")
16706 .join()
16707 .expect("branching rule chain should not overflow its stack");
16708 }
16709
16710 #[test]
16711 fn deeply_nested_rule_follows_grow_the_stack() {
16712 const DEPTH: usize = 4_096;
16713 const STACK_SIZE: usize = 256 * 1024;
16714 let atn = nested_rule_graph_atn(DEPTH, false, true);
16715 std::thread::Builder::new()
16716 .name("nested-rule-follows".to_owned())
16717 .stack_size(STACK_SIZE)
16718 .spawn(move || {
16719 let mut parser = mini_parser(repeated_x_tokens(DEPTH));
16720 parser.set_build_parse_trees(false);
16721 parser.fast_first_set_prefilter = false;
16722 parser
16723 .parse_atn_rule(&atn, 0)
16724 .expect("rule follow chain should grow the native stack");
16725 assert_eq!(parser.input.index(), DEPTH);
16726 })
16727 .expect("small-stack thread should start")
16728 .join()
16729 .expect("nested rule follow chain should not overflow its stack");
16730 }
16731
16732 #[test]
16733 fn deeply_nested_recovery_grows_the_stack() {
16734 const DEPTH: usize = 4_096;
16735 const STACK_SIZE: usize = 256 * 1024;
16736 let atn = nested_rule_chain_atn(DEPTH);
16737 std::thread::Builder::new()
16738 .name("nested-rule-recovery".to_owned())
16739 .stack_size(STACK_SIZE)
16740 .spawn(move || {
16741 let mut parser = mini_parser(vec![
16742 TestToken::new(2).with_text("z"),
16743 TestToken::new(1).with_text("x"),
16744 TestToken::eof("parser-test", 2, 1, 2),
16745 ]);
16746 parser.set_build_parse_trees(false);
16747 parser.fast_first_set_prefilter = false;
16748 parser
16749 .parse_atn_rule(&atn, 0)
16750 .expect("nested recovery should grow the native stack");
16751 assert_eq!(parser.input.index(), 2);
16752 assert_eq!(parser.number_of_syntax_errors(), 1);
16753 })
16754 .expect("small-stack thread should start")
16755 .join()
16756 .expect("nested rule recovery should not overflow its stack");
16757 }
16758
16759 #[test]
16760 fn ambiguous_ordinary_repetition_merges_equivalent_coordinates() {
16761 const REPETITIONS: usize = 64;
16762
16763 let atn = ambiguous_ordinary_star_loop_atn();
16764 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16765 let tree = parser
16766 .parse_atn_rule(&atn, 0)
16767 .expect("ambiguous ordinary repetition should parse");
16768
16769 let root = parser
16770 .node(tree)
16771 .as_rule()
16772 .expect("entry result should be a rule");
16773 assert_eq!(root.text(), format!("{}<EOF>", "x".repeat(REPETITIONS)));
16774 assert_eq!(parser.input.index(), REPETITIONS);
16775 assert!(
16776 parser.recognition_arena.deferred_nodes.len() <= REPETITIONS * 8,
16777 "equivalent segmentations should keep deferred storage linear"
16778 );
16779 assert_eq!(parser.number_of_syntax_errors(), 0);
16780 }
16781
16782 #[test]
16783 fn long_ordinary_repetition_does_not_consume_native_stack() {
16784 const REPETITIONS: usize = 20_000;
16785
16786 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
16787 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16788 parser.set_build_parse_trees(false);
16789 parser
16790 .parse_atn_rule(&atn, 0)
16791 .expect("long ordinary repetition should parse");
16792
16793 assert_eq!(parser.input.index(), REPETITIONS);
16794 assert_eq!(parser.number_of_syntax_errors(), 0);
16795 }
16796 }
16797
16798 #[test]
16799 fn long_rule_repetition_materializes_tree_with_linear_arena_growth() {
16800 const REPETITIONS: usize = 2_000;
16801 let expected_text = format!("{}<EOF>", "x".repeat(REPETITIONS));
16802
16803 for atn in [ordinary_star_loop_atn(), ordinary_plus_loop_atn()] {
16804 let mut parser = mini_parser(repeated_x_tokens(REPETITIONS));
16805 let tree = parser
16806 .parse_atn_rule(&atn, 0)
16807 .expect("long rule repetition should parse");
16808
16809 let root = parser
16810 .node(tree)
16811 .as_rule()
16812 .expect("entry result should be a rule");
16813 assert_eq!(root.text(), expected_text);
16814 assert_eq!(root.child_rules(1).count(), REPETITIONS);
16815 let first_body = root.child_rules(1).next().expect("first body rule");
16816 let last_body = root.child_rules(1).next_back().expect("last body rule");
16817 assert_eq!(first_body.start_id().expect("first body start").index(), 0);
16818 assert_eq!(
16819 last_body.stop_id().expect("last body stop").index(),
16820 REPETITIONS - 1
16821 );
16822
16823 let stats = parser.recognition_arena_stats();
16824 assert_eq!(
16825 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
16826 (REPETITIONS, REPETITIONS, 0)
16827 );
16828 assert_eq!(
16829 (stats.total_links, stats.live_links, stats.dead_links),
16830 (REPETITIONS, REPETITIONS, 0)
16831 );
16832 assert_eq!(parser.recognition_arena.deferred_rules.len(), REPETITIONS);
16833 assert_eq!(
16834 parser.recognition_arena.deferred_nodes.len(),
16835 REPETITIONS * 2 - 1
16836 );
16837 assert_eq!(parser.number_of_syntax_errors(), 0);
16838 }
16839 }
16840
16841 #[test]
16842 fn clean_memo_probe_selects_sparse_promote_and_reprobe_modes() {
16843 let key = |state_number| FastRecognizeKey {
16844 state_number,
16845 stop_state: 10,
16846 index: state_number,
16847 rule_start_index: 0,
16848 decision_start_index: None,
16849 precedence: 0,
16850 recovery_symbols_id: 0,
16851 recovery_state: None,
16852 };
16853
16854 let mut sparse = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16855 for state_number in 0..(CLEAN_MEMO_PROBE_LIMIT - 1) {
16856 assert!(sparse.clean_memo_enabled_for_key(&key(state_number)));
16857 }
16858 assert!(!sparse.clean_memo_enabled_for_key(&key(CLEAN_MEMO_PROBE_LIMIT)));
16859 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Sparse);
16860
16861 let mut promote = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
16862 let repeated = key(1);
16863 for _ in 0..=CLEAN_MEMO_REPEAT_LIMIT {
16864 assert!(promote.clean_memo_enabled_for_key(&repeated));
16865 }
16866 assert_eq!(promote.clean_memo_mode, CleanMemoMode::Promote);
16867
16868 for _ in 1..CLEAN_MEMO_REPROBE_INTERVAL {
16869 assert!(!sparse.clean_memo_enabled_for_key(&repeated));
16870 }
16871 assert!(sparse.clean_memo_enabled_for_key(&repeated));
16872 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Probe);
16873 for _ in 0..CLEAN_MEMO_REPEAT_LIMIT {
16874 assert!(sparse.clean_memo_enabled_for_key(&repeated));
16875 }
16876 assert_eq!(sparse.clean_memo_mode, CleanMemoMode::Promote);
16877 }
16878
16879 #[test]
16880 fn fast_recognize_memo_capacity_scales_from_small_floor_to_bounded_maximum() {
16881 assert_eq!(
16882 fast_recognize_memo_capacity(0),
16883 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
16884 );
16885 assert_eq!(
16886 fast_recognize_memo_capacity(FAST_RECOGNIZE_MIN_MEMO_CAPACITY / 8),
16887 FAST_RECOGNIZE_MIN_MEMO_CAPACITY
16888 );
16889 assert_eq!(fast_recognize_memo_capacity(1_000), 8_000);
16890 assert_eq!(
16891 fast_recognize_memo_capacity(usize::MAX),
16892 FAST_RECOGNIZE_MAX_MEMO_CAPACITY
16893 );
16894 }
16895
16896 #[test]
16897 fn fast_recognize_scratch_reuses_small_tables_and_releases_oversized_memo() {
16898 let mut scratch = FastRecognizeTopScratch::default();
16899 scratch.prepare(FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
16900 let retained_capacity = scratch.memo.capacity();
16901 assert!(retained_capacity >= FAST_RECOGNIZE_MIN_MEMO_CAPACITY);
16902 assert!(retained_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16903
16904 let larger_capacity = retained_capacity + 1;
16905 scratch.prepare(larger_capacity);
16906 let grown_capacity = scratch.memo.capacity();
16907 assert!(grown_capacity >= larger_capacity);
16908 assert!(grown_capacity <= FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16909
16910 scratch.memo.insert(
16911 FastRecognizeKey {
16912 state_number: 0,
16913 stop_state: 0,
16914 index: 0,
16915 rule_start_index: 0,
16916 decision_start_index: None,
16917 precedence: 0,
16918 recovery_symbols_id: 0,
16919 recovery_state: None,
16920 },
16921 Rc::from([FastRecognizeOutcome {
16922 index: 0,
16923 consumed_eof: false,
16924 diagnostics: DiagnosticSeqId::EMPTY,
16925 deferred_nodes: FastDeferredNodeId::EMPTY,
16926 nodes: NodeSeqId::EMPTY,
16927 }]),
16928 );
16929 scratch.release_oversized_memo();
16930 assert!(scratch.memo.is_empty());
16931 assert_eq!(scratch.memo.capacity(), grown_capacity);
16932
16933 scratch
16934 .memo
16935 .reserve(FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY * 2);
16936 assert!(scratch.memo.capacity() > FAST_RECOGNIZE_MAX_RETAINED_MEMO_CAPACITY);
16937
16938 scratch.release_oversized_memo();
16939 assert!(scratch.memo.is_empty());
16940 assert_eq!(scratch.memo.capacity(), 0);
16941 }
16942
16943 #[test]
16944 fn clean_empty_multi_alt_outcomes_are_memoized() {
16945 let mut atn = ParserAtnBuilder::new(2);
16946 assert_eq!(
16947 atn.add_state(AtnStateKind::RuleStart, Some(0))
16948 .expect("state")
16949 .index(),
16950 0
16951 );
16952 assert_eq!(
16953 atn.add_state(AtnStateKind::BlockStart, Some(0))
16954 .expect("state")
16955 .index(),
16956 1
16957 );
16958 assert_eq!(
16959 atn.add_state(AtnStateKind::RuleStop, Some(0))
16960 .expect("state")
16961 .index(),
16962 2
16963 );
16964 atn.set_rule_to_start_state(vec![0])
16965 .expect("rule start states");
16966 atn.set_rule_to_stop_state(vec![2])
16967 .expect("rule stop states");
16968 atn.add_transition(0, ParserTransitionSpec::Epsilon { target: 1 })
16969 .expect("transition");
16970 atn.add_transition(
16971 1,
16972 ParserTransitionSpec::Atom {
16973 target: 2,
16974 label: 1,
16975 },
16976 )
16977 .expect("transition");
16978 atn.add_transition(
16979 1,
16980 ParserTransitionSpec::Atom {
16981 target: 2,
16982 label: 2,
16983 },
16984 )
16985 .expect("transition");
16986 let atn = finish_atn(atn);
16987
16988 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
16989 parser.fast_recovery_enabled = false;
16990 let mut visiting = FxHashSet::default();
16991 let mut memo = FxHashMap::default();
16992 let mut expected = ExpectedTokens::default();
16993 let outcomes = parser.recognize_state_fast(
16994 &atn,
16995 FastRecognizeRequest {
16996 state_number: 1,
16997 stop_state: 2,
16998 index: 0,
16999 rule_start_index: 0,
17000 decision_start_index: None,
17001 precedence: 0,
17002 depth: 0,
17003 recovery_symbols: parser.empty_recovery_symbols(),
17004 recovery_state: None,
17005 },
17006 FastRecognizeScratch {
17007 predicate_context: None,
17008 visiting: &mut visiting,
17009 memo: &mut memo,
17010 expected: &mut expected,
17011 native_depth: 0,
17012 },
17013 );
17014
17015 assert!(outcomes.is_empty());
17016 assert_eq!(memo.len(), 1);
17017 assert!(memo.values().next().expect("memo entry").is_empty());
17018
17019 parser.clean_memo_mode = CleanMemoMode::Sparse;
17020 visiting.clear();
17021 memo.clear();
17022 expected = ExpectedTokens::default();
17023 let sparse_outcomes = parser.recognize_state_fast(
17024 &atn,
17025 FastRecognizeRequest {
17026 state_number: 1,
17027 stop_state: 2,
17028 index: 0,
17029 rule_start_index: 0,
17030 decision_start_index: None,
17031 precedence: 0,
17032 depth: 0,
17033 recovery_symbols: parser.empty_recovery_symbols(),
17034 recovery_state: None,
17035 },
17036 FastRecognizeScratch {
17037 predicate_context: None,
17038 visiting: &mut visiting,
17039 memo: &mut memo,
17040 expected: &mut expected,
17041 native_depth: 0,
17042 },
17043 );
17044
17045 assert!(sparse_outcomes.is_empty());
17046 assert!(memo.is_empty());
17047 }
17048
17049 #[test]
17050 fn wildcard_matches_non_eof_only() {
17051 let mut parser = mini_parser(vec![
17052 TestToken::new(1).with_text("x"),
17053 TestToken::eof("parser-test", 1, 1, 1),
17054 ]);
17055 let matched = parser.match_wildcard().expect("wildcard");
17056 assert_eq!(parser.node(matched).text(), "x");
17057 assert!(parser.match_wildcard().is_err());
17058 }
17059
17060 #[test]
17061 fn add_parse_child_records_match_even_without_tree_building() {
17062 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 1, 1, 1)]);
17067 let token = TestToken::new(1).with_text("x");
17068
17069 parser.set_build_parse_trees(false);
17070 let mut ctx = ParserRuleContext::new(0, 0);
17071 assert!(!ctx.has_matched_child());
17072 let child = parser.terminal_tree(token.id);
17073 parser.add_parse_child(&mut ctx, child);
17074 assert_eq!(ctx.child_count(), 0);
17076 assert_eq!(parser.parse_tree_storage().node_count(), 0);
17077 assert!(ctx.has_matched_child());
17079
17080 parser.set_build_parse_trees(true);
17082 let mut ctx = ParserRuleContext::new(0, 0);
17083 let child = parser.terminal_tree(token.id);
17084 parser.add_parse_child(&mut ctx, child);
17085 assert_eq!(ctx.child_count(), 1);
17086 assert!(ctx.has_matched_child());
17087 }
17088
17089 #[test]
17090 fn disabled_tree_building_does_not_grow_flat_storage() {
17091 let mut parser = mini_parser(vec![
17092 TestToken::new(1).with_text("x"),
17093 TestToken::new(1).with_text("y"),
17094 TestToken::eof("parser-test", 2, 1, 2),
17095 ]);
17096 parser.set_build_parse_trees(false);
17097 let mut context = ParserRuleContext::new(0, -1);
17098
17099 for _ in 0..2 {
17100 let child = parser.match_token(1).expect("token should match");
17101 parser.add_parse_child(&mut context, child);
17102 }
17103 let current = parser.input.lt_id(1).expect("EOF token");
17104 let error = parser.error_tree(current);
17105 parser.add_parse_child(&mut context, error);
17106 let root = parser.rule_node(context);
17107
17108 assert_eq!(
17109 parser.parse_tree_storage().stats(),
17110 ParseTreeStats::default()
17111 );
17112 assert!(
17113 parser
17114 .parse_tree_storage()
17115 .node(parser.token_store(), root)
17116 .is_none(),
17117 "the no-tree sentinel must not resolve to stored data"
17118 );
17119 }
17120
17121 #[test]
17122 fn disabled_tree_building_skips_recognition_rule_node_storage() {
17123 let atn = ordinary_star_loop_atn();
17124 let mut parser = mini_parser(repeated_x_tokens(3));
17125 parser.set_build_parse_trees(false);
17126
17127 parser
17128 .parse_atn_rule(&atn, 0)
17129 .expect("ordinary repetition should parse without a tree");
17130
17131 assert_eq!(parser.input.index(), 3);
17132 assert!(parser.recognition_arena.nodes.is_empty());
17133 assert!(parser.recognition_arena.seq_links.is_empty());
17134 assert!(parser.recognition_arena.deferred_nodes.is_empty());
17135 assert!(parser.recognition_arena.deferred_rules.is_empty());
17136 assert!(!parser.fast_token_nodes_enabled);
17137 assert!(parser.fast_recognize_scratch.memo.is_empty());
17138 }
17139
17140 #[test]
17141 fn parser_interprets_simple_atn_rule() {
17142 let atn = token_then_eof_atn();
17143 let mut parser = mini_parser(vec![
17144 TestToken::new(1).with_text("x"),
17145 TestToken::eof("parser-test", 1, 1, 1),
17146 ]);
17147
17148 let tree = parser
17149 .parse_atn_rule(&atn, 0)
17150 .expect("artificial parser rule should parse");
17151 assert_eq!(parser.node(tree).text(), "x<EOF>");
17152 assert_eq!(parser.number_of_syntax_errors(), 0);
17153 assert_eq!(
17154 parser
17155 .node(tree)
17156 .first_rule_stop(0)
17157 .expect("rule should stop at EOF")
17158 .token_type(),
17159 TOKEN_EOF
17160 );
17161
17162 let mut parser = mini_parser(vec![
17163 TestToken::new(1).with_text("x"),
17164 TestToken::eof("parser-test", 1, 1, 1),
17165 ]);
17166 let (tree, actions) = parser
17167 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17168 .expect("runtime-option parser rule should parse");
17169 assert!(actions.is_empty());
17170 assert_eq!(
17171 parser
17172 .node(tree)
17173 .first_rule_stop(0)
17174 .expect("rule should stop at EOF")
17175 .token_type(),
17176 TOKEN_EOF
17177 );
17178 }
17179
17180 #[test]
17181 fn runtime_options_default_ignores_noop_action_transitions() {
17182 let atn = noop_action_then_token_then_eof_atn();
17183 let mut parser = mini_parser(vec![
17184 TestToken::new(1).with_text("x"),
17185 TestToken::eof("parser-test", 1, 1, 1),
17186 ]);
17187
17188 let (tree, actions) = parser
17189 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17190 .expect("no-op parser action should not force action replay");
17191
17192 assert_eq!(parser.node(tree).text(), "x<EOF>");
17193 assert!(
17194 actions.is_empty(),
17195 "action_index=None transitions are ANTLR metadata, not replay actions"
17196 );
17197 assert_eq!(parser.number_of_syntax_errors(), 0);
17198 }
17199
17200 #[test]
17201 fn parser_exposes_buffered_token_stream_after_parse() {
17202 let atn = token_then_eof_atn();
17203 let mut parser = mini_parser(vec![
17204 TestToken::new(1).with_text("x"),
17205 TestToken::eof("parser-test", 1, 1, 1),
17206 ]);
17207
17208 let tree = parser
17209 .parse_atn_rule(&atn, 0)
17210 .expect("artificial parser rule should parse");
17211 assert_eq!(parser.node(tree).text(), "x<EOF>");
17212
17213 let stream = parser.token_stream();
17214 let source_index_after_parse = stream.token_source().index;
17215 let buffered = stream.tokens().collect::<Vec<_>>();
17216 assert_eq!(buffered.len(), 2);
17217 assert_eq!(buffered[0].text(), Some("x"));
17218 assert_eq!(buffered[0].token_id().index(), 0);
17219 assert_eq!(buffered[1].token_type(), TOKEN_EOF);
17220 assert_eq!(stream.token_source().index, source_index_after_parse);
17221 drop(buffered);
17222
17223 let stream = parser.into_token_stream();
17224 assert_eq!(stream.token_source().index, source_index_after_parse);
17225 assert_eq!(
17226 stream.tokens().next().expect("first token").text(),
17227 Some("x")
17228 );
17229 assert_eq!(
17230 stream.tokens().nth(1).expect("EOF token").token_type(),
17231 TOKEN_EOF
17232 );
17233 }
17234
17235 #[test]
17236 fn parsed_file_exposes_all_buffered_tokens() {
17237 let atn = token_then_eof_atn();
17238 let mut parser = mini_parser(vec![
17239 TestToken::new(99)
17240 .with_text(" comment")
17241 .with_channel(HIDDEN_CHANNEL),
17242 TestToken::new(1).with_text("x"),
17243 TestToken::eof("parser-test", 9, 1, 9),
17244 ]);
17245
17246 let tree = parser
17247 .parse_atn_rule(&atn, 0)
17248 .expect("artificial parser rule should parse");
17249 let parsed = parser.into_parsed_file(tree);
17250
17251 insta::assert_debug_snapshot!(
17254 "parsed_file_exposes_all_buffered_tokens",
17255 parsed
17256 .tokens()
17257 .iter()
17258 .map(|token| (token.token_type(), token.channel(), token.text()))
17259 .collect::<Vec<_>>()
17260 );
17261 assert_eq!(parsed.tokens().into_iter().count(), 3);
17262 }
17263
17264 #[test]
17265 fn parser_syntax_error_count_tracks_interpreted_recovery() {
17266 let atn = token_then_eof_atn();
17267 let mut parser = mini_parser(vec![
17268 TestToken::new(1).with_text("x"),
17269 TestToken::new(2).with_text("y"),
17270 TestToken::eof("parser-test", 2, 1, 2),
17271 ]);
17272
17273 let tree = parser
17274 .parse_atn_rule(&atn, 0)
17275 .expect("invalid token should recover into an error node");
17276
17277 assert_eq!(parser.number_of_syntax_errors(), 1);
17278 assert_eq!(
17279 parser
17280 .node(tree)
17281 .first_error_token()
17282 .expect("recovery should embed an error token")
17283 .text(),
17284 Some("y")
17285 );
17286 }
17287
17288 #[test]
17289 fn failed_interpreted_parse_notifies_error_listener() {
17290 let atn = token_then_eof_atn();
17291 let mut parser = mini_parser(vec![
17292 TestToken::new(2)
17293 .with_text("y")
17294 .with_span(0, 0)
17295 .with_position(3, 5),
17296 TestToken::eof("parser-test", 1, 1, 1),
17297 ]);
17298 parser.remove_error_listeners();
17299 let diagnostics = Arc::new(Mutex::new(Vec::new()));
17300 parser.add_error_listener(RecordingErrorListener {
17301 diagnostics: Arc::clone(&diagnostics),
17302 });
17303
17304 let error = parser
17305 .parse_atn_rule(&atn, 0)
17306 .expect_err("start-rule mismatch should remain a parser error");
17307
17308 assert_eq!(parser.number_of_syntax_errors(), 1);
17309 assert!(matches!(&error, AntlrError::ParserError { .. }));
17310 insta::assert_debug_snapshot!(
17311 "failed_interpreted_parse_notifies_error_listener",
17312 *diagnostics.lock().expect("recorded diagnostics lock")
17313 );
17314 }
17315
17316 #[test]
17317 fn adaptive_direct_rule_uses_simulator_decision() {
17318 let atn = two_alt_decision_atn();
17319 let mut simulator = ParserAtnSimulator::new(&atn);
17320 let mut parser = mini_parser(vec![
17321 TestToken::new(2).with_text("y"),
17322 TestToken::eof("parser-test", 1, 1, 1),
17323 ]);
17324
17325 let tree = parser
17326 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
17327 .expect("direct adaptive rule should parse");
17328
17329 assert_eq!(parser.node(tree).text(), "y");
17330 assert_eq!(parser.input.index(), 1);
17331 }
17332
17333 #[test]
17334 fn adaptive_direct_rule_restores_input_on_fallback() {
17335 let atn = predicate_after_token_atn();
17336 let mut simulator = ParserAtnSimulator::new(&atn);
17337 let mut parser = mini_parser(vec![
17338 TestToken::new(1).with_text("x"),
17339 TestToken::new(2).with_text("y"),
17340 TestToken::eof("parser-test", 2, 1, 2),
17341 ]);
17342
17343 let tree = parser
17344 .parse_atn_rule_adaptive_or_fallback(&atn, &mut simulator, 0)
17345 .expect("fallback recognizer should parse");
17346
17347 assert_eq!(parser.node(tree).text(), "xy");
17348 assert_eq!(parser.input.index(), 2);
17349 let stats = parser.parse_tree_storage().stats();
17350 assert_eq!(stats.nodes, parser.node(tree).descendants().count());
17351 assert_eq!(stats.edges, stats.nodes.saturating_sub(1));
17352 assert_eq!(stats.scratch_links, 0);
17353 }
17354
17355 #[test]
17356 fn unknown_predicate_policy_defaults_to_assume_true() {
17357 let atn = predicate_after_token_atn();
17358 let mut parser = mini_parser(vec![
17359 TestToken::new(1).with_text("x"),
17360 TestToken::new(2).with_text("y"),
17361 TestToken::eof("parser-test", 2, 1, 2),
17362 ]);
17363
17364 let (tree, _) = parser
17365 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17366 .expect("unknown predicate should pass under the default policy");
17367
17368 assert_eq!(parser.node(tree).text(), "xy");
17369 assert_eq!(parser.number_of_syntax_errors(), 0);
17370 }
17371
17372 #[test]
17373 fn private_context_alt_tracking_keeps_fast_predicate_recognition() {
17374 let atn = predicate_gated_same_lookahead_atn([0, 1]);
17375 let mut parser = mini_parser(vec![
17376 TestToken::new(1).with_text("x"),
17377 TestToken::eof("parser-test", 1, 1, 1),
17378 ]);
17379
17380 let (tree, _) = parser
17381 .parse_atn_rule_with_runtime_options(
17382 &atn,
17383 0,
17384 ParserRuntimeOptions {
17385 predicates: &[
17386 (0, 0, ParserPredicate::False),
17387 (0, 1, ParserPredicate::True),
17388 ],
17389 track_context_alt_numbers: true,
17390 ..ParserRuntimeOptions::default()
17391 },
17392 )
17393 .expect("the second predicate-gated alternative should match");
17394
17395 let root = parser.node(tree).as_rule().expect("entry result is a rule");
17396 insta::assert_debug_snapshot!(
17397 "private_context_alt_tracking_keeps_fast_predicate_recognition",
17398 (root.alt_number(), root.context_alt_number(), root.text())
17399 );
17400 assert_eq!(parser.number_of_syntax_errors(), 0);
17401 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&false));
17402 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 1)), Some(&true));
17403 }
17404
17405 #[test]
17406 fn nested_interpreted_parse_preserves_prior_unknown_predicate_hits() {
17407 let atn = token_then_eof_atn();
17411 let mut parser = mini_parser(vec![
17412 TestToken::new(1).with_text("x"),
17413 TestToken::eof("parser-test", 1, 1, 1),
17414 ]);
17415
17416 parser.unknown_predicate_hits.push((7, 3));
17418
17419 parser
17421 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17422 .expect("child rule parses");
17423
17424 let error = parser
17426 .take_unknown_semantic_error()
17427 .expect("parent's recorded coordinate must survive the nested interpreted parse");
17428 let AntlrError::Unsupported(message) = error else {
17429 panic!("expected AntlrError::Unsupported, got {error:?}");
17430 };
17431 assert!(message.contains("pred_index=3"), "message: {message}");
17432 }
17433
17434 #[test]
17435 fn unknown_predicate_policy_assume_false_kills_the_guarded_path() {
17436 let atn = predicate_after_token_atn();
17437 let mut parser = mini_parser(vec![
17438 TestToken::new(1).with_text("x"),
17439 TestToken::new(2).with_text("y"),
17440 TestToken::eof("parser-test", 2, 1, 2),
17441 ]);
17442
17443 let result = parser.parse_atn_rule_with_runtime_options(
17444 &atn,
17445 0,
17446 ParserRuntimeOptions {
17447 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
17448 ..ParserRuntimeOptions::default()
17449 },
17450 );
17451
17452 assert!(
17453 result.is_err(),
17454 "the only path is predicate-guarded, so assume-false must fail the parse"
17455 );
17456 }
17457
17458 #[test]
17459 fn predicate_failure_message_keeps_semantic_recovery_path() {
17460 let atn = predicate_after_token_atn();
17461 let mut parser = mini_parser(vec![
17462 TestToken::new(1).with_text("x"),
17463 TestToken::new(2).with_text("y"),
17464 TestToken::eof("parser-test", 2, 1, 2),
17465 ]);
17466
17467 let (tree, _) = parser
17468 .parse_atn_rule_with_runtime_options(
17469 &atn,
17470 0,
17471 ParserRuntimeOptions {
17472 predicates: &[(
17473 0,
17474 0,
17475 ParserPredicate::FalseWithMessage {
17476 message: "predicate rejected input",
17477 },
17478 )],
17479 ..ParserRuntimeOptions::default()
17480 },
17481 )
17482 .expect("failure-message predicates recover through the semantic interpreter");
17483
17484 assert_eq!(parser.node(tree).text(), "xy");
17485 assert_eq!(parser.number_of_syntax_errors(), 1);
17486 assert!(
17487 parser.fast_predicate_cache.is_empty(),
17488 "failure-message predicates need the semantic interpreter's recovery outcome"
17489 );
17490 }
17491
17492 #[test]
17493 fn unknown_predicate_policy_error_names_the_coordinate() {
17494 let atn = predicate_after_token_atn();
17495 let mut parser = mini_parser(vec![
17496 TestToken::new(1).with_text("x"),
17497 TestToken::new(2).with_text("y"),
17498 TestToken::eof("parser-test", 2, 1, 2),
17499 ]);
17500
17501 let error = parser
17502 .parse_atn_rule_with_runtime_options(
17503 &atn,
17504 0,
17505 ParserRuntimeOptions {
17506 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17507 ..ParserRuntimeOptions::default()
17508 },
17509 )
17510 .expect_err("evaluating an unknown predicate under Error policy must fail");
17511
17512 let AntlrError::Unsupported(message) = error else {
17513 panic!("expected AntlrError::Unsupported, got {error:?}");
17514 };
17515 assert!(
17516 message.contains("unsupported semantic predicate"),
17517 "message should name the failure class: {message}"
17518 );
17519 assert!(
17520 message.contains("pred_index=0"),
17521 "message should carry the coordinate: {message}"
17522 );
17523 }
17524
17525 #[test]
17526 fn fail_loud_hits_do_not_leak_into_a_reused_interpreter_parse() {
17527 let atn = predicate_after_token_atn();
17533 let mut parser = mini_parser(vec![
17534 TestToken::new(1).with_text("x"),
17535 TestToken::new(2).with_text("y"),
17536 TestToken::eof("parser-test", 2, 1, 2),
17537 ]);
17538
17539 parser
17540 .parse_atn_rule_with_runtime_options(
17541 &atn,
17542 0,
17543 ParserRuntimeOptions {
17544 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17545 ..ParserRuntimeOptions::default()
17546 },
17547 )
17548 .expect_err("first parse fails loud under the Error policy");
17549
17550 parser.reset_unknown_semantic_hits();
17555 assert!(
17556 parser.take_unknown_semantic_error().is_none(),
17557 "reset must drop stale unknown-predicate coordinates before a reused parse"
17558 );
17559 }
17560
17561 #[derive(Debug, Default)]
17562 struct RecordingHooks {
17563 predicates: Vec<(usize, usize, usize, Option<String>)>,
17564 actions: Vec<(usize, String, Option<String>)>,
17565 action_trees: Vec<Option<String>>,
17566 }
17567
17568 impl SemanticHooks for RecordingHooks {
17569 fn sempred<S>(
17570 &mut self,
17571 ctx: &mut ParserSemCtx<'_, S>,
17572 rule_index: usize,
17573 pred_index: usize,
17574 ) -> Option<bool>
17575 where
17576 S: TokenSource,
17577 {
17578 self.predicates.push((
17579 ctx.input_index(),
17580 rule_index,
17581 pred_index,
17582 ctx.token_text(1)
17583 .and_then(|token| token.text().map(str::to_owned)),
17584 ));
17585 Some(true)
17586 }
17587
17588 fn action<S>(&mut self, ctx: &mut ParserSemCtx<'_, S>, action: ParserAction) -> bool
17589 where
17590 S: TokenSource,
17591 {
17592 self.actions.push((
17593 action.source_state(),
17594 ctx.action_text(),
17595 ctx.rule_name().map(str::to_owned),
17596 ));
17597 self.action_trees.push(ctx.tree().map(Node::text));
17598 true
17599 }
17600 }
17601
17602 #[derive(Debug, Default)]
17603 struct RejectingPredicateHooks {
17604 predicates: Vec<(usize, usize, usize, Option<String>)>,
17605 }
17606
17607 impl SemanticHooks for RejectingPredicateHooks {
17608 fn sempred<S>(
17609 &mut self,
17610 ctx: &mut ParserSemCtx<'_, S>,
17611 rule_index: usize,
17612 pred_index: usize,
17613 ) -> Option<bool>
17614 where
17615 S: TokenSource,
17616 {
17617 self.predicates.push((
17618 ctx.input_index(),
17619 rule_index,
17620 pred_index,
17621 ctx.token_text(1)
17622 .and_then(|token| token.text().map(str::to_owned)),
17623 ));
17624 Some(false)
17625 }
17626 }
17627
17628 #[test]
17629 fn fast_predicate_cache_replays_hook_once_per_coordinate_and_input() {
17630 let atn = predicate_gated_same_lookahead_atn([0, 0]);
17631 let mut parser = mini_parser_with_hooks(
17632 vec![
17633 TestToken::new(1).with_text("x"),
17634 TestToken::eof("parser-test", 1, 1, 1),
17635 ],
17636 RecordingHooks::default(),
17637 );
17638
17639 let (tree, _) = parser
17640 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17641 .expect("both alternatives share one replay-safe predicate result");
17642
17643 assert_eq!(parser.node(tree).text(), "x<EOF>");
17644 assert_eq!(
17645 parser.semantic_hooks.predicates,
17646 vec![(0, 0, 0, Some("x".to_owned()))]
17647 );
17648 assert_eq!(parser.fast_predicate_cache.get(&(0, 0, 0)), Some(&true));
17649 }
17650
17651 #[test]
17652 fn semantic_hook_handles_unknown_predicate_before_error_policy() {
17653 let atn = predicate_after_token_atn();
17654 let mut parser = mini_parser_with_hooks(
17655 vec![
17656 TestToken::new(1).with_text("x"),
17657 TestToken::new(2).with_text("y"),
17658 TestToken::eof("parser-test", 2, 1, 2),
17659 ],
17660 RecordingHooks::default(),
17661 );
17662
17663 let (tree, _) = parser
17664 .parse_atn_rule_with_runtime_options(
17665 &atn,
17666 0,
17667 ParserRuntimeOptions {
17668 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17669 ..ParserRuntimeOptions::default()
17670 },
17671 )
17672 .expect("hook supplies the missing predicate result");
17673
17674 assert_eq!(parser.node(tree).text(), "xy");
17675 assert_eq!(
17676 parser.semantic_hooks.predicates,
17677 vec![(1, 0, 0, Some("y".to_owned()))]
17678 );
17679 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&true));
17680 }
17681
17682 #[test]
17683 fn runtime_options_default_preserves_semantic_hook_predicates() {
17684 let atn = predicate_after_token_atn();
17685 let mut parser = mini_parser_with_hooks(
17686 vec![
17687 TestToken::new(1).with_text("x"),
17688 TestToken::new(2).with_text("y"),
17689 TestToken::eof("parser-test", 2, 1, 2),
17690 ],
17691 RejectingPredicateHooks::default(),
17692 );
17693
17694 let result =
17695 parser.parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default());
17696
17697 assert!(
17698 result.is_err(),
17699 "default runtime options must not bypass semantic hooks for predicate ATNs"
17700 );
17701 assert_eq!(
17702 parser.semantic_hooks.predicates,
17703 vec![(1, 0, 0, Some("y".to_owned()))]
17704 );
17705 assert_eq!(parser.fast_predicate_cache.get(&(1, 0, 0)), Some(&false));
17706 }
17707
17708 #[test]
17709 fn semantic_hook_handles_committed_parser_action() {
17710 let atn = token_then_eof_atn();
17711 let mut parser = mini_parser_with_hooks(
17712 vec![
17713 TestToken::new(1).with_text("x"),
17714 TestToken::eof("parser-test", 1, 1, 1),
17715 ],
17716 RecordingHooks::default(),
17717 );
17718 let (tree, _) = parser
17719 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
17720 .expect("rule parses before action hook is tested");
17721
17722 assert!(parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17723 assert_eq!(
17724 parser.semantic_hooks.actions,
17725 vec![(42, "x".to_owned(), Some("s".to_owned()))]
17726 );
17727 assert_eq!(
17728 parser.semantic_hooks.action_trees,
17729 [Some("x<EOF>".to_owned())]
17730 );
17731 }
17732
17733 #[test]
17734 fn unhandled_committed_action_fails_loud_under_error_policy() {
17735 let mut parser = mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17739 parser.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
17740 let tree = parser.rule_node(ParserRuleContext::new(0, -1));
17741
17742 assert!(!parser.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17744
17745 let error = parser
17746 .take_unknown_semantic_error()
17747 .expect("an unhandled committed action under Error policy must fail loud");
17748 let AntlrError::Unsupported(message) = error else {
17749 panic!("expected AntlrError::Unsupported, got {error:?}");
17750 };
17751 assert!(
17752 message.contains("unhandled semantic action") && message.contains("state=42"),
17753 "message should name the dropped action coordinate: {message}"
17754 );
17755
17756 let mut lenient =
17758 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17759 let tree = lenient.rule_node(ParserRuleContext::new(0, -1));
17760 assert!(!lenient.parser_action_hook(ParserAction::new(42, 0, 0, Some(0)), tree));
17761 assert!(lenient.take_unknown_semantic_error().is_none());
17762 }
17763
17764 #[test]
17765 fn translated_predicate_is_unaffected_by_error_policy() {
17766 let atn = predicate_after_token_atn();
17767 let mut parser = mini_parser(vec![
17768 TestToken::new(1).with_text("x"),
17769 TestToken::new(2).with_text("y"),
17770 TestToken::eof("parser-test", 2, 1, 2),
17771 ]);
17772
17773 let (tree, _) = parser
17774 .parse_atn_rule_with_runtime_options(
17775 &atn,
17776 0,
17777 ParserRuntimeOptions {
17778 predicates: &[(0, 0, ParserPredicate::True)],
17779 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17780 ..ParserRuntimeOptions::default()
17781 },
17782 )
17783 .expect("a predicate covered by the table is not an unknown coordinate");
17784
17785 assert_eq!(parser.node(tree).text(), "xy");
17786 }
17787
17788 #[test]
17793 fn parser_speculative_replay_threads_stack_member_state() {
17794 let mut ir = SemIr::new();
17795 let one = ir.expr(PExpr::Int(1));
17796 let push = ir.stmt(AStmt::PushMember(0, one));
17797 let pop = ir.stmt(AStmt::PopMember(0));
17798 let semantics = ParserSemantics {
17799 ir,
17800 predicates: Vec::new(),
17801 actions: vec![
17802 ParserSemanticAction {
17803 source_state: 1,
17804 rule_index: usize::MAX,
17805 stmt: push,
17806 speculative: true,
17807 },
17808 ParserSemanticAction {
17809 source_state: 2,
17810 rule_index: usize::MAX,
17811 stmt: pop,
17812 speculative: true,
17813 },
17814 ],
17815 };
17816
17817 let pushed = member_values_after_action(1, &[], Some(&semantics), &MemberEnv::new());
17819 assert_eq!(pushed.stack_top(0), Some(1));
17820 assert_eq!(pushed.stack_len(0), 1);
17821
17822 assert_eq!(MemberEnv::new().stack_len(0), 0);
17825
17826 let popped = member_values_after_action(2, &[], Some(&semantics), &pushed);
17829 assert_eq!(popped.stack_top(0), None);
17830 assert_eq!(popped, MemberEnv::new(), "emptied stack must canonicalize");
17831
17832 let underflowed = member_values_after_action(2, &[], Some(&semantics), &MemberEnv::new());
17834 assert_eq!(underflowed, MemberEnv::new());
17835 }
17836
17837 fn hook_predicate_semantics() -> ParserSemantics {
17842 let mut ir = SemIr::new();
17843 let expr = ir.expr(PExpr::Hook(HookId::new(0)));
17844 ParserSemantics {
17845 ir,
17846 predicates: vec![ParserSemanticPredicate {
17847 rule_index: 0,
17848 pred_index: 0,
17849 expr,
17850 failure_message: None,
17851 }],
17852 actions: Vec::new(),
17853 }
17854 }
17855
17856 #[derive(Debug, Default)]
17857 struct DecliningHooks;
17858
17859 impl SemanticHooks for DecliningHooks {}
17860
17861 #[test]
17862 fn semir_hook_none_falls_through_to_assume_true() {
17863 let atn = predicate_after_token_atn();
17864 let semantics = hook_predicate_semantics();
17865 let mut parser = mini_parser_with_hooks(
17866 vec![
17867 TestToken::new(1).with_text("x"),
17868 TestToken::new(2).with_text("y"),
17869 TestToken::eof("parser-test", 2, 1, 2),
17870 ],
17871 DecliningHooks,
17872 );
17873
17874 let (tree, _) = parser
17875 .parse_atn_rule_with_runtime_options(
17876 &atn,
17877 0,
17878 ParserRuntimeOptions {
17879 semantics: Some(&semantics),
17880 unknown_predicate_policy: UnknownSemanticPolicy::AssumeTrue,
17881 ..ParserRuntimeOptions::default()
17882 },
17883 )
17884 .expect("a declined SemIR hook must pass under assume-true");
17885
17886 assert_eq!(parser.node(tree).text(), "xy");
17887 }
17888
17889 #[test]
17890 fn semir_hook_none_falls_through_to_assume_false() {
17891 let atn = predicate_after_token_atn();
17892 let semantics = hook_predicate_semantics();
17893 let mut parser = mini_parser_with_hooks(
17894 vec![
17895 TestToken::new(1).with_text("x"),
17896 TestToken::new(2).with_text("y"),
17897 TestToken::eof("parser-test", 2, 1, 2),
17898 ],
17899 DecliningHooks,
17900 );
17901
17902 let result = parser.parse_atn_rule_with_runtime_options(
17903 &atn,
17904 0,
17905 ParserRuntimeOptions {
17906 semantics: Some(&semantics),
17907 unknown_predicate_policy: UnknownSemanticPolicy::AssumeFalse,
17908 ..ParserRuntimeOptions::default()
17909 },
17910 );
17911
17912 assert!(
17913 result.is_err(),
17914 "a declined SemIR hook must fail the only guarded path under assume-false"
17915 );
17916 }
17917
17918 #[test]
17919 fn semir_hook_none_records_coordinate_under_error_policy() {
17920 let atn = predicate_after_token_atn();
17921 let semantics = hook_predicate_semantics();
17922 let mut parser = mini_parser_with_hooks(
17923 vec![
17924 TestToken::new(1).with_text("x"),
17925 TestToken::new(2).with_text("y"),
17926 TestToken::eof("parser-test", 2, 1, 2),
17927 ],
17928 DecliningHooks,
17929 );
17930
17931 let error = parser
17932 .parse_atn_rule_with_runtime_options(
17933 &atn,
17934 0,
17935 ParserRuntimeOptions {
17936 semantics: Some(&semantics),
17937 unknown_predicate_policy: UnknownSemanticPolicy::Error,
17938 ..ParserRuntimeOptions::default()
17939 },
17940 )
17941 .expect_err("a declined SemIR hook under Error policy must fail the parse");
17942
17943 let AntlrError::Unsupported(message) = error else {
17944 panic!("expected AntlrError::Unsupported, got {error:?}");
17945 };
17946 assert!(
17947 message.contains("unsupported semantic predicate") && message.contains("pred_index=0"),
17948 "message should name the unresolved coordinate: {message}"
17949 );
17950 }
17951
17952 #[test]
17953 fn generated_direct_predicate_honors_installed_policy() {
17954 let semantics = hook_predicate_semantics();
17960 let context = ParserRuleContext::new(0, -1);
17961
17962 let mut assume_true =
17963 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17964 assert!(
17965 assume_true.parser_semantic_ir_predicate_matches_with_context_and_local(
17966 &semantics, 0, 0, &context, 0
17967 ),
17968 "default AssumeTrue accepts a declined hook"
17969 );
17970 assert!(assume_true.take_unknown_semantic_error().is_none());
17971
17972 let mut error_policy =
17973 mini_parser_with_hooks(vec![TestToken::eof("t", 0, 1, 0)], DecliningHooks);
17974 error_policy.set_unknown_predicate_policy(UnknownSemanticPolicy::Error);
17975 assert!(
17976 !error_policy.parser_semantic_ir_predicate_matches_with_context_and_local(
17977 &semantics, 0, 0, &context, 0
17978 ),
17979 "Error policy rejects a declined hook on the generated-direct path"
17980 );
17981 let error = error_policy
17982 .take_unknown_semantic_error()
17983 .expect("Error policy records the unresolved coordinate for the generated path");
17984 let AntlrError::Unsupported(message) = error else {
17985 panic!("expected AntlrError::Unsupported, got {error:?}");
17986 };
17987 assert!(message.contains("pred_index=0"), "message: {message}");
17988 }
17989
17990 #[test]
17991 fn parser_rule_start_skips_leading_hidden_tokens() {
17992 let atn = token_then_eof_atn();
17993 let mut parser = mini_parser(vec![
17994 TestToken::new(99)
17995 .with_text(" ")
17996 .with_channel(HIDDEN_CHANNEL),
17997 TestToken::new(1).with_text("x"),
17998 TestToken::eof("parser-test", 2, 1, 2),
17999 ]);
18000
18001 let tree = parser
18002 .parse_atn_rule(&atn, 0)
18003 .expect("artificial parser rule should parse");
18004 let Some(rule) = parser.node(tree).first_rule(0).and_then(Node::as_rule) else {
18005 panic!("rule node should be present");
18006 };
18007 assert_eq!(
18008 rule.start()
18009 .expect("rule should have a start token")
18010 .token_type(),
18011 1
18012 );
18013 }
18014
18015 #[test]
18016 fn parser_action_after_eof_stops_at_eof_token() {
18017 let atn = eof_then_action_atn();
18018 let mut parser = mini_parser(vec![TestToken::eof("parser-test", 0, 1, 0)]);
18019
18020 let (_, actions) = parser
18021 .parse_atn_rule_with_runtime_options(&atn, 0, ParserRuntimeOptions::default())
18022 .expect("EOF action rule should parse");
18023
18024 assert_eq!(actions.len(), 1);
18025 assert_eq!(actions[0].stop_index(), Some(0));
18026 assert_eq!(
18027 parser.text_interval(actions[0].start_index(), actions[0].stop_index()),
18028 ""
18029 );
18030 }
18031
18032 #[test]
18033 fn after_action_stop_uses_rule_context_stop_not_cursor() {
18034 let mut id = TestToken::new(1).with_text("x");
18039 id.set_token_index(0);
18040 let mut eof = TestToken::eof("parser-test", 1, 1, 1);
18041 eof.set_token_index(1);
18042 let mut parser = mini_parser(vec![id.clone(), eof]);
18043 parser.consume();
18045 assert_eq!(parser.la(1), TOKEN_EOF);
18046
18047 let mut ctx = ParserRuleContext::new(0, 0);
18050 parser.set_context_stop(
18051 &mut ctx,
18052 parser.token_id_at(0).expect("ID token should be buffered"),
18053 );
18054 let tree = parser.rule_node(ctx);
18055
18056 let current_index = parser.input.index();
18057 assert_eq!(parser.after_action_stop_index(current_index), Some(1));
18059 assert_eq!(
18061 parser.after_action_stop_index_for_tree(tree, current_index),
18062 Some(0)
18063 );
18064 }
18065
18066 #[test]
18067 fn after_action_start_uses_rule_context_start_not_cursor() {
18068 let mut parser = mini_parser(vec![
18073 TestToken::new(9)
18074 .with_text(" ")
18075 .with_channel(HIDDEN_CHANNEL),
18076 TestToken::new(9)
18077 .with_text(" ")
18078 .with_channel(HIDDEN_CHANNEL),
18079 TestToken::new(1).with_text("x"),
18080 TestToken::eof("parser-test", 3, 1, 3),
18081 ]);
18082
18083 let mut ctx = ParserRuleContext::new(0, 0);
18084 parser.set_context_start(
18085 &mut ctx,
18086 parser.token_id_at(2).expect("ID token should be buffered"),
18087 );
18088 let tree = parser.rule_node(ctx);
18089
18090 assert_eq!(parser.after_action_start_index_for_tree(tree, 0), 2);
18093
18094 let empty = parser.rule_node(ParserRuleContext::new(0, 0));
18096 assert_eq!(parser.after_action_start_index_for_tree(empty, 7), 7);
18097 }
18098
18099 fn clean_fast_outcome(index: usize, consumed_eof: bool, marker: u32) -> FastRecognizeOutcome {
18100 FastRecognizeOutcome {
18101 index,
18102 consumed_eof,
18103 diagnostics: DiagnosticSeqId::EMPTY,
18104 deferred_nodes: FastDeferredNodeId::EMPTY,
18105 nodes: NodeSeqId(marker),
18106 }
18107 }
18108
18109 #[test]
18110 fn clean_fast_outcome_dedupe_scans_small_lists_inline() {
18111 let mut outcomes = vec![
18112 clean_fast_outcome(4, false, 0),
18113 clean_fast_outcome(2, false, 1),
18114 clean_fast_outcome(4, false, 2),
18115 clean_fast_outcome(4, true, 3),
18116 clean_fast_outcome(2, false, 4),
18117 ];
18118 let mut scratch = FastOutcomeDedupScratch::default();
18119
18120 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
18121
18122 assert_eq!(strategy, FastOutcomeDedupStrategy::Inline);
18123 assert_eq!(
18124 outcomes
18125 .iter()
18126 .map(|outcome| (outcome.index, outcome.consumed_eof, outcome.nodes.0))
18127 .collect::<Vec<_>>(),
18128 vec![(4, false, 0), (2, false, 1), (4, true, 3)]
18129 );
18130 assert!(scratch.dense_words.is_empty());
18131 assert!(scratch.sparse_keys.is_empty());
18132 }
18133
18134 #[test]
18135 fn clean_fast_outcome_dedupe_uses_and_reuses_dense_bitmap() {
18136 let mut scratch = FastOutcomeDedupScratch::default();
18137 let mut outcomes = (100..109)
18138 .flat_map(|index| {
18139 [
18140 clean_fast_outcome(
18141 index,
18142 false,
18143 u32::try_from(index).expect("test index fits in u32"),
18144 ),
18145 clean_fast_outcome(index, false, u32::MAX),
18146 ]
18147 })
18148 .collect();
18149
18150 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
18151
18152 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
18153 assert_eq!(outcomes.len(), 9);
18154 assert_eq!(outcomes[0].nodes, NodeSeqId(100));
18155 let dense_capacity = scratch.dense_words.capacity();
18156
18157 let mut reused = (1_000..1_009)
18158 .map(|index| {
18159 clean_fast_outcome(
18160 index,
18161 false,
18162 u32::try_from(index).expect("test index fits in u32"),
18163 )
18164 })
18165 .collect();
18166 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
18167
18168 assert_eq!(strategy, FastOutcomeDedupStrategy::Dense);
18169 assert_eq!(reused.len(), 9);
18170 assert_eq!(scratch.dense_words.capacity(), dense_capacity);
18171 }
18172
18173 #[test]
18174 fn clean_fast_outcome_dedupe_uses_and_reuses_sparse_hash() {
18175 let mut scratch = FastOutcomeDedupScratch::default();
18176 let sparse_indexes = [
18177 0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000, 800_000,
18178 ];
18179 let mut outcomes = sparse_indexes
18180 .into_iter()
18181 .chain([400_000])
18182 .enumerate()
18183 .map(|(marker, index)| {
18184 clean_fast_outcome(
18185 index,
18186 false,
18187 u32::try_from(marker).expect("test marker fits in u32"),
18188 )
18189 })
18190 .collect();
18191
18192 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
18193
18194 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
18195 assert_eq!(outcomes.len(), sparse_indexes.len());
18196 assert_eq!(outcomes[4].nodes, NodeSeqId(4));
18197 let sparse_capacity = scratch.sparse_keys.capacity();
18198
18199 let mut reused = sparse_indexes
18200 .into_iter()
18201 .map(|index| {
18202 clean_fast_outcome(
18203 index,
18204 false,
18205 u32::try_from(index).expect("test index fits in u32"),
18206 )
18207 })
18208 .collect();
18209 let strategy = dedupe_clean_fast_outcomes(&mut reused, &mut scratch);
18210
18211 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
18212 assert_eq!(reused.len(), sparse_indexes.len());
18213 assert_eq!(scratch.sparse_keys.capacity(), sparse_capacity);
18214 }
18215
18216 #[test]
18217 fn clean_fast_outcome_dedupe_releases_oversized_sparse_hash() {
18218 let mut scratch = FastOutcomeDedupScratch::default();
18219 scratch
18220 .sparse_keys
18221 .reserve(MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS * 2);
18222 assert!(scratch.sparse_keys.capacity() > MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
18223 let mut outcomes = (0..9)
18224 .map(|index| clean_fast_outcome(index * 100_000, false, index as u32))
18225 .collect();
18226
18227 let strategy = dedupe_clean_fast_outcomes(&mut outcomes, &mut scratch);
18228
18229 assert_eq!(strategy, FastOutcomeDedupStrategy::Sparse);
18230 assert!(scratch.sparse_keys.is_empty());
18231 assert!(scratch.sparse_keys.capacity() <= MAX_RETAINED_FAST_OUTCOME_SPARSE_KEYS);
18232 }
18233
18234 #[test]
18235 fn fast_outcome_selection_respects_sll_tie_order() {
18236 let mut arena = RecognitionArena::default();
18237 let first = FastRecognizeOutcome {
18238 index: 1,
18239 consumed_eof: false,
18240 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
18241 line: 1,
18242 column: 0,
18243 message: "mismatched input 'x'".to_owned(),
18244 offending: None,
18245 }]),
18246 deferred_nodes: FastDeferredNodeId::EMPTY,
18247 nodes: NodeSeqId::EMPTY,
18248 };
18249 let second = FastRecognizeOutcome {
18250 index: first.index,
18251 consumed_eof: first.consumed_eof,
18252 diagnostics: DiagnosticSeqId::EMPTY,
18253 deferred_nodes: FastDeferredNodeId::EMPTY,
18254 nodes: NodeSeqId::EMPTY,
18255 };
18256
18257 let selected = select_best_fast_outcome(
18258 [first, second].into_iter(),
18259 PredictionMode::Sll,
18260 None,
18261 |_| panic!("caller-follow token probe should not run"),
18262 &arena,
18263 )
18264 .expect("one outcome should be selected");
18265 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
18266 let eof_second = FastRecognizeOutcome {
18267 index: second.index,
18268 consumed_eof: true,
18269 diagnostics: DiagnosticSeqId::EMPTY,
18270 deferred_nodes: FastDeferredNodeId::EMPTY,
18271 nodes: NodeSeqId::EMPTY,
18272 };
18273 let selected = select_best_fast_outcome(
18274 [first, eof_second].into_iter(),
18275 PredictionMode::Sll,
18276 None,
18277 |_| panic!("caller-follow token probe should not run"),
18278 &arena,
18279 )
18280 .expect("one outcome should be selected");
18281 assert!(!selected.consumed_eof);
18282 let selected = select_best_fast_outcome(
18283 [first, second].into_iter(),
18284 PredictionMode::Ll,
18285 None,
18286 |_| panic!("caller-follow token probe should not run"),
18287 &arena,
18288 )
18289 .expect("one outcome should be selected");
18290 assert!(selected.diagnostics.is_empty());
18291 }
18292
18293 #[test]
18294 fn recovery_fast_outcome_dedupe_uses_selection_rank() {
18295 let mut arena = RecognitionArena::default();
18296 let first = FastRecognizeOutcome {
18297 index: 3,
18298 consumed_eof: false,
18299 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
18300 line: 1,
18301 column: 0,
18302 message: "mismatched input 'x' expecting 'a'".to_owned(),
18303 offending: None,
18304 }]),
18305 deferred_nodes: FastDeferredNodeId::EMPTY,
18306 nodes: NodeSeqId::EMPTY,
18307 };
18308 let same_rank = FastRecognizeOutcome {
18309 index: first.index,
18310 consumed_eof: first.consumed_eof,
18311 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
18312 line: 1,
18313 column: 0,
18314 message: "mismatched input 'x' expecting 'b'".to_owned(),
18315 offending: None,
18316 }]),
18317 deferred_nodes: FastDeferredNodeId::EMPTY,
18318 nodes: NodeSeqId::EMPTY,
18319 };
18320 let better_rank = FastRecognizeOutcome {
18321 index: first.index,
18322 consumed_eof: first.consumed_eof,
18323 diagnostics: arena.diagnostic_sequence([ParserDiagnostic {
18324 line: 1,
18325 column: 0,
18326 message: "missing 'a' at 'x'".to_owned(),
18327 offending: None,
18328 }]),
18329 deferred_nodes: FastDeferredNodeId::EMPTY,
18330 nodes: NodeSeqId::EMPTY,
18331 };
18332 let mut outcomes = vec![first, same_rank, better_rank];
18333
18334 dedupe_fast_outcomes(&mut outcomes, &arena);
18335
18336 assert_eq!(outcomes.len(), 2);
18337 assert_eq!(
18338 arena
18339 .diagnostics(outcomes[0].diagnostics)
18340 .next()
18341 .expect("first diagnostic")
18342 .message,
18343 "mismatched input 'x' expecting 'a'"
18344 );
18345 assert_eq!(
18346 arena
18347 .diagnostics(outcomes[1].diagnostics)
18348 .next()
18349 .expect("second diagnostic")
18350 .message,
18351 "missing 'a' at 'x'"
18352 );
18353 }
18354
18355 #[test]
18356 fn fast_outcome_selection_prefers_generated_caller_follow() {
18357 let arena = RecognitionArena::default();
18358 let earlier = FastRecognizeOutcome {
18359 index: 7,
18360 consumed_eof: false,
18361 diagnostics: DiagnosticSeqId::EMPTY,
18362 deferred_nodes: FastDeferredNodeId::EMPTY,
18363 nodes: NodeSeqId::EMPTY,
18364 };
18365 let later = FastRecognizeOutcome {
18366 index: 8,
18367 consumed_eof: false,
18368 diagnostics: DiagnosticSeqId::EMPTY,
18369 deferred_nodes: FastDeferredNodeId::EMPTY,
18370 nodes: NodeSeqId::EMPTY,
18371 };
18372 let mut follow = TokenBitSet::default();
18373 follow.insert(5);
18374
18375 let selected = select_best_fast_outcome(
18376 [later, earlier].into_iter(),
18377 PredictionMode::Ll,
18378 Some(&follow),
18379 |index| (if index == 7 { 5 } else { TOKEN_EOF }, index == 7, true),
18380 &arena,
18381 )
18382 .expect("one outcome should be selected");
18383 assert_eq!(selected.index, 7);
18384
18385 let selected = select_best_fast_outcome(
18386 [later, earlier].into_iter(),
18387 PredictionMode::Ll,
18388 Some(&follow),
18389 |index| (if index == 7 { 5 } else { TOKEN_EOF }, false, true),
18390 &arena,
18391 )
18392 .expect("one outcome should be selected");
18393 assert_eq!(selected.index, 8);
18394
18395 let indented_next_statement = FastRecognizeOutcome {
18396 index: 9,
18397 consumed_eof: false,
18398 diagnostics: DiagnosticSeqId::EMPTY,
18399 deferred_nodes: FastDeferredNodeId::EMPTY,
18400 nodes: NodeSeqId::EMPTY,
18401 };
18402 let selected = select_best_fast_outcome(
18403 [indented_next_statement, earlier].into_iter(),
18404 PredictionMode::Ll,
18405 Some(&follow),
18406 |index| {
18407 let is_boundary = index == 7;
18408 let is_boundary_gap = matches!(index, 7 | 8);
18409 (
18410 if index == 7 { 5 } else { TOKEN_EOF },
18411 is_boundary,
18412 is_boundary_gap,
18413 )
18414 },
18415 &arena,
18416 )
18417 .expect("one outcome should be selected");
18418 assert_eq!(selected.index, 7);
18419
18420 let continuation = FastRecognizeOutcome {
18421 index: 10,
18422 consumed_eof: false,
18423 diagnostics: DiagnosticSeqId::EMPTY,
18424 deferred_nodes: FastDeferredNodeId::EMPTY,
18425 nodes: NodeSeqId::EMPTY,
18426 };
18427 let selected = select_best_fast_outcome(
18428 [continuation, earlier].into_iter(),
18429 PredictionMode::Ll,
18430 Some(&follow),
18431 |index| {
18432 let is_boundary = matches!(index, 7 | 9);
18433 (
18434 if index == 7 { 5 } else { TOKEN_EOF },
18435 is_boundary,
18436 is_boundary,
18437 )
18438 },
18439 &arena,
18440 )
18441 .expect("one outcome should be selected");
18442 assert_eq!(selected.index, 10);
18443
18444 let selected = select_best_fast_outcome(
18445 [earlier, later].into_iter(),
18446 PredictionMode::Sll,
18447 Some(&follow),
18448 |_| panic!("caller-follow token probe should not run in SLL mode"),
18449 &arena,
18450 )
18451 .expect("one outcome should be selected");
18452 assert_eq!(selected.index, 8);
18453 }
18454
18455 #[test]
18456 fn caller_follow_boundary_text_requires_separator_shape() {
18457 assert!(is_caller_follow_boundary_text(";"));
18458 assert!(is_caller_follow_boundary_text("\n"));
18459 assert!(is_caller_follow_boundary_text("\r\n "));
18460 assert!(is_caller_follow_boundary_text(";\n"));
18461 assert!(!is_caller_follow_boundary_text("\"\"\"line1\nline2\"\"\""));
18462 assert!(!is_caller_follow_boundary_text("/* line1\nline2 */"));
18463 assert!(!is_caller_follow_boundary_text("identifier"));
18464 assert!(is_caller_follow_boundary_gap_text(" \t "));
18465 assert!(is_caller_follow_boundary_gap_text("\n "));
18466 assert!(is_caller_follow_boundary_gap_text(";\t"));
18467 assert!(!is_caller_follow_boundary_gap_text(
18468 "\"\"\"line1\nline2\"\"\""
18469 ));
18470 assert!(!is_caller_follow_boundary_gap_text("/* line1\nline2 */"));
18471 }
18472
18473 #[test]
18474 fn caller_follow_token_info_treats_hidden_tokens_as_boundary_gaps() {
18475 let mut parser = mini_parser(vec![
18476 TestToken::new(5).with_text("\n"),
18477 TestToken::new(6)
18478 .with_text("// comment\n")
18479 .with_channel(HIDDEN_CHANNEL),
18480 TestToken::new(1).with_text("x"),
18481 TestToken::eof("parser-test", 1, 2, 0),
18482 ]);
18483
18484 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
18485 assert_eq!(parser.caller_follow_token_info(1), (6, false, true));
18486 assert_eq!(parser.caller_follow_token_info(2), (1, false, false));
18487 }
18488
18489 #[test]
18490 fn caller_follow_token_info_uses_stream_visible_channel() {
18491 let source = Source {
18492 tokens: vec![
18493 TestToken::new(5).with_text("\n").with_channel(2),
18494 TestToken::new(1).with_text("x").with_channel(2),
18495 TestToken::new(6)
18496 .with_text("// comment\n")
18497 .with_channel(HIDDEN_CHANNEL),
18498 TestToken::eof("parser-test", 1, 2, 0),
18499 ],
18500 index: 0,
18501 };
18502 let data = RecognizerData::new(
18503 "Mini.g4",
18504 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18505 );
18506 let mut parser = BaseParser::new(CommonTokenStream::with_channel(source, 2), data);
18507
18508 assert_eq!(parser.caller_follow_token_info(0), (5, true, true));
18509 assert_eq!(parser.caller_follow_token_info(1), (1, false, false));
18510 assert_eq!(parser.caller_follow_token_info(2), (6, false, true));
18511 }
18512
18513 #[test]
18514 fn reset_per_parse_caches_clears_state_expected_token_cache() {
18515 let atn = token_then_eof_atn();
18516 let mut parser = mini_parser(Vec::new());
18517
18518 let _ = parser.cached_state_expected_token_set(&atn, 0);
18519 assert!(!parser.state_expected_token_cache.is_empty());
18520
18521 parser.reset_per_parse_caches();
18522 assert!(parser.state_expected_token_cache.is_empty());
18523 }
18524
18525 #[test]
18526 fn empty_cycle_cache_survives_reset_and_invalidates_for_a_different_atn() {
18527 let cyclic = epsilon_cycle_atn();
18528 let acyclic = token_then_eof_atn();
18529 let mut parser = mini_parser(Vec::new());
18530
18531 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
18532 assert_eq!(
18533 parser.empty_cycle_cache_atn,
18534 Some(SharedAtnCacheKey::for_atn(&cyclic))
18535 );
18536 assert_eq!(parser.empty_cycle_cache[1], Some(true));
18537
18538 parser.reset_per_parse_caches();
18539 assert_eq!(parser.empty_cycle_cache[1], Some(true));
18540 assert!(parser.state_can_reenter_without_consuming(&cyclic, 1));
18541
18542 assert!(!parser.state_can_reenter_without_consuming(&acyclic, 1));
18543 assert_eq!(
18544 parser.empty_cycle_cache_atn,
18545 Some(SharedAtnCacheKey::for_atn(&acyclic))
18546 );
18547 assert_eq!(parser.empty_cycle_cache[1], Some(false));
18548 }
18549
18550 #[test]
18551 fn parser_error_with_empty_expected_set_omits_empty_set_display() {
18552 let source = Source {
18553 tokens: vec![
18554 TestToken::new(1).with_text("x"),
18555 TestToken::eof("parser-test", 1, 1, 1),
18556 ],
18557 index: 0,
18558 };
18559 let data = RecognizerData::new(
18560 "Mini.g4",
18561 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18562 );
18563 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
18564 let expected = ExpectedTokens {
18565 index: Some(0),
18566 symbols: BTreeSet::new(),
18567 no_viable: None,
18568 };
18569
18570 let (_, message) = parser.expected_error_message(0, 0, &expected);
18571
18572 assert_eq!(message, "mismatched input 'x'");
18573 }
18574
18575 #[test]
18576 fn eof_rule_stop_index_points_at_eof_token() {
18577 let source = Source {
18578 tokens: vec![
18579 TestToken::new(1).with_text("x"),
18580 TestToken::eof("parser-test", 1, 1, 1),
18581 ],
18582 index: 0,
18583 };
18584 let data = RecognizerData::new(
18585 "Mini.g4",
18586 Vocabulary::new([None, Some("'x'")], [None, Some("X")], [None::<&str>, None]),
18587 );
18588 let mut parser = BaseParser::new(CommonTokenStream::new(source), data);
18589
18590 assert_eq!(parser.rule_stop_token_index(1, true), Some(1));
18591 assert_eq!(parser.rule_stop_token_index(1, false), Some(0));
18592 }
18593
18594 #[test]
18595 fn generated_parser_action_uses_current_rule_stop_boundary() {
18596 let mut parser = mini_parser(vec![
18597 TestToken::new(1).with_text("x"),
18598 TestToken::eof("parser-test", 1, 1, 1),
18599 ]);
18600
18601 parser.match_token(1).expect("token should match");
18602 let action = parser.parser_action_at_current(7, 0, 0, false);
18603 assert_eq!(action.source_state(), 7);
18604 assert_eq!(action.rule_index(), 0);
18605 assert_eq!(action.start_index(), 0);
18606 assert_eq!(action.stop_index(), Some(0));
18607
18608 parser.match_eof().expect("EOF should match");
18609 let action = parser.parser_action_at_current(8, 0, 0, true);
18610 assert_eq!(action.stop_index(), Some(1));
18611 }
18612
18613 #[test]
18614 fn folds_left_recursive_boundary_into_rule_node() {
18615 let mut arena = RecognitionArena::default();
18616 let first = arena.push_node(ArenaRecognizedNode::Token {
18617 token: TokenId::try_from(0).expect("test token ID"),
18618 });
18619 let boundary = arena.push_node(ArenaRecognizedNode::LeftRecursiveBoundary {
18620 rule_index: 1,
18621 alt_number: 3,
18622 });
18623 let second = arena.push_node(ArenaRecognizedNode::Token {
18624 token: TokenId::try_from(1).expect("test token ID"),
18625 });
18626 let mut nodes = NodeSeqId::EMPTY;
18627 for node in [first, boundary, second].into_iter().rev() {
18628 nodes = arena.prepend(nodes, node);
18629 }
18630
18631 let folded = arena.fold_left_recursive_boundaries(nodes);
18632 let folded_nodes = arena.iter(folded).collect::<Vec<_>>();
18633
18634 assert_eq!(folded_nodes.len(), 2);
18635 let ArenaRecognizedNode::Rule {
18636 rule_index,
18637 invoking_state,
18638 alt_number,
18639 start_index,
18640 stop_index,
18641 children,
18642 ..
18643 } = arena.node(folded_nodes[0])
18644 else {
18645 panic!("first folded node should be a rule");
18646 };
18647 insta::assert_debug_snapshot!(
18651 "folds_left_recursive_boundary_into_rule_node",
18652 (
18653 rule_index,
18654 invoking_state,
18655 alt_number,
18656 start_index,
18657 stop_index
18658 )
18659 );
18660 assert_eq!(arena.iter(children).collect::<Vec<_>>(), [first]);
18661 assert_eq!(arena.node(folded_nodes[1]), arena.node(second));
18662
18663 let stats = arena.stats(folded, DiagnosticSeqId::EMPTY);
18664 assert_eq!(
18665 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18666 (4, 3, 1)
18667 );
18668 assert_eq!(
18669 (stats.total_links, stats.live_links, stats.dead_links),
18670 (9, 3, 6)
18671 );
18672 }
18673
18674 #[test]
18675 fn recognition_arena_reports_live_dead_and_retained_capacity() {
18676 let mut arena = RecognitionArena::default();
18677 let token = arena.push_node(ArenaRecognizedNode::Token {
18678 token: TokenId::try_from(0).expect("test token ID"),
18679 });
18680 let extra = arena.push_extra(RecognitionExtra::MissingToken {
18681 token_type: 2,
18682 at_index: 1,
18683 text: "<missing X>".to_owned(),
18684 });
18685 let missing = arena.push_node(ArenaRecognizedNode::MissingToken { extra });
18686 let discarded = arena.push_node(ArenaRecognizedNode::ErrorToken {
18687 token: TokenId::try_from(1).expect("test token ID"),
18688 });
18689 let mut live = NodeSeqId::EMPTY;
18690 live = arena.prepend(live, missing);
18691 live = arena.prepend(live, token);
18692 let _discarded_sequence = arena.prepend(NodeSeqId::EMPTY, discarded);
18693 let live_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
18694 line: 1,
18695 column: 0,
18696 message: "missing X".to_owned(),
18697 offending: None,
18698 }]);
18699 let _discarded_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
18700 line: 1,
18701 column: 1,
18702 message: "discarded".to_owned(),
18703 offending: None,
18704 }]);
18705 let deferred_children = arena.deferred_fragment(live);
18706 let _deferred_rule = arena.deferred_rule_node(FastDeferredRule {
18707 rule_index: 0,
18708 invoking_state: -1,
18709 start_index: 0,
18710 stop_index: Some(1),
18711 deferred_children,
18712 children: NodeSeqId::EMPTY,
18713 });
18714
18715 let stats = arena.stats(live, live_diagnostics);
18716
18717 assert_eq!(
18718 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18719 (3, 2, 1)
18720 );
18721 assert_eq!(
18722 (stats.total_links, stats.live_links, stats.dead_links),
18723 (5, 3, 2)
18724 );
18725 assert_eq!(
18726 (stats.total_extras, stats.live_extras, stats.dead_extras),
18727 (3, 2, 1)
18728 );
18729 assert!(size_of::<SeqLink>() <= 8);
18730 assert!(size_of::<DiagnosticLink>() <= 8);
18731 assert!(size_of::<FastDeferredNode>() <= 12);
18732 assert!(size_of::<FastDeferredRule>() <= 28);
18733 assert!(size_of::<FastRecognizeOutcome>() <= 24);
18734 let capacities = (
18735 stats.node_capacity,
18736 stats.link_capacity,
18737 stats.extra_capacity,
18738 );
18739 let deferred_capacities = (
18740 arena.deferred_nodes.capacity(),
18741 arena.deferred_rules.capacity(),
18742 );
18743
18744 arena.reset();
18745 let reset = arena.stats(NodeSeqId::EMPTY, DiagnosticSeqId::EMPTY);
18746 assert_eq!(
18747 (reset.total_nodes, reset.total_links, reset.total_extras),
18748 (0, 0, 0)
18749 );
18750 assert_eq!(
18751 (
18752 reset.node_capacity,
18753 reset.link_capacity,
18754 reset.extra_capacity,
18755 ),
18756 capacities
18757 );
18758 assert!(arena.deferred_nodes.is_empty());
18759 assert!(arena.deferred_rules.is_empty());
18760 assert_eq!(
18761 (
18762 arena.deferred_nodes.capacity(),
18763 arena.deferred_rules.capacity(),
18764 ),
18765 deferred_capacities
18766 );
18767 }
18768
18769 #[test]
18770 fn parser_computes_recognition_arena_stats_on_demand() {
18771 let mut parser = mini_parser(Vec::new());
18772 let live = parser
18773 .recognition_arena
18774 .push_node(ArenaRecognizedNode::Token {
18775 token: TokenId::try_from(0).expect("test token ID"),
18776 });
18777 let discarded = parser
18778 .recognition_arena
18779 .push_node(ArenaRecognizedNode::ErrorToken {
18780 token: TokenId::try_from(1).expect("test token ID"),
18781 });
18782 let live_root = parser.recognition_arena.prepend(NodeSeqId::EMPTY, live);
18783 let _discarded_root = parser
18784 .recognition_arena
18785 .prepend(NodeSeqId::EMPTY, discarded);
18786 parser.finish_recognition_arena(live_root, DiagnosticSeqId::EMPTY);
18787
18788 let stats = parser.recognition_arena_stats();
18789
18790 assert_eq!(
18791 (stats.total_nodes, stats.live_nodes, stats.dead_nodes),
18792 (2, 1, 1)
18793 );
18794 assert_eq!(
18795 (stats.total_links, stats.live_links, stats.dead_links),
18796 (2, 1, 1)
18797 );
18798 }
18799
18800 #[test]
18801 fn recognition_arena_drops_capacity_above_retention_limit() {
18802 let mut storage = Vec::<u8>::with_capacity(4);
18803 storage.extend([1, 2, 3]);
18804
18805 reset_arena_vec(&mut storage, 3);
18806
18807 assert!(storage.is_empty());
18808 assert_eq!(storage.capacity(), 0);
18809 }
18810
18811 #[test]
18812 fn recognition_arena_concatenates_diagnostics_in_source_order() {
18813 let mut arena = RecognitionArena::default();
18814 let prefix = arena.diagnostic_sequence([
18815 ParserDiagnostic {
18816 line: 1,
18817 column: 0,
18818 message: "first".to_owned(),
18819 offending: None,
18820 },
18821 ParserDiagnostic {
18822 line: 1,
18823 column: 1,
18824 message: "second".to_owned(),
18825 offending: None,
18826 },
18827 ]);
18828 let suffix = arena.diagnostic_sequence([ParserDiagnostic {
18829 line: 1,
18830 column: 2,
18831 message: "third".to_owned(),
18832 offending: None,
18833 }]);
18834 let extras_before = arena.extras.len();
18835
18836 let combined = arena.concat_diagnostics(prefix, suffix);
18837 let messages = arena
18838 .diagnostics(combined)
18839 .map(|diagnostic| diagnostic.message.as_str())
18840 .collect::<Vec<_>>();
18841
18842 assert_eq!(messages, ["first", "second", "third"]);
18843 assert_eq!(arena.extras.len(), extras_before);
18844 }
18845
18846 #[test]
18847 fn outcome_ties_keep_later_non_recursive_alternative() {
18848 let arena = RecognitionArena::default();
18849 let first = RecognizeOutcome {
18850 index: 1,
18851 consumed_eof: false,
18852 alt_number: 0,
18853 member_values: MemberEnv::new(),
18854 return_values: BTreeMap::new(),
18855 diagnostics: DiagnosticSeqId::EMPTY,
18856 decisions: Vec::new(),
18857 actions: vec![ParserAction::new(1, 0, 0, None)],
18858 nodes: NodeSeqId::EMPTY,
18859 };
18860 let second = RecognizeOutcome {
18861 actions: vec![ParserAction::new(2, 0, 0, None)],
18862 ..first.clone()
18863 };
18864
18865 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18866 .expect("one outcome should be selected");
18867 assert_eq!(selected.actions[0].source_state(), 2);
18868 }
18869
18870 #[test]
18871 fn outcome_ties_prefer_more_actions_for_non_recursive_paths() {
18872 let arena = RecognitionArena::default();
18873 let first = RecognizeOutcome {
18874 index: 1,
18875 consumed_eof: false,
18876 alt_number: 0,
18877 member_values: MemberEnv::new(),
18878 return_values: BTreeMap::new(),
18879 diagnostics: DiagnosticSeqId::EMPTY,
18880 decisions: Vec::new(),
18881 actions: vec![ParserAction::new(1, 0, 0, None)],
18882 nodes: NodeSeqId::EMPTY,
18883 };
18884 let second = RecognizeOutcome {
18885 actions: vec![
18886 ParserAction::new(2, 0, 0, None),
18887 ParserAction::new(3, 0, 0, None),
18888 ],
18889 ..first.clone()
18890 };
18891
18892 let selected = select_best_outcome([second, first].into_iter(), PredictionMode::Ll, &arena)
18893 .expect("one outcome should be selected");
18894 assert_eq!(selected.actions.len(), 2);
18895 }
18896
18897 #[test]
18898 fn outcome_ties_prefer_later_action_stop_for_greedy_optional_paths() {
18899 let arena = RecognitionArena::default();
18900 let first = RecognizeOutcome {
18901 index: 7,
18902 consumed_eof: false,
18903 alt_number: 0,
18904 member_values: MemberEnv::new(),
18905 return_values: BTreeMap::new(),
18906 diagnostics: DiagnosticSeqId::EMPTY,
18907 decisions: vec![1, 0],
18908 actions: vec![
18909 ParserAction::new(23, 2, 2, Some(4)),
18910 ParserAction::new(23, 2, 0, Some(6)),
18911 ],
18912 nodes: NodeSeqId::EMPTY,
18913 };
18914 let second = RecognizeOutcome {
18915 decisions: vec![0, 1],
18916 actions: vec![
18917 ParserAction::new(23, 2, 2, Some(6)),
18918 ParserAction::new(23, 2, 0, Some(6)),
18919 ],
18920 ..first.clone()
18921 };
18922
18923 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18924 .expect("one outcome should be selected");
18925 assert_eq!(selected.actions[0].stop_index(), Some(6));
18926 }
18927
18928 #[test]
18929 fn outcome_ties_keep_first_recursive_tree_shape() {
18930 let mut arena = RecognitionArena::default();
18931 let token = arena.push_node(ArenaRecognizedNode::Token {
18932 token: TokenId::try_from(0).expect("test token ID"),
18933 });
18934 let token_children = arena.prepend(NodeSeqId::EMPTY, token);
18935 let inner = arena.push_node(ArenaRecognizedNode::Rule {
18936 rule_index: 1,
18937 invoking_state: -1,
18938 alt_number: 0,
18939 start_index: 0,
18940 stop_index: Some(0),
18941 return_values: None,
18942 children: token_children,
18943 });
18944 let inner_children = arena.prepend(NodeSeqId::EMPTY, inner);
18945 let outer = arena.push_node(ArenaRecognizedNode::Rule {
18946 rule_index: 1,
18947 invoking_state: -1,
18948 alt_number: 0,
18949 start_index: 0,
18950 stop_index: Some(0),
18951 return_values: None,
18952 children: inner_children,
18953 });
18954 let recursive_nodes = arena.prepend(NodeSeqId::EMPTY, outer);
18955 let first = RecognizeOutcome {
18956 index: 1,
18957 consumed_eof: false,
18958 alt_number: 0,
18959 member_values: MemberEnv::new(),
18960 return_values: BTreeMap::new(),
18961 diagnostics: DiagnosticSeqId::EMPTY,
18962 decisions: Vec::new(),
18963 actions: vec![ParserAction::new(1, 0, 0, None)],
18964 nodes: recursive_nodes,
18965 };
18966 let second = RecognizeOutcome {
18967 index: 1,
18968 consumed_eof: false,
18969 alt_number: 0,
18970 member_values: MemberEnv::new(),
18971 return_values: BTreeMap::new(),
18972 diagnostics: DiagnosticSeqId::EMPTY,
18973 decisions: Vec::new(),
18974 actions: vec![ParserAction::new(2, 0, 0, None)],
18975 nodes: recursive_nodes,
18976 };
18977
18978 let selected = select_best_outcome([first, second].into_iter(), PredictionMode::Ll, &arena)
18979 .expect("one outcome should be selected");
18980 assert_eq!(selected.actions[0].source_state(), 1);
18981 }
18982
18983 #[test]
18984 fn sll_outcome_selection_keeps_earlier_recovered_alt() {
18985 let mut arena = RecognitionArena::default();
18986 let recovered_diagnostics = arena.diagnostic_sequence([ParserDiagnostic {
18987 line: 1,
18988 column: 3,
18989 message: "missing 'Y' at '<EOF>'".to_owned(),
18990 offending: None,
18991 }]);
18992 let first_alt = RecognizeOutcome {
18993 index: 2,
18994 consumed_eof: true,
18995 alt_number: 0,
18996 member_values: MemberEnv::new(),
18997 return_values: BTreeMap::new(),
18998 diagnostics: recovered_diagnostics,
18999 decisions: vec![0],
19000 actions: vec![ParserAction::new(1, 0, 0, None)],
19001 nodes: NodeSeqId::EMPTY,
19002 };
19003 let second_alt = RecognizeOutcome {
19004 diagnostics: DiagnosticSeqId::EMPTY,
19005 decisions: vec![1],
19006 actions: vec![ParserAction::new(2, 0, 0, None)],
19007 ..first_alt.clone()
19008 };
19009
19010 let selected = select_best_outcome(
19011 [second_alt, first_alt].into_iter(),
19012 PredictionMode::Sll,
19013 &arena,
19014 )
19015 .expect("one outcome should be selected");
19016 assert_eq!(arena.diagnostics_len(selected.diagnostics), 1);
19017 assert_eq!(selected.decisions, [0]);
19018 }
19019}